nanoeffects 0.3.0 → 0.4.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/README.md +50 -55
- package/dist/{action-Bdfp-Wvd.d.ts → action-creator-D48fp13T.d.ts} +64 -72
- package/dist/actions.d.ts +40 -6
- package/dist/actions.js +1 -1
- package/dist/bus-Cho463Sq.js +1 -0
- package/dist/dev.d.ts +2 -2
- package/dist/effects.d.ts +1 -1
- package/dist/index.d.ts +2 -2
- package/dist/index.js +1 -1
- package/dist/{module-I1ixyJzx.d.ts → module-DVX8aYlq.d.ts} +9 -8
- package/dist/notrace/{action-Bdfp-Wvd.d.ts → action-creator-D48fp13T.d.ts} +64 -72
- package/dist/notrace/actions.d.ts +47 -12
- package/dist/notrace/actions.js +1 -1
- package/dist/notrace/bus-B12SvxLv.js +1 -0
- package/dist/notrace/effects.d.ts +1 -1
- package/dist/notrace/index.d.ts +2 -2
- package/dist/notrace/index.js +1 -1
- package/dist/notrace/policies.d.ts +1 -1
- package/dist/notrace/redux.d.ts +1 -1
- package/dist/notrace/redux.js +1 -1
- package/dist/observable.d.ts +1 -1
- package/dist/policies.d.ts +1 -1
- package/dist/redux.d.ts +1 -1
- package/dist/redux.js +1 -1
- package/dist/trace.d.ts +1 -1
- package/docs/README.md +24 -9
- package/docs/actions.md +117 -41
- package/docs/context.md +27 -8
- package/docs/effects.md +152 -73
- package/docs/errors.md +23 -10
- package/docs/guide.md +236 -129
- package/docs/hmr.md +25 -13
- package/docs/observable.md +10 -9
- package/docs/package.md +14 -0
- package/docs/policies.md +92 -30
- package/docs/semantics.md +5 -3
- package/docs/stores.md +96 -22
- package/docs/tracing.md +69 -54
- package/package.json +5 -4
- package/dist/bus-CRnlwmQ4.js +0 -1
- package/dist/notrace/bus-Dx0l9X6h.js +0 -1
- package/dist/notrace/event-0RIBGYqS.js +0 -1
|
@@ -1,29 +1,3 @@
|
|
|
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
|
|
27
1
|
//#region src/core/store.d.ts
|
|
28
2
|
declare const anyEventType = "*";
|
|
29
3
|
//#endregion
|
|
@@ -68,21 +42,29 @@ type Action<E extends EventMap> = {
|
|
|
68
42
|
type: EventKey<E>;
|
|
69
43
|
payload: EventPayload<E>;
|
|
70
44
|
};
|
|
71
|
-
type WithPayload<E extends EventMap, K extends EventKey<E>> = undefined extends E[K] ? {
|
|
72
|
-
type: K;
|
|
73
|
-
payload?: E[K];
|
|
74
|
-
} : {
|
|
75
|
-
type: K;
|
|
76
|
-
payload: E[K];
|
|
77
|
-
};
|
|
78
45
|
type EventLike<E extends EventMap> = { [K in EventKey<E>]: WithPayload<E, K>; }[Keys<E>];
|
|
79
46
|
/**
|
|
80
|
-
*
|
|
81
|
-
*
|
|
47
|
+
* Brands `{ type, payload }` from a command call so `emit` can run the command.
|
|
48
|
+
* Not enumerable on the object.
|
|
49
|
+
*/
|
|
50
|
+
declare const commandCall: unique symbol;
|
|
51
|
+
/**
|
|
52
|
+
* What `command(payload)` returns: an action-shaped value that `emit` runs as
|
|
53
|
+
* that command. A plain `{ type, payload }` without this brand is notify-only.
|
|
54
|
+
*/
|
|
55
|
+
type CommandCall<P = unknown, R = unknown> = {
|
|
56
|
+
type: string;
|
|
57
|
+
payload: P;
|
|
58
|
+
readonly [commandCall]: Command<P, R>;
|
|
59
|
+
};
|
|
60
|
+
/**
|
|
61
|
+
* A typed request for a result. Calling it builds `{ type, payload }` like
|
|
62
|
+
* `createAction`; `bus.emit(command(payload))` (or `bus.emit(command, payload)`)
|
|
63
|
+
* runs the handler as a task and returns what it returns. Made by
|
|
82
64
|
* `createCommand` in `nanoeffects/actions`.
|
|
83
65
|
*/
|
|
84
66
|
type Command<P = never, R = unknown> = {
|
|
85
|
-
(payload: P
|
|
67
|
+
(payload: P): CommandCall<P, R>;
|
|
86
68
|
readonly type: string;
|
|
87
69
|
/** Wraps the handler that really runs, e.g. to route its outcome. */
|
|
88
70
|
readonly wrap?: (run: (payload: never, ctx: never) => unknown) => (payload: never, ctx: never) => unknown;
|
|
@@ -96,11 +78,13 @@ interface Commands {
|
|
|
96
78
|
run(command: Command, payload: unknown, ctx: unknown): unknown;
|
|
97
79
|
}
|
|
98
80
|
/** Anything `emit` takes as its first argument: an event type, an action or a command. */
|
|
99
|
-
type Emittable<E extends EventMap> = EventKey<E> | Command | EventLike<E>;
|
|
81
|
+
type Emittable<E extends EventMap> = EventKey<E> | Command | CommandCall | EventLike<E>;
|
|
100
82
|
type Emit<E extends EventMap> = {
|
|
101
83
|
<K extends EventKey<E>>(event: K, ...payload: PayloadOf<E[K]>): void;
|
|
102
|
-
|
|
84
|
+
/** Before Handler: a command is callable too, and must return its result type. */
|
|
103
85
|
<P, R>(command: Command<P, R>, ...payload: PayloadOf<P>): R;
|
|
86
|
+
<P, R>(call: CommandCall<P, R>): R;
|
|
87
|
+
<K extends EventKey<E>, R>(event: Handler<E, R, K>, ...payload: PayloadOf<E[K]>): R;
|
|
104
88
|
(event: EventLike<E>): void;
|
|
105
89
|
};
|
|
106
90
|
type On<E extends EventMap> = {
|
|
@@ -119,6 +103,8 @@ type On<E extends EventMap> = {
|
|
|
119
103
|
}, fn: Task<E[K], E>): UnsubscribeCallback;
|
|
120
104
|
};
|
|
121
105
|
type Off<E extends EventMap> = {
|
|
106
|
+
/** Removes every listener of every event (including `"*"`). */
|
|
107
|
+
(): void;
|
|
122
108
|
(event: AnyEvent): void;
|
|
123
109
|
(event: AnyEvent, fn: Task<EventPayload<E>, E>): void;
|
|
124
110
|
<K extends EventKey<E>>(event: K): void;
|
|
@@ -173,6 +159,11 @@ type Context<E extends EventMap> = EventLike<E> & ContextOf<E> & {
|
|
|
173
159
|
};
|
|
174
160
|
interface Bus<E extends EventMap> {
|
|
175
161
|
on: On<E>;
|
|
162
|
+
/**
|
|
163
|
+
* Like `on`, but the handler runs at most once: it is removed before it is
|
|
164
|
+
* invoked, so a nested emit of the same event does not re-enter it.
|
|
165
|
+
*/
|
|
166
|
+
once: On<E>;
|
|
176
167
|
off: Off<E>;
|
|
177
168
|
emit: Emit<E>;
|
|
178
169
|
/**
|
|
@@ -223,7 +214,40 @@ type BusOptions<E extends EventMap> = {
|
|
|
223
214
|
};
|
|
224
215
|
declare const createBus: <Events extends EventMap>(options?: BusOptions<Events>) => Bus<Events>;
|
|
225
216
|
//#endregion
|
|
226
|
-
//#region src/
|
|
217
|
+
//#region src/core/types.d.ts
|
|
218
|
+
type PayloadOf<P> = undefined extends P ? [payload?: P] : [payload: P];
|
|
219
|
+
type EventMap = Record<string, unknown>;
|
|
220
|
+
type Keys<E> = keyof E & string;
|
|
221
|
+
type Task<P, E extends EventMap, R = unknown> = (payload: P, ctx: Context<E>) => R;
|
|
222
|
+
type EffectName = "every" | "latest" | "leading" | "debounce" | "throttle" | "run" | "all" | "race" | "retry" | "timeout" | "poll" | "take" | "queue" | "allSettled" | "command";
|
|
223
|
+
type Phase = "start" | "done" | "error" | "cancel" | "drop";
|
|
224
|
+
type TraceEvent<E = Record<string, unknown>> = { [K in Keys<E>]: {
|
|
225
|
+
id: number;
|
|
226
|
+
parent?: number;
|
|
227
|
+
type: K;
|
|
228
|
+
effect: EffectName;
|
|
229
|
+
phase: Phase;
|
|
230
|
+
payload: E[K];
|
|
231
|
+
error?: unknown;
|
|
232
|
+
}; }[Keys<E>];
|
|
233
|
+
/**
|
|
234
|
+
* The contract of every trace logger: receives each task phase of a bus.
|
|
235
|
+
* Adapters in `nanoeffects/trace` are factories that return one; pass it
|
|
236
|
+
* through `createTracer` to `createBus({ trace })`.
|
|
237
|
+
*/
|
|
238
|
+
type TraceLogger<E = Record<string, unknown>> = (event: TraceEvent<E>) => void;
|
|
239
|
+
/** One logger or several; a throwing logger never breaks the task or the others. */
|
|
240
|
+
type Trace<E = Record<string, unknown>> = TraceLogger<E> | readonly TraceLogger<E>[];
|
|
241
|
+
type UnsubscribeCallback = () => void;
|
|
242
|
+
//#endregion
|
|
243
|
+
//#region src/core/action-creator.d.ts
|
|
244
|
+
type WithPayload<E extends EventMap, K extends Keys<E>> = undefined extends E[K] ? {
|
|
245
|
+
type: K;
|
|
246
|
+
payload?: E[K];
|
|
247
|
+
} : {
|
|
248
|
+
type: K;
|
|
249
|
+
payload: E[K];
|
|
250
|
+
};
|
|
227
251
|
type Absent<P> = [P] extends [void] ? undefined : P;
|
|
228
252
|
type Made<P, T extends string> = WithPayload<{ [K in T]: Absent<P>; }, T>;
|
|
229
253
|
declare const free: unique symbol;
|
|
@@ -267,37 +291,5 @@ interface ActionCreator<P = void, T extends string = string, A extends unknown[]
|
|
|
267
291
|
}): action is Made<P, T>;
|
|
268
292
|
toString(): T;
|
|
269
293
|
}
|
|
270
|
-
/**
|
|
271
|
-
* Creates an action creator, as in Redux Toolkit.
|
|
272
|
-
*
|
|
273
|
-
* - `createAction("user/loaded")` needs no generics: the payload type comes
|
|
274
|
-
* from the event map of the bus that the action goes to, and the literal
|
|
275
|
-
* type of the action is kept.
|
|
276
|
-
* - `createAction<User>("user/loaded")` gives the payload type, for a bus
|
|
277
|
-
* without an event map or to check the calls of the creator. The type of
|
|
278
|
-
* the action is then `string`; to keep the literal, give it as the second
|
|
279
|
-
* generic: `createAction<User, "user/loaded">("user/loaded")`.
|
|
280
|
-
* - With `prepare` the arguments of the creator can differ from the payload,
|
|
281
|
-
* and both types are inferred.
|
|
282
|
-
*
|
|
283
|
-
* @example
|
|
284
|
-
* ```ts
|
|
285
|
-
* const added = createAction<number>("counter/added");
|
|
286
|
-
* added(2); // { type: "counter/added", payload: 2 }
|
|
287
|
-
* added.type; // "counter/added"
|
|
288
|
-
* added.match(action); // true for actions of this type
|
|
289
|
-
*
|
|
290
|
-
* const renamed = createAction("user/renamed", (id: string, name: string) => ({
|
|
291
|
-
* payload: { id, name },
|
|
292
|
-
* }));
|
|
293
|
-
*
|
|
294
|
-
* bus.emit(added(2));
|
|
295
|
-
* bus.on(added, (n) => console.log(n));
|
|
296
|
-
* ```
|
|
297
|
-
*/
|
|
298
|
-
declare function createAction<P = Free, T extends string = string>(type: T): [P] extends [Free] ? FreeActionCreator<T> : ActionCreator<P, T>;
|
|
299
|
-
declare function createAction<A extends unknown[], P, T extends string = string>(type: T, prepare: (...args: A) => {
|
|
300
|
-
payload: P;
|
|
301
|
-
}): ActionCreator<P, T, A>;
|
|
302
294
|
//#endregion
|
|
303
|
-
export {
|
|
295
|
+
export { Handler as A, ContextOf as C, EventKey as D, Emittable as E, WithType as F, commandCall as I, createBus as L, Off as M, On as N, EventLike as O, WithContext as P, Tracer as R, Context as S, Emit as T, Bus as _, EffectName as a, CommandCall as b, PayloadOf as c, Trace as d, TraceEvent as f, AnyEvent as g, Action as h, WithPayload as i, HandlerRef as j, EventPayload as k, Phase as l, UnsubscribeCallback as m, Free as n, EventMap as o, TraceLogger as p, FreeActionCreator as r, Keys as s, ActionCreator as t, Task as u, BusOptions as v, ContextOption as w, Commands as x, Command as y, anyEventType as z };
|
|
@@ -1,4 +1,38 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { S as Context, _ as Bus, c as PayloadOf, m as UnsubscribeCallback, n as Free, o as EventMap, r as FreeActionCreator, t as ActionCreator, u as Task, y as Command } from "./action-creator-D48fp13T.js";
|
|
2
|
+
//#region src/actions/action.d.ts
|
|
3
|
+
/**
|
|
4
|
+
* Creates an action creator, as in Redux Toolkit.
|
|
5
|
+
*
|
|
6
|
+
* - `createAction("user/loaded")` needs no generics: the payload type comes
|
|
7
|
+
* from the event map of the bus that the action goes to, and the literal
|
|
8
|
+
* type of the action is kept.
|
|
9
|
+
* - `createAction<User>("user/loaded")` gives the payload type, for a bus
|
|
10
|
+
* without an event map or to check the calls of the creator. The type of
|
|
11
|
+
* the action is then `string`; to keep the literal, give it as the second
|
|
12
|
+
* generic: `createAction<User, "user/loaded">("user/loaded")`.
|
|
13
|
+
* - With `prepare` the arguments of the creator can differ from the payload,
|
|
14
|
+
* and both types are inferred.
|
|
15
|
+
*
|
|
16
|
+
* @example
|
|
17
|
+
* ```ts
|
|
18
|
+
* const added = createAction<number>("counter/added");
|
|
19
|
+
* added(2); // { type: "counter/added", payload: 2 }
|
|
20
|
+
* added.type; // "counter/added"
|
|
21
|
+
* added.match(action); // true for actions of this type
|
|
22
|
+
*
|
|
23
|
+
* const renamed = createAction("user/renamed", (id: string, name: string) => ({
|
|
24
|
+
* payload: { id, name },
|
|
25
|
+
* }));
|
|
26
|
+
*
|
|
27
|
+
* bus.emit(added(2));
|
|
28
|
+
* bus.on(added, (n) => console.log(n));
|
|
29
|
+
* ```
|
|
30
|
+
*/
|
|
31
|
+
export declare function createAction<P = Free, T extends string = string>(type: T): [P] extends [Free] ? FreeActionCreator<T> : ActionCreator<P, T>;
|
|
32
|
+
export declare function createAction<A extends unknown[], P, T extends string = string>(type: T, prepare: (...args: A) => {
|
|
33
|
+
payload: P;
|
|
34
|
+
}): ActionCreator<P, T, A>;
|
|
35
|
+
//#endregion
|
|
2
36
|
//#region src/actions/command.d.ts
|
|
3
37
|
/** What `createCommand` returns: a command that also tells whether an action is of its type. */
|
|
4
38
|
type MadeCommand<P, R, T extends string> = Command<P, R> & {
|
|
@@ -13,17 +47,18 @@ type MadeCommand<P, R, T extends string> = Command<P, R> & {
|
|
|
13
47
|
};
|
|
14
48
|
};
|
|
15
49
|
/**
|
|
16
|
-
* Creates a command: a typed request for a result.
|
|
17
|
-
*
|
|
18
|
-
*
|
|
50
|
+
* Creates a command: a typed request for a result. Calling it builds
|
|
51
|
+
* `{ type, payload }` like `createAction`. `bus.emit(command(payload))` (or
|
|
52
|
+
* `bus.emit(command, payload)`) runs its handler as a task, with a context, and
|
|
53
|
+
* returns what the handler returns. Listeners of the command's type are told
|
|
54
|
+
* first, as for any event.
|
|
19
55
|
*
|
|
20
56
|
* The handler is optional. A command without one is only a contract, and the
|
|
21
57
|
* bus gets its implementation from the `commands` registry (see
|
|
22
58
|
* `commandsPlugin` and `bindHandler`). A handler bound there wins over the one
|
|
23
59
|
* the command was created with, so a test can give a bus its own implementation.
|
|
24
60
|
*
|
|
25
|
-
* A handler can be wrapped in a policy, e.g. `latest(fn)`.
|
|
26
|
-
* directly, `command(payload)`, runs its own handler outside of any bus.
|
|
61
|
+
* A handler can be wrapped in a policy, e.g. `latest(fn)`.
|
|
27
62
|
* `command.match(action)` tells whether an action has the type of the command,
|
|
28
63
|
* as it does for an action creator.
|
|
29
64
|
*
|
|
@@ -34,9 +69,9 @@ type MadeCommand<P, R, T extends string> = Command<P, R> & {
|
|
|
34
69
|
* );
|
|
35
70
|
* const sendMail = createCommand<Mail, void>("mail/send"); // implemented elsewhere
|
|
36
71
|
*
|
|
72
|
+
* const bus = createBus<Events>();
|
|
37
73
|
* bus.use(commandsPlugin([bindHandler(sendMail, smtpSend)]));
|
|
38
|
-
* const
|
|
39
|
-
* const user = await bus.emit(getUser, "1");
|
|
74
|
+
* const user = await bus.emit(getUser("1"));
|
|
40
75
|
*
|
|
41
76
|
* commands.handle(getUser, async () => fakeUser); // in a test
|
|
42
77
|
* ```
|
|
@@ -112,13 +147,13 @@ type Job<P, R, T extends string, S extends Outcome, F extends Outcome> = MadeCom
|
|
|
112
147
|
* is used and returned as it is. A missing one is made with the type
|
|
113
148
|
* `<type>/success` or `<type>/fail`.
|
|
114
149
|
*
|
|
115
|
-
* `bus.emit(
|
|
150
|
+
* `bus.emit(job(payload))` returns a promise of the result. An error of the
|
|
116
151
|
* handler always counts as handled: it goes to `job.fail` and the promise
|
|
117
152
|
* resolves with `undefined`; a command is the tool for a result that must reject.
|
|
118
153
|
* The actions are emitted as the task that ran the job, also for a handler bound
|
|
119
154
|
* with `commands.handle`, and are skipped once the task is aborted. A missing
|
|
120
155
|
* handler is not an outcome: `emit` throws `MissingHandlerError`. Calling the
|
|
121
|
-
* command
|
|
156
|
+
* job builds `{ type, payload }` like a command; it does not run the handler.
|
|
122
157
|
*
|
|
123
158
|
* @example
|
|
124
159
|
* ```ts
|
|
@@ -128,7 +163,7 @@ type Job<P, R, T extends string, S extends Outcome, F extends Outcome> = MadeCom
|
|
|
128
163
|
* });
|
|
129
164
|
*
|
|
130
165
|
* bus.on(loadUser.success, (user) => render(user));
|
|
131
|
-
* bus.emit(loadUser
|
|
166
|
+
* bus.emit(loadUser("1")); // loadUser.success(user) or loadUser.fail(error) comes later
|
|
132
167
|
* ```
|
|
133
168
|
*/
|
|
134
169
|
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`>(type: T, handler?: Task<P, E, R>, outcomes?: {
|
|
@@ -232,4 +267,4 @@ type ModuleApi<E extends EventMap = EventMap> = {
|
|
|
232
267
|
*/
|
|
233
268
|
export declare const modulePlugin: <E extends EventMap>(modules?: readonly Module<E>[]) => (bus: Bus<E>) => ModuleApi<E>;
|
|
234
269
|
//#endregion
|
|
235
|
-
export {
|
|
270
|
+
export type { ActionCreator, Binding, FreeActionCreator, Job, Module, ModuleApi, ModuleContext };
|
package/dist/notrace/actions.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
import{i as e,n as t,s as n}from"./context-yAWj0BFZ.js";import{
|
|
1
|
+
import{i as e,n as t,s as n}from"./context-yAWj0BFZ.js";import{a as r,r as i}from"./bus-B12SvxLv.js";function a(e,t){return Object.assign((...n)=>({type:e,payload:t?t(...n).payload:n[0]}),{type:e,match:t=>t.type===e,toString:()=>e})}var o=class extends Error{};const s=(e,t)=>{let n=t=>t.type===e;function r(n,r){if(typeof r==`object`){if(!t)throw new o(`No handler for command "${e}"`);return t(n,r)}return i(a,e,n)}let a=Object.assign(r,{type:e,match:n});return a},c=(e,t)=>[e,t],l=(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},u=e=>typeof e==`string`?a(e):e,d=(e,t,n)=>{let r=e.emit;r(Reflect.apply(t,null,[n]))},f=e=>{try{return Promise.resolve(e())}catch(e){if(e instanceof o)throw e;return Promise.reject(e)}},p=(e,t,n={})=>{let r=s(e,t),a=u(n.success??`${e}/success`),o=u(n.fail??`${e}/fail`),c=(e,t,n)=>{let r=n;return f(()=>Reflect.apply(e,null,[t,n])).then(e=>(d(r,a,e),e),e=>{d(r,o,e)})},l=e=>(t,n)=>c(e,t,n);function p(t,n){return typeof n==`object`?c(r,t,n):i(m,e,t)}let m=Object.assign(p,{type:e,match:r.match,wrap:l,success:a,fail:o});return m},m=(e,t)=>({name:e,setup:t}),h=(r=[])=>i=>{let a=i.commands??l()(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=t({event:{type:`app`,payload:void 0},bus:i,tracer:i.trace}),c=t=>{let r=/* @__PURE__ */ new Map,i=/* @__PURE__ */ new Map;return{mount:a=>{let s=r.get(a);if(s)return s;let l=i.get(a.name);l&&r.get(l)?.();let u=e(t,a.name),d=u.ctx,f=c(d),p=()=>{r.delete(a),i.get(a.name)===a&&i.delete(a.name),d.abort(),u.unlink()};r.set(a,p),i.set(a.name,a);let m=(e,t)=>{let r=Reflect.apply(o.handle,null,[e,t]);return n(d,r),r},h=(...e)=>{let t=e.map(e=>typeof e==`function`?m(e,e):f.mount(e));return()=>{for(let e of t)e()}},g=(e,...t)=>{d.run(e,...t).catch(e=>{if(!d.signal.aborted)throw e})};try{a.setup(Object.assign(d,{handle:m,use:h,spawn:g}))}catch(e){throw p(),e}return p},unmount:e=>r.get(e)?.(),isMounted:e=>r.has(e)}},u=c(s.ctx);for(let e of r)u.mount(e);return{commands:a,mount:e=>(s.ctx.signal.throwIfAborted(),u.mount(e)),unmount:u.unmount,isMounted:u.isMounted,dispose:()=>s.ctx.abort()}};export{c as bindHandler,l as commandsPlugin,a as createAction,s as createCommand,p as createJob,m as createModule,h as modulePlugin};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{a as e,c as t,n,r}from"./context-yAWj0BFZ.js";import{n as i}from"./promise-CSLpzwSR.js";const a=e=>typeof e==`string`?e:e.type,o=(e,t)=>typeof e==`object`?e.payload:t,s=`*`,c=()=>{let e={},t={},n=n=>(t[n]=void 0,e[n]??=/* @__PURE__ */ new Map,e[n]),r=(e,t)=>{let r=n(e),i=r.get(t)??0;i>1?r.set(t,i-1):t?r.delete(t):r.clear()};return{get:n=>(t[n]??=[...e[n]??[]].flatMap(([e,t])=>Array(t).fill(e)),t[n]),add:(e,t)=>{let i=n(e);return i.set(t,(i.get(t)??0)+1),()=>{r(e,t)}},remove:r,clear:()=>{for(let t of Reflect.ownKeys(e))delete e[t];for(let e of Reflect.ownKeys(t))delete t[e]}}},l=Symbol(`nanoeffects.commandCall`),u=(e,t,n)=>{let r={type:t,payload:n};return Object.defineProperty(r,l,{value:e,enumerable:!1}),r},d=e=>{if(typeof e==`function`)return e;if(typeof e==`object`&&e&&l in e)return e[l]},f=(e,t,n)=>Reflect.apply(e,null,[t,n]),p=(s={})=>{let l=c(),u=(e,t)=>l.add(a(e),t),p=(e,t)=>{let n=u(e,(e,r)=>(n(),t(e,r)));return n},m=(e,t)=>{e===void 0?l.clear():l.remove(a(e),t)},h=(e,a)=>{let{onError:o}=s,{ctx:c}=n({event:a,bus:g,tracer:s.trace,parent:{ref:r()}});if(!o){e(a.payload,c);return}let l=e=>{try{o(e,a)}catch(e){t(`onError failed`,e)}};try{let t=e(a.payload,c);i(t)&&Promise.resolve(t).catch(l)}catch(e){l(e)}},g={on:u,once:p,off:m,emit:(t,i)=>{let c=a(t),u=o(t,i),p={type:c,payload:u},m=d(t),_=[...l.get(c),...l.get(`*`)];_.length===0&&!m&&s.onUnhandled?.(p);for(let e of _)h(e,p);if(m){let{ctx:t}=n({event:p,bus:g,tracer:s.trace,parent:{ref:r()}}),i=g.commands?.run??f;return e(t,`command`,()=>i(m,u,t))}},use:e=>e(g),context:s.context,trace:s.trace};return g};export{a,s as i,p as n,u as r,l as t};
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { S as Context, o as EventMap, s as Keys, u as Task } from "./action-creator-D48fp13T.js";
|
|
2
2
|
//#region src/utils/delay.d.ts
|
|
3
3
|
/**
|
|
4
4
|
* Resolves after `ms`, or rejects early if `ctx.signal` aborts. `ms` can be a
|
package/dist/notrace/index.d.ts
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import { A as
|
|
2
|
-
export { type Action, type AnyEvent, type Bus, type BusOptions, type Command, type Commands, type Context, type ContextOf, type ContextOption, type EffectName, type Emit, type Emittable, type EventKey, type EventLike, type EventMap, type EventPayload, type Handler, type HandlerRef, type Keys, 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, createBus };
|
|
1
|
+
import { A as Handler, C as ContextOf, D as EventKey, E as Emittable, F as WithType, I as commandCall, L as createBus, M as Off, N as On, O as EventLike, P as WithContext, R as Tracer, S as Context, T as Emit, _ as Bus, a as EffectName, b as CommandCall, c as PayloadOf, d as Trace, f as TraceEvent, g as AnyEvent, h as Action, i as WithPayload, j as HandlerRef, k as EventPayload, l as Phase, m as UnsubscribeCallback, o as EventMap, p as TraceLogger, s as Keys, u as Task, v as BusOptions, w as ContextOption, x as Commands, y as Command, z as anyEventType } from "./action-creator-D48fp13T.js";
|
|
2
|
+
export { type Action, type AnyEvent, type Bus, type BusOptions, type Command, type CommandCall, type Commands, type Context, type ContextOf, type ContextOption, type EffectName, type Emit, type Emittable, type EventKey, type EventLike, type EventMap, type EventPayload, type Handler, type HandlerRef, type Keys, 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, createBus };
|
package/dist/notrace/index.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
export{
|
|
1
|
+
export{i as anyEventType,t as commandCall,n as createBus}from"./bus-B12SvxLv.js";
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { o as EventMap, u as Task } from "./action-creator-D48fp13T.js";
|
|
2
2
|
//#region src/policies/keyed.d.ts
|
|
3
3
|
/** Options shared by every policy that can keep its state per key. */
|
|
4
4
|
type KeyOption<P> = {
|
package/dist/notrace/redux.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { _ as Bus, o as EventMap, v as BusOptions } from "./action-creator-D48fp13T.js";
|
|
2
2
|
//#region src/store/redux/middleware.d.ts
|
|
3
3
|
/** What Redux passes through a middleware: an action is a plain object with a `type`. */
|
|
4
4
|
type ReduxAction = {
|
package/dist/notrace/redux.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
import{c as e}from"./context-yAWj0BFZ.js";import{t}from"./bus-
|
|
1
|
+
import{c as e}from"./context-yAWj0BFZ.js";import{n as t}from"./bus-B12SvxLv.js";const n=e=>typeof e==`object`&&!!e&&`type`in e,r=(e,t={})=>{let r=e.emit;return()=>e=>i=>{let a=e(i);return n(i)&&(t.filter?.(i)??!0)&&r(i),a}},i=(n={})=>{let{filter:i,context:a,onError:o,...s}=n,c,l=/* @__PURE__ */ new WeakMap,u=e=>({...a,store:c&&{getState:c.getState,dispatch:t=>{typeof t==`object`&&t&&l.set(t,e.type);let n=t;return c?.dispatch(n)}}}),d=t({...s,onError:o??((t,{type:n})=>{e(`handler of "${n}" failed`,t)}),context:u}),f=r(d,{filter:e=>l.get(e)!==e.type&&(i?.(e)??!0)});return{bus:d,middleware:e=>(c=e,f())}};export{i as createEffectsMiddleware};
|
package/dist/observable.d.ts
CHANGED
package/dist/policies.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { o as EventMap, u as Task } from "./action-creator-D48fp13T.js";
|
|
2
2
|
//#region src/policies/keyed.d.ts
|
|
3
3
|
/** Options shared by every policy that can keep its state per key. */
|
|
4
4
|
type KeyOption<P> = {
|
package/dist/redux.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { _ as Bus, o as EventMap, v as BusOptions } from "./action-creator-D48fp13T.js";
|
|
2
2
|
//#region src/store/redux/middleware.d.ts
|
|
3
3
|
/** What Redux passes through a middleware: an action is a plain object with a `type`. */
|
|
4
4
|
type ReduxAction = {
|
package/dist/redux.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
import{n as e}from"./onAbort-BgMfspK4.js";import{t}from"./bus-
|
|
1
|
+
import{n as e}from"./onAbort-BgMfspK4.js";import{n as t}from"./bus-Cho463Sq.js";const n=e=>typeof e==`object`&&!!e&&`type`in e,r=(e,t={})=>{let r=e.emit;return()=>e=>i=>{let a=e(i);return n(i)&&(t.filter?.(i)??!0)&&r(i),a}},i=(n={})=>{let{filter:i,context:a,onError:o,...s}=n,c,l=/* @__PURE__ */ new WeakMap,u=e=>({...a,store:c&&{getState:c.getState,dispatch:t=>{typeof t==`object`&&t&&l.set(t,e.type);let n=t;return c?.dispatch(n)}}}),d=t({...s,onError:o??((t,{type:n})=>{e(`handler of "${n}" failed`,t)}),context:u}),f=r(d,{filter:e=>l.get(e)!==e.type&&(i?.(e)??!0)});return{bus:d,middleware:e=>(c=e,f())}};export{i as createEffectsMiddleware};
|
package/dist/trace.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { R as Tracer, d as Trace, f as TraceEvent, p as TraceLogger } from "./action-creator-D48fp13T.js";
|
|
2
2
|
//#region src/trace/console.d.ts
|
|
3
3
|
type ConsoleLoggerOptions = {
|
|
4
4
|
/** Defaults to `globalThis.console`. */
|
package/docs/README.md
CHANGED
|
@@ -1,15 +1,30 @@
|
|
|
1
1
|
# Documentation
|
|
2
2
|
|
|
3
|
-
Start
|
|
3
|
+
## Start here
|
|
4
4
|
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
5
|
+
The [Guide](guide.md) is the ladder: small bus → policies for async UI → effects when you need them → commands and modules for domain logic off the UI.
|
|
6
|
+
|
|
7
|
+
Code for every guide step: [`examples/guide.ts`](../examples/guide.ts) (type-checked and tested).
|
|
8
|
+
|
|
9
|
+
## Jump by project need
|
|
10
|
+
|
|
11
|
+
| Project shape | First page |
|
|
12
|
+
| ------------- | ---------- |
|
|
13
|
+
| Small app / widget (rare races) | [Guide § Create a bus](guide.md#1-create-a-bus) |
|
|
14
|
+
| SPA with async UI | [Policies](policies.md), [Guide § latest](guide.md#3-abort-the-previous-run-with-latest) |
|
|
15
|
+
| Unreliable network / long flows | [Effects](effects.md) — one helper per job, then the rest as reference |
|
|
16
|
+
| Domain logic off the UI | [Actions, commands, modules](actions.md) |
|
|
17
|
+
| Already on Redux / Zustand / MobX | [Stores](stores.md) |
|
|
18
|
+
|
|
19
|
+
## Reference
|
|
20
|
+
|
|
21
|
+
- [Policies](policies.md) — `latest`, `leading`, `debounce`, `throttle`, `queue`, `key`
|
|
22
|
+
- [Effects and cancellation](effects.md) — `retry`, `timeout`, `poll`, `take`, `all`, …
|
|
8
23
|
- [Actions, commands, jobs and modules](actions.md)
|
|
9
|
-
- [
|
|
24
|
+
- [Context fields](context.md) — store or client on every task
|
|
10
25
|
- [Errors and unheard events](errors.md)
|
|
11
|
-
- [
|
|
12
|
-
- [
|
|
13
|
-
- [Observable
|
|
14
|
-
- [Hot reload and dev diagnostics](hmr.md)
|
|
26
|
+
- [Package entries](package.md) — which import holds what
|
|
27
|
+
- [Tracing](tracing.md) — loggers, Redux DevTools, `notrace`
|
|
28
|
+
- [Observable](observable.md) — events as TC39 Observables
|
|
29
|
+
- [Hot reload and dev diagnostics](hmr.md)
|
|
15
30
|
- [Semantics](semantics.md)
|