cogsbox-state 0.5.489 → 0.5.491

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.
@@ -22,7 +22,7 @@ import React, {
22
22
  useMemo,
23
23
  type ReactNode,
24
24
  } from 'react';
25
- import { getGlobalStore, ValidationError, ValidationSeverity } from './store';
25
+ import { getGlobalStore, ValidationError, ValidationSeverity } from './store';
26
26
  import { useInView } from 'react-intersection-observer';
27
27
  import { v4 as uuidv4 } from 'uuid';
28
28
  import { isDeepEqual } from './utility';
@@ -272,7 +272,6 @@ export function FormElementWrapper({
272
272
 
273
273
  useEffect(() => {
274
274
  const { getShadowMetadata, setShadowMetadata } = getGlobalStore.getState();
275
- console.log('FormElementWrapper effect running for:', stateKey, path);
276
275
 
277
276
  // Initialize clientActivityState if needed
278
277
  const currentMeta = getShadowMetadata(stateKey, path) || {};
@@ -304,7 +303,7 @@ export function FormElementWrapper({
304
303
  inputType: formElementRef.current?.type,
305
304
  mountedAt: Date.now(),
306
305
  });
307
- console.log('currentMeta', currentMeta);
306
+
308
307
  setShadowMetadata(stateKey, path, currentMeta);
309
308
 
310
309
  // Subscribe to path updates
@@ -526,55 +525,55 @@ export function FormElementWrapper({
526
525
  });
527
526
  }, [localValue, setState, path, stateKey, componentId, globalStateValue]);
528
527
 
529
- const baseState = rebuildStateShape({
530
- path: path,
531
- componentId: componentId,
532
- meta: undefined,
533
- });
534
- const validationState = getShadowMetadata(stateKey, path)?.validation;
535
- const validationStatus = validationState?.status || 'NOT_VALIDATED';
536
- const allErrors = (validationState?.errors || []).map((err) => ({
537
- ...err,
538
- path,
539
- })) as ValidationError[];
540
- const errorMessages = allErrors
541
- .filter((err) => err.severity === 'error')
542
- .map((err) => err.message);
543
- const warningMessages = allErrors
544
- .filter((err) => err.severity === 'warning')
545
- .map((err) => err.message);
546
- const validationMessage = errorMessages[0] || warningMessages[0] || '';
547
- const validationSeverity: ValidationSeverity =
548
- errorMessages.length > 0
549
- ? 'error'
550
- : warningMessages.length > 0
551
- ? 'warning'
552
- : undefined;
553
-
554
- const stateWithInputProps = new Proxy(baseState, {
555
- get(target, prop) {
556
- if (prop === '$inputProps') {
557
- return {
528
+ const baseState = rebuildStateShape({
529
+ path: path,
530
+ componentId: componentId,
531
+ meta: undefined,
532
+ });
533
+ const validationState = getShadowMetadata(stateKey, path)?.validation;
534
+ const validationStatus = validationState?.status || 'NOT_VALIDATED';
535
+ const allErrors = (validationState?.errors || []).map((err) => ({
536
+ ...err,
537
+ path,
538
+ })) as ValidationError[];
539
+ const errorMessages = allErrors
540
+ .filter((err) => err.severity === 'error')
541
+ .map((err) => err.message);
542
+ const warningMessages = allErrors
543
+ .filter((err) => err.severity === 'warning')
544
+ .map((err) => err.message);
545
+ const validationMessage = errorMessages[0] || warningMessages[0] || '';
546
+ const validationSeverity: ValidationSeverity =
547
+ errorMessages.length > 0
548
+ ? 'error'
549
+ : warningMessages.length > 0
550
+ ? 'warning'
551
+ : undefined;
552
+
553
+ const stateWithInputProps = new Proxy(baseState, {
554
+ get(target, prop) {
555
+ if (prop === '$inputProps') {
556
+ return {
558
557
  value: localValue ?? '',
559
558
  onChange: (e: any) => {
560
559
  debouncedUpdate(e.target.value);
561
560
  },
562
561
  onFocus: handleFocus,
563
562
  onBlur: handleBlur,
564
- ref: formElementRef,
565
- };
566
- }
567
- if (prop === 'status') return validationStatus;
568
- if (prop === 'severity') return validationSeverity;
569
- if (prop === 'hasErrors') return errorMessages.length > 0;
570
- if (prop === 'hasWarnings') return warningMessages.length > 0;
571
- if (prop === 'allErrors') return allErrors;
572
- if (prop === 'message') return validationMessage;
573
- if (prop === 'getData') return () => getShadowValue(stateKey, path);
574
-
575
- return target[prop];
576
- },
577
- });
563
+ ref: formElementRef,
564
+ };
565
+ }
566
+ if (prop === 'status') return validationStatus;
567
+ if (prop === 'severity') return validationSeverity;
568
+ if (prop === 'hasErrors') return errorMessages.length > 0;
569
+ if (prop === 'hasWarnings') return warningMessages.length > 0;
570
+ if (prop === 'allErrors') return allErrors;
571
+ if (prop === 'message') return validationMessage;
572
+ if (prop === 'getData') return () => getShadowValue(stateKey, path);
573
+
574
+ return target[prop];
575
+ },
576
+ });
578
577
 
579
578
  const initialElement = renderFn(stateWithInputProps);
580
579
 
package/src/plugins.ts CHANGED
@@ -29,6 +29,8 @@ export type ChainMethodContext<TOptions = any, THookReturn = any> = {
29
29
  getFieldMetaData: () => any;
30
30
  setFieldMetaData: (data: Record<string, any>) => void;
31
31
  removeFieldMetaData: () => void;
32
+ watchPluginMeta: (scope?: string) => void;
33
+ notifyPluginMeta: (scope?: string) => void;
32
34
  getFieldRefs: () => RefObject<any>[];
33
35
  getFieldElements: () => HTMLElement[];
34
36
  setFieldDisabled: (disabled: boolean) => void;
@@ -56,13 +58,17 @@ type ChainMethodCallable<THandler> = THandler extends (
56
58
  ? (...args: TArgs) => TReturn
57
59
  : never;
58
60
 
59
- export type ChainMethodCallables<TMethods> = {
60
- [K in keyof TMethods as K extends string
61
- ? `$${K}`
62
- : never]: TMethods[K] extends ChainMethodDefinition<infer TFn>
63
- ? ChainMethodCallable<TFn>
64
- : never;
65
- };
61
+ type LiteralStringKeys<T> = string extends keyof T
62
+ ? never
63
+ : Extract<keyof T, string>;
64
+
65
+ export type ChainMethodCallables<TMethods> = {
66
+ [K in LiteralStringKeys<TMethods> as K extends string
67
+ ? `$${K}`
68
+ : never]: TMethods[K] extends ChainMethodDefinition<infer TFn>
69
+ ? ChainMethodCallable<TFn>
70
+ : never;
71
+ };
66
72
 
67
73
  export type KeyedTypes<TMap extends Record<string, any>> = {
68
74
  __key: 'keyed';
@@ -472,14 +478,14 @@ type ZodObjOutput<T extends z.ZodObject<any>> = {
472
478
  type OutputOf<T extends z.ZodTypeAny> =
473
479
  T extends z.ZodObject<any> ? Prettify<ZodObjOutput<T>> : z.output<T>;
474
480
 
475
- type MethodFactory = <TArgs extends any[], TReturn>(
476
- handler: (
477
- ctx: ChainMethodContext<any, any>,
478
- ...args: TArgs
479
- ) => TReturn
480
- ) => ChainMethodDefinition<
481
- (ctx: ChainMethodContext<any, any>, ...args: TArgs) => TReturn
482
- >;
481
+ type MethodFactory = <TArgs extends any[], TReturn>(
482
+ handler: (
483
+ ctx: ChainMethodContext<any, any>,
484
+ ...args: TArgs
485
+ ) => TReturn
486
+ ) => ChainMethodDefinition<
487
+ (ctx: ChainMethodContext<any, any>, ...args: TArgs) => TReturn
488
+ >;
483
489
 
484
490
  type PathMethodFactory = MethodFactory & {
485
491
  array: MethodFactory;
package/src/store.ts CHANGED
@@ -4,7 +4,6 @@ import type { RefObject } from 'react';
4
4
  import type {
5
5
  OptionsType,
6
6
  ReactivityType,
7
- SyncInfo,
8
7
  UpdateTypeDetail,
9
8
  } from './CogsState.js';
10
9
 
@@ -134,18 +133,14 @@ export type ShadowMetadata = {
134
133
  value?: any;
135
134
  id?: string;
136
135
  typeInfo?: SchemaTypeInfo;
137
- stateSource?: 'default' | 'server' | 'localStorage';
138
- lastServerSync?: number;
139
- isDirty?: boolean;
140
136
  isRaw?: boolean;
141
- baseServerState?: any;
142
137
  arrayKeys?: string[];
143
138
  fields?: Record<string, any>;
144
139
  virtualizer?: {
145
140
  itemHeight?: number;
146
141
  domRef?: HTMLElement | null;
147
142
  };
148
- syncInfo?: { status: string };
143
+
149
144
  validation?: ValidationState;
150
145
  features?: {
151
146
  localStorageEnabled: boolean;
@@ -252,12 +247,6 @@ export type CogsGlobalState = {
252
247
  dependencyPath: string[],
253
248
  fullComponentId: string
254
249
  ) => void;
255
- markAsDirty: (
256
- key: string,
257
- path: string[],
258
- options: { bubble: boolean }
259
- ) => void;
260
-
261
250
  pathSubscribers: Map<string, Set<(newValue: any) => void>>;
262
251
  subscribeToPath: (
263
252
  path: string,
@@ -278,23 +267,8 @@ export type CogsGlobalState = {
278
267
  getInitialOptions: (key: string) => OptionsType | undefined;
279
268
  setInitialStateOptions: (key: string, value: OptionsType) => void;
280
269
 
281
- serverStateUpdates: Map<
282
- string,
283
- {
284
- data: any;
285
- status: 'loading' | 'success' | 'error';
286
- timestamp: number;
287
- }
288
- >;
289
-
290
- setServerStateUpdate: (key: string, serverState: any) => void;
291
-
292
270
  stateLog: Map<string, Map<string, UpdateTypeDetail>>;
293
- syncInfoStore: Map<string, SyncInfo>;
294
271
  addStateLog: (updates: UpdateTypeDetail[]) => void;
295
-
296
- setSyncInfo: (key: string, syncInfo: SyncInfo) => void;
297
- getSyncInfo: (key: string) => SyncInfo | null;
298
272
  };
299
273
  function getTypeFromZodSchema(
300
274
  schema: any,
@@ -787,9 +761,6 @@ export const getGlobalStore = create<CogsGlobalState>((set, get) => ({
787
761
  const {
788
762
  components,
789
763
  features,
790
- lastServerSync,
791
- stateSource,
792
- baseServerState,
793
764
  pathComponents,
794
765
  signals,
795
766
  validation,
@@ -797,9 +768,6 @@ export const getGlobalStore = create<CogsGlobalState>((set, get) => ({
797
768
 
798
769
  if (components) preservedMetadata.components = components;
799
770
  if (features) preservedMetadata.features = features;
800
- if (lastServerSync) preservedMetadata.lastServerSync = lastServerSync;
801
- if (stateSource) preservedMetadata.stateSource = stateSource;
802
- if (baseServerState) preservedMetadata.baseServerState = baseServerState;
803
771
  if (pathComponents) preservedMetadata.pathComponents = pathComponents;
804
772
  if (signals) preservedMetadata.signals = signals;
805
773
  if (validation) preservedMetadata.validation = validation;
@@ -962,15 +930,9 @@ export const getGlobalStore = create<CogsGlobalState>((set, get) => ({
962
930
  const {
963
931
  components,
964
932
  features,
965
- lastServerSync,
966
- stateSource,
967
- baseServerState,
968
933
  } = existingRoot._meta;
969
934
  if (components) preservedMetadata.components = components;
970
935
  if (features) preservedMetadata.features = features;
971
- if (lastServerSync) preservedMetadata.lastServerSync = lastServerSync;
972
- if (stateSource) preservedMetadata.stateSource = stateSource;
973
- if (baseServerState) preservedMetadata.baseServerState = baseServerState;
974
936
  }
975
937
 
976
938
  shadowStateStore.delete(key);
@@ -1467,55 +1429,6 @@ export const getGlobalStore = create<CogsGlobalState>((set, get) => ({
1467
1429
  }
1468
1430
  },
1469
1431
 
1470
- markAsDirty: (key, path, options = { bubble: true }) => {
1471
- // Start at the root node once.
1472
- let rootNode = get().getShadowNode(key, []);
1473
- if (!rootNode) return;
1474
-
1475
- // Navigate to the target node once.
1476
- let currentNode = rootNode;
1477
- for (const segment of path) {
1478
- currentNode = currentNode[segment];
1479
- if (!currentNode) return; // Path doesn't exist, nothing to mark.
1480
- }
1481
-
1482
- // Mark the target node as dirty.
1483
- if (!currentNode._meta) currentNode._meta = {};
1484
- currentNode._meta.isDirty = true;
1485
-
1486
- // If bubbling is disabled, we are done.
1487
- if (!options.bubble) return;
1488
-
1489
- // Efficiently bubble up using the path segments.
1490
- let parentNode = rootNode;
1491
- for (let i = 0; i < path.length; i++) {
1492
- // The current node in the loop is the parent of the next one.
1493
- if (parentNode._meta?.isDirty) {
1494
- // Optimization: If a parent is already dirty, all of its ancestors are too.
1495
- // We can stop bubbling immediately.
1496
- return;
1497
- }
1498
- if (!parentNode._meta) parentNode._meta = {};
1499
- parentNode._meta.isDirty = true;
1500
- parentNode = parentNode[path[i]!];
1501
- }
1502
- },
1503
-
1504
- // Keep these in Zustand as they need React reactivity
1505
- serverStateUpdates: new Map(),
1506
- setServerStateUpdate: (key, serverState) => {
1507
- set((state) => ({
1508
- serverStateUpdates: new Map(state.serverStateUpdates).set(
1509
- key,
1510
- serverState
1511
- ),
1512
- }));
1513
- get().notifyPathSubscribers(key, {
1514
- type: 'SERVER_STATE_UPDATE',
1515
- serverState,
1516
- });
1517
- },
1518
-
1519
1432
  pathSubscribers: new Map<string, Set<(newValue: any) => void>>(),
1520
1433
  subscribeToPath: (path, callback) => {
1521
1434
  const subscribers = get().pathSubscribers;
@@ -1654,14 +1567,7 @@ export const getGlobalStore = create<CogsGlobalState>((set, get) => ({
1654
1567
  }));
1655
1568
  },
1656
1569
 
1657
- syncInfoStore: new Map<string, SyncInfo>(),
1658
- setSyncInfo: (key, syncInfo) =>
1659
- set((state) => {
1660
- const newMap = new Map(state.syncInfoStore);
1661
- newMap.set(key, syncInfo);
1662
- return { syncInfoStore: newMap };
1663
- }),
1664
- getSyncInfo: (key) => get().syncInfoStore.get(key) || null,
1570
+ // Removed: syncInfo is now owned by Shape Plugin
1665
1571
  }));
1666
1572
 
1667
1573
  export function getAllFieldElements(stateKey: string): HTMLElement[] {