cogsbox-state 0.5.462 → 0.5.463

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/store.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"store.js","sources":["../src/store.ts"],"sourcesContent":["import { create } from 'zustand';\r\nimport { ulid } from 'ulid';\r\nimport type {\r\n OptionsType,\r\n ReactivityType,\r\n StateKeys,\r\n SyncInfo,\r\n UpdateTypeDetail,\r\n} from './CogsState.js';\r\n\r\nimport { startTransition, type ReactNode } from 'react';\r\n\r\ntype StateUpdater<StateValue> =\r\n | StateValue\r\n | ((prevValue: StateValue) => StateValue);\r\n\r\nexport type FreshValuesObject = {\r\n pathsToValues?: string[];\r\n prevValue?: any;\r\n newValue?: any;\r\n timeStamp: number;\r\n};\r\n\r\ntype SyncLogType = {\r\n timeStamp: number;\r\n};\r\ntype StateValue = any;\r\n\r\nexport type TrieNode = {\r\n subscribers: Set<string>;\r\n children: Map<string, TrieNode>;\r\n};\r\n\r\nexport type FormRefStoreState = {\r\n formRefs: Map<string, React.RefObject<any>>;\r\n registerFormRef: (id: string, ref: React.RefObject<any>) => void;\r\n getFormRef: (id: string) => React.RefObject<any> | undefined;\r\n removeFormRef: (id: string) => void;\r\n // New method to get all refs for a stateKey\r\n getFormRefsByStateKey: (\r\n stateKey: string\r\n ) => Map<string, React.RefObject<any>>;\r\n};\r\n\r\nexport const formRefStore = create<FormRefStoreState>((set, get) => ({\r\n formRefs: new Map(),\r\n\r\n registerFormRef: (id, ref) =>\r\n set((state) => {\r\n const newRefs = new Map(state.formRefs);\r\n newRefs.set(id, ref);\r\n return { formRefs: newRefs };\r\n }),\r\n\r\n getFormRef: (id) => get().formRefs.get(id),\r\n\r\n removeFormRef: (id) =>\r\n set((state) => {\r\n const newRefs = new Map(state.formRefs);\r\n newRefs.delete(id);\r\n return { formRefs: newRefs };\r\n }),\r\n\r\n // Get all refs that start with the stateKey prefix\r\n getFormRefsByStateKey: (stateKey) => {\r\n const allRefs = get().formRefs;\r\n const stateKeyPrefix = stateKey + '.';\r\n const filteredRefs = new Map();\r\n\r\n allRefs.forEach((ref, id) => {\r\n if (id.startsWith(stateKeyPrefix) || id === stateKey) {\r\n filteredRefs.set(id, ref);\r\n }\r\n });\r\n\r\n return filteredRefs;\r\n },\r\n}));\r\nexport type ComponentsType = {\r\n components?: Map<\r\n string,\r\n {\r\n forceUpdate: () => void;\r\n paths: Set<string>;\r\n deps?: any[];\r\n prevDeps?: any[];\r\n depsFunction?: (state: any) => any[] | true;\r\n reactiveType: ReactivityType[] | ReactivityType;\r\n }\r\n >;\r\n};\r\nexport type ShadowMetadata = {\r\n id?: string;\r\n\r\n stateSource?: 'default' | 'server' | 'localStorage';\r\n lastServerSync?: number;\r\n isDirty?: boolean;\r\n baseServerState?: any;\r\n\r\n arrayKeys?: string[];\r\n\r\n fields?: Record<string, any>;\r\n virtualizer?: {\r\n itemHeight?: number;\r\n domRef?: HTMLElement | null;\r\n };\r\n syncInfo?: { status: string };\r\n validation?: ValidationState;\r\n lastUpdated?: number;\r\n value?: any;\r\n classSignals?: Array<{\r\n // <-- ADD THIS BLOCK\r\n id: string;\r\n effect: string;\r\n lastClasses: string;\r\n deps: any[];\r\n }>;\r\n signals?: Array<{\r\n instanceId: string;\r\n parentId: string;\r\n position: number;\r\n effect?: string;\r\n }>;\r\n mapWrappers?: Array<{\r\n instanceId: string;\r\n path: string[];\r\n componentId: string;\r\n meta?: any;\r\n mapFn: (\r\n setter: any,\r\n index: number,\r\n\r\n arraySetter: any\r\n ) => ReactNode;\r\n containerRef: HTMLDivElement | null;\r\n rebuildStateShape: any;\r\n }>;\r\n transformCaches?: Map<\r\n string,\r\n {\r\n validIds: string[];\r\n computedAt: number;\r\n transforms: Array<{ type: 'filter' | 'sort'; fn: Function }>;\r\n }\r\n >;\r\n pathComponents?: Set<string>;\r\n streams?: Map<\r\n string,\r\n {\r\n buffer: any[];\r\n flushTimer: NodeJS.Timeout | null;\r\n }\r\n >;\r\n} & ComponentsType;\r\n\r\nexport type ValidationStatus =\r\n | 'PRISTINE' // Untouched, matches initial state.\r\n | 'DIRTY' // Changed, but no validation run yet.\r\n | 'VALID_LIVE' // Valid while typing.\r\n | 'INVALID_LIVE' // Gentle error during typing.\r\n | 'VALIDATION_FAILED' // Hard error on blur/submit.\r\n | 'VALID_PENDING_SYNC' // Passed validation, ready for sync.\r\n | 'SYNCING' // Actively being sent to the server.\r\n | 'SYNCED' // Server confirmed success.\r\n | 'SYNC_FAILED'; // Server rejected the data.\r\n\r\nexport type ValidationState = {\r\n status: ValidationStatus;\r\n message?: string;\r\n lastValidated?: number;\r\n validatedValue?: any;\r\n};\r\nexport type CogsEvent =\r\n | { type: 'INSERT'; path: string; itemKey: string; index: number }\r\n | { type: 'REMOVE'; path: string; itemKey: string }\r\n | { type: 'UPDATE'; path: string; newValue: any }\r\n | { type: 'ITEMHEIGHT'; itemKey: string; height: number } // For full re-initializations (e.g., when a component is removed)\r\n | { type: 'RELOAD'; path: string }; // For full re-initializations\r\nexport type CogsGlobalState = {\r\n updateQueue: Set<() => void>;\r\n isFlushScheduled: boolean;\r\n\r\n flushUpdates: () => void;\r\n\r\n // --- Shadow State and Subscription System ---\r\n registerComponent: (\r\n stateKey: string,\r\n componentId: string,\r\n registration: any\r\n ) => void;\r\n unregisterComponent: (stateKey: string, componentId: string) => void;\r\n addPathComponent: (\r\n stateKey: string,\r\n dependencyPath: string[],\r\n fullComponentId: string\r\n ) => void;\r\n shadowStateStore: Map<string, ShadowMetadata>;\r\n\r\n markAsDirty: (\r\n key: string,\r\n path: string[],\r\n options: { bubble: boolean }\r\n ) => void;\r\n // These method signatures stay the same\r\n initializeShadowState: (key: string, initialState: any) => void;\r\n updateShadowAtPath: (key: string, path: string[], newValue: any) => void;\r\n insertShadowArrayElement: (\r\n key: string,\r\n arrayPath: string[],\r\n newItem: any\r\n ) => void;\r\n removeShadowArrayElement: (key: string, arrayPath: string[]) => void;\r\n getShadowValue: (\r\n key: string,\r\n\r\n validArrayIds?: string[]\r\n ) => any;\r\n\r\n getShadowMetadata: (\r\n key: string,\r\n path: string[]\r\n ) => ShadowMetadata | undefined;\r\n setShadowMetadata: (\r\n key: string,\r\n path: string[],\r\n metadata: Omit<ShadowMetadata, 'id'>\r\n ) => void;\r\n setTransformCache: (\r\n key: string,\r\n path: string[],\r\n cacheKey: string,\r\n cacheData: any\r\n ) => void;\r\n\r\n pathSubscribers: Map<string, Set<(newValue: any) => void>>;\r\n subscribeToPath: (\r\n path: string,\r\n callback: (newValue: any) => void\r\n ) => () => void;\r\n notifyPathSubscribers: (updatedPath: string, newValue: any) => void;\r\n\r\n selectedIndicesMap: Map<string, string>; // stateKey -> (parentPath -> selectedIndex)\r\n getSelectedIndex: (stateKey: string, validArrayIds?: string[]) => number;\r\n setSelectedIndex: (key: string, itemKey: string) => void;\r\n clearSelectedIndex: ({ arrayKey }: { arrayKey: string }) => void;\r\n clearSelectedIndexesForState: (stateKey: string) => void;\r\n\r\n // --- Core State and Updaters ---\r\n\r\n initialStateOptions: { [key: string]: OptionsType };\r\n\r\n initialStateGlobal: { [key: string]: StateValue };\r\n\r\n updateInitialStateGlobal: (key: string, newState: StateValue) => void;\r\n\r\n getInitialOptions: (key: string) => OptionsType | undefined;\r\n setInitialStateOptions: (key: string, value: OptionsType) => void;\r\n\r\n // --- Validation ---\r\n\r\n // --- Server Sync and Logging ---\r\n\r\n serverStateUpdates: Map<\r\n string,\r\n {\r\n data: any;\r\n status: 'loading' | 'success' | 'error';\r\n timestamp: number;\r\n }\r\n >;\r\n\r\n setServerStateUpdate: (key: string, serverState: any) => void;\r\n\r\n stateLog: Map<string, Map<string, UpdateTypeDetail>>;\r\n syncInfoStore: Map<string, SyncInfo>;\r\n addStateLog: (key: string, update: UpdateTypeDetail) => void;\r\n\r\n setSyncInfo: (key: string, syncInfo: SyncInfo) => void;\r\n getSyncInfo: (key: string) => SyncInfo | null;\r\n};\r\nconst isSimpleObject = (value: any): boolean => {\r\n if (value === null || typeof value !== 'object') return false;\r\n\r\n // Handle special cases that should be treated as primitives\r\n if (\r\n value instanceof Uint8Array ||\r\n value instanceof Int8Array ||\r\n value instanceof Uint16Array ||\r\n value instanceof Int16Array ||\r\n value instanceof Uint32Array ||\r\n value instanceof Int32Array ||\r\n value instanceof Float32Array ||\r\n value instanceof Float64Array ||\r\n value instanceof ArrayBuffer ||\r\n value instanceof Date ||\r\n value instanceof RegExp ||\r\n value instanceof Map ||\r\n value instanceof Set\r\n ) {\r\n return false; // Treat as primitive\r\n }\r\n\r\n // Arrays and plain objects are complex\r\n return Array.isArray(value) || value.constructor === Object;\r\n};\r\nexport const getGlobalStore = create<CogsGlobalState>((set, get) => ({\r\n updateQueue: new Set<() => void>(),\r\n // A flag to ensure we only schedule the flush once per event-loop tick.\r\n isFlushScheduled: false,\r\n\r\n // This function is called by queueMicrotask to execute all queued updates.\r\n flushUpdates: () => {\r\n const { updateQueue } = get();\r\n\r\n if (updateQueue.size > 0) {\r\n startTransition(() => {\r\n updateQueue.forEach((updateFn) => updateFn());\r\n });\r\n }\r\n\r\n // Clear the queue and reset the flag for the next event loop tick.\r\n set({ updateQueue: new Set(), isFlushScheduled: false });\r\n },\r\n addPathComponent: (stateKey, dependencyPath, fullComponentId) => {\r\n set((state) => {\r\n const newShadowStore = new Map(state.shadowStateStore);\r\n const dependencyKey = [stateKey, ...dependencyPath].join('.');\r\n\r\n // --- Part 1: Update the path's own metadata ---\r\n const pathMeta = newShadowStore.get(dependencyKey) || {};\r\n // Create a *new* Set to ensure immutability\r\n const pathComponents = new Set(pathMeta.pathComponents);\r\n pathComponents.add(fullComponentId);\r\n // Update the metadata for the specific path\r\n newShadowStore.set(dependencyKey, { ...pathMeta, pathComponents });\r\n\r\n // --- Part 2: Update the component's own list of paths ---\r\n const rootMeta = newShadowStore.get(stateKey) || {};\r\n const component = rootMeta.components?.get(fullComponentId);\r\n\r\n // If the component exists, update its `paths` set immutably\r\n if (component) {\r\n const newPaths = new Set(component.paths);\r\n newPaths.add(dependencyKey);\r\n\r\n const newComponentRegistration = { ...component, paths: newPaths };\r\n const newComponentsMap = new Map(rootMeta.components);\r\n newComponentsMap.set(fullComponentId, newComponentRegistration);\r\n\r\n // Update the root metadata with the new components map\r\n newShadowStore.set(stateKey, {\r\n ...rootMeta,\r\n components: newComponentsMap,\r\n });\r\n }\r\n\r\n // Return the final, updated state\r\n return { shadowStateStore: newShadowStore };\r\n });\r\n },\r\n registerComponent: (stateKey, fullComponentId, registration) => {\r\n set((state) => {\r\n // Create a new Map to ensure Zustand detects the change\r\n const newShadowStore = new Map(state.shadowStateStore);\r\n\r\n // Get the metadata for the ROOT of the state (where the components map lives)\r\n const rootMeta = newShadowStore.get(stateKey) || {};\r\n\r\n // Also clone the components map to avoid direct mutation\r\n const components = new Map(rootMeta.components);\r\n components.set(fullComponentId, registration);\r\n\r\n // Update the root metadata with the new components map\r\n newShadowStore.set(stateKey, { ...rootMeta, components });\r\n\r\n // Return the updated state\r\n return { shadowStateStore: newShadowStore };\r\n });\r\n },\r\n\r\n unregisterComponent: (stateKey, fullComponentId) => {\r\n set((state) => {\r\n const newShadowStore = new Map(state.shadowStateStore);\r\n const rootMeta = newShadowStore.get(stateKey);\r\n\r\n // If there's no metadata or no components map, do nothing\r\n if (!rootMeta?.components) {\r\n return state; // Return original state, no change needed\r\n }\r\n\r\n const components = new Map(rootMeta.components);\r\n const wasDeleted = components.delete(fullComponentId);\r\n\r\n // Only update state if something was actually deleted\r\n if (wasDeleted) {\r\n newShadowStore.set(stateKey, { ...rootMeta, components });\r\n return { shadowStateStore: newShadowStore };\r\n }\r\n\r\n return state; // Nothing changed\r\n });\r\n },\r\n markAsDirty: (key: string, path: string[], options = { bubble: true }) => {\r\n const newShadowStore = new Map(get().shadowStateStore);\r\n let changed = false;\r\n\r\n const setDirty = (currentPath: string[]) => {\r\n const fullKey = [key, ...currentPath].join('.');\r\n const meta = newShadowStore.get(fullKey);\r\n\r\n // We mark something as dirty if it isn't already.\r\n // The original data source doesn't matter.\r\n if (meta && meta.isDirty !== true) {\r\n newShadowStore.set(fullKey, { ...meta, isDirty: true });\r\n changed = true;\r\n } else if (!meta) {\r\n // If there's no metadata, create it and mark it as dirty.\r\n // This handles newly created fields within an object.\r\n newShadowStore.set(fullKey, { isDirty: true });\r\n changed = true;\r\n }\r\n };\r\n\r\n // 1. Mark the target path itself as dirty.\r\n setDirty(path);\r\n\r\n // 2. If `bubble` is true, walk up the path and mark all parents as dirty.\r\n if (options.bubble) {\r\n let parentPath = [...path];\r\n while (parentPath.length > 0) {\r\n parentPath.pop();\r\n setDirty(parentPath);\r\n }\r\n }\r\n\r\n if (changed) {\r\n set({ shadowStateStore: newShadowStore });\r\n }\r\n },\r\n serverStateUpdates: new Map(),\r\n setServerStateUpdate: (key, serverState) => {\r\n set((state) => {\r\n const newMap = new Map(state.serverStateUpdates);\r\n newMap.set(key, serverState);\r\n return { serverStateUpdates: newMap };\r\n });\r\n\r\n // Notify all subscribers for this key\r\n get().notifyPathSubscribers(key, {\r\n type: 'SERVER_STATE_UPDATE',\r\n serverState,\r\n });\r\n },\r\n shadowStateStore: new Map(),\r\n getShadowNode: (key: string) => get().shadowStateStore.get(key),\r\n pathSubscribers: new Map<string, Set<(newValue: any) => void>>(),\r\n\r\n subscribeToPath: (path, callback) => {\r\n const subscribers = get().pathSubscribers;\r\n const subsForPath = subscribers.get(path) || new Set();\r\n subsForPath.add(callback);\r\n subscribers.set(path, subsForPath);\r\n\r\n return () => {\r\n const currentSubs = get().pathSubscribers.get(path);\r\n if (currentSubs) {\r\n currentSubs.delete(callback);\r\n if (currentSubs.size === 0) {\r\n get().pathSubscribers.delete(path);\r\n }\r\n }\r\n };\r\n },\r\n\r\n notifyPathSubscribers: (updatedPath, newValue) => {\r\n const subscribers = get().pathSubscribers;\r\n const subs = subscribers.get(updatedPath);\r\n\r\n if (subs) {\r\n subs.forEach((callback) => callback(newValue));\r\n }\r\n },\r\n\r\n initializeShadowState: (key: string, initialState: any) => {\r\n set((state) => {\r\n // 1. Make a copy of the current store to modify it\r\n const newShadowStore = new Map(state.shadowStateStore);\r\n\r\n // 2. PRESERVE the existing components map before doing anything else\r\n const existingRootMeta = newShadowStore.get(key);\r\n const preservedComponents = existingRootMeta?.components;\r\n\r\n // 3. Wipe all old shadow entries for this state key\r\n const prefixToDelete = key + '.';\r\n for (const k of Array.from(newShadowStore.keys())) {\r\n if (k === key || k.startsWith(prefixToDelete)) {\r\n newShadowStore.delete(k);\r\n }\r\n }\r\n\r\n // 4. Run your original logic to rebuild the state tree from scratch\r\n const processValue = (value: any, path: string[]) => {\r\n const nodeKey = [key, ...path].join('.');\r\n\r\n if (Array.isArray(value)) {\r\n const childIds: string[] = [];\r\n value.forEach(() => {\r\n const itemId = `id:${ulid()}`;\r\n childIds.push(nodeKey + '.' + itemId);\r\n });\r\n newShadowStore.set(nodeKey, { arrayKeys: childIds });\r\n value.forEach((item, index) => {\r\n const itemId = childIds[index]!.split('.').pop();\r\n processValue(item, [...path!, itemId!]);\r\n });\r\n } else if (isSimpleObject(value)) {\r\n const fields = Object.fromEntries(\r\n Object.keys(value).map((k) => [k, nodeKey + '.' + k])\r\n );\r\n newShadowStore.set(nodeKey, { fields });\r\n Object.keys(value).forEach((k) => {\r\n processValue(value[k], [...path, k]);\r\n });\r\n } else {\r\n newShadowStore.set(nodeKey, { value });\r\n }\r\n };\r\n processValue(initialState, []);\r\n\r\n // 5. RESTORE the preserved components map onto the new root metadata\r\n if (preservedComponents) {\r\n const newRootMeta = newShadowStore.get(key) || {};\r\n newShadowStore.set(key, {\r\n ...newRootMeta,\r\n components: preservedComponents,\r\n });\r\n }\r\n\r\n // 6. Return the completely updated state\r\n return { shadowStateStore: newShadowStore };\r\n });\r\n },\r\n\r\n getShadowValue: (fullKey: string, validArrayIds?: string[]) => {\r\n // The cache is created here. It's temporary and exists only for this one top-level call.\r\n const memo = new Map<string, any>();\r\n\r\n // This is the inner recursive function that does the real work.\r\n const reconstruct = (keyToBuild: string, ids?: string[]): any => {\r\n // --- STEP 1: Check the cache first ---\r\n // If we have already built the object for this path *during this call*, return it instantly.\r\n if (memo.has(keyToBuild)) {\r\n return memo.get(keyToBuild);\r\n }\r\n\r\n const shadowMeta = get().shadowStateStore.get(keyToBuild);\r\n\r\n if (!shadowMeta) {\r\n return undefined;\r\n }\r\n\r\n if (shadowMeta.value !== undefined) {\r\n return shadowMeta.value;\r\n }\r\n\r\n let result: any; // The value we are about to build.\r\n\r\n if (shadowMeta.arrayKeys) {\r\n const keys = ids ?? shadowMeta.arrayKeys;\r\n // --- IMPORTANT: Set the cache BEFORE the recursive calls ---\r\n // This handles circular references gracefully. We put an empty array in the cache now.\r\n result = [];\r\n memo.set(keyToBuild, result);\r\n // Now, fill the array with the recursively constructed items.\r\n keys.forEach((itemKey) => {\r\n result.push(reconstruct(itemKey)); // Pass the memo cache along implicitly via closure\r\n });\r\n } else if (shadowMeta.fields) {\r\n // --- IMPORTANT: Set the cache BEFORE the recursive calls ---\r\n result = {};\r\n memo.set(keyToBuild, result);\r\n // Now, fill the object with the recursively constructed items.\r\n Object.entries(shadowMeta.fields).forEach(([key, fieldPath]) => {\r\n result[key] = reconstruct(fieldPath as string);\r\n });\r\n } else {\r\n result = undefined;\r\n }\r\n\r\n // Return the final, fully populated result.\r\n return result;\r\n };\r\n\r\n // Start the process by calling the inner function on the root key.\r\n return reconstruct(fullKey, validArrayIds);\r\n },\r\n getShadowMetadata: (\r\n key: string,\r\n path: string[],\r\n validArrayIds?: string[]\r\n ) => {\r\n const fullKey = [key, ...path].join('.');\r\n let data = get().shadowStateStore.get(fullKey);\r\n\r\n return get().shadowStateStore.get(fullKey);\r\n },\r\n\r\n setShadowMetadata: (key, path, metadata) => {\r\n const fullKey = [key, ...path].join('.');\r\n const existingMeta = get().shadowStateStore.get(fullKey);\r\n\r\n // --- THIS IS THE TRAP ---\r\n // If the existing metadata HAS a components map, but the NEW metadata DOES NOT,\r\n // it means we are about to wipe it out. This is the bug.\r\n if (existingMeta?.components && !metadata.components) {\r\n console.group(\r\n '%c🚨 RACE CONDITION DETECTED! 🚨',\r\n 'color: red; font-size: 18px; font-weight: bold;'\r\n );\r\n console.error(\r\n `An overwrite is about to happen on stateKey: \"${key}\" at path: [${path.join(', ')}]`\r\n );\r\n console.log(\r\n 'The EXISTING metadata had a components map:',\r\n existingMeta.components\r\n );\r\n console.log(\r\n 'The NEW metadata is trying to save WITHOUT a components map:',\r\n metadata\r\n );\r\n console.log(\r\n '%cStack trace to the function that caused this overwrite:',\r\n 'font-weight: bold;'\r\n );\r\n console.trace(); // This prints the call stack, leading you to the bad code.\r\n console.groupEnd();\r\n }\r\n // --- END OF TRAP ---\r\n\r\n const newShadowStore = new Map(get().shadowStateStore);\r\n const finalMeta = { ...(existingMeta || {}), ...metadata };\r\n newShadowStore.set(fullKey, finalMeta);\r\n set({ shadowStateStore: newShadowStore });\r\n },\r\n setTransformCache: (\r\n key: string,\r\n path: string[],\r\n cacheKey: string,\r\n cacheData: any\r\n ) => {\r\n const fullKey = [key, ...path].join('.');\r\n const newShadowStore = new Map(get().shadowStateStore);\r\n const existing = newShadowStore.get(fullKey) || {};\r\n\r\n // Initialize transformCaches if it doesn't exist\r\n if (!existing.transformCaches) {\r\n existing.transformCaches = new Map();\r\n }\r\n\r\n // Update just the specific cache entry\r\n existing.transformCaches.set(cacheKey, cacheData);\r\n\r\n // Update shadow store WITHOUT notifying path subscribers\r\n newShadowStore.set(fullKey, existing);\r\n set({ shadowStateStore: newShadowStore });\r\n\r\n // Don't call notifyPathSubscribers here - cache updates shouldn't trigger renders\r\n },\r\n insertShadowArrayElement: (\r\n key: string,\r\n arrayPath: string[],\r\n newItem: any\r\n ) => {\r\n const newShadowStore = new Map(get().shadowStateStore);\r\n const arrayKey = [key, ...arrayPath].join('.');\r\n const parentMeta = newShadowStore.get(arrayKey);\r\n\r\n if (!parentMeta || !parentMeta.arrayKeys) return;\r\n\r\n const newItemId = `id:${ulid()}`;\r\n const fullItemKey = arrayKey + '.' + newItemId;\r\n\r\n // Just add to the end (or at a specific index if provided)\r\n const newArrayKeys = [...parentMeta.arrayKeys];\r\n newArrayKeys.push(fullItemKey); // Or use splice if you have an index\r\n newShadowStore.set(arrayKey, { ...parentMeta, arrayKeys: newArrayKeys });\r\n\r\n // Process the new item - but use the correct logic\r\n const processNewItem = (value: any, path: string[]) => {\r\n const nodeKey = [key, ...path].join('.');\r\n\r\n if (Array.isArray(value)) {\r\n // Handle arrays...\r\n } else if (typeof value === 'object' && value !== null) {\r\n // Create fields mapping\r\n const fields = Object.fromEntries(\r\n Object.keys(value).map((k) => [k, nodeKey + '.' + k])\r\n );\r\n newShadowStore.set(nodeKey, { fields });\r\n\r\n // Process each field\r\n Object.entries(value).forEach(([k, v]) => {\r\n processNewItem(v, [...path, k]);\r\n });\r\n } else {\r\n // Primitive value\r\n newShadowStore.set(nodeKey, { value });\r\n }\r\n };\r\n\r\n processNewItem(newItem, [...arrayPath, newItemId]);\r\n set({ shadowStateStore: newShadowStore });\r\n\r\n get().notifyPathSubscribers(arrayKey, {\r\n type: 'INSERT',\r\n path: arrayKey,\r\n itemKey: fullItemKey,\r\n });\r\n },\r\n removeShadowArrayElement: (key: string, itemPath: string[]) => {\r\n const newShadowStore = new Map(get().shadowStateStore);\r\n\r\n // Get the full item key (e.g., \"stateKey.products.id:xxx\")\r\n const itemKey = [key, ...itemPath].join('.');\r\n\r\n // Extract parent path and item ID\r\n const parentPath = itemPath.slice(0, -1);\r\n const parentKey = [key, ...parentPath].join('.');\r\n\r\n // Get parent metadata\r\n const parentMeta = newShadowStore.get(parentKey);\r\n\r\n if (parentMeta && parentMeta.arrayKeys) {\r\n // Find the index of the item to remove\r\n const indexToRemove = parentMeta.arrayKeys.findIndex(\r\n (arrayItemKey) => arrayItemKey === itemKey\r\n );\r\n\r\n if (indexToRemove !== -1) {\r\n // Create new array keys with the item removed\r\n const newArrayKeys = parentMeta.arrayKeys.filter(\r\n (arrayItemKey) => arrayItemKey !== itemKey\r\n );\r\n\r\n // Update parent with new array keys\r\n newShadowStore.set(parentKey, {\r\n ...parentMeta,\r\n arrayKeys: newArrayKeys,\r\n });\r\n\r\n // Delete all data associated with the removed item\r\n const prefixToDelete = itemKey + '.';\r\n for (const k of Array.from(newShadowStore.keys())) {\r\n if (k === itemKey || k.startsWith(prefixToDelete)) {\r\n newShadowStore.delete(k);\r\n }\r\n }\r\n }\r\n }\r\n\r\n set({ shadowStateStore: newShadowStore });\r\n\r\n get().notifyPathSubscribers(parentKey, {\r\n type: 'REMOVE',\r\n path: parentKey,\r\n itemKey: itemKey, // The exact ID of the removed item\r\n });\r\n },\r\n updateShadowAtPath: (key, path, newValue) => {\r\n const newShadowStore = new Map(get().shadowStateStore);\r\n const fullKey = [key, ...path].join('.');\r\n\r\n const updateValue = (currentKey: string, valueToSet: any) => {\r\n const meta = newShadowStore.get(currentKey);\r\n\r\n // If it's a simple object with fields, update recursively\r\n if (isSimpleObject(valueToSet) && meta && meta.fields) {\r\n for (const fieldKey in valueToSet) {\r\n if (Object.prototype.hasOwnProperty.call(valueToSet, fieldKey)) {\r\n const childPath = meta.fields[fieldKey];\r\n const childValue = valueToSet[fieldKey];\r\n\r\n if (childPath) {\r\n updateValue(childPath as string, childValue);\r\n }\r\n }\r\n }\r\n } else {\r\n // For primitives (including Uint8Array), just replace the value\r\n // This gives you useState-like behavior\r\n const existing = newShadowStore.get(currentKey) || {};\r\n newShadowStore.set(currentKey, { ...existing, value: valueToSet });\r\n }\r\n };\r\n\r\n updateValue(fullKey, newValue);\r\n get().notifyPathSubscribers(fullKey, { type: 'UPDATE', newValue });\r\n set({ shadowStateStore: newShadowStore });\r\n },\r\n selectedIndicesMap: new Map<string, string>(),\r\n getSelectedIndex: (arrayKey: string, validIds?: string[]): number => {\r\n const itemKey = get().selectedIndicesMap.get(arrayKey);\r\n\r\n if (!itemKey) return -1;\r\n\r\n // Use validIds if provided (for filtered views), otherwise use all arrayKeys\r\n const arrayKeys =\r\n validIds ||\r\n getGlobalStore.getState().getShadowMetadata(arrayKey, [])?.arrayKeys;\r\n\r\n if (!arrayKeys) return -1;\r\n\r\n return arrayKeys.indexOf(itemKey);\r\n },\r\n\r\n setSelectedIndex: (arrayKey: string, itemKey: string | undefined) => {\r\n set((state) => {\r\n const newMap = state.selectedIndicesMap;\r\n\r\n if (itemKey === undefined) {\r\n newMap.delete(arrayKey);\r\n } else {\r\n if (newMap.has(arrayKey)) {\r\n get().notifyPathSubscribers(newMap.get(arrayKey)!, {\r\n type: 'THIS_UNSELECTED',\r\n });\r\n }\r\n newMap.set(arrayKey, itemKey);\r\n\r\n get().notifyPathSubscribers(itemKey, {\r\n type: 'THIS_SELECTED',\r\n });\r\n }\r\n get().notifyPathSubscribers(arrayKey, {\r\n type: 'GET_SELECTED',\r\n });\r\n return {\r\n ...state,\r\n selectedIndicesMap: newMap,\r\n };\r\n });\r\n },\r\n clearSelectedIndex: ({ arrayKey }: { arrayKey: string }): void => {\r\n set((state) => {\r\n const newMap = state.selectedIndicesMap;\r\n const acutalKey = newMap.get(arrayKey);\r\n if (acutalKey) {\r\n get().notifyPathSubscribers(acutalKey, {\r\n type: 'CLEAR_SELECTION',\r\n });\r\n }\r\n\r\n newMap.delete(arrayKey);\r\n get().notifyPathSubscribers(arrayKey, {\r\n type: 'CLEAR_SELECTION',\r\n });\r\n return {\r\n ...state,\r\n selectedIndicesMap: newMap,\r\n };\r\n });\r\n },\r\n clearSelectedIndexesForState: (stateKey: string) => {\r\n set((state) => {\r\n const newOuterMap = new Map(state.selectedIndicesMap);\r\n const changed = newOuterMap.delete(stateKey);\r\n if (changed) {\r\n return { selectedIndicesMap: newOuterMap };\r\n } else {\r\n return {};\r\n }\r\n });\r\n },\r\n\r\n initialStateOptions: {},\r\n\r\n stateTimeline: {},\r\n cogsStateStore: {},\r\n stateLog: new Map(),\r\n\r\n initialStateGlobal: {},\r\n\r\n validationErrors: new Map(),\r\n addStateLog: (key, update) => {\r\n set((state) => {\r\n const newLog = new Map(state.stateLog);\r\n const stateLogForKey = new Map(newLog.get(key));\r\n const uniquePathKey = JSON.stringify(update.path);\r\n\r\n const existing = stateLogForKey.get(uniquePathKey);\r\n if (existing) {\r\n // If an update for this path already exists, just modify it. (Fast)\r\n existing.newValue = update.newValue;\r\n existing.timeStamp = update.timeStamp;\r\n } else {\r\n // Otherwise, add the new update. (Fast)\r\n stateLogForKey.set(uniquePathKey, { ...update });\r\n }\r\n\r\n newLog.set(key, stateLogForKey);\r\n return { stateLog: newLog };\r\n });\r\n },\r\n\r\n getInitialOptions: (key) => {\r\n return get().initialStateOptions[key];\r\n },\r\n\r\n setInitialStateOptions: (key, value) => {\r\n set((prev) => ({\r\n initialStateOptions: {\r\n ...prev.initialStateOptions,\r\n [key]: value,\r\n },\r\n }));\r\n },\r\n updateInitialStateGlobal: (key, newState) => {\r\n set((prev) => ({\r\n initialStateGlobal: {\r\n ...prev.initialStateGlobal,\r\n [key]: newState,\r\n },\r\n }));\r\n },\r\n\r\n syncInfoStore: new Map<string, SyncInfo>(),\r\n setSyncInfo: (key: string, syncInfo: SyncInfo) =>\r\n set((state) => {\r\n const newMap = new Map(state.syncInfoStore);\r\n newMap.set(key, syncInfo);\r\n return { ...state, syncInfoStore: newMap };\r\n }),\r\n getSyncInfo: (key: string) => get().syncInfoStore.get(key) || null,\r\n}));\r\n"],"names":["formRefStore","create","set","get","id","ref","state","newRefs","stateKey","allRefs","stateKeyPrefix","filteredRefs","isSimpleObject","value","getGlobalStore","updateQueue","startTransition","updateFn","dependencyPath","fullComponentId","newShadowStore","dependencyKey","pathMeta","pathComponents","rootMeta","component","newPaths","newComponentRegistration","newComponentsMap","registration","components","key","path","options","changed","setDirty","currentPath","fullKey","meta","parentPath","serverState","newMap","callback","subscribers","subsForPath","currentSubs","updatedPath","newValue","subs","initialState","preservedComponents","prefixToDelete","k","processValue","nodeKey","childIds","itemId","ulid","item","index","fields","newRootMeta","validArrayIds","memo","reconstruct","keyToBuild","ids","shadowMeta","result","keys","itemKey","fieldPath","metadata","existingMeta","finalMeta","cacheKey","cacheData","existing","arrayPath","newItem","arrayKey","parentMeta","newItemId","fullItemKey","newArrayKeys","processNewItem","v","itemPath","parentKey","arrayItemKey","updateValue","currentKey","valueToSet","fieldKey","childPath","childValue","validIds","arrayKeys","acutalKey","newOuterMap","update","newLog","stateLogForKey","uniquePathKey","prev","newState","syncInfo"],"mappings":"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"}
1
+ {"version":3,"file":"store.js","sources":["../src/store.ts"],"sourcesContent":["import { create } from 'zustand';\r\nimport { ulid } from 'ulid';\r\nimport type {\r\n OptionsType,\r\n ReactivityType,\r\n StateKeys,\r\n SyncInfo,\r\n UpdateTypeDetail,\r\n} from './CogsState.js';\r\n\r\nimport { startTransition, type ReactNode } from 'react';\r\n\r\ntype StateUpdater<StateValue> =\r\n | StateValue\r\n | ((prevValue: StateValue) => StateValue);\r\n\r\nexport type FreshValuesObject = {\r\n pathsToValues?: string[];\r\n prevValue?: any;\r\n newValue?: any;\r\n timeStamp: number;\r\n};\r\n\r\ntype SyncLogType = {\r\n timeStamp: number;\r\n};\r\ntype StateValue = any;\r\n\r\nexport type TrieNode = {\r\n subscribers: Set<string>;\r\n children: Map<string, TrieNode>;\r\n};\r\n\r\nexport type FormRefStoreState = {\r\n formRefs: Map<string, React.RefObject<any>>;\r\n registerFormRef: (id: string, ref: React.RefObject<any>) => void;\r\n getFormRef: (id: string) => React.RefObject<any> | undefined;\r\n removeFormRef: (id: string) => void;\r\n // New method to get all refs for a stateKey\r\n getFormRefsByStateKey: (\r\n stateKey: string\r\n ) => Map<string, React.RefObject<any>>;\r\n};\r\n\r\nexport const formRefStore = create<FormRefStoreState>((set, get) => ({\r\n formRefs: new Map(),\r\n\r\n registerFormRef: (id, ref) =>\r\n set((state) => {\r\n const newRefs = new Map(state.formRefs);\r\n newRefs.set(id, ref);\r\n return { formRefs: newRefs };\r\n }),\r\n\r\n getFormRef: (id) => get().formRefs.get(id),\r\n\r\n removeFormRef: (id) =>\r\n set((state) => {\r\n const newRefs = new Map(state.formRefs);\r\n newRefs.delete(id);\r\n return { formRefs: newRefs };\r\n }),\r\n\r\n // Get all refs that start with the stateKey prefix\r\n getFormRefsByStateKey: (stateKey) => {\r\n const allRefs = get().formRefs;\r\n const stateKeyPrefix = stateKey + '.';\r\n const filteredRefs = new Map();\r\n\r\n allRefs.forEach((ref, id) => {\r\n if (id.startsWith(stateKeyPrefix) || id === stateKey) {\r\n filteredRefs.set(id, ref);\r\n }\r\n });\r\n\r\n return filteredRefs;\r\n },\r\n}));\r\nexport type ComponentsType = {\r\n components?: Map<\r\n string,\r\n {\r\n forceUpdate: () => void;\r\n paths: Set<string>;\r\n deps?: any[];\r\n prevDeps?: any[];\r\n depsFunction?: (state: any) => any[] | true;\r\n reactiveType: ReactivityType[] | ReactivityType;\r\n }\r\n >;\r\n};\r\nexport type ShadowMetadata = {\r\n id?: string;\r\n\r\n stateSource?: 'default' | 'server' | 'localStorage';\r\n lastServerSync?: number;\r\n isDirty?: boolean;\r\n baseServerState?: any;\r\n\r\n arrayKeys?: string[];\r\n\r\n fields?: Record<string, any>;\r\n virtualizer?: {\r\n itemHeight?: number;\r\n domRef?: HTMLElement | null;\r\n };\r\n syncInfo?: { status: string };\r\n validation?: ValidationState;\r\n lastUpdated?: number;\r\n value?: any;\r\n classSignals?: Array<{\r\n id: string;\r\n effect: string;\r\n lastClasses: string;\r\n deps: any[];\r\n }>;\r\n signals?: Array<{\r\n instanceId: string;\r\n parentId: string;\r\n position: number;\r\n effect?: string;\r\n }>;\r\n mapWrappers?: Array<{\r\n instanceId: string;\r\n path: string[];\r\n componentId: string;\r\n meta?: any;\r\n mapFn: (\r\n setter: any,\r\n index: number,\r\n\r\n arraySetter: any\r\n ) => ReactNode;\r\n containerRef: HTMLDivElement | null;\r\n rebuildStateShape: any;\r\n }>;\r\n transformCaches?: Map<\r\n string,\r\n {\r\n validIds: string[];\r\n computedAt: number;\r\n transforms: Array<{ type: 'filter' | 'sort'; fn: Function }>;\r\n }\r\n >;\r\n pathComponents?: Set<string>;\r\n streams?: Map<\r\n string,\r\n {\r\n buffer: any[];\r\n flushTimer: NodeJS.Timeout | null;\r\n }\r\n >;\r\n} & ComponentsType;\r\n\r\nexport type ValidationStatus =\r\n | 'PRISTINE' // Untouched, matches initial state.\r\n | 'DIRTY' // Changed, but no validation run yet.\r\n | 'VALID_LIVE' // Valid while typing.\r\n | 'INVALID_LIVE' // Gentle error during typing.\r\n | 'VALIDATION_FAILED' // Hard error on blur/submit.\r\n | 'VALID_PENDING_SYNC' // Passed validation, ready for sync.\r\n | 'SYNCING' // Actively being sent to the server.\r\n | 'SYNCED' // Server confirmed success.\r\n | 'SYNC_FAILED'; // Server rejected the data.\r\n\r\nexport type ValidationState = {\r\n status: ValidationStatus;\r\n message?: string;\r\n lastValidated?: number;\r\n validatedValue?: any;\r\n};\r\nexport type CogsEvent =\r\n | { type: 'INSERT'; path: string; itemKey: string; index: number }\r\n | { type: 'REMOVE'; path: string; itemKey: string }\r\n | { type: 'UPDATE'; path: string; newValue: any }\r\n | { type: 'ITEMHEIGHT'; itemKey: string; height: number }\r\n | { type: 'RELOAD'; path: string };\r\nexport type CogsGlobalState = {\r\n updateQueue: Set<() => void>;\r\n isFlushScheduled: boolean;\r\n\r\n flushUpdates: () => void;\r\n\r\n // --- Shadow State and Subscription System ---\r\n registerComponent: (\r\n stateKey: string,\r\n componentId: string,\r\n registration: any\r\n ) => void;\r\n unregisterComponent: (stateKey: string, componentId: string) => void;\r\n addPathComponent: (\r\n stateKey: string,\r\n dependencyPath: string[],\r\n fullComponentId: string\r\n ) => void;\r\n shadowStateStore: Map<string, ShadowMetadata>;\r\n\r\n markAsDirty: (\r\n key: string,\r\n path: string[],\r\n options: { bubble: boolean }\r\n ) => void;\r\n // These method signatures stay the same\r\n initializeShadowState: (key: string, initialState: any) => void;\r\n updateShadowAtPath: (key: string, path: string[], newValue: any) => void;\r\n insertShadowArrayElement: (\r\n key: string,\r\n arrayPath: string[],\r\n newItem: any\r\n ) => void;\r\n removeShadowArrayElement: (key: string, arrayPath: string[]) => void;\r\n getShadowValue: (\r\n key: string,\r\n\r\n validArrayIds?: string[]\r\n ) => any;\r\n\r\n getShadowMetadata: (\r\n key: string,\r\n path: string[]\r\n ) => ShadowMetadata | undefined;\r\n setShadowMetadata: (\r\n key: string,\r\n path: string[],\r\n metadata: Omit<ShadowMetadata, 'id'>\r\n ) => void;\r\n setTransformCache: (\r\n key: string,\r\n path: string[],\r\n cacheKey: string,\r\n cacheData: any\r\n ) => void;\r\n\r\n pathSubscribers: Map<string, Set<(newValue: any) => void>>;\r\n subscribeToPath: (\r\n path: string,\r\n callback: (newValue: any) => void\r\n ) => () => void;\r\n notifyPathSubscribers: (updatedPath: string, newValue: any) => void;\r\n\r\n selectedIndicesMap: Map<string, string>; // stateKey -> (parentPath -> selectedIndex)\r\n getSelectedIndex: (stateKey: string, validArrayIds?: string[]) => number;\r\n setSelectedIndex: (key: string, itemKey: string) => void;\r\n clearSelectedIndex: ({ arrayKey }: { arrayKey: string }) => void;\r\n clearSelectedIndexesForState: (stateKey: string) => void;\r\n\r\n // --- Core State and Updaters ---\r\n\r\n initialStateOptions: { [key: string]: OptionsType };\r\n\r\n initialStateGlobal: { [key: string]: StateValue };\r\n\r\n updateInitialStateGlobal: (key: string, newState: StateValue) => void;\r\n\r\n getInitialOptions: (key: string) => OptionsType | undefined;\r\n setInitialStateOptions: (key: string, value: OptionsType) => void;\r\n\r\n serverStateUpdates: Map<\r\n string,\r\n {\r\n data: any;\r\n status: 'loading' | 'success' | 'error';\r\n timestamp: number;\r\n }\r\n >;\r\n\r\n setServerStateUpdate: (key: string, serverState: any) => void;\r\n\r\n stateLog: Map<string, Map<string, UpdateTypeDetail>>;\r\n syncInfoStore: Map<string, SyncInfo>;\r\n addStateLog: (key: string, update: UpdateTypeDetail) => void;\r\n\r\n setSyncInfo: (key: string, syncInfo: SyncInfo) => void;\r\n getSyncInfo: (key: string) => SyncInfo | null;\r\n};\r\nconst isSimpleObject = (value: any): boolean => {\r\n // Most common cases first\r\n if (value === null || typeof value !== 'object') return false;\r\n\r\n // Arrays are simple objects\r\n if (Array.isArray(value)) return true;\r\n\r\n // Plain objects second most common\r\n if (value.constructor === Object) return true;\r\n\r\n // Everything else is not simple\r\n return false;\r\n};\r\nexport const getGlobalStore = create<CogsGlobalState>((set, get) => ({\r\n updateQueue: new Set<() => void>(),\r\n // A flag to ensure we only schedule the flush once per event-loop tick.\r\n isFlushScheduled: false,\r\n\r\n // This function is called by queueMicrotask to execute all queued updates.\r\n flushUpdates: () => {\r\n const { updateQueue } = get();\r\n\r\n if (updateQueue.size > 0) {\r\n startTransition(() => {\r\n updateQueue.forEach((updateFn) => updateFn());\r\n });\r\n }\r\n\r\n // Clear the queue and reset the flag for the next event loop tick.\r\n set({ updateQueue: new Set(), isFlushScheduled: false });\r\n },\r\n addPathComponent: (stateKey, dependencyPath, fullComponentId) => {\r\n set((state) => {\r\n const newShadowStore = new Map(state.shadowStateStore);\r\n const dependencyKey = [stateKey, ...dependencyPath].join('.');\r\n\r\n // --- Part 1: Update the path's own metadata ---\r\n const pathMeta = newShadowStore.get(dependencyKey) || {};\r\n // Create a *new* Set to ensure immutability\r\n const pathComponents = new Set(pathMeta.pathComponents);\r\n pathComponents.add(fullComponentId);\r\n // Update the metadata for the specific path\r\n newShadowStore.set(dependencyKey, { ...pathMeta, pathComponents });\r\n\r\n // --- Part 2: Update the component's own list of paths ---\r\n const rootMeta = newShadowStore.get(stateKey) || {};\r\n const component = rootMeta.components?.get(fullComponentId);\r\n\r\n // If the component exists, update its `paths` set immutably\r\n if (component) {\r\n const newPaths = new Set(component.paths);\r\n newPaths.add(dependencyKey);\r\n\r\n const newComponentRegistration = { ...component, paths: newPaths };\r\n const newComponentsMap = new Map(rootMeta.components);\r\n newComponentsMap.set(fullComponentId, newComponentRegistration);\r\n\r\n // Update the root metadata with the new components map\r\n newShadowStore.set(stateKey, {\r\n ...rootMeta,\r\n components: newComponentsMap,\r\n });\r\n }\r\n\r\n // Return the final, updated state\r\n return { shadowStateStore: newShadowStore };\r\n });\r\n },\r\n registerComponent: (stateKey, fullComponentId, registration) => {\r\n set((state) => {\r\n const newShadowStore = new Map(state.shadowStateStore);\r\n const rootMeta = newShadowStore.get(stateKey) || {};\r\n const components = new Map(rootMeta.components);\r\n components.set(fullComponentId, registration);\r\n newShadowStore.set(stateKey, { ...rootMeta, components });\r\n return { shadowStateStore: newShadowStore };\r\n });\r\n },\r\n\r\n unregisterComponent: (stateKey, fullComponentId) => {\r\n set((state) => {\r\n const newShadowStore = new Map(state.shadowStateStore);\r\n const rootMeta = newShadowStore.get(stateKey);\r\n if (!rootMeta?.components) {\r\n return state; // Return original state, no change needed\r\n }\r\n\r\n const components = new Map(rootMeta.components);\r\n const wasDeleted = components.delete(fullComponentId);\r\n\r\n // Only update state if something was actually deleted\r\n if (wasDeleted) {\r\n newShadowStore.set(stateKey, { ...rootMeta, components });\r\n return { shadowStateStore: newShadowStore };\r\n }\r\n\r\n return state; // Nothing changed\r\n });\r\n },\r\n markAsDirty: (key: string, path: string[], options = { bubble: true }) => {\r\n const { shadowStateStore } = get();\r\n const updates = new Map<string, ShadowMetadata>();\r\n\r\n const setDirty = (currentPath: string[]) => {\r\n const fullKey = [key, ...currentPath].join('.');\r\n const meta = shadowStateStore.get(fullKey) || {};\r\n\r\n // If already dirty, no need to update\r\n if (meta.isDirty === true) {\r\n return true; // Return true to indicate parent is dirty\r\n }\r\n\r\n updates.set(fullKey, { ...meta, isDirty: true });\r\n return false; // Not previously dirty\r\n };\r\n\r\n // Mark the target path\r\n setDirty(path);\r\n\r\n // Bubble up if requested\r\n if (options.bubble) {\r\n let parentPath = [...path];\r\n while (parentPath.length > 0) {\r\n parentPath.pop();\r\n const wasDirty = setDirty(parentPath);\r\n if (wasDirty) {\r\n break; // Stop bubbling if parent was already dirty\r\n }\r\n }\r\n }\r\n\r\n // Apply all updates at once\r\n if (updates.size > 0) {\r\n set((state) => {\r\n updates.forEach((meta, key) => {\r\n state.shadowStateStore.set(key, meta);\r\n });\r\n return state;\r\n });\r\n }\r\n },\r\n serverStateUpdates: new Map(),\r\n setServerStateUpdate: (key, serverState) => {\r\n set((state) => {\r\n const newMap = new Map(state.serverStateUpdates);\r\n newMap.set(key, serverState);\r\n return { serverStateUpdates: newMap };\r\n });\r\n\r\n // Notify all subscribers for this key\r\n get().notifyPathSubscribers(key, {\r\n type: 'SERVER_STATE_UPDATE',\r\n serverState,\r\n });\r\n },\r\n shadowStateStore: new Map(),\r\n getShadowNode: (key: string) => get().shadowStateStore.get(key),\r\n pathSubscribers: new Map<string, Set<(newValue: any) => void>>(),\r\n\r\n subscribeToPath: (path, callback) => {\r\n const subscribers = get().pathSubscribers;\r\n const subsForPath = subscribers.get(path) || new Set();\r\n subsForPath.add(callback);\r\n subscribers.set(path, subsForPath);\r\n\r\n return () => {\r\n const currentSubs = get().pathSubscribers.get(path);\r\n if (currentSubs) {\r\n currentSubs.delete(callback);\r\n if (currentSubs.size === 0) {\r\n get().pathSubscribers.delete(path);\r\n }\r\n }\r\n };\r\n },\r\n\r\n notifyPathSubscribers: (updatedPath, newValue) => {\r\n const subscribers = get().pathSubscribers;\r\n const subs = subscribers.get(updatedPath);\r\n\r\n if (subs) {\r\n subs.forEach((callback) => callback(newValue));\r\n }\r\n },\r\n\r\n initializeShadowState: (key: string, initialState: any) => {\r\n set((state) => {\r\n // 1. Make a copy of the current store to modify it\r\n const newShadowStore = new Map(state.shadowStateStore);\r\n console.log('initializeShadowState');\r\n // 2. PRESERVE the existing components map before doing anything else\r\n const existingRootMeta = newShadowStore.get(key);\r\n const preservedComponents = existingRootMeta?.components;\r\n\r\n // 3. Wipe all old shadow entries for this state key\r\n const prefixToDelete = key + '.';\r\n for (const k of Array.from(newShadowStore.keys())) {\r\n if (k === key || k.startsWith(prefixToDelete)) {\r\n newShadowStore.delete(k);\r\n }\r\n }\r\n\r\n // 4. Run your original logic to rebuild the state tree from scratch\r\n const processValue = (value: any, path: string[]) => {\r\n const nodeKey = [key, ...path].join('.');\r\n\r\n if (Array.isArray(value)) {\r\n const childIds: string[] = [];\r\n value.forEach(() => {\r\n const itemId = `id:${ulid()}`;\r\n childIds.push(nodeKey + '.' + itemId);\r\n });\r\n newShadowStore.set(nodeKey, { arrayKeys: childIds });\r\n value.forEach((item, index) => {\r\n const itemId = childIds[index]!.split('.').pop();\r\n processValue(item, [...path!, itemId!]);\r\n });\r\n } else if (isSimpleObject(value)) {\r\n const fields = Object.fromEntries(\r\n Object.keys(value).map((k) => [k, nodeKey + '.' + k])\r\n );\r\n newShadowStore.set(nodeKey, { fields });\r\n Object.keys(value).forEach((k) => {\r\n processValue(value[k], [...path, k]);\r\n });\r\n } else {\r\n newShadowStore.set(nodeKey, { value });\r\n }\r\n };\r\n processValue(initialState, []);\r\n\r\n // 5. RESTORE the preserved components map onto the new root metadata\r\n if (preservedComponents) {\r\n const newRootMeta = newShadowStore.get(key) || {};\r\n newShadowStore.set(key, {\r\n ...newRootMeta,\r\n components: preservedComponents,\r\n });\r\n }\r\n\r\n // 6. Return the completely updated state\r\n return { shadowStateStore: newShadowStore };\r\n });\r\n },\r\n\r\n getShadowValue: (fullKey: string, validArrayIds?: string[]) => {\r\n const memo = new Map<string, any>();\r\n const reconstruct = (keyToBuild: string, ids?: string[]): any => {\r\n if (memo.has(keyToBuild)) {\r\n return memo.get(keyToBuild);\r\n }\r\n\r\n const shadowMeta = get().shadowStateStore.get(keyToBuild);\r\n if (!shadowMeta) {\r\n return undefined;\r\n }\r\n\r\n if (shadowMeta.value !== undefined) {\r\n return shadowMeta.value;\r\n }\r\n\r\n let result: any; // The value we are about to build.\r\n\r\n if (shadowMeta.arrayKeys) {\r\n const keys = ids ?? shadowMeta.arrayKeys;\r\n result = [];\r\n memo.set(keyToBuild, result);\r\n keys.forEach((itemKey) => {\r\n result.push(reconstruct(itemKey));\r\n });\r\n } else if (shadowMeta.fields) {\r\n result = {};\r\n memo.set(keyToBuild, result);\r\n Object.entries(shadowMeta.fields).forEach(([key, fieldPath]) => {\r\n result[key] = reconstruct(fieldPath as string);\r\n });\r\n } else {\r\n result = undefined;\r\n }\r\n\r\n // Return the final, fully populated result.\r\n return result;\r\n };\r\n\r\n // Start the process by calling the inner function on the root key.\r\n return reconstruct(fullKey, validArrayIds);\r\n },\r\n getShadowMetadata: (key: string, path: string[]) => {\r\n const fullKey = [key, ...path].join('.');\r\n\r\n return get().shadowStateStore.get(fullKey);\r\n },\r\n\r\n setShadowMetadata: (key, path, metadata) => {\r\n const fullKey = [key, ...path].join('.');\r\n const existingMeta = get().shadowStateStore.get(fullKey);\r\n\r\n // --- THIS IS THE TRAP ---\r\n // If the existing metadata HAS a components map, but the NEW metadata DOES NOT,\r\n // it means we are about to wipe it out. This is the bug.\r\n if (existingMeta?.components && !metadata.components) {\r\n console.group(\r\n '%c🚨 RACE CONDITION DETECTED! 🚨',\r\n 'color: red; font-size: 18px; font-weight: bold;'\r\n );\r\n console.error(\r\n `An overwrite is about to happen on stateKey: \"${key}\" at path: [${path.join(', ')}]`\r\n );\r\n console.log(\r\n 'The EXISTING metadata had a components map:',\r\n existingMeta.components\r\n );\r\n console.log(\r\n 'The NEW metadata is trying to save WITHOUT a components map:',\r\n metadata\r\n );\r\n console.log(\r\n '%cStack trace to the function that caused this overwrite:',\r\n 'font-weight: bold;'\r\n );\r\n console.trace(); // This prints the call stack, leading you to the bad code.\r\n console.groupEnd();\r\n }\r\n // --- END OF TRAP ---\r\n\r\n const newShadowStore = new Map(get().shadowStateStore);\r\n const finalMeta = { ...(existingMeta || {}), ...metadata };\r\n newShadowStore.set(fullKey, finalMeta);\r\n set({ shadowStateStore: newShadowStore });\r\n },\r\n setTransformCache: (\r\n key: string,\r\n path: string[],\r\n cacheKey: string,\r\n cacheData: any\r\n ) => {\r\n const fullKey = [key, ...path].join('.');\r\n const newShadowStore = new Map(get().shadowStateStore);\r\n const existing = newShadowStore.get(fullKey) || {};\r\n\r\n // Initialize transformCaches if it doesn't exist\r\n if (!existing.transformCaches) {\r\n existing.transformCaches = new Map();\r\n }\r\n\r\n // Update just the specific cache entry\r\n existing.transformCaches.set(cacheKey, cacheData);\r\n\r\n // Update shadow store WITHOUT notifying path subscribers\r\n newShadowStore.set(fullKey, existing);\r\n set({ shadowStateStore: newShadowStore });\r\n\r\n // Don't call notifyPathSubscribers here - cache updates shouldn't trigger renders\r\n },\r\n insertShadowArrayElement: (\r\n key: string,\r\n arrayPath: string[],\r\n newItem: any\r\n ) => {\r\n const newShadowStore = new Map(get().shadowStateStore);\r\n const arrayKey = [key, ...arrayPath].join('.');\r\n const parentMeta = newShadowStore.get(arrayKey);\r\n\r\n if (!parentMeta || !parentMeta.arrayKeys) return;\r\n\r\n const newItemId = `id:${ulid()}`;\r\n const fullItemKey = arrayKey + '.' + newItemId;\r\n\r\n // Just add to the end (or at a specific index if provided)\r\n const newArrayKeys = [...parentMeta.arrayKeys];\r\n newArrayKeys.push(fullItemKey); // Or use splice if you have an index\r\n newShadowStore.set(arrayKey, { ...parentMeta, arrayKeys: newArrayKeys });\r\n\r\n // Process the new item - but use the correct logic\r\n const processNewItem = (value: any, path: string[]) => {\r\n const nodeKey = [key, ...path].join('.');\r\n\r\n if (Array.isArray(value)) {\r\n // Handle arrays...\r\n } else if (typeof value === 'object' && value !== null) {\r\n // Create fields mapping\r\n const fields = Object.fromEntries(\r\n Object.keys(value).map((k) => [k, nodeKey + '.' + k])\r\n );\r\n newShadowStore.set(nodeKey, { fields });\r\n\r\n // Process each field\r\n Object.entries(value).forEach(([k, v]) => {\r\n processNewItem(v, [...path, k]);\r\n });\r\n } else {\r\n // Primitive value\r\n newShadowStore.set(nodeKey, { value });\r\n }\r\n };\r\n\r\n processNewItem(newItem, [...arrayPath, newItemId]);\r\n set({ shadowStateStore: newShadowStore });\r\n\r\n get().notifyPathSubscribers(arrayKey, {\r\n type: 'INSERT',\r\n path: arrayKey,\r\n itemKey: fullItemKey,\r\n });\r\n },\r\n removeShadowArrayElement: (key: string, itemPath: string[]) => {\r\n const newShadowStore = new Map(get().shadowStateStore);\r\n\r\n // Get the full item key (e.g., \"stateKey.products.id:xxx\")\r\n const itemKey = [key, ...itemPath].join('.');\r\n\r\n // Extract parent path and item ID\r\n const parentPath = itemPath.slice(0, -1);\r\n const parentKey = [key, ...parentPath].join('.');\r\n\r\n // Get parent metadata\r\n const parentMeta = newShadowStore.get(parentKey);\r\n\r\n if (parentMeta && parentMeta.arrayKeys) {\r\n // Find the index of the item to remove\r\n const indexToRemove = parentMeta.arrayKeys.findIndex(\r\n (arrayItemKey) => arrayItemKey === itemKey\r\n );\r\n\r\n if (indexToRemove !== -1) {\r\n // Create new array keys with the item removed\r\n const newArrayKeys = parentMeta.arrayKeys.filter(\r\n (arrayItemKey) => arrayItemKey !== itemKey\r\n );\r\n\r\n // Update parent with new array keys\r\n newShadowStore.set(parentKey, {\r\n ...parentMeta,\r\n arrayKeys: newArrayKeys,\r\n });\r\n\r\n // Delete all data associated with the removed item\r\n const prefixToDelete = itemKey + '.';\r\n for (const k of Array.from(newShadowStore.keys())) {\r\n if (k === itemKey || k.startsWith(prefixToDelete)) {\r\n newShadowStore.delete(k);\r\n }\r\n }\r\n }\r\n }\r\n\r\n set({ shadowStateStore: newShadowStore });\r\n\r\n get().notifyPathSubscribers(parentKey, {\r\n type: 'REMOVE',\r\n path: parentKey,\r\n itemKey: itemKey, // The exact ID of the removed item\r\n });\r\n },\r\n\r\n updateShadowAtPath: (key, path, newValue) => {\r\n const fullKey = [key, ...path].join('.');\r\n\r\n // Optimization: Only update if value actually changed\r\n const existingMeta = get().shadowStateStore.get(fullKey);\r\n if (existingMeta?.value === newValue && !isSimpleObject(newValue)) {\r\n return; // Skip update for unchanged primitives\r\n }\r\n\r\n // CHANGE: Don't clone the entire Map, just update in place\r\n set((state) => {\r\n const store = state.shadowStateStore;\r\n\r\n if (!isSimpleObject(newValue)) {\r\n const meta = store.get(fullKey) || {};\r\n store.set(fullKey, { ...meta, value: newValue });\r\n } else {\r\n // Handle objects by iterating\r\n const processObject = (currentPath: string[], objectToSet: any) => {\r\n const currentFullKey = [key, ...currentPath].join('.');\r\n const meta = store.get(currentFullKey);\r\n\r\n if (meta && meta.fields) {\r\n for (const fieldKey in objectToSet) {\r\n if (Object.prototype.hasOwnProperty.call(objectToSet, fieldKey)) {\r\n const childValue = objectToSet[fieldKey];\r\n const childFullPath = meta.fields[fieldKey];\r\n\r\n if (childFullPath) {\r\n if (isSimpleObject(childValue)) {\r\n processObject(\r\n childFullPath.split('.').slice(1),\r\n childValue\r\n );\r\n } else {\r\n const existingChildMeta = store.get(childFullPath) || {};\r\n store.set(childFullPath, {\r\n ...existingChildMeta,\r\n value: childValue,\r\n });\r\n }\r\n }\r\n }\r\n }\r\n }\r\n };\r\n\r\n processObject(path, newValue);\r\n }\r\n\r\n // Only notify after all changes are made\r\n get().notifyPathSubscribers(fullKey, { type: 'UPDATE', newValue });\r\n\r\n // Return same reference if using Zustand's immer middleware\r\n return state;\r\n });\r\n },\r\n selectedIndicesMap: new Map<string, string>(),\r\n getSelectedIndex: (arrayKey: string, validIds?: string[]): number => {\r\n const itemKey = get().selectedIndicesMap.get(arrayKey);\r\n\r\n if (!itemKey) return -1;\r\n\r\n // Use validIds if provided (for filtered views), otherwise use all arrayKeys\r\n const arrayKeys =\r\n validIds ||\r\n getGlobalStore.getState().getShadowMetadata(arrayKey, [])?.arrayKeys;\r\n\r\n if (!arrayKeys) return -1;\r\n\r\n return arrayKeys.indexOf(itemKey);\r\n },\r\n\r\n setSelectedIndex: (arrayKey: string, itemKey: string | undefined) => {\r\n set((state) => {\r\n const newMap = state.selectedIndicesMap;\r\n\r\n if (itemKey === undefined) {\r\n newMap.delete(arrayKey);\r\n } else {\r\n if (newMap.has(arrayKey)) {\r\n get().notifyPathSubscribers(newMap.get(arrayKey)!, {\r\n type: 'THIS_UNSELECTED',\r\n });\r\n }\r\n newMap.set(arrayKey, itemKey);\r\n\r\n get().notifyPathSubscribers(itemKey, {\r\n type: 'THIS_SELECTED',\r\n });\r\n }\r\n get().notifyPathSubscribers(arrayKey, {\r\n type: 'GET_SELECTED',\r\n });\r\n return {\r\n ...state,\r\n selectedIndicesMap: newMap,\r\n };\r\n });\r\n },\r\n clearSelectedIndex: ({ arrayKey }: { arrayKey: string }): void => {\r\n set((state) => {\r\n const newMap = state.selectedIndicesMap;\r\n const acutalKey = newMap.get(arrayKey);\r\n if (acutalKey) {\r\n get().notifyPathSubscribers(acutalKey, {\r\n type: 'CLEAR_SELECTION',\r\n });\r\n }\r\n\r\n newMap.delete(arrayKey);\r\n get().notifyPathSubscribers(arrayKey, {\r\n type: 'CLEAR_SELECTION',\r\n });\r\n return {\r\n ...state,\r\n selectedIndicesMap: newMap,\r\n };\r\n });\r\n },\r\n clearSelectedIndexesForState: (stateKey: string) => {\r\n set((state) => {\r\n const newOuterMap = new Map(state.selectedIndicesMap);\r\n const changed = newOuterMap.delete(stateKey);\r\n if (changed) {\r\n return { selectedIndicesMap: newOuterMap };\r\n } else {\r\n return {};\r\n }\r\n });\r\n },\r\n\r\n initialStateOptions: {},\r\n\r\n stateTimeline: {},\r\n cogsStateStore: {},\r\n stateLog: new Map(),\r\n\r\n initialStateGlobal: {},\r\n\r\n validationErrors: new Map(),\r\n addStateLog: (key, update) => {\r\n set((state) => {\r\n const newLog = new Map(state.stateLog);\r\n const stateLogForKey = new Map(newLog.get(key));\r\n const uniquePathKey = JSON.stringify(update.path);\r\n\r\n const existing = stateLogForKey.get(uniquePathKey);\r\n if (existing) {\r\n // If an update for this path already exists, just modify it. (Fast)\r\n existing.newValue = update.newValue;\r\n existing.timeStamp = update.timeStamp;\r\n } else {\r\n // Otherwise, add the new update. (Fast)\r\n stateLogForKey.set(uniquePathKey, { ...update });\r\n }\r\n\r\n newLog.set(key, stateLogForKey);\r\n return { stateLog: newLog };\r\n });\r\n },\r\n\r\n getInitialOptions: (key) => {\r\n return get().initialStateOptions[key];\r\n },\r\n\r\n setInitialStateOptions: (key, value) => {\r\n set((prev) => ({\r\n initialStateOptions: {\r\n ...prev.initialStateOptions,\r\n [key]: value,\r\n },\r\n }));\r\n },\r\n updateInitialStateGlobal: (key, newState) => {\r\n set((prev) => ({\r\n initialStateGlobal: {\r\n ...prev.initialStateGlobal,\r\n [key]: newState,\r\n },\r\n }));\r\n },\r\n\r\n syncInfoStore: new Map<string, SyncInfo>(),\r\n setSyncInfo: (key: string, syncInfo: SyncInfo) =>\r\n set((state) => {\r\n const newMap = new Map(state.syncInfoStore);\r\n newMap.set(key, syncInfo);\r\n return { ...state, syncInfoStore: newMap };\r\n }),\r\n getSyncInfo: (key: string) => get().syncInfoStore.get(key) || null,\r\n}));\r\n"],"names":["formRefStore","create","set","get","id","ref","state","newRefs","stateKey","allRefs","stateKeyPrefix","filteredRefs","isSimpleObject","value","getGlobalStore","updateQueue","startTransition","updateFn","dependencyPath","fullComponentId","newShadowStore","dependencyKey","pathMeta","pathComponents","rootMeta","component","newPaths","newComponentRegistration","newComponentsMap","registration","components","key","path","options","shadowStateStore","updates","setDirty","currentPath","fullKey","meta","parentPath","serverState","newMap","callback","subscribers","subsForPath","currentSubs","updatedPath","newValue","subs","initialState","preservedComponents","prefixToDelete","k","processValue","nodeKey","childIds","itemId","ulid","item","index","fields","newRootMeta","validArrayIds","memo","reconstruct","keyToBuild","ids","shadowMeta","result","keys","itemKey","fieldPath","metadata","existingMeta","finalMeta","cacheKey","cacheData","existing","arrayPath","newItem","arrayKey","parentMeta","newItemId","fullItemKey","newArrayKeys","processNewItem","v","itemPath","parentKey","arrayItemKey","store","processObject","objectToSet","currentFullKey","fieldKey","childValue","childFullPath","existingChildMeta","validIds","arrayKeys","acutalKey","newOuterMap","update","newLog","stateLogForKey","uniquePathKey","prev","newState","syncInfo"],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "cogsbox-state",
3
- "version": "0.5.462",
3
+ "version": "0.5.463",
4
4
  "description": "React state management library with form controls and server sync",
5
5
  "type": "module",
6
6
  "main": "./dist/index.js",
package/src/CogsState.tsx CHANGED
@@ -572,26 +572,21 @@ export const createCogsState = <State extends Record<StateKeys, unknown>>(
572
572
  }
573
573
  ) => {
574
574
  let newInitialState = initialState;
575
- console.log('optsc', opt?.__useSync);
576
575
  const [statePart, initialOptionsPart] =
577
576
  transformStateFunc<State>(newInitialState);
578
577
 
579
- // Store notifications if provided
580
578
  if (opt?.__fromSyncSchema && opt?.__syncNotifications) {
581
579
  getGlobalStore
582
580
  .getState()
583
581
  .setInitialStateOptions('__notifications', opt.__syncNotifications);
584
582
  }
585
583
 
586
- // Store apiParams map if provided
587
584
  if (opt?.__fromSyncSchema && opt?.__apiParamsMap) {
588
585
  getGlobalStore
589
586
  .getState()
590
587
  .setInitialStateOptions('__apiParamsMap', opt.__apiParamsMap);
591
588
  }
592
589
 
593
- // ... rest of your existing createCogsState code unchanged ...
594
-
595
590
  Object.keys(statePart).forEach((key) => {
596
591
  let existingOptions = initialOptionsPart[key] || {};
597
592
 
@@ -647,6 +642,7 @@ export const createCogsState = <State extends Record<StateKeys, unknown>>(
647
642
  stateKey: StateKey,
648
643
  options?: Prettify<OptionsType<(typeof statePart)[StateKey]>>
649
644
  ) => {
645
+ console.time('useCogsState');
650
646
  const [componentId] = useState(options?.componentId ?? uuidv4());
651
647
 
652
648
  setOptions({
@@ -661,6 +657,8 @@ export const createCogsState = <State extends Record<StateKeys, unknown>>(
661
657
  ? options.modifyState(thiState)
662
658
  : thiState;
663
659
 
660
+ console.timeEnd('useCogsState');
661
+
664
662
  const updater = useCogsStateFn<(typeof statePart)[StateKey]>(partialState, {
665
663
  stateKey: stateKey as string,
666
664
  syncUpdate: options?.syncUpdate,
@@ -972,6 +970,8 @@ function markEntireStateAsServerSynced(
972
970
  });
973
971
  }
974
972
  }
973
+ let updateBatchQueue = new Map<string, Array<UpdateArg<any>>>();
974
+ let batchFlushScheduled = false;
975
975
 
976
976
  export function useCogsStateFn<TStateObject extends unknown>(
977
977
  stateObject: TStateObject,
@@ -988,7 +988,6 @@ export function useCogsStateFn<TStateObject extends unknown>(
988
988
  dependencies,
989
989
  serverState,
990
990
  __useSync,
991
- syncOptions,
992
991
  }: {
993
992
  stateKey?: string;
994
993
  componentId?: string;
@@ -997,12 +996,11 @@ export function useCogsStateFn<TStateObject extends unknown>(
997
996
  syncOptions?: SyncOptionsType<any>;
998
997
  } & OptionsType<TStateObject> = {}
999
998
  ) {
999
+ console.time('useCogsStateFn top');
1000
1000
  const [reactiveForce, forceUpdate] = useState({}); //this is the key to reactivity
1001
1001
  const { sessionId } = useCogsConfig();
1002
-
1003
1002
  let noStateKey = stateKey ? false : true;
1004
1003
  const [thisKey] = useState(stateKey ?? uuidv4());
1005
-
1006
1004
  const componentIdRef = useRef(componentId ?? uuidv4());
1007
1005
  const latestInitialOptionsRef = useRef<OptionsType<TStateObject> | null>(
1008
1006
  null
@@ -1012,9 +1010,6 @@ export function useCogsStateFn<TStateObject extends unknown>(
1012
1010
 
1013
1011
  useEffect(() => {
1014
1012
  if (syncUpdate && syncUpdate.stateKey === thisKey && syncUpdate.path?.[0]) {
1015
- // Update the actual state value
1016
-
1017
- // Create combined key and update sync info
1018
1013
  const syncKey = `${syncUpdate.stateKey}:${syncUpdate.path.join('.')}`;
1019
1014
  getGlobalStore.getState().setSyncInfo(syncKey, {
1020
1015
  timeStamp: syncUpdate.timeStamp!,
@@ -1317,19 +1312,22 @@ export function useCogsStateFn<TStateObject extends unknown>(
1317
1312
  }, []);
1318
1313
 
1319
1314
  const syncApiRef = useRef<SyncApi | null>(null);
1315
+ console.timeEnd('useCogsStateFn top');
1320
1316
 
1321
1317
  const effectiveSetState = (
1322
1318
  newStateOrFunction: UpdateArg<TStateObject> | InsertParams<TStateObject>,
1323
1319
  path: string[],
1324
1320
  updateObj: UpdateOptions
1325
1321
  ) => {
1322
+ console.time('top of effectiveSetState');
1326
1323
  const fullPath = [thisKey, ...path].join('.');
1327
-
1328
1324
  const store = getGlobalStore.getState();
1329
1325
 
1330
1326
  const shadowMeta = store.getShadowMetadata(thisKey, path);
1331
1327
  const nestedShadowValue = store.getShadowValue(fullPath) as TStateObject;
1328
+ console.timeEnd('top of effectiveSetState');
1332
1329
 
1330
+ console.time('top of payload');
1333
1331
  const payload = (
1334
1332
  updateObj.updateType === 'insert' && isFunction(newStateOrFunction)
1335
1333
  ? newStateOrFunction({ state: nestedShadowValue, uuid: uuidv4() })
@@ -1349,17 +1347,15 @@ export function useCogsStateFn<TStateObject extends unknown>(
1349
1347
  oldValue: nestedShadowValue,
1350
1348
  newValue: payload,
1351
1349
  } satisfies UpdateTypeDetail;
1350
+ console.timeEnd('top of payload');
1352
1351
 
1352
+ console.time('switch in effectiveSetState');
1353
1353
  // Perform the update
1354
1354
  switch (updateObj.updateType) {
1355
1355
  case 'insert': {
1356
1356
  store.insertShadowArrayElement(thisKey, path, newUpdate.newValue);
1357
- // The array at `path` has been modified. Mark it AND all its parents as dirty.
1358
1357
  store.markAsDirty(thisKey, path, { bubble: true });
1359
-
1360
- // ALSO mark the newly inserted item itself as dirty
1361
- // Get the new item's path and mark it as dirty
1362
- const arrayMeta = store.getShadowMetadata(thisKey, path);
1358
+ const arrayMeta = shadowMeta;
1363
1359
  if (arrayMeta?.arrayKeys) {
1364
1360
  const newItemKey =
1365
1361
  arrayMeta.arrayKeys[arrayMeta.arrayKeys.length - 1];
@@ -1383,7 +1379,9 @@ export function useCogsStateFn<TStateObject extends unknown>(
1383
1379
  break;
1384
1380
  }
1385
1381
  }
1382
+ console.timeEnd('switch in effectiveSetState');
1386
1383
  const shouldSync = updateObj.sync !== false;
1384
+ console.time('signals');
1387
1385
 
1388
1386
  if (shouldSync && syncApiRef.current && syncApiRef.current.connected) {
1389
1387
  syncApiRef.current.updateState({ operation: newUpdate });
@@ -1536,6 +1534,7 @@ export function useCogsStateFn<TStateObject extends unknown>(
1536
1534
  });
1537
1535
  }
1538
1536
  }
1537
+
1539
1538
  if (updateObj.updateType === 'cut') {
1540
1539
  const arrayPath = path.slice(0, -1);
1541
1540
  const arrayMeta = store.getShadowMetadata(thisKey, arrayPath);
@@ -1553,7 +1552,9 @@ export function useCogsStateFn<TStateObject extends unknown>(
1553
1552
  });
1554
1553
  }
1555
1554
  }
1555
+ console.timeEnd('signals');
1556
1556
 
1557
+ console.time('notify');
1557
1558
  const rootMeta = store.getShadowMetadata(thisKey, []);
1558
1559
  const notifiedComponents = new Set<string>();
1559
1560
 
@@ -1740,6 +1741,8 @@ export function useCogsStateFn<TStateObject extends unknown>(
1740
1741
  }
1741
1742
  });
1742
1743
  notifiedComponents.clear();
1744
+ console.timeEnd('notify');
1745
+ console.time('end stuff');
1743
1746
  addStateLog(thisKey, newUpdate);
1744
1747
 
1745
1748
  saveToLocalStorage(
@@ -1754,6 +1757,7 @@ export function useCogsStateFn<TStateObject extends unknown>(
1754
1757
  update: newUpdate,
1755
1758
  });
1756
1759
  }
1760
+ console.timeEnd('end stuff');
1757
1761
  };
1758
1762
 
1759
1763
  if (!getGlobalStore.getState().initialStateGlobal[thisKey]) {
@@ -1761,12 +1765,15 @@ export function useCogsStateFn<TStateObject extends unknown>(
1761
1765
  }
1762
1766
 
1763
1767
  const updaterFinal = useMemo(() => {
1764
- return createProxyHandler<TStateObject>(
1768
+ console.time('createProxyHandler');
1769
+ const handler = createProxyHandler<TStateObject>(
1765
1770
  thisKey,
1766
1771
  effectiveSetState,
1767
1772
  componentIdRef.current,
1768
1773
  sessionId
1769
1774
  );
1775
+ console.timeEnd('createProxyHandler'); // <--- AND THIS
1776
+ return handler;
1770
1777
  }, [thisKey, sessionId]);
1771
1778
 
1772
1779
  const cogsSyncFn = __useSync;
@@ -1813,12 +1820,9 @@ function hashTransforms(transforms: any[]) {
1813
1820
  if (!transforms || transforms.length === 0) {
1814
1821
  return '';
1815
1822
  }
1816
- // This creates a string representation of the transforms AND their dependencies.
1817
- // Example: "filter['red']sort['score','asc']"
1818
1823
  return transforms
1819
1824
  .map(
1820
1825
  (transform) =>
1821
- // Safely stringify dependencies. An empty array becomes '[]'.
1822
1826
  `${transform.type}${JSON.stringify(transform.dependencies || [])}`
1823
1827
  )
1824
1828
  .join('');
@@ -1861,8 +1865,6 @@ const registerComponentDependency = (
1861
1865
  const fullComponentId = `${stateKey}////${componentId}`;
1862
1866
  const { addPathComponent, getShadowMetadata } = getGlobalStore.getState();
1863
1867
 
1864
- // First, check if the component should even be registered.
1865
- // This check is safe to do outside the setter.
1866
1868
  const rootMeta = getShadowMetadata(stateKey, []);
1867
1869
  const component = rootMeta?.components?.get(fullComponentId);
1868
1870
 
@@ -1878,7 +1880,6 @@ const registerComponentDependency = (
1878
1880
  return;
1879
1881
  }
1880
1882
 
1881
- // Now, call the single, safe, atomic function to perform the update.
1882
1883
  addPathComponent(stateKey, dependencyPath, fullComponentId);
1883
1884
  };
1884
1885
  const notifySelectionComponents = (
@@ -1935,6 +1936,9 @@ function createProxyHandler<T>(
1935
1936
  ): StateObject<T> {
1936
1937
  const proxyCache = new Map<string, any>();
1937
1938
  let stateVersion = 0;
1939
+ console.time('rebuildStateShape Outer');
1940
+
1941
+ let recursionTimerName: string | null = null;
1938
1942
 
1939
1943
  function rebuildStateShape({
1940
1944
  path = [],
@@ -1945,14 +1949,18 @@ function createProxyHandler<T>(
1945
1949
  componentId: string;
1946
1950
  meta?: MetaData;
1947
1951
  }): any {
1952
+ console.time('rebuildStateShape Inner');
1948
1953
  const derivationSignature = meta
1949
1954
  ? JSON.stringify(meta.validIds || meta.transforms)
1950
1955
  : '';
1951
1956
  const cacheKey = path.join('.') + ':' + derivationSignature;
1952
- const stateKeyPathKey = [stateKey, ...path].join('.');
1957
+ console.log('PROXY CACHE KEY ', cacheKey);
1953
1958
  if (proxyCache.has(cacheKey)) {
1959
+ console.log('PROXY CACHE HIT');
1954
1960
  return proxyCache.get(cacheKey);
1955
1961
  }
1962
+ const stateKeyPathKey = [stateKey, ...path].join('.');
1963
+
1956
1964
  type CallableStateObject<T> = {
1957
1965
  (): T;
1958
1966
  } & {
@@ -1972,9 +1980,11 @@ function createProxyHandler<T>(
1972
1980
  },
1973
1981
 
1974
1982
  get(target: any, prop: string) {
1975
- // V--------- THE CRUCIAL FIX IS HERE ---------V
1976
- // This handles requests for internal functions on the proxy,
1977
- // returning the function itself instead of treating it as state.
1983
+ if (path.length === 0) {
1984
+ // Create a unique name for this specific timer instance
1985
+ recursionTimerName = `Recursion-${Math.random()}`;
1986
+ console.time(recursionTimerName);
1987
+ }
1978
1988
  if (prop === '_rebuildStateShape') {
1979
1989
  return rebuildStateShape;
1980
1990
  }
@@ -3598,29 +3608,86 @@ function createProxyHandler<T>(
3598
3608
  if (prop === '_stateKey') return stateKey;
3599
3609
  if (prop === '_path') return path;
3600
3610
  if (prop === 'update') {
3611
+ if (recursionTimerName) {
3612
+ console.timeEnd(recursionTimerName);
3613
+ recursionTimerName = null;
3614
+ }
3615
+
3601
3616
  return (payload: UpdateArg<T>) => {
3602
- // Step 1: This is the same. It performs the data update.
3603
- effectiveSetState(payload as any, path, { updateType: 'update' });
3617
+ // Check if we're in a React event handler
3618
+ const error = new Error();
3619
+ const stack = error.stack || '';
3620
+ const inReactEvent =
3621
+ stack.includes('onClick') ||
3622
+ stack.includes('dispatchEvent') ||
3623
+ stack.includes('batchedUpdates');
3624
+
3625
+ // Only batch if we're in a React event
3626
+ if (inReactEvent) {
3627
+ const batchKey = `${stateKey}.${path.join('.')}`;
3628
+
3629
+ // Schedule flush if not already scheduled
3630
+ if (!batchFlushScheduled) {
3631
+ updateBatchQueue.clear();
3632
+ batchFlushScheduled = true;
3633
+
3634
+ queueMicrotask(() => {
3635
+ // Process all batched updates
3636
+ for (const [key, updates] of updateBatchQueue) {
3637
+ const parts = key.split('.');
3638
+ const batchStateKey = parts[0];
3639
+ const batchPath = parts.slice(1);
3640
+
3641
+ // Compose all updates for this path
3642
+ const composedUpdate = updates.reduce(
3643
+ (composed, update) => {
3644
+ if (
3645
+ typeof update === 'function' &&
3646
+ typeof composed === 'function'
3647
+ ) {
3648
+ // Compose functions
3649
+ return (state: any) => update(composed(state));
3650
+ }
3651
+ // If not functions, last one wins
3652
+ return update;
3653
+ }
3654
+ );
3655
+
3656
+ // Call effectiveSetState ONCE with composed update
3657
+ effectiveSetState(composedUpdate as any, batchPath, {
3658
+ updateType: 'update',
3659
+ });
3660
+ }
3661
+
3662
+ updateBatchQueue.clear();
3663
+ batchFlushScheduled = false;
3664
+ });
3665
+ }
3666
+
3667
+ // Add to batch
3668
+ const existing = updateBatchQueue.get(batchKey) || [];
3669
+ existing.push(payload);
3670
+ updateBatchQueue.set(batchKey, existing);
3671
+ } else {
3672
+ // NOT in React event - execute immediately
3673
+ console.time('update inner');
3674
+ effectiveSetState(payload as any, path, { updateType: 'update' });
3675
+ console.timeEnd('update inner');
3676
+ }
3604
3677
 
3605
3678
  return {
3606
- /**
3607
- * Marks this specific item, which was just updated, as 'synced' (not dirty).
3608
- */
3609
3679
  synced: () => {
3610
- // This function "remembers" the path of the item that was just updated.
3611
3680
  const shadowMeta = getGlobalStore
3612
3681
  .getState()
3613
3682
  .getShadowMetadata(stateKey, path);
3614
3683
 
3615
- // It updates ONLY the metadata for that specific item.
3616
3684
  getGlobalStore.getState().setShadowMetadata(stateKey, path, {
3617
3685
  ...shadowMeta,
3618
- isDirty: false, // EXPLICITLY set to false, not just undefined
3619
- stateSource: 'server', // Mark as coming from server
3620
- lastServerSync: Date.now(), // Add timestamp
3686
+ isDirty: false,
3687
+ stateSource: 'server',
3688
+ lastServerSync: Date.now(),
3621
3689
  });
3622
3690
 
3623
- // Force a re-render for components watching this path
3624
3691
  const fullPath = [stateKey, ...path].join('.');
3625
3692
  getGlobalStore.getState().notifyPathSubscribers(fullPath, {
3626
3693
  type: 'SYNC_STATUS_CHANGE',
@@ -3633,13 +3700,10 @@ function createProxyHandler<T>(
3633
3700
 
3634
3701
  if (prop === 'toggle') {
3635
3702
  const currentValueAtPath = getGlobalStore
3636
- .getState()
3637
- .getShadowValue([stateKey, ...path].join('.'));
3638
- const currentState = getGlobalStore
3639
3703
  .getState()
3640
3704
  .getShadowValue([stateKey, ...path].join('.'), meta?.validIds);
3641
- console.log('currentValueAtPath', currentValueAtPath);
3642
- if (typeof currentState != 'boolean') {
3705
+
3706
+ if (typeof currentValueAtPath != 'boolean') {
3643
3707
  throw new Error('toggle() can only be used on boolean values');
3644
3708
  }
3645
3709
  return () => {
@@ -3676,8 +3740,10 @@ function createProxyHandler<T>(
3676
3740
 
3677
3741
  const proxyInstance = new Proxy(baseFunction, handler);
3678
3742
  proxyCache.set(cacheKey, proxyInstance);
3743
+ console.timeEnd('rebuildStateShape Inner');
3679
3744
  return proxyInstance;
3680
3745
  }
3746
+ console.timeEnd('rebuildStateShape Outer');
3681
3747
 
3682
3748
  const baseObj = {
3683
3749
  revertToInitialState: (obj?: { validationKey?: string }) => {