Estás leyendo la documentación de 0.9. La versión más reciente es 0.10. Leer esta página en 0.10 →
La referencia de la API está disponible solo en inglés por ahora.

Store<EM extends EventMapBase, R extends string, S extends Record<R, any>>

class
store/Store.ts:229

implements StoreInstance<R, S, EM>

Public Store surface.

The concrete Store implements this as StoreInstance<R, DeepReadonly<S>, EM>.

Type parameters

NameTypeDescription
EMextends EventMapBaseReducer name union.
Rextends stringState record (already readonly at the call site).
Sextends Record<R, any>Event map.

Constructor

constructor

Creates a store from a StoreSpec.

signature
new<EM, R, S>(spec): Store<EM, R, S>

Creates a store from a StoreSpec.

Type parameters

NameTypeDescription
EMextends EventMapBase
Rextends string
Sextends Record<R, any>

Parameters

NameTypeDescription
specStoreSpec<R, S, EM>Store configuration (name, reducers, middleware, optional effects).

Returns

Store<EM, R, S>

Properties

NameTypeDescription
namestringStore name (used by DevTools & diagnostics).
isReplayingget/setbooleantrue while devtools is applying a snapshot or replaying events.

Methods

__devtoolsIntrospect

Returns a structured introspection snapshot for DevTools UIs.

signature
__devtoolsIntrospect(): { atomic: { property: string; reducer: string }[]; coarse: number; dedupHits: number; effects: { channel: string; description?: string; name?: string; origin: Origin; type: string }[]; event: { channel: string; duringReplay: boolean; phase: string; type: string }[]; middleware: { description?: string; name?: string; origin: Origin; when?: unknown }[]; queueDepth: number; reducers: { name: string; origin: Origin; owner: undefined | string; when: undefined | When<EM> }[] }

Returns a structured introspection snapshot for DevTools UIs.

Returns

{ atomic: { property: string; reducer: string }[]; coarse: number; dedupHits: number; effects: { channel: string; description?: string; name?: string; origin: Origin; type: string }[]; event: { channel: string; duringReplay: boolean; phase: string; type: string }[]; middleware: { description?: string; name?: string; origin: Origin; when?: unknown }[]; queueDepth: number; reducers: { name: string; origin: Origin; owner: undefined | string; when: undefined | When<EM> }[] }

static buildAncestorPaths

Builds ancestor paths for a dotted path. For "a.b.c", returns ["a", "a.b", "a.b.c"]. Leading dots are trimmed.

signature
buildAncestorPaths(path): string[]

Builds ancestor paths for a dotted path. For "a.b.c", returns ["a", "a.b", "a.b.c"]. Leading dots are trimmed.

Parameters

NameTypeDescription
pathstringDotted path string.

Returns

string[], Array of ancestor paths.

Example

example
Store.buildAncestorPaths('x.y.z'); // ['x','x.y','x.y.z']

call

Sends a request and waits for the reply, correlating the two automatically.

signature
call<C, T>(channel, type, payload, opts): CallHandle<EventUnion<EM>, EventUnion<EM>>

Sends a request and waits for the reply, correlating the two automatically.

Type parameters

NameTypeDescription
Cextends stringRequest channel.
Textends stringRequest type within C.

Parameters

NameTypeDescription
channelCChannel to send on.
NameTypeDescription
typeTEvent type to send.
NameTypeDescription
payloadEM[C][T]The **request** payload. This is what you are sending; what comes back is described by CallOptions.reply, not by this.
NameTypeDescription
optsCallOptions<EM>Which replies end the call, and how long to wait. See CallOptions.

Returns

CallHandle<EventUnion<EM>, EventUnion<EM>>, A CallHandle: await it for the terminal reply, or for await it for progress events as they arrive.

Example

example
// Survives a job that streams for minutes; fails a responder that goes quiet for 5s.
await store.call("job", "start", { id }, { reply: ["job", "done"], timeoutMs: 5_000 });

Example

example
const call = store.call("rpc", "ask", { q }, { reply: ["rpc", "answer"] });
useEffect(() => () => call.cancel("unmounted"), [call]);

connect

Connects a **fine-grained** listener to a dotted path under a slice.

signature
connect(spec, h, options?): () => void

Connects a **fine-grained** listener to a dotted path under a slice.

Parameters

spec, object with:

NameTypeDescription
propertystring
reducerR
NameTypeDescription
h(chg: Change) => voidHandler receiving a Change with { oldValue, newValue, path }.
NameTypeDescription
options?ConnectOptions

Returns

() => void, Unsubscribe function.

Example

