nanoeffects 0.29.0 → 0.31.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.
Files changed (127) hide show
  1. package/README.md +6 -5
  2. package/dist/{action-creator-jeEqIKgK.d.ts → action-creator-6rlBTmH9.d.ts} +27 -2
  3. package/dist/actions.d.ts +3 -3
  4. package/dist/actions.js +1 -1
  5. package/dist/{bus-0uYn_kRj.js → bus-DFlmNJ6h.js} +1 -1
  6. package/dist/context-B5Z2RpJt.js +1 -0
  7. package/dist/{context-types-Bme1mzkn.d.ts → context-types-DKNc5mkS.d.ts} +1 -1
  8. package/dist/context.d.ts +2 -2
  9. package/dist/dev.d.ts +49 -3
  10. package/dist/dev.js +2 -1
  11. package/dist/effects.d.ts +2 -2
  12. package/dist/effects.js +1 -1
  13. package/dist/emit-key-C6FL7Ewn.js +1 -0
  14. package/dist/guard.d.ts +59 -0
  15. package/dist/guard.js +1 -0
  16. package/dist/index.d.ts +1 -1
  17. package/dist/index.js +1 -1
  18. package/dist/match.d.ts +1 -1
  19. package/dist/{module-BWMW83qk.d.ts → module-G39MaVOt.d.ts} +2 -2
  20. package/dist/notrace/{action-creator-xpQ_I2h8.d.ts → action-creator-BrMSO3RP.d.ts} +1 -0
  21. package/dist/notrace/actions.d.ts +2 -2
  22. package/dist/notrace/effects.d.ts +2 -2
  23. package/dist/notrace/index.d.ts +1 -1
  24. package/dist/notrace/{plugin-6LhNx0th.d.ts → plugin-7GUL2EW5.d.ts} +1 -1
  25. package/dist/notrace/policies.d.ts +1 -1
  26. package/dist/notrace/redux.d.ts +1 -1
  27. package/dist/observable.d.ts +1 -1
  28. package/dist/oop.d.ts +1 -1
  29. package/dist/oop.js +1 -1
  30. package/dist/{plugin-BaErevLy.d.ts → plugin-BWNP23hr.d.ts} +2 -2
  31. package/dist/policies.d.ts +2 -2
  32. package/dist/policies.js +1 -1
  33. package/dist/production/dev.js +1 -1
  34. package/dist/react.d.ts +2 -2
  35. package/dist/react.js +1 -1
  36. package/dist/redux.d.ts +1 -1
  37. package/dist/scope.d.ts +2 -2
  38. package/dist/signal.d.ts +22 -2
  39. package/dist/signal.js +1 -1
  40. package/dist/site-DLvUoXs3.js +1 -0
  41. package/dist/svelte.d.ts +1 -1
  42. package/dist/trace.d.ts +151 -2
  43. package/dist/trace.js +3 -1
  44. package/dist/{types-D5xsR37j.d.ts → types-N_cdRr1r.d.ts} +2 -2
  45. package/dist/vue.d.ts +1 -1
  46. package/dist/{with-policy-C6BIiPIi.js → with-policy-CeM1rtES.js} +1 -1
  47. package/dist/{with-policy-BZVRBUOm.d.ts → with-policy-CthiBp_z.d.ts} +1 -1
  48. package/docs/README.md +62 -31
  49. package/docs/actions.md +44 -27
  50. package/docs/cancel-stale-requests.md +2 -0
  51. package/docs/chat-example.md +3 -1
  52. package/docs/chat-widget.md +2 -0
  53. package/docs/context.md +322 -9
  54. package/docs/debounce-and-abort.md +3 -1
  55. package/docs/debugging-loops.md +318 -0
  56. package/docs/effects.md +255 -138
  57. package/docs/errors.md +4 -2
  58. package/docs/examples.md +60 -0
  59. package/docs/guide.md +39 -22
  60. package/docs/hmr.md +35 -1
  61. package/docs/loop-guard.md +109 -0
  62. package/docs/migrating-from-effector.md +4 -2
  63. package/docs/migrating-from-mitt.md +6 -4
  64. package/docs/migrating-from-rxjs.md +2 -0
  65. package/docs/migrating-from-saga.md +2 -0
  66. package/docs/motivation.md +14 -21
  67. package/docs/observable.md +2 -0
  68. package/docs/oop.md +3 -1
  69. package/docs/package.md +4 -1
  70. package/docs/pass-the-signal.md +346 -0
  71. package/docs/plugins.md +22 -5
  72. package/docs/policies.md +73 -46
  73. package/docs/prevent-double-submit.md +3 -1
  74. package/docs/query-libraries.md +3 -1
  75. package/docs/react.md +42 -13
  76. package/docs/recipes.md +528 -0
  77. package/docs/ru/README.md +62 -0
  78. package/docs/ru/actions.md +412 -0
  79. package/docs/ru/cancel-stale-requests.md +106 -0
  80. package/docs/ru/chat-example.md +259 -0
  81. package/docs/ru/chat-widget.md +131 -0
  82. package/docs/ru/context.md +402 -0
  83. package/docs/ru/debounce-and-abort.md +105 -0
  84. package/docs/ru/debugging-loops.md +318 -0
  85. package/docs/ru/effects.md +538 -0
  86. package/docs/ru/errors.md +36 -0
  87. package/docs/ru/examples.md +60 -0
  88. package/docs/ru/guide.md +530 -0
  89. package/docs/ru/hmr.md +83 -0
  90. package/docs/ru/loop-guard.md +109 -0
  91. package/docs/ru/migrating-from-effector.md +339 -0
  92. package/docs/ru/migrating-from-mitt.md +99 -0
  93. package/docs/ru/migrating-from-rxjs.md +197 -0
  94. package/docs/ru/migrating-from-saga.md +97 -0
  95. package/docs/ru/motivation.md +47 -0
  96. package/docs/ru/observable.md +233 -0
  97. package/docs/ru/oop.md +431 -0
  98. package/docs/ru/package.md +42 -0
  99. package/docs/ru/pass-the-signal.md +346 -0
  100. package/docs/ru/plugins.md +398 -0
  101. package/docs/ru/policies.md +201 -0
  102. package/docs/ru/prevent-double-submit.md +122 -0
  103. package/docs/ru/query-libraries.md +392 -0
  104. package/docs/ru/react.md +309 -0
  105. package/docs/ru/recipes.md +528 -0
  106. package/docs/ru/semantics.md +19 -0
  107. package/docs/ru/server.md +204 -0
  108. package/docs/ru/starter.md +118 -0
  109. package/docs/ru/stores.md +673 -0
  110. package/docs/ru/svelte.md +78 -0
  111. package/docs/ru/tracing.md +466 -0
  112. package/docs/ru/typescript.md +170 -0
  113. package/docs/ru/vue.md +92 -0
  114. package/docs/semantics.md +2 -0
  115. package/docs/server.md +2 -0
  116. package/docs/starter.md +2 -0
  117. package/docs/stores.md +2 -0
  118. package/docs/svelte.md +3 -1
  119. package/docs/tracing.md +58 -1
  120. package/docs/typescript.md +2 -0
  121. package/docs/vue.md +3 -1
  122. package/llms-full.txt +2087 -418
  123. package/llms.txt +11 -8
  124. package/package.json +23 -6
  125. package/dist/context-DtUnzC-1.js +0 -1
  126. package/docs/scope.md +0 -278
  127. package/docs/stability.md +0 -90
package/README.md CHANGED
@@ -13,7 +13,7 @@ Move business logic and side effects out of React, Vue and Svelte components int
13
13
  npm install nanoeffects
14
14
  ```
15
15
 
16
- ESM only, no dependencies, types included.
16
+ `pnpm add nanoeffects` and `yarn add nanoeffects` work the same. The package is ESM only (use `import`, not `require`), has no dependencies and includes its types. It runs on Node 18 or newer and in any bundler.
17
17
 
18
18
  New project: `npm create nanoeffects@latest my-app` ([Docs](docs/starter.md)). Try it first: [playground](https://stackblitz.com/github/nanoeffects/nanoeffects/tree/main/examples/playground) in your browser, no install.
19
19
 
@@ -28,11 +28,11 @@ const bus = createBus(); // event bus; each handler call is a task
28
28
  const cart = [];
29
29
 
30
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));
31
+ const unbind = bus.on("cart/added", (item) => console.log("added", item));
32
32
  bus.on("cart/added", (item) => cart.push(item));
33
33
 
34
34
  bus.emit("cart/added", { id: "p1" }); // both listeners run, cart has the item
35
- unbind(); // stop tracking
35
+ unbind(); // stop logging
36
36
  ```
37
37
 
38
38
  ## Keep the logic out of the component
