@xstate/store
Advanced tools
Comparing version 2.5.0 to 2.6.0
import { EventObject } from 'xstate'; | ||
import { Cast, EventPayloadMap, ExtractEventsFromPayloadMap, Store, StoreAssigner, StoreContext, StorePropertyAssigner, StoreSnapshot } from "./types.js"; | ||
import { Cast, EnqueueObject, EventPayloadMap, ExtractEventsFromPayloadMap, Store, StoreAssigner, StoreContext, StorePropertyAssigner, StoreSnapshot } from "./types.js"; | ||
export type TransitionsFromEventPayloadMap<TEventPayloadMap extends EventPayloadMap, TContext extends StoreContext, TEmitted extends EventObject> = { | ||
@@ -112,6 +112,14 @@ [K in keyof TEventPayloadMap & string]: StoreAssigner<TContext, { | ||
*/ | ||
export declare function createStoreWithProducer<TContext extends StoreContext, TEventPayloadMap extends EventPayloadMap, TEmitted extends EventObject = EventObject>(producer: NoInfer<(context: TContext, recipe: (context: TContext) => void) => TContext>, config: { | ||
context: TContext; | ||
on: { | ||
[K in keyof TEventPayloadMap & string]: (context: NoInfer<TContext>, event: { | ||
type: K; | ||
} & TEventPayloadMap[K], enqueue: EnqueueObject<TEmitted>) => void; | ||
}; | ||
}): Store<TContext, ExtractEventsFromPayloadMap<TEventPayloadMap>, TEmitted>; | ||
export declare function createStoreWithProducer<TContext extends StoreContext, TEventPayloadMap extends EventPayloadMap, TEmitted extends EventObject = EventObject>(producer: NoInfer<(context: TContext, recipe: (context: TContext) => void) => TContext>, initialContext: TContext, transitions: { | ||
[K in keyof TEventPayloadMap & string]: (context: NoInfer<TContext>, event: { | ||
type: K; | ||
} & TEventPayloadMap[K]) => void; | ||
} & TEventPayloadMap[K], enqueue: EnqueueObject<TEmitted>) => void; | ||
}): Store<TContext, ExtractEventsFromPayloadMap<TEventPayloadMap>, TEmitted>; | ||
@@ -118,0 +126,0 @@ declare global { |
@@ -8,11 +8,8 @@ export type EventPayloadMap = Record<string, {} | null | undefined>; | ||
export type Recipe<T, TReturn> = (state: T) => TReturn; | ||
export type StoreAssigner<TContext extends StoreContext, TEvent extends EventObject, TEmitted extends EventObject> = (context: TContext, event: TEvent, enq: { | ||
export type EnqueueObject<TEmitted extends EventObject> = { | ||
emit: (ev: TEmitted) => void; | ||
}) => Partial<TContext>; | ||
export type StoreCompleteAssigner<TContext, TEvent extends EventObject, TEmitted extends EventObject> = (ctx: TContext, ev: TEvent, enq: { | ||
emit: (ev: TEmitted) => void; | ||
}) => TContext; | ||
export type StorePartialAssigner<TContext, TEvent extends EventObject, K extends keyof TContext, TEmitted extends EventObject> = (ctx: TContext, ev: TEvent, enq: { | ||
emit: (ev: TEmitted) => void; | ||
}) => Partial<TContext>[K]; | ||
}; | ||
export type StoreAssigner<TContext extends StoreContext, TEvent extends EventObject, TEmitted extends EventObject> = (context: TContext, event: TEvent, enq: EnqueueObject<TEmitted>) => Partial<TContext>; | ||
export type StoreCompleteAssigner<TContext, TEvent extends EventObject, TEmitted extends EventObject> = (ctx: TContext, ev: TEvent, enq: EnqueueObject<TEmitted>) => TContext; | ||
export type StorePartialAssigner<TContext, TEvent extends EventObject, K extends keyof TContext, TEmitted extends EventObject> = (ctx: TContext, ev: TEvent, enq: EnqueueObject<TEmitted>) => Partial<TContext>[K]; | ||
export type StorePropertyAssigner<TContext, TEvent extends EventObject, TEmitted extends EventObject> = { | ||
@@ -59,3 +56,3 @@ [K in keyof TContext]?: TContext[K] | StorePartialAssigner<TContext, TEvent, K, TEmitted>; | ||
*/ | ||
inspect: (observer: Observer<InspectionEvent> | ((inspectionEvent: InspectionEvent) => void)) => Subscription; | ||
inspect: (observer: Observer<StoreInspectionEvent> | ((inspectionEvent: StoreInspectionEvent) => void)) => Subscription; | ||
sessionId: string; | ||
@@ -167,4 +164,6 @@ on: <TEmittedType extends TEmitted['type']>(eventType: TEmittedType, emittedEventHandler: (ev: Compute<TEmitted & { | ||
type Values<T> = T[keyof T]; | ||
export type InspectionEvent = InspectedSnapshotEvent | InspectedEventEvent | InspectedActorEvent | InspectedMicrostepEvent | InspectedActionEvent; | ||
interface BaseInspectionEventProperties { | ||
export type StoreInspectionEvent = StoreInspectedSnapshotEvent | StoreInspectedEventEvent | StoreInspectedActorEvent; | ||
/** @deprecated Use `StoreInspectionEvent` instead. */ | ||
export type InspectionEvent = StoreInspectionEvent; | ||
interface StoreBaseInspectionEventProperties { | ||
rootId: string; | ||
@@ -180,3 +179,3 @@ /** | ||
} | ||
export interface InspectedSnapshotEvent extends BaseInspectionEventProperties { | ||
export interface StoreInspectedSnapshotEvent extends StoreBaseInspectionEventProperties { | ||
type: '@xstate.snapshot'; | ||
@@ -186,9 +185,3 @@ event: AnyEventObject; | ||
} | ||
interface InspectedMicrostepEvent extends BaseInspectionEventProperties { | ||
type: '@xstate.microstep'; | ||
event: AnyEventObject; | ||
snapshot: Snapshot<unknown>; | ||
_transitions: unknown[]; | ||
} | ||
export interface InspectedActionEvent extends BaseInspectionEventProperties { | ||
export interface StoreInspectedActionEvent extends StoreBaseInspectionEventProperties { | ||
type: '@xstate.action'; | ||
@@ -200,5 +193,5 @@ action: { | ||
} | ||
export interface InspectedEventEvent extends BaseInspectionEventProperties { | ||
export interface StoreInspectedEventEvent extends StoreBaseInspectionEventProperties { | ||
type: '@xstate.event'; | ||
sourceRef: ActorRefLike | undefined; | ||
sourceRef: AnyStore | undefined; | ||
event: AnyEventObject; | ||
@@ -210,3 +203,3 @@ } | ||
} | ||
export interface InspectedActorEvent extends BaseInspectionEventProperties { | ||
export interface StoreInspectedActorEvent extends StoreBaseInspectionEventProperties { | ||
type: '@xstate.actor'; | ||
@@ -216,3 +209,3 @@ } | ||
sessionId: string; | ||
send: (...args: never) => void; | ||
send: (event: any) => void; | ||
getSnapshot: () => any; | ||
@@ -219,0 +212,0 @@ }; |
@@ -253,4 +253,8 @@ 'use strict'; | ||
*/ | ||
function createStoreWithProducer(producer, initialContext, transitions) { | ||
return createStoreCore(initialContext, transitions, producer); | ||
function createStoreWithProducer(producer, initialContextOrConfig, transitions) { | ||
if (typeof initialContextOrConfig === 'object' && 'context' in initialContextOrConfig && 'on' in initialContextOrConfig) { | ||
return createStoreCore(initialContextOrConfig.context, initialContextOrConfig.on, producer); | ||
} | ||
return createStoreCore(initialContextOrConfig, transitions, producer); | ||
} | ||
@@ -257,0 +261,0 @@ /** |
@@ -249,4 +249,8 @@ // From https://github.com/reduxjs/react-redux/blob/720f0ba79236cdc3e1115f4ef9a7760a21784b48/src/utils/shallowEqual.ts | ||
*/ | ||
function createStoreWithProducer(producer, initialContext, transitions) { | ||
return createStoreCore(initialContext, transitions, producer); | ||
function createStoreWithProducer(producer, initialContextOrConfig, transitions) { | ||
if (typeof initialContextOrConfig === 'object' && 'context' in initialContextOrConfig && 'on' in initialContextOrConfig) { | ||
return createStoreCore(initialContextOrConfig.context, initialContextOrConfig.on, producer); | ||
} | ||
return createStoreCore(initialContextOrConfig, transitions, producer); | ||
} | ||
@@ -253,0 +257,0 @@ /** |
{ | ||
"name": "@xstate/store", | ||
"version": "2.5.0", | ||
"version": "2.6.0", | ||
"description": "Simple stores", | ||
@@ -58,2 +58,3 @@ "keywords": [ | ||
"devDependencies": { | ||
"@statelyai/inspect": "^0.4.0", | ||
"@testing-library/react": "^16.0.0", | ||
@@ -67,5 +68,5 @@ "@types/react": "^18.3.3", | ||
"solid-testing-library": "^0.3.0", | ||
"@xstate/vue": "^3.1.3", | ||
"@xstate/react": "^4.1.2", | ||
"xstate": "^5.18.1" | ||
"@xstate/react": "^4.1.3", | ||
"@xstate/vue": "^3.1.4", | ||
"xstate": "^5.18.2" | ||
}, | ||
@@ -72,0 +73,0 @@ "peerDependencies": { |
@@ -26,6 +26,8 @@ # `@xstate/store` | ||
export const donutStore = createStore( | ||
{ donuts: 0, favoriteFlavor: 'chocolate' }, | ||
{ | ||
export const donutStore = createStore({ | ||
context: { | ||
donuts: 0, | ||
favoriteFlavor: 'chocolate' | ||
}, | ||
on: { | ||
addDonut: { | ||
@@ -41,3 +43,3 @@ donuts: (context) => context.donuts + 1 | ||
} | ||
); | ||
}); | ||
@@ -58,2 +60,32 @@ donutStore.subscribe((snapshot) => { | ||
<details> | ||
<summary>Note: Deprecated <code>createStore(context, transitions)</code> API | ||
</summary> | ||
The previous version of `createStore` took two arguments: an initial context and an object of event handlers. This API is still supported but deprecated. Here's an example of the old usage: | ||
```ts | ||
import { createStore } from '@xstate/store'; | ||
const donutStore = createStore( | ||
{ | ||
donuts: 0, | ||
favoriteFlavor: 'chocolate' | ||
}, | ||
{ | ||
addDonut: (context) => ({ ...context, donuts: context.donuts + 1 }), | ||
changeFlavor: (context, event: { flavor: string }) => ({ | ||
...context, | ||
favoriteFlavor: event.flavor | ||
}), | ||
eatAllDonuts: (context) => ({ ...context, donuts: 0 }) | ||
} | ||
); | ||
``` | ||
We recommend using the new API for better type inference and more explicit configuration. | ||
</details> | ||
## Usage with React | ||
@@ -109,9 +141,8 @@ | ||
const donutStore = createStoreWithProducer( | ||
produce, | ||
{ | ||
const donutStore = createStoreWithProducer(produce, { | ||
context: { | ||
donuts: 0, | ||
favoriteFlavor: 'chocolate' | ||
}, | ||
{ | ||
on: { | ||
addDonut: (context) => { | ||
@@ -127,3 +158,3 @@ context.donuts++; // "Mutation" (thanks to the producer) | ||
} | ||
); | ||
}); | ||
@@ -140,4 +171,4 @@ // Everything else is the same! | ||
const donutStore = createStore( | ||
// Inferred as: | ||
const donutStore = createStore({ | ||
// Context inferred as: | ||
// { | ||
@@ -147,7 +178,7 @@ // donuts: number; | ||
// } | ||
{ | ||
context: { | ||
donuts: 0, | ||
favoriteFlavor: 'chocolate' | ||
}, | ||
{ | ||
on: { | ||
// Event inferred as: | ||
@@ -162,3 +193,3 @@ // { | ||
} | ||
); | ||
}); | ||
@@ -188,5 +219,8 @@ donutStore.getSnapshot().context.favoriteFlavor; // string | ||
const donutStore = createStore(donutContext, { | ||
// ... (transitions go here) | ||
const donutStore = createStore({ | ||
context: donutContext, | ||
on: { | ||
// ... (transitions go here) | ||
} | ||
}); | ||
``` |
56738
1364
218
12