UNPKG

@zeix/cause-effect

Version:

Cause & Effect - reactive state management primitives library for TypeScript.

135 lines (109 loc) 3.79 kB
--- title: "Memo, Task, and Effect" description: "API reference for synchronous derivation, async derivation, and side-effect routing." --- Import path for every item on this page: `@zeix/cause-effect`. Source files: `src/nodes/memo.ts`, `src/nodes/task.ts`, and `src/nodes/effect.ts`. ## `createMemo` ```ts function createMemo<T extends {}>( fn: (prev: T) => T, options: ComputedOptions<T> & { value: T }, ): Memo<T> function createMemo<T extends {}>( fn: MemoCallback<T>, options?: ComputedOptions<T>, ): Memo<T> ``` | Parameter | Type | Default | Description | |-----------|------|---------|-------------| | `fn` | `MemoCallback<T>` | — | Sync computation that may read signals and receive the previous value. | | `options.value` | `T` | `undefined` | Initial value for reducer patterns. | | `options.equals` | `(a: T, b: T) => boolean` | `DEFAULT_EQUALITY` | Suppresses downstream propagation on equal results. | | `options.guard` | `Guard<T>` | `undefined` | Validates the computed value. | | `options.watched` | `(invalidate: () => void) => Cleanup` | `undefined` | Lazy invalidation hook for external triggers. | ```ts type Memo<T extends {}> = { readonly [Symbol.toStringTag]: 'Memo' get(): T } ``` ## `createTask` ```ts function createTask<T extends {}>( fn: (prev: T, signal: AbortSignal) => Promise<T>, options: ComputedOptions<T> & { value: T }, ): Task<T> function createTask<T extends {}>( fn: TaskCallback<T>, options?: ComputedOptions<T>, ): Task<T> ``` | Parameter | Type | Default | Description | |-----------|------|---------|-------------| | `fn` | `TaskCallback<T>` | — | Async computation; the synchronous preamble defines dependencies. | | `options.value` | `T` | `undefined` | Seed value used before the first resolution. | | `options.equals` | `(a: T, b: T) => boolean` | `DEFAULT_EQUALITY` | Equality strategy for resolved values. | | `options.guard` | `Guard<T>` | `undefined` | Validates resolved values. | | `options.watched` | `(invalidate: () => void) => Cleanup` | `undefined` | External invalidation hook. | ```ts type Task<T extends {}> = { readonly [Symbol.toStringTag]: 'Task' get(): T isPending(): boolean abort(): void } ``` ## `createEffect` ```ts function createEffect(fn: EffectCallback): Cleanup ``` Runs immediately, tracks dependencies, and re-runs when they change. ## `match` ```ts function match<T extends {}>( signal: Signal<T>, handlers: SingleMatchHandlers<T>, ): MaybeCleanup function match<T extends readonly Signal<unknown & {}>[]>( signals: readonly [...T], handlers: MatchHandlers<T>, ): MaybeCleanup ``` Routing order is `nil` > `err` > `stale` > `ok`. If `stale` is absent, it falls back to `ok`. ```ts type MaybePromise<T> = T | Promise<T> type SingleMatchHandlers<T extends {}> = { ok: (value: T) => MaybePromise<MaybeCleanup> err?: (error: Error) => MaybePromise<MaybeCleanup> nil?: () => MaybePromise<MaybeCleanup> stale?: () => MaybePromise<MaybeCleanup> } ``` Usage: ```ts import { createState, createTask, createEffect, match, } from '@zeix/cause-effect' const id = createState(1) const user = createTask(async (_prev, abort) => { const response = await fetch(`/api/users/${id.get()}`, { signal: abort }) return response.json() as Promise<{ name: string }> }) createEffect(() => { match(user, { nil: () => console.log('Loading'), stale: () => console.log('Refreshing'), ok: value => console.log(value.name), err: error => console.error(error.message), }) }) ``` ### Guards ```ts function isMemo<T extends {} = unknown & {}>(value: unknown): value is Memo<T> function isTask<T extends {} = unknown & {}>(value: unknown): value is Task<T> ``` Related pages: `/docs/async-effects` and `/docs/guides/async-data-pipelines`.