state-surgeon 1.0.0

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.
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../src/core/diff.ts","../../src/core/mutation.ts","../../src/instrument/transport.ts","../../src/instrument/client.ts","../../src/instrument/api.ts","../../src/instrument/react.ts","../../src/instrument/redux.ts","../../src/instrument/zustand.ts"],"names":["uuidv4"],"mappings":"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","file":"index.mjs","sourcesContent":["import type { StateDiff } from './mutation';\n\n/**\n * Deep clones an object\n */\nexport function deepClone<T>(obj: T): T {\n if (obj === null || typeof obj !== 'object') {\n return obj;\n }\n\n if (Array.isArray(obj)) {\n return obj.map(item => deepClone(item)) as unknown as T;\n }\n\n if (obj instanceof Date) {\n return new Date(obj.getTime()) as unknown as T;\n }\n\n if (obj instanceof Map) {\n const clonedMap = new Map();\n obj.forEach((value, key) => {\n clonedMap.set(deepClone(key), deepClone(value));\n });\n return clonedMap as unknown as T;\n }\n\n if (obj instanceof Set) {\n const clonedSet = new Set();\n obj.forEach(value => {\n clonedSet.add(deepClone(value));\n });\n return clonedSet as unknown as T;\n }\n\n const cloned: Record<string, unknown> = {};\n for (const key in obj) {\n if (Object.prototype.hasOwnProperty.call(obj, key)) {\n cloned[key] = deepClone((obj as Record<string, unknown>)[key]);\n }\n }\n\n return cloned as T;\n}\n\n/**\n * Calculates the difference between two objects\n */\nexport function calculateDiff(before: unknown, after: unknown, path: string = ''): StateDiff[] {\n const diffs: StateDiff[] = [];\n\n // Handle primitives and null\n if (before === after) {\n return diffs;\n }\n\n if (before === null || before === undefined || typeof before !== 'object') {\n if (after === null || after === undefined || typeof after !== 'object') {\n // Both are primitives\n if (before !== after) {\n if (before === undefined) {\n diffs.push({ path: path || 'root', operation: 'ADD', newValue: after });\n } else if (after === undefined) {\n diffs.push({ path: path || 'root', operation: 'REMOVE', oldValue: before });\n } else {\n diffs.push({ path: path || 'root', operation: 'UPDATE', oldValue: before, newValue: after });\n }\n }\n return diffs;\n }\n // before is primitive, after is object\n diffs.push({ path: path || 'root', operation: 'UPDATE', oldValue: before, newValue: after });\n return diffs;\n }\n\n if (after === null || after === undefined || typeof after !== 'object') {\n // before is object, after is primitive\n diffs.push({ path: path || 'root', operation: 'UPDATE', oldValue: before, newValue: after });\n return diffs;\n }\n\n // Handle arrays\n if (Array.isArray(before) || Array.isArray(after)) {\n if (!Array.isArray(before) || !Array.isArray(after)) {\n diffs.push({ path: path || 'root', operation: 'UPDATE', oldValue: before, newValue: after });\n return diffs;\n }\n\n const maxLength = Math.max(before.length, after.length);\n for (let i = 0; i < maxLength; i++) {\n const itemPath = path ? `${path}[${i}]` : `[${i}]`;\n if (i >= before.length) {\n diffs.push({ path: itemPath, operation: 'ADD', newValue: after[i] });\n } else if (i >= after.length) {\n diffs.push({ path: itemPath, operation: 'REMOVE', oldValue: before[i] });\n } else {\n diffs.push(...calculateDiff(before[i], after[i], itemPath));\n }\n }\n return diffs;\n }\n\n // Handle objects\n const beforeObj = before as Record<string, unknown>;\n const afterObj = after as Record<string, unknown>;\n const allKeys = new Set([...Object.keys(beforeObj), ...Object.keys(afterObj)]);\n\n for (const key of allKeys) {\n const keyPath = path ? `${path}.${key}` : key;\n const beforeValue = beforeObj[key];\n const afterValue = afterObj[key];\n\n if (!(key in beforeObj)) {\n diffs.push({ path: keyPath, operation: 'ADD', newValue: afterValue });\n } else if (!(key in afterObj)) {\n diffs.push({ path: keyPath, operation: 'REMOVE', oldValue: beforeValue });\n } else {\n diffs.push(...calculateDiff(beforeValue, afterValue, keyPath));\n }\n }\n\n return diffs;\n}\n\n/**\n * Applies a diff to a state object\n */\nexport function applyDiff<T>(state: T, diffs: StateDiff[]): T {\n const result = deepClone(state);\n\n for (const diff of diffs) {\n setValueAtPath(result, diff.path, diff.operation === 'REMOVE' ? undefined : diff.newValue);\n }\n\n return result;\n}\n\n/**\n * Gets a value at a path in an object\n */\nexport function getValueAtPath(obj: unknown, path: string): unknown {\n if (!path || path === 'root') return obj;\n\n const parts = parsePath(path);\n let current: unknown = obj;\n\n for (const part of parts) {\n if (current === null || current === undefined) {\n return undefined;\n }\n current = (current as Record<string, unknown>)[part];\n }\n\n return current;\n}\n\n/**\n * Sets a value at a path in an object\n */\nexport function setValueAtPath(obj: unknown, path: string, value: unknown): void {\n if (!path || path === 'root') return;\n\n const parts = parsePath(path);\n let current = obj as Record<string, unknown>;\n\n for (let i = 0; i < parts.length - 1; i++) {\n const part = parts[i];\n if (current[part] === undefined) {\n // Create intermediate object or array based on next part\n const nextPart = parts[i + 1];\n current[part] = /^\\d+$/.test(nextPart) ? [] : {};\n }\n current = current[part] as Record<string, unknown>;\n }\n\n const lastPart = parts[parts.length - 1];\n if (value === undefined) {\n delete current[lastPart];\n } else {\n current[lastPart] = value;\n }\n}\n\n/**\n * Parses a path string into parts\n */\nfunction parsePath(path: string): string[] {\n const parts: string[] = [];\n let current = '';\n let inBracket = false;\n\n for (const char of path) {\n if (char === '.' && !inBracket) {\n if (current) parts.push(current);\n current = '';\n } else if (char === '[') {\n if (current) parts.push(current);\n current = '';\n inBracket = true;\n } else if (char === ']') {\n if (current) parts.push(current);\n current = '';\n inBracket = false;\n } else {\n current += char;\n }\n }\n\n if (current) parts.push(current);\n return parts;\n}\n\n/**\n * Checks if two values are deeply equal\n */\nexport function deepEqual(a: unknown, b: unknown): boolean {\n if (a === b) return true;\n\n if (typeof a !== typeof b) return false;\n\n if (a === null || b === null) return a === b;\n\n if (typeof a !== 'object') return a === b;\n\n if (Array.isArray(a) !== Array.isArray(b)) return false;\n\n if (Array.isArray(a) && Array.isArray(b)) {\n if (a.length !== b.length) return false;\n return a.every((item, index) => deepEqual(item, b[index]));\n }\n\n const aObj = a as Record<string, unknown>;\n const bObj = b as Record<string, unknown>;\n const aKeys = Object.keys(aObj);\n const bKeys = Object.keys(bObj);\n\n if (aKeys.length !== bKeys.length) return false;\n\n return aKeys.every(key => deepEqual(aObj[key], bObj[key]));\n}\n","import { v4 as uuidv4 } from 'uuid';\n\n/**\n * Source of the state mutation\n */\nexport type MutationSource = 'react' | 'redux' | 'zustand' | 'express' | 'websocket' | 'api' | 'custom';\n\n/**\n * Type of action that triggered the mutation\n */\nexport type ActionType = 'USER_CLICK' | 'API_RESPONSE' | 'TIMEOUT' | 'WEBHOOK' | 'INIT' | 'DISPATCH' | 'SET_STATE' | 'CUSTOM';\n\n/**\n * Represents a single state mutation captured by State Surgeon\n */\nexport interface Mutation {\n /** Unique identifier for this mutation */\n id: string;\n\n /** High-resolution timestamp (performance.now() or Date.now()) */\n timestamp: number;\n\n /** Lamport timestamp for causal ordering */\n logicalClock: number;\n\n /** Session this mutation belongs to */\n sessionId: string;\n\n /** Source of the mutation */\n source: MutationSource;\n\n /** Component or module name */\n component?: string;\n\n /** Function name that triggered the mutation */\n function?: string;\n\n /** Source file path */\n file?: string;\n\n /** Line number in source file */\n line?: number;\n\n /** Column number in source file */\n column?: number;\n\n /** Type of action that triggered this mutation */\n actionType: ActionType;\n\n /** Action payload (for Redux actions, etc.) */\n actionPayload?: unknown;\n\n /** State before the mutation */\n previousState: unknown;\n\n /** State after the mutation */\n nextState: unknown;\n\n /** Computed diff between states */\n diff?: StateDiff[];\n\n /** Call stack at time of mutation */\n callStack?: string[];\n\n /** Request ID for correlating with backend */\n requestId?: string;\n\n /** Duration of the mutation in milliseconds */\n duration?: number;\n\n /** Parent mutation ID for causal chains */\n parentMutationId?: string;\n\n /** IDs of events that caused this mutation */\n causes?: string[];\n\n /** Custom metadata */\n metadata?: Record<string, unknown>;\n}\n\n/**\n * Represents a single change in state\n */\nexport interface StateDiff {\n /** JSON path to the changed value */\n path: string;\n\n /** Type of change */\n operation: 'ADD' | 'UPDATE' | 'REMOVE';\n\n /** Previous value (for UPDATE and REMOVE) */\n oldValue?: unknown;\n\n /** New value (for ADD and UPDATE) */\n newValue?: unknown;\n}\n\n/**\n * Options for creating a mutation\n */\nexport interface CreateMutationOptions {\n source: MutationSource;\n sessionId: string;\n previousState: unknown;\n nextState: unknown;\n actionType?: ActionType;\n actionPayload?: unknown;\n component?: string;\n function?: string;\n captureStack?: boolean;\n metadata?: Record<string, unknown>;\n}\n\n// Global logical clock for this client\nlet logicalClock = 0;\n\n/**\n * Creates a new mutation record\n */\nexport function createMutation(options: CreateMutationOptions): Mutation {\n const {\n source,\n sessionId,\n previousState,\n nextState,\n actionType = 'CUSTOM',\n actionPayload,\n component,\n function: funcName,\n captureStack = true,\n metadata,\n } = options;\n\n logicalClock++;\n\n const mutation: Mutation = {\n id: `mut_${Date.now()}_${uuidv4().slice(0, 8)}`,\n timestamp: typeof performance !== 'undefined' ? performance.now() : Date.now(),\n logicalClock,\n sessionId,\n source,\n component,\n function: funcName,\n actionType,\n actionPayload,\n previousState,\n nextState,\n metadata,\n };\n\n // Capture call stack if enabled\n if (captureStack) {\n mutation.callStack = parseCallStack(new Error().stack);\n }\n\n return mutation;\n}\n\n/**\n * Parses an error stack trace into clean function names\n */\nexport function parseCallStack(stack?: string): string[] {\n if (!stack) return [];\n\n return stack\n .split('\\n')\n .slice(2) // Skip 'Error' and 'createMutation' lines\n .map(line => line.trim())\n .filter(line => line.startsWith('at '))\n .map(line => {\n // Extract function name and location\n const match = line.match(/at\\s+(.+?)\\s+\\((.+):(\\d+):(\\d+)\\)/);\n if (match) {\n return `${match[1]} (${match[2].split('/').pop()}:${match[3]})`;\n }\n // Anonymous function or simpler format\n const simpleMatch = line.match(/at\\s+(.+):(\\d+):(\\d+)/);\n if (simpleMatch) {\n return `anonymous (${simpleMatch[1].split('/').pop()}:${simpleMatch[2]})`;\n }\n return line.replace('at ', '');\n })\n .slice(0, 10); // Limit stack depth\n}\n\n/**\n * Gets the current logical clock value\n */\nexport function getLogicalClock(): number {\n return logicalClock;\n}\n\n/**\n * Resets the logical clock (for testing)\n */\nexport function resetLogicalClock(): void {\n logicalClock = 0;\n}\n\n/**\n * Generates a new session ID\n */\nexport function generateSessionId(): string {\n return `session_${Date.now()}_${uuidv4().slice(0, 8)}`;\n}\n","/**\n * WebSocket transport for sending mutations to the recorder\n */\n\nexport interface TransportMessage {\n type: string;\n payload: unknown;\n}\n\nexport interface TransportOptions {\n /** Maximum mutations to batch before sending */\n batchSize?: number;\n\n /** Interval in ms to flush batched mutations */\n flushInterval?: number;\n\n /** Reconnection delay in ms */\n reconnectDelay?: number;\n\n /** Maximum reconnection attempts */\n maxReconnectAttempts?: number;\n\n /** Callback when connected */\n onConnect?: () => void;\n\n /** Callback when disconnected */\n onDisconnect?: () => void;\n\n /** Callback on error */\n onError?: (error: Error) => void;\n\n /** Callback for received messages */\n onMessage?: (message: TransportMessage) => void;\n}\n\n/**\n * WebSocket transport layer for State Surgeon\n */\nexport class MutationTransport {\n private url: string;\n private options: Required<TransportOptions>;\n private ws: WebSocket | null = null;\n private buffer: TransportMessage[] = [];\n private flushTimer: ReturnType<typeof setInterval> | null = null;\n private reconnectAttempts = 0;\n private isConnecting = false;\n private shouldReconnect = true;\n\n constructor(url: string, options: TransportOptions = {}) {\n this.url = url;\n this.options = {\n batchSize: options.batchSize ?? 50,\n flushInterval: options.flushInterval ?? 100,\n reconnectDelay: options.reconnectDelay ?? 1000,\n maxReconnectAttempts: options.maxReconnectAttempts ?? 10,\n onConnect: options.onConnect ?? (() => {}),\n onDisconnect: options.onDisconnect ?? (() => {}),\n onError: options.onError ?? (() => {}),\n onMessage: options.onMessage ?? (() => {}),\n };\n }\n\n /**\n * Establishes WebSocket connection\n */\n connect(): void {\n if (this.ws || this.isConnecting) {\n return;\n }\n\n this.isConnecting = true;\n this.shouldReconnect = true;\n\n try {\n // Use WebSocket from global scope (browser) or ws package (Node.js)\n const WebSocketImpl = typeof WebSocket !== 'undefined'\n ? WebSocket\n : require('ws');\n\n this.ws = new WebSocketImpl(this.url);\n\n this.ws.onopen = () => {\n this.isConnecting = false;\n this.reconnectAttempts = 0;\n this.startFlushTimer();\n this.options.onConnect();\n };\n\n this.ws.onclose = () => {\n this.isConnecting = false;\n this.stopFlushTimer();\n this.ws = null;\n this.options.onDisconnect();\n this.attemptReconnect();\n };\n\n this.ws.onerror = (event: Event) => {\n this.isConnecting = false;\n const error = new Error('WebSocket error');\n this.options.onError(error);\n };\n\n this.ws.onmessage = (event: MessageEvent) => {\n try {\n const message = JSON.parse(event.data) as TransportMessage;\n this.options.onMessage(message);\n } catch (e) {\n // Ignore parse errors\n }\n };\n } catch (error) {\n this.isConnecting = false;\n this.options.onError(error instanceof Error ? error : new Error(String(error)));\n this.attemptReconnect();\n }\n }\n\n /**\n * Closes the WebSocket connection\n */\n disconnect(): void {\n this.shouldReconnect = false;\n this.stopFlushTimer();\n\n if (this.ws) {\n this.ws.close();\n this.ws = null;\n }\n }\n\n /**\n * Sends a message (adds to buffer)\n */\n send(message: TransportMessage): void {\n this.buffer.push(message);\n\n if (this.buffer.length >= this.options.batchSize) {\n this.flush();\n }\n }\n\n /**\n * Flushes the buffer immediately\n */\n flush(): void {\n if (this.buffer.length === 0) {\n return;\n }\n\n if (this.ws && this.ws.readyState === 1) { // WebSocket.OPEN = 1\n try {\n // Send as batch\n const batch = {\n type: 'MUTATION_BATCH',\n payload: {\n mutations: this.buffer.map(m => m.payload),\n timestamp: Date.now(),\n },\n };\n\n this.ws.send(JSON.stringify(batch));\n this.buffer = [];\n } catch (error) {\n this.options.onError(\n error instanceof Error ? error : new Error(String(error))\n );\n }\n }\n }\n\n /**\n * Checks if transport is connected\n */\n isConnected(): boolean {\n return this.ws !== null && this.ws.readyState === 1;\n }\n\n /**\n * Gets the current buffer size\n */\n getBufferSize(): number {\n return this.buffer.length;\n }\n\n private startFlushTimer(): void {\n if (this.flushTimer) {\n clearInterval(this.flushTimer);\n }\n\n this.flushTimer = setInterval(() => {\n this.flush();\n }, this.options.flushInterval);\n }\n\n private stopFlushTimer(): void {\n if (this.flushTimer) {\n clearInterval(this.flushTimer);\n this.flushTimer = null;\n }\n }\n\n private attemptReconnect(): void {\n if (!this.shouldReconnect) {\n return;\n }\n\n if (this.reconnectAttempts >= this.options.maxReconnectAttempts) {\n this.options.onError(new Error('Max reconnection attempts reached'));\n return;\n }\n\n this.reconnectAttempts++;\n const delay = this.options.reconnectDelay * Math.pow(1.5, this.reconnectAttempts - 1);\n\n setTimeout(() => {\n if (this.shouldReconnect) {\n this.connect();\n }\n }, Math.min(delay, 30000)); // Cap at 30 seconds\n }\n}\n","import { calculateDiff, deepClone } from '../core/diff';\nimport { createMutation, generateSessionId, type Mutation } from '../core/mutation';\nimport { MutationTransport, type TransportOptions } from './transport';\n\n/**\n * Options for the State Surgeon client\n */\nexport interface ClientOptions {\n /** Server URL for the recorder (default: 'ws://localhost:8081') */\n serverUrl?: string;\n\n /** Application ID for grouping sessions */\n appId?: string;\n\n /** Session ID (auto-generated if not provided) */\n sessionId?: string;\n\n /** Enable automatic connection on creation */\n autoConnect?: boolean;\n\n /** Batch size before flushing mutations */\n batchSize?: number;\n\n /** Flush interval in milliseconds */\n flushInterval?: number;\n\n /** Enable console logging for debugging */\n debug?: boolean;\n\n /** Transport options */\n transport?: TransportOptions;\n}\n\n/**\n * Mutation listener callback\n */\nexport type MutationListener = (mutation: Mutation) => void;\n\n/**\n * Main client for State Surgeon\n * Manages the connection to the recorder and handles mutation recording\n */\nexport class StateSurgeonClient {\n private sessionId: string;\n private appId: string;\n private transport: MutationTransport | null = null;\n private listeners: Set<MutationListener> = new Set();\n private isConnected = false;\n private debug: boolean;\n private serverUrl: string;\n private transportOptions: TransportOptions;\n\n // Track mutations locally for offline support\n private localMutations: Mutation[] = [];\n private maxLocalMutations = 10000;\n\n constructor(options: ClientOptions = {}) {\n this.sessionId = options.sessionId || generateSessionId();\n this.appId = options.appId || 'default';\n this.debug = options.debug || false;\n this.serverUrl = options.serverUrl || 'ws://localhost:8081';\n this.transportOptions = {\n batchSize: options.batchSize || 50,\n flushInterval: options.flushInterval || 100,\n ...options.transport,\n };\n\n if (options.autoConnect !== false) {\n this.connect();\n }\n\n this.log('State Surgeon Client initialized', { sessionId: this.sessionId, appId: this.appId });\n }\n\n /**\n * Connects to the recorder server\n */\n connect(): void {\n if (this.transport) {\n return;\n }\n\n this.transport = new MutationTransport(this.serverUrl, {\n ...this.transportOptions,\n onConnect: () => {\n this.isConnected = true;\n this.log('Connected to State Surgeon recorder');\n this.sendHandshake();\n },\n onDisconnect: () => {\n this.isConnected = false;\n this.log('Disconnected from State Surgeon recorder');\n },\n onError: (error) => {\n this.log('Transport error:', error);\n },\n });\n\n this.transport.connect();\n }\n\n /**\n * Disconnects from the recorder server\n */\n disconnect(): void {\n if (this.transport) {\n this.transport.disconnect();\n this.transport = null;\n }\n this.isConnected = false;\n }\n\n /**\n * Sends the initial handshake to register the session\n */\n private sendHandshake(): void {\n if (this.transport) {\n this.transport.send({\n type: 'REGISTER_SESSION',\n payload: {\n appId: this.appId,\n sessionId: this.sessionId,\n timestamp: Date.now(),\n userAgent: typeof navigator !== 'undefined' ? navigator.userAgent : 'node',\n url: typeof window !== 'undefined' ? window.location.href : undefined,\n },\n });\n }\n }\n\n /**\n * Records a mutation\n */\n recordMutation(mutation: Mutation): void {\n // Add to local storage\n this.localMutations.push(mutation);\n if (this.localMutations.length > this.maxLocalMutations) {\n this.localMutations.shift();\n }\n\n // Notify listeners\n for (const listener of this.listeners) {\n try {\n listener(mutation);\n } catch (error) {\n this.log('Listener error:', error);\n }\n }\n\n // Send to server\n if (this.transport && this.isConnected) {\n this.transport.send({\n type: 'MUTATION_RECORDED',\n payload: mutation,\n });\n }\n\n this.log('Mutation recorded:', mutation.id, mutation.source);\n }\n\n /**\n * Creates and records a mutation from state change\n */\n captureStateChange(\n source: Mutation['source'],\n previousState: unknown,\n nextState: unknown,\n options: {\n actionType?: Mutation['actionType'];\n actionPayload?: unknown;\n component?: string;\n function?: string;\n } = {}\n ): Mutation {\n const mutation = createMutation({\n source,\n sessionId: this.sessionId,\n previousState: deepClone(previousState),\n nextState: deepClone(nextState),\n actionType: options.actionType || 'CUSTOM',\n actionPayload: options.actionPayload,\n component: options.component,\n function: options.function,\n captureStack: true,\n });\n\n // Calculate diff\n mutation.diff = calculateDiff(mutation.previousState, mutation.nextState);\n\n this.recordMutation(mutation);\n return mutation;\n }\n\n /**\n * Adds a mutation listener\n */\n addListener(listener: MutationListener): () => void {\n this.listeners.add(listener);\n return () => this.listeners.delete(listener);\n }\n\n /**\n * Gets the current session ID\n */\n getSessionId(): string {\n return this.sessionId;\n }\n\n /**\n * Gets all local mutations\n */\n getMutations(): Mutation[] {\n return [...this.localMutations];\n }\n\n /**\n * Clears local mutations\n */\n clearMutations(): void {\n this.localMutations = [];\n }\n\n /**\n * Checks if connected to server\n */\n isServerConnected(): boolean {\n return this.isConnected;\n }\n\n /**\n * Flushes any pending mutations\n */\n flush(): void {\n if (this.transport) {\n this.transport.flush();\n }\n }\n\n private log(...args: unknown[]): void {\n if (this.debug) {\n console.log('[State Surgeon]', ...args);\n }\n }\n}\n\n// Global client instance for convenience\nlet globalClient: StateSurgeonClient | null = null;\n\n/**\n * Gets or creates the global State Surgeon client\n */\nexport function getClient(options?: ClientOptions): StateSurgeonClient {\n if (!globalClient) {\n globalClient = new StateSurgeonClient(options);\n }\n return globalClient;\n}\n\n/**\n * Sets the global client instance\n */\nexport function setClient(client: StateSurgeonClient): void {\n globalClient = client;\n}\n\n/**\n * Resets the global client (for testing)\n */\nexport function resetClient(): void {\n if (globalClient) {\n globalClient.disconnect();\n globalClient = null;\n }\n}\n","import { getClient, type StateSurgeonClient } from './client';\n\n/**\n * Options for API instrumentation\n */\nexport interface APIInstrumentationOptions {\n /** State Surgeon client (uses global if not provided) */\n client?: StateSurgeonClient;\n\n /** URLs to ignore (substring match) */\n ignoreUrls?: string[];\n\n /** Whether to capture request bodies */\n captureRequestBody?: boolean;\n\n /** Whether to capture response bodies */\n captureResponseBody?: boolean;\n\n /** Maximum body size to capture (in characters) */\n maxBodySize?: number;\n}\n\n// Store original fetch\nlet originalFetch: typeof fetch | null = null;\nlet fetchInstrumented = false;\n\n// Store original XMLHttpRequest methods\nlet originalXHROpen: typeof XMLHttpRequest.prototype.open | null = null;\nlet originalXHRSend: typeof XMLHttpRequest.prototype.send | null = null;\nlet xhrInstrumented = false;\n\n/**\n * Instruments the global fetch function to track API calls\n *\n * @example\n * ```tsx\n * import { instrumentFetch } from 'state-surgeon/instrument';\n *\n * const cleanup = instrumentFetch({\n * captureResponseBody: true,\n * ignoreUrls: ['/health', '/metrics'],\n * });\n * ```\n */\nexport function instrumentFetch(options: APIInstrumentationOptions = {}): () => void {\n if (fetchInstrumented) {\n console.warn('[State Surgeon] Fetch already instrumented');\n return () => {};\n }\n\n if (typeof fetch === 'undefined') {\n console.warn('[State Surgeon] Fetch not available in this environment');\n return () => {};\n }\n\n const client = options.client || getClient();\n const ignoreUrls = options.ignoreUrls || [];\n const captureRequestBody = options.captureRequestBody !== false;\n const captureResponseBody = options.captureResponseBody !== false;\n const maxBodySize = options.maxBodySize || 10000;\n\n originalFetch = fetch;\n\n (globalThis as any).fetch = async function instrumentedFetch(\n input: RequestInfo | URL,\n init?: RequestInit\n ): Promise<Response> {\n const url = typeof input === 'string' ? input : input instanceof URL ? input.href : input.url;\n\n // Check if URL should be ignored\n if (ignoreUrls.some(ignore => url.includes(ignore))) {\n return originalFetch!(input, init);\n }\n\n const startTime = Date.now();\n const requestId = `req_${startTime}_${Math.random().toString(36).slice(2, 8)}`;\n\n // Capture request info\n const requestInfo: Record<string, unknown> = {\n url,\n method: init?.method || 'GET',\n headers: init?.headers,\n };\n\n if (captureRequestBody && init?.body) {\n requestInfo.body = truncateBody(init.body, maxBodySize);\n }\n\n try {\n const response = await originalFetch!(input, init);\n const duration = Date.now() - startTime;\n\n // Clone response to read body without consuming it\n const clonedResponse = response.clone();\n\n // Capture response info\n const responseInfo: Record<string, unknown> = {\n status: response.status,\n statusText: response.statusText,\n headers: Object.fromEntries(response.headers.entries()),\n };\n\n if (captureResponseBody) {\n try {\n const text = await clonedResponse.text();\n responseInfo.body = truncateBody(text, maxBodySize);\n } catch {\n responseInfo.body = '[Unable to read response body]';\n }\n }\n\n // Record mutation\n client.captureStateChange('api', requestInfo, responseInfo, {\n actionType: 'API_RESPONSE',\n actionPayload: {\n requestId,\n url,\n method: requestInfo.method,\n status: response.status,\n duration,\n },\n function: 'fetch',\n });\n\n return response;\n } catch (error) {\n const duration = Date.now() - startTime;\n\n // Record error\n client.captureStateChange('api', requestInfo, {\n error: error instanceof Error ? error.message : String(error),\n stack: error instanceof Error ? error.stack : undefined,\n }, {\n actionType: 'API_RESPONSE',\n actionPayload: {\n requestId,\n url,\n method: requestInfo.method,\n status: 0,\n error: true,\n duration,\n },\n function: 'fetch',\n });\n\n throw error;\n }\n };\n\n fetchInstrumented = true;\n\n return () => {\n if (originalFetch) {\n (globalThis as any).fetch = originalFetch;\n originalFetch = null;\n }\n fetchInstrumented = false;\n };\n}\n\n/**\n * Instruments XMLHttpRequest to track AJAX calls\n *\n * @example\n * ```tsx\n * import { instrumentXHR } from 'state-surgeon/instrument';\n *\n * const cleanup = instrumentXHR();\n * ```\n */\nexport function instrumentXHR(options: APIInstrumentationOptions = {}): () => void {\n if (xhrInstrumented) {\n console.warn('[State Surgeon] XHR already instrumented');\n return () => {};\n }\n\n if (typeof XMLHttpRequest === 'undefined') {\n console.warn('[State Surgeon] XMLHttpRequest not available in this environment');\n return () => {};\n }\n\n const client = options.client || getClient();\n const ignoreUrls = options.ignoreUrls || [];\n const captureResponseBody = options.captureResponseBody !== false;\n const maxBodySize = options.maxBodySize || 10000;\n\n originalXHROpen = XMLHttpRequest.prototype.open;\n originalXHRSend = XMLHttpRequest.prototype.send;\n\n XMLHttpRequest.prototype.open = function (\n method: string,\n url: string | URL,\n async: boolean = true,\n username?: string | null,\n password?: string | null\n ) {\n (this as any)._stateSurgeon = {\n method,\n url: url.toString(),\n startTime: 0,\n };\n\n return originalXHROpen!.call(this, method, url, async, username, password);\n };\n\n XMLHttpRequest.prototype.send = function (body?: Document | XMLHttpRequestBodyInit | null) {\n const info = (this as any)._stateSurgeon;\n\n if (!info || ignoreUrls.some(ignore => info.url.includes(ignore))) {\n return originalXHRSend!.call(this, body);\n }\n\n info.startTime = Date.now();\n const requestId = `xhr_${info.startTime}_${Math.random().toString(36).slice(2, 8)}`;\n\n const requestInfo: Record<string, unknown> = {\n url: info.url,\n method: info.method,\n };\n\n this.addEventListener('loadend', () => {\n const duration = Date.now() - info.startTime;\n\n const responseInfo: Record<string, unknown> = {\n status: this.status,\n statusText: this.statusText,\n };\n\n if (captureResponseBody && this.responseText) {\n responseInfo.body = truncateBody(this.responseText, maxBodySize);\n }\n\n client.captureStateChange('api', requestInfo, responseInfo, {\n actionType: 'API_RESPONSE',\n actionPayload: {\n requestId,\n url: info.url,\n method: info.method,\n status: this.status,\n duration,\n },\n function: 'XMLHttpRequest',\n });\n });\n\n return originalXHRSend!.call(this, body);\n };\n\n xhrInstrumented = true;\n\n return () => {\n if (originalXHROpen) {\n XMLHttpRequest.prototype.open = originalXHROpen;\n originalXHROpen = null;\n }\n if (originalXHRSend) {\n XMLHttpRequest.prototype.send = originalXHRSend;\n originalXHRSend = null;\n }\n xhrInstrumented = false;\n };\n}\n\n/**\n * Truncates body data to maximum size\n */\nfunction truncateBody(body: unknown, maxSize: number): string {\n let str: string;\n\n if (typeof body === 'string') {\n str = body;\n } else if (body instanceof FormData) {\n str = '[FormData]';\n } else if (body instanceof Blob) {\n str = `[Blob: ${body.size} bytes]`;\n } else if (body instanceof ArrayBuffer) {\n str = `[ArrayBuffer: ${body.byteLength} bytes]`;\n } else {\n try {\n str = JSON.stringify(body);\n } catch {\n str = String(body);\n }\n }\n\n if (str.length > maxSize) {\n return str.slice(0, maxSize) + '... [truncated]';\n }\n\n return str;\n}\n","import { deepClone } from '../core/diff';\nimport { getClient, type StateSurgeonClient } from './client';\n\n/**\n * Options for React instrumentation\n */\nexport interface ReactInstrumentationOptions {\n /** State Surgeon client (uses global if not provided) */\n client?: StateSurgeonClient;\n\n /** Whether to capture component name from stack trace */\n captureComponentName?: boolean;\n\n /** Custom name for this instrumentation */\n name?: string;\n}\n\n// Store original React methods\nlet originalUseState: typeof import('react').useState | null = null;\nlet originalUseReducer: typeof import('react').useReducer | null = null;\nlet isInstrumented = false;\n\n/**\n * Instruments React hooks to capture state mutations\n *\n * @example\n * ```tsx\n * import React from 'react';\n * import { instrumentReact } from 'state-surgeon/instrument';\n *\n * // Call once at app initialization\n * const cleanup = instrumentReact(React);\n *\n * // Later, to restore original React\n * cleanup();\n * ```\n */\nexport function instrumentReact(\n React: typeof import('react'),\n options: ReactInstrumentationOptions = {}\n): () => void {\n if (isInstrumented) {\n console.warn('[State Surgeon] React already instrumented');\n return () => {};\n }\n\n const client = options.client || getClient();\n const captureComponentName = options.captureComponentName !== false;\n\n // Store originals\n originalUseState = React.useState;\n originalUseReducer = React.useReducer;\n\n // Patch useState\n (React as any).useState = function <T>(initialState: T | (() => T)) {\n const [state, originalSetState] = originalUseState!(initialState);\n\n const instrumentedSetState = (\n newStateOrUpdater: T | ((prevState: T) => T)\n ) => {\n const previousState = deepClone(state);\n\n // Calculate new state\n const newState = typeof newStateOrUpdater === 'function'\n ? (newStateOrUpdater as (prev: T) => T)(state)\n : newStateOrUpdater;\n\n // Record mutation\n client.captureStateChange('react', previousState, newState, {\n actionType: 'SET_STATE',\n component: captureComponentName ? getComponentName() : undefined,\n function: 'useState',\n });\n\n // Call original\n return originalSetState(newStateOrUpdater);\n };\n\n return [state, instrumentedSetState];\n };\n\n // Patch useReducer\n (React as any).useReducer = function <R extends React.Reducer<any, any>>(\n reducer: R,\n initialArg: React.ReducerState<R>,\n init?: (arg: React.ReducerState<R>) => React.ReducerState<R>\n ) {\n // Wrap the reducer to capture mutations\n const instrumentedReducer: R = ((state: React.ReducerState<R>, action: React.ReducerAction<R>) => {\n const previousState = deepClone(state);\n const newState = reducer(state, action);\n\n // Record mutation\n client.captureStateChange('react', previousState, newState, {\n actionType: 'DISPATCH',\n actionPayload: action,\n component: captureComponentName ? getComponentName() : undefined,\n function: 'useReducer',\n });\n\n return newState;\n }) as R;\n\n return originalUseReducer!(instrumentedReducer, initialArg, init);\n };\n\n isInstrumented = true;\n\n // Return cleanup function\n return () => {\n if (originalUseState) {\n (React as any).useState = originalUseState;\n }\n if (originalUseReducer) {\n (React as any).useReducer = originalUseReducer;\n }\n isInstrumented = false;\n originalUseState = null;\n originalUseReducer = null;\n };\n}\n\n/**\n * Attempts to extract component name from stack trace\n */\nfunction getComponentName(): string | undefined {\n const stack = new Error().stack;\n if (!stack) return undefined;\n\n const lines = stack.split('\\n');\n\n // Look for component-like function names\n for (const line of lines) {\n // Skip internal React and State Surgeon frames\n if (\n line.includes('instrumentedSetState') ||\n line.includes('instrumentedReducer') ||\n line.includes('useState') ||\n line.includes('useReducer') ||\n line.includes('react-dom') ||\n line.includes('react.development')\n ) {\n continue;\n }\n\n // Extract function name\n const match = line.match(/at\\s+([A-Z][A-Za-z0-9_]*)/);\n if (match) {\n return match[1];\n }\n }\n\n return undefined;\n}\n\n/**\n * Creates a manual state tracker for class components or custom state\n *\n * @example\n * ```tsx\n * const tracker = createStateTracker('MyComponent');\n *\n * function updateState(newValue) {\n * const oldValue = state.value;\n * state.value = newValue;\n * tracker.track(oldValue, newValue, 'value update');\n * }\n * ```\n */\nexport function createStateTracker(componentName: string, options: ReactInstrumentationOptions = {}) {\n const client = options.client || getClient();\n\n return {\n track(previousState: unknown, nextState: unknown, action?: string) {\n client.captureStateChange('react', previousState, nextState, {\n actionType: 'SET_STATE',\n component: componentName,\n actionPayload: action ? { description: action } : undefined,\n });\n },\n };\n}\n","import { deepClone } from '../core/diff';\nimport { getClient, type StateSurgeonClient } from './client';\n\n/**\n * Redux store interface (minimal)\n */\ninterface ReduxStore {\n getState: () => unknown;\n dispatch: (action: unknown) => unknown;\n subscribe: (listener: () => void) => () => void;\n replaceReducer?: (reducer: unknown) => void;\n}\n\n/**\n * Redux middleware API\n */\ninterface MiddlewareAPI {\n getState: () => unknown;\n dispatch: (action: unknown) => unknown;\n}\n\n/**\n * Options for Redux instrumentation\n */\nexport interface ReduxInstrumentationOptions {\n /** State Surgeon client (uses global if not provided) */\n client?: StateSurgeonClient;\n\n /** Whether to capture full state or just the diff */\n captureFullState?: boolean;\n\n /** Actions to ignore (by type) */\n ignoreActions?: string[];\n\n /** Custom name for this store */\n storeName?: string;\n}\n\n/**\n * Creates a Redux middleware that captures all actions and state changes\n *\n * @example\n * ```tsx\n * import { createStore, applyMiddleware } from 'redux';\n * import { createReduxMiddleware } from 'state-surgeon/instrument';\n *\n * const stateSurgeonMiddleware = createReduxMiddleware();\n * const store = createStore(rootReducer, applyMiddleware(stateSurgeonMiddleware));\n * ```\n */\nexport function createReduxMiddleware(options: ReduxInstrumentationOptions = {}) {\n const client = options.client || getClient();\n const ignoreActions = new Set(options.ignoreActions || []);\n const storeName = options.storeName || 'redux';\n\n return (storeAPI: MiddlewareAPI) => (next: (action: unknown) => unknown) => (action: unknown) => {\n const actionType = (action as { type?: string })?.type;\n\n // Skip ignored actions\n if (actionType && ignoreActions.has(actionType)) {\n return next(action);\n }\n\n // Capture state before\n const previousState = deepClone(storeAPI.getState());\n const startTime = typeof performance !== 'undefined' ? performance.now() : Date.now();\n\n // Execute action\n const result = next(action);\n\n // Capture state after\n const nextState = deepClone(storeAPI.getState());\n const duration = (typeof performance !== 'undefined' ? performance.now() : Date.now()) - startTime;\n\n // Record mutation\n const mutation = client.captureStateChange('redux', previousState, nextState, {\n actionType: 'DISPATCH',\n actionPayload: action,\n component: storeName,\n function: actionType || 'dispatch',\n });\n\n // Add duration\n mutation.duration = duration;\n\n return result;\n };\n}\n\n/**\n * Instruments an existing Redux store by wrapping its dispatch method\n *\n * @example\n * ```tsx\n * import { createStore } from 'redux';\n * import { instrumentReduxStore } from 'state-surgeon/instrument';\n *\n * const store = createStore(rootReducer);\n * const cleanup = instrumentReduxStore(store);\n * ```\n */\nexport function instrumentReduxStore(\n store: ReduxStore,\n options: ReduxInstrumentationOptions = {}\n): () => void {\n const client = options.client || getClient();\n const ignoreActions = new Set(options.ignoreActions || []);\n const storeName = options.storeName || 'redux';\n\n const originalDispatch = store.dispatch;\n\n store.dispatch = function instrumentedDispatch(action: unknown) {\n const actionType = (action as { type?: string })?.type;\n\n // Skip ignored actions\n if (actionType && ignoreActions.has(actionType)) {\n return originalDispatch(action);\n }\n\n // Capture state before\n const previousState = deepClone(store.getState());\n const startTime = typeof performance !== 'undefined' ? performance.now() : Date.now();\n\n // Execute action\n const result = originalDispatch(action);\n\n // Capture state after\n const nextState = deepClone(store.getState());\n const duration = (typeof performance !== 'undefined' ? performance.now() : Date.now()) - startTime;\n\n // Record mutation\n const mutation = client.captureStateChange('redux', previousState, nextState, {\n actionType: 'DISPATCH',\n actionPayload: action,\n component: storeName,\n function: actionType || 'dispatch',\n });\n\n mutation.duration = duration;\n\n return result;\n };\n\n // Return cleanup function\n return () => {\n store.dispatch = originalDispatch;\n };\n}\n\n/**\n * Creates a simple action logger that doesn't require Redux\n * Useful for debugging action flow without full instrumentation\n */\nexport function createActionLogger(options: ReduxInstrumentationOptions = {}) {\n const client = options.client || getClient();\n const storeName = options.storeName || 'action-log';\n\n return {\n log(actionType: string, payload?: unknown, previousState?: unknown, nextState?: unknown) {\n if (previousState !== undefined && nextState !== undefined) {\n client.captureStateChange('redux', previousState, nextState, {\n actionType: 'DISPATCH',\n actionPayload: { type: actionType, payload },\n component: storeName,\n function: actionType,\n });\n }\n },\n };\n}\n","import { deepClone } from '../core/diff';\nimport { getClient, type StateSurgeonClient } from './client';\n\n/**\n * Options for Zustand instrumentation\n */\nexport interface ZustandInstrumentationOptions {\n /** State Surgeon client (uses global if not provided) */\n client?: StateSurgeonClient;\n\n /** Custom name for this store */\n storeName?: string;\n}\n\n/**\n * Zustand's StateCreator type (simplified)\n */\ntype StateCreator<T> = (\n set: (partial: T | Partial<T> | ((state: T) => T | Partial<T>), replace?: boolean) => void,\n get: () => T,\n api: unknown\n) => T;\n\n/**\n * Instruments a Zustand store creator to capture state mutations\n *\n * @example\n * ```tsx\n * import { create } from 'zustand';\n * import { instrumentZustand } from 'state-surgeon/instrument';\n *\n * const useStore = create(\n * instrumentZustand((set) => ({\n * count: 0,\n * increment: () => set((state) => ({ count: state.count + 1 })),\n * }))\n * );\n * ```\n */\nexport function instrumentZustand<T extends object>(\n stateCreator: StateCreator<T>,\n options: ZustandInstrumentationOptions = {}\n): StateCreator<T> {\n const client = options.client || getClient();\n const storeName = options.storeName || 'zustand';\n\n return (set, get, api) => {\n // Wrap the set function\n const instrumentedSet: typeof set = (partial, replace) => {\n const previousState = deepClone(get());\n\n // Call original set\n set(partial, replace);\n\n const nextState = deepClone(get());\n\n // Record mutation\n client.captureStateChange('zustand', previousState, nextState, {\n actionType: 'SET_STATE',\n actionPayload: typeof partial === 'function' ? 'updater function' : partial,\n component: storeName,\n function: 'set',\n });\n };\n\n // Create the store with instrumented set\n return stateCreator(instrumentedSet, get, api);\n };\n}\n\n/**\n * Creates a Zustand middleware for more granular control\n *\n * @example\n * ```tsx\n * import { create } from 'zustand';\n * import { stateSurgeonMiddleware } from 'state-surgeon/instrument';\n *\n * const useStore = create(\n * stateSurgeonMiddleware(\n * (set) => ({\n * count: 0,\n * increment: () => set((state) => ({ count: state.count + 1 })),\n * }),\n * { storeName: 'counterStore' }\n * )\n * );\n * ```\n */\nexport function stateSurgeonMiddleware<T extends object>(\n stateCreator: StateCreator<T>,\n options: ZustandInstrumentationOptions = {}\n): StateCreator<T> {\n return instrumentZustand(stateCreator, options);\n}\n\n/**\n * Higher-order function to wrap individual actions for tracking\n *\n * @example\n * ```tsx\n * const useStore = create((set, get) => ({\n * count: 0,\n * increment: trackAction('increment', () => {\n * set((state) => ({ count: state.count + 1 }));\n * }),\n * }));\n * ```\n */\nexport function trackAction<T extends (...args: any[]) => any>(\n actionName: string,\n action: T,\n options: ZustandInstrumentationOptions = {}\n): T {\n const client = options.client || getClient();\n const storeName = options.storeName || 'zustand';\n\n return ((...args: Parameters<T>) => {\n const startTime = typeof performance !== 'undefined' ? performance.now() : Date.now();\n const result = action(...args);\n const duration = (typeof performance !== 'undefined' ? performance.now() : Date.now()) - startTime;\n\n // Log action execution (state changes captured separately via set wrapper)\n // This is useful for tracking async actions\n if (result instanceof Promise) {\n result.then(() => {\n // Async action completed\n }).catch(() => {\n // Async action failed\n });\n }\n\n return result;\n }) as T;\n}\n\n/**\n * Creates a subscribe-based tracker for Zustand stores\n * Useful when you can't modify the store creation\n *\n * @example\n * ```tsx\n * import { useStore } from './store';\n * import { subscribeToStore } from 'state-surgeon/instrument';\n *\n * // Subscribe to track all changes\n * const unsubscribe = subscribeToStore(useStore, 'myStore');\n * ```\n */\nexport function subscribeToStore<T extends object>(\n useStore: { getState: () => T; subscribe: (listener: (state: T, prevState: T) => void) => () => void },\n storeName: string,\n options: ZustandInstrumentationOptions = {}\n): () => void {\n const client = options.client || getClient();\n\n return useStore.subscribe((state, prevState) => {\n client.captureStateChange('zustand', prevState, state, {\n actionType: 'SET_STATE',\n component: storeName,\n function: 'subscribe',\n });\n });\n}\n"]}