nanoeffects 0.26.0 → 0.28.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 +85 -30
- package/dist/{action-creator-Bpa8BUS9.d.ts → action-creator-CcAEvUnw.d.ts} +90 -23
- package/dist/actions.d.ts +54 -21
- package/dist/actions.js +1 -1
- package/dist/bus-DlpEluzd.js +1 -0
- package/dist/{context-types-BKIH5a8s.d.ts → context-types-hCKgU8sC.d.ts} +1 -1
- package/dist/context.d.ts +2 -2
- package/dist/dev.d.ts +2 -2
- package/dist/dev.js +1 -1
- package/dist/effects.d.ts +2 -2
- package/dist/event-DVcW0mME.js +1 -0
- package/dist/index.d.ts +2 -2
- package/dist/index.js +1 -1
- package/dist/match.d.ts +1 -1
- package/dist/{module-B6rg5NIb.d.ts → module-C_oEXw1n.d.ts} +40 -57
- package/dist/notrace/{action-creator-D2CotugT.d.ts → action-creator-DxOvVo8I.d.ts} +90 -23
- package/dist/notrace/actions.d.ts +114 -98
- package/dist/notrace/actions.js +1 -1
- package/dist/notrace/bus-DmKn4SDD.js +1 -0
- package/dist/notrace/effects.d.ts +2 -2
- package/dist/notrace/index.d.ts +2 -2
- package/dist/notrace/index.js +1 -1
- package/dist/notrace/{plugin-Dz6hq8Jg.d.ts → plugin-lJjjd-SN.d.ts} +1 -1
- package/dist/notrace/policies.d.ts +1 -1
- package/dist/notrace/policies.js +1 -1
- package/dist/notrace/redux.d.ts +1 -1
- package/dist/observable.d.ts +6 -6
- package/dist/oop.d.ts +2 -2
- package/dist/oop.js +1 -1
- package/dist/{plugin-D-j1DarG.d.ts → plugin-CuvIgjnX.d.ts} +2 -2
- package/dist/policies.d.ts +2 -2
- package/dist/react.d.ts +2 -2
- package/dist/redux.d.ts +1 -1
- package/dist/scope.d.ts +2 -2
- package/dist/signal.d.ts +1 -1
- package/dist/signal.js +1 -1
- package/dist/svelte.d.ts +1 -1
- package/dist/trace.d.ts +1 -1
- package/dist/{types-Bkuhnkq6.d.ts → types-FV8fuvI9.d.ts} +2 -2
- package/dist/vue.d.ts +1 -1
- package/dist/{with-policy-BeH8wCkX.d.ts → with-policy-3bhFLEXs.d.ts} +1 -1
- package/docs/README.md +5 -4
- package/docs/actions.md +94 -53
- package/docs/chat-example.md +8 -8
- package/docs/chat-widget.md +135 -0
- package/docs/context.md +1 -1
- package/docs/errors.md +1 -1
- package/docs/guide.md +26 -26
- package/docs/hmr.md +1 -1
- package/docs/motivation.md +10 -4
- package/docs/oop.md +1 -1
- package/docs/package.md +2 -2
- package/docs/plugins.md +23 -23
- package/docs/query-libraries.md +14 -14
- package/docs/scope.md +22 -22
- package/docs/server.md +12 -12
- package/docs/stability.md +2 -2
- package/docs/starter.md +3 -3
- package/docs/tracing.md +5 -5
- package/docs/typescript.md +16 -16
- package/llms-full.txt +380 -194
- package/llms.txt +3 -2
- package/package.json +5 -4
- package/dist/bus-hHp-T7JV.js +0 -1
- package/dist/event-0RIBGYqS.js +0 -1
- package/dist/notrace/bus-BdyvumpX.js +0 -1
- package/dist/notrace/promise-CSLpzwSR.js +0 -1
package/dist/match.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { H as EventMap, Z as UnsubscribeCallback, h as Action, k as EventPayload, q as Task, v as Bus } from "./action-creator-CcAEvUnw.js";
|
|
2
2
|
//#region src/match/plugin.d.ts
|
|
3
3
|
/** A function over the action of an event: `{ type, payload }`. */
|
|
4
4
|
type Predicate<E extends EventMap> = (action: Action<E>) => boolean;
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import { n as ScopeSlots, r as Scoped
|
|
1
|
+
import { G as PayloadOf, H as EventMap, R as commandCall, S as Context, Z as UnsubscribeCallback, b as Command, c as Scope, g as Actions, q as Task, u as WithScope, v as Bus, x as CommandCall } from "./action-creator-CcAEvUnw.js";
|
|
2
|
+
import { n as ScopeSlots, r as Scoped } from "./types-FV8fuvI9.js";
|
|
3
3
|
//#region src/actions/command.d.ts
|
|
4
4
|
/** What `createCommand` returns: a command that also tells whether an action is of its type. */
|
|
5
5
|
type MadeCommand<P, R, T extends string> = Command<P, R> & {
|
|
@@ -17,67 +17,46 @@ type MadeCommand<P, R, T extends string> = Command<P, R> & {
|
|
|
17
17
|
type CarryingCalls<Made, P, R, F> = [unknown] extends [F] ? Made : ((payload: P) => CommandCall<P, R> & WithScope<F>) & Made & WithScope<F>;
|
|
18
18
|
/** A command made with a scope: its calls carry the fields of that scope, for the checker. */
|
|
19
19
|
type ScopedCommand<P, R, T extends string, F> = ((payload: P) => CommandCall<P, R> & WithScope<F>) & MadeCommand<P, R, T> & WithScope<F>;
|
|
20
|
+
/** A command (or its type) with the handler to bind to it; `setHandler` makes one. */
|
|
21
|
+
type Binding<E extends EventMap = EventMap> = readonly [Command<never, unknown> | string, Task<never, E, unknown>];
|
|
20
22
|
/**
|
|
21
|
-
*
|
|
22
|
-
*
|
|
23
|
-
*
|
|
24
|
-
* returns what the handler returns. Listeners of the command's type are told
|
|
25
|
-
* first, as for any event.
|
|
26
|
-
*
|
|
27
|
-
* The handler is optional. A command without one is only a contract, and the
|
|
28
|
-
* bus gets its implementation from the `commands` registry (see
|
|
29
|
-
* `commandsPlugin` and `bindHandler`). A handler bound there wins over the one
|
|
30
|
-
* the command was created with, so a test can give a bus its own implementation.
|
|
31
|
-
*
|
|
32
|
-
* A handler can be wrapped in a policy, e.g. `latest(fn)`.
|
|
33
|
-
* `command.match(action)` tells whether an action has the type of the command,
|
|
34
|
-
* as it does for an action creator.
|
|
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.
|
|
23
|
+
* Pairs an action with the handler to bind to it, for `actionsPlugin`. For a
|
|
24
|
+
* command (an action made with a handler, or with a `Call` type) it checks that
|
|
25
|
+
* the handler fits; any other action is accepted with a handler of any payload.
|
|
40
26
|
*
|
|
41
27
|
* @example
|
|
42
28
|
* ```ts
|
|
43
|
-
*
|
|
44
|
-
* fetchUser(id, { signal }),
|
|
45
|
-
* );
|
|
46
|
-
* const sendMail = createCommand<Mail, void>("mail/send"); // implemented elsewhere
|
|
47
|
-
*
|
|
48
|
-
* const bus = createBus<Events>();
|
|
49
|
-
* bus.use(commandsPlugin([bindHandler(sendMail, smtpSend)]));
|
|
50
|
-
* const user = await bus.emit(getUser("1"));
|
|
51
|
-
*
|
|
52
|
-
* commands.handle(getUser, async () => fakeUser); // in a test
|
|
29
|
+
* bus.use(actionsPlugin([setHandler(sendMail, smtpSend)]));
|
|
53
30
|
* ```
|
|
54
31
|
*/
|
|
55
|
-
declare function
|
|
56
|
-
declare function
|
|
57
|
-
|
|
58
|
-
|
|
32
|
+
declare function setHandler<P, R, E extends EventMap>(command: Command<P, R>, fn: Task<P, E, R>): Binding<E>;
|
|
33
|
+
declare function setHandler<A extends {
|
|
34
|
+
readonly type: string;
|
|
35
|
+
}, E extends EventMap>(action: A, fn: LooseHandler<A, E>): Binding<E>;
|
|
59
36
|
/**
|
|
60
|
-
*
|
|
61
|
-
*
|
|
62
|
-
*
|
|
63
|
-
* @example
|
|
64
|
-
* ```ts
|
|
65
|
-
* bus.use(commandsPlugin([bindHandler(sendMail, smtpSend)]));
|
|
66
|
-
* ```
|
|
37
|
+
* The handler an action that is not a command can have: any. A command
|
|
38
|
+
* (a creator whose calls are command calls) is not accepted here, so its own
|
|
39
|
+
* overload checks the handler against its payload and result.
|
|
67
40
|
*/
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
41
|
+
type LooseHandler<A, E extends EventMap> = A extends ((...args: never[]) => {
|
|
42
|
+
readonly [commandCall]: unknown;
|
|
43
|
+
}) ? never : Task<never, E, unknown>;
|
|
44
|
+
/** The registry of handlers that `actionsPlugin` returns: `run` for the bus, `handle` to bind more. */
|
|
45
|
+
interface Registry$1<E extends EventMap> extends Actions {
|
|
71
46
|
handle<P, R>(command: Command<P, R>, fn: Task<P, E, R>): UnsubscribeCallback;
|
|
47
|
+
/** Also an action made without a handler: what is emitted for its type runs `fn` and returns its result. */
|
|
48
|
+
handle<A extends {
|
|
49
|
+
readonly type: string;
|
|
50
|
+
}>(action: A, fn: LooseHandler<A, E>): UnsubscribeCallback;
|
|
72
51
|
handle(type: string, fn: Task<never, E, unknown>): UnsubscribeCallback;
|
|
73
52
|
handle(bindings: readonly Binding<E>[]): UnsubscribeCallback;
|
|
74
53
|
}
|
|
75
54
|
/**
|
|
76
55
|
* The plugin that gives a bus the handlers bound to commands:
|
|
77
|
-
* `bus.use(
|
|
56
|
+
* `bus.use(actionsPlugin(bindings))` makes the registry, sets it as the
|
|
78
57
|
* commands of the bus and returns it. Each bus has its own, so each test can
|
|
79
58
|
* have its own implementation. `handle` binds more later and returns the
|
|
80
|
-
* function that unbinds. A second `
|
|
59
|
+
* function that unbinds. A second `actionsPlugin` on the same bus binds its
|
|
81
60
|
* list in the registry that is there and returns it, so the order of the
|
|
82
61
|
* plugins does not matter. A `commands` that is not such a registry (a custom
|
|
83
62
|
* runner) is replaced.
|
|
@@ -88,13 +67,13 @@ interface Registry$1<E extends EventMap> extends Commands {
|
|
|
88
67
|
* @example
|
|
89
68
|
* ```ts
|
|
90
69
|
* const bus = createBus<Events>();
|
|
91
|
-
* const commands = bus.use(
|
|
70
|
+
* const commands = bus.use(actionsPlugin([setHandler(sendMail, smtpSend)]));
|
|
92
71
|
*
|
|
93
72
|
* const unbind = commands.handle(getUser, async () => fakeUser);
|
|
94
73
|
* unbind(); // the command's own handler is back
|
|
95
74
|
* ```
|
|
96
75
|
*/
|
|
97
|
-
declare const
|
|
76
|
+
declare const actionsPlugin: <E extends EventMap>(bindings?: readonly Binding<E>[]) => (bus: Bus<E>) => Registry$1<E>;
|
|
98
77
|
//#endregion
|
|
99
78
|
//#region src/actions/module.d.ts
|
|
100
79
|
/**
|
|
@@ -106,6 +85,10 @@ declare const commandsPlugin: <E extends EventMap>(bindings?: readonly Binding<E
|
|
|
106
85
|
type ModuleContext<E extends EventMap = EventMap> = Context<E> & {
|
|
107
86
|
/** Binds the handler of a command, or a list of them; undone on unmount. */
|
|
108
87
|
handle<P, R>(command: Command<P, R>, fn: Task<P, E, R>): UnsubscribeCallback;
|
|
88
|
+
/** Also an action made without a handler: the handler answers it as it would a command. */
|
|
89
|
+
handle<A extends {
|
|
90
|
+
readonly type: string;
|
|
91
|
+
}>(action: A, fn: LooseHandler<A, E>): UnsubscribeCallback;
|
|
109
92
|
handle(type: string, fn: Task<never, E, unknown>): UnsubscribeCallback;
|
|
110
93
|
handle(bindings: readonly Binding<E>[]): UnsubscribeCallback;
|
|
111
94
|
/**
|
|
@@ -141,7 +124,7 @@ type Module<E extends EventMap = EventMap> = {
|
|
|
141
124
|
* ```ts
|
|
142
125
|
* export const userModule = createModule<Events>("user", (m) => {
|
|
143
126
|
* m.handle(getUser, fetchUser);
|
|
144
|
-
* m.handle([
|
|
127
|
+
* m.handle([setHandler(sendMail, smtpSend)]);
|
|
145
128
|
* m.use(authModule);
|
|
146
129
|
*
|
|
147
130
|
* m.on(loginRequested, (user, ctx) => ctx.emit(userLoaded(user)));
|
|
@@ -153,7 +136,7 @@ type Module<E extends EventMap = EventMap> = {
|
|
|
153
136
|
*/
|
|
154
137
|
declare function createModule<E extends EventMap = EventMap>(name: string, setup: (m: ModuleContext<E>) => void): Module<E>;
|
|
155
138
|
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>;
|
|
156
|
-
type Registry<E extends EventMap> = ReturnType<ReturnType<typeof
|
|
139
|
+
type Registry<E extends EventMap> = ReturnType<ReturnType<typeof actionsPlugin<E>>>;
|
|
157
140
|
/**
|
|
158
141
|
* The modules of an app as the plugins that report on them see them: the part
|
|
159
142
|
* of what `modulePlugin` returns that `devPlugin` wraps.
|
|
@@ -176,7 +159,7 @@ interface WithApp {
|
|
|
176
159
|
/** What `modulePlugin` returns. */
|
|
177
160
|
type ModuleApi<E extends EventMap = EventMap> = {
|
|
178
161
|
/** The registry of command handlers of the bus: the one it was made with, or the app's own. */
|
|
179
|
-
|
|
162
|
+
actions: Registry<E>;
|
|
180
163
|
/**
|
|
181
164
|
* Mounts modules, in the order given, and returns the function that unmounts them, last
|
|
182
165
|
* mounted first. A module that is mounted already is not run again. If one of them throws,
|
|
@@ -198,15 +181,15 @@ type ModuleApi<E extends EventMap = EventMap> = {
|
|
|
198
181
|
};
|
|
199
182
|
/**
|
|
200
183
|
* The plugin that assembles an app from modules: `bus.use(modulePlugin(modules))`
|
|
201
|
-
* returns `mount`, `unmount`, `isMounted`, `dispose` and `
|
|
184
|
+
* returns `mount`, `unmount`, `isMounted`, `dispose` and `actions` for the
|
|
202
185
|
* modules that come and go, and mounts `modules`, in the order given, on the
|
|
203
186
|
* first use of the app or of the bus: the first `bus.emit`, or the first call
|
|
204
187
|
* of one of its methods. By then every plugin is on the bus, so the plugins can
|
|
205
188
|
* be used in any order. The `on`, `once` and `off` calls made in between are
|
|
206
189
|
* held and made right after the modules, so the listeners of a module stay
|
|
207
190
|
* ahead of them. The bus runs the commands that the modules bind: the registry
|
|
208
|
-
* that the bus has is used (a later `
|
|
209
|
-
* app attaches its own, as `app.
|
|
191
|
+
* that the bus has is used (a later `actionsPlugin` binds in it), otherwise the
|
|
192
|
+
* app attaches its own, as `app.actions`. The app is also `bus.app`.
|
|
210
193
|
*
|
|
211
194
|
* A module is known by its `name`: mounting a module whose name is taken
|
|
212
195
|
* replaces the mounted one, which is unmounted first. That is what hot reload
|
|
@@ -231,10 +214,10 @@ type ModuleApi<E extends EventMap = EventMap> = {
|
|
|
231
214
|
* });
|
|
232
215
|
*
|
|
233
216
|
* bus.emit(getUser, "1");
|
|
234
|
-
* app.
|
|
217
|
+
* app.actions.handle(getUser, fakeUser); // in a test
|
|
235
218
|
* app.dispose();
|
|
236
219
|
* ```
|
|
237
220
|
*/
|
|
238
221
|
declare const modulePlugin: <E extends EventMap>(modules?: readonly Module<E>[]) => (bus: Bus<E> & ScopeSlots & WithApp) => ModuleApi<E>;
|
|
239
222
|
//#endregion
|
|
240
|
-
export { createModule as a, CarryingCalls as c,
|
|
223
|
+
export { createModule as a, CarryingCalls as c, actionsPlugin as d, setHandler as f, WithApp as i, MadeCommand as l, ModuleApi as n, modulePlugin as o, ModuleContext as r, Binding as s, Module as t, ScopedCommand as u };
|
|
@@ -14,6 +14,27 @@ type UnsubscribeCallback = () => void;
|
|
|
14
14
|
//#endregion
|
|
15
15
|
//#region src/core/store.d.ts
|
|
16
16
|
declare const anyEventType = "*";
|
|
17
|
+
type AnyType = "*";
|
|
18
|
+
interface UnsubscribeTask<E extends EventMap> {
|
|
19
|
+
(task: Task<DataOf<E[Keys<E>]>, E>): void;
|
|
20
|
+
<K extends AnyType>(key: K, task?: Task<DataOf<E[Keys<E>]>, E>): void;
|
|
21
|
+
<K extends Keys<E>>(key: K, task?: Task<DataOf<E[K]>, E>): void;
|
|
22
|
+
}
|
|
23
|
+
type Store<E extends EventMap> = {
|
|
24
|
+
get: {
|
|
25
|
+
/** Every listener of every event, in the order of the events. */
|
|
26
|
+
(): Task<DataOf<E[Keys<E>]>, E>[];
|
|
27
|
+
(key: AnyType): Task<DataOf<E[Keys<E>]>, E>[];
|
|
28
|
+
<K extends Keys<E>>(key: K): Task<DataOf<E[K]>, E>[];
|
|
29
|
+
};
|
|
30
|
+
add: {
|
|
31
|
+
(key: AnyType, task: Task<DataOf<E[Keys<E>]>, E>): UnsubscribeCallback;
|
|
32
|
+
<K extends Keys<E>>(key: K, task: Task<DataOf<E[K]>, E>): UnsubscribeCallback;
|
|
33
|
+
};
|
|
34
|
+
remove: UnsubscribeTask<E>;
|
|
35
|
+
/** Drops every key; lists already handed out by `get` stay as they were. */
|
|
36
|
+
clear: () => void;
|
|
37
|
+
};
|
|
17
38
|
//#endregion
|
|
18
39
|
//#region src/core/tracer.d.ts
|
|
19
40
|
/**
|
|
@@ -49,7 +70,7 @@ interface Tracer<Ref extends object = object> {
|
|
|
49
70
|
/** Subscribes to every event; handlers receive the payload of any of them. */
|
|
50
71
|
type AnyEvent = typeof anyEventType;
|
|
51
72
|
type EventKey<E extends EventMap> = Keys<E>;
|
|
52
|
-
type EventPayload<E extends EventMap> = E[EventKey<E>]
|
|
73
|
+
type EventPayload<E extends EventMap> = DataOf<E[EventKey<E>]>;
|
|
53
74
|
type WithType<K extends string> = {
|
|
54
75
|
type: K;
|
|
55
76
|
};
|
|
@@ -69,7 +90,7 @@ type WithSignal = {
|
|
|
69
90
|
type HandlerRef<E extends EventMap, Response = unknown> = (action: Action<E>) => Response;
|
|
70
91
|
type Handler<E extends EventMap, Response = unknown, K extends EventKey<E> = EventKey<E>> = { [P in K]: {
|
|
71
92
|
type: P;
|
|
72
|
-
(payload: E[P]): Response;
|
|
93
|
+
(payload: DataOf<E[P]>): Response;
|
|
73
94
|
}; }[K];
|
|
74
95
|
type Action<E extends EventMap> = {
|
|
75
96
|
type: EventKey<E>;
|
|
@@ -103,35 +124,45 @@ type Command<P = never, R = unknown> = {
|
|
|
103
124
|
readonly wrap?: (run: (payload: never, ctx: never) => unknown) => (payload: never, ctx: never) => unknown;
|
|
104
125
|
};
|
|
105
126
|
/**
|
|
106
|
-
* What the bus needs to run
|
|
107
|
-
* `nanoeffects/actions`, holds the handlers bound to
|
|
108
|
-
* right one, so a bus without `
|
|
127
|
+
* What the bus needs to run the handlers of actions. The implementation,
|
|
128
|
+
* `actionsPlugin` in `nanoeffects/actions`, holds the handlers bound to
|
|
129
|
+
* actions and runs the right one, so a bus without `actions` carries none of
|
|
130
|
+
* that. `bound` tells, for an event type, whether a handler is bound to it: an
|
|
131
|
+
* action with no handler of its own is a command only then. A runner that has
|
|
132
|
+
* no `bound` runs commands only.
|
|
109
133
|
*/
|
|
110
|
-
interface
|
|
134
|
+
interface Actions {
|
|
111
135
|
run(command: Command, payload: unknown, ctx: unknown): unknown;
|
|
136
|
+
bound?(type: string): Command | undefined;
|
|
112
137
|
}
|
|
113
138
|
/** Anything `emit` takes as its first argument: an event type, an action or a command. */
|
|
114
139
|
type Emittable<E extends EventMap> = EventKey<E> | Command | CommandCall | EventLike<E>;
|
|
115
140
|
type Emit<E extends EventMap> = {
|
|
116
|
-
|
|
141
|
+
/**
|
|
142
|
+
* On a bus without an event map the caller can say what a handler bound for
|
|
143
|
+
* the type returns: `bus.emit<string>("user/getId")`. With a map the parameter
|
|
144
|
+
* is `never`, so this form is not taken and no check of names or payloads is lost.
|
|
145
|
+
*/
|
|
146
|
+
<R = void>(type: string extends EventKey<E> ? string : never, ...payload: unknown[]): R;
|
|
147
|
+
<K extends EventKey<E>>(event: K, ...payload: PayloadOf<DataOf<E[K]>>): ResultOf<E[K]>;
|
|
117
148
|
/** Before Handler: a command is callable too, and must return its result type. */
|
|
118
149
|
<P, R>(command: Command<P, R>, ...payload: PayloadOf<P>): R;
|
|
119
150
|
/** A scope as the second argument replaces context fields for the tasks of this emit; see `scopePlugin`. */
|
|
120
151
|
<P, R, F>(call: CommandCall<P, R> & WithScope<F>, scope?: EmitScope<E, F>): R;
|
|
121
152
|
<P, R>(call: CommandCall<P, R>, scope?: EmitScope<E>): R;
|
|
122
|
-
<K extends EventKey<E>, R>(event: Handler<E, R, K>, ...payload: PayloadOf<E[K]
|
|
153
|
+
<K extends EventKey<E>, R>(event: Handler<E, R, K>, ...payload: PayloadOf<DataOf<E[K]>>): R;
|
|
123
154
|
<F>(event: EventLike<E> & WithScope<F>, scope?: EmitScope<E, F>): void;
|
|
124
155
|
(event: EventLike<E>, scope?: EmitScope<E>): void;
|
|
125
156
|
};
|
|
126
157
|
type On<E extends EventMap> = {
|
|
127
158
|
(event: AnyEvent, fn: Task<EventPayload<E>, E>, options?: ListenerOptions): UnsubscribeCallback;
|
|
128
|
-
<K extends EventKey<E>>(event: K, fn: Task<E[K]
|
|
159
|
+
<K extends EventKey<E>>(event: K, fn: Task<DataOf<E[K]>, E>, options?: ListenerOptions): UnsubscribeCallback;
|
|
129
160
|
/** An action creator without a payload type: the payload comes from the event map. */
|
|
130
161
|
/** The creators and commands that carry a scope come first: the handler sees their fields. */
|
|
131
|
-
<K extends EventKey<E>, F>(creator: FreeActionCreator<K, F> & WithScope<F>, fn: Task<E[K]
|
|
162
|
+
<K extends EventKey<E>, F>(creator: FreeActionCreator<K, F> & WithScope<F>, fn: Task<DataOf<E[K]>, WithFields<E, F>>, options?: ListenerOptions): UnsubscribeCallback;
|
|
132
163
|
<P, F>(creator: ActionCreator<P, string, PayloadOf<P>, F> & WithScope<F>, fn: Task<P, WithFields<E, F>>, options?: ListenerOptions): UnsubscribeCallback;
|
|
133
164
|
<P, F>(command: Command<P, unknown> & WithScope<F>, fn: Task<P, WithFields<E, F>>, options?: ListenerOptions): UnsubscribeCallback;
|
|
134
|
-
<K extends EventKey<E>>(creator: FreeActionCreator<K>, fn: Task<E[K]
|
|
165
|
+
<K extends EventKey<E>>(creator: FreeActionCreator<K>, fn: Task<DataOf<E[K]>, E>, options?: ListenerOptions): UnsubscribeCallback;
|
|
135
166
|
/** An action creator: the payload comes from it, so an event map is not needed. */
|
|
136
167
|
<P>(creator: ActionCreator<P>, fn: Task<P, E>, options?: ListenerOptions): UnsubscribeCallback;
|
|
137
168
|
/** A command: the payload comes from it too. */
|
|
@@ -140,7 +171,7 @@ type On<E extends EventMap> = {
|
|
|
140
171
|
type: K;
|
|
141
172
|
}>(event: Event & {
|
|
142
173
|
type: K;
|
|
143
|
-
}, fn: Task<E[K]
|
|
174
|
+
}, fn: Task<DataOf<E[K]>, E>, options?: ListenerOptions): UnsubscribeCallback;
|
|
144
175
|
};
|
|
145
176
|
type Off<E extends EventMap> = {
|
|
146
177
|
/** Removes every listener of every event (including `"*"`). */
|
|
@@ -148,12 +179,12 @@ type Off<E extends EventMap> = {
|
|
|
148
179
|
(event: AnyEvent): void;
|
|
149
180
|
(event: AnyEvent, fn: Task<EventPayload<E>, E>): void;
|
|
150
181
|
<K extends EventKey<E>>(event: K): void;
|
|
151
|
-
<K extends EventKey<E>>(event: K, fn: Task<E[K]
|
|
182
|
+
<K extends EventKey<E>>(event: K, fn: Task<DataOf<E[K]>, E>): void;
|
|
152
183
|
<K extends EventKey<E>, Event extends {
|
|
153
184
|
type: K;
|
|
154
185
|
}>(event: Event & {
|
|
155
186
|
type: K;
|
|
156
|
-
}, fn: Task<E[K]
|
|
187
|
+
}, fn: Task<DataOf<E[K]>, E>): void;
|
|
157
188
|
<P>(command: Command<P, unknown>, fn?: Task<P, E>): void;
|
|
158
189
|
};
|
|
159
190
|
declare const contextKey: unique symbol;
|
|
@@ -217,6 +248,24 @@ interface Bus<E extends EventMap> {
|
|
|
217
248
|
*/
|
|
218
249
|
once: On<E>;
|
|
219
250
|
off: Off<E>;
|
|
251
|
+
/**
|
|
252
|
+
* The listeners an event has right now, in the order they run: what `on`,
|
|
253
|
+
* `once`, `ctx.on` and the `on` of a module registered, as the bus holds them
|
|
254
|
+
* (a plugin may have wrapped a function, so compare the length, not the
|
|
255
|
+
* functions). It takes the event name as a string, as the bus stores it, not
|
|
256
|
+
* an action creator: use `creator.type`. `"*"` gives the any-event listeners,
|
|
257
|
+
* which a named event does not include. The array is not changed afterwards: a later `on` or unbind
|
|
258
|
+
* gives the next `get` a new one.
|
|
259
|
+
*
|
|
260
|
+
* @example
|
|
261
|
+
* ```ts
|
|
262
|
+
* const unbind = bus.on("saved", save);
|
|
263
|
+
* bus.get("saved").length; // 1
|
|
264
|
+
* unbind();
|
|
265
|
+
* bus.get("saved").length; // 0
|
|
266
|
+
* ```
|
|
267
|
+
*/
|
|
268
|
+
get: Store<E>["get"];
|
|
220
269
|
emit: Emit<E>;
|
|
221
270
|
/**
|
|
222
271
|
* Calls `plugin` with the bus and returns what it returns: an api, a
|
|
@@ -224,10 +273,10 @@ interface Bus<E extends EventMap> {
|
|
|
224
273
|
* no list of them. See `modulePlugin` in `nanoeffects/actions`.
|
|
225
274
|
*/
|
|
226
275
|
use<R>(plugin: (bus: Bus<E>) => R): R;
|
|
227
|
-
/** `BusOptions.context` and `.trace`, and `
|
|
276
|
+
/** `BusOptions.context` and `.trace`, and `actions`, for what makes tasks of its own, like `modulePlugin`. */
|
|
228
277
|
readonly ctx?: ContextOption<E> | undefined;
|
|
229
|
-
/** What runs the
|
|
230
|
-
|
|
278
|
+
/** What runs the handlers of actions; `actionsPlugin` and `modulePlugin` set it. Without one a command runs its own handler. */
|
|
279
|
+
actions?: Actions | undefined;
|
|
231
280
|
readonly trace?: Tracer | undefined;
|
|
232
281
|
/** Called with every new task context to add fields to it, for what needs the task, like `effectsPlugin`. Chain to the previous one. */
|
|
233
282
|
addContext?: ((ctx: object) => void) | undefined;
|
|
@@ -245,8 +294,8 @@ type BusOptions<E extends EventMap> = {
|
|
|
245
294
|
onError?: (error: unknown, event: Action<E>) => void;
|
|
246
295
|
/**
|
|
247
296
|
* Called when an event is emitted and nobody listens to it: the usual sign
|
|
248
|
-
* of a typo in an event name. Not called for commands,
|
|
249
|
-
* handler to run. Typically a warning in development only.
|
|
297
|
+
* of a typo in an event name. Not called for commands, nor for an action with
|
|
298
|
+
* a handler bound in `actions`, which always have a handler to run. Typically a warning in development only.
|
|
250
299
|
*
|
|
251
300
|
* @example
|
|
252
301
|
* ```ts
|
|
@@ -336,15 +385,33 @@ type Merge<A, B> = Omit<A, keyof B> & B;
|
|
|
336
385
|
type WithFields<E extends EventMap, F> = [unknown] extends [F] ? E : Omit<E, keyof WithContext<object>> & WithContext<Merge<ContextOf<E>, F>>;
|
|
337
386
|
//#endregion
|
|
338
387
|
//#region src/core/action-creator.d.ts
|
|
339
|
-
type WithPayload<E extends EventMap, K extends Keys<E>> = undefined extends E[K] ? {
|
|
388
|
+
type WithPayload<E extends EventMap, K extends Keys<E>> = undefined extends DataOf<E[K]> ? {
|
|
340
389
|
type: K;
|
|
341
|
-
payload?: E[K]
|
|
390
|
+
payload?: DataOf<E[K]>;
|
|
342
391
|
} : {
|
|
343
392
|
type: K;
|
|
344
|
-
payload: E[K]
|
|
393
|
+
payload: DataOf<E[K]>;
|
|
345
394
|
};
|
|
346
395
|
type Absent<P> = [P] extends [void] ? undefined : P;
|
|
347
396
|
type Made<P, T extends string> = WithPayload<{ [K in T]: Absent<P>; }, T>;
|
|
397
|
+
declare const callBrand: unique symbol;
|
|
398
|
+
/**
|
|
399
|
+
* A payload type together with the type of what a handler of the action
|
|
400
|
+
* returns, for an event map or `createAction`:
|
|
401
|
+
* `type Events = { "user/getId": Call<void, string> }`, and then
|
|
402
|
+
* `bus.emit("user/getId")` is a `string`. A type only: it adds nothing to a
|
|
403
|
+
* bundle, and an entry that is not a `Call` means a payload, with no result.
|
|
404
|
+
*/
|
|
405
|
+
type Call<P = void, R = void> = {
|
|
406
|
+
readonly [callBrand]: {
|
|
407
|
+
payload: P;
|
|
408
|
+
result: R;
|
|
409
|
+
};
|
|
410
|
+
};
|
|
411
|
+
/** The payload type of an entry of an event map: the `P` of a `Call<P, R>`, the entry itself otherwise. */
|
|
412
|
+
type DataOf<T> = T extends Call<infer P, unknown> ? P : T;
|
|
413
|
+
/** What `emit` returns for an entry of an event map: the `R` of a `Call<P, R>`, `void` otherwise. */
|
|
414
|
+
type ResultOf<T> = T extends Call<unknown, infer R> ? R : void;
|
|
348
415
|
declare const free: unique symbol;
|
|
349
416
|
type Free = typeof free;
|
|
350
417
|
/**
|
|
@@ -387,4 +454,4 @@ interface ActionCreator<P = void, T extends string = string, A extends unknown[]
|
|
|
387
454
|
toString(): T;
|
|
388
455
|
}
|
|
389
456
|
//#endregion
|
|
390
|
-
export {
|
|
457
|
+
export { Off as A, Task as B, Emittable as C, EventsOf as D, EventPayload as E, commandCall as F, createBus as I, EventMap as L, WithContext as M, WithSignal as N, Handler as O, WithType as P, Keys as R, Emit as S, EventLike as T, UnsubscribeCallback as V, Command as _, WithPayload as a, ContextOf as b, WithScope as c, Effects as d, Action as f, BusOptions as g, Bus as h, FreeActionCreator as i, On as j, HandlerRef as k, BoundForm as l, AnyEvent as m, Call as n, Scope as o, Actions as p, Free as r, WithFields as s, ActionCreator as t, Effect as u, CommandCall as v, EventKey as w, ContextOption as x, Context as y, PayloadOf as z };
|