cogsbox-state 0.5.277 → 0.5.279

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/src/CogsState.tsx CHANGED
@@ -947,7 +947,7 @@ export function useCogsStateFn<TStateObject extends unknown>(
947
947
  options?.localStorage?.onChange(newState);
948
948
  }
949
949
  }
950
-
950
+ getGlobalStore.getState().initializeShadowState(thisKey, initialState);
951
951
  // Update the global state
952
952
  updateGlobalState(
953
953
  thisKey,
@@ -1010,8 +1010,6 @@ export function useCogsStateFn<TStateObject extends unknown>(
1010
1010
  //need to force update to create the stateUpdates references
1011
1011
  forceUpdate({});
1012
1012
  return () => {
1013
- const componentKey = `${thisKey}////${componentIdRef.current}`;
1014
-
1015
1013
  if (stateEntry) {
1016
1014
  stateEntry.components.delete(componentKey);
1017
1015
  if (stateEntry.components.size === 0) {
@@ -1080,6 +1078,33 @@ export function useCogsStateFn<TStateObject extends unknown>(
1080
1078
  });
1081
1079
  }
1082
1080
  }
1081
+
1082
+ const shadowUpdate = () => {
1083
+ const store = getGlobalStore.getState();
1084
+
1085
+ switch (updateObj.updateType) {
1086
+ case "update":
1087
+ // For updates, just mirror the structure at the path
1088
+ store.updateShadowAtPath(thisKey, path, payload);
1089
+ break;
1090
+
1091
+ case "insert":
1092
+ // For array insert, add empty element to shadow array
1093
+ const parentPath = path.slice(0, -1);
1094
+ store.insertShadowArrayElement(thisKey, parentPath);
1095
+ break;
1096
+
1097
+ case "cut":
1098
+ // For array cut, remove element from shadow array
1099
+ const arrayPath = path.slice(0, -1);
1100
+ const index = parseInt(path[path.length - 1]!);
1101
+ store.removeShadowArrayElement(thisKey, arrayPath, index);
1102
+ break;
1103
+ }
1104
+ };
1105
+
1106
+ shadowUpdate();
1107
+ console.log("shadowState", getGlobalStore.getState().shadowStateStore);
1083
1108
  if (
1084
1109
  updateObj.updateType === "update" &&
1085
1110
  (validationKey || latestInitialOptionsRef.current?.validation?.key) &&
@@ -1439,6 +1464,7 @@ function createProxyHandler<T>(
1439
1464
  }
1440
1465
  startTransition(() => {
1441
1466
  updateInitialStateGlobal(stateKey, newState);
1467
+ getGlobalStore.getState().initializeShadowState(stateKey, newState);
1442
1468
  setUpdaterState(stateKey, newUpdaterState);
1443
1469
  setState(stateKey, newState);
1444
1470
  const stateEntry = getGlobalStore
package/src/store.ts CHANGED
@@ -85,7 +85,32 @@ export const formRefStore = create<FormRefStoreState>((set, get) => ({
85
85
  return filteredRefs;
86
86
  },
87
87
  }));
88
+
89
+ type ShadowMetadata = {
90
+ virtualisedState?: { listItemHeight: number };
91
+ syncInfo?: { status: string };
92
+ // Add other metadata fields you need
93
+ };
94
+
95
+ type ShadowState<T> =
96
+ T extends Array<infer U>
97
+ ? Array<ShadowState<U>> & ShadowMetadata
98
+ : T extends object
99
+ ? { [K in keyof T]: ShadowState<T[K]> } & ShadowMetadata
100
+ : ShadowMetadata;
88
101
  export type CogsGlobalState = {
102
+ shadowStateStore: { [key: string]: any };
103
+ initializeShadowState: (key: string, initialState: any) => void;
104
+ updateShadowAtPath: (key: string, path: string[], newValue: any) => void;
105
+ insertShadowArrayElement: (key: string, arrayPath: string[]) => void;
106
+ removeShadowArrayElement: (
107
+ key: string,
108
+ arrayPath: string[],
109
+ index: number
110
+ ) => void;
111
+ getShadowMetadata: (key: string, path: string[]) => any;
112
+ setShadowMetadata: (key: string, path: string[], metadata: any) => void;
113
+
89
114
  selectedIndicesMap: Map<string, Map<string, number>>; // stateKey -> (parentPath -> selectedIndex)
90
115
 
91
116
  // Add these new methods
@@ -207,6 +232,130 @@ export type CogsGlobalState = {
207
232
  };
208
233
 
209
234
  export const getGlobalStore = create<CogsGlobalState>((set, get) => ({
235
+ shadowStateStore: {},
236
+ getShadowMetadata: (key: string, path: string[]) => {
237
+ const shadow = get().shadowStateStore[key];
238
+ if (!shadow) return null;
239
+
240
+ let current = shadow;
241
+ for (const segment of path) {
242
+ current = current?.[segment];
243
+ if (!current) return null;
244
+ }
245
+
246
+ return current;
247
+ },
248
+
249
+ setShadowMetadata: (key: string, path: string[], metadata: any) => {
250
+ set((state) => {
251
+ const newShadow = { ...state.shadowStateStore };
252
+ if (!newShadow[key]) return state;
253
+
254
+ newShadow[key] = JSON.parse(JSON.stringify(newShadow[key]));
255
+
256
+ let current = newShadow[key];
257
+ for (const segment of path) {
258
+ if (!current[segment]) current[segment] = {};
259
+ current = current[segment];
260
+ }
261
+
262
+ Object.assign(current, metadata);
263
+
264
+ return { shadowStateStore: newShadow };
265
+ });
266
+ },
267
+ initializeShadowState: (key: string, initialState: any) => {
268
+ const createShadowStructure = (obj: any): any => {
269
+ if (Array.isArray(obj)) {
270
+ return new Array(obj.length)
271
+ .fill(null)
272
+ .map((_, i) => createShadowStructure(obj[i]));
273
+ }
274
+ if (typeof obj === "object" && obj !== null) {
275
+ const shadow: any = {};
276
+ for (const k in obj) {
277
+ shadow[k] = createShadowStructure(obj[k]);
278
+ }
279
+ return shadow;
280
+ }
281
+ return {}; // Leaf node - empty object for metadata
282
+ };
283
+
284
+ set((state) => ({
285
+ shadowStateStore: {
286
+ ...state.shadowStateStore,
287
+ [key]: createShadowStructure(initialState),
288
+ },
289
+ }));
290
+ },
291
+
292
+ updateShadowAtPath: (key: string, path: string[], newValue: any) => {
293
+ set((state) => {
294
+ const newShadow = { ...state.shadowStateStore };
295
+ if (!newShadow[key]) return state;
296
+
297
+ let current = newShadow[key];
298
+ const pathCopy = [...path];
299
+ const lastSegment = pathCopy.pop();
300
+
301
+ // Navigate to parent
302
+ for (const segment of pathCopy) {
303
+ if (!current[segment]) current[segment] = {};
304
+ current = current[segment];
305
+ }
306
+
307
+ // Update shadow structure to match new value structure
308
+ if (lastSegment !== undefined) {
309
+ if (Array.isArray(newValue)) {
310
+ current[lastSegment] = new Array(newValue.length);
311
+ } else if (typeof newValue === "object" && newValue !== null) {
312
+ current[lastSegment] = {};
313
+ } else {
314
+ current[lastSegment] = current[lastSegment] || {};
315
+ }
316
+ }
317
+
318
+ return { shadowStateStore: newShadow };
319
+ });
320
+ },
321
+
322
+ insertShadowArrayElement: (key: string, arrayPath: string[]) => {
323
+ set((state) => {
324
+ const newShadow = { ...state.shadowStateStore };
325
+ let current = newShadow[key];
326
+
327
+ for (const segment of arrayPath) {
328
+ current = current?.[segment];
329
+ }
330
+
331
+ if (Array.isArray(current)) {
332
+ current.push({});
333
+ }
334
+
335
+ return { shadowStateStore: newShadow };
336
+ });
337
+ },
338
+
339
+ removeShadowArrayElement: (
340
+ key: string,
341
+ arrayPath: string[],
342
+ index: number
343
+ ) => {
344
+ set((state) => {
345
+ const newShadow = { ...state.shadowStateStore };
346
+ let current = newShadow[key];
347
+
348
+ for (const segment of arrayPath) {
349
+ current = current?.[segment];
350
+ }
351
+
352
+ if (Array.isArray(current)) {
353
+ current.splice(index, 1);
354
+ }
355
+
356
+ return { shadowStateStore: newShadow };
357
+ });
358
+ },
210
359
  selectedIndicesMap: new Map<string, Map<string, number>>(),
211
360
 
212
361
  // Add the new methods