Huge News!Announcing our $40M Series B led by Abstract Ventures.Learn More
Socket
Sign inDemoInstall
Socket

composable-functions

Package Overview
Dependencies
Maintainers
0
Versions
24
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

composable-functions - npm Package Compare versions

Comparing version 4.3.0 to 4.4.0

esm/context/context.js

31

API.md

@@ -39,5 +39,5 @@ # API Reference

- [Combinators with Context](#combinators-with-context)
- [context.branch](#contextbranch)
- [context.pipe](#contextpipe)
- [context.sequence](#contextsequence)
- [withContext.branch](#withcontextbranch)
- [withContext.pipe](#withcontextpipe)
- [withContext.sequence](#withcontextsequence)
- [Serialization](#serialization)

@@ -463,3 +463,3 @@ - [serialize](#serialize)

const traceToConsole = trace((result, ...args) => {
if(!context.result.success) {
if(!result.success) {
console.trace("Composable Failure ", result, ...args)

@@ -753,11 +753,11 @@ }

Use the sequential combinators from the namespace `context` to get this behavior.
Use the sequential combinators from the namespace `withContext` to get this behavior.
For a deeper explanation check the [`context` docs](./context.md).
For a deeper explanation check the [context docs](./context.md).
## context.branch
## withContext.branch
It is the same as `branch` but it will forward the context to the next composable.
```ts
import { context } from 'composable-functions'
import { withContext } from 'composable-functions'

@@ -779,3 +779,3 @@ const getIdOrEmail = (data: { id?: number, email?: string }) => {

}
const findUserByIdOrEmail = context.branch(
const findUserByIdOrEmail = withContext.branch(
getIdOrEmail,

@@ -786,7 +786,8 @@ (data) => (typeof data === "number" ? findUserById : findUserByEmail),

```
## context.pipe
## withContext.pipe
Similar to `pipe` but it will forward the context to the next composable.
```ts
import { context } from 'composable-functions'
import { withContext } from 'composable-functions'

@@ -797,3 +798,3 @@ const a = (aNumber: number, ctx: { user: User }) => String(aNumber)

const d = context.pipe(a, b, c)
const d = withContext.pipe(a, b, c)

@@ -803,7 +804,7 @@ const result = await d(1, { user: { admin: true } })

## context.sequence
## withContext.sequence
Similar to `sequence` but it will forward the context to the next composable.
```ts
import { context } from 'composable-functions'
import { withContext } from 'composable-functions'

@@ -814,3 +815,3 @@ const a = (aNumber: number, ctx: { user: User }) => String(aNumber)

const d = context.sequence(a, b, c)
const d = withContext.sequence(a, b, c)

@@ -817,0 +818,0 @@ const result = await d(1, { user: { admin: true } })

@@ -16,3 +16,3 @@ ## Context

```tsx
import { context } from 'composable-functions'
import { withContext } from 'composable-functions'
const dangerousFunction = async (input: string, { user } : { user: { name: string, admin: boolean } }) => {

@@ -22,3 +22,3 @@ // do something that only the admin can do

const carryUser = context.pipe(gatherInput, dangerousFunction)
const carryUser = withContext.pipe(gatherInput, dangerousFunction)
```

@@ -32,6 +32,6 @@

The context.pipe function allows you to compose multiple functions in a sequence, forwarding the context to each function in the chain.
The `withContext.pipe` function allows you to compose multiple functions in a sequence, forwarding the context to each function in the chain.
```ts
import { context } from 'composable-functions'
import { withContext } from 'composable-functions'

@@ -41,3 +41,3 @@ const a = (str: string, ctx: { user: User }) => str === '1'

const pipeline = context.pipe(a, b)
const pipeline = withContext.pipe(a, b)

@@ -55,6 +55,6 @@ const result = await pipeline('1', { user: { admin: true } })

### `sequence`
The context.sequence function works similarly to pipe, but it returns a tuple containing the result of each function in the sequence.
The `withContext.sequence` function works similarly to pipe, but it returns a tuple containing the result of each function in the sequence.
```ts
import { context } from 'composable-functions'
import { withContext } from 'composable-functions'

@@ -64,3 +64,3 @@ const a = (str: string, ctx: { user: User }) => str === '1'

const sequence = context.sequence(a, b)
const sequence = withContext.sequence(a, b)

@@ -79,6 +79,6 @@ const result = await sequence('1', { user: { admin: true } })

The context.branch function adds conditional logic to your compositions, forwarding the context to each branch as needed.
The `withContext.branch` function adds conditional logic to your compositions, forwarding the context to each branch as needed.
```ts
import { composable, context } from 'composable-functions'
import { withContext } from 'composable-functions'

@@ -88,3 +88,3 @@ const adminIncrement = (a: number, { user }: { user: { admin: boolean } }) =>

const adminMakeItEven = (sum: number) => sum % 2 != 0 ? adminIncrement : null
const incrementUntilEven = context.branch(adminIncrement, adminMakeItEven)
const incrementUntilEven = withContext.branch(adminIncrement, adminMakeItEven)

@@ -91,0 +91,0 @@ const result = await incrementUntilEven(1, { user: { admin: true } })

@@ -16,7 +16,7 @@ import * as A from '../combinators.js';

* ```ts
* import { context } from 'composable-functions'
* import { withContext } from 'composable-functions'
*
* const a = (aNumber: number) => String(aNumber)
* const b = (aString: string) => aString === '1'
* const d = context.pipe(a, b)
* const d = withContext.pipe(a, b)
* // ^? ComposableWithSchema<boolean>

@@ -31,3 +31,3 @@ * ```

/**
* Works like `context.pipe` but it will collect the output of every function in a tuple.
* Works like `withContext.pipe` but it will collect the output of every function in a tuple.
*

@@ -37,7 +37,7 @@ * @example

* ```ts
* import { context } from 'composable-functions'
* import { withContext } from 'composable-functions'
*
* const a = (aNumber: number) => String(aNumber)
* const b = (aString: string) => aString === '1'
* const aComposable = context.sequence(a, b)
* const aComposable = withContext.sequence(a, b)
* // ^? ComposableWithSchema<[string, boolean]>

@@ -44,0 +44,0 @@ * ```

import { branch, pipe, sequence } from './index.js';
/**
* @deprecated use `import { context } from 'composable-functions'` instead
* @deprecated use `import { withContext } from 'composable-functions'` instead
*/

@@ -5,0 +5,0 @@ const environment = {

@@ -8,2 +8,3 @@ export { applySchema, composable, failure, fromSuccess, success, withSchema, } from './constructors.js';

export { environment } from './context/environment.js';
export * as context from './context/index.js';
export { context } from './context/context.js';
export * as withContext from './context/index.js';

@@ -11,3 +11,3 @@ # Migrating from domain-functions

- 🕵🏽 Runtime Validation: Use the [`applySchema`](./API.md#applyschema) function for optional runtime validation of inputs and context. This provides flexibility to enforce data integrity when needed without mandating it for every function. Assuming you have a big chain of composables you can use [`applySchema`](./API.md#applyschema) to run your runtime validation only once **avoiding unnecessary processing**.
- 🔀 Flexible Compositions: The new combinators, such as [`context.pipe`](./API.md#contextpipe), [`context.sequence`](./API.md#contextsequence), and [`context.branch`](./API.md#contextbranch), offer powerful ways to manage **typed context** which are contextual information across your compositions.
- 🔀 Flexible Compositions: The new combinators, such as [`withContext.pipe`](./API.md#withcontextpipe), [`withContext.sequence`](./API.md#withcontextsequence), and [`withContext.branch`](./API.md#withcontextbranch), offer powerful ways to manage **typed context** which are contextual information across your compositions.
- 🛠️ Incremental Migration: Seamlessly migrate your existing codebase incrementally. **Both `domain-functions` and `composable-functions` can coexist**, allowing you to transition module by module.

@@ -93,12 +93,12 @@ - 🛟 Enhanced Combinators: New and improved combinators like [`map`](./API.md#map), [`mapParameters`](./API.md#mapparameters), [`mapErrors`](./API.md#maperrors) and [`catchFailure`](./API.md#catchfailure) provide more control over error handling and transformation, making your **code more resilient**.

Use the sequential combinators from the namespace `context` to keep this familiar behavior.
Use the sequential combinators from the namespace `withContext` to keep this familiar behavior.
```ts
import { context } from 'composable-functions'
import { withContext } from 'composable-functions'
const result = context.pipe(fn1, fn2)(input, ctx)
// same for `context.sequence` and `context.branch`
const result = withContext.pipe(fn1, fn2)(input, ctx)
// same for `withContext.sequence` and `withContext.branch`
```
**Note**: The `pipe`, `sequence`, and `branch` outside of the `context` namespace will not keep the context through the composition.
**Note**: The `pipe`, `sequence`, and `branch` outside of the `withContext` namespace will not keep the context through the composition.

@@ -271,9 +271,9 @@ ## Modified combinators

| `merge(df1, df2)` | `map(all(fn1, fn2), mergeObjects)` |
| `branch(df1, (res) => res ? null : df2)` | `context.branch(fn1, (res) => res ? null : fn2)` |
| `branch(df1, (res) => res ? null : df2)` | `withContext.branch(fn1, (res) => res ? null : fn2)` |
| -- | `branch(fn1, (res) => res ? null : fn2)` without context |
| `pipe(df1, df2)` | `context.pipe(fn1, fn2)` |
| `pipe(df1, df2)` | `withContext.pipe(fn1, fn2)` |
| -- | `pipe(fn1, fn2)` without context |
| `sequence(df1, df2)` | `context.sequence(fn1, fn2)` |
| `sequence(df1, df2)` | `withContext.sequence(fn1, fn2)` |
| -- | `sequence(fn1, fn2)` without context |
| `collectSequence({ name: nameDf, age: ageDf })` | `map(context.sequence(nameDf, ageDf), ([name, age]) => ({ name, age }))` |
| `collectSequence({ name: nameDf, age: ageDf })` | `map(withContext.sequence(nameDf, ageDf), ([name, age]) => ({ name, age }))` |
| `map(df, (o) => ({ result: o }))` | `map(fn, (o) => ({ result: o }))` |

@@ -280,0 +280,0 @@ | -- | `map(fn, (o, ...args) => ({ result: o, args }))` |

{
"name": "composable-functions",
"version": "4.3.0",
"version": "4.4.0",
"description": "Types and functions to make composition easy and safe",

@@ -5,0 +5,0 @@ "author": "Seasoned",

@@ -42,7 +42,7 @@ "use strict";

* ```ts
* import { context } from 'composable-functions'
* import { withContext } from 'composable-functions'
*
* const a = (aNumber: number) => String(aNumber)
* const b = (aString: string) => aString === '1'
* const d = context.pipe(a, b)
* const d = withContext.pipe(a, b)
* // ^? ComposableWithSchema<boolean>

@@ -58,3 +58,3 @@ * ```

/**
* Works like `context.pipe` but it will collect the output of every function in a tuple.
* Works like `withContext.pipe` but it will collect the output of every function in a tuple.
*

@@ -64,7 +64,7 @@ * @example

* ```ts
* import { context } from 'composable-functions'
* import { withContext } from 'composable-functions'
*
* const a = (aNumber: number) => String(aNumber)
* const b = (aString: string) => aString === '1'
* const aComposable = context.sequence(a, b)
* const aComposable = withContext.sequence(a, b)
* // ^? ComposableWithSchema<[string, boolean]>

@@ -71,0 +71,0 @@ * ```

@@ -6,3 +6,3 @@ "use strict";

/**
* @deprecated use `import { context } from 'composable-functions'` instead
* @deprecated use `import { withContext } from 'composable-functions'` instead
*/

@@ -9,0 +9,0 @@ const environment = {

@@ -26,3 +26,3 @@ "use strict";

Object.defineProperty(exports, "__esModule", { value: true });
exports.context = exports.environment = exports.isInputError = exports.isEnvironmentError = exports.isContextError = exports.InputError = exports.ErrorList = exports.EnvironmentError = exports.ContextError = exports.serializeError = exports.serialize = exports.inputFromUrl = exports.inputFromSearch = exports.inputFromFormData = exports.inputFromForm = exports.trace = exports.sequence = exports.pipe = exports.mergeObjects = exports.mapParameters = exports.mapErrors = exports.map = exports.collect = exports.catchFailure = exports.branch = exports.all = exports.withSchema = exports.success = exports.fromSuccess = exports.failure = exports.composable = exports.applySchema = void 0;
exports.withContext = exports.context = exports.environment = exports.isInputError = exports.isEnvironmentError = exports.isContextError = exports.InputError = exports.ErrorList = exports.EnvironmentError = exports.ContextError = exports.serializeError = exports.serialize = exports.inputFromUrl = exports.inputFromSearch = exports.inputFromFormData = exports.inputFromForm = exports.trace = exports.sequence = exports.pipe = exports.mergeObjects = exports.mapParameters = exports.mapErrors = exports.map = exports.collect = exports.catchFailure = exports.branch = exports.all = exports.withSchema = exports.success = exports.fromSuccess = exports.failure = exports.composable = exports.applySchema = void 0;
var constructors_js_1 = require("./constructors.js");

@@ -66,2 +66,4 @@ Object.defineProperty(exports, "applySchema", { enumerable: true, get: function () { return constructors_js_1.applySchema; } });

Object.defineProperty(exports, "environment", { enumerable: true, get: function () { return environment_js_1.environment; } });
exports.context = __importStar(require("./context/index.js"));
var context_js_1 = require("./context/context.js");
Object.defineProperty(exports, "context", { enumerable: true, get: function () { return context_js_1.context; } });
exports.withContext = __importStar(require("./context/index.js"));

@@ -41,3 +41,3 @@ import type { BranchReturn, CanComposeInParallel, CanComposeInSequence, Composable, MapParametersReturn, MergeObjects, PipeReturn, RecordToTuple, Result, SequenceReturn, UnpackData } from './types.js';

*/
declare function pipe<Fns extends [Internal.AnyFn, ...Internal.AnyFn[]]>(...fns: Fns): PipeReturn<CanComposeInSequence<Internal.Composables<Fns>>>;
declare function pipe<Fns extends [Function, ...Function[]]>(...fns: Fns): PipeReturn<CanComposeInSequence<Internal.Composables<Fns>>>;
/**

@@ -63,3 +63,3 @@ * Composes functions to run in parallel returning a tuple of all results when all are successful.

*/
declare function all<Fns extends Internal.AnyFn[]>(...fns: Fns): Composable<(...args: Parameters<NonNullable<CanComposeInParallel<Internal.Composables<Fns>>[0]>>) => {
declare function all<Fns extends Function[]>(...fns: Fns): Composable<(...args: Parameters<NonNullable<CanComposeInParallel<Internal.Composables<Fns>>[0]>>) => {
[k in keyof Fns]: UnpackData<Internal.Composables<Fns>[k]>;

@@ -81,5 +81,5 @@ }>;

*/
declare function collect<Fns extends Record<string, Internal.AnyFn>>(fns: Fns): Composable<(...args: Parameters<Exclude<CanComposeInParallel<RecordToTuple<Internal.Composables<Fns>>>[0], undefined>>) => {
declare function collect<Fns extends Record<string, Function>>(fns: Fns): Fns extends Record<string, Internal.AnyFn> ? Composable<(...args: Parameters<Exclude<CanComposeInParallel<RecordToTuple<Internal.Composables<Fns>>>[0], undefined>>) => {
[key in keyof Fns]: UnpackData<Composable<Fns[key]>>;
}>;
}> : never;
/**

@@ -99,3 +99,3 @@ * Works like `pipe` but it will collect the output of every function in a tuple.

*/
declare function sequence<Fns extends [Internal.AnyFn, ...Internal.AnyFn[]]>(...fns: Fns): SequenceReturn<CanComposeInSequence<Internal.Composables<Fns>>>;
declare function sequence<Fns extends [Function, ...Function[]]>(...fns: Fns): SequenceReturn<CanComposeInSequence<Internal.Composables<Fns>>>;
/**

@@ -117,3 +117,3 @@ * It takes a Composable and a mapper to apply a transformation over the resulting output. It only runs if the function was successfull. When the given function fails, its error is returned wihout changes.

*/
declare function map<Fn extends Internal.AnyFn, O>(fn: Fn, mapper: (res: UnpackData<Composable<Fn>>, ...originalInput: Parameters<Fn>) => O | Promise<O>): Composable<(...args: Parameters<Fn>) => O>;
declare function map<Fn extends Function, O>(fn: Fn, mapper: (res: UnpackData<Composable<Extract<Fn, Internal.AnyFn>>>, ...originalInput: Parameters<Extract<Fn, Internal.AnyFn>>) => O | Promise<O>): Fn extends Internal.AnyFn ? Composable<(...args: Parameters<Fn>) => O> : never;
/**

@@ -133,3 +133,3 @@ * It takes a Composable and a function that will map the input parameters to the expected input of the given Composable. Good to adequate the output of a composable into the input of the next composable in a composition. The function must return an array of parameters that will be passed to the Composable.

*/
declare function mapParameters<Fn extends Internal.AnyFn, NewParameters extends unknown[], const MapperOutput extends Parameters<Composable<Fn>>>(fn: Fn, mapper: (...args: NewParameters) => Promise<MapperOutput> | MapperOutput): MapParametersReturn<Composable<Fn>, NewParameters, MapperOutput>;
declare function mapParameters<Fn extends Function, NewParameters extends unknown[], const MapperOutput extends Parameters<Composable<Extract<Fn, Internal.AnyFn>>>>(fn: Fn, mapper: (...args: NewParameters) => Promise<MapperOutput> | MapperOutput): Fn extends Internal.AnyFn ? MapParametersReturn<Composable<Fn>, NewParameters, MapperOutput> : never;
/**

@@ -149,3 +149,3 @@ * Try to recover from a resulting Failure. When the given function succeeds, its result is returned without changes.

*/
declare function catchFailure<Fn extends Internal.AnyFn, C extends (err: Error[], ...originalInput: Parameters<Fn>) => any>(fn: Fn, catcher: C): Composable<(...args: Parameters<Fn>) => Awaited<ReturnType<C>> extends never[] ? UnpackData<Composable<Fn>> extends any[] ? UnpackData<Composable<Fn>> : Awaited<ReturnType<C>> | UnpackData<Composable<Fn>> : Awaited<ReturnType<C>> | UnpackData<Composable<Fn>>>;
declare function catchFailure<Fn extends Function, C extends (err: Error[], ...originalInput: Parameters<Extract<Fn, Internal.AnyFn>>) => any>(fn: Fn, catcher: C): Fn extends Internal.AnyFn ? Composable<(...args: Parameters<Fn>) => Awaited<ReturnType<C>> extends never[] ? UnpackData<Composable<Fn>> extends any[] ? UnpackData<Composable<Fn>> : Awaited<ReturnType<C>> | UnpackData<Composable<Fn>> : Awaited<ReturnType<C>> | UnpackData<Composable<Fn>>> : never;
/**

@@ -165,3 +165,3 @@ * Creates a new function that will apply a transformation over the list of Errors of a Failure from a given function. When the given function succeeds, its result is returned without changes.

*/
declare function mapErrors<Fn extends Internal.AnyFn>(fn: Fn, mapper: (err: Error[]) => Error[] | Promise<Error[]>): Composable<Fn>;
declare function mapErrors<Fn extends Function>(fn: Fn, mapper: (err: Error[]) => Error[] | Promise<Error[]>): Fn extends Internal.AnyFn ? Composable<Fn> : never;
/**

@@ -185,3 +185,3 @@ * Whenever you need to intercept inputs and a composable result without changing them you can use this function.

*/
declare function trace(traceFn: (result: Result<unknown>, ...originalInput: unknown[]) => Promise<void> | void): <Fn extends Internal.AnyFn>(fn: Fn) => Composable<Fn>;
declare function trace(traceFn: (result: Result<unknown>, ...originalInput: unknown[]) => Promise<void> | void): <Fn extends Function>(fn: Fn) => Fn extends Internal.AnyFn ? Composable<Fn> : never;
/**

@@ -208,3 +208,3 @@ * Compose 2 functions conditionally.

*/
declare function branch<SourceComposable extends Internal.AnyFn, Resolver extends (o: UnpackData<Composable<SourceComposable>>) => Internal.AnyFn | null | Promise<Internal.AnyFn | null>>(cf: SourceComposable, resolver: Resolver): BranchReturn<Composable<SourceComposable>, Resolver>;
declare function branch<SourceComposable extends Function, Resolver extends (o: UnpackData<Composable<Extract<SourceComposable, Internal.AnyFn>>>) => Internal.AnyFn | null | Promise<Internal.AnyFn | null>>(cf: SourceComposable, resolver: Resolver): BranchReturn<Composable<Extract<SourceComposable, Internal.AnyFn>>, Resolver>;
export { all, branch, catchFailure, collect, map, mapErrors, mapParameters, mergeObjects, pipe, sequence, trace, };

@@ -10,13 +10,13 @@ import type { Composable, UnpackData } from '../types.js';

* ```ts
* import { context } from 'composable-functions'
* import { withContext } from 'composable-functions'
*
* const a = (aNumber: number) => String(aNumber)
* const b = (aString: string) => aString === '1'
* const d = context.pipe(a, b)
* const d = withContext.pipe(a, b)
* // ^? ComposableWithSchema<boolean>
* ```
*/
declare function pipe<Fns extends Internal.AnyFn[]>(...fns: Fns): PipeReturn<Internal.Composables<Fns>>;
declare function pipe<Fns extends Function[]>(...fns: Fns): PipeReturn<Internal.Composables<Fns>>;
/**
* Works like `context.pipe` but it will collect the output of every function in a tuple.
* Works like `withContext.pipe` but it will collect the output of every function in a tuple.
*

@@ -26,15 +26,15 @@ * @example

* ```ts
* import { context } from 'composable-functions'
* import { withContext } from 'composable-functions'
*
* const a = (aNumber: number) => String(aNumber)
* const b = (aString: string) => aString === '1'
* const aComposable = context.sequence(a, b)
* const aComposable = withContext.sequence(a, b)
* // ^? ComposableWithSchema<[string, boolean]>
* ```
*/
declare function sequence<Fns extends Internal.AnyFn[]>(...fns: Fns): SequenceReturn<Internal.Composables<Fns>>;
declare function sequence<Fns extends Function[]>(...fns: Fns): SequenceReturn<Internal.Composables<Fns>>;
/**
* Like branch but preserving the context parameter.
*/
declare function branch<SourceComposable extends Internal.AnyFn, Resolver extends (o: UnpackData<Composable<SourceComposable>>) => Internal.AnyFn | null | Promise<Internal.AnyFn | null>>(cf: SourceComposable, resolver: Resolver): BranchReturn<Composable<SourceComposable>, Resolver>;
declare function branch<SourceComposable extends Function, Resolver extends (o: UnpackData<Composable<Extract<SourceComposable, Internal.AnyFn>>>) => Internal.AnyFn | null | Promise<Internal.AnyFn | null>>(cf: SourceComposable, resolver: Resolver): SourceComposable extends Internal.AnyFn ? BranchReturn<Composable<SourceComposable>, Resolver> : never;
export { branch, pipe, sequence };
import { branch, pipe, sequence } from './index.js';
/**
* @deprecated use `import { context } from 'composable-functions'` instead
* @deprecated use `import { withContext } from 'composable-functions'` instead
*/

@@ -5,0 +5,0 @@ declare const environment: {

@@ -9,2 +9,3 @@ export { applySchema, composable, failure, fromSuccess, success, withSchema, } from './constructors.js';

export { environment } from './context/environment.js';
export * as context from './context/index.js';
export { context } from './context/context.js';
export * as withContext from './context/index.js';

@@ -48,3 +48,3 @@ import type { Composable } from '../types.js';

} ? B : A extends Record<PropertyKey, unknown> ? B extends Record<PropertyKey, unknown> ? Prettify<A & B> : FailToCompose<A, B> : FailToCompose<A, B>;
type Composables<Fns extends Record<string, AnyFn> | Array<AnyFn>> = {
type Composables<Fns extends Record<string, Function> | Array<Function>> = {
[K in keyof Fns]: Composable<Extract<Fns[K], AnyFn>>;

@@ -51,0 +51,0 @@ };

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc