@sqlrooms/room-store 0.20.0 → 0.22.0
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/RoomStore.d.ts +24 -0
- package/dist/RoomStore.d.ts.map +1 -1
- package/dist/RoomStore.js +61 -13
- package/dist/RoomStore.js.map +1 -1
- package/dist/index.d.ts +1 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +1 -1
- package/dist/index.js.map +1 -1
- package/package.json +3 -3
package/dist/RoomStore.d.ts
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { StateCreator, StoreApi } from 'zustand';
|
|
2
2
|
export type RoomStore<PC> = StoreApi<RoomState<PC>>;
|
|
3
3
|
export type RoomStateProps<PC> = {
|
|
4
|
+
initialized: boolean;
|
|
4
5
|
lastSavedConfig: PC | undefined;
|
|
5
6
|
tasksProgress: Record<string, TaskProgress>;
|
|
6
7
|
captureException: (exception: unknown, captureContext?: unknown) => void;
|
|
@@ -26,6 +27,12 @@ export type RoomStateActions<PC> = {
|
|
|
26
27
|
* @returns True if the room has unsaved changes, false otherwise.
|
|
27
28
|
*/
|
|
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;
|
|
29
36
|
setTaskProgress: (id: string, taskProgress: TaskProgress | undefined) => void;
|
|
30
37
|
getLoadingProgress: () => TaskProgress | undefined;
|
|
31
38
|
};
|
|
@@ -48,4 +55,21 @@ export declare function createRoomStore<PC, RS extends RoomState<PC>>(stateCreat
|
|
|
48
55
|
roomStore: StoreApi<RS>;
|
|
49
56
|
useRoomStore: <T>(selector: (state: RS) => T) => T;
|
|
50
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
|
+
};
|
|
51
75
|
//# 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":"AACA,OAAO,EAAC,YAAY,EAAE,QAAQ,
|
|
1
|
+
{"version":3,"file":"RoomStore.d.ts","sourceRoot":"","sources":["../src/RoomStore.ts"],"names":[],"mappings":"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"}
|
package/dist/RoomStore.js
CHANGED
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
import { castDraft, produce } from 'immer';
|
|
2
|
-
import { createStore } from 'zustand';
|
|
3
|
-
import { useBaseRoomStore } from './RoomStateProvider';
|
|
2
|
+
import { createStore, useStore } from 'zustand';
|
|
4
3
|
export function createRoomSlice(props) {
|
|
5
4
|
const { config: initialConfig, room: roomStateProps, ...restState } = props;
|
|
6
5
|
const initialRoomState = {
|
|
7
6
|
...roomStateProps,
|
|
7
|
+
initialized: false,
|
|
8
8
|
lastSavedConfig: undefined,
|
|
9
9
|
tasksProgress: {},
|
|
10
10
|
captureException: (exception) => {
|
|
@@ -67,19 +67,67 @@ export function createBaseSlice(sliceCreator) {
|
|
|
67
67
|
* @returns The room store and a hook for accessing the room store
|
|
68
68
|
*/
|
|
69
69
|
export function createRoomStore(stateCreator) {
|
|
70
|
-
const
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
if (typeof window !== 'undefined') {
|
|
74
|
-
roomStore.getState().room.initialize();
|
|
75
|
-
}
|
|
76
|
-
else {
|
|
77
|
-
console.warn('Skipping room store initialization. Room store should be only used on client.');
|
|
78
|
-
}
|
|
70
|
+
const factory = createRoomStoreCreator();
|
|
71
|
+
const storeCreator = factory(() => stateCreator);
|
|
72
|
+
const roomStore = storeCreator.createRoomStore();
|
|
79
73
|
function useRoomStore(selector) {
|
|
80
|
-
|
|
81
|
-
return useBaseRoomStore(selector);
|
|
74
|
+
return storeCreator.useRoomStore(selector);
|
|
82
75
|
}
|
|
83
76
|
return { roomStore, useRoomStore };
|
|
84
77
|
}
|
|
78
|
+
export function isRoomSliceWithInitialize(slice) {
|
|
79
|
+
return (typeof slice === 'object' &&
|
|
80
|
+
slice !== null &&
|
|
81
|
+
'initialize' in slice &&
|
|
82
|
+
typeof slice.initialize === 'function');
|
|
83
|
+
}
|
|
84
|
+
/**
|
|
85
|
+
* Factory to create a room store creator with custom params.
|
|
86
|
+
*
|
|
87
|
+
* @template PC - Room config type
|
|
88
|
+
* @template RS - Room state type
|
|
89
|
+
* @param stateCreatorFactory - A function that takes params and returns a Zustand state creator
|
|
90
|
+
* @returns An object with createRoomStore(params) and useRoomStore(selector)
|
|
91
|
+
*
|
|
92
|
+
*/
|
|
93
|
+
export function createRoomStoreCreator() {
|
|
94
|
+
return function (stateCreatorFactory) {
|
|
95
|
+
let store;
|
|
96
|
+
function createRoomStore(...args) {
|
|
97
|
+
store = createStore(stateCreatorFactory(...args));
|
|
98
|
+
if (typeof window !== 'undefined') {
|
|
99
|
+
(async () => {
|
|
100
|
+
try {
|
|
101
|
+
// Initialize the room
|
|
102
|
+
await store.getState().room.initialize();
|
|
103
|
+
// Set initialized to true after initialization
|
|
104
|
+
store.setState((state) => produce(state, ({ room }) => {
|
|
105
|
+
room.initialized = true;
|
|
106
|
+
}));
|
|
107
|
+
// Subscribe to the project store changes after initialization
|
|
108
|
+
store.subscribe(async (state) => {
|
|
109
|
+
const { room } = state;
|
|
110
|
+
if (room.onSaveConfig && room.hasUnsavedChanges()) {
|
|
111
|
+
room.onSaveConfig(state.config);
|
|
112
|
+
}
|
|
113
|
+
});
|
|
114
|
+
}
|
|
115
|
+
catch (error) {
|
|
116
|
+
store.getState().room.captureException(error);
|
|
117
|
+
}
|
|
118
|
+
})();
|
|
119
|
+
}
|
|
120
|
+
else {
|
|
121
|
+
console.warn('Skipping room store initialization. Room store should be only used on client.');
|
|
122
|
+
}
|
|
123
|
+
return store;
|
|
124
|
+
}
|
|
125
|
+
function useRoomStore(selector) {
|
|
126
|
+
if (!store)
|
|
127
|
+
throw new Error('Room store not initialized. Call createRoomStore first.');
|
|
128
|
+
return useStore(store, selector);
|
|
129
|
+
}
|
|
130
|
+
return { createRoomStore, useRoomStore };
|
|
131
|
+
};
|
|
132
|
+
}
|
|
85
133
|
//# 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":"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","sourcesContent":["import {castDraft, produce} from 'immer';\nimport {StateCreator, StoreApi, createStore} from 'zustand';\nimport {useBaseRoomStore} from './RoomStateProvider';\n\nexport type RoomStore<PC> = StoreApi<RoomState<PC>>;\n\nexport type RoomStateProps<PC> = {\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 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 {config: initialConfig, room: roomStateProps, ...restState} = props;\n const initialRoomState: RoomStateProps<PC> = {\n ...roomStateProps,\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 roomStore = createStore<RS>((set, get, store) => ({\n ...stateCreator(set, get, store),\n }));\n\n if (typeof window !== 'undefined') {\n roomStore.getState().room.initialize();\n } else {\n console.warn(\n 'Skipping room store initialization. Room store should be only used on client.',\n );\n }\n\n function useRoomStore<T>(selector: (state: RS) => T): T {\n // @ts-ignore TODO fix typing\n return useBaseRoomStore(selector as (state: RS) => T);\n }\n return {roomStore, useRoomStore};\n}\n"]}
|
|
1
|
+
{"version":3,"file":"RoomStore.js","sourceRoot":"","sources":["../src/RoomStore.ts"],"names":[],"mappings":"AAAA,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,EAAC,MAAM,EAAE,aAAa,EAAE,IAAI,EAAE,cAAc,EAAE,GAAG,SAAS,EAAC,GAAG,KAAK,CAAC;IAC1E,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 {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 {config: initialConfig, room: roomStateProps, ...restState} = 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"]}
|
package/dist/index.d.ts
CHANGED
|
@@ -3,6 +3,6 @@
|
|
|
3
3
|
* @packageDocumentation
|
|
4
4
|
*/
|
|
5
5
|
export { RoomStateContext, RoomStateProvider, useBaseRoomStore, type RoomStateProviderProps, } from './RoomStateProvider';
|
|
6
|
-
export { createRoomStore, createRoomSlice, type RoomStateActions, type RoomStateProps, type RoomState, type RoomStore, type TaskProgress, createBaseSlice, } from './RoomStore';
|
|
6
|
+
export { createRoomStore, createRoomStoreCreator, createRoomSlice, type RoomStateActions, type RoomStateProps, type RoomState, type RoomStore, type TaskProgress, createBaseSlice, type RoomSlice, isRoomSliceWithInitialize, } from './RoomStore';
|
|
7
7
|
export * from '@sqlrooms/room-config';
|
|
8
8
|
//# 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,eAAe,EACf,KAAK,gBAAgB,EACrB,KAAK,cAAc,EACnB,KAAK,SAAS,EACd,KAAK,SAAS,EACd,KAAK,YAAY,EACjB,eAAe,
|
|
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,sBAAsB,EACtB,eAAe,EACf,KAAK,gBAAgB,EACrB,KAAK,cAAc,EACnB,KAAK,SAAS,EACd,KAAK,SAAS,EACd,KAAK,YAAY,EACjB,eAAe,EACf,KAAK,SAAS,EACd,yBAAyB,GAC1B,MAAM,aAAa,CAAC;AAErB,cAAc,uBAAuB,CAAC"}
|
package/dist/index.js
CHANGED
|
@@ -3,6 +3,6 @@
|
|
|
3
3
|
* @packageDocumentation
|
|
4
4
|
*/
|
|
5
5
|
export { RoomStateContext, RoomStateProvider, useBaseRoomStore, } from './RoomStateProvider';
|
|
6
|
-
export { createRoomStore, createRoomSlice, createBaseSlice, } from './RoomStore';
|
|
6
|
+
export { createRoomStore, createRoomStoreCreator, createRoomSlice, createBaseSlice, isRoomSliceWithInitialize, } from './RoomStore';
|
|
7
7
|
export * from '@sqlrooms/room-config';
|
|
8
8
|
//# 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,eAAe,EAMf,eAAe,
|
|
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,sBAAsB,EACtB,eAAe,EAMf,eAAe,EAEf,yBAAyB,GAC1B,MAAM,aAAa,CAAC;AAErB,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 createRoomStore,\n createRoomStoreCreator,\n createRoomSlice,\n type RoomStateActions,\n type RoomStateProps,\n type RoomState,\n type RoomStore,\n type TaskProgress,\n createBaseSlice,\n type RoomSlice,\n isRoomSliceWithInitialize,\n} from './RoomStore';\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.
|
|
3
|
+
"version": "0.22.0",
|
|
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.
|
|
21
|
+
"@sqlrooms/room-config": "0.22.0",
|
|
22
22
|
"immer": "^10.1.1",
|
|
23
23
|
"zod": "^3.25.57",
|
|
24
24
|
"zustand": "^5.0.5"
|
|
@@ -33,5 +33,5 @@
|
|
|
33
33
|
"typecheck": "tsc --noEmit",
|
|
34
34
|
"typedoc": "typedoc"
|
|
35
35
|
},
|
|
36
|
-
"gitHead": "
|
|
36
|
+
"gitHead": "8314c58ee9d14606ce1d704d23b772a092ddcd64"
|
|
37
37
|
}
|