nanoeffects 0.27.0 → 0.29.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 +26 -24
- package/dist/{action-creator-D_c223C7.d.ts → action-creator-jeEqIKgK.d.ts} +73 -32
- package/dist/actions.d.ts +18 -18
- package/dist/actions.js +1 -1
- package/dist/bus-0uYn_kRj.js +1 -0
- package/dist/context-DtUnzC-1.js +1 -0
- package/dist/context-types-Bme1mzkn.d.ts +31 -0
- package/dist/context.d.ts +8 -3
- package/dist/context.js +1 -1
- package/dist/{delay-18LJ8jSk.js → delay-5OhJZZQ0.js} +1 -1
- package/dist/dev.d.ts +2 -2
- package/dist/dev.js +1 -1
- package/dist/effects.d.ts +2 -2
- package/dist/effects.js +1 -1
- 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 +3 -3
- package/dist/match.js +1 -1
- package/dist/{module-WX0Gngnt.d.ts → module-BWMW83qk.d.ts} +38 -38
- package/dist/notrace/{action-creator-Bux7Zzsl.d.ts → action-creator-xpQ_I2h8.d.ts} +73 -32
- package/dist/notrace/actions.d.ts +52 -52
- package/dist/notrace/actions.js +1 -1
- package/dist/notrace/bus-37nlVljc.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-CATXOxtj.d.ts → plugin-6LhNx0th.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 +43 -1
- package/dist/observable.js +1 -1
- package/dist/onAbort-BgMfspK4.js +1 -0
- package/dist/oop.d.ts +3 -3
- package/dist/oop.js +1 -1
- package/dist/{plugin-vvkmIIz2.d.ts → plugin-BaErevLy.d.ts} +2 -2
- package/dist/policies.d.ts +2 -2
- package/dist/policies.js +1 -1
- package/dist/react.d.ts +2 -2
- package/dist/react.js +1 -1
- package/dist/redux.d.ts +1 -1
- package/dist/scope.d.ts +9 -9
- package/dist/signal-field-key-CWT-3OXC.js +1 -0
- package/dist/signal.d.ts +34 -6
- package/dist/signal.js +1 -1
- package/dist/svelte.d.ts +1 -1
- package/dist/trace.d.ts +20 -5
- package/dist/trace.js +1 -1
- package/dist/{types-Bf-LX_tE.d.ts → types-D5xsR37j.d.ts} +2 -2
- package/dist/vue.d.ts +1 -1
- package/dist/{with-policy-CPjx0sLm.d.ts → with-policy-BZVRBUOm.d.ts} +1 -1
- package/dist/{with-policy-D-SQRkPh.js → with-policy-C6BIiPIi.js} +1 -1
- package/docs/README.md +14 -1
- package/docs/actions.md +28 -2
- package/docs/chat-example.md +16 -4
- package/docs/chat-widget.md +135 -0
- package/docs/context.md +33 -1
- package/docs/effects.md +20 -9
- package/docs/guide.md +21 -3
- package/docs/migrating-from-effector.md +11 -0
- package/docs/observable.md +43 -0
- package/docs/oop.md +18 -1
- package/docs/package.md +22 -13
- package/docs/plugins.md +69 -11
- package/docs/query-libraries.md +273 -5
- package/docs/react.md +12 -2
- package/docs/scope.md +14 -2
- package/docs/semantics.md +10 -0
- package/docs/server.md +3 -3
- package/docs/stability.md +2 -2
- package/docs/starter.md +3 -3
- package/docs/tracing.md +77 -9
- package/docs/typescript.md +1 -1
- package/llms-full.txt +816 -72
- package/llms.txt +8 -7
- package/package.json +6 -6
- package/skills/nanoeffects/SKILL.md +2 -2
- package/dist/bus-DQDHUN5e.js +0 -1
- package/dist/context-UcmrAIhP.js +0 -1
- package/dist/context-types-nGtzhjxD.d.ts +0 -14
- package/dist/event-0RIBGYqS.js +0 -1
- package/dist/notrace/bus-CGi2lrd5.js +0 -1
- package/dist/notrace/promise-CSLpzwSR.js +0 -1
package/README.md
CHANGED
|
@@ -19,23 +19,22 @@ New project: `npm create nanoeffects@latest my-app` ([Docs](docs/starter.md)). T
|
|
|
19
19
|
|
|
20
20
|
## Create a bus
|
|
21
21
|
|
|
22
|
-
|
|
22
|
+
The project is built on the event emitter pattern, also known as [publish–subscribe](https://en.wikipedia.org/wiki/Publish%E2%80%93subscribe_pattern): every handler is an `on` listener and every message an `emit`. You rarely need to think about it, because policies, actions and modules (below) do the work. Full API of the bus (`once`, `off`, options): [Guide](docs/guide.md#1-create-a-bus).
|
|
23
23
|
|
|
24
24
|
```js
|
|
25
25
|
import { createBus } from "nanoeffects";
|
|
26
26
|
|
|
27
27
|
const bus = createBus(); // event bus; each handler call is a task
|
|
28
|
+
const cart = [];
|
|
28
29
|
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
30
|
+
// two independent listeners of one event; on returns the function that unsubscribes
|
|
31
|
+
const unbind = bus.on("cart/added", (item) => analytics.track("add", item));
|
|
32
|
+
bus.on("cart/added", (item) => cart.push(item));
|
|
32
33
|
|
|
33
|
-
bus.emit("
|
|
34
|
-
unbind();
|
|
34
|
+
bus.emit("cart/added", { id: "p1" }); // both listeners run, cart has the item
|
|
35
|
+
unbind(); // stop tracking
|
|
35
36
|
```
|
|
36
37
|
|
|
37
|
-
That is enough for a small app or a widget. The handler’s second argument is a task context (`signal`, `emit`, …).
|
|
38
|
-
|
|
39
38
|
## Keep the logic out of the component
|
|
40
39
|
|
|
41
40
|
A newer search should abort the older one. Put it in a handler outside the component, wrapped in `latest`.
|
|
@@ -61,7 +60,7 @@ bus.on(
|
|
|
61
60
|
|
|
62
61
|
`ctx.signal` is a standard [`AbortSignal`](https://developer.mozilla.org/en-US/docs/Web/API/AbortSignal), built into browsers and Node: `fetch` and many other APIs accept it and stop when it aborts.
|
|
63
62
|
|
|
64
|
-
The handler knows nothing about the UI: it only emits `results`. The component sends `search` and listens to `results` ([Vue](docs/vue.md) and [Svelte](docs/svelte.md)
|
|
63
|
+
The handler knows nothing about the UI: it only emits `results`. The component sends `search` and listens to `results`. React has hooks for it (`useEventState`, `useEmitter`: [React](docs/react.md#show-the-last-value-of-an-event-as-state)), and [Vue](docs/vue.md) and [Svelte](docs/svelte.md) have their own helpers:
|
|
65
64
|
|
|
66
65
|
```jsx
|
|
67
66
|
// SearchBox.jsx
|
|
@@ -87,21 +86,6 @@ export function SearchBox() {
|
|
|
87
86
|
}
|
|
88
87
|
```
|
|
89
88
|
|
|
90
|
-
## Take dependencies from the context
|
|
91
|
-
|
|
92
|
-
Put the API client, a store or a logger on every task once. A test passes a fake one.
|
|
93
|
-
|
|
94
|
-
```js
|
|
95
|
-
import { createBus } from "nanoeffects";
|
|
96
|
-
|
|
97
|
-
// context — every task gets these fields: the bus is the container for your dependencies
|
|
98
|
-
const bus = createBus({ context: { api } });
|
|
99
|
-
|
|
100
|
-
bus.on("save", async (draft, ctx) => {
|
|
101
|
-
await ctx.api.put(draft, { signal: ctx.signal });
|
|
102
|
-
});
|
|
103
|
-
```
|
|
104
|
-
|
|
105
89
|
## Load data and await the result
|
|
106
90
|
|
|
107
91
|
Give an action a handler, and `emit` returns its result. The caller does not import the request.
|
|
@@ -123,6 +107,24 @@ const user = await bus.emit(getUser("1"));
|
|
|
123
107
|
|
|
124
108
|
This is one way to load data. If you already use React Query or SWR, keep them: see [Query libraries](docs/query-libraries.md).
|
|
125
109
|
|
|
110
|
+
## Take dependencies from the context
|
|
111
|
+
|
|
112
|
+
Put an API client, a store or a logger on every task once. A test passes a fake one. Here the client is an [axios](https://axios-http.com) instance, but any object works.
|
|
113
|
+
|
|
114
|
+
```js
|
|
115
|
+
import axios from "axios";
|
|
116
|
+
import { createBus } from "nanoeffects";
|
|
117
|
+
|
|
118
|
+
const api = axios.create({ baseURL: "/api" });
|
|
119
|
+
|
|
120
|
+
// context — every task gets these fields: the bus is the container for your dependencies
|
|
121
|
+
const bus = createBus({ context: { api } });
|
|
122
|
+
|
|
123
|
+
bus.on("save", async (draft, ctx) => {
|
|
124
|
+
await ctx.api.put("/drafts", draft, { signal: ctx.signal });
|
|
125
|
+
});
|
|
126
|
+
```
|
|
127
|
+
|
|
126
128
|
## Docs
|
|
127
129
|
|
|
128
130
|
Start with the [Guide](docs/guide.md), or jump by need:
|
|
@@ -1,14 +1,16 @@
|
|
|
1
1
|
//#region src/core/types.d.ts
|
|
2
|
-
/** The third argument of `on` and `once`: read by
|
|
2
|
+
/** The third argument of `on` and `once`: each field is read by the plugin that names it, ignored without it. */
|
|
3
3
|
type ListenerOptions = {
|
|
4
|
-
/** Names the listener in the trace: each call of it is a task with this `type`. */
|
|
4
|
+
/** Names the listener in the trace: each call of it is a task with this `type`. Read by `tracePlugin`. */
|
|
5
5
|
traceId?: string;
|
|
6
|
+
/** Removes the listener when this aborts, and adds none if it aborted already. Read by `signalPlugin`. */
|
|
7
|
+
signal?: AbortSignal;
|
|
6
8
|
};
|
|
7
9
|
type PayloadOf<P> = undefined extends P ? [payload?: P] : [payload: P];
|
|
8
10
|
type EventMap = Record<string, unknown>;
|
|
9
11
|
type Keys<E> = keyof E & string;
|
|
10
12
|
type Task<P, E extends EventMap, R = unknown> = (payload: P, ctx: Context<E>) => R;
|
|
11
|
-
type EffectName = "every" | "latest" | "leading" | "debounce" | "throttle" | "run" | "all" | "race" | "retry" | "timeout" | "poll" | "take" | "queue" | "allSettled" | "
|
|
13
|
+
type EffectName = "every" | "latest" | "leading" | "debounce" | "throttle" | "run" | "all" | "race" | "retry" | "timeout" | "poll" | "take" | "queue" | "allSettled" | "action" | "emit";
|
|
12
14
|
type Phase = "start" | "done" | "error" | "cancel" | "drop";
|
|
13
15
|
type TraceEvent<E = Record<string, unknown>> = { [K in Keys<E>]: {
|
|
14
16
|
id: number;
|
|
@@ -36,6 +38,27 @@ type UnsubscribeCallback = () => void;
|
|
|
36
38
|
//#endregion
|
|
37
39
|
//#region src/core/store.d.ts
|
|
38
40
|
declare const anyEventType = "*";
|
|
41
|
+
type AnyType = "*";
|
|
42
|
+
interface UnsubscribeTask<E extends EventMap> {
|
|
43
|
+
(task: Task<DataOf<E[Keys<E>]>, E>): void;
|
|
44
|
+
<K extends AnyType>(key: K, task?: Task<DataOf<E[Keys<E>]>, E>): void;
|
|
45
|
+
<K extends Keys<E>>(key: K, task?: Task<DataOf<E[K]>, E>): void;
|
|
46
|
+
}
|
|
47
|
+
type Store<E extends EventMap> = {
|
|
48
|
+
get: {
|
|
49
|
+
/** Every listener of every event, in the order of the events. */
|
|
50
|
+
(): Task<DataOf<E[Keys<E>]>, E>[];
|
|
51
|
+
(key: AnyType): Task<DataOf<E[Keys<E>]>, E>[];
|
|
52
|
+
<K extends Keys<E>>(key: K): Task<DataOf<E[K]>, E>[];
|
|
53
|
+
};
|
|
54
|
+
add: {
|
|
55
|
+
(key: AnyType, task: Task<DataOf<E[Keys<E>]>, E>): UnsubscribeCallback;
|
|
56
|
+
<K extends Keys<E>>(key: K, task: Task<DataOf<E[K]>, E>): UnsubscribeCallback;
|
|
57
|
+
};
|
|
58
|
+
remove: UnsubscribeTask<E>;
|
|
59
|
+
/** Drops every key; lists already handed out by `get` stay as they were. */
|
|
60
|
+
clear: () => void;
|
|
61
|
+
};
|
|
39
62
|
//#endregion
|
|
40
63
|
//#region src/core/tracer.d.ts
|
|
41
64
|
/**
|
|
@@ -99,27 +122,27 @@ type Action<E extends EventMap> = {
|
|
|
99
122
|
};
|
|
100
123
|
type EventLike<E extends EventMap> = { [K in EventKey<E>]: WithPayload<E, K>; }[Keys<E>];
|
|
101
124
|
/**
|
|
102
|
-
* Brands `{ type, payload }` from a
|
|
125
|
+
* Brands `{ type, payload }` from a call of an action with a handler so `emit` can run the action.
|
|
103
126
|
* Not enumerable on the object.
|
|
104
127
|
*/
|
|
105
|
-
declare const
|
|
128
|
+
declare const handledCall: unique symbol;
|
|
106
129
|
/**
|
|
107
|
-
* What `
|
|
108
|
-
* that
|
|
130
|
+
* What `action(payload)` returns: an action-shaped value that `emit` runs as
|
|
131
|
+
* that action. A plain `{ type, payload }` without this brand is notify-only.
|
|
109
132
|
*/
|
|
110
|
-
type
|
|
133
|
+
type HandledCall<P = unknown, R = unknown> = {
|
|
111
134
|
type: string;
|
|
112
135
|
payload: P;
|
|
113
|
-
readonly [
|
|
136
|
+
readonly [handledCall]: Handled<P, R>;
|
|
114
137
|
};
|
|
115
138
|
/**
|
|
116
139
|
* A typed request for a result. Calling it builds `{ type, payload }` like
|
|
117
|
-
* `createAction`; `bus.emit(
|
|
140
|
+
* `createAction`; `bus.emit(action(payload))` (or `bus.emit(action, payload)`)
|
|
118
141
|
* runs the handler as a task and returns what it returns. Made by
|
|
119
|
-
* `
|
|
142
|
+
* `createAction` in `nanoeffects/actions`.
|
|
120
143
|
*/
|
|
121
|
-
type
|
|
122
|
-
(payload: P):
|
|
144
|
+
type Handled<P = never, R = unknown> = {
|
|
145
|
+
(payload: P): HandledCall<P, R>;
|
|
123
146
|
readonly type: string;
|
|
124
147
|
/** Wraps the handler that really runs, e.g. to route its outcome. */
|
|
125
148
|
readonly wrap?: (run: (payload: never, ctx: never) => unknown) => (payload: never, ctx: never) => unknown;
|
|
@@ -129,15 +152,15 @@ type Command<P = never, R = unknown> = {
|
|
|
129
152
|
* `actionsPlugin` in `nanoeffects/actions`, holds the handlers bound to
|
|
130
153
|
* actions and runs the right one, so a bus without `actions` carries none of
|
|
131
154
|
* that. `bound` tells, for an event type, whether a handler is bound to it: an
|
|
132
|
-
* action with no handler of its own is
|
|
133
|
-
* no `bound` runs
|
|
155
|
+
* action with no handler of its own is an action only then. A runner that has
|
|
156
|
+
* no `bound` runs actions only.
|
|
134
157
|
*/
|
|
135
158
|
interface Actions {
|
|
136
|
-
run(
|
|
137
|
-
bound?(type: string):
|
|
159
|
+
run(handled: Handled, payload: unknown, ctx: unknown): unknown;
|
|
160
|
+
bound?(type: string): Handled | undefined;
|
|
138
161
|
}
|
|
139
|
-
/** Anything `emit` takes as its first argument: an event type, an action or a
|
|
140
|
-
type Emittable<E extends EventMap> = EventKey<E> |
|
|
162
|
+
/** Anything `emit` takes as its first argument: an event type, an action creator or a call of one. */
|
|
163
|
+
type Emittable<E extends EventMap> = EventKey<E> | Handled | HandledCall | EventLike<E>;
|
|
141
164
|
type Emit<E extends EventMap> = {
|
|
142
165
|
/**
|
|
143
166
|
* On a bus without an event map the caller can say what a handler bound for
|
|
@@ -146,11 +169,11 @@ type Emit<E extends EventMap> = {
|
|
|
146
169
|
*/
|
|
147
170
|
<R = void>(type: string extends EventKey<E> ? string : never, ...payload: unknown[]): R;
|
|
148
171
|
<K extends EventKey<E>>(event: K, ...payload: PayloadOf<DataOf<E[K]>>): ResultOf<E[K]>;
|
|
149
|
-
/** Before Handler:
|
|
150
|
-
<P, R>(
|
|
172
|
+
/** Before Handler: an action is callable too, and must return its result type. */
|
|
173
|
+
<P, R>(handled: Handled<P, R>, ...payload: PayloadOf<P>): R;
|
|
151
174
|
/** A scope as the second argument replaces context fields for the tasks of this emit; see `scopePlugin`. */
|
|
152
|
-
<P, R, F>(call:
|
|
153
|
-
<P, R>(call:
|
|
175
|
+
<P, R, F>(call: HandledCall<P, R> & WithScope<F>, scope?: EmitScope<E, F>): R;
|
|
176
|
+
<P, R>(call: HandledCall<P, R>, scope?: EmitScope<E>): R;
|
|
154
177
|
<K extends EventKey<E>, R>(event: Handler<E, R, K>, ...payload: PayloadOf<DataOf<E[K]>>): R;
|
|
155
178
|
<F>(event: EventLike<E> & WithScope<F>, scope?: EmitScope<E, F>): void;
|
|
156
179
|
(event: EventLike<E>, scope?: EmitScope<E>): void;
|
|
@@ -159,15 +182,15 @@ type On<E extends EventMap> = {
|
|
|
159
182
|
(event: AnyEvent, fn: Task<EventPayload<E>, E>, options?: ListenerOptions): UnsubscribeCallback;
|
|
160
183
|
<K extends EventKey<E>>(event: K, fn: Task<DataOf<E[K]>, E>, options?: ListenerOptions): UnsubscribeCallback;
|
|
161
184
|
/** An action creator without a payload type: the payload comes from the event map. */
|
|
162
|
-
/** The creators and
|
|
185
|
+
/** The creators and actions that carry a scope come first: the handler sees their fields. */
|
|
163
186
|
<K extends EventKey<E>, F>(creator: FreeActionCreator<K, F> & WithScope<F>, fn: Task<DataOf<E[K]>, WithFields<E, F>>, options?: ListenerOptions): UnsubscribeCallback;
|
|
164
187
|
<P, F>(creator: ActionCreator<P, string, PayloadOf<P>, F> & WithScope<F>, fn: Task<P, WithFields<E, F>>, options?: ListenerOptions): UnsubscribeCallback;
|
|
165
|
-
<P, F>(
|
|
188
|
+
<P, F>(handled: Handled<P, unknown> & WithScope<F>, fn: Task<P, WithFields<E, F>>, options?: ListenerOptions): UnsubscribeCallback;
|
|
166
189
|
<K extends EventKey<E>>(creator: FreeActionCreator<K>, fn: Task<DataOf<E[K]>, E>, options?: ListenerOptions): UnsubscribeCallback;
|
|
167
190
|
/** An action creator: the payload comes from it, so an event map is not needed. */
|
|
168
191
|
<P>(creator: ActionCreator<P>, fn: Task<P, E>, options?: ListenerOptions): UnsubscribeCallback;
|
|
169
|
-
/**
|
|
170
|
-
<P>(
|
|
192
|
+
/** An action: the payload comes from it too. */
|
|
193
|
+
<P>(handled: Handled<P, unknown>, fn: Task<P, E>, options?: ListenerOptions): UnsubscribeCallback;
|
|
171
194
|
<K extends EventKey<E>, Event extends {
|
|
172
195
|
type: K;
|
|
173
196
|
}>(event: Event & {
|
|
@@ -186,7 +209,7 @@ type Off<E extends EventMap> = {
|
|
|
186
209
|
}>(event: Event & {
|
|
187
210
|
type: K;
|
|
188
211
|
}, fn: Task<DataOf<E[K]>, E>): void;
|
|
189
|
-
<P>(
|
|
212
|
+
<P>(handled: Handled<P, unknown>, fn?: Task<P, E>): void;
|
|
190
213
|
};
|
|
191
214
|
declare const contextKey: unique symbol;
|
|
192
215
|
/**
|
|
@@ -249,6 +272,24 @@ interface Bus<E extends EventMap> {
|
|
|
249
272
|
*/
|
|
250
273
|
once: On<E>;
|
|
251
274
|
off: Off<E>;
|
|
275
|
+
/**
|
|
276
|
+
* The listeners an event has right now, in the order they run: what `on`,
|
|
277
|
+
* `once`, `ctx.on` and the `on` of a module registered, as the bus holds them
|
|
278
|
+
* (a plugin may have wrapped a function, so compare the length, not the
|
|
279
|
+
* functions). It takes the event name as a string, as the bus stores it, not
|
|
280
|
+
* an action creator: use `creator.type`. `"*"` gives the any-event listeners,
|
|
281
|
+
* which a named event does not include. The array is not changed afterwards: a later `on` or unbind
|
|
282
|
+
* gives the next `get` a new one.
|
|
283
|
+
*
|
|
284
|
+
* @example
|
|
285
|
+
* ```ts
|
|
286
|
+
* const unbind = bus.on("saved", save);
|
|
287
|
+
* bus.get("saved").length; // 1
|
|
288
|
+
* unbind();
|
|
289
|
+
* bus.get("saved").length; // 0
|
|
290
|
+
* ```
|
|
291
|
+
*/
|
|
292
|
+
get: Store<E>["get"];
|
|
252
293
|
emit: Emit<E>;
|
|
253
294
|
/**
|
|
254
295
|
* Calls `plugin` with the bus and returns what it returns: an api, a
|
|
@@ -258,7 +299,7 @@ interface Bus<E extends EventMap> {
|
|
|
258
299
|
use<R>(plugin: (bus: Bus<E>) => R): R;
|
|
259
300
|
/** `BusOptions.context` and `.trace`, and `actions`, for what makes tasks of its own, like `modulePlugin`. */
|
|
260
301
|
readonly ctx?: ContextOption<E> | undefined;
|
|
261
|
-
/** What runs the handlers of actions; `actionsPlugin` and `modulePlugin` set it. Without one
|
|
302
|
+
/** What runs the handlers of actions; `actionsPlugin` and `modulePlugin` set it. Without one an action runs its own handler. */
|
|
262
303
|
actions?: Actions | undefined;
|
|
263
304
|
readonly trace?: Tracer | undefined;
|
|
264
305
|
/** Called with every new task context to add fields to it, for what needs the task, like `effectsPlugin`. Chain to the previous one. */
|
|
@@ -277,7 +318,7 @@ type BusOptions<E extends EventMap> = {
|
|
|
277
318
|
onError?: (error: unknown, event: Action<E>) => void;
|
|
278
319
|
/**
|
|
279
320
|
* Called when an event is emitted and nobody listens to it: the usual sign
|
|
280
|
-
* of a typo in an event name. Not called for
|
|
321
|
+
* of a typo in an event name. Not called for actions, nor for an action with
|
|
281
322
|
* a handler bound in `actions`, which always have a handler to run. Typically a warning in development only.
|
|
282
323
|
*
|
|
283
324
|
* @example
|
|
@@ -330,7 +371,7 @@ type BoundForm<F> = typeof bound extends keyof F ? NonNullable<F[typeof bound &
|
|
|
330
371
|
//#endregion
|
|
331
372
|
//#region src/core/scope-types.d.ts
|
|
332
373
|
declare const scopeFields: unique symbol;
|
|
333
|
-
/** What an action creator
|
|
374
|
+
/** What an action creator or a call knows of the scope it was made with: its fields, for the checker. */
|
|
334
375
|
type WithScope<F> = {
|
|
335
376
|
readonly [scopeFields]: F;
|
|
336
377
|
};
|
|
@@ -439,4 +480,4 @@ interface ActionCreator<P = void, T extends string = string, A extends unknown[]
|
|
|
439
480
|
toString(): T;
|
|
440
481
|
}
|
|
441
482
|
//#endregion
|
|
442
|
-
export {
|
|
483
|
+
export { HandledCall as A, Tracer as B, Emit as C, EventPayload as D, EventLike as E, WithContext as F, PayloadOf as G, EventMap as H, WithSignal as I, Trace as J, Phase as K, WithType as L, HandlerRef as M, Off as N, EventsOf as O, On as P, createBus as R, ContextOption as S, EventKey as T, Keys as U, EffectName as V, ListenerOptions as W, TraceLogger as X, TraceEvent as Y, UnsubscribeCallback as Z, AnyEvent as _, FreeActionCreator as a, Context as b, Scope as c, BoundForm as d, Effect as f, Actions as g, Action as h, Free as i, Handler as j, Handled as k, WithFields as l, Signaled as m, Call as n, WithPayload as o, Effects as p, Task as q, DataOf as r, EmitScope as s, ActionCreator as t, WithScope as u, Bus as v, Emittable as w, ContextOf as x, BusOptions as y, handledCall as z };
|
package/dist/actions.d.ts
CHANGED
|
@@ -1,16 +1,16 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import { r as Scoped, t as FieldsOfScope } from "./types-
|
|
3
|
-
import { a as createModule, c as CarryingCalls, d as actionsPlugin, f as setHandler, l as
|
|
1
|
+
import { G as PayloadOf, H as EventMap, T as EventKey, a as FreeActionCreator, c as Scope, i as Free, n as Call, q as Task, t as ActionCreator, u as WithScope, v as Bus } from "./action-creator-jeEqIKgK.js";
|
|
2
|
+
import { r as Scoped, t as FieldsOfScope } from "./types-D5xsR37j.js";
|
|
3
|
+
import { a as createModule, c as CarryingCalls, d as actionsPlugin, f as setHandler, l as MadeHandled, n as ModuleApi, o as modulePlugin, r as ModuleContext, s as Binding, t as Module, u as ScopedHandled } from "./module-BWMW83qk.js";
|
|
4
4
|
import { t as OriginOptions } from "./origin-key-CxK0SkeG.js";
|
|
5
5
|
//#region src/actions/action.d.ts
|
|
6
6
|
type Reserved = "handle" | "prepare";
|
|
7
|
-
type Made<P, T extends string> = [P] extends [Free] ? FreeActionCreator<T> : [P] extends [Call<infer Q, infer R>] ?
|
|
7
|
+
type Made<P, T extends string> = [P] extends [Free] ? FreeActionCreator<T> : [P] extends [Call<infer Q, infer R>] ? MadeHandled<Q, R, T> : ActionCreator<P, T>;
|
|
8
8
|
type ScopedCreator<P, T extends string, F> = [P] extends [Free] ? FreeActionCreator<T, F> & WithScope<F> : ActionCreator<P, T, PayloadOf<P>, F> & WithScope<F>;
|
|
9
9
|
type ScopeOf<S> = Omit<S, Reserved>;
|
|
10
|
-
type
|
|
10
|
+
type PreparedHandled<P, R, T extends string, A extends unknown[], F> = ((...args: A) => ReturnType<MadeHandled<P, R, T>> & WithScope<F>) & Omit<MadeHandled<P, R, T>, never> & WithScope<F>;
|
|
11
11
|
/**
|
|
12
12
|
* Creates an action creator, as in Redux Toolkit. With a handler it makes a
|
|
13
|
-
*
|
|
13
|
+
* action: `bus.emit(getUser("1"))` runs the handler and returns its result.
|
|
14
14
|
*
|
|
15
15
|
* - `createAction("user/loaded")` needs no generics: the payload type comes
|
|
16
16
|
* from the event map of the bus that the action goes to, and the literal
|
|
@@ -54,22 +54,22 @@ type PreparedCommand<P, R, T extends string, A extends unknown[], F> = ((...args
|
|
|
54
54
|
* ```
|
|
55
55
|
*/
|
|
56
56
|
export declare function createAction<P = Free, T extends string = string>(type: T): Made<P, T>;
|
|
57
|
-
export declare function createAction<P = void, R = void, T extends string = string, E extends EventMap = EventMap>(type: T, handler: Task<P, E, R>):
|
|
57
|
+
export declare function createAction<P = void, R = void, T extends string = string, E extends EventMap = EventMap>(type: T, handler: Task<P, E, R>): MadeHandled<P, R, T>;
|
|
58
58
|
export declare function createAction<P, R, A extends unknown[], T extends string, S extends Scope = Record<never, never>>(type: T, handler: Task<P, Scoped<EventMap, ScopeOf<S>>, R>, options: {
|
|
59
59
|
prepare: (...args: A) => {
|
|
60
60
|
payload: P;
|
|
61
61
|
};
|
|
62
|
-
} & S):
|
|
62
|
+
} & S): PreparedHandled<P, R, T, A, FieldsOfScope<EventMap, ScopeOf<S>>>;
|
|
63
63
|
export declare function createAction<P, R, A extends unknown[], T extends string, S extends Scope = Record<never, never>>(type: T, options: {
|
|
64
64
|
handle: Task<P, Scoped<EventMap, ScopeOf<S>>, R>;
|
|
65
65
|
prepare: (...args: A) => {
|
|
66
66
|
payload: P;
|
|
67
67
|
};
|
|
68
|
-
} & S):
|
|
69
|
-
export declare function createAction<P, R, T extends string, S extends Scope = Record<never, never>>(type: T, handler: Task<P, Scoped<EventMap, S>, R>, scope: S):
|
|
68
|
+
} & S): PreparedHandled<P, R, T, A, FieldsOfScope<EventMap, ScopeOf<S>>>;
|
|
69
|
+
export declare function createAction<P, R, T extends string, S extends Scope = Record<never, never>>(type: T, handler: Task<P, Scoped<EventMap, S>, R>, scope: S): ScopedHandled<P, R, T, FieldsOfScope<EventMap, S>>;
|
|
70
70
|
export declare function createAction<P, R, T extends string, S extends Scope = Record<never, never>>(type: T, options: {
|
|
71
71
|
handle: Task<P, Scoped<EventMap, ScopeOf<S>>, R>;
|
|
72
|
-
} & S):
|
|
72
|
+
} & S): ScopedHandled<P, R, T, FieldsOfScope<EventMap, ScopeOf<S>>>;
|
|
73
73
|
export declare function createAction<A extends unknown[], P, T extends string, S extends Scope = Record<never, never>>(type: T, options: {
|
|
74
74
|
prepare: (...args: A) => {
|
|
75
75
|
payload: P;
|
|
@@ -127,8 +127,8 @@ type Creator = {
|
|
|
127
127
|
readonly type: string;
|
|
128
128
|
};
|
|
129
129
|
type Outcome = string | Creator;
|
|
130
|
-
/** What `createJob` returns: the
|
|
131
|
-
type Job<P, R, T extends string, S extends Outcome, F extends Outcome, PE extends Outcome = `${T}/pending`, CE extends Outcome = `${T}/cancel`> =
|
|
130
|
+
/** What `createJob` returns: the action of the job, with its four outcome creators as properties. */
|
|
131
|
+
type Job<P, R, T extends string, S extends Outcome, F extends Outcome, PE extends Outcome = `${T}/pending`, CE extends Outcome = `${T}/cancel`> = MadeHandled<P, Promise<Awaited<R> | undefined>, T> & {
|
|
132
132
|
/** Made from a string with the payload of the call as its payload, or the creator that was given. */
|
|
133
133
|
readonly pending: PE extends string ? ActionCreator<P, PE> : PE;
|
|
134
134
|
/** Made from a string with the result as its payload, or the creator that was given. */
|
|
@@ -139,13 +139,13 @@ type Job<P, R, T extends string, S extends Outcome, F extends Outcome, PE extend
|
|
|
139
139
|
readonly cancel: CE extends string ? ActionCreator<unknown, CE> : CE;
|
|
140
140
|
};
|
|
141
141
|
/**
|
|
142
|
-
* Creates a job:
|
|
142
|
+
* Creates a job: an action whose outcome is sent on as actions. When the
|
|
143
143
|
* handler starts, `job.pending(payload)` is emitted on the bus. When it
|
|
144
144
|
* succeeds, `job.success(result)` follows, and when it fails, `job.fail(error)`.
|
|
145
145
|
* When the task is aborted after it started, `job.cancel(reason)` follows
|
|
146
146
|
* instead. After `pending`, exactly one of the three closes the call. A job is
|
|
147
147
|
* made for the case where nobody waits for the result and the bus carries it
|
|
148
|
-
* on, like `createAsyncThunk` or an effector effect. It returns the
|
|
148
|
+
* on, like `createAsyncThunk` or an effector effect. It returns the action,
|
|
149
149
|
* with the four actions on it.
|
|
150
150
|
*
|
|
151
151
|
* A scope as the last argument, `{ cache, $effects: { race } }`, gives the handler
|
|
@@ -159,14 +159,14 @@ type Job<P, R, T extends string, S extends Outcome, F extends Outcome, PE extend
|
|
|
159
159
|
*
|
|
160
160
|
* `bus.emit(job(payload))` returns a promise of the result. An error of the
|
|
161
161
|
* handler always counts as handled: it goes to `job.fail` and the promise
|
|
162
|
-
* resolves with `undefined`;
|
|
162
|
+
* resolves with `undefined`; an action is the tool for a result that must reject.
|
|
163
163
|
* The actions are emitted as the task that ran the job, also for a handler bound
|
|
164
|
-
* with `
|
|
164
|
+
* with `actions.handle`. Once the task is aborted, `success` and `fail` are
|
|
165
165
|
* skipped and `cancel` is sent when the handler settles (a handler that never
|
|
166
166
|
* settles sends nothing). A call that does not start, because a policy drops it
|
|
167
167
|
* or it is aborted while it waits in a `queue`, sends none of the four. A
|
|
168
168
|
* missing handler is not an outcome: `emit` throws `MissingHandlerError`.
|
|
169
|
-
* Calling the job builds `{ type, payload }` like
|
|
169
|
+
* Calling the job builds `{ type, payload }` like an action; it does not run
|
|
170
170
|
* the handler.
|
|
171
171
|
*
|
|
172
172
|
* @example
|
package/dist/actions.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
import{
|
|
1
|
+
import{n as e,t}from"./onAbort-BgMfspK4.js";import{i as n,l as r,n as i}from"./context-DtUnzC-1.js";import{t as a}from"./event-DVcW0mME.js";import{r as o}from"./bus-0uYn_kRj.js";import{n as s,t as c}from"./lifecycle-key-8iX8RUVD.js";import{t as l}from"./origin-key-BbWN3gmN.js";import{t as u}from"./scope-key-B7l7mUS5.js";import{t as d}from"./mount-each-D54UqAhZ.js";const f=(e,t)=>(t&&Object.defineProperty(e,u,{value:t}),e),p=(e,t)=>({...e,...t,$effects:{...e.$effects,...t.$effects}}),m=e=>Reflect.get(e,u),h=e=>{let t=Object.assign(n=>o(t,e,n),{type:e});return t},g=e=>typeof e==`object`&&!!e&&Reflect.get(e,`signal`)instanceof AbortSignal&&typeof Reflect.get(e,`emit`)==`function`;var _=class extends Error{};function v(e,t,n){return y(e,t,n)}function y(e,t,n,r){let i=t=>t.type===e,a=e=>r?e.length===2&&g(e[1]):typeof e[1]==`object`;function s(...i){let[s,c]=i;if(a(i)){if(!t)throw new _(`No handler for action "${e}"`);return t(s,c)}let u=r&&Reflect.apply(r,null,i),d=u?u.payload:s;return f(o(l,e,d),n)}let c=Object.assign(s,{type:e,match:i,toString:()=>e}),l=f(c,n);return l}function b(e,t){return[e,t]}const x=e=>typeof Reflect.get(e??{},`handle`)==`function`,S=(e=[])=>t=>{let n=t.actions;if(x(n))return n.handle(e),n;let r=/* @__PURE__ */ new Map,i=(e,t)=>{let n={fn:t};return r.set(e,[...r.get(e)??[],n]),()=>{let t=(r.get(e)??[]).filter(e=>e!==n);t.length>0?r.set(e,t):r.delete(e)}};function o(e,t){if(t)return i(a(e),t);let n=e.map(([e,t])=>i(a(e),t));return()=>{for(let e of n)e()}}o(e);let s={run:(e,t,n)=>{let i=(r.get(e.type)??[]).at(-1)?.fn,a=i&&e.wrap?e.wrap(i):i??e;return Reflect.apply(a,null,[t,n])},handle:o,bound:e=>r.has(e)?h(e):void 0};return t.actions=s,s};function C(e,t,n){let{handle:r,prepare:i,scope:a}=w(typeof t==`function`?n:t),o=typeof t==`function`?t:r;return o?y(e,o,a,i):Object.assign(f((...t)=>{let n=i&&Reflect.apply(i,null,t);return f({type:e,payload:n?n.payload:t[0]},a)},a),{type:e,match:t=>t.type===e,toString:()=>e})}const w=e=>{if(!e)return{};let{handle:t,prepare:n,...r}=e,i=typeof t==`function`,a=typeof n==`function`;if(!i&&!a)return{scope:e};let o=Object.keys(r).length>0?r:void 0;return{...i&&{handle:t},...a&&{prepare:n},...o&&{scope:o}}},T=()=>e=>{function t(t,n){return(...r)=>{let i=t(...r),a=Reflect.get(e,l);a?a(i,n):e.emit(i)}}return Object.assign(e,{emitter:t})},E=e=>typeof e==`string`?C(e):e,D=(e,t,n,r)=>{let i=m(t);e.emit(Reflect.apply(t,null,[n]),r&&i?p(r,i):r)},O=(t,n,i,a)=>{let o=t;o[r]=!0;try{D(t,n,i,a)}catch(t){e(`cancel listener`,t)}o[r]=!1},k=e=>{try{return Promise.resolve(e())}catch(e){if(e instanceof _)throw e;return Promise.reject(e)}},A=(n,r,i={},a)=>{let l=v(n,r),u=e=>E(i[e]??`${n}/${e}`),d=u(`pending`),p=u(`success`),m=u(`fail`),h=u(`cancel`),g=(n,r,i,o)=>{let s=i,l=`idle`,u=()=>{},f=()=>{l=`closed`,u()},g=e=>{l===`started`&&(f(),O(s,h,e,a))},_=()=>{l===`idle`&&(l=`started`,u=t(s,g),D(s,d,r,a))},v=e=>{l===`started`&&(f(),s.signal.aborted?O(s,h,s.signal.reason,a):`error`in e?D(s,m,e.error,a):D(s,p,e.value,a))};return Reflect.set(s,c,{start:_,cancel:g,done:v,drop:()=>{l===`idle`&&(l=`closed`)}}),k(()=>(o||_(),Reflect.apply(n,null,[r,i]))).then(e=>(v({value:e}),e),t=>{if(l===`idle`)try{_()}catch(t){e(`pending listener`,t)}v({error:t})})},_=e=>{let t=Reflect.get(e,s)===!0;return(n,r)=>g(e,n,r,t)},y=Reflect.get(r??{},s)===!0;function b(e,t){return typeof t==`object`?r?g(l,e,t,y):Reflect.apply(l,null,[e,t]):f(o(S,n,e),a)}let x=Object.assign(b,{type:n,match:l.match,wrap:_,pending:d,success:p,fail:m,cancel:h}),S=f(x,a);return S},j=e=>typeof e==`object`&&!!e,M=e=>{if(typeof e==`string`)return e;if(j(e)||typeof e==`function`){let t=Reflect.get(e,`type`);return typeof t==`string`?t:e}return e},N=(e,t)=>{let[n,r]=e;return n===void 0||Object.is(M(n),M(t[0]))&&(r===void 0||Object.is(r,t[1]))},P=e=>{let t={on:e.on,once:e.once,off:e.off},n=[],r=!0,i=(t,n)=>Reflect.apply(t,e,n),a=(e,t)=>(...a)=>{if(!r)return i(t,a);let o={kind:e,args:a,dropped:!1};return n.push(o),()=>{o.live?o.live():o.dropped=!0}},o=e=>(...t)=>{if(!r)return i(e,t);for(let e of n)e.kind!==`off`&&N(t,e.args)&&(e.dropped=!0);n.push({kind:`off`,args:t,dropped:!1})},s=a(`on`,t.on),c=a(`once`,t.once),l=o(t.off);return e.on=s,e.once=c,e.off=l,{release:()=>{r=!1,e.on===s&&(e.on=t.on),e.once===c&&(e.once=t.once),e.off===l&&(e.off=t.off)},replay:()=>{for(let e of n.splice(0))if(!e.dropped){if(e.kind===`off`)i(t.off,e.args);else{let n=e.kind===`on`?t.on:t.once;e.live=i(n,e.args)}}}}};function F(e,t,n){return n?{name:e,setup:t,scope:n}:{name:e,setup:t}}const I=(e,t)=>n=>t?e.fitScope?.(t,n)??n:n,L=(e,t,n)=>{n&&e.applyScope?.(t,n)},R=(e,t,n)=>Array.isArray(t)?[t.map(([t,n])=>[t,e(n)]),n]:[t,e(n)],z=(e,t)=>{let n=e.on;return(...e)=>{let[r,i,...a]=e;return Reflect.apply(n,null,[r,t(i),...a])}},B=e=>(t,...n)=>{e.run(t,...n).catch(t=>{if(!e.signal.aborted)throw t})},V=(r=[])=>a=>{let o=a.actions??S()(a),s={handle:(...e)=>{if(!o.handle)throw Error("modulePlugin: the `actions` of the bus is not a registry from `actionsPlugin()`");return Reflect.apply(o.handle,null,e)}},c=e=>{let r=/* @__PURE__ */ new Map,i=/* @__PURE__ */ new Map;return{mount:o=>{let l=r.get(o);if(l)return l;let u=i.get(o.name);u&&r.get(u)?.();let d=n(e,o.name),f=d.ctx,p=c(f),m=()=>{r.delete(o),i.get(o.name)===o&&i.delete(o.name),f.abort(),d.unlink()};r.set(o,m),i.set(o.name,o);let h=o.scope,g=I(a,h),_=(e,n)=>{let r=Reflect.apply(s.handle,null,R(g,e,n));return t(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=B(f),b=z(f,g);try{L(a,f,h),o.setup(Object.assign(f,{handle:_,use:v,spawn:y,on:b}))}catch(e){throw m(),e}return m},unmount:e=>r.get(e)?.(),isMounted:e=>r.has(e)}},l=P(a),u=a.emit,f=a.get,p,m=(e=!0)=>{if(p)return p;l.release(),a.emit===h&&(a.emit=u);let t=i({event:{type:`app`,payload:void 0},bus:a,tracer:a.trace});p={root:t,apps:d(c(t.ctx))};try{e&&p.apps.mount(...r)}finally{l.replay()}return p},h=(...e)=>(m(),Reflect.apply(u,a,e));a.emit=h,a.get=((...e)=>(m(),Reflect.apply(f,a,e))),r.length>0&&queueMicrotask(()=>{try{m()}catch(t){e(`the modules of the app could not start`,t)}});let g={get actions(){return m(),o},mount:(...e)=>{let{root:t,apps:n}=m();return t.ctx.signal.throwIfAborted(),n.mount(...e)},unmount:(...e)=>m().apps.unmount(...e),isMounted:e=>m().apps.isMounted(e),dispose:()=>m(!1).root.ctx.abort(),createModule:F};return a.app=g,g};export{S as actionsPlugin,C as createAction,A as createJob,F as createModule,T as emitterPlugin,V as modulePlugin,b as setHandler};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{n as e}from"./onAbort-BgMfspK4.js";import{n as t,o as n,r}from"./context-DtUnzC-1.js";import{n as i,t as a}from"./event-DVcW0mME.js";const o=()=>{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()},i=()=>{e={},t={}},a=n=>n===void 0?Object.keys(e).flatMap(a):(t[n]??=[...e[n]??[]].flatMap(([e,t])=>Array(t).fill(e)),t[n]);return{get:a,add:(e,t)=>{let i=n(e);return i.set(t,(i.get(t)??0)+1),()=>r(e,t)},remove:r,clear:i}},s=Symbol(),c=(e,t,n)=>{let r={type:t,payload:n};return Object.defineProperty(r,s,{value:e,enumerable:!1}),r},l=e=>{if(typeof e==`function`)return e;if(typeof e==`object`&&e&&s in e)return e[s]},u=(e,t,n)=>Reflect.apply(e,null,[t,n]),d=(s={})=>{let c=o(),d=(e,t)=>c.add(a(e),t),f=(e,t)=>{let n=d(e,(e,r)=>(n(),t(e,r)));return n},p=(e,t)=>{e===void 0?c.clear():c.remove(a(e),t)},m=e=>t({event:e,bus:g,tracer:s.trace,parent:{ref:r()}}).ctx,h=(t,n)=>{let{onError:r}=s,i=m(n);if(!r){t(n.payload,i);return}let a=t=>{try{r(t,n)}catch(t){e(`onError failed`,t)}};try{let e=t(n.payload,i);typeof e?.then==`function`&&Promise.resolve(e).catch(a)}catch(e){a(e)}},g={get:c.get,on:d,off:p,once:f,emit:(e,t)=>{let r=a(e),o=i(e,t),d={type:r,payload:o},f=l(e);f||=g.actions?.bound?.(r);let p=[...c.get(r),...c.get(`*`)];p.length===0&&!f&&s.onUnhandled?.(d);for(let e of p)h(e,d);if(f){let e=m(d),t=g.actions?.run??u;return n(e,`action`,()=>t(f,o,e))}},use:e=>e(g),ctx:s.context,trace:s.trace};return g};export{l as n,c as r,d as t};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{t as e}from"./onAbort-BgMfspK4.js";const t=t=>{let n=new AbortController;return{controller:n,unlink:e({signal:t},e=>n.abort(e))}},n=Symbol(),r=typeof __NANOEFFECTS_TRACE__>`u`||__NANOEFFECTS_TRACE__,i=/* @__PURE__ */ new WeakMap;let a;const o=()=>a,s=()=>{},c=(e,t,n,a)=>{let o=r&&i.get(e);o&&o.tracer.report(o.ref,t,n,a)},l=(e,t)=>{let n=r&&i.get(e);n&&n.tracer.rename?.(n.ref,t)},u=(e,t)=>{let n=r&&i.get(e);return n?n.tracer.settler(n.ref,t):s},d=(e,t,n)=>{let a=r&&i.get(e);return a?a.tracer.run(a.ref,t,e.signal,n):n()},f=Symbol(`nanoeffects.addContext`),p=(e,t)=>typeof e==`function`?e(t):e,m=({event:o,bus:c,tracer:l,parent:u})=>{let{controller:h,unlink:g}=t(u?.signal),{signal:_}=h,v=r&&l?{tracer:l,ref:l.task(o,u?.ref)}:void 0,y=(...e)=>{if(_.aborted&&!S[n])return;let t=c?.emit,r=a;a=v?.ref;try{return t?.(...e)}finally{a=r}},b=(...t)=>{if(_.aborted)return s;let n=c?.on,r=n?.(...t);if(!r)return s;let i=e({signal:_},r);return()=>{i(),r()}},x=async(e,...t)=>{_.throwIfAborted();let n=t[0],r=m({event:{type:o.type,payload:n},bus:c,tracer:l,parent:{signal:_,ref:v?.ref}});try{return await d(r.ctx,`run`,()=>e(n,r.ctx))}finally{r.unlink()}},S={...p(c?.ctx,o),type:o.type,payload:o.payload,signal:_,abort:e=>h.abort(e),emit:y,on:b,off:c?.off??s,run:x,[f]:c?.addContext};return c?.addContext?.(S),v&&i.set(S,v),{ctx:S,unlink:g}},h=(e,t)=>{let n=r?i.get(e):void 0;return m({event:{type:t??e.type??``,payload:e.payload},bus:{emit:e.emit,on:e.on,off:e.off,ctx:e,addContext:Reflect.get(e,f)},tracer:n?.tracer,parent:{signal:e.signal,ref:n?.ref}})};export{l as a,r as c,h as i,n as l,m as n,d as o,o as r,c as s,u as t};
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
import { H as EventMap, x as ContextOf } from "./action-creator-jeEqIKgK.js";
|
|
2
|
+
//#region src/core/signal-field-key.d.ts
|
|
3
|
+
/**
|
|
4
|
+
* Where `fromSignal` keeps the function that makes a context field from the signal of a
|
|
5
|
+
* task. `Symbol.for`, so `contextPlugin` finds it without importing `nanoeffects/signal`.
|
|
6
|
+
* `createBus` does not import this file.
|
|
7
|
+
*/
|
|
8
|
+
declare const signalFieldKey: unique symbol;
|
|
9
|
+
//#endregion
|
|
10
|
+
//#region src/core/context-types.d.ts
|
|
11
|
+
/** What a function that makes the fields of a task gets to see. */
|
|
12
|
+
type ContextTask = {
|
|
13
|
+
type: string;
|
|
14
|
+
payload?: unknown;
|
|
15
|
+
};
|
|
16
|
+
/**
|
|
17
|
+
* `unknown` when none of the `fields` is already a context field of the bus,
|
|
18
|
+
* else `never`: the call does not compile. Used as `bus: Bus<E> & NoClash<…>`.
|
|
19
|
+
*/
|
|
20
|
+
type NoClash<Fields extends object, E extends EventMap> = [keyof Fields & keyof ContextOf<E>] extends [never] ? unknown : never;
|
|
21
|
+
/**
|
|
22
|
+
* A context field that is made from the signal of each task, on its first read.
|
|
23
|
+
* Made by `fromSignal` in `nanoeffects/signal`; `contextPlugin` puts the made value on `ctx`.
|
|
24
|
+
*/
|
|
25
|
+
type FromSignal<T> = {
|
|
26
|
+
readonly [signalFieldKey]: (signal: AbortSignal) => T;
|
|
27
|
+
};
|
|
28
|
+
/** `Fields` as `ctx` has them: a `FromSignal<T>` field is its `T`. */
|
|
29
|
+
type Resolved<Fields extends object> = { [K in keyof Fields]: Fields[K] extends FromSignal<infer T> ? T : Fields[K]; };
|
|
30
|
+
//#endregion
|
|
31
|
+
export { Resolved as i, FromSignal as n, NoClash as r, ContextTask as t };
|
package/dist/context.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { F as WithContext, H as EventMap, v as Bus } from "./action-creator-
|
|
2
|
-
import {
|
|
1
|
+
import { F as WithContext, H as EventMap, v as Bus } from "./action-creator-jeEqIKgK.js";
|
|
2
|
+
import { i as Resolved, r as NoClash, t as ContextTask } from "./context-types-Bme1mzkn.js";
|
|
3
3
|
//#region src/context/plugin.d.ts
|
|
4
4
|
/**
|
|
5
5
|
* Puts `fields` on the context of every task of the bus: a store, a client, a
|
|
@@ -12,6 +12,11 @@ import { n as NoClash, t as ContextTask } from "./context-types-nGtzhjxD.js";
|
|
|
12
12
|
* fields of the library (`signal`, `emit`, `run`, …) win, and a field that the
|
|
13
13
|
* context already has is not replaced.
|
|
14
14
|
*
|
|
15
|
+
* A field made with `fromSignal` from `nanoeffects/signal` is built from the signal
|
|
16
|
+
* of each task, when the task first reads it, so a client or a handle that needs a
|
|
17
|
+
* signal is declared once. A child task (`ctx.run`) builds its own. It is not
|
|
18
|
+
* copied by `{ ...ctx }`.
|
|
19
|
+
*
|
|
15
20
|
* @example
|
|
16
21
|
* ```ts
|
|
17
22
|
* type Events = { "user/loaded": User };
|
|
@@ -20,6 +25,6 @@ import { n as NoClash, t as ContextTask } from "./context-types-nGtzhjxD.js";
|
|
|
20
25
|
* bus.on("user/loaded", (user, { store }) => store.put(user)); // ctx.store: Store
|
|
21
26
|
* ```
|
|
22
27
|
*/
|
|
23
|
-
export declare const contextPlugin: <Fields extends object>(fields: Fields | ((task: ContextTask) => Fields)) => <E extends EventMap>(bus: Bus<E> & NoClash<Fields, E>) => Bus<E & WithContext<Fields
|
|
28
|
+
export declare const contextPlugin: <Fields extends object>(fields: Fields | ((task: ContextTask) => Fields)) => <E extends EventMap>(bus: Bus<E> & NoClash<Fields, E>) => Bus<E & WithContext<Resolved<Fields>>>;
|
|
24
29
|
//#endregion
|
|
25
30
|
export type { ContextTask, NoClash };
|
package/dist/context.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
const
|
|
1
|
+
import{t as e}from"./signal-field-key-CWT-3OXC.js";const t=e=>typeof e==`function`,n=e=>({type:Reflect.get(e,`type`),payload:Reflect.get(e,`payload`)}),r=t=>{if(typeof t==`object`&&t)return Reflect.get(t,e)},i=(e,t)=>({configurable:!0,get(){let n=t(Reflect.get(this,`signal`));return Object.defineProperty(this,e,{configurable:!0,writable:!0,value:n}),n}}),a=/* @__PURE__ */ new WeakMap,o=(e,t)=>{let n=r(t);if(!(n&&typeof t==`object`&&t))return;let o=a.get(t);if(o?.key===e)return o.lazy;let s=i(e,n);return a.set(t,{key:e,lazy:s}),s},s=e=>r=>{let i=r.addContext;return r.addContext=r=>{i?.(r);let a=t(e)?e(n(r)):e;for(let[e,t]of Object.entries(a)){if(e in r)continue;let n=o(e,t);n?Object.defineProperty(r,e,n):Reflect.set(r,e,t)}},r};export{s as contextPlugin};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{
|
|
1
|
+
import{t as e}from"./onAbort-BgMfspK4.js";const t=e=>typeof e==`object`&&!!e,n=2**31-1,r=(e,t)=>{let r={id:null};if(t===1/0)return r;let i=t=>{r.id=setTimeout(()=>{t>n?i(t-n):(r.id=null,e())},Math.min(t,n))};return i(t>0?t:0),r},i=e=>{e.id!==null&&(clearTimeout(e.id),e.id=null)},a=(t,n)=>new Promise((a,o)=>{let s=r(()=>{c(),a()},typeof n==`function`?n():n),c=e(t,e=>{i(s),o(e)})});function o(e,n){return t(e)?a(e,n):t=>a(t,e)}export{t as i,i as n,r,o as t};
|
package/dist/dev.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { H as EventMap, Z as UnsubscribeCallback, v as Bus } from "./action-creator-
|
|
2
|
-
import { i as WithApp, n as ModuleApi } from "./module-
|
|
1
|
+
import { H as EventMap, Z as UnsubscribeCallback, v as Bus } from "./action-creator-jeEqIKgK.js";
|
|
2
|
+
import { i as WithApp, n as ModuleApi } from "./module-BWMW83qk.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/dev.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
import{t as e}from"./event-
|
|
1
|
+
import{t as e}from"./event-DVcW0mME.js";import{t}from"./mount-each-D54UqAhZ.js";const n=`[nanoeffects]`,r=(e={})=>t=>{let{maxListeners:n=10,leaks:r=!0,modules:i=!0,app:s}=e,c=e.log??(e=>console.warn(e)),l=e.log??(e=>console.info(e)),u=[];return r&&u.push(a(t,n,c)),i&&u.push(o(t,s,l)),()=>{for(let e of u.splice(0))e()}},i=t=>typeof t==`function`&&typeof Reflect.get(t,`type`)!=`string`?`*`:e(t),a=(e,t,r)=>{let a=e.on,o=/* @__PURE__ */ new Map,s=/* @__PURE__ */ new Set,c=!0,l=(...l)=>{if(!c)return Reflect.apply(a,e,l);let[u]=l,d=i(u),f=(o.get(d)??0)+1;o.set(d,f),f>t&&!s.has(d)&&(s.add(d),r(`${n} ${f} listeners of "${d}" were added and not unsubscribed (more than ${t}). A file that is reloaded and subscribes again, or an unsubscribe that is never called?`));let p=Reflect.apply(a,e,l),m=!1;return()=>{if(!m){m=!0;let e=(o.get(d)??1)-1;o.set(d,e),e<=t&&s.delete(d)}p()}};return e.on=l,()=>{c=!1,e.on===l&&(e.on=a)}},o=(e,t,n)=>{let r=t??e.app;if(r)return s(r,n);let i,a;return Object.defineProperty(e,"app",{configurable:!0,enumerable:!0,get:()=>i,set:e=>{a?.(),i=e,a=e?s(e,n):void 0}}),()=>{a?.(),Object.defineProperty(e,"app",{configurable:!0,enumerable:!0,writable:!0,value:i})}},s=(e,r)=>{let{mount:i,unmount:a}=e,o=/* @__PURE__ */ new Map,s=t({mount:t=>{let a=o.get(t.name);if(a===t&&e.isMounted(t))return i(t);let s=a!==void 0&&e.isMounted(a),c=i(t);return o.set(t.name,t),r(`${n} module "${t.name}" ${s?`replaced`:`mounted`}`),()=>{e.isMounted(t)&&r(`${n} module "${t.name}" unmounted`),c()}},unmount:t=>{e.isMounted(t)&&r(`${n} module "${t.name}" unmounted`),a(t)},isMounted:t=>e.isMounted(t)});return e.mount=s.mount,e.unmount=s.unmount,()=>{e.mount=i,e.unmount=a}};export{r as devPlugin};
|
package/dist/effects.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { H as EventMap, I as WithSignal,
|
|
2
|
-
import { a as RaceStarter, c as all, d as GroupOptions, f as Starter, i as take, l as ChildOf, m as delay, n as effectsPlugin, o as race, p as StarterOf, r as TakeOptions, s as allSettled, u as EffectContext } from "./plugin-
|
|
1
|
+
import { H as EventMap, I as WithSignal, b as Context, f as Effect, q as Task } from "./action-creator-jeEqIKgK.js";
|
|
2
|
+
import { a as RaceStarter, c as all, d as GroupOptions, f as Starter, i as take, l as ChildOf, m as delay, n as effectsPlugin, o as race, p as StarterOf, r as TakeOptions, s as allSettled, u as EffectContext } from "./plugin-BaErevLy.js";
|
|
3
3
|
//#region src/utils/onAbort.d.ts
|
|
4
4
|
export declare const onAbort: (ctx: {
|
|
5
5
|
signal?: AbortSignal | undefined;
|
package/dist/effects.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
import{i as e,n as t,r as n,t as r}from"./delay-
|
|
1
|
+
import{i as e,n as t,r as n,t as r}from"./delay-5OhJZZQ0.js";import{n as i,t as a}from"./onAbort-BgMfspK4.js";import{i as o,o as s,s as c,t as l}from"./context-DtUnzC-1.js";const u=(e,t)=>t?.signal?new Promise((n,r)=>{let i=a(t,r);e.then(n,r).finally(i)}):e,d=async(e,t,n,r)=>{t?.signal?.throwIfAborted();let{ctx:i,unlink:s}=o(t??{}),d=l(i,e);c(i,e,`start`),a(i,()=>d(`cancel`));try{let e=await u(n(i),t);return d(`done`),r?.(!1),e}catch(e){throw d(`error`,e),r?.(!0),e}finally{s()}},f=async(e,t)=>{let{ctx:n,unlink:r}=o(e);try{return await s(n,`run`,()=>t(n))}finally{r()}},p=e=>e,m=(e,t)=>n=>e(t,p(n)),h=e=>Array.isArray(e)?Array(e.length):{},g=(e,t)=>{let n=Object.entries(t).map(([t,n])=>{let r=o(e),i=()=>n(r.ctx);return{key:t,task:new Promise(e=>e(s(r.ctx,`run`,i))).finally(r.unlink),cancel:r.ctx.abort}});return{tasks:n.map(({key:e,task:t})=>[e,t]),cancelAll:()=>{for(let e of n)e.cancel()}}},_=e=>{let t=e?.concurrency??1/0;if(t!==1/0&&!(Number.isInteger(t)&&t>=1))throw RangeError(`concurrency must be a positive integer`);return t},v=(e,t,n,r)=>{let i=Object.entries(t),a=[],c=i.map(([e])=>[e,new Promise(e=>a.push(e))]),l=/* @__PURE__ */ new Set,u=0,d=0,f=!1,p=()=>{for(;!f&&!e.signal.aborted&&d<n&&u<i.length;){let t=u++,[,n]=i[t],c=o(e),m=()=>n(c.ctx),h=()=>{c.unlink(),l.delete(c.ctx.abort),d--};l.add(c.ctx.abort),d++;let g=new Promise(e=>e(s(c.ctx,`run`,m))).then(e=>(h(),p(),e),e=>{throw h(),f=r,p(),e});a[t]?.(g)}};return p(),{tasks:c,cancelAll:()=>{f=!0;for(let e of l)e()}}},y=(t,n)=>{if(t.length!==1)return n(...t);let[r]=t;if(e(Reflect.get(r,`signal`)))throw TypeError(`A group takes effects: call it as (effects), or as (ctx, effects); a context alone has none`);return e=>n(e,r)},b=(e,t,n,r,i,a)=>{let o=_(a),s=()=>{};return d(e,t,async t=>{let i=o===1/0?g(t,n):v(t,n,o,e===`all`);return s=i.cancelAll,r(i.tasks)},e=>{(e||i===`end`)&&s()})};function x(...e){return y(e,S)}const S=(e,t,n)=>b(`all`,e,t,async e=>{let n=await Promise.all(e.map(([,e])=>e)),r=h(t);for(let[t,[i]]of e.entries())r[i]=n[t];return r},`failure`,n),C=e=>e.then(e=>({status:`fulfilled`,value:e}),e=>({status:`rejected`,reason:e}));function w(...e){return y(e,T)}const T=(e,t,n)=>b(`allSettled`,e,t,async e=>{let n=await Promise.all(e.map(([,e])=>C(e))),r=h(t);for(let[t,[i]]of e.entries())r[i]=n[t];return r},`failure`,n),E=e=>e>0?e:0,D=(e={})=>{let t=E(e.base??100),n=e.factor??2,r=E(e.max??1/0),i=e.jitter??!1;return e=>{let a=E(Math.min(r,t*n**(e-1)));return i?Math.random()*a||0:a}},O=(e,t)=>e.signal.aborted?Promise.reject(e.signal.reason):new Promise((n,r)=>{let o=[],s=`pending`,c=e=>{try{e()}catch(e){i(`cancel cleanup failed`,e)}},l=a(e,e=>{s=`cancelled`;for(let e of o.reverse())c(e);r(e)}),u=e=>(...t)=>{s===`pending`&&(s=`settled`,l(),o.length=0,e(...t))},d=e=>{s===`pending`?o.push(e):s===`cancelled`&&c(e)};try{t({resolve:u(n),reject:u(r),onCancel:d})}catch(e){u(r)(e)}}),k=Symbol(`nanoeffects.effects.effect`),A=e=>t=>{let n=t.addContext,r=Object.entries(e);return t.addContext=e=>{n?.(e);for(let[t,n]of r){let r=Reflect.get(e,t);if(r===void 0||r[k]===n){let r=(...t)=>n(e,...t);r[k]=n,Reflect.set(e,t,r)}}},t},j=()=>/* @__PURE__ */ TypeError(`A Task is called as (payload, ctx), or as (ctx) when a group starts it; the single argument is not a context`),M=t=>{if(e(t)&&`signal`in t)return t;throw j()},N=(e,t,n)=>t===void 0?n(M(e),void 0):n(t,e),P=(e,r,i,o)=>{if(e.signal.aborted)return Promise.resolve();let s=o.leading??!1,c=o.waitForFn??!1;return d(`poll`,e,e=>new Promise((o,l)=>{let u=0,d=null,p=()=>{d!==null&&(t(d),d=null)},m=e=>{try{d=n(h,typeof i==`function`?i(e):i)}catch(e){p(),l(e)}},h=()=>{d=null,c||m(u+1),g()},g=()=>{let t=u++;f(e,e=>r(e,t)).then(()=>{c&&!e.signal.aborted&&m(u)},e=>{p(),l(e)})};a(e,p),s?(g(),c||m(u)):m(0)})).catch(t=>{if(!e.signal.aborted)throw t})};function F(e,t,n,r={}){if(typeof e!=`object`){let r=t,i=n??{},a=(t,n)=>P(t,m(r,n),e,i);return(e,t)=>N(e,t,a)}let i=t;return P(e,(e,t)=>i(t),n,r)}function I(...e){return y(e,L)}const L=(e,t)=>{let n=h(t);return Object.keys(t).length===0?Promise.resolve(n):b(`race`,e,t,async e=>{let[t,r]=await Promise.race(e.map(([e,t])=>t.then(t=>[e,t])));return n[t]=r,n},`end`)},R=(e,t,n)=>typeof e==`function`?e(t,n):e,z=e=>({times:e.times??3,delay:e.delay??0,shouldRetry:e.shouldRetry??(()=>!0)}),B=(e,t,n)=>d(`retry`,e,async e=>{let{times:i,delay:a,shouldRetry:o}=z(n);for(let n=1;;n++)try{return await f(e,e=>t(e,n))}catch(t){if(e.signal.throwIfAborted(),!(n<i)||!o(t,n))throw t;let s=R(a,n,t);s>0&&await r(e,s)}});function V(e,t,n={}){if(typeof e==`function`){let n=e,r=t??{},i=(e,t)=>B(e,m(n,t),r);return(e,t)=>N(e,t,i)}let r=t;return B(e,(e,t)=>r(t),n)}const H=(e,t,n={})=>d(`take`,e,r=>new Promise((i,o)=>{let{predicate:s}=n,c=[],l=()=>{for(let e of c)e()},u=e=>{l(),o(e)},d=t;c.push(e.on(d,e=>{(!s||s(e))&&(l(),i(e))})),c.push(a(r,u)),c.push(a({signal:n.signal},u))}));function U(t,n,r){if(e(t))return H(t,n,r);let i=n;return e=>H(e,t,i)}const W=(e,r,i)=>d(`timeout`,e,async e=>{let a=o(e),c=n(()=>a.ctx.abort(new DOMException(`Timed out after ${r}ms`,`TimeoutError`)),r);try{return await u(Promise.resolve(s(a.ctx,`run`,()=>i(a.ctx))),a.ctx)}finally{t(c),a.unlink()}});function G(e,t,n){if(typeof e==`number`){let n=t,r=(t,r)=>W(t,e,m(n,r));return(e,t)=>N(e,t,r)}return W(e,t,n)}export{x as all,w as allSettled,D as backoff,O as cancellable,r as delay,A as effectsPlugin,a as onAbort,F as poll,I as race,V as retry,U as take,G as timeout};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
const e=e=>e.type??e,t=(e,t)=>typeof e==`object`?e.payload:t;export{t as n,e as t};
|
package/dist/index.d.ts
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import { A as
|
|
2
|
-
export { type Action, type Actions, type AnyEvent, type Bus, type BusOptions, type Call, type
|
|
1
|
+
import { A as HandledCall, C as Emit, D as EventPayload, E as EventLike, F as WithContext, G as PayloadOf, H as EventMap, I as WithSignal, L as WithType, M as HandlerRef, N as Off, O as EventsOf, P as On, R as createBus, S as ContextOption, T as EventKey, U as Keys, Z as UnsubscribeCallback, _ as AnyEvent, b as Context, g as Actions, h as Action, j as Handler, k as Handled, n as Call, o as WithPayload, q as Task, v as Bus, w as Emittable, x as ContextOf, y as BusOptions } from "./action-creator-jeEqIKgK.js";
|
|
2
|
+
export { type Action, type Actions, type AnyEvent, type Bus, type BusOptions, type Call, type Context, type ContextOf, type ContextOption, type Emit, type Emittable, type EventKey, type EventLike, type EventMap, type EventPayload, type EventsOf, type Handled, type HandledCall, type Handler, type HandlerRef, type Keys, type Off, type On, type PayloadOf, type Task, type UnsubscribeCallback, type WithContext, type WithPayload, type WithSignal, type WithType, createBus };
|
package/dist/index.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
export{
|
|
1
|
+
export{t as createBus}from"./bus-0uYn_kRj.js";
|