quidproquo-actionprocessor-node 0.1.3 → 0.1.4

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.
Files changed (141) hide show
  1. package/lib/commonjs/actionProcessor/core/index.js +1 -0
  2. package/lib/commonjs/actionProcessor/core/index.js.map +1 -0
  3. package/lib/commonjs/actionProcessor/core/inlineFunction/getInlineFunctionExecuteActionProcessor.js +1 -0
  4. package/lib/commonjs/actionProcessor/core/inlineFunction/getInlineFunctionExecuteActionProcessor.js.map +1 -0
  5. package/lib/commonjs/actionProcessor/core/inlineFunction/index.js +1 -0
  6. package/lib/commonjs/actionProcessor/core/inlineFunction/index.js.map +1 -0
  7. package/lib/commonjs/actionProcessor/core/stream/getStreamCloseActionProcessor.js +1 -0
  8. package/lib/commonjs/actionProcessor/core/stream/getStreamCloseActionProcessor.js.map +1 -0
  9. package/lib/commonjs/actionProcessor/core/stream/getStreamReadActionProcessor.js +1 -0
  10. package/lib/commonjs/actionProcessor/core/stream/getStreamReadActionProcessor.js.map +1 -0
  11. package/lib/commonjs/actionProcessor/core/stream/index.js +1 -0
  12. package/lib/commonjs/actionProcessor/core/stream/index.js.map +1 -0
  13. package/lib/commonjs/actionProcessor/index.js +1 -0
  14. package/lib/commonjs/actionProcessor/index.js.map +1 -0
  15. package/lib/commonjs/actionProcessor/webserver/index.js +1 -0
  16. package/lib/commonjs/actionProcessor/webserver/index.js.map +1 -0
  17. package/lib/commonjs/dynamicActionProcessor/file/getFileDeleteActionProcessor.js +1 -0
  18. package/lib/commonjs/dynamicActionProcessor/file/getFileDeleteActionProcessor.js.map +1 -0
  19. package/lib/commonjs/dynamicActionProcessor/file/getFileExistsActionProcessor.js +1 -0
  20. package/lib/commonjs/dynamicActionProcessor/file/getFileExistsActionProcessor.js.map +1 -0
  21. package/lib/commonjs/dynamicActionProcessor/file/getFileGenerateTemporarySecureUrlActionProcessor.js +1 -0
  22. package/lib/commonjs/dynamicActionProcessor/file/getFileGenerateTemporarySecureUrlActionProcessor.js.map +1 -0
  23. package/lib/commonjs/dynamicActionProcessor/file/getFileGenerateTemporaryUploadSecureUrlActionProcessor.js +1 -0
  24. package/lib/commonjs/dynamicActionProcessor/file/getFileGenerateTemporaryUploadSecureUrlActionProcessor.js.map +1 -0
  25. package/lib/commonjs/dynamicActionProcessor/file/getFileIsColdStorageActionProcessor.js +1 -0
  26. package/lib/commonjs/dynamicActionProcessor/file/getFileIsColdStorageActionProcessor.js.map +1 -0
  27. package/lib/commonjs/dynamicActionProcessor/file/getFileListDirectoryActionProcessor.js +1 -0
  28. package/lib/commonjs/dynamicActionProcessor/file/getFileListDirectoryActionProcessor.js.map +1 -0
  29. package/lib/commonjs/dynamicActionProcessor/file/getFileReadBinaryContentsActionProcessor.js +1 -0
  30. package/lib/commonjs/dynamicActionProcessor/file/getFileReadBinaryContentsActionProcessor.js.map +1 -0
  31. package/lib/commonjs/dynamicActionProcessor/file/getFileReadObjectJsonActionProcessor.js +1 -0
  32. package/lib/commonjs/dynamicActionProcessor/file/getFileReadObjectJsonActionProcessor.js.map +1 -0
  33. package/lib/commonjs/dynamicActionProcessor/file/getFileReadTextContentsActionProcessor.js +1 -0
  34. package/lib/commonjs/dynamicActionProcessor/file/getFileReadTextContentsActionProcessor.js.map +1 -0
  35. package/lib/commonjs/dynamicActionProcessor/file/getFileStreamOpenActionProcessor.js +1 -0
  36. package/lib/commonjs/dynamicActionProcessor/file/getFileStreamOpenActionProcessor.js.map +1 -0
  37. package/lib/commonjs/dynamicActionProcessor/file/getFileWriteBinaryContentsActionProcessor.js +1 -0
  38. package/lib/commonjs/dynamicActionProcessor/file/getFileWriteBinaryContentsActionProcessor.js.map +1 -0
  39. package/lib/commonjs/dynamicActionProcessor/file/getFileWriteObjectJsonActionProcessor.js +1 -0
  40. package/lib/commonjs/dynamicActionProcessor/file/getFileWriteObjectJsonActionProcessor.js.map +1 -0
  41. package/lib/commonjs/dynamicActionProcessor/file/getFileWriteTextContentsActionProcessor.js +1 -0
  42. package/lib/commonjs/dynamicActionProcessor/file/getFileWriteTextContentsActionProcessor.js.map +1 -0
  43. package/lib/commonjs/dynamicActionProcessor/file/index.js +1 -0
  44. package/lib/commonjs/dynamicActionProcessor/file/index.js.map +1 -0
  45. package/lib/commonjs/dynamicActionProcessor/file/secureUrlUtils.js +1 -0
  46. package/lib/commonjs/dynamicActionProcessor/file/secureUrlUtils.js.map +1 -0
  47. package/lib/commonjs/dynamicActionProcessor/file/types.js +1 -0
  48. package/lib/commonjs/dynamicActionProcessor/file/types.js.map +1 -0
  49. package/lib/commonjs/dynamicActionProcessor/file/utils.js +1 -0
  50. package/lib/commonjs/dynamicActionProcessor/file/utils.js.map +1 -0
  51. package/lib/commonjs/dynamicActionProcessor/index.js +1 -0
  52. package/lib/commonjs/dynamicActionProcessor/index.js.map +1 -0
  53. package/lib/commonjs/index.d.ts +1 -0
  54. package/lib/commonjs/index.js +2 -0
  55. package/lib/commonjs/index.js.map +1 -0
  56. package/lib/commonjs/traceStoryExecution/controllerWorker.d.ts +11 -0
  57. package/lib/commonjs/traceStoryExecution/controllerWorker.js +409 -0
  58. package/lib/commonjs/traceStoryExecution/controllerWorker.js.map +1 -0
  59. package/lib/commonjs/traceStoryExecution/getSystemTraceStoryActionProcessor.d.ts +2 -0
  60. package/lib/commonjs/traceStoryExecution/getSystemTraceStoryActionProcessor.js +47 -0
  61. package/lib/commonjs/traceStoryExecution/getSystemTraceStoryActionProcessor.js.map +1 -0
  62. package/lib/commonjs/traceStoryExecution/index.d.ts +2 -0
  63. package/lib/commonjs/traceStoryExecution/index.js +19 -0
  64. package/lib/commonjs/traceStoryExecution/index.js.map +1 -0
  65. package/lib/commonjs/traceStoryExecution/resolveSourceMaps.d.ts +19 -0
  66. package/lib/commonjs/traceStoryExecution/resolveSourceMaps.js +159 -0
  67. package/lib/commonjs/traceStoryExecution/resolveSourceMaps.js.map +1 -0
  68. package/lib/commonjs/traceStoryExecution/traceStoryExecution.d.ts +17 -0
  69. package/lib/commonjs/traceStoryExecution/traceStoryExecution.js +140 -0
  70. package/lib/commonjs/traceStoryExecution/traceStoryExecution.js.map +1 -0
  71. package/lib/esm/actionProcessor/core/index.js +1 -0
  72. package/lib/esm/actionProcessor/core/index.js.map +1 -0
  73. package/lib/esm/actionProcessor/core/inlineFunction/getInlineFunctionExecuteActionProcessor.js +1 -0
  74. package/lib/esm/actionProcessor/core/inlineFunction/getInlineFunctionExecuteActionProcessor.js.map +1 -0
  75. package/lib/esm/actionProcessor/core/inlineFunction/index.js +1 -0
  76. package/lib/esm/actionProcessor/core/inlineFunction/index.js.map +1 -0
  77. package/lib/esm/actionProcessor/core/stream/getStreamCloseActionProcessor.js +1 -0
  78. package/lib/esm/actionProcessor/core/stream/getStreamCloseActionProcessor.js.map +1 -0
  79. package/lib/esm/actionProcessor/core/stream/getStreamReadActionProcessor.js +1 -0
  80. package/lib/esm/actionProcessor/core/stream/getStreamReadActionProcessor.js.map +1 -0
  81. package/lib/esm/actionProcessor/core/stream/index.js +1 -0
  82. package/lib/esm/actionProcessor/core/stream/index.js.map +1 -0
  83. package/lib/esm/actionProcessor/index.js +1 -0
  84. package/lib/esm/actionProcessor/index.js.map +1 -0
  85. package/lib/esm/actionProcessor/webserver/index.js +1 -0
  86. package/lib/esm/actionProcessor/webserver/index.js.map +1 -0
  87. package/lib/esm/dynamicActionProcessor/file/getFileDeleteActionProcessor.js +1 -0
  88. package/lib/esm/dynamicActionProcessor/file/getFileDeleteActionProcessor.js.map +1 -0
  89. package/lib/esm/dynamicActionProcessor/file/getFileExistsActionProcessor.js +1 -0
  90. package/lib/esm/dynamicActionProcessor/file/getFileExistsActionProcessor.js.map +1 -0
  91. package/lib/esm/dynamicActionProcessor/file/getFileGenerateTemporarySecureUrlActionProcessor.js +1 -0
  92. package/lib/esm/dynamicActionProcessor/file/getFileGenerateTemporarySecureUrlActionProcessor.js.map +1 -0
  93. package/lib/esm/dynamicActionProcessor/file/getFileGenerateTemporaryUploadSecureUrlActionProcessor.js +1 -0
  94. package/lib/esm/dynamicActionProcessor/file/getFileGenerateTemporaryUploadSecureUrlActionProcessor.js.map +1 -0
  95. package/lib/esm/dynamicActionProcessor/file/getFileIsColdStorageActionProcessor.js +1 -0
  96. package/lib/esm/dynamicActionProcessor/file/getFileIsColdStorageActionProcessor.js.map +1 -0
  97. package/lib/esm/dynamicActionProcessor/file/getFileListDirectoryActionProcessor.js +1 -0
  98. package/lib/esm/dynamicActionProcessor/file/getFileListDirectoryActionProcessor.js.map +1 -0
  99. package/lib/esm/dynamicActionProcessor/file/getFileReadBinaryContentsActionProcessor.js +1 -0
  100. package/lib/esm/dynamicActionProcessor/file/getFileReadBinaryContentsActionProcessor.js.map +1 -0
  101. package/lib/esm/dynamicActionProcessor/file/getFileReadObjectJsonActionProcessor.js +1 -0
  102. package/lib/esm/dynamicActionProcessor/file/getFileReadObjectJsonActionProcessor.js.map +1 -0
  103. package/lib/esm/dynamicActionProcessor/file/getFileReadTextContentsActionProcessor.js +1 -0
  104. package/lib/esm/dynamicActionProcessor/file/getFileReadTextContentsActionProcessor.js.map +1 -0
  105. package/lib/esm/dynamicActionProcessor/file/getFileStreamOpenActionProcessor.js +1 -0
  106. package/lib/esm/dynamicActionProcessor/file/getFileStreamOpenActionProcessor.js.map +1 -0
  107. package/lib/esm/dynamicActionProcessor/file/getFileWriteBinaryContentsActionProcessor.js +1 -0
  108. package/lib/esm/dynamicActionProcessor/file/getFileWriteBinaryContentsActionProcessor.js.map +1 -0
  109. package/lib/esm/dynamicActionProcessor/file/getFileWriteObjectJsonActionProcessor.js +1 -0
  110. package/lib/esm/dynamicActionProcessor/file/getFileWriteObjectJsonActionProcessor.js.map +1 -0
  111. package/lib/esm/dynamicActionProcessor/file/getFileWriteTextContentsActionProcessor.js +1 -0
  112. package/lib/esm/dynamicActionProcessor/file/getFileWriteTextContentsActionProcessor.js.map +1 -0
  113. package/lib/esm/dynamicActionProcessor/file/index.js +1 -0
  114. package/lib/esm/dynamicActionProcessor/file/index.js.map +1 -0
  115. package/lib/esm/dynamicActionProcessor/file/secureUrlUtils.js +1 -0
  116. package/lib/esm/dynamicActionProcessor/file/secureUrlUtils.js.map +1 -0
  117. package/lib/esm/dynamicActionProcessor/file/types.js +1 -0
  118. package/lib/esm/dynamicActionProcessor/file/types.js.map +1 -0
  119. package/lib/esm/dynamicActionProcessor/file/utils.js +1 -0
  120. package/lib/esm/dynamicActionProcessor/file/utils.js.map +1 -0
  121. package/lib/esm/dynamicActionProcessor/index.js +1 -0
  122. package/lib/esm/dynamicActionProcessor/index.js.map +1 -0
  123. package/lib/esm/index.d.ts +1 -0
  124. package/lib/esm/index.js +2 -0
  125. package/lib/esm/index.js.map +1 -0
  126. package/lib/esm/traceStoryExecution/controllerWorker.d.ts +11 -0
  127. package/lib/esm/traceStoryExecution/controllerWorker.js +406 -0
  128. package/lib/esm/traceStoryExecution/controllerWorker.js.map +1 -0
  129. package/lib/esm/traceStoryExecution/getSystemTraceStoryActionProcessor.d.ts +2 -0
  130. package/lib/esm/traceStoryExecution/getSystemTraceStoryActionProcessor.js +32 -0
  131. package/lib/esm/traceStoryExecution/getSystemTraceStoryActionProcessor.js.map +1 -0
  132. package/lib/esm/traceStoryExecution/index.d.ts +2 -0
  133. package/lib/esm/traceStoryExecution/index.js +3 -0
  134. package/lib/esm/traceStoryExecution/index.js.map +1 -0
  135. package/lib/esm/traceStoryExecution/resolveSourceMaps.d.ts +19 -0
  136. package/lib/esm/traceStoryExecution/resolveSourceMaps.js +118 -0
  137. package/lib/esm/traceStoryExecution/resolveSourceMaps.js.map +1 -0
  138. package/lib/esm/traceStoryExecution/traceStoryExecution.d.ts +17 -0
  139. package/lib/esm/traceStoryExecution/traceStoryExecution.js +126 -0
  140. package/lib/esm/traceStoryExecution/traceStoryExecution.js.map +1 -0
  141. package/package.json +7 -5
