nanoeffects 0.1.0 → 0.2.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 +62 -61
- package/dist/{action-BM-UdmJr.d.ts → action-rqZEnRIp.d.ts} +12 -11
- package/dist/actions.d.ts +47 -185
- package/dist/actions.js +1 -1
- package/dist/bus-CRnlwmQ4.js +1 -0
- package/dist/context-DlA80GOA.js +1 -0
- package/dist/dev.d.ts +46 -0
- package/dist/dev.js +1 -0
- package/dist/effects.d.ts +61 -21
- package/dist/effects.js +1 -1
- package/dist/index.d.ts +1 -2
- package/dist/index.js +1 -1
- package/dist/module-BSCdR9D1.d.ts +167 -0
- package/dist/notrace/{action-BM-UdmJr.d.ts → action-rqZEnRIp.d.ts} +12 -11
- package/dist/notrace/actions.d.ts +71 -45
- package/dist/notrace/actions.js +1 -1
- package/dist/notrace/bus-Dx0l9X6h.js +1 -0
- package/dist/notrace/context-yAWj0BFZ.js +1 -0
- package/dist/notrace/{delay-Cko_Q9hl.js → delay-Cgvn16oY.js} +1 -1
- package/dist/notrace/effects.d.ts +61 -21
- package/dist/notrace/effects.js +1 -1
- package/dist/notrace/index.d.ts +1 -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 +1 -1
- package/dist/notrace/redux.js +1 -1
- package/dist/observable.d.ts +1 -1
- package/dist/policies.d.ts +1 -1
- package/dist/policies.js +1 -1
- package/dist/production/dev.js +1 -0
- package/dist/redux.d.ts +1 -1
- package/dist/redux.js +1 -1
- package/dist/trace.d.ts +22 -4
- package/dist/trace.js +1 -1
- package/docs/README.md +4 -1
- package/docs/actions.md +21 -11
- package/docs/context.md +0 -1
- package/docs/effects.md +49 -31
- package/docs/errors.md +4 -4
- package/docs/guide.md +229 -0
- package/docs/hmr.md +20 -58
- package/docs/policies.md +4 -4
- package/docs/tracing.md +21 -8
- package/package.json +25 -5
- package/dist/bus-RUiw8f9p.js +0 -1
- package/dist/context-BXQ6Einm.js +0 -1
- package/dist/index-CaxrMD1A.d.ts +0 -1
- package/dist/notrace/bus-CFxgpsRL.js +0 -1
- package/dist/notrace/context-DGPIFXxI.js +0 -1
- package/dist/notrace/index-CaxrMD1A.d.ts +0 -1
package/dist/effects.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { A as Keys, k as EventMap, u as Context } from "./action-
|
|
1
|
+
import { A as Keys, N as Task, k as EventMap, u as Context } from "./action-rqZEnRIp.js";
|
|
2
2
|
//#region src/utils/delay.d.ts
|
|
3
3
|
/**
|
|
4
4
|
* Resolves after `ms`, or rejects early if `ctx.signal` aborts. `ms` can be a
|
|
@@ -129,30 +129,36 @@ type PollOptions = {
|
|
|
129
129
|
waitForFn?: boolean;
|
|
130
130
|
};
|
|
131
131
|
/**
|
|
132
|
-
* Calls
|
|
133
|
-
* `ms` (with `leading` also at once), and the next ticks keep a steady
|
|
134
|
-
* whatever the duration of
|
|
135
|
-
* (`waitForFn` starts each pause when the call ends instead).
|
|
136
|
-
*
|
|
132
|
+
* Calls a function every `ms`, like patronum `interval`: the first call comes
|
|
133
|
+
* after `ms` (with `leading` also at once), and the next ticks keep a steady
|
|
134
|
+
* rate whatever the duration of the function, so a slow one may overlap with
|
|
135
|
+
* the next call (`waitForFn` starts each pause when the call ends instead). An
|
|
136
|
+
* error stops the polling and rejects; an abort of the caller ends it without
|
|
137
|
+
* an error and clears the timer. Two forms:
|
|
138
|
+
*
|
|
139
|
+
* - `poll(ms, task, options)` wraps a Task `(payload, ctx) => result` and
|
|
140
|
+
* returns a Task. Each call gets a context of its own, a child of the
|
|
141
|
+
* caller's: `bus.on("watch", poll(10_000, refresh))`.
|
|
142
|
+
* - `poll(ctx, fn, ms, options)` is for one call inside a body; `fn` gets the
|
|
143
|
+
* number of the call, starting at 0.
|
|
137
144
|
*
|
|
138
145
|
* `ms` can be a function of the number of the call that the pause leads to, for
|
|
139
146
|
* a growing or random pause: `(call) => Math.min(1000 * 2 ** call, 60_000)`.
|
|
140
147
|
*
|
|
141
|
-
* It stops when `ctx` aborts: the result then resolves, it does not reject, and
|
|
142
|
-
* the pending timer is cleared. If a call throws, polling stops and the result
|
|
143
|
-
* rejects.
|
|
144
|
-
*
|
|
145
148
|
* @example
|
|
146
149
|
* ```ts
|
|
150
|
+
* bus.on("watch", poll(10_000, (_, { signal }) => refresh({ signal })));
|
|
151
|
+
*
|
|
147
152
|
* bus.on("watch", async (_, ctx) => {
|
|
148
|
-
* await poll(ctx, () => refresh(),
|
|
149
|
-
* cleanup(); // the task was aborted
|
|
153
|
+
* await poll(ctx, () => refresh(), 10_000);
|
|
150
154
|
* });
|
|
151
155
|
* ```
|
|
152
156
|
*/
|
|
153
|
-
|
|
157
|
+
type PollMs = number | ((call: number) => number);
|
|
158
|
+
export declare function poll<P, E extends EventMap, R>(ms: PollMs, task: Task<P, E, R>, options?: PollOptions): Task<P, E, Promise<void>>;
|
|
159
|
+
export declare function poll(ctx: {
|
|
154
160
|
signal: AbortSignal;
|
|
155
|
-
}, fn: (tick: number) => unknown, ms:
|
|
161
|
+
}, fn: (tick: number) => unknown, ms: PollMs, options?: PollOptions): Promise<void>;
|
|
156
162
|
//#endregion
|
|
157
163
|
//#region src/effects/race.d.ts
|
|
158
164
|
type RaceStarter<T> = Starter<T>;
|
|
@@ -192,9 +198,33 @@ type RetryOptions = {
|
|
|
192
198
|
/** Return `false` to stop retrying and throw `error`. Default: always retry. */
|
|
193
199
|
shouldRetry?: (error: unknown, attempt: number) => boolean;
|
|
194
200
|
};
|
|
195
|
-
|
|
201
|
+
/**
|
|
202
|
+
* Calls a function until it succeeds or `times` attempts are used, then throws
|
|
203
|
+
* the last error. If the caller aborts, retrying stops and the result rejects
|
|
204
|
+
* with the abort reason. Two forms:
|
|
205
|
+
*
|
|
206
|
+
* - `retry(task, options)` wraps a Task `(payload, ctx) => result` and returns
|
|
207
|
+
* a Task. Each attempt gets a context of its own, a child of the caller's, so
|
|
208
|
+
* it can go straight into `on` and into `ctx.run`:
|
|
209
|
+
* `bus.on("load", latest(retry(load, { times: 4 })))`. The number of the
|
|
210
|
+
* attempt is not passed; use the other form when it is needed.
|
|
211
|
+
* - `retry(ctx, fn, options)` is for one call inside a body. `fn` gets the
|
|
212
|
+
* number of the attempt, starting at 1.
|
|
213
|
+
*
|
|
214
|
+
* @example
|
|
215
|
+
* ```ts
|
|
216
|
+
* bus.on("load", latest(retry(loadUser, { times: 4, delay: (attempt) => 2 ** attempt * 100 })));
|
|
217
|
+
*
|
|
218
|
+
* bus.on("load", async (id, ctx) => {
|
|
219
|
+
* const user = await retry(ctx, () => fetchUser(id, { signal: ctx.signal }), { times: 4 });
|
|
220
|
+
* });
|
|
221
|
+
* ```
|
|
222
|
+
*/
|
|
223
|
+
type RetryFn<T> = (attempt: number) => T | PromiseLike<T>;
|
|
224
|
+
export declare function retry<P, E extends EventMap, R>(task: Task<P, E, R>, options?: RetryOptions): Task<P, E, Promise<Awaited<R>>>;
|
|
225
|
+
export declare function retry<T>(ctx: {
|
|
196
226
|
signal?: AbortSignal;
|
|
197
|
-
}, fn:
|
|
227
|
+
}, fn: RetryFn<T>, options?: RetryOptions): Promise<T>;
|
|
198
228
|
//#endregion
|
|
199
229
|
//#region src/effects/take.d.ts
|
|
200
230
|
type TakeOptions<P> = {
|
|
@@ -226,19 +256,29 @@ export declare const take: <E extends EventMap, K extends Keys<E>>(ctx: Context<
|
|
|
226
256
|
//#endregion
|
|
227
257
|
//#region src/effects/timeout.d.ts
|
|
228
258
|
/**
|
|
229
|
-
* Runs
|
|
230
|
-
* with a `TimeoutError` (a `DOMException`, like `AbortSignal.timeout`), even
|
|
231
|
-
*
|
|
259
|
+
* Runs a function; if it takes longer than `ms`, aborts its signal and rejects
|
|
260
|
+
* with a `TimeoutError` (a `DOMException`, like `AbortSignal.timeout`), even if
|
|
261
|
+
* it ignores the signal. If the caller aborts, rejects with its reason. Two
|
|
262
|
+
* forms:
|
|
263
|
+
*
|
|
264
|
+
* - `timeout(ms, task)` wraps a Task `(payload, ctx) => result` and returns a
|
|
265
|
+
* Task. The Task gets a context of its own whose `signal` the time limit
|
|
266
|
+
* aborts: `bus.on("load", latest(timeout(5000, load)))`.
|
|
267
|
+
* - `timeout(ctx, ms, starter)` is for one call inside a body; `starter` gets
|
|
268
|
+
* `{ signal, abort }`.
|
|
232
269
|
*
|
|
233
270
|
* @example
|
|
234
271
|
* ```ts
|
|
272
|
+
* bus.on("load", timeout(5000, (id, { signal }) => fetchData(id, { signal })));
|
|
273
|
+
*
|
|
235
274
|
* bus.on("load", async (id, ctx) => {
|
|
236
275
|
* const data = await timeout(ctx, 5000, ({ signal }) => fetchData(id, { signal }));
|
|
237
276
|
* });
|
|
238
277
|
* ```
|
|
239
278
|
*/
|
|
240
|
-
export declare
|
|
279
|
+
export declare function timeout<P, E extends EventMap, R>(ms: number, task: Task<P, E, R>): Task<P, E, Promise<Awaited<R>>>;
|
|
280
|
+
export declare function timeout<T>(ctx: {
|
|
241
281
|
signal?: AbortSignal;
|
|
242
|
-
}, ms: number, starter: Starter<T>)
|
|
282
|
+
}, ms: number, starter: Starter<T>): Promise<T>;
|
|
243
283
|
//#endregion
|
|
244
284
|
export type { CancellableExecutor, CancellableHandle, EffectContext, PollOptions, RaceStarter, RetryOptions, TakeOptions };
|
package/dist/effects.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
import{n as e,t}from"./onAbort-BgMfspK4.js";import{a as n,i as r,o as i,t as a}from"./context-
|
|
1
|
+
import{n as e,t}from"./onAbort-BgMfspK4.js";import{a as n,i as r,o as i,t as a}from"./context-DlA80GOA.js";import{n as o,r as s,t as c}from"./delay-CIHnOh_L.js";const l=(e,n)=>n?.signal?new Promise((r,i)=>{let a=t(n,i);e.then(r,i).finally(a)}):e,u=async(e,n,o,s)=>{n?.signal?.throwIfAborted();let{ctx:c,unlink:u}=r(n??{}),d=a(c,e);i(c,e,`start`),t(c,()=>d(`cancel`));try{let e=await l(o(c),n);return d(`done`),s?.(!1),e}catch(e){throw d(`error`,e),s?.(!0),e}finally{u()}},d=async(e,t)=>{let{ctx:i,unlink:a}=r(e);try{return await n(i,`run`,()=>t(i))}finally{a()}},f=e=>e,p=(e,t)=>n=>e(t,f(n)),m=e=>Array.isArray(e)?Array(e.length):{},h=(e,t)=>{let i=Object.entries(t).map(([t,i])=>{let a=r(e),o={signal:a.ctx.signal,abort:a.ctx.abort},s=()=>i(o);return{key:t,task:new Promise(e=>e(n(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=(n,r)=>n.signal.aborted?Promise.reject(n.signal.reason):new Promise((i,a)=>{let o=[],s=`pending`,c=t=>{try{t()}catch(t){e(`cancel cleanup failed`,t)}},l=t(n,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{r({resolve:u(i),reject:u(a),onCancel:d})}catch(e){u(a)(e)}}),x=(e,n,r,i)=>{if(e.signal.aborted)return Promise.resolve();let a=i.leading??!1,c=i.waitForFn??!1;return u(`poll`,e,e=>new Promise((i,l)=>{let u=0,f=null,p=()=>{f!==null&&(o(f),f=null)},m=e=>{try{f=s(h,typeof r==`function`?r(e):r)}catch(e){p(),l(e)}},h=()=>{f=null,c||m(u+1),g()},g=()=>{let t=u++;d(e,e=>n(e,t)).then(()=>{c&&!e.signal.aborted&&m(u)},e=>{p(),l(e)})};t(e,p),a?(g(),c||m(u)):m(0)})).catch(t=>{if(!e.signal.aborted)throw t})};function S(e,t,n,r={}){if(typeof e!=`object`){let r=t,i=n??{};return(t,n)=>x(n,p(r,t),e,i)}let i=t;return x(e,(e,t)=>i(t),n,r)}function C(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 w=(e,t,n)=>typeof e==`function`?e(t,n):e,T=e=>({times:e.times??3,delay:e.delay??0,shouldRetry:e.shouldRetry??(()=>!0)}),E=(e,t,n)=>u(`retry`,e,async e=>{let{times:r,delay:i,shouldRetry:a}=T(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=w(i,n,t);o>0&&await c(e,o)}});function D(e,t,n={}){if(typeof e==`function`){let n=e;return(e,r)=>E(r,p(n,e),t??{})}let r=t;return E(e,(e,t)=>r(t),n)}const O=(e,n,r={})=>u(`take`,e,i=>new Promise((a,o)=>{let{predicate:s}=r,c=[],l=()=>{for(let e of c)e()},u=e=>{l(),o(e)};c.push(e.on(n,e=>{(!s||s(e))&&(l(),a(e))})),c.push(t(i,u)),c.push(t({signal:r.signal},u))})),k=(e,t,i)=>u(`timeout`,e,async e=>{let a=r(e),c=s(()=>a.ctx.abort(new DOMException(`Timed out after ${t}ms`,`TimeoutError`)),t);try{return await l(Promise.resolve(n(a.ctx,`run`,()=>i(a.ctx))),a.ctx)}finally{o(c),a.unlink()}});function A(e,t,n){if(typeof e==`number`){let n=t;return(t,r)=>k(r,e,p(n,t))}let r=t,i=n;return k(e,r,e=>i({signal:e.signal,abort:e.abort}))}export{_ as all,y as allSettled,b as cancellable,c as delay,t as onAbort,S as poll,C as race,D as retry,O as take,A as timeout};
|
package/dist/index.d.ts
CHANGED
|
@@ -1,3 +1,2 @@
|
|
|
1
|
-
import { A as Keys, C as WithPayload, D as anyEventType, E as Tracer, F as TraceEvent, I as TraceLogger, L as UnsubscribeCallback, M as Phase, N as Task, O as EffectName, P as Trace, S as WithContext, T as createBus, _ as EventPayload, a as AnyEvent, b as Off, c as Command, d as ContextOf, f as ContextOption, g as EventLike, h as EventKey, i as Action, j as PayloadOf, k as EventMap, l as Commands, m as Emittable, o as Bus, p as Emit, s as BusOptions, u as Context, v as Handler, w as WithType, x as On, y as HandlerRef } from "./action-
|
|
2
|
-
import "./index-CaxrMD1A.js";
|
|
1
|
+
import { A as Keys, C as WithPayload, D as anyEventType, E as Tracer, F as TraceEvent, I as TraceLogger, L as UnsubscribeCallback, M as Phase, N as Task, O as EffectName, P as Trace, S as WithContext, T as createBus, _ as EventPayload, a as AnyEvent, b as Off, c as Command, d as ContextOf, f as ContextOption, g as EventLike, h as EventKey, i as Action, j as PayloadOf, k as EventMap, l as Commands, m as Emittable, o as Bus, p as Emit, s as BusOptions, u as Context, v as Handler, w as WithType, x as On, y as HandlerRef } from "./action-rqZEnRIp.js";
|
|
3
2
|
export { type Action, type AnyEvent, type Bus, type BusOptions, type Command, type Commands, type Context, type ContextOf, type ContextOption, type EffectName, type Emit, type Emittable, type EventKey, type EventLike, type EventMap, type EventPayload, type Handler, type HandlerRef, type Keys, type Off, type On, type PayloadOf, type Phase, type Task, type Trace, type TraceEvent, type TraceLogger, type Tracer, type UnsubscribeCallback, type WithContext, type WithPayload, type WithType, anyEventType, createBus };
|
package/dist/index.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
export{n as anyEventType,t as createBus}from"./bus-
|
|
1
|
+
export{n as anyEventType,t as createBus}from"./bus-CRnlwmQ4.js";
|
|
@@ -0,0 +1,167 @@
|
|
|
1
|
+
import { L as UnsubscribeCallback, N as Task, c as Command, j as PayloadOf, k as EventMap, o as Bus, u as Context } from "./action-rqZEnRIp.js";
|
|
2
|
+
//#region src/actions/command.d.ts
|
|
3
|
+
/**
|
|
4
|
+
* Creates a command: a typed request for a result. `bus.emit(command, payload)`
|
|
5
|
+
* runs its handler as a task, with a context, and returns what the handler
|
|
6
|
+
* returns. Listeners of the command's type are told first, as for any event.
|
|
7
|
+
*
|
|
8
|
+
* The handler is optional. A command without one is only a contract, and the
|
|
9
|
+
* bus gets its implementation from the `commands` registry (see
|
|
10
|
+
* `createCommands` and `bindHandler`). A handler bound there wins over the one
|
|
11
|
+
* the command was created with, so a test can give a bus its own implementation.
|
|
12
|
+
*
|
|
13
|
+
* A handler can be wrapped in a policy, e.g. `latest(fn)`. Calling the command
|
|
14
|
+
* directly, `command(payload)`, runs its own handler outside of any bus.
|
|
15
|
+
*
|
|
16
|
+
* @example
|
|
17
|
+
* ```ts
|
|
18
|
+
* const getUser = createCommand("user/get", (id: string, { signal }) =>
|
|
19
|
+
* fetchUser(id, { signal }),
|
|
20
|
+
* );
|
|
21
|
+
* const sendMail = createCommand<Mail, void>("mail/send"); // implemented elsewhere
|
|
22
|
+
*
|
|
23
|
+
* const commands = createCommands([bindHandler(sendMail, smtpSend)]);
|
|
24
|
+
* const bus = createBus({ commands });
|
|
25
|
+
* const user = await bus.emit(getUser, "1");
|
|
26
|
+
*
|
|
27
|
+
* commands.handle(getUser, async () => fakeUser); // in a test
|
|
28
|
+
* ```
|
|
29
|
+
*/
|
|
30
|
+
declare const createCommand: <P = void, R = void, T extends string = string, E extends EventMap = EventMap>(type: T, handler?: Task<P, E, R>) => Command<P, R> & {
|
|
31
|
+
readonly type: T;
|
|
32
|
+
};
|
|
33
|
+
/** A command (or its type) with the handler to bind to it; `bindHandler` makes one. */
|
|
34
|
+
type Binding<E extends EventMap = EventMap> = readonly [Command<never, unknown> | string, Task<never, E, unknown>];
|
|
35
|
+
/**
|
|
36
|
+
* Pairs a command with the handler to bind to it, for `createCommands`. It
|
|
37
|
+
* checks that the handler fits the command.
|
|
38
|
+
*
|
|
39
|
+
* @example
|
|
40
|
+
* ```ts
|
|
41
|
+
* createCommands([bindHandler(sendMail, smtpSend)]);
|
|
42
|
+
* ```
|
|
43
|
+
*/
|
|
44
|
+
declare const bindHandler: <P, R, E extends EventMap>(command: Command<P, R>, fn: Task<P, E, R>) => Binding<E>;
|
|
45
|
+
/**
|
|
46
|
+
* The handlers bound to commands of `bus`: it makes the registry, sets it as
|
|
47
|
+
* the commands of the bus and returns it. Each bus has its own, so each test
|
|
48
|
+
* can have its own implementation. `handle` binds more later and returns the
|
|
49
|
+
* function that unbinds. A second `createCommands(bus)` replaces the registry
|
|
50
|
+
* of that bus.
|
|
51
|
+
*
|
|
52
|
+
* What the bus runs for a command: the handler bound last, else the one the
|
|
53
|
+
* command was created with, else it throws `No handler for command "..."`.
|
|
54
|
+
*
|
|
55
|
+
* @example
|
|
56
|
+
* ```ts
|
|
57
|
+
* const bus = createBus<Events>();
|
|
58
|
+
* const commands = createCommands(bus, [bindHandler(sendMail, smtpSend)]);
|
|
59
|
+
*
|
|
60
|
+
* const unbind = commands.handle(getUser, async () => fakeUser);
|
|
61
|
+
* unbind(); // the command's own handler is back
|
|
62
|
+
* ```
|
|
63
|
+
*/
|
|
64
|
+
declare const createCommands: <E extends EventMap>(bus: Bus<E>, bindings?: readonly Binding<E>[]) => {
|
|
65
|
+
run: (command: Command, payload: unknown, ctx: unknown) => unknown;
|
|
66
|
+
handle: {
|
|
67
|
+
<P, R>(command: Command<P, R>, fn: Task<P, E, R>): UnsubscribeCallback;
|
|
68
|
+
(type: string, fn: Task<never, E, unknown>): UnsubscribeCallback;
|
|
69
|
+
(bindings: readonly Binding<E>[]): UnsubscribeCallback;
|
|
70
|
+
};
|
|
71
|
+
};
|
|
72
|
+
//#endregion
|
|
73
|
+
//#region src/actions/module.d.ts
|
|
74
|
+
/**
|
|
75
|
+
* What a module's `setup` gets: the context of the module's task, so `on`,
|
|
76
|
+
* `emit` and `run` work as in a handler, plus `handle` to bind commands, `use`
|
|
77
|
+
* to mount sub-modules and `spawn` to start a background task. Everything the
|
|
78
|
+
* module does is undone when it is unmounted.
|
|
79
|
+
*/
|
|
80
|
+
type ModuleContext<E extends EventMap = EventMap> = Context<E> & {
|
|
81
|
+
/** Binds the handler of a command, or a list of them; undone on unmount. */
|
|
82
|
+
handle<P, R>(command: Command<P, R>, fn: Task<P, E, R>): UnsubscribeCallback;
|
|
83
|
+
handle(type: string, fn: Task<never, E, unknown>): UnsubscribeCallback;
|
|
84
|
+
handle(bindings: readonly Binding<E>[]): UnsubscribeCallback;
|
|
85
|
+
/**
|
|
86
|
+
* Brings sub-modules and commands, in any order. A sub-module is mounted and
|
|
87
|
+
* unmounted with this one. A command is bound to the handler it carries, for
|
|
88
|
+
* as long as this module is mounted; a command that answers by itself keeps
|
|
89
|
+
* answering after the module is gone, since the handler is its own. The
|
|
90
|
+
* returned function undoes just this call, e.g. for what was added later from
|
|
91
|
+
* a listener.
|
|
92
|
+
*/
|
|
93
|
+
use(...items: Array<Module<E> | Command<never, unknown>>): UnsubscribeCallback;
|
|
94
|
+
/**
|
|
95
|
+
* Starts a background task that lives as long as the module: it is aborted
|
|
96
|
+
* on unmount, and an error of it is left unhandled, as in any handler.
|
|
97
|
+
*/
|
|
98
|
+
spawn<P>(fn: Task<P, E, unknown>, ...payload: PayloadOf<P>): void;
|
|
99
|
+
};
|
|
100
|
+
type Module<E extends EventMap = EventMap> = {
|
|
101
|
+
readonly name: string;
|
|
102
|
+
readonly setup: (m: ModuleContext<E>) => void;
|
|
103
|
+
};
|
|
104
|
+
/**
|
|
105
|
+
* Describes one domain of an app: the commands it handles, the events it
|
|
106
|
+
* listens to, its sub-modules and its background tasks. The `name` shows up as
|
|
107
|
+
* the type of the module's tasks in the trace.
|
|
108
|
+
*
|
|
109
|
+
* @example
|
|
110
|
+
* ```ts
|
|
111
|
+
* export const userModule = createModule<Events>("user", (m) => {
|
|
112
|
+
* m.handle(getUser, fetchUser);
|
|
113
|
+
* m.handle([bindHandler(sendMail, smtpSend)]);
|
|
114
|
+
* m.use(authModule);
|
|
115
|
+
*
|
|
116
|
+
* m.on(loginRequested, (user, ctx) => ctx.emit(userLoaded(user)));
|
|
117
|
+
* m.spawn(async (_, ctx) => {
|
|
118
|
+
* for (;;) await handleNext(await take(ctx, "job"));
|
|
119
|
+
* });
|
|
120
|
+
* });
|
|
121
|
+
* ```
|
|
122
|
+
*/
|
|
123
|
+
declare const createModule: <E extends EventMap = EventMap>(name: string, setup: (m: ModuleContext<E>) => void) => Module<E>;
|
|
124
|
+
type Registry<E extends EventMap> = ReturnType<typeof createCommands<E>>;
|
|
125
|
+
/** What `modulePlugin` returns. */
|
|
126
|
+
type ModuleApi<E extends EventMap = EventMap> = {
|
|
127
|
+
/** The registry of command handlers of the bus: the one it was made with, or the app's own. */
|
|
128
|
+
commands: Registry<E>;
|
|
129
|
+
/** Mounts a module and returns the function that unmounts it; a module that is mounted already is not run again. */
|
|
130
|
+
mount(module: Module<E>): UnsubscribeCallback;
|
|
131
|
+
unmount(module: Module<E>): void;
|
|
132
|
+
isMounted(module: Module<E>): boolean;
|
|
133
|
+
/** Unmounts every module; a disposed app cannot mount modules. */
|
|
134
|
+
dispose(): void;
|
|
135
|
+
};
|
|
136
|
+
/**
|
|
137
|
+
* The plugin that assembles an app from modules: `bus.use(modulePlugin(modules))`
|
|
138
|
+
* mounts `modules` at once, in the order given, and returns `mount`, `unmount`,
|
|
139
|
+
* `isMounted`, `dispose` and `commands` for the modules that come and go later. The bus runs the commands that the
|
|
140
|
+
* modules bind: if `createCommands(bus)` was called before, that registry is
|
|
141
|
+
* used, otherwise the app attaches its own, as `app.commands`.
|
|
142
|
+
*
|
|
143
|
+
* A module is known by its `name`: mounting a module whose name is taken
|
|
144
|
+
* replaces the mounted one, which is unmounted first. That is what hot reload
|
|
145
|
+
* needs (see `docs/hmr.md`): the new version of a module file mounts again and
|
|
146
|
+
* the old version goes away with its subscriptions, commands and tasks.
|
|
147
|
+
*
|
|
148
|
+
* Unmounting undoes everything the module did: its subscriptions, its bound
|
|
149
|
+
* commands, its sub-modules and its background tasks. `dispose` unmounts them
|
|
150
|
+
* all, and a disposed app cannot mount modules.
|
|
151
|
+
*
|
|
152
|
+
* @example
|
|
153
|
+
* ```ts
|
|
154
|
+
* const bus = createBus<Events>();
|
|
155
|
+
* const app = bus.use(modulePlugin([userModule]));
|
|
156
|
+
*
|
|
157
|
+
* const unmount = app.mount(orderModule); // later, e.g. after a lazy import
|
|
158
|
+
* unmount(); // or app.unmount(orderModule)
|
|
159
|
+
*
|
|
160
|
+
* bus.emit(getUser, "1");
|
|
161
|
+
* app.commands.handle(getUser, fakeUser); // in a test
|
|
162
|
+
* app.dispose();
|
|
163
|
+
* ```
|
|
164
|
+
*/
|
|
165
|
+
declare const modulePlugin: <E extends EventMap>(modules?: readonly Module<E>[]) => (bus: Bus<E>) => ModuleApi<E>;
|
|
166
|
+
//#endregion
|
|
167
|
+
export { modulePlugin as a, createCommand as c, createModule as i, createCommands as l, ModuleApi as n, Binding as o, ModuleContext as r, bindHandler as s, Module as t };
|
|
@@ -175,19 +175,19 @@ interface Bus<E extends EventMap> {
|
|
|
175
175
|
on: On<E>;
|
|
176
176
|
off: Off<E>;
|
|
177
177
|
emit: Emit<E>;
|
|
178
|
-
/**
|
|
178
|
+
/**
|
|
179
|
+
* Calls `plugin` with the bus and returns what it returns: an api, a
|
|
180
|
+
* function that undoes it. A plugin is any function of the bus; the bus keeps
|
|
181
|
+
* no list of them. See `modulePlugin` in `nanoeffects/actions`.
|
|
182
|
+
*/
|
|
183
|
+
use<R>(plugin: (bus: Bus<E>) => R): R;
|
|
184
|
+
/** `BusOptions.context` and `.trace`, and `commands`, for what makes tasks of its own, like `modulePlugin`. */
|
|
179
185
|
readonly context?: ContextOption<E> | undefined;
|
|
180
|
-
/** What runs the commands; `
|
|
186
|
+
/** What runs the commands; `createCommands(bus)` and `modulePlugin` set it. Without one a command runs its own handler. */
|
|
181
187
|
commands?: Commands | undefined;
|
|
182
188
|
readonly trace?: Tracer | undefined;
|
|
183
189
|
}
|
|
184
190
|
type BusOptions<E extends EventMap> = {
|
|
185
|
-
/**
|
|
186
|
-
* Runs commands: make it with `createCommands` from `nanoeffects/actions`.
|
|
187
|
-
* Without it an event that is a function runs as it is, with the payload and
|
|
188
|
-
* the task context.
|
|
189
|
-
*/
|
|
190
|
-
commands?: Commands;
|
|
191
191
|
/** Tracing of every task phase; make it with `createTracer` from `nanoeffects/trace`. */
|
|
192
192
|
trace?: never;
|
|
193
193
|
/**
|
|
@@ -214,9 +214,10 @@ type BusOptions<E extends EventMap> = {
|
|
|
214
214
|
/**
|
|
215
215
|
* Fields added to the context of every task of this bus, its child tasks
|
|
216
216
|
* and the tasks of effects included: a store, a logger, a client. Their
|
|
217
|
-
* types come from `WithContext` in the event map. The fields of the library
|
|
218
|
-
* these when the names are the same. A function gets
|
|
219
|
-
* the task and returns its fields, for fields that
|
|
217
|
+
* types come from `WithContext` in the event map. The fields of the library
|
|
218
|
+
* win over these when the names are the same. A function gets
|
|
219
|
+
* `{ type, payload }` of the task and returns its fields, for fields that
|
|
220
|
+
* depend on the task.
|
|
220
221
|
*/
|
|
221
222
|
context?: ContextOption<E>;
|
|
222
223
|
};
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { L as UnsubscribeCallback, N as Task, c as Command, j as PayloadOf, k as EventMap,
|
|
1
|
+
import { L as UnsubscribeCallback, N as Task, c as Command, j as PayloadOf, k as EventMap, n as FreeActionCreator, o as Bus, r as createAction, t as ActionCreator, u as Context } from "./action-rqZEnRIp.js";
|
|
2
2
|
//#region src/actions/command.d.ts
|
|
3
3
|
/**
|
|
4
4
|
* Creates a command: a typed request for a result. `bus.emit(command, payload)`
|
|
@@ -43,23 +43,25 @@ type Binding<E extends EventMap = EventMap> = readonly [Command<never, unknown>
|
|
|
43
43
|
*/
|
|
44
44
|
export declare const bindHandler: <P, R, E extends EventMap>(command: Command<P, R>, fn: Task<P, E, R>) => Binding<E>;
|
|
45
45
|
/**
|
|
46
|
-
* The handlers bound to commands
|
|
47
|
-
*
|
|
48
|
-
* later and returns the
|
|
46
|
+
* The handlers bound to commands of `bus`: it makes the registry, sets it as
|
|
47
|
+
* the commands of the bus and returns it. Each bus has its own, so each test
|
|
48
|
+
* can have its own implementation. `handle` binds more later and returns the
|
|
49
|
+
* function that unbinds. A second `createCommands(bus)` replaces the registry
|
|
50
|
+
* of that bus.
|
|
49
51
|
*
|
|
50
52
|
* What the bus runs for a command: the handler bound last, else the one the
|
|
51
53
|
* command was created with, else it throws `No handler for command "..."`.
|
|
52
54
|
*
|
|
53
55
|
* @example
|
|
54
56
|
* ```ts
|
|
55
|
-
* const
|
|
56
|
-
* const
|
|
57
|
+
* const bus = createBus<Events>();
|
|
58
|
+
* const commands = createCommands(bus, [bindHandler(sendMail, smtpSend)]);
|
|
57
59
|
*
|
|
58
60
|
* const unbind = commands.handle(getUser, async () => fakeUser);
|
|
59
61
|
* unbind(); // the command's own handler is back
|
|
60
62
|
* ```
|
|
61
63
|
*/
|
|
62
|
-
export declare const createCommands: <E extends EventMap
|
|
64
|
+
export declare const createCommands: <E extends EventMap>(bus: Bus<E>, bindings?: readonly Binding<E>[]) => {
|
|
63
65
|
run: (command: Command, payload: unknown, ctx: unknown) => unknown;
|
|
64
66
|
handle: {
|
|
65
67
|
<P, R>(command: Command<P, R>, fn: Task<P, E, R>): UnsubscribeCallback;
|
|
@@ -69,39 +71,59 @@ export declare const createCommands: <E extends EventMap = EventMap>(bindings?:
|
|
|
69
71
|
};
|
|
70
72
|
//#endregion
|
|
71
73
|
//#region src/actions/job.d.ts
|
|
74
|
+
type Creator = {
|
|
75
|
+
(...args: never[]): {
|
|
76
|
+
type: string;
|
|
77
|
+
payload?: unknown;
|
|
78
|
+
};
|
|
79
|
+
readonly type: string;
|
|
80
|
+
};
|
|
81
|
+
type Outcome = string | Creator;
|
|
82
|
+
/** What `createJob` returns: the command of the job and the actions of its outcome. */
|
|
83
|
+
type Job<P, R, T extends string, S extends Outcome, F extends Outcome> = {
|
|
84
|
+
command: Command<P, Promise<Awaited<R> | undefined>> & {
|
|
85
|
+
readonly type: T;
|
|
86
|
+
};
|
|
87
|
+
/** Made from a string with the result as its payload, or the creator that was given. */
|
|
88
|
+
successAction: S extends string ? ActionCreator<Awaited<R>, S> : S;
|
|
89
|
+
/** Made from a string with the error as its payload, or the creator that was given. */
|
|
90
|
+
failAction: F extends string ? ActionCreator<unknown, F> : F;
|
|
91
|
+
};
|
|
72
92
|
/**
|
|
73
|
-
* Creates a command whose outcome is sent on
|
|
74
|
-
*
|
|
75
|
-
*
|
|
76
|
-
*
|
|
77
|
-
*
|
|
78
|
-
*
|
|
79
|
-
*
|
|
80
|
-
*
|
|
81
|
-
*
|
|
82
|
-
* `
|
|
83
|
-
*
|
|
84
|
-
*
|
|
93
|
+
* Creates a job: a command whose outcome is sent on as actions. When the
|
|
94
|
+
* handler succeeds, `successAction(result)` is emitted on the bus, and when it
|
|
95
|
+
* fails, `failAction(error)`. It is made for the case where nobody waits for
|
|
96
|
+
* the result and the bus carries it on, like `createAsyncThunk` or an effector
|
|
97
|
+
* effect. It returns the three together: `{ command, successAction, failAction }`.
|
|
98
|
+
*
|
|
99
|
+
* `success` and `fail` are a type string, from which the job makes an action
|
|
100
|
+
* creator with `createAction`, or an action creator that exists already, which
|
|
101
|
+
* is used and returned as it is. A missing one is made with the type
|
|
102
|
+
* `<type>/success` or `<type>/fail`.
|
|
103
|
+
*
|
|
104
|
+
* `bus.emit(command, payload)` returns a promise of the result. An error of the
|
|
105
|
+
* handler always counts as handled: it goes to `failAction` and the promise
|
|
106
|
+
* resolves with `undefined`; a command is the tool for a result that must reject.
|
|
107
|
+
* The actions are emitted as the task that ran the job, also for a handler bound
|
|
108
|
+
* with `commands.handle`, and are skipped once the task is aborted. A missing
|
|
109
|
+
* handler is not an outcome: `emit` throws `MissingHandlerError`. Calling the
|
|
110
|
+
* command directly runs only its handler.
|
|
85
111
|
*
|
|
86
112
|
* @example
|
|
87
113
|
* ```ts
|
|
88
|
-
* const
|
|
89
|
-
*
|
|
90
|
-
*
|
|
91
|
-
* const loadUser = createJob("user/load", fetchUser, { done: loaded, fail: failed });
|
|
114
|
+
* const { command: loadUser, successAction: userLoaded, failAction: userFailed } =
|
|
115
|
+
* createJob("user/load", fetchUser, { success: "user/loaded", fail: "user/failed" });
|
|
92
116
|
*
|
|
93
|
-
* bus.on(
|
|
94
|
-
* bus.emit(loadUser, "1"); //
|
|
117
|
+
* bus.on(userLoaded, (user) => render(user));
|
|
118
|
+
* bus.emit(loadUser, "1"); // userLoaded(user) or userFailed(error) comes later
|
|
95
119
|
* ```
|
|
96
120
|
*/
|
|
97
|
-
export declare const createJob: <P = void, R = void, T extends string = string, E extends EventMap = EventMap
|
|
98
|
-
/** Gets the result when the handler succeeds. */
|
|
99
|
-
|
|
100
|
-
/** Gets the error when the handler fails. */
|
|
101
|
-
fail?:
|
|
102
|
-
}) =>
|
|
103
|
-
readonly type: T;
|
|
104
|
-
};
|
|
121
|
+
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?: {
|
|
122
|
+
/** Gets the result when the handler succeeds: a type to make an action creator of, or an action creator. */
|
|
123
|
+
success?: S;
|
|
124
|
+
/** Gets the error when the handler fails: a type to make an action creator of, or an action creator. */
|
|
125
|
+
fail?: F;
|
|
126
|
+
}) => Job<P, R, T, S, F>;
|
|
105
127
|
//#endregion
|
|
106
128
|
//#region src/actions/module.d.ts
|
|
107
129
|
/**
|
|
@@ -116,10 +138,14 @@ type ModuleContext<E extends EventMap = EventMap> = Context<E> & {
|
|
|
116
138
|
handle(type: string, fn: Task<never, E, unknown>): UnsubscribeCallback;
|
|
117
139
|
handle(bindings: readonly Binding<E>[]): UnsubscribeCallback;
|
|
118
140
|
/**
|
|
119
|
-
*
|
|
120
|
-
*
|
|
141
|
+
* Brings sub-modules and commands, in any order. A sub-module is mounted and
|
|
142
|
+
* unmounted with this one. A command is bound to the handler it carries, for
|
|
143
|
+
* as long as this module is mounted; a command that answers by itself keeps
|
|
144
|
+
* answering after the module is gone, since the handler is its own. The
|
|
145
|
+
* returned function undoes just this call, e.g. for what was added later from
|
|
146
|
+
* a listener.
|
|
121
147
|
*/
|
|
122
|
-
use(...
|
|
148
|
+
use(...items: Array<Module<E> | Command<never, unknown>>): UnsubscribeCallback;
|
|
123
149
|
/**
|
|
124
150
|
* Starts a background task that lives as long as the module: it is aborted
|
|
125
151
|
* on unmount, and an error of it is left unhandled, as in any handler.
|
|
@@ -151,7 +177,7 @@ type Module<E extends EventMap = EventMap> = {
|
|
|
151
177
|
*/
|
|
152
178
|
export declare const createModule: <E extends EventMap = EventMap>(name: string, setup: (m: ModuleContext<E>) => void) => Module<E>;
|
|
153
179
|
type Registry<E extends EventMap> = ReturnType<typeof createCommands<E>>;
|
|
154
|
-
/** What `
|
|
180
|
+
/** What `modulePlugin` returns. */
|
|
155
181
|
type ModuleApi<E extends EventMap = EventMap> = {
|
|
156
182
|
/** The registry of command handlers of the bus: the one it was made with, or the app's own. */
|
|
157
183
|
commands: Registry<E>;
|
|
@@ -163,11 +189,11 @@ type ModuleApi<E extends EventMap = EventMap> = {
|
|
|
163
189
|
dispose(): void;
|
|
164
190
|
};
|
|
165
191
|
/**
|
|
166
|
-
*
|
|
167
|
-
* order given, and returns `mount`, `unmount`,
|
|
168
|
-
* the modules that come and go later. The bus runs the commands that the
|
|
169
|
-
* modules bind: if
|
|
170
|
-
*
|
|
192
|
+
* The plugin that assembles an app from modules: `bus.use(modulePlugin(modules))`
|
|
193
|
+
* mounts `modules` at once, in the order given, and returns `mount`, `unmount`,
|
|
194
|
+
* `isMounted`, `dispose` and `commands` for the modules that come and go later. The bus runs the commands that the
|
|
195
|
+
* modules bind: if `createCommands(bus)` was called before, that registry is
|
|
196
|
+
* used, otherwise the app attaches its own, as `app.commands`.
|
|
171
197
|
*
|
|
172
198
|
* A module is known by its `name`: mounting a module whose name is taken
|
|
173
199
|
* replaces the mounted one, which is unmounted first. That is what hot reload
|
|
@@ -181,7 +207,7 @@ type ModuleApi<E extends EventMap = EventMap> = {
|
|
|
181
207
|
* @example
|
|
182
208
|
* ```ts
|
|
183
209
|
* const bus = createBus<Events>();
|
|
184
|
-
* const app =
|
|
210
|
+
* const app = bus.use(modulePlugin([userModule]));
|
|
185
211
|
*
|
|
186
212
|
* const unmount = app.mount(orderModule); // later, e.g. after a lazy import
|
|
187
213
|
* unmount(); // or app.unmount(orderModule)
|
|
@@ -191,6 +217,6 @@ type ModuleApi<E extends EventMap = EventMap> = {
|
|
|
191
217
|
* app.dispose();
|
|
192
218
|
* ```
|
|
193
219
|
*/
|
|
194
|
-
export declare const
|
|
220
|
+
export declare const modulePlugin: <E extends EventMap>(modules?: readonly Module<E>[]) => (bus: Bus<E>) => ModuleApi<E>;
|
|
195
221
|
//#endregion
|
|
196
|
-
export { type ActionCreator, type Binding, type FreeActionCreator, type Module, type ModuleApi, type ModuleContext, createAction };
|
|
222
|
+
export { type ActionCreator, type Binding, type FreeActionCreator, type Job, type Module, type ModuleApi, type ModuleContext, createAction };
|
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-yAWj0BFZ.js";import{t as r}from"./event-0RIBGYqS.js";function i(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 a=class extends Error{};const o=(e,n)=>Object.assign((r,i)=>{if(!n)throw new a(`No handler for command "${e}"`);return n(r,i??t({event:{type:e,payload:r}}).ctx)},{type:e}),s=(e,t)=>[e,t],c=(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(t);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 e.commands=o,o},l=e=>typeof e==`string`?i(e):e,u=(e,t,n)=>{let r=e.emit;r(Reflect.apply(t,null,[n]))},d=e=>{try{return Promise.resolve(e())}catch(e){if(e instanceof a)throw e;return Promise.reject(e)}},f=(e,t,n={})=>{let r=o(e,t),i=l(n.success??`${e}/success`),a=l(n.fail??`${e}/fail`),s=(e,t,n)=>{let r=n;return d(()=>Reflect.apply(e,null,[t,n])).then(e=>(u(r,i,e),e),e=>{u(r,a,e)})};return{command:Object.assign((e,t)=>t?s(r,e,t):d(()=>r(e)),{type:e,wrap:e=>(t,n)=>s(e,t,n)}),successAction:i,failAction:a}},p=(e,t)=>({name:e,setup:t}),m=(r=[])=>i=>{let a=i.commands??c(i),o={handle:(...e)=>{if(!a.handle)throw Error("modulePlugin: the `commands` of the bus is not a registry from `createCommands()`");return Reflect.apply(a.handle,null,e)}},s=t({event:{type:`app`,payload:void 0},bus:i,tracer:i.trace}),l=t=>{let r=/* @__PURE__ */ new Map,i=/* @__PURE__ */ new Map;return{mount:a=>{let s=r.get(a);if(s)return s;let c=i.get(a.name);c&&r.get(c)?.();let u=e(t,a.name),d=u.ctx,f=l(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=l(s.ctx);for(let e of r)u.mount(e);return{commands:a,mount:e=>(s.ctx.signal.throwIfAborted(),u.mount(e)),unmount:u.unmount,isMounted:u.isMounted,dispose:()=>s.ctx.abort()}};export{s as bindHandler,i as createAction,o as createCommand,c as createCommands,f as createJob,p as createModule,m as modulePlugin};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{a as e,c as t,n,r}from"./context-yAWj0BFZ.js";import{n as i}from"./promise-CSLpzwSR.js";import{n as a,t as o}from"./event-0RIBGYqS.js";const s=`*`,c=()=>{let e={},t=/* @__PURE__ */ new WeakSet,n=n=>{let r=e[n]??[];if(!t.has(r))return e[n]=r,r;let i=[...r];return e[n]=i,i},r=(t,r)=>{if(!r){e[t]=[];return}let i=(e[t]??[]).indexOf(r);i>=0&&n(t).splice(i,1)};return{get:n=>{let r=e[n]??[];return t.add(r),r},add:(e,t)=>(n(e).push(t),()=>{r(e,t)}),remove:r}},l=(e,t,n)=>Reflect.apply(e,null,[t,n]),u=(s={})=>{let u=c(),d=(e,t)=>u.add(o(e),t),f=(e,t)=>u.remove(o(e),t),p=(e,a)=>{let{onError:o}=s,{ctx:c}=n({event:a,bus:m,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)}},m={on:d,off:f,emit:(t,i)=>{let c=o(t),d=a(t,i),f={type:c,payload:d},h=[...u.get(c),...u.get(`*`)];h.length===0&&typeof t!=`function`&&s.onUnhandled?.(f);for(let e of h)p(e,f);if(typeof t==`function`){let{ctx:i}=n({event:f,bus:m,tracer:s.trace,parent:{ref:r()}}),a=m.commands?.run??l;return e(i,`command`,()=>a(t,d,i))}},use:e=>e(m),context:s.context,trace:s.trace};return m};export{s as n,u as t};
|
|
@@ -0,0 +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()}};return{ctx:p({...f(t?.context,e),type:e.type,payload:e.payload,signal:u,abort:e=>s.abort(e),emit:h,on:g,off:t?.off??c,run:_}),unlink:l}},h=(e,t)=>m({event:{type:t??e.type??``,payload:e.payload},bus:{emit:e.emit,on:e.on,off:e.off,context: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};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{s as e}from"./context-
|
|
1
|
+
import{s as e}from"./context-yAWj0BFZ.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};
|