dynamodb-reactive 0.1.21 → 0.1.22

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.
@@ -1,6 +1,6 @@
1
1
  import jsonpatch from 'fast-json-patch';
2
2
  import { error, debug, warn } from 'ag-common/dist/common/helpers/log.js';
3
- import { createContext, useState, useEffect, useContext, useSyncExternalStore, useRef } from 'react';
3
+ import { createContext, useState, useEffect, useContext, useSyncExternalStore, useRef, useCallback } from 'react';
4
4
  import { jsx } from 'react/jsx-runtime';
5
5
 
6
6
  // ../client/src/patcher.ts
@@ -727,7 +727,10 @@ var ReactiveClient = class {
727
727
  return void 0;
728
728
  }
729
729
  /**
730
- * Apply an optimistic update to a subscription's data
730
+ * Apply an optimistic update to a subscription's data.
731
+ * Stores the original data for rollback (on mutation error) or as base for
732
+ * incoming server patches. Safe to call after external API calls — the next
733
+ * server snapshot/patch will reconcile automatically.
731
734
  */
732
735
  applyOptimisticUpdate(subscriptionId, updater) {
733
736
  const state = this.subscriptions.get(subscriptionId);
@@ -982,10 +985,22 @@ function useSubscription(path, options = {}) {
982
985
  await subscriptionRef.current.refetch();
983
986
  }
984
987
  };
988
+ const setData = useCallback(
989
+ (updater) => {
990
+ if (client && subscriptionRef.current) {
991
+ client.applyOptimisticUpdate(
992
+ subscriptionRef.current.id,
993
+ updater
994
+ );
995
+ }
996
+ },
997
+ [client]
998
+ );
985
999
  return {
986
1000
  ...state,
987
1001
  disabled: !client,
988
- refetch
1002
+ refetch,
1003
+ setData
989
1004
  };
990
1005
  }
