tubeless 0.2.0 → 0.2.2
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.
- package/dist/cli/cli-command.d.ts +2 -2
- package/dist/cli/cli-command.js +28 -45
- package/dist/cli/cli-command.js.map +1 -1
- package/dist/cli/cli-pipeline-command.js +1 -1
- package/dist/cli/cli-pipeline-command.js.map +1 -1
- package/dist/core/child-execution.js +65 -4
- package/dist/core/child-execution.js.map +1 -1
- package/dist/core/child-progress.d.ts +6 -0
- package/dist/core/child-progress.js +48 -0
- package/dist/core/child-progress.js.map +1 -0
- package/dist/core/mapped-child-progress.d.ts +4 -2
- package/dist/core/mapped-child-progress.js.map +1 -1
- package/dist/core/pipeline-steps.d.ts +3 -3
- package/dist/core/pipeline-steps.js +12 -23
- package/dist/core/pipeline-steps.js.map +1 -1
- package/dist/core/pipeline-types.d.ts +8 -1
- package/dist/core/pipeline-types.js.map +1 -1
- package/dist/render/render.js +2 -6
- package/dist/render/render.js.map +1 -1
- package/dist/reporter/interactive-reporter.d.ts +1 -0
- package/dist/reporter/interactive-reporter.js +50 -15
- package/dist/reporter/interactive-reporter.js.map +1 -1
- package/dist/reporter/live-ticker-worker.js +8 -42
- package/dist/reporter/live-ticker-worker.js.map +1 -1
- package/dist/reporter/live-ticker.d.ts +10 -0
- package/dist/reporter/live-ticker.js +50 -47
- package/dist/reporter/live-ticker.js.map +1 -1
- package/dist/run-store/run-store-ndjson.js +8 -2
- package/dist/run-store/run-store-ndjson.js.map +1 -1
- package/dist/run-store/run-store.js +14 -33
- package/dist/run-store/run-store.js.map +1 -1
- package/dist/studio/run-store-ui-client-source.js +1 -1
- package/dist/studio/run-store-ui-client.d.ts +0 -1
- package/dist/studio/run-store-ui-client.js +5 -35
- package/dist/studio/run-store-ui-client.js.map +1 -1
- package/dist/studio/run-store-ui-page.d.ts +1 -1
- package/dist/studio/run-store-ui-page.js +1 -1
- package/dist/studio/run-store-ui-page.js.map +1 -1
- package/dist/tracing/tracing-internal.js +31 -5
- package/dist/tracing/tracing-internal.js.map +1 -1
- package/dist/workbench/pipeline-module.d.ts +2 -12
- package/dist/workbench/pipeline-module.js +4 -11
- package/dist/workbench/pipeline-module.js.map +1 -1
- package/dist/workbench/workbench-project-loader.js +1 -1
- package/dist/workbench/workbench-project-loader.js.map +1 -1
- package/dist/workbench/workbench-ui.js +1 -1
- package/dist/workbench/workbench-ui.js.map +1 -1
- package/docs/agent-guide.md +8 -0
- package/docs/api-reference.md +12 -12
- package/docs/api-report.json +12 -12
- package/docs/child-pipeline-composition.md +51 -19
- package/docs/cli.md +25 -0
- package/docs/recipes.md +2 -2
- package/examples/catalog/tubeless.project.ts +6 -0
- package/examples/fan-out-progress.ts +16 -2
- package/package.json +2 -1
|
@@ -117,6 +117,40 @@ function replaceLiveTokens(line, spinner, nowMs, color) {
|
|
|
117
117
|
export function paintLiveLines(lines, spinner, nowMs, columns, color = false) {
|
|
118
118
|
return lines.map((line) => fitLine(replaceLiveTokens(line, spinner, nowMs, color), columns));
|
|
119
119
|
}
|
|
120
|
+
/** Cursor and frame ownership shared by inline and worker tickers. */
|
|
121
|
+
export class TickerFrame {
|
|
122
|
+
write;
|
|
123
|
+
frameLineCount;
|
|
124
|
+
cursorHidden;
|
|
125
|
+
constructor(write, frameLineCount = 0) {
|
|
126
|
+
this.write = write;
|
|
127
|
+
this.frameLineCount = frameLineCount;
|
|
128
|
+
this.cursorHidden = frameLineCount > 0;
|
|
129
|
+
}
|
|
130
|
+
showCursor() {
|
|
131
|
+
if (!this.cursorHidden)
|
|
132
|
+
return;
|
|
133
|
+
this.write(ANSI.showCursor);
|
|
134
|
+
this.cursorHidden = false;
|
|
135
|
+
}
|
|
136
|
+
clear() {
|
|
137
|
+
if (this.frameLineCount === 0)
|
|
138
|
+
return;
|
|
139
|
+
this.write(`\u001B[${this.frameLineCount}F${ANSI.clearDown}`);
|
|
140
|
+
this.frameLineCount = 0;
|
|
141
|
+
}
|
|
142
|
+
redraw(lines) {
|
|
143
|
+
if (!this.cursorHidden) {
|
|
144
|
+
this.write(ANSI.hideCursor);
|
|
145
|
+
this.cursorHidden = true;
|
|
146
|
+
}
|
|
147
|
+
this.clear();
|
|
148
|
+
if (lines.length === 0)
|
|
149
|
+
return;
|
|
150
|
+
this.write(`${lines.join("\n")}\n`);
|
|
151
|
+
this.frameLineCount = lines.length;
|
|
152
|
+
}
|
|
153
|
+
}
|
|
120
154
|
function resolveColumns(options) {
|
|
121
155
|
return options.getColumns?.() ?? options.columns;
|
|
122
156
|
}
|
|
@@ -125,72 +159,41 @@ export function currentSpinner(unicode, refreshIntervalMs) {
|
|
|
125
159
|
return frames[Math.floor(Date.now() / refreshIntervalMs) % frames.length] ?? frames[0];
|
|
126
160
|
}
|
|
127
161
|
function createInlineTicker(options, adoptedFrameLineCount = 0) {
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
frameLineCount: adoptedFrameLineCount,
|
|
132
|
-
lines: [],
|
|
133
|
-
};
|
|
134
|
-
const write = (chunk) => {
|
|
135
|
-
options.write(chunk);
|
|
136
|
-
};
|
|
137
|
-
const hideCursor = () => {
|
|
138
|
-
if (state.cursorHidden)
|
|
139
|
-
return;
|
|
140
|
-
write(ANSI.hideCursor);
|
|
141
|
-
state.cursorHidden = true;
|
|
142
|
-
};
|
|
143
|
-
const showCursor = () => {
|
|
144
|
-
if (!state.cursorHidden)
|
|
145
|
-
return;
|
|
146
|
-
write(ANSI.showCursor);
|
|
147
|
-
state.cursorHidden = false;
|
|
148
|
-
};
|
|
149
|
-
const clearFrame = () => {
|
|
150
|
-
if (state.frameLineCount === 0)
|
|
151
|
-
return;
|
|
152
|
-
write(`\u001B[${state.frameLineCount}F${ANSI.clearDown}`);
|
|
153
|
-
state.frameLineCount = 0;
|
|
154
|
-
};
|
|
162
|
+
let disposed = false;
|
|
163
|
+
let lines = [];
|
|
164
|
+
const frame = new TickerFrame((chunk) => options.write(chunk), adoptedFrameLineCount);
|
|
155
165
|
const redraw = () => {
|
|
156
|
-
if (
|
|
166
|
+
if (disposed)
|
|
157
167
|
return;
|
|
158
|
-
|
|
159
|
-
clearFrame();
|
|
160
|
-
if (state.lines.length === 0)
|
|
161
|
-
return;
|
|
162
|
-
const painted = paintLiveLines(state.lines, currentSpinner(options.unicode, options.refreshIntervalMs), Date.now(), resolveColumns(options), options.color === true);
|
|
163
|
-
write(`${painted.join("\n")}\n`);
|
|
164
|
-
state.frameLineCount = painted.length;
|
|
168
|
+
frame.redraw(paintLiveLines(lines, currentSpinner(options.unicode, options.refreshIntervalMs), Date.now(), resolveColumns(options), options.color === true));
|
|
165
169
|
};
|
|
166
170
|
const timer = setInterval(() => {
|
|
167
|
-
if (
|
|
168
|
-
!
|
|
171
|
+
if (disposed ||
|
|
172
|
+
!lines.some((line) => line.includes(SPINNER_TOKEN) || line.includes(SHIMMER_TOKEN_START))) {
|
|
169
173
|
return;
|
|
170
174
|
}
|
|
171
175
|
redraw();
|
|
172
176
|
}, options.refreshIntervalMs);
|
|
173
177
|
timer.unref();
|
|
174
178
|
return {
|
|
175
|
-
setLines(
|
|
176
|
-
|
|
179
|
+
setLines(nextLines) {
|
|
180
|
+
lines = nextLines;
|
|
177
181
|
redraw();
|
|
178
182
|
},
|
|
179
183
|
writeLog(text) {
|
|
180
|
-
if (
|
|
181
|
-
write(text);
|
|
184
|
+
if (disposed) {
|
|
185
|
+
options.write(text);
|
|
182
186
|
return;
|
|
183
187
|
}
|
|
184
|
-
|
|
185
|
-
write(text);
|
|
186
|
-
state.frameLineCount = 0;
|
|
188
|
+
frame.clear();
|
|
189
|
+
options.write(text);
|
|
187
190
|
},
|
|
188
191
|
dispose() {
|
|
189
|
-
if (
|
|
192
|
+
if (disposed)
|
|
190
193
|
return;
|
|
191
|
-
|
|
194
|
+
disposed = true;
|
|
192
195
|
clearInterval(timer);
|
|
193
|
-
showCursor();
|
|
196
|
+
frame.showCursor();
|
|
194
197
|
},
|
|
195
198
|
};
|
|
196
199
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"live-ticker.js","sourceRoot":"","sources":["../../src/reporter/live-ticker.ts"],"names":[],"mappings":"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","sourcesContent":["import { writeSync } from \"node:fs\";\nimport { Worker } from \"node:worker_threads\";\nimport { formatDurationMs } from \"./reporter.js\";\n\nexport const SPINNER_TOKEN = \"\\u0001\";\nconst ELAPSED_TOKEN_START = \"\\u0002\";\nconst ELAPSED_TOKEN_END = \"\\u0003\";\nexport const SHIMMER_TOKEN_START = \"\\u0004\";\nconst SHIMMER_TOKEN_END = \"\\u0005\";\n\nconst ANSI = {\n clearDown: \"\\u001B[J\",\n hideCursor: \"\\u001B[?25l\",\n reset: \"\\u001B[0m\",\n showCursor: \"\\u001B[?25h\",\n} as const;\n\nconst SHIMMER_BAND_COLUMNS = 3;\nconst SHIMMER_BRIGHT = \"\\u001B[0;1;36m\";\nconst SHIMMER_DIM = \"\\u001B[0;2;36m\";\nconst SHIMMER_FRAME_MS = 80;\n\nconst ANSI_STYLE = /\\u001B\\[[0-9;]*m/g;\nconst ANSI_STYLE_PREFIX = /^\\u001B\\[[0-9;]*m/;\nconst COMBINING_MARK = /\\p{Mark}/u;\nconst EMOJI = /\\p{Extended_Pictographic}/u;\n\nconst SPINNERS = {\n ascii: [\"-\", \"\\\\\", \"|\", \"/\"],\n unicode: [\"⠋\", \"⠙\", \"⠹\", \"⠸\", \"⠼\", \"⠴\", \"⠦\", \"⠧\", \"⠇\", \"⠏\"],\n} as const;\n\nfunction characterWidth(character: string): number {\n if (COMBINING_MARK.test(character) || character === \"\\u200D\") return 0;\n if (EMOJI.test(character)) return 2;\n const codePoint = character.codePointAt(0) ?? 0;\n return codePoint >= 0x1100 &&\n (codePoint <= 0x115f ||\n codePoint === 0x2329 ||\n codePoint === 0x232a ||\n (codePoint >= 0x2e80 && codePoint <= 0xa4cf) ||\n (codePoint >= 0xac00 && codePoint <= 0xd7a3) ||\n (codePoint >= 0xf900 && codePoint <= 0xfaff) ||\n (codePoint >= 0xfe10 && codePoint <= 0xfe6f) ||\n (codePoint >= 0xff00 && codePoint <= 0xff60) ||\n (codePoint >= 0xffe0 && codePoint <= 0xffe6) ||\n (codePoint >= 0x20000 && codePoint <= 0x3fffd))\n ? 2\n : 1;\n}\n\nfunction visibleWidth(value: string): number {\n return [...value].reduce((width, character) => width + characterWidth(character), 0);\n}\n\nfunction fitLine(value: string, columns: number | undefined): string {\n if (!columns || columns <= 1) return value;\n const maxWidth = columns - 1;\n const plain = value.replace(ANSI_STYLE, \"\");\n if (visibleWidth(plain) <= maxWidth) return value;\n const targetWidth = Math.max(0, maxWidth - 1);\n let width = 0;\n let truncated = \"\";\n let index = 0;\n let hasStyle = false;\n while (index < value.length) {\n const style = value.slice(index).match(ANSI_STYLE_PREFIX)?.[0];\n if (style) {\n truncated += style;\n index += style.length;\n hasStyle = true;\n continue;\n }\n const character = String.fromCodePoint(value.codePointAt(index) ?? 0);\n const nextWidth = width + characterWidth(character);\n if (nextWidth > targetWidth) break;\n truncated += character;\n width = nextWidth;\n index += character.length;\n }\n return `${truncated}${hasStyle ? ANSI.reset : \"\"}…`;\n}\n\nexport function elapsedToken(startedAtMs: number): string {\n return `${ELAPSED_TOKEN_START}${startedAtMs}${ELAPSED_TOKEN_END}`;\n}\n\nexport function shimmerToken(value: string): string {\n return `${SHIMMER_TOKEN_START}${value}${SHIMMER_TOKEN_END}`;\n}\n\nfunction paintShimmerText(text: string, nowMs: number): string {\n const characters = [...text];\n if (characters.length === 0) return text;\n const widths = characters.map(characterWidth);\n const totalWidth = visibleWidth(text);\n const period = Math.max(1, totalWidth + SHIMMER_BAND_COLUMNS);\n const head = Math.floor(nowMs / SHIMMER_FRAME_MS) % period;\n const bandStart = head - SHIMMER_BAND_COLUMNS + 1;\n let column = 0;\n let output = ANSI.reset;\n let last: \"bright\" | \"dim\" | undefined;\n for (const [index, character] of characters.entries()) {\n const width = widths[index] ?? 0;\n const inBand =\n width === 0 ? last === \"bright\" : column <= head && column + width - 1 >= bandStart;\n const style = inBand ? \"bright\" : \"dim\";\n if (style !== last) {\n output += style === \"bright\" ? SHIMMER_BRIGHT : SHIMMER_DIM;\n last = style;\n }\n output += character;\n column += width;\n }\n return `${output}${ANSI.reset}`;\n}\n\nfunction replaceLiveTokens(line: string, spinner: string, nowMs: number, color: boolean): string {\n return line\n .replaceAll(SPINNER_TOKEN, spinner)\n .replace(\n new RegExp(`${ELAPSED_TOKEN_START}(\\\\d+)${ELAPSED_TOKEN_END}`, \"g\"),\n (_match, start: string) => formatDurationMs(Math.max(0, nowMs - Number(start)))\n )\n .replace(\n new RegExp(`${SHIMMER_TOKEN_START}(.*?)${SHIMMER_TOKEN_END}`, \"g\"),\n (_match, text: string) => (color ? paintShimmerText(text, nowMs) : text)\n );\n}\n\nexport function paintLiveLines(\n lines: readonly string[],\n spinner: string,\n nowMs: number,\n columns?: number,\n color = false\n): string[] {\n return lines.map((line) => fitLine(replaceLiveTokens(line, spinner, nowMs, color), columns));\n}\n\nexport interface LiveTicker {\n setLines(lines: readonly string[]): void;\n writeLog(text: string): void;\n dispose(): void;\n}\n\nexport interface LiveTickerOptions {\n columns?: number;\n getColumns?(): number | undefined;\n fd?: number;\n refreshIntervalMs: number;\n unicode: boolean;\n color?: boolean;\n write(chunk: string): void;\n workerUrl?: URL;\n supervisorUrl?: URL;\n}\n\ntype TickerWorkerMessage =\n | { columns?: number; lines: string[]; type: \"lines\" }\n | { text: string; type: \"log\" }\n | { columns?: number; lines: string[]; type: \"stop\" };\n\ninterface TickerState {\n cursorHidden: boolean;\n disposed: boolean;\n frameLineCount: number;\n lines: readonly string[];\n}\n\nfunction resolveColumns(options: LiveTickerOptions): number | undefined {\n return options.getColumns?.() ?? options.columns;\n}\n\nexport function currentSpinner(unicode: boolean, refreshIntervalMs: number): string {\n const frames = unicode ? SPINNERS.unicode : SPINNERS.ascii;\n return frames[Math.floor(Date.now() / refreshIntervalMs) % frames.length] ?? frames[0]!;\n}\n\nfunction createInlineTicker(options: LiveTickerOptions, adoptedFrameLineCount = 0): LiveTicker {\n const state: TickerState = {\n cursorHidden: adoptedFrameLineCount > 0,\n disposed: false,\n frameLineCount: adoptedFrameLineCount,\n lines: [],\n };\n\n const write = (chunk: string): void => {\n options.write(chunk);\n };\n\n const hideCursor = (): void => {\n if (state.cursorHidden) return;\n write(ANSI.hideCursor);\n state.cursorHidden = true;\n };\n\n const showCursor = (): void => {\n if (!state.cursorHidden) return;\n write(ANSI.showCursor);\n state.cursorHidden = false;\n };\n\n const clearFrame = (): void => {\n if (state.frameLineCount === 0) return;\n write(`\\u001B[${state.frameLineCount}F${ANSI.clearDown}`);\n state.frameLineCount = 0;\n };\n\n const redraw = (): void => {\n if (state.disposed) return;\n hideCursor();\n clearFrame();\n if (state.lines.length === 0) return;\n const painted = paintLiveLines(\n state.lines,\n currentSpinner(options.unicode, options.refreshIntervalMs),\n Date.now(),\n resolveColumns(options),\n options.color === true\n );\n write(`${painted.join(\"\\n\")}\\n`);\n state.frameLineCount = painted.length;\n };\n\n const timer = setInterval(() => {\n if (\n state.disposed ||\n !state.lines.some(\n (line) => line.includes(SPINNER_TOKEN) || line.includes(SHIMMER_TOKEN_START)\n )\n ) {\n return;\n }\n redraw();\n }, options.refreshIntervalMs);\n timer.unref();\n\n return {\n setLines(lines) {\n state.lines = lines;\n redraw();\n },\n writeLog(text) {\n if (state.disposed) {\n write(text);\n return;\n }\n clearFrame();\n write(text);\n state.frameLineCount = 0;\n },\n dispose() {\n if (state.disposed) return;\n state.disposed = true;\n clearInterval(timer);\n showCursor();\n },\n };\n}\n\nfunction resolveCompiledWorkerUrl(filename: string): URL {\n if (import.meta.url.endsWith(\".ts\")) {\n return new URL(`../../dist/reporter/${filename}`, import.meta.url);\n }\n return new URL(`./${filename}`, import.meta.url);\n}\n\nfunction resolveLiveTickerWorkerUrl(): URL {\n return resolveCompiledWorkerUrl(\"live-ticker-worker.js\");\n}\n\nfunction resolveLiveTickerSupervisorUrl(): URL {\n return resolveCompiledWorkerUrl(\"live-ticker-supervisor.js\");\n}\n\nfunction fileWorkerExecArgv(argv: readonly string[] = process.execArgv): string[] {\n const next: string[] = [];\n for (let i = 0; i < argv.length; i += 1) {\n const arg = argv[i];\n if (arg === \"--input-type\") {\n i += 1;\n continue;\n }\n if (arg.startsWith(\"--input-type=\")) continue;\n next.push(arg);\n }\n return next;\n}\n\nfunction createWorkerTicker(options: LiveTickerOptions & { fd: number }): LiveTicker {\n // [0] stop handshake, [1] painted rows, [2] accepted logs, [3] liveness beat\n const handshakeBuffer = new SharedArrayBuffer(16);\n const handshake = new Int32Array(handshakeBuffer);\n // [0] terminate request, [1] ticker isolate exited\n const controlBuffer = new SharedArrayBuffer(8);\n const control = new Int32Array(controlBuffer);\n const worker = new Worker(options.supervisorUrl ?? resolveLiveTickerSupervisorUrl(), {\n execArgv: fileWorkerExecArgv(),\n workerData: {\n controlBuffer,\n execArgv: fileWorkerExecArgv(),\n tickerData: {\n color: options.color === true,\n columns: resolveColumns(options),\n fd: options.fd,\n handshakeBuffer,\n refreshIntervalMs: options.refreshIntervalMs,\n unicode: options.unicode,\n },\n tickerUrl: (options.workerUrl ?? resolveLiveTickerWorkerUrl()).href,\n },\n });\n let disposed = false;\n let finalFramePainted = false;\n let inlineFallback: LiveTicker | undefined;\n let lines: readonly string[] = [];\n const pendingLogs: string[] = [];\n let ackedLogs = 0;\n\n const paintedFrameLineCount = (): number => Atomics.load(handshake, 1);\n\n const dropAcknowledgedLogs = (): void => {\n const accepted = Atomics.load(handshake, 2);\n if (accepted <= ackedLogs) return;\n pendingLogs.splice(0, accepted - ackedLogs);\n ackedLogs = accepted;\n };\n\n const send = (message: TickerWorkerMessage): void => {\n if (disposed || inlineFallback) return;\n worker.postMessage(message);\n };\n\n let supervisorGone = false;\n\n const requestTerminate = (): void => {\n Atomics.store(control, 0, 1);\n Atomics.notify(control, 0);\n try {\n worker.postMessage({ type: \"terminate\" });\n } catch {\n // Supervisor is already gone; isolate exit is best-effort.\n supervisorGone = true;\n }\n };\n\n // Supervisor stores control[1] on the ticker isolate's exit event.\n // A stale refresh beat is not isolate death: refreshIntervalMs is\n // user-configurable, and stop handlers clear the timer before done().\n const isolateNeverStarted = (): boolean =>\n Atomics.load(control, 1) === 0 &&\n Atomics.load(handshake, 1) === 0 &&\n Atomics.load(handshake, 2) === 0 &&\n Atomics.load(handshake, 3) === 0;\n\n const joinTickerIsolate = (ms: number): void => {\n // Only the supervisor stores control[1]. Once it is gone the join\n // cannot observe isolate exit, so skip rather than park for 1s.\n if (supervisorGone || Atomics.load(control, 1) === 1) return;\n Atomics.wait(control, 1, 0, ms);\n };\n\n const drainOwnershipWindow = (): void => {\n const park = new Int32Array(new SharedArrayBuffer(4));\n Atomics.wait(park, 0, 0, 160);\n };\n\n const stopWorker = (): void => {\n requestTerminate();\n try {\n joinTickerIsolate(1_000);\n // Exit can land in the same millisecond as the last beat. Wait out\n // the 80ms ownership window before the parent takes the fd.\n // supervisorGone is not enough to skip: a mid-flight supervisor\n // crash can leave the isolate still writing. Skip only when the\n // isolate never published a frame, log, beat, or exit.\n if (Atomics.load(handshake, 0) !== 1 && !isolateNeverStarted()) {\n drainOwnershipWindow();\n }\n } finally {\n void worker.terminate();\n }\n };\n\n const replayThrough = (ticker: LiveTicker): void => {\n dropAcknowledgedLogs();\n for (const text of pendingLogs) {\n ticker.writeLog(text);\n }\n pendingLogs.length = 0;\n ticker.setLines([...lines]);\n };\n\n const paintFinalFrame = (): void => {\n if (finalFramePainted) return;\n finalFramePainted = true;\n try {\n const ticker = createInlineTicker(options, paintedFrameLineCount());\n replayThrough(ticker);\n ticker.dispose();\n } catch {\n // Stream may already be closed after dispose.\n }\n };\n\n const failToInline = (): void => {\n if (inlineFallback || finalFramePainted) return;\n if (disposed) {\n if (Atomics.load(handshake, 0) !== 1) paintFinalFrame();\n return;\n }\n inlineFallback = createInlineTicker(options, paintedFrameLineCount());\n replayThrough(inlineFallback);\n };\n const requestedTerminate = (): boolean => Atomics.load(control, 0) === 1;\n\n worker.on(\"error\", () => {\n supervisorGone = true;\n if (!requestedTerminate()) failToInline();\n });\n worker.on(\"exit\", (code) => {\n supervisorGone = true;\n if (code !== 0 && !requestedTerminate()) failToInline();\n });\n worker.unref();\n worker.on(\n \"message\",\n (msg: {\n code?: number;\n event?: string;\n kind?: string;\n terminated?: boolean;\n type?: string;\n }) => {\n if (msg.type === \"supervisor\" && msg.event === \"error\") {\n if (msg.terminated !== true && !requestedTerminate()) failToInline();\n return;\n }\n if (msg.type === \"supervisor\" && msg.event === \"exit\") {\n if (msg.code !== 0 && msg.terminated !== true && !requestedTerminate()) {\n failToInline();\n }\n return;\n }\n if (msg.type === \"ack\" && msg.kind === \"log\") dropAcknowledgedLogs();\n }\n );\n\n return {\n setLines(nextLines) {\n lines = nextLines;\n if (inlineFallback) {\n inlineFallback.setLines(nextLines);\n return;\n }\n send({ columns: resolveColumns(options), lines: [...nextLines], type: \"lines\" });\n },\n writeLog(text) {\n if (inlineFallback) {\n inlineFallback.writeLog(text);\n return;\n }\n if (disposed) {\n writeSync(options.fd, text);\n return;\n }\n dropAcknowledgedLogs();\n pendingLogs.push(text);\n send({ text, type: \"log\" });\n },\n dispose() {\n if (disposed) return;\n disposed = true;\n if (inlineFallback) {\n inlineFallback.dispose();\n stopWorker();\n return;\n }\n Atomics.store(handshake, 0, 0);\n try {\n worker.postMessage({\n columns: resolveColumns(options),\n lines: [...lines],\n type: \"stop\",\n });\n } catch {\n stopWorker();\n paintFinalFrame();\n return;\n }\n if (Atomics.wait(handshake, 0, 0, 500) === \"timed-out\") {\n stopWorker();\n if (Atomics.load(handshake, 0) !== 1) paintFinalFrame();\n try {\n writeSync(options.fd, ANSI.showCursor);\n } catch {\n // Stream may already be closed; cursor restore is best-effort.\n }\n return;\n }\n try {\n writeSync(options.fd, ANSI.showCursor);\n } catch {\n // Stream may already be closed; cursor restore is best-effort.\n }\n stopWorker();\n },\n };\n}\n\nfunction outputFd(fd: number | undefined): fd is number {\n return fd !== undefined && Number.isInteger(fd) && fd >= 0;\n}\n\n/** Inline interval for tests; worker thread when `fd` is a real TTY/pipe. */\nexport function createLiveTicker(options: LiveTickerOptions): LiveTicker {\n if (outputFd(options.fd)) {\n try {\n return createWorkerTicker({ ...options, fd: options.fd });\n } catch {\n // Worker threads are unavailable in some embeddings; fall back.\n }\n }\n return createInlineTicker(options);\n}\n"]}
|
|
1
|
+
{"version":3,"file":"live-ticker.js","sourceRoot":"","sources":["../../src/reporter/live-ticker.ts"],"names":[],"mappings":"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","sourcesContent":["import { writeSync } from \"node:fs\";\nimport { Worker } from \"node:worker_threads\";\nimport { formatDurationMs } from \"./reporter.js\";\n\nexport const SPINNER_TOKEN = \"\\u0001\";\nconst ELAPSED_TOKEN_START = \"\\u0002\";\nconst ELAPSED_TOKEN_END = \"\\u0003\";\nexport const SHIMMER_TOKEN_START = \"\\u0004\";\nconst SHIMMER_TOKEN_END = \"\\u0005\";\n\nconst ANSI = {\n clearDown: \"\\u001B[J\",\n hideCursor: \"\\u001B[?25l\",\n reset: \"\\u001B[0m\",\n showCursor: \"\\u001B[?25h\",\n} as const;\n\nconst SHIMMER_BAND_COLUMNS = 3;\nconst SHIMMER_BRIGHT = \"\\u001B[0;1;36m\";\nconst SHIMMER_DIM = \"\\u001B[0;2;36m\";\nconst SHIMMER_FRAME_MS = 80;\n\nconst ANSI_STYLE = /\\u001B\\[[0-9;]*m/g;\nconst ANSI_STYLE_PREFIX = /^\\u001B\\[[0-9;]*m/;\nconst COMBINING_MARK = /\\p{Mark}/u;\nconst EMOJI = /\\p{Extended_Pictographic}/u;\n\nconst SPINNERS = {\n ascii: [\"-\", \"\\\\\", \"|\", \"/\"],\n unicode: [\"⠋\", \"⠙\", \"⠹\", \"⠸\", \"⠼\", \"⠴\", \"⠦\", \"⠧\", \"⠇\", \"⠏\"],\n} as const;\n\nfunction characterWidth(character: string): number {\n if (COMBINING_MARK.test(character) || character === \"\\u200D\") return 0;\n if (EMOJI.test(character)) return 2;\n const codePoint = character.codePointAt(0) ?? 0;\n return codePoint >= 0x1100 &&\n (codePoint <= 0x115f ||\n codePoint === 0x2329 ||\n codePoint === 0x232a ||\n (codePoint >= 0x2e80 && codePoint <= 0xa4cf) ||\n (codePoint >= 0xac00 && codePoint <= 0xd7a3) ||\n (codePoint >= 0xf900 && codePoint <= 0xfaff) ||\n (codePoint >= 0xfe10 && codePoint <= 0xfe6f) ||\n (codePoint >= 0xff00 && codePoint <= 0xff60) ||\n (codePoint >= 0xffe0 && codePoint <= 0xffe6) ||\n (codePoint >= 0x20000 && codePoint <= 0x3fffd))\n ? 2\n : 1;\n}\n\nfunction visibleWidth(value: string): number {\n return [...value].reduce((width, character) => width + characterWidth(character), 0);\n}\n\nfunction fitLine(value: string, columns: number | undefined): string {\n if (!columns || columns <= 1) return value;\n const maxWidth = columns - 1;\n const plain = value.replace(ANSI_STYLE, \"\");\n if (visibleWidth(plain) <= maxWidth) return value;\n const targetWidth = Math.max(0, maxWidth - 1);\n let width = 0;\n let truncated = \"\";\n let index = 0;\n let hasStyle = false;\n while (index < value.length) {\n const style = value.slice(index).match(ANSI_STYLE_PREFIX)?.[0];\n if (style) {\n truncated += style;\n index += style.length;\n hasStyle = true;\n continue;\n }\n const character = String.fromCodePoint(value.codePointAt(index) ?? 0);\n const nextWidth = width + characterWidth(character);\n if (nextWidth > targetWidth) break;\n truncated += character;\n width = nextWidth;\n index += character.length;\n }\n return `${truncated}${hasStyle ? ANSI.reset : \"\"}…`;\n}\n\nexport function elapsedToken(startedAtMs: number): string {\n return `${ELAPSED_TOKEN_START}${startedAtMs}${ELAPSED_TOKEN_END}`;\n}\n\nexport function shimmerToken(value: string): string {\n return `${SHIMMER_TOKEN_START}${value}${SHIMMER_TOKEN_END}`;\n}\n\nfunction paintShimmerText(text: string, nowMs: number): string {\n const characters = [...text];\n if (characters.length === 0) return text;\n const widths = characters.map(characterWidth);\n const totalWidth = visibleWidth(text);\n const period = Math.max(1, totalWidth + SHIMMER_BAND_COLUMNS);\n const head = Math.floor(nowMs / SHIMMER_FRAME_MS) % period;\n const bandStart = head - SHIMMER_BAND_COLUMNS + 1;\n let column = 0;\n let output = ANSI.reset;\n let last: \"bright\" | \"dim\" | undefined;\n for (const [index, character] of characters.entries()) {\n const width = widths[index] ?? 0;\n const inBand =\n width === 0 ? last === \"bright\" : column <= head && column + width - 1 >= bandStart;\n const style = inBand ? \"bright\" : \"dim\";\n if (style !== last) {\n output += style === \"bright\" ? SHIMMER_BRIGHT : SHIMMER_DIM;\n last = style;\n }\n output += character;\n column += width;\n }\n return `${output}${ANSI.reset}`;\n}\n\nfunction replaceLiveTokens(line: string, spinner: string, nowMs: number, color: boolean): string {\n return line\n .replaceAll(SPINNER_TOKEN, spinner)\n .replace(\n new RegExp(`${ELAPSED_TOKEN_START}(\\\\d+)${ELAPSED_TOKEN_END}`, \"g\"),\n (_match, start: string) => formatDurationMs(Math.max(0, nowMs - Number(start)))\n )\n .replace(\n new RegExp(`${SHIMMER_TOKEN_START}(.*?)${SHIMMER_TOKEN_END}`, \"g\"),\n (_match, text: string) => (color ? paintShimmerText(text, nowMs) : text)\n );\n}\n\nexport function paintLiveLines(\n lines: readonly string[],\n spinner: string,\n nowMs: number,\n columns?: number,\n color = false\n): string[] {\n return lines.map((line) => fitLine(replaceLiveTokens(line, spinner, nowMs, color), columns));\n}\n\nexport interface LiveTicker {\n setLines(lines: readonly string[]): void;\n writeLog(text: string): void;\n dispose(): void;\n}\n\nexport interface LiveTickerOptions {\n columns?: number;\n getColumns?(): number | undefined;\n fd?: number;\n refreshIntervalMs: number;\n unicode: boolean;\n color?: boolean;\n write(chunk: string): void;\n workerUrl?: URL;\n supervisorUrl?: URL;\n}\n\ntype TickerWorkerMessage =\n | { columns?: number; lines: string[]; type: \"lines\" }\n | { text: string; type: \"log\" }\n | { columns?: number; lines: string[]; type: \"stop\" };\n\n/** Cursor and frame ownership shared by inline and worker tickers. */\nexport class TickerFrame {\n private cursorHidden: boolean;\n\n constructor(\n private readonly write: (chunk: string) => void,\n public frameLineCount = 0\n ) {\n this.cursorHidden = frameLineCount > 0;\n }\n\n showCursor(): void {\n if (!this.cursorHidden) return;\n this.write(ANSI.showCursor);\n this.cursorHidden = false;\n }\n\n clear(): void {\n if (this.frameLineCount === 0) return;\n this.write(`\\u001B[${this.frameLineCount}F${ANSI.clearDown}`);\n this.frameLineCount = 0;\n }\n\n redraw(lines: readonly string[]): void {\n if (!this.cursorHidden) {\n this.write(ANSI.hideCursor);\n this.cursorHidden = true;\n }\n this.clear();\n if (lines.length === 0) return;\n this.write(`${lines.join(\"\\n\")}\\n`);\n this.frameLineCount = lines.length;\n }\n}\n\nfunction resolveColumns(options: LiveTickerOptions): number | undefined {\n return options.getColumns?.() ?? options.columns;\n}\n\nexport function currentSpinner(unicode: boolean, refreshIntervalMs: number): string {\n const frames = unicode ? SPINNERS.unicode : SPINNERS.ascii;\n return frames[Math.floor(Date.now() / refreshIntervalMs) % frames.length] ?? frames[0]!;\n}\n\nfunction createInlineTicker(options: LiveTickerOptions, adoptedFrameLineCount = 0): LiveTicker {\n let disposed = false;\n let lines: readonly string[] = [];\n const frame = new TickerFrame((chunk) => options.write(chunk), adoptedFrameLineCount);\n const redraw = (): void => {\n if (disposed) return;\n frame.redraw(\n paintLiveLines(\n lines,\n currentSpinner(options.unicode, options.refreshIntervalMs),\n Date.now(),\n resolveColumns(options),\n options.color === true\n )\n );\n };\n\n const timer = setInterval(() => {\n if (\n disposed ||\n !lines.some((line) => line.includes(SPINNER_TOKEN) || line.includes(SHIMMER_TOKEN_START))\n ) {\n return;\n }\n redraw();\n }, options.refreshIntervalMs);\n timer.unref();\n\n return {\n setLines(nextLines) {\n lines = nextLines;\n redraw();\n },\n writeLog(text) {\n if (disposed) {\n options.write(text);\n return;\n }\n frame.clear();\n options.write(text);\n },\n dispose() {\n if (disposed) return;\n disposed = true;\n clearInterval(timer);\n frame.showCursor();\n },\n };\n}\n\nfunction resolveCompiledWorkerUrl(filename: string): URL {\n if (import.meta.url.endsWith(\".ts\")) {\n return new URL(`../../dist/reporter/${filename}`, import.meta.url);\n }\n return new URL(`./${filename}`, import.meta.url);\n}\n\nfunction resolveLiveTickerWorkerUrl(): URL {\n return resolveCompiledWorkerUrl(\"live-ticker-worker.js\");\n}\n\nfunction resolveLiveTickerSupervisorUrl(): URL {\n return resolveCompiledWorkerUrl(\"live-ticker-supervisor.js\");\n}\n\nfunction fileWorkerExecArgv(argv: readonly string[] = process.execArgv): string[] {\n const next: string[] = [];\n for (let i = 0; i < argv.length; i += 1) {\n const arg = argv[i];\n if (arg === \"--input-type\") {\n i += 1;\n continue;\n }\n if (arg.startsWith(\"--input-type=\")) continue;\n next.push(arg);\n }\n return next;\n}\n\nfunction createWorkerTicker(options: LiveTickerOptions & { fd: number }): LiveTicker {\n // [0] stop handshake, [1] painted rows, [2] accepted logs, [3] liveness beat\n const handshakeBuffer = new SharedArrayBuffer(16);\n const handshake = new Int32Array(handshakeBuffer);\n // [0] terminate request, [1] ticker isolate exited\n const controlBuffer = new SharedArrayBuffer(8);\n const control = new Int32Array(controlBuffer);\n const worker = new Worker(options.supervisorUrl ?? resolveLiveTickerSupervisorUrl(), {\n execArgv: fileWorkerExecArgv(),\n workerData: {\n controlBuffer,\n execArgv: fileWorkerExecArgv(),\n tickerData: {\n color: options.color === true,\n columns: resolveColumns(options),\n fd: options.fd,\n handshakeBuffer,\n refreshIntervalMs: options.refreshIntervalMs,\n unicode: options.unicode,\n },\n tickerUrl: (options.workerUrl ?? resolveLiveTickerWorkerUrl()).href,\n },\n });\n let disposed = false;\n let finalFramePainted = false;\n let inlineFallback: LiveTicker | undefined;\n let lines: readonly string[] = [];\n const pendingLogs: string[] = [];\n let ackedLogs = 0;\n\n const paintedFrameLineCount = (): number => Atomics.load(handshake, 1);\n\n const dropAcknowledgedLogs = (): void => {\n const accepted = Atomics.load(handshake, 2);\n if (accepted <= ackedLogs) return;\n pendingLogs.splice(0, accepted - ackedLogs);\n ackedLogs = accepted;\n };\n\n const send = (message: TickerWorkerMessage): void => {\n if (disposed || inlineFallback) return;\n worker.postMessage(message);\n };\n\n let supervisorGone = false;\n\n const requestTerminate = (): void => {\n Atomics.store(control, 0, 1);\n Atomics.notify(control, 0);\n try {\n worker.postMessage({ type: \"terminate\" });\n } catch {\n // Supervisor is already gone; isolate exit is best-effort.\n supervisorGone = true;\n }\n };\n\n // Supervisor stores control[1] on the ticker isolate's exit event.\n // A stale refresh beat is not isolate death: refreshIntervalMs is\n // user-configurable, and stop handlers clear the timer before done().\n const isolateNeverStarted = (): boolean =>\n Atomics.load(control, 1) === 0 &&\n Atomics.load(handshake, 1) === 0 &&\n Atomics.load(handshake, 2) === 0 &&\n Atomics.load(handshake, 3) === 0;\n\n const joinTickerIsolate = (ms: number): void => {\n // Only the supervisor stores control[1]. Once it is gone the join\n // cannot observe isolate exit, so skip rather than park for 1s.\n if (supervisorGone || Atomics.load(control, 1) === 1) return;\n Atomics.wait(control, 1, 0, ms);\n };\n\n const drainOwnershipWindow = (): void => {\n const park = new Int32Array(new SharedArrayBuffer(4));\n Atomics.wait(park, 0, 0, 160);\n };\n\n const stopWorker = (): void => {\n requestTerminate();\n try {\n joinTickerIsolate(1_000);\n // Exit can land in the same millisecond as the last beat. Wait out\n // the 80ms ownership window before the parent takes the fd.\n // supervisorGone is not enough to skip: a mid-flight supervisor\n // crash can leave the isolate still writing. Skip only when the\n // isolate never published a frame, log, beat, or exit.\n if (Atomics.load(handshake, 0) !== 1 && !isolateNeverStarted()) {\n drainOwnershipWindow();\n }\n } finally {\n void worker.terminate();\n }\n };\n\n const replayThrough = (ticker: LiveTicker): void => {\n dropAcknowledgedLogs();\n for (const text of pendingLogs) {\n ticker.writeLog(text);\n }\n pendingLogs.length = 0;\n ticker.setLines([...lines]);\n };\n\n const paintFinalFrame = (): void => {\n if (finalFramePainted) return;\n finalFramePainted = true;\n try {\n const ticker = createInlineTicker(options, paintedFrameLineCount());\n replayThrough(ticker);\n ticker.dispose();\n } catch {\n // Stream may already be closed after dispose.\n }\n };\n\n const failToInline = (): void => {\n if (inlineFallback || finalFramePainted) return;\n if (disposed) {\n if (Atomics.load(handshake, 0) !== 1) paintFinalFrame();\n return;\n }\n inlineFallback = createInlineTicker(options, paintedFrameLineCount());\n replayThrough(inlineFallback);\n };\n const requestedTerminate = (): boolean => Atomics.load(control, 0) === 1;\n\n worker.on(\"error\", () => {\n supervisorGone = true;\n if (!requestedTerminate()) failToInline();\n });\n worker.on(\"exit\", (code) => {\n supervisorGone = true;\n if (code !== 0 && !requestedTerminate()) failToInline();\n });\n worker.unref();\n worker.on(\n \"message\",\n (msg: {\n code?: number;\n event?: string;\n kind?: string;\n terminated?: boolean;\n type?: string;\n }) => {\n if (msg.type === \"supervisor\" && msg.event === \"error\") {\n if (msg.terminated !== true && !requestedTerminate()) failToInline();\n return;\n }\n if (msg.type === \"supervisor\" && msg.event === \"exit\") {\n if (msg.code !== 0 && msg.terminated !== true && !requestedTerminate()) {\n failToInline();\n }\n return;\n }\n if (msg.type === \"ack\" && msg.kind === \"log\") dropAcknowledgedLogs();\n }\n );\n\n return {\n setLines(nextLines) {\n lines = nextLines;\n if (inlineFallback) {\n inlineFallback.setLines(nextLines);\n return;\n }\n send({ columns: resolveColumns(options), lines: [...nextLines], type: \"lines\" });\n },\n writeLog(text) {\n if (inlineFallback) {\n inlineFallback.writeLog(text);\n return;\n }\n if (disposed) {\n writeSync(options.fd, text);\n return;\n }\n dropAcknowledgedLogs();\n pendingLogs.push(text);\n send({ text, type: \"log\" });\n },\n dispose() {\n if (disposed) return;\n disposed = true;\n if (inlineFallback) {\n inlineFallback.dispose();\n stopWorker();\n return;\n }\n Atomics.store(handshake, 0, 0);\n try {\n worker.postMessage({\n columns: resolveColumns(options),\n lines: [...lines],\n type: \"stop\",\n });\n } catch {\n stopWorker();\n paintFinalFrame();\n return;\n }\n if (Atomics.wait(handshake, 0, 0, 500) === \"timed-out\") {\n stopWorker();\n if (Atomics.load(handshake, 0) !== 1) paintFinalFrame();\n try {\n writeSync(options.fd, ANSI.showCursor);\n } catch {\n // Stream may already be closed; cursor restore is best-effort.\n }\n return;\n }\n try {\n writeSync(options.fd, ANSI.showCursor);\n } catch {\n // Stream may already be closed; cursor restore is best-effort.\n }\n stopWorker();\n },\n };\n}\n\nfunction outputFd(fd: number | undefined): fd is number {\n return fd !== undefined && Number.isInteger(fd) && fd >= 0;\n}\n\n/** Inline interval for tests; worker thread when `fd` is a real TTY/pipe. */\nexport function createLiveTicker(options: LiveTickerOptions): LiveTicker {\n if (outputFd(options.fd)) {\n try {\n return createWorkerTicker({ ...options, fd: options.fd });\n } catch {\n // Worker threads are unavailable in some embeddings; fall back.\n }\n }\n return createInlineTicker(options);\n}\n"]}
|
|
@@ -97,6 +97,12 @@ function optionalString(record, key) {
|
|
|
97
97
|
throw new Error(`${key} must be a string`);
|
|
98
98
|
return value;
|
|
99
99
|
}
|
|
100
|
+
function diagnosticMessage(record) {
|
|
101
|
+
const message = optionalString(record, "message");
|
|
102
|
+
if (message === undefined)
|
|
103
|
+
throw new Error("message is required");
|
|
104
|
+
return message;
|
|
105
|
+
}
|
|
100
106
|
function finiteNumber(record, key) {
|
|
101
107
|
const value = record[key];
|
|
102
108
|
if (typeof value !== "number" || !Number.isFinite(value)) {
|
|
@@ -123,7 +129,7 @@ function parseCause(value, depth = 0) {
|
|
|
123
129
|
throw new Error("error.cause must be an object");
|
|
124
130
|
if (depth >= 16)
|
|
125
131
|
throw new Error("error.cause exceeds 16 levels");
|
|
126
|
-
const cause = { message:
|
|
132
|
+
const cause = { message: diagnosticMessage(value) };
|
|
127
133
|
const name = optionalString(value, "name");
|
|
128
134
|
if (name !== undefined)
|
|
129
135
|
cause.name = name;
|
|
@@ -234,7 +240,7 @@ function parseError(value) {
|
|
|
234
240
|
const error = {
|
|
235
241
|
code,
|
|
236
242
|
kind,
|
|
237
|
-
message:
|
|
243
|
+
message: diagnosticMessage(value),
|
|
238
244
|
phase,
|
|
239
245
|
};
|
|
240
246
|
if (value.cause !== undefined)
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"run-store-ndjson.js","sourceRoot":"","sources":["../../src/run-store/run-store-ndjson.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,IAAI,EAAE,MAAM,kBAAkB,CAAC;AACxC,OAAO,KAAK,IAAI,MAAM,WAAW,CAAC;AAqBlC,MAAM,iBAAiB,GAAG,EAAE,GAAG,KAAK,GAAG,KAAK,CAAC;AAC7C,MAAM,uBAAuB,GAAG,CAAC,GAAG,KAAK,GAAG,KAAK,CAAC;AAClD,MAAM,kBAAkB,GAAG,OAAO,CAAC;AACnC,MAAM,mBAAmB,GAAwB,IAAI,GAAG,CAAC,CAAC,WAAW,EAAE,WAAW,EAAE,QAAQ,CAAC,CAAC,CAAC;AAE/F,MAAM,UAAU,GAAwB,IAAI,GAAG,CAAC;IAC9C,oBAAoB;IACpB,cAAc;IACd,kBAAkB;IAClB,6BAA6B;IAC7B,0BAA0B;IAC1B,2BAA2B;IAC3B,gBAAgB;IAChB,gBAAgB;IAChB,aAAa;IACb,cAAc;IACd,cAAc;IACd,cAAc;IACd,eAAe;CAChB,CAAC,CAAC;AACH,MAAM,UAAU,GAAwB,IAAI,GAAG,CAAC;IAC9C,cAAc;IACd,OAAO;IACP,YAAY;IACZ,cAAc;IACd,WAAW;IACX,MAAM;IACN,YAAY;CACb,CAAC,CAAC;AACH,MAAM,WAAW,GAAwB,IAAI,GAAG,CAAC;IAC/C,YAAY;IACZ,WAAW;IACX,cAAc;IACd,UAAU;CACX,CAAC,CAAC;AACH,MAAM,UAAU,GAAwB,IAAI,GAAG,CAAC;IAC9C,uBAAuB;IACvB,8CAA8C;IAC9C,sCAAsC;IACtC,0CAA0C;IAC1C,6CAA6C;IAC7C,+CAA+C;IAC/C,iDAAiD;IACjD,uCAAuC;IACvC,6CAA6C;IAC7C,mCAAmC;IACnC,sCAAsC;IACtC,wCAAwC;IACxC,qCAAqC;IACrC,+CAA+C;IAC/C,yCAAyC;IACzC,uCAAuC;IACvC,iCAAiC;IACjC,8BAA8B;IAC9B,yCAAyC;IACzC,oCAAoC;IACpC,sCAAsC;IACtC,4CAA4C;IAC5C,wCAAwC;IACxC,gCAAgC;IAChC,8CAA8C;IAC9C,0CAA0C;IAC1C,qCAAqC;IACrC,kCAAkC;IAClC,wBAAwB;IACxB,wCAAwC;IACxC,sBAAsB;CACvB,CAAC,CAAC;AAeH,SAAS,QAAQ,CAAC,KAAc;IAC9B,OAAO,KAAK,KAAK,IAAI,IAAI,OAAO,KAAK,KAAK,QAAQ,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC;AAC9E,CAAC;AAED,SAAS,WAAW,CAAC,KAAa;IAChC,OAAO,UAAU,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC;AAC/B,CAAC;AAED,SAAS,WAAW,CAAC,KAAa;IAChC,OAAO,UAAU,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC;AAC/B,CAAC;AAED,SAAS,WAAW,CAAC,KAAa;IAChC,OAAO,UAAU,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC;AAC/B,CAAC;AAED,SAAS,YAAY,CAAC,KAAa;IACjC,OAAO,WAAW,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC;AAChC,CAAC;AAED,SAAS,cAAc,CAAC,MAA+B,EAAE,GAAW;IAClE,MAAM,KAAK,GAAG,MAAM,CAAC,GAAG,CAAC,CAAC;IAC1B,IAAI,OAAO,KAAK,KAAK,QAAQ,IAAI,KAAK,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QACpD,MAAM,IAAI,KAAK,CAAC,GAAG,GAAG,6BAA6B,CAAC,CAAC;IACvD,CAAC;IACD,OAAO,KAAK,CAAC;AACf,CAAC;AAED,SAAS,cAAc,CAAC,MAA+B,EAAE,GAAW;IAClE,MAAM,KAAK,GAAG,MAAM,CAAC,GAAG,CAAC,CAAC;IAC1B,IAAI,KAAK,KAAK,SAAS;QAAE,OAAO,SAAS,CAAC;IAC1C,IAAI,OAAO,KAAK,KAAK,QAAQ;QAAE,MAAM,IAAI,KAAK,CAAC,GAAG,GAAG,mBAAmB,CAAC,CAAC;IAC1E,OAAO,KAAK,CAAC;AACf,CAAC;AAED,SAAS,YAAY,CAAC,MAA+B,EAAE,GAAW;IAChE,MAAM,KAAK,GAAG,MAAM,CAAC,GAAG,CAAC,CAAC;IAC1B,IAAI,OAAO,KAAK,KAAK,QAAQ,IAAI,CAAC,MAAM,CAAC,QAAQ,CAAC,KAAK,CAAC,EAAE,CAAC;QACzD,MAAM,IAAI,KAAK,CAAC,GAAG,GAAG,0BAA0B,CAAC,CAAC;IACpD,CAAC;IACD,OAAO,KAAK,CAAC;AACf,CAAC;AAED,SAAS,eAAe,CAAC,KAAc;IACrC,IAAI,CAAC,QAAQ,CAAC,KAAK,CAAC;QAAE,MAAM,IAAI,KAAK,CAAC,8BAA8B,CAAC,CAAC;IACtE,MAAM,UAAU,GAA8C,EAAE,CAAC;IACjE,KAAK,MAAM,CAAC,GAAG,EAAE,SAAS,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,KAAK,CAAC,EAAE,CAAC;QACrD,IACE,OAAO,SAAS,KAAK,SAAS;YAC9B,OAAO,SAAS,KAAK,QAAQ;YAC7B,CAAC,OAAO,SAAS,KAAK,QAAQ,IAAI,CAAC,MAAM,CAAC,QAAQ,CAAC,SAAS,CAAC,CAAC,EAC9D,CAAC;YACD,MAAM,IAAI,KAAK,CAAC,+DAA+D,CAAC,CAAC;QACnF,CAAC;QACD,UAAU,CAAC,GAAG,CAAC,GAAG,SAAS,CAAC;IAC9B,CAAC;IACD,OAAO,UAAU,CAAC;AACpB,CAAC;AAED,SAAS,UAAU,CAAC,KAAc,EAAE,KAAK,GAAG,CAAC;IAC3C,IAAI,CAAC,QAAQ,CAAC,KAAK,CAAC;QAAE,MAAM,IAAI,KAAK,CAAC,+BAA+B,CAAC,CAAC;IACvE,IAAI,KAAK,IAAI,EAAE;QAAE,MAAM,IAAI,KAAK,CAAC,+BAA+B,CAAC,CAAC;IAClE,MAAM,KAAK,GAAuB,EAAE,OAAO,EAAE,cAAc,CAAC,KAAK,EAAE,SAAS,CAAC,EAAE,CAAC;IAChF,MAAM,IAAI,GAAG,cAAc,CAAC,KAAK,EAAE,MAAM,CAAC,CAAC;IAC3C,IAAI,IAAI,KAAK,SAAS;QAAE,KAAK,CAAC,IAAI,GAAG,IAAI,CAAC;IAC1C,MAAM,UAAU,GAAG,cAAc,CAAC,KAAK,EAAE,YAAY,CAAC,CAAC;IACvD,IAAI,UAAU,KAAK,SAAS;QAAE,KAAK,CAAC,UAAU,GAAG,UAAU,CAAC;IAC5D,IAAI,KAAK,CAAC,KAAK,KAAK,SAAS;QAAE,KAAK,CAAC,KAAK,GAAG,UAAU,CAAC,KAAK,CAAC,KAAK,EAAE,KAAK,GAAG,CAAC,CAAC,CAAC;IAChF,OAAO,KAAK,CAAC;AACf,CAAC;AAED,SAAS,WAAW,CAAC,KAAc;IACjC,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC;QAAE,MAAM,IAAI,KAAK,CAAC,+BAA+B,CAAC,CAAC;IAC5E,OAAO,KAAK,CAAC,GAAG,CAAC,CAAC,KAAK,EAAE,UAAU,EAAE,EAAE;QACrC,IAAI,CAAC,QAAQ,CAAC,KAAK,CAAC;YAAE,MAAM,IAAI,KAAK,CAAC,gBAAgB,UAAU,qBAAqB,CAAC,CAAC;QACvF,MAAM,MAAM,GAA4B,EAAE,OAAO,EAAE,cAAc,CAAC,KAAK,EAAE,SAAS,CAAC,EAAE,CAAC;QACtF,IAAI,KAAK,CAAC,IAAI,KAAK,SAAS,EAAE,CAAC;YAC7B,IACE,CAAC,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC,IAAI,CAAC;gBAC1B,CAAC,KAAK,CAAC,IAAI,CAAC,KAAK,CACf,CAAC,IAAI,EAAE,EAAE,CAAC,OAAO,IAAI,KAAK,QAAQ,IAAI,CAAC,OAAO,IAAI,KAAK,QAAQ,IAAI,MAAM,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC,CAC1F,EACD,CAAC;gBACD,MAAM,IAAI,KAAK,CAAC,gBAAgB,UAAU,+CAA+C,CAAC,CAAC;YAC7F,CAAC;YACD,MAAM,CAAC,IAAI,GAAG,KAAK,CAAC,IAAI,CAAC;QAC3B,CAAC;QACD,OAAO,MAAM,CAAC;IAChB,CAAC,CAAC,CAAC;AACL,CAAC;AAED,SAAS,kBAAkB,CAAC,MAA+B,EAAE,GAAW;IACtE,MAAM,KAAK,GAAG,YAAY,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC;IACxC,IAAI,CAAC,MAAM,CAAC,aAAa,CAAC,KAAK,CAAC,IAAI,KAAK,GAAG,CAAC,EAAE,CAAC;QAC9C,MAAM,IAAI,KAAK,CAAC,gBAAgB,GAAG,qCAAqC,CAAC,CAAC;IAC5E,CAAC;IACD,OAAO,KAAK,CAAC;AACf,CAAC;AAED,SAAS,gBAAgB,CAAC,KAAc,EAAE,KAAK,GAAG,CAAC;IACjD,IAAI,CAAC,QAAQ,CAAC,KAAK,CAAC;QAAE,MAAM,IAAI,KAAK,CAAC,sCAAsC,CAAC,CAAC;IAC9E,iEAAiE;IACjE,IAAI,KAAK,GAAG,CAAC;QAAE,MAAM,IAAI,KAAK,CAAC,4CAA4C,CAAC,CAAC;IAC7E,MAAM,OAAO,GAAG,cAAc,CAAC,KAAK,EAAE,SAAS,CAAC,CAAC;IACjD,IAAI,OAAO,KAAK,SAAS;QAAE,MAAM,IAAI,KAAK,CAAC,qCAAqC,CAAC,CAAC;IAClF,MAAM,KAAK,GAAuB,EAAE,OAAO,EAAE,CAAC;IAC9C,KAAK,MAAM,GAAG,IAAI,CAAC,MAAM,EAAE,YAAY,CAAU,EAAE,CAAC;QAClD,MAAM,IAAI,GAAG,cAAc,CAAC,KAAK,EAAE,GAAG,CAAC,CAAC;QACxC,IAAI,IAAI,KAAK,SAAS;YAAE,KAAK,CAAC,GAAG,CAAC,GAAG,IAAI,CAAC;IAC5C,CAAC;IACD,IACE,CAAC,KAAK,CAAC,OAAO,EAAE,KAAK,CAAC,IAAI,EAAE,KAAK,CAAC,UAAU,CAAC,CAAC,IAAI,CAChD,CAAC,IAAI,EAAE,EAAE,CAAC,IAAI,KAAK,SAAS,IAAI,IAAI,CAAC,MAAM,GAAG,IAAI,CACnD,EACD,CAAC;QACD,MAAM,IAAI,KAAK,CAAC,mDAAmD,CAAC,CAAC;IACvE,CAAC;IACD,IAAI,KAAK,CAAC,KAAK,KAAK,SAAS;QAAE,KAAK,CAAC,KAAK,GAAG,gBAAgB,CAAC,KAAK,CAAC,KAAK,EAAE,KAAK,GAAG,CAAC,CAAC,CAAC;IACtF,OAAO,KAAK,CAAC;AACf,CAAC;AAED,SAAS,WAAW,CAAC,KAAc;IACjC,IAAI,CAAC,QAAQ,CAAC,KAAK,CAAC;QAAE,MAAM,IAAI,KAAK,CAAC,gCAAgC,CAAC,CAAC;IACxE,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC,QAAQ,CAAC,IAAI,KAAK,CAAC,QAAQ,CAAC,MAAM,GAAG,EAAE,EAAE,CAAC;QACjE,MAAM,IAAI,KAAK,CAAC,8DAA8D,CAAC,CAAC;IAClF,CAAC;IACD,MAAM,YAAY,GAAG,kBAAkB,CAAC,KAAK,EAAE,cAAc,CAAC,CAAC;IAC/D,MAAM,mBAAmB,GAAG,kBAAkB,CAAC,KAAK,EAAE,qBAAqB,CAAC,CAAC;IAC7E,IAAI,YAAY,GAAG,KAAK,CAAC,QAAQ,CAAC,MAAM,KAAK,mBAAmB,EAAE,CAAC;QACjE,MAAM,IAAI,KAAK,CAAC,2CAA2C,CAAC,CAAC;IAC/D,CAAC;IACD,IAAI,aAAa,GAAG,CAAC,CAAC,CAAC;IACvB,MAAM,QAAQ,GAAG,KAAK,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAC,OAAO,EAAE,EAAE;QAC9C,IAAI,CAAC,QAAQ,CAAC,OAAO,CAAC;YAAE,MAAM,IAAI,KAAK,CAAC,wCAAwC,CAAC,CAAC;QAClF,MAAM,KAAK,GAAG,kBAAkB,CAAC,OAAO,EAAE,OAAO,CAAC,CAAC;QACnD,IAAI,KAAK,IAAI,aAAa;YAAE,MAAM,IAAI,KAAK,CAAC,6CAA6C,CAAC,CAAC;QAC3F,aAAa,GAAG,KAAK,CAAC;QACtB,MAAM,GAAG,GAAG,cAAc,CAAC,OAAO,EAAE,KAAK,CAAC,CAAC;QAC3C,IAAI,GAAG,KAAK,SAAS,IAAI,GAAG,CAAC,MAAM,GAAG,IAAI,EAAE,CAAC;YAC3C,MAAM,IAAI,KAAK,CAAC,8DAA8D,CAAC,CAAC;QAClF,CAAC;QACD,IAAI,OAAO,OAAO,CAAC,YAAY,KAAK,SAAS,IAAI,OAAO,OAAO,CAAC,SAAS,KAAK,SAAS,EAAE,CAAC;YACxF,MAAM,IAAI,KAAK,CAAC,0DAA0D,CAAC,CAAC;QAC9E,CAAC;QACD,OAAO;YACL,KAAK;YACL,GAAG;YACH,YAAY,EAAE,OAAO,CAAC,YAAY;YAClC,SAAS,EAAE,OAAO,CAAC,SAAS;YAC5B,KAAK,EAAE,gBAAgB,CAAC,OAAO,CAAC,KAAK,CAAC;SACvC,CAAC;IACJ,CAAC,CAAC,CAAC;IACH,MAAM,WAAW,GAA8B,EAAE,QAAQ,EAAE,YAAY,EAAE,mBAAmB,EAAE,CAAC;IAC/F,IAAI,KAAK,CAAC,cAAc,KAAK,SAAS;QACpC,WAAW,CAAC,cAAc,GAAG,gBAAgB,CAAC,KAAK,CAAC,cAAc,CAAC,CAAC;IACtE,OAAO,WAAW,CAAC;AACrB,CAAC;AAED,SAAS,UAAU,CAAC,KAAc;IAChC,IAAI,CAAC,QAAQ,CAAC,KAAK,CAAC;QAAE,MAAM,IAAI,KAAK,CAAC,yBAAyB,CAAC,CAAC;IACjE,MAAM,IAAI,GAAG,cAAc,CAAC,KAAK,EAAE,MAAM,CAAC,CAAC;IAC3C,MAAM,IAAI,GAAG,cAAc,CAAC,KAAK,EAAE,MAAM,CAAC,CAAC;IAC3C,MAAM,KAAK,GAAG,cAAc,CAAC,KAAK,EAAE,OAAO,CAAC,CAAC;IAC7C,IAAI,CAAC,WAAW,CAAC,IAAI,CAAC;QAAE,MAAM,IAAI,KAAK,CAAC,2BAA2B,CAAC,CAAC;IACrE,IAAI,CAAC,WAAW,CAAC,IAAI,CAAC;QAAE,MAAM,IAAI,KAAK,CAAC,2BAA2B,CAAC,CAAC;IACrE,IAAI,CAAC,YAAY,CAAC,KAAK,CAAC;QAAE,MAAM,IAAI,KAAK,CAAC,4BAA4B,CAAC,CAAC;IACxE,MAAM,KAAK,GAAuB;QAChC,IAAI;QACJ,IAAI;QACJ,OAAO,EAAE,cAAc,CAAC,KAAK,EAAE,SAAS,CAAC;QACzC,KAAK;KACN,CAAC;IACF,IAAI,KAAK,CAAC,KAAK,KAAK,SAAS;QAAE,KAAK,CAAC,KAAK,GAAG,UAAU,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC;IACrE,IAAI,KAAK,CAAC,MAAM,KAAK,SAAS;QAAE,KAAK,CAAC,MAAM,GAAG,WAAW,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC;IACzE,IAAI,KAAK,CAAC,MAAM,KAAK,SAAS;QAAE,KAAK,CAAC,MAAM,GAAG,WAAW,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC;IACzE,MAAM,UAAU,GAAG,cAAc,CAAC,KAAK,EAAE,YAAY,CAAC,CAAC;IACvD,IAAI,UAAU,KAAK,SAAS;QAAE,KAAK,CAAC,UAAU,GAAG,UAAU,CAAC;IAC5D,MAAM,KAAK,GAAG,cAAc,CAAC,KAAK,EAAE,OAAO,CAAC,CAAC;IAC7C,IAAI,KAAK,KAAK,SAAS;QAAE,KAAK,CAAC,KAAK,GAAG,KAAK,CAAC;IAC7C,OAAO,KAAK,CAAC;AACf,CAAC;AAED,SAAS,UAAU,CAAC,KAAc;IAChC,IAAI,CAAC,QAAQ,CAAC,KAAK,CAAC;QAAE,MAAM,IAAI,KAAK,CAAC,yBAAyB,CAAC,CAAC;IACjE,IAAI,KAAK,CAAC,OAAO,KAAK,CAAC;QAAE,MAAM,IAAI,KAAK,CAAC,mBAAmB,CAAC,CAAC;IAC9D,MAAM,IAAI,GAAG,cAAc,CAAC,KAAK,EAAE,MAAM,CAAC,CAAC;IAC3C,IAAI,CAAC,WAAW,CAAC,IAAI,CAAC;QAAE,MAAM,IAAI,KAAK,CAAC,qBAAqB,CAAC,CAAC;IAC/D,MAAM,KAAK,GAAuB;QAChC,UAAU,EAAE,eAAe,CAAC,KAAK,CAAC,UAAU,CAAC;QAC7C,IAAI;QACJ,UAAU,EAAE,cAAc,CAAC,KAAK,EAAE,YAAY,CAAC;QAC/C,KAAK,EAAE,cAAc,CAAC,KAAK,EAAE,OAAO,CAAC;QACrC,WAAW,EAAE,YAAY,CAAC,KAAK,EAAE,aAAa,CAAC;QAC/C,OAAO,EAAE,CAAC;KACX,CAAC;IACF,MAAM,SAAS,GAAG,cAAc,CAAC,KAAK,EAAE,WAAW,CAAC,CAAC;IACrD,IAAI,SAAS,KAAK,SAAS;QAAE,KAAK,CAAC,SAAS,GAAG,SAAS,CAAC;IACzD,IAAI,KAAK,CAAC,UAAU,KAAK,SAAS;QAAE,KAAK,CAAC,UAAU,GAAG,YAAY,CAAC,KAAK,EAAE,YAAY,CAAC,CAAC;IACzF,IAAI,KAAK,CAAC,KAAK,KAAK,SAAS;QAAE,KAAK,CAAC,KAAK,GAAG,UAAU,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC;IACrE,MAAM,OAAO,GAAG,cAAc,CAAC,KAAK,EAAE,SAAS,CAAC,CAAC;IACjD,IAAI,OAAO,KAAK,SAAS;QAAE,KAAK,CAAC,OAAO,GAAG,OAAO,CAAC;IACnD,MAAM,WAAW,GAAG,cAAc,CAAC,KAAK,EAAE,aAAa,CAAC,CAAC;IACzD,IAAI,WAAW,KAAK,SAAS;QAAE,KAAK,CAAC,WAAW,GAAG,WAAW,CAAC;IAC/D,MAAM,MAAM,GAAG,cAAc,CAAC,KAAK,EAAE,QAAQ,CAAC,CAAC;IAC/C,IAAI,MAAM,KAAK,SAAS;QAAE,KAAK,CAAC,MAAM,GAAG,MAAM,CAAC;IAChD,IAAI,KAAK,CAAC,IAAI,KAAK,oBAAoB,EAAE,CAAC;QACxC,MAAM,MAAM,GAAG,KAAK,CAAC,UAAU,CAAC,MAAM,CAAC;QACvC,IAAI,OAAO,MAAM,KAAK,QAAQ,IAAI,CAAC,mBAAmB,CAAC,GAAG,CAAC,MAAM,CAAC,EAAE,CAAC;YACnE,MAAM,IAAI,KAAK,CACb,kFAAkF,CACnF,CAAC;QACJ,CAAC;IACH,CAAC;IACD,OAAO,KAAK,CAAC;AACf,CAAC;AAED,SAAS,eAAe,CAAC,KAAyB,EAAE,QAAgB,EAAE,IAAY;IAChF,MAAM,QAAQ,GAAG,KAAK,IAAI,QAAQ,CAAC;IACnC,IAAI,CAAC,MAAM,CAAC,aAAa,CAAC,QAAQ,CAAC,IAAI,QAAQ,IAAI,CAAC,EAAE,CAAC;QACrD,MAAM,IAAI,KAAK,CAAC,GAAG,IAAI,mCAAmC,CAAC,CAAC;IAC9D,CAAC;IACD,OAAO,QAAQ,CAAC;AAClB,CAAC;AAED;;;;GAIG;AACH,MAAM,CAAC,KAAK,UAAU,0BAA0B,CAC9C,QAAgB,EAChB,OAAO,GAAsC,EAAE;IAE/C,MAAM,gBAAgB,GAAG,IAAI,CAAC,OAAO,CAAC,QAAQ,CAAC,CAAC;IAChD,MAAM,QAAQ,GAAG,eAAe,CAAC,OAAO,CAAC,QAAQ,EAAE,iBAAiB,EAAE,UAAU,CAAC,CAAC;IAClF,MAAM,aAAa,GAAG,eAAe,CACnC,OAAO,CAAC,aAAa,EACrB,uBAAuB,EACvB,eAAe,CAChB,CAAC;IACF,MAAM,SAAS,GAAG,eAAe,CAAC,OAAO,CAAC,SAAS,EAAE,kBAAkB,EAAE,WAAW,CAAC,CAAC;IACtF,MAAM,MAAM,GAAG,MAAM,IAAI,CAAC,gBAAgB,EAAE,GAAG,CAAC,CAAC;IACjD,IAAI,QAAgB,CAAC;IACrB,IAAI,CAAC;QACH,MAAM,QAAQ,GAAG,MAAM,MAAM,CAAC,IAAI,EAAE,CAAC;QACrC,IAAI,CAAC,QAAQ,CAAC,MAAM,EAAE;YAAE,MAAM,IAAI,KAAK,CAAC,GAAG,gBAAgB,yBAAyB,CAAC,CAAC;QACtF,IAAI,QAAQ,CAAC,IAAI,GAAG,QAAQ,EAAE,CAAC;YAC7B,MAAM,IAAI,KAAK,CAAC,GAAG,gBAAgB,gBAAgB,QAAQ,2BAA2B,CAAC,CAAC;QAC1F,CAAC;QACD,MAAM,MAAM,GAAa,EAAE,CAAC;QAC5B,IAAI,UAAU,GAAG,CAAC,CAAC;QACnB,IAAI,KAAK,EAAE,MAAM,KAAK,IAAI,MAAM,CAAC,gBAAgB,CAAC,EAAE,SAAS,EAAE,KAAK,EAAE,CAAC,EAAE,CAAC;YACxE,MAAM,MAAM,GAAG,MAAM,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;YACnE,UAAU,IAAI,MAAM,CAAC,UAAU,CAAC;YAChC,IAAI,UAAU,GAAG,QAAQ,EAAE,CAAC;gBAC1B,MAAM,IAAI,KAAK,CAAC,GAAG,gBAAgB,gBAAgB,QAAQ,2BAA2B,CAAC,CAAC;YAC1F,CAAC;YACD,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;QACtB,CAAC;QACD,QAAQ,GAAG,MAAM,CAAC,MAAM,CAAC,MAAM,EAAE,UAAU,CAAC,CAAC;IAC/C,CAAC;YAAS,CAAC;QACT,MAAM,MAAM,CAAC,KAAK,EAAE,CAAC;IACvB,CAAC;IAED,MAAM,OAAO,GAAG,IAAI,WAAW,CAAC,OAAO,EAAE,EAAE,KAAK,EAAE,IAAI,EAAE,CAAC,CAAC;IAC1D,MAAM,MAAM,GAA0B,EAAE,CAAC;IACzC,IAAI,UAAU,GAAG,CAAC,CAAC;IACnB,IAAI,SAAS,GAAG,CAAC,CAAC;IAClB,KAAK,IAAI,MAAM,GAAG,CAAC,EAAE,MAAM,IAAI,QAAQ,CAAC,MAAM,EAAE,MAAM,IAAI,CAAC,EAAE,CAAC;QAC5D,IAAI,MAAM,GAAG,QAAQ,CAAC,MAAM,IAAI,QAAQ,CAAC,MAAM,CAAC,KAAK,IAAI;YAAE,SAAS;QACpE,UAAU,IAAI,CAAC,CAAC;QAChB,IAAI,OAAO,GAAG,MAAM,CAAC;QACrB,IAAI,OAAO,GAAG,SAAS,IAAI,QAAQ,CAAC,OAAO,GAAG,CAAC,CAAC,KAAK,IAAI;YAAE,OAAO,IAAI,CAAC,CAAC;QACxE,MAAM,UAAU,GAAG,OAAO,GAAG,SAAS,CAAC;QACvC,IAAI,UAAU,GAAG,aAAa,EAAE,CAAC;YAC/B,MAAM,IAAI,KAAK,CACb,GAAG,gBAAgB,SAAS,UAAU,gBAAgB,aAAa,oBAAoB,CACxF,CAAC;QACJ,CAAC;QACD,MAAM,IAAI,GAAG,QAAQ,CAAC,QAAQ,CAAC,SAAS,EAAE,OAAO,CAAC,CAAC;QACnD,SAAS,GAAG,MAAM,GAAG,CAAC,CAAC;QACvB,IAAI,IAAI,CAAC,KAAK,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,IAAI,KAAK,IAAI,IAAI,IAAI,KAAK,IAAI,CAAC;YAAE,SAAS;QACnE,IAAI,MAAM,CAAC,MAAM,IAAI,SAAS,EAAE,CAAC;YAC/B,MAAM,IAAI,KAAK,CAAC,GAAG,gBAAgB,gBAAgB,SAAS,4BAA4B,CAAC,CAAC;QAC5F,CAAC;QACD,IAAI,OAAe,CAAC;QACpB,IAAI,CAAC;YACH,OAAO,GAAG,OAAO,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC;QACjC,CAAC;QAAC,MAAM,CAAC;YACP,MAAM,IAAI,KAAK,CAAC,GAAG,gBAAgB,SAAS,UAAU,sBAAsB,CAAC,CAAC;QAChF,CAAC;QACD,IAAI,MAAe,CAAC;QACpB,IAAI,CAAC;YACH,MAAM,GAAG,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC;QAC/B,CAAC;QAAC,MAAM,CAAC;YACP,MAAM,IAAI,KAAK,CAAC,GAAG,gBAAgB,SAAS,UAAU,qBAAqB,CAAC,CAAC;QAC/E,CAAC;QACD,IAAI,CAAC;YACH,MAAM,KAAK,GAAG,UAAU,CAAC,MAAM,CAAC,CAAC;YACjC,MAAM,CAAC,IAAI,CAAC,EAAE,GAAG,KAAK,EAAE,EAAE,EAAE,MAAM,CAAC,MAAM,EAAE,CAAC,CAAC;QAC/C,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,MAAM,MAAM,GAAG,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,kBAAkB,CAAC;YAC3E,MAAM,IAAI,KAAK,CAAC,GAAG,gBAAgB,SAAS,UAAU,gBAAgB,MAAM,GAAG,CAAC,CAAC;QACnF,CAAC;IACH,CAAC;IAED,IAAI,MAAM,GAAG,KAAK,CAAC;IACnB,OAAO;QACL,KAAK;YACH,MAAM,GAAG,IAAI,CAAC;QAChB,CAAC;QACD,KAAK,CAAC,UAAU,CAAC,KAAK,GAA0B,EAAE;YAChD,IAAI,MAAM;gBAAE,MAAM,IAAI,KAAK,CAAC,kDAAkD,CAAC,CAAC;YAChF,MAAM,KAAK,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,IAAI,CAAC,GAAG,CAAC,OAAO,EAAE,IAAI,CAAC,KAAK,CAAC,KAAK,CAAC,KAAK,IAAI,MAAM,CAAC,CAAC,CAAC,CAAC;YAChF,OAAO,MAAM;iBACV,MAAM,CACL,CAAC,KAAK,EAAE,EAAE,CACR,CAAC,KAAK,CAAC,OAAO,KAAK,SAAS,IAAI,KAAK,CAAC,EAAE,GAAG,KAAK,CAAC,OAAO,CAAC;gBACzD,CAAC,KAAK,CAAC,UAAU,KAAK,SAAS,IAAI,KAAK,CAAC,UAAU,KAAK,KAAK,CAAC,UAAU,CAAC;gBACzE,CAAC,KAAK,CAAC,KAAK,KAAK,SAAS,IAAI,KAAK,CAAC,KAAK,KAAK,KAAK,CAAC,KAAK,CAAC,CAC7D;iBACA,KAAK,CAAC,CAAC,EAAE,KAAK,CAAC;iBACf,GAAG,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,eAAe,CAAC,KAAK,CAAC,CAAC,CAAC;QAC5C,CAAC;KACF,CAAC;AACJ,CAAC","sourcesContent":["import { open } from \"node:fs/promises\";\nimport * as path from \"node:path\";\nimport type {\n PipelineErrorCause,\n PipelineErrorCode,\n PipelineErrorKind,\n PipelineErrorPhase,\n PipelineFanOutDiagnostics,\n PipelineValidationIssue,\n} from \"../core/pipeline.js\";\nimport type {\n PipelineRunEventQuery,\n PipelineRunEventReader,\n StoredPipelineEvent,\n} from \"./run-store.js\";\nimport type {\n PipelineTraceAttributes,\n PipelineTraceError,\n PipelineTraceEvent,\n PipelineTraceEventName,\n} from \"../tracing/tracing.js\";\n\nconst DEFAULT_MAX_BYTES = 64 * 1_024 * 1_024;\nconst DEFAULT_MAX_EVENT_BYTES = 1 * 1_024 * 1_024;\nconst DEFAULT_MAX_EVENTS = 100_000;\nconst pipelineRunStatuses: ReadonlySet<string> = new Set([\"cancelled\", \"completed\", \"failed\"]);\n\nconst eventNames: ReadonlySet<string> = new Set([\n \"pipeline.completed\",\n \"pipeline.log\",\n \"pipeline.started\",\n \"pipeline.finalize.completed\",\n \"pipeline.finalize.failed\",\n \"pipeline.finalize.started\",\n \"step.attempted\",\n \"step.cancelled\",\n \"step.failed\",\n \"step.planned\",\n \"step.running\",\n \"step.skipped\",\n \"step.complete\",\n]);\nconst errorKinds: ReadonlySet<string> = new Set([\n \"cancellation\",\n \"child\",\n \"definition\",\n \"finalization\",\n \"selection\",\n \"step\",\n \"validation\",\n]);\nconst errorPhases: ReadonlySet<string> = new Set([\n \"definition\",\n \"execution\",\n \"finalization\",\n \"planning\",\n]);\nconst errorCodes: ReadonlySet<string> = new Set([\n \"TUBELESS_CHILD_FAILED\",\n \"TUBELESS_DEFINITION_DEPENDENCY_CONTRADICTORY\",\n \"TUBELESS_DEFINITION_DEPENDENCY_CYCLE\",\n \"TUBELESS_DEFINITION_DEPENDENCY_DUPLICATE\",\n \"TUBELESS_DEFINITION_DEPENDENCY_NOT_IN_STEPS\",\n \"TUBELESS_DEFINITION_DEPENDENCY_SELF_REFERENCE\",\n \"TUBELESS_DEFINITION_FINALIZER_STEP_NOT_IN_STEPS\",\n \"TUBELESS_DEFINITION_PIPELINE_ID_BLANK\",\n \"TUBELESS_DEFINITION_OPTIONS_SCHEMA_CONFLICT\",\n \"TUBELESS_DEFINITION_STEP_ID_BLANK\",\n \"TUBELESS_DEFINITION_STEP_ID_RESERVED\",\n \"TUBELESS_DEFINITION_STEP_IDS_DUPLICATE\",\n \"TUBELESS_DEFINITION_STEP_NAME_BLANK\",\n \"TUBELESS_DEFINITION_TARGET_FINALIZER_MISMATCH\",\n \"TUBELESS_DEFINITION_TARGET_NOT_IN_STEPS\",\n \"TUBELESS_DEFINITION_TARGETS_DUPLICATE\",\n \"TUBELESS_FINALIZATION_CANCELLED\",\n \"TUBELESS_FINALIZATION_FAILED\",\n \"TUBELESS_FINAL_RESULT_VALIDATION_FAILED\",\n \"TUBELESS_OPTIONS_VALIDATION_FAILED\",\n \"TUBELESS_PLANNING_SELECTION_CONFLICT\",\n \"TUBELESS_PLANNING_STEP_SELECTION_DUPLICATE\",\n \"TUBELESS_PLANNING_STEP_SELECTION_EMPTY\",\n \"TUBELESS_PLANNING_STEP_UNKNOWN\",\n \"TUBELESS_PLANNING_TARGET_SELECTION_DUPLICATE\",\n \"TUBELESS_PLANNING_TARGET_SELECTION_EMPTY\",\n \"TUBELESS_PLANNING_TARGET_UNDECLARED\",\n \"TUBELESS_PLANNING_TARGET_UNKNOWN\",\n \"TUBELESS_RUN_CANCELLED\",\n \"TUBELESS_STEP_OUTPUT_VALIDATION_FAILED\",\n \"TUBELESS_STEP_FAILED\",\n]);\n\n/** Bounds applied while opening an untrusted NDJSON trace artifact. */\nexport interface OpenNdjsonPipelineRunStoreOptions {\n /** Maximum artifact size. Defaults to 64 MiB. */\n readonly maxBytes?: number;\n /** Maximum size of one event line. Defaults to 1 MiB. */\n readonly maxEventBytes?: number;\n /** Maximum non-blank event lines. Defaults to 100,000. */\n readonly maxEvents?: number;\n}\n\n/** A read-only, in-memory view of one validated NDJSON trace artifact. */\nexport interface NdjsonPipelineRunStore extends PipelineRunEventReader {}\n\nfunction isRecord(value: unknown): value is Record<string, unknown> {\n return value !== null && typeof value === \"object\" && !Array.isArray(value);\n}\n\nfunction isEventName(value: string): value is PipelineTraceEventName {\n return eventNames.has(value);\n}\n\nfunction isErrorCode(value: string): value is PipelineErrorCode {\n return errorCodes.has(value);\n}\n\nfunction isErrorKind(value: string): value is PipelineErrorKind {\n return errorKinds.has(value);\n}\n\nfunction isErrorPhase(value: string): value is PipelineErrorPhase {\n return errorPhases.has(value);\n}\n\nfunction requiredString(record: Record<string, unknown>, key: string): string {\n const value = record[key];\n if (typeof value !== \"string\" || value.length === 0) {\n throw new Error(`${key} must be a non-empty string`);\n }\n return value;\n}\n\nfunction optionalString(record: Record<string, unknown>, key: string): string | undefined {\n const value = record[key];\n if (value === undefined) return undefined;\n if (typeof value !== \"string\") throw new Error(`${key} must be a string`);\n return value;\n}\n\nfunction finiteNumber(record: Record<string, unknown>, key: string): number {\n const value = record[key];\n if (typeof value !== \"number\" || !Number.isFinite(value)) {\n throw new Error(`${key} must be a finite number`);\n }\n return value;\n}\n\nfunction parseAttributes(value: unknown): PipelineTraceAttributes {\n if (!isRecord(value)) throw new Error(\"attributes must be an object\");\n const attributes: Record<string, boolean | number | string> = {};\n for (const [key, attribute] of Object.entries(value)) {\n if (\n typeof attribute !== \"boolean\" &&\n typeof attribute !== \"string\" &&\n (typeof attribute !== \"number\" || !Number.isFinite(attribute))\n ) {\n throw new Error(\"attribute values must be booleans, finite numbers, or strings\");\n }\n attributes[key] = attribute;\n }\n return attributes;\n}\n\nfunction parseCause(value: unknown, depth = 0): PipelineErrorCause {\n if (!isRecord(value)) throw new Error(\"error.cause must be an object\");\n if (depth >= 16) throw new Error(\"error.cause exceeds 16 levels\");\n const cause: PipelineErrorCause = { message: requiredString(value, \"message\") };\n const name = optionalString(value, \"name\");\n if (name !== undefined) cause.name = name;\n const sourceCode = optionalString(value, \"sourceCode\");\n if (sourceCode !== undefined) cause.sourceCode = sourceCode;\n if (value.cause !== undefined) cause.cause = parseCause(value.cause, depth + 1);\n return cause;\n}\n\nfunction parseIssues(value: unknown): readonly PipelineValidationIssue[] {\n if (!Array.isArray(value)) throw new Error(\"error.issues must be an array\");\n return value.map((issue, issueIndex) => {\n if (!isRecord(issue)) throw new Error(`error.issues[${issueIndex}] must be an object`);\n const parsed: PipelineValidationIssue = { message: requiredString(issue, \"message\") };\n if (issue.path !== undefined) {\n if (\n !Array.isArray(issue.path) ||\n !issue.path.every(\n (part) => typeof part === \"string\" || (typeof part === \"number\" && Number.isFinite(part))\n )\n ) {\n throw new Error(`error.issues[${issueIndex}].path must contain strings or finite numbers`);\n }\n parsed.path = issue.path;\n }\n return parsed;\n });\n}\n\nfunction nonnegativeInteger(record: Record<string, unknown>, key: string): number {\n const value = finiteNumber(record, key);\n if (!Number.isSafeInteger(value) || value < 0) {\n throw new Error(`error.fanOut.${key} must be a nonnegative safe integer`);\n }\n return value;\n}\n\nfunction parseFanOutCause(value: unknown, depth = 0): PipelineErrorCause {\n if (!isRecord(value)) throw new Error(\"error.fanOut cause must be an object\");\n // Core emits eight cause levels followed by a truncation marker.\n if (depth > 8) throw new Error(\"error.fanOut cause exceeds its depth limit\");\n const message = optionalString(value, \"message\");\n if (message === undefined) throw new Error(\"error.fanOut cause requires message\");\n const cause: PipelineErrorCause = { message };\n for (const key of [\"name\", \"sourceCode\"] as const) {\n const text = optionalString(value, key);\n if (text !== undefined) cause[key] = text;\n }\n if (\n [cause.message, cause.name, cause.sourceCode].some(\n (text) => text !== undefined && text.length > 1024\n )\n ) {\n throw new Error(\"error.fanOut cause strings exceed 1024 code units\");\n }\n if (value.cause !== undefined) cause.cause = parseFanOutCause(value.cause, depth + 1);\n return cause;\n}\n\nfunction parseFanOut(value: unknown): PipelineFanOutDiagnostics {\n if (!isRecord(value)) throw new Error(\"error.fanOut must be an object\");\n if (!Array.isArray(value.failures) || value.failures.length > 32) {\n throw new Error(\"error.fanOut.failures must be an array of at most 32 entries\");\n }\n const failureCount = nonnegativeInteger(value, \"failureCount\");\n const omittedFailureCount = nonnegativeInteger(value, \"omittedFailureCount\");\n if (failureCount - value.failures.length !== omittedFailureCount) {\n throw new Error(\"error.fanOut counts do not match failures\");\n }\n let previousIndex = -1;\n const failures = value.failures.map((failure) => {\n if (!isRecord(failure)) throw new Error(\"error.fanOut failure must be an object\");\n const index = nonnegativeInteger(failure, \"index\");\n if (index <= previousIndex) throw new Error(\"error.fanOut indices must be in input order\");\n previousIndex = index;\n const key = optionalString(failure, \"key\");\n if (key === undefined || key.length > 1024) {\n throw new Error(\"error.fanOut key must be a string of at most 1024 code units\");\n }\n if (typeof failure.keyTruncated !== \"boolean\" || typeof failure.cancelled !== \"boolean\") {\n throw new Error(\"error.fanOut keyTruncated and cancelled must be booleans\");\n }\n return {\n index,\n key,\n keyTruncated: failure.keyTruncated,\n cancelled: failure.cancelled,\n error: parseFanOutCause(failure.error),\n };\n });\n const diagnostics: PipelineFanOutDiagnostics = { failures, failureCount, omittedFailureCount };\n if (value.schedulerError !== undefined)\n diagnostics.schedulerError = parseFanOutCause(value.schedulerError);\n return diagnostics;\n}\n\nfunction parseError(value: unknown): PipelineTraceError {\n if (!isRecord(value)) throw new Error(\"error must be an object\");\n const code = requiredString(value, \"code\");\n const kind = requiredString(value, \"kind\");\n const phase = requiredString(value, \"phase\");\n if (!isErrorCode(code)) throw new Error(\"error.code is unsupported\");\n if (!isErrorKind(kind)) throw new Error(\"error.kind is unsupported\");\n if (!isErrorPhase(phase)) throw new Error(\"error.phase is unsupported\");\n const error: PipelineTraceError = {\n code,\n kind,\n message: requiredString(value, \"message\"),\n phase,\n };\n if (value.cause !== undefined) error.cause = parseCause(value.cause);\n if (value.fanOut !== undefined) error.fanOut = parseFanOut(value.fanOut);\n if (value.issues !== undefined) error.issues = parseIssues(value.issues);\n const sourceCode = optionalString(value, \"sourceCode\");\n if (sourceCode !== undefined) error.sourceCode = sourceCode;\n const stack = optionalString(value, \"stack\");\n if (stack !== undefined) error.stack = stack;\n return error;\n}\n\nfunction parseEvent(value: unknown): PipelineTraceEvent {\n if (!isRecord(value)) throw new Error(\"event must be an object\");\n if (value.version !== 1) throw new Error(\"version must be 1\");\n const name = requiredString(value, \"name\");\n if (!isEventName(name)) throw new Error(\"name is unsupported\");\n const event: PipelineTraceEvent = {\n attributes: parseAttributes(value.attributes),\n name,\n pipelineId: requiredString(value, \"pipelineId\"),\n runId: requiredString(value, \"runId\"),\n timestampMs: finiteNumber(value, \"timestampMs\"),\n version: 1,\n };\n const attemptId = optionalString(value, \"attemptId\");\n if (attemptId !== undefined) event.attemptId = attemptId;\n if (value.durationMs !== undefined) event.durationMs = finiteNumber(value, \"durationMs\");\n if (value.error !== undefined) event.error = parseError(value.error);\n const itemKey = optionalString(value, \"itemKey\");\n if (itemKey !== undefined) event.itemKey = itemKey;\n const parentRunId = optionalString(value, \"parentRunId\");\n if (parentRunId !== undefined) event.parentRunId = parentRunId;\n const stepId = optionalString(value, \"stepId\");\n if (stepId !== undefined) event.stepId = stepId;\n if (event.name === \"pipeline.completed\") {\n const status = event.attributes.status;\n if (typeof status !== \"string\" || !pipelineRunStatuses.has(status)) {\n throw new Error(\n \"attributes.status must be cancelled, completed, or failed for pipeline.completed\"\n );\n }\n }\n return event;\n}\n\nfunction positiveInteger(value: number | undefined, fallback: number, name: string): number {\n const resolved = value ?? fallback;\n if (!Number.isSafeInteger(resolved) || resolved <= 0) {\n throw new Error(`${name} must be a positive safe integer.`);\n }\n return resolved;\n}\n\n/**\n * Open and validate an NDJSON trace without modifying it. Events receive\n * zero-based, store-local ids in file order. The file is fully read and closed\n * during this call, so later filesystem changes cannot alter the returned view.\n */\nexport async function openNdjsonPipelineRunStore(\n filename: string,\n options: OpenNdjsonPipelineRunStoreOptions = {}\n): Promise<NdjsonPipelineRunStore> {\n const resolvedFilename = path.resolve(filename);\n const maxBytes = positiveInteger(options.maxBytes, DEFAULT_MAX_BYTES, \"maxBytes\");\n const maxEventBytes = positiveInteger(\n options.maxEventBytes,\n DEFAULT_MAX_EVENT_BYTES,\n \"maxEventBytes\"\n );\n const maxEvents = positiveInteger(options.maxEvents, DEFAULT_MAX_EVENTS, \"maxEvents\");\n const handle = await open(resolvedFilename, \"r\");\n let contents: Buffer;\n try {\n const fileStat = await handle.stat();\n if (!fileStat.isFile()) throw new Error(`${resolvedFilename} is not a regular file.`);\n if (fileStat.size > maxBytes) {\n throw new Error(`${resolvedFilename} exceeds the ${maxBytes}-byte NDJSON trace limit.`);\n }\n const chunks: Buffer[] = [];\n let byteLength = 0;\n for await (const chunk of handle.createReadStream({ autoClose: false })) {\n const buffer = Buffer.isBuffer(chunk) ? chunk : Buffer.from(chunk);\n byteLength += buffer.byteLength;\n if (byteLength > maxBytes) {\n throw new Error(`${resolvedFilename} exceeds the ${maxBytes}-byte NDJSON trace limit.`);\n }\n chunks.push(buffer);\n }\n contents = Buffer.concat(chunks, byteLength);\n } finally {\n await handle.close();\n }\n\n const decoder = new TextDecoder(\"utf-8\", { fatal: true });\n const events: StoredPipelineEvent[] = [];\n let lineNumber = 0;\n let lineStart = 0;\n for (let cursor = 0; cursor <= contents.length; cursor += 1) {\n if (cursor < contents.length && contents[cursor] !== 0x0a) continue;\n lineNumber += 1;\n let lineEnd = cursor;\n if (lineEnd > lineStart && contents[lineEnd - 1] === 0x0d) lineEnd -= 1;\n const byteLength = lineEnd - lineStart;\n if (byteLength > maxEventBytes) {\n throw new Error(\n `${resolvedFilename} line ${lineNumber} exceeds the ${maxEventBytes}-byte event limit.`\n );\n }\n const line = contents.subarray(lineStart, lineEnd);\n lineStart = cursor + 1;\n if (line.every((byte) => byte === 0x20 || byte === 0x09)) continue;\n if (events.length >= maxEvents) {\n throw new Error(`${resolvedFilename} exceeds the ${maxEvents}-event NDJSON trace limit.`);\n }\n let decoded: string;\n try {\n decoded = decoder.decode(line);\n } catch {\n throw new Error(`${resolvedFilename} line ${lineNumber} is not valid UTF-8.`);\n }\n let parsed: unknown;\n try {\n parsed = JSON.parse(decoded);\n } catch {\n throw new Error(`${resolvedFilename} line ${lineNumber} is not valid JSON.`);\n }\n try {\n const event = parseEvent(parsed);\n events.push({ ...event, id: events.length });\n } catch (error) {\n const detail = error instanceof Error ? error.message : \"event is invalid\";\n throw new Error(`${resolvedFilename} line ${lineNumber} is invalid: ${detail}.`);\n }\n }\n\n let closed = false;\n return {\n close() {\n closed = true;\n },\n async listEvents(query: PipelineRunEventQuery = {}) {\n if (closed) throw new Error(\"Cannot query a closed NDJSON pipeline run store.\");\n const limit = Math.max(1, Math.min(100_000, Math.floor(query.limit ?? 20_000)));\n return events\n .filter(\n (event) =>\n (query.afterId === undefined || event.id > query.afterId) &&\n (query.pipelineId === undefined || event.pipelineId === query.pipelineId) &&\n (query.runId === undefined || event.runId === query.runId)\n )\n .slice(0, limit)\n .map((event) => structuredClone(event));\n },\n };\n}\n"]}
|
|
1
|
+
{"version":3,"file":"run-store-ndjson.js","sourceRoot":"","sources":["../../src/run-store/run-store-ndjson.ts"],"names":[],"mappings":"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","sourcesContent":["import { open } from \"node:fs/promises\";\nimport * as path from \"node:path\";\nimport type {\n PipelineErrorCause,\n PipelineErrorCode,\n PipelineErrorKind,\n PipelineErrorPhase,\n PipelineFanOutDiagnostics,\n PipelineValidationIssue,\n} from \"../core/pipeline.js\";\nimport type {\n PipelineRunEventQuery,\n PipelineRunEventReader,\n StoredPipelineEvent,\n} from \"./run-store.js\";\nimport type {\n PipelineTraceAttributes,\n PipelineTraceError,\n PipelineTraceEvent,\n PipelineTraceEventName,\n} from \"../tracing/tracing.js\";\n\nconst DEFAULT_MAX_BYTES = 64 * 1_024 * 1_024;\nconst DEFAULT_MAX_EVENT_BYTES = 1 * 1_024 * 1_024;\nconst DEFAULT_MAX_EVENTS = 100_000;\nconst pipelineRunStatuses: ReadonlySet<string> = new Set([\"cancelled\", \"completed\", \"failed\"]);\n\nconst eventNames: ReadonlySet<string> = new Set([\n \"pipeline.completed\",\n \"pipeline.log\",\n \"pipeline.started\",\n \"pipeline.finalize.completed\",\n \"pipeline.finalize.failed\",\n \"pipeline.finalize.started\",\n \"step.attempted\",\n \"step.cancelled\",\n \"step.failed\",\n \"step.planned\",\n \"step.running\",\n \"step.skipped\",\n \"step.complete\",\n]);\nconst errorKinds: ReadonlySet<string> = new Set([\n \"cancellation\",\n \"child\",\n \"definition\",\n \"finalization\",\n \"selection\",\n \"step\",\n \"validation\",\n]);\nconst errorPhases: ReadonlySet<string> = new Set([\n \"definition\",\n \"execution\",\n \"finalization\",\n \"planning\",\n]);\nconst errorCodes: ReadonlySet<string> = new Set([\n \"TUBELESS_CHILD_FAILED\",\n \"TUBELESS_DEFINITION_DEPENDENCY_CONTRADICTORY\",\n \"TUBELESS_DEFINITION_DEPENDENCY_CYCLE\",\n \"TUBELESS_DEFINITION_DEPENDENCY_DUPLICATE\",\n \"TUBELESS_DEFINITION_DEPENDENCY_NOT_IN_STEPS\",\n \"TUBELESS_DEFINITION_DEPENDENCY_SELF_REFERENCE\",\n \"TUBELESS_DEFINITION_FINALIZER_STEP_NOT_IN_STEPS\",\n \"TUBELESS_DEFINITION_PIPELINE_ID_BLANK\",\n \"TUBELESS_DEFINITION_OPTIONS_SCHEMA_CONFLICT\",\n \"TUBELESS_DEFINITION_STEP_ID_BLANK\",\n \"TUBELESS_DEFINITION_STEP_ID_RESERVED\",\n \"TUBELESS_DEFINITION_STEP_IDS_DUPLICATE\",\n \"TUBELESS_DEFINITION_STEP_NAME_BLANK\",\n \"TUBELESS_DEFINITION_TARGET_FINALIZER_MISMATCH\",\n \"TUBELESS_DEFINITION_TARGET_NOT_IN_STEPS\",\n \"TUBELESS_DEFINITION_TARGETS_DUPLICATE\",\n \"TUBELESS_FINALIZATION_CANCELLED\",\n \"TUBELESS_FINALIZATION_FAILED\",\n \"TUBELESS_FINAL_RESULT_VALIDATION_FAILED\",\n \"TUBELESS_OPTIONS_VALIDATION_FAILED\",\n \"TUBELESS_PLANNING_SELECTION_CONFLICT\",\n \"TUBELESS_PLANNING_STEP_SELECTION_DUPLICATE\",\n \"TUBELESS_PLANNING_STEP_SELECTION_EMPTY\",\n \"TUBELESS_PLANNING_STEP_UNKNOWN\",\n \"TUBELESS_PLANNING_TARGET_SELECTION_DUPLICATE\",\n \"TUBELESS_PLANNING_TARGET_SELECTION_EMPTY\",\n \"TUBELESS_PLANNING_TARGET_UNDECLARED\",\n \"TUBELESS_PLANNING_TARGET_UNKNOWN\",\n \"TUBELESS_RUN_CANCELLED\",\n \"TUBELESS_STEP_OUTPUT_VALIDATION_FAILED\",\n \"TUBELESS_STEP_FAILED\",\n]);\n\n/** Bounds applied while opening an untrusted NDJSON trace artifact. */\nexport interface OpenNdjsonPipelineRunStoreOptions {\n /** Maximum artifact size. Defaults to 64 MiB. */\n readonly maxBytes?: number;\n /** Maximum size of one event line. Defaults to 1 MiB. */\n readonly maxEventBytes?: number;\n /** Maximum non-blank event lines. Defaults to 100,000. */\n readonly maxEvents?: number;\n}\n\n/** A read-only, in-memory view of one validated NDJSON trace artifact. */\nexport interface NdjsonPipelineRunStore extends PipelineRunEventReader {}\n\nfunction isRecord(value: unknown): value is Record<string, unknown> {\n return value !== null && typeof value === \"object\" && !Array.isArray(value);\n}\n\nfunction isEventName(value: string): value is PipelineTraceEventName {\n return eventNames.has(value);\n}\n\nfunction isErrorCode(value: string): value is PipelineErrorCode {\n return errorCodes.has(value);\n}\n\nfunction isErrorKind(value: string): value is PipelineErrorKind {\n return errorKinds.has(value);\n}\n\nfunction isErrorPhase(value: string): value is PipelineErrorPhase {\n return errorPhases.has(value);\n}\n\nfunction requiredString(record: Record<string, unknown>, key: string): string {\n const value = record[key];\n if (typeof value !== \"string\" || value.length === 0) {\n throw new Error(`${key} must be a non-empty string`);\n }\n return value;\n}\n\nfunction optionalString(record: Record<string, unknown>, key: string): string | undefined {\n const value = record[key];\n if (value === undefined) return undefined;\n if (typeof value !== \"string\") throw new Error(`${key} must be a string`);\n return value;\n}\n\nfunction diagnosticMessage(record: Record<string, unknown>): string {\n const message = optionalString(record, \"message\");\n if (message === undefined) throw new Error(\"message is required\");\n return message;\n}\n\nfunction finiteNumber(record: Record<string, unknown>, key: string): number {\n const value = record[key];\n if (typeof value !== \"number\" || !Number.isFinite(value)) {\n throw new Error(`${key} must be a finite number`);\n }\n return value;\n}\n\nfunction parseAttributes(value: unknown): PipelineTraceAttributes {\n if (!isRecord(value)) throw new Error(\"attributes must be an object\");\n const attributes: Record<string, boolean | number | string> = {};\n for (const [key, attribute] of Object.entries(value)) {\n if (\n typeof attribute !== \"boolean\" &&\n typeof attribute !== \"string\" &&\n (typeof attribute !== \"number\" || !Number.isFinite(attribute))\n ) {\n throw new Error(\"attribute values must be booleans, finite numbers, or strings\");\n }\n attributes[key] = attribute;\n }\n return attributes;\n}\n\nfunction parseCause(value: unknown, depth = 0): PipelineErrorCause {\n if (!isRecord(value)) throw new Error(\"error.cause must be an object\");\n if (depth >= 16) throw new Error(\"error.cause exceeds 16 levels\");\n const cause: PipelineErrorCause = { message: diagnosticMessage(value) };\n const name = optionalString(value, \"name\");\n if (name !== undefined) cause.name = name;\n const sourceCode = optionalString(value, \"sourceCode\");\n if (sourceCode !== undefined) cause.sourceCode = sourceCode;\n if (value.cause !== undefined) cause.cause = parseCause(value.cause, depth + 1);\n return cause;\n}\n\nfunction parseIssues(value: unknown): readonly PipelineValidationIssue[] {\n if (!Array.isArray(value)) throw new Error(\"error.issues must be an array\");\n return value.map((issue, issueIndex) => {\n if (!isRecord(issue)) throw new Error(`error.issues[${issueIndex}] must be an object`);\n const parsed: PipelineValidationIssue = { message: requiredString(issue, \"message\") };\n if (issue.path !== undefined) {\n if (\n !Array.isArray(issue.path) ||\n !issue.path.every(\n (part) => typeof part === \"string\" || (typeof part === \"number\" && Number.isFinite(part))\n )\n ) {\n throw new Error(`error.issues[${issueIndex}].path must contain strings or finite numbers`);\n }\n parsed.path = issue.path;\n }\n return parsed;\n });\n}\n\nfunction nonnegativeInteger(record: Record<string, unknown>, key: string): number {\n const value = finiteNumber(record, key);\n if (!Number.isSafeInteger(value) || value < 0) {\n throw new Error(`error.fanOut.${key} must be a nonnegative safe integer`);\n }\n return value;\n}\n\nfunction parseFanOutCause(value: unknown, depth = 0): PipelineErrorCause {\n if (!isRecord(value)) throw new Error(\"error.fanOut cause must be an object\");\n // Core emits eight cause levels followed by a truncation marker.\n if (depth > 8) throw new Error(\"error.fanOut cause exceeds its depth limit\");\n const message = optionalString(value, \"message\");\n if (message === undefined) throw new Error(\"error.fanOut cause requires message\");\n const cause: PipelineErrorCause = { message };\n for (const key of [\"name\", \"sourceCode\"] as const) {\n const text = optionalString(value, key);\n if (text !== undefined) cause[key] = text;\n }\n if (\n [cause.message, cause.name, cause.sourceCode].some(\n (text) => text !== undefined && text.length > 1024\n )\n ) {\n throw new Error(\"error.fanOut cause strings exceed 1024 code units\");\n }\n if (value.cause !== undefined) cause.cause = parseFanOutCause(value.cause, depth + 1);\n return cause;\n}\n\nfunction parseFanOut(value: unknown): PipelineFanOutDiagnostics {\n if (!isRecord(value)) throw new Error(\"error.fanOut must be an object\");\n if (!Array.isArray(value.failures) || value.failures.length > 32) {\n throw new Error(\"error.fanOut.failures must be an array of at most 32 entries\");\n }\n const failureCount = nonnegativeInteger(value, \"failureCount\");\n const omittedFailureCount = nonnegativeInteger(value, \"omittedFailureCount\");\n if (failureCount - value.failures.length !== omittedFailureCount) {\n throw new Error(\"error.fanOut counts do not match failures\");\n }\n let previousIndex = -1;\n const failures = value.failures.map((failure) => {\n if (!isRecord(failure)) throw new Error(\"error.fanOut failure must be an object\");\n const index = nonnegativeInteger(failure, \"index\");\n if (index <= previousIndex) throw new Error(\"error.fanOut indices must be in input order\");\n previousIndex = index;\n const key = optionalString(failure, \"key\");\n if (key === undefined || key.length > 1024) {\n throw new Error(\"error.fanOut key must be a string of at most 1024 code units\");\n }\n if (typeof failure.keyTruncated !== \"boolean\" || typeof failure.cancelled !== \"boolean\") {\n throw new Error(\"error.fanOut keyTruncated and cancelled must be booleans\");\n }\n return {\n index,\n key,\n keyTruncated: failure.keyTruncated,\n cancelled: failure.cancelled,\n error: parseFanOutCause(failure.error),\n };\n });\n const diagnostics: PipelineFanOutDiagnostics = { failures, failureCount, omittedFailureCount };\n if (value.schedulerError !== undefined)\n diagnostics.schedulerError = parseFanOutCause(value.schedulerError);\n return diagnostics;\n}\n\nfunction parseError(value: unknown): PipelineTraceError {\n if (!isRecord(value)) throw new Error(\"error must be an object\");\n const code = requiredString(value, \"code\");\n const kind = requiredString(value, \"kind\");\n const phase = requiredString(value, \"phase\");\n if (!isErrorCode(code)) throw new Error(\"error.code is unsupported\");\n if (!isErrorKind(kind)) throw new Error(\"error.kind is unsupported\");\n if (!isErrorPhase(phase)) throw new Error(\"error.phase is unsupported\");\n const error: PipelineTraceError = {\n code,\n kind,\n message: diagnosticMessage(value),\n phase,\n };\n if (value.cause !== undefined) error.cause = parseCause(value.cause);\n if (value.fanOut !== undefined) error.fanOut = parseFanOut(value.fanOut);\n if (value.issues !== undefined) error.issues = parseIssues(value.issues);\n const sourceCode = optionalString(value, \"sourceCode\");\n if (sourceCode !== undefined) error.sourceCode = sourceCode;\n const stack = optionalString(value, \"stack\");\n if (stack !== undefined) error.stack = stack;\n return error;\n}\n\nfunction parseEvent(value: unknown): PipelineTraceEvent {\n if (!isRecord(value)) throw new Error(\"event must be an object\");\n if (value.version !== 1) throw new Error(\"version must be 1\");\n const name = requiredString(value, \"name\");\n if (!isEventName(name)) throw new Error(\"name is unsupported\");\n const event: PipelineTraceEvent = {\n attributes: parseAttributes(value.attributes),\n name,\n pipelineId: requiredString(value, \"pipelineId\"),\n runId: requiredString(value, \"runId\"),\n timestampMs: finiteNumber(value, \"timestampMs\"),\n version: 1,\n };\n const attemptId = optionalString(value, \"attemptId\");\n if (attemptId !== undefined) event.attemptId = attemptId;\n if (value.durationMs !== undefined) event.durationMs = finiteNumber(value, \"durationMs\");\n if (value.error !== undefined) event.error = parseError(value.error);\n const itemKey = optionalString(value, \"itemKey\");\n if (itemKey !== undefined) event.itemKey = itemKey;\n const parentRunId = optionalString(value, \"parentRunId\");\n if (parentRunId !== undefined) event.parentRunId = parentRunId;\n const stepId = optionalString(value, \"stepId\");\n if (stepId !== undefined) event.stepId = stepId;\n if (event.name === \"pipeline.completed\") {\n const status = event.attributes.status;\n if (typeof status !== \"string\" || !pipelineRunStatuses.has(status)) {\n throw new Error(\n \"attributes.status must be cancelled, completed, or failed for pipeline.completed\"\n );\n }\n }\n return event;\n}\n\nfunction positiveInteger(value: number | undefined, fallback: number, name: string): number {\n const resolved = value ?? fallback;\n if (!Number.isSafeInteger(resolved) || resolved <= 0) {\n throw new Error(`${name} must be a positive safe integer.`);\n }\n return resolved;\n}\n\n/**\n * Open and validate an NDJSON trace without modifying it. Events receive\n * zero-based, store-local ids in file order. The file is fully read and closed\n * during this call, so later filesystem changes cannot alter the returned view.\n */\nexport async function openNdjsonPipelineRunStore(\n filename: string,\n options: OpenNdjsonPipelineRunStoreOptions = {}\n): Promise<NdjsonPipelineRunStore> {\n const resolvedFilename = path.resolve(filename);\n const maxBytes = positiveInteger(options.maxBytes, DEFAULT_MAX_BYTES, \"maxBytes\");\n const maxEventBytes = positiveInteger(\n options.maxEventBytes,\n DEFAULT_MAX_EVENT_BYTES,\n \"maxEventBytes\"\n );\n const maxEvents = positiveInteger(options.maxEvents, DEFAULT_MAX_EVENTS, \"maxEvents\");\n const handle = await open(resolvedFilename, \"r\");\n let contents: Buffer;\n try {\n const fileStat = await handle.stat();\n if (!fileStat.isFile()) throw new Error(`${resolvedFilename} is not a regular file.`);\n if (fileStat.size > maxBytes) {\n throw new Error(`${resolvedFilename} exceeds the ${maxBytes}-byte NDJSON trace limit.`);\n }\n const chunks: Buffer[] = [];\n let byteLength = 0;\n for await (const chunk of handle.createReadStream({ autoClose: false })) {\n const buffer = Buffer.isBuffer(chunk) ? chunk : Buffer.from(chunk);\n byteLength += buffer.byteLength;\n if (byteLength > maxBytes) {\n throw new Error(`${resolvedFilename} exceeds the ${maxBytes}-byte NDJSON trace limit.`);\n }\n chunks.push(buffer);\n }\n contents = Buffer.concat(chunks, byteLength);\n } finally {\n await handle.close();\n }\n\n const decoder = new TextDecoder(\"utf-8\", { fatal: true });\n const events: StoredPipelineEvent[] = [];\n let lineNumber = 0;\n let lineStart = 0;\n for (let cursor = 0; cursor <= contents.length; cursor += 1) {\n if (cursor < contents.length && contents[cursor] !== 0x0a) continue;\n lineNumber += 1;\n let lineEnd = cursor;\n if (lineEnd > lineStart && contents[lineEnd - 1] === 0x0d) lineEnd -= 1;\n const byteLength = lineEnd - lineStart;\n if (byteLength > maxEventBytes) {\n throw new Error(\n `${resolvedFilename} line ${lineNumber} exceeds the ${maxEventBytes}-byte event limit.`\n );\n }\n const line = contents.subarray(lineStart, lineEnd);\n lineStart = cursor + 1;\n if (line.every((byte) => byte === 0x20 || byte === 0x09)) continue;\n if (events.length >= maxEvents) {\n throw new Error(`${resolvedFilename} exceeds the ${maxEvents}-event NDJSON trace limit.`);\n }\n let decoded: string;\n try {\n decoded = decoder.decode(line);\n } catch {\n throw new Error(`${resolvedFilename} line ${lineNumber} is not valid UTF-8.`);\n }\n let parsed: unknown;\n try {\n parsed = JSON.parse(decoded);\n } catch {\n throw new Error(`${resolvedFilename} line ${lineNumber} is not valid JSON.`);\n }\n try {\n const event = parseEvent(parsed);\n events.push({ ...event, id: events.length });\n } catch (error) {\n const detail = error instanceof Error ? error.message : \"event is invalid\";\n throw new Error(`${resolvedFilename} line ${lineNumber} is invalid: ${detail}.`);\n }\n }\n\n let closed = false;\n return {\n close() {\n closed = true;\n },\n async listEvents(query: PipelineRunEventQuery = {}) {\n if (closed) throw new Error(\"Cannot query a closed NDJSON pipeline run store.\");\n const limit = Math.max(1, Math.min(100_000, Math.floor(query.limit ?? 20_000)));\n return events\n .filter(\n (event) =>\n (query.afterId === undefined || event.id > query.afterId) &&\n (query.pipelineId === undefined || event.pipelineId === query.pipelineId) &&\n (query.runId === undefined || event.runId === query.runId)\n )\n .slice(0, limit)\n .map((event) => structuredClone(event));\n },\n };\n}\n"]}
|
|
@@ -51,6 +51,16 @@ function parseProgressDetails(attributes) {
|
|
|
51
51
|
if (!("id" in item) || !isStringValue(id) || id.length === 0)
|
|
52
52
|
return [];
|
|
53
53
|
const detail = { id: id.slice(0, 4_096) };
|
|
54
|
+
// SAFETY: parsed fields are checked by the same guards as other trace attributes.
|
|
55
|
+
const fields = item;
|
|
56
|
+
const name = fields.name;
|
|
57
|
+
if (isStringValue(name) && name)
|
|
58
|
+
detail.name = name.slice(0, 4_096);
|
|
59
|
+
for (const key of ["depth", "completed", "total"]) {
|
|
60
|
+
const number = fields[key];
|
|
61
|
+
if (isNumberValue(number) && Number.isFinite(number))
|
|
62
|
+
detail[key] = number;
|
|
63
|
+
}
|
|
54
64
|
// SAFETY: JSON.parse leaves object fields untyped; isStringValue keeps strings only.
|
|
55
65
|
const label = ("label" in item ? item.label : undefined);
|
|
56
66
|
if (isStringValue(label) && label) {
|
|
@@ -59,7 +69,8 @@ function parseProgressDetails(attributes) {
|
|
|
59
69
|
// SAFETY: JSON.parse leaves object fields untyped; isStringValue keeps strings only.
|
|
60
70
|
const status = ("status" in item ? item.status : undefined);
|
|
61
71
|
if (isStringValue(status) &&
|
|
62
|
-
(status === "
|
|
72
|
+
(status === "cancelled" ||
|
|
73
|
+
status === "completed" ||
|
|
63
74
|
status === "failed" ||
|
|
64
75
|
status === "pending" ||
|
|
65
76
|
status === "running" ||
|
|
@@ -271,22 +282,6 @@ function createRunProjection(event, retainLogs = true) {
|
|
|
271
282
|
applyRunEvent(projection, event);
|
|
272
283
|
return projection;
|
|
273
284
|
}
|
|
274
|
-
function cloneStep(step) {
|
|
275
|
-
const cloned = { ...step };
|
|
276
|
-
if (step.attempt)
|
|
277
|
-
cloned.attempt = { ...step.attempt, retries: [...step.attempt.retries] };
|
|
278
|
-
if (step.progress) {
|
|
279
|
-
cloned.progress = { ...step.progress };
|
|
280
|
-
if (step.progress.details)
|
|
281
|
-
cloned.progress.details = step.progress.details.map((detail) => ({ ...detail }));
|
|
282
|
-
}
|
|
283
|
-
if (step.nestedPipeline) {
|
|
284
|
-
cloned.nestedPipeline = { ...step.nestedPipeline, stepIds: [...step.nestedPipeline.stepIds] };
|
|
285
|
-
}
|
|
286
|
-
if (step.remote)
|
|
287
|
-
cloned.remote = { ...step.remote };
|
|
288
|
-
return cloned;
|
|
289
|
-
}
|
|
290
285
|
function materializeRun(projection) {
|
|
291
286
|
const { completed, eventCount, first, logs, started, stepOrder, steps } = projection;
|
|
292
287
|
const statusValue = completed && stringAttribute(completed.attributes, "status");
|
|
@@ -302,7 +297,7 @@ function materializeRun(projection) {
|
|
|
302
297
|
runId: first.runId,
|
|
303
298
|
startedAtMs: started.timestampMs,
|
|
304
299
|
status,
|
|
305
|
-
steps: stepOrder.map((stepId) =>
|
|
300
|
+
steps: stepOrder.map((stepId) => structuredClone(steps.get(stepId))),
|
|
306
301
|
version: RUN_MODEL_VERSION,
|
|
307
302
|
};
|
|
308
303
|
if (completed?.durationMs !== undefined)
|
|
@@ -394,20 +389,6 @@ function applyPipelineEvent(projection, event) {
|
|
|
394
389
|
projection.latestSteps.set(event.stepId, definitionStep(event));
|
|
395
390
|
}
|
|
396
391
|
}
|
|
397
|
-
function cloneDefinitionStep(step) {
|
|
398
|
-
const cloned = {
|
|
399
|
-
...step,
|
|
400
|
-
dependencies: [...step.dependencies],
|
|
401
|
-
optionalDependencies: [...step.optionalDependencies],
|
|
402
|
-
skipAfterFailureOf: [...step.skipAfterFailureOf],
|
|
403
|
-
};
|
|
404
|
-
if (step.nestedPipeline) {
|
|
405
|
-
cloned.nestedPipeline = { ...step.nestedPipeline, stepIds: [...step.nestedPipeline.stepIds] };
|
|
406
|
-
}
|
|
407
|
-
if (step.remote)
|
|
408
|
-
cloned.remote = { ...step.remote };
|
|
409
|
-
return cloned;
|
|
410
|
-
}
|
|
411
392
|
/**
|
|
412
393
|
* Incrementally fold accepted store events into the current run-history snapshot.
|
|
413
394
|
* `{ retainLogs: false }` keeps `logCount` without retaining or cloning log bodies.
|
|
@@ -449,7 +430,7 @@ export function createPipelineRunProjector(options = {}) {
|
|
|
449
430
|
lastSeenAtMs: pipeline.lastSeenAtMs,
|
|
450
431
|
pipelineId,
|
|
451
432
|
runCount: pipelineRuns.length,
|
|
452
|
-
steps: [...pipeline.latestSteps.values()].map(
|
|
433
|
+
steps: [...pipeline.latestSteps.values()].map((step) => structuredClone(step)),
|
|
453
434
|
targetIds: [...pipeline.targetIds],
|
|
454
435
|
};
|
|
455
436
|
})
|