@saptools/cf-inspector 0.3.17 → 0.3.19

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.js CHANGED
@@ -118,275 +118,6 @@ import { Command } from "commander";
118
118
  // src/cli/commands/attach.ts
119
119
  import process2 from "process";
120
120
 
121
- // src/pathMapper.ts
122
- init_types();
123
- var REGEX_PREFIX = "regex:";
124
- var REGEX_FLAGS_PATTERN = /^[dgimsuvy]*$/;
125
- var TS_JS_EXT_PATTERN = /\.(?:ts|js|mts|mjs|cts|cjs)$/i;
126
- function parseBreakpointSpec(input) {
127
- const idx = input.lastIndexOf(":");
128
- if (idx <= 0 || idx === input.length - 1) {
129
- throw new CfInspectorError(
130
- "INVALID_BREAKPOINT",
131
- `Breakpoint must be in 'file:line' form, received: "${input}"`
132
- );
133
- }
134
- const file = input.slice(0, idx).trim();
135
- const lineRaw = input.slice(idx + 1).trim();
136
- const line = Number.parseInt(lineRaw, 10);
137
- if (!Number.isInteger(line) || line <= 0 || line.toString() !== lineRaw) {
138
- throw new CfInspectorError(
139
- "INVALID_BREAKPOINT",
140
- `Breakpoint line must be a positive integer, received: "${lineRaw}"`
141
- );
142
- }
143
- if (file.length === 0) {
144
- throw new CfInspectorError(
145
- "INVALID_BREAKPOINT",
146
- `Breakpoint file path is empty in "${input}"`
147
- );
148
- }
149
- return { file, line };
150
- }
151
- function parseRemoteRoot(value) {
152
- const trimmed = value?.trim();
153
- if (trimmed === void 0 || trimmed.length === 0) {
154
- return { kind: "none" };
155
- }
156
- if (trimmed.startsWith(REGEX_PREFIX)) {
157
- return toRegex(trimmed.slice(REGEX_PREFIX.length), "");
158
- }
159
- const slashRegex = parseSlashDelimited(trimmed);
160
- if (slashRegex !== void 0) {
161
- return toRegex(slashRegex.pattern, slashRegex.flags);
162
- }
163
- return { kind: "literal", value: stripTrailingSlash(trimmed) };
164
- }
165
- function toRegex(pattern, flags) {
166
- try {
167
- const regex = new RegExp(pattern, flags);
168
- return { kind: "regex", pattern, flags, regex };
169
- } catch (err) {
170
- const message = err instanceof Error ? err.message : String(err);
171
- throw new CfInspectorError(
172
- "INVALID_REMOTE_ROOT",
173
- `Failed to compile remote-root regex "${pattern}" with flags "${flags}": ${message}`
174
- );
175
- }
176
- }
177
- function parseSlashDelimited(value) {
178
- if (!value.startsWith("/")) {
179
- return void 0;
180
- }
181
- const closing = findLastUnescapedSlash(value);
182
- if (closing <= 0) {
183
- return void 0;
184
- }
185
- const flags = value.slice(closing + 1);
186
- if (flags.length === 0 || !REGEX_FLAGS_PATTERN.test(flags)) {
187
- return void 0;
188
- }
189
- return { pattern: value.slice(1, closing), flags };
190
- }
191
- function findLastUnescapedSlash(value) {
192
- for (let i = value.length - 1; i > 0; i--) {
193
- if (value[i] === "/" && !isEscaped(value, i)) {
194
- return i;
195
- }
196
- }
197
- return -1;
198
- }
199
- function isEscaped(value, idx) {
200
- let backslashes = 0;
201
- for (let i = idx - 1; i >= 0; i--) {
202
- if (value[i] === "\\") {
203
- backslashes++;
204
- } else {
205
- break;
206
- }
207
- }
208
- return backslashes % 2 === 1;
209
- }
210
- function stripTrailingSlash(value) {
211
- if (value.length > 1 && value.endsWith("/")) {
212
- return value.slice(0, -1);
213
- }
214
- return value;
215
- }
216
- function normalizeRegexRootPattern(pattern) {
217
- const withoutStartAnchor = pattern.startsWith("^") ? pattern.slice(1) : pattern;
218
- const withoutEndAnchor = withoutStartAnchor.endsWith("$") && !isEscaped(withoutStartAnchor, withoutStartAnchor.length - 1) ? withoutStartAnchor.slice(0, -1) : withoutStartAnchor;
219
- return stripTrailingSlash(withoutEndAnchor);
220
- }
221
- function buildFileUrlRegex(rootPattern, tail) {
222
- const separator = rootPattern.endsWith("/") ? "" : "/";
223
- return `^file://${rootPattern}${separator}${tail}$`;
224
- }
225
- function escapeRegExp(value) {
226
- return value.replaceAll(/[.*+?^${}()|[\]\\]/g, String.raw`\$&`);
227
- }
228
- function normalizeRelative(file) {
229
- return file.replaceAll(/^[./\\]+/g, "").replaceAll("\\", "/");
230
- }
231
- function dropExtension(file) {
232
- const match = TS_JS_EXT_PATTERN.exec(file);
233
- if (!match) {
234
- return { stem: file, matchedExt: false };
235
- }
236
- return { stem: file.slice(0, match.index), matchedExt: true };
237
- }
238
- var EXT_GROUP = String.raw`\.(?:ts|js|mts|mjs|cts|cjs)`;
239
- var OPTIONAL_EXT_GROUP = String.raw`(?:\.(?:ts|js|mts|mjs|cts|cjs))?`;
240
- function buildBreakpointUrlRegex(input) {
241
- const normalized = normalizeRelative(input.file);
242
- const { stem, matchedExt } = dropExtension(normalized);
243
- const escapedStem = escapeRegExp(stem);
244
- const tail = matchedExt ? `${escapedStem}${EXT_GROUP}` : `${escapedStem}${OPTIONAL_EXT_GROUP}`;
245
- switch (input.remoteRoot.kind) {
246
- case "none": {
247
- return `(?:^|/)${tail}$`;
248
- }
249
- case "literal": {
250
- const escapedRoot = escapeRegExp(input.remoteRoot.value);
251
- return buildFileUrlRegex(escapedRoot, tail);
252
- }
253
- case "regex": {
254
- const rootPattern = normalizeRegexRootPattern(input.remoteRoot.pattern);
255
- return buildFileUrlRegex(rootPattern, tail);
256
- }
257
- }
258
- }
259
-
260
- // src/inspector/breakpoints.ts
261
- init_types();
262
-
263
- // src/inspector/conversions.ts
264
- function asString(value, fallback = "") {
265
- return typeof value === "string" ? value : fallback;
266
- }
267
- function asNumber(value, fallback = 0) {
268
- return typeof value === "number" && Number.isFinite(value) ? value : fallback;
269
- }
270
- function toResolvedLocations(value) {
271
- if (!Array.isArray(value)) {
272
- return [];
273
- }
274
- return value.flatMap((entry) => {
275
- if (typeof entry !== "object" || entry === null) {
276
- return [];
277
- }
278
- const candidate = entry;
279
- const scriptId = asString(candidate.scriptId);
280
- if (scriptId.length === 0) {
281
- return [];
282
- }
283
- const url = typeof candidate.url === "string" ? candidate.url : void 0;
284
- const lineNumber = asNumber(candidate.lineNumber);
285
- const result = url === void 0 ? { scriptId, lineNumber, columnNumber: asNumber(candidate.columnNumber) } : { scriptId, url, lineNumber, columnNumber: asNumber(candidate.columnNumber) };
286
- return [result];
287
- });
288
- }
289
- function toScopeChain(value) {
290
- if (!Array.isArray(value)) {
291
- return [];
292
- }
293
- return value.flatMap((entry) => {
294
- if (typeof entry !== "object" || entry === null) {
295
- return [];
296
- }
297
- const candidate = entry;
298
- const type = asString(candidate.type);
299
- if (type.length === 0) {
300
- return [];
301
- }
302
- const objectId = typeof candidate.object?.objectId === "string" ? candidate.object.objectId : void 0;
303
- const name = typeof candidate.name === "string" ? candidate.name : void 0;
304
- const base = name === void 0 ? { type } : { type, name };
305
- return [objectId === void 0 ? base : { ...base, objectId }];
306
- });
307
- }
308
- function toCallFrames(value) {
309
- if (!Array.isArray(value)) {
310
- return [];
311
- }
312
- return value.flatMap((entry) => {
313
- if (typeof entry !== "object" || entry === null) {
314
- return [];
315
- }
316
- const candidate = entry;
317
- const callFrameId = asString(candidate.callFrameId);
318
- if (callFrameId.length === 0) {
319
- return [];
320
- }
321
- const url = typeof candidate.url === "string" ? candidate.url : void 0;
322
- const base = {
323
- callFrameId,
324
- functionName: asString(candidate.functionName),
325
- lineNumber: asNumber(candidate.location?.lineNumber),
326
- columnNumber: asNumber(candidate.location?.columnNumber),
327
- scopeChain: toScopeChain(candidate.scopeChain)
328
- };
329
- return [url === void 0 ? base : { ...base, url }];
330
- });
331
- }
332
- function toPauseEvent(params, receivedAtMs) {
333
- return {
334
- reason: asString(params.reason),
335
- hitBreakpoints: Array.isArray(params.hitBreakpoints) ? params.hitBreakpoints.filter((id) => typeof id === "string") : [],
336
- callFrames: toCallFrames(params.callFrames),
337
- receivedAtMs
338
- };
339
- }
340
- function topFrameLocation(pause) {
341
- const top = pause.callFrames[0];
342
- if (top === void 0) {
343
- return "(no call frame)";
344
- }
345
- const url = top.url !== void 0 && top.url.length > 0 ? top.url : "(unknown)";
346
- return `${url}:${(top.lineNumber + 1).toString()}:${(top.columnNumber + 1).toString()}`;
347
- }
348
- function pauseDetail(pause) {
349
- return JSON.stringify({
350
- reason: pause.reason,
351
- hitBreakpoints: pause.hitBreakpoints,
352
- topFrame: topFrameLocation(pause)
353
- });
354
- }
355
-
356
- // src/inspector/breakpoints.ts
357
- async function setBreakpoint(session, input) {
358
- const remoteRoot = input.remoteRoot ?? { kind: "none" };
359
- const urlRegex = buildBreakpointUrlRegex({ file: input.file, remoteRoot });
360
- const params = {
361
- lineNumber: input.line - 1,
362
- urlRegex
363
- };
364
- if (input.condition !== void 0 && input.condition.length > 0) {
365
- params["condition"] = input.condition;
366
- }
367
- const result = await session.client.send(
368
- "Debugger.setBreakpointByUrl",
369
- params
370
- );
371
- const breakpointId = asString(result.breakpointId);
372
- if (breakpointId.length === 0) {
373
- throw new CfInspectorError(
374
- "CDP_REQUEST_FAILED",
375
- `setBreakpointByUrl did not return a breakpointId for ${input.file}:${input.line.toString()}`
376
- );
377
- }
378
- return {
379
- breakpointId,
380
- file: input.file,
381
- line: input.line,
382
- urlRegex,
383
- resolvedLocations: toResolvedLocations(result.locations)
384
- };
385
- }
386
- async function removeBreakpoint(session, breakpointId) {
387
- await session.client.send("Debugger.removeBreakpoint", { breakpointId });
388
- }
389
-
390
121
  // src/inspector/discovery.ts
