cogsbox-state 0.5.468 → 0.5.470
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/README.md +62 -311
- package/dist/CogsState.d.ts +63 -69
- package/dist/CogsState.d.ts.map +1 -1
- package/dist/CogsState.jsx +945 -995
- package/dist/CogsState.jsx.map +1 -1
- package/dist/Components.d.ts +10 -0
- package/dist/Components.d.ts.map +1 -1
- package/dist/Components.jsx +141 -119
- package/dist/Components.jsx.map +1 -1
- package/dist/index.js +5 -4
- package/dist/store.d.ts +3 -1
- package/dist/store.d.ts.map +1 -1
- package/dist/store.js +23 -18
- package/dist/store.js.map +1 -1
- package/package.json +1 -1
- package/src/CogsState.tsx +149 -209
- package/src/Components.tsx +55 -4
- package/src/store.ts +11 -6
package/src/CogsState.tsx
CHANGED
|
@@ -2,7 +2,6 @@
|
|
|
2
2
|
|
|
3
3
|
import {
|
|
4
4
|
createElement,
|
|
5
|
-
memo,
|
|
6
5
|
startTransition,
|
|
7
6
|
useCallback,
|
|
8
7
|
useEffect,
|
|
@@ -23,6 +22,7 @@ import {
|
|
|
23
22
|
} from './utility.js';
|
|
24
23
|
import {
|
|
25
24
|
FormElementWrapper,
|
|
25
|
+
IsolatedComponentWrapper,
|
|
26
26
|
MemoizedCogsItemWrapper,
|
|
27
27
|
ValidationWrapper,
|
|
28
28
|
} from './Components.js';
|
|
@@ -34,6 +34,7 @@ import {
|
|
|
34
34
|
formRefStore,
|
|
35
35
|
getGlobalStore,
|
|
36
36
|
ValidationError,
|
|
37
|
+
ValidationSeverity,
|
|
37
38
|
ValidationStatus,
|
|
38
39
|
type ComponentsType,
|
|
39
40
|
} from './store.js';
|
|
@@ -55,15 +56,7 @@ export type VirtualViewOptions = {
|
|
|
55
56
|
|
|
56
57
|
// The result now returns a real StateObject
|
|
57
58
|
export type VirtualStateObjectResult<T extends any[]> = {
|
|
58
|
-
/**
|
|
59
|
-
* A new, fully-functional StateObject that represents the virtualized slice.
|
|
60
|
-
* You can use `.get()`, `.stateMap()`, `.insert()`, `.cut()` etc. on this object.
|
|
61
|
-
*/
|
|
62
|
-
|
|
63
59
|
virtualState: StateObject<T>;
|
|
64
|
-
/**
|
|
65
|
-
* Props to be spread onto your DOM elements to enable virtualization.
|
|
66
|
-
*/
|
|
67
60
|
virtualizerProps: {
|
|
68
61
|
outer: { ref: RefObject<HTMLDivElement>; style: CSSProperties };
|
|
69
62
|
inner: { style: CSSProperties };
|
|
@@ -79,11 +72,13 @@ export type SyncInfo = {
|
|
|
79
72
|
};
|
|
80
73
|
|
|
81
74
|
export type FormElementParams<T> = StateObject<T> & {
|
|
82
|
-
inputProps: {
|
|
75
|
+
$inputProps: {
|
|
83
76
|
ref?: React.RefObject<any>;
|
|
84
77
|
value?: T extends boolean ? never : T;
|
|
85
78
|
onChange?: (
|
|
86
|
-
event: React.ChangeEvent<
|
|
79
|
+
event: React.ChangeEvent<
|
|
80
|
+
HTMLInputElement | HTMLTextAreaElement | HTMLSelectElement
|
|
81
|
+
>
|
|
87
82
|
) => void;
|
|
88
83
|
onBlur?: () => void;
|
|
89
84
|
};
|
|
@@ -149,78 +144,75 @@ export type StreamHandle<T> = {
|
|
|
149
144
|
pause: () => void;
|
|
150
145
|
resume: () => void;
|
|
151
146
|
};
|
|
147
|
+
|
|
152
148
|
export type ArrayEndType<TShape extends unknown> = {
|
|
153
|
-
stream: <T = Prettify<InferArrayElement<TShape>>, R = T>(
|
|
149
|
+
$stream: <T = Prettify<InferArrayElement<TShape>>, R = T>(
|
|
154
150
|
options?: StreamOptions<T, R>
|
|
155
151
|
) => StreamHandle<T>;
|
|
156
|
-
findWith: findWithFuncType<Prettify<InferArrayElement<TShape>>>;
|
|
157
|
-
index: (index: number) => StateObject<
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
152
|
+
$findWith: findWithFuncType<Prettify<InferArrayElement<TShape>>>;
|
|
153
|
+
$index: (index: number) => StateObject<
|
|
154
|
+
Prettify<InferArrayElement<TShape>>
|
|
155
|
+
> & {
|
|
156
|
+
$insert: InsertTypeObj<Prettify<InferArrayElement<TShape>>>;
|
|
157
|
+
$cut: CutFunctionType<TShape>;
|
|
158
|
+
$_index: number;
|
|
161
159
|
} & EndType<Prettify<InferArrayElement<TShape>>>;
|
|
162
|
-
insert: InsertType<Prettify<InferArrayElement<TShape>>>;
|
|
163
|
-
cut: CutFunctionType<TShape>;
|
|
164
|
-
cutSelected: () => void;
|
|
165
|
-
cutByValue: (value: string | number | boolean) => void;
|
|
166
|
-
toggleByValue: (value: string | number | boolean) => void;
|
|
167
|
-
stateSort: (
|
|
160
|
+
$insert: InsertType<Prettify<InferArrayElement<TShape>>>;
|
|
161
|
+
$cut: CutFunctionType<TShape>;
|
|
162
|
+
$cutSelected: () => void;
|
|
163
|
+
$cutByValue: (value: string | number | boolean) => void;
|
|
164
|
+
$toggleByValue: (value: string | number | boolean) => void;
|
|
165
|
+
$stateSort: (
|
|
168
166
|
compareFn: (
|
|
169
167
|
a: Prettify<InferArrayElement<TShape>>,
|
|
170
168
|
b: Prettify<InferArrayElement<TShape>>
|
|
171
169
|
) => number
|
|
172
170
|
) => ArrayEndType<TShape>;
|
|
173
|
-
useVirtualView: (
|
|
171
|
+
$useVirtualView: (
|
|
174
172
|
options: VirtualViewOptions
|
|
175
173
|
) => VirtualStateObjectResult<Prettify<InferArrayElement<TShape>>[]>;
|
|
176
174
|
|
|
177
|
-
stateList: (
|
|
175
|
+
$stateList: (
|
|
178
176
|
callbackfn: (
|
|
179
177
|
setter: StateObject<Prettify<InferArrayElement<TShape>>>,
|
|
180
178
|
index: number,
|
|
181
179
|
arraySetter: StateObject<TShape>
|
|
182
180
|
) => void
|
|
183
181
|
) => any;
|
|
184
|
-
stateMap: <U>(
|
|
182
|
+
$stateMap: <U>(
|
|
185
183
|
callbackfn: (
|
|
186
184
|
setter: StateObject<Prettify<InferArrayElement<TShape>>>,
|
|
187
185
|
index: number,
|
|
188
186
|
arraySetter: StateObject<TShape>
|
|
189
187
|
) => U
|
|
190
188
|
) => U[];
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
setter: StateObject<Prettify<InferArrayElement<TShape>>>,
|
|
194
|
-
index: number,
|
|
195
|
-
arraySetter: StateObject<TShape>
|
|
196
|
-
) => void
|
|
197
|
-
) => any;
|
|
198
|
-
stateFlattenOn: <K extends keyof Prettify<InferArrayElement<TShape>>>(
|
|
189
|
+
|
|
190
|
+
$stateFlattenOn: <K extends keyof Prettify<InferArrayElement<TShape>>>(
|
|
199
191
|
field: K
|
|
200
192
|
) => StateObject<InferArrayElement<Prettify<InferArrayElement<TShape>>[K]>[]>;
|
|
201
|
-
uniqueInsert: (
|
|
193
|
+
$uniqueInsert: (
|
|
202
194
|
payload: InsertParams<Prettify<InferArrayElement<TShape>>>,
|
|
203
195
|
fields?: (keyof Prettify<InferArrayElement<TShape>>)[],
|
|
204
196
|
onMatch?: (existingItem: any) => any
|
|
205
197
|
) => void;
|
|
206
|
-
stateFind: (
|
|
198
|
+
$stateFind: (
|
|
207
199
|
callbackfn: (
|
|
208
200
|
value: Prettify<InferArrayElement<TShape>>,
|
|
209
201
|
index: number
|
|
210
202
|
) => boolean
|
|
211
203
|
) => StateObject<Prettify<InferArrayElement<TShape>>> | undefined;
|
|
212
|
-
stateFilter: (
|
|
204
|
+
$stateFilter: (
|
|
213
205
|
callbackfn: (
|
|
214
206
|
value: Prettify<InferArrayElement<TShape>>,
|
|
215
207
|
index: number
|
|
216
208
|
) => void
|
|
217
209
|
) => ArrayEndType<TShape>;
|
|
218
|
-
getSelected: () =>
|
|
210
|
+
$getSelected: () =>
|
|
219
211
|
| StateObject<Prettify<InferArrayElement<TShape>>>
|
|
220
212
|
| undefined;
|
|
221
|
-
clearSelected: () => void;
|
|
222
|
-
getSelectedIndex: () => number;
|
|
223
|
-
last: () => StateObject<Prettify<InferArrayElement<TShape>>> | undefined;
|
|
213
|
+
$clearSelected: () => void;
|
|
214
|
+
$getSelectedIndex: () => number;
|
|
215
|
+
$last: () => StateObject<Prettify<InferArrayElement<TShape>>> | undefined;
|
|
224
216
|
} & EndType<TShape>;
|
|
225
217
|
|
|
226
218
|
export type FormOptsType = {
|
|
@@ -251,40 +243,40 @@ export type InsertTypeObj<T> = (payload: InsertParams<T>) => void;
|
|
|
251
243
|
|
|
252
244
|
type EffectFunction<T, R> = (state: T, deps: any[]) => R;
|
|
253
245
|
export type EndType<T, IsArrayElement = false> = {
|
|
254
|
-
addZodValidation: (errors: ValidationError[]) => void;
|
|
255
|
-
clearZodValidation: (paths?: string[]) => void;
|
|
256
|
-
applyJsonPatch: (patches: any[]) => void;
|
|
257
|
-
update: UpdateType<T>;
|
|
258
|
-
_path: string[];
|
|
259
|
-
_stateKey: string;
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
246
|
+
$addZodValidation: (errors: ValidationError[]) => void;
|
|
247
|
+
$clearZodValidation: (paths?: string[]) => void;
|
|
248
|
+
$applyJsonPatch: (patches: any[]) => void;
|
|
249
|
+
$update: UpdateType<T>;
|
|
250
|
+
$_path: string[];
|
|
251
|
+
$_stateKey: string;
|
|
252
|
+
$isolate: (
|
|
253
|
+
renderFn: (state: StateObject<T>) => React.ReactNode
|
|
254
|
+
) => JSX.Element;
|
|
255
|
+
$formElement: (control: FormControl<T>, opts?: FormOptsType) => JSX.Element;
|
|
263
256
|
$get: () => T;
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
_status: 'fresh' | 'dirty' | 'synced' | 'restored' | 'unknown';
|
|
267
|
-
getStatus: () => 'fresh' | 'dirty' | 'synced' | 'restored' | 'unknown';
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
validationWrapper: ({
|
|
257
|
+
$$get: () => T;
|
|
258
|
+
$$derive: <R>(fn: EffectFunction<T, R>) => R;
|
|
259
|
+
$_status: 'fresh' | 'dirty' | 'synced' | 'restored' | 'unknown';
|
|
260
|
+
$getStatus: () => 'fresh' | 'dirty' | 'synced' | 'restored' | 'unknown';
|
|
261
|
+
$showValidationErrors: () => string[];
|
|
262
|
+
$setValidation: (ctx: string) => void;
|
|
263
|
+
$removeValidation: (ctx: string) => void;
|
|
264
|
+
$ignoreFields: (fields: string[]) => StateObject<T>;
|
|
265
|
+
$isSelected: boolean;
|
|
266
|
+
$setSelected: (value: boolean) => void;
|
|
267
|
+
$toggleSelected: () => void;
|
|
268
|
+
$getFormRef: () => React.RefObject<any> | undefined;
|
|
269
|
+
$removeStorage: () => void;
|
|
270
|
+
$sync: () => void;
|
|
271
|
+
$validationWrapper: ({
|
|
280
272
|
children,
|
|
281
273
|
hideMessage,
|
|
282
274
|
}: {
|
|
283
275
|
children: React.ReactNode;
|
|
284
276
|
hideMessage?: boolean;
|
|
285
277
|
}) => JSX.Element;
|
|
286
|
-
lastSynced?: SyncInfo;
|
|
287
|
-
} & (IsArrayElement extends true ? { cutThis: () => void } : {});
|
|
278
|
+
$lastSynced?: SyncInfo;
|
|
279
|
+
} & (IsArrayElement extends true ? { $cutThis: () => void } : {});
|
|
288
280
|
|
|
289
281
|
export type StateObject<T> = (T extends any[]
|
|
290
282
|
? ArrayEndType<T>
|
|
@@ -294,20 +286,20 @@ export type StateObject<T> = (T extends any[]
|
|
|
294
286
|
? EndType<T, true>
|
|
295
287
|
: never) &
|
|
296
288
|
EndType<T, true> & {
|
|
297
|
-
toggle: T extends boolean ? () => void : never;
|
|
298
|
-
getAllFormRefs: () => Map<string, React.RefObject<any>>;
|
|
299
|
-
_componentId: string | null;
|
|
300
|
-
getComponents: () => ComponentsType;
|
|
289
|
+
$toggle: T extends boolean ? () => void : never;
|
|
290
|
+
$getAllFormRefs: () => Map<string, React.RefObject<any>>;
|
|
291
|
+
$_componentId: string | null;
|
|
292
|
+
$getComponents: () => ComponentsType;
|
|
301
293
|
|
|
302
|
-
_initialState: T;
|
|
303
|
-
updateInitialState: (newState: T | null) => {
|
|
294
|
+
$_initialState: T;
|
|
295
|
+
$updateInitialState: (newState: T | null) => {
|
|
304
296
|
fetchId: (field: keyof T) => string | number;
|
|
305
297
|
};
|
|
306
|
-
_isLoading: boolean;
|
|
307
|
-
_serverState: T;
|
|
308
|
-
revertToInitialState: (obj?: { validationKey?: string }) => T;
|
|
298
|
+
$_isLoading: boolean;
|
|
299
|
+
$_serverState: T;
|
|
300
|
+
$revertToInitialState: (obj?: { validationKey?: string }) => T;
|
|
309
301
|
|
|
310
|
-
middleware: (
|
|
302
|
+
$middleware: (
|
|
311
303
|
middles: ({
|
|
312
304
|
updateLog,
|
|
313
305
|
update,
|
|
@@ -317,7 +309,7 @@ export type StateObject<T> = (T extends any[]
|
|
|
317
309
|
}) => void
|
|
318
310
|
) => void;
|
|
319
311
|
|
|
320
|
-
getLocalStorage: (key: string) => LocalStorageData<T> | null;
|
|
312
|
+
$getLocalStorage: (key: string) => LocalStorageData<T> | null;
|
|
321
313
|
};
|
|
322
314
|
|
|
323
315
|
export type CogsUpdate<T extends unknown> = UpdateType<T>;
|
|
@@ -448,8 +440,8 @@ export type SyncRenderOptions<T extends unknown = unknown> = {
|
|
|
448
440
|
type FormsElementsType<T> = {
|
|
449
441
|
validation?: (options: {
|
|
450
442
|
children: React.ReactNode;
|
|
451
|
-
status: ValidationStatus;
|
|
452
|
-
|
|
443
|
+
status: ValidationStatus;
|
|
444
|
+
severity: ValidationSeverity;
|
|
453
445
|
hasErrors: boolean;
|
|
454
446
|
hasWarnings: boolean;
|
|
455
447
|
allErrors: ValidationError[];
|
|
@@ -483,7 +475,6 @@ export type TransformedStateType<T> = {
|
|
|
483
475
|
const {
|
|
484
476
|
getInitialOptions,
|
|
485
477
|
updateInitialStateGlobal,
|
|
486
|
-
// ALIAS THE NEW FUNCTIONS TO THE OLD NAMES
|
|
487
478
|
getShadowMetadata,
|
|
488
479
|
setShadowMetadata,
|
|
489
480
|
getShadowValue,
|
|
@@ -492,12 +483,9 @@ const {
|
|
|
492
483
|
insertShadowArrayElement,
|
|
493
484
|
insertManyShadowArrayElements,
|
|
494
485
|
removeShadowArrayElement,
|
|
495
|
-
getSelectedIndex,
|
|
496
486
|
setInitialStateOptions,
|
|
497
487
|
setServerStateUpdate,
|
|
498
488
|
markAsDirty,
|
|
499
|
-
registerComponent,
|
|
500
|
-
unregisterComponent,
|
|
501
489
|
addPathComponent,
|
|
502
490
|
clearSelectedIndexesForState,
|
|
503
491
|
addStateLog,
|
|
@@ -505,7 +493,6 @@ const {
|
|
|
505
493
|
clearSelectedIndex,
|
|
506
494
|
getSyncInfo,
|
|
507
495
|
notifyPathSubscribers,
|
|
508
|
-
subscribeToPath,
|
|
509
496
|
// Note: The old functions are no longer imported under their original names
|
|
510
497
|
} = getGlobalStore.getState();
|
|
511
498
|
function getArrayData(stateKey: string, path: string[], meta?: MetaData) {
|
|
@@ -1827,58 +1814,6 @@ function createProxyHandler<T>(
|
|
|
1827
1814
|
const proxyCache = new Map<string, any>();
|
|
1828
1815
|
let stateVersion = 0;
|
|
1829
1816
|
|
|
1830
|
-
const methodNames = new Set([
|
|
1831
|
-
'sync',
|
|
1832
|
-
'getStatus',
|
|
1833
|
-
'removeStorage',
|
|
1834
|
-
'showValidationErrors',
|
|
1835
|
-
'getSelected',
|
|
1836
|
-
'getSelectedIndex',
|
|
1837
|
-
'clearSelected',
|
|
1838
|
-
'useVirtualView',
|
|
1839
|
-
'stateMap',
|
|
1840
|
-
'$stateMap',
|
|
1841
|
-
'stateFind',
|
|
1842
|
-
'stateFilter',
|
|
1843
|
-
'stateSort',
|
|
1844
|
-
'stream',
|
|
1845
|
-
'stateList',
|
|
1846
|
-
'stateFlattenOn',
|
|
1847
|
-
'index',
|
|
1848
|
-
'last',
|
|
1849
|
-
'insert',
|
|
1850
|
-
'uniqueInsert',
|
|
1851
|
-
'cut',
|
|
1852
|
-
'cutSelected',
|
|
1853
|
-
'cutByValue',
|
|
1854
|
-
'toggleByValue',
|
|
1855
|
-
'findWith',
|
|
1856
|
-
'cutThis',
|
|
1857
|
-
'get',
|
|
1858
|
-
'getState',
|
|
1859
|
-
'$derive',
|
|
1860
|
-
'$get',
|
|
1861
|
-
'lastSynced',
|
|
1862
|
-
'getLocalStorage',
|
|
1863
|
-
'isSelected',
|
|
1864
|
-
'setSelected',
|
|
1865
|
-
'toggleSelected',
|
|
1866
|
-
'_componentId',
|
|
1867
|
-
'addZodValidation',
|
|
1868
|
-
'clearZodValidation',
|
|
1869
|
-
'applyJsonPatch',
|
|
1870
|
-
'getComponents',
|
|
1871
|
-
'getAllFormRefs',
|
|
1872
|
-
'getFormRef',
|
|
1873
|
-
'validationWrapper',
|
|
1874
|
-
'_stateKey',
|
|
1875
|
-
'_path',
|
|
1876
|
-
'update',
|
|
1877
|
-
'toggle',
|
|
1878
|
-
'formElement',
|
|
1879
|
-
// Add ANY other method names here
|
|
1880
|
-
]);
|
|
1881
|
-
|
|
1882
1817
|
function rebuildStateShape({
|
|
1883
1818
|
path = [],
|
|
1884
1819
|
meta,
|
|
@@ -1906,7 +1841,7 @@ function createProxyHandler<T>(
|
|
|
1906
1841
|
if (path.length === 0 && prop in rootLevelMethods) {
|
|
1907
1842
|
return rootLevelMethods[prop as keyof typeof rootLevelMethods];
|
|
1908
1843
|
}
|
|
1909
|
-
if (!
|
|
1844
|
+
if (!prop.startsWith('$')) {
|
|
1910
1845
|
const nextPath = [...path, prop];
|
|
1911
1846
|
return rebuildStateShape({
|
|
1912
1847
|
path: nextPath,
|
|
@@ -1914,11 +1849,11 @@ function createProxyHandler<T>(
|
|
|
1914
1849
|
meta,
|
|
1915
1850
|
});
|
|
1916
1851
|
}
|
|
1917
|
-
if (prop === '_rebuildStateShape') {
|
|
1852
|
+
if (prop === '$_rebuildStateShape') {
|
|
1918
1853
|
return rebuildStateShape;
|
|
1919
1854
|
}
|
|
1920
1855
|
|
|
1921
|
-
if (prop === 'sync' && path.length === 0) {
|
|
1856
|
+
if (prop === '$sync' && path.length === 0) {
|
|
1922
1857
|
return async function () {
|
|
1923
1858
|
const options = getGlobalStore
|
|
1924
1859
|
.getState()
|
|
@@ -1980,7 +1915,7 @@ function createProxyHandler<T>(
|
|
|
1980
1915
|
};
|
|
1981
1916
|
}
|
|
1982
1917
|
// Fixed getStatus function in createProxyHandler
|
|
1983
|
-
if (prop === '_status' || prop === 'getStatus') {
|
|
1918
|
+
if (prop === '$_status' || prop === '$getStatus') {
|
|
1984
1919
|
const getStatusFunc = () => {
|
|
1985
1920
|
// ✅ Use the optimized helper to get all data in one efficient call
|
|
1986
1921
|
const { shadowMeta, value } = getScopedData(stateKey, path, meta);
|
|
@@ -2022,9 +1957,9 @@ function createProxyHandler<T>(
|
|
|
2022
1957
|
};
|
|
2023
1958
|
|
|
2024
1959
|
// This part remains the same
|
|
2025
|
-
return prop === '_status' ? getStatusFunc() : getStatusFunc;
|
|
1960
|
+
return prop === '$_status' ? getStatusFunc() : getStatusFunc;
|
|
2026
1961
|
}
|
|
2027
|
-
if (prop === 'removeStorage') {
|
|
1962
|
+
if (prop === '$removeStorage') {
|
|
2028
1963
|
return () => {
|
|
2029
1964
|
const initialState =
|
|
2030
1965
|
getGlobalStore.getState().initialStateGlobal[stateKey];
|
|
@@ -2036,7 +1971,7 @@ function createProxyHandler<T>(
|
|
|
2036
1971
|
if (storageKey) localStorage.removeItem(storageKey);
|
|
2037
1972
|
};
|
|
2038
1973
|
}
|
|
2039
|
-
if (prop === 'showValidationErrors') {
|
|
1974
|
+
if (prop === '$showValidationErrors') {
|
|
2040
1975
|
return () => {
|
|
2041
1976
|
const { shadowMeta } = getScopedData(stateKey, path, meta);
|
|
2042
1977
|
if (
|
|
@@ -2052,7 +1987,7 @@ function createProxyHandler<T>(
|
|
|
2052
1987
|
};
|
|
2053
1988
|
}
|
|
2054
1989
|
|
|
2055
|
-
if (prop === 'getSelected') {
|
|
1990
|
+
if (prop === '$getSelected') {
|
|
2056
1991
|
return () => {
|
|
2057
1992
|
const arrayKey = [stateKey, ...path].join('.');
|
|
2058
1993
|
registerComponentDependency(stateKey, componentId, [
|
|
@@ -2091,7 +2026,7 @@ function createProxyHandler<T>(
|
|
|
2091
2026
|
});
|
|
2092
2027
|
};
|
|
2093
2028
|
}
|
|
2094
|
-
if (prop === 'getSelectedIndex') {
|
|
2029
|
+
if (prop === '$getSelectedIndex') {
|
|
2095
2030
|
return () => {
|
|
2096
2031
|
// Key for the array in the global selection map (e.g., "myState.products")
|
|
2097
2032
|
const arrayKey = stateKey + '.' + path.join('.');
|
|
@@ -2121,7 +2056,7 @@ function createProxyHandler<T>(
|
|
|
2121
2056
|
return (viewIds as string[]).indexOf(selectedId as string);
|
|
2122
2057
|
};
|
|
2123
2058
|
}
|
|
2124
|
-
if (prop === 'clearSelected') {
|
|
2059
|
+
if (prop === '$clearSelected') {
|
|
2125
2060
|
notifySelectionComponents(stateKey, path);
|
|
2126
2061
|
return () => {
|
|
2127
2062
|
clearSelectedIndex({
|
|
@@ -2130,7 +2065,7 @@ function createProxyHandler<T>(
|
|
|
2130
2065
|
};
|
|
2131
2066
|
}
|
|
2132
2067
|
|
|
2133
|
-
if (prop === 'useVirtualView') {
|
|
2068
|
+
if (prop === '$useVirtualView') {
|
|
2134
2069
|
return (
|
|
2135
2070
|
options: VirtualViewOptions
|
|
2136
2071
|
): VirtualStateObjectResult<any[]> => {
|
|
@@ -2480,7 +2415,7 @@ function createProxyHandler<T>(
|
|
|
2480
2415
|
};
|
|
2481
2416
|
};
|
|
2482
2417
|
}
|
|
2483
|
-
if (prop === 'stateMap') {
|
|
2418
|
+
if (prop === '$stateMap') {
|
|
2484
2419
|
return (
|
|
2485
2420
|
callbackfn: (setter: any, index: number, arraySetter: any) => void
|
|
2486
2421
|
) => {
|
|
@@ -2520,7 +2455,7 @@ function createProxyHandler<T>(
|
|
|
2520
2455
|
};
|
|
2521
2456
|
}
|
|
2522
2457
|
|
|
2523
|
-
if (prop === 'stateFilter') {
|
|
2458
|
+
if (prop === '$stateFilter') {
|
|
2524
2459
|
return (callbackfn: (value: any, index: number) => boolean) => {
|
|
2525
2460
|
const arrayPathKey = path.length > 0 ? path.join('.') : 'root';
|
|
2526
2461
|
|
|
@@ -2565,7 +2500,7 @@ function createProxyHandler<T>(
|
|
|
2565
2500
|
});
|
|
2566
2501
|
};
|
|
2567
2502
|
}
|
|
2568
|
-
if (prop === 'stateSort') {
|
|
2503
|
+
if (prop === '$stateSort') {
|
|
2569
2504
|
return (compareFn: (a: any, b: any) => number) => {
|
|
2570
2505
|
const arrayPathKey = path.length > 0 ? path.join('.') : 'root';
|
|
2571
2506
|
|
|
@@ -2606,7 +2541,7 @@ function createProxyHandler<T>(
|
|
|
2606
2541
|
};
|
|
2607
2542
|
}
|
|
2608
2543
|
// In createProxyHandler, inside the get trap where you have other array methods:
|
|
2609
|
-
if (prop === 'stream') {
|
|
2544
|
+
if (prop === '$stream') {
|
|
2610
2545
|
return function <U = InferArrayElement<T>, R = U>(
|
|
2611
2546
|
options: StreamOptions<U, R> = {}
|
|
2612
2547
|
): StreamHandle<U> {
|
|
@@ -2708,7 +2643,7 @@ function createProxyHandler<T>(
|
|
|
2708
2643
|
};
|
|
2709
2644
|
}
|
|
2710
2645
|
|
|
2711
|
-
if (prop === 'stateList') {
|
|
2646
|
+
if (prop === '$stateList') {
|
|
2712
2647
|
return (
|
|
2713
2648
|
callbackfn: (
|
|
2714
2649
|
setter: any,
|
|
@@ -2829,7 +2764,7 @@ function createProxyHandler<T>(
|
|
|
2829
2764
|
return <StateListWrapper />;
|
|
2830
2765
|
};
|
|
2831
2766
|
}
|
|
2832
|
-
if (prop === 'stateFlattenOn') {
|
|
2767
|
+
if (prop === '$stateFlattenOn') {
|
|
2833
2768
|
return (fieldName: string) => {
|
|
2834
2769
|
// FIX: Get the definitive list of IDs for the current view from meta.arrayViews.
|
|
2835
2770
|
const arrayPathKey = path.length > 0 ? path.join('.') : 'root';
|
|
@@ -2850,7 +2785,7 @@ function createProxyHandler<T>(
|
|
|
2850
2785
|
});
|
|
2851
2786
|
};
|
|
2852
2787
|
}
|
|
2853
|
-
if (prop === 'index') {
|
|
2788
|
+
if (prop === '$index') {
|
|
2854
2789
|
return (index: number) => {
|
|
2855
2790
|
const arrayPathKey = path.length > 0 ? path.join('.') : 'root';
|
|
2856
2791
|
const viewIds = meta?.arrayViews?.[arrayPathKey];
|
|
@@ -2879,7 +2814,7 @@ function createProxyHandler<T>(
|
|
|
2879
2814
|
});
|
|
2880
2815
|
};
|
|
2881
2816
|
}
|
|
2882
|
-
if (prop === 'last') {
|
|
2817
|
+
if (prop === '$last') {
|
|
2883
2818
|
return () => {
|
|
2884
2819
|
const { keys: currentViewIds } = getArrayData(stateKey, path, meta);
|
|
2885
2820
|
if (!currentViewIds || currentViewIds.length === 0) {
|
|
@@ -2899,7 +2834,7 @@ function createProxyHandler<T>(
|
|
|
2899
2834
|
});
|
|
2900
2835
|
};
|
|
2901
2836
|
}
|
|
2902
|
-
if (prop === 'insert') {
|
|
2837
|
+
if (prop === '$insert') {
|
|
2903
2838
|
return (
|
|
2904
2839
|
payload: InsertParams<InferArrayElement<T>>,
|
|
2905
2840
|
index?: number
|
|
@@ -2907,7 +2842,7 @@ function createProxyHandler<T>(
|
|
|
2907
2842
|
effectiveSetState(payload as any, path, { updateType: 'insert' });
|
|
2908
2843
|
};
|
|
2909
2844
|
}
|
|
2910
|
-
if (prop === 'uniqueInsert') {
|
|
2845
|
+
if (prop === '$uniqueInsert') {
|
|
2911
2846
|
return (
|
|
2912
2847
|
payload: UpdateArg<T>,
|
|
2913
2848
|
fields?: (keyof InferArrayElement<T>)[],
|
|
@@ -2949,7 +2884,7 @@ function createProxyHandler<T>(
|
|
|
2949
2884
|
}
|
|
2950
2885
|
};
|
|
2951
2886
|
}
|
|
2952
|
-
if (prop === 'cut') {
|
|
2887
|
+
if (prop === '$cut') {
|
|
2953
2888
|
return (index?: number, options?: { waitForSync?: boolean }) => {
|
|
2954
2889
|
const shadowMeta = getShadowMetadata(stateKey, path);
|
|
2955
2890
|
if (!shadowMeta?.arrayKeys || shadowMeta.arrayKeys.length === 0)
|
|
@@ -2970,7 +2905,7 @@ function createProxyHandler<T>(
|
|
|
2970
2905
|
});
|
|
2971
2906
|
};
|
|
2972
2907
|
}
|
|
2973
|
-
if (prop === 'cutSelected') {
|
|
2908
|
+
if (prop === '$cutSelected') {
|
|
2974
2909
|
return () => {
|
|
2975
2910
|
const arrayKey = [stateKey, ...path].join('.');
|
|
2976
2911
|
|
|
@@ -3001,7 +2936,7 @@ function createProxyHandler<T>(
|
|
|
3001
2936
|
});
|
|
3002
2937
|
};
|
|
3003
2938
|
}
|
|
3004
|
-
if (prop === 'cutByValue') {
|
|
2939
|
+
if (prop === '$cutByValue') {
|
|
3005
2940
|
return (value: string | number | boolean) => {
|
|
3006
2941
|
const {
|
|
3007
2942
|
isArray,
|
|
@@ -3020,7 +2955,7 @@ function createProxyHandler<T>(
|
|
|
3020
2955
|
};
|
|
3021
2956
|
}
|
|
3022
2957
|
|
|
3023
|
-
if (prop === 'toggleByValue') {
|
|
2958
|
+
if (prop === '$toggleByValue') {
|
|
3024
2959
|
return (value: string | number | boolean) => {
|
|
3025
2960
|
const {
|
|
3026
2961
|
isArray,
|
|
@@ -3043,7 +2978,7 @@ function createProxyHandler<T>(
|
|
|
3043
2978
|
}
|
|
3044
2979
|
};
|
|
3045
2980
|
}
|
|
3046
|
-
if (prop === 'findWith') {
|
|
2981
|
+
if (prop === '$findWith') {
|
|
3047
2982
|
return (searchKey: string, searchValue: any) => {
|
|
3048
2983
|
const { isArray, value, keys } = getArrayData(stateKey, path, meta);
|
|
3049
2984
|
|
|
@@ -3072,7 +3007,7 @@ function createProxyHandler<T>(
|
|
|
3072
3007
|
});
|
|
3073
3008
|
};
|
|
3074
3009
|
}
|
|
3075
|
-
if (prop === 'cutThis') {
|
|
3010
|
+
if (prop === '$cutThis') {
|
|
3076
3011
|
const { value: shadowValue } = getScopedData(stateKey, path, meta);
|
|
3077
3012
|
const parentPath = path.slice(0, -1);
|
|
3078
3013
|
notifySelectionComponents(stateKey, parentPath);
|
|
@@ -3081,7 +3016,7 @@ function createProxyHandler<T>(
|
|
|
3081
3016
|
};
|
|
3082
3017
|
}
|
|
3083
3018
|
|
|
3084
|
-
if (prop === 'get') {
|
|
3019
|
+
if (prop === '$get') {
|
|
3085
3020
|
return () => {
|
|
3086
3021
|
registerComponentDependency(stateKey, componentId, path);
|
|
3087
3022
|
const { value } = getScopedData(stateKey, path, meta);
|
|
@@ -3089,7 +3024,7 @@ function createProxyHandler<T>(
|
|
|
3089
3024
|
};
|
|
3090
3025
|
}
|
|
3091
3026
|
|
|
3092
|
-
if (prop === '
|
|
3027
|
+
if (prop === '$$derive') {
|
|
3093
3028
|
return (fn: any) =>
|
|
3094
3029
|
$cogsSignal({
|
|
3095
3030
|
_stateKey: stateKey,
|
|
@@ -3099,11 +3034,11 @@ function createProxyHandler<T>(
|
|
|
3099
3034
|
});
|
|
3100
3035
|
}
|
|
3101
3036
|
|
|
3102
|
-
if (prop === '
|
|
3037
|
+
if (prop === '$$get') {
|
|
3103
3038
|
return () =>
|
|
3104
3039
|
$cogsSignal({ _stateKey: stateKey, _path: path, _meta: meta });
|
|
3105
3040
|
}
|
|
3106
|
-
if (prop === 'lastSynced') {
|
|
3041
|
+
if (prop === '$lastSynced') {
|
|
3107
3042
|
const syncKey = `${stateKey}:${path.join('.')}`;
|
|
3108
3043
|
return getSyncInfo(syncKey);
|
|
3109
3044
|
}
|
|
@@ -3111,7 +3046,7 @@ function createProxyHandler<T>(
|
|
|
3111
3046
|
return (key: string) =>
|
|
3112
3047
|
loadFromLocalStorage(sessionId + '-' + stateKey + '-' + key);
|
|
3113
3048
|
}
|
|
3114
|
-
if (prop === 'isSelected') {
|
|
3049
|
+
if (prop === '$isSelected') {
|
|
3115
3050
|
const parentPathArray = path.slice(0, -1);
|
|
3116
3051
|
const parentMeta = getShadowMetadata(stateKey, parentPathArray);
|
|
3117
3052
|
|
|
@@ -3128,7 +3063,7 @@ function createProxyHandler<T>(
|
|
|
3128
3063
|
return undefined;
|
|
3129
3064
|
}
|
|
3130
3065
|
|
|
3131
|
-
if (prop === 'setSelected') {
|
|
3066
|
+
if (prop === '$setSelected') {
|
|
3132
3067
|
return (value: boolean) => {
|
|
3133
3068
|
const parentPath = path.slice(0, -1);
|
|
3134
3069
|
const fullParentKey = stateKey + '.' + parentPath.join('.');
|
|
@@ -3148,7 +3083,7 @@ function createProxyHandler<T>(
|
|
|
3148
3083
|
};
|
|
3149
3084
|
}
|
|
3150
3085
|
|
|
3151
|
-
if (prop === 'toggleSelected') {
|
|
3086
|
+
if (prop === '$toggleSelected') {
|
|
3152
3087
|
return () => {
|
|
3153
3088
|
const parentPath = path.slice(0, -1);
|
|
3154
3089
|
const fullParentKey = stateKey + '.' + parentPath.join('.');
|
|
@@ -3170,11 +3105,11 @@ function createProxyHandler<T>(
|
|
|
3170
3105
|
notifySelectionComponents(stateKey, parentPath);
|
|
3171
3106
|
};
|
|
3172
3107
|
}
|
|
3173
|
-
if (prop === '_componentId') {
|
|
3108
|
+
if (prop === '$_componentId') {
|
|
3174
3109
|
return componentId;
|
|
3175
3110
|
}
|
|
3176
3111
|
if (path.length == 0) {
|
|
3177
|
-
if (prop === 'addZodValidation') {
|
|
3112
|
+
if (prop === '$addZodValidation') {
|
|
3178
3113
|
return (zodErrors: any[]) => {
|
|
3179
3114
|
zodErrors.forEach((error) => {
|
|
3180
3115
|
const currentMeta =
|
|
@@ -3203,7 +3138,7 @@ function createProxyHandler<T>(
|
|
|
3203
3138
|
});
|
|
3204
3139
|
};
|
|
3205
3140
|
}
|
|
3206
|
-
if (prop === 'clearZodValidation') {
|
|
3141
|
+
if (prop === '$clearZodValidation') {
|
|
3207
3142
|
return (path?: string[]) => {
|
|
3208
3143
|
if (!path) {
|
|
3209
3144
|
throw new Error('clearZodValidation requires a path');
|
|
@@ -3221,7 +3156,7 @@ function createProxyHandler<T>(
|
|
|
3221
3156
|
});
|
|
3222
3157
|
};
|
|
3223
3158
|
}
|
|
3224
|
-
if (prop === 'applyJsonPatch') {
|
|
3159
|
+
if (prop === '$applyJsonPatch') {
|
|
3225
3160
|
return (patches: Operation[]) => {
|
|
3226
3161
|
const store = getGlobalStore.getState();
|
|
3227
3162
|
const rootMeta = store.getShadowMetadata(stateKey, []);
|
|
@@ -3313,17 +3248,17 @@ function createProxyHandler<T>(
|
|
|
3313
3248
|
};
|
|
3314
3249
|
}
|
|
3315
3250
|
|
|
3316
|
-
if (prop === 'getComponents')
|
|
3251
|
+
if (prop === '$getComponents')
|
|
3317
3252
|
return () => getShadowMetadata(stateKey, [])?.components;
|
|
3318
|
-
if (prop === 'getAllFormRefs')
|
|
3253
|
+
if (prop === '$getAllFormRefs')
|
|
3319
3254
|
return () =>
|
|
3320
3255
|
formRefStore.getState().getFormRefsByStateKey(stateKey);
|
|
3321
3256
|
}
|
|
3322
|
-
if (prop === 'getFormRef') {
|
|
3257
|
+
if (prop === '$getFormRef') {
|
|
3323
3258
|
return () =>
|
|
3324
3259
|
formRefStore.getState().getFormRef(stateKey + '.' + path.join('.'));
|
|
3325
3260
|
}
|
|
3326
|
-
if (prop === 'validationWrapper') {
|
|
3261
|
+
if (prop === '$validationWrapper') {
|
|
3327
3262
|
return ({
|
|
3328
3263
|
children,
|
|
3329
3264
|
hideMessage,
|
|
@@ -3342,9 +3277,9 @@ function createProxyHandler<T>(
|
|
|
3342
3277
|
</ValidationWrapper>
|
|
3343
3278
|
);
|
|
3344
3279
|
}
|
|
3345
|
-
if (prop === '_stateKey') return stateKey;
|
|
3346
|
-
if (prop === '_path') return path;
|
|
3347
|
-
if (prop === 'update') {
|
|
3280
|
+
if (prop === '$_stateKey') return stateKey;
|
|
3281
|
+
if (prop === '$_path') return path;
|
|
3282
|
+
if (prop === '$update') {
|
|
3348
3283
|
return (payload: UpdateArg<T>) => {
|
|
3349
3284
|
effectiveSetState(payload as any, path, { updateType: 'update' });
|
|
3350
3285
|
|
|
@@ -3372,7 +3307,7 @@ function createProxyHandler<T>(
|
|
|
3372
3307
|
};
|
|
3373
3308
|
};
|
|
3374
3309
|
}
|
|
3375
|
-
if (prop === 'toggle') {
|
|
3310
|
+
if (prop === '$toggle') {
|
|
3376
3311
|
const { value: currentValueAtPath } = getScopedData(
|
|
3377
3312
|
stateKey,
|
|
3378
3313
|
path,
|
|
@@ -3388,7 +3323,19 @@ function createProxyHandler<T>(
|
|
|
3388
3323
|
});
|
|
3389
3324
|
};
|
|
3390
3325
|
}
|
|
3391
|
-
if (prop === '
|
|
3326
|
+
if (prop === '$isolate') {
|
|
3327
|
+
return (renderFn: (state: any) => React.ReactNode) => {
|
|
3328
|
+
return (
|
|
3329
|
+
<IsolatedComponentWrapper
|
|
3330
|
+
stateKey={stateKey}
|
|
3331
|
+
path={path}
|
|
3332
|
+
rebuildStateShape={rebuildStateShape}
|
|
3333
|
+
renderFn={renderFn}
|
|
3334
|
+
/>
|
|
3335
|
+
);
|
|
3336
|
+
};
|
|
3337
|
+
}
|
|
3338
|
+
if (prop === '$formElement') {
|
|
3392
3339
|
return (child: FormControl<T>, formOpts?: FormOptsType) => {
|
|
3393
3340
|
return (
|
|
3394
3341
|
<FormElementWrapper
|
|
@@ -3403,9 +3350,6 @@ function createProxyHandler<T>(
|
|
|
3403
3350
|
};
|
|
3404
3351
|
}
|
|
3405
3352
|
const nextPath = [...path, prop];
|
|
3406
|
-
const nextValue = getGlobalStore
|
|
3407
|
-
.getState()
|
|
3408
|
-
.getShadowValue(stateKey, nextPath);
|
|
3409
3353
|
return rebuildStateShape({
|
|
3410
3354
|
path: nextPath,
|
|
3411
3355
|
componentId: componentId!,
|
|
@@ -3421,53 +3365,49 @@ function createProxyHandler<T>(
|
|
|
3421
3365
|
}
|
|
3422
3366
|
|
|
3423
3367
|
const rootLevelMethods = {
|
|
3424
|
-
revertToInitialState: (obj?: { validationKey?: string }) => {
|
|
3368
|
+
$revertToInitialState: (obj?: { validationKey?: string }) => {
|
|
3425
3369
|
const shadowMeta = getGlobalStore
|
|
3426
3370
|
.getState()
|
|
3427
3371
|
.getShadowMetadata(stateKey, []);
|
|
3428
3372
|
let revertState;
|
|
3429
3373
|
|
|
3374
|
+
// Determine the correct state to revert to (same logic as before)
|
|
3430
3375
|
if (shadowMeta?.stateSource === 'server' && shadowMeta.baseServerState) {
|
|
3431
|
-
// Revert to last known server state
|
|
3432
3376
|
revertState = shadowMeta.baseServerState;
|
|
3433
3377
|
} else {
|
|
3434
|
-
// Revert to initial/default state
|
|
3435
3378
|
revertState = getGlobalStore.getState().initialStateGlobal[stateKey];
|
|
3436
3379
|
}
|
|
3437
|
-
const initialState =
|
|
3438
|
-
getGlobalStore.getState().initialStateGlobal[stateKey];
|
|
3439
3380
|
|
|
3381
|
+
// Perform necessary cleanup
|
|
3440
3382
|
clearSelectedIndexesForState(stateKey);
|
|
3441
3383
|
|
|
3442
|
-
|
|
3443
|
-
|
|
3384
|
+
// FIX 1: Use the IMMEDIATE, SYNCHRONOUS state reset function.
|
|
3385
|
+
// This is what your tests expect for a clean slate.
|
|
3386
|
+
initializeShadowState(stateKey, revertState);
|
|
3387
|
+
|
|
3388
|
+
// Rebuild the proxy's internal shape after the reset
|
|
3444
3389
|
rebuildStateShape({
|
|
3445
3390
|
path: [],
|
|
3446
3391
|
componentId: outerComponentId!,
|
|
3447
3392
|
});
|
|
3393
|
+
|
|
3394
|
+
// Handle localStorage side-effects
|
|
3448
3395
|
const initalOptionsGet = getInitialOptions(stateKey as string);
|
|
3449
3396
|
const localKey = isFunction(initalOptionsGet?.localStorage?.key)
|
|
3450
|
-
? initalOptionsGet?.localStorage?.key(
|
|
3397
|
+
? initalOptionsGet?.localStorage?.key(revertState)
|
|
3451
3398
|
: initalOptionsGet?.localStorage?.key;
|
|
3452
|
-
|
|
3453
3399
|
const storageKey = `${sessionId}-${stateKey}-${localKey}`;
|
|
3454
|
-
|
|
3455
3400
|
if (storageKey) {
|
|
3456
3401
|
localStorage.removeItem(storageKey);
|
|
3457
3402
|
}
|
|
3458
3403
|
|
|
3459
|
-
|
|
3460
|
-
|
|
3461
|
-
|
|
3462
|
-
if (stateEntry) {
|
|
3463
|
-
stateEntry?.components?.forEach((component) => {
|
|
3464
|
-
component.forceUpdate();
|
|
3465
|
-
});
|
|
3466
|
-
}
|
|
3404
|
+
// FIX 2: Use the library's BATCHED notification system instead of a manual forceUpdate loop.
|
|
3405
|
+
// This fixes the original infinite loop bug safely.
|
|
3406
|
+
notifyComponents(stateKey);
|
|
3467
3407
|
|
|
3468
|
-
return
|
|
3408
|
+
return revertState;
|
|
3469
3409
|
},
|
|
3470
|
-
updateInitialState: (newState: T) => {
|
|
3410
|
+
$updateInitialState: (newState: T) => {
|
|
3471
3411
|
stateVersion++;
|
|
3472
3412
|
|
|
3473
3413
|
const newUpdaterState = createProxyHandler(
|
|
@@ -3505,7 +3445,7 @@ function createProxyHandler<T>(
|
|
|
3505
3445
|
});
|
|
3506
3446
|
|
|
3507
3447
|
return {
|
|
3508
|
-
fetchId: (field: keyof T) => (newUpdaterState
|
|
3448
|
+
fetchId: (field: keyof T) => (newUpdaterState.$get() as any)[field],
|
|
3509
3449
|
};
|
|
3510
3450
|
},
|
|
3511
3451
|
};
|