991
1006
  function useMutation(path, options) {
@@ -1084,5 +1099,5 @@ function createProcedureHooks(path) {
1084
1099
  }
1085
1100
 
1086
1101
  export { ReactiveClient, ReactiveClientProvider, WebSocketManager, applyPatches, createProcedureHooks, createReactiveClient, createReactiveHooks, useClient, useConnectionState, useMutation, useReactiveClient, useReactiveClientOrThrow, useSubscription };
1087
- //# sourceMappingURL=chunk-2A7GJ2UO.js.map
1088
- //# sourceMappingURL=chunk-2A7GJ2UO.js.map
1102
+ //# sourceMappingURL=chunk-2KC44Q5I.js.map
1103
+ //# sourceMappingURL=chunk-2KC44Q5I.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../client/src/patcher.ts","../../client/src/websocket.ts","../../client/src/client.ts","../../client/src/react.tsx"],"names":["document","error","debug"],"mappings":"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","file":"chunk-2KC44Q5I.js","sourcesContent":["import jsonpatch, { type Operation } from 'fast-json-patch';\n\nimport type { JsonPatch } from './types.js';\n\nconst { applyPatch } = jsonpatch;\n\n/**\n * Apply JSON patches to a document\n */\nexport function applyPatches<T>(document: T, patches: JsonPatch[]): T {\n if (patches.length === 0) {\n return document;\n }\n\n const operations: Operation[] = patches.map((patch) => {\n const op: Operation = {\n op: patch.op,\n path: patch.path,\n } as Operation;\n\n if ('value' in patch && patch.value !== undefined) {\n (op as { value: unknown }).value = patch.value;\n }\n if ('from' in patch && patch.from !== undefined) {\n (op as { from: string }).from = patch.from;\n }\n\n return op;\n });\n\n try {\n const result = applyPatch(\n structuredClone(document),\n operations,\n true, // Validate operations\n false, // Don't mutate the original\n );\n\n return result.newDocument as T;\n } catch (error) {\n throw new Error('Failed to apply patches', { cause: error });\n }\n}\n","/* eslint-disable no-console */\nimport { error } from 'ag-common/dist/common/helpers/log.js';\n\nimport type {\n ClientMessage,\n ConnectionState,\n ReactiveClientConfig,\n ServerMessage,\n} from './types.js';\n\n/**\n * WebSocket manager with automatic reconnection\n */\nexport class WebSocketManager {\n private config: Required<\n Omit<\n ReactiveClientConfig,\n 'auth' | 'httpUrl' | 'headers' | 'onConnect' | 'onDisconnect' | 'onError'\n >\n > &\n ReactiveClientConfig;\n private ws: WebSocket | null = null;\n private state: ConnectionState = 'disconnected';\n private reconnectAttempts = 0;\n private reconnectTimer: ReturnType<typeof setTimeout> | null = null;\n private messageQueue: ClientMessage[] = [];\n private messageHandlers = new Set<(message: ServerMessage) => void>();\n private stateHandlers = new Set<(state: ConnectionState) => void>();\n private _connectionId: string | null = null;\n private connectionIdResolvers: Array<(id: string) => void> = [];\n /** Flag to indicate intentional disconnect (skip auto-reconnect) */\n private intentionalDisconnect = false;\n\n constructor(config: ReactiveClientConfig) {\n this.config = {\n autoReconnect: true,\n reconnectDelay: 1000,\n maxReconnectAttempts: 10,\n ...config,\n };\n }\n\n /**\n * Get the current connection ID (null if not connected)\n */\n get connectionId(): string | null {\n return this._connectionId;\n }\n\n /**\n * Wait for the connection ID to be available\n */\n waitForConnectionId(): Promise<string> {\n if (this._connectionId) {\n return Promise.resolve(this._connectionId);\n }\n return new Promise((resolve) => {\n this.connectionIdResolvers.push(resolve);\n });\n }\n\n /**\n * Get current connection state\n */\n getState(): ConnectionState {\n return this.state;\n }\n\n /**\n * Connect to the WebSocket server\n */\n async connect(): Promise<void> {\n if (this.state === 'connected' || this.state === 'connecting') {\n return;\n }\n\n this.setState('connecting');\n\n try {\n const url = await this.buildUrl();\n this.ws = new WebSocket(url);\n\n this.ws.onopen = () => {\n this.reconnectAttempts = 0;\n // Send init message to get connectionId from server\n // Don't set state to 'connected' until we receive connectionId\n this.ws?.send(JSON.stringify({ type: 'init' }));\n };\n\n this.ws.onclose = () => {\n this.ws = null;\n this._connectionId = null;\n this.setState('disconnected');\n this.config.onDisconnect?.();\n\n // Always attempt reconnect unless intentionally disconnected\n // This handles server timeouts (which may close \"cleanly\") and network issues\n if (this.config.autoReconnect && !this.intentionalDisconnect) {\n this.scheduleReconnect();\n }\n this.intentionalDisconnect = false;\n };\n\n this.ws.onerror = () => {\n const error = new Error('WebSocket error');\n this.config.onError?.(error);\n };\n\n this.ws.onmessage = (event) => {\n try {\n const message = JSON.parse(event.data) as ServerMessage;\n\n // Handle 'connected' message - we got connectionId, now verify with ping/pong\n if (message.type === 'connected') {\n this._connectionId = message.connectionId;\n // Send ping to verify the connection is fully working\n this.ws?.send(JSON.stringify({ type: 'ping' }));\n return;\n }\n\n // Handle 'pong' message - connection is verified, now we're truly connected\n if (message.type === 'pong') {\n this.setState('connected');\n this.flushMessageQueue();\n this.config.onConnect?.();\n\n // Resolve any pending waitForConnectionId promises\n for (const resolve of this.connectionIdResolvers) {\n resolve(this._connectionId!);\n }\n this.connectionIdResolvers = [];\n return;\n }\n\n this.handleMessage(message);\n } catch (e) {\n error('Failed to parse WebSocket message:', e);\n }\n };\n } catch (e) {\n this.setState('disconnected');\n this.config.onError?.(e instanceof Error ? e : new Error(String(e)));\n\n if (this.config.autoReconnect) {\n this.scheduleReconnect();\n }\n }\n }\n\n /**\n * Disconnect from the WebSocket server\n */\n disconnect(): void {\n this.intentionalDisconnect = true;\n\n if (this.reconnectTimer) {\n clearTimeout(this.reconnectTimer);\n this.reconnectTimer = null;\n }\n\n if (this.ws) {\n this.ws.close(1000, 'Client disconnect');\n this.ws = null;\n }\n\n this._connectionId = null;\n this.setState('disconnected');\n }\n\n /**\n * Force reconnect - closes existing connection and reconnects\n * Useful for recovering from stale connections\n */\n forceReconnect(): void {\n // Close existing connection without setting intentionalDisconnect\n if (this.reconnectTimer) {\n clearTimeout(this.reconnectTimer);\n this.reconnectTimer = null;\n }\n\n if (this.ws) {\n this.ws.close(1000, 'Force reconnect');\n this.ws = null;\n }\n\n this._connectionId = null;\n this.reconnectAttempts = 0;\n this.setState('disconnected');\n\n // Immediately reconnect\n void this.connect();\n }\n\n /**\n * Send a message to the server\n */\n send(message: ClientMessage): void {\n // Check both our state and the actual WebSocket readyState\n if (this.state === 'connected' && this.ws?.readyState === WebSocket.OPEN) {\n this.ws.send(JSON.stringify(message));\n } else {\n // Queue message for when we reconnect\n this.messageQueue.push(message);\n }\n }\n\n /**\n * Subscribe to incoming messages\n */\n onMessage(handler: (message: ServerMessage) => void): () => void {\n this.messageHandlers.add(handler);\n return () => this.messageHandlers.delete(handler);\n }\n\n /**\n * Subscribe to connection state changes\n */\n onStateChange(handler: (state: ConnectionState) => void): () => void {\n this.stateHandlers.add(handler);\n return () => this.stateHandlers.delete(handler);\n }\n\n private async buildUrl(): Promise<string> {\n let url = this.config.url;\n\n if (this.config.auth) {\n const token =\n typeof this.config.auth === 'function'\n ? await this.config.auth()\n : this.config.auth;\n\n const separator = url.includes('?') ? '&' : '?';\n url = `${url}${separator}token=${encodeURIComponent(token)}`;\n }\n\n return url;\n }\n\n private setState(state: ConnectionState): void {\n this.state = state;\n for (const handler of this.stateHandlers) {\n handler(state);\n }\n }\n\n private handleMessage(message: ServerMessage): void {\n for (const handler of this.messageHandlers) {\n handler(message);\n }\n }\n\n private scheduleReconnect(): void {\n if (this.reconnectAttempts >= this.config.maxReconnectAttempts) {\n error('Max reconnection attempts reached');\n return;\n }\n\n this.setState('reconnecting');\n this.reconnectAttempts++;\n\n // Exponential backoff with jitter\n const delay =\n Math.min(\n this.config.reconnectDelay * Math.pow(2, this.reconnectAttempts - 1),\n 30000, // Max 30 seconds\n ) *\n (0.5 + Math.random() * 0.5);\n\n this.reconnectTimer = setTimeout(() => {\n this.reconnectTimer = null;\n void this.connect();\n }, delay);\n }\n\n private flushMessageQueue(): void {\n const queue = this.messageQueue;\n this.messageQueue = [];\n\n for (const message of queue) {\n this.send(message);\n }\n }\n}\n","import { debug } from 'ag-common/dist/common/helpers/log.js';\n\nimport { applyPatches } from './patcher.js';\nimport type {\n ConnectionState,\n JsonPatch,\n MutationOptions,\n ReactiveClientConfig,\n ServerMessage,\n Subscription,\n SubscriptionOptions,\n} from './types.js';\nimport { WebSocketManager } from './websocket.js';\n\n/**\n * Default HTTP URL for subscribe/call requests (Next.js API route)\n */\nconst DEFAULT_HTTP_URL = '/api/reactive';\n\n/**\n * Generate a unique subscription ID\n */\nfunction generateId(): string {\n return `${Date.now()}-${Math.random().toString(36).substring(2, 9)}`;\n}\n\n/**\n * Internal subscription state\n */\ninterface SubscriptionState<TData> {\n id: string;\n path: string;\n input: unknown;\n data: TData | undefined;\n loading: boolean;\n error: Error | undefined;\n listeners: Set<() => void>;\n options: SubscriptionOptions<unknown>;\n}\n\n/**\n * Pending call state\n */\ninterface PendingCall {\n resolve: (data: unknown) => void;\n reject: (error: Error) => void;\n}\n\n/**\n * Reactive client for type-safe subscriptions\n */\nexport class ReactiveClient {\n private wsManager: WebSocketManager;\n private httpUrl: string;\n private authGetter?: () => string | Promise<string>;\n private headersGetter?: () =>\n | Record<string, string>\n | Promise<Record<string, string>>;\n private subscriptions = new Map<string, SubscriptionState<unknown>>();\n private pendingCalls = new Map<string, PendingCall>();\n private connectionState: ConnectionState = 'disconnected';\n private stateListeners = new Set<(state: ConnectionState) => void>();\n // Stores original data for rollback when optimistic updates fail\n private optimisticUpdates = new Map<string, unknown>();\n\n constructor(config: ReactiveClientConfig) {\n this.wsManager = new WebSocketManager(config);\n this.httpUrl = config.httpUrl ?? DEFAULT_HTTP_URL;\n\n // Store auth getter for HTTP requests\n if (typeof config.auth === 'function') {\n this.authGetter = config.auth;\n } else if (config.auth) {\n this.authGetter = () => config.auth as string;\n }\n\n // Store headers getter for HTTP requests\n if (typeof config.headers === 'function') {\n this.headersGetter = config.headers;\n } else if (config.headers) {\n this.headersGetter = () => config.headers as Record<string, string>;\n }\n\n // Handle incoming messages (patches come via WebSocket)\n this.wsManager.onMessage((message) => this.handleMessage(message));\n\n // Handle connection state changes\n this.wsManager.onStateChange((state) => {\n this.connectionState = state;\n this.notifyStateListeners();\n\n if (state === 'connected') {\n this.resubscribeAll();\n }\n });\n }\n\n /**\n * Connect to the server\n */\n async connect(): Promise<void> {\n await this.wsManager.connect();\n }\n\n /**\n * Disconnect from the server\n */\n disconnect(): void {\n this.wsManager.disconnect();\n }\n\n /**\n * Force reconnect - closes existing connection and reconnects\n * Useful for recovering from stale connections\n */\n forceReconnect(): void {\n this.wsManager.forceReconnect();\n }\n\n /**\n * Update the headers getter for HTTP requests.\n * Useful for dynamically setting auth or user context headers.\n */\n setHeaders(\n headers:\n | Record<string, string>\n | (() => Record<string, string> | Promise<Record<string, string>>),\n ): void {\n if (typeof headers === 'function') {\n this.headersGetter = headers;\n } else {\n this.headersGetter = () => headers;\n }\n }\n\n /**\n * Get current connection state\n */\n getConnectionState(): ConnectionState {\n return this.connectionState;\n }\n\n /**\n * Subscribe to connection state changes\n */\n onConnectionStateChange(\n listener: (state: ConnectionState) => void,\n ): () => void {\n this.stateListeners.add(listener);\n return () => this.stateListeners.delete(listener);\n }\n\n /**\n * Subscribe to a procedure via HTTP.\n * Snapshot is returned via HTTP, patches come via WebSocket.\n */\n subscribe<TData>(\n path: string,\n options: SubscriptionOptions<unknown> = {},\n ): Subscription<TData> {\n const id = generateId();\n\n const state: SubscriptionState<TData> = {\n id,\n path,\n input: options.input,\n data: undefined,\n loading: true,\n error: undefined,\n listeners: new Set(),\n options,\n };\n\n this.subscriptions.set(id, state as SubscriptionState<unknown>);\n\n // Send subscribe request via HTTP (async)\n this.sendSubscribeRequest(id, path, options.input).catch((error) => {\n state.error = error instanceof Error ? error : new Error(String(error));\n state.loading = false;\n this.notifySubscriptionListeners(id);\n options.onError?.(state.error);\n });\n\n const subscription: Subscription<TData> = {\n id,\n get data() {\n return state.data;\n },\n get loading() {\n return state.loading;\n },\n get error() {\n return state.error;\n },\n unsubscribe: () => this.unsubscribe(id),\n refetch: () => this.refetch(id),\n };\n\n return subscription;\n }\n\n /**\n * Send subscribe request via HTTP\n */\n private async sendSubscribeRequest(\n subscriptionId: string,\n path: string,\n input: unknown,\n ): Promise<void> {\n // Wait for connectionId to be available\n const connectionId = await this.wsManager.waitForConnectionId();\n\n const headers: Record<string, string> = {\n 'Content-Type': 'application/json',\n };\n\n // Add custom headers if configured\n if (this.headersGetter) {\n const customHeaders = await this.headersGetter();\n Object.assign(headers, customHeaders);\n }\n\n // Add auth header if configured\n if (this.authGetter) {\n const token = await this.authGetter();\n headers['Authorization'] = `Bearer ${token}`;\n }\n\n const response = await fetch(this.httpUrl, {\n method: 'POST',\n headers,\n body: JSON.stringify({\n type: 'subscribe',\n connectionId,\n subscriptionId,\n path,\n input,\n }),\n });\n\n if (!response.ok) {\n throw new Error(\n `Subscribe failed: ${response.status} ${response.statusText}`,\n );\n }\n\n const result = (await response.json()) as {\n type: string;\n message?: string;\n data?: unknown;\n };\n\n if (result.type === 'error') {\n throw new Error(result.message ?? 'Unknown error');\n }\n\n if (result.type === 'snapshot') {\n this.handleSnapshot(subscriptionId, result.data);\n }\n }\n\n /**\n * Call a mutation procedure via HTTP with optimistic update support.\n * All optimistic updates are applied INSTANTLY (before HTTP request).\n */\n async call<TInput, TOutput>(\n path: string,\n input: TInput,\n options?: MutationOptions<TInput, TOutput>,\n ): Promise<TOutput> {\n const invalidatesPath = options?.invalidates;\n const updateType = options?.optimisticUpdate;\n let targetSubscriptionId: string | undefined;\n\n // Find subscription to optimistically update\n if (invalidatesPath) {\n targetSubscriptionId = this.findSubscriptionByPath(invalidatesPath);\n debug(\n '[optimistic] Looking for subscription:',\n invalidatesPath,\n '-> found:',\n targetSubscriptionId ?? 'NONE',\n );\n }\n\n // Apply INSTANT optimistic update (before HTTP request)\n if (targetSubscriptionId) {\n debug(\n '[optimistic] Applying update type:',\n updateType,\n 'to subscription:',\n targetSubscriptionId,\n );\n const state = this.subscriptions.get(targetSubscriptionId);\n const currentData = state?.data;\n\n if (updateType === 'remove') {\n // Remove: filter out item by id\n const inputId = (input as { id?: string }).id;\n if (inputId) {\n this.applyOptimisticUpdate(targetSubscriptionId, (data) => {\n if (!Array.isArray(data)) return data;\n return data.filter((item: { id?: string }) => item.id !== inputId);\n });\n }\n } else if (updateType === 'merge') {\n // Merge: find item by id and merge input fields into it\n const inputWithId = input as { id?: string };\n if (inputWithId.id) {\n this.applyOptimisticUpdate(targetSubscriptionId, (data) => {\n if (!Array.isArray(data)) return data;\n const idx = data.findIndex(\n (item: { id?: string }) => item.id === inputWithId.id,\n );\n if (idx >= 0) {\n // Merge input into existing item\n return [\n ...data.slice(0, idx),\n { ...data[idx], ...input },\n ...data.slice(idx + 1),\n ];\n }\n return data;\n });\n } else if (options?.optimisticData) {\n // For creates without id, use provided optimisticData\n const optimistic =\n typeof options.optimisticData === 'function'\n ? (\n options.optimisticData as (\n input: TInput,\n data: unknown[],\n ) => TOutput\n )(input, Array.isArray(currentData) ? currentData : [])\n : options.optimisticData;\n if (optimistic) {\n this.applyOptimisticUpdate(targetSubscriptionId, (data) => {\n if (!Array.isArray(data)) return data;\n return [optimistic, ...data];\n });\n }\n }\n } else if (typeof updateType === 'function') {\n // Custom update function - apply instantly\n this.applyOptimisticUpdate(targetSubscriptionId, (data) => {\n if (!Array.isArray(data)) return data;\n return updateType(data, input, undefined);\n });\n }\n }\n\n // Wait for connectionId to be available\n const connectionId = await this.wsManager.waitForConnectionId();\n\n const headers: Record<string, string> = {\n 'Content-Type': 'application/json',\n };\n\n // Add custom headers if configured\n if (this.headersGetter) {\n const customHeaders = await this.headersGetter();\n Object.assign(headers, customHeaders);\n }\n\n // Add auth header if configured\n if (this.authGetter) {\n const token = await this.authGetter();\n headers['Authorization'] = `Bearer ${token}`;\n }\n\n try {\n const response = await fetch(this.httpUrl, {\n method: 'POST',\n headers,\n body: JSON.stringify({\n type: 'call',\n connectionId,\n path,\n input,\n }),\n });\n\n if (!response.ok) {\n throw new Error(\n `Call failed: ${response.status} ${response.statusText}`,\n );\n }\n\n const result = (await response.json()) as {\n type: string;\n message?: string;\n data?: unknown;\n };\n\n if (result.type === 'error') {\n throw new Error(result.message ?? 'Unknown error');\n }\n\n const data = result.data as TOutput;\n\n // After HTTP success, reconcile with real server data\n if (targetSubscriptionId && updateType === 'merge') {\n const resultWithId = data as { id?: string };\n if (resultWithId.id) {\n this.applyOptimisticUpdate(targetSubscriptionId, (currentData) => {\n if (!Array.isArray(currentData)) return currentData;\n const idx = currentData.findIndex(\n (item: { id?: string }) => item.id === resultWithId.id,\n );\n if (idx >= 0) {\n // Update with real server data\n return [\n ...currentData.slice(0, idx),\n data,\n ...currentData.slice(idx + 1),\n ];\n } else {\n // New item - add it (and remove any temp items)\n return [\n data,\n ...currentData.filter(\n (item: { id?: string }) =>\n item.id && !item.id.startsWith('temp-'),\n ),\n ];\n }\n });\n }\n }\n\n return data;\n } catch (error) {\n // Rollback on error\n if (targetSubscriptionId) {\n this.rollbackOptimisticUpdate(targetSubscriptionId);\n }\n throw error;\n }\n }\n\n /**\n * Unsubscribe from a subscription\n */\n private unsubscribe(id: string): void {\n const state = this.subscriptions.get(id);\n if (!state) return;\n\n this.subscriptions.delete(id);\n\n this.wsManager.send({\n type: 'unsubscribe',\n subscriptionId: id,\n });\n }\n\n /**\n * Refetch a subscription via HTTP\n */\n private async refetch(id: string): Promise<void> {\n const state = this.subscriptions.get(id);\n if (!state) return;\n\n state.loading = true;\n this.notifySubscriptionListeners(id);\n\n try {\n await this.sendSubscribeRequest(id, state.path, state.input);\n } catch (error) {\n state.error = error instanceof Error ? error : new Error(String(error));\n state.loading = false;\n this.notifySubscriptionListeners(id);\n state.options.onError?.(state.error);\n }\n }\n\n /**\n * Handle incoming server messages.\n * Note: 'connected' messages are handled by WebSocketManager before reaching here.\n */\n private handleMessage(message: ServerMessage): void {\n switch (message.type) {\n case 'connected':\n // Handled by WebSocketManager - should not reach here\n break;\n\n case 'pong':\n // Heartbeat response - no action needed\n break;\n\n case 'snapshot':\n this.handleSnapshot(message.subscriptionId, message.data);\n break;\n\n case 'patch':\n this.handlePatch(message.subscriptionId, message.patches);\n break;\n\n case 'result':\n this.handleResult(message.callId, message.data);\n break;\n\n case 'error':\n this.handleError(message);\n break;\n }\n }\n\n /**\n * Handle a snapshot message\n */\n private handleSnapshot(subscriptionId: string, data: unknown): void {\n const state = this.subscriptions.get(subscriptionId);\n if (!state) return;\n\n // Clear optimistic state since we have authoritative data\n this.clearOptimisticUpdate(subscriptionId);\n\n state.data = data;\n state.loading = false;\n state.error = undefined;\n\n this.notifySubscriptionListeners(subscriptionId);\n state.options.onData?.(data);\n }\n\n /**\n * Handle a patch message\n */\n private handlePatch(subscriptionId: string, patches: JsonPatch[]): void {\n const state = this.subscriptions.get(subscriptionId);\n if (!state || state.data === undefined) return;\n\n // If we have optimistic state, apply patch to the ORIGINAL data\n // This prevents conflicts when patch tries to modify already-modified data\n const originalData = this.optimisticUpdates.get(subscriptionId);\n const baseData = originalData !== undefined ? originalData : state.data;\n\n // Clear optimistic state since we have authoritative patch data\n this.clearOptimisticUpdate(subscriptionId);\n\n try {\n state.data = applyPatches(baseData, patches);\n this.notifySubscriptionListeners(subscriptionId);\n state.options.onData?.(state.data);\n } catch (error) {\n state.error = error instanceof Error ? error : new Error(String(error));\n this.notifySubscriptionListeners(subscriptionId);\n state.options.onError?.(state.error);\n }\n }\n\n /**\n * Handle a result message\n */\n private handleResult(callId: string, data: unknown): void {\n const pending = this.pendingCalls.get(callId);\n if (!pending) return;\n\n this.pendingCalls.delete(callId);\n pending.resolve(data);\n }\n\n /**\n * Handle an error message\n */\n private handleError(message: {\n message: string;\n subscriptionId?: string;\n callId?: string;\n }): void {\n const error = new Error(message.message);\n\n if (message.subscriptionId) {\n const state = this.subscriptions.get(message.subscriptionId);\n if (state) {\n state.error = error;\n state.loading = false;\n this.notifySubscriptionListeners(message.subscriptionId);\n state.options.onError?.(error);\n }\n }\n\n if (message.callId) {\n const pending = this.pendingCalls.get(message.callId);\n if (pending) {\n this.pendingCalls.delete(message.callId);\n pending.reject(error);\n }\n }\n }\n\n /**\n * Resubscribe to all subscriptions after reconnect via HTTP\n */\n private resubscribeAll(): void {\n for (const [id, state] of this.subscriptions) {\n if (state.options.resubscribeOnReconnect !== false) {\n state.loading = true;\n this.notifySubscriptionListeners(id);\n\n // Re-subscribe via HTTP\n this.sendSubscribeRequest(id, state.path, state.input).catch(\n (error) => {\n state.error =\n error instanceof Error ? error : new Error(String(error));\n state.loading = false;\n this.notifySubscriptionListeners(id);\n state.options.onError?.(state.error);\n },\n );\n }\n }\n }\n\n /**\n * Notify subscription listeners of state changes\n */\n private notifySubscriptionListeners(id: string): void {\n const state = this.subscriptions.get(id);\n if (!state) return;\n\n for (const listener of state.listeners) {\n listener();\n }\n }\n\n /**\n * Notify connection state listeners\n */\n private notifyStateListeners(): void {\n for (const listener of this.stateListeners) {\n listener(this.connectionState);\n }\n }\n\n /**\n * Add a listener for subscription state changes\n * Used internally by React hooks\n */\n addSubscriptionListener(id: string, listener: () => void): () => void {\n const state = this.subscriptions.get(id);\n if (!state) return () => {};\n\n state.listeners.add(listener);\n return () => state.listeners.delete(listener);\n }\n\n /**\n * Get subscription state\n * Used internally by React hooks\n */\n getSubscriptionState<TData>(\n id: string,\n ): SubscriptionState<TData> | undefined {\n return this.subscriptions.get(id) as SubscriptionState<TData> | undefined;\n }\n\n /**\n * Find subscription by path\n */\n private findSubscriptionByPath(path: string): string | undefined {\n debug(\n '[optimistic] Searching for path:',\n path,\n 'in subscriptions:',\n Array.from(this.subscriptions.entries()).map(([id, s]) => ({\n id,\n path: s.path,\n })),\n );\n for (const [id, state] of this.subscriptions) {\n if (state.path === path) {\n return id;\n }\n }\n return undefined;\n }\n\n /**\n * Apply an optimistic update to a subscription's data.\n * Stores the original data for rollback (on mutation error) or as base for\n * incoming server patches. Safe to call after external API calls — the next\n * server snapshot/patch will reconcile automatically.\n */\n applyOptimisticUpdate(\n subscriptionId: string,\n updater: (data: unknown) => unknown,\n ): void {\n const state = this.subscriptions.get(subscriptionId);\n if (!state) {\n debug(\n '[optimistic] applyOptimisticUpdate: subscription not found:',\n subscriptionId,\n );\n return;\n }\n if (state.data === undefined) {\n debug(\n '[optimistic] applyOptimisticUpdate: subscription data is undefined (still loading?):',\n subscriptionId,\n );\n return;\n }\n debug(\n '[optimistic] applyOptimisticUpdate: applying update, current data length:',\n Array.isArray(state.data) ? state.data.length : 'not array',\n );\n\n // Store original data for rollback (only if not already stored)\n if (!this.optimisticUpdates.has(subscriptionId)) {\n this.optimisticUpdates.set(\n subscriptionId,\n JSON.parse(JSON.stringify(state.data)),\n );\n }\n\n // Apply the update\n state.data = updater(state.data);\n this.notifySubscriptionListeners(subscriptionId);\n }\n\n /**\n * Rollback an optimistic update\n */\n private rollbackOptimisticUpdate(subscriptionId: string): void {\n const original = this.optimisticUpdates.get(subscriptionId);\n if (original === undefined) return;\n\n const state = this.subscriptions.get(subscriptionId);\n if (state) {\n state.data = original;\n this.notifySubscriptionListeners(subscriptionId);\n }\n this.optimisticUpdates.delete(subscriptionId);\n }\n\n /**\n * Clear optimistic state (called when real data arrives)\n */\n private clearOptimisticUpdate(subscriptionId: string): void {\n this.optimisticUpdates.delete(subscriptionId);\n }\n}\n\n/**\n * Create a type-safe reactive client\n */\nexport function createReactiveClient<TRouter>(\n config: ReactiveClientConfig,\n): TypedReactiveClient<TRouter> {\n const client = new ReactiveClient(config);\n return createTypedProxy(client, []) as TypedReactiveClient<TRouter>;\n}\n\n/**\n * Type-safe client proxy type\n */\nexport type TypedReactiveClient<TRouter> = {\n [K in keyof TRouter]: TRouter[K] extends { query: unknown }\n ? {\n useSubscription: <TData = unknown>(\n input?: unknown,\n options?: Omit<SubscriptionOptions<unknown>, 'input'>,\n ) => Subscription<TData>;\n }\n : TRouter[K] extends { mutation: unknown }\n ? {\n mutate: <TInput, TOutput>(input: TInput) => Promise<TOutput>;\n }\n : TypedReactiveClient<TRouter[K]>;\n} & {\n _client: ReactiveClient;\n connect: () => Promise<void>;\n disconnect: () => void;\n};\n\n/**\n * Create a typed proxy for path-based access\n */\nfunction createTypedProxy(client: ReactiveClient, path: string[]): unknown {\n return new Proxy(\n {},\n {\n get(_target, prop) {\n if (prop === '_client') return client;\n if (prop === 'connect') return () => client.connect();\n if (prop === 'disconnect') return () => client.disconnect();\n\n if (typeof prop !== 'string') return undefined;\n\n const newPath = [...path, prop];\n\n // Check if this is a subscription or mutation\n if (prop === 'useSubscription') {\n return (input?: unknown, options?: SubscriptionOptions<unknown>) => {\n const parentPath = path.join('.');\n return client.subscribe(parentPath, { ...options, input });\n };\n }\n\n if (prop === 'mutate') {\n return async (input: unknown) => {\n const parentPath = path.join('.');\n // Auto-detect invalidates path: 'todos.toggle' → 'todos.list'\n const invalidatesPath =\n path.length >= 2\n ? `${path.slice(0, -1).join('.')}.list`\n : undefined;\n // Auto-detect update type: '*.delete' → 'remove', others → 'merge'\n const updateType = parentPath.endsWith('.delete')\n ? ('remove' as const)\n : ('merge' as const);\n return client.call(parentPath, input, {\n invalidates: invalidatesPath,\n optimisticUpdate: updateType,\n });\n };\n }\n\n return createTypedProxy(client, newPath);\n },\n },\n );\n}\n","import { debug, warn } from 'ag-common/dist/common/helpers/log.js';\nimport {\n createContext,\n type ReactNode,\n useCallback,\n useContext,\n useEffect,\n useRef,\n useState,\n useSyncExternalStore,\n} from 'react';\n\nimport { ReactiveClient } from './client.js';\nimport type {\n ConnectionState,\n MutationOptions,\n ReactiveClientConfig,\n Subscription,\n SubscriptionOptions,\n} from './types.js';\n\n/**\n * Context for the reactive client\n */\nconst ReactiveClientContext = createContext<ReactiveClient | null>(null);\n\n/**\n * Provider component for the reactive client\n *\n * If no config.url or client is provided, WebSocket features are disabled\n * and children are rendered without the reactive context.\n */\nexport function ReactiveClientProvider({\n children,\n config,\n client: externalClient,\n}: {\n children: ReactNode;\n config?: ReactiveClientConfig;\n client?: ReactiveClient;\n}) {\n // Extract URL for stable dependency\n const url = config?.url;\n const hasUrl = Boolean(url);\n\n // Always start with null to avoid hydration mismatch\n // Client will be created in useEffect after hydration\n const [client, setClient] = useState<ReactiveClient | null>(\n externalClient ?? null,\n );\n\n // Create client after mount (avoids hydration mismatch)\n useEffect(() => {\n // Skip if we have an external client or no URL\n if (externalClient || !url) return;\n\n // Create client if we don't have one\n if (!client) {\n const newClient = new ReactiveClient({ ...config, url });\n setClient(newClient);\n }\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [url, externalClient]);\n\n // Connect/disconnect effect\n useEffect(() => {\n if (!client) return;\n\n void client.connect();\n\n return () => {\n client.disconnect();\n };\n }, [client]);\n\n // Visibility change and focus handlers - reconnect when tab becomes active\n useEffect(() => {\n // Skip if not in browser environment or no client\n if (typeof window === 'undefined' || typeof document === 'undefined') {\n return;\n }\n if (!client) return;\n\n const attemptReconnect = () => {\n const state = client.getConnectionState();\n if (state === 'connected') {\n // Already connected, nothing to do\n return;\n }\n if (state === 'connecting') {\n // Already connecting, give it a moment\n return;\n }\n if (state === 'reconnecting') {\n // Stuck in backoff, force immediate reconnect\n debug(\n '[dynamodb-reactive] Tab became active during reconnect backoff, forcing reconnect...',\n );\n client.forceReconnect();\n } else {\n // Disconnected, connect normally\n debug(\n '[dynamodb-reactive] Tab became active while disconnected, reconnecting...',\n );\n void client.connect();\n }\n };\n\n const handleVisibilityChange = () => {\n if (document.visibilityState === 'visible') {\n attemptReconnect();\n }\n };\n\n const handleFocus = () => {\n attemptReconnect();\n };\n\n document.addEventListener('visibilitychange', handleVisibilityChange);\n window.addEventListener('focus', handleFocus);\n\n return () => {\n document.removeEventListener('visibilitychange', handleVisibilityChange);\n window.removeEventListener('focus', handleFocus);\n };\n }, [client]);\n\n // Log warning if no URL configured (only once in dev)\n useEffect(() => {\n if (!hasUrl && process.env.NODE_ENV === 'development') {\n warn(\n '[dynamodb-reactive] WebSocket URL not configured, real-time features disabled',\n );\n }\n }, [hasUrl]);\n\n // Always render with context provider - hooks will handle null client\n return (\n <ReactiveClientContext.Provider value={client}>\n {children}\n </ReactiveClientContext.Provider>\n );\n}\n\n/**\n * Hook to get the reactive client\n * Returns null if WebSocket is not configured\n */\nexport function useReactiveClient(): ReactiveClient | null {\n return useContext(ReactiveClientContext);\n}\n\n/**\n * Hook to get the reactive client, throwing if not available\n */\nexport function useReactiveClientOrThrow(): ReactiveClient {\n const client = useContext(ReactiveClientContext);\n if (!client) {\n throw new Error(\n 'useReactiveClientOrThrow must be used within a ReactiveClientProvider with a configured URL',\n );\n }\n return client;\n}\n\n/**\n * Hook to get the connection state\n * Returns 'disabled' if WebSocket is not configured\n */\nexport function useConnectionState(): ConnectionState | 'disabled' {\n const client = useReactiveClient();\n\n return useSyncExternalStore(\n (callback) => {\n if (!client) return () => {};\n return client.onConnectionStateChange(callback);\n },\n () => (client ? client.getConnectionState() : 'disabled'),\n () => 'disabled' as const,\n );\n}\n\n/**\n * Hook for reactive subscriptions\n * Returns disabled state if WebSocket is not configured\n */\nexport function useSubscription<TData>(\n path: string,\n options: SubscriptionOptions<unknown> = {},\n): {\n data: TData | undefined;\n loading: boolean;\n error: Error | undefined;\n disabled: boolean;\n refetch: () => Promise<void>;\n setData: (updater: (data: TData) => TData) => void;\n} {\n const client = useReactiveClient();\n const subscriptionRef = useRef<Subscription<TData> | null>(null);\n const [state, setState] = useState<{\n data: TData | undefined;\n loading: boolean;\n error: Error | undefined;\n }>({\n data: undefined,\n loading: !client ? false : true,\n error: undefined,\n });\n\n // Serialize options for dependency comparison\n const inputKey = JSON.stringify(options.input);\n // Store callbacks in refs to avoid re-subscribing when they change\n const onDataRef = useRef(options.onData);\n const onErrorRef = useRef(options.onError);\n onDataRef.current = options.onData;\n onErrorRef.current = options.onError;\n\n useEffect(() => {\n if (!client) return;\n\n // Parse input from inputKey to ensure we use the serialized value\n const input = inputKey ? JSON.parse(inputKey) : undefined;\n\n const subscription = client.subscribe<TData>(path, {\n input,\n onData: (data) => {\n setState((prev) => ({\n ...prev,\n data: data as TData,\n loading: false,\n error: undefined,\n }));\n onDataRef.current?.(data);\n },\n onError: (error) => {\n setState((prev) => ({\n ...prev,\n error,\n loading: false,\n }));\n onErrorRef.current?.(error);\n },\n });\n\n subscriptionRef.current = subscription;\n\n // Register a listener for optimistic updates (notifySubscriptionListeners)\n // This ensures React state updates when optimistic changes happen\n const unregisterListener = client.addSubscriptionListener(\n subscription.id,\n () => {\n // Re-read current state from subscription\n debug(\n '[optimistic] useSubscription listener fired for:',\n path,\n 'data length:',\n Array.isArray(subscription.data)\n ? subscription.data.length\n : 'not array',\n );\n setState({\n data: subscription.data,\n loading: subscription.loading,\n error: subscription.error,\n });\n },\n );\n\n // Update state from subscription\n setState({\n data: subscription.data,\n loading: subscription.loading,\n error: subscription.error,\n });\n\n return () => {\n unregisterListener();\n subscription.unsubscribe();\n subscriptionRef.current = null;\n };\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [client, path, inputKey]);\n\n const refetch = async () => {\n if (subscriptionRef.current) {\n setState((prev) => ({ ...prev, loading: true }));\n await subscriptionRef.current.refetch();\n }\n };\n\n const setData = useCallback(\n (updater: (data: TData) => TData) => {\n if (client && subscriptionRef.current) {\n client.applyOptimisticUpdate(\n subscriptionRef.current.id,\n updater as (data: unknown) => unknown,\n );\n }\n },\n [client],\n );\n\n return {\n ...state,\n disabled: !client,\n refetch,\n setData,\n };\n}\n\n/**\n * Hook for mutations with automatic optimistic updates\n *\n * Auto-detection:\n * - `invalidates`: Auto-detected from path (e.g., 'todos.toggle' -> 'todos.list')\n * - `optimisticUpdate`: Auto-detected from path ('*.delete' -> 'remove', others -> 'merge')\n *\n * You can override these with explicit options.\n */\nexport function useMutation<TInput, TOutput>(\n path: string,\n options?: MutationOptions<TInput, TOutput>,\n): {\n mutate: (input: TInput) => Promise<TOutput>;\n data: TOutput | undefined;\n loading: boolean;\n error: Error | undefined;\n disabled: boolean;\n reset: () => void;\n} {\n const client = useReactiveClient();\n const [state, setState] = useState<{\n data: TOutput | undefined;\n loading: boolean;\n error: Error | undefined;\n }>({\n data: undefined,\n loading: false,\n error: undefined,\n });\n\n // Auto-detect invalidates path from mutation path\n // e.g., 'todos.toggle' -> 'todos.list', 'todos.create' -> 'todos.list'\n const autoInvalidates =\n options?.invalidates ??\n (() => {\n const parts = path.split('.');\n if (parts.length >= 2) {\n return `${parts.slice(0, -1).join('.')}.list`;\n }\n return undefined;\n })();\n\n // Auto-detect update type from path\n // '*.delete' -> 'remove', others -> 'merge'\n const autoUpdateType =\n options?.optimisticUpdate ??\n (path.endsWith('.delete') ? 'remove' : 'merge');\n\n const mutate = async (input: TInput): Promise<TOutput> => {\n if (!client) {\n throw new Error('WebSocket not configured - mutations are disabled');\n }\n\n debug('[optimistic] useMutation.mutate called:', {\n path,\n autoInvalidates,\n autoUpdateType,\n input,\n });\n\n setState((prev) => ({ ...prev, loading: true, error: undefined }));\n\n try {\n const result = await client.call<TInput, TOutput>(path, input, {\n invalidates: autoInvalidates,\n optimisticUpdate: autoUpdateType,\n });\n setState({ data: result, loading: false, error: undefined });\n return result;\n } catch (error) {\n const err = error instanceof Error ? error : new Error(String(error));\n setState((prev) => ({ ...prev, loading: false, error: err }));\n throw err;\n }\n };\n\n const reset = () => {\n setState({ data: undefined, loading: false, error: undefined });\n };\n\n return {\n mutate,\n ...state,\n disabled: !client,\n reset,\n };\n}\n\n/**\n * Type helper for extracting procedure input type from ProcedureDefinition\n * Uses Zod's internal _output property to extract the parsed type\n * (Zod schemas have _input/_output as actual properties for type inference)\n */\ntype ProcedureInput<T> = T extends { inputSchema?: { _output: infer I } }\n ? I\n : undefined;\n\n/**\n * Type helper for extracting procedure output type from ProcedureDefinition\n * Extracts from resolver return type using any[] for flexible argument matching\n */\ntype ProcedureOutput<T> = T extends {\n resolver: (...args: any[]) => infer TReturn; // eslint-disable-line @typescript-eslint/no-explicit-any -- contravariance requires `any`\n}\n ? Awaited<TReturn>\n : unknown;\n\n/**\n * Typed client hooks for a router procedure\n * Provides both useQuery and useMutation - use whichever matches your procedure type\n */\ntype TypedProcedureHooks<TInput, TOutput> = {\n useQuery: (\n input: TInput,\n options?: Omit<SubscriptionOptions<TInput>, 'input'>,\n ) => {\n data: TOutput | undefined;\n loading: boolean;\n error: Error | undefined;\n disabled: boolean;\n refetch: () => Promise<void>;\n setData: (updater: (data: TOutput) => TOutput) => void;\n };\n useMutation: (options?: MutationOptions<TInput, TOutput>) => {\n mutate: (input: TInput) => Promise<TOutput>;\n data: TOutput | undefined;\n loading: boolean;\n error: Error | undefined;\n disabled: boolean;\n reset: () => void;\n };\n};\n\n/**\n * Extract router definition from Router class or use T directly\n */\ntype ExtractRouterDefinition<T> = T extends { definition: infer TDef }\n ? TDef\n : T;\n\n/**\n * Recursive type for typed client proxy\n * Checks for 'resolver' property to identify procedures (all procedures have it)\n */\ntype TypedClientProxyRecursive<T> = T extends { resolver: unknown }\n ? TypedProcedureHooks<ProcedureInput<T>, ProcedureOutput<T>>\n : { [K in keyof T]: TypedClientProxyRecursive<T[K]> };\n\n/**\n * Client utilities available at the root level\n */\ninterface ClientUtilities {\n /**\n * Set custom headers to be sent with HTTP requests.\n * Useful for auth context (e.g., user tokens, session info).\n */\n setHeaders: (\n headers:\n | Record<string, string>\n | (() => Record<string, string> | Promise<Record<string, string>>),\n ) => void;\n}\n\n/**\n * Typed client proxy combining router procedures and client utilities\n */\ntype TypedClientProxy<T> = TypedClientProxyRecursive<\n ExtractRouterDefinition<T>\n> &\n ClientUtilities;\n\n/**\n * Create a typed client proxy for use in React components.\n *\n * @example\n * ```tsx\n * const client = useClient<AppRouter>();\n *\n * // Queries (subscriptions)\n * const { data, loading } = client.todos.list.useQuery({});\n *\n * // Mutations\n * const { mutate, loading } = client.todos.toggle.useMutation();\n * await mutate({ id: '123' });\n *\n * // Set custom headers for HTTP requests (e.g., for auth context)\n * client.setHeaders({ 'Authorization': 'Bearer token' });\n * ```\n */\nexport function useClient<TRouter>(): TypedClientProxy<TRouter> {\n const client = useReactiveClient();\n\n function buildProxy(path: string[]): unknown {\n return new Proxy(\n {},\n {\n get(_target, prop: string) {\n if (prop === 'useQuery') {\n // Return a hook function for subscriptions\n return function useQueryHook(\n input?: unknown,\n options?: SubscriptionOptions<unknown>,\n ) {\n const pathStr = path.join('.');\n // eslint-disable-next-line react-hooks/rules-of-hooks\n return useSubscription(pathStr, { ...options, input });\n };\n }\n\n if (prop === 'useMutation') {\n // Return a hook function for mutations\n return function useMutationHook(\n options?: MutationOptions<unknown, unknown>,\n ) {\n const pathStr = path.join('.');\n // eslint-disable-next-line react-hooks/rules-of-hooks\n return useMutation(pathStr, options);\n };\n }\n\n // Expose setHeaders from the underlying client\n if (prop === 'setHeaders') {\n return (\n headers:\n | Record<string, string>\n | (() =>\n | Record<string, string>\n | Promise<Record<string, string>>),\n ) => {\n client?.setHeaders(headers);\n };\n }\n\n return buildProxy([...path, prop]);\n },\n },\n );\n }\n\n return buildProxy([]) as TypedClientProxy<TRouter>;\n}\n\n/**\n * @deprecated Use useClient<TRouter>() instead for typed proxy access\n */\nexport function createReactiveHooks() {\n return {\n useSubscription: <TPath extends string, TData = unknown>(\n path: TPath,\n options?: SubscriptionOptions<unknown>,\n ) => useSubscription<TData>(path, options),\n\n useMutation: <TPath extends string, TInput = unknown, TOutput = unknown>(\n path: TPath,\n options?: MutationOptions<TInput, TOutput>,\n ) => useMutation<TInput, TOutput>(path, options),\n\n useConnectionState,\n useReactiveClient,\n };\n}\n\n/**\n * @deprecated Use useClient<TRouter>() instead for typed proxy access\n */\nexport function createProcedureHooks<TInput, TOutput>(path: string) {\n return {\n useSubscription: (\n input?: TInput,\n options?: Omit<SubscriptionOptions<TInput>, 'input'>,\n ) => useSubscription<TOutput>(path, { ...options, input }),\n\n useMutation: (options?: MutationOptions<TInput, TOutput>) =>\n useMutation<TInput, TOutput>(path, options),\n };\n}\n"]}
package/dist/client.d.ts CHANGED
@@ -1,5 +1,5 @@
1
- import { R as ReactiveClientConfig, C as ConnectionState, a as ClientMessage, S as ServerMessage, J as JsonPatch } from './react-B2b5RIz_.js';
2
- export { d as CallMessage, E as ErrorMessage, I as InferInput, e as InferOutput, M as MutationOptions, P as PatchMessage, b as ReactiveClient, m as ReactiveClientProvider, f as ResultMessage, g as SnapshotMessage, h as SubscribeMessage, i as Subscription, j as SubscriptionOptions, T as TypedReactiveClient, U as UnsubscribeMessage, k as createProcedureHooks, c as createReactiveClient, l as createReactiveHooks, u as useClient, n as useConnectionState, o as useMutation, p as useReactiveClient, q as useReactiveClientOrThrow, r as useSubscription } from './react-B2b5RIz_.js';
1
+ import { R as ReactiveClientConfig, C as ConnectionState, a as ClientMessage, S as ServerMessage, J as JsonPatch } from './react-D_NLHuuO.js';
2
+ export { d as CallMessage, E as ErrorMessage, I as InferInput, e as InferOutput, M as MutationOptions, P as PatchMessage, b as ReactiveClient, m as ReactiveClientProvider, f as ResultMessage, g as SnapshotMessage, h as SubscribeMessage, i as Subscription, j as SubscriptionOptions, T as TypedReactiveClient, U as UnsubscribeMessage, k as createProcedureHooks, c as createReactiveClient, l as createReactiveHooks, u as useClient, n as useConnectionState, o as useMutation, p as useReactiveClient, q as useReactiveClientOrThrow, r as useSubscription } from './react-D_NLHuuO.js';
3
3
  import 'react/jsx-runtime';
4
4
  import 'react';
5
5
 
package/dist/client.js CHANGED
@@ -1,3 +1,3 @@
1
- export { ReactiveClient, ReactiveClientProvider, WebSocketManager, applyPatches, createProcedureHooks, createReactiveClient, createReactiveHooks, useClient, useConnectionState, useMutation, useReactiveClient, useReactiveClientOrThrow, useSubscription } from './chunk-2A7GJ2UO.js';
1
+ export { ReactiveClient, ReactiveClientProvider, WebSocketManager, applyPatches, createProcedureHooks, createReactiveClient, createReactiveHooks, useClient, useConnectionState, useMutation, useReactiveClient, useReactiveClientOrThrow, useSubscription } from './chunk-2KC44Q5I.js';
2
2
  //# sourceMappingURL=client.js.map
3
3
  //# sourceMappingURL=client.js.map
@@ -329,9 +329,12 @@ declare class ReactiveClient {
329
329
  */
330
330
  private findSubscriptionByPath;
331
331
  /**
332
- * Apply an optimistic update to a subscription's data
332
+ * Apply an optimistic update to a subscription's data.
333
+ * Stores the original data for rollback (on mutation error) or as base for
334
+ * incoming server patches. Safe to call after external API calls — the next
335
+ * server snapshot/patch will reconcile automatically.
333
336
  */
334
- private applyOptimisticUpdate;
337
+ applyOptimisticUpdate(subscriptionId: string, updater: (data: unknown) => unknown): void;
335
338
  /**
336
339
  * Rollback an optimistic update
337
340
  */
@@ -399,6 +402,7 @@ declare function useSubscription<TData>(path: string, options?: SubscriptionOpti
399
402
  error: Error | undefined;
400
403
  disabled: boolean;
401
404
  refetch: () => Promise<void>;
405
+ setData: (updater: (data: TData) => TData) => void;
402
406
  };
403
407
  /**
404
408
  * Hook for mutations with automatic optimistic updates
@@ -445,6 +449,7 @@ type TypedProcedureHooks<TInput, TOutput> = {
445
449
  error: Error | undefined;
446
450
  disabled: boolean;
447
451
  refetch: () => Promise<void>;
452
+ setData: (updater: (data: TOutput) => TOutput) => void;
448
453
  };
449
454
  useMutation: (options?: MutationOptions<TInput, TOutput>) => {
450
455
  mutate: (input: TInput) => Promise<TOutput>;
@@ -513,6 +518,7 @@ declare function createReactiveHooks(): {
513
518
  error: Error | undefined;
514
519
  disabled: boolean;
515
520
  refetch: () => Promise<void>;
521
+ setData: (updater: (data: TData) => TData) => void;
516
522
  };
517
523
  useMutation: <TPath extends string, TInput = unknown, TOutput = unknown>(path: TPath, options?: MutationOptions<TInput, TOutput>) => {
518
524
  mutate: (input: TInput) => Promise<TOutput>;
@@ -535,6 +541,7 @@ declare function createProcedureHooks<TInput, TOutput>(path: string): {
535
541
  error: Error | undefined;
536
542
  disabled: boolean;
537
543
  refetch: () => Promise<void>;
544
+ setData: (updater: (data: TOutput) => TOutput) => void;
538
545
  };
539
546
  useMutation: (options?: MutationOptions<TInput, TOutput>) => {
540
547
  mutate: (input: TInput) => Promise<TOutput>;
package/dist/react.d.ts CHANGED
@@ -1,3 +1,3 @@
1
- export { m as ReactiveClientProvider, k as createProcedureHooks, l as createReactiveHooks, u as useClient, n as useConnectionState, o as useMutation, p as useReactiveClient, q as useReactiveClientOrThrow, r as useSubscription } from './react-B2b5RIz_.js';
1
+ export { m as ReactiveClientProvider, k as createProcedureHooks, l as createReactiveHooks, u as useClient, n as useConnectionState, o as useMutation, p as useReactiveClient, q as useReactiveClientOrThrow, r as useSubscription } from './react-D_NLHuuO.js';
2
2
  import 'react/jsx-runtime';
3
3
  import 'react';
package/dist/react.js CHANGED
@@ -1,3 +1,3 @@
1
- export { ReactiveClientProvider, createProcedureHooks, createReactiveHooks, useClient, useConnectionState, useMutation, useReactiveClient, useReactiveClientOrThrow, useSubscription } from './chunk-2A7GJ2UO.js';
1
+ export { ReactiveClientProvider, createProcedureHooks, createReactiveHooks, useClient, useConnectionState, useMutation, useReactiveClient, useReactiveClientOrThrow, useSubscription } from './chunk-2KC44Q5I.js';
2
2
  //# sourceMappingURL=react.js.map
3
3
  //# sourceMappingURL=react.js.map
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "dynamodb-reactive",
3
- "version": "0.1.21",
3
+ "version": "0.1.22",
4
4
  "type": "module",
5
5
  "description": "A Serverless, Reactive tRPC replacement for AWS DynamoDB",
6
6
  "keywords": [
@@ -1 +0,0 @@
1
- {"version":3,"sources":["../../client/src/patcher.ts","../../client/src/websocket.ts","../../client/src/client.ts","../../client/src/react.tsx"],"names":["document","error","debug"],"mappings":";;;;;;AAIA,IAAM,EAAE,YAAW,GAAI,SAAA;AAKhB,SAAS,YAAA,CAAgBA,WAAa,OAAA,EAAyB;AACpE,EAAA,IAAI,OAAA,CAAQ,WAAW,CAAA,EAAG;AACxB,IAAA,OAAOA,SAAAA;AAAA,EACT;AAEA,EAAA,MAAM,UAAA,GAA0B,OAAA,CAAQ,GAAA,CAAI,CAAC,KAAA,KAAU;AACrD,IAAA,MAAM,EAAA,GAAgB;AAAA,MACpB,IAAI,KAAA,CAAM,EAAA;AAAA,MACV,MAAM,KAAA,CAAM;AAAA,KACd;AAEA,IAAA,IAAI,OAAA,IAAW,KAAA,IAAS,KAAA,CAAM,KAAA,KAAU,MAAA,EAAW;AACjD,MAAC,EAAA,CAA0B,QAAQ,KAAA,CAAM,KAAA;AAAA,IAC3C;AACA,IAAA,IAAI,MAAA,IAAU,KAAA,IAAS,KAAA,CAAM,IAAA,KAAS,MAAA,EAAW;AAC/C,MAAC,EAAA,CAAwB,OAAO,KAAA,CAAM,IAAA;AAAA,IACxC;AAEA,IAAA,OAAO,EAAA;AAAA,EACT,CAAC,CAAA;AAED,EAAA,IAAI;AACF,IAAA,MAAM,MAAA,GAAS,UAAA;AAAA,MACb,gBAAgBA,SAAQ,CAAA;AAAA,MACxB,UAAA;AAAA,MACA,IAAA;AAAA;AAAA,MACA;AAAA;AAAA,KACF;AAEA,IAAA,OAAO,MAAA,CAAO,WAAA;AAAA,EAChB,SAASC,MAAAA,EAAO;AACd,IAAA,MAAM,IAAI,KAAA,CAAM,yBAAA,EAA2B,EAAE,KAAA,EAAOA,QAAO,CAAA;AAAA,EAC7D;AACF;AC7BO,IAAM,mBAAN,MAAuB;AAAA,EACpB,MAAA;AAAA,EAOA,EAAA,GAAuB,IAAA;AAAA,EACvB,KAAA,GAAyB,cAAA;AAAA,EACzB,iBAAA,GAAoB,CAAA;AAAA,EACpB,cAAA,GAAuD,IAAA;AAAA,EACvD,eAAgC,EAAC;AAAA,EACjC,eAAA,uBAAsB,GAAA,EAAsC;AAAA,EAC5D,aAAA,uBAAoB,GAAA,EAAsC;AAAA,EAC1D,aAAA,GAA+B,IAAA;AAAA,EAC/B,wBAAqD,EAAC;AAAA;AAAA,EAEtD,qBAAA,GAAwB,KAAA;AAAA,EAEhC,YAAY,MAAA,EAA8B;AACxC,IAAA,IAAA,CAAK,MAAA,GAAS;AAAA,MACZ,aAAA,EAAe,IAAA;AAAA,MACf,cAAA,EAAgB,GAAA;AAAA,MAChB,oBAAA,EAAsB,EAAA;AAAA,MACtB,GAAG;AAAA,KACL;AAAA,EACF;AAAA;AAAA;AAAA;AAAA,EAKA,IAAI,YAAA,GAA8B;AAChC,IAAA,OAAO,IAAA,CAAK,aAAA;AAAA,EACd;AAAA;AAAA;AAAA;AAAA,EAKA,mBAAA,GAAuC;AACrC,IAAA,IAAI,KAAK,aAAA,EAAe;AACtB,MAAA,OAAO,OAAA,CAAQ,OAAA,CAAQ,IAAA,CAAK,aAAa,CAAA;AAAA,IAC3C;AACA,IAAA,OAAO,IAAI,OAAA,CAAQ,CAAC,OAAA,KAAY;AAC9B,MAAA,IAAA,CAAK,qBAAA,CAAsB,KAAK,OAAO,CAAA;AAAA,IACzC,CAAC,CAAA;AAAA,EACH;AAAA;AAAA;AAAA;AAAA,EAKA,QAAA,GAA4B;AAC1B,IAAA,OAAO,IAAA,CAAK,KAAA;AAAA,EACd;AAAA;AAAA;AAAA;AAAA,EAKA,MAAM,OAAA,GAAyB;AAC7B,IAAA,IAAI,IAAA,CAAK,KAAA,KAAU,WAAA,IAAe,IAAA,CAAK,UAAU,YAAA,EAAc;AAC7D,MAAA;AAAA,IACF;AAEA,IAAA,IAAA,CAAK,SAAS,YAAY,CAAA;AAE1B,IAAA,IAAI;AACF,MAAA,MAAM,GAAA,GAAM,MAAM,IAAA,CAAK,QAAA,EAAS;AAChC,MAAA,IAAA,CAAK,EAAA,GAAK,IAAI,SAAA,CAAU,GAAG,CAAA;AAE3B,MAAA,IAAA,CAAK,EAAA,CAAG,SAAS,MAAM;AACrB,QAAA,IAAA,CAAK,iBAAA,GAAoB,CAAA;AAGzB,QAAA,IAAA,CAAK,EAAA,EAAI,KAAK,IAAA,CAAK,SAAA,CAAU,EAAE,IAAA,EAAM,MAAA,EAAQ,CAAC,CAAA;AAAA,MAChD,CAAA;AAEA,MAAA,IAAA,CAAK,EAAA,CAAG,UAAU,MAAM;AACtB,QAAA,IAAA,CAAK,EAAA,GAAK,IAAA;AACV,QAAA,IAAA,CAAK,aAAA,GAAgB,IAAA;AACrB,QAAA,IAAA,CAAK,SAAS,cAAc,CAAA;AAC5B,QAAA,IAAA,CAAK,OAAO,YAAA,IAAe;AAI3B,QAAA,IAAI,IAAA,CAAK,MAAA,CAAO,aAAA,IAAiB,CAAC,KAAK,qBAAA,EAAuB;AAC5D,UAAA,IAAA,CAAK,iBAAA,EAAkB;AAAA,QACzB;AACA,QAAA,IAAA,CAAK,qBAAA,GAAwB,KAAA;AAAA,MAC/B,CAAA;AAEA,MAAA,IAAA,CAAK,EAAA,CAAG,UAAU,MAAM;AACtB,QAAA,MAAMA,MAAAA,GAAQ,IAAI,KAAA,CAAM,iBAAiB,CAAA;AACzC,QAAA,IAAA,CAAK,MAAA,CAAO,UAAUA,MAAK,CAAA;AAAA,MAC7B,CAAA;AAEA,MAAA,IAAA,CAAK,EAAA,CAAG,SAAA,GAAY,CAAC,KAAA,KAAU;AAC7B,QAAA,IAAI;AACF,UAAA,MAAM,OAAA,GAAU,IAAA,CAAK,KAAA,CAAM,KAAA,CAAM,IAAI,CAAA;AAGrC,UAAA,IAAI,OAAA,CAAQ,SAAS,WAAA,EAAa;AAChC,YAAA,IAAA,CAAK,gBAAgB,OAAA,CAAQ,YAAA;AAE7B,YAAA,IAAA,CAAK,EAAA,EAAI,KAAK,IAAA,CAAK,SAAA,CAAU,EAAE,IAAA,EAAM,MAAA,EAAQ,CAAC,CAAA;AAC9C,YAAA;AAAA,UACF;AAGA,UAAA,IAAI,OAAA,CAAQ,SAAS,MAAA,EAAQ;AAC3B,YAAA,IAAA,CAAK,SAAS,WAAW,CAAA;AACzB,YAAA,IAAA,CAAK,iBAAA,EAAkB;AACvB,YAAA,IAAA,CAAK,OAAO,SAAA,IAAY;AAGxB,YAAA,KAAA,MAAW,OAAA,IAAW,KAAK,qBAAA,EAAuB;AAChD,cAAA,OAAA,CAAQ,KAAK,aAAc,CAAA;AAAA,YAC7B;AACA,YAAA,IAAA,CAAK,wBAAwB,EAAC;AAC9B,YAAA;AAAA,UACF;AAEA,UAAA,IAAA,CAAK,cAAc,OAAO,CAAA;AAAA,QAC5B,SAAS,CAAA,EAAG;AACV,UAAA,KAAA,CAAM,sCAAsC,CAAC,CAAA;AAAA,QAC/C;AAAA,MACF,CAAA;AAAA,IACF,SAAS,CAAA,EAAG;AACV,MAAA,IAAA,CAAK,SAAS,cAAc,CAAA;AAC5B,MAAA,IAAA,CAAK,MAAA,CAAO,OAAA,GAAU,CAAA,YAAa,KAAA,GAAQ,CAAA,GAAI,IAAI,KAAA,CAAM,MAAA,CAAO,CAAC,CAAC,CAAC,CAAA;AAEnE,MAAA,IAAI,IAAA,CAAK,OAAO,aAAA,EAAe;AAC7B,QAAA,IAAA,CAAK,iBAAA,EAAkB;AAAA,MACzB;AAAA,IACF;AAAA,EACF;AAAA;AAAA;AAAA;AAAA,EAKA,UAAA,GAAmB;AACjB,IAAA,IAAA,CAAK,qBAAA,GAAwB,IAAA;AAE7B,IAAA,IAAI,KAAK,cAAA,EAAgB;AACvB,MAAA,YAAA,CAAa,KAAK,cAAc,CAAA;AAChC,MAAA,IAAA,CAAK,cAAA,GAAiB,IAAA;AAAA,IACxB;AAEA,IAAA,IAAI,KAAK,EAAA,EAAI;AACX,MAAA,IAAA,CAAK,EAAA,CAAG,KAAA,CAAM,GAAA,EAAM,mBAAmB,CAAA;AACvC,MAAA,IAAA,CAAK,EAAA,GAAK,IAAA;AAAA,IACZ;AAEA,IAAA,IAAA,CAAK,aAAA,GAAgB,IAAA;AACrB,IAAA,IAAA,CAAK,SAAS,cAAc,CAAA;AAAA,EAC9B;AAAA;AAAA;AAAA;AAAA;AAAA,EAMA,cAAA,GAAuB;AAErB,IAAA,IAAI,KAAK,cAAA,EAAgB;AACvB,MAAA,YAAA,CAAa,KAAK,cAAc,CAAA;AAChC,MAAA,IAAA,CAAK,cAAA,GAAiB,IAAA;AAAA,IACxB;AAEA,IAAA,IAAI,KAAK,EAAA,EAAI;AACX,MAAA,IAAA,CAAK,EAAA,CAAG,KAAA,CAAM,GAAA,EAAM,iBAAiB,CAAA;AACrC,MAAA,IAAA,CAAK,EAAA,GAAK,IAAA;AAAA,IACZ;AAEA,IAAA,IAAA,CAAK,aAAA,GAAgB,IAAA;AACrB,IAAA,IAAA,CAAK,iBAAA,GAAoB,CAAA;AACzB,IAAA,IAAA,CAAK,SAAS,cAAc,CAAA;AAG5B,IAAA,KAAK,KAAK,OAAA,EAAQ;AAAA,EACpB;AAAA;AAAA;AAAA;AAAA,EAKA,KAAK,OAAA,EAA8B;AAEjC,IAAA,IAAI,KAAK,KAAA,KAAU,WAAA,IAAe,KAAK,EAAA,EAAI,UAAA,KAAe,UAAU,IAAA,EAAM;AACxE,MAAA,IAAA,CAAK,EAAA,CAAG,IAAA,CAAK,IAAA,CAAK,SAAA,CAAU,OAAO,CAAC,CAAA;AAAA,IACtC,CAAA,MAAO;AAEL,MAAA,IAAA,CAAK,YAAA,CAAa,KAAK,OAAO,CAAA;AAAA,IAChC;AAAA,EACF;AAAA;AAAA;AAAA;AAAA,EAKA,UAAU,OAAA,EAAuD;AAC/D,IAAA,IAAA,CAAK,eAAA,CAAgB,IAAI,OAAO,CAAA;AAChC,IAAA,OAAO,MAAM,IAAA,CAAK,eAAA,CAAgB,MAAA,CAAO,OAAO,CAAA;AAAA,EAClD;AAAA;AAAA;AAAA;AAAA,EAKA,cAAc,OAAA,EAAuD;AACnE,IAAA,IAAA,CAAK,aAAA,CAAc,IAAI,OAAO,CAAA;AAC9B,IAAA,OAAO,MAAM,IAAA,CAAK,aAAA,CAAc,MAAA,CAAO,OAAO,CAAA;AAAA,EAChD;AAAA,EAEA,MAAc,QAAA,GAA4B;AACxC,IAAA,IAAI,GAAA,GAAM,KAAK,MAAA,CAAO,GAAA;AAEtB,IAAA,IAAI,IAAA,CAAK,OAAO,IAAA,EAAM;AACpB,MAAA,MAAM,KAAA,GACJ,OAAO,IAAA,CAAK,MAAA,CAAO,IAAA,KAAS,UAAA,GACxB,MAAM,IAAA,CAAK,MAAA,CAAO,IAAA,EAAK,GACvB,IAAA,CAAK,MAAA,CAAO,IAAA;AAElB,MAAA,MAAM,SAAA,GAAY,GAAA,CAAI,QAAA,CAAS,GAAG,IAAI,GAAA,GAAM,GAAA;AAC5C,MAAA,GAAA,GAAM,GAAG,GAAG,CAAA,EAAG,SAAS,CAAA,MAAA,EAAS,kBAAA,CAAmB,KAAK,CAAC,CAAA,CAAA;AAAA,IAC5D;AAEA,IAAA,OAAO,GAAA;AAAA,EACT;AAAA,EAEQ,SAAS,KAAA,EAA8B;AAC7C,IAAA,IAAA,CAAK,KAAA,GAAQ,KAAA;AACb,IAAA,KAAA,MAAW,OAAA,IAAW,KAAK,aAAA,EAAe;AACxC,MAAA,OAAA,CAAQ,KAAK,CAAA;AAAA,IACf;AAAA,EACF;AAAA,EAEQ,cAAc,OAAA,EAA8B;AAClD,IAAA,KAAA,MAAW,OAAA,IAAW,KAAK,eAAA,EAAiB;AAC1C,MAAA,OAAA,CAAQ,OAAO,CAAA;AAAA,IACjB;AAAA,EACF;AAAA,EAEQ,iBAAA,GAA0B;AAChC,IAAA,IAAI,IAAA,CAAK,iBAAA,IAAqB,IAAA,CAAK,MAAA,CAAO,oBAAA,EAAsB;AAC9D,MAAA,KAAA,CAAM,mCAAmC,CAAA;AACzC,MAAA;AAAA,IACF;AAEA,IAAA,IAAA,CAAK,SAAS,cAAc,CAAA;AAC5B,IAAA,IAAA,CAAK,iBAAA,EAAA;AAGL,IAAA,MAAM,QACJ,IAAA,CAAK,GAAA;AAAA,MACH,IAAA,CAAK,OAAO,cAAA,GAAiB,IAAA,CAAK,IAAI,CAAA,EAAG,IAAA,CAAK,oBAAoB,CAAC,CAAA;AAAA,MACnE;AAAA;AAAA,KACF,IACC,GAAA,GAAM,IAAA,CAAK,MAAA,EAAO,GAAI,GAAA,CAAA;AAEzB,IAAA,IAAA,CAAK,cAAA,GAAiB,WAAW,MAAM;AACrC,MAAA,IAAA,CAAK,cAAA,GAAiB,IAAA;AACtB,MAAA,KAAK,KAAK,OAAA,EAAQ;AAAA,IACpB,GAAG,KAAK,CAAA;AAAA,EACV;AAAA,EAEQ,iBAAA,GAA0B;AAChC,IAAA,MAAM,QAAQ,IAAA,CAAK,YAAA;AACnB,IAAA,IAAA,CAAK,eAAe,EAAC;AAErB,IAAA,KAAA,MAAW,WAAW,KAAA,EAAO;AAC3B,MAAA,IAAA,CAAK,KAAK,OAAO,CAAA;AAAA,IACnB;AAAA,EACF;AACF;ACzQA,IAAM,gBAAA,GAAmB,eAAA;AAKzB,SAAS,UAAA,GAAqB;AAC5B,EAAA,OAAO,CAAA,EAAG,IAAA,CAAK,GAAA,EAAK,IAAI,IAAA,CAAK,MAAA,EAAO,CAAE,QAAA,CAAS,EAAE,CAAA,CAAE,SAAA,CAAU,CAAA,EAAG,CAAC,CAAC,CAAA,CAAA;AACpE;AA2BO,IAAM,iBAAN,MAAqB;AAAA,EAClB,SAAA;AAAA,EACA,OAAA;AAAA,EACA,UAAA;AAAA,EACA,aAAA;AAAA,EAGA,aAAA,uBAAoB,GAAA,EAAwC;AAAA,EAC5D,YAAA,uBAAmB,GAAA,EAAyB;AAAA,EAC5C,eAAA,GAAmC,cAAA;AAAA,EACnC,cAAA,uBAAqB,GAAA,EAAsC;AAAA;AAAA,EAE3D,iBAAA,uBAAwB,GAAA,EAAqB;AAAA,EAErD,YAAY,MAAA,EAA8B;AACxC,IAAA,IAAA,CAAK,SAAA,GAAY,IAAI,gBAAA,CAAiB,MAAM,CAAA;AAC5C,IAAA,IAAA,CAAK,OAAA,GAAU,OAAO,OAAA,IAAW,gBAAA;AAGjC,IAAA,IAAI,OAAO,MAAA,CAAO,IAAA,KAAS,UAAA,EAAY;AACrC,MAAA,IAAA,CAAK,aAAa,MAAA,CAAO,IAAA;AAAA,IAC3B,CAAA,MAAA,IAAW,OAAO,IAAA,EAAM;AACtB,MAAA,IAAA,CAAK,UAAA,GAAa,MAAM,MAAA,CAAO,IAAA;AAAA,IACjC;AAGA,IAAA,IAAI,OAAO,MAAA,CAAO,OAAA,KAAY,UAAA,EAAY;AACxC,MAAA,IAAA,CAAK,gBAAgB,MAAA,CAAO,OAAA;AAAA,IAC9B,CAAA,MAAA,IAAW,OAAO,OAAA,EAAS;AACzB,MAAA,IAAA,CAAK,aAAA,GAAgB,MAAM,MAAA,CAAO,OAAA;AAAA,IACpC;AAGA,IAAA,IAAA,CAAK,UAAU,SAAA,CAAU,CAAC,YAAY,IAAA,CAAK,aAAA,CAAc,OAAO,CAAC,CAAA;AAGjE,IAAA,IAAA,CAAK,SAAA,CAAU,aAAA,CAAc,CAAC,KAAA,KAAU;AACtC,MAAA,IAAA,CAAK,eAAA,GAAkB,KAAA;AACvB,MAAA,IAAA,CAAK,oBAAA,EAAqB;AAE1B,MAAA,IAAI,UAAU,WAAA,EAAa;AACzB,QAAA,IAAA,CAAK,cAAA,EAAe;AAAA,MACtB;AAAA,IACF,CAAC,CAAA;AAAA,EACH;AAAA;AAAA;AAAA;AAAA,EAKA,MAAM,OAAA,GAAyB;AAC7B,IAAA,MAAM,IAAA,CAAK,UAAU,OAAA,EAAQ;AAAA,EAC/B;AAAA;AAAA;AAAA;AAAA,EAKA,UAAA,GAAmB;AACjB,IAAA,IAAA,CAAK,UAAU,UAAA,EAAW;AAAA,EAC5B;AAAA;AAAA;AAAA;AAAA;AAAA,EAMA,cAAA,GAAuB;AACrB,IAAA,IAAA,CAAK,UAAU,cAAA,EAAe;AAAA,EAChC;AAAA;AAAA;AAAA;AAAA;AAAA,EAMA,WACE,OAAA,EAGM;AACN,IAAA,IAAI,OAAO,YAAY,UAAA,EAAY;AACjC,MAAA,IAAA,CAAK,aAAA,GAAgB,OAAA;AAAA,IACvB,CAAA,MAAO;AACL,MAAA,IAAA,CAAK,gBAAgB,MAAM,OAAA;AAAA,IAC7B;AAAA,EACF;AAAA;AAAA;AAAA;AAAA,EAKA,kBAAA,GAAsC;AACpC,IAAA,OAAO,IAAA,CAAK,eAAA;AAAA,EACd;AAAA;AAAA;AAAA;AAAA,EAKA,wBACE,QAAA,EACY;AACZ,IAAA,IAAA,CAAK,cAAA,CAAe,IAAI,QAAQ,CAAA;AAChC,IAAA,OAAO,MAAM,IAAA,CAAK,cAAA,CAAe,MAAA,CAAO,QAAQ,CAAA;AAAA,EAClD;AAAA;AAAA;AAAA;AAAA;AAAA,EAMA,SAAA,CACE,IAAA,EACA,OAAA,GAAwC,EAAC,EACpB;AACrB,IAAA,MAAM,KAAK,UAAA,EAAW;AAEtB,IAAA,MAAM,KAAA,GAAkC;AAAA,MACtC,EAAA;AAAA,MACA,IAAA;AAAA,MACA,OAAO,OAAA,CAAQ,KAAA;AAAA,MACf,IAAA,EAAM,MAAA;AAAA,MACN,OAAA,EAAS,IAAA;AAAA,MACT,KAAA,EAAO,MAAA;AAAA,MACP,SAAA,sBAAe,GAAA,EAAI;AAAA,MACnB;AAAA,KACF;AAEA,IAAA,IAAA,CAAK,aAAA,CAAc,GAAA,CAAI,EAAA,EAAI,KAAmC,CAAA;AAG9D,IAAA,IAAA,CAAK,oBAAA,CAAqB,IAAI,IAAA,EAAM,OAAA,CAAQ,KAAK,CAAA,CAAE,KAAA,CAAM,CAACA,MAAAA,KAAU;AAClE,MAAA,KAAA,CAAM,KAAA,GAAQA,kBAAiB,KAAA,GAAQA,MAAAA,GAAQ,IAAI,KAAA,CAAM,MAAA,CAAOA,MAAK,CAAC,CAAA;AACtE,MAAA,KAAA,CAAM,OAAA,GAAU,KAAA;AAChB,MAAA,IAAA,CAAK,4BAA4B,EAAE,CAAA;AACnC,MAAA,OAAA,CAAQ,OAAA,GAAU,MAAM,KAAK,CAAA;AAAA,IAC/B,CAAC,CAAA;AAED,IAAA,MAAM,YAAA,GAAoC;AAAA,MACxC,EAAA;AAAA,MACA,IAAI,IAAA,GAAO;AACT,QAAA,OAAO,KAAA,CAAM,IAAA;AAAA,MACf,CAAA;AAAA,MACA,IAAI,OAAA,GAAU;AACZ,QAAA,OAAO,KAAA,CAAM,OAAA;AAAA,MACf,CAAA;AAAA,MACA,IAAI,KAAA,GAAQ;AACV,QAAA,OAAO,KAAA,CAAM,KAAA;AAAA,MACf,CAAA;AAAA,MACA,WAAA,EAAa,MAAM,IAAA,CAAK,WAAA,CAAY,EAAE,CAAA;AAAA,MACtC,OAAA,EAAS,MAAM,IAAA,CAAK,OAAA,CAAQ,EAAE;AAAA,KAChC;AAEA,IAAA,OAAO,YAAA;AAAA,EACT;AAAA;AAAA;AAAA;AAAA,EAKA,MAAc,oBAAA,CACZ,cAAA,EACA,IAAA,EACA,KAAA,EACe;AAEf,IAAA,MAAM,YAAA,GAAe,MAAM,IAAA,CAAK,SAAA,CAAU,mBAAA,EAAoB;AAE9D,IAAA,MAAM,OAAA,GAAkC;AAAA,MACtC,cAAA,EAAgB;AAAA,KAClB;AAGA,IAAA,IAAI,KAAK,aAAA,EAAe;AACtB,MAAA,MAAM,aAAA,GAAgB,MAAM,IAAA,CAAK,aAAA,EAAc;AAC/C,MAAA,MAAA,CAAO,MAAA,CAAO,SAAS,aAAa,CAAA;AAAA,IACtC;AAGA,IAAA,IAAI,KAAK,UAAA,EAAY;AACnB,MAAA,MAAM,KAAA,GAAQ,MAAM,IAAA,CAAK,UAAA,EAAW;AACpC,MAAA,OAAA,CAAQ,eAAe,CAAA,GAAI,CAAA,OAAA,EAAU,KAAK,CAAA,CAAA;AAAA,IAC5C;AAEA,IAAA,MAAM,QAAA,GAAW,MAAM,KAAA,CAAM,IAAA,CAAK,OAAA,EAAS;AAAA,MACzC,MAAA,EAAQ,MAAA;AAAA,MACR,OAAA;AAAA,MACA,IAAA,EAAM,KAAK,SAAA,CAAU;AAAA,QACnB,IAAA,EAAM,WAAA;AAAA,QACN,YAAA;AAAA,QACA,cAAA;AAAA,QACA,IAAA;AAAA,QACA;AAAA,OACD;AAAA,KACF,CAAA;AAED,IAAA,IAAI,CAAC,SAAS,EAAA,EAAI;AAChB,MAAA,MAAM,IAAI,KAAA;AAAA,QACR,CAAA,kBAAA,EAAqB,QAAA,CAAS,MAAM,CAAA,CAAA,EAAI,SAAS,UAAU,CAAA;AAAA,OAC7D;AAAA,IACF;AAEA,IAAA,MAAM,MAAA,GAAU,MAAM,QAAA,CAAS,IAAA,EAAK;AAMpC,IAAA,IAAI,MAAA,CAAO,SAAS,OAAA,EAAS;AAC3B,MAAA,MAAM,IAAI,KAAA,CAAM,MAAA,CAAO,OAAA,IAAW,eAAe,CAAA;AAAA,IACnD;AAEA,IAAA,IAAI,MAAA,CAAO,SAAS,UAAA,EAAY;AAC9B,MAAA,IAAA,CAAK,cAAA,CAAe,cAAA,EAAgB,MAAA,CAAO,IAAI,CAAA;AAAA,IACjD;AAAA,EACF;AAAA;AAAA;AAAA;AAAA;AAAA,EAMA,MAAM,IAAA,CACJ,IAAA,EACA,KAAA,EACA,OAAA,EACkB;AAClB,IAAA,MAAM,kBAAkB,OAAA,EAAS,WAAA;AACjC,IAAA,MAAM,aAAa,OAAA,EAAS,gBAAA;AAC5B,IAAA,IAAI,oBAAA;AAGJ,IAAA,IAAI,eAAA,EAAiB;AACnB,MAAA,oBAAA,GAAuB,IAAA,CAAK,uBAAuB,eAAe,CAAA;AAClE,MAAA,KAAA;AAAA,QACE,wCAAA;AAAA,QACA,eAAA;AAAA,QACA,WAAA;AAAA,QACA,oBAAA,IAAwB;AAAA,OAC1B;AAAA,IACF;AAGA,IAAA,IAAI,oBAAA,EAAsB;AACxB,MAAA,KAAA;AAAA,QACE,oCAAA;AAAA,QACA,UAAA;AAAA,QACA,kBAAA;AAAA,QACA;AAAA,OACF;AACA,MAAA,MAAM,KAAA,GAAQ,IAAA,CAAK,aAAA,CAAc,GAAA,CAAI,oBAAoB,CAAA;AACzD,MAAA,MAAM,cAAc,KAAA,EAAO,IAAA;AAE3B,MAAA,IAAI,eAAe,QAAA,EAAU;AAE3B,QAAA,MAAM,UAAW,KAAA,CAA0B,EAAA;AAC3C,QAAA,IAAI,OAAA,EAAS;AACX,UAAA,IAAA,CAAK,qBAAA,CAAsB,oBAAA,EAAsB,CAAC,IAAA,KAAS;AACzD,YAAA,IAAI,CAAC,KAAA,CAAM,OAAA,CAAQ,IAAI,GAAG,OAAO,IAAA;AACjC,YAAA,OAAO,KAAK,MAAA,CAAO,CAAC,IAAA,KAA0B,IAAA,CAAK,OAAO,OAAO,CAAA;AAAA,UACnE,CAAC,CAAA;AAAA,QACH;AAAA,MACF,CAAA,MAAA,IAAW,eAAe,OAAA,EAAS;AAEjC,QAAA,MAAM,WAAA,GAAc,KAAA;AACpB,QAAA,IAAI,YAAY,EAAA,EAAI;AAClB,UAAA,IAAA,CAAK,qBAAA,CAAsB,oBAAA,EAAsB,CAAC,IAAA,KAAS;AACzD,YAAA,IAAI,CAAC,KAAA,CAAM,OAAA,CAAQ,IAAI,GAAG,OAAO,IAAA;AACjC,YAAA,MAAM,MAAM,IAAA,CAAK,SAAA;AAAA,cACf,CAAC,IAAA,KAA0B,IAAA,CAAK,EAAA,KAAO,WAAA,CAAY;AAAA,aACrD;AACA,YAAA,IAAI,OAAO,CAAA,EAAG;AAEZ,cAAA,OAAO;AAAA,gBACL,GAAG,IAAA,CAAK,KAAA,CAAM,CAAA,EAAG,GAAG,CAAA;AAAA,gBACpB,EAAE,GAAG,IAAA,CAAK,GAAG,CAAA,EAAG,GAAG,KAAA,EAAM;AAAA,gBACzB,GAAG,IAAA,CAAK,KAAA,CAAM,GAAA,GAAM,CAAC;AAAA,eACvB;AAAA,YACF;AACA,YAAA,OAAO,IAAA;AAAA,UACT,CAAC,CAAA;AAAA,QACH,CAAA,MAAA,IAAW,SAAS,cAAA,EAAgB;AAElC,UAAA,MAAM,aACJ,OAAO,OAAA,CAAQ,cAAA,KAAmB,UAAA,GAE5B,QAAQ,cAAA,CAIR,KAAA,EAAO,KAAA,CAAM,OAAA,CAAQ,WAAW,CAAA,GAAI,WAAA,GAAc,EAAE,IACtD,OAAA,CAAQ,cAAA;AACd,UAAA,IAAI,UAAA,EAAY;AACd,YAAA,IAAA,CAAK,qBAAA,CAAsB,oBAAA,EAAsB,CAAC,IAAA,KAAS;AACzD,cAAA,IAAI,CAAC,KAAA,CAAM,OAAA,CAAQ,IAAI,GAAG,OAAO,IAAA;AACjC,cAAA,OAAO,CAAC,UAAA,EAAY,GAAG,IAAI,CAAA;AAAA,YAC7B,CAAC,CAAA;AAAA,UACH;AAAA,QACF;AAAA,MACF,CAAA,MAAA,IAAW,OAAO,UAAA,KAAe,UAAA,EAAY;AAE3C,QAAA,IAAA,CAAK,qBAAA,CAAsB,oBAAA,EAAsB,CAAC,IAAA,KAAS;AACzD,UAAA,IAAI,CAAC,KAAA,CAAM,OAAA,CAAQ,IAAI,GAAG,OAAO,IAAA;AACjC,UAAA,OAAO,UAAA,CAAW,IAAA,EAAM,KAAA,EAAO,MAAS,CAAA;AAAA,QAC1C,CAAC,CAAA;AAAA,MACH;AAAA,IACF;AAGA,IAAA,MAAM,YAAA,GAAe,MAAM,IAAA,CAAK,SAAA,CAAU,mBAAA,EAAoB;AAE9D,IAAA,MAAM,OAAA,GAAkC;AAAA,MACtC,cAAA,EAAgB;AAAA,KAClB;AAGA,IAAA,IAAI,KAAK,aAAA,EAAe;AACtB,MAAA,MAAM,aAAA,GAAgB,MAAM,IAAA,CAAK,aAAA,EAAc;AAC/C,MAAA,MAAA,CAAO,MAAA,CAAO,SAAS,aAAa,CAAA;AAAA,IACtC;AAGA,IAAA,IAAI,KAAK,UAAA,EAAY;AACnB,MAAA,MAAM,KAAA,GAAQ,MAAM,IAAA,CAAK,UAAA,EAAW;AACpC,MAAA,OAAA,CAAQ,eAAe,CAAA,GAAI,CAAA,OAAA,EAAU,KAAK,CAAA,CAAA;AAAA,IAC5C;AAEA,IAAA,IAAI;AACF,MAAA,MAAM,QAAA,GAAW,MAAM,KAAA,CAAM,IAAA,CAAK,OAAA,EAAS;AAAA,QACzC,MAAA,EAAQ,MAAA;AAAA,QACR,OAAA;AAAA,QACA,IAAA,EAAM,KAAK,SAAA,CAAU;AAAA,UACnB,IAAA,EAAM,MAAA;AAAA,UACN,YAAA;AAAA,UACA,IAAA;AAAA,UACA;AAAA,SACD;AAAA,OACF,CAAA;AAED,MAAA,IAAI,CAAC,SAAS,EAAA,EAAI;AAChB,QAAA,MAAM,IAAI,KAAA;AAAA,UACR,CAAA,aAAA,EAAgB,QAAA,CAAS,MAAM,CAAA,CAAA,EAAI,SAAS,UAAU,CAAA;AAAA,SACxD;AAAA,MACF;AAEA,MAAA,MAAM,MAAA,GAAU,MAAM,QAAA,CAAS,IAAA,EAAK;AAMpC,MAAA,IAAI,MAAA,CAAO,SAAS,OAAA,EAAS;AAC3B,QAAA,MAAM,IAAI,KAAA,CAAM,MAAA,CAAO,OAAA,IAAW,eAAe,CAAA;AAAA,MACnD;AAEA,MAAA,MAAM,OAAO,MAAA,CAAO,IAAA;AAGpB,MAAA,IAAI,oBAAA,IAAwB,eAAe,OAAA,EAAS;AAClD,QAAA,MAAM,YAAA,GAAe,IAAA;AACrB,QAAA,IAAI,aAAa,EAAA,EAAI;AACnB,UAAA,IAAA,CAAK,qBAAA,CAAsB,oBAAA,EAAsB,CAAC,WAAA,KAAgB;AAChE,YAAA,IAAI,CAAC,KAAA,CAAM,OAAA,CAAQ,WAAW,GAAG,OAAO,WAAA;AACxC,YAAA,MAAM,MAAM,WAAA,CAAY,SAAA;AAAA,cACtB,CAAC,IAAA,KAA0B,IAAA,CAAK,EAAA,KAAO,YAAA,CAAa;AAAA,aACtD;AACA,YAAA,IAAI,OAAO,CAAA,EAAG;AAEZ,cAAA,OAAO;AAAA,gBACL,GAAG,WAAA,CAAY,KAAA,CAAM,CAAA,EAAG,GAAG,CAAA;AAAA,gBAC3B,IAAA;AAAA,gBACA,GAAG,WAAA,CAAY,KAAA,CAAM,GAAA,GAAM,CAAC;AAAA,eAC9B;AAAA,YACF,CAAA,MAAO;AAEL,cAAA,OAAO;AAAA,gBACL,IAAA;AAAA,gBACA,GAAG,WAAA,CAAY,MAAA;AAAA,kBACb,CAAC,SACC,IAAA,CAAK,EAAA,IAAM,CAAC,IAAA,CAAK,EAAA,CAAG,WAAW,OAAO;AAAA;AAC1C,eACF;AAAA,YACF;AAAA,UACF,CAAC,CAAA;AAAA,QACH;AAAA,MACF;AAEA,MAAA,OAAO,IAAA;AAAA,IACT,SAASA,MAAAA,EAAO;AAEd,MAAA,IAAI,oBAAA,EAAsB;AACxB,QAAA,IAAA,CAAK,yBAAyB,oBAAoB,CAAA;AAAA,MACpD;AACA,MAAA,MAAMA,MAAAA;AAAA,IACR;AAAA,EACF;AAAA;AAAA;AAAA;AAAA,EAKQ,YAAY,EAAA,EAAkB;AACpC,IAAA,MAAM,KAAA,GAAQ,IAAA,CAAK,aAAA,CAAc,GAAA,CAAI,EAAE,CAAA;AACvC,IAAA,IAAI,CAAC,KAAA,EAAO;AAEZ,IAAA,IAAA,CAAK,aAAA,CAAc,OAAO,EAAE,CAAA;AAE5B,IAAA,IAAA,CAAK,UAAU,IAAA,CAAK;AAAA,MAClB,IAAA,EAAM,aAAA;AAAA,MACN,cAAA,EAAgB;AAAA,KACjB,CAAA;AAAA,EACH;AAAA;AAAA;AAAA;AAAA,EAKA,MAAc,QAAQ,EAAA,EAA2B;AAC/C,IAAA,MAAM,KAAA,GAAQ,IAAA,CAAK,aAAA,CAAc,GAAA,CAAI,EAAE,CAAA;AACvC,IAAA,IAAI,CAAC,KAAA,EAAO;AAEZ,IAAA,KAAA,CAAM,OAAA,GAAU,IAAA;AAChB,IAAA,IAAA,CAAK,4BAA4B,EAAE,CAAA;AAEnC,IAAA,IAAI;AACF,MAAA,MAAM,KAAK,oBAAA,CAAqB,EAAA,EAAI,KAAA,CAAM,IAAA,EAAM,MAAM,KAAK,CAAA;AAAA,IAC7D,SAASA,MAAAA,EAAO;AACd,MAAA,KAAA,CAAM,KAAA,GAAQA,kBAAiB,KAAA,GAAQA,MAAAA,GAAQ,IAAI,KAAA,CAAM,MAAA,CAAOA,MAAK,CAAC,CAAA;AACtE,MAAA,KAAA,CAAM,OAAA,GAAU,KAAA;AAChB,MAAA,IAAA,CAAK,4BAA4B,EAAE,CAAA;AACnC,MAAA,KAAA,CAAM,OAAA,CAAQ,OAAA,GAAU,KAAA,CAAM,KAAK,CAAA;AAAA,IACrC;AAAA,EACF;AAAA;AAAA;AAAA;AAAA;AAAA,EAMQ,cAAc,OAAA,EAA8B;AAClD,IAAA,QAAQ,QAAQ,IAAA;AAAM,MACpB,KAAK,WAAA;AAEH,QAAA;AAAA,MAEF,KAAK,MAAA;AAEH,QAAA;AAAA,MAEF,KAAK,UAAA;AACH,QAAA,IAAA,CAAK,cAAA,CAAe,OAAA,CAAQ,cAAA,EAAgB,OAAA,CAAQ,IAAI,CAAA;AACxD,QAAA;AAAA,MAEF,KAAK,OAAA;AACH,QAAA,IAAA,CAAK,WAAA,CAAY,OAAA,CAAQ,cAAA,EAAgB,OAAA,CAAQ,OAAO,CAAA;AACxD,QAAA;AAAA,MAEF,KAAK,QAAA;AACH,QAAA,IAAA,CAAK,YAAA,CAAa,OAAA,CAAQ,MAAA,EAAQ,OAAA,CAAQ,IAAI,CAAA;AAC9C,QAAA;AAAA,MAEF,KAAK,OAAA;AACH,QAAA,IAAA,CAAK,YAAY,OAAO,CAAA;AACxB,QAAA;AAAA;AACJ,EACF;AAAA;AAAA;AAAA;AAAA,EAKQ,cAAA,CAAe,gBAAwB,IAAA,EAAqB;AAClE,IAAA,MAAM,KAAA,GAAQ,IAAA,CAAK,aAAA,CAAc,GAAA,CAAI,cAAc,CAAA;AACnD,IAAA,IAAI,CAAC,KAAA,EAAO;AAGZ,IAAA,IAAA,CAAK,sBAAsB,cAAc,CAAA;AAEzC,IAAA,KAAA,CAAM,IAAA,GAAO,IAAA;AACb,IAAA,KAAA,CAAM,OAAA,GAAU,KAAA;AAChB,IAAA,KAAA,CAAM,KAAA,GAAQ,MAAA;AAEd,IAAA,IAAA,CAAK,4BAA4B,cAAc,CAAA;AAC/C,IAAA,KAAA,CAAM,OAAA,CAAQ,SAAS,IAAI,CAAA;AAAA,EAC7B;AAAA;AAAA;AAAA;AAAA,EAKQ,WAAA,CAAY,gBAAwB,OAAA,EAA4B;AACtE,IAAA,MAAM,KAAA,GAAQ,IAAA,CAAK,aAAA,CAAc,GAAA,CAAI,cAAc,CAAA;AACnD,IAAA,IAAI,CAAC,KAAA,IAAS,KAAA,CAAM,IAAA,KAAS,MAAA,EAAW;AAIxC,IAAA,MAAM,YAAA,GAAe,IAAA,CAAK,iBAAA,CAAkB,GAAA,CAAI,cAAc,CAAA;AAC9D,IAAA,MAAM,QAAA,GAAW,YAAA,KAAiB,MAAA,GAAY,YAAA,GAAe,KAAA,CAAM,IAAA;AAGnE,IAAA,IAAA,CAAK,sBAAsB,cAAc,CAAA;AAEzC,IAAA,IAAI;AACF,MAAA,KAAA,CAAM,IAAA,GAAO,YAAA,CAAa,QAAA,EAAU,OAAO,CAAA;AAC3C,MAAA,IAAA,CAAK,4BAA4B,cAAc,CAAA;AAC/C,MAAA,KAAA,CAAM,OAAA,CAAQ,MAAA,GAAS,KAAA,CAAM,IAAI,CAAA;AAAA,IACnC,SAASA,MAAAA,EAAO;AACd,MAAA,KAAA,CAAM,KAAA,GAAQA,kBAAiB,KAAA,GAAQA,MAAAA,GAAQ,IAAI,KAAA,CAAM,MAAA,CAAOA,MAAK,CAAC,CAAA;AACtE,MAAA,IAAA,CAAK,4BAA4B,cAAc,CAAA;AAC/C,MAAA,KAAA,CAAM,OAAA,CAAQ,OAAA,GAAU,KAAA,CAAM,KAAK,CAAA;AAAA,IACrC;AAAA,EACF;AAAA;AAAA;AAAA;AAAA,EAKQ,YAAA,CAAa,QAAgB,IAAA,EAAqB;AACxD,IAAA,MAAM,OAAA,GAAU,IAAA,CAAK,YAAA,CAAa,GAAA,CAAI,MAAM,CAAA;AAC5C,IAAA,IAAI,CAAC,OAAA,EAAS;AAEd,IAAA,IAAA,CAAK,YAAA,CAAa,OAAO,MAAM,CAAA;AAC/B,IAAA,OAAA,CAAQ,QAAQ,IAAI,CAAA;AAAA,EACtB;AAAA;AAAA;AAAA;AAAA,EAKQ,YAAY,OAAA,EAIX;AACP,IAAA,MAAMA,MAAAA,GAAQ,IAAI,KAAA,CAAM,OAAA,CAAQ,OAAO,CAAA;AAEvC,IAAA,IAAI,QAAQ,cAAA,EAAgB;AAC1B,MAAA,MAAM,KAAA,GAAQ,IAAA,CAAK,aAAA,CAAc,GAAA,CAAI,QAAQ,cAAc,CAAA;AAC3D,MAAA,IAAI,KAAA,EAAO;AACT,QAAA,KAAA,CAAM,KAAA,GAAQA,MAAAA;AACd,QAAA,KAAA,CAAM,OAAA,GAAU,KAAA;AAChB,QAAA,IAAA,CAAK,2BAAA,CAA4B,QAAQ,cAAc,CAAA;AACvD,QAAA,KAAA,CAAM,OAAA,CAAQ,UAAUA,MAAK,CAAA;AAAA,MAC/B;AAAA,IACF;AAEA,IAAA,IAAI,QAAQ,MAAA,EAAQ;AAClB,MAAA,MAAM,OAAA,GAAU,IAAA,CAAK,YAAA,CAAa,GAAA,CAAI,QAAQ,MAAM,CAAA;AACpD,MAAA,IAAI,OAAA,EAAS;AACX,QAAA,IAAA,CAAK,YAAA,CAAa,MAAA,CAAO,OAAA,CAAQ,MAAM,CAAA;AACvC,QAAA,OAAA,CAAQ,OAAOA,MAAK,CAAA;AAAA,MACtB;AAAA,IACF;AAAA,EACF;AAAA;AAAA;AAAA;AAAA,EAKQ,cAAA,GAAuB;AAC7B,IAAA,KAAA,MAAW,CAAC,EAAA,EAAI,KAAK,CAAA,IAAK,KAAK,aAAA,EAAe;AAC5C,MAAA,IAAI,KAAA,CAAM,OAAA,CAAQ,sBAAA,KAA2B,KAAA,EAAO;AAClD,QAAA,KAAA,CAAM,OAAA,GAAU,IAAA;AAChB,QAAA,IAAA,CAAK,4BAA4B,EAAE,CAAA;AAGnC,QAAA,IAAA,CAAK,qBAAqB,EAAA,EAAI,KAAA,CAAM,IAAA,EAAM,KAAA,CAAM,KAAK,CAAA,CAAE,KAAA;AAAA,UACrD,CAACA,MAAAA,KAAU;AACT,YAAA,KAAA,CAAM,KAAA,GACJA,kBAAiB,KAAA,GAAQA,MAAAA,GAAQ,IAAI,KAAA,CAAM,MAAA,CAAOA,MAAK,CAAC,CAAA;AAC1D,YAAA,KAAA,CAAM,OAAA,GAAU,KAAA;AAChB,YAAA,IAAA,CAAK,4BAA4B,EAAE,CAAA;AACnC,YAAA,KAAA,CAAM,OAAA,CAAQ,OAAA,GAAU,KAAA,CAAM,KAAK,CAAA;AAAA,UACrC;AAAA,SACF;AAAA,MACF;AAAA,IACF;AAAA,EACF;AAAA;AAAA;AAAA;AAAA,EAKQ,4BAA4B,EAAA,EAAkB;AACpD,IAAA,MAAM,KAAA,GAAQ,IAAA,CAAK,aAAA,CAAc,GAAA,CAAI,EAAE,CAAA;AACvC,IAAA,IAAI,CAAC,KAAA,EAAO;AAEZ,IAAA,KAAA,MAAW,QAAA,IAAY,MAAM,SAAA,EAAW;AACtC,MAAA,QAAA,EAAS;AAAA,IACX;AAAA,EACF;AAAA;AAAA;AAAA;AAAA,EAKQ,oBAAA,GAA6B;AACnC,IAAA,KAAA,MAAW,QAAA,IAAY,KAAK,cAAA,EAAgB;AAC1C,MAAA,QAAA,CAAS,KAAK,eAAe,CAAA;AAAA,IAC/B;AAAA,EACF;AAAA;AAAA;AAAA;AAAA;AAAA,EAMA,uBAAA,CAAwB,IAAY,QAAA,EAAkC;AACpE,IAAA,MAAM,KAAA,GAAQ,IAAA,CAAK,aAAA,CAAc,GAAA,CAAI,EAAE,CAAA;AACvC,IAAA,IAAI,CAAC,KAAA,EAAO,OAAO,MAAM;AAAA,IAAC,CAAA;AAE1B,IAAA,KAAA,CAAM,SAAA,CAAU,IAAI,QAAQ,CAAA;AAC5B,IAAA,OAAO,MAAM,KAAA,CAAM,SAAA,CAAU,MAAA,CAAO,QAAQ,CAAA;AAAA,EAC9C;AAAA;AAAA;AAAA;AAAA;AAAA,EAMA,qBACE,EAAA,EACsC;AACtC,IAAA,OAAO,IAAA,CAAK,aAAA,CAAc,GAAA,CAAI,EAAE,CAAA;AAAA,EAClC;AAAA;AAAA;AAAA;AAAA,EAKQ,uBAAuB,IAAA,EAAkC;AAC/D,IAAA,KAAA;AAAA,MACE,kCAAA;AAAA,MACA,IAAA;AAAA,MACA,mBAAA;AAAA,MACA,KAAA,CAAM,IAAA,CAAK,IAAA,CAAK,aAAA,CAAc,OAAA,EAAS,CAAA,CAAE,GAAA,CAAI,CAAC,CAAC,EAAA,EAAI,CAAC,CAAA,MAAO;AAAA,QACzD,EAAA;AAAA,QACA,MAAM,CAAA,CAAE;AAAA,OACV,CAAE;AAAA,KACJ;AACA,IAAA,KAAA,MAAW,CAAC,EAAA,EAAI,KAAK,CAAA,IAAK,KAAK,aAAA,EAAe;AAC5C,MAAA,IAAI,KAAA,CAAM,SAAS,IAAA,EAAM;AACvB,QAAA,OAAO,EAAA;AAAA,MACT;AAAA,IACF;AACA,IAAA,OAAO,MAAA;AAAA,EACT;AAAA;AAAA;AAAA;AAAA,EAKQ,qBAAA,CACN,gBACA,OAAA,EACM;AACN,IAAA,MAAM,KAAA,GAAQ,IAAA,CAAK,aAAA,CAAc,GAAA,CAAI,cAAc,CAAA;AACnD,IAAA,IAAI,CAAC,KAAA,EAAO;AACV,MAAA,KAAA;AAAA,QACE,6DAAA;AAAA,QACA;AAAA,OACF;AACA,MAAA;AAAA,IACF;AACA,IAAA,IAAI,KAAA,CAAM,SAAS,MAAA,EAAW;AAC5B,MAAA,KAAA;AAAA,QACE,sFAAA;AAAA,QACA;AAAA,OACF;AACA,MAAA;AAAA,IACF;AACA,IAAA,KAAA;AAAA,MACE,2EAAA;AAAA,MACA,MAAM,OAAA,CAAQ,KAAA,CAAM,IAAI,CAAA,GAAI,KAAA,CAAM,KAAK,MAAA,GAAS;AAAA,KAClD;AAGA,IAAA,IAAI,CAAC,IAAA,CAAK,iBAAA,CAAkB,GAAA,CAAI,cAAc,CAAA,EAAG;AAC/C,MAAA,IAAA,CAAK,iBAAA,CAAkB,GAAA;AAAA,QACrB,cAAA;AAAA,QACA,KAAK,KAAA,CAAM,IAAA,CAAK,SAAA,CAAU,KAAA,CAAM,IAAI,CAAC;AAAA,OACvC;AAAA,IACF;AAGA,IAAA,KAAA,CAAM,IAAA,GAAO,OAAA,CAAQ,KAAA,CAAM,IAAI,CAAA;AAC/B,IAAA,IAAA,CAAK,4BAA4B,cAAc,CAAA;AAAA,EACjD;AAAA;AAAA;AAAA;AAAA,EAKQ,yBAAyB,cAAA,EAA8B;AAC7D,IAAA,MAAM,QAAA,GAAW,IAAA,CAAK,iBAAA,CAAkB,GAAA,CAAI,cAAc,CAAA;AAC1D,IAAA,IAAI,aAAa,MAAA,EAAW;AAE5B,IAAA,MAAM,KAAA,GAAQ,IAAA,CAAK,aAAA,CAAc,GAAA,CAAI,cAAc,CAAA;AACnD,IAAA,IAAI,KAAA,EAAO;AACT,MAAA,KAAA,CAAM,IAAA,GAAO,QAAA;AACb,MAAA,IAAA,CAAK,4BAA4B,cAAc,CAAA;AAAA,IACjD;AACA,IAAA,IAAA,CAAK,iBAAA,CAAkB,OAAO,cAAc,CAAA;AAAA,EAC9C;AAAA;AAAA;AAAA;AAAA,EAKQ,sBAAsB,cAAA,EAA8B;AAC1D,IAAA,IAAA,CAAK,iBAAA,CAAkB,OAAO,cAAc,CAAA;AAAA,EAC9C;AACF;AAKO,SAAS,qBACd,MAAA,EAC8B;AAC9B,EAAA,MAAM,MAAA,GAAS,IAAI,cAAA,CAAe,MAAM,CAAA;AACxC,EAAA,OAAO,gBAAA,CAAiB,MAAA,EAAQ,EAAE,CAAA;AACpC;AA2BA,SAAS,gBAAA,CAAiB,QAAwB,IAAA,EAAyB;AACzE,EAAA,OAAO,IAAI,KAAA;AAAA,IACT,EAAC;AAAA,IACD;AAAA,MACE,GAAA,CAAI,SAAS,IAAA,EAAM;AACjB,QAAA,IAAI,IAAA,KAAS,WAAW,OAAO,MAAA;AAC/B,QAAA,IAAI,IAAA,KAAS,SAAA,EAAW,OAAO,MAAM,OAAO,OAAA,EAAQ;AACpD,QAAA,IAAI,IAAA,KAAS,YAAA,EAAc,OAAO,MAAM,OAAO,UAAA,EAAW;AAE1D,QAAA,IAAI,OAAO,IAAA,KAAS,QAAA,EAAU,OAAO,MAAA;AAErC,QAAA,MAAM,OAAA,GAAU,CAAC,GAAG,IAAA,EAAM,IAAI,CAAA;AAG9B,QAAA,IAAI,SAAS,iBAAA,EAAmB;AAC9B,UAAA,OAAO,CAAC,OAAiB,OAAA,KAA2C;AAClE,YAAA,MAAM,UAAA,GAAa,IAAA,CAAK,IAAA,CAAK,GAAG,CAAA;AAChC,YAAA,OAAO,OAAO,SAAA,CAAU,UAAA,EAAY,EAAE,GAAG,OAAA,EAAS,OAAO,CAAA;AAAA,UAC3D,CAAA;AAAA,QACF;AAEA,QAAA,IAAI,SAAS,QAAA,EAAU;AACrB,UAAA,OAAO,OAAO,KAAA,KAAmB;AAC/B,YAAA,MAAM,UAAA,GAAa,IAAA,CAAK,IAAA,CAAK,GAAG,CAAA;AAEhC,YAAA,MAAM,eAAA,GACJ,IAAA,CAAK,MAAA,IAAU,CAAA,GACX,CAAA,EAAG,IAAA,CAAK,KAAA,CAAM,CAAA,EAAG,EAAE,CAAA,CAAE,IAAA,CAAK,GAAG,CAAC,CAAA,KAAA,CAAA,GAC9B,MAAA;AAEN,YAAA,MAAM,UAAA,GAAa,UAAA,CAAW,QAAA,CAAS,SAAS,IAC3C,QAAA,GACA,OAAA;AACL,YAAA,OAAO,MAAA,CAAO,IAAA,CAAK,UAAA,EAAY,KAAA,EAAO;AAAA,cACpC,WAAA,EAAa,eAAA;AAAA,cACb,gBAAA,EAAkB;AAAA,aACnB,CAAA;AAAA,UACH,CAAA;AAAA,QACF;AAEA,QAAA,OAAO,gBAAA,CAAiB,QAAQ,OAAO,CAAA;AAAA,MACzC;AAAA;AACF,GACF;AACF;AC7xBA,IAAM,qBAAA,GAAwB,cAAqC,IAAI,CAAA;AAQhE,SAAS,sBAAA,CAAuB;AAAA,EACrC,QAAA;AAAA,EACA,MAAA;AAAA,EACA,MAAA,EAAQ;AACV,CAAA,EAIG;AAED,EAAA,MAAM,MAAM,MAAA,EAAQ,GAAA;AACpB,EAAA,MAAM,MAAA,GAAS,QAAQ,GAAG,CAAA;AAI1B,EAAA,MAAM,CAAC,MAAA,EAAQ,SAAS,CAAA,GAAI,QAAA;AAAA,IAC1B,cAAA,IAAkB;AAAA,GACpB;AAGA,EAAA,SAAA,CAAU,MAAM;AAEd,IAAA,IAAI,cAAA,IAAkB,CAAC,GAAA,EAAK;AAG5B,IAAA,IAAI,CAAC,MAAA,EAAQ;AACX,MAAA,MAAM,YAAY,IAAI,cAAA,CAAe,EAAE,GAAG,MAAA,EAAQ,KAAK,CAAA;AACvD,MAAA,SAAA,CAAU,SAAS,CAAA;AAAA,IACrB;AAAA,EAEF,CAAA,EAAG,CAAC,GAAA,EAAK,cAAc,CAAC,CAAA;AAGxB,EAAA,SAAA,CAAU,MAAM;AACd,IAAA,IAAI,CAAC,MAAA,EAAQ;AAEb,IAAA,KAAK,OAAO,OAAA,EAAQ;AAEpB,IAAA,OAAO,MAAM;AACX,MAAA,MAAA,CAAO,UAAA,EAAW;AAAA,IACpB,CAAA;AAAA,EACF,CAAA,EAAG,CAAC,MAAM,CAAC,CAAA;AAGX,EAAA,SAAA,CAAU,MAAM;AAEd,IAAA,IAAI,OAAO,MAAA,KAAW,WAAA,IAAe,OAAO,aAAa,WAAA,EAAa;AACpE,MAAA;AAAA,IACF;AACA,IAAA,IAAI,CAAC,MAAA,EAAQ;AAEb,IAAA,MAAM,mBAAmB,MAAM;AAC7B,MAAA,MAAM,KAAA,GAAQ,OAAO,kBAAA,EAAmB;AACxC,MAAA,IAAI,UAAU,WAAA,EAAa;AAEzB,QAAA;AAAA,MACF;AACA,MAAA,IAAI,UAAU,YAAA,EAAc;AAE1B,QAAA;AAAA,MACF;AACA,MAAA,IAAI,UAAU,cAAA,EAAgB;AAE5B,QAAAC,KAAAA;AAAA,UACE;AAAA,SACF;AACA,QAAA,MAAA,CAAO,cAAA,EAAe;AAAA,MACxB,CAAA,MAAO;AAEL,QAAAA,KAAAA;AAAA,UACE;AAAA,SACF;AACA,QAAA,KAAK,OAAO,OAAA,EAAQ;AAAA,MACtB;AAAA,IACF,CAAA;AAEA,IAAA,MAAM,yBAAyB,MAAM;AACnC,MAAA,IAAI,QAAA,CAAS,oBAAoB,SAAA,EAAW;AAC1C,QAAA,gBAAA,EAAiB;AAAA,MACnB;AAAA,IACF,CAAA;AAEA,IAAA,MAAM,cAAc,MAAM;AACxB,MAAA,gBAAA,EAAiB;AAAA,IACnB,CAAA;AAEA,IAAA,QAAA,CAAS,gBAAA,CAAiB,oBAAoB,sBAAsB,CAAA;AACpE,IAAA,MAAA,CAAO,gBAAA,CAAiB,SAAS,WAAW,CAAA;AAE5C,IAAA,OAAO,MAAM;AACX,MAAA,QAAA,CAAS,mBAAA,CAAoB,oBAAoB,sBAAsB,CAAA;AACvE,MAAA,MAAA,CAAO,mBAAA,CAAoB,SAAS,WAAW,CAAA;AAAA,IACjD,CAAA;AAAA,EACF,CAAA,EAAG,CAAC,MAAM,CAAC,CAAA;AAGX,EAAA,SAAA,CAAU,MAAM;AACd,IAAA,IAAI,CAAC,MAAA,IAAU,OAAA,CAAQ,GAAA,CAAI,aAAa,aAAA,EAAe;AACrD,MAAA,IAAA;AAAA,QACE;AAAA,OACF;AAAA,IACF;AAAA,EACF,CAAA,EAAG,CAAC,MAAM,CAAC,CAAA;AAGX,EAAA,2BACG,qBAAA,CAAsB,QAAA,EAAtB,EAA+B,KAAA,EAAO,QACpC,QAAA,EACH,CAAA;AAEJ;AAMO,SAAS,iBAAA,GAA2C;AACzD,EAAA,OAAO,WAAW,qBAAqB,CAAA;AACzC;AAKO,SAAS,wBAAA,GAA2C;AACzD,EAAA,MAAM,MAAA,GAAS,WAAW,qBAAqB,CAAA;AAC/C,EAAA,IAAI,CAAC,MAAA,EAAQ;AACX,IAAA,MAAM,IAAI,KAAA;AAAA,MACR;AAAA,KACF;AAAA,EACF;AACA,EAAA,OAAO,MAAA;AACT;AAMO,SAAS,kBAAA,GAAmD;AACjE,EAAA,MAAM,SAAS,iBAAA,EAAkB;AAEjC,EAAA,OAAO,oBAAA;AAAA,IACL,CAAC,QAAA,KAAa;AACZ,MAAA,IAAI,CAAC,MAAA,EAAQ,OAAO,MAAM;AAAA,MAAC,CAAA;AAC3B,MAAA,OAAO,MAAA,CAAO,wBAAwB,QAAQ,CAAA;AAAA,IAChD,CAAA;AAAA,IACA,MAAO,MAAA,GAAS,MAAA,CAAO,kBAAA,EAAmB,GAAI,UAAA;AAAA,IAC9C,MAAM;AAAA,GACR;AACF;AAMO,SAAS,eAAA,CACd,IAAA,EACA,OAAA,GAAwC,EAAC,EAOzC;AACA,EAAA,MAAM,SAAS,iBAAA,EAAkB;AACjC,EAAA,MAAM,eAAA,GAAkB,OAAmC,IAAI,CAAA;AAC/D,EAAA,MAAM,CAAC,KAAA,EAAO,QAAQ,CAAA,GAAI,QAAA,CAIvB;AAAA,IACD,IAAA,EAAM,MAAA;AAAA,IACN,OAAA,EAAS,CAAC,MAAA,GAAS,KAAA,GAAQ,IAAA;AAAA,IAC3B,KAAA,EAAO;AAAA,GACR,CAAA;AAGD,EAAA,MAAM,QAAA,GAAW,IAAA,CAAK,SAAA,CAAU,OAAA,CAAQ,KAAK,CAAA;AAE7C,EAAA,MAAM,SAAA,GAAY,MAAA,CAAO,OAAA,CAAQ,MAAM,CAAA;AACvC,EAAA,MAAM,UAAA,GAAa,MAAA,CAAO,OAAA,CAAQ,OAAO,CAAA;AACzC,EAAA,SAAA,CAAU,UAAU,OAAA,CAAQ,MAAA;AAC5B,EAAA,UAAA,CAAW,UAAU,OAAA,CAAQ,OAAA;AAE7B,EAAA,SAAA,CAAU,MAAM;AACd,IAAA,IAAI,CAAC,MAAA,EAAQ;AAGb,IAAA,MAAM,KAAA,GAAQ,QAAA,GAAW,IAAA,CAAK,KAAA,CAAM,QAAQ,CAAA,GAAI,MAAA;AAEhD,IAAA,MAAM,YAAA,GAAe,MAAA,CAAO,SAAA,CAAiB,IAAA,EAAM;AAAA,MACjD,KAAA;AAAA,MACA,MAAA,EAAQ,CAAC,IAAA,KAAS;AAChB,QAAA,QAAA,CAAS,CAAC,IAAA,MAAU;AAAA,UAClB,GAAG,IAAA;AAAA,UACH,IAAA;AAAA,UACA,OAAA,EAAS,KAAA;AAAA,UACT,KAAA,EAAO;AAAA,SACT,CAAE,CAAA;AACF,QAAA,SAAA,CAAU,UAAU,IAAI,CAAA;AAAA,MAC1B,CAAA;AAAA,MACA,OAAA,EAAS,CAACD,MAAAA,KAAU;AAClB,QAAA,QAAA,CAAS,CAAC,IAAA,MAAU;AAAA,UAClB,GAAG,IAAA;AAAA,UACH,KAAA,EAAAA,MAAAA;AAAA,UACA,OAAA,EAAS;AAAA,SACX,CAAE,CAAA;AACF,QAAA,UAAA,CAAW,UAAUA,MAAK,CAAA;AAAA,MAC5B;AAAA,KACD,CAAA;AAED,IAAA,eAAA,CAAgB,OAAA,GAAU,YAAA;AAI1B,IAAA,MAAM,qBAAqB,MAAA,CAAO,uBAAA;AAAA,MAChC,YAAA,CAAa,EAAA;AAAA,MACb,MAAM;AAEJ,QAAAC,KAAAA;AAAA,UACE,kDAAA;AAAA,UACA,IAAA;AAAA,UACA,cAAA;AAAA,UACA,MAAM,OAAA,CAAQ,YAAA,CAAa,IAAI,CAAA,GAC3B,YAAA,CAAa,KAAK,MAAA,GAClB;AAAA,SACN;AACA,QAAA,QAAA,CAAS;AAAA,UACP,MAAM,YAAA,CAAa,IAAA;AAAA,UACnB,SAAS,YAAA,CAAa,OAAA;AAAA,UACtB,OAAO,YAAA,CAAa;AAAA,SACrB,CAAA;AAAA,MACH;AAAA,KACF;AAGA,IAAA,QAAA,CAAS;AAAA,MACP,MAAM,YAAA,CAAa,IAAA;AAAA,MACnB,SAAS,YAAA,CAAa,OAAA;AAAA,MACtB,OAAO,YAAA,CAAa;AAAA,KACrB,CAAA;AAED,IAAA,OAAO,MAAM;AACX,MAAA,kBAAA,EAAmB;AACnB,MAAA,YAAA,CAAa,WAAA,EAAY;AACzB,MAAA,eAAA,CAAgB,OAAA,GAAU,IAAA;AAAA,IAC5B,CAAA;AAAA,EAEF,CAAA,EAAG,CAAC,MAAA,EAAQ,IAAA,EAAM,QAAQ,CAAC,CAAA;AAE3B,EAAA,MAAM,UAAU,YAAY;AAC1B,IAAA,IAAI,gBAAgB,OAAA,EAAS;AAC3B,MAAA,QAAA,CAAS,CAAC,IAAA,MAAU,EAAE,GAAG,IAAA,EAAM,OAAA,EAAS,MAAK,CAAE,CAAA;AAC/C,MAAA,MAAM,eAAA,CAAgB,QAAQ,OAAA,EAAQ;AAAA,IACxC;AAAA,EACF,CAAA;AAEA,EAAA,OAAO;AAAA,IACL,GAAG,KAAA;AAAA,IACH,UAAU,CAAC,MAAA;AAAA,IACX;AAAA,GACF;AACF;AAWO,SAAS,WAAA,CACd,MACA,OAAA,EAQA;AACA,EAAA,MAAM,SAAS,iBAAA,EAAkB;AACjC,EAAA,MAAM,CAAC,KAAA,EAAO,QAAQ,CAAA,GAAI,QAAA,CAIvB;AAAA,IACD,IAAA,EAAM,MAAA;AAAA,IACN,OAAA,EAAS,KAAA;AAAA,IACT,KAAA,EAAO;AAAA,GACR,CAAA;AAID,EAAA,MAAM,eAAA,GACJ,OAAA,EAAS,WAAA,IAAA,CACR,MAAM;AACL,IAAA,MAAM,KAAA,GAAQ,IAAA,CAAK,KAAA,CAAM,GAAG,CAAA;AAC5B,IAAA,IAAI,KAAA,CAAM,UAAU,CAAA,EAAG;AACrB,MAAA,OAAO,CAAA,EAAG,MAAM,KAAA,CAAM,CAAA,EAAG,EAAE,CAAA,CAAE,IAAA,CAAK,GAAG,CAAC,CAAA,KAAA,CAAA;AAAA,IACxC;AACA,IAAA,OAAO,MAAA;AAAA,EACT,CAAA,GAAG;AAIL,EAAA,MAAM,iBACJ,OAAA,EAAS,gBAAA,KACR,KAAK,QAAA,CAAS,SAAS,IAAI,QAAA,GAAW,OAAA,CAAA;AAEzC,EAAA,MAAM,MAAA,GAAS,OAAO,KAAA,KAAoC;AACxD,IAAA,IAAI,CAAC,MAAA,EAAQ;AACX,MAAA,MAAM,IAAI,MAAM,mDAAmD,CAAA;AAAA,IACrE;AAEA,IAAAA,MAAM,yCAAA,EAA2C;AAAA,MAC/C,IAAA;AAAA,MACA,eAAA;AAAA,MACA,cAAA;AAAA,MACA;AAAA,KACD,CAAA;AAED,IAAA,QAAA,CAAS,CAAC,UAAU,EAAE,GAAG,MAAM,OAAA,EAAS,IAAA,EAAM,KAAA,EAAO,MAAA,EAAU,CAAE,CAAA;AAEjE,IAAA,IAAI;AACF,MAAA,MAAM,MAAA,GAAS,MAAM,MAAA,CAAO,IAAA,CAAsB,MAAM,KAAA,EAAO;AAAA,QAC7D,WAAA,EAAa,eAAA;AAAA,QACb,gBAAA,EAAkB;AAAA,OACnB,CAAA;AACD,MAAA,QAAA,CAAS,EAAE,IAAA,EAAM,MAAA,EAAQ,SAAS,KAAA,EAAO,KAAA,EAAO,QAAW,CAAA;AAC3D,MAAA,OAAO,MAAA;AAAA,IACT,SAASD,MAAAA,EAAO;AACd,MAAA,MAAM,GAAA,GAAMA,kBAAiB,KAAA,GAAQA,MAAAA,GAAQ,IAAI,KAAA,CAAM,MAAA,CAAOA,MAAK,CAAC,CAAA;AACpE,MAAA,QAAA,CAAS,CAAC,UAAU,EAAE,GAAG,MAAM,OAAA,EAAS,KAAA,EAAO,KAAA,EAAO,GAAA,EAAI,CAAE,CAAA;AAC5D,MAAA,MAAM,GAAA;AAAA,IACR;AAAA,EACF,CAAA;AAEA,EAAA,MAAM,QAAQ,MAAM;AAClB,IAAA,QAAA,CAAS,EAAE,IAAA,EAAM,MAAA,EAAW,SAAS,KAAA,EAAO,KAAA,EAAO,QAAW,CAAA;AAAA,EAChE,CAAA;AAEA,EAAA,OAAO;AAAA,IACL,MAAA;AAAA,IACA,GAAG,KAAA;AAAA,IACH,UAAU,CAAC,MAAA;AAAA,IACX;AAAA,GACF;AACF;AAsGO,SAAS,SAAA,GAAgD;AAC9D,EAAA,MAAM,SAAS,iBAAA,EAAkB;AAEjC,EAAA,SAAS,WAAW,IAAA,EAAyB;AAC3C,IAAA,OAAO,IAAI,KAAA;AAAA,MACT,EAAC;AAAA,MACD;AAAA,QACE,GAAA,CAAI,SAAS,IAAA,EAAc;AACzB,UAAA,IAAI,SAAS,UAAA,EAAY;AAEvB,YAAA,OAAO,SAAS,YAAA,CACd,KAAA,EACA,OAAA,EACA;AACA,cAAA,MAAM,OAAA,GAAU,IAAA,CAAK,IAAA,CAAK,GAAG,CAAA;AAE7B,cAAA,OAAO,gBAAgB,OAAA,EAAS,EAAE,GAAG,OAAA,EAAS,OAAO,CAAA;AAAA,YACvD,CAAA;AAAA,UACF;AAEA,UAAA,IAAI,SAAS,aAAA,EAAe;AAE1B,YAAA,OAAO,SAAS,gBACd,OAAA,EACA;AACA,cAAA,MAAM,OAAA,GAAU,IAAA,CAAK,IAAA,CAAK,GAAG,CAAA;AAE7B,cAAA,OAAO,WAAA,CAAY,SAAS,OAAO,CAAA;AAAA,YACrC,CAAA;AAAA,UACF;AAGA,UAAA,IAAI,SAAS,YAAA,EAAc;AACzB,YAAA,OAAO,CACL,OAAA,KAKG;AACH,cAAA,MAAA,EAAQ,WAAW,OAAO,CAAA;AAAA,YAC5B,CAAA;AAAA,UACF;AAEA,UAAA,OAAO,UAAA,CAAW,CAAC,GAAG,IAAA,EAAM,IAAI,CAAC,CAAA;AAAA,QACnC;AAAA;AACF,KACF;AAAA,EACF;AAEA,EAAA,OAAO,UAAA,CAAW,EAAE,CAAA;AACtB;AAKO,SAAS,mBAAA,GAAsB;AACpC,EAAA,OAAO;AAAA,IACL,iBAAiB,CACf,IAAA,EACA,OAAA,KACG,eAAA,CAAuB,MAAM,OAAO,CAAA;AAAA,IAEzC,aAAa,CACX,IAAA,EACA,OAAA,KACG,WAAA,CAA6B,MAAM,OAAO,CAAA;AAAA,IAE/C,kBAAA;AAAA,IACA;AAAA,GACF;AACF;AAKO,SAAS,qBAAsC,IAAA,EAAc;AAClE,EAAA,OAAO;AAAA,IACL,eAAA,EAAiB,CACf,KAAA,EACA,OAAA,KACG,eAAA,CAAyB,MAAM,EAAE,GAAG,OAAA,EAAS,KAAA,EAAO,CAAA;AAAA,IAEzD,WAAA,EAAa,CAAC,OAAA,KACZ,WAAA,CAA6B,MAAM,OAAO;AAAA,GAC9C;AACF","file":"chunk-2A7GJ2UO.js","sourcesContent":["import jsonpatch, { type Operation } from 'fast-json-patch';\n\nimport type { JsonPatch } from './types.js';\n\nconst { applyPatch } = jsonpatch;\n\n/**\n * Apply JSON patches to a document\n */\nexport function applyPatches<T>(document: T, patches: JsonPatch[]): T {\n if (patches.length === 0) {\n return document;\n }\n\n const operations: Operation[] = patches.map((patch) => {\n const op: Operation = {\n op: patch.op,\n path: patch.path,\n } as Operation;\n\n if ('value' in patch && patch.value !== undefined) {\n (op as { value: unknown }).value = patch.value;\n }\n if ('from' in patch && patch.from !== undefined) {\n (op as { from: string }).from = patch.from;\n }\n\n return op;\n });\n\n try {\n const result = applyPatch(\n structuredClone(document),\n operations,\n true, // Validate operations\n false, // Don't mutate the original\n );\n\n return result.newDocument as T;\n } catch (error) {\n throw new Error('Failed to apply patches', { cause: error });\n }\n}\n","/* eslint-disable no-console */\nimport { error } from 'ag-common/dist/common/helpers/log.js';\n\nimport type {\n ClientMessage,\n ConnectionState,\n ReactiveClientConfig,\n ServerMessage,\n} from './types.js';\n\n/**\n * WebSocket manager with automatic reconnection\n */\nexport class WebSocketManager {\n private config: Required<\n Omit<\n ReactiveClientConfig,\n 'auth' | 'httpUrl' | 'headers' | 'onConnect' | 'onDisconnect' | 'onError'\n >\n > &\n ReactiveClientConfig;\n private ws: WebSocket | null = null;\n private state: ConnectionState = 'disconnected';\n private reconnectAttempts = 0;\n private reconnectTimer: ReturnType<typeof setTimeout> | null = null;\n private messageQueue: ClientMessage[] = [];\n private messageHandlers = new Set<(message: ServerMessage) => void>();\n private stateHandlers = new Set<(state: ConnectionState) => void>();\n private _connectionId: string | null = null;\n private connectionIdResolvers: Array<(id: string) => void> = [];\n /** Flag to indicate intentional disconnect (skip auto-reconnect) */\n private intentionalDisconnect = false;\n\n constructor(config: ReactiveClientConfig) {\n this.config = {\n autoReconnect: true,\n reconnectDelay: 1000,\n maxReconnectAttempts: 10,\n ...config,\n };\n }\n\n /**\n * Get the current connection ID (null if not connected)\n */\n get connectionId(): string | null {\n return this._connectionId;\n }\n\n /**\n * Wait for the connection ID to be available\n */\n waitForConnectionId(): Promise<string> {\n if (this._connectionId) {\n return Promise.resolve(this._connectionId);\n }\n return new Promise((resolve) => {\n this.connectionIdResolvers.push(resolve);\n });\n }\n\n /**\n * Get current connection state\n */\n getState(): ConnectionState {\n return this.state;\n }\n\n /**\n * Connect to the WebSocket server\n */\n async connect(): Promise<void> {\n if (this.state === 'connected' || this.state === 'connecting') {\n return;\n }\n\n this.setState('connecting');\n\n try {\n const url = await this.buildUrl();\n this.ws = new WebSocket(url);\n\n this.ws.onopen = () => {\n this.reconnectAttempts = 0;\n // Send init message to get connectionId from server\n // Don't set state to 'connected' until we receive connectionId\n this.ws?.send(JSON.stringify({ type: 'init' }));\n };\n\n this.ws.onclose = () => {\n this.ws = null;\n this._connectionId = null;\n this.setState('disconnected');\n this.config.onDisconnect?.();\n\n // Always attempt reconnect unless intentionally disconnected\n // This handles server timeouts (which may close \"cleanly\") and network issues\n if (this.config.autoReconnect && !this.intentionalDisconnect) {\n this.scheduleReconnect();\n }\n this.intentionalDisconnect = false;\n };\n\n this.ws.onerror = () => {\n const error = new Error('WebSocket error');\n this.config.onError?.(error);\n };\n\n this.ws.onmessage = (event) => {\n try {\n const message = JSON.parse(event.data) as ServerMessage;\n\n // Handle 'connected' message - we got connectionId, now verify with ping/pong\n if (message.type === 'connected') {\n this._connectionId = message.connectionId;\n // Send ping to verify the connection is fully working\n this.ws?.send(JSON.stringify({ type: 'ping' }));\n return;\n }\n\n // Handle 'pong' message - connection is verified, now we're truly connected\n if (message.type === 'pong') {\n this.setState('connected');\n this.flushMessageQueue();\n this.config.onConnect?.();\n\n // Resolve any pending waitForConnectionId promises\n for (const resolve of this.connectionIdResolvers) {\n resolve(this._connectionId!);\n }\n this.connectionIdResolvers = [];\n return;\n }\n\n this.handleMessage(message);\n } catch (e) {\n error('Failed to parse WebSocket message:', e);\n }\n };\n } catch (e) {\n this.setState('disconnected');\n this.config.onError?.(e instanceof Error ? e : new Error(String(e)));\n\n if (this.config.autoReconnect) {\n this.scheduleReconnect();\n }\n }\n }\n\n /**\n * Disconnect from the WebSocket server\n */\n disconnect(): void {\n this.intentionalDisconnect = true;\n\n if (this.reconnectTimer) {\n clearTimeout(this.reconnectTimer);\n this.reconnectTimer = null;\n }\n\n if (this.ws) {\n this.ws.close(1000, 'Client disconnect');\n this.ws = null;\n }\n\n this._connectionId = null;\n this.setState('disconnected');\n }\n\n /**\n * Force reconnect - closes existing connection and reconnects\n * Useful for recovering from stale connections\n */\n forceReconnect(): void {\n // Close existing connection without setting intentionalDisconnect\n if (this.reconnectTimer) {\n clearTimeout(this.reconnectTimer);\n this.reconnectTimer = null;\n }\n\n if (this.ws) {\n this.ws.close(1000, 'Force reconnect');\n this.ws = null;\n }\n\n this._connectionId = null;\n this.reconnectAttempts = 0;\n this.setState('disconnected');\n\n // Immediately reconnect\n void this.connect();\n }\n\n /**\n * Send a message to the server\n */\n send(message: ClientMessage): void {\n // Check both our state and the actual WebSocket readyState\n if (this.state === 'connected' && this.ws?.readyState === WebSocket.OPEN) {\n this.ws.send(JSON.stringify(message));\n } else {\n // Queue message for when we reconnect\n this.messageQueue.push(message);\n }\n }\n\n /**\n * Subscribe to incoming messages\n */\n onMessage(handler: (message: ServerMessage) => void): () => void {\n this.messageHandlers.add(handler);\n return () => this.messageHandlers.delete(handler);\n }\n\n /**\n * Subscribe to connection state changes\n */\n onStateChange(handler: (state: ConnectionState) => void): () => void {\n this.stateHandlers.add(handler);\n return () => this.stateHandlers.delete(handler);\n }\n\n private async buildUrl(): Promise<string> {\n let url = this.config.url;\n\n if (this.config.auth) {\n const token =\n typeof this.config.auth === 'function'\n ? await this.config.auth()\n : this.config.auth;\n\n const separator = url.includes('?') ? '&' : '?';\n url = `${url}${separator}token=${encodeURIComponent(token)}`;\n }\n\n return url;\n }\n\n private setState(state: ConnectionState): void {\n this.state = state;\n for (const handler of this.stateHandlers) {\n handler(state);\n }\n }\n\n private handleMessage(message: ServerMessage): void {\n for (const handler of this.messageHandlers) {\n handler(message);\n }\n }\n\n private scheduleReconnect(): void {\n if (this.reconnectAttempts >= this.config.maxReconnectAttempts) {\n error('Max reconnection attempts reached');\n return;\n }\n\n this.setState('reconnecting');\n this.reconnectAttempts++;\n\n // Exponential backoff with jitter\n const delay =\n Math.min(\n this.config.reconnectDelay * Math.pow(2, this.reconnectAttempts - 1),\n 30000, // Max 30 seconds\n ) *\n (0.5 + Math.random() * 0.5);\n\n this.reconnectTimer = setTimeout(() => {\n this.reconnectTimer = null;\n void this.connect();\n }, delay);\n }\n\n private flushMessageQueue(): void {\n const queue = this.messageQueue;\n this.messageQueue = [];\n\n for (const message of queue) {\n this.send(message);\n }\n }\n}\n","import { debug } from 'ag-common/dist/common/helpers/log.js';\n\nimport { applyPatches } from './patcher.js';\nimport type {\n ConnectionState,\n JsonPatch,\n MutationOptions,\n ReactiveClientConfig,\n ServerMessage,\n Subscription,\n SubscriptionOptions,\n} from './types.js';\nimport { WebSocketManager } from './websocket.js';\n\n/**\n * Default HTTP URL for subscribe/call requests (Next.js API route)\n */\nconst DEFAULT_HTTP_URL = '/api/reactive';\n\n/**\n * Generate a unique subscription ID\n */\nfunction generateId(): string {\n return `${Date.now()}-${Math.random().toString(36).substring(2, 9)}`;\n}\n\n/**\n * Internal subscription state\n */\ninterface SubscriptionState<TData> {\n id: string;\n path: string;\n input: unknown;\n data: TData | undefined;\n loading: boolean;\n error: Error | undefined;\n listeners: Set<() => void>;\n options: SubscriptionOptions<unknown>;\n}\n\n/**\n * Pending call state\n */\ninterface PendingCall {\n resolve: (data: unknown) => void;\n reject: (error: Error) => void;\n}\n\n/**\n * Reactive client for type-safe subscriptions\n */\nexport class ReactiveClient {\n private wsManager: WebSocketManager;\n private httpUrl: string;\n private authGetter?: () => string | Promise<string>;\n private headersGetter?: () =>\n | Record<string, string>\n | Promise<Record<string, string>>;\n private subscriptions = new Map<string, SubscriptionState<unknown>>();\n private pendingCalls = new Map<string, PendingCall>();\n private connectionState: ConnectionState = 'disconnected';\n private stateListeners = new Set<(state: ConnectionState) => void>();\n // Stores original data for rollback when optimistic updates fail\n private optimisticUpdates = new Map<string, unknown>();\n\n constructor(config: ReactiveClientConfig) {\n this.wsManager = new WebSocketManager(config);\n this.httpUrl = config.httpUrl ?? DEFAULT_HTTP_URL;\n\n // Store auth getter for HTTP requests\n if (typeof config.auth === 'function') {\n this.authGetter = config.auth;\n } else if (config.auth) {\n this.authGetter = () => config.auth as string;\n }\n\n // Store headers getter for HTTP requests\n if (typeof config.headers === 'function') {\n this.headersGetter = config.headers;\n } else if (config.headers) {\n this.headersGetter = () => config.headers as Record<string, string>;\n }\n\n // Handle incoming messages (patches come via WebSocket)\n this.wsManager.onMessage((message) => this.handleMessage(message));\n\n // Handle connection state changes\n this.wsManager.onStateChange((state) => {\n this.connectionState = state;\n this.notifyStateListeners();\n\n if (state === 'connected') {\n this.resubscribeAll();\n }\n });\n }\n\n /**\n * Connect to the server\n */\n async connect(): Promise<void> {\n await this.wsManager.connect();\n }\n\n /**\n * Disconnect from the server\n */\n disconnect(): void {\n this.wsManager.disconnect();\n }\n\n /**\n * Force reconnect - closes existing connection and reconnects\n * Useful for recovering from stale connections\n */\n forceReconnect(): void {\n this.wsManager.forceReconnect();\n }\n\n /**\n * Update the headers getter for HTTP requests.\n * Useful for dynamically setting auth or user context headers.\n */\n setHeaders(\n headers:\n | Record<string, string>\n | (() => Record<string, string> | Promise<Record<string, string>>),\n ): void {\n if (typeof headers === 'function') {\n this.headersGetter = headers;\n } else {\n this.headersGetter = () => headers;\n }\n }\n\n /**\n * Get current connection state\n */\n getConnectionState(): ConnectionState {\n return this.connectionState;\n }\n\n /**\n * Subscribe to connection state changes\n */\n onConnectionStateChange(\n listener: (state: ConnectionState) => void,\n ): () => void {\n this.stateListeners.add(listener);\n return () => this.stateListeners.delete(listener);\n }\n\n /**\n * Subscribe to a procedure via HTTP.\n * Snapshot is returned via HTTP, patches come via WebSocket.\n */\n subscribe<TData>(\n path: string,\n options: SubscriptionOptions<unknown> = {},\n ): Subscription<TData> {\n const id = generateId();\n\n const state: SubscriptionState<TData> = {\n id,\n path,\n input: options.input,\n data: undefined,\n loading: true,\n error: undefined,\n listeners: new Set(),\n options,\n };\n\n this.subscriptions.set(id, state as SubscriptionState<unknown>);\n\n // Send subscribe request via HTTP (async)\n this.sendSubscribeRequest(id, path, options.input).catch((error) => {\n state.error = error instanceof Error ? error : new Error(String(error));\n state.loading = false;\n this.notifySubscriptionListeners(id);\n options.onError?.(state.error);\n });\n\n const subscription: Subscription<TData> = {\n id,\n get data() {\n return state.data;\n },\n get loading() {\n return state.loading;\n },\n get error() {\n return state.error;\n },\n unsubscribe: () => this.unsubscribe(id),\n refetch: () => this.refetch(id),\n };\n\n return subscription;\n }\n\n /**\n * Send subscribe request via HTTP\n */\n private async sendSubscribeRequest(\n subscriptionId: string,\n path: string,\n input: unknown,\n ): Promise<void> {\n // Wait for connectionId to be available\n const connectionId = await this.wsManager.waitForConnectionId();\n\n const headers: Record<string, string> = {\n 'Content-Type': 'application/json',\n };\n\n // Add custom headers if configured\n if (this.headersGetter) {\n const customHeaders = await this.headersGetter();\n Object.assign(headers, customHeaders);\n }\n\n // Add auth header if configured\n if (this.authGetter) {\n const token = await this.authGetter();\n headers['Authorization'] = `Bearer ${token}`;\n }\n\n const response = await fetch(this.httpUrl, {\n method: 'POST',\n headers,\n body: JSON.stringify({\n type: 'subscribe',\n connectionId,\n subscriptionId,\n path,\n input,\n }),\n });\n\n if (!response.ok) {\n throw new Error(\n `Subscribe failed: ${response.status} ${response.statusText}`,\n );\n }\n\n const result = (await response.json()) as {\n type: string;\n message?: string;\n data?: unknown;\n };\n\n if (result.type === 'error') {\n throw new Error(result.message ?? 'Unknown error');\n }\n\n if (result.type === 'snapshot') {\n this.handleSnapshot(subscriptionId, result.data);\n }\n }\n\n /**\n * Call a mutation procedure via HTTP with optimistic update support.\n * All optimistic updates are applied INSTANTLY (before HTTP request).\n */\n async call<TInput, TOutput>(\n path: string,\n input: TInput,\n options?: MutationOptions<TInput, TOutput>,\n ): Promise<TOutput> {\n const invalidatesPath = options?.invalidates;\n const updateType = options?.optimisticUpdate;\n let targetSubscriptionId: string | undefined;\n\n // Find subscription to optimistically update\n if (invalidatesPath) {\n targetSubscriptionId = this.findSubscriptionByPath(invalidatesPath);\n debug(\n '[optimistic] Looking for subscription:',\n invalidatesPath,\n '-> found:',\n targetSubscriptionId ?? 'NONE',\n );\n }\n\n // Apply INSTANT optimistic update (before HTTP request)\n if (targetSubscriptionId) {\n debug(\n '[optimistic] Applying update type:',\n updateType,\n 'to subscription:',\n targetSubscriptionId,\n );\n const state = this.subscriptions.get(targetSubscriptionId);\n const currentData = state?.data;\n\n if (updateType === 'remove') {\n // Remove: filter out item by id\n const inputId = (input as { id?: string }).id;\n if (inputId) {\n this.applyOptimisticUpdate(targetSubscriptionId, (data) => {\n if (!Array.isArray(data)) return data;\n return data.filter((item: { id?: string }) => item.id !== inputId);\n });\n }\n } else if (updateType === 'merge') {\n // Merge: find item by id and merge input fields into it\n const inputWithId = input as { id?: string };\n if (inputWithId.id) {\n this.applyOptimisticUpdate(targetSubscriptionId, (data) => {\n if (!Array.isArray(data)) return data;\n const idx = data.findIndex(\n (item: { id?: string }) => item.id === inputWithId.id,\n );\n if (idx >= 0) {\n // Merge input into existing item\n return [\n ...data.slice(0, idx),\n { ...data[idx], ...input },\n ...data.slice(idx + 1),\n ];\n }\n return data;\n });\n } else if (options?.optimisticData) {\n // For creates without id, use provided optimisticData\n const optimistic =\n typeof options.optimisticData === 'function'\n ? (\n options.optimisticData as (\n input: TInput,\n data: unknown[],\n ) => TOutput\n )(input, Array.isArray(currentData) ? currentData : [])\n : options.optimisticData;\n if (optimistic) {\n this.applyOptimisticUpdate(targetSubscriptionId, (data) => {\n if (!Array.isArray(data)) return data;\n return [optimistic, ...data];\n });\n }\n }\n } else if (typeof updateType === 'function') {\n // Custom update function - apply instantly\n this.applyOptimisticUpdate(targetSubscriptionId, (data) => {\n if (!Array.isArray(data)) return data;\n return updateType(data, input, undefined);\n });\n }\n }\n\n // Wait for connectionId to be available\n const connectionId = await this.wsManager.waitForConnectionId();\n\n const headers: Record<string, string> = {\n 'Content-Type': 'application/json',\n };\n\n // Add custom headers if configured\n if (this.headersGetter) {\n const customHeaders = await this.headersGetter();\n Object.assign(headers, customHeaders);\n }\n\n // Add auth header if configured\n if (this.authGetter) {\n const token = await this.authGetter();\n headers['Authorization'] = `Bearer ${token}`;\n }\n\n try {\n const response = await fetch(this.httpUrl, {\n method: 'POST',\n headers,\n body: JSON.stringify({\n type: 'call',\n connectionId,\n path,\n input,\n }),\n });\n\n if (!response.ok) {\n throw new Error(\n `Call failed: ${response.status} ${response.statusText}`,\n );\n }\n\n const result = (await response.json()) as {\n type: string;\n message?: string;\n data?: unknown;\n };\n\n if (result.type === 'error') {\n throw new Error(result.message ?? 'Unknown error');\n }\n\n const data = result.data as TOutput;\n\n // After HTTP success, reconcile with real server data\n if (targetSubscriptionId && updateType === 'merge') {\n const resultWithId = data as { id?: string };\n if (resultWithId.id) {\n this.applyOptimisticUpdate(targetSubscriptionId, (currentData) => {\n if (!Array.isArray(currentData)) return currentData;\n const idx = currentData.findIndex(\n (item: { id?: string }) => item.id === resultWithId.id,\n );\n if (idx >= 0) {\n // Update with real server data\n return [\n ...currentData.slice(0, idx),\n data,\n ...currentData.slice(idx + 1),\n ];\n } else {\n // New item - add it (and remove any temp items)\n return [\n data,\n ...currentData.filter(\n (item: { id?: string }) =>\n item.id && !item.id.startsWith('temp-'),\n ),\n ];\n }\n });\n }\n }\n\n return data;\n } catch (error) {\n // Rollback on error\n if (targetSubscriptionId) {\n this.rollbackOptimisticUpdate(targetSubscriptionId);\n }\n throw error;\n }\n }\n\n /**\n * Unsubscribe from a subscription\n */\n private unsubscribe(id: string): void {\n const state = this.subscriptions.get(id);\n if (!state) return;\n\n this.subscriptions.delete(id);\n\n this.wsManager.send({\n type: 'unsubscribe',\n subscriptionId: id,\n });\n }\n\n /**\n * Refetch a subscription via HTTP\n */\n private async refetch(id: string): Promise<void> {\n const state = this.subscriptions.get(id);\n if (!state) return;\n\n state.loading = true;\n this.notifySubscriptionListeners(id);\n\n try {\n await this.sendSubscribeRequest(id, state.path, state.input);\n } catch (error) {\n state.error = error instanceof Error ? error : new Error(String(error));\n state.loading = false;\n this.notifySubscriptionListeners(id);\n state.options.onError?.(state.error);\n }\n }\n\n /**\n * Handle incoming server messages.\n * Note: 'connected' messages are handled by WebSocketManager before reaching here.\n */\n private handleMessage(message: ServerMessage): void {\n switch (message.type) {\n case 'connected':\n // Handled by WebSocketManager - should not reach here\n break;\n\n case 'pong':\n // Heartbeat response - no action needed\n break;\n\n case 'snapshot':\n this.handleSnapshot(message.subscriptionId, message.data);\n break;\n\n case 'patch':\n this.handlePatch(message.subscriptionId, message.patches);\n break;\n\n case 'result':\n this.handleResult(message.callId, message.data);\n break;\n\n case 'error':\n this.handleError(message);\n break;\n }\n }\n\n /**\n * Handle a snapshot message\n */\n private handleSnapshot(subscriptionId: string, data: unknown): void {\n const state = this.subscriptions.get(subscriptionId);\n if (!state) return;\n\n // Clear optimistic state since we have authoritative data\n this.clearOptimisticUpdate(subscriptionId);\n\n state.data = data;\n state.loading = false;\n state.error = undefined;\n\n this.notifySubscriptionListeners(subscriptionId);\n state.options.onData?.(data);\n }\n\n /**\n * Handle a patch message\n */\n private handlePatch(subscriptionId: string, patches: JsonPatch[]): void {\n const state = this.subscriptions.get(subscriptionId);\n if (!state || state.data === undefined) return;\n\n // If we have optimistic state, apply patch to the ORIGINAL data\n // This prevents conflicts when patch tries to modify already-modified data\n const originalData = this.optimisticUpdates.get(subscriptionId);\n const baseData = originalData !== undefined ? originalData : state.data;\n\n // Clear optimistic state since we have authoritative patch data\n this.clearOptimisticUpdate(subscriptionId);\n\n try {\n state.data = applyPatches(baseData, patches);\n this.notifySubscriptionListeners(subscriptionId);\n state.options.onData?.(state.data);\n } catch (error) {\n state.error = error instanceof Error ? error : new Error(String(error));\n this.notifySubscriptionListeners(subscriptionId);\n state.options.onError?.(state.error);\n }\n }\n\n /**\n * Handle a result message\n */\n private handleResult(callId: string, data: unknown): void {\n const pending = this.pendingCalls.get(callId);\n if (!pending) return;\n\n this.pendingCalls.delete(callId);\n pending.resolve(data);\n }\n\n /**\n * Handle an error message\n */\n private handleError(message: {\n message: string;\n subscriptionId?: string;\n callId?: string;\n }): void {\n const error = new Error(message.message);\n\n if (message.subscriptionId) {\n const state = this.subscriptions.get(message.subscriptionId);\n if (state) {\n state.error = error;\n state.loading = false;\n this.notifySubscriptionListeners(message.subscriptionId);\n state.options.onError?.(error);\n }\n }\n\n if (message.callId) {\n const pending = this.pendingCalls.get(message.callId);\n if (pending) {\n this.pendingCalls.delete(message.callId);\n pending.reject(error);\n }\n }\n }\n\n /**\n * Resubscribe to all subscriptions after reconnect via HTTP\n */\n private resubscribeAll(): void {\n for (const [id, state] of this.subscriptions) {\n if (state.options.resubscribeOnReconnect !== false) {\n state.loading = true;\n this.notifySubscriptionListeners(id);\n\n // Re-subscribe via HTTP\n this.sendSubscribeRequest(id, state.path, state.input).catch(\n (error) => {\n state.error =\n error instanceof Error ? error : new Error(String(error));\n state.loading = false;\n this.notifySubscriptionListeners(id);\n state.options.onError?.(state.error);\n },\n );\n }\n }\n }\n\n /**\n * Notify subscription listeners of state changes\n */\n private notifySubscriptionListeners(id: string): void {\n const state = this.subscriptions.get(id);\n if (!state) return;\n\n for (const listener of state.listeners) {\n listener();\n }\n }\n\n /**\n * Notify connection state listeners\n */\n private notifyStateListeners(): void {\n for (const listener of this.stateListeners) {\n listener(this.connectionState);\n }\n }\n\n /**\n * Add a listener for subscription state changes\n * Used internally by React hooks\n */\n addSubscriptionListener(id: string, listener: () => void): () => void {\n const state = this.subscriptions.get(id);\n if (!state) return () => {};\n\n state.listeners.add(listener);\n return () => state.listeners.delete(listener);\n }\n\n /**\n * Get subscription state\n * Used internally by React hooks\n */\n getSubscriptionState<TData>(\n id: string,\n ): SubscriptionState<TData> | undefined {\n return this.subscriptions.get(id) as SubscriptionState<TData> | undefined;\n }\n\n /**\n * Find subscription by path\n */\n private findSubscriptionByPath(path: string): string | undefined {\n debug(\n '[optimistic] Searching for path:',\n path,\n 'in subscriptions:',\n Array.from(this.subscriptions.entries()).map(([id, s]) => ({\n id,\n path: s.path,\n })),\n );\n for (const [id, state] of this.subscriptions) {\n if (state.path === path) {\n return id;\n }\n }\n return undefined;\n }\n\n /**\n * Apply an optimistic update to a subscription's data\n */\n private applyOptimisticUpdate(\n subscriptionId: string,\n updater: (data: unknown) => unknown,\n ): void {\n const state = this.subscriptions.get(subscriptionId);\n if (!state) {\n debug(\n '[optimistic] applyOptimisticUpdate: subscription not found:',\n subscriptionId,\n );\n return;\n }\n if (state.data === undefined) {\n debug(\n '[optimistic] applyOptimisticUpdate: subscription data is undefined (still loading?):',\n subscriptionId,\n );\n return;\n }\n debug(\n '[optimistic] applyOptimisticUpdate: applying update, current data length:',\n Array.isArray(state.data) ? state.data.length : 'not array',\n );\n\n // Store original data for rollback (only if not already stored)\n if (!this.optimisticUpdates.has(subscriptionId)) {\n this.optimisticUpdates.set(\n subscriptionId,\n JSON.parse(JSON.stringify(state.data)),\n );\n }\n\n // Apply the update\n state.data = updater(state.data);\n this.notifySubscriptionListeners(subscriptionId);\n }\n\n /**\n * Rollback an optimistic update\n */\n private rollbackOptimisticUpdate(subscriptionId: string): void {\n const original = this.optimisticUpdates.get(subscriptionId);\n if (original === undefined) return;\n\n const state = this.subscriptions.get(subscriptionId);\n if (state) {\n state.data = original;\n this.notifySubscriptionListeners(subscriptionId);\n }\n this.optimisticUpdates.delete(subscriptionId);\n }\n\n /**\n * Clear optimistic state (called when real data arrives)\n */\n private clearOptimisticUpdate(subscriptionId: string): void {\n this.optimisticUpdates.delete(subscriptionId);\n }\n}\n\n/**\n * Create a type-safe reactive client\n */\nexport function createReactiveClient<TRouter>(\n config: ReactiveClientConfig,\n): TypedReactiveClient<TRouter> {\n const client = new ReactiveClient(config);\n return createTypedProxy(client, []) as TypedReactiveClient<TRouter>;\n}\n\n/**\n * Type-safe client proxy type\n */\nexport type TypedReactiveClient<TRouter> = {\n [K in keyof TRouter]: TRouter[K] extends { query: unknown }\n ? {\n useSubscription: <TData = unknown>(\n input?: unknown,\n options?: Omit<SubscriptionOptions<unknown>, 'input'>,\n ) => Subscription<TData>;\n }\n : TRouter[K] extends { mutation: unknown }\n ? {\n mutate: <TInput, TOutput>(input: TInput) => Promise<TOutput>;\n }\n : TypedReactiveClient<TRouter[K]>;\n} & {\n _client: ReactiveClient;\n connect: () => Promise<void>;\n disconnect: () => void;\n};\n\n/**\n * Create a typed proxy for path-based access\n */\nfunction createTypedProxy(client: ReactiveClient, path: string[]): unknown {\n return new Proxy(\n {},\n {\n get(_target, prop) {\n if (prop === '_client') return client;\n if (prop === 'connect') return () => client.connect();\n if (prop === 'disconnect') return () => client.disconnect();\n\n if (typeof prop !== 'string') return undefined;\n\n const newPath = [...path, prop];\n\n // Check if this is a subscription or mutation\n if (prop === 'useSubscription') {\n return (input?: unknown, options?: SubscriptionOptions<unknown>) => {\n const parentPath = path.join('.');\n return client.subscribe(parentPath, { ...options, input });\n };\n }\n\n if (prop === 'mutate') {\n return async (input: unknown) => {\n const parentPath = path.join('.');\n // Auto-detect invalidates path: 'todos.toggle' → 'todos.list'\n const invalidatesPath =\n path.length >= 2\n ? `${path.slice(0, -1).join('.')}.list`\n : undefined;\n // Auto-detect update type: '*.delete' → 'remove', others → 'merge'\n const updateType = parentPath.endsWith('.delete')\n ? ('remove' as const)\n : ('merge' as const);\n return client.call(parentPath, input, {\n invalidates: invalidatesPath,\n optimisticUpdate: updateType,\n });\n };\n }\n\n return createTypedProxy(client, newPath);\n },\n },\n );\n}\n","import { debug, warn } from 'ag-common/dist/common/helpers/log.js';\nimport {\n createContext,\n type ReactNode,\n useContext,\n useEffect,\n useRef,\n useState,\n useSyncExternalStore,\n} from 'react';\n\nimport { ReactiveClient } from './client.js';\nimport type {\n ConnectionState,\n MutationOptions,\n ReactiveClientConfig,\n Subscription,\n SubscriptionOptions,\n} from './types.js';\n\n/**\n * Context for the reactive client\n */\nconst ReactiveClientContext = createContext<ReactiveClient | null>(null);\n\n/**\n * Provider component for the reactive client\n *\n * If no config.url or client is provided, WebSocket features are disabled\n * and children are rendered without the reactive context.\n */\nexport function ReactiveClientProvider({\n children,\n config,\n client: externalClient,\n}: {\n children: ReactNode;\n config?: ReactiveClientConfig;\n client?: ReactiveClient;\n}) {\n // Extract URL for stable dependency\n const url = config?.url;\n const hasUrl = Boolean(url);\n\n // Always start with null to avoid hydration mismatch\n // Client will be created in useEffect after hydration\n const [client, setClient] = useState<ReactiveClient | null>(\n externalClient ?? null,\n );\n\n // Create client after mount (avoids hydration mismatch)\n useEffect(() => {\n // Skip if we have an external client or no URL\n if (externalClient || !url) return;\n\n // Create client if we don't have one\n if (!client) {\n const newClient = new ReactiveClient({ ...config, url });\n setClient(newClient);\n }\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [url, externalClient]);\n\n // Connect/disconnect effect\n useEffect(() => {\n if (!client) return;\n\n void client.connect();\n\n return () => {\n client.disconnect();\n };\n }, [client]);\n\n // Visibility change and focus handlers - reconnect when tab becomes active\n useEffect(() => {\n // Skip if not in browser environment or no client\n if (typeof window === 'undefined' || typeof document === 'undefined') {\n return;\n }\n if (!client) return;\n\n const attemptReconnect = () => {\n const state = client.getConnectionState();\n if (state === 'connected') {\n // Already connected, nothing to do\n return;\n }\n if (state === 'connecting') {\n // Already connecting, give it a moment\n return;\n }\n if (state === 'reconnecting') {\n // Stuck in backoff, force immediate reconnect\n debug(\n '[dynamodb-reactive] Tab became active during reconnect backoff, forcing reconnect...',\n );\n client.forceReconnect();\n } else {\n // Disconnected, connect normally\n debug(\n '[dynamodb-reactive] Tab became active while disconnected, reconnecting...',\n );\n void client.connect();\n }\n };\n\n const handleVisibilityChange = () => {\n if (document.visibilityState === 'visible') {\n attemptReconnect();\n }\n };\n\n const handleFocus = () => {\n attemptReconnect();\n };\n\n document.addEventListener('visibilitychange', handleVisibilityChange);\n window.addEventListener('focus', handleFocus);\n\n return () => {\n document.removeEventListener('visibilitychange', handleVisibilityChange);\n window.removeEventListener('focus', handleFocus);\n };\n }, [client]);\n\n // Log warning if no URL configured (only once in dev)\n useEffect(() => {\n if (!hasUrl && process.env.NODE_ENV === 'development') {\n warn(\n '[dynamodb-reactive] WebSocket URL not configured, real-time features disabled',\n );\n }\n }, [hasUrl]);\n\n // Always render with context provider - hooks will handle null client\n return (\n <ReactiveClientContext.Provider value={client}>\n {children}\n </ReactiveClientContext.Provider>\n );\n}\n\n/**\n * Hook to get the reactive client\n * Returns null if WebSocket is not configured\n */\nexport function useReactiveClient(): ReactiveClient | null {\n return useContext(ReactiveClientContext);\n}\n\n/**\n * Hook to get the reactive client, throwing if not available\n */\nexport function useReactiveClientOrThrow(): ReactiveClient {\n const client = useContext(ReactiveClientContext);\n if (!client) {\n throw new Error(\n 'useReactiveClientOrThrow must be used within a ReactiveClientProvider with a configured URL',\n );\n }\n return client;\n}\n\n/**\n * Hook to get the connection state\n * Returns 'disabled' if WebSocket is not configured\n */\nexport function useConnectionState(): ConnectionState | 'disabled' {\n const client = useReactiveClient();\n\n return useSyncExternalStore(\n (callback) => {\n if (!client) return () => {};\n return client.onConnectionStateChange(callback);\n },\n () => (client ? client.getConnectionState() : 'disabled'),\n () => 'disabled' as const,\n );\n}\n\n/**\n * Hook for reactive subscriptions\n * Returns disabled state if WebSocket is not configured\n */\nexport function useSubscription<TData>(\n path: string,\n options: SubscriptionOptions<unknown> = {},\n): {\n data: TData | undefined;\n loading: boolean;\n error: Error | undefined;\n disabled: boolean;\n refetch: () => Promise<void>;\n} {\n const client = useReactiveClient();\n const subscriptionRef = useRef<Subscription<TData> | null>(null);\n const [state, setState] = useState<{\n data: TData | undefined;\n loading: boolean;\n error: Error | undefined;\n }>({\n data: undefined,\n loading: !client ? false : true,\n error: undefined,\n });\n\n // Serialize options for dependency comparison\n const inputKey = JSON.stringify(options.input);\n // Store callbacks in refs to avoid re-subscribing when they change\n const onDataRef = useRef(options.onData);\n const onErrorRef = useRef(options.onError);\n onDataRef.current = options.onData;\n onErrorRef.current = options.onError;\n\n useEffect(() => {\n if (!client) return;\n\n // Parse input from inputKey to ensure we use the serialized value\n const input = inputKey ? JSON.parse(inputKey) : undefined;\n\n const subscription = client.subscribe<TData>(path, {\n input,\n onData: (data) => {\n setState((prev) => ({\n ...prev,\n data: data as TData,\n loading: false,\n error: undefined,\n }));\n onDataRef.current?.(data);\n },\n onError: (error) => {\n setState((prev) => ({\n ...prev,\n error,\n loading: false,\n }));\n onErrorRef.current?.(error);\n },\n });\n\n subscriptionRef.current = subscription;\n\n // Register a listener for optimistic updates (notifySubscriptionListeners)\n // This ensures React state updates when optimistic changes happen\n const unregisterListener = client.addSubscriptionListener(\n subscription.id,\n () => {\n // Re-read current state from subscription\n debug(\n '[optimistic] useSubscription listener fired for:',\n path,\n 'data length:',\n Array.isArray(subscription.data)\n ? subscription.data.length\n : 'not array',\n );\n setState({\n data: subscription.data,\n loading: subscription.loading,\n error: subscription.error,\n });\n },\n );\n\n // Update state from subscription\n setState({\n data: subscription.data,\n loading: subscription.loading,\n error: subscription.error,\n });\n\n return () => {\n unregisterListener();\n subscription.unsubscribe();\n subscriptionRef.current = null;\n };\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [client, path, inputKey]);\n\n const refetch = async () => {\n if (subscriptionRef.current) {\n setState((prev) => ({ ...prev, loading: true }));\n await subscriptionRef.current.refetch();\n }\n };\n\n return {\n ...state,\n disabled: !client,\n refetch,\n };\n}\n\n/**\n * Hook for mutations with automatic optimistic updates\n *\n * Auto-detection:\n * - `invalidates`: Auto-detected from path (e.g., 'todos.toggle' -> 'todos.list')\n * - `optimisticUpdate`: Auto-detected from path ('*.delete' -> 'remove', others -> 'merge')\n *\n * You can override these with explicit options.\n */\nexport function useMutation<TInput, TOutput>(\n path: string,\n options?: MutationOptions<TInput, TOutput>,\n): {\n mutate: (input: TInput) => Promise<TOutput>;\n data: TOutput | undefined;\n loading: boolean;\n error: Error | undefined;\n disabled: boolean;\n reset: () => void;\n} {\n const client = useReactiveClient();\n const [state, setState] = useState<{\n data: TOutput | undefined;\n loading: boolean;\n error: Error | undefined;\n }>({\n data: undefined,\n loading: false,\n error: undefined,\n });\n\n // Auto-detect invalidates path from mutation path\n // e.g., 'todos.toggle' -> 'todos.list', 'todos.create' -> 'todos.list'\n const autoInvalidates =\n options?.invalidates ??\n (() => {\n const parts = path.split('.');\n if (parts.length >= 2) {\n return `${parts.slice(0, -1).join('.')}.list`;\n }\n return undefined;\n })();\n\n // Auto-detect update type from path\n // '*.delete' -> 'remove', others -> 'merge'\n const autoUpdateType =\n options?.optimisticUpdate ??\n (path.endsWith('.delete') ? 'remove' : 'merge');\n\n const mutate = async (input: TInput): Promise<TOutput> => {\n if (!client) {\n throw new Error('WebSocket not configured - mutations are disabled');\n }\n\n debug('[optimistic] useMutation.mutate called:', {\n path,\n autoInvalidates,\n autoUpdateType,\n input,\n });\n\n setState((prev) => ({ ...prev, loading: true, error: undefined }));\n\n try {\n const result = await client.call<TInput, TOutput>(path, input, {\n invalidates: autoInvalidates,\n optimisticUpdate: autoUpdateType,\n });\n setState({ data: result, loading: false, error: undefined });\n return result;\n } catch (error) {\n const err = error instanceof Error ? error : new Error(String(error));\n setState((prev) => ({ ...prev, loading: false, error: err }));\n throw err;\n }\n };\n\n const reset = () => {\n setState({ data: undefined, loading: false, error: undefined });\n };\n\n return {\n mutate,\n ...state,\n disabled: !client,\n reset,\n };\n}\n\n/**\n * Type helper for extracting procedure input type from ProcedureDefinition\n * Uses Zod's internal _output property to extract the parsed type\n * (Zod schemas have _input/_output as actual properties for type inference)\n */\ntype ProcedureInput<T> = T extends { inputSchema?: { _output: infer I } }\n ? I\n : undefined;\n\n/**\n * Type helper for extracting procedure output type from ProcedureDefinition\n * Extracts from resolver return type using any[] for flexible argument matching\n */\ntype ProcedureOutput<T> = T extends {\n resolver: (...args: any[]) => infer TReturn; // eslint-disable-line @typescript-eslint/no-explicit-any -- contravariance requires `any`\n}\n ? Awaited<TReturn>\n : unknown;\n\n/**\n * Typed client hooks for a router procedure\n * Provides both useQuery and useMutation - use whichever matches your procedure type\n */\ntype TypedProcedureHooks<TInput, TOutput> = {\n useQuery: (\n input: TInput,\n options?: Omit<SubscriptionOptions<TInput>, 'input'>,\n ) => {\n data: TOutput | undefined;\n loading: boolean;\n error: Error | undefined;\n disabled: boolean;\n refetch: () => Promise<void>;\n };\n useMutation: (options?: MutationOptions<TInput, TOutput>) => {\n mutate: (input: TInput) => Promise<TOutput>;\n data: TOutput | undefined;\n loading: boolean;\n error: Error | undefined;\n disabled: boolean;\n reset: () => void;\n };\n};\n\n/**\n * Extract router definition from Router class or use T directly\n */\ntype ExtractRouterDefinition<T> = T extends { definition: infer TDef }\n ? TDef\n : T;\n\n/**\n * Recursive type for typed client proxy\n * Checks for 'resolver' property to identify procedures (all procedures have it)\n */\ntype TypedClientProxyRecursive<T> = T extends { resolver: unknown }\n ? TypedProcedureHooks<ProcedureInput<T>, ProcedureOutput<T>>\n : { [K in keyof T]: TypedClientProxyRecursive<T[K]> };\n\n/**\n * Client utilities available at the root level\n */\ninterface ClientUtilities {\n /**\n * Set custom headers to be sent with HTTP requests.\n * Useful for auth context (e.g., user tokens, session info).\n */\n setHeaders: (\n headers:\n | Record<string, string>\n | (() => Record<string, string> | Promise<Record<string, string>>),\n ) => void;\n}\n\n/**\n * Typed client proxy combining router procedures and client utilities\n */\ntype TypedClientProxy<T> = TypedClientProxyRecursive<\n ExtractRouterDefinition<T>\n> &\n ClientUtilities;\n\n/**\n * Create a typed client proxy for use in React components.\n *\n * @example\n * ```tsx\n * const client = useClient<AppRouter>();\n *\n * // Queries (subscriptions)\n * const { data, loading } = client.todos.list.useQuery({});\n *\n * // Mutations\n * const { mutate, loading } = client.todos.toggle.useMutation();\n * await mutate({ id: '123' });\n *\n * // Set custom headers for HTTP requests (e.g., for auth context)\n * client.setHeaders({ 'Authorization': 'Bearer token' });\n * ```\n */\nexport function useClient<TRouter>(): TypedClientProxy<TRouter> {\n const client = useReactiveClient();\n\n function buildProxy(path: string[]): unknown {\n return new Proxy(\n {},\n {\n get(_target, prop: string) {\n if (prop === 'useQuery') {\n // Return a hook function for subscriptions\n return function useQueryHook(\n input?: unknown,\n options?: SubscriptionOptions<unknown>,\n ) {\n const pathStr = path.join('.');\n // eslint-disable-next-line react-hooks/rules-of-hooks\n return useSubscription(pathStr, { ...options, input });\n };\n }\n\n if (prop === 'useMutation') {\n // Return a hook function for mutations\n return function useMutationHook(\n options?: MutationOptions<unknown, unknown>,\n ) {\n const pathStr = path.join('.');\n // eslint-disable-next-line react-hooks/rules-of-hooks\n return useMutation(pathStr, options);\n };\n }\n\n // Expose setHeaders from the underlying client\n if (prop === 'setHeaders') {\n return (\n headers:\n | Record<string, string>\n | (() =>\n | Record<string, string>\n | Promise<Record<string, string>>),\n ) => {\n client?.setHeaders(headers);\n };\n }\n\n return buildProxy([...path, prop]);\n },\n },\n );\n }\n\n return buildProxy([]) as TypedClientProxy<TRouter>;\n}\n\n/**\n * @deprecated Use useClient<TRouter>() instead for typed proxy access\n */\nexport function createReactiveHooks() {\n return {\n useSubscription: <TPath extends string, TData = unknown>(\n path: TPath,\n options?: SubscriptionOptions<unknown>,\n ) => useSubscription<TData>(path, options),\n\n useMutation: <TPath extends string, TInput = unknown, TOutput = unknown>(\n path: TPath,\n options?: MutationOptions<TInput, TOutput>,\n ) => useMutation<TInput, TOutput>(path, options),\n\n useConnectionState,\n useReactiveClient,\n };\n}\n\n/**\n * @deprecated Use useClient<TRouter>() instead for typed proxy access\n */\nexport function createProcedureHooks<TInput, TOutput>(path: string) {\n return {\n useSubscription: (\n input?: TInput,\n options?: Omit<SubscriptionOptions<TInput>, 'input'>,\n ) => useSubscription<TOutput>(path, { ...options, input }),\n\n useMutation: (options?: MutationOptions<TInput, TOutput>) =>\n useMutation<TInput, TOutput>(path, options),\n };\n}\n"]}