example
const off = store.connect(
  { reducer: 'todos', property: 'items.0.title' },
  (chg) => console.log('title changed:', chg.newValue)
);
off();

Example

example
// Listen to any item title change
const off = store.connect(
  { reducer: 'todos', property: 'items.*.title' },
  (chg) => console.log('some title changed')
);

dispose

Cleanup resources (timers, etc.) when disposing the store. Call this if you're dynamically creating/destroying stores.

signature
dispose(): void

Cleanup resources (timers, etc.) when disposing the store. Call this if you're dynamically creating/destroying stores.

Returns

void

Example

example
const store = createStore({ ... });
// later
store.dispose();

emit

Emit a typed event (channel, type, payload). Returns a promise that resolves when the event has been processed.

signature
emit<C, T>(channel, type, payload, opts?): Promise<EmitResult>

Emits a typed event (channel, type, payload). Events are queued and processed **sequentially** (FIFO). **Pipeline per event:** the *reduce phase* (steps 1-4) runs **synchronously**, so getState() reflects the change as soon as emit() returns; the *effect phase* (step 5) runs afterwards, asynchronously. 1. **Deduplication** (opt-in) - Skip when content-dedup is enabled (dedupWindowMs > 0) or a matching dedupKey recurs; off by default 2. **Middleware** (sync) - Pre-reducer hooks; may cancel by returning false 3. **Reducers** (sync) - every matching slice is *staged*; nothing is written yet, so a refusal from the last reducer still stops the first one's write 4. **Commit + subscribers** (sync) - all staged slices are assigned under one new root, then event subscribers (committed, then written when state actually changed), then coarse listeners 5. **Effects** (async) - side-effects keyed by (channel, type); the returned promise resolves once they complete **Change Detection**: Uses reference equality (===) on this.state to determine if any slice changed. Works because the commit builds a new state reference via shallow spread when any slice changes.

Type parameters

NameTypeDescription
Cextends stringChannel key in EM.
Textends stringType key within channel C.

Parameters

NameTypeDescription
channelCChannel name.
NameTypeDescription
typeTEvent type name.
NameTypeDescription
payloadEM[C][T]Payload typed as EM[C][T].
NameTypeDescription
opts?EmitOptionsOptional per-emit options (e.g. dedupKey for identity-based dedup).

Returns

Promise<EmitResult>, A promise that resolves once this event's effects have finished. State is already updated synchronously before emit() returns.

Example

example
await store.emit('ui', 'increment', 1);

Example

example
store.registerMiddleware((state, event) => {
  if (event.type === 'dangerous') return false; // cancel
  return true; // allow
});

await store.emit('ui', 'dangerous', null); // cancelled, no state change

getState

Returns the current immutable state snapshot.

signature
getState(): DeepReadonly<S>

Returns the current immutable state snapshot.

Returns

DeepReadonly<S>, Deep-readonly state object.

Example

example
const state = store.getState();
console.log(state.counter.value);

hotReplace

Convenience API to replace **any subset** of store parts (HMR patterns).

signature
hotReplace(partial): void

Convenience API to replace **any subset** of store parts (HMR patterns).

Parameters

partial, object with:

NameTypeDescription
effects?EffectSpec<DeepReadonly<S>, EM>[]
middleware?MiddlewareInput<DeepReadonly<S>, EM>[]
preserveState?boolean
reducer?Record<R, ReducerSpec<S[R], EM>>
scope?ReplaceScope

Returns

void

Example

example
store.hotReplace({
  reducer: newReducers,
  middleware: newMiddleware,
  effects: newEffects,
  preserveState: true
});

instrument

Registers an instrumentation observer. See StoreInstance.instrument.

signature
instrument(observer): Unsubscribe

Registers an instrumentation observer. See StoreInstance.instrument.

Parameters

NameTypeDescription
observerInstrumentationObserver<EM>

Returns

Unsubscribe

onEffect

Convenience helper to register an **effect** filtered by a single (channel, type) pair.

signature
onEffect<C, T>(channel, type, handler): () => void

Convenience helper to register an **effect** filtered by a single (channel, type) pair.

Type parameters

NameTypeDescription
Cextends stringChannel key within EM.
Textends stringEvent type key within channel C.

Parameters

NameTypeDescription
channelCChannel to filter.
NameTypeDescription
typeTEvent type to filter.
NameTypeDescription
handler(payload: EM[C][T], getState: () => DeepReadonly<S>, emit: Emit<EM>, event: Event<EM, C, T>) => void | Promise<void>Effect handler (payload, getState, emit, event).

Returns

() => void, Unsubscribe/teardown function.

Example

