createStore

function
store/Store.ts:2670

Overload 1

signature
createStore<S, EM>(cfg): StoreInstance<keyof S & string, S, EM>

Creates a store with explicit State and EventMap types. Use this overload for: - **Event-only stores** (no reducers, just middleware/effects) - When TypeScript inference from reducers isn't sufficient - When you want to define the EventMap independently of reducers

Type parameters

NameTypeDescription
Sextends Record<string, any>State record type (can be empty {} for event-only stores).
EMextends EventMapBaseEvent map type defining all channel → type → payload combinations.

Parameters

cfg — object with:

NameTypeDescription
dedupWindowMs?number
devtools?{ allowReplay?: boolean }
effects?EffectSpec<DeepReadonly<S>, EM>[]
idFactory?() => string
maxReduceDepth?number
maxTransitionsPerDrain?number
middleware?MiddlewareInput<DeepReadonly<S>, EM>[]
namestring
onCascade?(info: CascadeInfo<EM>) => void
onEffectError?(error: unknown, event: EventUnion<EM>) => void
onReducerError?(error: unknown, event: EventUnion<EM>, slice: string) => void
onRejected?(rejection: Rejection, event: EventUnion<EM>, slice: string) => void
reducer?{ [K in string | number | symbol]?: ReducerSpec<S[K], EM> }

Returns

StoreInstance<keyof S & string, S, EM>A typed StoreInstance.

Example

example
type AppEM = {
  notifications: { show: { message: string }; hide: void };
};

const store = createStore<{}, AppEM>({
  name: 'NotificationBus',
  effects: [{
    when: { channel: 'notifications' },
    effect: (evt) => {
      if (evt.type === 'show') showToast(evt.payload.message);
    },
  }],
});

Example

example
const store = createStore<AppState, AppEM>({
  name: 'App',
  reducer: { counter: counterSpec },
  middleware: [loggingMiddleware],
});

Overload 2

signature
createStore<RM>(cfg): StoreInstance<keyof RM & string, StateFromReducers<RM>, EMFromReducersStrict<RM>>

Creates a store with types inferred from the reducers map. This is the primary overload for most use cases where reducers define both the state shape and the event map.

Type parameters

NameTypeDescription
RMextends ReducersMapAnyReducers map object with each slice's ReducerSpec.

Parameters

cfg — object with:

NameTypeDescription
dedupWindowMs?number
devtools?{ allowReplay?: boolean }
effects?EffectSpec<DeepReadonly<StateFromReducers<RM>>, EMFromReducersStrict<RM>>[]
idFactory?() => string
maxReduceDepth?number
maxTransitionsPerDrain?number
middleware?MiddlewareInput<DeepReadonly<StateFromReducers<RM>>, EMFromReducersStrict<RM>>[]
namestring
onCascade?(info: CascadeInfo<EMFromReducersStrict<RM>>) => void
onEffectError?(error: unknown, event: EventUnion<EMFromReducersStrict<RM>>) => void
onReducerError?(error: unknown, event: EventUnion<EMFromReducersStrict<RM>>, slice: string) => void
onRejected?(rejection: Rejection, event: EventUnion<EMFromReducersStrict<RM>>, slice: string) => void
reducerRM

Returns

StoreInstance<keyof RM & string, StateFromReducers<RM>, EMFromReducersStrict<RM>>A typed StoreInstance.

Example

example
const store = createStore({
  name: 'App',
  reducer: {
    counter: {
      state: { value: 0 },
      when: { keys: eventKeys<MyEM>()([['ui', 'increment']]) },
      reducer: (s, evt) => evt.type === 'increment' ? { value: s.value + evt.payload } : s
    }
  },
  middleware: [],
  effects: []
});