@@ -51,7 +51,8 @@ export const bus = createBus();
51
51
  bus.on(
52
52
  "search",
53
53
  latest(async (query, ctx) => {
54
- // signal — lets latest cancel this request, not only drop its result
54
+ // api is your own client (a fetch wrapper, axios, ...); signal lets latest cancel
55
+ // this request, not only drop its result
55
56
  const items = await api.search(query, { signal: ctx.signal });
56
57
  ctx.emit("results", items);
57
58
  }),
@@ -127,7 +128,7 @@ bus.on("save", async (draft, ctx) => {
127
128
 
128
129
  ## Docs
129
130
 
130
- Start with the [Guide](docs/guide.md), or jump by need:
131
+ Read it on the [docs site](https://nanoeffects.github.io/nanoeffects/) (search and sidebar; [in Russian](https://nanoeffects.github.io/nanoeffects/ru/)), or start with the [Guide](docs/guide.md) and jump by need:
131
132
 
132
133
  | Need | Page |
133
134
  | ---- | ---- |
@@ -31,7 +31,31 @@ type TraceEvent<E = Record<string, unknown>> = { [K in Keys<E>]: {
31
31
  * Adapters in `nanoeffects/trace` are factories that return one; pass it
32
32
  * through `createTracer` to `createBus({ trace })`.
33
33
  */
34
- type TraceLogger<E = Record<string, unknown>> = (event: TraceEvent<E>) => void;
34
+ type TraceLogger<E = Record<string, unknown>> = ((event: TraceEvent<E>) => void) & {
35
+ /**
36
+ * Optional: called when a task is made (and again when it is renamed), also for the tasks that
37
+ * never report an event, like a plain handler. Not called for a root that is not sampled.
38
+ */
39
+ task?: (task: TaskInfo) => void;
40
+ };
41
+ /** What a logger's `task` method gets about one task. */
42
+ type TaskInfo = {
43
+ /** Opaque handle of the task; the same one in the call for a rename. Key a `WeakMap` with it. */
44
+ ref: object;
45
+ /** Handle of the parent task; absent for a root. */
46
+ parent?: object;
47
+ /** The number the events of the task use as `id`. */
48
+ id: number;
49
+ /** The type of the task now: the event, or the name of a listener after a rename. */
50
+ type: string;
51
+ /** After a rename, the type the task had before it (the event the listener handles). */
52
+ event?: string;
53
+ /** `true` for the emit event that `tracePlugin` makes, which has no handler of its own. */
54
+ leaf?: boolean;
55
+ /** `false` for a task that `ctx.run` or an effect or a policy made inside a handler; `true` for the task of an emit. */
56
+ emitted?: boolean;
57
+ traceGroupId?: string;
58
+ };
35
59
  /** One logger or several; a throwing logger never breaks the task or the others. */
36
60
  type Trace<E = Record<string, unknown>> = TraceLogger<E> | readonly TraceLogger<E>[];
37
61
  type UnsubscribeCallback = () => void;
@@ -76,6 +100,7 @@ interface Tracer<Ref extends object = object> {
76
100
  type: string;
77
101
  payload?: unknown;
78
102
  traceGroupId?: string;
103
+ leaf?: boolean;
79
104
  }, parent?: Ref): Ref;
80
105
  /** Gives the task another `type`, for a task that is named after it was made (a named listener). A tracer may leave it out. */
81
106
  rename?(ref: Ref, type: string): void;
@@ -480,4 +505,4 @@ interface ActionCreator<P = void, T extends string = string, A extends unknown[]
480
505
  toString(): T;
481
506
  }
482
507
  //#endregion
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 };
508
+ 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, TaskInfo as J, Phase as K, WithType as L, HandlerRef as M, Off as N, EventsOf as O, On as P, UnsubscribeCallback as Q, createBus as R, ContextOption as S, EventKey as T, Keys as U, EffectName as V, ListenerOptions as W, TraceEvent as X, Trace as Y, TraceLogger 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,6 +1,6 @@
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";
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-6rlBTmH9.js";
2
+ import { r as Scoped, t as FieldsOfScope } from "./types-N_cdRr1r.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-G39MaVOt.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";
package/dist/actions.js CHANGED
@@ -1 +1 @@
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};
1
+ import{n as e,t}from"./onAbort-BgMfspK4.js";import{i as n,n as r}from"./context-B5Z2RpJt.js";import{t as i}from"./emit-key-C6FL7Ewn.js";import{t as a}from"./event-DVcW0mME.js";import{r as o}from"./bus-DFlmNJ6h.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,r,a)=>{let o=t;o[i]=!0;try{D(t,n,r,a)}catch(t){e(`cancel listener`,t)}o[i]=!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=(i=[])=>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=r({event:{type:`app`,payload:void 0},bus:a,tracer:a.trace});p={root:t,apps:d(c(t.ctx))};try{e&&p.apps.mount(...i)}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))),i.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};
@@ -1 +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};
1
+ import{n as e}from"./onAbort-BgMfspK4.js";import{n as t,o as n,r}from"./context-B5Z2RpJt.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";import{t}from"./emit-key-C6FL7Ewn.js";const n=t=>{let n=new AbortController;return{controller:n,unlink:e({signal:t},e=>n.abort(e))}},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}=n(u?.signal),{signal:_}=h,v=r&&l?{tracer:l,ref:l.task(o,u?.ref)}:void 0,y=(...e)=>{if(_.aborted&&!S[t])return;let n=c?.emit,r=a;a=v?.ref;try{return n?.(...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,m as n,d as o,o as r,c as s,u as t};
@@ -1,4 +1,4 @@
1
- import { H as EventMap, x as ContextOf } from "./action-creator-jeEqIKgK.js";
1
+ import { H as EventMap, x as ContextOf } from "./action-creator-6rlBTmH9.js";
2
2
  //#region src/core/signal-field-key.d.ts
3
3
  /**
4
4
  * Where `fromSignal` keeps the function that makes a context field from the signal of a
package/dist/context.d.ts CHANGED
@@ -1,5 +1,5 @@
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";
1
+ import { F as WithContext, H as EventMap, v as Bus } from "./action-creator-6rlBTmH9.js";
2
+ import { i as Resolved, r as NoClash, t as ContextTask } from "./context-types-DKNc5mkS.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
package/dist/dev.d.ts CHANGED
@@ -1,5 +1,5 @@
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";
1
+ import { H as EventMap, Q as UnsubscribeCallback, v as Bus } from "./action-creator-6rlBTmH9.js";
2
+ import { i as WithApp, n as ModuleApi } from "./module-G39MaVOt.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">;
@@ -10,11 +10,32 @@ type DevOptions<E extends EventMap = EventMap> = {
10
10
  leaks?: boolean;
11
11
  /** Report the modules of `app` that are mounted, replaced and unmounted. Default `true`. */
12
12
  modules?: boolean;
13
+ /** Warn when a handler emits after its task was aborted, which means it ignored `ctx.signal`. Default `true`. */
14
+ abandoned?: boolean;
15
+ /** Follow the `fetch` requests of the handlers, and count the ones that kept running after a cancel. Node only; needs `abandoned`. Default `true`. */
16
+ requests?: boolean;
13
17
  /** Receives every message. Default: `console.warn` for leaks and `console.info` for modules. */
14
18
  log?: (message: string) => void;
15
19
  /** What `modulePlugin` returned, to report its modules. Without it the app that `modulePlugin` put on the bus is used, in either order of the two plugins. */
16
20
  app?: ReportedApp<E>;
17
21
  };
22
+ /** One signal that a handler lost: it kept working after its task was aborted. */
23
+ type LostSignal = {
24
+ /**
25
+ * `emit`: the handler emitted after the abort (the emit was dropped); `on`: it subscribed after the abort;
26
+ * `request`: a `fetch` of the handler was still running after the abort and did not stop (Node only).
27
+ */
28
+ kind: "emit" | "on" | "request";
29
+ /** The type of the task that was aborted: the event its handler works on. */
30
+ handler: string;
31
+ /** The event that was emitted or subscribed to, or the url of the request. */
32
+ event: string;
33
+ };
34
+ /** What `getLostSignalsCount` takes. */
35
+ type LostSignalsOptions = {
36
+ /** How long to wait, in ms, before counting, so handlers that are still running can finish. Default 0: one turn of the event loop. */
37
+ wait?: number;
38
+ };
18
39
  /** A plugin that connects the diagnostics to a bus; the function it returns disconnects them. */
19
40
  type DevPlugin = <E extends EventMap>(options?: DevOptions<E>) => (bus: Bus<E> & WithApp) => UnsubscribeCallback;
20
41
  //#endregion
@@ -28,6 +49,10 @@ type DevPlugin = <E extends EventMap>(options?: DevOptions<E>) => (bus: Bus<E> &
28
49
  * the count: a file that was reloaded and subscribes again, or an
29
50
  * unsubscribe that is never called. The count follows the function that `on`
30
51
  * returns; `bus.off(event, fn)` is not seen.
52
+ * - **Handlers that ignore the signal.** When a handler emits after its task was aborted (a newer
53
+ * call of `latest`, an unmounted module), the emit is dropped, and one warning names the handler
54
+ * and the event: the handler did not stop when it was cancelled, usually because `ctx.signal` was
55
+ * never given to the request. Nothing is added to the policies; the check is this plugin's.
31
56
  * - **Modules.** It reports a module that is mounted, replaced by name and
32
57
  * unmounted, for the app that `modulePlugin` returned: the `app` option, or
33
58
  * else the one `modulePlugin` put on the bus, whichever plugin was used first.
@@ -43,5 +68,26 @@ type DevPlugin = <E extends EventMap>(options?: DevOptions<E>) => (bus: Bus<E> &
43
68
  * ```
44
69
  */
45
70
  export declare const devPlugin: DevPlugin;
71
+ /**
72
+ * The signals that handlers of a bus lost so far, for a test: every emit or `ctx.on` that a handler made after
73
+ * its task was aborted (the bus drops it), which means the handler kept working after it was cancelled. The bus
74
+ * needs `devPlugin` with `abandoned` on. It waits one turn of the event loop first (`wait` for longer), so handlers
75
+ * that are finishing are counted.
76
+ *
77
+ * @example
78
+ * ```ts
79
+ * const bus = createBus<Events>();
80
+ * bus.use(devPlugin({ log: () => {} }));
81
+ * bus.on("search", latest(searchHandler));
82
+ *
83
+ * bus.emit("search", "a");
84
+ * bus.emit("search", "ab"); // cancels the first call
85
+ *
86
+ * expect(await getLostSignalsCount(bus, { wait: 50 })).toBe(0);
87
+ * ```
88
+ */
89
+ export declare const getLostSignals: (bus: object, options?: LostSignalsOptions) => Promise<LostSignal[]>;
90
+ /** The number of signals that handlers of a bus lost so far: see `getLostSignals` for the list. */
91
+ export declare const getLostSignalsCount: (bus: object, options?: LostSignalsOptions) => Promise<number>;
46
92
  //#endregion
47
- export type { DevOptions, DevPlugin };
93
+ export type { DevOptions, DevPlugin, LostSignal, LostSignalsOptions };
package/dist/dev.js CHANGED
@@ -1 +1,2 @@
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};
1
+ import{t as e}from"./emit-key-C6FL7Ewn.js";import{t}from"./event-DVcW0mME.js";import{t as n}from"./site-DLvUoXs3.js";import{t as r}from"./mount-each-D54UqAhZ.js";const i=()=>{let e=globalThis.process?.getBuiltinModule,t=e?.(`node:async_hooks`)?.AsyncLocalStorage;return t?new t:null},a=e=>typeof e==`string`?e:e instanceof URL?e.href:String(Reflect.get(Object(e),`url`)),o=(e,t)=>t?.signal?t.signal:typeof Request==`function`&&e instanceof Request?e.signal:void 0,s=(e,t,n)=>{let r=i(),s=globalThis.fetch;if(!r||typeof s!=`function`)return null;let c=/* @__PURE__ */ new Set,l=/* @__PURE__ */ new WeakMap,u=e=>{for(let r of l.get(e)??[]){if(r.counted||r.settled||r.signal?.aborted)continue;r.counted=!0,t.push({kind:`request`,handler:e.type,event:r.url});let i=`${e.type}\u0000${r.url}`;c.has(i)||(c.add(i),n(`[nanoeffects] the handler of "${e.type}" has a request to "${r.url}" that kept running after its task was aborted. Pass ctx.signal to it (fetch(url, { signal: ctx.signal })), or make it through a client bound with fromSignal.`))}},d=(e,t,n,r)=>{let i={url:a(t),signal:o(t,n),settled:!1,counted:!1},s=()=>{i.settled=!0};r.then(s,s);let c=()=>u(e),d=l.get(e);d?d.push(i):(l.set(e,[i]),e.signal.addEventListener(`abort`,()=>queueMicrotask(c),{once:!0})),e.signal.aborted&&queueMicrotask(c)},f=(e,t)=>{let n=r.getStore(),i=s(e,t);return n&&d(n,e,t,i),i};globalThis.fetch=f;let p=e.emit,m=(...e)=>{let t=r.getStore();try{return p(...e)}finally{r.enterWith(t)}};return e.emit=m,{enter(e){r.enterWith(e);let t=e.run;e.run=(...e)=>{let n=r.getStore();try{return t(...e)}finally{r.enterWith(n)}}},stop(){globalThis.fetch===f&&(globalThis.fetch=s),e.emit===m&&(e.emit=p)}}},c=`[nanoeffects]`,l=(e={})=>t=>{let{maxListeners:n=10,leaks:r=!0,modules:i=!0,abandoned:a=!0,requests:o=!0,app:s}=e,c=e.log??(e=>console.warn(e)),l=e.log??(e=>console.info(e)),u=[];return r&&u.push(p(t,n,c)),i&&u.push(_(t,s,l)),a&&u.push(g(t,c,o)),()=>{for(let e of u.splice(0))e()}},u=e=>typeof e==`function`&&typeof Reflect.get(e,`type`)!=`string`?`*`:t(e),d=()=>(((/* @__PURE__ */ Error()).stack?.split(`
2
+ `)??[])[4]??``).trim().replace(/^at /,``),f=e=>{let t=e[2],r=typeof t==`object`&&t?Reflect.get(t,`traceId`):void 0,i=typeof r==`string`?d():``;return typeof r==`string`&&i!==``?n(r,i):()=>{}},p=(e,t,n)=>{let r=e.on,i=/* @__PURE__ */ new Map,a=/* @__PURE__ */ new Set,o=!0,s=(...s)=>{if(!o)return Reflect.apply(r,e,s);let[l]=s,d=u(l),p=(i.get(d)??0)+1;i.set(d,p),p>t&&!a.has(d)&&(a.add(d),n(`${c} ${p} 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 m=Reflect.apply(r,e,s),h=f(s),g=!1;return()=>{if(!g){g=!0,h();let e=(i.get(d)??1)-1;i.set(d,e),e<=t&&a.delete(d)}m()}};return e.on=s,()=>{o=!1,e.on===s&&(e.on=r)}},m=e=>typeof e==`string`?e:String(Reflect.get(Object(e),`type`)),h=/* @__PURE__ */ new WeakMap,g=(t,n,r)=>{let i=t.addContext,a=/* @__PURE__ */ new Set,o=[];h.set(t,o);let l=r?s(t,o,n):null,u=!0,d=t=>{i?.(t);let r=t;l?.enter(r);let s=r.emit;r.emit=(i,...l)=>{let d=Reflect.get(t,e),f=m(i),p=`${r.type}\u0000${f}`,h=u&&r.signal.aborted&&d!==!0;return h&&o.push({kind:`emit`,handler:r.type,event:f}),h&&!a.has(p)&&(a.add(p),n(`${c} the handler of "${r.type}" emitted "${f}" after its task was aborted, so the emit was dropped. The handler kept running after it was cancelled: pass ctx.signal to the request (fetch(url, { signal: ctx.signal })) or give ctx to an effect (retry(ctx, ...)).`)),s(i,...l)};let d=r.on;r.on=(e,...t)=>{let i=m(e),s=`${r.type}\u0000on\u0000${i}`,l=u&&r.signal.aborted;return l&&o.push({kind:`on`,handler:r.type,event:i}),l&&!a.has(s)&&(a.add(s),n(`${c} the handler of "${r.type}" subscribed to "${i}" after its task was aborted, so the subscription was dropped. The handler kept running after it was cancelled: pass ctx.signal to the request or give ctx to an effect.`)),d(e,...t)}};return t.addContext=d,()=>{u=!1,l?.stop(),t.addContext===d&&(t.addContext=i)}},_=(e,t,n)=>{let r=t??e.app;if(r)return v(r,n);let i,a;return Object.defineProperty(e,"app",{configurable:!0,enumerable:!0,get:()=>i,set:e=>{a?.(),i=e,a=e?v(e,n):void 0}}),()=>{a?.(),Object.defineProperty(e,"app",{configurable:!0,enumerable:!0,writable:!0,value:i})}},v=(e,t)=>{let{mount:n,unmount:i}=e,a=/* @__PURE__ */ new Map,o=r({mount:r=>{let i=a.get(r.name);if(i===r&&e.isMounted(r))return n(r);let o=i!==void 0&&e.isMounted(i),s=n(r);return a.set(r.name,r),t(`${c} module "${r.name}" ${o?`replaced`:`mounted`}`),()=>{e.isMounted(r)&&t(`${c} module "${r.name}" unmounted`),s()}},unmount:n=>{e.isMounted(n)&&t(`${c} module "${n.name}" unmounted`),i(n)},isMounted:t=>e.isMounted(t)});return e.mount=o.mount,e.unmount=o.unmount,()=>{e.mount=n,e.unmount=i}},y=async(e,t={})=>{let n=h.get(e);if(!n)throw Error("getLostSignalsCount: the bus has no devPlugin, or devPlugin has `abandoned: false`. Use bus.use(devPlugin()) before the test.");return await new Promise(e=>setTimeout(e,t.wait??0)),[...n]},b=async(e,t={})=>(await y(e,t)).length;export{l as devPlugin,y as getLostSignals,b as getLostSignalsCount};
package/dist/effects.d.ts CHANGED
@@ -1,5 +1,5 @@
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";
1
+ import { H as EventMap, I as WithSignal, b as Context, f as Effect, q as Task } from "./action-creator-6rlBTmH9.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-BWNP23hr.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-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};
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-B5Z2RpJt.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=Symbol();export{e as t};
@@ -0,0 +1,59 @@
1
+ import { H as EventMap, v as Bus } from "./action-creator-6rlBTmH9.js";
2
+ //#region src/guard/plugin.d.ts
3
+ /** What a guard found when it refused an emit. */
4
+ type LimitFinding = {
5
+ /** `repeats`: one event is in the chain too often; `depth`: the chain is too long; `storm`: too many emits from outside any task. */
6
+ limit: "repeats" | "depth" | "storm";
7
+ /** The event names of the loop, from the earlier turn of the refused event to it; for a storm, the event. */
8
+ path: string[];
9
+ };
10
+ type LoopGuardOptions = {
11
+ /** How many times one event may be in a chain; the emit that would pass it is refused. Default 50. */
12
+ maxRepeats?: number;
13
+ /** How many emits long a chain may be, whatever the names are. Default 1000. */
14
+ maxDepth?: number;
15
+ /** Events from outside any task, per second, for each type; over it they are refused. Default: no limit. */
16
+ maxPerSecond?: number;
17
+ /** Event names (or a predicate) that the repeat count skips; `maxDepth` still applies. */
18
+ ignore?: readonly string[] | ((name: string) => boolean);
19
+ /** What to do with a refused emit: `"drop"` does not send it (default), `"throw"` throws a `LoopError` from it. */
20
+ onLimit?: "drop" | "throw";
21
+ /** Receives each finding once for a path. Default: `console.error` with the path. */
22
+ report?: (finding: LimitFinding) => void;
23
+ /** The clock for `maxPerSecond`, in ms. Default `performance.now`. */
24
+ now?: () => number;
25
+ };
26
+ /** Thrown by an emit that the guard refused, with `onLimit: "throw"`. */
27
+ export declare class LoopError extends Error {
28
+ readonly limit: LimitFinding["limit"];
29
+ readonly path: string[];
30
+ constructor(finding: LimitFinding);
31
+ }
32
+ /**
33
+ * Cuts a loop while the app runs. It follows the chain of emits that `ctx.emit`
34
+ * makes, across `await` and timers, and refuses the emit that would pass a limit:
35
+ * the same event too often in one chain (`maxRepeats`), or a chain too long
36
+ * (`maxDepth`). Nothing else is touched: other chains go on, and the next emit
37
+ * from outside starts a fresh chain.
38
+ *
39
+ * A refused emit is not sent (`onLimit: "drop"`, the default) or throws a
40
+ * `LoopError`, and is always reported once for each path. The state of the app can
41
+ * be half done when a loop is cut. The plugin needs no tracer and nothing else, so
42
+ * it can stay on in production as a safety net. Returns the same bus.
43
+ *
44
+ * A chain that repeats on purpose (a handler that emits the same event again after
45
+ * a timer, forever) is cut too: list its event in `ignore`.
46
+ *
47
+ * @example
48
+ * ```ts
49
+ * import { createBus } from "nanoeffects";
50
+ * import { loopGuardPlugin } from "nanoeffects/guard";
51
+ *
52
+ * const bus = createBus().use(
53
+ * loopGuardPlugin({ maxRepeats: 50, onLimit: "drop" }),
54
+ * );
55
+ * ```
56
+ */
57
+ export declare const loopGuardPlugin: (options?: LoopGuardOptions) => <E extends EventMap>(bus: Bus<E>) => Bus<E>;
58
+ //#endregion
59
+ export type { LimitFinding, LoopGuardOptions };
package/dist/guard.js ADDED
@@ -0,0 +1 @@
1
+ var e=class extends Error{limit;path;constructor(e){super(`event loop stopped (${e.limit}): ${e.path.join(` → `)}`),this.name=`LoopError`,this.limit=e.limit,this.path=e.path}};const t=e=>typeof e==`string`?e:String(Reflect.get(Object(e),`type`)),n=e=>{if(typeof e==`function`)return e;let t=new Set(e);return e=>t.has(e)},r=(e,t)=>{let n=0;for(let r=e;r;r=r.parent)!r.inner&&r.type===t&&(n+=1);return n},i=(e,t)=>{let n=[];for(let r=e;r&&!(!r.inner&&(n.push(r.type),r.type===t));r=r.parent);return[...n.reverse(),t]},a=(a={})=>s=>{let c=a.maxRepeats??50,l=a.maxDepth??1e3,u=a.onLimit??`drop`,d=n(a.ignore),f=a.now??(()=>globalThis.performance.now()),p=/* @__PURE__ */ new WeakMap,m=/* @__PURE__ */ new Set,h=/* @__PURE__ */ new Map,g,_=!1,v=e=>{let t=`${e.limit}:${e.path.join(`\0`)}`;if(!m.has(t)){m.add(t);try{(a.report??o)(e)}catch(e){globalThis.console?.error(`[nanoeffects] loop guard report failed`,e)}}},y=t=>{if(v(t),u===`throw`)throw new e(t)},b=e=>g?g.depth+1>l?(y({limit:`depth`,path:i(g,e).slice(-20)}),!1):!d(e)&&r(g,e)>=c?(y({limit:`repeats`,path:i(g,e)}),!1):!0:x(e),x=e=>{let t=a.maxPerSecond;if(t===void 0)return!0;let n=f(),r=(h.get(e)??[]).filter(e=>n-e<1e3);return r.length>=t?(h.set(e,r),y({limit:`storm`,path:[e]}),!1):(r.push(n),h.set(e,r),!0)},S=s.addContext;s.addContext=e=>{S?.(e);let t=e,n=g,r=_&&n!==void 0,i={type:t.type,parent:n,depth:n?n.depth+ +!r:0,inner:r};p.set(e,i);let a=t.emit;t.emit=(e,...t)=>{let n=g;g=i;try{return a(e,...t)}finally{g=n}};let o=t.run;t.run=(...e)=>{let t=g,n=_;g=i,_=!0;try{return o(...e)}finally{g=t,_=n}}};let C=s.emit;return s.emit=(e,...n)=>{if(!b(t(e)))return;let r=_;_=!1;try{return C(e,...n)}finally{_=r}},s},o=e=>{globalThis.console?.error(`[nanoeffects] loop guard: ${e.limit} limit reached: ${e.path.join(` → `)}. The emit was refused.`)};export{e as LoopError,a as loopGuardPlugin};
package/dist/index.d.ts CHANGED
@@ -1,2 +1,2 @@
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";
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, Q as UnsubscribeCallback, R as createBus, S as ContextOption, T as EventKey, U as Keys, _ 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-6rlBTmH9.js";
2
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{t as createBus}from"./bus-0uYn_kRj.js";
1
+ export{t as createBus}from"./bus-DFlmNJ6h.js";
package/dist/match.d.ts CHANGED
@@ -1,4 +1,4 @@
1
- import { D as EventPayload, H as EventMap, Z as UnsubscribeCallback, h as Action, q as Task, v as Bus } from "./action-creator-jeEqIKgK.js";
1
+ import { D as EventPayload, H as EventMap, Q as UnsubscribeCallback, h as Action, q as Task, v as Bus } from "./action-creator-6rlBTmH9.js";
2
2
  //#region src/match/plugin.d.ts
3
3
  /** A function over the action of an event: `{ type, payload }`. */
4
4
  type Predicate<E extends EventMap> = (action: Action<E>) => boolean;
@@ -1,5 +1,5 @@
1
- import { A as HandledCall, G as PayloadOf, H as EventMap, Z as UnsubscribeCallback, b as Context, c as Scope, g as Actions, k as Handled, q as Task, u as WithScope, v as Bus, z as handledCall } from "./action-creator-jeEqIKgK.js";
2
- import { n as ScopeSlots, r as Scoped } from "./types-D5xsR37j.js";
1
+ import { A as HandledCall, G as PayloadOf, H as EventMap, Q as UnsubscribeCallback, b as Context, c as Scope, g as Actions, k as Handled, q as Task, u as WithScope, v as Bus, z as handledCall } from "./action-creator-6rlBTmH9.js";
2
+ import { n as ScopeSlots, r as Scoped } from "./types-N_cdRr1r.js";
3
3
  //#region src/actions/handled.d.ts
4
4
  /** What `createAction` returns: an action that also tells whether an action is of its type. */
5
5
  type MadeHandled<P, R, T extends string> = Handled<P, R> & {
@@ -54,6 +54,7 @@ interface Tracer<Ref extends object = object> {
54
54
  type: string;
55
55
  payload?: unknown;
56
56
  traceGroupId?: string;
57
+ leaf?: boolean;
57
58
  }, parent?: Ref): Ref;
58
59
  /** Gives the task another `type`, for a task that is named after it was made (a named listener). A tracer may leave it out. */
59
60
  rename?(ref: Ref, type: string): void;
@@ -1,5 +1,5 @@
1
- import { B as Task, D as HandledCall, E as Handled, I as handledCall, L as EventMap, S as EventKey, V as UnsubscribeCallback, _ as Context, c as WithScope, d as Effects, h as Bus, i as FreeActionCreator, n as Call, o as Scope, p as Actions, r as Free, s as WithFields, t as ActionCreator, z as PayloadOf } from "./action-creator-xpQ_I2h8.js";
2
- import { t as BoundOf } from "./plugin-6LhNx0th.js";
1
+ import { B as Task, D as HandledCall, E as Handled, I as handledCall, L as EventMap, S as EventKey, V as UnsubscribeCallback, _ as Context, c as WithScope, d as Effects, h as Bus, i as FreeActionCreator, n as Call, o as Scope, p as Actions, r as Free, s as WithFields, t as ActionCreator, z as PayloadOf } from "./action-creator-BrMSO3RP.js";
2
+ import { t as BoundOf } from "./plugin-7GUL2EW5.js";
3
3
  import { t as OriginOptions } from "./origin-key-CxK0SkeG.js";
4
4
  //#region src/scope/types.d.ts
5
5
  /**
@@ -1,5 +1,5 @@
1
- import { B as Task, L as EventMap, N as WithSignal, _ as Context, u as Effect } from "./action-creator-xpQ_I2h8.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-6LhNx0th.js";
1
+ import { B as Task, L as EventMap, N as WithSignal, _ as Context, u as Effect } from "./action-creator-BrMSO3RP.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-7GUL2EW5.js";
3
3
  //#region src/utils/onAbort.d.ts
4
4
  export declare const onAbort: (ctx: {
5
5
  signal?: AbortSignal | undefined;
@@ -1,2 +1,2 @@
1
- import { A as Off, B as Task, C as EventLike, D as HandledCall, E as Handled, F as createBus, L as EventMap, M as WithContext, N as WithSignal, O as Handler, P as WithType, R as Keys, S as EventKey, T as EventsOf, V as UnsubscribeCallback, _ as Context, a as WithPayload, b as Emit, f as Action, g as BusOptions, h as Bus, j as On, k as HandlerRef, m as AnyEvent, n as Call, p as Actions, v as ContextOf, w as EventPayload, x as Emittable, y as ContextOption, z as PayloadOf } from "./action-creator-xpQ_I2h8.js";
1
+ import { A as Off, B as Task, C as EventLike, D as HandledCall, E as Handled, F as createBus, L as EventMap, M as WithContext, N as WithSignal, O as Handler, P as WithType, R as Keys, S as EventKey, T as EventsOf, V as UnsubscribeCallback, _ as Context, a as WithPayload, b as Emit, f as Action, g as BusOptions, h as Bus, j as On, k as HandlerRef, m as AnyEvent, n as Call, p as Actions, v as ContextOf, w as EventPayload, x as Emittable, y as ContextOption, z as PayloadOf } from "./action-creator-BrMSO3RP.js";
2
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 };
@@ -1,4 +1,4 @@
1
- import { L as EventMap, M as WithContext, R as Keys, _ as Context, d as Effects, h as Bus, i as FreeActionCreator, l as BoundForm, t as ActionCreator, v as ContextOf } from "./action-creator-xpQ_I2h8.js";
1
+ import { L as EventMap, M as WithContext, R as Keys, _ as Context, d as Effects, h as Bus, i as FreeActionCreator, l as BoundForm, t as ActionCreator, v as ContextOf } from "./action-creator-BrMSO3RP.js";
2
2
  //#region src/core/context-types.d.ts
3
3
  /**
4
4
  * `unknown` when none of the `fields` is already a context field of the bus,
@@ -1,4 +1,4 @@
1
- import { B as Task, L as EventMap, z as PayloadOf } from "./action-creator-xpQ_I2h8.js";
1
+ import { B as Task, L as EventMap, z as PayloadOf } from "./action-creator-BrMSO3RP.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> = {
@@ -1,4 +1,4 @@
1
- import { L as EventMap, h as Bus } from "./action-creator-xpQ_I2h8.js";
1
+ import { L as EventMap, h as Bus } from "./action-creator-BrMSO3RP.js";
2
2
  import { t as OriginOptions } from "./origin-key-CxK0SkeG.js";
3
3
  //#region src/store/redux/middleware.d.ts
4
4
  /** What Redux passes through a middleware: an action is a plain object with a `type`. */
@@ -1,4 +1,4 @@
1
- import { H as EventMap, P as On, U as Keys, a as FreeActionCreator, k as Handled, r as DataOf, t as ActionCreator, v as Bus } from "./action-creator-jeEqIKgK.js";
1
+ import { H as EventMap, P as On, U as Keys, a as FreeActionCreator, k as Handled, r as DataOf, t as ActionCreator, v as Bus } from "./action-creator-6rlBTmH9.js";
2
2
  //#region src/observable.d.ts
3
3
  declare global {
4
4
  interface SymbolConstructor {
package/dist/oop.d.ts CHANGED
@@ -1,4 +1,4 @@
1
- import { H as EventMap, W as ListenerOptions, k as Handled, t as ActionCreator, v as Bus } from "./action-creator-jeEqIKgK.js";
1
+ import { H as EventMap, W as ListenerOptions, k as Handled, t as ActionCreator, v as Bus } from "./action-creator-6rlBTmH9.js";
2
2
  //#region src/oop/types.d.ts
3
3
  type Slots = "ctx" | "actions" | "trace" | "addContext" | "applyScope" | "fitScope" | "app" | "use";
4
4
  type AnyFunction = (...args: never[]) => unknown;
package/dist/oop.js CHANGED
@@ -1 +1 @@
1
- import{t as e}from"./bus-0uYn_kRj.js";const t=/* @__PURE__ */ new WeakMap,n=e=>typeof e==`function`,r=e=>Reflect.ownKeys(e).flatMap(t=>{let r=Reflect.getOwnPropertyDescriptor(e,t)?.value;return n(r)?[{key:t,value:r}]:[]}),i=/* @__PURE__ */ new WeakMap,a=e=>{let n=i.get(e);if(n)return n;let a=/* @__PURE__ */ new Set,o=[];for(let n=e;n&&n!==Object.prototype;n=Reflect.getPrototypeOf(n))for(let{key:e,value:i}of r(n)){if(e===`constructor`||a.has(e))continue;a.add(e);let n=t.get(i);n&&o.push({key:e,method:i,spec:n})}return i.set(e,o),o},o=/* @__PURE__ */ new WeakMap,s=e=>typeof e==`object`&&!!e||typeof e==`function`,c=e=>{let t=o.get(e);if(t)return t;let n=/* @__PURE__ */ new Set;return o.set(e,n),n},l=e=>{if(typeof e==`string`)return e;if(s(e)){let t=Reflect.get(e,`type`);return typeof t==`string`?t:e}return e},u=(e,t,n)=>Reflect.apply(Reflect.get(e,t),e,n),d=(e,t,n,r)=>{let[i,a,...o]=r,s=c(e),l={event:i,handler:a,off:()=>{}},d=u(t,n,[i,n===`once`?(e,t)=>(s.delete(l),typeof a==`function`?Reflect.apply(a,null,[e,t]):void 0):a,...o]),f=typeof d==`function`?()=>d():()=>{};return l.off=f,s.add(l),()=>{s.delete(l),f()}},f=(e,t,n)=>{let[r,i]=n,a=c(e);r===void 0&&a.clear();for(let e of[...a])Object.is(l(e.event),l(r))&&(i===void 0||e.handler===i)&&(a.delete(e),e.off());return u(t,`off`,n)},p=e=>{if(!s(e))return;let t=o.get(e);if(t){o.delete(e);for(let e of t)e.off()}},m=/* @__PURE__ */ new Set([`on`,`once`,`off`,`emit`,`ctx`,`actions`,`trace`,`addContext`,`applyScope`,`fitScope`,`app`,`use`]),h=Reflect.get(Symbol,`dispose`),g=e=>typeof e==`function`;var _=class{};const v=(e,t,n,r)=>{n in t||Object.defineProperty(e,n,{configurable:!0,enumerable:!1,...r})},y=/* @__PURE__ */ new WeakMap,b=(e,t)=>{let n=y.get(e);if(n)return n;let r={on:(...n)=>d(e,t,`on`,n),once:(...n)=>d(e,t,`once`,n),off:(...n)=>f(e,t,n)};return y.set(e,r),r},x=(e,t)=>(...n)=>Reflect.apply(Reflect.get(e,t),e,n),S=(e,t)=>{for(let{method:n,spec:r}of a(Reflect.getPrototypeOf(e)??{})){let i=(t,r)=>Reflect.apply(n,e,[t,r]),a=r.wrap?r.wrap(i):i,o=r.once?`once`:`on`;d(e,t,o,[r.event,a,r.options])}},C=(e,t,n)=>{for(let r of[`on`,`once`,`off`])v(e,t,r,{get(){return b(this,n)[r]}});v(e,t,`emit`,{value:x(n,`emit`)});for(let[r,i]of Object.entries(n))typeof i==`function`&&!m.has(r)&&v(e,t,r,{value:x(n,r)});let r=function(){p(this)};v(e,t,`dispose`,{value:r}),h&&v(e,t,h,{value:r}),v(e,t,`bus`,{get:()=>n})},w=(e,t)=>{let n=function(...r){let i=Reflect.construct(t,r,new.target??n);return S(i,e),i};return Object.setPrototypeOf(n,t),n.prototype=Object.create(t.prototype,{constructor:{value:n,writable:!0,configurable:!0}}),Object.defineProperty(n,"name",{value:t.name,configurable:!0}),`bus`in t||Object.defineProperty(n,"bus",{value:e,configurable:!0}),C(n.prototype,t.prototype,e),n};function T(t,n){return g(t)?w(e(),t):w(t,n??_)}function E(e){return t=>e?T(e,t):T(t)}const D=e=>{let[t,n,r]=e;return typeof n==`string`||typeof n==`symbol`?Reflect.get(Object(r),`value`):t},O=(e,n,r,i)=>((...a)=>{let o=D(a);if(typeof o==`function`){let a=typeof n==`function`?n:void 0,s=typeof n==`function`?r:n??r;t.set(o,{event:e,wrap:a,once:i,options:s})}});function k(e,t,n){return O(e,t,n,!1)}function A(e,t,n){return O(e,t,n,!0)}const j=/* @__PURE__ */ new WeakMap,M=t=>{let n=j.get(t);if(n)return n;let r=e();return j.set(t,r),r},N=[`on`,`once`,`off`,`emit`],P=e=>{for(let t of N){let n=Reflect.get(e,t);Reflect.set(e,t,n.bind(e))}};var F=class{constructor(){P(this),S(this,M(this))}get bus(){return M(this)}dispose(){p(this)}};const I={on(...e){return d(this,M(this),`on`,e)},once(...e){return d(this,M(this),`once`,e)},off(...e){return f(this,M(this),e)},emit(...e){let t=M(this);return Reflect.apply(Reflect.get(t,`emit`),t,e)}};for(let e of N)Object.defineProperty(F.prototype,e,{configurable:!0,writable:!0,value:I[e]});h&&Object.defineProperty(F.prototype,h,{configurable:!0,value:function(){this.dispose()}});export{F as Emitter,k as On,A as Once,E as WithBus,p as disposeBus,T as extendBus};
1
+ import{t as e}from"./bus-DFlmNJ6h.js";const t=/* @__PURE__ */ new WeakMap,n=e=>typeof e==`function`,r=e=>Reflect.ownKeys(e).flatMap(t=>{let r=Reflect.getOwnPropertyDescriptor(e,t)?.value;return n(r)?[{key:t,value:r}]:[]}),i=/* @__PURE__ */ new WeakMap,a=e=>{let n=i.get(e);if(n)return n;let a=/* @__PURE__ */ new Set,o=[];for(let n=e;n&&n!==Object.prototype;n=Reflect.getPrototypeOf(n))for(let{key:e,value:i}of r(n)){if(e===`constructor`||a.has(e))continue;a.add(e);let n=t.get(i);n&&o.push({key:e,method:i,spec:n})}return i.set(e,o),o},o=/* @__PURE__ */ new WeakMap,s=e=>typeof e==`object`&&!!e||typeof e==`function`,c=e=>{let t=o.get(e);if(t)return t;let n=/* @__PURE__ */ new Set;return o.set(e,n),n},l=e=>{if(typeof e==`string`)return e;if(s(e)){let t=Reflect.get(e,`type`);return typeof t==`string`?t:e}return e},u=(e,t,n)=>Reflect.apply(Reflect.get(e,t),e,n),d=(e,t,n,r)=>{let[i,a,...o]=r,s=c(e),l={event:i,handler:a,off:()=>{}},d=u(t,n,[i,n===`once`?(e,t)=>(s.delete(l),typeof a==`function`?Reflect.apply(a,null,[e,t]):void 0):a,...o]),f=typeof d==`function`?()=>d():()=>{};return l.off=f,s.add(l),()=>{s.delete(l),f()}},f=(e,t,n)=>{let[r,i]=n,a=c(e);r===void 0&&a.clear();for(let e of[...a])Object.is(l(e.event),l(r))&&(i===void 0||e.handler===i)&&(a.delete(e),e.off());return u(t,`off`,n)},p=e=>{if(!s(e))return;let t=o.get(e);if(t){o.delete(e);for(let e of t)e.off()}},m=/* @__PURE__ */ new Set([`on`,`once`,`off`,`emit`,`ctx`,`actions`,`trace`,`addContext`,`applyScope`,`fitScope`,`app`,`use`]),h=Reflect.get(Symbol,`dispose`),g=e=>typeof e==`function`;var _=class{};const v=(e,t,n,r)=>{n in t||Object.defineProperty(e,n,{configurable:!0,enumerable:!1,...r})},y=/* @__PURE__ */ new WeakMap,b=(e,t)=>{let n=y.get(e);if(n)return n;let r={on:(...n)=>d(e,t,`on`,n),once:(...n)=>d(e,t,`once`,n),off:(...n)=>f(e,t,n)};return y.set(e,r),r},x=(e,t)=>(...n)=>Reflect.apply(Reflect.get(e,t),e,n),S=(e,t)=>{for(let{method:n,spec:r}of a(Reflect.getPrototypeOf(e)??{})){let i=(t,r)=>Reflect.apply(n,e,[t,r]),a=r.wrap?r.wrap(i):i,o=r.once?`once`:`on`;d(e,t,o,[r.event,a,r.options])}},C=(e,t,n)=>{for(let r of[`on`,`once`,`off`])v(e,t,r,{get(){return b(this,n)[r]}});v(e,t,`emit`,{value:x(n,`emit`)});for(let[r,i]of Object.entries(n))typeof i==`function`&&!m.has(r)&&v(e,t,r,{value:x(n,r)});let r=function(){p(this)};v(e,t,`dispose`,{value:r}),h&&v(e,t,h,{value:r}),v(e,t,`bus`,{get:()=>n})},w=(e,t)=>{let n=function(...r){let i=Reflect.construct(t,r,new.target??n);return S(i,e),i};return Object.setPrototypeOf(n,t),n.prototype=Object.create(t.prototype,{constructor:{value:n,writable:!0,configurable:!0}}),Object.defineProperty(n,"name",{value:t.name,configurable:!0}),`bus`in t||Object.defineProperty(n,"bus",{value:e,configurable:!0}),C(n.prototype,t.prototype,e),n};function T(t,n){return g(t)?w(e(),t):w(t,n??_)}function E(e){return t=>e?T(e,t):T(t)}const D=e=>{let[t,n,r]=e;return typeof n==`string`||typeof n==`symbol`?Reflect.get(Object(r),`value`):t},O=(e,n,r,i)=>((...a)=>{let o=D(a);if(typeof o==`function`){let a=typeof n==`function`?n:void 0,s=typeof n==`function`?r:n??r;t.set(o,{event:e,wrap:a,once:i,options:s})}});function k(e,t,n){return O(e,t,n,!1)}function A(e,t,n){return O(e,t,n,!0)}const j=/* @__PURE__ */ new WeakMap,M=t=>{let n=j.get(t);if(n)return n;let r=e();return j.set(t,r),r},N=[`on`,`once`,`off`,`emit`],P=e=>{for(let t of N){let n=Reflect.get(e,t);Reflect.set(e,t,n.bind(e))}};var F=class{constructor(){P(this),S(this,M(this))}get bus(){return M(this)}dispose(){p(this)}};const I={on(...e){return d(this,M(this),`on`,e)},once(...e){return d(this,M(this),`once`,e)},off(...e){return f(this,M(this),e)},emit(...e){let t=M(this);return Reflect.apply(Reflect.get(t,`emit`),t,e)}};for(let e of N)Object.defineProperty(F.prototype,e,{configurable:!0,writable:!0,value:I[e]});h&&Object.defineProperty(F.prototype,h,{configurable:!0,value:function(){this.dispose()}});export{F as Emitter,k as On,A as Once,E as WithBus,p as disposeBus,T as extendBus};
@@ -1,5 +1,5 @@
1
- import { F as WithContext, H as EventMap, U as Keys, a as FreeActionCreator, b as Context, d as BoundForm, p as Effects, t as ActionCreator, v as Bus } from "./action-creator-jeEqIKgK.js";
2
- import { r as NoClash } from "./context-types-Bme1mzkn.js";
1
+ import { F as WithContext, H as EventMap, U as Keys, a as FreeActionCreator, b as Context, d as BoundForm, p as Effects, t as ActionCreator, v as Bus } from "./action-creator-6rlBTmH9.js";
2
+ import { r as NoClash } from "./context-types-DKNc5mkS.js";
3
3
  //#region src/utils/delay.d.ts
4
4
  type Milliseconds = number | (() => number);
5
5
  /**
@@ -1,5 +1,5 @@
1
- import { H as EventMap, q as Task } from "./action-creator-jeEqIKgK.js";
2
- import { n as withPolicy, t as PolicyFunction } from "./with-policy-BZVRBUOm.js";
1
+ import { H as EventMap, q as Task } from "./action-creator-6rlBTmH9.js";
2
+ import { n as withPolicy, t as PolicyFunction } from "./with-policy-CthiBp_z.js";
3
3
  //#region src/policies/keyed.d.ts
4
4
  /** Options shared by every policy that can keep its state per key. */
5
5
  type KeyOption<P> = {
package/dist/policies.js CHANGED
@@ -1 +1 @@
1
- import{n as e,r as t,t as n}from"./delay-5OhJZZQ0.js";import{t as r}from"./onAbort-BgMfspK4.js";import{i,o as a,s as o,t as s}from"./context-DtUnzC-1.js";import{n as c,t as l}from"./promise-CSLpzwSR.js";import{n as u,t as d}from"./lifecycle-key-8iX8RUVD.js";import{t as f}from"./with-policy-C6BIiPIi.js";const p=e=>Reflect.get(e,d),m=e=>{p(e)?.start()},h=(e,t,n)=>(m(e),a(e,t,n)),g=(e,t)=>{o(e,t,`drop`),p(e)?.drop()},_=(e,t)=>{p(e)?.done(t)},v=(e,t,n)=>{let r=p(e);t?r?.cancel(n):r?.drop()},y=e=>(Reflect.set(e,u,!0),e),b=()=>{},x=(e,t,n)=>typeof e==`function`?n(e,t??{}):t=>n(t,e??{}),S=(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)}},C=(e,t)=>y(e?S(e,t):t(b));function w(e,t){return x(e,t,T)}const T=(e,t)=>C(t.key,t=>E(`latest`,(t,n,r)=>(r(),e(t,n)),t)),E=(e,t,n=b)=>{let a=null;return(l,u)=>{if(a?.abort(),u.signal.aborted)return;let{ctx:d,unlink:f}=i(u);a=d;let p=s(d,e),h=!1,g=()=>{d.signal.aborted||(h=!0,m(d),o(d,e,`start`))};r(d,e=>{v(d,h,e),p(h?`cancel`:`drop`)});let _=()=>{f(),a===d&&(a=null,n())},y=e=>{if(!d.signal.aborted)return p(h?`done`:`drop`),e};try{let e=t(l,d,g);return c(e)?Promise.resolve(e).then(y,e=>{if(!d.signal.aborted)throw p(`error`,e),e}).finally(_):(_(),y(e))}catch(e){if(_(),d.signal.aborted)return;throw p(`error`,e),e}}};function D(e,t,n){return x(t,n,(t,n)=>O(e,t,n))}const O=(e,t,n)=>C(n.key,r=>A(e,t,n,r)),k=(n,r,i,a)=>{let o=a!==b,s=null,c=null;return(l,u)=>{if(u.signal.aborted)return;let d=Date.now(),f=s===null||d-s>=n||d-s<0;return s=d,c!==null&&e(c),c=o?t(a,n):null,i&&f?Promise.resolve(h(u,`debounce`,()=>r(l,u))):(g(u,`debounce`),Promise.resolve(void 0))}},A=(e,t,i,a)=>{let o=i.leading??!1,s=i.trailing??!0;if(!s)return k(e,t,o,a);let c=!1,l=0,u=E(`debounce`,([i,a],o,u)=>{let d=l;return r(o,()=>{l===d&&(c=!1)}),n(o,e).then(()=>{if(c=!1,s&&!a)return u(),t(i,o)})},a);return(e,n)=>{if(n.signal.aborted)return;let r=o&&!c;c=!0,l++;let i=u([e,r],n);return r?Promise.resolve(h(n,`debounce`,()=>t(e,n))):i}};function j(e,t){return x(e,t,M)}const M=(e,t)=>C(t.key,t=>{let n=null;return(i,a)=>{if(a.signal.aborted)return;if(n){g(a,`leading`);return}let o={};n=o;let s=()=>{c(),n===o&&(n=null,t())},c=r(a,s);try{return l(h(a,`leading`,()=>e(i,a)),s)}catch(e){throw s(),e}}});function N(e,t){return x(e,t,P)}const P=(e,t)=>C(t.key,n=>F(e,t,n)),F=(e,t,n)=>{let i=t.concurrency??1,a=t.limit??1/0,o=[],s=0,c=()=>{for(;s<i;){let e=o.shift();if(!e)return;e.start()}};return(l,u)=>new Promise((d,f)=>{if(u.signal.aborted){d(void 0);return}let p=b,m=()=>{p(),g(u,`queue`),d(void 0)},v=()=>{if(p(),u.signal.aborted){m();return}s++;let t=!0,i=()=>{c(),s===0&&o.length===0&&n()},a=(e=!1)=>{t&&(t=!1,s--,e?queueMicrotask(i):i())},g=r(u,()=>{a(!0),d(void 0)}),v;try{v=Promise.resolve(h(u,`queue`,()=>e(l,u)))}catch(e){v=Promise.reject(e)}let y=()=>{g(),a()};v.then(e=>{_(u,{value:e}),y(),d(u.signal.aborted?void 0:e)},e=>{_(u,{error:e}),y(),u.signal.aborted?d(void 0):f(e)})};if(s<i){v();return}if(o.length>=a){if(t.overflow!==`drop-old`||a<=0){m();return}o.shift()?.drop()}let y={start:v,drop:m};o.push(y),p=r(u,()=>{let e=o.indexOf(y);e>=0&&o.splice(e,1),m()})})};function I(e,t,n){return x(t,n,(t,n)=>L(e,t,n))}const L=(e,t,n)=>C(n.key,r=>R(e,t,n,r)),R=(n,r,i,a)=>{let o=i.leading??!0,s=i.trailing??!0,c=a!==b,l=null,u=0,d=null,f=null,p=null,m=!1,_=e=>l===null||e-l>=n||e-l<0||e-u>=n,v=e=>g(e,`throttle`),y=()=>{let e=p;p=null,e&&(v(e.ctx),e.resolve())},x=(e,t)=>(y(),new Promise((n,r)=>{p={payload:e,ctx:t,resolve:n,reject:r}})),S=(e,t,n)=>{y(),u=n,m=!0;try{return h(t,`throttle`,()=>r(e,t))}finally{m=!1}},C=()=>{c&&(f=t(w,n))},w=()=>{if(f=null,!c||d!==null||p)return;let e=Date.now(),r=Math.max(n-(e-(l??-1/0)),n-(e-u));r<=0?a():f=t(w,r)},T=e=>{d=null;let t=p;if(s&&t&&!t.ctx.signal.aborted){p=null;try{t.resolve(S(t.payload,t.ctx,e))}catch(e){t.reject(e)}}else y();w()},E=()=>{let e=Date.now();_(e)?T(e):d=t(E,Math.min(n-(e-(l??e)),n-(e-u)))},D=()=>{f!==null&&(e(f),f=null)},O=(e,t)=>{if(!s)v(t);else return x(e,t)},k=(e,t,n,r)=>{if(!r)v(t);else if(u=n,C(),!o)v(t);else return S(e,t,n)},A=(r,i,a,s)=>s&&d!==null?(e(d),d=t(E,n),S(r,i,a)):d===null&&(d=t(E,n),s&&(u=a,o))?S(r,i,a):O(r,i);return(e,t)=>{if(t.signal.aborted)return;let n=Date.now(),r=!m&&_(n);return l=n,D(),s?A(e,t,n,r):k(e,t,n,r)}};export{D as debounce,w as latest,j as leading,N as queue,I as throttle,f as withPolicy};
1
+ import{n as e,r as t,t as n}from"./delay-5OhJZZQ0.js";import{t as r}from"./onAbort-BgMfspK4.js";import{i,o as a,s as o,t as s}from"./context-B5Z2RpJt.js";import{n as c,t as l}from"./promise-CSLpzwSR.js";import{n as u,t as d}from"./lifecycle-key-8iX8RUVD.js";import{t as f}from"./with-policy-CeM1rtES.js";const p=e=>Reflect.get(e,d),m=e=>{p(e)?.start()},h=(e,t,n)=>(m(e),a(e,t,n)),g=(e,t)=>{o(e,t,`drop`),p(e)?.drop()},_=(e,t)=>{p(e)?.done(t)},v=(e,t,n)=>{let r=p(e);t?r?.cancel(n):r?.drop()},y=e=>(Reflect.set(e,u,!0),e),b=()=>{},x=(e,t,n)=>typeof e==`function`?n(e,t??{}):t=>n(t,e??{}),S=(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)}},C=(e,t)=>y(e?S(e,t):t(b));function w(e,t){return x(e,t,T)}const T=(e,t)=>C(t.key,t=>E(`latest`,(t,n,r)=>(r(),e(t,n)),t)),E=(e,t,n=b)=>{let a=null;return(l,u)=>{if(a?.abort(),u.signal.aborted)return;let{ctx:d,unlink:f}=i(u);a=d;let p=s(d,e),h=!1,g=()=>{d.signal.aborted||(h=!0,m(d),o(d,e,`start`))};r(d,e=>{v(d,h,e),p(h?`cancel`:`drop`)});let _=()=>{f(),a===d&&(a=null,n())},y=e=>{if(!d.signal.aborted)return p(h?`done`:`drop`),e};try{let e=t(l,d,g);return c(e)?Promise.resolve(e).then(y,e=>{if(!d.signal.aborted)throw p(`error`,e),e}).finally(_):(_(),y(e))}catch(e){if(_(),d.signal.aborted)return;throw p(`error`,e),e}}};function D(e,t,n){return x(t,n,(t,n)=>O(e,t,n))}const O=(e,t,n)=>C(n.key,r=>A(e,t,n,r)),k=(n,r,i,a)=>{let o=a!==b,s=null,c=null;return(l,u)=>{if(u.signal.aborted)return;let d=Date.now(),f=s===null||d-s>=n||d-s<0;return s=d,c!==null&&e(c),c=o?t(a,n):null,i&&f?Promise.resolve(h(u,`debounce`,()=>r(l,u))):(g(u,`debounce`),Promise.resolve(void 0))}},A=(e,t,i,a)=>{let o=i.leading??!1,s=i.trailing??!0;if(!s)return k(e,t,o,a);let c=!1,l=0,u=E(`debounce`,([i,a],o,u)=>{let d=l;return r(o,()=>{l===d&&(c=!1)}),n(o,e).then(()=>{if(c=!1,s&&!a)return u(),t(i,o)})},a);return(e,n)=>{if(n.signal.aborted)return;let r=o&&!c;c=!0,l++;let i=u([e,r],n);return r?Promise.resolve(h(n,`debounce`,()=>t(e,n))):i}};function j(e,t){return x(e,t,M)}const M=(e,t)=>C(t.key,t=>{let n=null;return(i,a)=>{if(a.signal.aborted)return;if(n){g(a,`leading`);return}let o={};n=o;let s=()=>{c(),n===o&&(n=null,t())},c=r(a,s);try{return l(h(a,`leading`,()=>e(i,a)),s)}catch(e){throw s(),e}}});function N(e,t){return x(e,t,P)}const P=(e,t)=>C(t.key,n=>F(e,t,n)),F=(e,t,n)=>{let i=t.concurrency??1,a=t.limit??1/0,o=[],s=0,c=()=>{for(;s<i;){let e=o.shift();if(!e)return;e.start()}};return(l,u)=>new Promise((d,f)=>{if(u.signal.aborted){d(void 0);return}let p=b,m=()=>{p(),g(u,`queue`),d(void 0)},v=()=>{if(p(),u.signal.aborted){m();return}s++;let t=!0,i=()=>{c(),s===0&&o.length===0&&n()},a=(e=!1)=>{t&&(t=!1,s--,e?queueMicrotask(i):i())},g=r(u,()=>{a(!0),d(void 0)}),v;try{v=Promise.resolve(h(u,`queue`,()=>e(l,u)))}catch(e){v=Promise.reject(e)}let y=()=>{g(),a()};v.then(e=>{_(u,{value:e}),y(),d(u.signal.aborted?void 0:e)},e=>{_(u,{error:e}),y(),u.signal.aborted?d(void 0):f(e)})};if(s<i){v();return}if(o.length>=a){if(t.overflow!==`drop-old`||a<=0){m();return}o.shift()?.drop()}let y={start:v,drop:m};o.push(y),p=r(u,()=>{let e=o.indexOf(y);e>=0&&o.splice(e,1),m()})})};function I(e,t,n){return x(t,n,(t,n)=>L(e,t,n))}const L=(e,t,n)=>C(n.key,r=>R(e,t,n,r)),R=(n,r,i,a)=>{let o=i.leading??!0,s=i.trailing??!0,c=a!==b,l=null,u=0,d=null,f=null,p=null,m=!1,_=e=>l===null||e-l>=n||e-l<0||e-u>=n,v=e=>g(e,`throttle`),y=()=>{let e=p;p=null,e&&(v(e.ctx),e.resolve())},x=(e,t)=>(y(),new Promise((n,r)=>{p={payload:e,ctx:t,resolve:n,reject:r}})),S=(e,t,n)=>{y(),u=n,m=!0;try{return h(t,`throttle`,()=>r(e,t))}finally{m=!1}},C=()=>{c&&(f=t(w,n))},w=()=>{if(f=null,!c||d!==null||p)return;let e=Date.now(),r=Math.max(n-(e-(l??-1/0)),n-(e-u));r<=0?a():f=t(w,r)},T=e=>{d=null;let t=p;if(s&&t&&!t.ctx.signal.aborted){p=null;try{t.resolve(S(t.payload,t.ctx,e))}catch(e){t.reject(e)}}else y();w()},E=()=>{let e=Date.now();_(e)?T(e):d=t(E,Math.min(n-(e-(l??e)),n-(e-u)))},D=()=>{f!==null&&(e(f),f=null)},O=(e,t)=>{if(!s)v(t);else return x(e,t)},k=(e,t,n,r)=>{if(!r)v(t);else if(u=n,C(),!o)v(t);else return S(e,t,n)},A=(r,i,a,s)=>s&&d!==null?(e(d),d=t(E,n),S(r,i,a)):d===null&&(d=t(E,n),s&&(u=a,o))?S(r,i,a):O(r,i);return(e,t)=>{if(t.signal.aborted)return;let n=Date.now(),r=!m&&_(n);return l=n,D(),s?A(e,t,n,r):k(e,t,n,r)}};export{D as debounce,w as latest,j as leading,N as queue,I as throttle,f as withPolicy};
@@ -1 +1 @@
1
- const e=()=>{},t=()=>e,n=()=>t;export{n as devPlugin};
1
+ const e=()=>{},t=()=>e,n=()=>t,r=async()=>[],i=async()=>0;export{n as devPlugin,r as getLostSignals,i as getLostSignalsCount};
package/dist/react.d.ts CHANGED
@@ -1,6 +1,6 @@
1
- import { H as EventMap, T as EventKey, a as FreeActionCreator, q as Task, t as ActionCreator, v as Bus } from "./action-creator-jeEqIKgK.js";
1
+ import { H as EventMap, T as EventKey, a as FreeActionCreator, q as Task, t as ActionCreator, v as Bus } from "./action-creator-6rlBTmH9.js";
2
2
  import { t as OriginOptions } from "./origin-key-CxK0SkeG.js";
