cogsbox-state 0.5.426 → 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.
@@ -1,203 +1,201 @@
1
- import { jsx as V, Fragment as M } from "react/jsx-runtime";
1
+ import { jsx as V, Fragment as C } from "react/jsx-runtime";
2
2
  import "./CogsState.jsx";
3
- import { getNestedValue as N, isFunction as O, updateNestedProperty as T } from "./utility.js";
4
- import I, { useRef as b, useState as U, useEffect as R } from "react";
5
- import { getGlobalStore as m, formRefStore as L } from "./store.js";
6
- import { validateZodPathFunc as W } from "./useValidateZodPath.js";
7
- function j(r, e, t, n) {
8
- r(
9
- (o) => {
10
- if (O(e)) {
11
- const u = e(N(o, t));
12
- let i = T(t, o, u);
13
- return typeof i == "string" && (i = i.trim()), i;
3
+ import { isFunction as G, getNestedValue as R, updateNestedPropertyIds as w } from "./utility.js";
4
+ import k, { useRef as b, useState as D, useEffect as T } from "react";
5
+ import { getGlobalStore as m, formRefStore as x } from "./store.js";
6
+ import { validateZodPathFunc as K } from "./useValidateZodPath.js";
7
+ import { ulid as L } from "ulid";
8
+ function F(n, e, t, r) {
9
+ n(
10
+ (i) => {
11
+ if (G(e)) {
12
+ const s = e(R(i, t));
13
+ console.group("nestedValue", t, s);
14
+ let o = w(t, i, s);
15
+ return console.group("updateFn", o), typeof o == "string" && (o = o.trim()), o;
14
16
  } else {
15
- let u = !t || t.length == 0 ? e : T(t, o, e);
16
- return typeof u == "string" && (u = u.trim()), u;
17
+ let s = !t || t.length == 0 ? e : w(t, i, e);
18
+ return typeof s == "string" && (s = s.trim()), s;
17
19
  }
18
20
  },
19
21
  t,
20
22
  { updateType: "update" },
21
- n
23
+ r
22
24
  );
23
25
  }
24
- function p(r, e, t, n, o) {
25
- const u = m.getState().getNestedState(n, t);
26
- r(
27
- (i) => {
28
- let c = !t || t.length == 0 ? i : N(i, [...t]), s = [...c];
29
- return s.splice(
30
- Number(o) == 0 ? o : c.length,
31
- 0,
32
- O(e) ? e(c) : e
33
- ), t.length == 0 ? s : T([...t], i, s);
26
+ function te(n, e, t, r, i) {
27
+ const s = m.getState().getNestedState(r, t) || [], o = G(e) ? e(s) : e;
28
+ typeof o == "object" && o !== null && !o.id && (o.id = L());
29
+ const f = o.id;
30
+ n(
31
+ (c) => {
32
+ const u = [...R(c, [...t]) || []];
33
+ return u.splice(u.length, 0, o), w([...t], c, u);
34
34
  },
35
- [
36
- ...t,
37
- (u.length - 1).toString()
38
- ],
35
+ [...t, `id:${f}`],
36
+ // Now we use the ID that is guaranteed to be correct.
39
37
  {
40
38
  updateType: "insert"
41
39
  }
42
40
  );
43
41
  }
44
- function ee(r, e, t, n) {
45
- const o = m.getState().getNestedState(t, e);
46
- r(
47
- (u) => {
48
- const i = N(u, [...e]);
49
- if (n < 0 || n >= i?.length)
50
- throw new Error(`Index ${n} does not exist in the array.`);
51
- const c = n || Number(n) == 0 ? n : i.length - 1, s = [
52
- ...i.slice(0, c),
53
- ...i.slice(c + 1)
42
+ function ne(n, e, t, r) {
43
+ const i = [t, ...e].join("."), o = m.getState().shadowStateStore.get(i)?.arrayKeys?.[r];
44
+ if (!o)
45
+ throw new Error(`No ID found for index ${r} in array`);
46
+ n(
47
+ (f) => {
48
+ const c = R(f, [...e]);
49
+ if (r < 0 || r >= c?.length)
50
+ throw new Error(`Index ${r} does not exist in the array.`);
51
+ const d = [
52
+ ...c.slice(0, r),
53
+ ...c.slice(r + 1)
54
54
  ];
55
- return e.length == 0 ? s : T([...e], u, s);
55
+ return e.length == 0 ? d : w([...e], f, d);
56
56
  },
57
- [
58
- ...e,
59
- n || n === 0 ? n?.toString() : (o.length - 1).toString()
60
- ],
57
+ [...e, o],
58
+ // Use the ID here!
61
59
  { updateType: "cut" }
62
60
  );
63
61
  }
64
- const w = (r, e, t = (n, o) => JSON.stringify(n) === JSON.stringify(o)) => {
65
- const [n, o] = U(
66
- () => e(m.getState(), r)
67
- ), u = b(n), i = b(r);
68
- return R(() => {
69
- i.current = r, o(e(m.getState(), r));
70
- const c = (f) => {
71
- const g = e(f, i.current);
72
- t(u.current, g) || (u.current = g, o(g));
73
- }, s = m.subscribe(c);
62
+ const I = (n, e, t = (r, i) => JSON.stringify(r) === JSON.stringify(i)) => {
63
+ const [r, i] = D(
64
+ () => e(m.getState(), n)
65
+ ), s = b(r), o = b(n);
66
+ return T(() => {
67
+ o.current = n, i(e(m.getState(), n));
68
+ const f = (d) => {
69
+ const u = e(d, o.current);
70
+ t(s.current, u) || (s.current = u, i(u));
71
+ }, c = m.subscribe(f);
74
72
  return () => {
75
- s();
73
+ c();
76
74
  };
77
- }, [r]), n;
78
- }, Z = (r, e, t) => {
79
- const n = r + "." + (e.length > 0 ? [e.join(".")] : []) + (t && t.length > 0 ? "." + t : "");
80
- return w(
81
- n,
82
- (u, i) => u.getValidationErrors(i) || []
75
+ }, [n]), r;
76
+ }, W = (n, e, t) => {
77
+ const r = n + "." + (e.length > 0 ? [e.join(".")] : []) + (t && t.length > 0 ? "." + t : "");
78
+ return I(
79
+ r,
80
+ (s, o) => s.getValidationErrors(o) || []
83
81
  );
84
- }, q = (r, e) => {
85
- const t = `${r}:${e.join(".")}`;
86
- return w(
82
+ }, Z = (n, e) => {
83
+ const t = `${n}:${e.join(".")}`;
84
+ return I(
87
85
  t,
88
- (n, o) => n.getSyncInfo(o)
86
+ (r, i) => r.getSyncInfo(i)
89
87
  );
90
- }, H = (r, e) => w(
91
- `${r}:${e.join(".")}`,
92
- (t, n) => t.getNestedState(r, e)
93
- ), te = ({
94
- setState: r,
88
+ }, p = (n, e) => I(
89
+ `${n}:${e.join(".")}`,
90
+ (t, r) => t.getNestedState(n, e)
91
+ ), re = ({
92
+ setState: n,
95
93
  // This is the real effectiveSetState from the hook
96
94
  path: e,
97
95
  child: t,
98
- formOpts: n,
99
- stateKey: o
96
+ formOpts: r,
97
+ stateKey: i
100
98
  }) => {
101
- const { registerFormRef: u, getFormRef: i } = L.getState(), {
102
- getValidationErrors: c,
103
- addValidationError: s,
104
- getInitialOptions: f,
105
- removeValidationError: g
106
- } = m.getState(), C = o + "." + e.join("."), $ = b(null), k = i(C);
107
- k || u(C, $);
108
- const z = k || $, v = H(o, e), [E, B] = U(v), S = b(!1), l = b(null);
109
- R(() => {
110
- !S.current && v !== E && B(v);
111
- }, [v]), R(() => () => {
112
- l.current && (clearTimeout(l.current), l.current = null, S.current = !1);
99
+ const { registerFormRef: s, getFormRef: o } = x.getState(), {
100
+ getValidationErrors: f,
101
+ addValidationError: c,
102
+ getInitialOptions: d,
103
+ removeValidationError: u
104
+ } = m.getState(), N = i + "." + e.join("."), $ = b(null), B = o(N);
105
+ B || s(N, $);
106
+ const O = B || $, y = p(i, e), [E, M] = D(y), S = b(!1), a = b(null);
107
+ T(() => {
108
+ !S.current && y !== E && M(y);
109
+ }, [y]), T(() => () => {
110
+ a.current && (clearTimeout(a.current), a.current = null, S.current = !1);
113
111
  }, []);
114
- const G = (a) => {
115
- if (B(a), S.current = !0, a === "") {
116
- l.current && (clearTimeout(l.current), l.current = null), j(r, a, e, d), S.current = !1;
112
+ const U = (l) => {
113
+ if (M(l), S.current = !0, l === "") {
114
+ a.current && (clearTimeout(a.current), a.current = null), F(n, l, e, g), S.current = !1;
117
115
  return;
118
116
  }
119
- l.current && clearTimeout(l.current), l.current = setTimeout(
117
+ a.current && clearTimeout(a.current), a.current = setTimeout(
120
118
  () => {
121
- S.current = !1, j(r, a, e, d);
119
+ S.current = !1, F(n, l, e, g);
122
120
  },
123
- n?.debounceTime ?? (typeof v == "boolean" ? 20 : 200)
121
+ r?.debounceTime ?? (typeof y == "boolean" ? 20 : 200)
124
122
  );
125
- }, y = f(o);
126
- if (!y?.validation?.key)
123
+ }, v = d(i);
124
+ if (!v?.validation?.key)
127
125
  throw new Error("Validation key not found.");
128
- const d = y.validation.key, A = y.validation.onBlur === !0, D = async () => {
129
- if (l.current && (clearTimeout(l.current), l.current = null, S.current = !1, j(r, E, e, d)), !(!y.validation?.zodSchema || !A)) {
130
- g(d + "." + e.join("."));
126
+ const g = v.validation.key, z = v.validation.onBlur === !0, A = async () => {
127
+ if (a.current && (clearTimeout(a.current), a.current = null, S.current = !1, F(n, E, e, g)), !(!v.validation?.zodSchema || !z)) {
128
+ u(g + "." + e.join("."));
131
129
  try {
132
- const a = m.getState().getNestedState(o, e);
133
- await W(
134
- d,
135
- y.validation.zodSchema,
130
+ const l = m.getState().getNestedState(i, e);
131
+ await K(
132
+ g,
133
+ v.validation.zodSchema,
136
134
  e,
137
- a
135
+ l
138
136
  );
139
- } catch (a) {
140
- console.error("Validation error on blur:", a);
137
+ } catch (l) {
138
+ console.error("Validation error on blur:", l);
141
139
  }
142
140
  }
143
- }, F = q(o, e), J = F ? { ...F, date: new Date(F.timeStamp) } : null, P = t({
141
+ }, j = Z(i, e), J = j ? { ...j, date: new Date(j.timeStamp) } : null, P = t({
144
142
  // --- START CHANGES ---
145
143
  get: () => E,
146
144
  // Get should return the immediate local value
147
- set: G,
145
+ set: U,
148
146
  // Use the new debounced updater
149
147
  // --- END CHANGES ---
150
148
  syncStatus: J,
151
149
  path: e,
152
- validationErrors: () => c(d + "." + e.join(".")),
153
- addValidationError: (a) => {
154
- g(d + "." + e.join(".")), s(d + "." + e.join("."), a ?? "");
150
+ validationErrors: () => f(g + "." + e.join(".")),
151
+ addValidationError: (l) => {
152
+ u(g + "." + e.join(".")), c(g + "." + e.join("."), l ?? "");
155
153
  },
156
154
  inputProps: {
157
155
  // --- START CHANGES ---
158
156
  value: E ?? "",
159
157
  // Input value is always the local state
160
- onChange: (a) => G(a.target.value),
158
+ onChange: (l) => U(l.target.value),
161
159
  // Use debounced updater
162
160
  // --- END CHANGES ---
163
- onBlur: D,
164
- ref: z
161
+ onBlur: A,
162
+ ref: O
165
163
  }
166
164
  });
167
- return /* @__PURE__ */ V(M, { children: /* @__PURE__ */ V(Q, { formOpts: n, path: e, stateKey: o, children: P }) });
165
+ return /* @__PURE__ */ V(C, { children: /* @__PURE__ */ V(q, { formOpts: r, path: e, stateKey: i, children: P }) });
168
166
  };
169
- function Q({
170
- formOpts: r,
167
+ function q({
168
+ formOpts: n,
171
169
  path: e,
172
170
  stateKey: t,
173
- children: n,
174
- validIndices: o
171
+ children: r,
172
+ validIndices: i
175
173
  }) {
176
- const { getInitialOptions: u } = m.getState(), i = u(t), c = i?.validation?.key ?? t, s = Z(
177
- c,
174
+ const { getInitialOptions: s } = m.getState(), o = s(t), f = o?.validation?.key ?? t, c = W(
175
+ f,
178
176
  e,
179
- o
180
- ), f = [];
181
- if (s) {
182
- const g = s.join(", ");
183
- f.includes(g) || f.push(g);
177
+ i
178
+ ), d = [];
179
+ if (c) {
180
+ const u = c.join(", ");
181
+ d.includes(u) || d.push(u);
184
182
  }
185
- return /* @__PURE__ */ V(M, { children: i?.formElements?.validation && !r?.validation?.disable ? i.formElements.validation({
186
- children: /* @__PURE__ */ V(I.Fragment, { children: n }, e.toString()),
187
- active: s.length > 0,
188
- message: r?.validation?.hideMessage ? "" : r?.validation?.message ? r?.validation?.message : f.map((g) => g).join(", "),
183
+ return /* @__PURE__ */ V(C, { children: o?.formElements?.validation && !n?.validation?.disable ? o.formElements.validation({
184
+ children: /* @__PURE__ */ V(k.Fragment, { children: r }, e.toString()),
185
+ active: c.length > 0,
186
+ message: n?.validation?.hideMessage ? "" : n?.validation?.message ? n?.validation?.message : d.map((u) => u).join(", "),
189
187
  path: e
190
- }) : /* @__PURE__ */ V(I.Fragment, { children: n }, e.toString()) });
188
+ }) : /* @__PURE__ */ V(k.Fragment, { children: r }, e.toString()) });
191
189
  }
192
190
  export {
193
- te as FormControlComponent,
194
- Q as ValidationWrapper,
195
- ee as cutFunc,
196
- p as pushFunc,
197
- j as updateFn,
198
- H as useGetKeyState,
199
- q as useGetSyncInfo,
200
- Z as useGetValidationErrors,
201
- w as useStoreSubscription
191
+ re as FormControlComponent,
192
+ q as ValidationWrapper,
193
+ ne as cutFunc,
194
+ te as pushFunc,
195
+ F as updateFn,
196
+ p as useGetKeyState,
197
+ Z as useGetSyncInfo,
198
+ W as useGetValidationErrors,
199
+ I as useStoreSubscription
202
200
  };
203
201
  //# sourceMappingURL=Functions.jsx.map
@@ -1 +1 @@
1
- {"version":3,"file":"Functions.jsx","sources":["../src/Functions.tsx"],"sourcesContent":["import {\r\n notifyComponent,\r\n type EffectiveSetState,\r\n type FormElementParams,\r\n type FormOptsType,\r\n type UpdateArg,\r\n type UpdateOpts,\r\n} from \"./CogsState\";\r\n\r\nimport { getNestedValue, isFunction, updateNestedProperty } from \"./utility\";\r\nimport { useEffect, useRef, useState } from \"react\";\r\nimport React from \"react\";\r\nimport { getGlobalStore, formRefStore } from \"./store\";\r\nimport { validateZodPathFunc } from \"./useValidateZodPath\";\r\n\r\nexport function updateFn<U>(\r\n setState: EffectiveSetState<U>,\r\n payload: UpdateArg<U>,\r\n path: string[],\r\n validationKey?: string\r\n): void {\r\n setState(\r\n (prevState) => {\r\n if (isFunction<U>(payload)) {\r\n const nestedValue = payload(getNestedValue(prevState, path));\r\n let value = updateNestedProperty(path, prevState, nestedValue);\r\n if (typeof value == \"string\") {\r\n value = value.trim();\r\n }\r\n return value;\r\n } else {\r\n let value =\r\n !path || path.length == 0\r\n ? payload\r\n : updateNestedProperty(path, prevState, payload);\r\n if (typeof value == \"string\") {\r\n value = value.trim();\r\n }\r\n return value;\r\n }\r\n },\r\n path,\r\n { updateType: \"update\" },\r\n validationKey\r\n );\r\n}\r\n\r\nexport function pushFunc<U>(\r\n setState: EffectiveSetState<U>,\r\n payload: UpdateArg<U>,\r\n path: string[],\r\n stateKey: string,\r\n index?: number\r\n): void {\r\n const array = getGlobalStore.getState().getNestedState(stateKey, path) as U[];\r\n setState(\r\n (prevState) => {\r\n let arrayToUpdate =\r\n !path || path.length == 0\r\n ? prevState\r\n : getNestedValue(prevState, [...path]);\r\n let returnedArray = [...arrayToUpdate];\r\n\r\n returnedArray.splice(\r\n index || Number(index) == 0 ? index : arrayToUpdate.length,\r\n 0,\r\n isFunction<U>(payload)\r\n ? payload(index == -1 ? undefined : arrayToUpdate)\r\n : payload\r\n );\r\n const value =\r\n path.length == 0\r\n ? returnedArray\r\n : updateNestedProperty([...path], prevState, returnedArray);\r\n\r\n return value as U;\r\n },\r\n [\r\n ...path,\r\n index || index === 0 ? index?.toString() : (array!.length - 1).toString(),\r\n ],\r\n {\r\n updateType: \"insert\",\r\n }\r\n );\r\n}\r\n\r\nexport function cutFunc<U>(\r\n setState: EffectiveSetState<U>,\r\n path: string[],\r\n stateKey: string,\r\n index: number\r\n): void {\r\n const array = getGlobalStore.getState().getNestedState(stateKey, path) as U[];\r\n setState(\r\n (prevState) => {\r\n const arrayToUpdate = getNestedValue(prevState, [...path]);\r\n if (index < 0 || index >= arrayToUpdate?.length) {\r\n throw new Error(`Index ${index} does not exist in the array.`);\r\n }\r\n const indexToCut =\r\n index || Number(index) == 0 ? index : arrayToUpdate.length - 1;\r\n\r\n const updatedArray = [\r\n ...arrayToUpdate.slice(0, indexToCut),\r\n ...arrayToUpdate.slice(indexToCut + 1),\r\n ] as U;\r\n\r\n return path.length == 0\r\n ? updatedArray\r\n : updateNestedProperty([...path], prevState, updatedArray);\r\n },\r\n [\r\n ...path,\r\n index || index === 0 ? index?.toString() : (array!.length - 1).toString(),\r\n ],\r\n { updateType: \"cut\" }\r\n );\r\n}\r\n\r\nexport const useStoreSubscription = <T,>(\r\n fullPath: string,\r\n selector: (\r\n store: ReturnType<typeof getGlobalStore.getState>,\r\n path: string\r\n ) => T,\r\n compare: (a: T, b: T) => boolean = (a, b) =>\r\n JSON.stringify(a) === JSON.stringify(b)\r\n) => {\r\n const [value, setValue] = useState<T>(() =>\r\n selector(getGlobalStore.getState(), fullPath)\r\n );\r\n const previousValueRef = useRef<T>(value);\r\n const fullPathRef = useRef(fullPath);\r\n useEffect(() => {\r\n fullPathRef.current = fullPath; // Ensure latest fullPath is always used\r\n\r\n setValue(selector(getGlobalStore.getState(), fullPath));\r\n\r\n const callback = (store: any) => {\r\n const newValue = selector(store, fullPathRef.current);\r\n\r\n if (!compare(previousValueRef.current, newValue)) {\r\n previousValueRef.current = newValue;\r\n setValue(newValue);\r\n }\r\n };\r\n const unsubscribe = getGlobalStore.subscribe(callback);\r\n return () => {\r\n unsubscribe();\r\n };\r\n }, [fullPath]);\r\n return value;\r\n};\r\nexport const useGetValidationErrors = (\r\n validationKey: string,\r\n path: string[],\r\n validIndices?: number[]\r\n) => {\r\n const fullPath =\r\n validationKey +\r\n \".\" +\r\n (path.length > 0 ? [path.join(\".\")] : []) +\r\n (validIndices && validIndices.length > 0 ? \".\" + validIndices : \"\");\r\n\r\n const returnresult = useStoreSubscription(\r\n fullPath,\r\n (store, path) => store.getValidationErrors(path) || []\r\n );\r\n\r\n return returnresult;\r\n};\r\n\r\nexport const useGetSyncInfo = (key: string, path: string[]) => {\r\n const syncKey = `${key}:${path.join(\".\")}`;\r\n return useStoreSubscription(syncKey, (store, path) =>\r\n store.getSyncInfo(path)\r\n );\r\n};\r\nexport const useGetKeyState = (key: string, path: string[]) => {\r\n return useStoreSubscription(`${key}:${path.join(\".\")}`, (store, fullPath) =>\r\n store.getNestedState(key, path)\r\n );\r\n};\r\ninterface FormControlComponentProps<TStateObject> {\r\n setState: EffectiveSetState<TStateObject>;\r\n\r\n path: string[];\r\n child: (obj: FormElementParams<TStateObject>) => JSX.Element;\r\n formOpts?: FormOptsType;\r\n stateKey: string;\r\n}\r\n// Find FormControlComponent in your Functions.ts or equivalent file\r\n\r\nexport const FormControlComponent = <TStateObject,>({\r\n setState, // This is the real effectiveSetState from the hook\r\n path,\r\n child,\r\n formOpts,\r\n stateKey,\r\n}: FormControlComponentProps<TStateObject>) => {\r\n const { registerFormRef, getFormRef } = formRefStore.getState();\r\n const {\r\n getValidationErrors,\r\n addValidationError,\r\n getInitialOptions,\r\n removeValidationError,\r\n } = getGlobalStore.getState();\r\n\r\n const refKey = stateKey + \".\" + path.join(\".\");\r\n const localFormRef = useRef<HTMLInputElement>(null);\r\n const existingRef = getFormRef(refKey);\r\n if (!existingRef) {\r\n registerFormRef(refKey, localFormRef);\r\n }\r\n const formRef = existingRef || localFormRef;\r\n\r\n // --- START CHANGES ---\r\n\r\n const globalStateValue = useGetKeyState(stateKey, path);\r\n const [localValue, setLocalValue] = useState<any>(globalStateValue);\r\n const isCurrentlyDebouncing = useRef(false);\r\n const debounceTimeoutRef = useRef<NodeJS.Timeout | null>(null);\r\n\r\n // Effect to sync local state if global state changes externally\r\n useEffect(() => {\r\n // Only update local if not actively debouncing a local change\r\n if (!isCurrentlyDebouncing.current && globalStateValue !== localValue) {\r\n setLocalValue(globalStateValue);\r\n }\r\n }, [globalStateValue]); // Removed localValue dependency\r\n\r\n // Effect for cleanup\r\n useEffect(() => {\r\n return () => {\r\n if (debounceTimeoutRef.current) {\r\n clearTimeout(debounceTimeoutRef.current);\r\n debounceTimeoutRef.current = null; // Explicitly nullify\r\n isCurrentlyDebouncing.current = false;\r\n }\r\n };\r\n }, []);\r\n\r\n const debouncedUpdater = (payload: UpdateArg<TStateObject>) => {\r\n setLocalValue(payload); // Update local state immediately\r\n isCurrentlyDebouncing.current = true;\r\n\r\n if (payload === \"\") {\r\n if (debounceTimeoutRef.current) {\r\n clearTimeout(debounceTimeoutRef.current); // Clear pending timer\r\n debounceTimeoutRef.current = null;\r\n }\r\n updateFn(setState, payload, path, validationKey); // Update global state NOW\r\n isCurrentlyDebouncing.current = false; // No longer debouncing\r\n return; // Don't proceed to set another timeout\r\n }\r\n\r\n // If not empty, proceed with normal debouncing\r\n if (debounceTimeoutRef.current) {\r\n clearTimeout(debounceTimeoutRef.current);\r\n }\r\n\r\n debounceTimeoutRef.current = setTimeout(\r\n () => {\r\n isCurrentlyDebouncing.current = false;\r\n updateFn(setState, payload, path, validationKey);\r\n },\r\n formOpts?.debounceTime ??\r\n (typeof globalStateValue == \"boolean\" ? 20 : 200)\r\n );\r\n };\r\n\r\n const initialOptions = getInitialOptions(stateKey);\r\n if (!initialOptions?.validation?.key) {\r\n throw new Error(\"Validation key not found.\");\r\n }\r\n const validationKey = initialOptions.validation.key;\r\n const validateOnBlur = initialOptions.validation.onBlur === true;\r\n\r\n const handleBlur = async () => {\r\n // --- Ensure latest value is flushed if debouncing ---\r\n if (debounceTimeoutRef.current) {\r\n clearTimeout(debounceTimeoutRef.current); // Clear pending timer\r\n debounceTimeoutRef.current = null;\r\n isCurrentlyDebouncing.current = false;\r\n // Ensure the absolute latest local value is committed on blur\r\n updateFn(setState, localValue, path, validationKey);\r\n }\r\n // --- End modification ---\r\n\r\n if (!initialOptions.validation?.zodSchema || !validateOnBlur) return;\r\n removeValidationError(validationKey + \".\" + path.join(\".\"));\r\n try {\r\n // Use the potentially just flushed value\r\n const fieldValue = getGlobalStore\r\n .getState()\r\n .getNestedState(stateKey, path);\r\n await validateZodPathFunc(\r\n validationKey,\r\n initialOptions.validation.zodSchema,\r\n path,\r\n fieldValue\r\n );\r\n // forceUpdate might be needed if validation state update doesn't trigger render\r\n // Consider using useGetValidationErrors hook result directly for validation display\r\n } catch (error) {\r\n console.error(\"Validation error on blur:\", error);\r\n }\r\n };\r\n\r\n const rawSyncStatus = useGetSyncInfo(stateKey, path);\r\n const syncStatus = rawSyncStatus\r\n ? { ...rawSyncStatus, date: new Date(rawSyncStatus.timeStamp) }\r\n : null;\r\n\r\n const childElement = child({\r\n // --- START CHANGES ---\r\n get: () => localValue, // Get should return the immediate local value\r\n set: debouncedUpdater, // Use the new debounced updater\r\n // --- END CHANGES ---\r\n syncStatus,\r\n path: path,\r\n validationErrors: () =>\r\n getValidationErrors(validationKey + \".\" + path.join(\".\")),\r\n addValidationError: (message?: string) => {\r\n removeValidationError(validationKey + \".\" + path.join(\".\"));\r\n addValidationError(validationKey + \".\" + path.join(\".\"), message ?? \"\");\r\n },\r\n inputProps: {\r\n // --- START CHANGES ---\r\n value: localValue ?? \"\", // Input value is always the local state\r\n onChange: (e: any) => debouncedUpdater(e.target.value), // Use debounced updater\r\n // --- END CHANGES ---\r\n onBlur: handleBlur,\r\n ref: formRef,\r\n },\r\n });\r\n\r\n return (\r\n <>\r\n <ValidationWrapper {...{ formOpts, path, stateKey }}>\r\n {childElement}\r\n </ValidationWrapper>\r\n </>\r\n );\r\n};\r\nexport type ValidationWrapperProps = {\r\n formOpts?: FormOptsType;\r\n path: string[];\r\n stateKey: string;\r\n children: React.ReactNode;\r\n validIndices?: number[];\r\n};\r\nexport function ValidationWrapper({\r\n formOpts,\r\n path,\r\n\r\n stateKey,\r\n children,\r\n validIndices,\r\n}: ValidationWrapperProps) {\r\n const { getInitialOptions } = getGlobalStore.getState();\r\n const thisStateOpts = getInitialOptions(stateKey!);\r\n const validationKey = thisStateOpts?.validation?.key ?? stateKey!;\r\n const validationErrors = useGetValidationErrors(\r\n validationKey,\r\n path,\r\n validIndices\r\n );\r\n // console.log(\r\n // \"validationErrors ValidationWrapper\",\r\n // stateKey,\r\n // validationKey,\r\n // path,\r\n // validationErrors\r\n // );\r\n const thesMessages: string[] = [];\r\n\r\n if (validationErrors) {\r\n const newMessage = validationErrors!.join(\", \");\r\n if (!thesMessages.includes(newMessage)) {\r\n thesMessages.push(newMessage);\r\n }\r\n }\r\n\r\n return (\r\n <>\r\n {thisStateOpts?.formElements?.validation &&\r\n !formOpts?.validation?.disable ? (\r\n thisStateOpts.formElements!.validation!({\r\n children: (\r\n <React.Fragment key={path.toString()}>{children}</React.Fragment>\r\n ),\r\n active: validationErrors.length > 0 ? true : false,\r\n message: formOpts?.validation?.hideMessage\r\n ? \"\"\r\n : formOpts?.validation?.message\r\n ? formOpts?.validation?.message\r\n : thesMessages.map((m) => m).join(\", \"),\r\n path: path,\r\n })\r\n ) : (\r\n <React.Fragment key={path.toString()}>{children}</React.Fragment>\r\n )}\r\n </>\r\n );\r\n}\r\n"],"names":["updateFn","setState","payload","path","validationKey","prevState","isFunction","nestedValue","getNestedValue","value","updateNestedProperty","pushFunc","stateKey","index","array","getGlobalStore","arrayToUpdate","returnedArray","cutFunc","indexToCut","updatedArray","useStoreSubscription","fullPath","selector","compare","a","b","setValue","useState","previousValueRef","useRef","fullPathRef","useEffect","callback","store","newValue","unsubscribe","useGetValidationErrors","validIndices","useGetSyncInfo","key","syncKey","useGetKeyState","FormControlComponent","child","formOpts","registerFormRef","getFormRef","formRefStore","getValidationErrors","addValidationError","getInitialOptions","removeValidationError","refKey","localFormRef","existingRef","formRef","globalStateValue","localValue","setLocalValue","isCurrentlyDebouncing","debounceTimeoutRef","debouncedUpdater","initialOptions","validateOnBlur","handleBlur","fieldValue","validateZodPathFunc","error","rawSyncStatus","syncStatus","childElement","message","e","jsx","Fragment","ValidationWrapper","children","thisStateOpts","validationErrors","thesMessages","newMessage","React","m"],"mappings":"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"}
1
+ {"version":3,"file":"Functions.jsx","sources":["../src/Functions.tsx"],"sourcesContent":["import {\r\n notifyComponent,\r\n type EffectiveSetState,\r\n type FormElementParams,\r\n type FormOptsType,\r\n type UpdateArg,\r\n type UpdateOpts,\r\n} from \"./CogsState\";\r\n\r\nimport {\r\n getNestedValue,\r\n isFunction,\r\n updateNestedProperty,\r\n updateNestedPropertyIds,\r\n} from \"./utility\";\r\nimport { useEffect, useRef, useState } from \"react\";\r\nimport React from \"react\";\r\nimport { getGlobalStore, formRefStore } from \"./store\";\r\nimport { validateZodPathFunc } from \"./useValidateZodPath\";\r\nimport { ulid } from \"ulid\";\r\n\r\nexport function updateFn<U>(\r\n setState: EffectiveSetState<U>,\r\n payload: UpdateArg<U>,\r\n path: string[],\r\n validationKey?: string\r\n): void {\r\n setState(\r\n (prevState) => {\r\n if (isFunction<U>(payload)) {\r\n const nestedValue = payload(getNestedValue(prevState, path));\r\n console.group(\"nestedValue\", path, nestedValue);\r\n let value = updateNestedPropertyIds(path, prevState, nestedValue);\r\n console.group(\"updateFn\", value);\r\n if (typeof value == \"string\") {\r\n value = value.trim();\r\n }\r\n return value;\r\n } else {\r\n let value =\r\n !path || path.length == 0\r\n ? payload\r\n : updateNestedPropertyIds(path, prevState, payload);\r\n if (typeof value == \"string\") {\r\n value = value.trim();\r\n }\r\n return value;\r\n }\r\n },\r\n path,\r\n { updateType: \"update\" },\r\n validationKey\r\n );\r\n}\r\nexport function pushFunc<U>(\r\n setState: EffectiveSetState<U>,\r\n payload: UpdateArg<U>,\r\n path: string[],\r\n stateKey: string,\r\n index?: number\r\n): void {\r\n // --- THE FIX ---\r\n // 1. Determine the newItem and its ID BEFORE calling setState.\r\n const arrayBeforeUpdate =\r\n (getGlobalStore.getState().getNestedState(stateKey, path) as any[]) || [];\r\n\r\n const newItem = isFunction<U>(payload)\r\n ? payload(arrayBeforeUpdate as any)\r\n : payload;\r\n\r\n // 2. Ensure it has an ID.\r\n if (typeof newItem === \"object\" && newItem !== null && !(newItem as any).id) {\r\n (newItem as any).id = ulid();\r\n }\r\n const finalId = (newItem as any).id;\r\n // --- END OF FIX ---\r\n\r\n setState(\r\n (prevState) => {\r\n // The logic inside here is now much simpler.\r\n // We already have the final `newItem`.\r\n const arrayToUpdate = getNestedValue(prevState, [...path]) || [];\r\n const newArray = [...arrayToUpdate];\r\n newArray.splice(index ?? newArray.length, 0, newItem);\r\n return updateNestedPropertyIds([...path], prevState, newArray);\r\n },\r\n [...path, `id:${finalId}`], // Now we use the ID that is guaranteed to be correct.\r\n {\r\n updateType: \"insert\",\r\n }\r\n );\r\n}\r\nexport function cutFunc<U>(\r\n setState: EffectiveSetState<U>,\r\n path: string[],\r\n stateKey: string,\r\n index: number\r\n): void {\r\n // Get the ordered IDs to find the ID for this index\r\n const arrayKey = [stateKey, ...path].join(\".\");\r\n const arrayMeta = getGlobalStore.getState().shadowStateStore.get(arrayKey);\r\n const itemId = arrayMeta?.arrayKeys?.[index];\r\n\r\n if (!itemId) {\r\n throw new Error(`No ID found for index ${index} in array`);\r\n }\r\n\r\n setState(\r\n (prevState) => {\r\n const arrayToUpdate = getNestedValue(prevState, [...path]);\r\n if (index < 0 || index >= arrayToUpdate?.length) {\r\n throw new Error(`Index ${index} does not exist in the array.`);\r\n }\r\n\r\n const updatedArray = [\r\n ...arrayToUpdate.slice(0, index),\r\n ...arrayToUpdate.slice(index + 1),\r\n ] as U;\r\n\r\n return path.length == 0\r\n ? updatedArray\r\n : updateNestedPropertyIds([...path], prevState, updatedArray);\r\n },\r\n [...path, itemId], // Use the ID here!\r\n { updateType: \"cut\" }\r\n );\r\n}\r\n\r\nexport const useStoreSubscription = <T,>(\r\n fullPath: string,\r\n selector: (\r\n store: ReturnType<typeof getGlobalStore.getState>,\r\n path: string\r\n ) => T,\r\n compare: (a: T, b: T) => boolean = (a, b) =>\r\n JSON.stringify(a) === JSON.stringify(b)\r\n) => {\r\n const [value, setValue] = useState<T>(() =>\r\n selector(getGlobalStore.getState(), fullPath)\r\n );\r\n const previousValueRef = useRef<T>(value);\r\n const fullPathRef = useRef(fullPath);\r\n useEffect(() => {\r\n fullPathRef.current = fullPath; // Ensure latest fullPath is always used\r\n\r\n setValue(selector(getGlobalStore.getState(), fullPath));\r\n\r\n const callback = (store: any) => {\r\n const newValue = selector(store, fullPathRef.current);\r\n\r\n if (!compare(previousValueRef.current, newValue)) {\r\n previousValueRef.current = newValue;\r\n setValue(newValue);\r\n }\r\n };\r\n const unsubscribe = getGlobalStore.subscribe(callback);\r\n return () => {\r\n unsubscribe();\r\n };\r\n }, [fullPath]);\r\n return value;\r\n};\r\nexport const useGetValidationErrors = (\r\n validationKey: string,\r\n path: string[],\r\n validIndices?: number[]\r\n) => {\r\n const fullPath =\r\n validationKey +\r\n \".\" +\r\n (path.length > 0 ? [path.join(\".\")] : []) +\r\n (validIndices && validIndices.length > 0 ? \".\" + validIndices : \"\");\r\n\r\n const returnresult = useStoreSubscription(\r\n fullPath,\r\n (store, path) => store.getValidationErrors(path) || []\r\n );\r\n\r\n return returnresult;\r\n};\r\n\r\nexport const useGetSyncInfo = (key: string, path: string[]) => {\r\n const syncKey = `${key}:${path.join(\".\")}`;\r\n return useStoreSubscription(syncKey, (store, path) =>\r\n store.getSyncInfo(path)\r\n );\r\n};\r\nexport const useGetKeyState = (key: string, path: string[]) => {\r\n return useStoreSubscription(`${key}:${path.join(\".\")}`, (store, fullPath) =>\r\n store.getNestedState(key, path)\r\n );\r\n};\r\ninterface FormControlComponentProps<TStateObject> {\r\n setState: EffectiveSetState<TStateObject>;\r\n\r\n path: string[];\r\n child: (obj: FormElementParams<TStateObject>) => JSX.Element;\r\n formOpts?: FormOptsType;\r\n stateKey: string;\r\n}\r\n// Find FormControlComponent in your Functions.ts or equivalent file\r\n\r\nexport const FormControlComponent = <TStateObject,>({\r\n setState, // This is the real effectiveSetState from the hook\r\n path,\r\n child,\r\n formOpts,\r\n stateKey,\r\n}: FormControlComponentProps<TStateObject>) => {\r\n const { registerFormRef, getFormRef } = formRefStore.getState();\r\n const {\r\n getValidationErrors,\r\n addValidationError,\r\n getInitialOptions,\r\n removeValidationError,\r\n } = getGlobalStore.getState();\r\n\r\n const refKey = stateKey + \".\" + path.join(\".\");\r\n const localFormRef = useRef<HTMLInputElement>(null);\r\n const existingRef = getFormRef(refKey);\r\n if (!existingRef) {\r\n registerFormRef(refKey, localFormRef);\r\n }\r\n const formRef = existingRef || localFormRef;\r\n\r\n // --- START CHANGES ---\r\n\r\n const globalStateValue = useGetKeyState(stateKey, path);\r\n const [localValue, setLocalValue] = useState<any>(globalStateValue);\r\n const isCurrentlyDebouncing = useRef(false);\r\n const debounceTimeoutRef = useRef<NodeJS.Timeout | null>(null);\r\n\r\n // Effect to sync local state if global state changes externally\r\n useEffect(() => {\r\n // Only update local if not actively debouncing a local change\r\n if (!isCurrentlyDebouncing.current && globalStateValue !== localValue) {\r\n setLocalValue(globalStateValue);\r\n }\r\n }, [globalStateValue]); // Removed localValue dependency\r\n\r\n // Effect for cleanup\r\n useEffect(() => {\r\n return () => {\r\n if (debounceTimeoutRef.current) {\r\n clearTimeout(debounceTimeoutRef.current);\r\n debounceTimeoutRef.current = null; // Explicitly nullify\r\n isCurrentlyDebouncing.current = false;\r\n }\r\n };\r\n }, []);\r\n\r\n const debouncedUpdater = (payload: UpdateArg<TStateObject>) => {\r\n setLocalValue(payload); // Update local state immediately\r\n isCurrentlyDebouncing.current = true;\r\n\r\n if (payload === \"\") {\r\n if (debounceTimeoutRef.current) {\r\n clearTimeout(debounceTimeoutRef.current); // Clear pending timer\r\n debounceTimeoutRef.current = null;\r\n }\r\n updateFn(setState, payload, path, validationKey); // Update global state NOW\r\n isCurrentlyDebouncing.current = false; // No longer debouncing\r\n return; // Don't proceed to set another timeout\r\n }\r\n\r\n // If not empty, proceed with normal debouncing\r\n if (debounceTimeoutRef.current) {\r\n clearTimeout(debounceTimeoutRef.current);\r\n }\r\n\r\n debounceTimeoutRef.current = setTimeout(\r\n () => {\r\n isCurrentlyDebouncing.current = false;\r\n updateFn(setState, payload, path, validationKey);\r\n },\r\n formOpts?.debounceTime ??\r\n (typeof globalStateValue == \"boolean\" ? 20 : 200)\r\n );\r\n };\r\n\r\n const initialOptions = getInitialOptions(stateKey);\r\n if (!initialOptions?.validation?.key) {\r\n throw new Error(\"Validation key not found.\");\r\n }\r\n const validationKey = initialOptions.validation.key;\r\n const validateOnBlur = initialOptions.validation.onBlur === true;\r\n\r\n const handleBlur = async () => {\r\n // --- Ensure latest value is flushed if debouncing ---\r\n if (debounceTimeoutRef.current) {\r\n clearTimeout(debounceTimeoutRef.current); // Clear pending timer\r\n debounceTimeoutRef.current = null;\r\n isCurrentlyDebouncing.current = false;\r\n // Ensure the absolute latest local value is committed on blur\r\n updateFn(setState, localValue, path, validationKey);\r\n }\r\n // --- End modification ---\r\n\r\n if (!initialOptions.validation?.zodSchema || !validateOnBlur) return;\r\n removeValidationError(validationKey + \".\" + path.join(\".\"));\r\n try {\r\n // Use the potentially just flushed value\r\n const fieldValue = getGlobalStore\r\n .getState()\r\n .getNestedState(stateKey, path);\r\n await validateZodPathFunc(\r\n validationKey,\r\n initialOptions.validation.zodSchema,\r\n path,\r\n fieldValue\r\n );\r\n // forceUpdate might be needed if validation state update doesn't trigger render\r\n // Consider using useGetValidationErrors hook result directly for validation display\r\n } catch (error) {\r\n console.error(\"Validation error on blur:\", error);\r\n }\r\n };\r\n\r\n const rawSyncStatus = useGetSyncInfo(stateKey, path);\r\n const syncStatus = rawSyncStatus\r\n ? { ...rawSyncStatus, date: new Date(rawSyncStatus.timeStamp) }\r\n : null;\r\n\r\n const childElement = child({\r\n // --- START CHANGES ---\r\n get: () => localValue, // Get should return the immediate local value\r\n set: debouncedUpdater, // Use the new debounced updater\r\n // --- END CHANGES ---\r\n syncStatus,\r\n path: path,\r\n validationErrors: () =>\r\n getValidationErrors(validationKey + \".\" + path.join(\".\")),\r\n addValidationError: (message?: string) => {\r\n removeValidationError(validationKey + \".\" + path.join(\".\"));\r\n addValidationError(validationKey + \".\" + path.join(\".\"), message ?? \"\");\r\n },\r\n inputProps: {\r\n // --- START CHANGES ---\r\n value: localValue ?? \"\", // Input value is always the local state\r\n onChange: (e: any) => debouncedUpdater(e.target.value), // Use debounced updater\r\n // --- END CHANGES ---\r\n onBlur: handleBlur,\r\n ref: formRef,\r\n },\r\n });\r\n\r\n return (\r\n <>\r\n <ValidationWrapper {...{ formOpts, path, stateKey }}>\r\n {childElement}\r\n </ValidationWrapper>\r\n </>\r\n );\r\n};\r\nexport type ValidationWrapperProps = {\r\n formOpts?: FormOptsType;\r\n path: string[];\r\n stateKey: string;\r\n children: React.ReactNode;\r\n validIndices?: number[];\r\n};\r\nexport function ValidationWrapper({\r\n formOpts,\r\n path,\r\n\r\n stateKey,\r\n children,\r\n validIndices,\r\n}: ValidationWrapperProps) {\r\n const { getInitialOptions } = getGlobalStore.getState();\r\n const thisStateOpts = getInitialOptions(stateKey!);\r\n const validationKey = thisStateOpts?.validation?.key ?? stateKey!;\r\n const validationErrors = useGetValidationErrors(\r\n validationKey,\r\n path,\r\n validIndices\r\n );\r\n // console.log(\r\n // \"validationErrors ValidationWrapper\",\r\n // stateKey,\r\n // validationKey,\r\n // path,\r\n // validationErrors\r\n // );\r\n const thesMessages: string[] = [];\r\n\r\n if (validationErrors) {\r\n const newMessage = validationErrors!.join(\", \");\r\n if (!thesMessages.includes(newMessage)) {\r\n thesMessages.push(newMessage);\r\n }\r\n }\r\n\r\n return (\r\n <>\r\n {thisStateOpts?.formElements?.validation &&\r\n !formOpts?.validation?.disable ? (\r\n thisStateOpts.formElements!.validation!({\r\n children: (\r\n <React.Fragment key={path.toString()}>{children}</React.Fragment>\r\n ),\r\n active: validationErrors.length > 0 ? true : false,\r\n message: formOpts?.validation?.hideMessage\r\n ? \"\"\r\n : formOpts?.validation?.message\r\n ? formOpts?.validation?.message\r\n : thesMessages.map((m) => m).join(\", \"),\r\n path: path,\r\n })\r\n ) : (\r\n <React.Fragment key={path.toString()}>{children}</React.Fragment>\r\n )}\r\n </>\r\n );\r\n}\r\n"],"names":["updateFn","setState","payload","path","validationKey","prevState","isFunction","nestedValue","getNestedValue","value","updateNestedPropertyIds","pushFunc","stateKey","index","arrayBeforeUpdate","getGlobalStore","newItem","ulid","finalId","newArray","cutFunc","arrayKey","itemId","arrayToUpdate","updatedArray","useStoreSubscription","fullPath","selector","compare","a","b","setValue","useState","previousValueRef","useRef","fullPathRef","useEffect","callback","store","newValue","unsubscribe","useGetValidationErrors","validIndices","useGetSyncInfo","key","syncKey","useGetKeyState","FormControlComponent","child","formOpts","registerFormRef","getFormRef","formRefStore","getValidationErrors","addValidationError","getInitialOptions","removeValidationError","refKey","localFormRef","existingRef","formRef","globalStateValue","localValue","setLocalValue","isCurrentlyDebouncing","debounceTimeoutRef","debouncedUpdater","initialOptions","validateOnBlur","handleBlur","fieldValue","validateZodPathFunc","error","rawSyncStatus","syncStatus","childElement","message","e","jsx","Fragment","ValidationWrapper","children","thisStateOpts","validationErrors","thesMessages","newMessage","React","m"],"mappings":"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"}
package/dist/index.js CHANGED
@@ -1,14 +1,14 @@
1
- import { $cogsSignal as r, $cogsSignalStore as o, addStateOptions as n, createCogsState as s, notifyComponent as a, useCogsStateFn as i } from "./CogsState.jsx";
1
+ import { $cogsSignal as r, $cogsSignalStore as o, addStateOptions as s, createCogsState as n, notifyComponent as a, useCogsStateFn as i } from "./CogsState.jsx";
2
2
  import { CogsStateClient as f, config as c, useCogsConfig as p } from "./CogsStateClient.jsx";
3
- import { debounce as u, deleteNestedProperty as y, getArrayLengthDifferences as C, getArrayLengthDifferencesArray as S, getDifferences as l, getDifferencesArray as m, getNestedValue as A, isArray as D, isDeepEqual as x, isFunction as F, isObject as L, transformStateFunc as N, updateNestedProperty as b } from "./utility.js";
3
+ import { debounce as u, deleteNestedProperty as y, getArrayLengthDifferences as C, getArrayLengthDifferencesArray as S, getDifferences as l, getDifferencesArray as m, getNestedValue as A, isArray as D, isDeepEqual as x, isFunction as N, isObject as F, transformStateFunc as L, updateNestedProperty as P, updateNestedPropertyIds as b } from "./utility.js";
4
4
  import { useCogsTrpcValidationLink as O } from "./TRPCValidationLink.js";
5
5
  export {
6
6
  r as $cogsSignal,
7
7
  o as $cogsSignalStore,
8
8
  f as CogsStateClient,
9
- n as addStateOptions,
9
+ s as addStateOptions,
10
10
  c as config,
11
- s as createCogsState,
11
+ n as createCogsState,
12
12
  u as debounce,
13
13
  y as deleteNestedProperty,
14
14
  C as getArrayLengthDifferences,
@@ -18,11 +18,12 @@ export {
18
18
  A as getNestedValue,
19
19
  D as isArray,
20
20
  x as isDeepEqual,
21
- F as isFunction,
22
- L as isObject,
21
+ N as isFunction,
22
+ F as isObject,
23
23
  a as notifyComponent,
24
- N as transformStateFunc,
25
- b as updateNestedProperty,
24
+ L as transformStateFunc,
25
+ P as updateNestedProperty,
26
+ b as updateNestedPropertyIds,
26
27
  p as useCogsConfig,
27
28
  i as useCogsStateFn,
28
29
  O as useCogsTrpcValidationLink
package/dist/store.d.ts CHANGED
@@ -32,18 +32,28 @@ export type FormRefStoreState = {
32
32
  getFormRefsByStateKey: (stateKey: string) => Map<string, React.RefObject<any>>;
33
33
  };
34
34
  export declare const formRefStore: import('zustand').UseBoundStore<import('zustand').StoreApi<FormRefStoreState>>;
35
- export type CogsGlobalState = {
36
- shadowStateStore: {
37
- [key: string]: any;
35
+ export type ShadowMetadata = {
36
+ id: string;
37
+ arrayKeys?: string[];
38
+ virtualizer?: {
39
+ itemHeight?: number;
40
+ domRef?: HTMLElement | null;
38
41
  };
39
- shadowStateSubscribers: Map<string, Set<() => void>>;
40
- subscribeToShadowState: (key: string, callback: () => void) => () => void;
42
+ syncInfo?: {
43
+ status: string;
44
+ };
45
+ lastUpdated?: number;
46
+ };
47
+ export type CogsGlobalState = {
48
+ shadowStateStore: Map<string, ShadowMetadata>;
41
49
  initializeShadowState: (key: string, initialState: any) => void;
42
50
  updateShadowAtPath: (key: string, path: string[], newValue: any) => void;
43
51
  insertShadowArrayElement: (key: string, arrayPath: string[], newItem: any) => void;
44
- removeShadowArrayElement: (key: string, arrayPath: string[], index: number) => void;
45
- getShadowMetadata: (key: string, path: string[]) => any;
46
- setShadowMetadata: (key: string, path: string[], metadata: any) => void;
52
+ removeShadowArrayElement: (key: string, arrayPath: string[]) => void;
53
+ getShadowMetadata: (key: string, path: string[]) => ShadowMetadata | undefined;
54
+ setShadowMetadata: (key: string, path: string[], metadata: Omit<ShadowMetadata, "id">) => void;
55
+ shadowStateSubscribers: Map<string, Set<() => void>>;
56
+ subscribeToShadowState: (key: string, callback: () => void) => () => void;
47
57
  selectedIndicesMap: Map<string, Map<string, number>>;
48
58
  getSelectedIndex: (stateKey: string, parentPath: string) => number | undefined;
49
59
  setSelectedIndex: (stateKey: string, parentPath: string, index: number | undefined) => void;