@@ -0,0 +1 @@
1
+ {"version":3,"file":"controllerWorker.js","sourceRoot":"","sources":["../../../src/traceStoryExecution/controllerWorker.ts"],"names":[],"mappings":"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","sourcesContent":["// The debug controller — runs on a WORKER THREAD and drives the V8 inspector against\n// the MAIN thread, which is executing the story replay (see traceStoryExecution).\n//\n// Strategy (chosen by the phase-0 spike, see trace-replay-plan.md): set a breakpoint on\n// every statement position of the traced scripts up front (getPossibleBreakpoints), then\n// plain resume between hits. This survives the yield -> await -> reader.next() chain of\n// the replay loop regardless of async task boundaries, and wastes no pauses on node\n// internals (unlike blackbox + stepInto).\n//\n// SHIPPING CONSTRAINT: lambdas are single-file webpack bundles, so this can't be loaded\n// as a worker FILE — traceStoryExecution serializes this function with\n// Function.prototype.toString() and runs it via new Worker(source, { eval: true }).\n// It must therefore be fully self-contained:\n// - builtin require()s only, nothing captured from module scope\n// - no syntax tsc would downlevel with module-scope helpers under the ES6 target:\n// no async/await (__awaiter), no generators (__generator), no object spread (__assign)\n//\n// Protocol with the parent (traceStoryExecution):\n// worker -> parent: { type: 'ready', tracedScriptUrls } breakpoints armed, start the replay\n// { type: 'trace', steps, scripts, stats } reply to 'done'\n// { type: 'filterLocations', requestId, scriptUrl, locations } onlyOwnCode: map these through the source map\n// { type: 'fatal', error }\n// parent -> worker: { type: 'done' } replay finished, send the trace\n// { type: 'filteredLocations', requestId, locations } reply to 'filterLocations'\n//\n// The story function is located via globalThis.__qpqTraceStoryFunction (set by the\n// parent before spawning): Runtime.evaluate -> [[FunctionLocation]] -> scriptId. Extra\n// scripts (other bundle chunks, dynamically loaded ones) are matched by scriptPatterns.\n\nexport interface TraceControllerWorkerData {\n // Regex sources matched against script urls; matching scripts are traced in addition\n // to the story function's own script.\n scriptPatterns: string[];\n\n // Ask the parent to source-map-filter breakpoint locations so only the service's own\n // code gets breakpoints (the parent holds trace-mapping; this eval worker can't).\n onlyOwnCode: boolean;\n\n maxSteps: number;\n maxTraceMs: number;\n maxValueLength: number;\n maxProperties: number;\n maxValueDepth: number;\n maxSerializedLength: number;\n}\n\ninterface TraceRawValue {\n preview: string;\n json?: string;\n}\n\ninterface TraceRawStep {\n scriptId: string;\n line: number; // 0-based (CDP)\n column: number;\n functionName: string;\n locals: Record<string, TraceRawValue>;\n returnValue?: TraceRawValue;\n}\n\nexport function traceControllerWorkerMain(): void {\n // require, not import: this function body is the ENTIRE worker source (eval mode) —\n // imports at module scope wouldn't exist when it runs. And eval('require'), not a\n // bare require: bundlers rewrite require() calls at build time (webpack lambda builds\n // turn them into __webpack_require__, which doesn't exist when this string is eval'd\n // in the worker) — eval is opaque to them, so the worker's REAL cjs require survives.\n const dynamicRequire = eval('require');\n const inspector = dynamicRequire('node:inspector');\n const workerThreads = dynamicRequire('node:worker_threads');\n\n const parentPort = workerThreads.parentPort;\n const options: TraceControllerWorkerData = workerThreads.workerData;\n\n const session = new inspector.Session();\n session.connectToMainThread();\n\n const post = (method: string, params?: object): Promise<any> =>\n new Promise((resolve, reject) =>\n session.post(method, params || {}, (error: Error | null, result: unknown) =>\n error ? reject(new Error(method + ': ' + error.message)) : resolve(result),\n ),\n );\n\n const fatal = (error: unknown): void => {\n parentPort.postMessage({ type: 'fatal', error: String((error && (error as Error).stack) || error) });\n };\n\n const scriptPatterns = options.scriptPatterns.map((pattern) => new RegExp(pattern));\n const scriptUrlsById = new Map<string, string>();\n const instrumentedScriptIds = new Set<string>();\n\n // The directory of the story function's own script (set during init). Bundles are\n // chunk-SPLIT: a story exported through a factory wrapper (export const x = wrap(story))\n // has its function object created in the FACTORY's chunk, while the code it runs lives\n // in sibling chunks — so every script in the same directory is traced too. This covers\n // any bundle layout (federated /tmp cache, lambda shell, dev-server dist) without\n // needing an environment-specific pattern.\n let storyScriptDirUrl = '';\n\n // CJS require() scripts get plain-path urls, ESM imports get file:// urls — the same\n // directory can appear both ways in one process, so compare scheme-stripped.\n const normalizeScriptUrl = (url: string): string => url.replace(/^file:\\/\\//, '').replace(/\\\\/g, '/');\n\n const isTraceTargetUrl = (url: string): boolean =>\n !!url && (scriptPatterns.some((pattern) => pattern.test(url)) || (!!storyScriptDirUrl && normalizeScriptUrl(url).startsWith(storyScriptDirUrl)));\n\n const steps: TraceRawStep[] = [];\n let pauses = 0;\n let breakpoints = 0;\n let truncated = false;\n let localsCaptureMs = 0;\n let instrumentMs = 0;\n let firstPauseAt = 0;\n let ready = false;\n\n // ── Value summarization ─────────────────────────────────────────────────────\n // RemoteObject -> short display string. Depth comes from generatePreview (one level);\n // the caps keep pathological values from exploding the trace.\n const clampText = (text: string): string => (text.length > options.maxValueLength ? text.slice(0, options.maxValueLength) + '…' : text);\n\n const summarizeValue = (remoteObject: any): string => {\n if (!remoteObject) return 'undefined';\n if (remoteObject.type === 'undefined') return 'undefined';\n if (remoteObject.subtype === 'null') return 'null';\n if (remoteObject.unserializableValue) return remoteObject.unserializableValue;\n if (remoteObject.type === 'string' || remoteObject.type === 'number' || remoteObject.type === 'boolean') {\n return clampText(JSON.stringify(remoteObject.value));\n }\n if (remoteObject.preview) {\n const parts: string[] = [];\n const previewProperties = remoteObject.preview.properties || [];\n for (let i = 0; i < previewProperties.length && i < options.maxProperties; i += 1) {\n const property = previewProperties[i];\n const value = property.type === 'string' ? \"'\" + property.value + \"'\" : property.value;\n parts.push(remoteObject.preview.subtype === 'array' ? value : property.name + ': ' + value);\n }\n const overflow = remoteObject.preview.overflow || previewProperties.length > options.maxProperties ? ', …' : '';\n const body = parts.join(', ') + overflow;\n return clampText(remoteObject.preview.subtype === 'array' ? '[' + body + ']' : '{' + body + '}');\n }\n return clampText(remoteObject.description || remoteObject.type);\n };\n\n // ── Deep serialization ──────────────────────────────────────────────────────\n // Runs IN THE DEBUGGEE (Runtime.callFunctionOn with `this` = the value) at the pause,\n // returning a JSON string of the value walked to the caps — what powers expandable\n // object inspection in the viewer. Property reads are try/catch'd (getters can throw);\n // circular refs and overflow become «...» placeholder strings. Same serialization\n // constraints as this whole file: no async/generators/spread (it ships via toString).\n function qpqSerializeValue(this: any, maxDepth: number, maxString: number, maxProps: number, maxTotal: number): string | null {\n const seen: any[] = [];\n\n const walk = (value: any, depth: number): any => {\n if (value === null || typeof value === 'number' || typeof value === 'boolean') return value;\n if (typeof value === 'string') return value.length > maxString ? value.slice(0, maxString) + '…' : value;\n if (typeof value === 'undefined') return '«undefined»';\n if (typeof value === 'function') return '«function ' + (value.name || '') + '»';\n if (typeof value === 'bigint') return value.toString() + 'n';\n if (typeof value === 'symbol') return value.toString();\n\n if (value instanceof Date) return value.toISOString();\n if (value instanceof Error) return '«' + (value.name || 'Error') + ': ' + value.message + '»';\n if (value instanceof Map) return '«Map(' + value.size + ')»';\n if (value instanceof Set) return '«Set(' + value.size + ')»';\n\n if (depth >= maxDepth) return Array.isArray(value) ? '«array[' + value.length + ']»' : '«object»';\n if (seen.indexOf(value) >= 0) return '«circular»';\n seen.push(value);\n\n let result: any;\n if (Array.isArray(value)) {\n result = [];\n for (let i = 0; i < value.length && i < maxProps; i += 1) {\n try {\n result.push(walk(value[i], depth + 1));\n } catch (error) {\n result.push('«threw»');\n }\n }\n if (value.length > maxProps) result.push('«+' + (value.length - maxProps) + ' more»');\n } else {\n result = {};\n const keys = Object.keys(value);\n for (let i = 0; i < keys.length && i < maxProps; i += 1) {\n try {\n result[keys[i]] = walk(value[keys[i]], depth + 1);\n } catch (error) {\n result[keys[i]] = '«threw»';\n }\n }\n if (keys.length > maxProps) result['«more»'] = '+' + (keys.length - maxProps) + ' properties';\n }\n\n seen.pop();\n return result;\n };\n\n try {\n const json = JSON.stringify(walk(this, 0));\n return json && json.length <= maxTotal ? json : null;\n } catch (error) {\n return null;\n }\n }\n\n const isDeepSerializable = (remoteObject: any): boolean =>\n !!remoteObject && remoteObject.type === 'object' && remoteObject.subtype !== 'null' && !!remoteObject.objectId;\n\n // ── Value capture ───────────────────────────────────────────────────────────\n // Every value gets a short preview; object values also get a deep JSON serialization\n // (in the debuggee, see qpqSerializeValue). Never fails — a value that can't be\n // serialized keeps its preview.\n const captureRemoteValue = (remoteObject: any): { captured: TraceRawValue; work: Promise<unknown> } => {\n const captured: TraceRawValue = { preview: summarizeValue(remoteObject) };\n\n if (!isDeepSerializable(remoteObject)) {\n return { captured, work: Promise.resolve() };\n }\n\n const work = post('Runtime.callFunctionOn', {\n objectId: remoteObject.objectId,\n functionDeclaration: qpqSerializeValue.toString(),\n arguments: [\n { value: options.maxValueDepth },\n { value: options.maxValueLength },\n { value: options.maxProperties },\n { value: options.maxSerializedLength },\n ],\n returnByValue: true,\n }).then(\n (result: any) => {\n if (result && result.result && typeof result.result.value === 'string') {\n captured.json = result.result.value;\n }\n },\n () => undefined,\n );\n\n return { captured, work };\n };\n\n interface CapturedStepValues {\n locals: Record<string, TraceRawValue>;\n returnValue?: TraceRawValue;\n }\n\n // Local + block scopes only, outermost first so inner scopes win name collisions.\n // At a return break position the frame also carries the value being returned.\n const captureStepValues = (frame: any): Promise<CapturedStepValues> => {\n const startedAt = Date.now();\n const values: CapturedStepValues = { locals: {} };\n const scopes = frame.scopeChain\n .filter((scope: any) => (scope.type === 'local' || scope.type === 'block') && scope.object && scope.object.objectId)\n .reverse();\n\n let chain: Promise<unknown> = Promise.resolve();\n scopes.forEach((scope: any) => {\n chain = chain\n .then(() => post('Runtime.getProperties', { objectId: scope.object.objectId, ownProperties: true, generatePreview: true }))\n .then((response: any) => {\n let valueChain: Promise<unknown> = Promise.resolve();\n (response.result || []).forEach((property: any) => {\n const capture = captureRemoteValue(property.value);\n values.locals[property.name] = capture.captured;\n valueChain = valueChain.then(() => capture.work);\n });\n return valueChain;\n });\n });\n\n if (frame.returnValue) {\n const returnCapture = captureRemoteValue(frame.returnValue);\n values.returnValue = returnCapture.captured;\n chain = chain.then(() => returnCapture.work);\n }\n\n return chain.then(() => {\n localsCaptureMs += Date.now() - startedAt;\n return values;\n });\n };\n\n // ── Script instrumentation ──────────────────────────────────────────────────\n // onlyOwnCode: the parent (traceStoryExecution) filters candidate locations through\n // the script's source map — only positions originating in the service's own code\n // (not node_modules) get breakpoints. Round-tripped over parentPort because this\n // worker can't load the source-map library (see the shipping constraint above).\n let filterRequestSeq = 0;\n const pendingFilterRequests = new Map<number, (locations: any[]) => void>();\n\n const filterLocationsViaParent = (scriptId: string, locations: any[]): Promise<any[]> => {\n if (!options.onlyOwnCode || locations.length === 0) return Promise.resolve(locations);\n\n filterRequestSeq += 1;\n const requestId = filterRequestSeq;\n return new Promise((resolve) => {\n pendingFilterRequests.set(requestId, resolve);\n parentPort.postMessage({ type: 'filterLocations', requestId, scriptUrl: scriptUrlsById.get(scriptId) || '', locations });\n });\n };\n\n // getPossibleBreakpoints CAPS its response (~1000 locations) when the range is large —\n // on a real bundle chunk (tens of thousands of lines) a single call covers only the\n // top of the file and everything below it silently gets no breakpoints. Page through\n // the script, restarting just past the last returned location, until a page comes back\n // empty or stops advancing.\n const getAllPossibleBreakpoints = (scriptId: string): Promise<any[]> => {\n const allLocations: any[] = [];\n\n const readPage = (startLine: number, startColumn: number): Promise<any[]> =>\n post('Debugger.getPossibleBreakpoints', { start: { scriptId, lineNumber: startLine, columnNumber: startColumn } }).then((response: any) => {\n const locations = response.locations || [];\n if (locations.length === 0) return allLocations;\n\n locations.forEach((location: any) => allLocations.push(location));\n\n const last = locations[locations.length - 1];\n const nextLine = last.lineNumber;\n const nextColumn = (last.columnNumber || 0) + 1;\n if (nextLine < startLine || (nextLine === startLine && nextColumn <= startColumn)) return allLocations;\n\n return readPage(nextLine, nextColumn);\n });\n\n return readPage(0, 0);\n };\n\n const instrumentScript = (scriptId: string): Promise<void> => {\n if (instrumentedScriptIds.has(scriptId)) return Promise.resolve();\n instrumentedScriptIds.add(scriptId);\n\n return getAllPossibleBreakpoints(scriptId)\n .then((locations: any[]) => filterLocationsViaParent(scriptId, locations))\n .then((locations: any[]) => {\n // PIPELINED, not chained: a service's chunks can hold tens of thousands of\n // statement positions, and awaiting each setBreakpoint round-trip serially made\n // instrumentation the dominant setup cost (it blew the ready timeout on real\n // services). The session queues the posts; the backend processes them in order.\n // Per-location failures are tolerated: nearby candidate positions can RESOLVE to\n // the same actual breakpoint (\"already exists\") — one lost position must not\n // abort the whole trace.\n return Promise.all(\n locations.map((location: any) =>\n post('Debugger.setBreakpoint', { location }).then(\n () => {\n breakpoints += 1;\n },\n () => undefined,\n ),\n ),\n ).then(() => undefined);\n });\n };\n\n session.on('Debugger.scriptParsed', (message: any) => {\n const url = message.params.url || '';\n scriptUrlsById.set(message.params.scriptId, url);\n\n // A traced bundle chunk loaded mid-story (async-node chunk loading) — instrument it\n // as it appears so its statements are traced too.\n if (ready && isTraceTargetUrl(url)) {\n instrumentScript(message.params.scriptId).catch(fatal);\n }\n });\n\n // ── Pause loop ──────────────────────────────────────────────────────────────\n const onPaused = (message: any): Promise<unknown> => {\n pauses += 1;\n if (!firstPauseAt) firstPauseAt = Date.now();\n const frame = message.params.callFrames[0];\n\n // Non-traced pause (e.g. the debugger; statement in qpqExecuteLog) — just resume.\n if (!instrumentedScriptIds.has(frame.location.scriptId)) {\n return post('Debugger.resume');\n }\n\n // Step budget AND wall-clock budget: locals capture costs several CDP round trips\n // per step, so a big story can take MINUTES against maxSteps alone — long-running\n // invocations stress their whole sandbox (a >5min trace exposed a 300s long-poll\n // timeout bug in the qpq-log-extension, killing the lambda). Past either budget,\n // stop pausing entirely so the replay finishes at full speed.\n if (steps.length >= options.maxSteps || Date.now() - firstPauseAt > options.maxTraceMs) {\n truncated = true;\n return post('Debugger.setBreakpointsActive', { active: false }).then(() => post('Debugger.resume'));\n }\n\n return captureStepValues(frame)\n .then((values) => {\n const step: TraceRawStep = {\n scriptId: frame.location.scriptId,\n line: frame.location.lineNumber,\n column: frame.location.columnNumber,\n functionName: frame.functionName || '',\n locals: values.locals,\n };\n if (values.returnValue) {\n step.returnValue = values.returnValue;\n }\n steps.push(step);\n })\n .then(() => post('Debugger.resume'));\n };\n\n session.on('Debugger.paused', (message: any) => {\n onPaused(message).catch(fatal);\n });\n\n // ── Parent protocol (also keeps the worker's event loop alive — an inspector\n // session alone does not, the worker would silently exit) ────────────────────\n parentPort.on('message', (message: any) => {\n if (message && message.type === 'filteredLocations') {\n const resolveFilter = pendingFilterRequests.get(message.requestId);\n if (resolveFilter) {\n pendingFilterRequests.delete(message.requestId);\n resolveFilter(message.locations || []);\n }\n return;\n }\n\n if (message && message.type === 'done') {\n const scripts: Record<string, string> = {};\n scriptUrlsById.forEach((url, scriptId) => {\n scripts[scriptId] = url;\n });\n const instrumentedScriptUrls: string[] = [];\n instrumentedScriptIds.forEach((scriptId) => {\n instrumentedScriptUrls.push(scriptUrlsById.get(scriptId) || scriptId);\n });\n parentPort.postMessage({\n type: 'trace',\n steps,\n scripts,\n stats: { pauses, breakpoints, localsCaptureMs, truncated, instrumentMs, instrumentedScriptUrls },\n });\n }\n });\n\n // ── Init: enable domains, find the story function's script, arm breakpoints ──\n const initStartedAt = Date.now();\n post('Runtime.enable')\n .then(() => post('Debugger.enable'))\n .then(() => post('Runtime.evaluate', { expression: 'globalThis.__qpqTraceStoryFunction' }))\n .then((evaluation: any) => {\n const objectId = evaluation && evaluation.result && evaluation.result.objectId;\n if (!objectId) return null;\n return post('Runtime.getProperties', { objectId, ownProperties: true }).then((response: any) => {\n const functionLocation = (response.internalProperties || []).find((property: any) => property.name === '[[FunctionLocation]]');\n const location = functionLocation && functionLocation.value && functionLocation.value.value;\n return location ? location.scriptId : null;\n });\n })\n .then((storyFunctionScriptId: string | null) => {\n const targetScriptIds = new Set<string>();\n if (storyFunctionScriptId) {\n targetScriptIds.add(storyFunctionScriptId);\n\n const storyScriptUrl = normalizeScriptUrl(scriptUrlsById.get(storyFunctionScriptId) || '');\n storyScriptDirUrl = storyScriptUrl.slice(0, storyScriptUrl.lastIndexOf('/') + 1);\n }\n\n scriptUrlsById.forEach((url, scriptId) => {\n if (isTraceTargetUrl(url)) targetScriptIds.add(scriptId);\n });\n\n if (targetScriptIds.size === 0) {\n throw new Error('trace controller found no scripts to trace (no story function location, no scriptPatterns match)');\n }\n\n const instrumentations: Promise<void>[] = [];\n targetScriptIds.forEach((scriptId) => {\n instrumentations.push(instrumentScript(scriptId));\n });\n return Promise.all(instrumentations).then(() => targetScriptIds);\n })\n .then((targetScriptIds: any) => {\n ready = true;\n instrumentMs = Date.now() - initStartedAt;\n const tracedScriptUrls: string[] = [];\n targetScriptIds.forEach((scriptId: string) => tracedScriptUrls.push(scriptUrlsById.get(scriptId) || scriptId));\n parentPort.postMessage({ type: 'ready', tracedScriptUrls });\n })\n .catch(fatal);\n}\n"]}
@@ -0,0 +1,2 @@
1
+ import { ActionProcessorListResolver } from 'quidproquo-core';
2
+ export declare const getSystemTraceStoryActionProcessor: (defaultScriptPatterns?: string[]) => ActionProcessorListResolver;
@@ -0,0 +1,32 @@
1
+ import { actionResult, actionResultError, ErrorTypeEnum, SystemActionType, } from 'quidproquo-core';
2
+ import { traceStoryExecution } from './traceStoryExecution';
3
+ // Shared System::TraceStory processor for node runtimes (lambda and the dev server).
4
+ // Loads the recorded story's real code through the runtime's dynamicModuleLoader (which
5
+ // federates on lambda), then replays it under the tracer. defaultScriptPatterns lets the
6
+ // host add environment-specific scripts to trace (e.g. the lambda federated code cache).
7
+ const getProcessTraceStory = (qpqConfig, defaultScriptPatterns) => {
8
+ return async (payload, session, actionProcessors, logger, updateSession, dynamicModuleLoader) => {
9
+ const { storyResult, scriptPatterns, onlyOwnCode } = payload;
10
+ if (!storyResult.qpqFunctionRuntimeInfo) {
11
+ return actionResultError(ErrorTypeEnum.BadRequest, `Story [${storyResult.correlation}] has no qpqFunctionRuntimeInfo - cannot locate its code to trace`);
12
+ }
13
+ const story = await dynamicModuleLoader(storyResult.qpqFunctionRuntimeInfo);
14
+ if (!story) {
15
+ return actionResultError(ErrorTypeEnum.NotFound, `Unable to dynamically load story for [${storyResult.correlation}]`);
16
+ }
17
+ try {
18
+ const { trace } = await traceStoryExecution(storyResult, story, {
19
+ scriptPatterns: [...defaultScriptPatterns, ...(scriptPatterns || [])],
20
+ onlyOwnCode,
21
+ });
22
+ return actionResult(trace);
23
+ }
24
+ catch (error) {
25
+ return actionResultError(ErrorTypeEnum.GenericError, `Trace failed for [${storyResult.correlation}]: ${error.message}`);
26
+ }
27
+ };
28
+ };
29
+ export const getSystemTraceStoryActionProcessor = (defaultScriptPatterns = []) => async (qpqConfig) => ({
30
+ [SystemActionType.TraceStory]: getProcessTraceStory(qpqConfig, defaultScriptPatterns),
31
+ });
32
+ //# sourceMappingURL=getSystemTraceStoryActionProcessor.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"getSystemTraceStoryActionProcessor.js","sourceRoot":"","sources":["../../../src/traceStoryExecution/getSystemTraceStoryActionProcessor.ts"],"names":[],"mappings":"AAAA,OAAO,EAGL,YAAY,EACZ,iBAAiB,EAEjB,aAAa,EAKb,gBAAgB,GAGjB,MAAM,iBAAiB,CAAC;AAEzB,OAAO,EAAE,mBAAmB,EAAE,MAAM,uBAAuB,CAAC;AAE5D,qFAAqF;AACrF,wFAAwF;AACxF,yFAAyF;AACzF,yFAAyF;AACzF,MAAM,oBAAoB,GAAG,CAAC,SAAoB,EAAE,qBAA+B,EAAmC,EAAE;IACtH,OAAO,KAAK,EACV,OAAsC,EACtC,OAAqB,EACrB,gBAAqC,EACrC,MAAiB,EACjB,aAAkC,EAClC,mBAAwC,EACxC,EAAE;QACF,MAAM,EAAE,WAAW,EAAE,cAAc,EAAE,WAAW,EAAE,GAAG,OAAO,CAAC;QAE7D,IAAI,CAAC,WAAW,CAAC,sBAAsB,EAAE,CAAC;YACxC,OAAO,iBAAiB,CACtB,aAAa,CAAC,UAAU,EACxB,UAAU,WAAW,CAAC,WAAW,mEAAmE,CACrG,CAAC;QACJ,CAAC;QAED,MAAM,KAAK,GAAG,MAAM,mBAAmB,CAAC,WAAW,CAAC,sBAAsB,CAAC,CAAC;QAC5E,IAAI,CAAC,KAAK,EAAE,CAAC;YACX,OAAO,iBAAiB,CAAC,aAAa,CAAC,QAAQ,EAAE,yCAAyC,WAAW,CAAC,WAAW,GAAG,CAAC,CAAC;QACxH,CAAC;QAED,IAAI,CAAC;YACH,MAAM,EAAE,KAAK,EAAE,GAAG,MAAM,mBAAmB,CAAC,WAAW,EAAE,KAAK,EAAE;gBAC9D,cAAc,EAAE,CAAC,GAAG,qBAAqB,EAAE,GAAG,CAAC,cAAc,IAAI,EAAE,CAAC,CAAC;gBACrE,WAAW;aACZ,CAAC,CAAC;YAEH,OAAO,YAAY,CAAC,KAAK,CAAC,CAAC;QAC7B,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,OAAO,iBAAiB,CAAC,aAAa,CAAC,YAAY,EAAE,qBAAqB,WAAW,CAAC,WAAW,MAAO,KAAe,CAAC,OAAO,EAAE,CAAC,CAAC;QACrI,CAAC;IACH,CAAC,CAAC;AACJ,CAAC,CAAC;AAEF,MAAM,CAAC,MAAM,kCAAkC,GAC7C,CAAC,wBAAkC,EAAE,EAA+B,EAAE,CACtE,KAAK,EAAE,SAAoB,EAAgC,EAAE,CAAC,CAAC;IAC7D,CAAC,gBAAgB,CAAC,UAAU,CAAC,EAAE,oBAAoB,CAAC,SAAS,EAAE,qBAAqB,CAAC;CACtF,CAAC,CAAC","sourcesContent":["import {\n ActionProcessorList,\n ActionProcessorListResolver,\n actionResult,\n actionResultError,\n DynamicModuleLoader,\n ErrorTypeEnum,\n QPQConfig,\n QpqLogger,\n StorySession,\n StorySessionUpdater,\n SystemActionType,\n SystemTraceStoryActionPayload,\n SystemTraceStoryActionProcessor,\n} from 'quidproquo-core';\n\nimport { traceStoryExecution } from './traceStoryExecution';\n\n// Shared System::TraceStory processor for node runtimes (lambda and the dev server).\n// Loads the recorded story's real code through the runtime's dynamicModuleLoader (which\n// federates on lambda), then replays it under the tracer. defaultScriptPatterns lets the\n// host add environment-specific scripts to trace (e.g. the lambda federated code cache).\nconst getProcessTraceStory = (qpqConfig: QPQConfig, defaultScriptPatterns: string[]): SystemTraceStoryActionProcessor => {\n return async (\n payload: SystemTraceStoryActionPayload,\n session: StorySession,\n actionProcessors: ActionProcessorList,\n logger: QpqLogger,\n updateSession: StorySessionUpdater,\n dynamicModuleLoader: DynamicModuleLoader,\n ) => {\n const { storyResult, scriptPatterns, onlyOwnCode } = payload;\n\n if (!storyResult.qpqFunctionRuntimeInfo) {\n return actionResultError(\n ErrorTypeEnum.BadRequest,\n `Story [${storyResult.correlation}] has no qpqFunctionRuntimeInfo - cannot locate its code to trace`,\n );\n }\n\n const story = await dynamicModuleLoader(storyResult.qpqFunctionRuntimeInfo);\n if (!story) {\n return actionResultError(ErrorTypeEnum.NotFound, `Unable to dynamically load story for [${storyResult.correlation}]`);\n }\n\n try {\n const { trace } = await traceStoryExecution(storyResult, story, {\n scriptPatterns: [...defaultScriptPatterns, ...(scriptPatterns || [])],\n onlyOwnCode,\n });\n\n return actionResult(trace);\n } catch (error) {\n return actionResultError(ErrorTypeEnum.GenericError, `Trace failed for [${storyResult.correlation}]: ${(error as Error).message}`);\n }\n };\n};\n\nexport const getSystemTraceStoryActionProcessor =\n (defaultScriptPatterns: string[] = []): ActionProcessorListResolver =>\n async (qpqConfig: QPQConfig): Promise<ActionProcessorList> => ({\n [SystemActionType.TraceStory]: getProcessTraceStory(qpqConfig, defaultScriptPatterns),\n });\n"]}
@@ -0,0 +1,2 @@
1
+ export * from './getSystemTraceStoryActionProcessor';
2
+ export * from './traceStoryExecution';
@@ -0,0 +1,3 @@
1
+ export * from './getSystemTraceStoryActionProcessor';
2
+ export * from './traceStoryExecution';
3
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/traceStoryExecution/index.ts"],"names":[],"mappings":"AAAA,cAAc,sCAAsC,CAAC;AACrD,cAAc,uBAAuB,CAAC","sourcesContent":["export * from './getSystemTraceStoryActionProcessor';\nexport * from './traceStoryExecution';\n"]}
@@ -0,0 +1,19 @@
1
+ import { QpqExecutionTraceSource, QpqExecutionTraceStep, QpqExecutionTraceValue } from 'quidproquo-core';
2
+ interface RawTraceStep {
3
+ scriptId: string;
4
+ line: number;
5
+ column: number;
6
+ functionName: string;
7
+ locals: Record<string, QpqExecutionTraceValue>;
8
+ returnValue?: QpqExecutionTraceValue;
9
+ }
10
+ export declare const filterOwnCodeLocations: <TLocation extends {
11
+ lineNumber: number;
12
+ columnNumber?: number;
13
+ }>(scriptUrl: string, locations: TLocation[]) => TLocation[];
14
+ export interface ResolvedTraceSteps {
15
+ sources: QpqExecutionTraceSource[];
16
+ steps: QpqExecutionTraceStep[];
17
+ }
18
+ export declare const resolveSourceMappedSteps: (rawSteps: RawTraceStep[], scriptUrlsById: Record<string, string>) => ResolvedTraceSteps;
19
+ export {};
@@ -0,0 +1,118 @@
1
+ // Post-processing: map the controller's raw steps (generated script positions) back to
2
+ // original sources via the .map files sitting next to the traced scripts on disk —
3
+ // the same files the federated store syncs to /tmp alongside the code. When a map
4
+ // carries sourcesContent (the federated remote build embeds it), the original source
5
+ // text is embedded in the trace so viewers need no access to the repo.
6
+ import * as fs from 'fs';
7
+ import * as path from 'path';
8
+ import { fileURLToPath } from 'url';
9
+ import { originalPositionFor, sourceContentFor, TraceMap } from '@jridgewell/trace-mapping';
10
+ const scriptUrlToPath = (scriptUrl) => (scriptUrl.startsWith('file://') ? fileURLToPath(scriptUrl) : scriptUrl);
11
+ // The LAST sourceMappingURL comment wins (bundles can contain earlier ones from inlined
12
+ // third-party code).
13
+ const findSourceMappingUrl = (scriptText) => {
14
+ const matches = scriptText.match(/\/\/[#@] sourceMappingURL=(\S+)/g);
15
+ if (!matches || matches.length === 0)
16
+ return null;
17
+ return matches[matches.length - 1].replace(/\/\/[#@] sourceMappingURL=/, '');
18
+ };
19
+ const loadTraceMap = (scriptPath) => {
20
+ try {
21
+ const scriptText = fs.readFileSync(scriptPath, 'utf8');
22
+ const sourceMappingUrl = findSourceMappingUrl(scriptText);
23
+ if (!sourceMappingUrl)
24
+ return null;
25
+ if (sourceMappingUrl.startsWith('data:')) {
26
+ const base64Match = sourceMappingUrl.match(/^data:application\/json[^,]*;base64,(.*)$/);
27
+ const json = base64Match
28
+ ? Buffer.from(base64Match[1], 'base64').toString('utf8')
29
+ : decodeURIComponent(sourceMappingUrl.replace(/^data:[^,]*,/, ''));
30
+ return new TraceMap(json);
31
+ }
32
+ const mapPath = path.resolve(path.dirname(scriptPath), sourceMappingUrl);
33
+ return new TraceMap(fs.readFileSync(mapPath, 'utf8'));
34
+ }
35
+ catch {
36
+ // No map is a degraded trace, not a failure — generated positions still tell the story
37
+ return null;
38
+ }
39
+ };
40
+ // Which candidate breakpoint positions land in the service's OWN code — answers the
41
+ // controller worker's filterLocations request when onlyOwnCode tracing is on (the eval
42
+ // worker can't load trace-mapping itself). Positions mapping into node_modules
43
+ // (framework/deps) or not mapping at all (webpack runtime glue) are dropped. No map
44
+ // means the bundle can't be classified — everything stays traced.
45
+ export const filterOwnCodeLocations = (scriptUrl, locations) => {
46
+ const traceMap = scriptUrl ? loadTraceMap(scriptUrlToPath(scriptUrl)) : null;
47
+ if (!traceMap) {
48
+ return locations;
49
+ }
50
+ return locations.filter((location) => {
51
+ const original = originalPositionFor(traceMap, { line: location.lineNumber + 1, column: location.columnNumber ?? 0 });
52
+ return !!original.source && !original.source.includes('node_modules');
53
+ });
54
+ };
55
+ export const resolveSourceMappedSteps = (rawSteps, scriptUrlsById) => {
56
+ const traceMapsByScriptId = new Map();
57
+ const sourceIndexByPath = new Map();
58
+ const sources = [];
59
+ const getTraceMap = (scriptId) => {
60
+ if (!traceMapsByScriptId.has(scriptId)) {
61
+ const scriptUrl = scriptUrlsById[scriptId];
62
+ traceMapsByScriptId.set(scriptId, scriptUrl ? loadTraceMap(scriptUrlToPath(scriptUrl)) : null);
63
+ }
64
+ return traceMapsByScriptId.get(scriptId) ?? null;
65
+ };
66
+ const getSourceIndex = (sourcePath, content) => {
67
+ const existing = sourceIndexByPath.get(sourcePath);
68
+ if (existing !== undefined)
69
+ return existing;
70
+ const index = sources.length;
71
+ sources.push(content !== undefined ? { path: sourcePath, content } : { path: sourcePath });
72
+ sourceIndexByPath.set(sourcePath, index);
73
+ return index;
74
+ };
75
+ // Unmapped fallback: the generated script itself becomes the source, content included
76
+ // so the viewer can still render something.
77
+ const getGeneratedSourceIndex = (scriptId) => {
78
+ const scriptUrl = scriptUrlsById[scriptId] || scriptId;
79
+ const existing = sourceIndexByPath.get(scriptUrl);
80
+ if (existing !== undefined)
81
+ return existing;
82
+ let content;
83
+ try {
84
+ content = fs.readFileSync(scriptUrlToPath(scriptUrl), 'utf8');
85
+ }
86
+ catch {
87
+ content = undefined;
88
+ }
89
+ return getSourceIndex(scriptUrl, content);
90
+ };
91
+ const steps = rawSteps.map((rawStep) => {
92
+ const traceMap = getTraceMap(rawStep.scriptId);
93
+ if (traceMap) {
94
+ const original = originalPositionFor(traceMap, { line: rawStep.line + 1, column: rawStep.column });
95
+ if (original.source) {
96
+ const content = sourceContentFor(traceMap, original.source) ?? undefined;
97
+ return {
98
+ sourceIndex: getSourceIndex(original.source, content),
99
+ line: original.line ?? rawStep.line + 1,
100
+ column: original.column ?? rawStep.column,
101
+ functionName: rawStep.functionName,
102
+ locals: rawStep.locals,
103
+ returnValue: rawStep.returnValue,
104
+ };
105
+ }
106
+ }
107
+ return {
108
+ sourceIndex: getGeneratedSourceIndex(rawStep.scriptId),
109
+ line: rawStep.line + 1,
110
+ column: rawStep.column,
111
+ functionName: rawStep.functionName,
112
+ locals: rawStep.locals,
113
+ returnValue: rawStep.returnValue,
114
+ };
115
+ });
116
+ return { sources, steps };
117
+ };
118
+ //# sourceMappingURL=resolveSourceMaps.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"resolveSourceMaps.js","sourceRoot":"","sources":["../../../src/traceStoryExecution/resolveSourceMaps.ts"],"names":[],"mappings":"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","sourcesContent":["// Post-processing: map the controller's raw steps (generated script positions) back to\n// original sources via the .map files sitting next to the traced scripts on disk —\n// the same files the federated store syncs to /tmp alongside the code. When a map\n// carries sourcesContent (the federated remote build embeds it), the original source\n// text is embedded in the trace so viewers need no access to the repo.\n\nimport { QpqExecutionTraceSource, QpqExecutionTraceStep, QpqExecutionTraceValue } from 'quidproquo-core';\n\nimport * as fs from 'fs';\nimport * as path from 'path';\nimport { fileURLToPath } from 'url';\nimport { originalPositionFor, sourceContentFor, TraceMap } from '@jridgewell/trace-mapping';\n\ninterface RawTraceStep {\n scriptId: string;\n line: number; // 0-based (CDP)\n column: number;\n functionName: string;\n locals: Record<string, QpqExecutionTraceValue>;\n returnValue?: QpqExecutionTraceValue;\n}\n\nconst scriptUrlToPath = (scriptUrl: string): string => (scriptUrl.startsWith('file://') ? fileURLToPath(scriptUrl) : scriptUrl);\n\n// The LAST sourceMappingURL comment wins (bundles can contain earlier ones from inlined\n// third-party code).\nconst findSourceMappingUrl = (scriptText: string): string | null => {\n const matches = scriptText.match(/\\/\\/[#@] sourceMappingURL=(\\S+)/g);\n if (!matches || matches.length === 0) return null;\n return matches[matches.length - 1].replace(/\\/\\/[#@] sourceMappingURL=/, '');\n};\n\nconst loadTraceMap = (scriptPath: string): TraceMap | null => {\n try {\n const scriptText = fs.readFileSync(scriptPath, 'utf8');\n const sourceMappingUrl = findSourceMappingUrl(scriptText);\n if (!sourceMappingUrl) return null;\n\n if (sourceMappingUrl.startsWith('data:')) {\n const base64Match = sourceMappingUrl.match(/^data:application\\/json[^,]*;base64,(.*)$/);\n const json = base64Match\n ? Buffer.from(base64Match[1], 'base64').toString('utf8')\n : decodeURIComponent(sourceMappingUrl.replace(/^data:[^,]*,/, ''));\n return new TraceMap(json);\n }\n\n const mapPath = path.resolve(path.dirname(scriptPath), sourceMappingUrl);\n return new TraceMap(fs.readFileSync(mapPath, 'utf8'));\n } catch {\n // No map is a degraded trace, not a failure — generated positions still tell the story\n return null;\n }\n};\n\n// Which candidate breakpoint positions land in the service's OWN code — answers the\n// controller worker's filterLocations request when onlyOwnCode tracing is on (the eval\n// worker can't load trace-mapping itself). Positions mapping into node_modules\n// (framework/deps) or not mapping at all (webpack runtime glue) are dropped. No map\n// means the bundle can't be classified — everything stays traced.\nexport const filterOwnCodeLocations = <TLocation extends { lineNumber: number; columnNumber?: number }>(\n scriptUrl: string,\n locations: TLocation[],\n): TLocation[] => {\n const traceMap = scriptUrl ? loadTraceMap(scriptUrlToPath(scriptUrl)) : null;\n if (!traceMap) {\n return locations;\n }\n\n return locations.filter((location) => {\n const original = originalPositionFor(traceMap, { line: location.lineNumber + 1, column: location.columnNumber ?? 0 });\n return !!original.source && !original.source.includes('node_modules');\n });\n};\n\nexport interface ResolvedTraceSteps {\n sources: QpqExecutionTraceSource[];\n steps: QpqExecutionTraceStep[];\n}\n\nexport const resolveSourceMappedSteps = (rawSteps: RawTraceStep[], scriptUrlsById: Record<string, string>): ResolvedTraceSteps => {\n const traceMapsByScriptId = new Map<string, TraceMap | null>();\n const sourceIndexByPath = new Map<string, number>();\n const sources: QpqExecutionTraceSource[] = [];\n\n const getTraceMap = (scriptId: string): TraceMap | null => {\n if (!traceMapsByScriptId.has(scriptId)) {\n const scriptUrl = scriptUrlsById[scriptId];\n traceMapsByScriptId.set(scriptId, scriptUrl ? loadTraceMap(scriptUrlToPath(scriptUrl)) : null);\n }\n return traceMapsByScriptId.get(scriptId) ?? null;\n };\n\n const getSourceIndex = (sourcePath: string, content?: string): number => {\n const existing = sourceIndexByPath.get(sourcePath);\n if (existing !== undefined) return existing;\n\n const index = sources.length;\n sources.push(content !== undefined ? { path: sourcePath, content } : { path: sourcePath });\n sourceIndexByPath.set(sourcePath, index);\n return index;\n };\n\n // Unmapped fallback: the generated script itself becomes the source, content included\n // so the viewer can still render something.\n const getGeneratedSourceIndex = (scriptId: string): number => {\n const scriptUrl = scriptUrlsById[scriptId] || scriptId;\n const existing = sourceIndexByPath.get(scriptUrl);\n if (existing !== undefined) return existing;\n\n let content: string | undefined;\n try {\n content = fs.readFileSync(scriptUrlToPath(scriptUrl), 'utf8');\n } catch {\n content = undefined;\n }\n return getSourceIndex(scriptUrl, content);\n };\n\n const steps = rawSteps.map((rawStep): QpqExecutionTraceStep => {\n const traceMap = getTraceMap(rawStep.scriptId);\n\n if (traceMap) {\n const original = originalPositionFor(traceMap, { line: rawStep.line + 1, column: rawStep.column });\n if (original.source) {\n const content = sourceContentFor(traceMap, original.source) ?? undefined;\n return {\n sourceIndex: getSourceIndex(original.source, content),\n line: original.line ?? rawStep.line + 1,\n column: original.column ?? rawStep.column,\n functionName: rawStep.functionName,\n locals: rawStep.locals,\n returnValue: rawStep.returnValue,\n };\n }\n }\n\n return {\n sourceIndex: getGeneratedSourceIndex(rawStep.scriptId),\n line: rawStep.line + 1,\n column: rawStep.column,\n functionName: rawStep.functionName,\n locals: rawStep.locals,\n returnValue: rawStep.returnValue,\n };\n });\n\n return { sources, steps };\n};\n"]}
@@ -0,0 +1,17 @@
1
+ import { ActionProcessorList, QpqExecutionTrace, StoryResult } from 'quidproquo-core';
2
+ export interface TraceStoryExecutionOptions {
3
+ scriptPatterns?: string[];
4
+ onlyOwnCode?: boolean;
5
+ maxSteps?: number;
6
+ maxTraceMs?: number;
7
+ maxValueLength?: number;
8
+ maxProperties?: number;
9
+ maxValueDepth?: number;
10
+ maxSerializedLength?: number;
11
+ overrides?: ActionProcessorList;
12
+ }
13
+ export interface TraceStoryExecutionResult {
14
+ trace: QpqExecutionTrace;
15
+ replay: StoryResult<any>;
16
+ }
17
+ export declare const traceStoryExecution: (storyResult: StoryResult<any>, runtime: any, options?: TraceStoryExecutionOptions) => Promise<TraceStoryExecutionResult>;
@@ -0,0 +1,126 @@
1
+ // traceStoryExecution — replay a StoryResult log against real story code and record a
2
+ // line-by-line execution trace: every statement executed, with local variable values.
3
+ //
4
+ // Wraps qpqExecuteLog (deterministic replay: every impure action is answered from the
5
+ // log's history), while a worker-thread debug controller (see controllerWorker.ts)
6
+ // drives the V8 inspector against this thread and captures each statement + locals.
7
+ // Because the replay is deterministic, the recorded trace carries the same information
8
+ // an interactive debug session would. See trace-replay-plan.md.
9
+ //
10
+ // The CALLER must run on the process MAIN THREAD (lambda handlers and the dev server
11
+ // do) — inspector.Session.connectToMainThread only targets the main thread.
12
+ import { getQpqIsoDateTimeFromDate, qpqExecuteLog } from 'quidproquo-core';
13
+ import { Worker } from 'worker_threads';
14
+ import { traceControllerWorkerMain } from './controllerWorker';
15
+ import { filterOwnCodeLocations, resolveSourceMappedSteps } from './resolveSourceMaps';
16
+ // Ready covers domain enable + breakpoint installation across every traced chunk —
17
+ // generous because the service function running this has minutes of budget, and an
18
+ // abort here wastes a replay that would have succeeded (instrumentMs in the trace stats
19
+ // shows the real cost).
20
+ const READY_TIMEOUT_MS = 120_000;
21
+ const TRACE_TIMEOUT_MS = 60_000;
22
+ // One trace at a time per process: the controller owns process-wide debugger state
23
+ // (breakpoints, pause handling), and the story function handoff is a global.
24
+ let traceInFlight = false;
25
+ const waitForControllerMessage = (controller, type, timeoutMs) => new Promise((resolve, reject) => {
26
+ const cleanUp = () => {
27
+ controller.off('message', onMessage);
28
+ controller.off('error', onError);
29
+ controller.off('exit', onExit);
30
+ clearTimeout(timeout);
31
+ };
32
+ const onMessage = (message) => {
33
+ if (message?.type === type) {
34
+ cleanUp();
35
+ resolve(message);
36
+ }
37
+ else if (message?.type === 'fatal') {
38
+ cleanUp();
39
+ reject(new Error(`trace controller failed: ${message.error}`));
40
+ }
41
+ };
42
+ const onError = (error) => {
43
+ cleanUp();
44
+ reject(error);
45
+ };
46
+ const onExit = (code) => {
47
+ cleanUp();
48
+ reject(new Error(`trace controller exited early with code [${code}]`));
49
+ };
50
+ const timeout = setTimeout(() => {
51
+ cleanUp();
52
+ reject(new Error(`timed out after ${timeoutMs}ms waiting for trace controller [${type}]`));
53
+ }, timeoutMs);
54
+ controller.on('message', onMessage);
55
+ controller.on('error', onError);
56
+ controller.on('exit', onExit);
57
+ });
58
+ export const traceStoryExecution = async (storyResult, runtime, options = {}) => {
59
+ if (traceInFlight) {
60
+ throw new Error('a story trace is already in progress in this process');
61
+ }
62
+ traceInFlight = true;
63
+ // The controller locates the story's script through this global ([[FunctionLocation]])
64
+ globalThis.__qpqTraceStoryFunction = runtime;
65
+ const workerData = {
66
+ scriptPatterns: options.scriptPatterns ?? [],
67
+ onlyOwnCode: options.onlyOwnCode ?? false,
68
+ maxSteps: options.maxSteps ?? 20_000,
69
+ maxTraceMs: options.maxTraceMs ?? 120_000,
70
+ maxValueLength: options.maxValueLength ?? 1_000,
71
+ maxProperties: options.maxProperties ?? 32,
72
+ maxValueDepth: options.maxValueDepth ?? 4,
73
+ maxSerializedLength: options.maxSerializedLength ?? 30_000,
74
+ };
75
+ // Lambdas ship as single-file webpack bundles, so the controller can't be a worker
76
+ // FILE on disk — it's serialized and run as an eval worker (see controllerWorker.ts).
77
+ const controller = new Worker(`(${traceControllerWorkerMain.toString()})()`, {
78
+ eval: true,
79
+ workerData,
80
+ });
81
+ // onlyOwnCode: the worker can't load trace-mapping (eval worker, builtin requires
82
+ // only), so it round-trips candidate breakpoint locations here for source-map
83
+ // filtering. Attached before the ready-wait — instrumentation happens during init.
84
+ controller.on('message', (message) => {
85
+ if (message?.type === 'filterLocations') {
86
+ controller.postMessage({
87
+ type: 'filteredLocations',
88
+ requestId: message.requestId,
89
+ locations: filterOwnCodeLocations(message.scriptUrl, message.locations || []),
90
+ });
91
+ }
92
+ });
93
+ try {
94
+ await waitForControllerMessage(controller, 'ready', READY_TIMEOUT_MS);
95
+ const replayStartedAt = Date.now();
96
+ const replay = await qpqExecuteLog(storyResult, runtime, options.overrides);
97
+ const replayMs = Date.now() - replayStartedAt;
98
+ const tracePromise = waitForControllerMessage(controller, 'trace', TRACE_TIMEOUT_MS);
99
+ controller.postMessage({ type: 'done' });
100
+ const rawTrace = await tracePromise;
101
+ const { sources, steps } = resolveSourceMappedSteps(rawTrace.steps, rawTrace.scripts);
102
+ const trace = {
103
+ correlation: storyResult.correlation,
104
+ moduleName: storyResult.moduleName,
105
+ tracedAt: getQpqIsoDateTimeFromDate(new Date()),
106
+ truncated: rawTrace.stats.truncated,
107
+ sources,
108
+ steps,
109
+ stats: {
110
+ pauses: rawTrace.stats.pauses,
111
+ breakpoints: rawTrace.stats.breakpoints,
112
+ replayMs,
113
+ localsCaptureMs: rawTrace.stats.localsCaptureMs,
114
+ instrumentMs: rawTrace.stats.instrumentMs,
115
+ instrumentedScriptUrls: rawTrace.stats.instrumentedScriptUrls,
116
+ },
117
+ };
118
+ return { trace, replay };
119
+ }
120
+ finally {
121
+ delete globalThis.__qpqTraceStoryFunction;
122
+ traceInFlight = false;
123
+ await controller.terminate();
124
+ }
125
+ };
126
+ //# sourceMappingURL=traceStoryExecution.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"traceStoryExecution.js","sourceRoot":"","sources":["../../../src/traceStoryExecution/traceStoryExecution.ts"],"names":[],"mappings":"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","sourcesContent":["// traceStoryExecution — replay a StoryResult log against real story code and record a\n// line-by-line execution trace: every statement executed, with local variable values.\n//\n// Wraps qpqExecuteLog (deterministic replay: every impure action is answered from the\n// log's history), while a worker-thread debug controller (see controllerWorker.ts)\n// drives the V8 inspector against this thread and captures each statement + locals.\n// Because the replay is deterministic, the recorded trace carries the same information\n// an interactive debug session would. See trace-replay-plan.md.\n//\n// The CALLER must run on the process MAIN THREAD (lambda handlers and the dev server\n// do) — inspector.Session.connectToMainThread only targets the main thread.\n\nimport { ActionProcessorList, getQpqIsoDateTimeFromDate, qpqExecuteLog, QpqExecutionTrace, StoryResult } from 'quidproquo-core';\n\nimport { Worker } from 'worker_threads';\n\nimport { TraceControllerWorkerData, traceControllerWorkerMain } from './controllerWorker';\nimport { filterOwnCodeLocations, resolveSourceMappedSteps } from './resolveSourceMaps';\n\nexport interface TraceStoryExecutionOptions {\n // Regex sources matched against script urls to trace IN ADDITION to the story\n // function's own script (auto-detected via [[FunctionLocation]]). Use for bundles\n // split across chunks, e.g. ['/tmp/qpq-federated-code/'].\n scriptPatterns?: string[];\n\n // Only break on statements whose source-mapped origin is the service's own code —\n // node_modules positions get no breakpoints, so the step/time budgets are spent\n // entirely on user statements. Scripts without a source map stay fully traced.\n onlyOwnCode?: boolean;\n\n // Step budget and wall-clock budget: past either, the replay finishes untraced and\n // the trace is marked truncated. The wall clock is what bounds total runtime — locals\n // capture makes per-step cost variable, so step count alone doesn't bound time.\n maxSteps?: number;\n maxTraceMs?: number;\n\n // Serialization caps for captured locals: string length, properties per object level,\n // object walk depth for the deep json capture, and total json size per value.\n maxValueLength?: number;\n maxProperties?: number;\n maxValueDepth?: number;\n maxSerializedLength?: number;\n\n // Passed through to qpqExecuteLog — lets specific action types execute for real\n // instead of being answered from the log.\n overrides?: ActionProcessorList;\n}\n\nexport interface TraceStoryExecutionResult {\n trace: QpqExecutionTrace;\n\n // The replay's own StoryResult (result/error of re-running the story)\n replay: StoryResult<any>;\n}\n\n// Ready covers domain enable + breakpoint installation across every traced chunk —\n// generous because the service function running this has minutes of budget, and an\n// abort here wastes a replay that would have succeeded (instrumentMs in the trace stats\n// shows the real cost).\nconst READY_TIMEOUT_MS = 120_000;\nconst TRACE_TIMEOUT_MS = 60_000;\n\n// One trace at a time per process: the controller owns process-wide debugger state\n// (breakpoints, pause handling), and the story function handoff is a global.\nlet traceInFlight = false;\n\nconst waitForControllerMessage = (controller: Worker, type: string, timeoutMs: number): Promise<any> =>\n new Promise((resolve, reject) => {\n const cleanUp = () => {\n controller.off('message', onMessage);\n controller.off('error', onError);\n controller.off('exit', onExit);\n clearTimeout(timeout);\n };\n const onMessage = (message: any) => {\n if (message?.type === type) {\n cleanUp();\n resolve(message);\n } else if (message?.type === 'fatal') {\n cleanUp();\n reject(new Error(`trace controller failed: ${message.error}`));\n }\n };\n const onError = (error: Error) => {\n cleanUp();\n reject(error);\n };\n const onExit = (code: number) => {\n cleanUp();\n reject(new Error(`trace controller exited early with code [${code}]`));\n };\n const timeout = setTimeout(() => {\n cleanUp();\n reject(new Error(`timed out after ${timeoutMs}ms waiting for trace controller [${type}]`));\n }, timeoutMs);\n\n controller.on('message', onMessage);\n controller.on('error', onError);\n controller.on('exit', onExit);\n });\n\nexport const traceStoryExecution = async (\n storyResult: StoryResult<any>,\n runtime: any,\n options: TraceStoryExecutionOptions = {},\n): Promise<TraceStoryExecutionResult> => {\n if (traceInFlight) {\n throw new Error('a story trace is already in progress in this process');\n }\n traceInFlight = true;\n\n // The controller locates the story's script through this global ([[FunctionLocation]])\n (globalThis as any).__qpqTraceStoryFunction = runtime;\n\n const workerData: TraceControllerWorkerData = {\n scriptPatterns: options.scriptPatterns ?? [],\n onlyOwnCode: options.onlyOwnCode ?? false,\n maxSteps: options.maxSteps ?? 20_000,\n maxTraceMs: options.maxTraceMs ?? 120_000,\n maxValueLength: options.maxValueLength ?? 1_000,\n maxProperties: options.maxProperties ?? 32,\n maxValueDepth: options.maxValueDepth ?? 4,\n maxSerializedLength: options.maxSerializedLength ?? 30_000,\n };\n\n // Lambdas ship as single-file webpack bundles, so the controller can't be a worker\n // FILE on disk — it's serialized and run as an eval worker (see controllerWorker.ts).\n const controller = new Worker(`(${traceControllerWorkerMain.toString()})()`, {\n eval: true,\n workerData,\n });\n\n // onlyOwnCode: the worker can't load trace-mapping (eval worker, builtin requires\n // only), so it round-trips candidate breakpoint locations here for source-map\n // filtering. Attached before the ready-wait — instrumentation happens during init.\n controller.on('message', (message: any) => {\n if (message?.type === 'filterLocations') {\n controller.postMessage({\n type: 'filteredLocations',\n requestId: message.requestId,\n locations: filterOwnCodeLocations(message.scriptUrl, message.locations || []),\n });\n }\n });\n\n try {\n await waitForControllerMessage(controller, 'ready', READY_TIMEOUT_MS);\n\n const replayStartedAt = Date.now();\n const replay = await qpqExecuteLog(storyResult, runtime, options.overrides);\n const replayMs = Date.now() - replayStartedAt;\n\n const tracePromise = waitForControllerMessage(controller, 'trace', TRACE_TIMEOUT_MS);\n controller.postMessage({ type: 'done' });\n const rawTrace = await tracePromise;\n\n const { sources, steps } = resolveSourceMappedSteps(rawTrace.steps, rawTrace.scripts);\n\n const trace: QpqExecutionTrace = {\n correlation: storyResult.correlation,\n moduleName: storyResult.moduleName,\n tracedAt: getQpqIsoDateTimeFromDate(new Date()),\n truncated: rawTrace.stats.truncated,\n sources,\n steps,\n stats: {\n pauses: rawTrace.stats.pauses,\n breakpoints: rawTrace.stats.breakpoints,\n replayMs,\n localsCaptureMs: rawTrace.stats.localsCaptureMs,\n instrumentMs: rawTrace.stats.instrumentMs,\n instrumentedScriptUrls: rawTrace.stats.instrumentedScriptUrls,\n },\n };\n\n return { trace, replay };\n } finally {\n delete (globalThis as any).__qpqTraceStoryFunction;\n traceInFlight = false;\n await controller.terminate();\n }\n};\n"]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "quidproquo-actionprocessor-node",
3
- "version": "0.1.3",
3
+ "version": "0.1.4",
4
4
  "description": "",
5
5
  "main": "./lib/commonjs/index.js",
6
6
  "module": "./lib/esm/index.js",
@@ -33,13 +33,15 @@
33
33
  "homepage": "https://github.com/joe-coady/quidproquo#readme",
34
34
  "dependencies": {
35
35
  "@anthropic-ai/sdk": "^0.19.1",
36
- "quidproquo-actionprocessor-js": "0.1.3",
37
- "quidproquo-core": "0.1.3",
38
- "quidproquo-webserver": "0.1.3",
36
+ "@jridgewell/trace-mapping": "^0.3.25",
37
+ "quidproquo-actionprocessor-js": "0.1.4",
38
+ "quidproquo-core": "0.1.4",
39
+ "quidproquo-webserver": "0.1.4",
39
40
  "uuidv7": "^1.0.1"
40
41
  },
41
42
  "devDependencies": {
42
- "quidproquo-tsconfig": "0.1.3",
43
+ "@types/node": "^22.13.13",
44
+ "quidproquo-tsconfig": "0.1.4",
43
45
  "typescript": "^5.8.2"
44
46
  }
45
47
  }