@sqlrooms/room-store 0.26.1-rc.3 → 0.26.1-rc.5

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,4 +1,5 @@
1
1
  import { StateCreator, StoreApi } from 'zustand';
2
+ export type { StateCreator };
2
3
  export interface SliceFunctions {
3
4
  initialize?: () => Promise<void>;
4
5
  destroy?: () => Promise<void>;
@@ -1 +1 @@
1
- {"version":3,"file":"BaseRoomStore.d.ts","sourceRoot":"","sources":["../src/BaseRoomStore.ts"],"names":[],"mappings":"AACA,OAAO,EAAC,YAAY,EAAE,QAAQ,EAAwB,MAAM,SAAS,CAAC;AAEtE,MAAM,WAAW,cAAc;IAC7B,UAAU,CAAC,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,CAAC;IACjC,OAAO,CAAC,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,CAAC;CAC/B;AAED,MAAM,MAAM,kBAAkB,GAAG;IAC/B,IAAI,EAAE;QACJ,WAAW,EAAE,OAAO,CAAC;QACrB,UAAU,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,CAAC;QAChC,OAAO,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,CAAC;QAC7B,gBAAgB,EAAE,CAAC,SAAS,EAAE,OAAO,EAAE,cAAc,CAAC,EAAE,OAAO,KAAK,IAAI,CAAC;KAC1E,CAAC;CACH,CAAC;AAEF,MAAM,MAAM,aAAa,CAAC,EAAE,SAAS,kBAAkB,IAAI,QAAQ,CAAC,EAAE,CAAC,CAAC;AAExE,MAAM,MAAM,wBAAwB,GAAG;IACrC,gBAAgB,CAAC,EAAE,kBAAkB,CAAC,MAAM,CAAC,CAAC,kBAAkB,CAAC,CAAC;CACnE,CAAC;AAEF,wBAAgB,mBAAmB,CACjC,KAAK,CAAC,EAAE,wBAAwB,GAC/B,YAAY,CAAC,kBAAkB,CAAC,CAuBlC;AACD,kDAAkD;AAClD,eAAO,MAAM,eAAe,4BAAsB,CAAC;AAEnD,wBAAgB,WAAW,CACzB,UAAU,EACV,UAAU,SAAS,UAAU,GAAG,kBAAkB,GAAG,UAAU,EAE/D,YAAY,EAAE,CAAC,GAAG,IAAI,EAAE,UAAU,CAAC,YAAY,CAAC,UAAU,CAAC,CAAC,KAAK,UAAU,GAC1E,YAAY,CAAC,UAAU,CAAC,CAG1B;AAED,0CAA0C;AAC1C,eAAO,MAAM,eAAe,oBAAc,CAAC;AAE3C;;;;;GAKG;AACH,wBAAgB,eAAe,CAAC,EAAE,SAAS,kBAAkB,EAC3D,YAAY,EAAE,YAAY,CAAC,EAAE,CAAC;;mBAMR,CAAC,YAAY,CAAC,KAAK,EAAE,EAAE,KAAK,CAAC,KAAG,CAAC;EAKxD;AAED;;;;;;;GAOG;AACH,wBAAgB,sBAAsB,CAAC,EAAE,SAAS,kBAAkB,MACjD,QAAQ,SAAS,CAAC,GAAG,IAAI,EAAE,GAAG,EAAE,KAAK,YAAY,CAAC,EAAE,CAAC,EACpE,qBAAqB,QAAQ,KAC5B;IACD,eAAe,EAAE,CAAC,GAAG,IAAI,EAAE,UAAU,CAAC,QAAQ,CAAC,KAAK,QAAQ,CAAC,EAAE,CAAC,CAAC;IACjE,YAAY,EAAE,CAAC,CAAC,EAAE,QAAQ,EAAE,CAAC,KAAK,EAAE,EAAE,KAAK,CAAC,KAAK,CAAC,CAAC;CACpD,CAsCF;AAED,wBAAgB,yBAAyB,CACvC,KAAK,EAAE,OAAO,GACb,KAAK,IAAI,QAAQ,CAAC,IAAI,CAAC,cAAc,EAAE,YAAY,CAAC,CAAC,CAOvD;AAED,wBAAgB,sBAAsB,CACpC,KAAK,EAAE,OAAO,GACb,KAAK,IAAI,QAAQ,CAAC,IAAI,CAAC,cAAc,EAAE,SAAS,CAAC,CAAC,CAOpD"}
1
+ {"version":3,"file":"BaseRoomStore.d.ts","sourceRoot":"","sources":["../src/BaseRoomStore.ts"],"names":[],"mappings":"AACA,OAAO,EAAC,YAAY,EAAE,QAAQ,EAAwB,MAAM,SAAS,CAAC;AAGtE,YAAY,EAAC,YAAY,EAAC,CAAC;AAE3B,MAAM,WAAW,cAAc;IAC7B,UAAU,CAAC,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,CAAC;IACjC,OAAO,CAAC,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,CAAC;CAC/B;AAED,MAAM,MAAM,kBAAkB,GAAG;IAC/B,IAAI,EAAE;QACJ,WAAW,EAAE,OAAO,CAAC;QACrB,UAAU,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,CAAC;QAChC,OAAO,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,CAAC;QAC7B,gBAAgB,EAAE,CAAC,SAAS,EAAE,OAAO,EAAE,cAAc,CAAC,EAAE,OAAO,KAAK,IAAI,CAAC;KAC1E,CAAC;CACH,CAAC;AAEF,MAAM,MAAM,aAAa,CAAC,EAAE,SAAS,kBAAkB,IAAI,QAAQ,CAAC,EAAE,CAAC,CAAC;AAExE,MAAM,MAAM,wBAAwB,GAAG;IACrC,gBAAgB,CAAC,EAAE,kBAAkB,CAAC,MAAM,CAAC,CAAC,kBAAkB,CAAC,CAAC;CACnE,CAAC;AAEF,wBAAgB,mBAAmB,CACjC,KAAK,CAAC,EAAE,wBAAwB,GAC/B,YAAY,CAAC,kBAAkB,CAAC,CAgClC;AACD,kDAAkD;AAClD,eAAO,MAAM,eAAe,4BAAsB,CAAC;AAEnD,wBAAgB,WAAW,CACzB,UAAU,EACV,UAAU,SAAS,UAAU,GAAG,kBAAkB,GAAG,UAAU,EAE/D,YAAY,EAAE,CAAC,GAAG,IAAI,EAAE,UAAU,CAAC,YAAY,CAAC,UAAU,CAAC,CAAC,KAAK,UAAU,GAC1E,YAAY,CAAC,UAAU,CAAC,CAG1B;AAED,0CAA0C;AAC1C,eAAO,MAAM,eAAe,oBAAc,CAAC;AAE3C;;;;;GAKG;AACH,wBAAgB,eAAe,CAAC,EAAE,SAAS,kBAAkB,EAC3D,YAAY,EAAE,YAAY,CAAC,EAAE,CAAC;;mBAMR,CAAC,YAAY,CAAC,KAAK,EAAE,EAAE,KAAK,CAAC,KAAG,CAAC;EAKxD;AAED;;;;;;;GAOG;AACH,wBAAgB,sBAAsB,CAAC,EAAE,SAAS,kBAAkB,MACjD,QAAQ,SAAS,CAAC,GAAG,IAAI,EAAE,GAAG,EAAE,KAAK,YAAY,CAAC,EAAE,CAAC,EACpE,qBAAqB,QAAQ,KAC5B;IACD,eAAe,EAAE,CAAC,GAAG,IAAI,EAAE,UAAU,CAAC,QAAQ,CAAC,KAAK,QAAQ,CAAC,EAAE,CAAC,CAAC;IACjE,YAAY,EAAE,CAAC,CAAC,EAAE,QAAQ,EAAE,CAAC,KAAK,EAAE,EAAE,KAAK,CAAC,KAAK,CAAC,CAAC;CACpD,CAsCF;AAED,wBAAgB,yBAAyB,CACvC,KAAK,EAAE,OAAO,GACb,KAAK,IAAI,QAAQ,CAAC,IAAI,CAAC,cAAc,EAAE,YAAY,CAAC,CAAC,CAOvD;AAED,wBAAgB,sBAAsB,CACpC,KAAK,EAAE,OAAO,GACb,KAAK,IAAI,QAAQ,CAAC,IAAI,CAAC,cAAc,EAAE,SAAS,CAAC,CAAC,CAOpD"}
@@ -5,14 +5,18 @@ export function createBaseRoomSlice(props) {
5
5
  room: {
6
6
  initialized: false,
7
7
  initialize: async () => {
8
- await Promise.all(Object.values(store.getState())
9
- .filter(isRoomSliceWithInitialize)
10
- .map((slice) => slice.initialize));
8
+ await Promise.all(Object.entries(store.getState())
9
+ .filter(([key, slice]) => key !== 'room' && isRoomSliceWithInitialize(slice))
10
+ .map(async ([_key, slice]) => {
11
+ await slice.initialize();
12
+ }));
11
13
  },
12
14
  destroy: async () => {
13
- await Promise.all(Object.values(store.getState())
14
- .filter(isRoomSliceWithDestroy)
15
- .map((slice) => slice.destroy));
15
+ await Promise.all(Object.entries(store.getState())
16
+ .filter(([key, slice]) => key !== 'room' && isRoomSliceWithDestroy(slice))
17
+ .map(async ([_key, slice]) => {
18
+ await slice.destroy();
19
+ }));
16
20
  },
17
21
  captureException: props?.captureException ??
18
22
  ((exception) => console.error(exception)),
@@ -1 +1 @@
1
- {"version":3,"file":"BaseRoomStore.js","sourceRoot":"","sources":["../src/BaseRoomStore.ts"],"names":[],"mappings":"AAAA,OAAO,EAAC,OAAO,EAAC,MAAM,OAAO,CAAC;AAC9B,OAAO,EAAyB,WAAW,EAAE,QAAQ,EAAC,MAAM,SAAS,CAAC;AAsBtE,MAAM,UAAU,mBAAmB,CACjC,KAAgC;IAEhC,OAAO,CAAC,IAAI,EAAE,IAAI,EAAE,KAAK,EAAE,EAAE,CAAC,CAAC;QAC7B,IAAI,EAAE;YACJ,WAAW,EAAE,KAAK;YAClB,UAAU,EAAE,KAAK,IAAI,EAAE;gBACrB,MAAM,OAAO,CAAC,GAAG,CACf,MAAM,CAAC,MAAM,CAAC,KAAK,CAAC,QAAQ,EAAE,CAAC;qBAC5B,MAAM,CAAC,yBAAyB,CAAC;qBACjC,GAAG,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,KAAK,CAAC,UAAU,CAAC,CACpC,CAAC;YACJ,CAAC;YACD,OAAO,EAAE,KAAK,IAAI,EAAE;gBAClB,MAAM,OAAO,CAAC,GAAG,CACf,MAAM,CAAC,MAAM,CAAC,KAAK,CAAC,QAAQ,EAAE,CAAC;qBAC5B,MAAM,CAAC,sBAAsB,CAAC;qBAC9B,GAAG,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,KAAK,CAAC,OAAO,CAAC,CACjC,CAAC;YACJ,CAAC;YACD,gBAAgB,EACd,KAAK,EAAE,gBAAgB;gBACvB,CAAC,CAAC,SAAkB,EAAE,EAAE,CAAC,OAAO,CAAC,KAAK,CAAC,SAAS,CAAC,CAAC;SACrD;KACF,CAAC,CAAC;AACL,CAAC;AACD,kDAAkD;AAClD,MAAM,CAAC,MAAM,eAAe,GAAG,mBAAmB,CAAC;AAEnD,MAAM,UAAU,WAAW,CAIzB,YAA2E;IAE3E,OAAO,CAAC,GAAG,EAAE,GAAG,EAAE,KAAK,EAAE,EAAE,CACzB,YAAY,CAAC,GAAG,EAAE,GAAuB,EAAE,KAA6B,CAAC,CAAC;AAC9E,CAAC;AAED,0CAA0C;AAC1C,MAAM,CAAC,MAAM,eAAe,GAAG,WAAW,CAAC;AAE3C;;;;;GAKG;AACH,MAAM,UAAU,eAAe,CAC7B,YAA8B;IAE9B,MAAM,OAAO,GAAG,sBAAsB,EAA2B,CAAC;IAClE,MAAM,YAAY,GAAG,OAAO,CAAC,GAAG,EAAE,CAAC,YAAY,CAAC,CAAC;IACjD,MAAM,SAAS,GAAG,YAAY,CAAC,eAAe,EAAE,CAAC;IAEjD,SAAS,YAAY,CAAI,QAA0B;QACjD,OAAO,YAAY,CAAC,YAAY,CAAC,QAAQ,CAAC,CAAC;IAC7C,CAAC;IAED,OAAO,EAAC,SAAS,EAAE,YAAY,EAAC,CAAC;AACnC,CAAC;AAED;;;;;;;GAOG;AACH,MAAM,UAAU,sBAAsB;IACpC,OAAO,UACL,mBAA6B;QAK7B,IAAI,KAA+B,CAAC;QAEpC,SAAS,eAAe,CAAC,GAAG,IAA0B;YACpD,KAAK,GAAG,WAAW,CAAC,mBAAmB,CAAC,GAAG,IAAI,CAAC,CAAC,CAAC;YAClD,IAAI,OAAO,MAAM,KAAK,WAAW,EAAE,CAAC;gBAClC,CAAC,KAAK,IAAI,EAAE;oBACV,IAAI,CAAC;wBACH,sBAAsB;wBACtB,MAAM,KAAK,CAAC,QAAQ,EAAE,CAAC,IAAI,CAAC,UAAU,EAAE,CAAC;wBACzC,+CAA+C;wBAC/C,KAAK,CAAC,QAAQ,CAAC,CAAC,KAAK,EAAE,EAAE,CACvB,OAAO,CAAC,KAAK,EAAE,CAAC,KAAK,EAAE,EAAE;4BACvB,KAAK,CAAC,IAAI,CAAC,WAAW,GAAG,IAAI,CAAC;wBAChC,CAAC,CAAC,CACH,CAAC;oBACJ,CAAC;oBAAC,OAAO,KAAK,EAAE,CAAC;wBACf,KAAK,CAAC,QAAQ,EAAE,CAAC,IAAI,CAAC,gBAAgB,CAAC,KAAK,CAAC,CAAC;oBAChD,CAAC;gBACH,CAAC,CAAC,EAAE,CAAC;YACP,CAAC;iBAAM,CAAC;gBACN,OAAO,CAAC,IAAI,CACV,uFAAuF,CACxF,CAAC;YACJ,CAAC;YACD,OAAO,KAAK,CAAC;QACf,CAAC;QAED,SAAS,YAAY,CAAI,QAA0B;YACjD,IAAI,CAAC,KAAK;gBACR,MAAM,IAAI,KAAK,CACb,yDAAyD,CAC1D,CAAC;YACJ,OAAO,QAAQ,CAAC,KAAK,EAAE,QAAQ,CAAC,CAAC;QACnC,CAAC;QAED,OAAO,EAAC,eAAe,EAAE,YAAY,EAAC,CAAC;IACzC,CAAC,CAAC;AACJ,CAAC;AAED,MAAM,UAAU,yBAAyB,CACvC,KAAc;IAEd,OAAO,CACL,OAAO,KAAK,KAAK,QAAQ;QACzB,KAAK,KAAK,IAAI;QACd,YAAY,IAAI,KAAK;QACrB,OAAO,KAAK,CAAC,UAAU,KAAK,UAAU,CACvC,CAAC;AACJ,CAAC;AAED,MAAM,UAAU,sBAAsB,CACpC,KAAc;IAEd,OAAO,CACL,OAAO,KAAK,KAAK,QAAQ;QACzB,KAAK,KAAK,IAAI;QACd,SAAS,IAAI,KAAK;QAClB,OAAO,KAAK,CAAC,OAAO,KAAK,UAAU,CACpC,CAAC;AACJ,CAAC","sourcesContent":["import {produce} from 'immer';\nimport {StateCreator, StoreApi, createStore, useStore} from 'zustand';\n\nexport interface SliceFunctions {\n initialize?: () => Promise<void>;\n destroy?: () => Promise<void>;\n}\n\nexport type BaseRoomStoreState = {\n room: {\n initialized: boolean;\n initialize: () => Promise<void>;\n destroy: () => Promise<void>;\n captureException: (exception: unknown, captureContext?: unknown) => void;\n };\n};\n\nexport type BaseRoomStore<RS extends BaseRoomStoreState> = StoreApi<RS>;\n\nexport type CreateBaseRoomSliceProps = {\n captureException?: BaseRoomStoreState['room']['captureException'];\n};\n\nexport function createBaseRoomSlice(\n props?: CreateBaseRoomSliceProps,\n): StateCreator<BaseRoomStoreState> {\n return (_set, _get, store) => ({\n room: {\n initialized: false,\n initialize: async () => {\n await Promise.all(\n Object.values(store.getState())\n .filter(isRoomSliceWithInitialize)\n .map((slice) => slice.initialize),\n );\n },\n destroy: async () => {\n await Promise.all(\n Object.values(store.getState())\n .filter(isRoomSliceWithDestroy)\n .map((slice) => slice.destroy),\n );\n },\n captureException:\n props?.captureException ??\n ((exception: unknown) => console.error(exception)),\n },\n });\n}\n/** @deprecated Use createBaseRoomSlice instead */\nexport const createRoomSlice = createBaseRoomSlice;\n\nexport function createSlice<\n SliceState,\n StoreState extends SliceState = BaseRoomStoreState & SliceState,\n>(\n sliceCreator: (...args: Parameters<StateCreator<StoreState>>) => SliceState,\n): StateCreator<SliceState> {\n return (set, get, store) =>\n sliceCreator(set, get as () => StoreState, store as StoreApi<StoreState>);\n}\n\n/** @deprecated Use createSlice instead */\nexport const createBaseSlice = createSlice;\n\n/**\n * Create a room store with custom fields and methods\n * @param initialState - The initial state and config for the room\n * @param sliceCreators - The slices to add to the room store\n * @returns The room store and a hook for accessing the room store\n */\nexport function createRoomStore<RS extends BaseRoomStoreState>(\n stateCreator: StateCreator<RS>,\n) {\n const factory = createRoomStoreCreator<BaseRoomStoreState & RS>();\n const storeCreator = factory(() => stateCreator);\n const roomStore = storeCreator.createRoomStore();\n\n function useRoomStore<T>(selector: (state: RS) => T): T {\n return storeCreator.useRoomStore(selector);\n }\n\n return {roomStore, useRoomStore};\n}\n\n/**\n * Factory to create a room store creator with custom params.\n *\n * @template RS - Room state type\n * @param stateCreatorFactory - A function that takes params and returns a Zustand state creator\n * @returns An object with createRoomStore(params) and useRoomStore(selector)\n *\n */\nexport function createRoomStoreCreator<RS extends BaseRoomStoreState>() {\n return function <TFactory extends (...args: any[]) => StateCreator<RS>>(\n stateCreatorFactory: TFactory,\n ): {\n createRoomStore: (...args: Parameters<TFactory>) => StoreApi<RS>;\n useRoomStore: <T>(selector: (state: RS) => T) => T;\n } {\n let store: StoreApi<RS> | undefined;\n\n function createRoomStore(...args: Parameters<TFactory>): StoreApi<RS> {\n store = createStore(stateCreatorFactory(...args));\n if (typeof window !== 'undefined') {\n (async () => {\n try {\n // Initialize the room\n await store.getState().room.initialize();\n // Set initialized to true after initialization\n store.setState((state) =>\n produce(state, (draft) => {\n draft.room.initialized = true;\n }),\n );\n } catch (error) {\n store.getState().room.captureException(error);\n }\n })();\n } else {\n console.warn(\n 'Skipping room store initialization. The room store should only be used on the client.',\n );\n }\n return store;\n }\n\n function useRoomStore<T>(selector: (state: RS) => T): T {\n if (!store)\n throw new Error(\n 'Room store not initialized. Call createRoomStore first.',\n );\n return useStore(store, selector);\n }\n\n return {createRoomStore, useRoomStore};\n };\n}\n\nexport function isRoomSliceWithInitialize(\n slice: unknown,\n): slice is Required<Pick<SliceFunctions, 'initialize'>> {\n return (\n typeof slice === 'object' &&\n slice !== null &&\n 'initialize' in slice &&\n typeof slice.initialize === 'function'\n );\n}\n\nexport function isRoomSliceWithDestroy(\n slice: unknown,\n): slice is Required<Pick<SliceFunctions, 'destroy'>> {\n return (\n typeof slice === 'object' &&\n slice !== null &&\n 'destroy' in slice &&\n typeof slice.destroy === 'function'\n );\n}\n"]}
1
+ {"version":3,"file":"BaseRoomStore.js","sourceRoot":"","sources":["../src/BaseRoomStore.ts"],"names":[],"mappings":"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","sourcesContent":["import {produce} from 'immer';\nimport {StateCreator, StoreApi, createStore, useStore} from 'zustand';\n\n// Re-export for convenience\nexport type {StateCreator};\n\nexport interface SliceFunctions {\n initialize?: () => Promise<void>;\n destroy?: () => Promise<void>;\n}\n\nexport type BaseRoomStoreState = {\n room: {\n initialized: boolean;\n initialize: () => Promise<void>;\n destroy: () => Promise<void>;\n captureException: (exception: unknown, captureContext?: unknown) => void;\n };\n};\n\nexport type BaseRoomStore<RS extends BaseRoomStoreState> = StoreApi<RS>;\n\nexport type CreateBaseRoomSliceProps = {\n captureException?: BaseRoomStoreState['room']['captureException'];\n};\n\nexport function createBaseRoomSlice(\n props?: CreateBaseRoomSliceProps,\n): StateCreator<BaseRoomStoreState> {\n return (_set, _get, store) => ({\n room: {\n initialized: false,\n initialize: async () => {\n await Promise.all(\n Object.entries(store.getState())\n .filter(\n ([key, slice]) =>\n key !== 'room' && isRoomSliceWithInitialize(slice),\n )\n .map(async ([_key, slice]) => {\n await slice.initialize();\n }),\n );\n },\n destroy: async () => {\n await Promise.all(\n Object.entries(store.getState())\n .filter(\n ([key, slice]) => key !== 'room' && isRoomSliceWithDestroy(slice),\n )\n .map(async ([_key, slice]) => {\n await slice.destroy();\n }),\n );\n },\n captureException:\n props?.captureException ??\n ((exception: unknown) => console.error(exception)),\n },\n });\n}\n/** @deprecated Use createBaseRoomSlice instead */\nexport const createRoomSlice = createBaseRoomSlice;\n\nexport function createSlice<\n SliceState,\n StoreState extends SliceState = BaseRoomStoreState & SliceState,\n>(\n sliceCreator: (...args: Parameters<StateCreator<StoreState>>) => SliceState,\n): StateCreator<SliceState> {\n return (set, get, store) =>\n sliceCreator(set, get as () => StoreState, store as StoreApi<StoreState>);\n}\n\n/** @deprecated Use createSlice instead */\nexport const createBaseSlice = createSlice;\n\n/**\n * Create a room store with custom fields and methods\n * @param initialState - The initial state and config for the room\n * @param sliceCreators - The slices to add to the room store\n * @returns The room store and a hook for accessing the room store\n */\nexport function createRoomStore<RS extends BaseRoomStoreState>(\n stateCreator: StateCreator<RS>,\n) {\n const factory = createRoomStoreCreator<BaseRoomStoreState & RS>();\n const storeCreator = factory(() => stateCreator);\n const roomStore = storeCreator.createRoomStore();\n\n function useRoomStore<T>(selector: (state: RS) => T): T {\n return storeCreator.useRoomStore(selector);\n }\n\n return {roomStore, useRoomStore};\n}\n\n/**\n * Factory to create a room store creator with custom params.\n *\n * @template RS - Room state type\n * @param stateCreatorFactory - A function that takes params and returns a Zustand state creator\n * @returns An object with createRoomStore(params) and useRoomStore(selector)\n *\n */\nexport function createRoomStoreCreator<RS extends BaseRoomStoreState>() {\n return function <TFactory extends (...args: any[]) => StateCreator<RS>>(\n stateCreatorFactory: TFactory,\n ): {\n createRoomStore: (...args: Parameters<TFactory>) => StoreApi<RS>;\n useRoomStore: <T>(selector: (state: RS) => T) => T;\n } {\n let store: StoreApi<RS> | undefined;\n\n function createRoomStore(...args: Parameters<TFactory>): StoreApi<RS> {\n store = createStore(stateCreatorFactory(...args));\n if (typeof window !== 'undefined') {\n (async () => {\n try {\n // Initialize the room\n await store.getState().room.initialize();\n // Set initialized to true after initialization\n store.setState((state) =>\n produce(state, (draft) => {\n draft.room.initialized = true;\n }),\n );\n } catch (error) {\n store.getState().room.captureException(error);\n }\n })();\n } else {\n console.warn(\n 'Skipping room store initialization. The room store should only be used on the client.',\n );\n }\n return store;\n }\n\n function useRoomStore<T>(selector: (state: RS) => T): T {\n if (!store)\n throw new Error(\n 'Room store not initialized. Call createRoomStore first.',\n );\n return useStore(store, selector);\n }\n\n return {createRoomStore, useRoomStore};\n };\n}\n\nexport function isRoomSliceWithInitialize(\n slice: unknown,\n): slice is Required<Pick<SliceFunctions, 'initialize'>> {\n return (\n typeof slice === 'object' &&\n slice !== null &&\n 'initialize' in slice &&\n typeof slice.initialize === 'function'\n );\n}\n\nexport function isRoomSliceWithDestroy(\n slice: unknown,\n): slice is Required<Pick<SliceFunctions, 'destroy'>> {\n return (\n typeof slice === 'object' &&\n slice !== null &&\n 'destroy' in slice &&\n typeof slice.destroy === 'function'\n );\n}\n"]}
@@ -1,4 +1,6 @@
1
+ import { PersistOptions } from 'zustand/middleware';
1
2
  import z from 'zod';
3
+ import { StateCreator } from './BaseRoomStore';
2
4
  /**
3
5
  * Creates partialize and merge functions for Zustand persist middleware.
4
6
  * Automatically handles extracting and merging slice configs.
@@ -30,4 +32,76 @@ export declare function createPersistHelpers<T extends Record<string, z.ZodType>
30
32
  partialize: (state: any) => Record<string, any>;
31
33
  merge: (persistedState: any, currentState: any) => any;
32
34
  };
35
+ /**
36
+ * Wraps a state creator with Zustand's persist middleware and automatically
37
+ * handles slice config serialization/deserialization using Zod schemas.
38
+ *
39
+ * This helper combines persist functionality with automatic `partialize` and `merge`
40
+ * functions generated from your slice config schemas, eliminating manual type casting.
41
+ *
42
+ * @param options - Persist configuration object
43
+ * @param options.name - Unique storage key (required)
44
+ * @param options.sliceConfigSchemas - Map of slice names to Zod schemas for their configs
45
+ * @param options.partialize - Optional custom partialize function (overrides auto-generated one)
46
+ * @param options.merge - Optional custom merge function (overrides auto-generated one)
47
+ * @param options.storage - Custom storage implementation (optional, defaults to localStorage)
48
+ * @param options.version - Schema version for migrations (optional)
49
+ * @param options.migrate - Migration function for version changes (optional)
50
+ * @param options.skipHydration - Skip auto-hydration for SSR (optional)
51
+ * @param stateCreator - Zustand state creator function
52
+ * @returns Properly typed StateCreator with persist middleware applied
53
+ *
54
+ * @see {@link https://zustand.docs.pmnd.rs/middlewares/persist | Zustand persist middleware docs}
55
+ *
56
+ * @example
57
+ * Basic usage:
58
+ * ```ts
59
+ * export const {roomStore, useRoomStore} = createRoomStore<RoomState>(
60
+ * persistSliceConfigs(
61
+ * {
62
+ * name: 'my-app-state-storage',
63
+ * sliceConfigSchemas: {
64
+ * room: BaseRoomConfig,
65
+ * layout: LayoutConfig,
66
+ * sqlEditor: SqlEditorSliceConfig,
67
+ * },
68
+ * },
69
+ * (set, get, store) => ({
70
+ * ...createRoomSlice()(set, get, store),
71
+ * ...createLayoutSlice({...})(set, get, store),
72
+ * })
73
+ * )
74
+ * );
75
+ * ```
76
+ *
77
+ * @example
78
+ * With custom partialize/merge for additional state:
79
+ * ```ts
80
+ * export const {roomStore, useRoomStore} = createRoomStore<RoomState>(
81
+ * persistSliceConfigs(
82
+ * {
83
+ * name: 'my-app-state-storage',
84
+ * sliceConfigSchemas: {
85
+ * room: BaseRoomConfig,
86
+ * layout: LayoutConfig,
87
+ * },
88
+ * partialize: (state) => ({
89
+ * apiKey: state.apiKey, // Persist additional field
90
+ * ...createPersistHelpers({room: BaseRoomConfig, layout: LayoutConfig}).partialize(state),
91
+ * }),
92
+ * merge: (persisted, current) => ({
93
+ * ...createPersistHelpers({room: BaseRoomConfig, layout: LayoutConfig}).merge(persisted, current),
94
+ * apiKey: persisted.apiKey, // Restore additional field
95
+ * }),
96
+ * },
97
+ * (set, get, store) => ({...})
98
+ * )
99
+ * );
100
+ * ```
101
+ */
102
+ export declare function persistSliceConfigs<S>(options: {
103
+ sliceConfigSchemas: Record<string, z.ZodType>;
104
+ partialize?: (state: S) => Partial<S>;
105
+ merge?: (persistedState: unknown, currentState: S) => S;
106
+ } & Omit<PersistOptions<S>, 'partialize' | 'merge'>, stateCreator: StateCreator<S>): StateCreator<S>;
33
107
  //# sourceMappingURL=createPersistHelpers.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"createPersistHelpers.d.ts","sourceRoot":"","sources":["../src/createPersistHelpers.ts"],"names":[],"mappings":"AAAA,OAAO,CAAC,MAAM,KAAK,CAAC;AAEpB;;;;;;;;;;;;;;;;;;;;;;;;;;GA0BG;AACH,wBAAgB,oBAAoB,CAAC,CAAC,SAAS,MAAM,CAAC,MAAM,EAAE,CAAC,CAAC,OAAO,CAAC,EACtE,YAAY,EAAE,CAAC;wBAGO,GAAG;4BAQC,GAAG,gBAAgB,GAAG;EAWjD"}
1
+ {"version":3,"file":"createPersistHelpers.d.ts","sourceRoot":"","sources":["../src/createPersistHelpers.ts"],"names":[],"mappings":"AAAA,OAAO,EAAU,cAAc,EAAC,MAAM,oBAAoB,CAAC;AAC3D,OAAO,CAAC,MAAM,KAAK,CAAC;AACpB,OAAO,EAAC,YAAY,EAAC,MAAM,iBAAiB,CAAC;AAE7C;;;;;;;;;;;;;;;;;;;;;;;;;;GA0BG;AACH,wBAAgB,oBAAoB,CAAC,CAAC,SAAS,MAAM,CAAC,MAAM,EAAE,CAAC,CAAC,OAAO,CAAC,EACtE,YAAY,EAAE,CAAC;wBAGO,GAAG;4BAcC,GAAG,gBAAgB,GAAG;EAiBjD;AAED;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAkEG;AACH,wBAAgB,mBAAmB,CAAC,CAAC,EACnC,OAAO,EAAE;IACP,kBAAkB,EAAE,MAAM,CAAC,MAAM,EAAE,CAAC,CAAC,OAAO,CAAC,CAAC;IAC9C,UAAU,CAAC,EAAE,CAAC,KAAK,EAAE,CAAC,KAAK,OAAO,CAAC,CAAC,CAAC,CAAC;IACtC,KAAK,CAAC,EAAE,CAAC,cAAc,EAAE,OAAO,EAAE,YAAY,EAAE,CAAC,KAAK,CAAC,CAAC;CACzD,GAAG,IAAI,CAAC,cAAc,CAAC,CAAC,CAAC,EAAE,YAAY,GAAG,OAAO,CAAC,EACnD,YAAY,EAAE,YAAY,CAAC,CAAC,CAAC,GAC5B,YAAY,CAAC,CAAC,CAAC,CASjB"}
@@ -1,3 +1,4 @@
1
+ import { persist } from 'zustand/middleware';
1
2
  /**
2
3
  * Creates partialize and merge functions for Zustand persist middleware.
3
4
  * Automatically handles extracting and merging slice configs.
@@ -30,20 +31,110 @@ export function createPersistHelpers(sliceConfigs) {
30
31
  partialize: (state) => {
31
32
  const result = {};
32
33
  for (const [key, schema] of Object.entries(sliceConfigs)) {
33
- result[key] = schema.parse(state[key].config);
34
+ try {
35
+ result[key] = schema.parse(state[key]?.config);
36
+ }
37
+ catch (error) {
38
+ throw new Error(`Error parsing config key "${key}"`, {
39
+ cause: error,
40
+ });
41
+ }
34
42
  }
35
43
  return result;
36
44
  },
37
45
  merge: (persistedState, currentState) => {
38
46
  const merged = { ...currentState };
39
47
  for (const [key, schema] of Object.entries(sliceConfigs)) {
40
- merged[key] = {
41
- ...currentState[key],
42
- config: schema.parse(persistedState[key]),
43
- };
48
+ try {
49
+ merged[key] = {
50
+ ...currentState[key],
51
+ config: schema.parse(persistedState[key]),
52
+ };
53
+ }
54
+ catch (error) {
55
+ throw new Error(`Error parsing config key "${key}"`, {
56
+ cause: error,
57
+ });
58
+ }
44
59
  }
45
60
  return merged;
46
61
  },
47
62
  };
48
63
  }
64
+ /**
65
+ * Wraps a state creator with Zustand's persist middleware and automatically
66
+ * handles slice config serialization/deserialization using Zod schemas.
67
+ *
68
+ * This helper combines persist functionality with automatic `partialize` and `merge`
69
+ * functions generated from your slice config schemas, eliminating manual type casting.
70
+ *
71
+ * @param options - Persist configuration object
72
+ * @param options.name - Unique storage key (required)
73
+ * @param options.sliceConfigSchemas - Map of slice names to Zod schemas for their configs
74
+ * @param options.partialize - Optional custom partialize function (overrides auto-generated one)
75
+ * @param options.merge - Optional custom merge function (overrides auto-generated one)
76
+ * @param options.storage - Custom storage implementation (optional, defaults to localStorage)
77
+ * @param options.version - Schema version for migrations (optional)
78
+ * @param options.migrate - Migration function for version changes (optional)
79
+ * @param options.skipHydration - Skip auto-hydration for SSR (optional)
80
+ * @param stateCreator - Zustand state creator function
81
+ * @returns Properly typed StateCreator with persist middleware applied
82
+ *
83
+ * @see {@link https://zustand.docs.pmnd.rs/middlewares/persist | Zustand persist middleware docs}
84
+ *
85
+ * @example
86
+ * Basic usage:
87
+ * ```ts
88
+ * export const {roomStore, useRoomStore} = createRoomStore<RoomState>(
89
+ * persistSliceConfigs(
90
+ * {
91
+ * name: 'my-app-state-storage',
92
+ * sliceConfigSchemas: {
93
+ * room: BaseRoomConfig,
94
+ * layout: LayoutConfig,
95
+ * sqlEditor: SqlEditorSliceConfig,
96
+ * },
97
+ * },
98
+ * (set, get, store) => ({
99
+ * ...createRoomSlice()(set, get, store),
100
+ * ...createLayoutSlice({...})(set, get, store),
101
+ * })
102
+ * )
103
+ * );
104
+ * ```
105
+ *
106
+ * @example
107
+ * With custom partialize/merge for additional state:
108
+ * ```ts
109
+ * export const {roomStore, useRoomStore} = createRoomStore<RoomState>(
110
+ * persistSliceConfigs(
111
+ * {
112
+ * name: 'my-app-state-storage',
113
+ * sliceConfigSchemas: {
114
+ * room: BaseRoomConfig,
115
+ * layout: LayoutConfig,
116
+ * },
117
+ * partialize: (state) => ({
118
+ * apiKey: state.apiKey, // Persist additional field
119
+ * ...createPersistHelpers({room: BaseRoomConfig, layout: LayoutConfig}).partialize(state),
120
+ * }),
121
+ * merge: (persisted, current) => ({
122
+ * ...createPersistHelpers({room: BaseRoomConfig, layout: LayoutConfig}).merge(persisted, current),
123
+ * apiKey: persisted.apiKey, // Restore additional field
124
+ * }),
125
+ * },
126
+ * (set, get, store) => ({...})
127
+ * )
128
+ * );
129
+ * ```
130
+ */
131
+ export function persistSliceConfigs(options, stateCreator) {
132
+ const { sliceConfigSchemas, partialize, merge, ...persistOptions } = options;
133
+ const helpers = createPersistHelpers(sliceConfigSchemas);
134
+ return persist(stateCreator, {
135
+ ...persistOptions,
136
+ partialize: partialize || helpers.partialize,
137
+ merge: merge || helpers.merge,
138
+ });
139
+ }
49
140
  //# sourceMappingURL=createPersistHelpers.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"createPersistHelpers.js","sourceRoot":"","sources":["../src/createPersistHelpers.ts"],"names":[],"mappings":"AAEA;;;;;;;;;;;;;;;;;;;;;;;;;;GA0BG;AACH,MAAM,UAAU,oBAAoB,CAClC,YAAe;IAEf,OAAO;QACL,UAAU,EAAE,CAAC,KAAU,EAAE,EAAE;YACzB,MAAM,MAAM,GAAwB,EAAE,CAAC;YACvC,KAAK,MAAM,CAAC,GAAG,EAAE,MAAM,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,YAAY,CAAC,EAAE,CAAC;gBACzD,MAAM,CAAC,GAAG,CAAC,GAAG,MAAM,CAAC,KAAK,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,MAAM,CAAC,CAAC;YAChD,CAAC;YACD,OAAO,MAAM,CAAC;QAChB,CAAC;QAED,KAAK,EAAE,CAAC,cAAmB,EAAE,YAAiB,EAAE,EAAE;YAChD,MAAM,MAAM,GAAG,EAAC,GAAG,YAAY,EAAC,CAAC;YACjC,KAAK,MAAM,CAAC,GAAG,EAAE,MAAM,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,YAAY,CAAC,EAAE,CAAC;gBACzD,MAAM,CAAC,GAAG,CAAC,GAAG;oBACZ,GAAG,YAAY,CAAC,GAAG,CAAC;oBACpB,MAAM,EAAE,MAAM,CAAC,KAAK,CAAC,cAAc,CAAC,GAAG,CAAC,CAAC;iBAC1C,CAAC;YACJ,CAAC;YACD,OAAO,MAAM,CAAC;QAChB,CAAC;KACF,CAAC;AACJ,CAAC","sourcesContent":["import z from 'zod';\n\n/**\n * Creates partialize and merge functions for Zustand persist middleware.\n * Automatically handles extracting and merging slice configs.\n *\n * @param sliceConfigs - Map of slice names to their Zod config schemas\n * @returns Object with partialize and merge functions\n *\n * @example\n * ```ts\n * const {partialize, merge} = createPersistHelpers({\n * room: BaseRoomConfig,\n * layout: LayoutConfig,\n * sqlEditor: SqlEditorSliceConfig,\n * });\n *\n * export const {roomStore, useRoomStore} = createRoomStore<RoomState>(\n * persist(\n * (set, get, store) => ({...}),\n * {\n * name: 'my-app-state-storage',\n * partialize,\n * merge,\n * },\n * ) as StateCreator<RoomState>,\n * );\n * ```\n */\nexport function createPersistHelpers<T extends Record<string, z.ZodType>>(\n sliceConfigs: T,\n) {\n return {\n partialize: (state: any) => {\n const result: Record<string, any> = {};\n for (const [key, schema] of Object.entries(sliceConfigs)) {\n result[key] = schema.parse(state[key].config);\n }\n return result;\n },\n\n merge: (persistedState: any, currentState: any) => {\n const merged = {...currentState};\n for (const [key, schema] of Object.entries(sliceConfigs)) {\n merged[key] = {\n ...currentState[key],\n config: schema.parse(persistedState[key]),\n };\n }\n return merged;\n },\n };\n}\n"]}
1
+ {"version":3,"file":"createPersistHelpers.js","sourceRoot":"","sources":["../src/createPersistHelpers.ts"],"names":[],"mappings":"AAAA,OAAO,EAAC,OAAO,EAAiB,MAAM,oBAAoB,CAAC;AAI3D;;;;;;;;;;;;;;;;;;;;;;;;;;GA0BG;AACH,MAAM,UAAU,oBAAoB,CAClC,YAAe;IAEf,OAAO;QACL,UAAU,EAAE,CAAC,KAAU,EAAE,EAAE;YACzB,MAAM,MAAM,GAAwB,EAAE,CAAC;YACvC,KAAK,MAAM,CAAC,GAAG,EAAE,MAAM,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,YAAY,CAAC,EAAE,CAAC;gBACzD,IAAI,CAAC;oBACH,MAAM,CAAC,GAAG,CAAC,GAAG,MAAM,CAAC,KAAK,CAAC,KAAK,CAAC,GAAG,CAAC,EAAE,MAAM,CAAC,CAAC;gBACjD,CAAC;gBAAC,OAAO,KAAK,EAAE,CAAC;oBACf,MAAM,IAAI,KAAK,CAAC,6BAA6B,GAAG,GAAG,EAAE;wBACnD,KAAK,EAAE,KAAK;qBACb,CAAC,CAAC;gBACL,CAAC;YACH,CAAC;YACD,OAAO,MAAM,CAAC;QAChB,CAAC;QAED,KAAK,EAAE,CAAC,cAAmB,EAAE,YAAiB,EAAE,EAAE;YAChD,MAAM,MAAM,GAAG,EAAC,GAAG,YAAY,EAAC,CAAC;YACjC,KAAK,MAAM,CAAC,GAAG,EAAE,MAAM,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,YAAY,CAAC,EAAE,CAAC;gBACzD,IAAI,CAAC;oBACH,MAAM,CAAC,GAAG,CAAC,GAAG;wBACZ,GAAG,YAAY,CAAC,GAAG,CAAC;wBACpB,MAAM,EAAE,MAAM,CAAC,KAAK,CAAC,cAAc,CAAC,GAAG,CAAC,CAAC;qBAC1C,CAAC;gBACJ,CAAC;gBAAC,OAAO,KAAK,EAAE,CAAC;oBACf,MAAM,IAAI,KAAK,CAAC,6BAA6B,GAAG,GAAG,EAAE;wBACnD,KAAK,EAAE,KAAK;qBACb,CAAC,CAAC;gBACL,CAAC;YACH,CAAC;YACD,OAAO,MAAM,CAAC;QAChB,CAAC;KACF,CAAC;AACJ,CAAC;AAED;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAkEG;AACH,MAAM,UAAU,mBAAmB,CACjC,OAImD,EACnD,YAA6B;IAE7B,MAAM,EAAC,kBAAkB,EAAE,UAAU,EAAE,KAAK,EAAE,GAAG,cAAc,EAAC,GAAG,OAAO,CAAC;IAC3E,MAAM,OAAO,GAAG,oBAAoB,CAAC,kBAAkB,CAAC,CAAC;IAEzD,OAAO,OAAO,CAAI,YAAY,EAAE;QAC9B,GAAG,cAAc;QACjB,UAAU,EAAE,UAAU,IAAI,OAAO,CAAC,UAAU;QAC5C,KAAK,EAAE,KAAK,IAAI,OAAO,CAAC,KAAK;KACT,CAAoB,CAAC;AAC7C,CAAC","sourcesContent":["import {persist, PersistOptions} from 'zustand/middleware';\nimport z from 'zod';\nimport {StateCreator} from './BaseRoomStore';\n\n/**\n * Creates partialize and merge functions for Zustand persist middleware.\n * Automatically handles extracting and merging slice configs.\n *\n * @param sliceConfigs - Map of slice names to their Zod config schemas\n * @returns Object with partialize and merge functions\n *\n * @example\n * ```ts\n * const {partialize, merge} = createPersistHelpers({\n * room: BaseRoomConfig,\n * layout: LayoutConfig,\n * sqlEditor: SqlEditorSliceConfig,\n * });\n *\n * export const {roomStore, useRoomStore} = createRoomStore<RoomState>(\n * persist(\n * (set, get, store) => ({...}),\n * {\n * name: 'my-app-state-storage',\n * partialize,\n * merge,\n * },\n * ) as StateCreator<RoomState>,\n * );\n * ```\n */\nexport function createPersistHelpers<T extends Record<string, z.ZodType>>(\n sliceConfigs: T,\n) {\n return {\n partialize: (state: any) => {\n const result: Record<string, any> = {};\n for (const [key, schema] of Object.entries(sliceConfigs)) {\n try {\n result[key] = schema.parse(state[key]?.config);\n } catch (error) {\n throw new Error(`Error parsing config key \"${key}\"`, {\n cause: error,\n });\n }\n }\n return result;\n },\n\n merge: (persistedState: any, currentState: any) => {\n const merged = {...currentState};\n for (const [key, schema] of Object.entries(sliceConfigs)) {\n try {\n merged[key] = {\n ...currentState[key],\n config: schema.parse(persistedState[key]),\n };\n } catch (error) {\n throw new Error(`Error parsing config key \"${key}\"`, {\n cause: error,\n });\n }\n }\n return merged;\n },\n };\n}\n\n/**\n * Wraps a state creator with Zustand's persist middleware and automatically\n * handles slice config serialization/deserialization using Zod schemas.\n *\n * This helper combines persist functionality with automatic `partialize` and `merge`\n * functions generated from your slice config schemas, eliminating manual type casting.\n *\n * @param options - Persist configuration object\n * @param options.name - Unique storage key (required)\n * @param options.sliceConfigSchemas - Map of slice names to Zod schemas for their configs\n * @param options.partialize - Optional custom partialize function (overrides auto-generated one)\n * @param options.merge - Optional custom merge function (overrides auto-generated one)\n * @param options.storage - Custom storage implementation (optional, defaults to localStorage)\n * @param options.version - Schema version for migrations (optional)\n * @param options.migrate - Migration function for version changes (optional)\n * @param options.skipHydration - Skip auto-hydration for SSR (optional)\n * @param stateCreator - Zustand state creator function\n * @returns Properly typed StateCreator with persist middleware applied\n *\n * @see {@link https://zustand.docs.pmnd.rs/middlewares/persist | Zustand persist middleware docs}\n *\n * @example\n * Basic usage:\n * ```ts\n * export const {roomStore, useRoomStore} = createRoomStore<RoomState>(\n * persistSliceConfigs(\n * {\n * name: 'my-app-state-storage',\n * sliceConfigSchemas: {\n * room: BaseRoomConfig,\n * layout: LayoutConfig,\n * sqlEditor: SqlEditorSliceConfig,\n * },\n * },\n * (set, get, store) => ({\n * ...createRoomSlice()(set, get, store),\n * ...createLayoutSlice({...})(set, get, store),\n * })\n * )\n * );\n * ```\n *\n * @example\n * With custom partialize/merge for additional state:\n * ```ts\n * export const {roomStore, useRoomStore} = createRoomStore<RoomState>(\n * persistSliceConfigs(\n * {\n * name: 'my-app-state-storage',\n * sliceConfigSchemas: {\n * room: BaseRoomConfig,\n * layout: LayoutConfig,\n * },\n * partialize: (state) => ({\n * apiKey: state.apiKey, // Persist additional field\n * ...createPersistHelpers({room: BaseRoomConfig, layout: LayoutConfig}).partialize(state),\n * }),\n * merge: (persisted, current) => ({\n * ...createPersistHelpers({room: BaseRoomConfig, layout: LayoutConfig}).merge(persisted, current),\n * apiKey: persisted.apiKey, // Restore additional field\n * }),\n * },\n * (set, get, store) => ({...})\n * )\n * );\n * ```\n */\nexport function persistSliceConfigs<S>(\n options: {\n sliceConfigSchemas: Record<string, z.ZodType>;\n partialize?: (state: S) => Partial<S>;\n merge?: (persistedState: unknown, currentState: S) => S;\n } & Omit<PersistOptions<S>, 'partialize' | 'merge'>,\n stateCreator: StateCreator<S>,\n): StateCreator<S> {\n const {sliceConfigSchemas, partialize, merge, ...persistOptions} = options;\n const helpers = createPersistHelpers(sliceConfigSchemas);\n\n return persist<S>(stateCreator, {\n ...persistOptions,\n partialize: partialize || helpers.partialize,\n merge: merge || helpers.merge,\n } as PersistOptions<S>) as StateCreator<S>;\n}\n"]}
package/dist/index.d.ts CHANGED
@@ -2,9 +2,11 @@
2
2
  * {@include ../README.md}
3
3
  * @packageDocumentation
4
4
  */
5
- export { RoomStateContext, RoomStateProvider, useBaseRoomStore, type RoomStateProviderProps, } from './RoomStateProvider';
6
- export { createBaseRoomSlice, createBaseSlice, createSlice, createRoomSlice, createRoomStore, createRoomStoreCreator, isRoomSliceWithDestroy, isRoomSliceWithInitialize, type BaseRoomStoreState, type CreateBaseRoomSliceProps, type BaseRoomStore, } from './BaseRoomStore';
7
- export { createPersistHelpers } from './createPersistHelpers';
5
+ export { RoomStateContext, RoomStateProvider, useBaseRoomStore, } from './RoomStateProvider';
6
+ export type { RoomStateProviderProps } from './RoomStateProvider';
7
+ export { createBaseRoomSlice, createBaseSlice, createSlice, createRoomSlice, createRoomStore, createRoomStoreCreator, isRoomSliceWithDestroy, isRoomSliceWithInitialize, } from './BaseRoomStore';
8
+ export type { BaseRoomStoreState, CreateBaseRoomSliceProps, BaseRoomStore, } from './BaseRoomStore';
9
+ export { createPersistHelpers, persistSliceConfigs, } from './createPersistHelpers';
8
10
  export type { StateCreator, StoreApi } from 'zustand';
9
- export * from '@sqlrooms/room-config';
11
+ export { BaseRoomConfig, DEFAULT_ROOM_TITLE, createDefaultBaseRoomConfig, DataSourceTypes, BaseDataSource, FileDataSource, UrlDataSource, SqlQueryDataSource, DataSource, isFileDataSource, isUrlDataSource, isSqlQueryDataSource, LoadFile, StandardLoadOptions, SpatialLoadOptions, SpatialLoadFileOptions, isSpatialLoadFileOptions, StandardLoadFileOptions, LoadFileOptions, MAIN_VIEW, LayoutTypes, DEFAULT_MOSAIC_LAYOUT, createDefaultMosaicLayout, MosaicLayoutDirection, MosaicLayoutParent, isMosaicLayoutParent, MosaicLayoutNodeKey, MosaicLayoutNode, MosaicLayoutConfig, LayoutConfig, } from '@sqlrooms/room-config';
10
12
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,EACL,gBAAgB,EAChB,iBAAiB,EACjB,gBAAgB,EAChB,KAAK,sBAAsB,GAC5B,MAAM,qBAAqB,CAAC;AAE7B,OAAO,EACL,mBAAmB,EACnB,eAAe,EACf,WAAW,EACX,eAAe,EACf,eAAe,EACf,sBAAsB,EACtB,sBAAsB,EACtB,yBAAyB,EACzB,KAAK,kBAAkB,EACvB,KAAK,wBAAwB,EAC7B,KAAK,aAAa,GACnB,MAAM,iBAAiB,CAAC;AAEzB,OAAO,EAAC,oBAAoB,EAAC,MAAM,wBAAwB,CAAC;AAC5D,YAAY,EAAC,YAAY,EAAE,QAAQ,EAAC,MAAM,SAAS,CAAC;AAEpD,cAAc,uBAAuB,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,EACL,gBAAgB,EAChB,iBAAiB,EACjB,gBAAgB,GACjB,MAAM,qBAAqB,CAAC;AAC7B,YAAY,EAAC,sBAAsB,EAAC,MAAM,qBAAqB,CAAC;AAEhE,OAAO,EACL,mBAAmB,EACnB,eAAe,EACf,WAAW,EACX,eAAe,EACf,eAAe,EACf,sBAAsB,EACtB,sBAAsB,EACtB,yBAAyB,GAC1B,MAAM,iBAAiB,CAAC;AACzB,YAAY,EACV,kBAAkB,EAClB,wBAAwB,EACxB,aAAa,GACd,MAAM,iBAAiB,CAAC;AAEzB,OAAO,EACL,oBAAoB,EACpB,mBAAmB,GACpB,MAAM,wBAAwB,CAAC;AAChC,YAAY,EAAC,YAAY,EAAE,QAAQ,EAAC,MAAM,SAAS,CAAC;AAIpD,OAAO,EACL,cAAc,EACd,kBAAkB,EAClB,2BAA2B,EAC3B,eAAe,EACf,cAAc,EACd,cAAc,EACd,aAAa,EACb,kBAAkB,EAClB,UAAU,EACV,gBAAgB,EAChB,eAAe,EACf,oBAAoB,EACpB,QAAQ,EACR,mBAAmB,EACnB,kBAAkB,EAClB,sBAAsB,EACtB,wBAAwB,EACxB,uBAAuB,EACvB,eAAe,EACf,SAAS,EACT,WAAW,EACX,qBAAqB,EACrB,yBAAyB,EACzB,qBAAqB,EACrB,kBAAkB,EAClB,oBAAoB,EACpB,mBAAmB,EACnB,gBAAgB,EAChB,kBAAkB,EAClB,YAAY,GACb,MAAM,uBAAuB,CAAC"}
package/dist/index.js CHANGED
@@ -4,6 +4,8 @@
4
4
  */
5
5
  export { RoomStateContext, RoomStateProvider, useBaseRoomStore, } from './RoomStateProvider';
6
6
  export { createBaseRoomSlice, createBaseSlice, createSlice, createRoomSlice, createRoomStore, createRoomStoreCreator, isRoomSliceWithDestroy, isRoomSliceWithInitialize, } from './BaseRoomStore';
7
- export { createPersistHelpers } from './createPersistHelpers';
8
- export * from '@sqlrooms/room-config';
7
+ export { createPersistHelpers, persistSliceConfigs, } from './createPersistHelpers';
8
+ // Re-export from @sqlrooms/room-config
9
+ // Values also export their corresponding types automatically (Zod pattern)
10
+ export { BaseRoomConfig, DEFAULT_ROOM_TITLE, createDefaultBaseRoomConfig, DataSourceTypes, BaseDataSource, FileDataSource, UrlDataSource, SqlQueryDataSource, DataSource, isFileDataSource, isUrlDataSource, isSqlQueryDataSource, LoadFile, StandardLoadOptions, SpatialLoadOptions, SpatialLoadFileOptions, isSpatialLoadFileOptions, StandardLoadFileOptions, LoadFileOptions, MAIN_VIEW, LayoutTypes, DEFAULT_MOSAIC_LAYOUT, createDefaultMosaicLayout, MosaicLayoutDirection, MosaicLayoutParent, isMosaicLayoutParent, MosaicLayoutNodeKey, MosaicLayoutNode, MosaicLayoutConfig, LayoutConfig, } from '@sqlrooms/room-config';
9
11
  //# sourceMappingURL=index.js.map
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,EACL,gBAAgB,EAChB,iBAAiB,EACjB,gBAAgB,GAEjB,MAAM,qBAAqB,CAAC;AAE7B,OAAO,EACL,mBAAmB,EACnB,eAAe,EACf,WAAW,EACX,eAAe,EACf,eAAe,EACf,sBAAsB,EACtB,sBAAsB,EACtB,yBAAyB,GAI1B,MAAM,iBAAiB,CAAC;AAEzB,OAAO,EAAC,oBAAoB,EAAC,MAAM,wBAAwB,CAAC;AAG5D,cAAc,uBAAuB,CAAC","sourcesContent":["/**\n * {@include ../README.md}\n * @packageDocumentation\n */\n\nexport {\n RoomStateContext,\n RoomStateProvider,\n useBaseRoomStore,\n type RoomStateProviderProps,\n} from './RoomStateProvider';\n\nexport {\n createBaseRoomSlice,\n createBaseSlice,\n createSlice,\n createRoomSlice,\n createRoomStore,\n createRoomStoreCreator,\n isRoomSliceWithDestroy,\n isRoomSliceWithInitialize,\n type BaseRoomStoreState,\n type CreateBaseRoomSliceProps,\n type BaseRoomStore,\n} from './BaseRoomStore';\n\nexport {createPersistHelpers} from './createPersistHelpers';\nexport type {StateCreator, StoreApi} from 'zustand';\n\nexport * from '@sqlrooms/room-config';\n"]}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,EACL,gBAAgB,EAChB,iBAAiB,EACjB,gBAAgB,GACjB,MAAM,qBAAqB,CAAC;AAG7B,OAAO,EACL,mBAAmB,EACnB,eAAe,EACf,WAAW,EACX,eAAe,EACf,eAAe,EACf,sBAAsB,EACtB,sBAAsB,EACtB,yBAAyB,GAC1B,MAAM,iBAAiB,CAAC;AAOzB,OAAO,EACL,oBAAoB,EACpB,mBAAmB,GACpB,MAAM,wBAAwB,CAAC;AAGhC,uCAAuC;AACvC,2EAA2E;AAC3E,OAAO,EACL,cAAc,EACd,kBAAkB,EAClB,2BAA2B,EAC3B,eAAe,EACf,cAAc,EACd,cAAc,EACd,aAAa,EACb,kBAAkB,EAClB,UAAU,EACV,gBAAgB,EAChB,eAAe,EACf,oBAAoB,EACpB,QAAQ,EACR,mBAAmB,EACnB,kBAAkB,EAClB,sBAAsB,EACtB,wBAAwB,EACxB,uBAAuB,EACvB,eAAe,EACf,SAAS,EACT,WAAW,EACX,qBAAqB,EACrB,yBAAyB,EACzB,qBAAqB,EACrB,kBAAkB,EAClB,oBAAoB,EACpB,mBAAmB,EACnB,gBAAgB,EAChB,kBAAkB,EAClB,YAAY,GACb,MAAM,uBAAuB,CAAC","sourcesContent":["/**\n * {@include ../README.md}\n * @packageDocumentation\n */\n\nexport {\n RoomStateContext,\n RoomStateProvider,\n useBaseRoomStore,\n} from './RoomStateProvider';\nexport type {RoomStateProviderProps} from './RoomStateProvider';\n\nexport {\n createBaseRoomSlice,\n createBaseSlice,\n createSlice,\n createRoomSlice,\n createRoomStore,\n createRoomStoreCreator,\n isRoomSliceWithDestroy,\n isRoomSliceWithInitialize,\n} from './BaseRoomStore';\nexport type {\n BaseRoomStoreState,\n CreateBaseRoomSliceProps,\n BaseRoomStore,\n} from './BaseRoomStore';\n\nexport {\n createPersistHelpers,\n persistSliceConfigs,\n} from './createPersistHelpers';\nexport type {StateCreator, StoreApi} from 'zustand';\n\n// Re-export from @sqlrooms/room-config\n// Values also export their corresponding types automatically (Zod pattern)\nexport {\n BaseRoomConfig,\n DEFAULT_ROOM_TITLE,\n createDefaultBaseRoomConfig,\n DataSourceTypes,\n BaseDataSource,\n FileDataSource,\n UrlDataSource,\n SqlQueryDataSource,\n DataSource,\n isFileDataSource,\n isUrlDataSource,\n isSqlQueryDataSource,\n LoadFile,\n StandardLoadOptions,\n SpatialLoadOptions,\n SpatialLoadFileOptions,\n isSpatialLoadFileOptions,\n StandardLoadFileOptions,\n LoadFileOptions,\n MAIN_VIEW,\n LayoutTypes,\n DEFAULT_MOSAIC_LAYOUT,\n createDefaultMosaicLayout,\n MosaicLayoutDirection,\n MosaicLayoutParent,\n isMosaicLayoutParent,\n MosaicLayoutNodeKey,\n MosaicLayoutNode,\n MosaicLayoutConfig,\n LayoutConfig,\n} from '@sqlrooms/room-config';\n"]}
package/package.json CHANGED
@@ -1,10 +1,11 @@
1
1
  {
2
2
  "name": "@sqlrooms/room-store",
3
- "version": "0.26.1-rc.3",
3
+ "version": "0.26.1-rc.5",
4
4
  "main": "dist/index.js",
5
5
  "types": "dist/index.d.ts",
6
6
  "module": "dist/index.js",
7
7
  "type": "module",
8
+ "sideEffects": false,
8
9
  "author": "Ilya Boyandin <ilya@boyandin.me>",
9
10
  "license": "MIT",
10
11
  "repository": {
@@ -18,8 +19,8 @@
18
19
  "access": "public"
19
20
  },
20
21
  "dependencies": {
21
- "@sqlrooms/room-config": "0.26.1-rc.3",
22
- "immer": "^10.1.3",
22
+ "@sqlrooms/room-config": "0.26.1-rc.5",
23
+ "immer": "^11.0.1",
23
24
  "zod": "^4.1.8",
24
25
  "zustand": "^5.0.8"
25
26
  },
@@ -33,5 +34,5 @@
33
34
  "typecheck": "tsc --noEmit",
34
35
  "typedoc": "typedoc"
35
36
  },
36
- "gitHead": "096cc4abdaf13e8f26d37e0ef048526b445c78a8"
37
+ "gitHead": "1df21f4729c5deb96f7af790cff7c189c6885074"
37
38
  }