391
122
  init_types();
392
123
  import { request } from "http";
@@ -505,164 +236,93 @@ async function fetchInspectorVersion(host, port, timeoutMs) {
505
236
  return { browser, protocolVersion };
506
237
  }
507
238
 
508
- // src/inspector/pause.ts
509
- init_types();
510
- import { performance } from "perf_hooks";
511
- function pauseMatches(pause, breakpointIds) {
512
- if (breakpointIds === void 0 || breakpointIds.length === 0) {
513
- return true;
514
- }
515
- return pause.hitBreakpoints.some((id) => breakpointIds.includes(id));
516
- }
517
- function remainingUntil(deadlineMs) {
518
- return Math.max(0, deadlineMs - performance.now());
519
- }
520
- function hasResumedSincePause(session, pause) {
521
- const pauseAt = pause.receivedAtMs;
522
- const resumedAt = session.debuggerState.lastResumedAtMs;
523
- return pauseAt !== void 0 && resumedAt !== void 0 && resumedAt >= pauseAt;
524
- }
525
- function throwBreakpointTimeout(timeoutMs) {
526
- throw new CfInspectorError(
527
- "BREAKPOINT_NOT_HIT",
528
- `Timed out waiting for matching Debugger.paused after ${timeoutMs.toString()}ms`
529
- );
530
- }
531
- function throwUnrelatedPauseTimeout(pause, timeoutMs) {
532
- throw new CfInspectorError(
533
- "UNRELATED_PAUSE_TIMEOUT",
534
- `Target stayed paused by another debugger event before this command's breakpoint could hit within ${timeoutMs.toString()}ms`,
535
- pauseDetail(pause)
536
- );
239
+ // src/cli/output.ts
240
+ import process from "process";
241
+ function writeJson(value) {
242
+ process.stdout.write(`${JSON.stringify(value, null, 2)}
243
+ `);
537
244
  }
538
- async function waitForUnmatchedPauseToResume(session, pause, deadlineMs, timeoutMs) {
539
- if (hasResumedSincePause(session, pause)) {
540
- return;
541
- }
542
- const remainingMs = remainingUntil(deadlineMs);
543
- if (remainingMs <= 0) {
544
- throwUnrelatedPauseTimeout(pause, timeoutMs);
245
+ function writeHumanSnapshot(snapshot) {
246
+ const pausedDuration = snapshot.pausedDurationMs === null ? "unknown" : `${snapshot.pausedDurationMs.toFixed(1)}ms`;
247
+ const lines = [];
248
+ lines.push(
249
+ `Snapshot @ ${snapshot.capturedAt}`,
250
+ ` reason: ${snapshot.reason}`,
251
+ ` paused: ${pausedDuration}`
252
+ );
253
+ if (snapshot.topFrame) {
254
+ appendFrameLines(lines, snapshot);
545
255
  }
546
- try {
547
- await session.client.waitFor("Debugger.resumed", { timeoutMs: remainingMs });
548
- session.debuggerState.lastResumedAtMs = performance.now();
549
- } catch (err) {
550
- if (err instanceof CfInspectorError && err.code === "BREAKPOINT_NOT_HIT") {
551
- throwUnrelatedPauseTimeout(pause, timeoutMs);
256
+ if (snapshot.captures.length > 0) {
257
+ lines.push(" captures:");
258
+ for (const capture of snapshot.captures) {
259
+ const detail = capture.error ?? capture.value ?? "undefined";
260
+ lines.push(` ${capture.expression} = ${detail}`);
552
261
  }
553
- throw err;
554
262
  }
263
+ process.stdout.write(`${lines.join("\n")}
264
+ `);
555
265
  }
556
- async function handleUnmatchedPause(session, pause, options, deadlineMs) {
557
- if (options.unmatchedPausePolicy === "fail") {
558
- throw new CfInspectorError(
559
- "UNRELATED_PAUSE",
560
- "Target paused before this command's breakpoint was reached",
561
- pauseDetail(pause)
562
- );
266
+ function appendFrameLines(lines, snapshot) {
267
+ const frame = snapshot.topFrame;
268
+ if (frame === void 0) {
269
+ return;
563
270
  }
564
- if (hasResumedSincePause(session, pause)) {
271
+ const fnName = frame.functionName.length === 0 ? "(anonymous)" : frame.functionName;
272
+ const sourceUrl = frame.url !== void 0 && frame.url.length > 0 ? frame.url : "(unknown)";
273
+ lines.push(
274
+ ` frame: ${fnName} ${sourceUrl}:${frame.line.toString()}:${frame.column.toString()}`
275
+ );
276
+ if (frame.scopes === void 0) {
565
277
  return;
566
278
  }
567
- options.onUnmatchedPause?.(pause);
568
- await waitForUnmatchedPauseToResume(session, pause, deadlineMs, options.timeoutMs);
569
- }
570
- async function waitForPause(session, options) {
571
- const deadlineMs = performance.now() + options.timeoutMs;
572
- const buffer = session.pauseBuffer;
573
- while (buffer.length > 0 || remainingUntil(deadlineMs) > 0) {
574
- while (buffer.length > 0) {
575
- const buffered = buffer.shift();
576
- if (buffered === void 0) {
577
- continue;
578
- }
579
- if (pauseMatches(buffered, options.breakpointIds)) {
580
- return buffered;
581
- }
582
- await handleUnmatchedPause(session, buffered, options, deadlineMs);
583
- }
584
- const pause = await waitForLivePause(session, options, deadlineMs);
585
- if (pauseMatches(pause, options.breakpointIds)) {
586
- return pause;
279
+ for (const scope of frame.scopes) {
280
+ lines.push(` scope ${scope.type} (${scope.variables.length.toString()} vars):`);
281
+ for (const variable of scope.variables) {
282
+ lines.push(` ${variable.name} = ${variable.value}`);
587
283
  }
588
- await handleUnmatchedPause(session, pause, options, deadlineMs);
589
284
  }
590
- throwBreakpointTimeout(options.timeoutMs);
591
285
  }
592
- async function waitForLivePause(session, options, deadlineMs) {
593
- const remainingMs = remainingUntil(deadlineMs);
594
- if (remainingMs <= 0) {
595
- throwBreakpointTimeout(options.timeoutMs);
596
- }
597
- session.pauseWaitGate.active = true;
598
- let receivedAtMs;
599
- let params;
600
- try {
601
- params = await session.client.waitFor("Debugger.paused", {
602
- timeoutMs: remainingMs,
603
- predicate: () => {
604
- receivedAtMs = performance.now();
605
- return true;
606
- }
607
- });
608
- } finally {
609
- session.pauseWaitGate.active = false;
286
+ function writeLogEvent(event, json) {
287
+ if (json) {
288
+ process.stdout.write(`${JSON.stringify(event)}
289
+ `);
290
+ return;
610
291
  }
611
- return toPauseEvent(params, receivedAtMs ?? performance.now());
612
- }
613
-
614
- // src/inspector/runtime.ts
615
- init_types();
616
- async function resume(session) {
617
- await session.client.send("Debugger.resume");
618
- }
619
- async function evaluateOnFrame(session, callFrameId, expression) {
620
- return await session.client.send("Debugger.evaluateOnCallFrame", {
621
- callFrameId,
622
- expression,
623
- returnByValue: false,
624
- generatePreview: true,
625
- silent: true
626
- });
627
- }
628
- async function evaluateGlobal(session, expression) {
629
- return await session.client.send("Runtime.evaluate", {
630
- expression,
631
- returnByValue: false,
632
- generatePreview: true,
633
- silent: true
634
- });
635
- }
636
- function listScripts(session) {
637
- return [...session.scripts.values()];
638
- }
639
- async function validateExpression(session, expression) {
640
- const result = await session.client.send("Runtime.compileScript", {
641
- expression,
642
- sourceURL: "<cf-inspector-validate>",
643
- persistScript: false
644
- });
645
- if (result.exceptionDetails === void 0) {
292
+ if (event.error !== void 0) {
293
+ process.stdout.write(`[${event.ts}] ${event.at} !err ${event.error}
294
+ `);
646
295
  return;
647
296
  }
648
- const description = typeof result.exceptionDetails.exception?.description === "string" ? result.exceptionDetails.exception.description : typeof result.exceptionDetails.text === "string" ? result.exceptionDetails.text : "expression failed to compile";
649
- throw new CfInspectorError("INVALID_EXPRESSION", description);
297
+ process.stdout.write(`[${event.ts}] ${event.at} ${event.value ?? ""}
298
+ `);
650
299
  }
651
- async function getProperties(session, objectId) {
652
- const result = await session.client.send("Runtime.getProperties", {
653
- objectId,
654
- ownProperties: true,
655
- accessorPropertiesOnly: false,
656
- generatePreview: true
657
- });
658
- if (!Array.isArray(result.result)) {
659
- return [];
660
- }
661
- return result.result;
300
+
301
+ // src/cf/tunnel.ts
302
+ import { startDebugger } from "@saptools/cf-debugger";
303
+ async function openCfTunnel(target) {
304
+ const opts = {
305
+ region: target.region,
306
+ org: target.org,
307
+ space: target.space,
308
+ app: target.app,
309
+ ...target.tunnelReadyTimeoutMs === void 0 ? {} : { tunnelReadyTimeoutMs: target.tunnelReadyTimeoutMs },
310
+ ...target.preferredPort === void 0 ? {} : { preferredPort: target.preferredPort },
311
+ ...target.verbose === void 0 ? {} : { verbose: target.verbose },
312
+ ...target.signal === void 0 ? {} : { signal: target.signal }
313
+ };
314
+ const handle = await startDebugger(opts);
315
+ return {
316
+ localPort: handle.session.localPort,
317
+ handle,
318
+ dispose: async () => {
319
+ await handle.dispose();
320
+ }
321
+ };
662
322
  }
663
323
 
664
324
  // src/inspector/session.ts
665
- import { performance as performance2 } from "perf_hooks";
325
+ import { performance } from "perf_hooks";
666
326
 
667
327
  // src/cdp/client.ts
668
328
  init_types();
@@ -888,7 +548,116 @@ var CdpClient = class _CdpClient {
888
548
  };
889
549
 
890
550
  // src/inspector/session.ts
891
- init_types();
551
+ init_types();
552
+
553
+ // src/inspector/conversions.ts
554
+ function asString(value, fallback = "") {
555
+ return typeof value === "string" ? value : fallback;
556
+ }
557
+ function asNumber(value, fallback = 0) {
558
+ return typeof value === "number" && Number.isFinite(value) ? value : fallback;
559
+ }
560
+ function nonEmptyString(value) {
561
+ return typeof value === "string" && value.length > 0 ? value : void 0;
562
+ }
563
+ function toResolvedLocations(value) {
564
+ if (!Array.isArray(value)) {
565
+ return [];
566
+ }
567
+ return value.flatMap((entry) => {
568
+ if (typeof entry !== "object" || entry === null) {
569
+ return [];
570
+ }
571
+ const candidate = entry;
572
+ const scriptId = asString(candidate.scriptId);
573
+ if (scriptId.length === 0) {
574
+ return [];
575
+ }
576
+ const url = typeof candidate.url === "string" ? candidate.url : void 0;
577
+ const lineNumber = asNumber(candidate.lineNumber);
578
+ const result = url === void 0 ? { scriptId, lineNumber, columnNumber: asNumber(candidate.columnNumber) } : { scriptId, url, lineNumber, columnNumber: asNumber(candidate.columnNumber) };
579
+ return [result];
580
+ });
581
+ }
582
+ function toScopeChain(value) {
583
+ if (!Array.isArray(value)) {
584
+ return [];
585
+ }
586
+ return value.flatMap((entry) => {
587
+ if (typeof entry !== "object" || entry === null) {
588
+ return [];
589
+ }
590
+ const candidate = entry;
591
+ const type = asString(candidate.type);
592
+ if (type.length === 0) {
593
+ return [];
594
+ }
595
+ const objectId = typeof candidate.object?.objectId === "string" ? candidate.object.objectId : void 0;
596
+ const name = typeof candidate.name === "string" ? candidate.name : void 0;
597
+ const base = name === void 0 ? { type } : { type, name };
598
+ return [objectId === void 0 ? base : { ...base, objectId }];
599
+ });
600
+ }
601
+ function resolveCallFrameUrl(frame, scripts) {
602
+ const direct = nonEmptyString(frame.url);
603
+ if (direct !== void 0) {
604
+ return direct;
605
+ }
606
+ const scriptId = nonEmptyString(frame.location?.scriptId);
607
+ if (scriptId === void 0) {
608
+ return void 0;
609
+ }
610
+ return nonEmptyString(scripts?.get(scriptId)?.url);
611
+ }
612
+ function toCallFrames(value, scripts) {
613
+ if (!Array.isArray(value)) {
614
+ return [];
615
+ }
616
+ return value.flatMap((entry) => {
617
+ if (typeof entry !== "object" || entry === null) {
618
+ return [];
619
+ }
620
+ const candidate = entry;
621
+ const callFrameId = asString(candidate.callFrameId);
622
+ if (callFrameId.length === 0) {
623
+ return [];
624
+ }
625
+ const url = resolveCallFrameUrl(candidate, scripts);
626
+ const base = {
627
+ callFrameId,
628
+ functionName: asString(candidate.functionName),
629
+ lineNumber: asNumber(candidate.location?.lineNumber),
630
+ columnNumber: asNumber(candidate.location?.columnNumber),
631
+ scopeChain: toScopeChain(candidate.scopeChain)
632
+ };
633
+ return [url === void 0 ? base : { ...base, url }];
634
+ });
635
+ }
636
+ function toPauseEvent(params, receivedAtMs, scripts) {
637
+ return {
638
+ reason: asString(params.reason),
639
+ hitBreakpoints: Array.isArray(params.hitBreakpoints) ? params.hitBreakpoints.filter((id) => typeof id === "string") : [],
640
+ callFrames: toCallFrames(params.callFrames, scripts),
641
+ receivedAtMs
642
+ };
643
+ }
644
+ function topFrameLocation(pause) {
645
+ const top = pause.callFrames[0];
646
+ if (top === void 0) {
647
+ return "(no call frame)";
648
+ }
649
+ const url = top.url !== void 0 && top.url.length > 0 ? top.url : "(unknown)";
650
+ return `${url}:${(top.lineNumber + 1).toString()}:${(top.columnNumber + 1).toString()}`;
651
+ }
652
+ function pauseDetail(pause) {
653
+ return JSON.stringify({
654
+ reason: pause.reason,
655
+ hitBreakpoints: pause.hitBreakpoints,
656
+ topFrame: topFrameLocation(pause)
657
+ });
658
+ }
659
+
660
+ // src/inspector/session.ts
892
661
  var DEFAULT_CONNECT_TIMEOUT_MS = 5e3;
893
662
  var DEFAULT_HOST = "127.0.0.1";
894
663
  var PAUSE_BUFFER_LIMIT = 32;
@@ -922,14 +691,14 @@ async function connectInspector(options) {
922
691
  return;
923
692
  }
924
693
  const params = raw;
925
- const event = toPauseEvent(params, performance2.now());
694
+ const event = toPauseEvent(params, performance.now(), scripts);
926
695
  if (pauseBuffer.length >= PAUSE_BUFFER_LIMIT) {
927
696
  pauseBuffer.shift();
928
697
  }
929
698
  pauseBuffer.push(event);
930
699
  });
931
700
  client.on("Debugger.resumed", () => {
932
- debuggerState.lastResumedAtMs = performance2.now();
701
+ debuggerState.lastResumedAtMs = performance.now();
933
702
  });
934
703
  await client.send("Runtime.enable");
935
704
  await client.send("Debugger.enable");
@@ -950,91 +719,6 @@ async function connectInspector(options) {
950
719
  };
951
720
  }
952
721
 
953
- // src/cli/output.ts
954
- import process from "process";
955
- function writeJson(value) {
956
- process.stdout.write(`${JSON.stringify(value, null, 2)}
957
- `);
958
- }
959
- function writeHumanSnapshot(snapshot) {
960
- const pausedDuration = snapshot.pausedDurationMs === null ? "unknown" : `${snapshot.pausedDurationMs.toFixed(1)}ms`;
961
- const lines = [];
962
- lines.push(
963
- `Snapshot @ ${snapshot.capturedAt}`,
964
- ` reason: ${snapshot.reason}`,
965
- ` paused: ${pausedDuration}`
966
- );
967
- if (snapshot.topFrame) {
968
- appendFrameLines(lines, snapshot);
969
- }
970
- if (snapshot.captures.length > 0) {
971
- lines.push(" captures:");
972
- for (const capture of snapshot.captures) {
973
- const detail = capture.error ?? capture.value ?? "undefined";
974
- lines.push(` ${capture.expression} = ${detail}`);
975
- }
976
- }
977
- process.stdout.write(`${lines.join("\n")}
978
- `);
979
- }
980
- function appendFrameLines(lines, snapshot) {
981
- const frame = snapshot.topFrame;
982
- if (frame === void 0) {
983
- return;
984
- }
985
- const fnName = frame.functionName.length === 0 ? "(anonymous)" : frame.functionName;
986
- const sourceUrl = frame.url !== void 0 && frame.url.length > 0 ? frame.url : "(unknown)";
987
- lines.push(
988
- ` frame: ${fnName} ${sourceUrl}:${frame.line.toString()}:${frame.column.toString()}`
989
- );
990
- if (frame.scopes === void 0) {
991
- return;
992
- }
993
- for (const scope of frame.scopes) {
994
- lines.push(` scope ${scope.type} (${scope.variables.length.toString()} vars):`);
995
- for (const variable of scope.variables) {
996
- lines.push(` ${variable.name} = ${variable.value}`);
997
- }
998
- }
999
- }
1000
- function writeLogEvent(event, json) {
1001
- if (json) {
1002
- process.stdout.write(`${JSON.stringify(event)}
1003
- `);
1004
- return;
1005
- }
1006
- if (event.error !== void 0) {
1007
- process.stdout.write(`[${event.ts}] ${event.at} !err ${event.error}
1008
- `);
1009
- return;
1010
- }
1011
- process.stdout.write(`[${event.ts}] ${event.at} ${event.value ?? ""}
1012
- `);
1013
- }
1014
-
1015
- // src/cf/tunnel.ts
1016
- import { startDebugger } from "@saptools/cf-debugger";
1017
- async function openCfTunnel(target) {
1018
- const opts = {
1019
- region: target.region,
1020
- org: target.org,
1021
- space: target.space,
1022
- app: target.app,
1023
- ...target.tunnelReadyTimeoutMs === void 0 ? {} : { tunnelReadyTimeoutMs: target.tunnelReadyTimeoutMs },
1024
- ...target.preferredPort === void 0 ? {} : { preferredPort: target.preferredPort },
1025
- ...target.verbose === void 0 ? {} : { verbose: target.verbose },
1026
- ...target.signal === void 0 ? {} : { signal: target.signal }
1027
- };
1028
- const handle = await startDebugger(opts);
1029
- return {
1030
- localPort: handle.session.localPort,
1031
- handle,
1032
- dispose: async () => {
1033
- await handle.dispose();
1034
- }
1035
- };
1036
- }
1037
-
1038
722
  // src/cli/target.ts
1039
723
  init_types();
1040
724
 
@@ -1134,67 +818,293 @@ async function handleAttach(opts) {
1134
818
  await tunnel.dispose();
1135
819
  }
1136
820
  }
1137
-
1138
- // src/cli/commands/eval.ts
1139
- import process3 from "process";
1140
- async function handleEval(opts) {
1141
- const target = resolveTarget(opts);
1142
- const result = await withSession(target, async (session) => {
1143
- return await evaluateGlobal(session, opts.expr);
1144
- });
1145
- if (opts.json) {
1146
- writeJson(result);
1147
- if (result.exceptionDetails !== void 0) {
1148
- process3.exitCode = 1;
821
+
822
+ // src/cli/commands/eval.ts
823
+ import process3 from "process";
824
+
825
+ // src/inspector/runtime.ts
826
+ init_types();
827
+ async function resume(session) {
828
+ await session.client.send("Debugger.resume");
829
+ }
830
+ async function evaluateOnFrame(session, callFrameId, expression) {
831
+ return await session.client.send("Debugger.evaluateOnCallFrame", {
832
+ callFrameId,
833
+ expression,
834
+ returnByValue: false,
835
+ generatePreview: true,
836
+ silent: true
837
+ });
838
+ }
839
+ async function evaluateGlobal(session, expression) {
840
+ return await session.client.send("Runtime.evaluate", {
841
+ expression,
842
+ returnByValue: false,
843
+ generatePreview: true,
844
+ silent: true
845
+ });
846
+ }
847
+ function listScripts(session) {
848
+ return [...session.scripts.values()];
849
+ }
850
+ async function validateExpression(session, expression) {
851
+ const result = await session.client.send("Runtime.compileScript", {
852
+ expression,
853
+ sourceURL: "<cf-inspector-validate>",
854
+ persistScript: false
855
+ });
856
+ if (result.exceptionDetails === void 0) {
857
+ return;
858
+ }
859
+ const description = typeof result.exceptionDetails.exception?.description === "string" ? result.exceptionDetails.exception.description : typeof result.exceptionDetails.text === "string" ? result.exceptionDetails.text : "expression failed to compile";
860
+ throw new CfInspectorError("INVALID_EXPRESSION", description);
861
+ }
862
+ async function getProperties(session, objectId) {
863
+ const result = await session.client.send("Runtime.getProperties", {
864
+ objectId,
865
+ ownProperties: true,
866
+ accessorPropertiesOnly: false,
867
+ generatePreview: true
868
+ });
869
+ if (!Array.isArray(result.result)) {
870
+ return [];
871
+ }
872
+ return result.result;
873
+ }
874
+
875
+ // src/cli/commands/eval.ts
876
+ async function handleEval(opts) {
877
+ const target = resolveTarget(opts);
878
+ const result = await withSession(target, async (session) => {
879
+ return await evaluateGlobal(session, opts.expr);
880
+ });
881
+ if (opts.json) {
882
+ writeJson(result);
883
+ if (result.exceptionDetails !== void 0) {
884
+ process3.exitCode = 1;
885
+ }
886
+ return;
887
+ }
888
+ writeHumanEvalResult(result);
889
+ }
890
+ function writeHumanEvalResult(result) {
891
+ if (result.exceptionDetails !== void 0) {
892
+ const detail = typeof result.exceptionDetails.exception?.description === "string" ? result.exceptionDetails.exception.description : typeof result.exceptionDetails.text === "string" ? result.exceptionDetails.text : "evaluation failed";
893
+ process3.stderr.write(`${detail}
894
+ `);
895
+ process3.exitCode = 1;
896
+ return;
897
+ }
898
+ const inner = result.result;
899
+ if (inner === void 0) {
900
+ process3.stdout.write("\n");
901
+ return;
902
+ }
903
+ if (typeof inner.value === "string") {
904
+ process3.stdout.write(`${inner.value}
905
+ `);
906
+ return;
907
+ }
908
+ if (typeof inner.description === "string") {
909
+ process3.stdout.write(`${inner.description}
910
+ `);
911
+ return;
912
+ }
913
+ process3.stdout.write(`${JSON.stringify(inner.value)}
914
+ `);
915
+ }
916
+
917
+ // src/cli/commands/listScripts.ts
918
+ import process4 from "process";
919
+ async function handleListScripts(opts) {
920
+ const target = resolveTarget(opts);
921
+ const scripts = await withSession(target, (session) => Promise.resolve(listScripts(session)));
922
+ if (opts.json) {
923
+ writeJson(scripts);
924
+ return;
925
+ }
926
+ for (const script of scripts) {
927
+ process4.stdout.write(`${script.scriptId} ${script.url}
928
+ `);
929
+ }
930
+ }
931
+
932
+ // src/cli/commands/log.ts
933
+ import process6 from "process";
934
+
935
+ // src/pathMapper.ts
936
+ init_types();
937
+ var REGEX_PREFIX = "regex:";
938
+ var REGEX_FLAGS_PATTERN = /^[dgimsuvy]*$/;
939
+ var TS_JS_EXT_PATTERN = /\.(?:ts|js|mts|mjs|cts|cjs)$/i;
940
+ function parseBreakpointSpec(input) {
941
+ const idx = input.lastIndexOf(":");
942
+ if (idx <= 0 || idx === input.length - 1) {
943
+ throw new CfInspectorError(
944
+ "INVALID_BREAKPOINT",
945
+ `Breakpoint must be in 'file:line' form, received: "${input}"`
946
+ );
947
+ }
948
+ const file = input.slice(0, idx).trim();
949
+ const lineRaw = input.slice(idx + 1).trim();
950
+ const line = Number.parseInt(lineRaw, 10);
951
+ if (!Number.isInteger(line) || line <= 0 || line.toString() !== lineRaw) {
952
+ throw new CfInspectorError(
953
+ "INVALID_BREAKPOINT",
954
+ `Breakpoint line must be a positive integer, received: "${lineRaw}"`
955
+ );
956
+ }
957
+ if (file.length === 0) {
958
+ throw new CfInspectorError(
959
+ "INVALID_BREAKPOINT",
960
+ `Breakpoint file path is empty in "${input}"`
961
+ );
962
+ }
963
+ return { file, line };
964
+ }
965
+ function parseRemoteRoot(value) {
966
+ const trimmed = value?.trim();
967
+ if (trimmed === void 0 || trimmed.length === 0) {
968
+ return { kind: "none" };
969
+ }
970
+ if (trimmed.startsWith(REGEX_PREFIX)) {
971
+ return toRegex(trimmed.slice(REGEX_PREFIX.length), "");
972
+ }
973
+ const slashRegex = parseSlashDelimited(trimmed);
974
+ if (slashRegex !== void 0) {
975
+ return toRegex(slashRegex.pattern, slashRegex.flags);
976
+ }
977
+ return { kind: "literal", value: stripTrailingSlash(trimmed) };
978
+ }
979
+ function toRegex(pattern, flags) {
980
+ try {
981
+ const regex = new RegExp(pattern, flags);
982
+ return { kind: "regex", pattern, flags, regex };
983
+ } catch (err) {
984
+ const message = err instanceof Error ? err.message : String(err);
985
+ throw new CfInspectorError(
986
+ "INVALID_REMOTE_ROOT",
987
+ `Failed to compile remote-root regex "${pattern}" with flags "${flags}": ${message}`
988
+ );
989
+ }
990
+ }
991
+ function parseSlashDelimited(value) {
992
+ if (!value.startsWith("/")) {
993
+ return void 0;
994
+ }
995
+ const closing = findLastUnescapedSlash(value);
996
+ if (closing <= 0) {
997
+ return void 0;
998
+ }
999
+ const flags = value.slice(closing + 1);
1000
+ if (flags.length === 0 || !REGEX_FLAGS_PATTERN.test(flags)) {
1001
+ return void 0;
1002
+ }
1003
+ return { pattern: value.slice(1, closing), flags };
1004
+ }
1005
+ function findLastUnescapedSlash(value) {
1006
+ for (let i = value.length - 1; i > 0; i--) {
1007
+ if (value[i] === "/" && !isEscaped(value, i)) {
1008
+ return i;
1149
1009
  }
1150
- return;
1151
1010
  }
1152
- writeHumanEvalResult(result);
1011
+ return -1;
1153
1012
  }
1154
- function writeHumanEvalResult(result) {
1155
- if (result.exceptionDetails !== void 0) {
1156
- const detail = typeof result.exceptionDetails.exception?.description === "string" ? result.exceptionDetails.exception.description : typeof result.exceptionDetails.text === "string" ? result.exceptionDetails.text : "evaluation failed";
1157
- process3.stderr.write(`${detail}
1158
- `);
1159
- process3.exitCode = 1;
1160
- return;
1013
+ function isEscaped(value, idx) {
1014
+ let backslashes = 0;
1015
+ for (let i = idx - 1; i >= 0; i--) {
1016
+ if (value[i] === "\\") {
1017
+ backslashes++;
1018
+ } else {
1019
+ break;
1020
+ }
1161
1021
  }
1162
- const inner = result.result;
1163
- if (inner === void 0) {
1164
- process3.stdout.write("\n");
1165
- return;
1022
+ return backslashes % 2 === 1;
1023
+ }
1024
+ function stripTrailingSlash(value) {
1025
+ if (value.length > 1 && value.endsWith("/")) {
1026
+ return value.slice(0, -1);
1166
1027
  }
1167
- if (typeof inner.value === "string") {
1168
- process3.stdout.write(`${inner.value}
1169
- `);
1170
- return;
1028
+ return value;
1029
+ }
1030
+ function normalizeRegexRootPattern(pattern) {
1031
+ const withoutStartAnchor = pattern.startsWith("^") ? pattern.slice(1) : pattern;
1032
+ const withoutEndAnchor = withoutStartAnchor.endsWith("$") && !isEscaped(withoutStartAnchor, withoutStartAnchor.length - 1) ? withoutStartAnchor.slice(0, -1) : withoutStartAnchor;
1033
+ return stripTrailingSlash(withoutEndAnchor);
1034
+ }
1035
+ function buildFileUrlRegex(rootPattern, tail) {
1036
+ const separator = rootPattern.endsWith("/") ? "" : "/";
1037
+ return `^file://${rootPattern}${separator}${tail}$`;
1038
+ }
1039
+ function escapeRegExp(value) {
1040
+ return value.replaceAll(/[.*+?^${}()|[\]\\]/g, String.raw`\$&`);
1041
+ }
1042
+ function normalizeRelative(file) {
1043
+ return file.replaceAll(/^[./\\]+/g, "").replaceAll("\\", "/");
1044
+ }
1045
+ function dropExtension(file) {
1046
+ const match = TS_JS_EXT_PATTERN.exec(file);
1047
+ if (!match) {
1048
+ return { stem: file, matchedExt: false };
1171
1049
  }
1172
- if (typeof inner.description === "string") {
1173
- process3.stdout.write(`${inner.description}
1174
- `);
1175
- return;
1050
+ return { stem: file.slice(0, match.index), matchedExt: true };
1051
+ }
1052
+ var EXT_GROUP = String.raw`\.(?:ts|js|mts|mjs|cts|cjs)`;
1053
+ var OPTIONAL_EXT_GROUP = String.raw`(?:\.(?:ts|js|mts|mjs|cts|cjs))?`;
1054
+ function buildBreakpointUrlRegex(input) {
1055
+ const normalized = normalizeRelative(input.file);
1056
+ const { stem, matchedExt } = dropExtension(normalized);
1057
+ const escapedStem = escapeRegExp(stem);
1058
+ const tail = matchedExt ? `${escapedStem}${EXT_GROUP}` : `${escapedStem}${OPTIONAL_EXT_GROUP}`;
1059
+ switch (input.remoteRoot.kind) {
1060
+ case "none": {
1061
+ return `(?:^|/)${tail}$`;
1062
+ }
1063
+ case "literal": {
1064
+ const escapedRoot = escapeRegExp(input.remoteRoot.value);
1065
+ return buildFileUrlRegex(escapedRoot, tail);
1066
+ }
1067
+ case "regex": {
1068
+ const rootPattern = normalizeRegexRootPattern(input.remoteRoot.pattern);
1069
+ return buildFileUrlRegex(rootPattern, tail);
1070
+ }
1176
1071
  }
1177
- process3.stdout.write(`${JSON.stringify(inner.value)}
1178
- `);
1179
1072
  }
1180
1073
 
1181
- // src/cli/commands/listScripts.ts
1182
- import process4 from "process";
1183
- async function handleListScripts(opts) {
1184
- const target = resolveTarget(opts);
1185
- const scripts = await withSession(target, (session) => Promise.resolve(listScripts(session)));
1186
- if (opts.json) {
1187
- writeJson(scripts);
1188
- return;
1074
+ // src/inspector/breakpoints.ts
1075
+ init_types();
1076
+ async function setBreakpoint(session, input) {
1077
+ const remoteRoot = input.remoteRoot ?? { kind: "none" };
1078
+ const urlRegex = buildBreakpointUrlRegex({ file: input.file, remoteRoot });
1079
+ const params = {
1080
+ lineNumber: input.line - 1,
1081
+ urlRegex
1082
+ };
1083
+ if (input.condition !== void 0 && input.condition.length > 0) {
1084
+ params["condition"] = input.condition;
1189
1085
  }
1190
- for (const script of scripts) {
1191
- process4.stdout.write(`${script.scriptId} ${script.url}
1192
- `);
1086
+ const result = await session.client.send(
1087
+ "Debugger.setBreakpointByUrl",
1088
+ params
1089
+ );
1090
+ const breakpointId = asString(result.breakpointId);
1091
+ if (breakpointId.length === 0) {
1092
+ throw new CfInspectorError(
1093
+ "CDP_REQUEST_FAILED",
1094
+ `setBreakpointByUrl did not return a breakpointId for ${input.file}:${input.line.toString()}`
1095
+ );
1193
1096
  }
1097
+ return {
1098
+ breakpointId,
1099
+ file: input.file,
1100
+ line: input.line,
1101
+ urlRegex,
1102
+ resolvedLocations: toResolvedLocations(result.locations)
1103
+ };
1104
+ }
1105
+ async function removeBreakpoint(session, breakpointId) {
1106
+ await session.client.send("Debugger.removeBreakpoint", { breakpointId });
1194
1107
  }
1195
-
1196
- // src/cli/commands/log.ts
1197
- import process6 from "process";
1198
1108
 
1199
1109
  // src/logpoint/condition.ts
1200
1110
  import { randomBytes } from "crypto";
@@ -1447,6 +1357,112 @@ function writeLogSummary(stoppedReason, emitted, json) {
1447
1357
  import { performance as performance3 } from "perf_hooks";
1448
1358
  import process7 from "process";
1449
1359
 
1360
+ // src/inspector/pause.ts
1361
+ init_types();
1362
+ import { performance as performance2 } from "perf_hooks";
1363
+ function pauseMatches(pause, breakpointIds) {
1364
+ if (breakpointIds === void 0 || breakpointIds.length === 0) {
1365
+ return true;
1366
+ }
1367
+ return pause.hitBreakpoints.some((id) => breakpointIds.includes(id));
1368
+ }
1369
+ function remainingUntil(deadlineMs) {
1370
+ return Math.max(0, deadlineMs - performance2.now());
1371
+ }
1372
+ function hasResumedSincePause(session, pause) {
1373
+ const pauseAt = pause.receivedAtMs;
1374
+ const resumedAt = session.debuggerState.lastResumedAtMs;
1375
+ return pauseAt !== void 0 && resumedAt !== void 0 && resumedAt >= pauseAt;
1376
+ }
1377
+ function throwBreakpointTimeout(timeoutMs) {
1378
+ throw new CfInspectorError(
1379
+ "BREAKPOINT_NOT_HIT",
1380
+ `Timed out waiting for matching Debugger.paused after ${timeoutMs.toString()}ms`
1381
+ );
1382
+ }
1383
+ function throwUnrelatedPauseTimeout(pause, timeoutMs) {
1384
+ throw new CfInspectorError(
1385
+ "UNRELATED_PAUSE_TIMEOUT",
1386
+ `Target stayed paused by another debugger event before this command's breakpoint could hit within ${timeoutMs.toString()}ms`,
1387
+ pauseDetail(pause)
1388
+ );
1389
+ }
1390
+ async function waitForUnmatchedPauseToResume(session, pause, deadlineMs, timeoutMs) {
1391
+ if (hasResumedSincePause(session, pause)) {
1392
+ return;
1393
+ }
1394
+ const remainingMs = remainingUntil(deadlineMs);
1395
+ if (remainingMs <= 0) {
1396
+ throwUnrelatedPauseTimeout(pause, timeoutMs);
1397
+ }
1398
+ try {
1399
+ await session.client.waitFor("Debugger.resumed", { timeoutMs: remainingMs });
1400
+ session.debuggerState.lastResumedAtMs = performance2.now();
1401
+ } catch (err) {
1402
+ if (err instanceof CfInspectorError && err.code === "BREAKPOINT_NOT_HIT") {
1403
+ throwUnrelatedPauseTimeout(pause, timeoutMs);
1404
+ }
1405
+ throw err;
1406
+ }
1407
+ }
1408
+ async function handleUnmatchedPause(session, pause, options, deadlineMs) {
1409
+ if (options.unmatchedPausePolicy === "fail") {
1410
+ throw new CfInspectorError(
1411
+ "UNRELATED_PAUSE",
1412
+ "Target paused before this command's breakpoint was reached",
1413
+ pauseDetail(pause)
1414
+ );
1415
+ }
1416
+ if (hasResumedSincePause(session, pause)) {
1417
+ return;
1418
+ }
1419
+ options.onUnmatchedPause?.(pause);
1420
+ await waitForUnmatchedPauseToResume(session, pause, deadlineMs, options.timeoutMs);
1421
+ }
1422
+ async function waitForPause(session, options) {
1423
+ const deadlineMs = performance2.now() + options.timeoutMs;
1424
+ const buffer = session.pauseBuffer;
1425
+ while (buffer.length > 0 || remainingUntil(deadlineMs) > 0) {
1426
+ while (buffer.length > 0) {
1427
+ const buffered = buffer.shift();
1428
+ if (buffered === void 0) {
1429
+ continue;
1430
+ }
1431
+ if (pauseMatches(buffered, options.breakpointIds)) {
1432
+ return buffered;
1433
+ }
1434
+ await handleUnmatchedPause(session, buffered, options, deadlineMs);
1435
+ }
1436
+ const pause = await waitForLivePause(session, options, deadlineMs);
1437
+ if (pauseMatches(pause, options.breakpointIds)) {
1438
+ return pause;
1439
+ }
1440
+ await handleUnmatchedPause(session, pause, options, deadlineMs);
1441
+ }
1442
+ throwBreakpointTimeout(options.timeoutMs);
1443
+ }
1444
+ async function waitForLivePause(session, options, deadlineMs) {
1445
+ const remainingMs = remainingUntil(deadlineMs);
1446
+ if (remainingMs <= 0) {
1447
+ throwBreakpointTimeout(options.timeoutMs);
1448
+ }
1449
+ session.pauseWaitGate.active = true;
1450
+ let receivedAtMs;
1451
+ let params;
1452
+ try {
1453
+ params = await session.client.waitFor("Debugger.paused", {
1454
+ timeoutMs: remainingMs,
1455
+ predicate: () => {
1456
+ receivedAtMs = performance2.now();
1457
+ return true;
1458
+ }
1459
+ });
1460
+ } finally {
1461
+ session.pauseWaitGate.active = false;
1462
+ }
1463
+ return toPauseEvent(params, receivedAtMs ?? performance2.now(), session.scripts);
1464
+ }
1465
+
1450
1466
  // src/snapshot/values.ts
1451
1467
  init_types();
1452
1468
  var DEFAULT_MAX_VALUE_LENGTH = 4096;