nanoeffects 0.3.0 → 0.5.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 +53 -55
- package/dist/{action-Bdfp-Wvd.d.ts → action-creator-DOWcbXpy.d.ts} +79 -73
- package/dist/actions.d.ts +75 -6
- package/dist/actions.js +1 -1
- package/dist/bus-BAs9x7IQ.js +1 -0
- package/dist/{context-DlA80GOA.js → context-CK0ZomWt.js} +1 -1
- package/dist/context-plugin-B0sLWOxR.d.ts +34 -0
- package/dist/dev.d.ts +2 -2
- package/dist/effects.d.ts +153 -56
- package/dist/effects.js +1 -1
- package/dist/index.d.ts +3 -2
- package/dist/index.js +1 -1
- package/dist/{module-I1ixyJzx.d.ts → module-DCJl-qfi.d.ts} +24 -9
- package/dist/notrace/{action-Bdfp-Wvd.d.ts → action-creator-DOWcbXpy.d.ts} +79 -73
- package/dist/notrace/actions.d.ts +97 -13
- package/dist/notrace/actions.js +1 -1
- package/dist/notrace/bus-Bdk0YyFQ.js +1 -0
- package/dist/notrace/{context-yAWj0BFZ.js → context-CctVmHLC.js} +1 -1
- package/dist/notrace/context-plugin-B0sLWOxR.d.ts +34 -0
- package/dist/notrace/{delay-Cgvn16oY.js → delay-B_W1tnkS.js} +1 -1
- package/dist/notrace/effects.d.ts +153 -56
- package/dist/notrace/effects.js +1 -1
- package/dist/notrace/index.d.ts +3 -2
- package/dist/notrace/index.js +1 -1
- package/dist/notrace/policies.d.ts +1 -1
- package/dist/notrace/policies.js +1 -1
- package/dist/notrace/redux.d.ts +18 -20
- package/dist/notrace/redux.js +1 -1
- package/dist/observable.d.ts +1 -1
- package/dist/policies.d.ts +1 -1
- package/dist/policies.js +1 -1
- package/dist/react.d.ts +50 -0
- package/dist/react.js +1 -0
- package/dist/redux.d.ts +18 -20
- package/dist/redux.js +1 -1
- package/dist/trace.d.ts +1 -1
- package/docs/README.md +30 -9
- package/docs/actions.md +117 -41
- package/docs/context.md +48 -7
- package/docs/effects.md +229 -73
- package/docs/errors.md +23 -10
- package/docs/guide.md +238 -129
- package/docs/hmr.md +25 -13
- package/docs/migrating-from-effector.md +293 -0
- package/docs/migrating-from-rxjs.md +127 -0
- package/docs/migrating-from-saga.md +93 -0
- package/docs/observable.md +11 -9
- package/docs/package.md +24 -0
- package/docs/policies.md +93 -30
- package/docs/react.md +157 -0
- package/docs/semantics.md +5 -3
- package/docs/stores.md +488 -25
- package/docs/tracing.md +69 -54
- package/docs/typescript.md +153 -0
- package/llms-full.txt +2645 -0
- package/llms.txt +48 -0
- package/package.json +39 -9
- package/dist/bus-CRnlwmQ4.js +0 -1
- package/dist/notrace/bus-Dx0l9X6h.js +0 -1
- package/dist/notrace/event-0RIBGYqS.js +0 -1
|
@@ -1,4 +1,38 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { D as EventKey, 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-DOWcbXpy.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
|
* ```
|
|
@@ -83,6 +118,41 @@ export declare const commandsPlugin: <E extends EventMap>(bindings?: readonly Bi
|
|
|
83
118
|
};
|
|
84
119
|
};
|
|
85
120
|
//#endregion
|
|
121
|
+
//#region src/actions/emitter.d.ts
|
|
122
|
+
/** What `emitterPlugin` adds to the bus. */
|
|
123
|
+
type EmitterApi<E extends EventMap> = {
|
|
124
|
+
/**
|
|
125
|
+
* Turns an action creator into a function that emits its action on this
|
|
126
|
+
* bus, to pass as a callback. The function takes what the creator takes.
|
|
127
|
+
*/
|
|
128
|
+
emitter: {
|
|
129
|
+
/** A creator without a payload type: the payload comes from the event map. */
|
|
130
|
+
<K extends EventKey<E>>(creator: FreeActionCreator<K>): (...payload: PayloadOf<E[K]>) => void;
|
|
131
|
+
<P, T extends string, A extends unknown[]>(creator: ActionCreator<P, T, A>): (...args: A) => void;
|
|
132
|
+
};
|
|
133
|
+
};
|
|
134
|
+
/**
|
|
135
|
+
* Adds `bus.emitter(creator)`: a function that emits the action of `creator`
|
|
136
|
+
* on this bus. Use it where something wants a callback, such as the
|
|
137
|
+
* subscription of a state manager, instead of `(value) => bus.emit(creator(value))`.
|
|
138
|
+
* The creator stays a plain `createAction`, so `bus.emit(creator(value))` and
|
|
139
|
+
* `bus.on(creator, …)` work as before. Returns the same bus.
|
|
140
|
+
*
|
|
141
|
+
* @example
|
|
142
|
+
* ```ts
|
|
143
|
+
* import { createBus } from "nanoeffects";
|
|
144
|
+
* import { createAction, emitterPlugin } from "nanoeffects/actions";
|
|
145
|
+
*
|
|
146
|
+
* const bus = createBus().use(emitterPlugin());
|
|
147
|
+
* const nameChanged = createAction<string>("name/changed");
|
|
148
|
+
* const emitNameChanged = bus.emitter(nameChanged);
|
|
149
|
+
*
|
|
150
|
+
* // nanostores: the store calls it with the new value
|
|
151
|
+
* $name.listen(emitNameChanged);
|
|
152
|
+
* ```
|
|
153
|
+
*/
|
|
154
|
+
export declare const emitterPlugin: () => <E extends EventMap>(bus: Bus<E>) => Bus<E> & EmitterApi<E>;
|
|
155
|
+
//#endregion
|
|
86
156
|
//#region src/actions/job.d.ts
|
|
87
157
|
type Creator = {
|
|
88
158
|
(...args: never[]): {
|
|
@@ -112,13 +182,13 @@ type Job<P, R, T extends string, S extends Outcome, F extends Outcome> = MadeCom
|
|
|
112
182
|
* is used and returned as it is. A missing one is made with the type
|
|
113
183
|
* `<type>/success` or `<type>/fail`.
|
|
114
184
|
*
|
|
115
|
-
* `bus.emit(
|
|
185
|
+
* `bus.emit(job(payload))` returns a promise of the result. An error of the
|
|
116
186
|
* handler always counts as handled: it goes to `job.fail` and the promise
|
|
117
187
|
* resolves with `undefined`; a command is the tool for a result that must reject.
|
|
118
188
|
* The actions are emitted as the task that ran the job, also for a handler bound
|
|
119
189
|
* with `commands.handle`, and are skipped once the task is aborted. A missing
|
|
120
190
|
* handler is not an outcome: `emit` throws `MissingHandlerError`. Calling the
|
|
121
|
-
* command
|
|
191
|
+
* job builds `{ type, payload }` like a command; it does not run the handler.
|
|
122
192
|
*
|
|
123
193
|
* @example
|
|
124
194
|
* ```ts
|
|
@@ -128,7 +198,7 @@ type Job<P, R, T extends string, S extends Outcome, F extends Outcome> = MadeCom
|
|
|
128
198
|
* });
|
|
129
199
|
*
|
|
130
200
|
* bus.on(loadUser.success, (user) => render(user));
|
|
131
|
-
* bus.emit(loadUser
|
|
201
|
+
* bus.emit(loadUser("1")); // loadUser.success(user) or loadUser.fail(error) comes later
|
|
132
202
|
* ```
|
|
133
203
|
*/
|
|
134
204
|
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?: {
|
|
@@ -158,7 +228,10 @@ type ModuleContext<E extends EventMap = EventMap> = Context<E> & {
|
|
|
158
228
|
* returned function undoes just this call, e.g. for what was added later from
|
|
159
229
|
* a listener.
|
|
160
230
|
*/
|
|
161
|
-
use(...items: Array<Module<E> |
|
|
231
|
+
use(...items: Array<Module<E> | {
|
|
232
|
+
readonly type: string;
|
|
233
|
+
(payload: never): unknown;
|
|
234
|
+
}>): UnsubscribeCallback;
|
|
162
235
|
/**
|
|
163
236
|
* Starts a background task that lives as long as the module: it is aborted
|
|
164
237
|
* on unmount, and an error of it is left unhandled, as in any handler.
|
|
@@ -200,6 +273,12 @@ type ModuleApi<E extends EventMap = EventMap> = {
|
|
|
200
273
|
isMounted(module: Module<E>): boolean;
|
|
201
274
|
/** Unmounts every module; a disposed app cannot mount modules. */
|
|
202
275
|
dispose(): void;
|
|
276
|
+
/**
|
|
277
|
+
* `createModule` with the event map of this bus: the module sees the context
|
|
278
|
+
* fields of the bus without a type argument. It returns a plain module, not
|
|
279
|
+
* mounted, with no link to this bus.
|
|
280
|
+
*/
|
|
281
|
+
createModule(name: string, setup: (m: ModuleContext<E>) => void): Module<E>;
|
|
203
282
|
};
|
|
204
283
|
/**
|
|
205
284
|
* The plugin that assembles an app from modules: `bus.use(modulePlugin(modules))`
|
|
@@ -225,6 +304,11 @@ type ModuleApi<E extends EventMap = EventMap> = {
|
|
|
225
304
|
* const unmount = app.mount(orderModule); // later, e.g. after a lazy import
|
|
226
305
|
* unmount(); // or app.unmount(orderModule)
|
|
227
306
|
*
|
|
307
|
+
* // a module made from the app has the context fields of the bus, typed
|
|
308
|
+
* const userModule = app.createModule("user", (m) => {
|
|
309
|
+
* m.on("loaded", (user, { store }) => store.put(user));
|
|
310
|
+
* });
|
|
311
|
+
*
|
|
228
312
|
* bus.emit(getUser, "1");
|
|
229
313
|
* app.commands.handle(getUser, fakeUser); // in a test
|
|
230
314
|
* app.dispose();
|
|
@@ -232,4 +316,4 @@ type ModuleApi<E extends EventMap = EventMap> = {
|
|
|
232
316
|
*/
|
|
233
317
|
export declare const modulePlugin: <E extends EventMap>(modules?: readonly Module<E>[]) => (bus: Bus<E>) => ModuleApi<E>;
|
|
234
318
|
//#endregion
|
|
235
|
-
export {
|
|
319
|
+
export type { ActionCreator, Binding, EmitterApi, 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-
|
|
1
|
+
import{i as e,n as t,s as n}from"./context-CctVmHLC.js";import{a as r,r as i}from"./bus-Bdk0YyFQ.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=>{function t(t){return(...n)=>{let r=t(...n);e.emit(r)}}return Object.assign(e,{emitter:t})},d=e=>typeof e==`string`?a(e):e,f=(e,t,n)=>{let r=e.emit;r(Reflect.apply(t,null,[n]))},p=e=>{try{return Promise.resolve(e())}catch(e){if(e instanceof o)throw e;return Promise.reject(e)}},m=(e,t,n={})=>{let r=s(e,t),a=d(n.success??`${e}/success`),o=d(n.fail??`${e}/fail`),c=(e,t,n)=>{let r=n;return p(()=>Reflect.apply(e,null,[t,n])).then(e=>(f(r,a,e),e),e=>{f(r,o,e)})},l=e=>(t,n)=>c(e,t,n);function u(t,n){return typeof n==`object`?c(r,t,n):i(m,e,t)}let m=Object.assign(u,{type:e,match:r.match,wrap:l,success:a,fail:o});return m},h=(e,t)=>({name:e,setup:t}),g=(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(),createModule:h}};export{c as bindHandler,l as commandsPlugin,a as createAction,s as createCommand,m as createJob,h as createModule,u as emitterPlugin,g as modulePlugin};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{a as e,c as t,n,r}from"./context-CctVmHLC.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),ctx:s.context,trace:s.trace};return g};export{a,s as i,p as n,u as r,l as t};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
const e=(e,t)=>{globalThis.console?.error(`[nanoeffects] ${e}`,t)},t=()=>{},n=/* @__PURE__ */ new WeakMap,r=t=>{let r=n.get(t);if(r)return r;let i=/* @__PURE__ */ new Set;return n.set(t,i),t.addEventListener(`abort`,()=>{let n=[...i];i.clear();for(let{fn:r}of n)try{r(t.reason)}catch(t){e(`abort callback failed`,t)}},{once:!0}),i},i=(e,n)=>{let{signal:i}=e;if(!i)return t;if(i.aborted)return n(i.reason),t;let a=r(i),o={fn:n};return a.add(o),()=>{a.delete(o)}},a=e=>{let t=new AbortController;return{controller:t,unlink:i({signal:e},e=>t.abort(e))}};let o;const s=()=>o,c=()=>{},l=(e,t,n,r)=>{},u=(e,t)=>c,d=(e,t,n)=>n(),f=(e,t)=>typeof e==`function`?e(t):e,p=e=>e,m=({event:e,bus:t,tracer:n,parent:r})=>{let{controller:s,unlink:l}=a(r?.signal),{signal:u}=s,h=(...e)=>{if(u.aborted)return;let n=t?.emit,r=o;o=void 0;try{return n?.(...e)}finally{o=r}},g=(...e)=>{if(u.aborted)return c;let n=t?.on,r=n?.(...e);if(!r)return c;let a=i({signal:u},r);return()=>{a(),r()}},_=async(r,...i)=>{u.throwIfAborted();let a=i[0],o=m({event:{type:e.type,payload:a},bus:t,tracer:n,parent:{signal:u,ref:void 0}});try{return await d(o.ctx,`run`,()=>r(a,o.ctx))}finally{o.unlink()}}
|
|
1
|
+
const e=(e,t)=>{globalThis.console?.error(`[nanoeffects] ${e}`,t)},t=()=>{},n=/* @__PURE__ */ new WeakMap,r=t=>{let r=n.get(t);if(r)return r;let i=/* @__PURE__ */ new Set;return n.set(t,i),t.addEventListener(`abort`,()=>{let n=[...i];i.clear();for(let{fn:r}of n)try{r(t.reason)}catch(t){e(`abort callback failed`,t)}},{once:!0}),i},i=(e,n)=>{let{signal:i}=e;if(!i)return t;if(i.aborted)return n(i.reason),t;let a=r(i),o={fn:n};return a.add(o),()=>{a.delete(o)}},a=e=>{let t=new AbortController;return{controller:t,unlink:i({signal:e},e=>t.abort(e))}};let o;const s=()=>o,c=()=>{},l=(e,t,n,r)=>{},u=(e,t)=>c,d=(e,t,n)=>n(),f=(e,t)=>typeof e==`function`?e(t):e,p=e=>e,m=({event:e,bus:t,tracer:n,parent:r})=>{let{controller:s,unlink:l}=a(r?.signal),{signal:u}=s,h=(...e)=>{if(u.aborted)return;let n=t?.emit,r=o;o=void 0;try{return n?.(...e)}finally{o=r}},g=(...e)=>{if(u.aborted)return c;let n=t?.on,r=n?.(...e);if(!r)return c;let a=i({signal:u},r);return()=>{a(),r()}},_=async(r,...i)=>{u.throwIfAborted();let a=i[0],o=m({event:{type:e.type,payload:a},bus:t,tracer:n,parent:{signal:u,ref:void 0}});try{return await d(o.ctx,`run`,()=>r(a,o.ctx))}finally{o.unlink()}},v=p({...f(t?.ctx,e),type:e.type,payload:e.payload,signal:u,abort:e=>s.abort(e),emit:h,on:g,off:t?.off??c,run:_});return t?.addContext?.(v),{ctx:v,unlink:l}},h=(e,t)=>m({event:{type:t??e.type??``,payload:e.payload},bus:{emit:e.emit,on:e.on,off:e.off,ctx:e},tracer:void 0,parent:{signal:e.signal,ref:void 0}});export{d as a,e as c,h as i,m as n,l as o,s as r,i as s,u as t};
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
import { C as ContextOf, F as WithContext, _ as Bus, o as EventMap } from "./action-creator-DOWcbXpy.js";
|
|
2
|
+
//#region src/core/context-plugin.d.ts
|
|
3
|
+
/** What a function that makes the fields of a task gets to see. */
|
|
4
|
+
type ContextTask = {
|
|
5
|
+
type: string;
|
|
6
|
+
payload?: unknown;
|
|
7
|
+
};
|
|
8
|
+
/**
|
|
9
|
+
* `unknown` when none of the `fields` is already a context field of the bus,
|
|
10
|
+
* else `never`: the call does not compile. Used as `bus: Bus<E> & NoClash<…>`.
|
|
11
|
+
*/
|
|
12
|
+
type NoClash<Fields extends object, E extends EventMap> = [keyof Fields & keyof ContextOf<E>] extends [never] ? unknown : never;
|
|
13
|
+
/**
|
|
14
|
+
* Puts `fields` on the context of every task of the bus: a store, a client, a
|
|
15
|
+
* logger. The types come from the value, so the event map needs no
|
|
16
|
+
* `WithContext`. Returns the same bus, typed with the fields. A function gets
|
|
17
|
+
* `{ type, payload }` of the task and returns its fields.
|
|
18
|
+
*
|
|
19
|
+
* Several uses merge with each other, with the `context` option of `createBus`
|
|
20
|
+
* and with `effectsPlugin`. A name that the bus already has is a type error. The
|
|
21
|
+
* fields of the library (`signal`, `emit`, `run`, …) win, and a field that the
|
|
22
|
+
* context already has is not replaced.
|
|
23
|
+
*
|
|
24
|
+
* @example
|
|
25
|
+
* ```ts
|
|
26
|
+
* type Events = { "user/loaded": User };
|
|
27
|
+
*
|
|
28
|
+
* const bus = createBus<Events>().use(contextPlugin({ store }));
|
|
29
|
+
* bus.on("user/loaded", (user, { store }) => store.put(user)); // ctx.store: Store
|
|
30
|
+
* ```
|
|
31
|
+
*/
|
|
32
|
+
declare const contextPlugin: <Fields extends object>(fields: Fields | ((task: ContextTask) => Fields)) => <E extends EventMap>(bus: Bus<E> & NoClash<Fields, E>) => Bus<E & WithContext<Fields>>;
|
|
33
|
+
//#endregion
|
|
34
|
+
export { NoClash as n, contextPlugin as r, ContextTask as t };
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{s as e}from"./context-
|
|
1
|
+
import{s as e}from"./context-CctVmHLC.js";const t=2**31-1,n=(e,n)=>{let r={id:null};if(n===1/0)return r;let i=n=>{r.id=setTimeout(()=>{n>t?i(n-t):(r.id=null,e())},Math.min(n,t))};return i(n>0?n:0),r},r=e=>{e.id!==null&&(clearTimeout(e.id),e.id=null)},i=(t,i)=>new Promise((a,o)=>{let s=n(()=>{c(),a()},typeof i==`function`?i():i),c=e(t,e=>{r(s),o(e)})});export{r as n,n as r,i as t};
|
|
@@ -1,4 +1,5 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { F as WithContext, S as Context, _ as Bus, o as EventMap, s as Keys, u as Task } from "./action-creator-DOWcbXpy.js";
|
|
2
|
+
import { n as NoClash } from "./context-plugin-B0sLWOxR.js";
|
|
2
3
|
//#region src/utils/delay.d.ts
|
|
3
4
|
/**
|
|
4
5
|
* Resolves after `ms`, or rejects early if `ctx.signal` aborts. `ms` can be a
|
|
@@ -85,6 +86,38 @@ export declare function allSettled<const T extends readonly Starter<unknown>[]>(
|
|
|
85
86
|
signal?: AbortSignal;
|
|
86
87
|
}, effects: T): Promise<{ -readonly [K in keyof T]: PromiseSettledResult<Awaited<ReturnType<T[K]>>>; }>;
|
|
87
88
|
//#endregion
|
|
89
|
+
//#region src/effects/backoff.d.ts
|
|
90
|
+
type BackoffOptions = {
|
|
91
|
+
/** Pause before the second attempt, in ms. Default 100. */
|
|
92
|
+
base?: number;
|
|
93
|
+
/** How many times each pause is longer than the one before. Default 2. */
|
|
94
|
+
factor?: number;
|
|
95
|
+
/** Longest pause, in ms. Default `Infinity`. */
|
|
96
|
+
max?: number;
|
|
97
|
+
/**
|
|
98
|
+
* Use a random pause from 0 up to the computed one ("full jitter"), so
|
|
99
|
+
* clients that failed together do not retry together. Default `false`.
|
|
100
|
+
*/
|
|
101
|
+
jitter?: boolean;
|
|
102
|
+
};
|
|
103
|
+
/**
|
|
104
|
+
* Builds the `delay` of `retry`: the pause grows as `base * factor ** (attempt - 1)`
|
|
105
|
+
* and never passes `max`. `retry` counts attempts from 1; `poll` counts calls from
|
|
106
|
+
* 0, so there the first pause is `base / factor`.
|
|
107
|
+
*
|
|
108
|
+
* @example
|
|
109
|
+
* ```ts
|
|
110
|
+
* bus.on(
|
|
111
|
+
* "load",
|
|
112
|
+
* retry(loadUser, {
|
|
113
|
+
* times: 5,
|
|
114
|
+
* delay: backoff({ base: 200, max: 5000, jitter: true }), // 200, 400, 800, ... up to 5 s, randomised
|
|
115
|
+
* }),
|
|
116
|
+
* );
|
|
117
|
+
* ```
|
|
118
|
+
*/
|
|
119
|
+
export declare const backoff: (options?: BackoffOptions) => (attempt: number) => number;
|
|
120
|
+
//#endregion
|
|
88
121
|
//#region src/effects/cancellable.d.ts
|
|
89
122
|
type CancellableHandle<T> = {
|
|
90
123
|
resolve: (value: T | PromiseLike<T>) => void;
|
|
@@ -118,6 +151,124 @@ export declare const cancellable: <T = void>(ctx: {
|
|
|
118
151
|
signal: AbortSignal;
|
|
119
152
|
}, executor: CancellableExecutor<T>) => Promise<T>;
|
|
120
153
|
//#endregion
|
|
154
|
+
//#region src/effects/race.d.ts
|
|
155
|
+
type RaceStarter<T> = Starter<T>;
|
|
156
|
+
/**
|
|
157
|
+
* Runs all starters; first to settle wins, losers are cancelled via `ctx.abort`.
|
|
158
|
+
* The result holds only the winner's value, under its key or index.
|
|
159
|
+
*
|
|
160
|
+
* @example
|
|
161
|
+
* ```ts
|
|
162
|
+
* bus.on("load", async (id, ctx) => {
|
|
163
|
+
* const result = await race(ctx, {
|
|
164
|
+
* data: ({ signal }) => fetchData(id, { signal }),
|
|
165
|
+
* timeout: ({ signal }) => delay({ signal }, 5000),
|
|
166
|
+
* });
|
|
167
|
+
*
|
|
168
|
+
* if ("timeout" in result) throw new Error("timed out");
|
|
169
|
+
* render(result.data);
|
|
170
|
+
* });
|
|
171
|
+
* ```
|
|
172
|
+
*/
|
|
173
|
+
export declare function race<T extends Record<string, RaceStarter<unknown>>>(ctx: {
|
|
174
|
+
signal?: AbortSignal;
|
|
175
|
+
}, effects: T): Promise<{ [K in keyof T]?: Awaited<ReturnType<T[K]>>; }>;
|
|
176
|
+
export declare function race<const T extends readonly RaceStarter<unknown>[]>(ctx: {
|
|
177
|
+
signal?: AbortSignal;
|
|
178
|
+
}, effects: T): Promise<{ -readonly [K in keyof T]?: Awaited<ReturnType<T[K]>>; }>;
|
|
179
|
+
//#endregion
|
|
180
|
+
//#region src/effects/take.d.ts
|
|
181
|
+
type TakeOptions<P> = {
|
|
182
|
+
/**
|
|
183
|
+
* Wait for the first payload this accepts; others are skipped. A type guard
|
|
184
|
+
* (`(payload): payload is T`) narrows the type of the result to `T`.
|
|
185
|
+
*/
|
|
186
|
+
predicate?: (payload: P) => boolean;
|
|
187
|
+
/** Stop waiting when this aborts, e.g. the signal of a `race` starter. */
|
|
188
|
+
signal?: AbortSignal | undefined;
|
|
189
|
+
};
|
|
190
|
+
/**
|
|
191
|
+
* Waits for the next `event` on the bus and resolves with its payload. It sees
|
|
192
|
+
* only events emitted after the call, takes only one, and unsubscribes when it
|
|
193
|
+
* is done. If `ctx` (or `options.signal`) aborts first, it unsubscribes and
|
|
194
|
+
* rejects with the abort reason.
|
|
195
|
+
*
|
|
196
|
+
* @example
|
|
197
|
+
* ```ts
|
|
198
|
+
* bus.on("login", async (user, ctx) => {
|
|
199
|
+
* const reason = await take(ctx, "logout");
|
|
200
|
+
* cleanup(user, reason);
|
|
201
|
+
* });
|
|
202
|
+
*
|
|
203
|
+
* // wait for a matching event, but not longer than 5 s
|
|
204
|
+
* const done = await timeout(ctx, 5000, ({ signal }) =>
|
|
205
|
+
* take(ctx, "saved", { signal, predicate: (id) => id === draftId }),
|
|
206
|
+
* );
|
|
207
|
+
*
|
|
208
|
+
* // a type guard narrows the result: `failed` is `{ ok: false }`
|
|
209
|
+
* const failed = await take(ctx, "result", {
|
|
210
|
+
* predicate: (result): result is { ok: false } => !result.ok,
|
|
211
|
+
* });
|
|
212
|
+
* ```
|
|
213
|
+
*/
|
|
214
|
+
export declare function take<E extends EventMap, K extends Keys<E>, T extends E[K]>(ctx: Context<E>, event: K, options: TakeOptions<E[K]> & {
|
|
215
|
+
predicate: (payload: E[K]) => payload is T;
|
|
216
|
+
}): Promise<T>;
|
|
217
|
+
export declare function take<E extends EventMap, K extends Keys<E>>(ctx: Context<E>, event: K, options?: TakeOptions<E[K]>): Promise<E[K]>;
|
|
218
|
+
//#endregion
|
|
219
|
+
//#region src/effects/plugin.d.ts
|
|
220
|
+
/** The effects that `effectsPlugin` can put on `ctx`. */
|
|
221
|
+
type Supported = {
|
|
222
|
+
race: typeof race;
|
|
223
|
+
all: typeof all;
|
|
224
|
+
allSettled: typeof allSettled;
|
|
225
|
+
take: typeof take;
|
|
226
|
+
delay: typeof delay;
|
|
227
|
+
};
|
|
228
|
+
type Results = Record<string, Starter<unknown>>;
|
|
229
|
+
type List = readonly Starter<unknown>[];
|
|
230
|
+
/** Each supported effect without its leading `ctx` argument. `take` knows the events of the bus. */
|
|
231
|
+
type Bound<E extends EventMap> = {
|
|
232
|
+
race: {
|
|
233
|
+
<T extends Results>(effects: T): Promise<{ [K in keyof T]?: Awaited<ReturnType<T[K]>>; }>;
|
|
234
|
+
<const T extends List>(effects: T): Promise<{ -readonly [K in keyof T]?: Awaited<ReturnType<T[K]>>; }>;
|
|
235
|
+
};
|
|
236
|
+
all: {
|
|
237
|
+
<T extends Results>(effects: T): Promise<{ [K in keyof T]: Awaited<ReturnType<T[K]>>; }>;
|
|
238
|
+
<const T extends List>(effects: T): Promise<{ -readonly [K in keyof T]: Awaited<ReturnType<T[K]>>; }>;
|
|
239
|
+
};
|
|
240
|
+
allSettled: {
|
|
241
|
+
<T extends Results>(effects: T): Promise<{ [K in keyof T]: PromiseSettledResult<Awaited<ReturnType<T[K]>>>; }>;
|
|
242
|
+
<const T extends List>(effects: T): Promise<{ -readonly [K in keyof T]: PromiseSettledResult<Awaited<ReturnType<T[K]>>>; }>;
|
|
243
|
+
};
|
|
244
|
+
take: <K extends Keys<E>>(event: K, options?: TakeOptions<E[K]>) => Promise<E[K]>;
|
|
245
|
+
delay: (ms: number | (() => number)) => Promise<void>;
|
|
246
|
+
};
|
|
247
|
+
type Helpers = Partial<Supported>;
|
|
248
|
+
type BoundOf<H extends Helpers, E extends EventMap> = { [K in keyof H & keyof Bound<E>]: Bound<E>[K]; };
|
|
249
|
+
/**
|
|
250
|
+
* Puts the effects you pass on the context of every task of the bus, bound to
|
|
251
|
+
* that task, so a handler can write `({ race })` instead of `race(ctx, …)`.
|
|
252
|
+
* The key is the name of the effect: `race`, `all`, `allSettled`, `take`,
|
|
253
|
+
* `delay`. Returns the same bus, typed with the new fields.
|
|
254
|
+
*
|
|
255
|
+
* @example
|
|
256
|
+
* ```ts
|
|
257
|
+
* import { createBus } from "nanoeffects";
|
|
258
|
+
* import { all, delay, effectsPlugin, race } from "nanoeffects/effects";
|
|
259
|
+
*
|
|
260
|
+
* const bus = createBus().use(effectsPlugin({ race, delay }));
|
|
261
|
+
*
|
|
262
|
+
* bus.on("load", async (id, { race, delay }) => {
|
|
263
|
+
* const result = await race({
|
|
264
|
+
* data: ({ signal }) => fetchData(id, { signal }),
|
|
265
|
+
* timeout: () => delay(5000),
|
|
266
|
+
* });
|
|
267
|
+
* });
|
|
268
|
+
* ```
|
|
269
|
+
*/
|
|
270
|
+
export declare const effectsPlugin: <H extends Helpers>(helpers: H) => <E extends EventMap>(bus: Bus<E> & NoClash<BoundOf<H, E>, E>) => Bus<E & WithContext<BoundOf<H, E>>>;
|
|
271
|
+
//#endregion
|
|
121
272
|
//#region src/effects/poll.d.ts
|
|
122
273
|
type PollOptions = {
|
|
123
274
|
/** Also call `fn` at once, not only after the first `ms`. Default `false`. */
|
|
@@ -160,32 +311,6 @@ export declare function poll(ctx: {
|
|
|
160
311
|
signal: AbortSignal;
|
|
161
312
|
}, fn: (tick: number) => unknown, ms: PollMs, options?: PollOptions): Promise<void>;
|
|
162
313
|
//#endregion
|
|
163
|
-
//#region src/effects/race.d.ts
|
|
164
|
-
type RaceStarter<T> = Starter<T>;
|
|
165
|
-
/**
|
|
166
|
-
* Runs all starters; first to settle wins, losers are cancelled via `ctx.abort`.
|
|
167
|
-
* The result holds only the winner's value, under its key or index.
|
|
168
|
-
*
|
|
169
|
-
* @example
|
|
170
|
-
* ```ts
|
|
171
|
-
* bus.on("load", async (id, ctx) => {
|
|
172
|
-
* const result = await race(ctx, {
|
|
173
|
-
* data: ({ signal }) => fetchData(id, { signal }),
|
|
174
|
-
* timeout: ({ signal }) => delay({ signal }, 5000),
|
|
175
|
-
* });
|
|
176
|
-
*
|
|
177
|
-
* if ("timeout" in result) throw new Error("timed out");
|
|
178
|
-
* render(result.data);
|
|
179
|
-
* });
|
|
180
|
-
* ```
|
|
181
|
-
*/
|
|
182
|
-
export declare function race<T extends Record<string, RaceStarter<unknown>>>(ctx: {
|
|
183
|
-
signal?: AbortSignal;
|
|
184
|
-
}, effects: T): Promise<{ [K in keyof T]?: Awaited<ReturnType<T[K]>>; }>;
|
|
185
|
-
export declare function race<const T extends readonly RaceStarter<unknown>[]>(ctx: {
|
|
186
|
-
signal?: AbortSignal;
|
|
187
|
-
}, effects: T): Promise<{ -readonly [K in keyof T]?: Awaited<ReturnType<T[K]>>; }>;
|
|
188
|
-
//#endregion
|
|
189
314
|
//#region src/effects/retry.d.ts
|
|
190
315
|
type RetryOptions = {
|
|
191
316
|
/** Total number of attempts, the first one included. Default 3. */
|
|
@@ -226,34 +351,6 @@ export declare function retry<T>(ctx: {
|
|
|
226
351
|
signal?: AbortSignal;
|
|
227
352
|
}, fn: RetryFn<T>, options?: RetryOptions): Promise<T>;
|
|
228
353
|
//#endregion
|
|
229
|
-
//#region src/effects/take.d.ts
|
|
230
|
-
type TakeOptions<P> = {
|
|
231
|
-
/** Wait for the first payload this accepts; others are skipped. */
|
|
232
|
-
predicate?: (payload: P) => boolean;
|
|
233
|
-
/** Stop waiting when this aborts, e.g. the signal of a `race` starter. */
|
|
234
|
-
signal?: AbortSignal | undefined;
|
|
235
|
-
};
|
|
236
|
-
/**
|
|
237
|
-
* Waits for the next `event` on the bus and resolves with its payload. It sees
|
|
238
|
-
* only events emitted after the call, takes only one, and unsubscribes when it
|
|
239
|
-
* is done. If `ctx` (or `options.signal`) aborts first, it unsubscribes and
|
|
240
|
-
* rejects with the abort reason.
|
|
241
|
-
*
|
|
242
|
-
* @example
|
|
243
|
-
* ```ts
|
|
244
|
-
* bus.on("login", async (user, ctx) => {
|
|
245
|
-
* const reason = await take(ctx, "logout");
|
|
246
|
-
* cleanup(user, reason);
|
|
247
|
-
* });
|
|
248
|
-
*
|
|
249
|
-
* // wait for a matching event, but not longer than 5 s
|
|
250
|
-
* const done = await timeout(ctx, 5000, ({ signal }) =>
|
|
251
|
-
* take(ctx, "saved", { signal, predicate: (id) => id === draftId }),
|
|
252
|
-
* );
|
|
253
|
-
* ```
|
|
254
|
-
*/
|
|
255
|
-
export declare const take: <E extends EventMap, K extends Keys<E>>(ctx: Context<E>, event: K, options?: TakeOptions<E[K]>) => Promise<E[K]>;
|
|
256
|
-
//#endregion
|
|
257
354
|
//#region src/effects/timeout.d.ts
|
|
258
355
|
/**
|
|
259
356
|
* Runs a function; if it takes longer than `ms`, aborts its signal and rejects
|
|
@@ -281,4 +378,4 @@ export declare function timeout<T>(ctx: {
|
|
|
281
378
|
signal?: AbortSignal;
|
|
282
379
|
}, ms: number, starter: Starter<T>): Promise<T>;
|
|
283
380
|
//#endregion
|
|
284
|
-
export type { CancellableExecutor, CancellableHandle, EffectContext, PollOptions, RaceStarter, RetryOptions, TakeOptions };
|
|
381
|
+
export type { BackoffOptions, CancellableExecutor, CancellableHandle, EffectContext, PollOptions, RaceStarter, RetryOptions, TakeOptions };
|
package/dist/notrace/effects.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
import{a as e,c as t,i as n,o as r,s as i,t as a}from"./context-
|
|
1
|
+
import{a as e,c as t,i as n,o as r,s as i,t as a}from"./context-CctVmHLC.js";import{n as o,r as s,t as c}from"./delay-B_W1tnkS.js";const l=(e,t)=>t?.signal?new Promise((n,r)=>{let a=i(t,r);e.then(n,r).finally(a)}):e,u=async(e,t,o,s)=>{t?.signal?.throwIfAborted();let{ctx:c,unlink:u}=n(t??{}),d=a(c,e);r(c,e,`start`),i(c,()=>d(`cancel`));try{let e=await l(o(c),t);return d(`done`),s?.(!1),e}catch(e){throw d(`error`,e),s?.(!0),e}finally{u()}},d=async(t,r)=>{let{ctx:i,unlink:a}=n(t);try{return await e(i,`run`,()=>r(i))}finally{a()}},f=e=>e,p=(e,t)=>n=>e(t,f(n)),m=e=>Array.isArray(e)?Array(e.length):{},h=(t,r)=>{let i=Object.entries(r).map(([r,i])=>{let a=n(t),o={signal:a.ctx.signal,abort:a.ctx.abort},s=()=>i(o);return{key:r,task:new Promise(t=>t(e(a.ctx,`run`,s))).finally(a.unlink),cancel:a.ctx.abort}});return{tasks:i.map(({key:e,task:t})=>[e,t]),cancelAll:()=>{for(let e of i)e.cancel()}}},g=(e,t,n,r,i)=>{let a=()=>{};return u(e,t,async e=>{let t=h(e,n);return a=t.cancelAll,r(t.tasks)},e=>{(e||i===`end`)&&a()})};function _(e,t){return g(`all`,e,t,async e=>{let n=await Promise.all(e.map(([,e])=>e)),r=m(t);for(let[t,[i]]of e.entries())r[i]=n[t];return r},`failure`)}const v=e=>e.then(e=>({status:`fulfilled`,value:e}),e=>({status:`rejected`,reason:e}));function y(e,t){return g(`allSettled`,e,t,async e=>{let n=await Promise.all(e.map(([,e])=>v(e))),r=m(t);for(let[t,[i]]of e.entries())r[i]=n[t];return r},`failure`)}const b=e=>e>0?e:0,x=(e={})=>{let t=b(e.base??100),n=e.factor??2,r=b(e.max??1/0),i=e.jitter??!1;return e=>{let a=b(Math.min(r,t*n**(e-1)));return i?Math.random()*a||0:a}},S=(e,n)=>e.signal.aborted?Promise.reject(e.signal.reason):new Promise((r,a)=>{let o=[],s=`pending`,c=e=>{try{e()}catch(e){t(`cancel cleanup failed`,e)}},l=i(e,e=>{s=`cancelled`;for(let e of o.reverse())c(e);a(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{n({resolve:u(r),reject:u(a),onCancel:d})}catch(e){u(a)(e)}}),C=e=>t=>{let n=t.addContext,r=Object.entries(e);return t.addContext=e=>{n?.(e);for(let[t,n]of r)Object.assign(e,{[t]:(...t)=>n(e,...t)})},t},w=(e,t,n,r)=>{if(e.signal.aborted)return Promise.resolve();let a=r.leading??!1,c=r.waitForFn??!1;return u(`poll`,e,e=>new Promise((r,l)=>{let u=0,f=null,p=()=>{f!==null&&(o(f),f=null)},m=e=>{try{f=s(h,typeof n==`function`?n(e):n)}catch(e){p(),l(e)}},h=()=>{f=null,c||m(u+1),g()},g=()=>{let n=u++;d(e,e=>t(e,n)).then(()=>{c&&!e.signal.aborted&&m(u)},e=>{p(),l(e)})};i(e,p),a?(g(),c||m(u)):m(0)})).catch(t=>{if(!e.signal.aborted)throw t})};function T(e,t,n,r={}){if(typeof e!=`object`){let r=t,i=n??{};return(t,n)=>w(n,p(r,t),e,i)}let i=t;return w(e,(e,t)=>i(t),n,r)}function E(e,t){let n=m(t);return Object.keys(t).length===0?Promise.resolve(n):g(`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`)}const D=(e,t,n)=>typeof e==`function`?e(t,n):e,O=e=>({times:e.times??3,delay:e.delay??0,shouldRetry:e.shouldRetry??(()=>!0)}),k=(e,t,n)=>u(`retry`,e,async e=>{let{times:r,delay:i,shouldRetry:a}=O(n);for(let n=1;;n++)try{return await d(e,e=>t(e,n))}catch(t){if(e.signal.throwIfAborted(),!(n<r)||!a(t,n))throw t;let o=D(i,n,t);o>0&&await c(e,o)}});function A(e,t,n={}){if(typeof e==`function`){let n=e;return(e,r)=>k(r,p(n,e),t??{})}let r=t;return k(e,(e,t)=>r(t),n)}function j(e,t,n={}){return u(`take`,e,r=>new Promise((a,o)=>{let{predicate:s}=n,c=[],l=()=>{for(let e of c)e()},u=e=>{l(),o(e)};c.push(e.on(t,e=>{(!s||s(e))&&(l(),a(e))})),c.push(i(r,u)),c.push(i({signal:n.signal},u))}))}const M=(t,r,i)=>u(`timeout`,t,async t=>{let a=n(t),c=s(()=>a.ctx.abort(new DOMException(`Timed out after ${r}ms`,`TimeoutError`)),r);try{return await l(Promise.resolve(e(a.ctx,`run`,()=>i(a.ctx))),a.ctx)}finally{o(c),a.unlink()}});function N(e,t,n){if(typeof e==`number`){let n=t;return(t,r)=>M(r,e,p(n,t))}let r=t,i=n;return M(e,r,e=>i({signal:e.signal,abort:e.abort}))}export{_ as all,y as allSettled,x as backoff,S as cancellable,c as delay,C as effectsPlugin,i as onAbort,T as poll,E as race,A as retry,j as take,N as timeout};
|
package/dist/notrace/index.d.ts
CHANGED
|
@@ -1,2 +1,3 @@
|
|
|
1
|
-
import { A as
|
|
2
|
-
|
|
1
|
+
import { A as EventsOf, B as anyEventType, C as ContextOf, D as EventKey, E as Emittable, F as WithContext, I as WithType, L as commandCall, M as HandlerRef, N as Off, O as EventLike, P as On, R as createBus, 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 Handler, 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 Tracer } from "./action-creator-DOWcbXpy.js";
|
|
2
|
+
import { n as NoClash, r as contextPlugin, t as ContextTask } from "./context-plugin-B0sLWOxR.js";
|
|
3
|
+
export { type Action, type AnyEvent, type Bus, type BusOptions, type Command, type CommandCall, type Commands, type Context, type ContextOf, type ContextOption, type ContextTask, type EffectName, type Emit, type Emittable, type EventKey, type EventLike, type EventMap, type EventPayload, type EventsOf, type Handler, type HandlerRef, type Keys, type NoClash, type Off, type On, type PayloadOf, type Phase, type Task, type Trace, type TraceEvent, type TraceLogger, type Tracer, type UnsubscribeCallback, type WithContext, type WithPayload, type WithType, anyEventType, commandCall, contextPlugin, createBus };
|
package/dist/notrace/index.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
|
|
1
|
+
import{i as e,n as t,t as n}from"./bus-Bdk0YyFQ.js";const r=e=>typeof e==`function`,i=e=>({type:Reflect.get(e,`type`),payload:Reflect.get(e,`payload`)}),a=e=>t=>{let n=t.addContext;return t.addContext=t=>{n?.(t);let a=r(e)?e(i(t)):e;for(let[e,n]of Object.entries(a))e in t||Reflect.set(t,e,n)},t};export{e as anyEventType,n as commandCall,a as contextPlugin,t as createBus};
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { o as EventMap, u as Task } from "./action-creator-DOWcbXpy.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/policies.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
import{a as e,i as t,o as n,s as r,t as i}from"./context-
|
|
1
|
+
import{a as e,i as t,o as n,s as r,t as i}from"./context-CctVmHLC.js";import{n as a,r as o,t as s}from"./delay-B_W1tnkS.js";import{n as c,t as l}from"./promise-CSLpzwSR.js";const u=()=>{},d=(e,t)=>{let n=/* @__PURE__ */ new Map;return(r,i)=>{let a=e(r),o=n.get(a);if(!o){let e=t(()=>{n.get(a)===e&&n.delete(a)});o=e,n.set(a,e)}return o(r,i)}},f=(e,t)=>e?d(e,t):t(u),p=(e,t={})=>f(t.key,t=>m(`latest`,(t,n,r)=>(r(),e(t,n)),t)),m=(e,a,o=u)=>{let s=null;return(l,u)=>{if(s?.abort(),u.signal.aborted)return;let{ctx:d,unlink:f}=t(u);s=d;let p=i(d,e),m=!1,h=()=>{d.signal.aborted||(m=!0,n(d,e,`start`))};r(d,()=>p(m?`cancel`:`drop`));let g=()=>{f(),s===d&&(s=null,o())},_=e=>{if(!d.signal.aborted)return p(m?`done`:`drop`),e};try{let e=a(l,d,h);return c(e)?Promise.resolve(e).then(_,e=>{if(!d.signal.aborted)throw p(`error`,e),e}).finally(g):(g(),_(e))}catch(e){if(g(),d.signal.aborted)return;throw p(`error`,e),e}}},h=(e,t,n={})=>f(n.key,r=>_(e,t,n,r)),g=(t,r,i,s)=>{let c=s!==u,l=null,d=null;return(u,f)=>{if(f.signal.aborted)return;let p=Date.now(),m=l===null||p-l>=t||p-l<0;return l=p,d!==null&&a(d),d=c?o(s,t):null,i&&m?Promise.resolve(e(f,`debounce`,()=>r(u,f))):(n(f,`debounce`,`drop`),Promise.resolve(void 0))}},_=(t,n,i,a)=>{let o=i.leading??!1,c=i.trailing??!0;if(!c)return g(t,n,o,a);let l=!1,u=0,d=m(`debounce`,([e,i],a,o)=>{let d=u;return r(a,()=>{u===d&&(l=!1)}),s(a,t).then(()=>{if(l=!1,c&&!i)return o(),n(e,a)})},a);return(t,r)=>{if(r.signal.aborted)return;let i=o&&!l;l=!0,u++;let a=d([t,i],r);return i?Promise.resolve(e(r,`debounce`,()=>n(t,r))):a}},v=(t,i={})=>f(i.key,i=>{let a=null;return(o,s)=>{if(s.signal.aborted)return;if(a){n(s,`leading`,`drop`);return}let c={};a=c;let u=()=>{d(),a===c&&(a=null,i())},d=r(s,u);try{return l(e(s,`leading`,()=>t(o,s)),u)}catch(e){throw u(),e}}}),y=(e,t={})=>f(t.key,n=>b(e,t,n)),b=(t,i,a)=>{let o=i.concurrency??1,s=i.limit??1/0,c=[],l=0,d=()=>{for(;l<o;){let e=c.shift();if(!e)return;e.start()}};return(f,p)=>new Promise((m,h)=>{if(p.signal.aborted){m(void 0);return}let g=u,_=()=>{g(),n(p,`queue`,`drop`),m(void 0)},v=()=>{if(g(),p.signal.aborted){_();return}l++;let n=!0,i=()=>{n&&(n=!1,l--,d(),l===0&&c.length===0&&a())},o=r(p,()=>{i(),m(void 0)}),s;try{s=Promise.resolve(e(p,`queue`,()=>t(f,p)))}catch(e){s=Promise.reject(e)}let u=()=>{o(),i()};s.then(e=>{u(),m(p.signal.aborted?void 0:e)},e=>{u(),p.signal.aborted?m(void 0):h(e)})};if(l<o){v();return}if(c.length>=s){if(i.overflow!==`drop-old`||s<=0){_();return}c.shift()?.drop()}let y={start:v,drop:_};c.push(y),g=r(p,()=>{let e=c.indexOf(y);e>=0&&c.splice(e,1),_()})})},x=(e,t,n={})=>f(n.key,r=>S(e,t,n,r)),S=(t,r,i,s)=>{let c=i.leading??!0,l=i.trailing??!0,d=s!==u,f=null,p=0,m=null,h=null,g=null,_=!1,v=e=>f===null||e-f>=t||e-f<0||e-p>=t,y=e=>n(e,`throttle`,`drop`),b=()=>{let e=g;g=null,e&&(y(e.ctx),e.resolve())},x=(e,t)=>(b(),new Promise((n,r)=>{g={payload:e,ctx:t,resolve:n,reject:r}})),S=(t,n,i)=>{b(),p=i,_=!0;try{return e(n,`throttle`,()=>r(t,n))}finally{_=!1}},C=()=>{d&&(h=o(w,t))},w=()=>{if(h=null,!d||m!==null||g)return;let e=Date.now(),n=Math.max(t-(e-(f??-1/0)),t-(e-p));n<=0?s():h=o(w,n)},T=e=>{m=null;let t=g;if(l&&t&&!t.ctx.signal.aborted){g=null;try{t.resolve(S(t.payload,t.ctx,e))}catch(e){t.reject(e)}}else b();w()},E=()=>{let e=Date.now();v(e)?T(e):m=o(E,Math.min(t-(e-(f??e)),t-(e-p)))},D=()=>{h!==null&&(a(h),h=null)},O=(e,t)=>{if(!l)y(t);else return x(e,t)},k=(e,t,n,r)=>{if(!r)y(t);else if(p=n,C(),!c)y(t);else return S(e,t,n)},A=(e,n,r,i)=>i&&m!==null?(a(m),m=o(E,t),S(e,n,r)):m===null&&(m=o(E,t),i&&(p=r,c))?S(e,n,r):O(e,n);return(e,t)=>{if(t.signal.aborted)return;let n=Date.now(),r=!_&&v(n);return f=n,D(),l?A(e,t,n,r):k(e,t,n,r)}};export{h as debounce,p as latest,v as leading,y as queue,x as throttle};
|