nanoeffects 0.13.0 → 0.14.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 CHANGED
@@ -87,8 +87,9 @@ Start with the [Guide](docs/guide.md) (bus → policies → effects → modules)
87
87
  | Retry, timeout, wait for events | [Effects](docs/effects.md) |
88
88
  | Domain logic off the UI | [Actions, commands, modules](docs/actions.md) |
89
89
  | Redux / Zustand / MobX | [Stores](docs/stores.md) |
90
+ | See what ran and why (console, Redux DevTools) | [Tracing](docs/tracing.md) |
90
91
 
91
- [Full index, package entries, tracing](docs/README.md) · [Examples](examples/README.md) · [Why nanoeffects exists](docs/motivation.md)
92
+ [Full index and package entries](docs/README.md) · [Examples](examples/README.md) · [Why nanoeffects exists](docs/motivation.md)
92
93
 
93
94
  - **Tiny.** `createBus` is about 1.4 kB gzip (1.3 kB brotli); other entries load only when imported.
94
95
  - **Cancellation first.** Aborting a task aborts its children and drops its result.
package/dist/actions.d.ts CHANGED
@@ -1,6 +1,6 @@
1
1
  import { B as EventMap, G as Task, T as EventKey, U as PayloadOf, c as WithScope, h as Bus, n as Free, o as Scope, r as FreeActionCreator, t as ActionCreator } from "./action-creator-CQlFgQm4.js";
2
- import { r as Scoped, t as FieldsOfScope } from "./types-bzocBVYc.js";
3
- import { a as createModule, c as CarryingCalls, d as commandsPlugin, f as createCommand, l as MadeCommand, n as ModuleApi, o as modulePlugin, r as ModuleContext, s as Binding, t as Module, u as bindHandler } from "./module-woawvR28.js";
2
+ import { r as Scoped, t as FieldsOfScope } from "./types-C7ukMwE-.js";
3
+ import { a as createModule, c as CarryingCalls, d as commandsPlugin, f as createCommand, l as MadeCommand, n as ModuleApi, o as modulePlugin, r as ModuleContext, s as Binding, t as Module, u as bindHandler } from "./module-COv9ZSzS.js";
4
4
  import { t as OriginOptions } from "./origin-key-CxK0SkeG.js";
5
5
  //#region src/actions/action.d.ts
6
6
  type ScopedCreator<P, T extends string, F> = [P] extends [Free] ? FreeActionCreator<T, F> & WithScope<F> : ActionCreator<P, T, PayloadOf<P>, F> & WithScope<F>;
@@ -0,0 +1,14 @@
1
+ import { B as EventMap, x as ContextOf } from "./action-creator-CQlFgQm4.js";
2
+ //#region src/core/context-types.d.ts
3
+ /** What a function that makes the fields of a task gets to see. */
4
+ type ContextTask = {
5
+ type: string;
6
+ payload?: unknown;
7
+ };
8
+ /**
9
+ * `unknown` when none of the `fields` is already a context field of the bus,
10
+ * else `never`: the call does not compile. Used as `bus: Bus<E> & NoClash<…>`.
11
+ */
12
+ type NoClash<Fields extends object, E extends EventMap> = [keyof Fields & keyof ContextOf<E>] extends [never] ? unknown : never;
13
+ //#endregion
14
+ export { NoClash as n, ContextTask as t };
@@ -0,0 +1,25 @@
1
+ import { B as EventMap, N as WithContext, h as Bus } from "./action-creator-CQlFgQm4.js";
2
+ import { n as NoClash, t as ContextTask } from "./context-types-qXxr_Grf.js";
3
+ //#region src/context/plugin.d.ts
4
+ /**
5
+ * Puts `fields` on the context of every task of the bus: a store, a client, a
6
+ * logger. The types come from the value, so the event map needs no
7
+ * `WithContext`. Returns the same bus, typed with the fields. A function gets
8
+ * `{ type, payload }` of the task and returns its fields.
9
+ *
10
+ * Several uses merge with each other, with the `context` option of `createBus`
11
+ * and with `effectsPlugin`. A name that the bus already has is a type error. The
12
+ * fields of the library (`signal`, `emit`, `run`, …) win, and a field that the
13
+ * context already has is not replaced.
14
+ *
15
+ * @example
16
+ * ```ts
17
+ * type Events = { "user/loaded": User };
18
+ *
19
+ * const bus = createBus<Events>().use(contextPlugin({ store }));
20
+ * bus.on("user/loaded", (user, { store }) => store.put(user)); // ctx.store: Store
21
+ * ```
22
+ */
23
+ export declare const contextPlugin: <Fields extends object>(fields: Fields | ((task: ContextTask) => Fields)) => <E extends EventMap>(bus: Bus<E> & NoClash<Fields, E>) => Bus<E & WithContext<Fields>>;
24
+ //#endregion
25
+ export type { ContextTask, NoClash };
@@ -0,0 +1 @@
1
+ const e=e=>typeof e==`function`,t=e=>({type:Reflect.get(e,`type`),payload:Reflect.get(e,`payload`)}),n=n=>r=>{let i=r.addContext;return r.addContext=r=>{i?.(r);let a=e(n)?n(t(r)):n;for(let[e,t]of Object.entries(a))e in r||Reflect.set(r,e,t)},r};export{n as contextPlugin};
package/dist/dev.d.ts CHANGED
@@ -1,5 +1,5 @@
1
1
  import { B as EventMap, Y as UnsubscribeCallback, h as Bus } from "./action-creator-CQlFgQm4.js";
