@sqlrooms/room-store 0.27.0-rc.0 → 0.27.0-rc.2
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.
- package/dist/BaseRoomStore.d.ts +17 -1
- package/dist/BaseRoomStore.d.ts.map +1 -1
- package/dist/BaseRoomStore.js +43 -1
- package/dist/BaseRoomStore.js.map +1 -1
- package/dist/hmr.d.ts +36 -0
- package/dist/hmr.d.ts.map +1 -0
- package/dist/hmr.js +45 -0
- package/dist/hmr.js.map +1 -0
- package/package.json +3 -3
package/dist/BaseRoomStore.d.ts
CHANGED
|
@@ -16,6 +16,17 @@ export type BaseRoomStore<RS extends BaseRoomStoreState> = StoreApi<RS>;
|
|
|
16
16
|
export type CreateBaseRoomSliceProps = {
|
|
17
17
|
captureException?: BaseRoomStoreState['room']['captureException'];
|
|
18
18
|
};
|
|
19
|
+
export type CreateRoomStoreOptions = {
|
|
20
|
+
/**
|
|
21
|
+
* Optional store key used for dev HMR reuse.
|
|
22
|
+
* Provide a project-specific key to force recreation when it changes.
|
|
23
|
+
*/
|
|
24
|
+
storeKey?: string;
|
|
25
|
+
};
|
|
26
|
+
type CreateRoomStoreArgs<TFactory extends (...args: any[]) => any> = [
|
|
27
|
+
...Parameters<TFactory>,
|
|
28
|
+
CreateRoomStoreOptions?
|
|
29
|
+
];
|
|
19
30
|
export declare function createBaseRoomSlice(props?: CreateBaseRoomSliceProps): StateCreator<BaseRoomStoreState>;
|
|
20
31
|
/** @deprecated Use createBaseRoomSlice instead */
|
|
21
32
|
export declare const createRoomSlice: typeof createBaseRoomSlice;
|
|
@@ -39,9 +50,14 @@ export declare function createRoomStore<RS extends BaseRoomStoreState>(stateCrea
|
|
|
39
50
|
* @param stateCreatorFactory - A function that takes params and returns a Zustand state creator
|
|
40
51
|
* @returns An object with createRoomStore(params) and useRoomStore(selector)
|
|
41
52
|
*
|
|
53
|
+
* @example
|
|
54
|
+
* const {createRoomStore} = createRoomStoreCreator<MyRoomState>()(
|
|
55
|
+
* (projectId: string) => createMyRoomState(projectId),
|
|
56
|
+
* );
|
|
57
|
+
* createRoomStore('project-a', {storeKey: 'project-a'});
|
|
42
58
|
*/
|
|
43
59
|
export declare function createRoomStoreCreator<RS extends BaseRoomStoreState>(): <TFactory extends (...args: any[]) => StateCreator<RS>>(stateCreatorFactory: TFactory) => {
|
|
44
|
-
createRoomStore: (...args:
|
|
60
|
+
createRoomStore: (...args: CreateRoomStoreArgs<TFactory>) => StoreApi<RS>;
|
|
45
61
|
useRoomStore: <T>(selector: (state: RS) => T) => T;
|
|
46
62
|
};
|
|
47
63
|
export declare function isRoomSliceWithInitialize(slice: unknown): slice is Required<Pick<SliceFunctions, 'initialize'>>;
|
|
@@ -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;
|
|
1
|
+
{"version":3,"file":"BaseRoomStore.d.ts","sourceRoot":"","sources":["../src/BaseRoomStore.ts"],"names":[],"mappings":"AACA,OAAO,EAAC,YAAY,EAAE,QAAQ,EAAwB,MAAM,SAAS,CAAC;AAItE,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,MAAM,MAAM,sBAAsB,GAAG;IACnC;;;OAGG;IACH,QAAQ,CAAC,EAAE,MAAM,CAAC;CACnB,CAAC;AAEF,KAAK,mBAAmB,CAAC,QAAQ,SAAS,CAAC,GAAG,IAAI,EAAE,GAAG,EAAE,KAAK,GAAG,IAAI;IACnE,GAAG,UAAU,CAAC,QAAQ,CAAC;IACvB,sBAAsB,CAAC;CACxB,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;;;;;;;;;;;;GAYG;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,mBAAmB,CAAC,QAAQ,CAAC,KAAK,QAAQ,CAAC,EAAE,CAAC,CAAC;IAC1E,YAAY,EAAE,CAAC,CAAC,EAAE,QAAQ,EAAE,CAAC,KAAK,EAAE,EAAE,KAAK,CAAC,KAAK,CAAC,CAAC;CACpD,CAsFF;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"}
|
package/dist/BaseRoomStore.js
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { produce } from 'immer';
|
|
2
2
|
import { createStore, useStore } from 'zustand';
|
|
3
|
+
import { DEV_HMR } from './hmr';
|
|
3
4
|
export function createBaseRoomSlice(props) {
|
|
4
5
|
return (_set, _get, store) => ({
|
|
5
6
|
room: {
|
|
@@ -52,12 +53,53 @@ export function createRoomStore(stateCreator) {
|
|
|
52
53
|
* @param stateCreatorFactory - A function that takes params and returns a Zustand state creator
|
|
53
54
|
* @returns An object with createRoomStore(params) and useRoomStore(selector)
|
|
54
55
|
*
|
|
56
|
+
* @example
|
|
57
|
+
* const {createRoomStore} = createRoomStoreCreator<MyRoomState>()(
|
|
58
|
+
* (projectId: string) => createMyRoomState(projectId),
|
|
59
|
+
* );
|
|
60
|
+
* createRoomStore('project-a', {storeKey: 'project-a'});
|
|
55
61
|
*/
|
|
56
62
|
export function createRoomStoreCreator() {
|
|
57
63
|
return function (stateCreatorFactory) {
|
|
64
|
+
const defaultStoreKey = DEV_HMR?.nextId();
|
|
58
65
|
let store;
|
|
66
|
+
let currentStoreKey = defaultStoreKey;
|
|
67
|
+
function isCreateRoomStoreOptions(value) {
|
|
68
|
+
return typeof value === 'object' && value !== null && 'storeKey' in value;
|
|
69
|
+
}
|
|
59
70
|
function createRoomStore(...args) {
|
|
60
|
-
|
|
71
|
+
const lastArg = args[args.length - 1];
|
|
72
|
+
const options = isCreateRoomStoreOptions(lastArg) ? lastArg : undefined;
|
|
73
|
+
const factoryArgs = (options ? args.slice(0, -1) : args);
|
|
74
|
+
const storeKey = DEV_HMR
|
|
75
|
+
? (options?.storeKey ?? defaultStoreKey)
|
|
76
|
+
: undefined;
|
|
77
|
+
// Dev-only: Check for existing store from previous hot reload
|
|
78
|
+
if (DEV_HMR && storeKey) {
|
|
79
|
+
if (currentStoreKey && currentStoreKey !== storeKey) {
|
|
80
|
+
const previousStore = DEV_HMR.get(currentStoreKey);
|
|
81
|
+
if (previousStore) {
|
|
82
|
+
const state = previousStore.getState();
|
|
83
|
+
if (isRoomSliceWithDestroy(state.room)) {
|
|
84
|
+
state.room.destroy().catch((error) => {
|
|
85
|
+
state.room.captureException(error);
|
|
86
|
+
});
|
|
87
|
+
}
|
|
88
|
+
}
|
|
89
|
+
DEV_HMR.delete(currentStoreKey);
|
|
90
|
+
}
|
|
91
|
+
currentStoreKey = storeKey;
|
|
92
|
+
const existingStore = DEV_HMR.get(storeKey);
|
|
93
|
+
if (existingStore) {
|
|
94
|
+
store = existingStore;
|
|
95
|
+
return existingStore;
|
|
96
|
+
}
|
|
97
|
+
}
|
|
98
|
+
store = createStore(stateCreatorFactory(...factoryArgs));
|
|
99
|
+
// Dev-only: Register store for HMR preservation
|
|
100
|
+
if (DEV_HMR && currentStoreKey) {
|
|
101
|
+
DEV_HMR.set(currentStoreKey, store);
|
|
102
|
+
}
|
|
61
103
|
if (typeof window !== 'undefined') {
|
|
62
104
|
(async () => {
|
|
63
105
|
try {
|
|
@@ -1 +1 @@
|
|
|
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
|
+
{"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';\nimport {DEV_HMR} from './hmr';\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 type CreateRoomStoreOptions = {\n /**\n * Optional store key used for dev HMR reuse.\n * Provide a project-specific key to force recreation when it changes.\n */\n storeKey?: string;\n};\n\ntype CreateRoomStoreArgs<TFactory extends (...args: any[]) => any> = [\n ...Parameters<TFactory>,\n CreateRoomStoreOptions?,\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 * @example\n * const {createRoomStore} = createRoomStoreCreator<MyRoomState>()(\n * (projectId: string) => createMyRoomState(projectId),\n * );\n * createRoomStore('project-a', {storeKey: 'project-a'});\n */\nexport function createRoomStoreCreator<RS extends BaseRoomStoreState>() {\n return function <TFactory extends (...args: any[]) => StateCreator<RS>>(\n stateCreatorFactory: TFactory,\n ): {\n createRoomStore: (...args: CreateRoomStoreArgs<TFactory>) => StoreApi<RS>;\n useRoomStore: <T>(selector: (state: RS) => T) => T;\n } {\n const defaultStoreKey = DEV_HMR?.nextId();\n let store: StoreApi<RS> | undefined;\n let currentStoreKey: string | undefined = defaultStoreKey;\n\n function isCreateRoomStoreOptions(\n value: unknown,\n ): value is CreateRoomStoreOptions {\n return typeof value === 'object' && value !== null && 'storeKey' in value;\n }\n\n function createRoomStore(\n ...args: CreateRoomStoreArgs<TFactory>\n ): StoreApi<RS> {\n const lastArg = args[args.length - 1];\n const options = isCreateRoomStoreOptions(lastArg) ? lastArg : undefined;\n const factoryArgs = (\n options ? args.slice(0, -1) : args\n ) as Parameters<TFactory>;\n const storeKey = DEV_HMR\n ? (options?.storeKey ?? defaultStoreKey)\n : undefined;\n\n // Dev-only: Check for existing store from previous hot reload\n if (DEV_HMR && storeKey) {\n if (currentStoreKey && currentStoreKey !== storeKey) {\n const previousStore = DEV_HMR.get(currentStoreKey);\n if (previousStore) {\n const state = previousStore.getState();\n if (isRoomSliceWithDestroy(state.room)) {\n state.room.destroy().catch((error: unknown) => {\n state.room.captureException(error);\n });\n }\n }\n DEV_HMR.delete(currentStoreKey);\n }\n currentStoreKey = storeKey;\n\n const existingStore = DEV_HMR.get(storeKey);\n if (existingStore) {\n store = existingStore;\n return existingStore;\n }\n }\n\n store = createStore(stateCreatorFactory(...factoryArgs));\n\n // Dev-only: Register store for HMR preservation\n if (DEV_HMR && currentStoreKey) {\n DEV_HMR.set(currentStoreKey, store);\n }\n\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"]}
|
package/dist/hmr.d.ts
ADDED
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
import { StoreApi } from 'zustand';
|
|
2
|
+
/**
|
|
3
|
+
* Dev-only: HMR store preservation utilities.
|
|
4
|
+
* These are isolated and tree-shakable in production builds.
|
|
5
|
+
*
|
|
6
|
+
* Returns null in production, so all usages should be guarded with:
|
|
7
|
+
* `if (DEV_HMR) { ... }`
|
|
8
|
+
*
|
|
9
|
+
* The problem this solves is that during hot module replacement (HMR), the
|
|
10
|
+
* store module would get re-executed,but the closure's store variable would be
|
|
11
|
+
* undefined, causing the error when components tried to use useRoomStore.
|
|
12
|
+
*
|
|
13
|
+
* The fix adds three key changes:
|
|
14
|
+
*
|
|
15
|
+
* 1. Creates a persistent registry on the window object that survives hot
|
|
16
|
+
* reloads. This stores all store instances by unique IDs.
|
|
17
|
+
* 2. Each store creator gets a unique ID. Since the counter resets on hot
|
|
18
|
+
* reload but stores are created in the same order, the IDs remain
|
|
19
|
+
* consistent across reloads.
|
|
20
|
+
* 3. Before creating a new store, it checks if one already exists in the
|
|
21
|
+
* registry from a previous hot reload. If found, it reuses the existing
|
|
22
|
+
* store, preserving all state and preventing initialization errors.
|
|
23
|
+
*
|
|
24
|
+
* This ensures that:
|
|
25
|
+
* - Store state is preserved across hot reloads
|
|
26
|
+
* - No "Room store not initialized" errors during development
|
|
27
|
+
* - The store initialization only happens once, not on every hot reload
|
|
28
|
+
*
|
|
29
|
+
*/
|
|
30
|
+
export declare const DEV_HMR: {
|
|
31
|
+
nextId: () => string;
|
|
32
|
+
get: (id: string) => any;
|
|
33
|
+
set: (id: string, store: StoreApi<any>) => any;
|
|
34
|
+
delete: (id: string) => any;
|
|
35
|
+
} | null;
|
|
36
|
+
//# sourceMappingURL=hmr.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"hmr.d.ts","sourceRoot":"","sources":["../src/hmr.ts"],"names":[],"mappings":"AAAA,OAAO,EAAC,QAAQ,EAAC,MAAM,SAAS,CAAC;AAEjC;;;;;;;;;;;;;;;;;;;;;;;;;;;GA2BG;AACH,eAAO,MAAM,OAAO;;cAiBN,MAAM;cACN,MAAM,SAAS,QAAQ,CAAC,GAAG,CAAC;iBACzB,MAAM;QAEnB,CAAC"}
|
package/dist/hmr.js
ADDED
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Dev-only: HMR store preservation utilities.
|
|
3
|
+
* These are isolated and tree-shakable in production builds.
|
|
4
|
+
*
|
|
5
|
+
* Returns null in production, so all usages should be guarded with:
|
|
6
|
+
* `if (DEV_HMR) { ... }`
|
|
7
|
+
*
|
|
8
|
+
* The problem this solves is that during hot module replacement (HMR), the
|
|
9
|
+
* store module would get re-executed,but the closure's store variable would be
|
|
10
|
+
* undefined, causing the error when components tried to use useRoomStore.
|
|
11
|
+
*
|
|
12
|
+
* The fix adds three key changes:
|
|
13
|
+
*
|
|
14
|
+
* 1. Creates a persistent registry on the window object that survives hot
|
|
15
|
+
* reloads. This stores all store instances by unique IDs.
|
|
16
|
+
* 2. Each store creator gets a unique ID. Since the counter resets on hot
|
|
17
|
+
* reload but stores are created in the same order, the IDs remain
|
|
18
|
+
* consistent across reloads.
|
|
19
|
+
* 3. Before creating a new store, it checks if one already exists in the
|
|
20
|
+
* registry from a previous hot reload. If found, it reuses the existing
|
|
21
|
+
* store, preserving all state and preventing initialization errors.
|
|
22
|
+
*
|
|
23
|
+
* This ensures that:
|
|
24
|
+
* - Store state is preserved across hot reloads
|
|
25
|
+
* - No "Room store not initialized" errors during development
|
|
26
|
+
* - The store initialization only happens once, not on every hot reload
|
|
27
|
+
*
|
|
28
|
+
*/
|
|
29
|
+
export const DEV_HMR = (() => {
|
|
30
|
+
if (process.env.NODE_ENV === 'production') {
|
|
31
|
+
return null;
|
|
32
|
+
}
|
|
33
|
+
// Only initialize in development mode
|
|
34
|
+
const registry = typeof window !== 'undefined'
|
|
35
|
+
? (window.__SQLROOMS_STORE_REGISTRY__ ??= new Map())
|
|
36
|
+
: new Map();
|
|
37
|
+
let idCounter = 0;
|
|
38
|
+
return {
|
|
39
|
+
nextId: () => `store_${idCounter++}`,
|
|
40
|
+
get: (id) => registry.get(id),
|
|
41
|
+
set: (id, store) => registry.set(id, store),
|
|
42
|
+
delete: (id) => registry.delete(id),
|
|
43
|
+
};
|
|
44
|
+
})();
|
|
45
|
+
//# sourceMappingURL=hmr.js.map
|
package/dist/hmr.js.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"hmr.js","sourceRoot":"","sources":["../src/hmr.ts"],"names":[],"mappings":"AAEA;;;;;;;;;;;;;;;;;;;;;;;;;;;GA2BG;AACH,MAAM,CAAC,MAAM,OAAO,GAAG,CAAC,GAAG,EAAE;IAC3B,IAAI,OAAO,CAAC,GAAG,CAAC,QAAQ,KAAK,YAAY,EAAE,CAAC;QAC1C,OAAO,IAAI,CAAC;IACd,CAAC;IAED,sCAAsC;IACtC,MAAM,QAAQ,GACZ,OAAO,MAAM,KAAK,WAAW;QAC3B,CAAC,CAAC,CAAE,MAAc,CAAC,2BAA2B,KAAK,IAAI,GAAG,EAGrD,CAAC;QACN,CAAC,CAAC,IAAI,GAAG,EAAyB,CAAC;IACvC,IAAI,SAAS,GAAG,CAAC,CAAC;IAElB,OAAO;QACL,MAAM,EAAE,GAAG,EAAE,CAAC,SAAS,SAAS,EAAE,EAAE;QACpC,GAAG,EAAE,CAAC,EAAU,EAAE,EAAE,CAAC,QAAQ,CAAC,GAAG,CAAC,EAAE,CAAC;QACrC,GAAG,EAAE,CAAC,EAAU,EAAE,KAAoB,EAAE,EAAE,CAAC,QAAQ,CAAC,GAAG,CAAC,EAAE,EAAE,KAAK,CAAC;QAClE,MAAM,EAAE,CAAC,EAAU,EAAE,EAAE,CAAC,QAAQ,CAAC,MAAM,CAAC,EAAE,CAAC;KAC5C,CAAC;AACJ,CAAC,CAAC,EAAE,CAAC","sourcesContent":["import {StoreApi} from 'zustand';\n\n/**\n * Dev-only: HMR store preservation utilities.\n * These are isolated and tree-shakable in production builds.\n *\n * Returns null in production, so all usages should be guarded with:\n * `if (DEV_HMR) { ... }`\n *\n * The problem this solves is that during hot module replacement (HMR), the\n * store module would get re-executed,but the closure's store variable would be\n * undefined, causing the error when components tried to use useRoomStore.\n *\n * The fix adds three key changes:\n *\n * 1. Creates a persistent registry on the window object that survives hot\n * reloads. This stores all store instances by unique IDs.\n * 2. Each store creator gets a unique ID. Since the counter resets on hot\n * reload but stores are created in the same order, the IDs remain\n * consistent across reloads.\n * 3. Before creating a new store, it checks if one already exists in the\n * registry from a previous hot reload. If found, it reuses the existing\n * store, preserving all state and preventing initialization errors.\n *\n * This ensures that:\n * - Store state is preserved across hot reloads\n * - No \"Room store not initialized\" errors during development\n * - The store initialization only happens once, not on every hot reload\n *\n */\nexport const DEV_HMR = (() => {\n if (process.env.NODE_ENV === 'production') {\n return null;\n }\n\n // Only initialize in development mode\n const registry =\n typeof window !== 'undefined'\n ? ((window as any).__SQLROOMS_STORE_REGISTRY__ ??= new Map<\n string,\n StoreApi<any>\n >())\n : new Map<string, StoreApi<any>>();\n let idCounter = 0;\n\n return {\n nextId: () => `store_${idCounter++}`,\n get: (id: string) => registry.get(id),\n set: (id: string, store: StoreApi<any>) => registry.set(id, store),\n delete: (id: string) => registry.delete(id),\n };\n})();\n"]}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@sqlrooms/room-store",
|
|
3
|
-
"version": "0.27.0-rc.
|
|
3
|
+
"version": "0.27.0-rc.2",
|
|
4
4
|
"main": "dist/index.js",
|
|
5
5
|
"types": "dist/index.d.ts",
|
|
6
6
|
"module": "dist/index.js",
|
|
@@ -19,7 +19,7 @@
|
|
|
19
19
|
"access": "public"
|
|
20
20
|
},
|
|
21
21
|
"dependencies": {
|
|
22
|
-
"@sqlrooms/room-config": "0.27.0-rc.
|
|
22
|
+
"@sqlrooms/room-config": "0.27.0-rc.2",
|
|
23
23
|
"immer": "^11.0.1",
|
|
24
24
|
"zod": "^4.1.8",
|
|
25
25
|
"zustand": "^5.0.8"
|
|
@@ -34,5 +34,5 @@
|
|
|
34
34
|
"typecheck": "tsc --noEmit",
|
|
35
35
|
"typedoc": "typedoc"
|
|
36
36
|
},
|
|
37
|
-
"gitHead": "
|
|
37
|
+
"gitHead": "eec06537352a9e760de21d7bcc77d9aa2db2a5ec"
|
|
38
38
|
}
|