cogsbox-state 0.5.459 → 0.5.461
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/dist/CogsState.d.ts +24 -12
- package/dist/CogsState.d.ts.map +1 -1
- package/dist/CogsState.jsx +1229 -1229
- package/dist/CogsState.jsx.map +1 -1
- package/dist/TRPCValidationLink.d.ts.map +1 -1
- package/dist/TRPCValidationLink.js.map +1 -1
- package/dist/store.d.ts +0 -4
- package/dist/store.d.ts.map +1 -1
- package/dist/store.js +78 -133
- package/dist/store.js.map +1 -1
- package/package.json +1 -1
- package/src/CogsState.tsx +142 -241
- package/src/TRPCValidationLink.ts +1 -1
- package/src/store.ts +0 -93
package/src/CogsState.tsx
CHANGED
|
@@ -251,7 +251,8 @@ export type ValidationError = {
|
|
|
251
251
|
};
|
|
252
252
|
type EffectFunction<T, R> = (state: T, deps: any[]) => R;
|
|
253
253
|
export type EndType<T, IsArrayElement = false> = {
|
|
254
|
-
|
|
254
|
+
addZodValidation: (errors: ValidationError[]) => void;
|
|
255
|
+
clearZodValidation: (paths?: string[]) => void;
|
|
255
256
|
applyJsonPatch: (patches: any[]) => void;
|
|
256
257
|
update: UpdateType<T>;
|
|
257
258
|
_path: string[];
|
|
@@ -297,7 +298,7 @@ export type StateObject<T> = (T extends any[]
|
|
|
297
298
|
getAllFormRefs: () => Map<string, React.RefObject<any>>;
|
|
298
299
|
_componentId: string | null;
|
|
299
300
|
getComponents: () => ComponentsType;
|
|
300
|
-
|
|
301
|
+
|
|
301
302
|
_initialState: T;
|
|
302
303
|
updateInitialState: (newState: T | null) => {
|
|
303
304
|
fetchId: (field: keyof T) => string | number;
|
|
@@ -375,12 +376,23 @@ type ValidationOptionsType = {
|
|
|
375
376
|
|
|
376
377
|
onBlur?: boolean;
|
|
377
378
|
};
|
|
379
|
+
type UseSyncType<T> = (state: T, a: SyncOptionsType<any>) => SyncApi;
|
|
380
|
+
type SyncOptionsType<TApiParams> = {
|
|
381
|
+
apiParams: TApiParams;
|
|
382
|
+
stateKey?: string;
|
|
383
|
+
stateRoom:
|
|
384
|
+
| number
|
|
385
|
+
| string
|
|
386
|
+
| (({ clientId }: { clientId: string }) => string | null);
|
|
387
|
+
connect?: boolean;
|
|
388
|
+
inMemoryState?: boolean;
|
|
389
|
+
};
|
|
378
390
|
export type OptionsType<T extends unknown = unknown, TApiParams = never> = {
|
|
379
391
|
log?: boolean;
|
|
380
392
|
componentId?: string;
|
|
381
|
-
|
|
382
|
-
validation?: ValidationOptionsType;
|
|
393
|
+
syncOptions?: SyncOptionsType<TApiParams>;
|
|
383
394
|
|
|
395
|
+
validation?: ValidationOptionsType;
|
|
384
396
|
serverState?: {
|
|
385
397
|
id?: string | number;
|
|
386
398
|
data?: T;
|
|
@@ -390,9 +402,10 @@ export type OptionsType<T extends unknown = unknown, TApiParams = never> = {
|
|
|
390
402
|
| boolean
|
|
391
403
|
| {
|
|
392
404
|
strategy: 'append' | 'prepend' | 'diff';
|
|
393
|
-
key?: string;
|
|
405
|
+
key?: string;
|
|
394
406
|
};
|
|
395
407
|
};
|
|
408
|
+
|
|
396
409
|
sync?: {
|
|
397
410
|
action: (state: T) => Promise<{
|
|
398
411
|
success: boolean;
|
|
@@ -481,7 +494,6 @@ function setAndMergeOptions(stateKey: string, newOptions: OptionsType<any>) {
|
|
|
481
494
|
...newOptions,
|
|
482
495
|
});
|
|
483
496
|
}
|
|
484
|
-
|
|
485
497
|
function setOptions<StateKey, Opt>({
|
|
486
498
|
stateKey,
|
|
487
499
|
options,
|
|
@@ -525,10 +537,19 @@ function setOptions<StateKey, Opt>({
|
|
|
525
537
|
}
|
|
526
538
|
}
|
|
527
539
|
|
|
540
|
+
// Always preserve syncOptions if it exists in mergedOptions but not in options
|
|
541
|
+
if (
|
|
542
|
+
mergedOptions.syncOptions &&
|
|
543
|
+
(!options || !options.hasOwnProperty('syncOptions'))
|
|
544
|
+
) {
|
|
545
|
+
needToAdd = true;
|
|
546
|
+
}
|
|
547
|
+
|
|
528
548
|
if (needToAdd) {
|
|
529
549
|
setInitialStateOptions(stateKey as string, mergedOptions);
|
|
530
550
|
}
|
|
531
551
|
}
|
|
552
|
+
|
|
532
553
|
export function addStateOptions<T extends unknown>(
|
|
533
554
|
initialState: T,
|
|
534
555
|
{ formElements, validation }: OptionsType<T>
|
|
@@ -551,11 +572,13 @@ export const createCogsState = <State extends Record<StateKeys, unknown>>(
|
|
|
551
572
|
validation?: ValidationOptionsType;
|
|
552
573
|
__fromSyncSchema?: boolean;
|
|
553
574
|
__syncNotifications?: Record<string, Function>;
|
|
554
|
-
__apiParamsMap?: Record<string, any>;
|
|
575
|
+
__apiParamsMap?: Record<string, any>;
|
|
576
|
+
__useSync?: UseSyncType<State>;
|
|
577
|
+
__syncSchemas?: Record<string, any>;
|
|
555
578
|
}
|
|
556
579
|
) => {
|
|
557
580
|
let newInitialState = initialState;
|
|
558
|
-
|
|
581
|
+
console.log('optsc', opt?.__useSync);
|
|
559
582
|
const [statePart, initialOptionsPart] =
|
|
560
583
|
transformStateFunc<State>(newInitialState);
|
|
561
584
|
|
|
@@ -599,7 +622,12 @@ export const createCogsState = <State extends Record<StateKeys, unknown>>(
|
|
|
599
622
|
mergedOptions.validation.key = `${opt.validation.key}.${key}`;
|
|
600
623
|
}
|
|
601
624
|
}
|
|
602
|
-
|
|
625
|
+
if (opt?.__syncSchemas?.[key]?.schemas?.validation) {
|
|
626
|
+
mergedOptions.validation = {
|
|
627
|
+
zodSchemaV4: opt.__syncSchemas[key].schemas.validation,
|
|
628
|
+
...existingOptions.validation,
|
|
629
|
+
};
|
|
630
|
+
}
|
|
603
631
|
if (Object.keys(mergedOptions).length > 0) {
|
|
604
632
|
const existingGlobalOptions = getInitialOptions(key);
|
|
605
633
|
|
|
@@ -626,17 +654,10 @@ export const createCogsState = <State extends Record<StateKeys, unknown>>(
|
|
|
626
654
|
options?: Prettify<OptionsType<(typeof statePart)[StateKey]>>
|
|
627
655
|
) => {
|
|
628
656
|
const [componentId] = useState(options?.componentId ?? uuidv4());
|
|
629
|
-
const apiParamsSchema = opt?.__apiParamsMap?.[stateKey as string];
|
|
630
|
-
|
|
631
|
-
// Merge apiParams into options
|
|
632
|
-
const enhancedOptions = {
|
|
633
|
-
...options,
|
|
634
|
-
apiParamsSchema, // Add the schema here
|
|
635
|
-
} as any;
|
|
636
657
|
|
|
637
658
|
setOptions({
|
|
638
659
|
stateKey,
|
|
639
|
-
options
|
|
660
|
+
options,
|
|
640
661
|
initialOptionsPart,
|
|
641
662
|
});
|
|
642
663
|
const thiState =
|
|
@@ -657,6 +678,8 @@ export const createCogsState = <State extends Record<StateKeys, unknown>>(
|
|
|
657
678
|
defaultState: options?.defaultState as any,
|
|
658
679
|
dependencies: options?.dependencies,
|
|
659
680
|
serverState: options?.serverState,
|
|
681
|
+
syncOptions: options?.syncOptions,
|
|
682
|
+
__useSync: opt?.__useSync as UseSyncType<(typeof statePart)[StateKey]>,
|
|
660
683
|
});
|
|
661
684
|
|
|
662
685
|
return updater;
|
|
@@ -675,28 +698,33 @@ export const createCogsState = <State extends Record<StateKeys, unknown>>(
|
|
|
675
698
|
notifyComponents(stateKey as string);
|
|
676
699
|
}
|
|
677
700
|
|
|
678
|
-
return { useCogsState, setCogsOptions } as CogsApi<State>;
|
|
701
|
+
return { useCogsState, setCogsOptions } as CogsApi<State, never>;
|
|
679
702
|
};
|
|
680
|
-
|
|
681
|
-
// Fix for UseCogsStateHook to support per-key apiParams
|
|
682
703
|
type UseCogsStateHook<
|
|
683
704
|
T extends Record<string, any>,
|
|
684
|
-
TApiParamsMap extends Record<string, any> =
|
|
685
|
-
> = <StateKey extends keyof TransformedStateType<T
|
|
705
|
+
TApiParamsMap extends Record<string, any> = never,
|
|
706
|
+
> = <StateKey extends keyof TransformedStateType<T> & string>(
|
|
686
707
|
stateKey: StateKey,
|
|
687
|
-
options?:
|
|
688
|
-
|
|
689
|
-
|
|
690
|
-
|
|
691
|
-
|
|
692
|
-
|
|
693
|
-
|
|
708
|
+
options?: [TApiParamsMap] extends [never]
|
|
709
|
+
? // When TApiParamsMap is never (no sync)
|
|
710
|
+
Prettify<OptionsType<TransformedStateType<T>[StateKey]>>
|
|
711
|
+
: // When TApiParamsMap exists (sync enabled)
|
|
712
|
+
StateKey extends keyof TApiParamsMap
|
|
713
|
+
? Prettify<
|
|
714
|
+
OptionsType<
|
|
715
|
+
TransformedStateType<T>[StateKey],
|
|
716
|
+
TApiParamsMap[StateKey]
|
|
717
|
+
> & {
|
|
718
|
+
syncOptions: Prettify<SyncOptionsType<TApiParamsMap[StateKey]>>;
|
|
719
|
+
}
|
|
720
|
+
>
|
|
721
|
+
: Prettify<OptionsType<TransformedStateType<T>[StateKey]>>
|
|
694
722
|
) => StateObject<TransformedStateType<T>[StateKey]>;
|
|
695
723
|
|
|
696
|
-
//
|
|
724
|
+
// Update CogsApi to default to never instead of Record<string, never>
|
|
697
725
|
type CogsApi<
|
|
698
726
|
T extends Record<string, any>,
|
|
699
|
-
TApiParamsMap extends Record<string, any> =
|
|
727
|
+
TApiParamsMap extends Record<string, any> = never,
|
|
700
728
|
> = {
|
|
701
729
|
useCogsState: UseCogsStateHook<T, TApiParamsMap>;
|
|
702
730
|
setCogsOptions: SetCogsOptionsFunc<T>;
|
|
@@ -704,9 +732,9 @@ type CogsApi<
|
|
|
704
732
|
type GetParamType<SchemaEntry> = SchemaEntry extends {
|
|
705
733
|
api?: { queryData?: { _paramType?: infer P } };
|
|
706
734
|
}
|
|
707
|
-
? P
|
|
708
|
-
: never;
|
|
709
|
-
|
|
735
|
+
? P
|
|
736
|
+
: never;
|
|
737
|
+
|
|
710
738
|
export function createCogsStateFromSync<
|
|
711
739
|
TSyncSchema extends {
|
|
712
740
|
schemas: Record<
|
|
@@ -722,7 +750,8 @@ export function createCogsStateFromSync<
|
|
|
722
750
|
notifications: Record<string, any>;
|
|
723
751
|
},
|
|
724
752
|
>(
|
|
725
|
-
syncSchema: TSyncSchema
|
|
753
|
+
syncSchema: TSyncSchema,
|
|
754
|
+
useSync: UseSyncType<any>
|
|
726
755
|
): CogsApi<
|
|
727
756
|
{
|
|
728
757
|
[K in keyof TSyncSchema['schemas']]: TSyncSchema['schemas'][K]['schemas']['defaultValues'];
|
|
@@ -748,20 +777,19 @@ export function createCogsStateFromSync<
|
|
|
748
777
|
}
|
|
749
778
|
}
|
|
750
779
|
|
|
751
|
-
// Pass the sync schema metadata to createCogsState
|
|
752
780
|
return createCogsState(initialState, {
|
|
753
781
|
__fromSyncSchema: true,
|
|
754
782
|
__syncNotifications: syncSchema.notifications,
|
|
755
783
|
__apiParamsMap: apiParamsMap,
|
|
784
|
+
__useSync: useSync,
|
|
785
|
+
__syncSchemas: schemas,
|
|
756
786
|
}) as any;
|
|
757
787
|
}
|
|
758
788
|
const {
|
|
759
789
|
getInitialOptions,
|
|
760
|
-
|
|
790
|
+
|
|
761
791
|
setStateLog,
|
|
762
792
|
updateInitialStateGlobal,
|
|
763
|
-
addValidationError,
|
|
764
|
-
removeValidationError,
|
|
765
793
|
} = getGlobalStore.getState();
|
|
766
794
|
const saveToLocalStorage = <T,>(
|
|
767
795
|
state: T,
|
|
@@ -951,122 +979,6 @@ function markEntireStateAsServerSynced(
|
|
|
951
979
|
}
|
|
952
980
|
}
|
|
953
981
|
|
|
954
|
-
const _notifySubscribedComponents = (
|
|
955
|
-
stateKey: string,
|
|
956
|
-
path: string[],
|
|
957
|
-
updateType: 'update' | 'insert' | 'cut',
|
|
958
|
-
oldValue: any,
|
|
959
|
-
newValue: any
|
|
960
|
-
) => {
|
|
961
|
-
const store = getGlobalStore.getState();
|
|
962
|
-
const rootMeta = store.getShadowMetadata(stateKey, []);
|
|
963
|
-
if (!rootMeta?.components) {
|
|
964
|
-
return;
|
|
965
|
-
}
|
|
966
|
-
|
|
967
|
-
const notifiedComponents = new Set<string>();
|
|
968
|
-
const shadowMeta = store.getShadowMetadata(stateKey, path);
|
|
969
|
-
|
|
970
|
-
// --- PASS 1: Notify specific subscribers based on update type ---
|
|
971
|
-
|
|
972
|
-
if (updateType === 'update') {
|
|
973
|
-
if (shadowMeta?.pathComponents) {
|
|
974
|
-
shadowMeta.pathComponents.forEach((componentId) => {
|
|
975
|
-
if (notifiedComponents.has(componentId)) return;
|
|
976
|
-
const component = rootMeta.components?.get(componentId);
|
|
977
|
-
if (component) {
|
|
978
|
-
const reactiveTypes = Array.isArray(component.reactiveType)
|
|
979
|
-
? component.reactiveType
|
|
980
|
-
: [component.reactiveType || 'component'];
|
|
981
|
-
if (!reactiveTypes.includes('none')) {
|
|
982
|
-
component.forceUpdate();
|
|
983
|
-
notifiedComponents.add(componentId);
|
|
984
|
-
}
|
|
985
|
-
}
|
|
986
|
-
});
|
|
987
|
-
}
|
|
988
|
-
|
|
989
|
-
if (
|
|
990
|
-
newValue &&
|
|
991
|
-
typeof newValue === 'object' &&
|
|
992
|
-
!isArray(newValue) &&
|
|
993
|
-
oldValue &&
|
|
994
|
-
typeof oldValue === 'object' &&
|
|
995
|
-
!isArray(oldValue)
|
|
996
|
-
) {
|
|
997
|
-
const changedSubPaths = getDifferences(newValue, oldValue);
|
|
998
|
-
changedSubPaths.forEach((subPathString) => {
|
|
999
|
-
const subPath = subPathString.split('.');
|
|
1000
|
-
const fullSubPath = [...path, ...subPath];
|
|
1001
|
-
const subPathMeta = store.getShadowMetadata(stateKey, fullSubPath);
|
|
1002
|
-
if (subPathMeta?.pathComponents) {
|
|
1003
|
-
subPathMeta.pathComponents.forEach((componentId) => {
|
|
1004
|
-
if (notifiedComponents.has(componentId)) return;
|
|
1005
|
-
const component = rootMeta.components?.get(componentId);
|
|
1006
|
-
if (component) {
|
|
1007
|
-
const reactiveTypes = Array.isArray(component.reactiveType)
|
|
1008
|
-
? component.reactiveType
|
|
1009
|
-
: [component.reactiveType || 'component'];
|
|
1010
|
-
if (!reactiveTypes.includes('none')) {
|
|
1011
|
-
component.forceUpdate();
|
|
1012
|
-
notifiedComponents.add(componentId);
|
|
1013
|
-
}
|
|
1014
|
-
}
|
|
1015
|
-
});
|
|
1016
|
-
}
|
|
1017
|
-
});
|
|
1018
|
-
}
|
|
1019
|
-
} else if (updateType === 'insert' || updateType === 'cut') {
|
|
1020
|
-
const parentArrayPath = updateType === 'insert' ? path : path.slice(0, -1);
|
|
1021
|
-
const parentMeta = store.getShadowMetadata(stateKey, parentArrayPath);
|
|
1022
|
-
if (parentMeta?.pathComponents) {
|
|
1023
|
-
parentMeta.pathComponents.forEach((componentId) => {
|
|
1024
|
-
if (!notifiedComponents.has(componentId)) {
|
|
1025
|
-
const component = rootMeta.components?.get(componentId);
|
|
1026
|
-
if (component) {
|
|
1027
|
-
component.forceUpdate();
|
|
1028
|
-
notifiedComponents.add(componentId);
|
|
1029
|
-
}
|
|
1030
|
-
}
|
|
1031
|
-
});
|
|
1032
|
-
}
|
|
1033
|
-
}
|
|
1034
|
-
|
|
1035
|
-
// --- PASS 2: Notify global subscribers ('all', 'deps') ---
|
|
1036
|
-
|
|
1037
|
-
rootMeta.components.forEach((component, componentId) => {
|
|
1038
|
-
if (notifiedComponents.has(componentId)) {
|
|
1039
|
-
return;
|
|
1040
|
-
}
|
|
1041
|
-
|
|
1042
|
-
const reactiveTypes = Array.isArray(component.reactiveType)
|
|
1043
|
-
? component.reactiveType
|
|
1044
|
-
: [component.reactiveType || 'component'];
|
|
1045
|
-
|
|
1046
|
-
if (reactiveTypes.includes('all')) {
|
|
1047
|
-
component.forceUpdate();
|
|
1048
|
-
notifiedComponents.add(componentId);
|
|
1049
|
-
return;
|
|
1050
|
-
}
|
|
1051
|
-
|
|
1052
|
-
if (reactiveTypes.includes('deps')) {
|
|
1053
|
-
if (component.depsFunction) {
|
|
1054
|
-
const currentState = store.getShadowValue(stateKey);
|
|
1055
|
-
const newDeps = component.depsFunction(currentState);
|
|
1056
|
-
let shouldUpdate = false;
|
|
1057
|
-
if (newDeps === true || !isDeepEqual(component.prevDeps, newDeps)) {
|
|
1058
|
-
if (Array.isArray(newDeps)) component.prevDeps = newDeps;
|
|
1059
|
-
shouldUpdate = true;
|
|
1060
|
-
}
|
|
1061
|
-
if (shouldUpdate) {
|
|
1062
|
-
component.forceUpdate();
|
|
1063
|
-
notifiedComponents.add(componentId);
|
|
1064
|
-
}
|
|
1065
|
-
}
|
|
1066
|
-
}
|
|
1067
|
-
});
|
|
1068
|
-
};
|
|
1069
|
-
|
|
1070
982
|
export function useCogsStateFn<TStateObject extends unknown>(
|
|
1071
983
|
stateObject: TStateObject,
|
|
1072
984
|
{
|
|
@@ -1081,12 +993,14 @@ export function useCogsStateFn<TStateObject extends unknown>(
|
|
|
1081
993
|
syncUpdate,
|
|
1082
994
|
dependencies,
|
|
1083
995
|
serverState,
|
|
1084
|
-
|
|
996
|
+
__useSync,
|
|
997
|
+
syncOptions,
|
|
1085
998
|
}: {
|
|
1086
999
|
stateKey?: string;
|
|
1087
1000
|
componentId?: string;
|
|
1088
1001
|
defaultState?: TStateObject;
|
|
1089
|
-
|
|
1002
|
+
__useSync?: UseSyncType<TStateObject>;
|
|
1003
|
+
syncOptions?: SyncOptionsType<any>;
|
|
1090
1004
|
} & OptionsType<TStateObject> = {}
|
|
1091
1005
|
) {
|
|
1092
1006
|
const [reactiveForce, forceUpdate] = useState({}); //this is the key to reactivity
|
|
@@ -1189,7 +1103,7 @@ export function useCogsStateFn<TStateObject extends unknown>(
|
|
|
1189
1103
|
.subscribeToPath(thisKey, (event) => {
|
|
1190
1104
|
if (event?.type === 'SERVER_STATE_UPDATE') {
|
|
1191
1105
|
const serverStateData = event.serverState;
|
|
1192
|
-
|
|
1106
|
+
console.log('SERVER_STATE_UPDATE', event);
|
|
1193
1107
|
if (
|
|
1194
1108
|
serverStateData?.status === 'success' &&
|
|
1195
1109
|
serverStateData.data !== undefined
|
|
@@ -1208,13 +1122,12 @@ export function useCogsStateFn<TStateObject extends unknown>(
|
|
|
1208
1122
|
.getState()
|
|
1209
1123
|
.getShadowValue(thisKey);
|
|
1210
1124
|
const incomingData = serverStateData.data;
|
|
1211
|
-
|
|
1212
1125
|
if (
|
|
1213
1126
|
mergeConfig &&
|
|
1214
1127
|
Array.isArray(currentState) &&
|
|
1215
1128
|
Array.isArray(incomingData)
|
|
1216
1129
|
) {
|
|
1217
|
-
const keyField = mergeConfig.key
|
|
1130
|
+
const keyField = mergeConfig.key;
|
|
1218
1131
|
const existingIds = new Set(
|
|
1219
1132
|
currentState.map((item: any) => item[keyField])
|
|
1220
1133
|
);
|
|
@@ -1656,11 +1569,7 @@ export function useCogsStateFn<TStateObject extends unknown>(
|
|
|
1656
1569
|
const newState = getGlobalStore.getState().getShadowValue(thisKey);
|
|
1657
1570
|
const rootMeta = getGlobalStore.getState().getShadowMetadata(thisKey, []);
|
|
1658
1571
|
const notifiedComponents = new Set<string>();
|
|
1659
|
-
|
|
1660
|
-
'rootMeta',
|
|
1661
|
-
thisKey,
|
|
1662
|
-
getGlobalStore.getState().shadowStateStore
|
|
1663
|
-
);
|
|
1572
|
+
|
|
1664
1573
|
if (!rootMeta?.components) {
|
|
1665
1574
|
return newState;
|
|
1666
1575
|
}
|
|
@@ -1895,9 +1804,14 @@ export function useCogsStateFn<TStateObject extends unknown>(
|
|
|
1895
1804
|
);
|
|
1896
1805
|
}, [thisKey, sessionId]);
|
|
1897
1806
|
|
|
1898
|
-
const cogsSyncFn =
|
|
1807
|
+
const cogsSyncFn = __useSync;
|
|
1808
|
+
const syncOpt = latestInitialOptionsRef.current?.syncOptions;
|
|
1809
|
+
|
|
1899
1810
|
if (cogsSyncFn) {
|
|
1900
|
-
syncApiRef.current = cogsSyncFn(
|
|
1811
|
+
syncApiRef.current = cogsSyncFn(
|
|
1812
|
+
updaterFinal as any,
|
|
1813
|
+
syncOpt ?? ({} as any)
|
|
1814
|
+
);
|
|
1901
1815
|
}
|
|
1902
1816
|
|
|
1903
1817
|
return updaterFinal;
|
|
@@ -2169,14 +2083,14 @@ function createProxyHandler<T>(
|
|
|
2169
2083
|
response.errors &&
|
|
2170
2084
|
validationKey
|
|
2171
2085
|
) {
|
|
2172
|
-
getGlobalStore.getState().removeValidationError(validationKey);
|
|
2173
|
-
response.errors.forEach((error) => {
|
|
2174
|
-
|
|
2175
|
-
|
|
2176
|
-
|
|
2177
|
-
|
|
2178
|
-
});
|
|
2179
|
-
notifyComponents(stateKey);
|
|
2086
|
+
// getGlobalStore.getState().removeValidationError(validationKey);
|
|
2087
|
+
// response.errors.forEach((error) => {
|
|
2088
|
+
// const errorPath = [validationKey, ...error.path].join('.');
|
|
2089
|
+
// getGlobalStore
|
|
2090
|
+
// .getState()
|
|
2091
|
+
// .addValidationError(errorPath, error.message);
|
|
2092
|
+
// });
|
|
2093
|
+
// notifyComponents(stateKey);
|
|
2180
2094
|
}
|
|
2181
2095
|
|
|
2182
2096
|
if (response?.success) {
|
|
@@ -3566,18 +3480,60 @@ function createProxyHandler<T>(
|
|
|
3566
3480
|
return componentId;
|
|
3567
3481
|
}
|
|
3568
3482
|
if (path.length == 0) {
|
|
3569
|
-
if (prop === '
|
|
3570
|
-
return (
|
|
3483
|
+
if (prop === 'addZodValidation') {
|
|
3484
|
+
return (zodErrors: any[]) => {
|
|
3571
3485
|
const init = getGlobalStore
|
|
3572
3486
|
.getState()
|
|
3573
3487
|
.getInitialOptions(stateKey)?.validation;
|
|
3574
|
-
|
|
3575
|
-
|
|
3576
|
-
|
|
3577
|
-
const
|
|
3578
|
-
|
|
3488
|
+
|
|
3489
|
+
// For each error, set shadow metadata
|
|
3490
|
+
zodErrors.forEach((error) => {
|
|
3491
|
+
const currentMeta =
|
|
3492
|
+
getGlobalStore
|
|
3493
|
+
.getState()
|
|
3494
|
+
.getShadowMetadata(stateKey, error.path) || {};
|
|
3495
|
+
|
|
3496
|
+
getGlobalStore
|
|
3497
|
+
.getState()
|
|
3498
|
+
.setShadowMetadata(stateKey, error.path, {
|
|
3499
|
+
...currentMeta,
|
|
3500
|
+
validation: {
|
|
3501
|
+
status: 'VALIDATION_FAILED',
|
|
3502
|
+
message: error.message,
|
|
3503
|
+
validatedValue: undefined,
|
|
3504
|
+
},
|
|
3505
|
+
});
|
|
3506
|
+
getGlobalStore.getState().notifyPathSubscribers(error.path, {
|
|
3507
|
+
type: 'VALIDATION_FAILED',
|
|
3508
|
+
message: error.message,
|
|
3509
|
+
validatedValue: undefined,
|
|
3510
|
+
});
|
|
3579
3511
|
});
|
|
3580
|
-
|
|
3512
|
+
};
|
|
3513
|
+
}
|
|
3514
|
+
if (prop === 'clearZodValidation') {
|
|
3515
|
+
return (path?: string[]) => {
|
|
3516
|
+
// Clear specific paths
|
|
3517
|
+
if (!path) {
|
|
3518
|
+
throw new Error('clearZodValidation requires a path');
|
|
3519
|
+
return;
|
|
3520
|
+
}
|
|
3521
|
+
const currentMeta =
|
|
3522
|
+
getGlobalStore.getState().getShadowMetadata(stateKey, path) ||
|
|
3523
|
+
{};
|
|
3524
|
+
|
|
3525
|
+
if (currentMeta.validation) {
|
|
3526
|
+
getGlobalStore.getState().setShadowMetadata(stateKey, path, {
|
|
3527
|
+
...currentMeta,
|
|
3528
|
+
validation: undefined,
|
|
3529
|
+
});
|
|
3530
|
+
|
|
3531
|
+
getGlobalStore
|
|
3532
|
+
.getState()
|
|
3533
|
+
.notifyPathSubscribers([stateKey, ...path].join('.'), {
|
|
3534
|
+
type: 'VALIDATION_CLEARED',
|
|
3535
|
+
});
|
|
3536
|
+
}
|
|
3581
3537
|
};
|
|
3582
3538
|
}
|
|
3583
3539
|
if (prop === 'applyJsonPatch') {
|
|
@@ -3617,7 +3573,7 @@ function createProxyHandler<T>(
|
|
|
3617
3573
|
stateKey,
|
|
3618
3574
|
currentPath
|
|
3619
3575
|
);
|
|
3620
|
-
|
|
3576
|
+
|
|
3621
3577
|
if (pathMeta?.pathComponents) {
|
|
3622
3578
|
pathMeta.pathComponents.forEach((componentId) => {
|
|
3623
3579
|
if (!notifiedComponents.has(componentId)) {
|
|
@@ -3670,51 +3626,6 @@ function createProxyHandler<T>(
|
|
|
3670
3626
|
}
|
|
3671
3627
|
};
|
|
3672
3628
|
}
|
|
3673
|
-
if (prop === 'validateZodSchema') {
|
|
3674
|
-
return () => {
|
|
3675
|
-
const init = getGlobalStore
|
|
3676
|
-
.getState()
|
|
3677
|
-
.getInitialOptions(stateKey)?.validation;
|
|
3678
|
-
|
|
3679
|
-
// UPDATED: Select v4 schema, with a fallback to v3
|
|
3680
|
-
const zodSchema = init?.zodSchemaV4 || init?.zodSchemaV3;
|
|
3681
|
-
|
|
3682
|
-
if (!zodSchema || !init?.key) {
|
|
3683
|
-
throw new Error(
|
|
3684
|
-
'Zod schema (v3 or v4) or validation key not found'
|
|
3685
|
-
);
|
|
3686
|
-
}
|
|
3687
|
-
|
|
3688
|
-
removeValidationError(init.key);
|
|
3689
|
-
const thisObject = getGlobalStore
|
|
3690
|
-
.getState()
|
|
3691
|
-
.getShadowValue(stateKey);
|
|
3692
|
-
|
|
3693
|
-
// Use the selected schema for parsing
|
|
3694
|
-
const result = zodSchema.safeParse(thisObject);
|
|
3695
|
-
|
|
3696
|
-
if (!result.success) {
|
|
3697
|
-
// This logic already handles both v3 and v4 error types correctly
|
|
3698
|
-
if ('issues' in result.error) {
|
|
3699
|
-
// Zod v4 error
|
|
3700
|
-
result.error.issues.forEach((error) => {
|
|
3701
|
-
const fullErrorPath = [init.key, ...error.path].join('.');
|
|
3702
|
-
addValidationError(fullErrorPath, error.message);
|
|
3703
|
-
});
|
|
3704
|
-
} else {
|
|
3705
|
-
// Zod v3 error
|
|
3706
|
-
(result.error as any).errors.forEach((error: any) => {
|
|
3707
|
-
const fullErrorPath = [init.key, ...error.path].join('.');
|
|
3708
|
-
addValidationError(fullErrorPath, error.message);
|
|
3709
|
-
});
|
|
3710
|
-
}
|
|
3711
|
-
|
|
3712
|
-
notifyComponents(stateKey);
|
|
3713
|
-
return false;
|
|
3714
|
-
}
|
|
3715
|
-
return true;
|
|
3716
|
-
};
|
|
3717
|
-
}
|
|
3718
3629
|
|
|
3719
3630
|
if (prop === 'getComponents')
|
|
3720
3631
|
return () =>
|
|
@@ -3834,22 +3745,10 @@ function createProxyHandler<T>(
|
|
|
3834
3745
|
}
|
|
3835
3746
|
|
|
3836
3747
|
const baseObj = {
|
|
3837
|
-
removeValidation: (obj?: { validationKey?: string }) => {
|
|
3838
|
-
if (obj?.validationKey) {
|
|
3839
|
-
removeValidationError(obj.validationKey);
|
|
3840
|
-
}
|
|
3841
|
-
},
|
|
3842
3748
|
revertToInitialState: (obj?: { validationKey?: string }) => {
|
|
3843
3749
|
const init = getGlobalStore
|
|
3844
3750
|
.getState()
|
|
3845
3751
|
.getInitialOptions(stateKey)?.validation;
|
|
3846
|
-
if (init?.key) {
|
|
3847
|
-
removeValidationError(init.key);
|
|
3848
|
-
}
|
|
3849
|
-
|
|
3850
|
-
if (obj?.validationKey) {
|
|
3851
|
-
removeValidationError(obj.validationKey);
|
|
3852
|
-
}
|
|
3853
3752
|
|
|
3854
3753
|
const shadowMeta = getGlobalStore
|
|
3855
3754
|
.getState()
|
|
@@ -4486,6 +4385,7 @@ function FormElementWrapper({
|
|
|
4486
4385
|
validation: {
|
|
4487
4386
|
status: 'VALID_LIVE',
|
|
4488
4387
|
validatedValue: newValue,
|
|
4388
|
+
message: undefined,
|
|
4489
4389
|
},
|
|
4490
4390
|
});
|
|
4491
4391
|
}
|
|
@@ -4496,6 +4396,7 @@ function FormElementWrapper({
|
|
|
4496
4396
|
validation: {
|
|
4497
4397
|
status: 'VALID_LIVE',
|
|
4498
4398
|
validatedValue: newValue,
|
|
4399
|
+
message: undefined,
|
|
4499
4400
|
},
|
|
4500
4401
|
});
|
|
4501
4402
|
}
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
//@ts-nocheck
|
|
1
2
|
import { observable } from '@trpc/server/observable';
|
|
2
3
|
import type { AnyRouter } from '@trpc/server';
|
|
3
4
|
import type { TRPCLink } from '@trpc/client';
|
|
@@ -11,7 +12,6 @@ export const useCogsTrpcValidationLink = <
|
|
|
11
12
|
log?: boolean;
|
|
12
13
|
}) => {
|
|
13
14
|
const addValidationError = getGlobalStore.getState().addValidationError;
|
|
14
|
-
|
|
15
15
|
const TrpcValidationLink = (): TRPCLink<TRouter> => {
|
|
16
16
|
return (opts) => {
|
|
17
17
|
return ({ next, op }: { next: any; op: Operation }) => {
|