2
- import { i as WithApp, n as ModuleApi } from "./module-woawvR28.js";
2
+ import { i as WithApp, n as ModuleApi } from "./module-COv9ZSzS.js";
3
3
  //#region src/dev/types.d.ts
4
4
  /** The parts of what `modulePlugin` returned that the diagnostics report. */
5
5
  type ReportedApp<E extends EventMap> = Pick<ModuleApi<E>, "mount" | "unmount" | "isMounted">;
package/dist/effects.d.ts CHANGED
@@ -1,5 +1,5 @@
1
1
  import { B as EventMap, G as Task, u as Effect } from "./action-creator-CQlFgQm4.js";
2
- import { a as RaceStarter, c as all, d as delay, i as take, l as EffectContext, n as effectsPlugin, o as race, r as TakeOptions, s as allSettled, u as Starter } from "./plugin-BrTsPg2Y.js";
2
+ import { a as RaceStarter, c as all, d as delay, i as take, l as EffectContext, n as effectsPlugin, o as race, r as TakeOptions, s as allSettled, u as Starter } from "./plugin-15-kkZp0.js";
3
3
  //#region src/utils/onAbort.d.ts
4
4
  export declare const onAbort: (ctx: {
5
5
  signal?: AbortSignal | undefined;
package/dist/index.d.ts CHANGED
@@ -1,3 +1,3 @@
1
1
  import { A as HandlerRef, B as EventMap, C as Emit, D as EventPayload, E as EventLike, F as commandCall, G as Task, I as createBus, J as TraceLogger, K as Trace, L as Tracer, M as On, N as WithContext, O as EventsOf, P as WithType, R as anyEventType, S as ContextOption, T as EventKey, U as PayloadOf, V as Keys, W as Phase, Y as UnsubscribeCallback, _ as Command, b as Context, g as BusOptions, h as Bus, i as WithPayload, j as Off, k as Handler, m as AnyEvent, p as Action, q as TraceEvent, v as CommandCall, w as Emittable, x as ContextOf, y as Commands, z as EffectName } from "./action-creator-CQlFgQm4.js";
2
- import { n as NoClash, r as contextPlugin, t as ContextTask } from "./context-plugin-Cphk8jfq.js";
3
- export { type Action, type AnyEvent, type Bus, type BusOptions, type Command, type CommandCall, type Commands, type Context, type ContextOf, type ContextOption, type ContextTask, type EffectName, type Emit, type Emittable, type EventKey, type EventLike, type EventMap, type EventPayload, type EventsOf, type Handler, type HandlerRef, type Keys, type NoClash, type Off, type On, type PayloadOf, type Phase, type Task, type Trace, type TraceEvent, type TraceLogger, type Tracer, type UnsubscribeCallback, type WithContext, type WithPayload, type WithType, anyEventType, commandCall, contextPlugin, createBus };
2
+ import { n as NoClash, t as ContextTask } from "./context-types-qXxr_Grf.js";
3
+ export { type Action, type AnyEvent, type Bus, type BusOptions, type Command, type CommandCall, type Commands, type Context, type ContextOf, type ContextOption, type ContextTask, type EffectName, type Emit, type Emittable, type EventKey, type EventLike, type EventMap, type EventPayload, type EventsOf, type Handler, type HandlerRef, type Keys, type NoClash, type Off, type On, type PayloadOf, type Phase, type Task, type Trace, type TraceEvent, type TraceLogger, type Tracer, type UnsubscribeCallback, type WithContext, type WithPayload, type WithType, anyEventType, commandCall, createBus };
package/dist/index.js CHANGED
@@ -1 +1 @@
1
- import{a as e,r as t,t as n}from"./bus-Cdw5ajKF.js";const r=e=>typeof e==`function`,i=e=>({type:Reflect.get(e,`type`),payload:Reflect.get(e,`payload`)}),a=e=>t=>{let n=t.addContext;return t.addContext=t=>{n?.(t);let a=r(e)?e(i(t)):e;for(let[e,n]of Object.entries(a))e in t||Reflect.set(t,e,n)},t};export{e as anyEventType,n as commandCall,a as contextPlugin,t as createBus};
1
+ export{a as anyEventType,t as commandCall,r as createBus}from"./bus-Cdw5ajKF.js";
@@ -1,5 +1,5 @@
1
1
  import { B as EventMap, G as Task, U as PayloadOf, Y as UnsubscribeCallback, _ as Command, b as Context, c as WithScope, h as Bus, o as Scope, v as CommandCall, y as Commands } from "./action-creator-CQlFgQm4.js";
2
- import { n as ScopeSlots, r as Scoped, t as FieldsOfScope } from "./types-bzocBVYc.js";
2
+ import { n as ScopeSlots, r as Scoped, t as FieldsOfScope } from "./types-C7ukMwE-.js";
3
3
  //#region src/actions/command.d.ts
4
4
  /** What `createCommand` returns: a command that also tells whether an action is of its type. */
5
5
  type MadeCommand<P, R, T extends string> = Command<P, R> & {
@@ -1,5 +1,5 @@
1
1
  import { B as PayloadOf, C as EventKey, H as Task, K as UnsubscribeCallback, R as EventMap, _ as Commands, a as Scope, g as CommandCall, h as Command, n as Free, o as WithFields, p as Bus, r as FreeActionCreator, s as WithScope, t as ActionCreator, u as Effects, v as Context } from "./action-creator-Ls3Gy3jk.js";
2
- import { t as BoundOf } from "./plugin-Cw45_-Bo.js";
2
+ import { t as BoundOf } from "./plugin-W4pZY7mM.js";
3
3
  import { t as OriginOptions } from "./origin-key-CxK0SkeG.js";
4
4
  //#region src/scope/types.d.ts
5
5
  /**
@@ -0,0 +1,14 @@
1
+ import { R as EventMap, y as ContextOf } from "./action-creator-Ls3Gy3jk.js";
2
+ //#region src/core/context-types.d.ts
3
+ /** What a function that makes the fields of a task gets to see. */
4
+ type ContextTask = {
5
+ type: string;
6
+ payload?: unknown;
7
+ };
8
+ /**
9
+ * `unknown` when none of the `fields` is already a context field of the bus,
10
+ * else `never`: the call does not compile. Used as `bus: Bus<E> & NoClash<…>`.
11
+ */
12
+ type NoClash<Fields extends object, E extends EventMap> = [keyof Fields & keyof ContextOf<E>] extends [never] ? unknown : never;
13
+ //#endregion
14
+ export { NoClash as n, ContextTask as t };
@@ -1,5 +1,5 @@
1
1
  import { H as Task, R as EventMap, l as Effect } from "./action-creator-Ls3Gy3jk.js";
2
- import { a as RaceStarter, c as all, d as delay, i as take, l as EffectContext, n as effectsPlugin, o as race, r as TakeOptions, s as allSettled, u as Starter } from "./plugin-Cw45_-Bo.js";
2
+ import { a as RaceStarter, c as all, d as delay, i as take, l as EffectContext, n as effectsPlugin, o as race, r as TakeOptions, s as allSettled, u as Starter } from "./plugin-W4pZY7mM.js";
3
3
  //#region src/utils/onAbort.d.ts
4
4
  export declare const onAbort: (ctx: {
5
5
  signal?: AbortSignal | undefined;
@@ -1,3 +1,3 @@
1
1
  import { A as On, B as PayloadOf, C as EventKey, D as Handler, E as EventsOf, F as Tracer, G as TraceLogger, H as Task, I as anyEventType, K as UnsubscribeCallback, L as EffectName, M as WithType, N as commandCall, O as HandlerRef, P as createBus, R as EventMap, S as Emittable, T as EventPayload, U as Trace, V as Phase, W as TraceEvent, _ as Commands, b as ContextOption, d as Action, f as AnyEvent, g as CommandCall, h as Command, i as WithPayload, j as WithContext, k as Off, m as BusOptions, p as Bus, v as Context, w as EventLike, x as Emit, y as ContextOf, z as Keys } from "./action-creator-Ls3Gy3jk.js";
2
- import { n as NoClash, r as contextPlugin, t as ContextTask } from "./context-plugin-BQa-wtbj.js";
3
- export { type Action, type AnyEvent, type Bus, type BusOptions, type Command, type CommandCall, type Commands, type Context, type ContextOf, type ContextOption, type ContextTask, type EffectName, type Emit, type Emittable, type EventKey, type EventLike, type EventMap, type EventPayload, type EventsOf, type Handler, type HandlerRef, type Keys, type NoClash, type Off, type On, type PayloadOf, type Phase, type Task, type Trace, type TraceEvent, type TraceLogger, type Tracer, type UnsubscribeCallback, type WithContext, type WithPayload, type WithType, anyEventType, commandCall, contextPlugin, createBus };
2
+ import { n as NoClash, t as ContextTask } from "./context-types-DQYBFJG4.js";
3
+ export { type Action, type AnyEvent, type Bus, type BusOptions, type Command, type CommandCall, type Commands, type Context, type ContextOf, type ContextOption, type ContextTask, type EffectName, type Emit, type Emittable, type EventKey, type EventLike, type EventMap, type EventPayload, type EventsOf, type Handler, type HandlerRef, type Keys, type NoClash, type Off, type On, type PayloadOf, type Phase, type Task, type Trace, type TraceEvent, type TraceLogger, type Tracer, type UnsubscribeCallback, type WithContext, type WithPayload, type WithType, anyEventType, commandCall, createBus };
@@ -1 +1 @@
1
- import{i as e,n as t,t as n}from"./bus-G2AdGObY.js";const r=e=>typeof e==`function`,i=e=>({type:Reflect.get(e,`type`),payload:Reflect.get(e,`payload`)}),a=e=>t=>{let n=t.addContext;return t.addContext=t=>{n?.(t);let a=r(e)?e(i(t)):e;for(let[e,n]of Object.entries(a))e in t||Reflect.set(t,e,n)},t};export{e as anyEventType,n as commandCall,a as contextPlugin,t as createBus};
1
+ export{i as anyEventType,t as commandCall,n as createBus}from"./bus-G2AdGObY.js";
@@ -1,5 +1,5 @@
1
1
  import { R as EventMap, c as BoundForm, j as WithContext, p as Bus, u as Effects, v as Context, z as Keys } from "./action-creator-Ls3Gy3jk.js";
2
- import { n as NoClash } from "./context-plugin-BQa-wtbj.js";
2
+ import { n as NoClash } from "./context-types-DQYBFJG4.js";
3
3
  //#region src/utils/delay.d.ts
4
4
  /**
5
5
  * Resolves after `ms`, or rejects early if `ctx.signal` aborts. `ms` can be a
@@ -1,5 +1,5 @@
1
1
  import { B as EventMap, N as WithContext, V as Keys, b as Context, d as Effects, h as Bus, l as BoundForm } from "./action-creator-CQlFgQm4.js";
2
- import { n as NoClash } from "./context-plugin-Cphk8jfq.js";
2
+ import { n as NoClash } from "./context-types-qXxr_Grf.js";
3
3
  //#region src/utils/delay.d.ts
4
4
  /**
5
5
  * Resolves after `ms`, or rejects early if `ctx.signal` aborts. `ms` can be a
package/dist/scope.d.ts CHANGED
@@ -1,5 +1,5 @@
1
1
  import { B as EventMap, a as EmitScope, d as Effects, f as Signaled, h as Bus, o as Scope, u as Effect } from "./action-creator-CQlFgQm4.js";
2
- import { n as ScopeSlots, r as Scoped } from "./types-bzocBVYc.js";
2
+ import { n as ScopeSlots, r as Scoped } from "./types-C7ukMwE-.js";
3
3
  //#region src/scope/effect.d.ts
4
4
  /**
5
5
  * Marks a function whose first parameter is `{ signal }` as an effect, so that
@@ -1,5 +1,5 @@
1
1
  import { B as EventMap, d as Effects, o as Scope, s as WithFields } from "./action-creator-CQlFgQm4.js";
2
- import { t as BoundOf } from "./plugin-BrTsPg2Y.js";
2
+ import { t as BoundOf } from "./plugin-15-kkZp0.js";
3
3
  //#region src/scope/types.d.ts
4
4
  /**
5
5
  * The slots `scopePlugin` fills for `modulePlugin`. They are not on `Bus`: a bus
package/docs/context.md CHANGED
@@ -25,10 +25,11 @@ To give fields to **one** command, action, job or module, or to replace them for
25
25
 
26
26
  ## Type the fields (optional)
27
27
 
28
- In TypeScript, `contextPlugin` puts the fields on every task of **this** bus and takes their types from the value you pass. The event map holds only events. It does not wire anything across the app — another bus can have different fields or none.
28
+ In TypeScript, `contextPlugin` (from `nanoeffects/context`) puts the fields on every task of **this** bus and takes their types from the value you pass. The event map holds only events. It does not wire anything across the app — another bus can have different fields or none.
29
29
 
30
30
  ```ts
31
- import { contextPlugin, createBus } from "nanoeffects";
31
+ import { createBus } from "nanoeffects";
32
+ import { contextPlugin } from "nanoeffects/context";
32
33
 
33
34
  // Events — event name → payload
34
35
  type Events = { save: Draft };
package/docs/package.md CHANGED
@@ -9,6 +9,7 @@ Imports are split so you only load what you use. `createBus` stays small; the re
9
9
  | `nanoeffects/effects` | `retry`, `timeout`, `poll`, `delay`, `take`, `all`, `allSettled`, `race`, `effectsPlugin` |
10
10
  | `nanoeffects/actions` | `createAction`, `createCommand`, `createJob`, `createModule`, `modulePlugin`, `commandsPlugin` |
11
11
  | `nanoeffects/match` | `matchPlugin`: `on`, `once` and `off` that take a function which picks the events |
12
+ | `nanoeffects/context` | `contextPlugin`: your own fields (a store, a client) on `ctx` of every task, typed from the value |
12
13
  | `nanoeffects/signal` | `signalPlugin`: `emit(call, { signal })` ties the tasks of an emit to an outside `AbortSignal` |
13
14
  | `nanoeffects/oop` | `extendBus`, `WithBus`, `On`, `Once`, `disposeBus`: the methods of a bus on a class, with the subscriptions of each instance ended by `dispose()` |
14
15
  | `nanoeffects/scope` | `scopePlugin`, `effect`: fields for one command, action, job, module or `emit` (the types `Scope`, `Effect`) |
package/docs/plugins.md CHANGED
@@ -24,7 +24,8 @@ These four cover what most apps need: shared dependencies, effects, commands and
24
24
  Every task gets the same fields on `ctx`: a store, an API client, a logger. The types come from the values. More in [Context fields](context.md).
25
25
 
26
26
  ```js
27
- import { contextPlugin, createBus } from "nanoeffects";
27
+ import { createBus } from "nanoeffects";
28
+ import { contextPlugin } from "nanoeffects/context";
28
29
 
29
30
  // contextPlugin — every handler gets ctx.store
30
31
  const bus = createBus().use(contextPlugin({ store }));
@@ -232,7 +233,8 @@ One bus with every plugin that does not need React, in a file of its own. The ev
232
233
 
233
234
  ```js
234
235
  // bus.js
235
- import { contextPlugin, createBus } from "nanoeffects";
236
+ import { createBus } from "nanoeffects";
237
+ import { contextPlugin } from "nanoeffects/context";
236
238
  import {
237
239
  commandsPlugin,
238
240
  emitterPlugin,
package/docs/stores.md CHANGED
@@ -131,8 +131,9 @@ The bus, the events, the handlers and the link from the store to the bus are the
131
131
 
132
132
  ```js
133
133
  // bus.js
134
- import { contextPlugin, createBus } from "nanoeffects";
134
+ import { createBus } from "nanoeffects";
135
135
  import { emitterPlugin } from "nanoeffects/actions";
136
+ import { contextPlugin } from "nanoeffects/context";
136
137
  import { store } from "./store";
137
138
 
138
139
  export const bus = createBus()
@@ -513,8 +514,9 @@ export const query = createValue("");
513
514
 
514
515
  ```js
515
516
  // bus.js
516
- import { contextPlugin, createBus } from "nanoeffects";
517
+ import { createBus } from "nanoeffects";
517
518
  import { emitterPlugin } from "nanoeffects/actions";
519
+ import { contextPlugin } from "nanoeffects/context";
518
520
  import { query } from "./query";
519
521
 
520
522
  // emitterPlugin adds bus.emitter; contextPlugin puts `query` on every task as ctx.query
package/docs/tracing.md CHANGED
@@ -1,6 +1,8 @@
1
1
  # Trace tasks
2
2
 
3
- Reference for long-lived apps that need to observe task phases, Redux DevTools, or a build without tracing. Not part of onboarding.
3
+ Find out what your app did and why: which events were emitted, which calls a policy cancelled or dropped, which request failed. You see it in the browser console, in Redux DevTools, or in the Performance panel.
4
+
5
+ Tracing is optional. A bus works the same without it, and it costs almost nothing until you turn it on. If you only want to see what happens while you develop, jump to [Show every emit](#show-every-emit) and [Configure Redux DevTools](#configure-redux-devtools); the rest of the page is for apps that need to follow a flow or turn tracing off in a build.
4
6
 
5
7
  ## Attach a tracer
6
8
 
@@ -70,8 +70,9 @@ At runtime the bus still gives the task its fields. Only the checker does not kn
70
70
  <!-- docs-check: skip - a file of examples/typescript-context, type-checked there -->
71
71
  ```ts
72
72
  // bus.ts
73
- import { type Context, contextPlugin, createBus, type EventsOf } from "nanoeffects";
73
+ import { type Context, createBus, type EventsOf } from "nanoeffects";
74
74
  import { modulePlugin } from "nanoeffects/actions";
75
+ import { contextPlugin } from "nanoeffects/context";
75
76
  import { effectsPlugin, race } from "nanoeffects/effects";
76
77
 
77
78
  // Events: event name → payload; nothing about ctx is written here
package/llms-full.txt CHANGED
@@ -559,6 +559,7 @@ Imports are split so you only load what you use. `createBus` stays small; the re
559
559
  | `nanoeffects/effects` | `retry`, `timeout`, `poll`, `delay`, `take`, `all`, `allSettled`, `race`, `effectsPlugin` |
560
560
  | `nanoeffects/actions` | `createAction`, `createCommand`, `createJob`, `createModule`, `modulePlugin`, `commandsPlugin` |
561
561
  | `nanoeffects/match` | `matchPlugin`: `on`, `once` and `off` that take a function which picks the events |
562
+ | `nanoeffects/context` | `contextPlugin`: your own fields (a store, a client) on `ctx` of every task, typed from the value |
562
563
  | `nanoeffects/signal` | `signalPlugin`: `emit(call, { signal })` ties the tasks of an emit to an outside `AbortSignal` |
563
564
  | `nanoeffects/oop` | `extendBus`, `WithBus`, `On`, `Once`, `disposeBus`: the methods of a bus on a class, with the subscriptions of each instance ended by `dispose()` |
564
565
  | `nanoeffects/scope` | `scopePlugin`, `effect`: fields for one command, action, job, module or `emit` (the types `Scope`, `Effect`) |
@@ -609,7 +610,8 @@ These four cover what most apps need: shared dependencies, effects, commands and
609
610
  Every task gets the same fields on `ctx`: a store, an API client, a logger. The types come from the values. More in [Context fields](context.md).
610
611
 
611
612
  ```js
612
- import { contextPlugin, createBus } from "nanoeffects";
613
+ import { createBus } from "nanoeffects";
614
+ import { contextPlugin } from "nanoeffects/context";
613
615
 
614
616
  // contextPlugin — every handler gets ctx.store
615
617
  const bus = createBus().use(contextPlugin({ store }));
@@ -817,7 +819,8 @@ One bus with every plugin that does not need React, in a file of its own. The ev
817
819
 
818
820
  ```js
819
821
  // bus.js
820
- import { contextPlugin, createBus } from "nanoeffects";
822
+ import { createBus } from "nanoeffects";
823
+ import { contextPlugin } from "nanoeffects/context";
821
824
  import {
822
825
  commandsPlugin,
823
826
  emitterPlugin,
@@ -2189,8 +2192,9 @@ The bus, the events, the handlers and the link from the store to the bus are the
2189
2192
 
2190
2193
  ```js
2191
2194
  // bus.js
2192
- import { contextPlugin, createBus } from "nanoeffects";
2195
+ import { createBus } from "nanoeffects";
2193
2196
  import { emitterPlugin } from "nanoeffects/actions";
2197
+ import { contextPlugin } from "nanoeffects/context";
2194
2198
  import { store } from "./store";
2195
2199
 
2196
2200
  export const bus = createBus()
@@ -2571,8 +2575,9 @@ export const query = createValue("");
2571
2575
 
2572
2576
  ```js
2573
2577
  // bus.js
2574
- import { contextPlugin, createBus } from "nanoeffects";
2578
+ import { createBus } from "nanoeffects";
2575
2579
  import { emitterPlugin } from "nanoeffects/actions";
2580
+ import { contextPlugin } from "nanoeffects/context";
2576
2581
  import { query } from "./query";
2577
2582
 
2578
2583
  // emitterPlugin adds bus.emitter; contextPlugin puts `query` on every task as ctx.query
@@ -3101,10 +3106,11 @@ To give fields to **one** command, action, job or module, or to replace them for
3101
3106
 
3102
3107
  ## Type the fields (optional)
3103
3108
 
3104
- In TypeScript, `contextPlugin` puts the fields on every task of **this** bus and takes their types from the value you pass. The event map holds only events. It does not wire anything across the app — another bus can have different fields or none.
3109
+ In TypeScript, `contextPlugin` (from `nanoeffects/context`) puts the fields on every task of **this** bus and takes their types from the value you pass. The event map holds only events. It does not wire anything across the app — another bus can have different fields or none.
3105
3110
 
3106
3111
  ```ts
3107
- import { contextPlugin, createBus } from "nanoeffects";
3112
+ import { createBus } from "nanoeffects";
3113
+ import { contextPlugin } from "nanoeffects/context";
3108
3114
 
3109
3115
  // Events — event name → payload
3110
3116
  type Events = { save: Draft };
@@ -3770,8 +3776,9 @@ At runtime the bus still gives the task its fields. Only the checker does not kn
3770
3776
  <!-- docs-check: skip - a file of examples/typescript-context, type-checked there -->
3771
3777
  ```ts
3772
3778
  // bus.ts
3773
- import { type Context, contextPlugin, createBus, type EventsOf } from "nanoeffects";
3779
+ import { type Context, createBus, type EventsOf } from "nanoeffects";
3774
3780
  import { modulePlugin } from "nanoeffects/actions";
3781
+ import { contextPlugin } from "nanoeffects/context";
3775
3782
  import { effectsPlugin, race } from "nanoeffects/effects";
3776
3783
 
3777
3784
  // Events: event name → payload; nothing about ctx is written here
@@ -4540,7 +4547,9 @@ Source: docs/tracing.md
4540
4547
 
4541
4548
  # Trace tasks
4542
4549
 
4543
- Reference for long-lived apps that need to observe task phases, Redux DevTools, or a build without tracing. Not part of onboarding.
4550
+ Find out what your app did and why: which events were emitted, which calls a policy cancelled or dropped, which request failed. You see it in the browser console, in Redux DevTools, or in the Performance panel.
4551
+
4552
+ Tracing is optional. A bus works the same without it, and it costs almost nothing until you turn it on. If you only want to see what happens while you develop, jump to [Show every emit](#show-every-emit) and [Configure Redux DevTools](#configure-redux-devtools); the rest of the page is for apps that need to follow a flow or turn tracing off in a build.
4544
4553
 
4545
4554
  ## Attach a tracer
4546
4555
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "nanoeffects",
3
- "version": "0.13.0",
3
+ "version": "0.14.0",
4
4
  "description": "Cancel stale async work and fix race conditions in event handlers: a typed event bus where every handler is a task with an AbortSignal, plus latest, debounce, throttle, queue, retry, timeout and poll. About 1.4 kB gzip.",
5
5
  "keywords": [
6
6
  "event-bus",
@@ -40,7 +40,7 @@
40
40
  "node": ">=18"
41
41
  },
42
42
  "type": "module",
43
- "packageManager": "pnpm@11.13.0",
43
+ "packageManager": "pnpm@11.28.9",
44
44
  "sideEffects": false,
45
45
  "files": [
46
46
  "dist",
@@ -98,6 +98,10 @@
98
98
  "types": "./dist/signal.d.ts",
99
99
  "import": "./dist/signal.js"
100
100
  },
101
+ "./context": {
102
+ "types": "./dist/context.d.ts",
103
+ "import": "./dist/context.js"
104
+ },
101
105
  "./oop": {
102
106
  "types": "./dist/oop.d.ts",
103
107
  "import": "./dist/oop.js"
@@ -214,6 +218,11 @@
214
218
  "path": "dist/signal.js",
215
219
  "limit": "0.6 kB"
216
220
  },
221
+ {
222
+ "name": "context (plugin)",
223
+ "path": "dist/context.js",
224
+ "limit": "0.2 kB"
225
+ },
217
226
  {
218
227
  "name": "oop (class entry)",
219
228
  "path": "dist/oop.js",
@@ -1,34 +0,0 @@
1
- import { B as EventMap, N as WithContext, h as Bus, x as ContextOf } from "./action-creator-CQlFgQm4.js";
2
- //#region src/core/context-plugin.d.ts
3
- /** What a function that makes the fields of a task gets to see. */
4
- type ContextTask = {
5
- type: string;
6
- payload?: unknown;
7
- };
8
- /**
9
- * `unknown` when none of the `fields` is already a context field of the bus,
10
- * else `never`: the call does not compile. Used as `bus: Bus<E> & NoClash<…>`.
11
- */
12
- type NoClash<Fields extends object, E extends EventMap> = [keyof Fields & keyof ContextOf<E>] extends [never] ? unknown : never;
13
- /**
14
- * Puts `fields` on the context of every task of the bus: a store, a client, a
15
- * logger. The types come from the value, so the event map needs no
16
- * `WithContext`. Returns the same bus, typed with the fields. A function gets
17
- * `{ type, payload }` of the task and returns its fields.
18
- *
19
- * Several uses merge with each other, with the `context` option of `createBus`
20
- * and with `effectsPlugin`. A name that the bus already has is a type error. The
21
- * fields of the library (`signal`, `emit`, `run`, …) win, and a field that the
22
- * context already has is not replaced.
23
- *
24
- * @example
25
- * ```ts
26
- * type Events = { "user/loaded": User };
27
- *
28
- * const bus = createBus<Events>().use(contextPlugin({ store }));
29
- * bus.on("user/loaded", (user, { store }) => store.put(user)); // ctx.store: Store
30
- * ```
31
- */
32
- declare const contextPlugin: <Fields extends object>(fields: Fields | ((task: ContextTask) => Fields)) => <E extends EventMap>(bus: Bus<E> & NoClash<Fields, E>) => Bus<E & WithContext<Fields>>;
33
- //#endregion
34
- export { NoClash as n, contextPlugin as r, ContextTask as t };
@@ -1,34 +0,0 @@
1
- import { R as EventMap, j as WithContext, p as Bus, y as ContextOf } from "./action-creator-Ls3Gy3jk.js";
2
- //#region src/core/context-plugin.d.ts
3
- /** What a function that makes the fields of a task gets to see. */
4
- type ContextTask = {
5
- type: string;
6
- payload?: unknown;
7
- };
8
- /**
9
- * `unknown` when none of the `fields` is already a context field of the bus,
10
- * else `never`: the call does not compile. Used as `bus: Bus<E> & NoClash<…>`.
11
- */
12
- type NoClash<Fields extends object, E extends EventMap> = [keyof Fields & keyof ContextOf<E>] extends [never] ? unknown : never;
13
- /**
14
- * Puts `fields` on the context of every task of the bus: a store, a client, a
15
- * logger. The types come from the value, so the event map needs no
16
- * `WithContext`. Returns the same bus, typed with the fields. A function gets
17
- * `{ type, payload }` of the task and returns its fields.
18
- *
19
- * Several uses merge with each other, with the `context` option of `createBus`
20
- * and with `effectsPlugin`. A name that the bus already has is a type error. The
21
- * fields of the library (`signal`, `emit`, `run`, …) win, and a field that the
22
- * context already has is not replaced.
23
- *
24
- * @example
25
- * ```ts
26
- * type Events = { "user/loaded": User };
27
- *
28
- * const bus = createBus<Events>().use(contextPlugin({ store }));
29
- * bus.on("user/loaded", (user, { store }) => store.put(user)); // ctx.store: Store
30
- * ```
31
- */
32
- declare const contextPlugin: <Fields extends object>(fields: Fields | ((task: ContextTask) => Fields)) => <E extends EventMap>(bus: Bus<E> & NoClash<Fields, E>) => Bus<E & WithContext<Fields>>;
33
- //#endregion
34
- export { NoClash as n, contextPlugin as r, ContextTask as t };