diff --git a/src/chain.ts b/src/chain.ts index 832f5d0..2b91a52 100644 --- a/src/chain.ts +++ b/src/chain.ts @@ -7,8 +7,12 @@ export class Chain { constructor(private initialValue: I, private ops: ((value: any) => any)[] = []) { } - pipe(fn: (value: O) => U): Chain { - return new Chain(this.initialValue, [...this.ops, fn]); + pipe(fn: (value: O) => U): Chain; + pipe(fn: (value: O, ...args: Args) => U, builder: (x: (...args: Args) => void) => void): Chain; + pipe(fn: (value: O, ...args: Args) => U, builder?: (x: (...args: Args) => void) => void): Chain { + let thisArgs: Args = [] as unknown as Args; + builder?.((...args: Args) => thisArgs = args); + return new Chain(this.initialValue, [...this.ops, (value: O) => fn(value, ...thisArgs)]); } value(): O { @@ -16,39 +20,6 @@ export class Chain { } } -/** - * Converts a function into a format suitable for use with the `Chain.pipe` method. - * This allows for the inclusion of additional parameters to the function prior to its - * execution in the chain. `$op` effectively curries the provided function, splitting - * its application into two steps: first, `$op` is called with the function to adapt, - * returning a new function. This returned function is then called with the additional - * arguments needed for the adapted function, and it returns yet another function that - * expects the current value in the chain as its input. This final function is suitable - * for use with `Chain.pipe`, as it matches the expected signature by taking a single - * argument—the current value in the chain—and applying the original function to it, - * along with the pre-specified additional arguments. - * - * @param fn The function to be converted. This function can take multiple parameters, - * with the first parameter intended to be the current value in the chain, and the - * rest being additional arguments provided during the subsequent call. - * @returns A function that, when called with additional arguments, returns a new - * function designed for the `Chain.pipe` method. This new function takes the current - * value in the chain as its sole argument and applies the original function with the - * specified additional arguments. - * - * @example - * // Assuming `add` and `multiply` are defined as: - * // const add = (x, y) => x + y; - * // const multiply = (x, y) => x * y; - * - * // Correct usage in a chain - * chain(5).pipe($op(add)(5)).pipe($op(multiply)(2)).value(); // returns 20 - */ -export function $op(fn: (value: T, ...args: Args) => U) { - return (...args: Args) => (value: T) => fn(value, ...args); -} - - /** * Chains a value to be used in a pipeline. * @param value value to chain diff --git a/tests/chain.test.ts b/tests/chain.test.ts index 3b94c5b..78966a5 100644 --- a/tests/chain.test.ts +++ b/tests/chain.test.ts @@ -1,42 +1,9 @@ import { describe, test, it, expect } from 'bun:test' -import { $op, chain } from '../src/index' +import { chain } from '../src/index' // Define a simple function for testing const add = (x: number, y: number): number => x + y; -describe('$op function', () => { - it('correctly curries a function with provided arguments', () => { - // Curry the `add` function with $op - const curriedAdd = $op(add); - - // Prepare the curried function with one argument (5) - const addFive = curriedAdd(5); - - // Now `addFive` should be a function that expects another number and adds 5 to it - const result = addFive(10); // This should be equivalent to `add(10, 5)` - - // Verify the result is as expected - expect(result).toBe(15); - }); - - it('returns a function that correctly applies all arguments to the original function', () => { - // Define a more complex function for testing - const subtract = (x: number, y: number, z: number): number => x - y - z; - - // Curry the `subtract` function with $op - const curriedSubtract = $op(subtract); - - // Prepare the curried function with two arguments (10, 5) - const subtractTenAndFive = curriedSubtract(10, 5); - - // Now `subtractTenAndFive` should be a function that expects another number, - // subtracts 10 and then 5 from it - const result = subtractTenAndFive(20); // This should be equivalent to `subtract(20, 10, 5)` - - // Verify the result is as expected - expect(result).toBe(5); - }); -}); describe('Chain class', () => { it('initializes with a value and unwraps it correctly', () => { @@ -73,4 +40,13 @@ describe('Chain class', () => { // Expected result is a string transformation of the initial value expect(result).toBe("Hello 5"); }); + + it('handles operations with arguments', () => { + const initialValue = 5; + const add = (x: number, y: number) => x + y; + const result = chain(initialValue).pipe(add, x => x(5)).value(); + + expect(result).toBe(10); + }); + }); \ No newline at end of file