nanoeffects 0.5.0 → 0.7.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/{action-creator-DOWcbXpy.d.ts → action-creator-Bd4TBZgl.d.ts} +115 -33
- package/dist/actions.d.ts +18 -4
- package/dist/actions.js +1 -1
- package/dist/{notrace/context-plugin-B0sLWOxR.d.ts → context-plugin-BVNKqkIx.d.ts} +1 -1
- package/dist/dev.d.ts +2 -2
- package/dist/effects.d.ts +3 -202
- package/dist/index.d.ts +2 -2
- package/dist/{module-DCJl-qfi.d.ts → module-DZ5ngUrM.d.ts} +19 -4
- package/dist/notrace/{action-creator-DOWcbXpy.d.ts → action-creator-D-y_-xRS.d.ts} +115 -33
- package/dist/notrace/actions.d.ts +45 -5
- package/dist/notrace/actions.js +1 -1
- package/dist/{context-plugin-B0sLWOxR.d.ts → notrace/context-plugin-DDfsaErA.d.ts} +1 -1
- package/dist/notrace/effects.d.ts +3 -202
- package/dist/notrace/index.d.ts +2 -2
- package/dist/notrace/plugin-CDAngHwg.d.ts +207 -0
- package/dist/notrace/policies.d.ts +1 -1
- package/dist/notrace/redux.d.ts +1 -1
- package/dist/observable.d.ts +1 -1
- package/dist/plugin-DQNPBcxx.d.ts +207 -0
- package/dist/policies.d.ts +1 -1
- package/dist/react.d.ts +1 -1
- package/dist/redux.d.ts +1 -1
- package/dist/scope-key-B7l7mUS5.js +1 -0
- package/dist/scope.d.ts +58 -0
- package/dist/scope.js +1 -0
- package/dist/trace.d.ts +1 -1
- package/dist/types-BJ0fzV1p.d.ts +15 -0
- package/docs/README.md +1 -0
- package/docs/actions.md +24 -0
- package/docs/context.md +2 -0
- package/docs/effects.md +3 -2
- package/docs/guide.md +22 -0
- package/docs/package.md +3 -0
- package/docs/plugins.md +108 -0
- package/docs/scope.md +228 -0
- package/llms-full.txt +398 -2
- package/llms.txt +2 -0
- package/package.json +11 -2
|
@@ -1,3 +1,29 @@
|
|
|
1
|
+
//#region src/core/types.d.ts
|
|
2
|
+
type PayloadOf<P> = undefined extends P ? [payload?: P] : [payload: P];
|
|
3
|
+
type EventMap = Record<string, unknown>;
|
|
4
|
+
type Keys<E> = keyof E & string;
|
|
5
|
+
type Task<P, E extends EventMap, R = unknown> = (payload: P, ctx: Context<E>) => R;
|
|
6
|
+
type EffectName = "every" | "latest" | "leading" | "debounce" | "throttle" | "run" | "all" | "race" | "retry" | "timeout" | "poll" | "take" | "queue" | "allSettled" | "command";
|
|
7
|
+
type Phase = "start" | "done" | "error" | "cancel" | "drop";
|
|
8
|
+
type TraceEvent<E = Record<string, unknown>> = { [K in Keys<E>]: {
|
|
9
|
+
id: number;
|
|
10
|
+
parent?: number;
|
|
11
|
+
type: K;
|
|
12
|
+
effect: EffectName;
|
|
13
|
+
phase: Phase;
|
|
14
|
+
payload: E[K];
|
|
15
|
+
error?: unknown;
|
|
16
|
+
}; }[Keys<E>];
|
|
17
|
+
/**
|
|
18
|
+
* The contract of every trace logger: receives each task phase of a bus.
|
|
19
|
+
* Adapters in `nanoeffects/trace` are factories that return one; pass it
|
|
20
|
+
* through `createTracer` to `createBus({ trace })`.
|
|
21
|
+
*/
|
|
22
|
+
type TraceLogger<E = Record<string, unknown>> = (event: TraceEvent<E>) => void;
|
|
23
|
+
/** One logger or several; a throwing logger never breaks the task or the others. */
|
|
24
|
+
type Trace<E = Record<string, unknown>> = TraceLogger<E> | readonly TraceLogger<E>[];
|
|
25
|
+
type UnsubscribeCallback = () => void;
|
|
26
|
+
//#endregion
|
|
1
27
|
//#region src/core/store.d.ts
|
|
2
28
|
declare const anyEventType = "*";
|
|
3
29
|
//#endregion
|
|
@@ -83,14 +109,21 @@ type Emit<E extends EventMap> = {
|
|
|
83
109
|
<K extends EventKey<E>>(event: K, ...payload: PayloadOf<E[K]>): void;
|
|
84
110
|
/** Before Handler: a command is callable too, and must return its result type. */
|
|
85
111
|
<P, R>(command: Command<P, R>, ...payload: PayloadOf<P>): R;
|
|
86
|
-
|
|
112
|
+
/** A scope as the second argument replaces context fields for the tasks of this emit; see `scopePlugin`. */
|
|
113
|
+
<P, R, F>(call: CommandCall<P, R> & WithScope<F>, scope?: EmitScope<E, F>): R;
|
|
114
|
+
<P, R>(call: CommandCall<P, R>, scope?: EmitScope<E>): R;
|
|
87
115
|
<K extends EventKey<E>, R>(event: Handler<E, R, K>, ...payload: PayloadOf<E[K]>): R;
|
|
88
|
-
(event: EventLike<E>): void;
|
|
116
|
+
<F>(event: EventLike<E> & WithScope<F>, scope?: EmitScope<E, F>): void;
|
|
117
|
+
(event: EventLike<E>, scope?: EmitScope<E>): void;
|
|
89
118
|
};
|
|
90
119
|
type On<E extends EventMap> = {
|
|
91
120
|
(event: AnyEvent, fn: Task<EventPayload<E>, E>): UnsubscribeCallback;
|
|
92
121
|
<K extends EventKey<E>>(event: K, fn: Task<E[K], E>): UnsubscribeCallback;
|
|
93
122
|
/** An action creator without a payload type: the payload comes from the event map. */
|
|
123
|
+
/** The creators and commands that carry a scope come first: the handler sees their fields. */
|
|
124
|
+
<K extends EventKey<E>, F>(creator: FreeActionCreator<K, F> & WithScope<F>, fn: Task<E[K], WithFields<E, F>>): UnsubscribeCallback;
|
|
125
|
+
<P, F>(creator: ActionCreator<P, string, PayloadOf<P>, F> & WithScope<F>, fn: Task<P, WithFields<E, F>>): UnsubscribeCallback;
|
|
126
|
+
<P, F>(command: Command<P, unknown> & WithScope<F>, fn: Task<P, WithFields<E, F>>): UnsubscribeCallback;
|
|
94
127
|
<K extends EventKey<E>>(creator: FreeActionCreator<K>, fn: Task<E[K], E>): UnsubscribeCallback;
|
|
95
128
|
/** An action creator: the payload comes from it, so an event map is not needed. */
|
|
96
129
|
<P>(creator: ActionCreator<P>, fn: Task<P, E>): UnsubscribeCallback;
|
|
@@ -191,6 +224,10 @@ interface Bus<E extends EventMap> {
|
|
|
191
224
|
readonly trace?: Tracer | undefined;
|
|
192
225
|
/** Called with every new task context to add fields to it, for what needs the task, like `effectsPlugin`. Chain to the previous one. */
|
|
193
226
|
addContext?: ((ctx: object) => void) | undefined;
|
|
227
|
+
/** Puts the fields of a module's scope on the context of one of its tasks; `scopePlugin` sets it. Without it a module's scope is ignored. */
|
|
228
|
+
applyScope?: ((ctx: object, scope: Scope) => void) | undefined;
|
|
229
|
+
/** Wraps a handler so it runs with the fields of a module's scope; `scopePlugin` sets it. */
|
|
230
|
+
fitScope?: ((scope: Scope, fn: unknown) => unknown) | undefined;
|
|
194
231
|
}
|
|
195
232
|
type BusOptions<E extends EventMap> = {
|
|
196
233
|
/** Tracing of every task phase; make it with `createTracer` from `nanoeffects/trace`. */
|
|
@@ -228,31 +265,76 @@ type BusOptions<E extends EventMap> = {
|
|
|
228
265
|
};
|
|
229
266
|
declare const createBus: <Events extends EventMap>(options?: BusOptions<Events>) => Bus<Events>;
|
|
230
267
|
//#endregion
|
|
231
|
-
//#region src/core/types.d.ts
|
|
232
|
-
|
|
233
|
-
type
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
type
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
type: K;
|
|
242
|
-
effect: EffectName;
|
|
243
|
-
phase: Phase;
|
|
244
|
-
payload: E[K];
|
|
245
|
-
error?: unknown;
|
|
246
|
-
}; }[Keys<E>];
|
|
268
|
+
//#region src/core/effect-types.d.ts
|
|
269
|
+
/** What an effect needs of the task it runs for: its signal. A task context fits, and so does `{ signal }`. */
|
|
270
|
+
type Signaled = {
|
|
271
|
+
signal: AbortSignal;
|
|
272
|
+
};
|
|
273
|
+
/** An effect: a function whose first parameter takes `{ signal }`, like `retry(ctx, fn)`. */
|
|
274
|
+
type SignalFirst = (ctx: Signaled, ...args: never[]) => unknown;
|
|
275
|
+
/** The effects of a scope or of `effectsPlugin`, by the name they get on the context. */
|
|
276
|
+
type Effects = Record<string, SignalFirst>;
|
|
277
|
+
declare const bound: unique symbol;
|
|
247
278
|
/**
|
|
248
|
-
*
|
|
249
|
-
*
|
|
250
|
-
*
|
|
279
|
+
* An effect that says what it looks like once it is bound to a task (without
|
|
280
|
+
* the `ctx` parameter). A plain effect has its first parameter removed, which
|
|
281
|
+
* erases its generics; this type keeps them, because `F` is carried as it is.
|
|
282
|
+
* It changes the checker only: the function is the same at run time.
|
|
283
|
+
*
|
|
284
|
+
* @example
|
|
285
|
+
* ```ts
|
|
286
|
+
* type First = <T>(items: T[]) => T; // how a handler calls it
|
|
287
|
+
* const first: Effect<First> = (ctx, items) => items[0];
|
|
288
|
+
* ```
|
|
251
289
|
*/
|
|
252
|
-
type
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
290
|
+
type Effect<F extends (...args: never[]) => unknown> = ((ctx: Signaled, ...args: Parameters<F>) => ReturnType<F>) & {
|
|
291
|
+
readonly [bound]?: F;
|
|
292
|
+
};
|
|
293
|
+
/** The bound form of a plain effect: the first parameter is gone, and so are its generics. */
|
|
294
|
+
type Strip<F> = F extends ((ctx: never, ...args: infer A) => infer R) ? (...args: A) => R : never;
|
|
295
|
+
/** The bound type an `Effect<F>` carries, or `Strip` of a plain function. */
|
|
296
|
+
type BoundForm<F> = typeof bound extends keyof F ? NonNullable<F[typeof bound & keyof F]> : Strip<F>;
|
|
297
|
+
//#endregion
|
|
298
|
+
//#region src/core/scope-types.d.ts
|
|
299
|
+
declare const scopeFields: unique symbol;
|
|
300
|
+
/** What an action creator, a command or a call knows of the scope it was made with: its fields, for the checker. */
|
|
301
|
+
type WithScope<F> = {
|
|
302
|
+
readonly [scopeFields]: F;
|
|
303
|
+
};
|
|
304
|
+
/** `X`, marked with the scope fields `F` it carries; `X` itself when there are none, so unscoped types stay as they were. */
|
|
305
|
+
type Carrying<X, F> = X & ([unknown] extends [F] ? unknown : WithScope<F>);
|
|
306
|
+
/**
|
|
307
|
+
* What a task gets on top of the context of its bus, for one place: every key
|
|
308
|
+
* is a context value and goes on `ctx` as it is, except `$effects`, whose
|
|
309
|
+
* functions (each takes `{ signal }` first) are bound to the task. Made work by
|
|
310
|
+
* `scopePlugin` from `nanoeffects/scope`; without it a scope is ignored.
|
|
311
|
+
*
|
|
312
|
+
* @example
|
|
313
|
+
* ```ts
|
|
314
|
+
* const scope = { cache, $effects: { race } }; // ctx.cache, and ctx.race bound to the task
|
|
315
|
+
* ```
|
|
316
|
+
*/
|
|
317
|
+
type Scope = {
|
|
318
|
+
readonly $effects?: Effects;
|
|
319
|
+
readonly [field: string]: unknown;
|
|
320
|
+
};
|
|
321
|
+
/**
|
|
322
|
+
* What a call may replace of what it already has: the fields of the bus and
|
|
323
|
+
* those of its own scope, and its effects. The types must match the ones they
|
|
324
|
+
* replace; a field that neither declares has no type to check against, so it is
|
|
325
|
+
* an error.
|
|
326
|
+
*/
|
|
327
|
+
type EmitScope<E extends EventMap, F = unknown> = ([unknown] extends [ContextOf<E> & F] ? unknown : Partial<ContextOf<E> & F>) & {
|
|
328
|
+
$effects?: Partial<Effects>;
|
|
329
|
+
};
|
|
330
|
+
/** `A` with the fields of `B` replacing those of the same name, not intersected with them. */
|
|
331
|
+
type Merge<A, B> = Omit<A, keyof B> & B;
|
|
332
|
+
/**
|
|
333
|
+
* The event map `E` with the fields `F` of a scope on top of its context
|
|
334
|
+
* fields; `E` itself when there are none. A field of the scope replaces the
|
|
335
|
+
* one of the bus in the type too.
|
|
336
|
+
*/
|
|
337
|
+
type WithFields<E extends EventMap, F> = [unknown] extends [F] ? E : Omit<E, keyof WithContext<object>> & WithContext<Merge<ContextOf<E>, F>>;
|
|
256
338
|
//#endregion
|
|
257
339
|
//#region src/core/action-creator.d.ts
|
|
258
340
|
type WithPayload<E extends EventMap, K extends Keys<E>> = undefined extends E[K] ? {
|
|
@@ -271,15 +353,15 @@ type Free = typeof free;
|
|
|
271
353
|
* it is given, and the bus checks it against its event map, so
|
|
272
354
|
* `createAction("user/loaded")` needs no generics and keeps its literal type.
|
|
273
355
|
*/
|
|
274
|
-
interface FreeActionCreator<T extends string> {
|
|
275
|
-
(): {
|
|
356
|
+
interface FreeActionCreator<T extends string, F = unknown> {
|
|
357
|
+
(): Carrying<{
|
|
276
358
|
type: T;
|
|
277
359
|
payload: undefined;
|
|
278
|
-
}
|
|
279
|
-
<P>(payload: P): {
|
|
360
|
+
}, F>;
|
|
361
|
+
<P>(payload: P): Carrying<{
|
|
280
362
|
type: T;
|
|
281
363
|
payload: P;
|
|
282
|
-
}
|
|
364
|
+
}, F>;
|
|
283
365
|
readonly type: T;
|
|
284
366
|
/** Tells whether an action is one of this creator. */
|
|
285
367
|
match(action: {
|
|
@@ -295,8 +377,8 @@ interface FreeActionCreator<T extends string> {
|
|
|
295
377
|
* Makes actions of one type. It also works as the event of that type:
|
|
296
378
|
* `bus.on(creator, fn)` and `bus.emit(creator(payload))`.
|
|
297
379
|
*/
|
|
298
|
-
interface ActionCreator<P = void, T extends string = string, A extends unknown[] = PayloadOf<P
|
|
299
|
-
(...args: A): Made<P, T>;
|
|
380
|
+
interface ActionCreator<P = void, T extends string = string, A extends unknown[] = PayloadOf<P>, F = unknown> {
|
|
381
|
+
(...args: A): Carrying<Made<P, T>, F>;
|
|
300
382
|
readonly type: T;
|
|
301
383
|
/** Tells whether an action is one of this creator, and narrows its type. */
|
|
302
384
|
match(action: {
|
|
@@ -306,4 +388,4 @@ interface ActionCreator<P = void, T extends string = string, A extends unknown[]
|
|
|
306
388
|
toString(): T;
|
|
307
389
|
}
|
|
308
390
|
//#endregion
|
|
309
|
-
export {
|
|
391
|
+
export { HandlerRef as A, EventMap as B, Emit as C, EventPayload as D, EventLike as E, commandCall as F, Trace as G, PayloadOf as H, createBus as I, UnsubscribeCallback as J, TraceEvent as K, Tracer as L, On as M, WithContext as N, EventsOf as O, WithType as P, anyEventType as R, ContextOption as S, EventKey as T, Phase as U, Keys as V, Task as W, Command as _, EmitScope as a, Context as b, WithScope as c, Effects as d, Signaled as f, BusOptions as g, Bus as h, WithPayload as i, Off as j, Handler as k, BoundForm as l, AnyEvent as m, Free as n, Scope as o, Action as p, TraceLogger as q, FreeActionCreator as r, WithFields as s, ActionCreator as t, Effect as u, CommandCall as v, Emittable as w, ContextOf as x, Commands as y, EffectName as z };
|
package/dist/actions.d.ts
CHANGED
|
@@ -1,6 +1,8 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import {
|
|
1
|
+
import { B as EventMap, H as PayloadOf, T as EventKey, W as Task, c as WithScope, h as Bus, n as Free, o as Scope, r as FreeActionCreator, t as ActionCreator } from "./action-creator-Bd4TBZgl.js";
|
|
2
|
+
import { n as Scoped, t as FieldsOfScope } from "./types-BJ0fzV1p.js";
|
|
3
|
+
import { a as modulePlugin, c as MadeCommand, d as createCommand, i as createModule, l as bindHandler, n as ModuleApi, o as Binding, r as ModuleContext, s as CarryingCalls, t as Module, u as commandsPlugin } from "./module-DZ5ngUrM.js";
|
|
3
4
|
//#region src/actions/action.d.ts
|
|
5
|
+
type ScopedCreator<P, T extends string, F> = [P] extends [Free] ? FreeActionCreator<T, F> & WithScope<F> : ActionCreator<P, T, PayloadOf<P>, F> & WithScope<F>;
|
|
4
6
|
/**
|
|
5
7
|
* Creates an action creator, as in Redux Toolkit.
|
|
6
8
|
*
|
|
@@ -13,6 +15,9 @@ import { a as modulePlugin, c as bindHandler, i as createModule, l as commandsPl
|
|
|
13
15
|
* generic: `createAction<User, "user/loaded">("user/loaded")`.
|
|
14
16
|
* - With `prepare` the arguments of the creator can differ from the payload,
|
|
15
17
|
* and both types are inferred.
|
|
18
|
+
* - A scope as the last argument, `{ cache, $effects: { race } }`, gives the
|
|
19
|
+
* listeners of its calls those context fields; it works on a bus that uses `scopePlugin`
|
|
20
|
+
* from `nanoeffects/scope` and is ignored on any other.
|
|
16
21
|
*
|
|
17
22
|
* @example
|
|
18
23
|
* ```ts
|
|
@@ -33,6 +38,10 @@ export declare function createAction<P = Free, T extends string = string>(type:
|
|
|
33
38
|
export declare function createAction<A extends unknown[], P, T extends string = string>(type: T, prepare: (...args: A) => {
|
|
34
39
|
payload: P;
|
|
35
40
|
}): ActionCreator<P, T, A>;
|
|
41
|
+
export declare function createAction<P = Free, T extends string = string, S extends Scope = Record<never, never>>(type: T, scope: S): ScopedCreator<P, T, FieldsOfScope<EventMap, S>>;
|
|
42
|
+
export declare function createAction<A extends unknown[], P, T extends string, S extends Scope>(type: T, prepare: (...args: A) => {
|
|
43
|
+
payload: P;
|
|
44
|
+
}, scope: S): ActionCreator<P, T, A, FieldsOfScope<EventMap, S>> & WithScope<FieldsOfScope<EventMap, S>>;
|
|
36
45
|
//#endregion
|
|
37
46
|
//#region src/actions/emitter.d.ts
|
|
38
47
|
/** What `emitterPlugin` adds to the bus. */
|
|
@@ -93,6 +102,9 @@ type Job<P, R, T extends string, S extends Outcome, F extends Outcome> = MadeCom
|
|
|
93
102
|
* effect. It returns the command, with the two actions on it: `job.success` and
|
|
94
103
|
* `job.fail`.
|
|
95
104
|
*
|
|
105
|
+
* A scope as the last argument, `{ cache, $effects: { race } }`, gives the handler
|
|
106
|
+
* and the listeners of the outcome those context fields; see `scopePlugin`.
|
|
107
|
+
*
|
|
96
108
|
* `success` and `fail` are a type string, from which the job makes an action
|
|
97
109
|
* creator with `createAction`, or an action creator that exists already, which
|
|
98
110
|
* is used and returned as it is. A missing one is made with the type
|
|
@@ -117,11 +129,13 @@ type Job<P, R, T extends string, S extends Outcome, F extends Outcome> = MadeCom
|
|
|
117
129
|
* bus.emit(loadUser("1")); // loadUser.success(user) or loadUser.fail(error) comes later
|
|
118
130
|
* ```
|
|
119
131
|
*/
|
|
120
|
-
export declare const createJob: <P = void, R = void, T extends string = string, E extends EventMap = EventMap, S extends Outcome = `${T}/success`, F extends Outcome = `${T}/fail
|
|
132
|
+
export declare const createJob: <P = void, R = void, T extends string = string, E extends EventMap = EventMap, S extends Outcome = `${T}/success`, F extends Outcome = `${T}/fail`, X extends Scope = Record<never, never>>(type: T, handler?: Task<P, Scoped<E, X>, R>, outcomes?: {
|
|
121
133
|
/** Gets the result when the handler succeeds: a type to make an action creator of, or an action creator. */
|
|
122
134
|
success?: S;
|
|
123
135
|
/** Gets the error when the handler fails: a type to make an action creator of, or an action creator. */
|
|
124
136
|
fail?: F;
|
|
125
|
-
}
|
|
137
|
+
},
|
|
138
|
+
/** Context values and `$effects` for the handler and for the listeners of the outcome; see `scopePlugin`. */
|
|
139
|
+
scope?: X) => CarryingCalls<Job<P, R, T, S, F>, P, Promise<Awaited<R> | undefined>, FieldsOfScope<E, X>>;
|
|
126
140
|
//#endregion
|
|
127
141
|
export { type ActionCreator, type Binding, type EmitterApi, type FreeActionCreator, type Job, type Module, type ModuleApi, type ModuleContext, bindHandler, commandsPlugin, createCommand, createModule, modulePlugin };
|
package/dist/actions.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
import{t as e}from"./onAbort-BgMfspK4.js";import{i as t,n}from"./context-CK0ZomWt.js";import{t as r}from"./event-0RIBGYqS.js";import{r as i}from"./bus-BAs9x7IQ.js";
|
|
1
|
+
import{t as e}from"./onAbort-BgMfspK4.js";import{i as t,n}from"./context-CK0ZomWt.js";import{t as r}from"./event-0RIBGYqS.js";import{r as i}from"./bus-BAs9x7IQ.js";import{t as a}from"./scope-key-B7l7mUS5.js";const o=(e,t)=>(t&&Object.defineProperty(e,a,{value:t}),e),s=(e,t)=>({...e,...t,$effects:{...e.$effects,...t.$effects}}),c=e=>Reflect.get(e,a);function l(e,t,n){let r=typeof t==`function`?t:void 0,i=typeof t==`function`?n:t;return Object.assign(o((...t)=>o({type:e,payload:r?r(...t).payload:t[0]},i),i),{type:e,match:t=>t.type===e,toString:()=>e})}var u=class extends Error{};function d(e,t,n){let r=t=>t.type===e;function a(r,a){if(typeof a==`object`){if(!t)throw new u(`No handler for command "${e}"`);return t(r,a)}return o(i(c,e,r),n)}let s=Object.assign(a,{type:e,match:r}),c=o(s,n);return c}const f=(e,t)=>[e,t],p=(e=[])=>t=>{let n=/* @__PURE__ */ new Map,i=(e,t)=>{let r={fn:t};return n.set(e,[...n.get(e)??[],r]),()=>{let t=(n.get(e)??[]).filter(e=>e!==r);t.length>0?n.set(e,t):n.delete(e)}};function a(e,t){if(t)return i(r(e),t);let n=e.map(([e,t])=>i(r(e),t));return()=>{for(let e of n)e()}}a(e);let o={run:(e,t,r)=>{let i=(n.get(e.type)??[]).at(-1)?.fn,a=i&&e.wrap?e.wrap(i):i??e;return Reflect.apply(a,null,[t,r])},handle:a};return t.commands=o,o},m=()=>e=>{function t(t){return(...n)=>{let r=t(...n);e.emit(r)}}return Object.assign(e,{emitter:t})},h=e=>typeof e==`string`?l(e):e,g=(e,t,n,r)=>{let i=c(t);e.emit(Reflect.apply(t,null,[n]),r&&i?s(r,i):r)},_=e=>{try{return Promise.resolve(e())}catch(e){if(e instanceof u)throw e;return Promise.reject(e)}},v=(e,t,n={},r)=>{let a=d(e,t),s=h(n.success??`${e}/success`),c=h(n.fail??`${e}/fail`),l=(e,t,n)=>{let i=n;return _(()=>Reflect.apply(e,null,[t,n])).then(e=>(g(i,s,e,r),e),e=>{g(i,c,e,r)})},u=e=>(t,n)=>l(e,t,n);function f(t,n){return typeof n==`object`?l(a,t,n):o(i(m,e,t),r)}let p=Object.assign(f,{type:e,match:a.match,wrap:u,success:s,fail:c}),m=o(p,r);return m};function y(e,t,n){return n?{name:e,setup:t,scope:n}:{name:e,setup:t}}const b=(e,t)=>n=>t?e.fitScope?.(t,n)??n:n,x=(e,t,n)=>{n&&e.applyScope?.(t,n)},S=(e,t,n)=>Array.isArray(t)?[t.map(([t,n])=>[t,e(n)]),n]:[t,e(n)],C=(e,t)=>{let n=e.on;return(...e)=>{let[r,i]=e;return Reflect.apply(n,null,[r,t(i)])}},w=e=>(t,...n)=>{e.run(t,...n).catch(t=>{if(!e.signal.aborted)throw t})},T=(r=[])=>i=>{let a=i.commands??p()(i),o={handle:(...e)=>{if(!a.handle)throw Error("modulePlugin: the `commands` of the bus is not a registry from `commandsPlugin()`");return Reflect.apply(a.handle,null,e)}},s=n({event:{type:`app`,payload:void 0},bus:i,tracer:i.trace}),c=n=>{let r=/* @__PURE__ */ new Map,a=/* @__PURE__ */ new Map;return{mount:s=>{let l=r.get(s);if(l)return l;let u=a.get(s.name);u&&r.get(u)?.();let d=t(n,s.name),f=d.ctx,p=c(f),m=()=>{r.delete(s),a.get(s.name)===s&&a.delete(s.name),f.abort(),d.unlink()};r.set(s,m),a.set(s.name,s);let h=s.scope,g=b(i,h),_=(t,n)=>{let r=Reflect.apply(o.handle,null,S(g,t,n));return e(f,r),r},v=(...e)=>{let t=e.map(e=>typeof e==`function`?_(e,e):p.mount(e));return()=>{for(let e of t)e()}},y=w(f),T=C(f,g);try{x(i,f,h),s.setup(Object.assign(f,{handle:_,use:v,spawn:y,on:T}))}catch(e){throw m(),e}return m},unmount:e=>r.get(e)?.(),isMounted:e=>r.has(e)}},l=c(s.ctx);for(let e of r)l.mount(e);return{commands:a,mount:e=>(s.ctx.signal.throwIfAborted(),l.mount(e)),unmount:l.unmount,isMounted:l.isMounted,dispose:()=>s.ctx.abort(),createModule:y}};export{f as bindHandler,p as commandsPlugin,l as createAction,d as createCommand,v as createJob,y as createModule,m as emitterPlugin,T as modulePlugin};
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { B as EventMap, N as WithContext, h as Bus, x as ContextOf } from "./action-creator-Bd4TBZgl.js";
|
|
2
2
|
//#region src/core/context-plugin.d.ts
|
|
3
3
|
/** What a function that makes the fields of a task gets to see. */
|
|
4
4
|
type ContextTask = {
|
package/dist/dev.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import { n as ModuleApi } from "./module-
|
|
1
|
+
import { B as EventMap, J as UnsubscribeCallback, h as Bus } from "./action-creator-Bd4TBZgl.js";
|
|
2
|
+
import { n as ModuleApi } from "./module-DZ5ngUrM.js";
|
|
3
3
|
//#region src/dev/types.d.ts
|
|
4
4
|
/** The parts of what `modulePlugin` returned that the diagnostics report. */
|
|
5
5
|
type ReportedApp<E extends EventMap> = Pick<ModuleApi<E>, "mount" | "unmount" | "isMounted">;
|
package/dist/effects.d.ts
CHANGED
|
@@ -1,91 +1,10 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import { n as
|
|
3
|
-
//#region src/utils/delay.d.ts
|
|
4
|
-
/**
|
|
5
|
-
* Resolves after `ms`, or rejects early if `ctx.signal` aborts. `ms` can be a
|
|
6
|
-
* function that returns the number of ms, called once when the delay starts:
|
|
7
|
-
* handy for a random pause (jitter).
|
|
8
|
-
*
|
|
9
|
-
* @example
|
|
10
|
-
* ```ts
|
|
11
|
-
* await delay({}, 500);
|
|
12
|
-
*
|
|
13
|
-
* // 200 to 400 ms
|
|
14
|
-
* await delay({}, () => 200 + Math.random() * 200);
|
|
15
|
-
*
|
|
16
|
-
* // inside a task: stops waiting when the task is aborted
|
|
17
|
-
* bus.on("retry", async (_, ctx) => {
|
|
18
|
-
* await delay(ctx, 1000);
|
|
19
|
-
* await load();
|
|
20
|
-
* });
|
|
21
|
-
* ```
|
|
22
|
-
*/
|
|
23
|
-
export declare const delay: (ctx: {
|
|
24
|
-
signal?: AbortSignal | undefined;
|
|
25
|
-
}, ms: number | (() => number)) => Promise<void>;
|
|
26
|
-
//#endregion
|
|
1
|
+
import { B as EventMap, W as Task, u as Effect } from "./action-creator-Bd4TBZgl.js";
|
|
2
|
+
import { a as RaceStarter, c as all, d as delay, i as take, l as EffectContext, n as effectsPlugin, o as race, r as TakeOptions, s as allSettled, u as Starter } from "./plugin-DQNPBcxx.js";
|
|
27
3
|
//#region src/utils/onAbort.d.ts
|
|
28
4
|
export declare const onAbort: (ctx: {
|
|
29
5
|
signal?: AbortSignal | undefined;
|
|
30
6
|
}, fn: (reason: unknown) => void) => (() => void);
|
|
31
7
|
//#endregion
|
|
32
|
-
//#region src/effects/run.d.ts
|
|
33
|
-
/** Context passed into `race` / `all` effect starters. */
|
|
34
|
-
type EffectContext = {
|
|
35
|
-
signal: AbortSignal;
|
|
36
|
-
abort: (reason?: unknown) => void;
|
|
37
|
-
};
|
|
38
|
-
type Starter<T> = (ctx: EffectContext) => T | PromiseLike<T>;
|
|
39
|
-
//#endregion
|
|
40
|
-
//#region src/effects/all.d.ts
|
|
41
|
-
/**
|
|
42
|
-
* Runs all starters; waits for every result. On failure or parent abort, cancels the rest.
|
|
43
|
-
*
|
|
44
|
-
* @example
|
|
45
|
-
* ```ts
|
|
46
|
-
* bus.on("load", async (id, ctx) => {
|
|
47
|
-
* const { user, posts } = await all(ctx, {
|
|
48
|
-
* user: ({ signal }) => fetchUser(id, { signal }),
|
|
49
|
-
* posts: ({ signal }) => fetchPosts(id, { signal }),
|
|
50
|
-
* });
|
|
51
|
-
*
|
|
52
|
-
* // arrays work too: const [user, posts] = await all(ctx, [getUser, getPosts]);
|
|
53
|
-
* });
|
|
54
|
-
* ```
|
|
55
|
-
*/
|
|
56
|
-
export declare function all<T extends Record<string, Starter<unknown>>>(ctx: {
|
|
57
|
-
signal?: AbortSignal;
|
|
58
|
-
}, effects: T): Promise<{ [K in keyof T]: Awaited<ReturnType<T[K]>>; }>;
|
|
59
|
-
export declare function all<const T extends readonly Starter<unknown>[]>(ctx: {
|
|
60
|
-
signal?: AbortSignal;
|
|
61
|
-
}, effects: T): Promise<{ -readonly [K in keyof T]: Awaited<ReturnType<T[K]>>; }>;
|
|
62
|
-
//#endregion
|
|
63
|
-
//#region src/effects/allSettled.d.ts
|
|
64
|
-
/**
|
|
65
|
-
* Runs all starters and waits for every one to settle, whether it succeeds or
|
|
66
|
-
* fails: nothing is cancelled when a starter fails. The result has, for each
|
|
67
|
-
* starter, `{ status: "fulfilled", value }` or `{ status: "rejected", reason }`.
|
|
68
|
-
* Only an abort of `ctx` rejects it, with the abort reason.
|
|
69
|
-
*
|
|
70
|
-
* @example
|
|
71
|
-
* ```ts
|
|
72
|
-
* bus.on("load", async (id, ctx) => {
|
|
73
|
-
* const { user, posts } = await allSettled(ctx, {
|
|
74
|
-
* user: ({ signal }) => fetchUser(id, { signal }),
|
|
75
|
-
* posts: ({ signal }) => fetchPosts(id, { signal }),
|
|
76
|
-
* });
|
|
77
|
-
*
|
|
78
|
-
* if (user.status === "fulfilled") render(user.value);
|
|
79
|
-
* });
|
|
80
|
-
* ```
|
|
81
|
-
*/
|
|
82
|
-
export declare function allSettled<T extends Record<string, Starter<unknown>>>(ctx: {
|
|
83
|
-
signal?: AbortSignal;
|
|
84
|
-
}, effects: T): Promise<{ [K in keyof T]: PromiseSettledResult<Awaited<ReturnType<T[K]>>>; }>;
|
|
85
|
-
export declare function allSettled<const T extends readonly Starter<unknown>[]>(ctx: {
|
|
86
|
-
signal?: AbortSignal;
|
|
87
|
-
}, effects: T): Promise<{ -readonly [K in keyof T]: PromiseSettledResult<Awaited<ReturnType<T[K]>>>; }>;
|
|
88
|
-
//#endregion
|
|
89
8
|
//#region src/effects/backoff.d.ts
|
|
90
9
|
type BackoffOptions = {
|
|
91
10
|
/** Pause before the second attempt, in ms. Default 100. */
|
|
@@ -151,124 +70,6 @@ export declare const cancellable: <T = void>(ctx: {
|
|
|
151
70
|
signal: AbortSignal;
|
|
152
71
|
}, executor: CancellableExecutor<T>) => Promise<T>;
|
|
153
72
|
//#endregion
|
|
154
|
-
//#region src/effects/race.d.ts
|
|
155
|
-
type RaceStarter<T> = Starter<T>;
|
|
156
|
-
/**
|
|
157
|
-
* Runs all starters; first to settle wins, losers are cancelled via `ctx.abort`.
|
|
158
|
-
* The result holds only the winner's value, under its key or index.
|
|
159
|
-
*
|
|
160
|
-
* @example
|
|
161
|
-
* ```ts
|
|
162
|
-
* bus.on("load", async (id, ctx) => {
|
|
163
|
-
* const result = await race(ctx, {
|
|
164
|
-
* data: ({ signal }) => fetchData(id, { signal }),
|
|
165
|
-
* timeout: ({ signal }) => delay({ signal }, 5000),
|
|
166
|
-
* });
|
|
167
|
-
*
|
|
168
|
-
* if ("timeout" in result) throw new Error("timed out");
|
|
169
|
-
* render(result.data);
|
|
170
|
-
* });
|
|
171
|
-
* ```
|
|
172
|
-
*/
|
|
173
|
-
export declare function race<T extends Record<string, RaceStarter<unknown>>>(ctx: {
|
|
174
|
-
signal?: AbortSignal;
|
|
175
|
-
}, effects: T): Promise<{ [K in keyof T]?: Awaited<ReturnType<T[K]>>; }>;
|
|
176
|
-
export declare function race<const T extends readonly RaceStarter<unknown>[]>(ctx: {
|
|
177
|
-
signal?: AbortSignal;
|
|
178
|
-
}, effects: T): Promise<{ -readonly [K in keyof T]?: Awaited<ReturnType<T[K]>>; }>;
|
|
179
|
-
//#endregion
|
|
180
|
-
//#region src/effects/take.d.ts
|
|
181
|
-
type TakeOptions<P> = {
|
|
182
|
-
/**
|
|
183
|
-
* Wait for the first payload this accepts; others are skipped. A type guard
|
|
184
|
-
* (`(payload): payload is T`) narrows the type of the result to `T`.
|
|
185
|
-
*/
|
|
186
|
-
predicate?: (payload: P) => boolean;
|
|
187
|
-
/** Stop waiting when this aborts, e.g. the signal of a `race` starter. */
|
|
188
|
-
signal?: AbortSignal | undefined;
|
|
189
|
-
};
|
|
190
|
-
/**
|
|
191
|
-
* Waits for the next `event` on the bus and resolves with its payload. It sees
|
|
192
|
-
* only events emitted after the call, takes only one, and unsubscribes when it
|
|
193
|
-
* is done. If `ctx` (or `options.signal`) aborts first, it unsubscribes and
|
|
194
|
-
* rejects with the abort reason.
|
|
195
|
-
*
|
|
196
|
-
* @example
|
|
197
|
-
* ```ts
|
|
198
|
-
* bus.on("login", async (user, ctx) => {
|
|
199
|
-
* const reason = await take(ctx, "logout");
|
|
200
|
-
* cleanup(user, reason);
|
|
201
|
-
* });
|
|
202
|
-
*
|
|
203
|
-
* // wait for a matching event, but not longer than 5 s
|
|
204
|
-
* const done = await timeout(ctx, 5000, ({ signal }) =>
|
|
205
|
-
* take(ctx, "saved", { signal, predicate: (id) => id === draftId }),
|
|
206
|
-
* );
|
|
207
|
-
*
|
|
208
|
-
* // a type guard narrows the result: `failed` is `{ ok: false }`
|
|
209
|
-
* const failed = await take(ctx, "result", {
|
|
210
|
-
* predicate: (result): result is { ok: false } => !result.ok,
|
|
211
|
-
* });
|
|
212
|
-
* ```
|
|
213
|
-
*/
|
|
214
|
-
export declare function take<E extends EventMap, K extends Keys<E>, T extends E[K]>(ctx: Context<E>, event: K, options: TakeOptions<E[K]> & {
|
|
215
|
-
predicate: (payload: E[K]) => payload is T;
|
|
216
|
-
}): Promise<T>;
|
|
217
|
-
export declare function take<E extends EventMap, K extends Keys<E>>(ctx: Context<E>, event: K, options?: TakeOptions<E[K]>): Promise<E[K]>;
|
|
218
|
-
//#endregion
|
|
219
|
-
//#region src/effects/plugin.d.ts
|
|
220
|
-
/** The effects that `effectsPlugin` can put on `ctx`. */
|
|
221
|
-
type Supported = {
|
|
222
|
-
race: typeof race;
|
|
223
|
-
all: typeof all;
|
|
224
|
-
allSettled: typeof allSettled;
|
|
225
|
-
take: typeof take;
|
|
226
|
-
delay: typeof delay;
|
|
227
|
-
};
|
|
228
|
-
type Results = Record<string, Starter<unknown>>;
|
|
229
|
-
type List = readonly Starter<unknown>[];
|
|
230
|
-
/** Each supported effect without its leading `ctx` argument. `take` knows the events of the bus. */
|
|
231
|
-
type Bound<E extends EventMap> = {
|
|
232
|
-
race: {
|
|
233
|
-
<T extends Results>(effects: T): Promise<{ [K in keyof T]?: Awaited<ReturnType<T[K]>>; }>;
|
|
234
|
-
<const T extends List>(effects: T): Promise<{ -readonly [K in keyof T]?: Awaited<ReturnType<T[K]>>; }>;
|
|
235
|
-
};
|
|
236
|
-
all: {
|
|
237
|
-
<T extends Results>(effects: T): Promise<{ [K in keyof T]: Awaited<ReturnType<T[K]>>; }>;
|
|
238
|
-
<const T extends List>(effects: T): Promise<{ -readonly [K in keyof T]: Awaited<ReturnType<T[K]>>; }>;
|
|
239
|
-
};
|
|
240
|
-
allSettled: {
|
|
241
|
-
<T extends Results>(effects: T): Promise<{ [K in keyof T]: PromiseSettledResult<Awaited<ReturnType<T[K]>>>; }>;
|
|
242
|
-
<const T extends List>(effects: T): Promise<{ -readonly [K in keyof T]: PromiseSettledResult<Awaited<ReturnType<T[K]>>>; }>;
|
|
243
|
-
};
|
|
244
|
-
take: <K extends Keys<E>>(event: K, options?: TakeOptions<E[K]>) => Promise<E[K]>;
|
|
245
|
-
delay: (ms: number | (() => number)) => Promise<void>;
|
|
246
|
-
};
|
|
247
|
-
type Helpers = Partial<Supported>;
|
|
248
|
-
type BoundOf<H extends Helpers, E extends EventMap> = { [K in keyof H & keyof Bound<E>]: Bound<E>[K]; };
|
|
249
|
-
/**
|
|
250
|
-
* Puts the effects you pass on the context of every task of the bus, bound to
|
|
251
|
-
* that task, so a handler can write `({ race })` instead of `race(ctx, …)`.
|
|
252
|
-
* The key is the name of the effect: `race`, `all`, `allSettled`, `take`,
|
|
253
|
-
* `delay`. Returns the same bus, typed with the new fields.
|
|
254
|
-
*
|
|
255
|
-
* @example
|
|
256
|
-
* ```ts
|
|
257
|
-
* import { createBus } from "nanoeffects";
|
|
258
|
-
* import { all, delay, effectsPlugin, race } from "nanoeffects/effects";
|
|
259
|
-
*
|
|
260
|
-
* const bus = createBus().use(effectsPlugin({ race, delay }));
|
|
261
|
-
*
|
|
262
|
-
* bus.on("load", async (id, { race, delay }) => {
|
|
263
|
-
* const result = await race({
|
|
264
|
-
* data: ({ signal }) => fetchData(id, { signal }),
|
|
265
|
-
* timeout: () => delay(5000),
|
|
266
|
-
* });
|
|
267
|
-
* });
|
|
268
|
-
* ```
|
|
269
|
-
*/
|
|
270
|
-
export declare const effectsPlugin: <H extends Helpers>(helpers: H) => <E extends EventMap>(bus: Bus<E> & NoClash<BoundOf<H, E>, E>) => Bus<E & WithContext<BoundOf<H, E>>>;
|
|
271
|
-
//#endregion
|
|
272
73
|
//#region src/effects/poll.d.ts
|
|
273
74
|
type PollOptions = {
|
|
274
75
|
/** Also call `fn` at once, not only after the first `ms`. Default `false`. */
|
|
@@ -378,4 +179,4 @@ export declare function timeout<T>(ctx: {
|
|
|
378
179
|
signal?: AbortSignal;
|
|
379
180
|
}, ms: number, starter: Starter<T>): Promise<T>;
|
|
380
181
|
//#endregion
|
|
381
|
-
export type
|
|
182
|
+
export { type BackoffOptions, type CancellableExecutor, type CancellableHandle, type Effect, type EffectContext, type PollOptions, type RaceStarter, type RetryOptions, type TakeOptions, all, allSettled, delay, effectsPlugin, race, take };
|
package/dist/index.d.ts
CHANGED
|
@@ -1,3 +1,3 @@
|
|
|
1
|
-
import { A as
|
|
2
|
-
import { n as NoClash, r as contextPlugin, t as ContextTask } from "./context-plugin-
|
|
1
|
+
import { A as HandlerRef, B as EventMap, C as Emit, D as EventPayload, E as EventLike, F as commandCall, G as Trace, H as PayloadOf, I as createBus, J as UnsubscribeCallback, K as TraceEvent, L as Tracer, M as On, N as WithContext, O as EventsOf, P as WithType, R as anyEventType, S as ContextOption, T as EventKey, U as Phase, V as Keys, W as Task, _ as Command, b as Context, g as BusOptions, h as Bus, i as WithPayload, j as Off, k as Handler, m as AnyEvent, p as Action, q as TraceLogger, v as CommandCall, w as Emittable, x as ContextOf, y as Commands, z as EffectName } from "./action-creator-Bd4TBZgl.js";
|
|
2
|
+
import { n as NoClash, r as contextPlugin, t as ContextTask } from "./context-plugin-BVNKqkIx.js";
|
|
3
3
|
export { type Action, type AnyEvent, type Bus, type BusOptions, type Command, type CommandCall, type Commands, type Context, type ContextOf, type ContextOption, type ContextTask, type EffectName, type Emit, type Emittable, type EventKey, type EventLike, type EventMap, type EventPayload, type EventsOf, type Handler, type HandlerRef, type Keys, type NoClash, type Off, type On, type PayloadOf, type Phase, type Task, type Trace, type TraceEvent, type TraceLogger, type Tracer, type UnsubscribeCallback, type WithContext, type WithPayload, type WithType, anyEventType, commandCall, contextPlugin, createBus };
|
|
@@ -1,4 +1,5 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { B as EventMap, H as PayloadOf, J as UnsubscribeCallback, W as Task, _ as Command, b as Context, c as WithScope, h as Bus, o as Scope, v as CommandCall } from "./action-creator-Bd4TBZgl.js";
|
|
2
|
+
import { n as Scoped, t as FieldsOfScope } from "./types-BJ0fzV1p.js";
|
|
2
3
|
//#region src/actions/command.d.ts
|
|
3
4
|
/** What `createCommand` returns: a command that also tells whether an action is of its type. */
|
|
4
5
|
type MadeCommand<P, R, T extends string> = Command<P, R> & {
|
|
@@ -12,6 +13,10 @@ type MadeCommand<P, R, T extends string> = Command<P, R> & {
|
|
|
12
13
|
payload: P;
|
|
13
14
|
};
|
|
14
15
|
};
|
|
16
|
+
/** `Made`, called so that its calls carry the scope fields `F`; `Made` itself when there are none. */
|
|
17
|
+
type CarryingCalls<Made, P, R, F> = [unknown] extends [F] ? Made : ((payload: P) => CommandCall<P, R> & WithScope<F>) & Made & WithScope<F>;
|
|
18
|
+
/** A command made with a scope: its calls carry the fields of that scope, for the checker. */
|
|
19
|
+
type ScopedCommand<P, R, T extends string, F> = ((payload: P) => CommandCall<P, R> & WithScope<F>) & MadeCommand<P, R, T> & WithScope<F>;
|
|
15
20
|
/**
|
|
16
21
|
* Creates a command: a typed request for a result. Calling it builds
|
|
17
22
|
* `{ type, payload }` like `createAction`. `bus.emit(command(payload))` (or
|
|
@@ -28,6 +33,11 @@ type MadeCommand<P, R, T extends string> = Command<P, R> & {
|
|
|
28
33
|
* `command.match(action)` tells whether an action has the type of the command,
|
|
29
34
|
* as it does for an action creator.
|
|
30
35
|
*
|
|
36
|
+
* A scope as the third argument, `{ cache, $effects: { race } }`, puts those fields on
|
|
37
|
+
* the context of the handler and of the listeners of the command; the handler
|
|
38
|
+
* sees them typed. It works on a bus that uses `scopePlugin` from
|
|
39
|
+
* `nanoeffects/scope` and is ignored on any other.
|
|
40
|
+
*
|
|
31
41
|
* @example
|
|
32
42
|
* ```ts
|
|
33
43
|
* const getUser = createCommand("user/get", (id: string, { signal }) =>
|
|
@@ -42,7 +52,8 @@ type MadeCommand<P, R, T extends string> = Command<P, R> & {
|
|
|
42
52
|
* commands.handle(getUser, async () => fakeUser); // in a test
|
|
43
53
|
* ```
|
|
44
54
|
*/
|
|
45
|
-
declare
|
|
55
|
+
declare function createCommand<P = void, R = void, T extends string = string, E extends EventMap = EventMap>(type: T, handler?: Task<P, E, R>): MadeCommand<P, R, T>;
|
|
56
|
+
declare function createCommand<P, R, T extends string, S extends Scope = Record<never, never>>(type: T, handler: Task<P, Scoped<EventMap, S>, R>, scope: S): ScopedCommand<P, R, T, FieldsOfScope<EventMap, S>>;
|
|
46
57
|
/** A command (or its type) with the handler to bind to it; `bindHandler` makes one. */
|
|
47
58
|
type Binding<E extends EventMap = EventMap> = readonly [Command<never, unknown> | string, Task<never, E, unknown>];
|
|
48
59
|
/**
|
|
@@ -117,6 +128,8 @@ type ModuleContext<E extends EventMap = EventMap> = Context<E> & {
|
|
|
117
128
|
type Module<E extends EventMap = EventMap> = {
|
|
118
129
|
readonly name: string;
|
|
119
130
|
readonly setup: (m: ModuleContext<E>) => void;
|
|
131
|
+
/** Fields for everything the module owns; see `scopePlugin`. */
|
|
132
|
+
readonly scope?: Scope;
|
|
120
133
|
};
|
|
121
134
|
/**
|
|
122
135
|
* Describes one domain of an app: the commands it handles, the events it
|
|
@@ -137,7 +150,8 @@ type Module<E extends EventMap = EventMap> = {
|
|
|
137
150
|
* });
|
|
138
151
|
* ```
|
|
139
152
|
*/
|
|
140
|
-
declare
|
|
153
|
+
declare function createModule<E extends EventMap = EventMap>(name: string, setup: (m: ModuleContext<E>) => void): Module<E>;
|
|
154
|
+
declare function createModule<E extends EventMap, S extends Scope = Record<never, never>>(name: string, setup: (m: ModuleContext<Scoped<E, S>>) => void, scope: S): Module<E>;
|
|
141
155
|
type Registry<E extends EventMap> = ReturnType<ReturnType<typeof commandsPlugin<E>>>;
|
|
142
156
|
/** What `modulePlugin` returns. */
|
|
143
157
|
type ModuleApi<E extends EventMap = EventMap> = {
|
|
@@ -155,6 +169,7 @@ type ModuleApi<E extends EventMap = EventMap> = {
|
|
|
155
169
|
* mounted, with no link to this bus.
|
|
156
170
|
*/
|
|
157
171
|
createModule(name: string, setup: (m: ModuleContext<E>) => void): Module<E>;
|
|
172
|
+
createModule<S extends Scope = Record<never, never>>(name: string, setup: (m: ModuleContext<Scoped<E, S>>) => void, scope: S): Module<E>;
|
|
158
173
|
};
|
|
159
174
|
/**
|
|
160
175
|
* The plugin that assembles an app from modules: `bus.use(modulePlugin(modules))`
|
|
@@ -192,4 +207,4 @@ type ModuleApi<E extends EventMap = EventMap> = {
|
|
|
192
207
|
*/
|
|
193
208
|
declare const modulePlugin: <E extends EventMap>(modules?: readonly Module<E>[]) => (bus: Bus<E>) => ModuleApi<E>;
|
|
194
209
|
//#endregion
|
|
195
|
-
export { modulePlugin as a,
|
|
210
|
+
export { modulePlugin as a, MadeCommand as c, createCommand as d, createModule as i, bindHandler as l, ModuleApi as n, Binding as o, ModuleContext as r, CarryingCalls as s, Module as t, commandsPlugin as u };
|