@sqlrooms/room-store 0.26.0-rc.3 → 0.26.0-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.
- 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/RoomStore.d.ts +27 -54
- package/dist/RoomStore.d.ts.map +1 -1
- package/dist/RoomStore.js +38 -75
- package/dist/RoomStore.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
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
import React, { ReactNode } from 'react';
|
|
2
|
-
import {
|
|
3
|
-
export declare const RoomStateContext: React.Context<RoomStore<
|
|
4
|
-
export type RoomStateProviderProps<
|
|
5
|
-
roomStore?: RoomStore<
|
|
2
|
+
import { BaseRoomStoreState, RoomStore } from './RoomStore';
|
|
3
|
+
export declare const RoomStateContext: React.Context<RoomStore<BaseRoomStoreState> | null>;
|
|
4
|
+
export type RoomStateProviderProps<RS extends BaseRoomStoreState> = React.PropsWithChildren<{
|
|
5
|
+
roomStore?: RoomStore<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,SAAS,EAAC,MAAM,aAAa,CAAC;AAI1D,eAAO,MAAM,gBAAgB,qDAC8B,CAAC;AAE5D,MAAM,MAAM,sBAAsB,CAAC,EAAE,SAAS,kBAAkB,IAC9D,KAAK,CAAC,iBAAiB,CAAC;IACtB,SAAS,CAAC,EAAE,SAAS,CAAC,EAAE,CAAC,CAAC;CAC3B,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,CAAuC,IAAI,CAAC,CAAC;AAO5D,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, RoomStore} from './RoomStore';\n\n// See https://docs.pmnd.rs/zustand/guides/initialize-state-with-props\n\nexport const RoomStateContext =\n createContext<RoomStore<BaseRoomStoreState> | null>(null);\n\nexport type RoomStateProviderProps<RS extends BaseRoomStoreState> =\n React.PropsWithChildren<{\n roomStore?: RoomStore<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"]}
|
package/dist/RoomStore.d.ts
CHANGED
|
@@ -1,75 +1,48 @@
|
|
|
1
1
|
import { StateCreator, StoreApi } from 'zustand';
|
|
2
|
-
export
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
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;
|
|
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
|
+
};
|
|
38
13
|
};
|
|
39
|
-
export type
|
|
40
|
-
|
|
41
|
-
room
|
|
14
|
+
export type RoomStore<RS extends BaseRoomStoreState> = StoreApi<RS>;
|
|
15
|
+
export type CreateBaseRoomSliceProps = {
|
|
16
|
+
captureException?: BaseRoomStoreState['room']['captureException'];
|
|
42
17
|
};
|
|
43
|
-
export declare function
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
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;
|
|
48
24
|
/**
|
|
49
25
|
* Create a room store with custom fields and methods
|
|
50
26
|
* @param initialState - The initial state and config for the room
|
|
51
27
|
* @param sliceCreators - The slices to add to the room store
|
|
52
28
|
* @returns The room store and a hook for accessing the room store
|
|
53
29
|
*/
|
|
54
|
-
export declare function createRoomStore<
|
|
55
|
-
roomStore: StoreApi<RS>;
|
|
30
|
+
export declare function createRoomStore<RS extends BaseRoomStoreState>(stateCreator: StateCreator<RS>): {
|
|
31
|
+
roomStore: StoreApi<BaseRoomStoreState & RS>;
|
|
56
32
|
useRoomStore: <T>(selector: (state: RS) => T) => T;
|
|
57
33
|
};
|
|
58
|
-
export interface RoomSlice {
|
|
59
|
-
initialize?: () => Promise<void>;
|
|
60
|
-
}
|
|
61
|
-
export declare function isRoomSliceWithInitialize(slice: unknown): slice is RoomSlice & Required<Pick<RoomSlice, 'initialize'>>;
|
|
62
34
|
/**
|
|
63
35
|
* Factory to create a room store creator with custom params.
|
|
64
36
|
*
|
|
65
|
-
* @template PC - Room config type
|
|
66
37
|
* @template RS - Room state type
|
|
67
38
|
* @param stateCreatorFactory - A function that takes params and returns a Zustand state creator
|
|
68
39
|
* @returns An object with createRoomStore(params) and useRoomStore(selector)
|
|
69
40
|
*
|
|
70
41
|
*/
|
|
71
|
-
export declare function createRoomStoreCreator<
|
|
72
|
-
createRoomStore: (...args: Parameters<TFactory>) => StoreApi<
|
|
73
|
-
useRoomStore: <T>(selector: (state:
|
|
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;
|
|
74
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'>>;
|
|
75
48
|
//# sourceMappingURL=RoomStore.d.ts.map
|
package/dist/RoomStore.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"RoomStore.d.ts","sourceRoot":"","sources":["../src/RoomStore.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"RoomStore.d.ts","sourceRoot":"","sources":["../src/RoomStore.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,SAAS,CAAC,EAAE,SAAS,kBAAkB,IAAI,QAAQ,CAAC,EAAE,CAAC,CAAC;AAEpE,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"}
|
package/dist/RoomStore.js
CHANGED
|
@@ -1,66 +1,31 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import { castDraft, produce } from 'immer';
|
|
1
|
+
import { produce } from 'immer';
|
|
3
2
|
import { createStore, useStore } from 'zustand';
|
|
4
|
-
export function
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
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
|
-
},
|
|
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));
|
|
54
11
|
},
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
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
|
+
});
|
|
60
21
|
}
|
|
61
|
-
|
|
22
|
+
/** @deprecated Use createBaseRoomSlice instead */
|
|
23
|
+
export const createRoomSlice = createBaseRoomSlice;
|
|
24
|
+
export function createSlice(sliceCreator) {
|
|
62
25
|
return (set, get, store) => sliceCreator(set, get, store);
|
|
63
26
|
}
|
|
27
|
+
/** @deprecated Use createSlice instead */
|
|
28
|
+
export const createBaseSlice = createSlice;
|
|
64
29
|
/**
|
|
65
30
|
* Create a room store with custom fields and methods
|
|
66
31
|
* @param initialState - The initial state and config for the room
|
|
@@ -76,16 +41,9 @@ export function createRoomStore(stateCreator) {
|
|
|
76
41
|
}
|
|
77
42
|
return { roomStore, useRoomStore };
|
|
78
43
|
}
|
|
79
|
-
export function isRoomSliceWithInitialize(slice) {
|
|
80
|
-
return (typeof slice === 'object' &&
|
|
81
|
-
slice !== null &&
|
|
82
|
-
'initialize' in slice &&
|
|
83
|
-
typeof slice.initialize === 'function');
|
|
84
|
-
}
|
|
85
44
|
/**
|
|
86
45
|
* Factory to create a room store creator with custom params.
|
|
87
46
|
*
|
|
88
|
-
* @template PC - Room config type
|
|
89
47
|
* @template RS - Room state type
|
|
90
48
|
* @param stateCreatorFactory - A function that takes params and returns a Zustand state creator
|
|
91
49
|
* @returns An object with createRoomStore(params) and useRoomStore(selector)
|
|
@@ -102,16 +60,9 @@ export function createRoomStoreCreator() {
|
|
|
102
60
|
// Initialize the room
|
|
103
61
|
await store.getState().room.initialize();
|
|
104
62
|
// Set initialized to true after initialization
|
|
105
|
-
store.setState((state) => produce(state, (
|
|
106
|
-
room.initialized = true;
|
|
63
|
+
store.setState((state) => produce(state, (draft) => {
|
|
64
|
+
draft.room.initialized = true;
|
|
107
65
|
}));
|
|
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
66
|
}
|
|
116
67
|
catch (error) {
|
|
117
68
|
store.getState().room.captureException(error);
|
|
@@ -119,7 +70,7 @@ export function createRoomStoreCreator() {
|
|
|
119
70
|
})();
|
|
120
71
|
}
|
|
121
72
|
else {
|
|
122
|
-
console.warn('Skipping room store initialization.
|
|
73
|
+
console.warn('Skipping room store initialization. The room store should only be used on the client.');
|
|
123
74
|
}
|
|
124
75
|
return store;
|
|
125
76
|
}
|
|
@@ -131,4 +82,16 @@ export function createRoomStoreCreator() {
|
|
|
131
82
|
return { createRoomStore, useRoomStore };
|
|
132
83
|
};
|
|
133
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
|
+
}
|
|
134
97
|
//# sourceMappingURL=RoomStore.js.map
|
package/dist/RoomStore.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"RoomStore.js","sourceRoot":"","sources":["../src/RoomStore.ts"],"names":[],"mappings":"AAAA,OAAO,EAAC,2BAA2B,EAAC,MAAM,uBAAuB,CAAC;AAClE,OAAO,EAAC,SAAS,EAAE,OAAO,EAAC,MAAM,OAAO,CAAC;AACzC,OAAO,EAAyB,WAAW,EAAE,QAAQ,EAAC,MAAM,SAAS,CAAC;AAkDtE,MAAM,UAAU,eAAe,CAAK,KAGnC;IACC,MAAM,EACJ,MAAM,EAAE,aAAa,GAAG,2BAA2B,EAAQ,EAC3D,IAAI,EAAE,cAAc,EACpB,GAAG,SAAS,EACb,GAAG,KAAK,IAAI,EAAE,CAAC;IAChB,MAAM,gBAAgB,GAAuB;QAC3C,GAAG,cAAc;QACjB,WAAW,EAAE,KAAK;QAClB,eAAe,EAAE,SAAS;QAC1B,aAAa,EAAE,EAAE;QACjB,gBAAgB,EAAE,CAAC,SAAkB,EAAE,EAAE;YACvC,OAAO,CAAC,KAAK,CAAC,SAAS,CAAC,CAAC;QAC3B,CAAC;KACF,CAAC;IACF,MAAM,KAAK,GAAgC,CAAC,GAAG,EAAE,GAAG,EAAE,EAAE;QACtD,MAAM,SAAS,GAAkB;YAC/B,MAAM,EAAE,aAAa;YACrB,IAAI,EAAE;gBACJ,GAAG,gBAAgB;gBACnB,UAAU,EAAE,KAAK,IAAI,EAAE;oBACrB,qCAAqC;gBACvC,CAAC;gBAED,aAAa,EAAE,CAAC,MAAM,EAAE,EAAE,CACxB,GAAG,CAAC,CAAC,KAAK,EAAE,EAAE,CACZ,OAAO,CAAC,KAAK,EAAE,CAAC,KAAK,EAAE,EAAE;oBACvB,KAAK,CAAC,MAAM,GAAG,SAAS,CAAC,MAAM,CAAC,CAAC;gBACnC,CAAC,CAAC,CACH;gBACH,kBAAkB,EAAE,CAAC,MAAM,EAAE,EAAE,CAC7B,GAAG,CAAC,CAAC,KAAK,EAAE,EAAE,CACZ,OAAO,CAAC,KAAK,EAAE,CAAC,KAAK,EAAE,EAAE;oBACvB,KAAK,CAAC,IAAI,CAAC,eAAe,GAAG,SAAS,CAAC,MAAM,CAAC,CAAC;gBACjD,CAAC,CAAC,CACH;gBAEH,iBAAiB,EAAE,GAAG,EAAE;oBACtB,MAAM,EAAC,eAAe,EAAC,GAAG,GAAG,EAAE,CAAC,IAAI,CAAC;oBACrC,MAAM,EAAC,MAAM,EAAC,GAAG,GAAG,EAAE,CAAC;oBACvB,OAAO,MAAM,KAAK,eAAe,CAAC;gBACpC,CAAC;gBAED,4CAA4C;gBAC5C,kBAAkB;oBAChB,MAAM,EAAC,aAAa,EAAC,GAAG,GAAG,EAAE,CAAC,IAAI,CAAC;oBACnC,MAAM,IAAI,GAAG,MAAM,CAAC,IAAI,CAAC,aAAa,CAAC,CAAC;oBACxC,MAAM,OAAO,GAAG,IAAI,CAAC,IAAI,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC;oBACtC,IAAI,OAAO,EAAE,CAAC;wBACZ,OAAO,aAAa,CAAC,OAAO,CAAC,CAAC;oBAChC,CAAC;oBACD,OAAO,SAAS,CAAC;gBACnB,CAAC;gBAED,eAAe,CAAC,EAAE,EAAE,YAAY;oBAC9B,GAAG,CAAC,CAAC,KAAK,EAAE,EAAE,CACZ,OAAO,CAAC,KAAK,EAAE,CAAC,KAAK,EAAE,EAAE;wBACvB,IAAI,YAAY,EAAE,CAAC;4BACjB,KAAK,CAAC,IAAI,CAAC,aAAa,CAAC,EAAE,CAAC,GAAG,YAAY,CAAC;wBAC9C,CAAC;6BAAM,CAAC;4BACN,OAAO,KAAK,CAAC,IAAI,CAAC,aAAa,CAAC,EAAE,CAAC,CAAC;wBACtC,CAAC;oBACH,CAAC,CAAC,CACH,CAAC;gBACJ,CAAC;aACF;YACD,GAAG,SAAS;SACb,CAAC;QAEF,OAAO,SAAS,CAAC;IACnB,CAAC,CAAC;IAEF,OAAO,KAAK,CAAC;AACf,CAAC;AAED,MAAM,UAAU,eAAe,CAC7B,YAAyE;IAEzE,OAAO,CAAC,GAAG,EAAE,GAAG,EAAE,KAAK,EAAE,EAAE,CACzB,YAAY,CACV,GAAG,EACH,GAA8B,EAC9B,KAAoC,CACrC,CAAC;AACN,CAAC;AAED;;;;;GAKG;AACH,MAAM,UAAU,eAAe,CAC7B,YAA8B;IAE9B,MAAM,OAAO,GAAG,sBAAsB,EAAM,CAAC;IAC7C,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;AAMD,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;;;;;;;;GAQG;AACH,MAAM,UAAU,sBAAsB;IACpC,OAAO,UACL,mBAA6B;QAK7B,IAAI,KAAmC,CAAC;QAExC,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,EAAC,IAAI,EAAC,EAAE,EAAE;4BACxB,IAAI,CAAC,WAAW,GAAG,IAAI,CAAC;wBAC1B,CAAC,CAAC,CACH,CAAC;wBACF,8DAA8D;wBAC9D,KAAK,CAAC,SAAS,CAAC,KAAK,EAAE,KAAK,EAAE,EAAE;4BAC9B,MAAM,EAAC,IAAI,EAAC,GAAG,KAAK,CAAC;4BACrB,IAAI,IAAI,CAAC,YAAY,IAAI,IAAI,CAAC,iBAAiB,EAAE,EAAE,CAAC;gCAClD,IAAI,CAAC,YAAY,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC;4BAClC,CAAC;wBACH,CAAC,CAAC,CAAC;oBACL,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,+EAA+E,CAChF,CAAC;YACJ,CAAC;YACD,OAAO,KAAK,CAAC;QACf,CAAC;QAED,SAAS,YAAY,CAAI,QAA8B;YACrD,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","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"]}
|
|
1
|
+
{"version":3,"file":"RoomStore.js","sourceRoot":"","sources":["../src/RoomStore.ts"],"names":[],"mappings":"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","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 RoomStore<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"]}
|
|
@@ -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 RoomStore, } from './RoomStore';
|
|
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,SAAS,GACf,MAAM,aAAa,CAAC;AAErB,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 './RoomStore';
|
|
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,aAAa,CAAC;AAErB,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 RoomStore,\n} from './RoomStore';\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.5",
|
|
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.5",
|
|
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": "dc1c3b765718c8748aa11cce3cc83f907d3e5963"
|
|
37
37
|
}
|