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/recorder/api.ts","../../src/core/diff.ts","../../src/recorder/reconstructor.ts","../../src/recorder/store.ts","../../src/recorder/server.ts"],"names":[],"mappings":"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","file":"index.mjs","sourcesContent":["import { Router, type Request, type Response } from 'express';\nimport type { TimelineReconstructor } from './reconstructor';\nimport type { MutationStore } from './store';\n\n/**\n * Creates Express API routes for the recorder\n */\nexport function createAPIRoutes(\n store: MutationStore,\n reconstructor: TimelineReconstructor\n): Router {\n const router = Router();\n\n // Health check\n router.get('/health', (_req: Request, res: Response) => {\n res.json({ status: 'ok', timestamp: Date.now() });\n });\n\n // Get all sessions\n router.get('/sessions', (req: Request, res: Response) => {\n try {\n const appId = req.query.appId as string | undefined;\n const sessions = store.getSessions(appId);\n res.json({ sessions });\n } catch (error) {\n res.status(500).json({ error: String(error) });\n }\n });\n\n // Get a specific session\n router.get('/sessions/:sessionId', (req: Request, res: Response) => {\n try {\n const session = store.getSession(req.params.sessionId);\n if (!session) {\n return res.status(404).json({ error: 'Session not found' });\n }\n res.json({ session });\n } catch (error) {\n res.status(500).json({ error: String(error) });\n }\n });\n\n // Delete a session\n router.delete('/sessions/:sessionId', (req: Request, res: Response) => {\n try {\n const deleted = store.deleteSession(req.params.sessionId);\n res.json({ deleted });\n } catch (error) {\n res.status(500).json({ error: String(error) });\n }\n });\n\n // Get timeline for a session\n router.get('/sessions/:sessionId/timeline', (req: Request, res: Response) => {\n try {\n const timeline = store.getTimeline(req.params.sessionId);\n res.json({ timeline, count: timeline.length });\n } catch (error) {\n res.status(500).json({ error: String(error) });\n }\n });\n\n // Query mutations\n router.get('/mutations', (req: Request, res: Response) => {\n try {\n const options = {\n sessionId: req.query.sessionId as string | undefined,\n startTime: req.query.startTime ? Number(req.query.startTime) : undefined,\n endTime: req.query.endTime ? Number(req.query.endTime) : undefined,\n source: req.query.source as string | undefined,\n component: req.query.component as string | undefined,\n limit: req.query.limit ? Number(req.query.limit) : 100,\n offset: req.query.offset ? Number(req.query.offset) : 0,\n sortOrder: (req.query.sortOrder as 'asc' | 'desc') || 'asc',\n };\n\n const mutations = store.queryMutations(options);\n res.json({ mutations, count: mutations.length });\n } catch (error) {\n res.status(500).json({ error: String(error) });\n }\n });\n\n // Get a specific mutation\n router.get('/mutations/:mutationId', (req: Request, res: Response) => {\n try {\n const mutation = store.getMutation(req.params.mutationId);\n if (!mutation) {\n return res.status(404).json({ error: 'Mutation not found' });\n }\n res.json({ mutation });\n } catch (error) {\n res.status(500).json({ error: String(error) });\n }\n });\n\n // Get state at mutation\n router.get('/mutations/:mutationId/state', async (req: Request, res: Response) => {\n try {\n const state = await reconstructor.getStateAtMutation(req.params.mutationId);\n res.json({ state });\n } catch (error) {\n res.status(500).json({ error: String(error) });\n }\n });\n\n // Get causal chain\n router.get('/mutations/:mutationId/chain', async (req: Request, res: Response) => {\n try {\n const maxDepth = req.query.maxDepth ? Number(req.query.maxDepth) : 100;\n const chain = await reconstructor.findCausalChain(req.params.mutationId, maxDepth);\n res.json({ chain });\n } catch (error) {\n res.status(500).json({ error: String(error) });\n }\n });\n\n // Find mutations for a path\n router.get('/sessions/:sessionId/path', async (req: Request, res: Response) => {\n try {\n const path = req.query.path as string;\n if (!path) {\n return res.status(400).json({ error: 'Path is required' });\n }\n const mutations = await reconstructor.findMutationsForPath(req.params.sessionId, path);\n res.json({ mutations, count: mutations.length });\n } catch (error) {\n res.status(500).json({ error: String(error) });\n }\n });\n\n // Summarize time range\n router.get('/sessions/:sessionId/summary', async (req: Request, res: Response) => {\n try {\n const startTime = Number(req.query.startTime);\n const endTime = Number(req.query.endTime);\n\n if (isNaN(startTime) || isNaN(endTime)) {\n return res.status(400).json({ error: 'startTime and endTime are required' });\n }\n\n const summary = await reconstructor.summarizeTimeRange(\n req.params.sessionId,\n startTime,\n endTime\n );\n res.json({ summary });\n } catch (error) {\n res.status(500).json({ error: String(error) });\n }\n });\n\n // Get store statistics\n router.get('/stats', (_req: Request, res: Response) => {\n try {\n const stats = store.getStats();\n res.json({ stats });\n } catch (error) {\n res.status(500).json({ error: String(error) });\n }\n });\n\n // Clear all data\n router.delete('/clear', (_req: Request, res: Response) => {\n try {\n store.clear();\n reconstructor.clearCache();\n res.json({ success: true });\n } catch (error) {\n res.status(500).json({ error: String(error) });\n }\n });\n\n return router;\n}\n","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 { deepClone, getValueAtPath } from '../core/diff';\nimport type { Mutation } from '../core/mutation';\nimport type { MutationStore } from './store';\n\n/**\n * Validation function for state corruption detection\n */\nexport type StateValidator = (state: unknown) => boolean;\n\n/**\n * Result of causal chain analysis\n */\nexport interface CausalChain {\n mutations: Mutation[];\n rootCause?: Mutation;\n corrupted?: Mutation;\n}\n\n/**\n * Timeline reconstruction engine\n * Provides tools for investigating state history\n */\nexport class TimelineReconstructor {\n private store: MutationStore;\n private stateCache: Map<string, unknown> = new Map();\n private maxCacheSize = 1000;\n\n constructor(store: MutationStore) {\n this.store = store;\n }\n\n /**\n * Reconstructs the state at a specific mutation\n */\n async getStateAtMutation(mutationId: string): Promise<unknown> {\n // Check cache\n const cached = this.stateCache.get(mutationId);\n if (cached !== undefined) {\n return deepClone(cached);\n }\n\n // Find the mutation\n const targetMutation = this.store.getMutation(mutationId);\n if (!targetMutation) {\n throw new Error(`Mutation not found: ${mutationId}`);\n }\n\n // Get all mutations up to this point\n const timeline = this.store.getTimeline(targetMutation.sessionId);\n const targetIndex = timeline.findIndex(m => m.id === mutationId);\n\n if (targetIndex === -1) {\n throw new Error(`Mutation not in timeline: ${mutationId}`);\n }\n\n // Build state by applying mutations in order\n let state: unknown = {};\n\n for (let i = 0; i <= targetIndex; i++) {\n const mutation = timeline[i];\n state = mutation.nextState;\n\n // Cache each state along the way\n this.cacheState(mutation.id, state);\n }\n\n return deepClone(state);\n }\n\n /**\n * Reconstructs the state at a specific timestamp\n */\n async getStateAtTime(sessionId: string, timestamp: number): Promise<unknown> {\n const timeline = this.store.getTimeline(sessionId);\n\n // Find the last mutation before or at the timestamp\n let lastMutation: Mutation | null = null;\n\n for (const mutation of timeline) {\n if (mutation.timestamp <= timestamp) {\n lastMutation = mutation;\n } else {\n break;\n }\n }\n\n if (!lastMutation) {\n return {}; // No mutations yet, return empty state\n }\n\n return this.getStateAtMutation(lastMutation.id);\n }\n\n /**\n * Finds the causal chain leading to a mutation\n */\n async findCausalChain(\n mutationId: string,\n maxDepth: number = 100\n ): Promise<CausalChain> {\n const chain: Mutation[] = [];\n let currentId: string | undefined = mutationId;\n let depth = 0;\n\n while (currentId && depth < maxDepth) {\n const mutation = this.store.getMutation(currentId);\n if (!mutation) break;\n\n chain.push(mutation);\n\n // Follow parent or causes\n if (mutation.parentMutationId) {\n currentId = mutation.parentMutationId;\n } else if (mutation.causes && mutation.causes.length > 0) {\n currentId = mutation.causes[0];\n } else {\n break;\n }\n\n depth++;\n }\n\n return {\n mutations: chain.reverse(),\n rootCause: chain[0],\n };\n }\n\n /**\n * Binary search to find when state became invalid\n */\n async findStateCorruption(\n sessionId: string,\n validator: StateValidator\n ): Promise<Mutation | null> {\n const timeline = this.store.getTimeline(sessionId);\n\n if (timeline.length === 0) {\n return null;\n }\n\n let left = 0;\n let right = timeline.length - 1;\n let firstBad: number | null = null;\n\n while (left <= right) {\n const mid = Math.floor((left + right) / 2);\n const state = await this.getStateAtMutation(timeline[mid].id);\n const isValid = validator(state);\n\n if (isValid) {\n // State is valid at this point, corruption is after\n left = mid + 1;\n } else {\n // State is invalid, corruption is at or before\n firstBad = mid;\n right = mid - 1;\n }\n }\n\n return firstBad !== null ? timeline[firstBad] : null;\n }\n\n /**\n * Finds all mutations that touched a specific path\n */\n async findMutationsForPath(\n sessionId: string,\n path: string\n ): Promise<Mutation[]> {\n const timeline = this.store.getTimeline(sessionId);\n const result: Mutation[] = [];\n\n for (const mutation of timeline) {\n // Check if the diff touches this path\n if (mutation.diff) {\n for (const diff of mutation.diff) {\n if (diff.path === path || diff.path.startsWith(path + '.') || diff.path.startsWith(path + '[')) {\n result.push(mutation);\n break;\n }\n }\n } else {\n // No diff, compare values directly\n const prevValue = getValueAtPath(mutation.previousState, path);\n const nextValue = getValueAtPath(mutation.nextState, path);\n\n if (prevValue !== nextValue) {\n result.push(mutation);\n }\n }\n }\n\n return result;\n }\n\n /**\n * Compares two sessions to find divergence points\n */\n async compareSessions(\n sessionId1: string,\n sessionId2: string\n ): Promise<{\n divergencePoint?: number;\n session1Only: Mutation[];\n session2Only: Mutation[];\n }> {\n const timeline1 = this.store.getTimeline(sessionId1);\n const timeline2 = this.store.getTimeline(sessionId2);\n\n let divergencePoint: number | undefined;\n\n // Find first point of divergence\n const minLength = Math.min(timeline1.length, timeline2.length);\n\n for (let i = 0; i < minLength; i++) {\n const state1 = await this.getStateAtMutation(timeline1[i].id);\n const state2 = await this.getStateAtMutation(timeline2[i].id);\n\n if (JSON.stringify(state1) !== JSON.stringify(state2)) {\n divergencePoint = i;\n break;\n }\n }\n\n // Find unique actions\n const actions1 = new Set(timeline1.map(m => `${m.actionType}:${JSON.stringify(m.actionPayload)}`));\n const actions2 = new Set(timeline2.map(m => `${m.actionType}:${JSON.stringify(m.actionPayload)}`));\n\n const session1Only = timeline1.filter(m =>\n !actions2.has(`${m.actionType}:${JSON.stringify(m.actionPayload)}`)\n );\n const session2Only = timeline2.filter(m =>\n !actions1.has(`${m.actionType}:${JSON.stringify(m.actionPayload)}`)\n );\n\n return {\n divergencePoint,\n session1Only,\n session2Only,\n };\n }\n\n /**\n * Generates a summary of what happened in a time range\n */\n async summarizeTimeRange(\n sessionId: string,\n startTime: number,\n endTime: number\n ): Promise<{\n mutationCount: number;\n componentBreakdown: Record<string, number>;\n sourceBreakdown: Record<string, number>;\n pathsChanged: string[];\n }> {\n const mutations = this.store.queryMutations({\n sessionId,\n startTime,\n endTime,\n });\n\n const componentBreakdown: Record<string, number> = {};\n const sourceBreakdown: Record<string, number> = {};\n const pathsSet = new Set<string>();\n\n for (const mutation of mutations) {\n // Count by component\n const component = mutation.component || 'unknown';\n componentBreakdown[component] = (componentBreakdown[component] || 0) + 1;\n\n // Count by source\n sourceBreakdown[mutation.source] = (sourceBreakdown[mutation.source] || 0) + 1;\n\n // Collect changed paths\n if (mutation.diff) {\n for (const diff of mutation.diff) {\n pathsSet.add(diff.path);\n }\n }\n }\n\n return {\n mutationCount: mutations.length,\n componentBreakdown,\n sourceBreakdown,\n pathsChanged: Array.from(pathsSet),\n };\n }\n\n /**\n * Clears the state cache\n */\n clearCache(): void {\n this.stateCache.clear();\n }\n\n private cacheState(mutationId: string, state: unknown): void {\n if (this.stateCache.size >= this.maxCacheSize) {\n // Remove oldest entry\n const firstKey = this.stateCache.keys().next().value;\n if (firstKey) {\n this.stateCache.delete(firstKey);\n }\n }\n this.stateCache.set(mutationId, deepClone(state));\n }\n}\n","import { calculateDiff } from '../core/diff';\nimport type { Mutation } from '../core/mutation';\n\n/**\n * Session metadata\n */\nexport interface Session {\n id: string;\n appId: string;\n startTime: Date;\n endTime?: Date;\n userAgent?: string;\n url?: string;\n metadata?: Record<string, unknown>;\n mutationCount: number;\n}\n\n/**\n * Query options for fetching mutations\n */\nexport interface MutationQueryOptions {\n sessionId?: string;\n startTime?: number;\n endTime?: number;\n source?: Mutation['source'];\n component?: string;\n limit?: number;\n offset?: number;\n sortOrder?: 'asc' | 'desc';\n}\n\n/**\n * Options for the mutation store\n */\nexport interface MutationStoreOptions {\n /** Maximum mutations to keep per session */\n maxMutationsPerSession?: number;\n\n /** Maximum total mutations across all sessions */\n maxTotalMutations?: number;\n\n /** Session timeout in milliseconds */\n sessionTimeout?: number;\n\n /** Enable debug logging */\n debug?: boolean;\n}\n\n/**\n * In-memory mutation store\n * Can be extended to support MongoDB or other persistent storage\n */\nexport class MutationStore {\n private sessions: Map<string, Session> = new Map();\n private mutations: Map<string, Mutation[]> = new Map();\n private options: Required<MutationStoreOptions>;\n private totalMutationCount = 0;\n\n constructor(options: MutationStoreOptions = {}) {\n this.options = {\n maxMutationsPerSession: options.maxMutationsPerSession ?? 10000,\n maxTotalMutations: options.maxTotalMutations ?? 100000,\n sessionTimeout: options.sessionTimeout ?? 30 * 60 * 1000, // 30 minutes\n debug: options.debug ?? false,\n };\n }\n\n /**\n * Creates or updates a session\n */\n registerSession(\n sessionId: string,\n appId: string,\n metadata?: Record<string, unknown>\n ): Session {\n let session = this.sessions.get(sessionId);\n\n if (!session) {\n session = {\n id: sessionId,\n appId,\n startTime: new Date(),\n metadata,\n mutationCount: 0,\n };\n this.sessions.set(sessionId, session);\n this.mutations.set(sessionId, []);\n this.log('Session registered:', sessionId);\n }\n\n return session;\n }\n\n /**\n * Ends a session\n */\n endSession(sessionId: string): void {\n const session = this.sessions.get(sessionId);\n if (session) {\n session.endTime = new Date();\n this.log('Session ended:', sessionId);\n }\n }\n\n /**\n * Stores a mutation\n */\n storeMutation(mutation: Mutation): void {\n const sessionId = mutation.sessionId;\n\n // Ensure session exists\n if (!this.sessions.has(sessionId)) {\n this.registerSession(sessionId, 'unknown');\n }\n\n // Get or create mutation array\n let sessionMutations = this.mutations.get(sessionId);\n if (!sessionMutations) {\n sessionMutations = [];\n this.mutations.set(sessionId, sessionMutations);\n }\n\n // Add diff if not present\n if (!mutation.diff && mutation.previousState !== undefined && mutation.nextState !== undefined) {\n mutation.diff = calculateDiff(mutation.previousState, mutation.nextState);\n }\n\n // Enforce limits\n if (sessionMutations.length >= this.options.maxMutationsPerSession) {\n sessionMutations.shift();\n this.totalMutationCount--;\n }\n\n if (this.totalMutationCount >= this.options.maxTotalMutations) {\n this.evictOldestMutations();\n }\n\n // Store mutation\n sessionMutations.push(mutation);\n this.totalMutationCount++;\n\n // Update session\n const session = this.sessions.get(sessionId)!;\n session.mutationCount++;\n\n this.log('Mutation stored:', mutation.id);\n }\n\n /**\n * Stores multiple mutations at once\n */\n storeMutations(mutations: Mutation[]): void {\n for (const mutation of mutations) {\n this.storeMutation(mutation);\n }\n }\n\n /**\n * Gets a session by ID\n */\n getSession(sessionId: string): Session | undefined {\n return this.sessions.get(sessionId);\n }\n\n /**\n * Gets all sessions\n */\n getSessions(appId?: string): Session[] {\n const sessions = Array.from(this.sessions.values());\n if (appId) {\n return sessions.filter(s => s.appId === appId);\n }\n return sessions;\n }\n\n /**\n * Gets a specific mutation by ID\n */\n getMutation(mutationId: string): Mutation | undefined {\n for (const sessionMutations of this.mutations.values()) {\n const mutation = sessionMutations.find(m => m.id === mutationId);\n if (mutation) return mutation;\n }\n return undefined;\n }\n\n /**\n * Queries mutations with filters\n */\n queryMutations(options: MutationQueryOptions = {}): Mutation[] {\n let results: Mutation[] = [];\n\n // Get mutations from specific session or all sessions\n if (options.sessionId) {\n const sessionMutations = this.mutations.get(options.sessionId);\n if (sessionMutations) {\n results = [...sessionMutations];\n }\n } else {\n for (const sessionMutations of this.mutations.values()) {\n results.push(...sessionMutations);\n }\n }\n\n // Filter by time range\n if (options.startTime !== undefined) {\n results = results.filter(m => m.timestamp >= options.startTime!);\n }\n if (options.endTime !== undefined) {\n results = results.filter(m => m.timestamp <= options.endTime!);\n }\n\n // Filter by source\n if (options.source) {\n results = results.filter(m => m.source === options.source);\n }\n\n // Filter by component\n if (options.component) {\n results = results.filter(m => m.component === options.component);\n }\n\n // Sort\n results.sort((a, b) => {\n const order = options.sortOrder === 'desc' ? -1 : 1;\n return (a.logicalClock - b.logicalClock) * order;\n });\n\n // Apply pagination\n if (options.offset !== undefined) {\n results = results.slice(options.offset);\n }\n if (options.limit !== undefined) {\n results = results.slice(0, options.limit);\n }\n\n return results;\n }\n\n /**\n * Gets the timeline for a session\n */\n getTimeline(sessionId: string): Mutation[] {\n const mutations = this.mutations.get(sessionId) || [];\n return [...mutations].sort((a, b) => a.logicalClock - b.logicalClock);\n }\n\n /**\n * Deletes a session and its mutations\n */\n deleteSession(sessionId: string): boolean {\n const sessionMutations = this.mutations.get(sessionId);\n if (sessionMutations) {\n this.totalMutationCount -= sessionMutations.length;\n }\n\n this.mutations.delete(sessionId);\n return this.sessions.delete(sessionId);\n }\n\n /**\n * Clears all data\n */\n clear(): void {\n this.sessions.clear();\n this.mutations.clear();\n this.totalMutationCount = 0;\n this.log('Store cleared');\n }\n\n /**\n * Gets store statistics\n */\n getStats(): {\n sessionCount: number;\n totalMutations: number;\n mutationsPerSession: Record<string, number>;\n } {\n const mutationsPerSession: Record<string, number> = {};\n for (const [sessionId, mutations] of this.mutations.entries()) {\n mutationsPerSession[sessionId] = mutations.length;\n }\n\n return {\n sessionCount: this.sessions.size,\n totalMutations: this.totalMutationCount,\n mutationsPerSession,\n };\n }\n\n /**\n * Evicts oldest mutations when capacity is exceeded\n */\n private evictOldestMutations(): void {\n // Find session with oldest mutations\n let oldestSession: string | null = null;\n let oldestTime = Infinity;\n\n for (const [sessionId, session] of this.sessions.entries()) {\n if (session.startTime.getTime() < oldestTime) {\n oldestTime = session.startTime.getTime();\n oldestSession = sessionId;\n }\n }\n\n if (oldestSession) {\n const mutations = this.mutations.get(oldestSession);\n if (mutations && mutations.length > 0) {\n mutations.shift();\n this.totalMutationCount--;\n this.log('Evicted oldest mutation from:', oldestSession);\n }\n }\n }\n\n private log(...args: unknown[]): void {\n if (this.options.debug) {\n console.log('[MutationStore]', ...args);\n }\n }\n}\n","import express, { type Express } from 'express';\nimport type { Server } from 'http';\nimport { WebSocket, WebSocketServer } from 'ws';\nimport type { Mutation } from '../core/mutation';\nimport { createAPIRoutes } from './api';\nimport { TimelineReconstructor } from './reconstructor';\nimport { MutationStore, type MutationStoreOptions } from './store';\n\n/**\n * Options for the recorder server\n */\nexport interface RecorderServerOptions {\n /** HTTP port (default: 8080) */\n port?: number;\n\n /** WebSocket port (default: 8081) */\n wsPort?: number;\n\n /** Enable CORS (default: true) */\n cors?: boolean;\n\n /** API base path (default: '/api') */\n apiPath?: string;\n\n /** Mutation store options */\n storeOptions?: MutationStoreOptions;\n\n /** Enable debug logging */\n debug?: boolean;\n}\n\n/**\n * Recorder server instance\n */\nexport interface RecorderServer {\n /** Express application */\n app: Express;\n\n /** HTTP server */\n httpServer: Server;\n\n /** WebSocket server */\n wss: WebSocketServer;\n\n /** Mutation store */\n store: MutationStore;\n\n /** Timeline reconstructor */\n reconstructor: TimelineReconstructor;\n\n /** Start the server */\n start: () => Promise<void>;\n\n /** Stop the server */\n stop: () => Promise<void>;\n}\n\ninterface WSMessage {\n type: string;\n payload: unknown;\n}\n\n/**\n * Creates a State Surgeon recorder server\n *\n * @example\n * ```ts\n * import { createRecorderServer } from 'state-surgeon/recorder';\n *\n * const server = createRecorderServer({ port: 8080 });\n * await server.start();\n *\n * console.log('State Surgeon Recorder running on http://localhost:8080');\n * ```\n */\nexport function createRecorderServer(options: RecorderServerOptions = {}): RecorderServer {\n const port = options.port ?? 8080;\n const wsPort = options.wsPort ?? 8081;\n const apiPath = options.apiPath ?? '/api';\n const debug = options.debug ?? false;\n\n // Create store and reconstructor\n const store = new MutationStore(options.storeOptions);\n const reconstructor = new TimelineReconstructor(store);\n\n // Create Express app\n const app = express();\n\n // Middleware\n app.use(express.json({ limit: '10mb' }));\n\n // CORS\n if (options.cors !== false) {\n app.use((_req, res, next) => {\n res.header('Access-Control-Allow-Origin', '*');\n res.header('Access-Control-Allow-Methods', 'GET, POST, PUT, DELETE, OPTIONS');\n res.header('Access-Control-Allow-Headers', 'Origin, X-Requested-With, Content-Type, Accept');\n next();\n });\n }\n\n // API routes\n app.use(apiPath, createAPIRoutes(store, reconstructor));\n\n // Dashboard route placeholder\n app.get('/_surgeon', (_req, res) => {\n res.send(`\n <!DOCTYPE html>\n <html>\n <head>\n <title>State Surgeon Dashboard</title>\n <style>\n body { font-family: system-ui, sans-serif; padding: 2rem; background: #1a1a2e; color: #eee; }\n h1 { color: #00d9ff; }\n .stats { background: #16213e; padding: 1rem; border-radius: 8px; margin: 1rem 0; }\n pre { background: #0f0f23; padding: 1rem; border-radius: 4px; overflow: auto; }\n </style>\n </head>\n <body>\n <h1>🔬 State Surgeon Dashboard</h1>\n <p>Recorder is running. Connect your application to start capturing mutations.</p>\n <div class=\"stats\">\n <h3>Quick Stats</h3>\n <div id=\"stats\">Loading...</div>\n </div>\n <h3>Recent Sessions</h3>\n <pre id=\"sessions\">Loading...</pre>\n <script>\n async function loadData() {\n try {\n const statsRes = await fetch('${apiPath}/stats');\n const stats = await statsRes.json();\n document.getElementById('stats').innerHTML =\n '<pre>' + JSON.stringify(stats, null, 2) + '</pre>';\n\n const sessionsRes = await fetch('${apiPath}/sessions');\n const sessions = await sessionsRes.json();\n document.getElementById('sessions').textContent =\n JSON.stringify(sessions, null, 2);\n } catch (e) {\n document.getElementById('stats').textContent = 'Error loading stats';\n }\n }\n loadData();\n setInterval(loadData, 5000);\n </script>\n </body>\n </html>\n `);\n });\n\n // Create HTTP server\n const httpServer = app.listen(0); // Will bind to actual port in start()\n httpServer.close();\n\n // Create WebSocket server\n let wss: WebSocketServer;\n\n // Connected clients\n const clients = new Map<WebSocket, { sessionId?: string }>();\n\n function log(...args: unknown[]) {\n if (debug) {\n console.log('[State Surgeon Recorder]', ...args);\n }\n }\n\n function handleMessage(ws: WebSocket, message: WSMessage) {\n log('Received message:', message.type);\n\n switch (message.type) {\n case 'REGISTER_SESSION': {\n const payload = message.payload as {\n sessionId: string;\n appId: string;\n userAgent?: string;\n url?: string;\n };\n\n store.registerSession(payload.sessionId, payload.appId, {\n userAgent: payload.userAgent,\n url: payload.url,\n });\n\n clients.set(ws, { sessionId: payload.sessionId });\n\n ws.send(JSON.stringify({\n type: 'SESSION_CONFIRMED',\n payload: { sessionId: payload.sessionId },\n }));\n\n log('Session registered:', payload.sessionId);\n break;\n }\n\n case 'MUTATION_RECORDED': {\n const mutation = message.payload as Mutation;\n store.storeMutation(mutation);\n\n ws.send(JSON.stringify({\n type: 'MUTATION_ACKNOWLEDGED',\n payload: { mutationId: mutation.id, receivedAt: Date.now() },\n }));\n break;\n }\n\n case 'MUTATION_BATCH': {\n const payload = message.payload as { mutations: Mutation[] };\n store.storeMutations(payload.mutations);\n\n ws.send(JSON.stringify({\n type: 'BATCH_ACKNOWLEDGED',\n payload: { count: payload.mutations.length, receivedAt: Date.now() },\n }));\n\n log('Batch received:', payload.mutations.length, 'mutations');\n break;\n }\n\n case 'END_SESSION': {\n const clientInfo = clients.get(ws);\n if (clientInfo?.sessionId) {\n store.endSession(clientInfo.sessionId);\n log('Session ended:', clientInfo.sessionId);\n }\n break;\n }\n\n default:\n log('Unknown message type:', message.type);\n }\n }\n\n const server: RecorderServer = {\n app,\n httpServer: null as unknown as Server,\n wss: null as unknown as WebSocketServer,\n store,\n reconstructor,\n\n async start() {\n return new Promise((resolve) => {\n // Start HTTP server\n server.httpServer = app.listen(port, () => {\n log(`HTTP server listening on port ${port}`);\n });\n\n // Start WebSocket server\n wss = new WebSocketServer({ port: wsPort });\n server.wss = wss;\n\n wss.on('connection', (ws) => {\n log('Client connected');\n clients.set(ws, {});\n\n ws.on('message', (data) => {\n try {\n const message = JSON.parse(data.toString()) as WSMessage;\n handleMessage(ws, message);\n } catch (error) {\n log('Error parsing message:', error);\n }\n });\n\n ws.on('close', () => {\n const clientInfo = clients.get(ws);\n if (clientInfo?.sessionId) {\n store.endSession(clientInfo.sessionId);\n }\n clients.delete(ws);\n log('Client disconnected');\n });\n\n ws.on('error', (error) => {\n log('WebSocket error:', error);\n });\n });\n\n wss.on('listening', () => {\n log(`WebSocket server listening on port ${wsPort}`);\n resolve();\n });\n });\n },\n\n async stop() {\n return new Promise((resolve) => {\n // Close all WebSocket connections\n for (const ws of clients.keys()) {\n ws.close();\n }\n clients.clear();\n\n // Close WebSocket server\n if (wss) {\n wss.close(() => {\n log('WebSocket server closed');\n });\n }\n\n // Close HTTP server\n if (server.httpServer) {\n server.httpServer.close(() => {\n log('HTTP server closed');\n resolve();\n });\n } else {\n resolve();\n }\n });\n },\n };\n\n return server;\n}\n"]}
package/package.json ADDED
@@ -0,0 +1,94 @@
1
+ {
2
+ "name": "state-surgeon",
3
+ "version": "1.0.0",
4
+ "description": "Time-travel debugging platform that records every state mutation across full-stack JavaScript applications and provides interactive forensic tools to investigate bugs",
5
+ "main": "dist/index.js",
6
+ "module": "dist/index.mjs",
7
+ "types": "dist/index.d.ts",
8
+ "exports": {
9
+ ".": {
10
+ "types": "./dist/index.d.ts",
11
+ "import": "./dist/index.mjs",
12
+ "require": "./dist/index.js"
13
+ },
14
+ "./instrument": {
15
+ "types": "./dist/instrument/index.d.ts",
16
+ "import": "./dist/instrument/index.mjs",
17
+ "require": "./dist/instrument/index.js"
18
+ },
19
+ "./recorder": {
20
+ "types": "./dist/recorder/index.d.ts",
21
+ "import": "./dist/recorder/index.mjs",
22
+ "require": "./dist/recorder/index.js"
23
+ },
24
+ "./dashboard": {
25
+ "types": "./dist/dashboard/index.d.ts",
26
+ "import": "./dist/dashboard/index.mjs",
27
+ "require": "./dist/dashboard/index.js"
28
+ }
29
+ },
30
+ "scripts": {
31
+ "build": "tsup",
32
+ "dev": "tsup --watch",
33
+ "test": "vitest run",
34
+ "test:watch": "vitest",
35
+ "lint": "eslint src/",
36
+ "typecheck": "tsc --noEmit",
37
+ "prepublishOnly": "npm run build",
38
+ "demo": "node examples/buggy-cart/server.js"
39
+ },
40
+ "keywords": [
41
+ "debugging",
42
+ "time-travel",
43
+ "state-management",
44
+ "react",
45
+ "redux",
46
+ "zustand",
47
+ "devtools",
48
+ "forensic-debugging",
49
+ "mutation-tracking",
50
+ "state-history"
51
+ ],
52
+ "author": "Your Name <your.email@example.com>",
53
+ "license": "MIT",
54
+ "repository": {
55
+ "type": "git",
56
+ "url": "git+https://github.com/YOUR_GITHUB_USERNAME/state-surgeon.git"
57
+ },
58
+ "bugs": {
59
+ "url": "https://github.com/YOUR_GITHUB_USERNAME/state-surgeon/issues"
60
+ },
61
+ "homepage": "https://github.com/YOUR_GITHUB_USERNAME/state-surgeon#readme",
62
+ "peerDependencies": {
63
+ "react": ">=16.8.0"
64
+ },
65
+ "peerDependenciesMeta": {
66
+ "react": {
67
+ "optional": true
68
+ }
69
+ },
70
+ "dependencies": {
71
+ "express": "^4.18.2",
72
+ "uuid": "^9.0.1",
73
+ "ws": "^8.16.0"
74
+ },
75
+ "devDependencies": {
76
+ "@types/express": "^4.17.21",
77
+ "@types/node": "^20.11.0",
78
+ "@types/react": "^19.2.9",
79
+ "@types/react-dom": "^19.2.3",
80
+ "@types/uuid": "^9.0.7",
81
+ "@types/ws": "^8.5.10",
82
+ "tsup": "^8.0.1",
83
+ "typescript": "^5.3.3",
84
+ "vitest": "^1.2.0"
85
+ },
86
+ "engines": {
87
+ "node": ">=16.0.0"
88
+ },
89
+ "files": [
90
+ "dist",
91
+ "README.md",
92
+ "LICENSE"
93
+ ]
94
+ }