@saptools/cf-inspector 0.5.0 → 0.6.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/cli.js CHANGED
@@ -486,66 +486,70 @@ import "@saptools/cf-debugger";
486
486
 
487
487
  // src/cf/tunnel.ts
488
488
  import { startDebugger } from "@saptools/cf-debugger";
489
- async function openCfTunnel(target) {
490
- const opts = {
491
- region: target.region,
489
+ function targetOptions(target) {
490
+ return {
492
491
  ...target.apiEndpoint === void 0 ? {} : { apiEndpoint: target.apiEndpoint },
493
- org: target.org,
494
- space: target.space,
495
- app: target.app,
492
+ ...target.process === void 0 ? {} : { process: target.process },
493
+ ...target.instance === void 0 ? {} : { instance: target.instance },
494
+ ...target.nodePid === void 0 ? {} : { nodePid: target.nodePid }
495
+ };
496
+ }
497
+ function lifecycleOptions(target) {
498
+ return {
499
+ ...target.allowSshEnableRestart === void 0 ? {} : { allowSshEnableRestart: target.allowSshEnableRestart },
496
500
  ...target.tunnelReadyTimeoutMs === void 0 ? {} : { tunnelReadyTimeoutMs: target.tunnelReadyTimeoutMs },
497
501
  ...target.preferredPort === void 0 ? {} : { preferredPort: target.preferredPort },
498
502
  ...target.verbose === void 0 ? {} : { verbose: target.verbose },
499
503
  ...target.signal === void 0 ? {} : { signal: target.signal },
500
504
  ...target.onStatus === void 0 ? {} : { onStatus: target.onStatus }
501
505
  };
502
- try {
503
- const handle = await startDebugger(opts);
504
- return {
505
- localPort: handle.session.localPort,
506
- handle,
507
- dispose: async () => {
508
- await handle.dispose();
509
- }
510
- };
511
- } catch (err) {
512
- return reuseExistingTunnelOrThrow(err, target.onStatus);
513
- }
514
506
  }
515
- function reuseExistingTunnelOrThrow(err, onStatus) {
516
- if (!isSessionAlreadyRunningError(err)) {
517
- throw err;
518
- }
519
- const message = err instanceof Error ? err.message : String(err);
520
- const port = extractExistingTunnelPort(message);
521
- if (port === void 0) {
522
- throw err;
523
- }
524
- const warning = `Reusing existing tunnel on port ${port.toString()}`;
525
- onStatus?.("ready", warning);
507
+ function toStartDebuggerOptions(target) {
526
508
  return {
527
- localPort: port,
528
- dispose: () => Promise.resolve()
509
+ region: target.region,
510
+ org: target.org,
511
+ space: target.space,
512
+ app: target.app,
513
+ ...targetOptions(target),
514
+ ...lifecycleOptions(target)
529
515
  };
530
516
  }
531
- function isSessionAlreadyRunningError(err) {
532
- if (typeof err !== "object" || err === null) {
533
- return false;
534
- }
535
- const code = err.code;
536
- return code === "SESSION_ALREADY_RUNNING";
517
+ async function openOwnedCfTunnel(target) {
518
+ const opts = toStartDebuggerOptions(target);
519
+ const handle = await startDebugger(opts);
520
+ return {
521
+ localPort: handle.session.localPort,
522
+ handle,
523
+ dispose: async () => {
524
+ await handle.dispose();
525
+ }
526
+ };
527
+ }
528
+ function isExistingSessionError(error) {
529
+ return error instanceof Error && "code" in error && error.code === "SESSION_ALREADY_RUNNING";
537
530
  }
538
- function extractExistingTunnelPort(message) {
539
- const match = /on port (\d+)/i.exec(message);
540
- if (match === null) {
531
+ function existingTunnelPort(error) {
532
+ if (!isExistingSessionError(error)) {
541
533
  return void 0;
542
534
  }
543
- const rawPort = match[1];
535
+ const rawPort = /\bon port (\d+)\b/iu.exec(error.message)?.[1];
544
536
  if (rawPort === void 0) {
545
537
  return void 0;
546
538
  }
547
539
  const port = Number.parseInt(rawPort, 10);
548
- return Number.isNaN(port) ? void 0 : port;
540
+ return Number.isInteger(port) && port >= 1 && port <= 65535 ? port : void 0;
541
+ }
542
+ async function openCfTunnel(target) {
543
+ try {
544
+ return await openOwnedCfTunnel(target);
545
+ } catch (error) {
546
+ const localPort = existingTunnelPort(error);
547
+ if (localPort === void 0) {
548
+ throw error;
549
+ }
550
+ target.onStatus?.("ready", `Reusing existing tunnel on port ${localPort.toString()}`);
551
+ return { localPort, dispose: () => Promise.resolve() };
552
+ }
549
553
  }
550
554
 
551
555
  // src/inspector/session.ts
@@ -652,54 +656,70 @@ var CdpClient = class _CdpClient {
652
656
  if (this.closed) {
653
657
  throw this.closeReason ?? new CfInspectorError("INSPECTOR_CONNECTION_FAILED", "Connection closed");
654
658
  }
655
- return await new Promise((resolve, reject) => {
659
+ if (options.signal?.aborted === true) {
660
+ throw this.createWaitAbortError(method);
661
+ }
662
+ return await this.createEventWait(method, options);
663
+ }
664
+ createEventWait(method, options) {
665
+ return new Promise((resolve, reject) => {
656
666
  let settled = false;
667
+ let offEvent = () => void 0;
668
+ let offClose = () => void 0;
657
669
  const cleanup = () => {
658
670
  clearTimeout(timer);
659
671
  offEvent();
660
672
  offClose();
673
+ options.signal?.removeEventListener("abort", onAbort);
661
674
  };
662
- const finish = (value) => {
675
+ const resolveOnce = (value) => {
676
+ if (settled) {
677
+ return;
678
+ }
663
679
  settled = true;
664
680
  cleanup();
665
681
  resolve(value);
666
682
  };
667
- const offEvent = this.on(method, (raw) => {
668
- if (settled) {
669
- return;
670
- }
671
- const params = raw;
672
- if (options.predicate) {
673
- let accepted;
674
- try {
675
- accepted = options.predicate(params);
676
- } catch {
677
- return;
678
- }
679
- if (!accepted) {
680
- return;
681
- }
682
- }
683
- finish(params);
684
- });
685
- const offClose = this.onClose((err) => {
683
+ const rejectOnce = (error) => {
686
684
  if (settled) {
687
685
  return;
688
686
  }
689
687
  settled = true;
690
688
  cleanup();
691
- reject(err);
692
- });
689
+ reject(error);
690
+ };
691
+ const onAbort = () => {
692
+ rejectOnce(this.createWaitAbortError(method));
693
+ };
693
694
  const timer = setTimeout(() => {
694
- if (settled) {
695
+ rejectOnce(this.createWaitTimeoutError(method, options.timeoutMs));
696
+ }, options.timeoutMs);
697
+ offEvent = this.on(method, (raw) => {
698
+ const params = raw;
699
+ if (!this.eventMatches(params, options.predicate)) {
695
700
  return;
696
701
  }
697
- settled = true;
698
- cleanup();
699
- reject(this.createWaitTimeoutError(method, options.timeoutMs));
700
- }, options.timeoutMs);
702
+ resolveOnce(params);
703
+ });
704
+ offClose = this.onClose((error) => {
705
+ rejectOnce(error);
706
+ });
707
+ options.signal?.addEventListener("abort", onAbort, { once: true });
708
+ if (options.signal?.aborted === true) {
709
+ onAbort();
710
+ }
701
711
  });
702
712
  }
713
+ eventMatches(params, predicate) {
714
+ if (predicate === void 0) {
715
+ return true;
716
+ }
717
+ try {
718
+ return predicate(params);
719
+ } catch {
720
+ return false;
721
+ }
722
+ }
703
723
  onClose(listener) {
704
724
  if (this.closed) {
705
725
  const reason = this.closeReason ?? new CfInspectorError("INSPECTOR_CONNECTION_FAILED", "Connection closed");
@@ -766,6 +786,9 @@ var CdpClient = class _CdpClient {
766
786
  `Timed out waiting for ${method} after ${timeoutMs.toString()}ms`
767
787
  );
768
788
  }
789
+ createWaitAbortError(method) {
790
+ return new CfInspectorError("ABORTED", `Aborted while waiting for ${method}`);
791
+ }
769
792
  sendPayload(id, method, payload, timer, reject) {
770
793
  try {
771
794
  this.transport.send(payload);
@@ -892,96 +915,277 @@ async function createNodeWorkerClient(parent, sessionId, requestTimeoutMs = DEFA
892
915
  init_types();
893
916
 
894
917
  // src/inspector/conversions.ts
918
+ var INTERNAL_SLOT_SUBTYPES = /* @__PURE__ */ new Set([
919
+ "regexp",
920
+ "date",
921
+ "map",
922
+ "set",
923
+ "weakmap",
924
+ "weakset",
925
+ "iterator",
926
+ "generator",
927
+ "promise",
928
+ "typedarray",
929
+ "arraybuffer",
930
+ "dataview",
931
+ "webassemblymemory",
932
+ "wasmvalue",
933
+ "trustedtype"
934
+ ]);
895
935
  function asString(value, fallback = "") {
896
936
  return typeof value === "string" ? value : fallback;
897
937
  }
898
938
  function asNumber(value, fallback = 0) {
899
939
  return typeof value === "number" && Number.isFinite(value) ? value : fallback;
900
940
  }
941
+ function isRecord(value) {
942
+ return typeof value === "object" && value !== null && !Array.isArray(value);
943
+ }
901
944
  function nonEmptyString(value) {
902
945
  return typeof value === "string" && value.length > 0 ? value : void 0;
903
946
  }
947
+ function optionalNumber(value) {
948
+ return typeof value === "number" && Number.isFinite(value) ? value : void 0;
949
+ }
950
+ function optionalCoordinate(value) {
951
+ const number = optionalNumber(value);
952
+ return number !== void 0 && Number.isSafeInteger(number) && number >= 0 ? number : void 0;
953
+ }
954
+ function optionalBoolean(value) {
955
+ return typeof value === "boolean" ? value : void 0;
956
+ }
957
+ function toScriptLocation(value) {
958
+ if (!isRecord(value)) {
959
+ return void 0;
960
+ }
961
+ const scriptId = nonEmptyString(value["scriptId"]);
962
+ const lineNumber = optionalCoordinate(value["lineNumber"]);
963
+ if (scriptId === void 0 || lineNumber === void 0) {
964
+ return void 0;
965
+ }
966
+ const rawColumnNumber = value["columnNumber"];
967
+ const columnNumber = optionalCoordinate(rawColumnNumber);
968
+ if (rawColumnNumber !== void 0 && columnNumber === void 0) {
969
+ return void 0;
970
+ }
971
+ return columnNumber === void 0 ? { scriptId, lineNumber } : { scriptId, lineNumber, columnNumber };
972
+ }
904
973
  function toResolvedLocations(value) {
905
974
  if (!Array.isArray(value)) {
906
975
  return [];
907
976
  }
908
977
  return value.flatMap((entry) => {
909
- if (typeof entry !== "object" || entry === null) {
910
- return [];
911
- }
912
- const candidate = entry;
913
- const scriptId = asString(candidate.scriptId);
914
- if (scriptId.length === 0) {
978
+ const location = toScriptLocation(entry);
979
+ if (location === void 0 || !isRecord(entry)) {
915
980
  return [];
916
981
  }
917
- const url = typeof candidate.url === "string" ? candidate.url : void 0;
918
- const lineNumber = asNumber(candidate.lineNumber);
919
- const result = url === void 0 ? { scriptId, lineNumber, columnNumber: asNumber(candidate.columnNumber) } : { scriptId, url, lineNumber, columnNumber: asNumber(candidate.columnNumber) };
920
- return [result];
982
+ const url = typeof entry["url"] === "string" ? entry["url"] : void 0;
983
+ return [url === void 0 ? location : { ...location, url }];
921
984
  });
922
985
  }
923
- function toScopeChain(value) {
924
- if (!Array.isArray(value)) {
925
- return [];
986
+ function remoteCompleteness(subtype) {
987
+ if (subtype === "proxy") {
988
+ return "unavailable";
926
989
  }
927
- return value.flatMap((entry) => {
928
- if (typeof entry !== "object" || entry === null) {
929
- return [];
930
- }
931
- const candidate = entry;
932
- const type = asString(candidate.type);
933
- if (type.length === 0) {
934
- return [];
935
- }
936
- const objectId = typeof candidate.object?.objectId === "string" ? candidate.object.objectId : void 0;
937
- const name = typeof candidate.name === "string" ? candidate.name : void 0;
938
- const base = name === void 0 ? { type } : { type, name };
939
- return [objectId === void 0 ? base : { ...base, objectId }];
940
- });
990
+ return subtype !== void 0 && INTERNAL_SLOT_SUBTYPES.has(subtype) ? "truncated" : void 0;
991
+ }
992
+ function optionalOwnField(key, value) {
993
+ return Object.hasOwn(value, key) ? { [key]: value[key] } : {};
994
+ }
995
+ function toRemoteObject(value) {
996
+ if (!isRecord(value)) {
997
+ return void 0;
998
+ }
999
+ const type = nonEmptyString(value["type"]);
1000
+ if (type === void 0) {
1001
+ return void 0;
1002
+ }
1003
+ const subtype = nonEmptyString(value["subtype"]);
1004
+ const completeness = remoteCompleteness(subtype);
1005
+ return {
1006
+ type,
1007
+ ...subtype === void 0 ? {} : { subtype },
1008
+ ...optionalTextField("className", value["className"]),
1009
+ ...completeness === void 0 ? {} : { completeness },
1010
+ ...optionalOwnField("value", value),
1011
+ ...optionalTextField("unserializableValue", value["unserializableValue"]),
1012
+ ...optionalTextField("description", value["description"]),
1013
+ ...optionalOwnField("deepSerializedValue", value),
1014
+ ...optionalTextField("objectId", value["objectId"]),
1015
+ ...optionalOwnField("preview", value),
1016
+ ...optionalOwnField("customPreview", value)
1017
+ };
1018
+ }
1019
+ function optionalTextField(key, value) {
1020
+ return typeof value === "string" ? { [key]: value } : {};
1021
+ }
1022
+ function toScope(value) {
1023
+ if (!isRecord(value)) {
1024
+ return void 0;
1025
+ }
1026
+ const type = nonEmptyString(value["type"]);
1027
+ if (type === void 0) {
1028
+ return void 0;
1029
+ }
1030
+ const object = toRemoteObject(value["object"]);
1031
+ const name = nonEmptyString(value["name"]);
1032
+ const startLocation = toScriptLocation(value["startLocation"]);
1033
+ const endLocation = toScriptLocation(value["endLocation"]);
1034
+ return {
1035
+ type,
1036
+ ...name === void 0 ? {} : { name },
1037
+ ...object === void 0 ? {} : { object },
1038
+ ...object?.objectId === void 0 ? {} : { objectId: object.objectId },
1039
+ ...startLocation === void 0 ? {} : { startLocation },
1040
+ ...endLocation === void 0 ? {} : { endLocation }
1041
+ };
1042
+ }
1043
+ function toScopeChain(value) {
1044
+ return Array.isArray(value) ? value.flatMap((entry) => {
1045
+ const scope = toScope(entry);
1046
+ return scope === void 0 ? [] : [scope];
1047
+ }) : [];
941
1048
  }
942
1049
  function resolveCallFrameUrl(frame, scripts) {
943
- const direct = nonEmptyString(frame.url);
1050
+ const direct = nonEmptyString(frame["url"]);
944
1051
  if (direct !== void 0) {
945
1052
  return direct;
946
1053
  }
947
- const scriptId = nonEmptyString(frame.location?.scriptId);
948
- if (scriptId === void 0) {
1054
+ const scriptId = toScriptLocation(frame["location"])?.scriptId;
1055
+ return scriptId === void 0 ? void 0 : nonEmptyString(scripts?.get(scriptId)?.url);
1056
+ }
1057
+ function toCallFrameMetadata(candidate, location, scripts) {
1058
+ const functionLocation = toScriptLocation(candidate["functionLocation"]);
1059
+ const thisObject = toRemoteObject(candidate["this"]);
1060
+ const returnValue = toRemoteObject(candidate["returnValue"]);
1061
+ const url = resolveCallFrameUrl(candidate, scripts);
1062
+ return {
1063
+ ...location === void 0 ? {} : { scriptId: location.scriptId },
1064
+ ...functionLocation === void 0 ? {} : { functionLocation },
1065
+ ...url === void 0 ? {} : { url },
1066
+ ...thisObject === void 0 ? {} : { thisObject },
1067
+ ...returnValue === void 0 ? {} : { returnValue }
1068
+ };
1069
+ }
1070
+ function toCallFrame(value, scripts) {
1071
+ if (!isRecord(value)) {
1072
+ return void 0;
1073
+ }
1074
+ const callFrameId = nonEmptyString(value["callFrameId"]);
1075
+ if (callFrameId === void 0) {
949
1076
  return void 0;
950
1077
  }
951
- return nonEmptyString(scripts?.get(scriptId)?.url);
1078
+ const location = toScriptLocation(value["location"]);
1079
+ return {
1080
+ callFrameId,
1081
+ functionName: asString(value["functionName"]),
1082
+ ...toCallFrameMetadata(value, location, scripts),
1083
+ lineNumber: location?.lineNumber ?? 0,
1084
+ columnNumber: location?.columnNumber ?? 0,
1085
+ scopeChain: toScopeChain(value["scopeChain"])
1086
+ };
952
1087
  }
953
1088
  function toCallFrames(value, scripts) {
954
- if (!Array.isArray(value)) {
955
- return [];
1089
+ return Array.isArray(value) ? value.flatMap((entry) => {
1090
+ const frame = toCallFrame(entry, scripts);
1091
+ return frame === void 0 ? [] : [frame];
1092
+ }) : [];
1093
+ }
1094
+ function toStackTraceId(value) {
1095
+ if (!isRecord(value)) {
1096
+ return void 0;
956
1097
  }
957
- return value.flatMap((entry) => {
958
- if (typeof entry !== "object" || entry === null) {
959
- return [];
960
- }
961
- const candidate = entry;
962
- const callFrameId = asString(candidate.callFrameId);
963
- if (callFrameId.length === 0) {
964
- return [];
965
- }
966
- const url = resolveCallFrameUrl(candidate, scripts);
967
- const base = {
968
- callFrameId,
969
- functionName: asString(candidate.functionName),
970
- lineNumber: asNumber(candidate.location?.lineNumber),
971
- columnNumber: asNumber(candidate.location?.columnNumber),
972
- scopeChain: toScopeChain(candidate.scopeChain)
973
- };
974
- return [url === void 0 ? base : { ...base, url }];
1098
+ const id = nonEmptyString(value["id"]);
1099
+ if (id === void 0) {
1100
+ return void 0;
1101
+ }
1102
+ const debuggerId = nonEmptyString(value["debuggerId"]);
1103
+ return debuggerId === void 0 ? { id } : { id, debuggerId };
1104
+ }
1105
+ function toStackTraceFrame(value) {
1106
+ if (!isRecord(value)) {
1107
+ return void 0;
1108
+ }
1109
+ const scriptId = nonEmptyString(value["scriptId"]);
1110
+ if (scriptId === void 0) {
1111
+ return void 0;
1112
+ }
1113
+ return {
1114
+ functionName: asString(value["functionName"]),
1115
+ scriptId,
1116
+ url: asString(value["url"]),
1117
+ lineNumber: asNumber(value["lineNumber"]),
1118
+ columnNumber: asNumber(value["columnNumber"])
1119
+ };
1120
+ }
1121
+ function toStackTrace(value) {
1122
+ if (!isRecord(value) || !Array.isArray(value["callFrames"])) {
1123
+ return void 0;
1124
+ }
1125
+ const callFrames = value["callFrames"].flatMap((entry) => {
1126
+ const frame = toStackTraceFrame(entry);
1127
+ return frame === void 0 ? [] : [frame];
975
1128
  });
1129
+ const description = nonEmptyString(value["description"]);
1130
+ const parent = toStackTrace(value["parent"]);
1131
+ const parentId = toStackTraceId(value["parentId"]);
1132
+ return {
1133
+ callFrames,
1134
+ ...description === void 0 ? {} : { description },
1135
+ ...parent === void 0 ? {} : { parent },
1136
+ ...parentId === void 0 ? {} : { parentId }
1137
+ };
976
1138
  }
977
- function toPauseEvent(params, receivedAtMs, scripts) {
978
- const base = {
979
- reason: asString(params.reason),
980
- hitBreakpoints: Array.isArray(params.hitBreakpoints) ? params.hitBreakpoints.filter((id) => typeof id === "string") : [],
981
- callFrames: toCallFrames(params.callFrames, scripts),
982
- receivedAtMs
1139
+ function toPauseEvent(value, receivedAtMs, scripts) {
1140
+ const params = isRecord(value) ? value : {};
1141
+ const asyncStackTrace = toStackTrace(params["asyncStackTrace"]);
1142
+ const asyncStackTraceId = toStackTraceId(params["asyncStackTraceId"]);
1143
+ const asyncCallStackTraceId = toStackTraceId(params["asyncCallStackTraceId"]);
1144
+ return {
1145
+ reason: asString(params["reason"]),
1146
+ hitBreakpoints: Array.isArray(params["hitBreakpoints"]) ? params["hitBreakpoints"].filter((id) => typeof id === "string") : [],
1147
+ callFrames: toCallFrames(params["callFrames"], scripts),
1148
+ receivedAtMs,
1149
+ ...params["data"] === void 0 ? {} : { data: params["data"] },
1150
+ ...asyncStackTrace === void 0 ? {} : { asyncStackTrace },
1151
+ ...asyncStackTraceId === void 0 ? {} : { asyncStackTraceId },
1152
+ ...asyncCallStackTraceId === void 0 ? {} : { asyncCallStackTraceId }
983
1153
  };
984
- return params.data === void 0 ? base : { ...base, data: params.data };
1154
+ }
1155
+ function toScriptInfo(value) {
1156
+ if (!isRecord(value)) {
1157
+ return void 0;
1158
+ }
1159
+ const scriptId = nonEmptyString(value["scriptId"]);
1160
+ if (scriptId === void 0) {
1161
+ return void 0;
1162
+ }
1163
+ const stackTrace = toStackTrace(value["stackTrace"]);
1164
+ return {
1165
+ scriptId,
1166
+ url: asString(value["url"]),
1167
+ ...optionalNumericField("startLine", value["startLine"]),
1168
+ ...optionalNumericField("startColumn", value["startColumn"]),
1169
+ ...optionalNumericField("endLine", value["endLine"]),
1170
+ ...optionalNumericField("endColumn", value["endColumn"]),
1171
+ ...optionalNumericField("executionContextId", value["executionContextId"]),
1172
+ ...optionalTextField("hash", value["hash"]),
1173
+ ...optionalTextField("buildId", value["buildId"]),
1174
+ ...value["executionContextAuxData"] === void 0 ? {} : { executionContextAuxData: value["executionContextAuxData"] },
1175
+ ...optionalTextField("sourceMapURL", value["sourceMapURL"]),
1176
+ ...optionalBooleanField("hasSourceURL", value["hasSourceURL"]),
1177
+ ...optionalBooleanField("isModule", value["isModule"]),
1178
+ ...optionalNumericField("length", value["length"]),
1179
+ ...stackTrace === void 0 ? {} : { stackTrace }
1180
+ };
1181
+ }
1182
+ function optionalNumericField(key, value) {
1183
+ const number = optionalNumber(value);
1184
+ return number === void 0 ? {} : { [key]: number };
1185
+ }
1186
+ function optionalBooleanField(key, value) {
1187
+ const boolean = optionalBoolean(value);
1188
+ return boolean === void 0 ? {} : { [key]: boolean };
985
1189
  }
986
1190
  function topFrameLocation(pause) {
987
1191
  const top = pause.callFrames[0];
@@ -1191,24 +1395,29 @@ async function discoverNodeWorkerTargets(target, connectTimeoutMs = DEFAULT_CONN
1191
1395
  }
1192
1396
  async function initSession(client, target) {
1193
1397
  const scripts = /* @__PURE__ */ new Map();
1194
- client.on("Debugger.scriptParsed", (raw) => {
1195
- const params = raw;
1196
- const scriptId = asString(params.scriptId);
1197
- const url = asString(params.url);
1198
- if (scriptId.length === 0) {
1199
- return;
1200
- }
1201
- scripts.set(scriptId, { scriptId, url });
1202
- });
1398
+ registerScriptTracking(client, scripts);
1203
1399
  const pauseBuffer = [];
1204
1400
  const pauseWaitGate = { active: false };
1205
1401
  const debuggerState = {};
1402
+ registerPauseTracking(client, scripts, pauseBuffer, pauseWaitGate, debuggerState);
1403
+ await client.send("Runtime.enable");
1404
+ await client.send("Debugger.enable");
1405
+ return createSession(client, target, scripts, pauseBuffer, pauseWaitGate, debuggerState);
1406
+ }
1407
+ function registerScriptTracking(client, scripts) {
1408
+ client.on("Debugger.scriptParsed", (raw) => {
1409
+ const script = toScriptInfo(raw);
1410
+ if (script !== void 0) {
1411
+ scripts.set(script.scriptId, script);
1412
+ }
1413
+ });
1414
+ }
1415
+ function registerPauseTracking(client, scripts, pauseBuffer, pauseWaitGate, debuggerState) {
1206
1416
  client.on("Debugger.paused", (raw) => {
1207
1417
  if (pauseWaitGate.active) {
1208
1418
  return;
1209
1419
  }
1210
- const params = raw;
1211
- const event = toPauseEvent(params, performance2.now(), scripts);
1420
+ const event = toPauseEvent(raw, performance2.now(), scripts);
1212
1421
  if (pauseBuffer.length >= PAUSE_BUFFER_LIMIT) {
1213
1422
  pauseBuffer.shift();
1214
1423
  }
@@ -1217,8 +1426,8 @@ async function initSession(client, target) {
1217
1426
  client.on("Debugger.resumed", () => {
1218
1427
  debuggerState.lastResumedAtMs = performance2.now();
1219
1428
  });
1220
- await client.send("Runtime.enable");
1221
- await client.send("Debugger.enable");
1429
+ }
1430
+ function createSession(client, target, scripts, pauseBuffer, pauseWaitGate, debuggerState) {
1222
1431
  return {
1223
1432
  client,
1224
1433
  target,
@@ -1577,8 +1786,8 @@ function optionalText(value) {
1577
1786
  const trimmed = value?.trim();
1578
1787
  return trimmed === void 0 || trimmed.length === 0 ? void 0 : trimmed;
1579
1788
  }
1580
- async function withSession(target, fn, reportProgress) {
1581
- const tunnel = await openTarget(target, reportProgress);
1789
+ async function withSession(target, fn, reportProgress, signal) {
1790
+ const tunnel = await openTarget(target, reportProgress, signal);
1582
1791
  let session;
1583
1792
  try {
1584
1793
  reportProgress?.(
@@ -1605,7 +1814,7 @@ async function withSession(target, fn, reportProgress) {
1605
1814
  await tunnel.dispose();
1606
1815
  }
1607
1816
  }
1608
- async function openTarget(target, reportProgress) {
1817
+ async function openTarget(target, reportProgress, signal) {
1609
1818
  if (target.kind === "port") {
1610
1819
  return {
1611
1820
  port: target.port,
@@ -1621,6 +1830,7 @@ async function openTarget(target, reportProgress) {
1621
1830
  space: target.space,
1622
1831
  app: target.app,
1623
1832
  tunnelReadyTimeoutMs: target.tunnelTimeoutMs,
1833
+ ...signal === void 0 ? {} : { signal },
1624
1834
  ...reportProgress === void 0 ? {} : {
1625
1835
  onStatus: (status, message) => {
1626
1836
  reportProgress(message ?? formatCfTunnelStatus(status));
@@ -1675,7 +1885,8 @@ async function evaluateOnFrame(session, callFrameId, expression, options = {}) {
1675
1885
  returnByValue: false,
1676
1886
  generatePreview: true,
1677
1887
  silent: true,
1678
- ...options.throwOnSideEffect === void 0 ? {} : { throwOnSideEffect: options.throwOnSideEffect }
1888
+ ...options.throwOnSideEffect === void 0 ? {} : { throwOnSideEffect: options.throwOnSideEffect },
1889
+ ...options.objectGroup === void 0 ? {} : { objectGroup: options.objectGroup }
1679
1890
  });
1680
1891
  }
1681
1892
  function isSideEffectRefusal(result) {
@@ -2012,6 +2223,11 @@ function pauseMatches(pause, breakpointIds, pauseReasons) {
2012
2223
  function remainingUntil(deadlineMs) {
2013
2224
  return Math.max(0, deadlineMs - performance3.now());
2014
2225
  }
2226
+ function throwIfAborted(signal) {
2227
+ if (signal?.aborted === true) {
2228
+ throw new CfInspectorError("ABORTED", "Aborted while waiting for Debugger.paused");
2229
+ }
2230
+ }
2015
2231
  function hasResumedSincePause(session, pause) {
2016
2232
  const pauseAt = pause.receivedAtMs;
2017
2233
  const resumedAt = session.debuggerState.lastResumedAtMs;
@@ -2030,20 +2246,23 @@ function throwUnrelatedPauseTimeout(pause, timeoutMs) {
2030
2246
  pauseDetail(pause)
2031
2247
  );
2032
2248
  }
2033
- async function waitForUnmatchedPauseToResume(session, pause, deadlineMs, timeoutMs) {
2249
+ async function waitForUnmatchedPauseToResume(session, pause, deadlineMs, options) {
2034
2250
  if (hasResumedSincePause(session, pause)) {
2035
2251
  return;
2036
2252
  }
2037
2253
  const remainingMs = remainingUntil(deadlineMs);
2038
2254
  if (remainingMs <= 0) {
2039
- throwUnrelatedPauseTimeout(pause, timeoutMs);
2255
+ throwUnrelatedPauseTimeout(pause, options.timeoutMs);
2040
2256
  }
2041
2257
  try {
2042
- await session.client.waitFor("Debugger.resumed", { timeoutMs: remainingMs });
2258
+ await session.client.waitFor("Debugger.resumed", {
2259
+ timeoutMs: remainingMs,
2260
+ ...options.signal === void 0 ? {} : { signal: options.signal }
2261
+ });
2043
2262
  session.debuggerState.lastResumedAtMs = performance3.now();
2044
2263
  } catch (err) {
2045
2264
  if (err instanceof CfInspectorError && err.code === "BREAKPOINT_NOT_HIT") {
2046
- throwUnrelatedPauseTimeout(pause, timeoutMs);
2265
+ throwUnrelatedPauseTimeout(pause, options.timeoutMs);
2047
2266
  }
2048
2267
  throw err;
2049
2268
  }
@@ -2060,13 +2279,16 @@ async function handleUnmatchedPause(session, pause, options, deadlineMs) {
2060
2279
  return;
2061
2280
  }
2062
2281
  options.onUnmatchedPause?.(pause);
2063
- await waitForUnmatchedPauseToResume(session, pause, deadlineMs, options.timeoutMs);
2282
+ await waitForUnmatchedPauseToResume(session, pause, deadlineMs, options);
2064
2283
  }
2065
2284
  async function waitForPause(session, options) {
2285
+ throwIfAborted(options.signal);
2066
2286
  const deadlineMs = performance3.now() + options.timeoutMs;
2067
2287
  const buffer = session.pauseBuffer;
2068
2288
  while (buffer.length > 0 || remainingUntil(deadlineMs) > 0) {
2289
+ throwIfAborted(options.signal);
2069
2290
  while (buffer.length > 0) {
2291
+ throwIfAborted(options.signal);
2070
2292
  const buffered = buffer.shift();
2071
2293
  if (buffered === void 0) {
2072
2294
  continue;
@@ -2095,6 +2317,7 @@ async function waitForLivePause(session, options, deadlineMs) {
2095
2317
  try {
2096
2318
  params = await session.client.waitFor("Debugger.paused", {
2097
2319
  timeoutMs: remainingMs,
2320
+ ...options.signal === void 0 ? {} : { signal: options.signal },
2098
2321
  predicate: () => {
2099
2322
  receivedAtMs = performance3.now();
2100
2323
  return true;
@@ -3399,7 +3622,7 @@ async function handleLog(opts) {
3399
3622
  warnOnBoundBreakpointWithoutHit([result.handle]);
3400
3623
  }
3401
3624
  writeLogSummary(result.stoppedReason, result.emitted, opts.json);
3402
- });
3625
+ }, void 0, signal);
3403
3626
  });
3404
3627
  }
3405
3628
  function writeLogSummary(stoppedReason, emitted, json) {
@@ -3597,7 +3820,7 @@ async function handleWatch(opts) {
3597
3820
  const result = await runWatchLoop(session, prepared, opts, signal);
3598
3821
  stoppedReason = result.stoppedReason;
3599
3822
  emitted = result.emitted;
3600
- });
3823
+ }, void 0, signal);
3601
3824
  });
3602
3825
  writeWatchSummary(stoppedReason, emitted, opts.json);
3603
3826
  }
@@ -3762,10 +3985,14 @@ async function waitForNextWatchPause(session, handles, timeoutMs, signal) {
3762
3985
  return await waitForPause(session, {
3763
3986
  timeoutMs,
3764
3987
  breakpointIds: handles.map((h) => h.breakpointId),
3765
- unmatchedPausePolicy: "wait-for-resume"
3988
+ unmatchedPausePolicy: "wait-for-resume",
3989
+ signal
3766
3990
  });
3767
3991
  } catch (err) {
3768
3992
  if (err instanceof CfInspectorError) {
3993
+ if (err.code === "ABORTED") {
3994
+ return "signal";
3995
+ }
3769
3996
  if (err.code === "BREAKPOINT_NOT_HIT") {
3770
3997
  return "timeout";
3771
3998
  }