cogsbox-state 0.5.476 → 0.5.478
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 +92 -0
- package/dist/CogsState.d.ts +78 -33
- package/dist/CogsState.d.ts.map +1 -1
- package/dist/CogsState.js +920 -841
- package/dist/CogsState.js.map +1 -1
- package/dist/Components.d.ts.map +1 -1
- package/dist/Components.js +110 -108
- package/dist/Components.js.map +1 -1
- package/dist/PluginRunner.d.ts.map +1 -1
- package/dist/PluginRunner.js +0 -1
- package/dist/PluginRunner.js.map +1 -1
- package/dist/index.js +35 -34
- package/dist/plugins.d.ts +1404 -198
- package/dist/plugins.d.ts.map +1 -1
- package/dist/plugins.js +141 -59
- package/dist/plugins.js.map +1 -1
- package/dist/store.d.ts +3 -0
- package/dist/store.d.ts.map +1 -1
- package/dist/store.js +470 -417
- package/dist/store.js.map +1 -1
- package/dist/utility.d.ts +1 -3
- package/dist/utility.d.ts.map +1 -1
- package/dist/utility.js +63 -73
- package/dist/utility.js.map +1 -1
- package/package.json +3 -3
- package/src/CogsState.tsx +286 -83
- package/src/Components.tsx +3 -1
- package/src/PluginRunner.tsx +2 -2
- package/src/plugins.ts +338 -28
- package/src/store.ts +131 -3
- package/src/utility.ts +1 -33
package/src/CogsState.tsx
CHANGED
|
@@ -1,6 +1,10 @@
|
|
|
1
1
|
'use client';
|
|
2
2
|
import { pluginStore } from './pluginStore';
|
|
3
|
-
import {
|
|
3
|
+
import {
|
|
4
|
+
FormWrapperParams,
|
|
5
|
+
type ChainMethodCallables,
|
|
6
|
+
type CogsPlugin,
|
|
7
|
+
} from './plugins';
|
|
4
8
|
import {
|
|
5
9
|
createElement,
|
|
6
10
|
startTransition,
|
|
@@ -79,7 +83,8 @@ type CutFunctionType<T> = (
|
|
|
79
83
|
options?: { waitForSync?: boolean }
|
|
80
84
|
) => StateObject<T>;
|
|
81
85
|
|
|
82
|
-
export type InferArrayElement<T> =
|
|
86
|
+
export type InferArrayElement<T> =
|
|
87
|
+
NonNullable<T> extends (infer U)[] ? U : never;
|
|
83
88
|
|
|
84
89
|
export type FormControl<T> = (obj: FormElementParams<T>) => JSX.Element;
|
|
85
90
|
|
|
@@ -175,6 +180,7 @@ export type EndType<
|
|
|
175
180
|
selectText: () => void;
|
|
176
181
|
};
|
|
177
182
|
$removeStorage: () => void;
|
|
183
|
+
$setRaw: (value: T) => void;
|
|
178
184
|
$sync: () => void;
|
|
179
185
|
$validationWrapper: ({
|
|
180
186
|
children,
|
|
@@ -303,20 +309,21 @@ export type StateObject<
|
|
|
303
309
|
> = {
|
|
304
310
|
(): T;
|
|
305
311
|
(newValue: T | ((prev: T) => T)): void;
|
|
306
|
-
} & (T extends any[]
|
|
312
|
+
} & ([NonNullable<T>] extends [any[]] // <-- Wrap in brackets
|
|
307
313
|
? ArrayEndType<T, TPlugins>
|
|
308
|
-
: T extends Record<string, unknown> | object
|
|
309
|
-
? {
|
|
310
|
-
|
|
314
|
+
: [NonNullable<T>] extends [Record<string, unknown> | object] // <-- Wrap in brackets
|
|
315
|
+
? {
|
|
316
|
+
[K in keyof NonNullable<T>]-?: StateObject<NonNullable<T>[K], TPlugins>;
|
|
317
|
+
}
|
|
318
|
+
: {}) & // Fallback to {} since we intersect EndType below anyway
|
|
311
319
|
EndType<T, TPlugins> & {
|
|
312
|
-
|
|
313
|
-
$toggle: T extends boolean ? () => void : never;
|
|
320
|
+
$toggle: NonNullable<T> extends boolean ? () => void : never;
|
|
314
321
|
$validate: () => { success: boolean; data?: T; error?: any };
|
|
315
322
|
$_componentId: string | null;
|
|
316
323
|
$getComponents: () => ComponentsType;
|
|
317
324
|
$_initialState: T;
|
|
318
325
|
$updateInitialState: (newState: T | null) => {
|
|
319
|
-
fetchId: (field: keyof T) => string | number;
|
|
326
|
+
fetchId: (field: keyof NonNullable<T>) => string | number;
|
|
320
327
|
};
|
|
321
328
|
$initializeAndMergeShadowState: (newState: any | null) => void;
|
|
322
329
|
$_isLoading: boolean;
|
|
@@ -332,10 +339,23 @@ export type StateObject<
|
|
|
332
339
|
}) => void
|
|
333
340
|
) => void;
|
|
334
341
|
$getLocalStorage: (key: string) => LocalStorageData<T> | null;
|
|
335
|
-
}
|
|
336
|
-
|
|
342
|
+
} & PluginChainMethodCallables<TPlugins>;
|
|
337
343
|
export type CogsUpdate<T extends unknown> = UpdateType<T>;
|
|
338
344
|
|
|
345
|
+
type UnionToIntersection<T> = (
|
|
346
|
+
T extends any ? (arg: T) => void : never
|
|
347
|
+
) extends (arg: infer I) => void
|
|
348
|
+
? I
|
|
349
|
+
: never;
|
|
350
|
+
|
|
351
|
+
type PluginChainMethodCallables<
|
|
352
|
+
TPlugins extends readonly CogsPlugin<any, any, any, any, any>[],
|
|
353
|
+
> = UnionToIntersection<
|
|
354
|
+
TPlugins[number] extends CogsPlugin<any, any, any, any, any, infer TMethods>
|
|
355
|
+
? ChainMethodCallables<TMethods>
|
|
356
|
+
: {}
|
|
357
|
+
>;
|
|
358
|
+
|
|
339
359
|
type EffectiveSetStateArg<
|
|
340
360
|
T,
|
|
341
361
|
UpdateType extends 'update' | 'insert' | 'cut',
|
|
@@ -504,16 +524,6 @@ export type FormsElementsType<
|
|
|
504
524
|
key?: string;
|
|
505
525
|
}) => React.ReactNode;
|
|
506
526
|
};
|
|
507
|
-
export type CogsInitialState<T> =
|
|
508
|
-
| {
|
|
509
|
-
initialState: T;
|
|
510
|
-
}
|
|
511
|
-
| CreateStateOptionsType<T>;
|
|
512
|
-
|
|
513
|
-
export type TransformedStateType<T> = {
|
|
514
|
-
[P in keyof T]: T[P] extends CogsInitialState<infer U> ? U : T[P];
|
|
515
|
-
};
|
|
516
|
-
|
|
517
527
|
const {
|
|
518
528
|
getInitialOptions,
|
|
519
529
|
updateInitialStateGlobal,
|
|
@@ -692,16 +702,6 @@ function setOptions<StateKey, Opt>({
|
|
|
692
702
|
|
|
693
703
|
return mergedOptions;
|
|
694
704
|
}
|
|
695
|
-
export function addStateOptions<T>(
|
|
696
|
-
initialState: T,
|
|
697
|
-
options: CreateStateOptionsType<T>
|
|
698
|
-
) {
|
|
699
|
-
return {
|
|
700
|
-
...options,
|
|
701
|
-
initialState,
|
|
702
|
-
_addStateOptions: true,
|
|
703
|
-
};
|
|
704
|
-
}
|
|
705
705
|
export type PluginData = {
|
|
706
706
|
plugin: CogsPlugin<any, any, any, any, any>;
|
|
707
707
|
options: any;
|
|
@@ -721,60 +721,70 @@ export const createCogsState = <
|
|
|
721
721
|
validation?: ValidationOptionsType;
|
|
722
722
|
}
|
|
723
723
|
) => {
|
|
724
|
-
type
|
|
725
|
-
|
|
726
|
-
|
|
727
|
-
|
|
728
|
-
|
|
729
|
-
any,
|
|
730
|
-
any
|
|
731
|
-
>
|
|
724
|
+
type ExtractPluginOptions<T> = T extends {
|
|
725
|
+
useHook?: (params: { options: infer O }) => any; // infers O here
|
|
726
|
+
}
|
|
727
|
+
? O
|
|
728
|
+
: T extends CogsPlugin<string, infer O, any, any, any> // AND here
|
|
732
729
|
? O
|
|
733
730
|
: never;
|
|
731
|
+
|
|
732
|
+
type PluginOptions = {
|
|
733
|
+
[K in TPlugins[number] as K['name']]?: ExtractPluginOptions<K>;
|
|
734
734
|
};
|
|
735
735
|
|
|
736
736
|
if (opt?.plugins) {
|
|
737
737
|
pluginStore.getState().setRegisteredPlugins(opt.plugins as any);
|
|
738
738
|
}
|
|
739
739
|
|
|
740
|
+
type UnionToIntersection<U> = (
|
|
741
|
+
U extends any ? (k: U) => void : never
|
|
742
|
+
) extends (k: infer I) => void
|
|
743
|
+
? I
|
|
744
|
+
: never;
|
|
745
|
+
|
|
746
|
+
type FullState = State &
|
|
747
|
+
UnionToIntersection<
|
|
748
|
+
{
|
|
749
|
+
[K in keyof TPlugins]: TPlugins[K] extends {
|
|
750
|
+
initialState: () => infer S;
|
|
751
|
+
}
|
|
752
|
+
? S
|
|
753
|
+
: {};
|
|
754
|
+
}[number]
|
|
755
|
+
>;
|
|
756
|
+
|
|
757
|
+
const pluginState: Record<string, unknown> = {};
|
|
758
|
+
if (opt?.plugins) {
|
|
759
|
+
for (const plugin of opt.plugins) {
|
|
760
|
+
if (typeof plugin.initialState === 'function') {
|
|
761
|
+
Object.assign(pluginState, plugin.initialState());
|
|
762
|
+
}
|
|
763
|
+
}
|
|
764
|
+
}
|
|
765
|
+
const mergedInitialState = { ...pluginState, ...initialState } as FullState;
|
|
766
|
+
|
|
740
767
|
const [statePart, initialOptionsPart] =
|
|
741
|
-
transformStateFunc<
|
|
768
|
+
transformStateFunc<FullState>(mergedInitialState);
|
|
742
769
|
|
|
743
|
-
// FIX: Store options INCLUDING validation for each state key
|
|
744
770
|
Object.keys(statePart).forEach((key) => {
|
|
745
|
-
let
|
|
746
|
-
|
|
747
|
-
const mergedOptions: any = {
|
|
748
|
-
...existingOptions,
|
|
749
|
-
};
|
|
771
|
+
let mergedOptions: any = {};
|
|
750
772
|
|
|
751
773
|
if (opt?.formElements) {
|
|
752
|
-
mergedOptions.formElements =
|
|
753
|
-
...opt.formElements,
|
|
754
|
-
...(existingOptions.formElements || {}),
|
|
755
|
-
};
|
|
774
|
+
mergedOptions.formElements = opt.formElements;
|
|
756
775
|
}
|
|
757
776
|
|
|
758
777
|
mergedOptions.validation = {
|
|
759
778
|
onBlur: 'error',
|
|
760
779
|
...opt?.validation,
|
|
761
|
-
...(existingOptions.validation || {}),
|
|
762
780
|
};
|
|
763
781
|
|
|
764
|
-
if (opt?.validation?.key && !existingOptions.validation?.key) {
|
|
765
|
-
mergedOptions.validation.key = `${opt.validation.key}.${key}`;
|
|
766
|
-
}
|
|
767
|
-
|
|
768
782
|
const existingGlobalOptions = getInitialOptions(key);
|
|
769
783
|
|
|
770
784
|
const finalOptions = existingGlobalOptions
|
|
771
785
|
? {
|
|
772
786
|
...existingGlobalOptions,
|
|
773
|
-
|
|
774
|
-
formElements: {
|
|
775
|
-
...existingGlobalOptions.formElements,
|
|
776
|
-
...mergedOptions.formElements,
|
|
777
|
-
},
|
|
787
|
+
formElements: opt?.formElements,
|
|
778
788
|
validation: {
|
|
779
789
|
...existingGlobalOptions.validation,
|
|
780
790
|
...mergedOptions.validation,
|
|
@@ -782,7 +792,9 @@ export const createCogsState = <
|
|
|
782
792
|
}
|
|
783
793
|
: mergedOptions;
|
|
784
794
|
|
|
785
|
-
|
|
795
|
+
if (Object.keys(finalOptions).length > 0) {
|
|
796
|
+
setInitialStateOptions(key, finalOptions);
|
|
797
|
+
}
|
|
786
798
|
});
|
|
787
799
|
|
|
788
800
|
Object.keys(statePart).forEach((key) => {
|
|
@@ -793,19 +805,42 @@ export const createCogsState = <
|
|
|
793
805
|
} & {};
|
|
794
806
|
type StateKeys = keyof typeof statePart;
|
|
795
807
|
|
|
808
|
+
// Flattens the 4x spam into a single clean object
|
|
809
|
+
type CleanIntersection<T> = T extends object ? { [K in keyof T]: T[K] } : T;
|
|
810
|
+
|
|
811
|
+
// Helper to find which keys are "keyed" (like queryParams)
|
|
812
|
+
type KeyedKeys<P> = {
|
|
813
|
+
[K in keyof P]-?: NonNullable<P[K]> extends { __key: 'keyed'; map: any }
|
|
814
|
+
? K
|
|
815
|
+
: never;
|
|
816
|
+
}[keyof P];
|
|
817
|
+
|
|
796
818
|
const useCogsState = <StateKey extends StateKeys>(
|
|
797
819
|
stateKey: StateKey,
|
|
798
820
|
options?: Prettify<
|
|
799
821
|
OptionsType<(typeof statePart)[StateKey], never> & {
|
|
800
822
|
[PName in keyof PluginOptions]?: PluginOptions[PName] extends infer P
|
|
801
823
|
? P extends Record<string, any>
|
|
802
|
-
?
|
|
803
|
-
|
|
804
|
-
|
|
805
|
-
|
|
806
|
-
|
|
807
|
-
|
|
808
|
-
|
|
824
|
+
? Prettify<
|
|
825
|
+
// 1. NON-KEYED: Partial physically forces stateRoom to be optional
|
|
826
|
+
Partial<Pick<P, Exclude<keyof P, KeyedKeys<P>>>> &
|
|
827
|
+
// 2. KEYED: Resolves queryParams and squashes the 4x intersection
|
|
828
|
+
{
|
|
829
|
+
[K in KeyedKeys<P> as StateKey extends keyof NonNullable<
|
|
830
|
+
P[K]
|
|
831
|
+
>['map']
|
|
832
|
+
? NonNullable<P[K]>['map'][StateKey] extends undefined
|
|
833
|
+
? never
|
|
834
|
+
: keyof NonNullable<P[K]>['map'][StateKey] extends never
|
|
835
|
+
? never
|
|
836
|
+
: K
|
|
837
|
+
: never]: CleanIntersection<
|
|
838
|
+
StateKey extends keyof NonNullable<P[K]>['map']
|
|
839
|
+
? NonNullable<P[K]>['map'][StateKey]
|
|
840
|
+
: never
|
|
841
|
+
>;
|
|
842
|
+
}
|
|
843
|
+
>
|
|
809
844
|
: P
|
|
810
845
|
: never;
|
|
811
846
|
}
|
|
@@ -825,7 +860,7 @@ export const createCogsState = <
|
|
|
825
860
|
const thiState =
|
|
826
861
|
getShadowValue(stateKey as string, []) || statePart[stateKey as string];
|
|
827
862
|
|
|
828
|
-
const updater = useCogsStateFn<(typeof statePart)[StateKey]
|
|
863
|
+
const updater = useCogsStateFn<(typeof statePart)[StateKey]>(
|
|
829
864
|
thiState,
|
|
830
865
|
{
|
|
831
866
|
stateKey: stateKey as string,
|
|
@@ -858,7 +893,7 @@ export const createCogsState = <
|
|
|
858
893
|
};
|
|
859
894
|
}, [stateKey, updater]);
|
|
860
895
|
|
|
861
|
-
return updater
|
|
896
|
+
return updater as StateObject<(typeof statePart)[StateKey]>;
|
|
862
897
|
};
|
|
863
898
|
|
|
864
899
|
function setCogsOptionsByKey<StateKey extends StateKeys>(
|
|
@@ -984,6 +1019,18 @@ const loadFromLocalStorage = (localStorageKey: string) => {
|
|
|
984
1019
|
return null;
|
|
985
1020
|
}
|
|
986
1021
|
};
|
|
1022
|
+
|
|
1023
|
+
const removeFromLocalStorage = (localStorageKey?: string) => {
|
|
1024
|
+
if (!localStorageKey) return;
|
|
1025
|
+
|
|
1026
|
+
try {
|
|
1027
|
+
if (typeof window !== 'undefined' && window.localStorage) {
|
|
1028
|
+
window.localStorage.removeItem(localStorageKey);
|
|
1029
|
+
}
|
|
1030
|
+
} catch (error) {
|
|
1031
|
+
console.error('Error removing from localStorage:', error);
|
|
1032
|
+
}
|
|
1033
|
+
};
|
|
987
1034
|
const loadAndApplyLocalStorage = (stateKey: string, options: any) => {
|
|
988
1035
|
const currentState = getShadowValue(stateKey, []);
|
|
989
1036
|
const { sessionId } = useCogsConfig();
|
|
@@ -1210,7 +1257,7 @@ function getComponentNotifications(
|
|
|
1210
1257
|
const pathMeta = getShadowMetadata(stateKey, currentPath);
|
|
1211
1258
|
|
|
1212
1259
|
if (pathMeta?.pathComponents) {
|
|
1213
|
-
pathMeta.pathComponents.forEach((componentId
|
|
1260
|
+
pathMeta.pathComponents.forEach((componentId) => {
|
|
1214
1261
|
const component = rootMeta.components?.get(componentId);
|
|
1215
1262
|
if (component) {
|
|
1216
1263
|
componentsToNotify.add(component);
|
|
@@ -1499,7 +1546,7 @@ function createEffectiveSetState<T>(
|
|
|
1499
1546
|
|
|
1500
1547
|
export function useCogsStateFn<
|
|
1501
1548
|
TStateObject extends unknown,
|
|
1502
|
-
const TPlugins extends readonly CogsPlugin<any, any, any, any, any>[],
|
|
1549
|
+
const TPlugins extends readonly CogsPlugin<any, any, any, any, any>[] = [],
|
|
1503
1550
|
>(
|
|
1504
1551
|
stateObject: TStateObject,
|
|
1505
1552
|
{
|
|
@@ -1959,6 +2006,61 @@ function getScopedData(stateKey: string, path: string[], meta?: MetaData) {
|
|
|
1959
2006
|
};
|
|
1960
2007
|
}
|
|
1961
2008
|
|
|
2009
|
+
function pathMatchesPattern(path: string[], pattern?: string[]) {
|
|
2010
|
+
if (!pattern) return true;
|
|
2011
|
+
if (path.length !== pattern.length) return false;
|
|
2012
|
+
|
|
2013
|
+
return pattern.every((segment, index) => {
|
|
2014
|
+
return segment === '*' || segment === path[index];
|
|
2015
|
+
});
|
|
2016
|
+
}
|
|
2017
|
+
|
|
2018
|
+
function valueMatchesChainTarget(value: any, target: string) {
|
|
2019
|
+
if (target === 'any') return true;
|
|
2020
|
+
if (target === 'array') return Array.isArray(value);
|
|
2021
|
+
if (target === 'boolean') return typeof value === 'boolean';
|
|
2022
|
+
if (target === 'object') {
|
|
2023
|
+
return value !== null && typeof value === 'object' && !Array.isArray(value);
|
|
2024
|
+
}
|
|
2025
|
+
if (target === 'primitive') {
|
|
2026
|
+
return (
|
|
2027
|
+
value === null || (typeof value !== 'object' && !Array.isArray(value))
|
|
2028
|
+
);
|
|
2029
|
+
}
|
|
2030
|
+
return false;
|
|
2031
|
+
}
|
|
2032
|
+
|
|
2033
|
+
function getFieldRefsForPath(stateKey: string, path: string[]) {
|
|
2034
|
+
const meta = getGlobalStore.getState().getShadowMetadata(stateKey, path);
|
|
2035
|
+
if (!meta?.clientActivityState?.elements) return [];
|
|
2036
|
+
const refs: RefObject<any>[] = [];
|
|
2037
|
+
meta.clientActivityState.elements.forEach((entry: any) => {
|
|
2038
|
+
if (entry.domRef?.current) refs.push(entry.domRef);
|
|
2039
|
+
});
|
|
2040
|
+
return refs;
|
|
2041
|
+
}
|
|
2042
|
+
|
|
2043
|
+
function getFieldElementsForPath(stateKey: string, path: string[]) {
|
|
2044
|
+
const refs = getFieldRefsForPath(stateKey, path);
|
|
2045
|
+
return refs.map((ref) => ref.current).filter(Boolean);
|
|
2046
|
+
}
|
|
2047
|
+
|
|
2048
|
+
function setFieldDisabledForPath(
|
|
2049
|
+
stateKey: string,
|
|
2050
|
+
path: string[],
|
|
2051
|
+
disabled: boolean
|
|
2052
|
+
) {
|
|
2053
|
+
getFieldElementsForPath(stateKey, path).forEach((el: any) => {
|
|
2054
|
+
if ('disabled' in el) {
|
|
2055
|
+
el.disabled = disabled;
|
|
2056
|
+
return;
|
|
2057
|
+
}
|
|
2058
|
+
|
|
2059
|
+
el.style.pointerEvents = disabled ? 'none' : '';
|
|
2060
|
+
el.setAttribute('aria-disabled', String(disabled));
|
|
2061
|
+
});
|
|
2062
|
+
}
|
|
2063
|
+
|
|
1962
2064
|
function createProxyHandler<
|
|
1963
2065
|
T,
|
|
1964
2066
|
const TPlugins extends readonly CogsPlugin<any, any, any, any, any>[],
|
|
@@ -1979,6 +2081,11 @@ function createProxyHandler<
|
|
|
1979
2081
|
componentId: string;
|
|
1980
2082
|
meta?: MetaData;
|
|
1981
2083
|
}): any {
|
|
2084
|
+
const rawMeta = getShadowMetadata(stateKey, path);
|
|
2085
|
+
if (rawMeta?.isRaw) {
|
|
2086
|
+
return getShadowValue(stateKey, path);
|
|
2087
|
+
}
|
|
2088
|
+
|
|
1982
2089
|
const derivationSignature = meta
|
|
1983
2090
|
? JSON.stringify(meta.arrayViews || meta.transforms)
|
|
1984
2091
|
: '';
|
|
@@ -2055,6 +2162,91 @@ function createProxyHandler<
|
|
|
2055
2162
|
}
|
|
2056
2163
|
|
|
2057
2164
|
if (typeof prop === 'string' && !prop.startsWith('$')) {
|
|
2165
|
+
const { value } = getScopedData(stateKey, path, meta);
|
|
2166
|
+
const hasStateChild =
|
|
2167
|
+
value !== null &&
|
|
2168
|
+
typeof value === 'object' &&
|
|
2169
|
+
!Array.isArray(value) &&
|
|
2170
|
+
Object.prototype.hasOwnProperty.call(value, prop);
|
|
2171
|
+
|
|
2172
|
+
if (hasStateChild) {
|
|
2173
|
+
const nextPath = [...path, prop];
|
|
2174
|
+
return rebuildStateShape({
|
|
2175
|
+
path: nextPath,
|
|
2176
|
+
componentId: componentId!,
|
|
2177
|
+
meta,
|
|
2178
|
+
});
|
|
2179
|
+
}
|
|
2180
|
+
|
|
2181
|
+
const registeredPlugins = pluginStore.getState().registeredPlugins;
|
|
2182
|
+
for (const plugin of registeredPlugins) {
|
|
2183
|
+
const chainMethod = (plugin.chainMethods as any)?.[prop];
|
|
2184
|
+
if (!chainMethod) continue;
|
|
2185
|
+
if (!pathMatchesPattern(path, chainMethod.pathPattern)) continue;
|
|
2186
|
+
if (!valueMatchesChainTarget(value, chainMethod.target)) continue;
|
|
2187
|
+
|
|
2188
|
+
return (...args: any[]) => {
|
|
2189
|
+
const store = pluginStore.getState();
|
|
2190
|
+
const options = store.pluginOptions
|
|
2191
|
+
.get(stateKey)
|
|
2192
|
+
?.get(plugin.name);
|
|
2193
|
+
const hookData = store.getHookResult(stateKey, plugin.name);
|
|
2194
|
+
|
|
2195
|
+
return chainMethod.handler(
|
|
2196
|
+
{
|
|
2197
|
+
stateKey,
|
|
2198
|
+
path,
|
|
2199
|
+
pluginName: plugin.name,
|
|
2200
|
+
options,
|
|
2201
|
+
hookData,
|
|
2202
|
+
$get: () => getScopedData(stateKey, path, meta).value,
|
|
2203
|
+
$update: (payload: any) => {
|
|
2204
|
+
effectiveSetState(payload, path, {
|
|
2205
|
+
updateType: 'update',
|
|
2206
|
+
});
|
|
2207
|
+
|
|
2208
|
+
return {
|
|
2209
|
+
synced: () => {
|
|
2210
|
+
const shadowMeta = getGlobalStore
|
|
2211
|
+
.getState()
|
|
2212
|
+
.getShadowMetadata(stateKey, path);
|
|
2213
|
+
|
|
2214
|
+
setShadowMetadata(stateKey, path, {
|
|
2215
|
+
...shadowMeta,
|
|
2216
|
+
isDirty: false,
|
|
2217
|
+
stateSource: 'server',
|
|
2218
|
+
lastServerSync: Date.now(),
|
|
2219
|
+
});
|
|
2220
|
+
},
|
|
2221
|
+
};
|
|
2222
|
+
},
|
|
2223
|
+
$applyOperation: (
|
|
2224
|
+
operation: UpdateTypeDetail,
|
|
2225
|
+
metaData?: Record<string, any>
|
|
2226
|
+
) => {
|
|
2227
|
+
effectiveSetState(operation.newValue, operation.path, {
|
|
2228
|
+
updateType: operation.updateType,
|
|
2229
|
+
itemId: operation.itemId,
|
|
2230
|
+
metaData,
|
|
2231
|
+
});
|
|
2232
|
+
},
|
|
2233
|
+
getFieldMetaData: () =>
|
|
2234
|
+
getPluginMetaDataMap(stateKey, path)?.get(plugin.name),
|
|
2235
|
+
setFieldMetaData: (data: Record<string, any>) =>
|
|
2236
|
+
setPluginMetaData(stateKey, path, plugin.name, data),
|
|
2237
|
+
removeFieldMetaData: () =>
|
|
2238
|
+
removePluginMetaData(stateKey, path, plugin.name),
|
|
2239
|
+
getFieldRefs: () => getFieldRefsForPath(stateKey, path),
|
|
2240
|
+
getFieldElements: () =>
|
|
2241
|
+
getFieldElementsForPath(stateKey, path),
|
|
2242
|
+
setFieldDisabled: (disabled: boolean) =>
|
|
2243
|
+
setFieldDisabledForPath(stateKey, path, disabled),
|
|
2244
|
+
},
|
|
2245
|
+
...args
|
|
2246
|
+
);
|
|
2247
|
+
};
|
|
2248
|
+
}
|
|
2249
|
+
|
|
2058
2250
|
const nextPath = [...path, prop];
|
|
2059
2251
|
return rebuildStateShape({
|
|
2060
2252
|
path: nextPath,
|
|
@@ -2171,8 +2363,18 @@ function createProxyHandler<
|
|
|
2171
2363
|
const localKey = isFunction(initalOptionsGet?.localStorage?.key)
|
|
2172
2364
|
? initalOptionsGet.localStorage.key(initialState)
|
|
2173
2365
|
: initalOptionsGet?.localStorage?.key;
|
|
2174
|
-
const storageKey =
|
|
2175
|
-
|
|
2366
|
+
const storageKey =
|
|
2367
|
+
sessionId && localKey
|
|
2368
|
+
? `${sessionId}-${stateKey}-${localKey}`
|
|
2369
|
+
: undefined;
|
|
2370
|
+
removeFromLocalStorage(storageKey);
|
|
2371
|
+
};
|
|
2372
|
+
}
|
|
2373
|
+
if (prop === '$setRaw') {
|
|
2374
|
+
return (value: any) => {
|
|
2375
|
+
const currentMeta = getShadowMetadata(stateKey, path) || {};
|
|
2376
|
+
setShadowMetadata(stateKey, path, { ...currentMeta, isRaw: true });
|
|
2377
|
+
effectiveSetState(value, path, { updateType: 'update' });
|
|
2176
2378
|
};
|
|
2177
2379
|
}
|
|
2178
2380
|
|
|
@@ -3323,10 +3525,11 @@ function createProxyHandler<
|
|
|
3323
3525
|
const localKey = isFunction(initalOptionsGet?.localStorage?.key)
|
|
3324
3526
|
? initalOptionsGet?.localStorage?.key(revertState)
|
|
3325
3527
|
: initalOptionsGet?.localStorage?.key;
|
|
3326
|
-
const storageKey =
|
|
3327
|
-
|
|
3328
|
-
|
|
3329
|
-
|
|
3528
|
+
const storageKey =
|
|
3529
|
+
sessionId && localKey
|
|
3530
|
+
? `${sessionId}-${stateKey}-${localKey}`
|
|
3531
|
+
: undefined;
|
|
3532
|
+
removeFromLocalStorage(storageKey);
|
|
3330
3533
|
|
|
3331
3534
|
notifyComponents(stateKey);
|
|
3332
3535
|
|
|
@@ -3350,11 +3553,11 @@ function createProxyHandler<
|
|
|
3350
3553
|
? initalOptionsGet?.localStorage?.key(initialState)
|
|
3351
3554
|
: initalOptionsGet?.localStorage?.key;
|
|
3352
3555
|
|
|
3353
|
-
const storageKey =
|
|
3354
|
-
|
|
3355
|
-
|
|
3356
|
-
|
|
3357
|
-
|
|
3556
|
+
const storageKey =
|
|
3557
|
+
sessionId && localKey
|
|
3558
|
+
? `${sessionId}-${stateKey}-${localKey}`
|
|
3559
|
+
: undefined;
|
|
3560
|
+
removeFromLocalStorage(storageKey);
|
|
3358
3561
|
startTransition(() => {
|
|
3359
3562
|
updateInitialStateGlobal(stateKey, newState);
|
|
3360
3563
|
initializeShadowState(stateKey, newState);
|
package/src/Components.tsx
CHANGED
|
@@ -271,6 +271,7 @@ export function FormElementWrapper({
|
|
|
271
271
|
|
|
272
272
|
useEffect(() => {
|
|
273
273
|
const { getShadowMetadata, setShadowMetadata } = getGlobalStore.getState();
|
|
274
|
+
console.log('FormElementWrapper effect running for:', stateKey, path);
|
|
274
275
|
|
|
275
276
|
// Initialize clientActivityState if needed
|
|
276
277
|
const currentMeta = getShadowMetadata(stateKey, path) || {};
|
|
@@ -302,7 +303,7 @@ export function FormElementWrapper({
|
|
|
302
303
|
inputType: formElementRef.current?.type,
|
|
303
304
|
mountedAt: Date.now(),
|
|
304
305
|
});
|
|
305
|
-
|
|
306
|
+
console.log('currentMeta', currentMeta);
|
|
306
307
|
setShadowMetadata(stateKey, path, currentMeta);
|
|
307
308
|
|
|
308
309
|
// Subscribe to path updates
|
|
@@ -551,6 +552,7 @@ export function FormElementWrapper({
|
|
|
551
552
|
</ValidationWrapper>
|
|
552
553
|
);
|
|
553
554
|
}
|
|
555
|
+
|
|
554
556
|
export function useRegisterComponent(
|
|
555
557
|
stateKey: string,
|
|
556
558
|
componentId: string,
|
package/src/PluginRunner.tsx
CHANGED
|
@@ -8,7 +8,6 @@ import {
|
|
|
8
8
|
} from './plugins';
|
|
9
9
|
import type { CogsPlugin } from './plugins';
|
|
10
10
|
import type { StateObject, UpdateTypeDetail } from './CogsState';
|
|
11
|
-
import { ClientActivityState, FormEventType } from './store';
|
|
12
11
|
|
|
13
12
|
const { setHookResult, removeHookResult } = pluginStore.getState();
|
|
14
13
|
|
|
@@ -118,7 +117,7 @@ const PluginInstance = React.memo(
|
|
|
118
117
|
options,
|
|
119
118
|
hookData: hookDataRef.current,
|
|
120
119
|
...deconstructed,
|
|
121
|
-
...scopedMetadata,
|
|
120
|
+
...scopedMetadata,
|
|
122
121
|
});
|
|
123
122
|
}
|
|
124
123
|
};
|
|
@@ -177,6 +176,7 @@ export function PluginRunner({ children }: { children: React.ReactNode }) {
|
|
|
177
176
|
// this component will re-render to update the list of PluginInstances.
|
|
178
177
|
useEffect(() => {
|
|
179
178
|
const unsubscribe = pluginStore.subscribe(forceUpdate);
|
|
179
|
+
|
|
180
180
|
return unsubscribe;
|
|
181
181
|
}, []);
|
|
182
182
|
|