example
const off = store.onEffect('ui', 'increment', async (n, get, emit) => {
  if (n > 10) await emit('ui', 'increment', -10);
});
// later
off();

onEvent

Subscribe to events by channel and type. Event subscriptions are intended for the View layer (e.g., React components) to react to events without affecting the event flow. They are fire-and-forget and cannot cancel event propagation. **Phases:** - 'committed' (default): Events that passed middleware and reached reducers. Notified after reducers, before effects. - 'uncommitted': Events rejected by middleware. Notified immediately after rejection. - 'written': Events that actually changed state. Stricter than committed, which fires for every event a store accepts including one with no reducers at all. - 'all': Both committed and uncommitted events. Handler receives the phase parameter to distinguish between the two. Deliberately not written as well: an event that writes is also committed, so folding it in would notify every existing all subscriber twice for one event. **Replay:** a handler is not called while devtools is replaying, unless it opted in with { duringReplay: true }.

signature
onEvent<C, T>(channel, type, handler, phase, options?): Unsubscribe

Subscribe to events by channel and type. Event subscriptions are intended for the View layer (e.g., React components) to react to events without affecting the event flow. They are fire-and-forget and cannot cancel event propagation. **Phases:** - 'committed' (default): Events that passed middleware and reached reducers. Notified after reducers, before effects. - 'uncommitted': Events rejected by middleware. Notified immediately after rejection. - 'written': Events that actually changed state. Stricter than committed, which fires for every event a store accepts including one with no reducers at all. - 'all': Both committed and uncommitted events. Handler receives the phase parameter to distinguish between the two. Deliberately not written as well: an event that writes is also committed, so folding it in would notify every existing all subscriber twice for one event. **Replay:** a handler is not called while devtools is replaying, unless it opted in with { duringReplay: true }.

Type parameters

NameTypeDescription
Cextends stringChannel key within EM.
Textends stringEvent type key within channel C.

Parameters

NameTypeDescription
channelCChannel to subscribe to.
NameTypeDescription
typeTEvent type to subscribe to.
NameTypeDescription
handlerNarrowedEventHandler<DeepReadonly<S>, EM, C, T>Handler function (event, getState, emit, phase).
NameTypeDescription
phaseEventPhaseEvent phase to subscribe to (default: 'committed').

options, object with:

NameTypeDescription
duringReplay?boolean

Returns

Unsubscribe, Unsubscribe function.

Example

example
const off = store.onEvent('ui', 'save', (event, getState, emit, phase) => {
  console.log('Save committed:', event.payload);
});
off();

Example

example
store.onEvent('ui', 'delete', (event, getState, emit, phase) => {
  console.log('Delete was rejected by middleware');
}, 'uncommitted');

Example

example
store.onEvent('ui', 'action', (event, getState, emit, phase) => {
  console.log('Action:', phase); // 'committed' or 'uncommitted'
}, 'all');

onRegistrationChange

Subscribe to reducer, middleware and effect registrations. Delivered as an array, one batch per public call: replaceReducers unmounts and then remounts, and a per-change observer would see a spurious unmount of a slice that is only being updated. Observers run after the state broadcast, and a registration made by an observer is queued rather than delivered re-entrantly. Replay never produces a change, so there is no duringReplay option here. dispose() fires nothing.

signature
onRegistrationChange(observer, options?): Unsubscribe

Subscribe to reducer, middleware and effect registrations. Delivered as an array, one batch per public call: replaceReducers unmounts and then remounts, and a per-change observer would see a spurious unmount of a slice that is only being updated. Observers run after the state broadcast, and a registration made by an observer is queued rather than delivered re-entrantly. Replay never produces a change, so there is no duringReplay option here. dispose() fires nothing.

Parameters

NameTypeDescription
observerRegistrationObserver<EM>Receives one batch per registration change.

options, object with:

NameTypeDescription
emitCurrent?boolean

Returns

Unsubscribe, Unsubscribe function.

Example

example
const off = store.onRegistrationChange((changes) => {
  for (const c of changes) {
    console.log(c.op, c.kind, c.name, c.origin);
  }
}, { emitCurrent: true });
off();

registerEffect

Register a post-reducer effect (sees final state). Returns an unsubscribe.

signature
registerEffect(spec): any

Register a post-reducer effect (sees final state). Returns an unsubscribe.

Parameters

NameTypeDescription
specEffectSpec<DeepReadonly<S>, EM>

Returns

any

registerMiddleware

Registers a middleware (runs **before** reducers).

signature
registerMiddleware(mw): any

Registers a middleware (runs **before** reducers).

Parameters

