UNPKG

@gensx/react

Version:

React hooks and components for GenSX AI workflows.

1 lines 9.12 kB
{"version":3,"file":"use-object.cjs","sources":["@gensx/react/../../../../src/hooks/use-object.ts"],"sourcesContent":["import type {\n JsonValue,\n ObjectMessage,\n Operation,\n WorkflowMessage,\n} from \"@gensx/core\";\n\nimport * as fastJsonPatch from \"fast-json-patch\";\nimport { useEffect, useRef } from \"react\";\nimport { useState } from \"react\";\n\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\nexport type PublishableData = any;\n\n// eslint-disable-next-line @typescript-eslint/no-unnecessary-type-parameters\nexport function useObject<T = JsonValue>(\n events: WorkflowMessage[],\n label: string,\n): T | undefined {\n const [result, setResult] = useState<T | undefined>(undefined);\n\n // Store the reconstructed object and last processed event index\n const reconstructedRef = useRef<JsonValue>({});\n const lastIndexRef = useRef<number>(-1);\n const lastEventsRef = useRef<WorkflowMessage[]>([]);\n\n useEffect(() => {\n // Find all relevant object events\n const objectEvents = events.filter(\n (event): event is ObjectMessage =>\n event.type === \"object\" && event.label === label,\n );\n\n // Detect reset: events array replaced or truncated\n const isReset =\n events !== lastEventsRef.current ||\n objectEvents.length < lastIndexRef.current + 1;\n\n if (isReset) {\n reconstructedRef.current = {};\n lastIndexRef.current = -1;\n }\n\n // Apply only new patches\n for (let i = lastIndexRef.current + 1; i < objectEvents.length; i++) {\n const event = objectEvents[i];\n if (event.isInitial) {\n reconstructedRef.current = {};\n }\n try {\n reconstructedRef.current = applyObjectPatches(\n event.patches,\n reconstructedRef.current,\n );\n } catch (error) {\n console.warn(`Failed to apply patches for object \"${label}\":`, error);\n }\n }\n\n lastIndexRef.current = objectEvents.length - 1;\n lastEventsRef.current = events;\n\n setResult(\n objectEvents.length > 0 ? (reconstructedRef.current as T) : undefined,\n );\n }, [events, label]);\n\n return result;\n}\n\n/**\n * Apply a JSON patch to reconstruct object state. This is useful for consumers who want to reconstruct the full object state from patches.\n *\n * @param patches - The JSON patch operations to apply.\n * @param currentState - The current state of the object (defaults to empty object).\n * @returns The new state after applying the patches.\n */\nfunction applyObjectPatches(\n patches: Operation[],\n currentState: PublishableData = {},\n): PublishableData {\n let document = fastJsonPatch.deepClone(currentState);\n\n let standardPatches: fastJsonPatch.Operation[] = [];\n for (const operation of patches) {\n if (operation.op === \"string-append\") {\n // Handle string append operation\n if (operation.path === \"\") {\n // Root-level string append\n if (typeof document === \"string\") {\n document = document + operation.value;\n } else {\n // Warn and skip instead of throwing or replacing\n console.warn(\n `Cannot apply string-append: root value is not a string. Skipping operation.`,\n );\n // Do nothing\n }\n continue;\n }\n const pathParts = operation.path.split(\"/\").slice(1); // Remove empty first element\n const target = getValueByPath(document, pathParts.slice(0, -1));\n const property = pathParts[pathParts.length - 1];\n\n if (typeof target === \"object\" && target !== null) {\n const currentValue = (target as Record<string, JsonValue>)[property];\n if (typeof currentValue === \"string\") {\n (target as Record<string, JsonValue>)[property] =\n currentValue + operation.value;\n } else {\n // Warn and skip instead of replacing\n console.warn(\n `Cannot apply string-append: target path '${operation.path}' is not a string. Skipping operation.`,\n );\n // Do nothing\n }\n } else {\n // Warn and skip instead of throwing\n console.warn(\n `Cannot apply string-append: target path '${operation.path}' does not exist or is not an object. Skipping operation.`,\n );\n // Do nothing\n }\n } else {\n // Handle standard JSON Patch operations\n standardPatches.push(operation);\n }\n }\n\n if (standardPatches.length > 0) {\n const result = fastJsonPatch.applyPatch(\n document,\n fastJsonPatch.deepClone(standardPatches) as fastJsonPatch.Operation[],\n );\n return result.newDocument;\n }\n\n return document;\n}\n\n/**\n * Helper function to get a value by path in an object or array (RFC 6901 compliant)\n */\nfunction getValueByPath(obj: PublishableData, path: string[]): PublishableData {\n let current: PublishableData = obj;\n for (const segment of path) {\n if (Array.isArray(current)) {\n const idx = Number(segment);\n if (!Number.isNaN(idx) && idx >= 0 && idx < current.length) {\n current = current[idx];\n } else {\n return undefined;\n }\n } else if (isPlainObject(current)) {\n if (segment in current) {\n current = current[segment];\n } else {\n return undefined;\n }\n } else {\n return undefined;\n }\n }\n return current;\n}\n\n/**\n * Utility to check if a value is a non-null, non-array object\n */\nfunction isPlainObject(val: unknown): val is Record<string, JsonValue> {\n return typeof val === \"object\" && val !== null && !Array.isArray(val);\n}\n"],"names":["useState","useRef","useEffect","fastJsonPatch.deepClone","fastJsonPatch.applyPatch"],"mappings":"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"}