File tree Expand file tree Collapse file tree
Expand file tree Collapse file tree Original file line number Diff line number Diff line change 1+ ---
2+ ' @xstate/store ' : minor
3+ ---
4+
5+ Expose ` store.schemas ` so integrations can read the store's context, event, and emitted event schemas at runtime.
6+
7+ ``` ts
8+ const store = createStore ({
9+ schemas: {
10+ context: z .object ({ count: z .number () }),
11+ events: {
12+ inc: z .object ({ by: z .number () })
13+ }
14+ },
15+ context: { count: 0 },
16+ on: {
17+ inc : (context , event ) => ({ count: context .count + event .by })
18+ }
19+ });
20+
21+ store .schemas ?.events ?.inc ;
22+ ```
Original file line number Diff line number Diff line change @@ -246,6 +246,7 @@ function createStoreCore<
246246 let currentSnapshot : TSnapshot = initialSnapshot ;
247247 const atom = createAtom < StoreSnapshot < TContext > > ( currentSnapshot ) ;
248248 const eventTypes = logic . eventTypes ;
249+ const schemas = logic . schemas ;
249250
250251 const emit = ( ev : TEmitted ) => {
251252 listeners ?. get ( ev . type ) ?. forEach ( ( listener ) => listener ( ev ) ) ;
@@ -360,6 +361,7 @@ function createStoreCore<
360361 transition ( state , event ) {
361362 return transition ( state as TSnapshot , event ) ;
362363 } ,
364+ schemas,
363365 sessionId : uniqueId ( ) ,
364366 send,
365367 getSnapshot ( ) {
Original file line number Diff line number Diff line change @@ -193,6 +193,8 @@ export interface Store<
193193> extends Subscribable < StoreSnapshot < TContext > > ,
194194 InteropObservable < StoreSnapshot < TContext > > ,
195195 Readable < StoreSnapshot < TContext > > {
196+ /** Standard Schema definitions for this store, if provided. */
197+ readonly schemas ?: StoreSchemas < any , any , any > ;
196198 send : ( event : ExtractEvents < TEventPayloadMap > ) => void ;
197199 getSnapshot : ( ) => StoreSnapshot < TContext > ;
198200 /** Read the current snapshot as a `Readable` value. */
Original file line number Diff line number Diff line change @@ -155,6 +155,43 @@ it('does not expose atom internals at runtime', () => {
155155 expect ( '_snapshot' in store ) . toBe ( false ) ;
156156} ) ;
157157
158+ it ( 'exposes schemas at runtime' , ( ) => {
159+ const schemas = {
160+ context : z . object ( { count : z . number ( ) } ) ,
161+ events : {
162+ inc : z . object ( { by : z . number ( ) } )
163+ } ,
164+ emitted : {
165+ increased : z . object ( { by : z . number ( ) } )
166+ }
167+ } ;
168+ const store = createStore ( {
169+ schemas,
170+ context : { count : 0 } ,
171+ on : {
172+ inc : ( context , event , enq ) => {
173+ enq . emit . increased ( { by : event . by } ) ;
174+ return { count : context . count + event . by } ;
175+ }
176+ }
177+ } ) ;
178+
179+ expect ( store . schemas ) . toBe ( schemas ) ;
180+ } ) ;
181+
182+ it ( 'exposes schemas after extension' , ( ) => {
183+ const schemas = {
184+ context : z . object ( { count : z . number ( ) } )
185+ } ;
186+ const store = createStore ( {
187+ schemas,
188+ context : { count : 0 } ,
189+ on : { }
190+ } ) . with ( reset ( ) ) ;
191+
192+ expect ( store . schemas ) . toBe ( schemas ) ;
193+ } ) ;
194+
158195it ( 'can be inspected' , ( ) => {
159196 const store = createStore ( {
160197 context : {
Original file line number Diff line number Diff line change 11import { createActor } from 'xstate' ;
2- import { createStore , createStoreLogic , fromStore } from '../src/index.ts' ;
2+ import {
3+ createStore ,
4+ createStoreLogic ,
5+ fromStore ,
6+ type StoreSchemas
7+ } from '../src/index.ts' ;
38import { z } from 'zod' ;
49
510describe ( 'emitted' , ( ) => {
@@ -372,10 +377,11 @@ describe('schemas', () => {
372377 } ) ;
373378
374379 it ( 'uses schema-declared context for snapshot typing' , ( ) => {
380+ const schemas = {
381+ context : z . object ( { count : z . number ( ) , label : z . string ( ) } )
382+ } ;
375383 const store = createStore ( {
376- schemas : {
377- context : z . object ( { count : z . number ( ) , label : z . string ( ) } )
378- } ,
384+ schemas,
379385 context : {
380386 count : 0 ,
381387 label : 'ready'
@@ -384,6 +390,7 @@ describe('schemas', () => {
384390 } ) ;
385391
386392 store . getSnapshot ( ) . context . label satisfies string ;
393+ store . schemas satisfies StoreSchemas | undefined ;
387394
388395 // @ts -expect-error
389396 store . getSnapshot ( ) . context . label satisfies number ;
You can’t perform that action at this time.
0 commit comments