π Introduction β
Just want to try it out? Skip to the π Get Started .
π Overview β
Cano TS is a lightweight and type-safe utility for function composition in TypeScript, inspired by Elixirβs pipe operator (|>)
. It allows you to build fluent, readable, and maintainable pipelines for both synchronous and asynchronous operations.
typescript
import { pipeSync } from "cano-ts";
const applyDiscount =
(price: number, discount: number) => price - discount;
const applyTax =
(price: number, taxRate: number) => price + price * taxRate;
const formatPrice =
(price: number, currency: string) => `${currency} ${price.toFixed(2)}`;
const finalPrice = pipeSync(100)
.next(applyDiscount, 10) // 100 - 10 = 90
.next(applyTax, 0.2) // 90 + 20% tax = 108
.next(formatPrice, "$") // Format as "$ 108.00"
.result();
console.log(finalPrice); // "$ 108.00"
β¨ Features β
- β
Fluent API β Chain functions using
.next()
- β
Supports async & sync pipelines β
pipe()
forasync
,pipeSync()
for sync - β
Function History Tracking β Debug easily with
.log()
- β
Array Utilities β Built-in
E
module with functional array operations - β Fully Type-Safe β Leverages TypeScript generics for strong typings
π§ Array Utilities with E Module β
The E
module provides functional array operations that integrate seamlessly with pipes:
typescript
import { pipeSync, E } from "cano-ts";
// Data processing pipeline
const users = [
{ id: 1, name: "Alice", age: 25, active: true },
{ id: 2, name: "Bob", age: 30, active: false },
{ id: 3, name: "Charlie", age: 35, active: true },
{ id: 4, name: "Diana", age: 28, active: true },
];
const activeUserNames = pipeSync(users)
.next(E.filter, (user) => user.active) // Filter active users
.next(E.sort, (a, b) => b.age - a.age) // Sort by age (desc)
.next(E.map, (user) => user.name) // Extract names
.next(E.slice, 0, 2) // Take first 2
.next(E.join, " & ") // Join with "&"
.result();
console.log(activeUserNames); // "Charlie & Diana"
Available E Functions:
E.map
,E.filter
,E.reduce
,E.find
- Core transformationsE.sort
,E.reverse
,E.slice
- Array manipulationE.concat
,E.flat
,E.join
- Combining and formattingE.every
,E.some
,E.includes
- Boolean operations
π Real-World Examples β
Data Processing Pipeline β
typescript
import { pipe, E } from "cano-ts";
// Process sales data
const salesData = [
{ product: "Laptop", price: 999, category: "Electronics", inStock: true },
{ product: "Phone", price: 699, category: "Electronics", inStock: false },
{ product: "Book", price: 25, category: "Education", inStock: true },
{ product: "Tablet", price: 399, category: "Electronics", inStock: true },
];
const electronicsReport = pipeSync(salesData)
.next(E.filter, (item) => item.category === "Electronics" && item.inStock)
.next(E.sort, (a, b) => b.price - a.price)
.next(E.map, (item) => `${item.product}: $${item.price}`)
.next(E.join, "\n")
.result();
console.log(electronicsReport);
// Laptop: $999
// Tablet: $399
Async Data Fetching with Processing β
typescript
async function fetchUsers() {
const response = await fetch('/api/users');
return response.json();
}
async function enrichUserData(user) {
const profile = await fetch(`/api/profiles/${user.id}`);
return { ...user, profile: await profile.json() };
}
const topActiveUsers = await pipe()
.next(fetchUsers) // Fetch all users
.next(E.filter, (user) => user.active) // Filter active users
.next(E.slice, 0, 5) // Take top 5
.next(E.map, enrichUserData) // Enrich each user (parallel)
.result();