@sqlrooms/room-store 0.26.0-rc.4 → 0.26.0-rc.6
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 +48 -0
- package/dist/BaseRoomStore.d.ts.map +1 -0
- package/dist/BaseRoomStore.js +97 -0
- package/dist/BaseRoomStore.js.map +1 -0
- package/dist/RoomStateProvider.d.ts +6 -6
- package/dist/RoomStateProvider.d.ts.map +1 -1
- package/dist/RoomStateProvider.js +1 -1
- package/dist/RoomStateProvider.js.map +1 -1
- package/dist/createPersistHelpers.d.ts +33 -0
- package/dist/createPersistHelpers.d.ts.map +1 -0
- package/dist/createPersistHelpers.js +49 -0
- package/dist/createPersistHelpers.js.map +1 -0
- package/dist/index.d.ts +2 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +2 -1
- package/dist/index.js.map +1 -1
- package/package.json +3 -3
- package/dist/RoomStore.d.ts +0 -75
- package/dist/RoomStore.d.ts.map +0 -1
- package/dist/RoomStore.js +0 -134
- package/dist/RoomStore.js.map +0 -1
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
import { StateCreator, StoreApi } from 'zustand';
|
|
2
|
+
export interface SliceFunctions {
|
|
3
|
+
initialize?: () => Promise<void>;
|
|
4
|
+
destroy?: () => Promise<void>;
|
|
5
|
+
}
|
|
6
|
+
export type BaseRoomStoreState = {
|
|
7
|
+
room: {
|
|
8
|
+
initialized: boolean;
|
|
9
|
+
initialize: () => Promise<void>;
|
|
10
|
+
destroy: () => Promise<void>;
|
|
11
|
+
captureException: (exception: unknown, captureContext?: unknown) => void;
|
|
12
|
+
};
|
|
13
|
+
};
|
|
14
|
+
export type BaseRoomStore<RS extends BaseRoomStoreState> = StoreApi<RS>;
|
|
15
|
+
export type CreateBaseRoomSliceProps = {
|
|
16
|
+
captureException?: BaseRoomStoreState['room']['captureException'];
|
|
17
|
+
};
|
|
18
|
+
export declare function createBaseRoomSlice(props?: CreateBaseRoomSliceProps): StateCreator<BaseRoomStoreState>;
|
|
19
|
+
/** @deprecated Use createBaseRoomSlice instead */
|
|
20
|
+
export declare const createRoomSlice: typeof createBaseRoomSlice;
|
|
21
|
+
export declare function createSlice<SliceState, StoreState extends SliceState = BaseRoomStoreState & SliceState>(sliceCreator: (...args: Parameters<StateCreator<StoreState>>) => SliceState): StateCreator<SliceState>;
|
|
22
|
+
/** @deprecated Use createSlice instead */
|
|
23
|
+
export declare const createBaseSlice: typeof createSlice;
|
|
24
|
+
/**
|
|
25
|
+
* Create a room store with custom fields and methods
|
|
26
|
+
* @param initialState - The initial state and config for the room
|
|
27
|
+
* @param sliceCreators - The slices to add to the room store
|
|
28
|
+
* @returns The room store and a hook for accessing the room store
|
|
29
|
+
*/
|
|
30
|
+
export declare function createRoomStore<RS extends BaseRoomStoreState>(stateCreator: StateCreator<RS>): {
|
|
31
|
+
roomStore: StoreApi<BaseRoomStoreState & RS>;
|
|
32
|
+
useRoomStore: <T>(selector: (state: RS) => T) => T;
|
|
33
|
+
};
|
|
34
|
+
/**
|
|
35
|
+
* Factory to create a room store creator with custom params.
|
|
36
|
+
*
|
|
37
|
+
* @template RS - Room state type
|
|
38
|
+
* @param stateCreatorFactory - A function that takes params and returns a Zustand state creator
|
|
39
|
+
* @returns An object with createRoomStore(params) and useRoomStore(selector)
|
|
40
|
+
*
|
|
41
|
+
*/
|
|
42
|
+
export declare function createRoomStoreCreator<RS extends BaseRoomStoreState>(): <TFactory extends (...args: any[]) => StateCreator<RS>>(stateCreatorFactory: TFactory) => {
|
|
43
|
+
createRoomStore: (...args: Parameters<TFactory>) => StoreApi<RS>;
|
|
44
|
+
useRoomStore: <T>(selector: (state: RS) => T) => T;
|
|
45
|
+
};
|
|
46
|
+
export declare function isRoomSliceWithInitialize(slice: unknown): slice is Required<Pick<SliceFunctions, 'initialize'>>;
|
|
47
|
+
export declare function isRoomSliceWithDestroy(slice: unknown): slice is Required<Pick<SliceFunctions, 'destroy'>>;
|
|
48
|
+
//# sourceMappingURL=BaseRoomStore.d.ts.map
|
|
@@ -0,0 +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"}
|
|
@@ -0,0 +1,97 @@
|
|
|
1
|
+
import { produce } from 'immer';
|
|
2
|
+
import { createStore, useStore } from 'zustand';
|
|
3
|
+
export function createBaseRoomSlice(props) {
|
|
4
|
+
return (_set, _get, store) => ({
|
|
5
|
+
room: {
|
|
6
|
+
initialized: false,
|
|
7
|
+
initialize: async () => {
|
|
8
|
+
await Promise.all(Object.values(store.getState())
|
|
9
|
+
.filter(isRoomSliceWithInitialize)
|
|
10
|
+
.map((slice) => slice.initialize));
|
|
11
|
+
},
|
|
12
|
+
destroy: async () => {
|
|
13
|
+
await Promise.all(Object.values(store.getState())
|
|
14
|
+
.filter(isRoomSliceWithDestroy)
|
|
15
|
+
.map((slice) => slice.destroy));
|
|
16
|
+
},
|
|
17
|
+
captureException: props?.captureException ??
|
|
18
|
+
((exception) => console.error(exception)),
|
|
19
|
+
},
|
|
20
|
+
});
|
|
21
|
+
}
|
|
22
|
+
/** @deprecated Use createBaseRoomSlice instead */
|
|
23
|
+
export const createRoomSlice = createBaseRoomSlice;
|
|
24
|
+
export function createSlice(sliceCreator) {
|
|
25
|
+
return (set, get, store) => sliceCreator(set, get, store);
|
|
26
|
+
}
|
|
27
|
+
/** @deprecated Use createSlice instead */
|
|
28
|
+
export const createBaseSlice = createSlice;
|
|
29
|
+
/**
|
|
30
|
+
* Create a room store with custom fields and methods
|
|
31
|
+
* @param initialState - The initial state and config for the room
|
|
32
|
+
* @param sliceCreators - The slices to add to the room store
|
|
33
|
+
* @returns The room store and a hook for accessing the room store
|
|
34
|
+
*/
|
|
35
|
+
export function createRoomStore(stateCreator) {
|
|
36
|
+
const factory = createRoomStoreCreator();
|
|
37
|
+
const storeCreator = factory(() => stateCreator);
|
|
38
|
+
const roomStore = storeCreator.createRoomStore();
|
|
39
|
+
function useRoomStore(selector) {
|
|
40
|
+
return storeCreator.useRoomStore(selector);
|
|
41
|
+
}
|
|
42
|
+
return { roomStore, useRoomStore };
|
|
43
|
+
}
|
|
44
|
+
/**
|
|
45
|
+
* Factory to create a room store creator with custom params.
|
|
46
|
+
*
|
|
47
|
+
* @template RS - Room state type
|
|
48
|
+
* @param stateCreatorFactory - A function that takes params and returns a Zustand state creator
|
|
49
|
+
* @returns An object with createRoomStore(params) and useRoomStore(selector)
|
|
50
|
+
*
|
|
51
|
+
*/
|
|
52
|
+
export function createRoomStoreCreator() {
|
|
53
|
+
return function (stateCreatorFactory) {
|
|
54
|
+
let store;
|
|
55
|
+
function createRoomStore(...args) {
|
|
56
|
+
store = createStore(stateCreatorFactory(...args));
|
|
57
|
+
if (typeof window !== 'undefined') {
|
|
58
|
+
(async () => {
|
|
59
|
+
try {
|
|
60
|
+
// Initialize the room
|
|
61
|
+
await store.getState().room.initialize();
|
|
62
|
+
// Set initialized to true after initialization
|
|
63
|
+
store.setState((state) => produce(state, (draft) => {
|
|
64
|
+
draft.room.initialized = true;
|
|
65
|
+
}));
|
|
66
|
+
}
|
|
67
|
+
catch (error) {
|
|
68
|
+
store.getState().room.captureException(error);
|
|
69
|
+
}
|
|
70
|
+
})();
|
|
71
|
+
}
|
|
72
|
+
else {
|
|
73
|
+
console.warn('Skipping room store initialization. The room store should only be used on the client.');
|
|
74
|
+
}
|
|
75
|
+
return store;
|
|
76
|
+
}
|
|
77
|
+
function useRoomStore(selector) {
|
|
78
|
+
if (!store)
|
|
79
|
+
throw new Error('Room store not initialized. Call createRoomStore first.');
|
|
80
|
+
return useStore(store, selector);
|
|
81
|
+
}
|
|
82
|
+
return { createRoomStore, useRoomStore };
|
|
83
|
+
};
|
|
84
|
+
}
|
|
85
|
+
export function isRoomSliceWithInitialize(slice) {
|
|
86
|
+
return (typeof slice === 'object' &&
|
|
87
|
+
slice !== null &&
|
|
88
|
+
'initialize' in slice &&
|
|
89
|
+
typeof slice.initialize === 'function');
|
|
90
|
+
}
|
|
91
|
+
export function isRoomSliceWithDestroy(slice) {
|
|
92
|
+
return (typeof slice === 'object' &&
|
|
93
|
+
slice !== null &&
|
|
94
|
+
'destroy' in slice &&
|
|
95
|
+
typeof slice.destroy === 'function');
|
|
96
|
+
}
|
|
97
|
+
//# sourceMappingURL=BaseRoomStore.js.map
|
|
@@ -0,0 +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,9 +1,9 @@
|
|
|
1
1
|
import React, { ReactNode } from 'react';
|
|
2
|
-
import {
|
|
3
|
-
export declare const RoomStateContext: React.Context<
|
|
4
|
-
export type RoomStateProviderProps<
|
|
5
|
-
roomStore?:
|
|
2
|
+
import { BaseRoomStoreState, BaseRoomStore } from './BaseRoomStore';
|
|
3
|
+
export declare const RoomStateContext: React.Context<BaseRoomStore<BaseRoomStoreState> | null>;
|
|
4
|
+
export type RoomStateProviderProps<RS extends BaseRoomStoreState> = React.PropsWithChildren<{
|
|
5
|
+
roomStore?: BaseRoomStore<RS>;
|
|
6
6
|
}>;
|
|
7
|
-
export declare function RoomStateProvider<
|
|
8
|
-
export declare function useBaseRoomStore<
|
|
7
|
+
export declare function RoomStateProvider<RS extends BaseRoomStoreState>({ children, roomStore, }: RoomStateProviderProps<RS>): ReactNode;
|
|
8
|
+
export declare function useBaseRoomStore<RS extends object, T>(selector: (state: RS & BaseRoomStoreState) => T): T;
|
|
9
9
|
//# sourceMappingURL=RoomStateProvider.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"RoomStateProvider.d.ts","sourceRoot":"","sources":["../src/RoomStateProvider.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,EAAgB,SAAS,EAAa,MAAM,OAAO,CAAC;AAElE,OAAO,EAAC,
|
|
1
|
+
{"version":3,"file":"RoomStateProvider.d.ts","sourceRoot":"","sources":["../src/RoomStateProvider.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,EAAgB,SAAS,EAAa,MAAM,OAAO,CAAC;AAElE,OAAO,EAAC,kBAAkB,EAAE,aAAa,EAAC,MAAM,iBAAiB,CAAC;AAIlE,eAAO,MAAM,gBAAgB,yDACkC,CAAC;AAEhE,MAAM,MAAM,sBAAsB,CAAC,EAAE,SAAS,kBAAkB,IAC9D,KAAK,CAAC,iBAAiB,CAAC;IACtB,SAAS,CAAC,EAAE,aAAa,CAAC,EAAE,CAAC,CAAC;CAC/B,CAAC,CAAC;AAEL,wBAAgB,iBAAiB,CAAC,EAAE,SAAS,kBAAkB,EAAE,EAC/D,QAAQ,EACR,SAAS,GACV,EAAE,sBAAsB,CAAC,EAAE,CAAC,GAAG,SAAS,CAMxC;AAED,wBAAgB,gBAAgB,CAAC,EAAE,SAAS,MAAM,EAAE,CAAC,EACnD,QAAQ,EAAE,CAAC,KAAK,EAAE,EAAE,GAAG,kBAAkB,KAAK,CAAC,GAC9C,CAAC,CASH"}
|
|
@@ -4,7 +4,7 @@ import { useStore } from 'zustand';
|
|
|
4
4
|
// See https://docs.pmnd.rs/zustand/guides/initialize-state-with-props
|
|
5
5
|
export const RoomStateContext = createContext(null);
|
|
6
6
|
export function RoomStateProvider({ children, roomStore, }) {
|
|
7
|
-
return (_jsx(RoomStateContext.Provider, { value: roomStore, children: children }));
|
|
7
|
+
return (_jsx(RoomStateContext.Provider, { value: roomStore ?? null, children: children }));
|
|
8
8
|
}
|
|
9
9
|
export function useBaseRoomStore(selector) {
|
|
10
10
|
const store = useContext(RoomStateContext);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"RoomStateProvider.js","sourceRoot":"","sources":["../src/RoomStateProvider.tsx"],"names":[],"mappings":";AAAA,OAAc,EAAC,aAAa,EAAa,UAAU,EAAC,MAAM,OAAO,CAAC;AAClE,OAAO,EAAW,QAAQ,EAAC,MAAM,SAAS,CAAC;AAG3C,sEAAsE;AAEtE,MAAM,CAAC,MAAM,gBAAgB,
|
|
1
|
+
{"version":3,"file":"RoomStateProvider.js","sourceRoot":"","sources":["../src/RoomStateProvider.tsx"],"names":[],"mappings":";AAAA,OAAc,EAAC,aAAa,EAAa,UAAU,EAAC,MAAM,OAAO,CAAC;AAClE,OAAO,EAAW,QAAQ,EAAC,MAAM,SAAS,CAAC;AAG3C,sEAAsE;AAEtE,MAAM,CAAC,MAAM,gBAAgB,GAC3B,aAAa,CAA2C,IAAI,CAAC,CAAC;AAOhE,MAAM,UAAU,iBAAiB,CAAgC,EAC/D,QAAQ,EACR,SAAS,GACkB;IAC3B,OAAO,CACL,KAAC,gBAAgB,CAAC,QAAQ,IAAC,KAAK,EAAE,SAAS,IAAI,IAAI,YAChD,QAAQ,GACiB,CAC7B,CAAC;AACJ,CAAC;AAED,MAAM,UAAU,gBAAgB,CAC9B,QAA+C;IAE/C,MAAM,KAAK,GAAG,UAAU,CAAC,gBAAgB,CAAC,CAAC;IAC3C,IAAI,CAAC,KAAK,EAAE,CAAC;QACX,MAAM,IAAI,KAAK,CAAC,uCAAuC,CAAC,CAAC;IAC3D,CAAC;IACD,OAAO,QAAQ,CACb,KAAqD,EACrD,QAAQ,CACT,CAAC;AACJ,CAAC","sourcesContent":["import React, {createContext, ReactNode, useContext} from 'react';\nimport {StoreApi, useStore} from 'zustand';\nimport {BaseRoomStoreState, BaseRoomStore} from './BaseRoomStore';\n\n// See https://docs.pmnd.rs/zustand/guides/initialize-state-with-props\n\nexport const RoomStateContext =\n createContext<BaseRoomStore<BaseRoomStoreState> | null>(null);\n\nexport type RoomStateProviderProps<RS extends BaseRoomStoreState> =\n React.PropsWithChildren<{\n roomStore?: BaseRoomStore<RS>;\n }>;\n\nexport function RoomStateProvider<RS extends BaseRoomStoreState>({\n children,\n roomStore,\n}: RoomStateProviderProps<RS>): ReactNode {\n return (\n <RoomStateContext.Provider value={roomStore ?? null}>\n {children}\n </RoomStateContext.Provider>\n );\n}\n\nexport function useBaseRoomStore<RS extends object, T>(\n selector: (state: RS & BaseRoomStoreState) => T,\n): T {\n const store = useContext(RoomStateContext);\n if (!store) {\n throw new Error('Missing RoomStateProvider in the tree');\n }\n return useStore(\n store as unknown as StoreApi<RS & BaseRoomStoreState>,\n selector,\n );\n}\n"]}
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
import z from 'zod';
|
|
2
|
+
/**
|
|
3
|
+
* Creates partialize and merge functions for Zustand persist middleware.
|
|
4
|
+
* Automatically handles extracting and merging slice configs.
|
|
5
|
+
*
|
|
6
|
+
* @param sliceConfigs - Map of slice names to their Zod config schemas
|
|
7
|
+
* @returns Object with partialize and merge functions
|
|
8
|
+
*
|
|
9
|
+
* @example
|
|
10
|
+
* ```ts
|
|
11
|
+
* const {partialize, merge} = createPersistHelpers({
|
|
12
|
+
* room: BaseRoomConfig,
|
|
13
|
+
* layout: LayoutConfig,
|
|
14
|
+
* sqlEditor: SqlEditorSliceConfig,
|
|
15
|
+
* });
|
|
16
|
+
*
|
|
17
|
+
* export const {roomStore, useRoomStore} = createRoomStore<RoomState>(
|
|
18
|
+
* persist(
|
|
19
|
+
* (set, get, store) => ({...}),
|
|
20
|
+
* {
|
|
21
|
+
* name: 'my-app-state-storage',
|
|
22
|
+
* partialize,
|
|
23
|
+
* merge,
|
|
24
|
+
* },
|
|
25
|
+
* ) as StateCreator<RoomState>,
|
|
26
|
+
* );
|
|
27
|
+
* ```
|
|
28
|
+
*/
|
|
29
|
+
export declare function createPersistHelpers<T extends Record<string, z.ZodType>>(sliceConfigs: T): {
|
|
30
|
+
partialize: (state: any) => Record<string, any>;
|
|
31
|
+
merge: (persistedState: any, currentState: any) => any;
|
|
32
|
+
};
|
|
33
|
+
//# sourceMappingURL=createPersistHelpers.d.ts.map
|
|
@@ -0,0 +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"}
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Creates partialize and merge functions for Zustand persist middleware.
|
|
3
|
+
* Automatically handles extracting and merging slice configs.
|
|
4
|
+
*
|
|
5
|
+
* @param sliceConfigs - Map of slice names to their Zod config schemas
|
|
6
|
+
* @returns Object with partialize and merge functions
|
|
7
|
+
*
|
|
8
|
+
* @example
|
|
9
|
+
* ```ts
|
|
10
|
+
* const {partialize, merge} = createPersistHelpers({
|
|
11
|
+
* room: BaseRoomConfig,
|
|
12
|
+
* layout: LayoutConfig,
|
|
13
|
+
* sqlEditor: SqlEditorSliceConfig,
|
|
14
|
+
* });
|
|
15
|
+
*
|
|
16
|
+
* export const {roomStore, useRoomStore} = createRoomStore<RoomState>(
|
|
17
|
+
* persist(
|
|
18
|
+
* (set, get, store) => ({...}),
|
|
19
|
+
* {
|
|
20
|
+
* name: 'my-app-state-storage',
|
|
21
|
+
* partialize,
|
|
22
|
+
* merge,
|
|
23
|
+
* },
|
|
24
|
+
* ) as StateCreator<RoomState>,
|
|
25
|
+
* );
|
|
26
|
+
* ```
|
|
27
|
+
*/
|
|
28
|
+
export function createPersistHelpers(sliceConfigs) {
|
|
29
|
+
return {
|
|
30
|
+
partialize: (state) => {
|
|
31
|
+
const result = {};
|
|
32
|
+
for (const [key, schema] of Object.entries(sliceConfigs)) {
|
|
33
|
+
result[key] = schema.parse(state[key].config);
|
|
34
|
+
}
|
|
35
|
+
return result;
|
|
36
|
+
},
|
|
37
|
+
merge: (persistedState, currentState) => {
|
|
38
|
+
const merged = { ...currentState };
|
|
39
|
+
for (const [key, schema] of Object.entries(sliceConfigs)) {
|
|
40
|
+
merged[key] = {
|
|
41
|
+
...currentState[key],
|
|
42
|
+
config: schema.parse(persistedState[key]),
|
|
43
|
+
};
|
|
44
|
+
}
|
|
45
|
+
return merged;
|
|
46
|
+
},
|
|
47
|
+
};
|
|
48
|
+
}
|
|
49
|
+
//# sourceMappingURL=createPersistHelpers.js.map
|
|
@@ -0,0 +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"]}
|
package/dist/index.d.ts
CHANGED
|
@@ -3,7 +3,8 @@
|
|
|
3
3
|
* @packageDocumentation
|
|
4
4
|
*/
|
|
5
5
|
export { RoomStateContext, RoomStateProvider, useBaseRoomStore, type RoomStateProviderProps, } from './RoomStateProvider';
|
|
6
|
-
export {
|
|
6
|
+
export { createBaseRoomSlice, createBaseSlice, createSlice, createRoomSlice, createRoomStore, createRoomStoreCreator, isRoomSliceWithDestroy, isRoomSliceWithInitialize, type BaseRoomStoreState, type CreateBaseRoomSliceProps, type BaseRoomStore, } from './BaseRoomStore';
|
|
7
|
+
export { createPersistHelpers } from './createPersistHelpers';
|
|
7
8
|
export type { StateCreator, StoreApi } from 'zustand';
|
|
8
9
|
export * from '@sqlrooms/room-config';
|
|
9
10
|
//# sourceMappingURL=index.d.ts.map
|
package/dist/index.d.ts.map
CHANGED
|
@@ -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,eAAe,EACf,
|
|
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"}
|
package/dist/index.js
CHANGED
|
@@ -3,6 +3,7 @@
|
|
|
3
3
|
* @packageDocumentation
|
|
4
4
|
*/
|
|
5
5
|
export { RoomStateContext, RoomStateProvider, useBaseRoomStore, } from './RoomStateProvider';
|
|
6
|
-
export {
|
|
6
|
+
export { createBaseRoomSlice, createBaseSlice, createSlice, createRoomSlice, createRoomStore, createRoomStoreCreator, isRoomSliceWithDestroy, isRoomSliceWithInitialize, } from './BaseRoomStore';
|
|
7
|
+
export { createPersistHelpers } from './createPersistHelpers';
|
|
7
8
|
export * from '@sqlrooms/room-config';
|
|
8
9
|
//# 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,eAAe,EACf,
|
|
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"]}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@sqlrooms/room-store",
|
|
3
|
-
"version": "0.26.0-rc.
|
|
3
|
+
"version": "0.26.0-rc.6",
|
|
4
4
|
"main": "dist/index.js",
|
|
5
5
|
"types": "dist/index.d.ts",
|
|
6
6
|
"module": "dist/index.js",
|
|
@@ -18,7 +18,7 @@
|
|
|
18
18
|
"access": "public"
|
|
19
19
|
},
|
|
20
20
|
"dependencies": {
|
|
21
|
-
"@sqlrooms/room-config": "0.26.0-rc.
|
|
21
|
+
"@sqlrooms/room-config": "0.26.0-rc.6",
|
|
22
22
|
"immer": "^10.1.3",
|
|
23
23
|
"zod": "^4.1.8",
|
|
24
24
|
"zustand": "^5.0.8"
|
|
@@ -33,5 +33,5 @@
|
|
|
33
33
|
"typecheck": "tsc --noEmit",
|
|
34
34
|
"typedoc": "typedoc"
|
|
35
35
|
},
|
|
36
|
-
"gitHead": "
|
|
36
|
+
"gitHead": "f7b18280e7d81f653bb437cf81b1e23243809053"
|
|
37
37
|
}
|
package/dist/RoomStore.d.ts
DELETED
|
@@ -1,75 +0,0 @@
|
|
|
1
|
-
import { StateCreator, StoreApi } from 'zustand';
|
|
2
|
-
export type RoomStore<PC> = StoreApi<RoomState<PC>>;
|
|
3
|
-
export type RoomStateProps<PC> = {
|
|
4
|
-
initialized: boolean;
|
|
5
|
-
lastSavedConfig: PC | undefined;
|
|
6
|
-
tasksProgress: Record<string, TaskProgress>;
|
|
7
|
-
captureException: (exception: unknown, captureContext?: unknown) => void;
|
|
8
|
-
};
|
|
9
|
-
export type TaskProgress = {
|
|
10
|
-
progress?: number | undefined;
|
|
11
|
-
message: string;
|
|
12
|
-
};
|
|
13
|
-
export type RoomStateActions<PC> = {
|
|
14
|
-
initialize: () => Promise<void>;
|
|
15
|
-
/**
|
|
16
|
-
* Set the room config.
|
|
17
|
-
* @param config - The room config to set.
|
|
18
|
-
*/
|
|
19
|
-
setRoomConfig: (config: PC) => void;
|
|
20
|
-
/**
|
|
21
|
-
* Set the last saved room config. This can be used to check if the room has unsaved changes.
|
|
22
|
-
* @param config - The room config to set.
|
|
23
|
-
*/
|
|
24
|
-
setLastSavedConfig: (config: PC) => void;
|
|
25
|
-
/**
|
|
26
|
-
* Check if the room has unsaved changes.
|
|
27
|
-
* @returns True if the room has unsaved changes, false otherwise.
|
|
28
|
-
*/
|
|
29
|
-
hasUnsavedChanges(): boolean;
|
|
30
|
-
/**
|
|
31
|
-
* Called when the project config gets changed. Can be used for saving.
|
|
32
|
-
* To be overridden by the custom project state.
|
|
33
|
-
* @param config - The project config to save.
|
|
34
|
-
*/
|
|
35
|
-
onSaveConfig?: (config: PC) => Promise<void> | undefined;
|
|
36
|
-
setTaskProgress: (id: string, taskProgress: TaskProgress | undefined) => void;
|
|
37
|
-
getLoadingProgress: () => TaskProgress | undefined;
|
|
38
|
-
};
|
|
39
|
-
export type RoomState<PC> = {
|
|
40
|
-
config: PC;
|
|
41
|
-
room: RoomStateProps<PC> & RoomStateActions<PC>;
|
|
42
|
-
};
|
|
43
|
-
export declare function createRoomSlice<PC>(props?: {
|
|
44
|
-
config?: PC;
|
|
45
|
-
room?: Partial<Omit<RoomStateProps<PC>, 'config'>>;
|
|
46
|
-
}): StateCreator<RoomState<PC>>;
|
|
47
|
-
export declare function createBaseSlice<PC, S>(sliceCreator: (...args: Parameters<StateCreator<S & RoomState<PC>>>) => S): StateCreator<S>;
|
|
48
|
-
/**
|
|
49
|
-
* Create a room store with custom fields and methods
|
|
50
|
-
* @param initialState - The initial state and config for the room
|
|
51
|
-
* @param sliceCreators - The slices to add to the room store
|
|
52
|
-
* @returns The room store and a hook for accessing the room store
|
|
53
|
-
*/
|
|
54
|
-
export declare function createRoomStore<PC, RS extends RoomState<PC>>(stateCreator: StateCreator<RS>): {
|
|
55
|
-
roomStore: StoreApi<RS>;
|
|
56
|
-
useRoomStore: <T>(selector: (state: RS) => T) => T;
|
|
57
|
-
};
|
|
58
|
-
export interface RoomSlice {
|
|
59
|
-
initialize?: () => Promise<void>;
|
|
60
|
-
}
|
|
61
|
-
export declare function isRoomSliceWithInitialize(slice: unknown): slice is RoomSlice & Required<Pick<RoomSlice, 'initialize'>>;
|
|
62
|
-
/**
|
|
63
|
-
* Factory to create a room store creator with custom params.
|
|
64
|
-
*
|
|
65
|
-
* @template PC - Room config type
|
|
66
|
-
* @template RS - Room state type
|
|
67
|
-
* @param stateCreatorFactory - A function that takes params and returns a Zustand state creator
|
|
68
|
-
* @returns An object with createRoomStore(params) and useRoomStore(selector)
|
|
69
|
-
*
|
|
70
|
-
*/
|
|
71
|
-
export declare function createRoomStoreCreator<TState extends RoomState<any>>(): <TFactory extends (...args: any[]) => StateCreator<TState>>(stateCreatorFactory: TFactory) => {
|
|
72
|
-
createRoomStore: (...args: Parameters<TFactory>) => StoreApi<TState>;
|
|
73
|
-
useRoomStore: <T>(selector: (state: TState) => T) => T;
|
|
74
|
-
};
|
|
75
|
-
//# sourceMappingURL=RoomStore.d.ts.map
|
package/dist/RoomStore.d.ts.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"RoomStore.d.ts","sourceRoot":"","sources":["../src/RoomStore.ts"],"names":[],"mappings":"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"}
|
package/dist/RoomStore.js
DELETED
|
@@ -1,134 +0,0 @@
|
|
|
1
|
-
import { createDefaultBaseRoomConfig } from '@sqlrooms/room-config';
|
|
2
|
-
import { castDraft, produce } from 'immer';
|
|
3
|
-
import { createStore, useStore } from 'zustand';
|
|
4
|
-
export function createRoomSlice(props) {
|
|
5
|
-
const { config: initialConfig = createDefaultBaseRoomConfig(), room: roomStateProps, ...restState } = props ?? {};
|
|
6
|
-
const initialRoomState = {
|
|
7
|
-
...roomStateProps,
|
|
8
|
-
initialized: false,
|
|
9
|
-
lastSavedConfig: undefined,
|
|
10
|
-
tasksProgress: {},
|
|
11
|
-
captureException: (exception) => {
|
|
12
|
-
console.error(exception);
|
|
13
|
-
},
|
|
14
|
-
};
|
|
15
|
-
const slice = (set, get) => {
|
|
16
|
-
const roomState = {
|
|
17
|
-
config: initialConfig,
|
|
18
|
-
room: {
|
|
19
|
-
...initialRoomState,
|
|
20
|
-
initialize: async () => {
|
|
21
|
-
// To be overridden by the room shell
|
|
22
|
-
},
|
|
23
|
-
setRoomConfig: (config) => set((state) => produce(state, (draft) => {
|
|
24
|
-
draft.config = castDraft(config);
|
|
25
|
-
})),
|
|
26
|
-
setLastSavedConfig: (config) => set((state) => produce(state, (draft) => {
|
|
27
|
-
draft.room.lastSavedConfig = castDraft(config);
|
|
28
|
-
})),
|
|
29
|
-
hasUnsavedChanges: () => {
|
|
30
|
-
const { lastSavedConfig } = get().room;
|
|
31
|
-
const { config } = get();
|
|
32
|
-
return config !== lastSavedConfig;
|
|
33
|
-
},
|
|
34
|
-
/** Returns the progress of the last task */
|
|
35
|
-
getLoadingProgress() {
|
|
36
|
-
const { tasksProgress } = get().room;
|
|
37
|
-
const keys = Object.keys(tasksProgress);
|
|
38
|
-
const lastKey = keys[keys.length - 1];
|
|
39
|
-
if (lastKey) {
|
|
40
|
-
return tasksProgress[lastKey];
|
|
41
|
-
}
|
|
42
|
-
return undefined;
|
|
43
|
-
},
|
|
44
|
-
setTaskProgress(id, taskProgress) {
|
|
45
|
-
set((state) => produce(state, (draft) => {
|
|
46
|
-
if (taskProgress) {
|
|
47
|
-
draft.room.tasksProgress[id] = taskProgress;
|
|
48
|
-
}
|
|
49
|
-
else {
|
|
50
|
-
delete draft.room.tasksProgress[id];
|
|
51
|
-
}
|
|
52
|
-
}));
|
|
53
|
-
},
|
|
54
|
-
},
|
|
55
|
-
...restState,
|
|
56
|
-
};
|
|
57
|
-
return roomState;
|
|
58
|
-
};
|
|
59
|
-
return slice;
|
|
60
|
-
}
|
|
61
|
-
export function createBaseSlice(sliceCreator) {
|
|
62
|
-
return (set, get, store) => sliceCreator(set, get, store);
|
|
63
|
-
}
|
|
64
|
-
/**
|
|
65
|
-
* Create a room store with custom fields and methods
|
|
66
|
-
* @param initialState - The initial state and config for the room
|
|
67
|
-
* @param sliceCreators - The slices to add to the room store
|
|
68
|
-
* @returns The room store and a hook for accessing the room store
|
|
69
|
-
*/
|
|
70
|
-
export function createRoomStore(stateCreator) {
|
|
71
|
-
const factory = createRoomStoreCreator();
|
|
72
|
-
const storeCreator = factory(() => stateCreator);
|
|
73
|
-
const roomStore = storeCreator.createRoomStore();
|
|
74
|
-
function useRoomStore(selector) {
|
|
75
|
-
return storeCreator.useRoomStore(selector);
|
|
76
|
-
}
|
|
77
|
-
return { roomStore, useRoomStore };
|
|
78
|
-
}
|
|
79
|
-
export function isRoomSliceWithInitialize(slice) {
|
|
80
|
-
return (typeof slice === 'object' &&
|
|
81
|
-
slice !== null &&
|
|
82
|
-
'initialize' in slice &&
|
|
83
|
-
typeof slice.initialize === 'function');
|
|
84
|
-
}
|
|
85
|
-
/**
|
|
86
|
-
* Factory to create a room store creator with custom params.
|
|
87
|
-
*
|
|
88
|
-
* @template PC - Room config type
|
|
89
|
-
* @template RS - Room state type
|
|
90
|
-
* @param stateCreatorFactory - A function that takes params and returns a Zustand state creator
|
|
91
|
-
* @returns An object with createRoomStore(params) and useRoomStore(selector)
|
|
92
|
-
*
|
|
93
|
-
*/
|
|
94
|
-
export function createRoomStoreCreator() {
|
|
95
|
-
return function (stateCreatorFactory) {
|
|
96
|
-
let store;
|
|
97
|
-
function createRoomStore(...args) {
|
|
98
|
-
store = createStore(stateCreatorFactory(...args));
|
|
99
|
-
if (typeof window !== 'undefined') {
|
|
100
|
-
(async () => {
|
|
101
|
-
try {
|
|
102
|
-
// Initialize the room
|
|
103
|
-
await store.getState().room.initialize();
|
|
104
|
-
// Set initialized to true after initialization
|
|
105
|
-
store.setState((state) => produce(state, ({ room }) => {
|
|
106
|
-
room.initialized = true;
|
|
107
|
-
}));
|
|
108
|
-
// Subscribe to the project store changes after initialization
|
|
109
|
-
store.subscribe(async (state) => {
|
|
110
|
-
const { room } = state;
|
|
111
|
-
if (room.onSaveConfig && room.hasUnsavedChanges()) {
|
|
112
|
-
room.onSaveConfig(state.config);
|
|
113
|
-
}
|
|
114
|
-
});
|
|
115
|
-
}
|
|
116
|
-
catch (error) {
|
|
117
|
-
store.getState().room.captureException(error);
|
|
118
|
-
}
|
|
119
|
-
})();
|
|
120
|
-
}
|
|
121
|
-
else {
|
|
122
|
-
console.warn('Skipping room store initialization. Room store should be only used on client.');
|
|
123
|
-
}
|
|
124
|
-
return store;
|
|
125
|
-
}
|
|
126
|
-
function useRoomStore(selector) {
|
|
127
|
-
if (!store)
|
|
128
|
-
throw new Error('Room store not initialized. Call createRoomStore first.');
|
|
129
|
-
return useStore(store, selector);
|
|
130
|
-
}
|
|
131
|
-
return { createRoomStore, useRoomStore };
|
|
132
|
-
};
|
|
133
|
-
}
|
|
134
|
-
//# sourceMappingURL=RoomStore.js.map
|
package/dist/RoomStore.js.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"RoomStore.js","sourceRoot":"","sources":["../src/RoomStore.ts"],"names":[],"mappings":"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","sourcesContent":["import {createDefaultBaseRoomConfig} from '@sqlrooms/room-config';\nimport {castDraft, produce} from 'immer';\nimport {StateCreator, StoreApi, createStore, useStore} from 'zustand';\n\nexport type RoomStore<PC> = StoreApi<RoomState<PC>>;\n\nexport type RoomStateProps<PC> = {\n initialized: boolean;\n lastSavedConfig: PC | undefined;\n tasksProgress: Record<string, TaskProgress>;\n captureException: (exception: unknown, captureContext?: unknown) => void;\n};\n\nexport type TaskProgress = {\n progress?: number | undefined;\n message: string;\n};\n\nexport type RoomStateActions<PC> = {\n initialize: () => Promise<void>;\n\n /**\n * Set the room config.\n * @param config - The room config to set.\n */\n setRoomConfig: (config: PC) => void;\n /**\n * Set the last saved room config. This can be used to check if the room has unsaved changes.\n * @param config - The room config to set.\n */\n setLastSavedConfig: (config: PC) => void;\n /**\n * Check if the room has unsaved changes.\n * @returns True if the room has unsaved changes, false otherwise.\n */\n hasUnsavedChanges(): boolean; // since last save\n /**\n * Called when the project config gets changed. Can be used for saving.\n * To be overridden by the custom project state.\n * @param config - The project config to save.\n */\n onSaveConfig?: (config: PC) => Promise<void> | undefined;\n\n setTaskProgress: (id: string, taskProgress: TaskProgress | undefined) => void;\n getLoadingProgress: () => TaskProgress | undefined;\n};\n\nexport type RoomState<PC> = {\n config: PC;\n room: RoomStateProps<PC> & RoomStateActions<PC>;\n};\n\nexport function createRoomSlice<PC>(props?: {\n config?: PC;\n room?: Partial<Omit<RoomStateProps<PC>, 'config'>>;\n}): StateCreator<RoomState<PC>> {\n const {\n config: initialConfig = createDefaultBaseRoomConfig() as PC,\n room: roomStateProps,\n ...restState\n } = props ?? {};\n const initialRoomState: RoomStateProps<PC> = {\n ...roomStateProps,\n initialized: false,\n lastSavedConfig: undefined,\n tasksProgress: {},\n captureException: (exception: unknown) => {\n console.error(exception);\n },\n };\n const slice: StateCreator<RoomState<PC>> = (set, get) => {\n const roomState: RoomState<PC> = {\n config: initialConfig,\n room: {\n ...initialRoomState,\n initialize: async () => {\n // To be overridden by the room shell\n },\n\n setRoomConfig: (config) =>\n set((state) =>\n produce(state, (draft) => {\n draft.config = castDraft(config);\n }),\n ),\n setLastSavedConfig: (config) =>\n set((state) =>\n produce(state, (draft) => {\n draft.room.lastSavedConfig = castDraft(config);\n }),\n ),\n\n hasUnsavedChanges: () => {\n const {lastSavedConfig} = get().room;\n const {config} = get();\n return config !== lastSavedConfig;\n },\n\n /** Returns the progress of the last task */\n getLoadingProgress() {\n const {tasksProgress} = get().room;\n const keys = Object.keys(tasksProgress);\n const lastKey = keys[keys.length - 1];\n if (lastKey) {\n return tasksProgress[lastKey];\n }\n return undefined;\n },\n\n setTaskProgress(id, taskProgress) {\n set((state) =>\n produce(state, (draft) => {\n if (taskProgress) {\n draft.room.tasksProgress[id] = taskProgress;\n } else {\n delete draft.room.tasksProgress[id];\n }\n }),\n );\n },\n },\n ...restState,\n };\n\n return roomState;\n };\n\n return slice;\n}\n\nexport function createBaseSlice<PC, S>(\n sliceCreator: (...args: Parameters<StateCreator<S & RoomState<PC>>>) => S,\n): StateCreator<S> {\n return (set, get, store) =>\n sliceCreator(\n set,\n get as () => S & RoomState<PC>,\n store as StoreApi<S & RoomState<PC>>,\n );\n}\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<PC, RS extends RoomState<PC>>(\n stateCreator: StateCreator<RS>,\n) {\n const factory = createRoomStoreCreator<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\nexport interface RoomSlice {\n initialize?: () => Promise<void>;\n}\n\nexport function isRoomSliceWithInitialize(\n slice: unknown,\n): slice is RoomSlice & Required<Pick<RoomSlice, 'initialize'>> {\n return (\n typeof slice === 'object' &&\n slice !== null &&\n 'initialize' in slice &&\n typeof slice.initialize === 'function'\n );\n}\n\n/**\n * Factory to create a room store creator with custom params.\n *\n * @template PC - Room config type\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<TState extends RoomState<any>>() {\n return function <TFactory extends (...args: any[]) => StateCreator<TState>>(\n stateCreatorFactory: TFactory,\n ): {\n createRoomStore: (...args: Parameters<TFactory>) => StoreApi<TState>;\n useRoomStore: <T>(selector: (state: TState) => T) => T;\n } {\n let store: StoreApi<TState> | undefined;\n\n function createRoomStore(...args: Parameters<TFactory>): StoreApi<TState> {\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, ({room}) => {\n room.initialized = true;\n }),\n );\n // Subscribe to the project store changes after initialization\n store.subscribe(async (state) => {\n const {room} = state;\n if (room.onSaveConfig && room.hasUnsavedChanges()) {\n room.onSaveConfig(state.config);\n }\n });\n } catch (error) {\n store.getState().room.captureException(error);\n }\n })();\n } else {\n console.warn(\n 'Skipping room store initialization. Room store should be only used on client.',\n );\n }\n return store;\n }\n\n function useRoomStore<T>(selector: (state: TState) => 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"]}
|