cogsbox-state 0.5.427 → 0.5.428

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/Functions.tsx CHANGED
@@ -7,11 +7,17 @@ import {
7
7
  type UpdateOpts,
8
8
  } from "./CogsState";
9
9
 
10
- import { getNestedValue, isFunction, updateNestedProperty } from "./utility";
10
+ import {
11
+ getNestedValue,
12
+ isFunction,
13
+ updateNestedProperty,
14
+ updateNestedPropertyIds,
15
+ } from "./utility";
11
16
  import { useEffect, useRef, useState } from "react";
12
17
  import React from "react";
13
18
  import { getGlobalStore, formRefStore } from "./store";
14
19
  import { validateZodPathFunc } from "./useValidateZodPath";
20
+ import { ulid } from "ulid";
15
21
 
16
22
  export function updateFn<U>(
17
23
  setState: EffectiveSetState<U>,
@@ -23,7 +29,9 @@ export function updateFn<U>(
23
29
  (prevState) => {
24
30
  if (isFunction<U>(payload)) {
25
31
  const nestedValue = payload(getNestedValue(prevState, path));
26
- let value = updateNestedProperty(path, prevState, nestedValue);
32
+ console.group("nestedValue", path, nestedValue);
33
+ let value = updateNestedPropertyIds(path, prevState, nestedValue);
34
+ console.group("updateFn", value);
27
35
  if (typeof value == "string") {
28
36
  value = value.trim();
29
37
  }
@@ -32,7 +40,7 @@ export function updateFn<U>(
32
40
  let value =
33
41
  !path || path.length == 0
34
42
  ? payload
35
- : updateNestedProperty(path, prevState, payload);
43
+ : updateNestedPropertyIds(path, prevState, payload);
36
44
  if (typeof value == "string") {
37
45
  value = value.trim();
38
46
  }
@@ -44,7 +52,6 @@ export function updateFn<U>(
44
52
  validationKey
45
53
  );
46
54
  }
47
-
48
55
  export function pushFunc<U>(
49
56
  setState: EffectiveSetState<U>,
50
57
  payload: UpdateArg<U>,
@@ -52,68 +59,69 @@ export function pushFunc<U>(
52
59
  stateKey: string,
53
60
  index?: number
54
61
  ): void {
55
- const array = getGlobalStore.getState().getNestedState(stateKey, path) as U[];
62
+ // --- THE FIX ---
63
+ // 1. Determine the newItem and its ID BEFORE calling setState.
64
+ const arrayBeforeUpdate =
65
+ (getGlobalStore.getState().getNestedState(stateKey, path) as any[]) || [];
66
+
67
+ const newItem = isFunction<U>(payload)
68
+ ? payload(arrayBeforeUpdate as any)
69
+ : payload;
70
+
71
+ // 2. Ensure it has an ID.
72
+ if (typeof newItem === "object" && newItem !== null && !(newItem as any).id) {
73
+ (newItem as any).id = ulid();
74
+ }
75
+ const finalId = (newItem as any).id;
76
+ // --- END OF FIX ---
77
+
56
78
  setState(
57
79
  (prevState) => {
58
- let arrayToUpdate =
59
- !path || path.length == 0
60
- ? prevState
61
- : getNestedValue(prevState, [...path]);
62
- let returnedArray = [...arrayToUpdate];
63
-
64
- returnedArray.splice(
65
- index || Number(index) == 0 ? index : arrayToUpdate.length,
66
- 0,
67
- isFunction<U>(payload)
68
- ? payload(index == -1 ? undefined : arrayToUpdate)
69
- : payload
70
- );
71
- const value =
72
- path.length == 0
73
- ? returnedArray
74
- : updateNestedProperty([...path], prevState, returnedArray);
75
-
76
- return value as U;
80
+ // The logic inside here is now much simpler.
81
+ // We already have the final `newItem`.
82
+ const arrayToUpdate = getNestedValue(prevState, [...path]) || [];
83
+ const newArray = [...arrayToUpdate];
84
+ newArray.splice(index ?? newArray.length, 0, newItem);
85
+ return updateNestedPropertyIds([...path], prevState, newArray);
77
86
  },
78
- [
79
- ...path,
80
- index || index === 0 ? index?.toString() : (array!.length - 1).toString(),
81
- ],
87
+ [...path, `id:${finalId}`], // Now we use the ID that is guaranteed to be correct.
82
88
  {
83
89
  updateType: "insert",
84
90
  }
85
91
  );
86
92
  }
87
-
88
93
  export function cutFunc<U>(
89
94
  setState: EffectiveSetState<U>,
90
95
  path: string[],
91
96
  stateKey: string,
92
97
  index: number
93
98
  ): void {
94
- const array = getGlobalStore.getState().getNestedState(stateKey, path) as U[];
99
+ // Get the ordered IDs to find the ID for this index
100
+ const arrayKey = [stateKey, ...path].join(".");
101
+ const arrayMeta = getGlobalStore.getState().shadowStateStore.get(arrayKey);
102
+ const itemId = arrayMeta?.arrayKeys?.[index];
103
+
104
+ if (!itemId) {
105
+ throw new Error(`No ID found for index ${index} in array`);
106
+ }
107
+
95
108
  setState(
96
109
  (prevState) => {
97
110
  const arrayToUpdate = getNestedValue(prevState, [...path]);
98
111
  if (index < 0 || index >= arrayToUpdate?.length) {
99
112
  throw new Error(`Index ${index} does not exist in the array.`);
100
113
  }
101
- const indexToCut =
102
- index || Number(index) == 0 ? index : arrayToUpdate.length - 1;
103
114
 
104
115
  const updatedArray = [
105
- ...arrayToUpdate.slice(0, indexToCut),
106
- ...arrayToUpdate.slice(indexToCut + 1),
116
+ ...arrayToUpdate.slice(0, index),
117
+ ...arrayToUpdate.slice(index + 1),
107
118
  ] as U;
108
119
 
109
120
  return path.length == 0
110
121
  ? updatedArray
111
- : updateNestedProperty([...path], prevState, updatedArray);
122
+ : updateNestedPropertyIds([...path], prevState, updatedArray);
112
123
  },
113
- [
114
- ...path,
115
- index || index === 0 ? index?.toString() : (array!.length - 1).toString(),
116
- ],
124
+ [...path, itemId], // Use the ID here!
117
125
  { updateType: "cut" }
118
126
  );
119
127
  }
package/src/store.ts CHANGED
@@ -1,4 +1,5 @@
1
1
  import { create } from "zustand";
2
+ import { ulid } from "ulid";
2
3
  import type {
3
4
  OptionsType,
4
5
  ReactivityType,
@@ -86,51 +87,42 @@ export const formRefStore = create<FormRefStoreState>((set, get) => ({
86
87
  },
87
88
  }));
88
89
 
89
- export type ItemMeta = {
90
- _cogsId: string;
90
+ export type ShadowMetadata = {
91
+ id: string;
92
+ arrayKeys?: string[];
91
93
  virtualizer?: {
92
94
  itemHeight?: number;
93
- domRef?: HTMLDivElement | null;
95
+ domRef?: HTMLElement | null;
94
96
  };
95
- syncStatus?: "new" | "syncing" | "synced" | "failed";
96
- error?: string;
97
+ syncInfo?: { status: string };
98
+ lastUpdated?: number;
97
99
  };
98
-
99
- // THE NEW, CORRECT, RECURSIVE TYPE FOR THE SHADOW STATE
100
- // A ShadowNode is either:
101
- // 1. An array of ItemMeta (if it represents a user's array).
102
- // 2. An object that can be indexed by any string, whose values are other ShadowNodes.
103
- export type ShadowNode = ItemMeta[] | { [key: string]: ShadowNode };
104
-
105
- // This is the top-level type for the store, mapping state keys to our ShadowNode structure.
106
- export type ShadowStateStore = {
107
- [key: string]: ShadowNode;
108
- };
109
-
110
100
  export type CogsGlobalState = {
111
101
  // --- Shadow State and Subscription System ---
112
- shadowStateStore: ShadowStateStore;
113
- shadowStateSubscribers: Map<string, Set<() => void>>;
114
- subscribeToShadowState: (key: string, callback: () => void) => () => void;
115
- initializeShadowState: <T>(key: string, initialState: T) => void;
116
- updateShadowAtPath: <T>(key: string, path: string[], newValue: T) => void;
102
+ shadowStateStore: Map<string, ShadowMetadata>;
103
+
104
+ // These method signatures stay the same
105
+ initializeShadowState: (key: string, initialState: any) => void;
106
+ updateShadowAtPath: (key: string, path: string[], newValue: any) => void;
117
107
  insertShadowArrayElement: (
118
108
  key: string,
119
109
  arrayPath: string[],
120
- newItemMeta: ItemMeta
110
+ newItem: any
121
111
  ) => void;
122
- removeShadowArrayElement: (
112
+ removeShadowArrayElement: (key: string, arrayPath: string[]) => void;
113
+ getShadowMetadata: (
123
114
  key: string,
124
- arrayPath: string[],
125
- index: number
126
- ) => void;
127
- getShadowMetadata: (key: string, path: string[]) => ShadowNode | null;
115
+ path: string[]
116
+ ) => ShadowMetadata | undefined;
128
117
  setShadowMetadata: (
129
118
  key: string,
130
119
  path: string[],
131
- metadata: Partial<ItemMeta>
120
+ metadata: Omit<ShadowMetadata, "id">
132
121
  ) => void;
133
- // --- Selected Item State ---
122
+
123
+ shadowStateSubscribers: Map<string, Set<() => void>>; // Stores subscribers for shadow state updates
124
+ subscribeToShadowState: (key: string, callback: () => void) => () => void;
125
+
134
126
  selectedIndicesMap: Map<string, Map<string, number>>; // stateKey -> (parentPath -> selectedIndex)
135
127
  getSelectedIndex: (
136
128
  stateKey: string,
@@ -253,192 +245,163 @@ export type CogsGlobalState = {
253
245
  };
254
246
 
255
247
  export const getGlobalStore = create<CogsGlobalState>((set, get) => ({
256
- shadowStateStore: {},
257
- getShadowMetadata: (key: string, path: string[]) => {
258
- const shadow = get().shadowStateStore[key];
259
- if (!shadow) return null;
260
-
261
- let current: any = shadow;
262
- for (const segment of path) {
263
- current = current?.[segment];
264
- if (!current) return null;
265
- }
248
+ shadowStateStore: new Map(),
249
+ shadowStateSubscribers: new Map(),
266
250
 
267
- return current;
268
- },
251
+ subscribeToShadowState: (key: string, callback: () => void) => {
252
+ set((state) => {
253
+ const newSubs = new Map(state.shadowStateSubscribers);
254
+ const subsForKey = newSubs.get(key) || new Set();
255
+ subsForKey.add(callback);
256
+ newSubs.set(key, subsForKey);
257
+ return { shadowStateSubscribers: newSubs };
258
+ });
269
259
 
270
- initializeShadowState: (key: string, initialState: any) => {
271
- const createShadowStructure = (obj: any): any => {
272
- if (Array.isArray(obj)) {
273
- return new Array(obj.length)
274
- .fill(null)
275
- .map((_, i) => createShadowStructure(obj[i]));
276
- }
277
- if (typeof obj === "object" && obj !== null) {
278
- const shadow: any = {};
279
- for (const k in obj) {
280
- shadow[k] = createShadowStructure(obj[k]);
260
+ // Return unsubscribe function
261
+ return () => {
262
+ set((state) => {
263
+ const newSubs = new Map(state.shadowStateSubscribers);
264
+ const subsForKey = newSubs.get(key);
265
+ if (subsForKey) {
266
+ subsForKey.delete(callback);
267
+ if (subsForKey.size === 0) {
268
+ newSubs.delete(key);
269
+ }
281
270
  }
282
- return shadow;
283
- }
284
- return {}; // Leaf node - empty object for metadata
271
+ return { shadowStateSubscribers: newSubs };
272
+ });
285
273
  };
286
-
287
- set((state) => ({
288
- shadowStateStore: {
289
- ...state.shadowStateStore,
290
- [key]: createShadowStructure(initialState),
291
- },
292
- }));
293
274
  },
275
+ initializeShadowState: (key: string, initialState: any) => {
276
+ const newShadowStore = new Map<string, ShadowMetadata>();
294
277
 
295
- updateShadowAtPath: (key: string, path: string[], newValue: any) => {
296
- set((state) => {
297
- const newShadow = { ...state.shadowStateStore };
298
- if (!newShadow[key]) return state;
299
-
300
- let current: any = newShadow[key];
301
- const pathCopy = [...path];
302
- const lastSegment = pathCopy.pop();
303
-
304
- // Navigate to parent
305
- for (const segment of pathCopy) {
306
- if (!current[segment]) current[segment] = {};
307
- current = current[segment];
308
- }
278
+ const processValue = (value: any, path: string[]) => {
279
+ const nodeKey = [key, ...path].join(".");
309
280
 
310
- // Update shadow structure to match new value structure
311
- if (lastSegment !== undefined) {
312
- if (Array.isArray(newValue)) {
313
- current[lastSegment] = new Array(newValue.length);
314
- } else if (typeof newValue === "object" && newValue !== null) {
315
- current[lastSegment] = {};
316
- } else {
317
- current[lastSegment] = current[lastSegment] || {};
318
- }
319
- }
281
+ if (Array.isArray(value)) {
282
+ const childIds: string[] = [];
320
283
 
321
- return { shadowStateStore: newShadow };
322
- });
323
- },
284
+ value.forEach((item) => {
285
+ if (typeof item === "object" && item !== null && !item.id) {
286
+ item.id = ulid();
287
+ }
324
288
 
325
- insertShadowArrayElement: (
326
- key: string,
327
- arrayPath: string[],
328
- newItem: any
329
- ) => {
330
- set((state) => {
331
- const newShadow = { ...state.shadowStateStore };
332
- if (!newShadow[key]) return state;
289
+ const itemId = `id:${item.id}`;
290
+ childIds.push(itemId);
333
291
 
334
- newShadow[key] = JSON.parse(JSON.stringify(newShadow[key]));
292
+ const itemPath = [...path, itemId];
293
+ processValue(item, itemPath);
294
+ });
335
295
 
336
- let current: any = newShadow[key];
296
+ const arrayContainerMetadata: ShadowMetadata = {
297
+ id: ulid(),
298
+ arrayKeys: childIds,
299
+ };
300
+ newShadowStore.set(nodeKey, arrayContainerMetadata);
301
+ } else if (typeof value === "object" && value !== null) {
302
+ newShadowStore.set(nodeKey, { id: ulid() });
337
303
 
338
- for (const segment of arrayPath) {
339
- current = current[segment];
340
- if (!current) return state;
304
+ Object.keys(value).forEach((k) => {
305
+ processValue(value[k], [...path, k]);
306
+ });
307
+ } else {
308
+ newShadowStore.set(nodeKey, { id: ulid() });
341
309
  }
310
+ };
342
311
 
343
- if (Array.isArray(current)) {
344
- // Create shadow structure based on the actual new item
345
- const createShadowStructure = (obj: any): any => {
346
- if (Array.isArray(obj)) {
347
- return obj.map((item) => createShadowStructure(item));
348
- }
349
- if (typeof obj === "object" && obj !== null) {
350
- const shadow: any = {};
351
- for (const k in obj) {
352
- shadow[k] = createShadowStructure(obj[k]);
353
- }
354
- return shadow;
355
- }
356
- return {}; // Leaf nodes get empty object for metadata
357
- };
312
+ processValue(initialState, []);
358
313
 
359
- current.push(createShadowStructure(newItem));
360
- }
314
+ set({ shadowStateStore: newShadowStore });
315
+ },
316
+ getShadowMetadata: (key: string, path: string[]) => {
317
+ const fullKey = [key, ...path].join(".");
318
+ return get().shadowStateStore.get(fullKey);
319
+ },
361
320
 
362
- return { shadowStateStore: newShadow };
363
- });
321
+ setShadowMetadata: (key: string, path: string[], metadata: any) => {
322
+ const fullKey = [key, ...path].join(".");
323
+ const newShadowStore = new Map(get().shadowStateStore);
324
+ const existing = newShadowStore.get(fullKey) || { id: ulid() };
325
+ newShadowStore.set(fullKey, { ...existing, ...metadata });
326
+ set({ shadowStateStore: newShadowStore });
327
+
328
+ if (metadata.virtualizer?.itemHeight) {
329
+ const subscribers = get().shadowStateSubscribers.get(key);
330
+ subscribers?.forEach((cb) => cb());
331
+ }
364
332
  },
365
- removeShadowArrayElement: (
333
+
334
+ insertShadowArrayElement: (
366
335
  key: string,
367
336
  arrayPath: string[],
368
- index: number
337
+ newItem: any
369
338
  ) => {
370
- set((state) => {
371
- const newShadow = { ...state.shadowStateStore };
372
- let current: any = newShadow[key];
339
+ const newShadowStore = new Map(get().shadowStateStore);
340
+ const arrayKey = [key, ...arrayPath].join(".");
341
+ const parentMeta = newShadowStore.get(arrayKey);
342
+ const newArrayState = get().getNestedState(key, arrayPath) as any[];
373
343
 
374
- for (const segment of arrayPath) {
375
- current = current?.[segment];
376
- }
344
+ if (!parentMeta || !parentMeta.arrayKeys) return;
377
345
 
378
- if (Array.isArray(current)) {
379
- current.splice(index, 1);
380
- }
346
+ const newItemId = `id:${newItem.id}`;
347
+ const newIndex = newArrayState.findIndex((item) => item.id === newItem.id);
381
348
 
382
- return { shadowStateStore: newShadow };
383
- });
384
- },
385
- shadowStateSubscribers: new Map<string, Set<() => void>>(), // key -> Set of callbacks
349
+ if (newIndex === -1) return;
386
350
 
387
- subscribeToShadowState: (key: string, callback: () => void) => {
388
- set((state) => {
389
- const newSubs = new Map(state.shadowStateSubscribers);
390
- const subsForKey = newSubs.get(key) || new Set();
391
- subsForKey.add(callback);
392
- newSubs.set(key, subsForKey);
393
- return { shadowStateSubscribers: newSubs };
394
- });
395
- // Return an unsubscribe function
396
- return () => {
397
- set((state) => {
398
- const newSubs = new Map(state.shadowStateSubscribers);
399
- const subsForKey = newSubs.get(key);
400
- if (subsForKey) {
401
- subsForKey.delete(callback);
402
- }
403
- return { shadowStateSubscribers: newSubs };
404
- });
405
- };
406
- },
351
+ const newArrayKeys = [...parentMeta.arrayKeys];
352
+ newArrayKeys.splice(newIndex, 0, newItemId);
353
+ newShadowStore.set(arrayKey, { ...parentMeta, arrayKeys: newArrayKeys });
407
354
 
408
- setShadowMetadata: (key: string, path: string[], metadata: any) => {
409
- let hasChanged = false;
410
- set((state) => {
411
- const newShadow = { ...state.shadowStateStore };
412
- if (!newShadow[key]) return state;
355
+ const processNewItem = (value: any, path: string[]) => {
356
+ const nodeKey = [key, ...path].join(".");
357
+ if (typeof value === "object" && value !== null) {
358
+ newShadowStore.set(nodeKey, { id: ulid() });
359
+ Object.keys(value).forEach((k) => {
360
+ processNewItem(value[k], [...path, k]);
361
+ });
362
+ } else {
363
+ newShadowStore.set(nodeKey, { id: ulid() });
364
+ }
365
+ };
413
366
 
414
- newShadow[key] = JSON.parse(JSON.stringify(newShadow[key]));
367
+ processNewItem(newItem, [...arrayPath, newItemId]);
415
368
 
416
- let current: any = newShadow[key];
417
- for (const segment of path) {
418
- if (!current[segment]) current[segment] = {};
419
- current = current[segment];
420
- }
369
+ set({ shadowStateStore: newShadowStore });
370
+ },
421
371
 
422
- const oldHeight = current.virtualizer?.itemHeight;
423
- const newHeight = metadata.virtualizer?.itemHeight;
372
+ removeShadowArrayElement: (key: string, itemPath: string[]) => {
373
+ const newShadowStore = new Map(get().shadowStateStore);
374
+ const itemKey = [key, ...itemPath].join(".");
375
+ const itemIdToRemove = itemPath[itemPath.length - 1];
424
376
 
425
- if (newHeight && oldHeight !== newHeight) {
426
- hasChanged = true;
427
- if (!current.virtualizer) current.virtualizer = {};
428
- current.virtualizer.itemHeight = newHeight;
429
- }
377
+ const parentPath = itemPath.slice(0, -1);
378
+ const parentKey = [key, ...parentPath].join(".");
379
+ const parentMeta = newShadowStore.get(parentKey);
430
380
 
431
- return { shadowStateStore: newShadow };
432
- });
381
+ if (parentMeta && parentMeta.arrayKeys) {
382
+ const newArrayKeys = parentMeta.arrayKeys.filter(
383
+ (id) => id !== itemIdToRemove
384
+ );
385
+ newShadowStore.set(parentKey, { ...parentMeta, arrayKeys: newArrayKeys });
386
+ }
433
387
 
434
- // If a height value was actually changed, notify the specific subscribers.
435
- if (hasChanged) {
436
- const subscribers = get().shadowStateSubscribers.get(key);
437
- if (subscribers) {
438
- subscribers.forEach((callback) => callback());
388
+ const prefixToDelete = itemKey + ".";
389
+ for (const k of Array.from(newShadowStore.keys())) {
390
+ if (k === itemKey || k.startsWith(prefixToDelete)) {
391
+ newShadowStore.delete(k);
439
392
  }
440
393
  }
394
+
395
+ set({ shadowStateStore: newShadowStore });
396
+ },
397
+ updateShadowAtPath: (key: string, path: string[], newValue: any) => {
398
+ const fullKey = [key, ...path].join(".");
399
+ const newShadowStore = new Map(get().shadowStateStore);
400
+ const existing = newShadowStore.get(fullKey) || { id: ulid() };
401
+ newShadowStore.set(fullKey, { ...existing, lastUpdated: Date.now() });
402
+ set({ shadowStateStore: newShadowStore });
441
403
  },
404
+
442
405
  selectedIndicesMap: new Map<string, Map<string, number>>(),
443
406
 
444
407
  // Add the new methods
@@ -745,41 +708,44 @@ export const getGlobalStore = create<CogsGlobalState>((set, get) => ({
745
708
  getNestedState: (key: string, path: string[]) => {
746
709
  const rootState = get().cogsStateStore[key];
747
710
 
748
- const getValueWithAsterisk = (obj: any, pathArray: string[]): any => {
749
- if (pathArray.length === 0) return obj;
711
+ const resolvePath = (obj: any, pathArray: string[]): any => {
712
+ if (pathArray.length === 0 || obj === undefined) {
713
+ return obj;
714
+ }
750
715
 
751
- const currentPath = pathArray[0];
716
+ const currentSegment = pathArray[0];
752
717
  const remainingPath = pathArray.slice(1);
753
718
 
754
- if (currentPath === "[*]") {
719
+ // FIX: Handle ID-based array access like 'id:xyz'
720
+ if (
721
+ Array.isArray(obj) &&
722
+ typeof currentSegment === "string" &&
723
+ currentSegment.startsWith("id:")
724
+ ) {
725
+ const targetId = currentSegment.split(":")[1];
726
+ const foundItem = obj.find(
727
+ (item) => item && String(item.id) === targetId
728
+ );
729
+ return resolvePath(foundItem, remainingPath);
730
+ }
731
+
732
+ // Handle wildcard array access: '[*]'
733
+ if (currentSegment === "[*]") {
755
734
  if (!Array.isArray(obj)) {
756
735
  console.warn("Asterisk notation used on non-array value");
757
736
  return undefined;
758
737
  }
759
-
760
738
  if (remainingPath.length === 0) return obj;
761
-
762
- // Get result for each array item
763
- const results = obj.map((item) =>
764
- getValueWithAsterisk(item, remainingPath)
765
- );
766
-
767
- // If the next path segment exists and returns arrays, flatten them
768
- if (Array.isArray(results[0])) {
769
- return results.flat();
770
- }
771
-
772
- return results;
739
+ const results = obj.map((item) => resolvePath(item, remainingPath));
740
+ return Array.isArray(results[0]) ? results.flat() : results;
773
741
  }
774
742
 
775
- const value = obj[currentPath as keyof typeof obj];
776
- if (value === undefined) return undefined;
777
-
778
- return getValueWithAsterisk(value, remainingPath);
743
+ // Handle standard object property access and numeric array indices
744
+ const nextObj = obj[currentSegment as keyof typeof obj];
745
+ return resolvePath(nextObj, remainingPath);
779
746
  };
780
747
 
781
- // This will still get the value but we need to make it reactive only to specific paths
782
- return getValueWithAsterisk(rootState, path);
748
+ return resolvePath(rootState, path);
783
749
  },
784
750
  setInitialStateOptions: (key, value) => {
785
751
  set((prev) => ({