File tree Expand file tree Collapse file tree 4 files changed +44
-21
lines changed
Expand file tree Collapse file tree 4 files changed +44
-21
lines changed Original file line number Diff line number Diff line change @@ -27,10 +27,10 @@ const useStore = create((set) => ({
2727
2828### Store Shape Mode (` sliceMode ` )
2929
30- ` create() ` uses ` sliceMode: 'auto' ` by default. ` auto ` only handles unambiguous
31- inputs. If you pass an object whose enumerable values are all functions, you
32- must set ` sliceMode ` explicitly because that shape can mean either a plain store
33- or slices .
30+ ` create() ` uses ` sliceMode: 'auto' ` by default. For backward compatibility,
31+ ` auto ` still treats a non-empty object whose enumerable values are all
32+ functions as slices. That shape is ambiguous with a plain store that only
33+ contains methods, so you should set ` sliceMode ` explicitly .
3434
3535You can force behavior explicitly:
3636
Original file line number Diff line number Diff line change @@ -20,6 +20,21 @@ import { wrapStore } from './wrapStore';
2020import { handleMainTransport } from './handleMainTransport' ;
2121
2222const namespaceMap = new Map < string , boolean > ( ) ;
23+ let hasWarnedAmbiguousFunctionMap = false ;
24+
25+ const warnAmbiguousFunctionMap = ( ) => {
26+ if (
27+ hasWarnedAmbiguousFunctionMap ||
28+ process . env . NODE_ENV === 'production' ||
29+ process . env . NODE_ENV === 'test'
30+ ) {
31+ return ;
32+ }
33+ hasWarnedAmbiguousFunctionMap = true ;
34+ console . warn (
35+ `sliceMode: 'auto' inferred slices from an object of functions. This shape is ambiguous with a single store that only contains methods. Set sliceMode to 'slices' or 'single' explicitly.`
36+ ) ;
37+ } ;
2338
2439/**
2540 * Create a simple store or a shared store. The shared store can be used in a worker or another thread.
@@ -124,9 +139,8 @@ export const create: Creator = <T extends CreateState>(
124139 return true ;
125140 }
126141 if ( isFunctionMapObject ( ) ) {
127- throw new Error (
128- `sliceMode: 'auto' cannot infer whether an object of functions is a single store or slices. Please set sliceMode to 'single' or 'slices'.`
129- ) ;
142+ warnAmbiguousFunctionMap ( ) ;
143+ return true ;
130144 }
131145 return false ;
132146 } ;
Original file line number Diff line number Diff line change @@ -206,8 +206,8 @@ export type StoreOptions<T extends CreateState> = {
206206 enablePatches ?: boolean ;
207207 /**
208208 * control how createState should be interpreted.
209- * - auto: infer only unambiguous shapes . Object maps whose values are all
210- * functions must set `sliceMode` explicitly.
209+ * - auto: infer from createState shape . Object maps whose values are all
210+ * functions are ambiguous, so prefer setting `sliceMode` explicitly.
211211 * - slices: force slices mode.
212212 * - single: force single-store mode.
213213 */
@@ -222,8 +222,8 @@ export type ClientStoreOptions<T extends CreateState> = {
222222 middlewares ?: Middleware < T > [ ] ;
223223 /**
224224 * control how createState should be interpreted.
225- * - auto: infer only unambiguous shapes . Object maps whose values are all
226- * functions must set `sliceMode` explicitly.
225+ * - auto: infer from createState shape . Object maps whose values are all
226+ * functions are ambiguous, so prefer setting `sliceMode` explicitly.
227227 * - slices: force slices mode.
228228 * - single: force single-store mode.
229229 */
Original file line number Diff line number Diff line change @@ -435,16 +435,25 @@ describe('Store Name Lifecycle', () => {
435435} ) ;
436436
437437describe ( 'sliceMode' , ( ) => {
438- test ( 'auto mode rejects ambiguous function maps without invoking them' , ( ) => {
439- const ping = jest . fn ( ( ) => ( { ok : true } ) ) ;
440- expect ( ( ) =>
441- create ( {
442- ping
443- } as any )
444- ) . toThrow (
445- "sliceMode: 'auto' cannot infer whether an object of functions is a single store or slices. Please set sliceMode to 'single' or 'slices'."
446- ) ;
447- expect ( ping ) . not . toHaveBeenCalled ( ) ;
438+ test ( 'auto mode preserves slices inference and warns in development' , ( ) => {
439+ const prev = process . env . NODE_ENV ;
440+ process . env . NODE_ENV = 'development' ;
441+ const warn = jest . spyOn ( console , 'warn' ) . mockImplementation ( ( ) => { } ) ;
442+ try {
443+ const useStore = create ( {
444+ counter : ( ) => ( {
445+ count : 0
446+ } )
447+ } ) ;
448+ expect ( useStore . isSliceStore ) . toBe ( true ) ;
449+ expect ( useStore . getState ( ) . counter . count ) . toBe ( 0 ) ;
450+ expect ( warn ) . toHaveBeenCalledWith (
451+ "sliceMode: 'auto' inferred slices from an object of functions. This shape is ambiguous with a single store that only contains methods. Set sliceMode to 'slices' or 'single' explicitly."
452+ ) ;
453+ } finally {
454+ warn . mockRestore ( ) ;
455+ process . env . NODE_ENV = prev ;
456+ }
448457 } ) ;
449458
450459 test ( 'single mode treats function maps as a plain store' , ( ) => {
You can’t perform that action at this time.
0 commit comments