@thi.ng/interceptors
Version:
Interceptor based event bus, side effect & immutable state handling
222 lines • 7.75 kB
TypeScript
import type { Fn, FnO, Path } from "@thi.ng/api";
import { type Event, type InterceptorFn, type InterceptorPredicate } from "./api.js";
/**
* Debug interceptor to log the current event to the console.
*/
export declare const trace: InterceptorFn;
/**
* Higher-order interceptor. Returns interceptor which unpacks payload
* from event and assigns it as is to given side effect ID. Assigns
* `true` to side effect if event has no payload.
*
* @param fxID - side effect ID
*/
export declare const forwardSideFx: (fxID: string) => InterceptorFn;
/**
* Higher-order interceptor. Returns interceptor which assigns given
* event to `FX_DISPATCH` side effect.
*
* @param event -
*/
export declare const dispatch: (event: Event) => InterceptorFn;
/**
* Higher-order interceptor. Returns interceptor which assigns given
* event to `FX_DISPATCH_NOW` side effect.
*
* @param event -
*/
export declare const dispatchNow: (event: Event) => InterceptorFn;
/**
* Higher-order interceptor. Returns interceptor which calls `ctx[id].record()`,
* where `ctx` is the currently active {@link InterceptorContext} passed to all
* event handlers and `ctx[id]` is assumed to be a
* [`History`](https://docs.thi.ng/umbrella/atom/classes/History.html) instance,
* passed to {@link EventBus.processQueue}. The default ID for the history
* instance is `"history"`.
*
* Example usage:
*
* @example
* ```ts tangle:../export/snapshot.ts
* import { defAtom, defHistory } from "@thi.ng/atom";
* import { EventBus, snapshot, valueSetter, EV_UNDO } from "@thi.ng/interceptors";
*
* const state = defAtom({ foo: 42 });
* const history = defHistory(state);
* const bus = new EventBus(state);
* // register event handler
* // each time the `foo` event is triggered, a snapshot of
* // current app state is recorded first
* bus.addHandlers({
* foo: [snapshot(), valueSetter("foo")]
* });
*
* // trigger event
* bus.dispatch(["foo", 23]);
*
* // pass history instance via interceptor context to handlers
* bus.processQueue({ history });
*
* // show updated state
* console.log(state.deref());
*
* // trigger & process built-in undo event
* bus.dispatch([EV_UNDO]);
* bus.processQueue({ history });
*
* // show restored state
* console.log(state.deref());
* ```
*
* @param id -
*/
export declare const snapshot: (id?: string) => InterceptorFn;
/**
* Higher-order interceptor for validation purposes. Takes a predicate
* function and an optional interceptor function, which will only be
* called if the predicate fails for a given event. By default the
* `FX_CANCEL` side effect is triggered if the predicate failed, thus
* ensuring the actual event handler for the failed event will not be
* executed anymore. However, this can be overridden using the error
* interceptor's result, which is merged into the result of this
* interceptor.
*
* The error interceptor can return any number of other side effects and
* so be used to dispatch alternative events instead, for example:
*
* ```js
* import { ensurePred, FX_DISPATCH_NOW } from "@thi.ng/interceptors";
*
* // this interceptor will cause cancellation of current event
* // and trigger an "error" event instead
* ensurePred(
* // a dummy predicate which always fails
* () => false
* // error interceptor fn
* () => ({[FX_DISPATCH_NOW]: ["error", "reason"]})
* )
* ```
*
* Note: For this interceptor to work as expected, it needs to be
* provided BEFORE the main handler in the interceptor list for a given
* event, i.e.
*
* ```js
* import { ensurePred } from "@thi.ng/interceptors";
*
* [
* ensurePred((state, e) => false),
* // actual event handler
* (state, e) => console.log("no one never calls me")
* ]
* ```
*
* @param pred - predicate applied to given state & event
* @param err - interceptor triggered on predicate failure
*/
export declare const ensurePred: (pred: InterceptorPredicate, err?: InterceptorFn) => InterceptorFn;
/**
* Specialization of {@link ensurePred} to ensure a state value is less than
* given max at the time when the event is being processed. The optional
* `path` fn is used to extract or produce the path for the state value
* to be validated. If omitted, the event's payload item is interpreted
* as the value path.
*
* For example, without a provided `path` function and for an event of
* this form: `["event-id", "foo.bar"]`, the term `"foo.bar"` would be
* interpreted as path.
*
* If the event has this shape: `["event-id", ["foo.bar", 23]]`, we must
* provide `(e) => e[1][0]` as path function to extract `"foo.bar"` from
* the event.
*
* @param max -
* @param path - path extractor
* @param err - error interceptor
*/
export declare const ensureStateLessThan: (max: number, path?: Fn<Event, Path>, err?: InterceptorFn) => InterceptorFn;
/**
* Specialization of {@link ensurePred} to ensure a state value is greater
* than given min. See {@link ensureStateLessThan} for further details.
*
* @param min -
* @param path - path extractor
* @param err - error interceptor
*/
export declare const ensureStateGreaterThan: (min: number, path?: Fn<Event, Path>, err?: InterceptorFn) => InterceptorFn;
/**
* Specialization of {@link ensurePred} to ensure a state value is within
* given `min` / `max` closed interval. See {@link ensureStateLessThan} for
* further details.
*
* @param min -
* @param max -
* @param path - path extractor
* @param err - error interceptor
*/
export declare const ensureStateRange: (min: number, max: number, path?: Fn<Event, Path>, err?: InterceptorFn) => InterceptorFn;
/**
* Specialization of {@link ensurePred} to ensure an event's payload value
* is within given `min` / `max` closed interval. By default, assumes
* event format like: `[event-id, value]`. However if `value` is given,
* the provided function can be used to extract the value to be
* validated from any event. If the value is outside the given interval,
* triggers `FX_CANCEL` side effect and if `err` is given, the error
* interceptor can return any number of other side effects and so be
* used to dispatch alternative events instead.
*
* @param min -
* @param max -
* @param value - event value extractor
* @param err - error interceptor
*/
export declare const ensureParamRange: (min: number, max: number, value?: Fn<Event, number>, err?: InterceptorFn) => InterceptorFn;
/**
* Higher-order interceptor. Returns new interceptor to set state value
* at provided path. This allows for dedicated events to set state
* values more concisely, e.g. given this event definition:
*
* @example
* ```ts
* setFoo: valueSetter("foo.bar")
* ```
*
* ...the `setFoo` event then can be triggered like so to update the
* state value at `foo.bar`:
*
* @example
* ```ts
* // (bus here is an EventBus instance)
* bus.dispatch(["setFoo", 23])
* ```
*
* @param path -
* @param tx -
*/
export declare const valueSetter: <T>(path: Path, tx?: Fn<T, T>) => InterceptorFn;
/**
* Higher-order interceptor. Returns new interceptor to update state
* value at provided path with given function. This allows for dedicated
* events to update state values more concisely, e.g. given this event
* definition:
*
* @example
* ```ts
* incFoo: valueUpdater("foo.bar", (x, y) => x + y)
* ```
*
* ...the `incFoo` event then can be triggered like so to update the
* state value at `foo.bar` (where `1` is the extra arg provided to the
* update fn:
*
* @example
* ```ts
* // (bus here is an EventBus instance)
* bus.dispatch(["incFoo", 1]) // results in value = value + 1
* ```
*
* @param path -
* @param fn -
*/
export declare const valueUpdater: <T>(path: Path, fn: FnO<T, T>) => InterceptorFn;
//# sourceMappingURL=interceptors.d.ts.map