quidproquo-actionprocessor-node 0.1.20 → 0.1.22

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -49,6 +49,11 @@ function traceControllerWorkerMain() {
49
49
  const scriptPatterns = options.scriptPatterns.map((pattern) => new RegExp(pattern));
50
50
  const scriptUrlsById = new Map();
51
51
  const instrumentedScriptIds = new Set();
52
+ // Script end positions from scriptParsed. getPossibleBreakpoints MUST be given an
53
+ // explicit end: with the range left open, V8 answers with an empty list once the
54
+ // script's bytecode has been flushed by GC (functions parsed but not run for a few
55
+ // collections), so a story loaded a while before the trace would get no breakpoints.
56
+ const scriptEndById = new Map();
52
57
  // The directory of the story function's own script (set during init). Bundles are
53
58
  // chunk-SPLIT: a story exported through a factory wrapper (export const x = wrap(story))
54
59
  // has its function object created in the FACTORY's chunk, while the code it runs lives
@@ -254,7 +259,11 @@ function traceControllerWorkerMain() {
254
259
  // empty or stops advancing.
255
260
  const getAllPossibleBreakpoints = (scriptId) => {
256
261
  const allLocations = [];
257
- const readPage = (startLine, startColumn) => post('Debugger.getPossibleBreakpoints', { start: { scriptId, lineNumber: startLine, columnNumber: startColumn } }).then((response) => {
262
+ const scriptEnd = scriptEndById.get(scriptId);
263
+ const readPage = (startLine, startColumn) => post('Debugger.getPossibleBreakpoints', {
264
+ start: { scriptId, lineNumber: startLine, columnNumber: startColumn },
265
+ end: scriptEnd ? { scriptId, lineNumber: scriptEnd.lineNumber, columnNumber: scriptEnd.columnNumber } : undefined,
266
+ }).then((response) => {
258
267
  const locations = response.locations || [];
259
268
  if (locations.length === 0)
260
269
  return allLocations;
@@ -290,6 +299,7 @@ function traceControllerWorkerMain() {
290
299
  session.on('Debugger.scriptParsed', (message) => {
291
300
  const url = message.params.url || '';
292
301
  scriptUrlsById.set(message.params.scriptId, url);
302
+ scriptEndById.set(message.params.scriptId, { lineNumber: message.params.endLine, columnNumber: message.params.endColumn });
293
303
  // A traced bundle chunk loaded mid-story (async-node chunk loading) — instrument it
294
304
  // as it appears so its statements are traced too.
295
305
  if (ready && isTraceTargetUrl(url)) {
@@ -1 +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"]}
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 // Script end positions from scriptParsed. getPossibleBreakpoints MUST be given an\n // explicit end: with the range left open, V8 answers with an empty list once the\n // script's bytecode has been flushed by GC (functions parsed but not run for a few\n // collections), so a story loaded a while before the trace would get no breakpoints.\n const scriptEndById = new Map<string, { lineNumber: number; columnNumber: number }>();\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 const scriptEnd = scriptEndById.get(scriptId);\n\n const readPage = (startLine: number, startColumn: number): Promise<any[]> =>\n post('Debugger.getPossibleBreakpoints', {\n start: { scriptId, lineNumber: startLine, columnNumber: startColumn },\n end: scriptEnd ? { scriptId, lineNumber: scriptEnd.lineNumber, columnNumber: scriptEnd.columnNumber } : undefined,\n }).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 scriptEndById.set(message.params.scriptId, { lineNumber: message.params.endLine, columnNumber: message.params.endColumn });\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"]}
@@ -46,6 +46,11 @@ export function traceControllerWorkerMain() {
46
46
  const scriptPatterns = options.scriptPatterns.map((pattern) => new RegExp(pattern));
47
47
  const scriptUrlsById = new Map();
48
48
  const instrumentedScriptIds = new Set();
49
+ // Script end positions from scriptParsed. getPossibleBreakpoints MUST be given an
50
+ // explicit end: with the range left open, V8 answers with an empty list once the
51
+ // script's bytecode has been flushed by GC (functions parsed but not run for a few
52
+ // collections), so a story loaded a while before the trace would get no breakpoints.
53
+ const scriptEndById = new Map();
49
54
  // The directory of the story function's own script (set during init). Bundles are
50
55
  // chunk-SPLIT: a story exported through a factory wrapper (export const x = wrap(story))
51
56
  // has its function object created in the FACTORY's chunk, while the code it runs lives
@@ -251,7 +256,11 @@ export function traceControllerWorkerMain() {
251
256
  // empty or stops advancing.
252
257
  const getAllPossibleBreakpoints = (scriptId) => {
253
258
  const allLocations = [];
254
- const readPage = (startLine, startColumn) => post('Debugger.getPossibleBreakpoints', { start: { scriptId, lineNumber: startLine, columnNumber: startColumn } }).then((response) => {
259
+ const scriptEnd = scriptEndById.get(scriptId);
260
+ const readPage = (startLine, startColumn) => post('Debugger.getPossibleBreakpoints', {
261
+ start: { scriptId, lineNumber: startLine, columnNumber: startColumn },
262
+ end: scriptEnd ? { scriptId, lineNumber: scriptEnd.lineNumber, columnNumber: scriptEnd.columnNumber } : undefined,
263
+ }).then((response) => {
255
264
  const locations = response.locations || [];
256
265
  if (locations.length === 0)
257
266
  return allLocations;
@@ -287,6 +296,7 @@ export function traceControllerWorkerMain() {
287
296
  session.on('Debugger.scriptParsed', (message) => {
288
297
  const url = message.params.url || '';
289
298
  scriptUrlsById.set(message.params.scriptId, url);
299
+ scriptEndById.set(message.params.scriptId, { lineNumber: message.params.endLine, columnNumber: message.params.endColumn });
290
300
  // A traced bundle chunk loaded mid-story (async-node chunk loading) — instrument it
291
301
  // as it appears so its statements are traced too.
292
302
  if (ready && isTraceTargetUrl(url)) {
@@ -1 +1 @@
1
- {"version":3,"file":"controllerWorker.js","sourceRoot":"","sources":["../../../src/traceStoryExecution/controllerWorker.ts"],"names":[],"mappings":"AAAA,qFAAqF;AACrF,kFAAkF;AAClF,EAAE;AACF,wFAAwF;AACxF,yFAAyF;AACzF,wFAAwF;AACxF,oFAAoF;AACpF,0CAA0C;AAC1C,EAAE;AACF,wFAAwF;AACxF,uEAAuE;AACvE,oFAAoF;AACpF,6CAA6C;AAC7C,kEAAkE;AAClE,oFAAoF;AACpF,2FAA2F;AAC3F,EAAE;AACF,kDAAkD;AAClD,gGAAgG;AAChG,iFAAiF;AACjF,mIAAmI;AACnI,+CAA+C;AAC/C,yEAAyE;AACzE,uGAAuG;AACvG,EAAE;AACF,mFAAmF;AACnF,uFAAuF;AACvF,wFAAwF;AAiCxF,MAAM,UAAU,yBAAyB;IACvC,oFAAoF;IACpF,kFAAkF;IAClF,sFAAsF;IACtF,qFAAqF;IACrF,sFAAsF;IACtF,MAAM,cAAc,GAAG,IAAI,CAAC,SAAS,CAAC,CAAC;IACvC,MAAM,SAAS,GAAG,cAAc,CAAC,gBAAgB,CAAC,CAAC;IACnD,MAAM,aAAa,GAAG,cAAc,CAAC,qBAAqB,CAAC,CAAC;IAE5D,MAAM,UAAU,GAAG,aAAa,CAAC,UAAU,CAAC;IAC5C,MAAM,OAAO,GAA8B,aAAa,CAAC,UAAU,CAAC;IAEpE,MAAM,OAAO,GAAG,IAAI,SAAS,CAAC,OAAO,EAAE,CAAC;IACxC,OAAO,CAAC,mBAAmB,EAAE,CAAC;IAE9B,MAAM,IAAI,GAAG,CAAC,MAAc,EAAE,MAAe,EAAgB,EAAE,CAC7D,IAAI,OAAO,CAAC,CAAC,OAAO,EAAE,MAAM,EAAE,EAAE,CAC9B,OAAO,CAAC,IAAI,CAAC,MAAM,EAAE,MAAM,IAAI,EAAE,EAAE,CAAC,KAAmB,EAAE,MAAe,EAAE,EAAE,CAC1E,KAAK,CAAC,CAAC,CAAC,MAAM,CAAC,IAAI,KAAK,CAAC,MAAM,GAAG,IAAI,GAAG,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,MAAM,CAAC,CAC3E,CACF,CAAC;IAEJ,MAAM,KAAK,GAAG,CAAC,KAAc,EAAQ,EAAE;QACrC,UAAU,CAAC,WAAW,CAAC,EAAE,IAAI,EAAE,OAAO,EAAE,KAAK,EAAE,MAAM,CAAC,CAAC,KAAK,IAAK,KAAe,CAAC,KAAK,CAAC,IAAI,KAAK,CAAC,EAAE,CAAC,CAAC;IACvG,CAAC,CAAC;IAEF,MAAM,cAAc,GAAG,OAAO,CAAC,cAAc,CAAC,GAAG,CAAC,CAAC,OAAO,EAAE,EAAE,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,CAAC,CAAC;IACpF,MAAM,cAAc,GAAG,IAAI,GAAG,EAAkB,CAAC;IACjD,MAAM,qBAAqB,GAAG,IAAI,GAAG,EAAU,CAAC;IAEhD,kFAAkF;IAClF,yFAAyF;IACzF,uFAAuF;IACvF,uFAAuF;IACvF,kFAAkF;IAClF,2CAA2C;IAC3C,IAAI,iBAAiB,GAAG,EAAE,CAAC;IAE3B,qFAAqF;IACrF,6EAA6E;IAC7E,MAAM,kBAAkB,GAAG,CAAC,GAAW,EAAU,EAAE,CAAC,GAAG,CAAC,OAAO,CAAC,YAAY,EAAE,EAAE,CAAC,CAAC,OAAO,CAAC,KAAK,EAAE,GAAG,CAAC,CAAC;IAEtG,MAAM,gBAAgB,GAAG,CAAC,GAAW,EAAW,EAAE,CAChD,CAAC,CAAC,GAAG,IAAI,CAAC,cAAc,CAAC,IAAI,CAAC,CAAC,OAAO,EAAE,EAAE,CAAC,OAAO,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,iBAAiB,IAAI,kBAAkB,CAAC,GAAG,CAAC,CAAC,UAAU,CAAC,iBAAiB,CAAC,CAAC,CAAC,CAAC;IAEnJ,MAAM,KAAK,GAAmB,EAAE,CAAC;IACjC,IAAI,MAAM,GAAG,CAAC,CAAC;IACf,IAAI,WAAW,GAAG,CAAC,CAAC;IACpB,IAAI,SAAS,GAAG,KAAK,CAAC;IACtB,IAAI,eAAe,GAAG,CAAC,CAAC;IACxB,IAAI,YAAY,GAAG,CAAC,CAAC;IACrB,IAAI,YAAY,GAAG,CAAC,CAAC;IACrB,IAAI,KAAK,GAAG,KAAK,CAAC;IAElB,+EAA+E;IAC/E,sFAAsF;IACtF,8DAA8D;IAC9D,MAAM,SAAS,GAAG,CAAC,IAAY,EAAU,EAAE,CAAC,CAAC,IAAI,CAAC,MAAM,GAAG,OAAO,CAAC,cAAc,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,EAAE,OAAO,CAAC,cAAc,CAAC,GAAG,GAAG,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC;IAExI,MAAM,cAAc,GAAG,CAAC,YAAiB,EAAU,EAAE;QACnD,IAAI,CAAC,YAAY;YAAE,OAAO,WAAW,CAAC;QACtC,IAAI,YAAY,CAAC,IAAI,KAAK,WAAW;YAAE,OAAO,WAAW,CAAC;QAC1D,IAAI,YAAY,CAAC,OAAO,KAAK,MAAM;YAAE,OAAO,MAAM,CAAC;QACnD,IAAI,YAAY,CAAC,mBAAmB;YAAE,OAAO,YAAY,CAAC,mBAAmB,CAAC;QAC9E,IAAI,YAAY,CAAC,IAAI,KAAK,QAAQ,IAAI,YAAY,CAAC,IAAI,KAAK,QAAQ,IAAI,YAAY,CAAC,IAAI,KAAK,SAAS,EAAE,CAAC;YACxG,OAAO,SAAS,CAAC,IAAI,CAAC,SAAS,CAAC,YAAY,CAAC,KAAK,CAAC,CAAC,CAAC;QACvD,CAAC;QACD,IAAI,YAAY,CAAC,OAAO,EAAE,CAAC;YACzB,MAAM,KAAK,GAAa,EAAE,CAAC;YAC3B,MAAM,iBAAiB,GAAG,YAAY,CAAC,OAAO,CAAC,UAAU,IAAI,EAAE,CAAC;YAChE,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,iBAAiB,CAAC,MAAM,IAAI,CAAC,GAAG,OAAO,CAAC,aAAa,EAAE,CAAC,IAAI,CAAC,EAAE,CAAC;gBAClF,MAAM,QAAQ,GAAG,iBAAiB,CAAC,CAAC,CAAC,CAAC;gBACtC,MAAM,KAAK,GAAG,QAAQ,CAAC,IAAI,KAAK,QAAQ,CAAC,CAAC,CAAC,GAAG,GAAG,QAAQ,CAAC,KAAK,GAAG,GAAG,CAAC,CAAC,CAAC,QAAQ,CAAC,KAAK,CAAC;gBACvF,KAAK,CAAC,IAAI,CAAC,YAAY,CAAC,OAAO,CAAC,OAAO,KAAK,OAAO,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,QAAQ,CAAC,IAAI,GAAG,IAAI,GAAG,KAAK,CAAC,CAAC;YAC9F,CAAC;YACD,MAAM,QAAQ,GAAG,YAAY,CAAC,OAAO,CAAC,QAAQ,IAAI,iBAAiB,CAAC,MAAM,GAAG,OAAO,CAAC,aAAa,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE,CAAC;YAChH,MAAM,IAAI,GAAG,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG,QAAQ,CAAC;YACzC,OAAO,SAAS,CAAC,YAAY,CAAC,OAAO,CAAC,OAAO,KAAK,OAAO,CAAC,CAAC,CAAC,GAAG,GAAG,IAAI,GAAG,GAAG,CAAC,CAAC,CAAC,GAAG,GAAG,IAAI,GAAG,GAAG,CAAC,CAAC;QACnG,CAAC;QACD,OAAO,SAAS,CAAC,YAAY,CAAC,WAAW,IAAI,YAAY,CAAC,IAAI,CAAC,CAAC;IAClE,CAAC,CAAC;IAEF,+EAA+E;IAC/E,sFAAsF;IACtF,mFAAmF;IACnF,uFAAuF;IACvF,kFAAkF;IAClF,sFAAsF;IACtF,SAAS,iBAAiB,CAAY,QAAgB,EAAE,SAAiB,EAAE,QAAgB,EAAE,QAAgB;QAC3G,MAAM,IAAI,GAAU,EAAE,CAAC;QAEvB,MAAM,IAAI,GAAG,CAAC,KAAU,EAAE,KAAa,EAAO,EAAE;YAC9C,IAAI,KAAK,KAAK,IAAI,IAAI,OAAO,KAAK,KAAK,QAAQ,IAAI,OAAO,KAAK,KAAK,SAAS;gBAAE,OAAO,KAAK,CAAC;YAC5F,IAAI,OAAO,KAAK,KAAK,QAAQ;gBAAE,OAAO,KAAK,CAAC,MAAM,GAAG,SAAS,CAAC,CAAC,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC,EAAE,SAAS,CAAC,GAAG,GAAG,CAAC,CAAC,CAAC,KAAK,CAAC;YACzG,IAAI,OAAO,KAAK,KAAK,WAAW;gBAAE,OAAO,aAAa,CAAC;YACvD,IAAI,OAAO,KAAK,KAAK,UAAU;gBAAE,OAAO,YAAY,GAAG,CAAC,KAAK,CAAC,IAAI,IAAI,EAAE,CAAC,GAAG,GAAG,CAAC;YAChF,IAAI,OAAO,KAAK,KAAK,QAAQ;gBAAE,OAAO,KAAK,CAAC,QAAQ,EAAE,GAAG,GAAG,CAAC;YAC7D,IAAI,OAAO,KAAK,KAAK,QAAQ;gBAAE,OAAO,KAAK,CAAC,QAAQ,EAAE,CAAC;YAEvD,IAAI,KAAK,YAAY,IAAI;gBAAE,OAAO,KAAK,CAAC,WAAW,EAAE,CAAC;YACtD,IAAI,KAAK,YAAY,KAAK;gBAAE,OAAO,GAAG,GAAG,CAAC,KAAK,CAAC,IAAI,IAAI,OAAO,CAAC,GAAG,IAAI,GAAG,KAAK,CAAC,OAAO,GAAG,GAAG,CAAC;YAC9F,IAAI,KAAK,YAAY,GAAG;gBAAE,OAAO,OAAO,GAAG,KAAK,CAAC,IAAI,GAAG,IAAI,CAAC;YAC7D,IAAI,KAAK,YAAY,GAAG;gBAAE,OAAO,OAAO,GAAG,KAAK,CAAC,IAAI,GAAG,IAAI,CAAC;YAE7D,IAAI,KAAK,IAAI,QAAQ;gBAAE,OAAO,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,SAAS,GAAG,KAAK,CAAC,MAAM,GAAG,IAAI,CAAC,CAAC,CAAC,UAAU,CAAC;YAClG,IAAI,IAAI,CAAC,OAAO,CAAC,KAAK,CAAC,IAAI,CAAC;gBAAE,OAAO,YAAY,CAAC;YAClD,IAAI,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;YAEjB,IAAI,MAAW,CAAC;YAChB,IAAI,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC,EAAE,CAAC;gBACzB,MAAM,GAAG,EAAE,CAAC;gBACZ,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,KAAK,CAAC,MAAM,IAAI,CAAC,GAAG,QAAQ,EAAE,CAAC,IAAI,CAAC,EAAE,CAAC;oBACzD,IAAI,CAAC;wBACH,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE,KAAK,GAAG,CAAC,CAAC,CAAC,CAAC;oBACzC,CAAC;oBAAC,OAAO,KAAK,EAAE,CAAC;wBACf,MAAM,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC;oBACzB,CAAC;gBACH,CAAC;gBACD,IAAI,KAAK,CAAC,MAAM,GAAG,QAAQ;oBAAE,MAAM,CAAC,IAAI,CAAC,IAAI,GAAG,CAAC,KAAK,CAAC,MAAM,GAAG,QAAQ,CAAC,GAAG,QAAQ,CAAC,CAAC;YACxF,CAAC;iBAAM,CAAC;gBACN,MAAM,GAAG,EAAE,CAAC;gBACZ,MAAM,IAAI,GAAG,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;gBAChC,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,IAAI,CAAC,MAAM,IAAI,CAAC,GAAG,QAAQ,EAAE,CAAC,IAAI,CAAC,EAAE,CAAC;oBACxD,IAAI,CAAC;wBACH,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,GAAG,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,EAAE,KAAK,GAAG,CAAC,CAAC,CAAC;oBACpD,CAAC;oBAAC,OAAO,KAAK,EAAE,CAAC;wBACf,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,GAAG,SAAS,CAAC;oBAC9B,CAAC;gBACH,CAAC;gBACD,IAAI,IAAI,CAAC,MAAM,GAAG,QAAQ;oBAAE,MAAM,CAAC,QAAQ,CAAC,GAAG,GAAG,GAAG,CAAC,IAAI,CAAC,MAAM,GAAG,QAAQ,CAAC,GAAG,aAAa,CAAC;YAChG,CAAC;YAED,IAAI,CAAC,GAAG,EAAE,CAAC;YACX,OAAO,MAAM,CAAC;QAChB,CAAC,CAAC;QAEF,IAAI,CAAC;YACH,MAAM,IAAI,GAAG,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC,CAAC;YAC3C,OAAO,IAAI,IAAI,IAAI,CAAC,MAAM,IAAI,QAAQ,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC;QACvD,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,OAAO,IAAI,CAAC;QACd,CAAC;IACH,CAAC;IAED,MAAM,kBAAkB,GAAG,CAAC,YAAiB,EAAW,EAAE,CACxD,CAAC,CAAC,YAAY,IAAI,YAAY,CAAC,IAAI,KAAK,QAAQ,IAAI,YAAY,CAAC,OAAO,KAAK,MAAM,IAAI,CAAC,CAAC,YAAY,CAAC,QAAQ,CAAC;IAEjH,+EAA+E;IAC/E,qFAAqF;IACrF,gFAAgF;IAChF,gCAAgC;IAChC,MAAM,kBAAkB,GAAG,CAAC,YAAiB,EAAuD,EAAE;QACpG,MAAM,QAAQ,GAAkB,EAAE,OAAO,EAAE,cAAc,CAAC,YAAY,CAAC,EAAE,CAAC;QAE1E,IAAI,CAAC,kBAAkB,CAAC,YAAY,CAAC,EAAE,CAAC;YACtC,OAAO,EAAE,QAAQ,EAAE,IAAI,EAAE,OAAO,CAAC,OAAO,EAAE,EAAE,CAAC;QAC/C,CAAC;QAED,MAAM,IAAI,GAAG,IAAI,CAAC,wBAAwB,EAAE;YAC1C,QAAQ,EAAE,YAAY,CAAC,QAAQ;YAC/B,mBAAmB,EAAE,iBAAiB,CAAC,QAAQ,EAAE;YACjD,SAAS,EAAE;gBACT,EAAE,KAAK,EAAE,OAAO,CAAC,aAAa,EAAE;gBAChC,EAAE,KAAK,EAAE,OAAO,CAAC,cAAc,EAAE;gBACjC,EAAE,KAAK,EAAE,OAAO,CAAC,aAAa,EAAE;gBAChC,EAAE,KAAK,EAAE,OAAO,CAAC,mBAAmB,EAAE;aACvC;YACD,aAAa,EAAE,IAAI;SACpB,CAAC,CAAC,IAAI,CACL,CAAC,MAAW,EAAE,EAAE;YACd,IAAI,MAAM,IAAI,MAAM,CAAC,MAAM,IAAI,OAAO,MAAM,CAAC,MAAM,CAAC,KAAK,KAAK,QAAQ,EAAE,CAAC;gBACvE,QAAQ,CAAC,IAAI,GAAG,MAAM,CAAC,MAAM,CAAC,KAAK,CAAC;YACtC,CAAC;QACH,CAAC,EACD,GAAG,EAAE,CAAC,SAAS,CAChB,CAAC;QAEF,OAAO,EAAE,QAAQ,EAAE,IAAI,EAAE,CAAC;IAC5B,CAAC,CAAC;IAOF,kFAAkF;IAClF,8EAA8E;IAC9E,MAAM,iBAAiB,GAAG,CAAC,KAAU,EAA+B,EAAE;QACpE,MAAM,SAAS,GAAG,IAAI,CAAC,GAAG,EAAE,CAAC;QAC7B,MAAM,MAAM,GAAuB,EAAE,MAAM,EAAE,EAAE,EAAE,CAAC;QAClD,MAAM,MAAM,GAAG,KAAK,CAAC,UAAU;aAC5B,MAAM,CAAC,CAAC,KAAU,EAAE,EAAE,CAAC,CAAC,KAAK,CAAC,IAAI,KAAK,OAAO,IAAI,KAAK,CAAC,IAAI,KAAK,OAAO,CAAC,IAAI,KAAK,CAAC,MAAM,IAAI,KAAK,CAAC,MAAM,CAAC,QAAQ,CAAC;aACnH,OAAO,EAAE,CAAC;QAEb,IAAI,KAAK,GAAqB,OAAO,CAAC,OAAO,EAAE,CAAC;QAChD,MAAM,CAAC,OAAO,CAAC,CAAC,KAAU,EAAE,EAAE;YAC5B,KAAK,GAAG,KAAK;iBACV,IAAI,CAAC,GAAG,EAAE,CAAC,IAAI,CAAC,uBAAuB,EAAE,EAAE,QAAQ,EAAE,KAAK,CAAC,MAAM,CAAC,QAAQ,EAAE,aAAa,EAAE,IAAI,EAAE,eAAe,EAAE,IAAI,EAAE,CAAC,CAAC;iBAC1H,IAAI,CAAC,CAAC,QAAa,EAAE,EAAE;gBACtB,IAAI,UAAU,GAAqB,OAAO,CAAC,OAAO,EAAE,CAAC;gBACrD,CAAC,QAAQ,CAAC,MAAM,IAAI,EAAE,CAAC,CAAC,OAAO,CAAC,CAAC,QAAa,EAAE,EAAE;oBAChD,MAAM,OAAO,GAAG,kBAAkB,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAC;oBACnD,MAAM,CAAC,MAAM,CAAC,QAAQ,CAAC,IAAI,CAAC,GAAG,OAAO,CAAC,QAAQ,CAAC;oBAChD,UAAU,GAAG,UAAU,CAAC,IAAI,CAAC,GAAG,EAAE,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC;gBACnD,CAAC,CAAC,CAAC;gBACH,OAAO,UAAU,CAAC;YACpB,CAAC,CAAC,CAAC;QACP,CAAC,CAAC,CAAC;QAEH,IAAI,KAAK,CAAC,WAAW,EAAE,CAAC;YACtB,MAAM,aAAa,GAAG,kBAAkB,CAAC,KAAK,CAAC,WAAW,CAAC,CAAC;YAC5D,MAAM,CAAC,WAAW,GAAG,aAAa,CAAC,QAAQ,CAAC;YAC5C,KAAK,GAAG,KAAK,CAAC,IAAI,CAAC,GAAG,EAAE,CAAC,aAAa,CAAC,IAAI,CAAC,CAAC;QAC/C,CAAC;QAED,OAAO,KAAK,CAAC,IAAI,CAAC,GAAG,EAAE;YACrB,eAAe,IAAI,IAAI,CAAC,GAAG,EAAE,GAAG,SAAS,CAAC;YAC1C,OAAO,MAAM,CAAC;QAChB,CAAC,CAAC,CAAC;IACL,CAAC,CAAC;IAEF,+EAA+E;IAC/E,oFAAoF;IACpF,iFAAiF;IACjF,iFAAiF;IACjF,gFAAgF;IAChF,IAAI,gBAAgB,GAAG,CAAC,CAAC;IACzB,MAAM,qBAAqB,GAAG,IAAI,GAAG,EAAsC,CAAC;IAE5E,MAAM,wBAAwB,GAAG,CAAC,QAAgB,EAAE,SAAgB,EAAkB,EAAE;QACtF,IAAI,CAAC,OAAO,CAAC,WAAW,IAAI,SAAS,CAAC,MAAM,KAAK,CAAC;YAAE,OAAO,OAAO,CAAC,OAAO,CAAC,SAAS,CAAC,CAAC;QAEtF,gBAAgB,IAAI,CAAC,CAAC;QACtB,MAAM,SAAS,GAAG,gBAAgB,CAAC;QACnC,OAAO,IAAI,OAAO,CAAC,CAAC,OAAO,EAAE,EAAE;YAC7B,qBAAqB,CAAC,GAAG,CAAC,SAAS,EAAE,OAAO,CAAC,CAAC;YAC9C,UAAU,CAAC,WAAW,CAAC,EAAE,IAAI,EAAE,iBAAiB,EAAE,SAAS,EAAE,SAAS,EAAE,cAAc,CAAC,GAAG,CAAC,QAAQ,CAAC,IAAI,EAAE,EAAE,SAAS,EAAE,CAAC,CAAC;QAC3H,CAAC,CAAC,CAAC;IACL,CAAC,CAAC;IAEF,uFAAuF;IACvF,oFAAoF;IACpF,qFAAqF;IACrF,uFAAuF;IACvF,4BAA4B;IAC5B,MAAM,yBAAyB,GAAG,CAAC,QAAgB,EAAkB,EAAE;QACrE,MAAM,YAAY,GAAU,EAAE,CAAC;QAE/B,MAAM,QAAQ,GAAG,CAAC,SAAiB,EAAE,WAAmB,EAAkB,EAAE,CAC1E,IAAI,CAAC,iCAAiC,EAAE,EAAE,KAAK,EAAE,EAAE,QAAQ,EAAE,UAAU,EAAE,SAAS,EAAE,YAAY,EAAE,WAAW,EAAE,EAAE,CAAC,CAAC,IAAI,CAAC,CAAC,QAAa,EAAE,EAAE;YACxI,MAAM,SAAS,GAAG,QAAQ,CAAC,SAAS,IAAI,EAAE,CAAC;YAC3C,IAAI,SAAS,CAAC,MAAM,KAAK,CAAC;gBAAE,OAAO,YAAY,CAAC;YAEhD,SAAS,CAAC,OAAO,CAAC,CAAC,QAAa,EAAE,EAAE,CAAC,YAAY,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC,CAAC;YAElE,MAAM,IAAI,GAAG,SAAS,CAAC,SAAS,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC;YAC7C,MAAM,QAAQ,GAAG,IAAI,CAAC,UAAU,CAAC;YACjC,MAAM,UAAU,GAAG,CAAC,IAAI,CAAC,YAAY,IAAI,CAAC,CAAC,GAAG,CAAC,CAAC;YAChD,IAAI,QAAQ,GAAG,SAAS,IAAI,CAAC,QAAQ,KAAK,SAAS,IAAI,UAAU,IAAI,WAAW,CAAC;gBAAE,OAAO,YAAY,CAAC;YAEvG,OAAO,QAAQ,CAAC,QAAQ,EAAE,UAAU,CAAC,CAAC;QACxC,CAAC,CAAC,CAAC;QAEL,OAAO,QAAQ,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC;IACxB,CAAC,CAAC;IAEF,MAAM,gBAAgB,GAAG,CAAC,QAAgB,EAAiB,EAAE;QAC3D,IAAI,qBAAqB,CAAC,GAAG,CAAC,QAAQ,CAAC;YAAE,OAAO,OAAO,CAAC,OAAO,EAAE,CAAC;QAClE,qBAAqB,CAAC,GAAG,CAAC,QAAQ,CAAC,CAAC;QAEpC,OAAO,yBAAyB,CAAC,QAAQ,CAAC;aACvC,IAAI,CAAC,CAAC,SAAgB,EAAE,EAAE,CAAC,wBAAwB,CAAC,QAAQ,EAAE,SAAS,CAAC,CAAC;aACzE,IAAI,CAAC,CAAC,SAAgB,EAAE,EAAE;YACzB,2EAA2E;YAC3E,gFAAgF;YAChF,6EAA6E;YAC7E,gFAAgF;YAChF,iFAAiF;YACjF,6EAA6E;YAC7E,yBAAyB;YACzB,OAAO,OAAO,CAAC,GAAG,CAChB,SAAS,CAAC,GAAG,CAAC,CAAC,QAAa,EAAE,EAAE,CAC9B,IAAI,CAAC,wBAAwB,EAAE,EAAE,QAAQ,EAAE,CAAC,CAAC,IAAI,CAC/C,GAAG,EAAE;gBACH,WAAW,IAAI,CAAC,CAAC;YACnB,CAAC,EACD,GAAG,EAAE,CAAC,SAAS,CAChB,CACF,CACF,CAAC,IAAI,CAAC,GAAG,EAAE,CAAC,SAAS,CAAC,CAAC;QAC1B,CAAC,CAAC,CAAC;IACP,CAAC,CAAC;IAEF,OAAO,CAAC,EAAE,CAAC,uBAAuB,EAAE,CAAC,OAAY,EAAE,EAAE;QACnD,MAAM,GAAG,GAAG,OAAO,CAAC,MAAM,CAAC,GAAG,IAAI,EAAE,CAAC;QACrC,cAAc,CAAC,GAAG,CAAC,OAAO,CAAC,MAAM,CAAC,QAAQ,EAAE,GAAG,CAAC,CAAC;QAEjD,oFAAoF;QACpF,kDAAkD;QAClD,IAAI,KAAK,IAAI,gBAAgB,CAAC,GAAG,CAAC,EAAE,CAAC;YACnC,gBAAgB,CAAC,OAAO,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC;QACzD,CAAC;IACH,CAAC,CAAC,CAAC;IAEH,+EAA+E;IAC/E,MAAM,QAAQ,GAAG,CAAC,OAAY,EAAoB,EAAE;QAClD,MAAM,IAAI,CAAC,CAAC;QACZ,IAAI,CAAC,YAAY;YAAE,YAAY,GAAG,IAAI,CAAC,GAAG,EAAE,CAAC;QAC7C,MAAM,KAAK,GAAG,OAAO,CAAC,MAAM,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC;QAE3C,kFAAkF;QAClF,IAAI,CAAC,qBAAqB,CAAC,GAAG,CAAC,KAAK,CAAC,QAAQ,CAAC,QAAQ,CAAC,EAAE,CAAC;YACxD,OAAO,IAAI,CAAC,iBAAiB,CAAC,CAAC;QACjC,CAAC;QAED,kFAAkF;QAClF,kFAAkF;QAClF,iFAAiF;QACjF,iFAAiF;QACjF,8DAA8D;QAC9D,IAAI,KAAK,CAAC,MAAM,IAAI,OAAO,CAAC,QAAQ,IAAI,IAAI,CAAC,GAAG,EAAE,GAAG,YAAY,GAAG,OAAO,CAAC,UAAU,EAAE,CAAC;YACvF,SAAS,GAAG,IAAI,CAAC;YACjB,OAAO,IAAI,CAAC,+BAA+B,EAAE,EAAE,MAAM,EAAE,KAAK,EAAE,CAAC,CAAC,IAAI,CAAC,GAAG,EAAE,CAAC,IAAI,CAAC,iBAAiB,CAAC,CAAC,CAAC;QACtG,CAAC;QAED,OAAO,iBAAiB,CAAC,KAAK,CAAC;aAC5B,IAAI,CAAC,CAAC,MAAM,EAAE,EAAE;YACf,MAAM,IAAI,GAAiB;gBACzB,QAAQ,EAAE,KAAK,CAAC,QAAQ,CAAC,QAAQ;gBACjC,IAAI,EAAE,KAAK,CAAC,QAAQ,CAAC,UAAU;gBAC/B,MAAM,EAAE,KAAK,CAAC,QAAQ,CAAC,YAAY;gBACnC,YAAY,EAAE,KAAK,CAAC,YAAY,IAAI,EAAE;gBACtC,MAAM,EAAE,MAAM,CAAC,MAAM;aACtB,CAAC;YACF,IAAI,MAAM,CAAC,WAAW,EAAE,CAAC;gBACvB,IAAI,CAAC,WAAW,GAAG,MAAM,CAAC,WAAW,CAAC;YACxC,CAAC;YACD,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QACnB,CAAC,CAAC;aACD,IAAI,CAAC,GAAG,EAAE,CAAC,IAAI,CAAC,iBAAiB,CAAC,CAAC,CAAC;IACzC,CAAC,CAAC;IAEF,OAAO,CAAC,EAAE,CAAC,iBAAiB,EAAE,CAAC,OAAY,EAAE,EAAE;QAC7C,QAAQ,CAAC,OAAO,CAAC,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC;IACjC,CAAC,CAAC,CAAC;IAEH,8EAA8E;IAC9E,+EAA+E;IAC/E,UAAU,CAAC,EAAE,CAAC,SAAS,EAAE,CAAC,OAAY,EAAE,EAAE;QACxC,IAAI,OAAO,IAAI,OAAO,CAAC,IAAI,KAAK,mBAAmB,EAAE,CAAC;YACpD,MAAM,aAAa,GAAG,qBAAqB,CAAC,GAAG,CAAC,OAAO,CAAC,SAAS,CAAC,CAAC;YACnE,IAAI,aAAa,EAAE,CAAC;gBAClB,qBAAqB,CAAC,MAAM,CAAC,OAAO,CAAC,SAAS,CAAC,CAAC;gBAChD,aAAa,CAAC,OAAO,CAAC,SAAS,IAAI,EAAE,CAAC,CAAC;YACzC,CAAC;YACD,OAAO;QACT,CAAC;QAED,IAAI,OAAO,IAAI,OAAO,CAAC,IAAI,KAAK,MAAM,EAAE,CAAC;YACvC,MAAM,OAAO,GAA2B,EAAE,CAAC;YAC3C,cAAc,CAAC,OAAO,CAAC,CAAC,GAAG,EAAE,QAAQ,EAAE,EAAE;gBACvC,OAAO,CAAC,QAAQ,CAAC,GAAG,GAAG,CAAC;YAC1B,CAAC,CAAC,CAAC;YACH,MAAM,sBAAsB,GAAa,EAAE,CAAC;YAC5C,qBAAqB,CAAC,OAAO,CAAC,CAAC,QAAQ,EAAE,EAAE;gBACzC,sBAAsB,CAAC,IAAI,CAAC,cAAc,CAAC,GAAG,CAAC,QAAQ,CAAC,IAAI,QAAQ,CAAC,CAAC;YACxE,CAAC,CAAC,CAAC;YACH,UAAU,CAAC,WAAW,CAAC;gBACrB,IAAI,EAAE,OAAO;gBACb,KAAK;gBACL,OAAO;gBACP,KAAK,EAAE,EAAE,MAAM,EAAE,WAAW,EAAE,eAAe,EAAE,SAAS,EAAE,YAAY,EAAE,sBAAsB,EAAE;aACjG,CAAC,CAAC;QACL,CAAC;IACH,CAAC,CAAC,CAAC;IAEH,gFAAgF;IAChF,MAAM,aAAa,GAAG,IAAI,CAAC,GAAG,EAAE,CAAC;IACjC,IAAI,CAAC,gBAAgB,CAAC;SACnB,IAAI,CAAC,GAAG,EAAE,CAAC,IAAI,CAAC,iBAAiB,CAAC,CAAC;SACnC,IAAI,CAAC,GAAG,EAAE,CAAC,IAAI,CAAC,kBAAkB,EAAE,EAAE,UAAU,EAAE,oCAAoC,EAAE,CAAC,CAAC;SAC1F,IAAI,CAAC,CAAC,UAAe,EAAE,EAAE;QACxB,MAAM,QAAQ,GAAG,UAAU,IAAI,UAAU,CAAC,MAAM,IAAI,UAAU,CAAC,MAAM,CAAC,QAAQ,CAAC;QAC/E,IAAI,CAAC,QAAQ;YAAE,OAAO,IAAI,CAAC;QAC3B,OAAO,IAAI,CAAC,uBAAuB,EAAE,EAAE,QAAQ,EAAE,aAAa,EAAE,IAAI,EAAE,CAAC,CAAC,IAAI,CAAC,CAAC,QAAa,EAAE,EAAE;YAC7F,MAAM,gBAAgB,GAAG,CAAC,QAAQ,CAAC,kBAAkB,IAAI,EAAE,CAAC,CAAC,IAAI,CAAC,CAAC,QAAa,EAAE,EAAE,CAAC,QAAQ,CAAC,IAAI,KAAK,sBAAsB,CAAC,CAAC;YAC/H,MAAM,QAAQ,GAAG,gBAAgB,IAAI,gBAAgB,CAAC,KAAK,IAAI,gBAAgB,CAAC,KAAK,CAAC,KAAK,CAAC;YAC5F,OAAO,QAAQ,CAAC,CAAC,CAAC,QAAQ,CAAC,QAAQ,CAAC,CAAC,CAAC,IAAI,CAAC;QAC7C,CAAC,CAAC,CAAC;IACL,CAAC,CAAC;SACD,IAAI,CAAC,CAAC,qBAAoC,EAAE,EAAE;QAC7C,MAAM,eAAe,GAAG,IAAI,GAAG,EAAU,CAAC;QAC1C,IAAI,qBAAqB,EAAE,CAAC;YAC1B,eAAe,CAAC,GAAG,CAAC,qBAAqB,CAAC,CAAC;YAE3C,MAAM,cAAc,GAAG,kBAAkB,CAAC,cAAc,CAAC,GAAG,CAAC,qBAAqB,CAAC,IAAI,EAAE,CAAC,CAAC;YAC3F,iBAAiB,GAAG,cAAc,CAAC,KAAK,CAAC,CAAC,EAAE,cAAc,CAAC,WAAW,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC;QACnF,CAAC;QAED,cAAc,CAAC,OAAO,CAAC,CAAC,GAAG,EAAE,QAAQ,EAAE,EAAE;YACvC,IAAI,gBAAgB,CAAC,GAAG,CAAC;gBAAE,eAAe,CAAC,GAAG,CAAC,QAAQ,CAAC,CAAC;QAC3D,CAAC,CAAC,CAAC;QAEH,IAAI,eAAe,CAAC,IAAI,KAAK,CAAC,EAAE,CAAC;YAC/B,MAAM,IAAI,KAAK,CAAC,kGAAkG,CAAC,CAAC;QACtH,CAAC;QAED,MAAM,gBAAgB,GAAoB,EAAE,CAAC;QAC7C,eAAe,CAAC,OAAO,CAAC,CAAC,QAAQ,EAAE,EAAE;YACnC,gBAAgB,CAAC,IAAI,CAAC,gBAAgB,CAAC,QAAQ,CAAC,CAAC,CAAC;QACpD,CAAC,CAAC,CAAC;QACH,OAAO,OAAO,CAAC,GAAG,CAAC,gBAAgB,CAAC,CAAC,IAAI,CAAC,GAAG,EAAE,CAAC,eAAe,CAAC,CAAC;IACnE,CAAC,CAAC;SACD,IAAI,CAAC,CAAC,eAAoB,EAAE,EAAE;QAC7B,KAAK,GAAG,IAAI,CAAC;QACb,YAAY,GAAG,IAAI,CAAC,GAAG,EAAE,GAAG,aAAa,CAAC;QAC1C,MAAM,gBAAgB,GAAa,EAAE,CAAC;QACtC,eAAe,CAAC,OAAO,CAAC,CAAC,QAAgB,EAAE,EAAE,CAAC,gBAAgB,CAAC,IAAI,CAAC,cAAc,CAAC,GAAG,CAAC,QAAQ,CAAC,IAAI,QAAQ,CAAC,CAAC,CAAC;QAC/G,UAAU,CAAC,WAAW,CAAC,EAAE,IAAI,EAAE,OAAO,EAAE,gBAAgB,EAAE,CAAC,CAAC;IAC9D,CAAC,CAAC;SACD,KAAK,CAAC,KAAK,CAAC,CAAC;AAClB,CAAC","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"]}
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 // Script end positions from scriptParsed. getPossibleBreakpoints MUST be given an\n // explicit end: with the range left open, V8 answers with an empty list once the\n // script's bytecode has been flushed by GC (functions parsed but not run for a few\n // collections), so a story loaded a while before the trace would get no breakpoints.\n const scriptEndById = new Map<string, { lineNumber: number; columnNumber: number }>();\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 const scriptEnd = scriptEndById.get(scriptId);\n\n const readPage = (startLine: number, startColumn: number): Promise<any[]> =>\n post('Debugger.getPossibleBreakpoints', {\n start: { scriptId, lineNumber: startLine, columnNumber: startColumn },\n end: scriptEnd ? { scriptId, lineNumber: scriptEnd.lineNumber, columnNumber: scriptEnd.columnNumber } : undefined,\n }).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 scriptEndById.set(message.params.scriptId, { lineNumber: message.params.endLine, columnNumber: message.params.endColumn });\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"]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "quidproquo-actionprocessor-node",
3
- "version": "0.1.20",
3
+ "version": "0.1.22",
4
4
  "description": "",
5
5
  "main": "./lib/commonjs/index.js",
6
6
  "module": "./lib/esm/index.js",
@@ -36,15 +36,15 @@
36
36
  "homepage": "https://github.com/qpqjs/quidproquo#readme",
37
37
  "dependencies": {
38
38
  "@jridgewell/trace-mapping": "^0.3.25",
39
- "quidproquo-actionprocessor-js": "0.1.20",
40
- "quidproquo-core": "0.1.20",
41
- "quidproquo-webserver": "0.1.20",
39
+ "quidproquo-actionprocessor-js": "0.1.22",
40
+ "quidproquo-core": "0.1.22",
41
+ "quidproquo-webserver": "0.1.22",
42
42
  "uuidv7": "^1.0.1"
43
43
  },
44
44
  "devDependencies": {
45
45
  "@jridgewell/gen-mapping": "^0.3.13",
46
46
  "@types/node": "^22.13.13",
47
- "quidproquo-tsconfig": "0.1.20",
47
+ "quidproquo-tsconfig": "0.1.22",
48
48
  "typescript": "^5.8.2"
49
49
  }
50
50
  }