3
- import { t as PolicyFunction } from "./with-policy-BZVRBUOm.js";
3
+ import { t as PolicyFunction } from "./with-policy-CthiBp_z.js";
4
4
  import { t as StateOf } from "./state-of-C19H6BoV.js";
5
5
  //#region src/react/plugin.d.ts
6
6
  /** Tells whether two values are the same: `Object.is` unless the caller gives another. */
package/dist/react.js CHANGED
@@ -1 +1 @@
1
- import{t as e}from"./with-policy-C6BIiPIi.js";import{t}from"./origin-key-BbWN3gmN.js";import{useEffect as n,useMemo as r,useRef as i,useState as a}from"react";const o=()=>e=>{function r(r,a,o){let s=i(a),c=i({event:r,options:o});n(()=>{c.current={event:r,options:o}}),n(()=>{let{event:n,options:r}=c.current,i=r?.equals??Object.is,o=s.current;if(i(o,a))return;s.current=a;let l=typeof n==`function`?n(a):{type:n,payload:a},u=Reflect.get(e,t);u?u(l,r??{}):e.emit(l)},[a])}function o(t,r){let[i,o]=a(r);return n(()=>{let n=t;return e.on(n,e=>{let t=e;o(()=>t)})},[t]),[i,o]}return Object.assign(e,{useEmitter:r,useEventState:o})},s=(t,a,o=[])=>{let s=i(t);n(()=>{s.current=t});let c=r(()=>e(a((e,t)=>s.current(e,t))),o);return n(()=>()=>c.cancel(),[c]),c};export{o as reactPlugin,s as usePolicy};
1
+ import{t as e}from"./with-policy-CeM1rtES.js";import{t}from"./origin-key-BbWN3gmN.js";import{useEffect as n,useMemo as r,useRef as i,useState as a}from"react";const o=()=>e=>{function r(r,a,o){let s=i(a),c=i({event:r,options:o});n(()=>{c.current={event:r,options:o}}),n(()=>{let{event:n,options:r}=c.current,i=r?.equals??Object.is,o=s.current;if(i(o,a))return;s.current=a;let l=typeof n==`function`?n(a):{type:n,payload:a},u=Reflect.get(e,t);u?u(l,r??{}):e.emit(l)},[a])}function o(t,r){let[i,o]=a(r);return n(()=>{let n=t;return e.on(n,e=>{let t=e;o(()=>t)})},[t]),[i,o]}return Object.assign(e,{useEmitter:r,useEventState:o})},s=(t,a,o=[])=>{let s=i(t);n(()=>{s.current=t});let c=r(()=>e(a((e,t)=>s.current(e,t))),o);return n(()=>()=>c.cancel(),[c]),c};export{o as reactPlugin,s as usePolicy};
package/dist/redux.d.ts CHANGED
@@ -1,4 +1,4 @@
1
- import { H as EventMap, v as Bus } from "./action-creator-jeEqIKgK.js";
1
+ import { H as EventMap, v as Bus } from "./action-creator-6rlBTmH9.js";
2
2
  import { t as OriginOptions } from "./origin-key-CxK0SkeG.js";
3
3
  //#region src/store/redux/middleware.d.ts
4
4
  /** What Redux passes through a middleware: an action is a plain object with a `type`. */