NameTypeDescription
mwMiddlewareInput<any, any>Middleware (state, event, emit) => boolean. Return false to cancel event propagation.

Returns

any, Unsubscribe function that removes this middleware.

Example

example
const off = store.registerMiddleware((state, event) => {
  console.log('Event:', event.channel, event.type, event.payload);
  return true; // allow
});
off();

Example

example
store.registerMiddleware((state, event) => {
  if (event.type === 'forbidden') return false; // cancel
  return true;
});

registerReducer

Dynamically **adds** a named slice reducer at runtime.

signature
registerReducer(name, spec, options?): any

Dynamically **adds** a named slice reducer at runtime.

Parameters

NameTypeDescription
namestringNew slice name (must not already exist).
NameTypeDescription
specReducerSpec<any, any>Reducer spec (state, when, reducer).

options, object with:

NameTypeDescription
owner?string

Returns

any, Disposer function that **removes** the slice (and its state).

Example

example
const dispose = store.registerReducer('filters', {
  state: { q: '' },
  events: [['ui', 'setQuery']],
  reducer(s, evt) {
    return evt.type === 'setQuery' ? { q: evt.payload } : s;
  }
});
// Later:
dispose();

registerSlice

Mounts a slice and hands back the widened store alongside a disposer.

signature
registerSlice(name, spec, options?): any

Mounts a slice and hands back the widened store alongside a disposer.

Parameters

NameTypeDescription
namestring
NameTypeDescription
specReducerSpec<any, any>

options, object with:

NameTypeDescription
owner?string

Returns

any

replaceEffects

Replaces all registered **effects** (HMR-friendly).

signature
replaceEffects(next, opts): void

Replaces all registered **effects** (HMR-friendly).

Parameters

NameTypeDescription
nextEffectSpec<DeepReadonly<S>, EM>[]New effects array (as EffectSpecs).

opts, object with:

NameTypeDescription
scope?ReplaceScope

Returns

void

Example

example
if (import.meta.hot) {
  import.meta.hot.accept('./effects', (newModule) => {
    store.replaceEffects(newModule.effects);
  });
}

replaceMiddleware

Replaces the **entire** middleware pipeline (HMR-friendly).

signature
replaceMiddleware(next, opts): void

Replaces the **entire** middleware pipeline (HMR-friendly).

Parameters

NameTypeDescription
nextMiddlewareInput<DeepReadonly<S>, EM>[]New middleware array.

opts, object with:

NameTypeDescription
scope?ReplaceScope

Returns

void

Example

example
if (import.meta.hot) {
  import.meta.hot.accept('./middleware', (newModule) => {
    store.replaceMiddleware(newModule.middleware);
  });
}

replaceReducers

Replaces the entire **reducer set** (HMR-friendly).

signature
replaceReducers(next, opts): void

Replaces the entire **reducer set** (HMR-friendly).

Parameters

NameTypeDescription
nextRecord<R, ReducerSpec<S[R], EM>>Map of slice specs keyed by slice name.

opts, object with:

NameTypeDescription
preserveState?boolean
scope?ReplaceScope

Returns

void

Example

example
if (import.meta.hot) {
  import.meta.hot.accept('./reducers', (newModule) => {
    store.replaceReducers(newModule.reducers, { preserveState: true });
  });
}

subscribe

Subscribes to **coarse-grained** commits (called once per successful event, only if state changed). **Use Case**: React's useSyncExternalStore or similar external store integrations.

signature
subscribe(fn): () => void

Subscribes to **coarse-grained** commits (called once per successful event, only if state changed). **Use Case**: React's useSyncExternalStore or similar external store integrations.

Parameters

NameTypeDescription
fn() => voidListener invoked after reducers/effects have run and state has changed.

Returns

() => void, Unsubscribe function.

Example

example
const off = store.subscribe(() => console.log('state committed'));
// Later:
off();

withEffect

Registers an effect and returns the widened store, for chaining.

signature
withEffect(spec): any

Registers an effect and returns the widened store, for chaining.

Parameters

NameTypeDescription
specEffectSpec<any, any>

Returns

any

withMiddleware

Registers middleware and returns the widened store, for chaining.

signature
withMiddleware(mw): any

Registers middleware and returns the widened store, for chaining.

Parameters

NameTypeDescription
mwMiddlewareInput<any, any>

Returns

any

withSlice

Mounts a slice and returns the widened store, for chaining.

signature
withSlice(name, spec, options?): any

Mounts a slice and returns the widened store, for chaining.

Parameters

NameTypeDescription
namestring
NameTypeDescription
specReducerSpec<any, any>

options, object with:

NameTypeDescription
owner?string

Returns

any