@saptools/cf-live-trace 0.1.4 → 0.1.6
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 +247 -71
- package/dist/cli.js.map +1 -1
- package/dist/index.d.ts +15 -4
- package/dist/index.js +139 -33
- package/dist/index.js.map +1 -1
- package/package.json +2 -2
package/dist/cli.js
CHANGED
|
@@ -1,5 +1,8 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
|
|
3
|
+
// src/cli.ts
|
|
4
|
+
import process4 from "process";
|
|
5
|
+
|
|
3
6
|
// src/cli/program.ts
|
|
4
7
|
import process3 from "process";
|
|
5
8
|
import { Command } from "commander";
|
|
@@ -52,16 +55,16 @@ async function ensureSshEnabled(target, dependencies = defaultCfDependencies) {
|
|
|
52
55
|
timeoutMs: CF_SSH_READY_TIMEOUT_MS
|
|
53
56
|
});
|
|
54
57
|
}
|
|
55
|
-
async function
|
|
58
|
+
async function startNodeInspector(target, dependencies = defaultCfDependencies) {
|
|
59
|
+
const redactor = createSecretRedactor([target.email, target.password]);
|
|
56
60
|
try {
|
|
57
|
-
const redactor = createSecretRedactor([target.email, target.password]);
|
|
58
61
|
const stdout = await dependencies.runCf(
|
|
59
62
|
buildCfSshArgs(target.app, target.instanceIndex, ["-c", buildInspectorSignalCommand()]),
|
|
60
63
|
{ ...buildRunOptions(target, redactor), timeoutMs: INSPECTOR_SIGNAL_TIMEOUT_MS }
|
|
61
64
|
);
|
|
62
|
-
return hasInspectorReadyMarker(stdout);
|
|
63
|
-
} catch {
|
|
64
|
-
return
|
|
65
|
+
return hasInspectorReadyMarker(stdout) ? { status: "ready" } : { status: "not-ready", ...optionalDetail(summarizeInspectorStartupOutput(stdout)) };
|
|
66
|
+
} catch (error) {
|
|
67
|
+
return { status: "not-ready", ...optionalDetail(redactor(formatErrorMessage(error))) };
|
|
65
68
|
}
|
|
66
69
|
}
|
|
67
70
|
async function openInspectorTunnel(target, dependencies = defaultTunnelDependencies) {
|
|
@@ -109,6 +112,8 @@ function spawnPortForward(params) {
|
|
|
109
112
|
env: buildCfEnv(params.cfHomeDir),
|
|
110
113
|
stdio: ["ignore", "pipe", "pipe"]
|
|
111
114
|
});
|
|
115
|
+
child.stdout.resume();
|
|
116
|
+
child.stderr.resume();
|
|
112
117
|
return {
|
|
113
118
|
process: child,
|
|
114
119
|
localPort: params.localPort,
|
|
@@ -216,6 +221,7 @@ function resolveTunnelAppName(target) {
|
|
|
216
221
|
return appName;
|
|
217
222
|
}
|
|
218
223
|
async function raceForwardReadiness(handle, dependencies) {
|
|
224
|
+
const controller = new AbortController();
|
|
219
225
|
let markFailed = () => {
|
|
220
226
|
return;
|
|
221
227
|
};
|
|
@@ -226,11 +232,14 @@ async function raceForwardReadiness(handle, dependencies) {
|
|
|
226
232
|
handle.process.once("exit", markFailed);
|
|
227
233
|
handle.process.once("error", markFailed);
|
|
228
234
|
});
|
|
229
|
-
const ready = dependencies.waitForLocalPort(handle.localPort, TUNNEL_READY_TIMEOUT_MS);
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
235
|
+
const ready = dependencies.waitForLocalPort(handle.localPort, TUNNEL_READY_TIMEOUT_MS, controller.signal);
|
|
236
|
+
try {
|
|
237
|
+
return await Promise.race([ready, failedEarly]);
|
|
238
|
+
} finally {
|
|
239
|
+
controller.abort();
|
|
240
|
+
handle.process.removeListener("exit", markFailed);
|
|
241
|
+
handle.process.removeListener("error", markFailed);
|
|
242
|
+
}
|
|
234
243
|
}
|
|
235
244
|
function resolveCommand(command) {
|
|
236
245
|
const resolvedBin = command ?? process.env["CF_LIVE_TRACE_CF_BIN"] ?? "cf";
|
|
@@ -258,7 +267,15 @@ function extractErrorDetail(error) {
|
|
|
258
267
|
if (stderr.length > 0) {
|
|
259
268
|
return stderr;
|
|
260
269
|
}
|
|
261
|
-
|
|
270
|
+
const message = error["message"];
|
|
271
|
+
if (typeof message === "string") {
|
|
272
|
+
return message.trim();
|
|
273
|
+
}
|
|
274
|
+
return message instanceof Error ? message.message.trim() : "";
|
|
275
|
+
}
|
|
276
|
+
function formatErrorMessage(error) {
|
|
277
|
+
const message = error instanceof Error ? error.message : String(error);
|
|
278
|
+
return message.trim().length > 0 ? message.trim() : "Unknown error";
|
|
262
279
|
}
|
|
263
280
|
function formatArgs(args) {
|
|
264
281
|
return args.join(" ");
|
|
@@ -266,6 +283,13 @@ function formatArgs(args) {
|
|
|
266
283
|
function hasInspectorReadyMarker(stdout) {
|
|
267
284
|
return stdout.split(/\r?\n/).map((line) => line.trim()).includes("saptools-inspector-ready");
|
|
268
285
|
}
|
|
286
|
+
function summarizeInspectorStartupOutput(stdout) {
|
|
287
|
+
const markers = stdout.split(/\r?\n/).map((line) => line.trim()).filter((line) => line.startsWith("saptools-inspector-"));
|
|
288
|
+
return markers.length === 0 ? void 0 : markers.join("; ");
|
|
289
|
+
}
|
|
290
|
+
function optionalDetail(detail) {
|
|
291
|
+
return detail === void 0 || detail.length === 0 ? {} : { detail };
|
|
292
|
+
}
|
|
269
293
|
function findFreePort() {
|
|
270
294
|
return new Promise((resolve, reject) => {
|
|
271
295
|
const server = createServer();
|
|
@@ -283,29 +307,61 @@ function findFreePort() {
|
|
|
283
307
|
});
|
|
284
308
|
});
|
|
285
309
|
}
|
|
286
|
-
function waitForLocalPort(port, timeoutMs) {
|
|
310
|
+
function waitForLocalPort(port, timeoutMs, signal) {
|
|
287
311
|
const deadline = Date.now() + timeoutMs;
|
|
288
312
|
return new Promise((resolve) => {
|
|
313
|
+
let activeSocket;
|
|
314
|
+
let settled = false;
|
|
315
|
+
let retryTimer;
|
|
316
|
+
const finish = (ready) => {
|
|
317
|
+
if (settled) {
|
|
318
|
+
return;
|
|
319
|
+
}
|
|
320
|
+
settled = true;
|
|
321
|
+
if (retryTimer !== void 0) {
|
|
322
|
+
clearTimeout(retryTimer);
|
|
323
|
+
}
|
|
324
|
+
activeSocket?.destroy();
|
|
325
|
+
activeSocket = void 0;
|
|
326
|
+
signal?.removeEventListener("abort", onAbort);
|
|
327
|
+
resolve(ready);
|
|
328
|
+
};
|
|
329
|
+
const onAbort = () => {
|
|
330
|
+
finish(false);
|
|
331
|
+
};
|
|
289
332
|
const attempt = () => {
|
|
333
|
+
if (settled) {
|
|
334
|
+
return;
|
|
335
|
+
}
|
|
290
336
|
const socket = netConnect({ host: "127.0.0.1", port });
|
|
337
|
+
activeSocket = socket;
|
|
291
338
|
socket.once("connect", () => {
|
|
292
339
|
socket.destroy();
|
|
293
|
-
|
|
340
|
+
activeSocket = void 0;
|
|
341
|
+
finish(true);
|
|
294
342
|
});
|
|
295
343
|
socket.once("error", () => {
|
|
296
|
-
|
|
344
|
+
activeSocket = void 0;
|
|
345
|
+
retryPortProbe(socket, deadline, attempt, finish, (timer) => {
|
|
346
|
+
retryTimer = timer;
|
|
347
|
+
});
|
|
297
348
|
});
|
|
298
349
|
};
|
|
350
|
+
if (signal?.aborted === true) {
|
|
351
|
+
finish(false);
|
|
352
|
+
return;
|
|
353
|
+
}
|
|
354
|
+
signal?.addEventListener("abort", onAbort, { once: true });
|
|
299
355
|
attempt();
|
|
300
356
|
});
|
|
301
357
|
}
|
|
302
|
-
function retryPortProbe(socket, deadline, attempt,
|
|
358
|
+
function retryPortProbe(socket, deadline, attempt, finish, setRetryTimer) {
|
|
303
359
|
socket.destroy();
|
|
304
360
|
if (Date.now() >= deadline) {
|
|
305
|
-
|
|
361
|
+
finish(false);
|
|
306
362
|
return;
|
|
307
363
|
}
|
|
308
|
-
setTimeout(attempt, TUNNEL_READY_POLL_MS);
|
|
364
|
+
setRetryTimer(setTimeout(attempt, TUNNEL_READY_POLL_MS));
|
|
309
365
|
}
|
|
310
366
|
function isRecord(value) {
|
|
311
367
|
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
@@ -579,7 +635,7 @@ function isRecord2(value) {
|
|
|
579
635
|
|
|
580
636
|
// src/runtime-source.ts
|
|
581
637
|
var CF_LIVE_TRACE_GLOBAL_NAME = "__SAPTOOLS_CF_LIVE_TRACE__";
|
|
582
|
-
var CF_LIVE_TRACE_RUNTIME_VERSION =
|
|
638
|
+
var CF_LIVE_TRACE_RUNTIME_VERSION = 2;
|
|
583
639
|
var CF_LIVE_TRACE_RUNTIME_SOURCE = `
|
|
584
640
|
(() => {
|
|
585
641
|
const name = '${CF_LIVE_TRACE_GLOBAL_NAME}';
|
|
@@ -776,15 +832,12 @@ var CF_LIVE_TRACE_RUNTIME_SOURCE = `
|
|
|
776
832
|
status() {
|
|
777
833
|
return { installed: state.installed, enabled: state.enabled, queueSize: state.queue.length, droppedCount: state.droppedCount, maxEvents: state.options.maxEvents };
|
|
778
834
|
},
|
|
779
|
-
uninstall() {
|
|
835
|
+
async uninstall() {
|
|
780
836
|
state.enabled = false;
|
|
781
|
-
const
|
|
782
|
-
|
|
783
|
-
|
|
784
|
-
|
|
785
|
-
if (state.originals.httpServerEmit && http && http.Server) http.Server.prototype.emit = state.originals.httpServerEmit;
|
|
786
|
-
if (state.originals.httpsServerEmit && https && https.Server) https.Server.prototype.emit = state.originals.httpsServerEmit;
|
|
787
|
-
}
|
|
837
|
+
const http = await loadModule('http');
|
|
838
|
+
const https = await loadModule('https');
|
|
839
|
+
if (state.originals.httpServerEmit && http && http.Server) http.Server.prototype.emit = state.originals.httpServerEmit;
|
|
840
|
+
if (state.originals.httpsServerEmit && https && https.Server) https.Server.prototype.emit = state.originals.httpsServerEmit;
|
|
788
841
|
state.installed = false;
|
|
789
842
|
return api.status();
|
|
790
843
|
}
|
|
@@ -893,7 +946,7 @@ var DRAIN_TRANSPORT_BODY_LIMIT = 2e4;
|
|
|
893
946
|
var defaultDependencies = {
|
|
894
947
|
prepareCfSession,
|
|
895
948
|
ensureSshEnabled,
|
|
896
|
-
tryStartNodeInspector,
|
|
949
|
+
tryStartNodeInspector: startNodeInspector,
|
|
897
950
|
openInspectorTunnel,
|
|
898
951
|
connectInspector: connectRuntimeInspector,
|
|
899
952
|
setInterval,
|
|
@@ -924,6 +977,9 @@ var LiveTraceSession = class {
|
|
|
924
977
|
async stop(options) {
|
|
925
978
|
this.stopRequested = true;
|
|
926
979
|
if (!this.isRunning()) {
|
|
980
|
+
if (this.state === "error" && options.reason === "error") {
|
|
981
|
+
return;
|
|
982
|
+
}
|
|
927
983
|
this.postState("stopped", `Trace stopped (${options.reason}).`, false, false);
|
|
928
984
|
return;
|
|
929
985
|
}
|
|
@@ -946,9 +1002,11 @@ var LiveTraceSession = class {
|
|
|
946
1002
|
} catch (error) {
|
|
947
1003
|
this.log(`Live Trace startup failed for ${this.options.target.app}: ${formatError(error)}`);
|
|
948
1004
|
await this.stopRuntimeTrace(false);
|
|
1005
|
+
const startupError = toStartupError(error);
|
|
949
1006
|
if (!this.shouldStop()) {
|
|
950
|
-
this.postState("error",
|
|
1007
|
+
this.postState("error", startupError.stateMessage, false, false);
|
|
951
1008
|
}
|
|
1009
|
+
throw startupError;
|
|
952
1010
|
}
|
|
953
1011
|
}
|
|
954
1012
|
async startInspector(options) {
|
|
@@ -958,7 +1016,7 @@ var LiveTraceSession = class {
|
|
|
958
1016
|
return;
|
|
959
1017
|
}
|
|
960
1018
|
this.postState("starting-inspector", "Requesting Node Inspector startup.", false, false);
|
|
961
|
-
await this.dependencies.tryStartNodeInspector(this.options.target);
|
|
1019
|
+
this.reportInspectorStartup(await this.dependencies.tryStartNodeInspector(this.options.target));
|
|
962
1020
|
if (this.shouldStop()) {
|
|
963
1021
|
return;
|
|
964
1022
|
}
|
|
@@ -972,8 +1030,10 @@ var LiveTraceSession = class {
|
|
|
972
1030
|
return;
|
|
973
1031
|
}
|
|
974
1032
|
if (tunnel.status !== "ready") {
|
|
975
|
-
|
|
976
|
-
|
|
1033
|
+
throw new LiveTraceStartupError(
|
|
1034
|
+
"Node Inspector is not reachable on 127.0.0.1:9229.",
|
|
1035
|
+
"Node Inspector is not reachable on 127.0.0.1:9229."
|
|
1036
|
+
);
|
|
977
1037
|
}
|
|
978
1038
|
this.tunnelHandle = tunnel.handle;
|
|
979
1039
|
this.inspectorClient = await this.dependencies.connectInspector(tunnel.handle.localPort);
|
|
@@ -1044,11 +1104,27 @@ var LiveTraceSession = class {
|
|
|
1044
1104
|
this.stopPolling();
|
|
1045
1105
|
this.consecutiveDrainTimeouts = 0;
|
|
1046
1106
|
const uninstalled = await this.stopInspectorHook(uninstallRuntimeHook);
|
|
1047
|
-
await this.
|
|
1107
|
+
await this.closeInspectorClient();
|
|
1108
|
+
this.stopTunnel();
|
|
1109
|
+
return uninstalled;
|
|
1110
|
+
}
|
|
1111
|
+
async closeInspectorClient() {
|
|
1112
|
+
const client = this.inspectorClient;
|
|
1048
1113
|
this.inspectorClient = void 0;
|
|
1049
|
-
|
|
1114
|
+
try {
|
|
1115
|
+
await client?.close();
|
|
1116
|
+
} catch (error) {
|
|
1117
|
+
this.log(`Live Trace inspector close failed for ${this.options.target.app}: ${formatError(error)}`);
|
|
1118
|
+
}
|
|
1119
|
+
}
|
|
1120
|
+
stopTunnel() {
|
|
1121
|
+
const tunnel = this.tunnelHandle;
|
|
1050
1122
|
this.tunnelHandle = void 0;
|
|
1051
|
-
|
|
1123
|
+
try {
|
|
1124
|
+
tunnel?.stop();
|
|
1125
|
+
} catch (error) {
|
|
1126
|
+
this.log(`Live Trace tunnel cleanup failed for ${this.options.target.app}: ${formatError(error)}`);
|
|
1127
|
+
}
|
|
1052
1128
|
}
|
|
1053
1129
|
async stopInspectorHook(uninstallRuntimeHook) {
|
|
1054
1130
|
if (this.inspectorClient === void 0) {
|
|
@@ -1092,6 +1168,21 @@ var LiveTraceSession = class {
|
|
|
1092
1168
|
log(message) {
|
|
1093
1169
|
this.options.onLog?.(message);
|
|
1094
1170
|
}
|
|
1171
|
+
reportInspectorStartup(result) {
|
|
1172
|
+
const normalized = normalizeInspectorStartupResult(result);
|
|
1173
|
+
if (normalized.status === "ready") {
|
|
1174
|
+
return;
|
|
1175
|
+
}
|
|
1176
|
+
const detail = normalized.detail === void 0 ? "" : `: ${normalized.detail}`;
|
|
1177
|
+
this.log(`Node Inspector startup was not confirmed for ${this.options.target.app}${detail}`);
|
|
1178
|
+
}
|
|
1179
|
+
};
|
|
1180
|
+
var LiveTraceStartupError = class extends Error {
|
|
1181
|
+
constructor(message, stateMessage, cause) {
|
|
1182
|
+
super(message, cause === void 0 ? void 0 : { cause });
|
|
1183
|
+
this.stateMessage = stateMessage;
|
|
1184
|
+
}
|
|
1185
|
+
stateMessage;
|
|
1095
1186
|
};
|
|
1096
1187
|
function resolveStartOptions(options) {
|
|
1097
1188
|
return {
|
|
@@ -1114,6 +1205,19 @@ function isEvaluateTimeout(error) {
|
|
|
1114
1205
|
const message = error instanceof Error ? error.message : String(error);
|
|
1115
1206
|
return message.includes("Runtime.evaluate timed out");
|
|
1116
1207
|
}
|
|
1208
|
+
function toStartupError(error) {
|
|
1209
|
+
if (error instanceof LiveTraceStartupError) {
|
|
1210
|
+
return error;
|
|
1211
|
+
}
|
|
1212
|
+
return new LiveTraceStartupError(
|
|
1213
|
+
"Runtime HTTP trace could not be started.",
|
|
1214
|
+
"Runtime HTTP trace could not be started.",
|
|
1215
|
+
error
|
|
1216
|
+
);
|
|
1217
|
+
}
|
|
1218
|
+
function normalizeInspectorStartupResult(result) {
|
|
1219
|
+
return typeof result === "boolean" ? { status: result ? "ready" : "not-ready" } : result;
|
|
1220
|
+
}
|
|
1117
1221
|
function formatError(error) {
|
|
1118
1222
|
const message = error instanceof Error ? error.message : String(error);
|
|
1119
1223
|
return message.trim().length > 0 ? message.trim() : "Unknown error";
|
|
@@ -1305,30 +1409,35 @@ async function main(argv) {
|
|
|
1305
1409
|
}
|
|
1306
1410
|
async function runTraceCommand(options) {
|
|
1307
1411
|
const cfHome = await resolveCfHome(options);
|
|
1308
|
-
|
|
1309
|
-
|
|
1310
|
-
|
|
1311
|
-
|
|
1312
|
-
|
|
1313
|
-
|
|
1314
|
-
|
|
1315
|
-
|
|
1316
|
-
|
|
1317
|
-
|
|
1318
|
-
|
|
1319
|
-
|
|
1412
|
+
try {
|
|
1413
|
+
const events = [];
|
|
1414
|
+
const eventLimit = createEventLimit(options);
|
|
1415
|
+
const runtimeError = createRuntimeErrorStopWaiter();
|
|
1416
|
+
const session = new LiveTraceSession({
|
|
1417
|
+
target: { ...options.target, cfHomeDir: cfHome.path },
|
|
1418
|
+
onState: (event) => {
|
|
1419
|
+
if (!options.quiet) {
|
|
1420
|
+
writeProgress(event);
|
|
1421
|
+
}
|
|
1422
|
+
runtimeError.report(event);
|
|
1423
|
+
},
|
|
1424
|
+
onLog: (message) => {
|
|
1425
|
+
if (!options.quiet) {
|
|
1426
|
+
writeLog(message);
|
|
1427
|
+
}
|
|
1428
|
+
},
|
|
1429
|
+
onEvents: (batch) => {
|
|
1430
|
+
handleEvents(batch, options, events);
|
|
1431
|
+
eventLimit.check(events.length);
|
|
1320
1432
|
}
|
|
1321
|
-
}
|
|
1322
|
-
|
|
1323
|
-
|
|
1324
|
-
|
|
1433
|
+
});
|
|
1434
|
+
await runUntilStopped(session, options, eventLimit, runtimeError);
|
|
1435
|
+
if (options.format === "json") {
|
|
1436
|
+
writeJson({ events });
|
|
1325
1437
|
}
|
|
1326
|
-
}
|
|
1327
|
-
|
|
1328
|
-
if (options.format === "json") {
|
|
1329
|
-
writeJson({ events });
|
|
1438
|
+
} finally {
|
|
1439
|
+
await cfHome.dispose();
|
|
1330
1440
|
}
|
|
1331
|
-
await cfHome.dispose();
|
|
1332
1441
|
}
|
|
1333
1442
|
function handleEvents(batch, options, events) {
|
|
1334
1443
|
for (const event of batch) {
|
|
@@ -1341,30 +1450,46 @@ function handleEvents(batch, options, events) {
|
|
|
1341
1450
|
}
|
|
1342
1451
|
}
|
|
1343
1452
|
}
|
|
1344
|
-
async function runUntilStopped(session, options, eventLimit) {
|
|
1453
|
+
async function runUntilStopped(session, options, eventLimit, runtimeError) {
|
|
1345
1454
|
const abort = createAbortPromise();
|
|
1455
|
+
const duration = createDurationStopWaiter(options.limits.durationMs);
|
|
1346
1456
|
let stopReason = "user";
|
|
1457
|
+
let failed = false;
|
|
1347
1458
|
try {
|
|
1348
1459
|
await session.start(options.trace);
|
|
1349
|
-
stopReason = await waitForStop(
|
|
1460
|
+
stopReason = await waitForStop([abort, eventLimit, duration, runtimeError]);
|
|
1461
|
+
} catch (error) {
|
|
1462
|
+
failed = true;
|
|
1463
|
+
throw error;
|
|
1350
1464
|
} finally {
|
|
1351
1465
|
abort.cleanup();
|
|
1352
|
-
|
|
1466
|
+
duration.cleanup();
|
|
1467
|
+
eventLimit.cleanup();
|
|
1468
|
+
runtimeError.cleanup();
|
|
1469
|
+
await session.stop({ uninstallRuntimeHook: options.uninstallOnExit, reason: failed ? "error" : stopReason });
|
|
1353
1470
|
}
|
|
1354
1471
|
}
|
|
1355
|
-
async function waitForStop(
|
|
1356
|
-
|
|
1357
|
-
if (options.limits.durationMs !== void 0) {
|
|
1358
|
-
waits.push(waitForDuration(options.limits.durationMs));
|
|
1359
|
-
}
|
|
1360
|
-
return await Promise.race(waits);
|
|
1472
|
+
async function waitForStop(waiters) {
|
|
1473
|
+
return await Promise.race(waiters.map((waiter) => waiter.promise));
|
|
1361
1474
|
}
|
|
1362
|
-
function
|
|
1363
|
-
|
|
1364
|
-
|
|
1475
|
+
function createDurationStopWaiter(durationMs) {
|
|
1476
|
+
if (durationMs === void 0) {
|
|
1477
|
+
return createNeverStopWaiter();
|
|
1478
|
+
}
|
|
1479
|
+
let timer;
|
|
1480
|
+
const promise = new Promise((resolve) => {
|
|
1481
|
+
timer = setTimeout(() => {
|
|
1365
1482
|
resolve("duration");
|
|
1366
1483
|
}, durationMs);
|
|
1367
1484
|
});
|
|
1485
|
+
return {
|
|
1486
|
+
promise,
|
|
1487
|
+
cleanup: () => {
|
|
1488
|
+
if (timer !== void 0) {
|
|
1489
|
+
clearTimeout(timer);
|
|
1490
|
+
}
|
|
1491
|
+
}
|
|
1492
|
+
};
|
|
1368
1493
|
}
|
|
1369
1494
|
function createAbortPromise() {
|
|
1370
1495
|
let resolveStop = () => {
|
|
@@ -1386,12 +1511,50 @@ function createAbortPromise() {
|
|
|
1386
1511
|
}
|
|
1387
1512
|
};
|
|
1388
1513
|
}
|
|
1514
|
+
function createNeverStopWaiter() {
|
|
1515
|
+
return {
|
|
1516
|
+
promise: new Promise(() => {
|
|
1517
|
+
return;
|
|
1518
|
+
}),
|
|
1519
|
+
cleanup: () => {
|
|
1520
|
+
return;
|
|
1521
|
+
}
|
|
1522
|
+
};
|
|
1523
|
+
}
|
|
1524
|
+
function createRuntimeErrorStopWaiter() {
|
|
1525
|
+
let hasStreamed = false;
|
|
1526
|
+
let settled = false;
|
|
1527
|
+
let rejectStop = () => {
|
|
1528
|
+
return;
|
|
1529
|
+
};
|
|
1530
|
+
const promise = new Promise((_resolve, reject) => {
|
|
1531
|
+
rejectStop = reject;
|
|
1532
|
+
});
|
|
1533
|
+
promise.catch(() => {
|
|
1534
|
+
return;
|
|
1535
|
+
});
|
|
1536
|
+
return {
|
|
1537
|
+
promise,
|
|
1538
|
+
report: (event) => {
|
|
1539
|
+
if (event.state === "streaming") {
|
|
1540
|
+
hasStreamed = true;
|
|
1541
|
+
return;
|
|
1542
|
+
}
|
|
1543
|
+
if (event.state !== "error" || !hasStreamed || settled) {
|
|
1544
|
+
return;
|
|
1545
|
+
}
|
|
1546
|
+
settled = true;
|
|
1547
|
+
rejectStop(new Error(event.message));
|
|
1548
|
+
},
|
|
1549
|
+
cleanup: () => {
|
|
1550
|
+
settled = true;
|
|
1551
|
+
}
|
|
1552
|
+
};
|
|
1553
|
+
}
|
|
1389
1554
|
function createEventLimit(options) {
|
|
1390
1555
|
if (options.limits.maxEvents === void 0) {
|
|
1391
1556
|
return {
|
|
1392
|
-
|
|
1393
|
-
return;
|
|
1394
|
-
}),
|
|
1557
|
+
...createNeverStopWaiter(),
|
|
1395
1558
|
check: () => {
|
|
1396
1559
|
return;
|
|
1397
1560
|
}
|
|
@@ -1409,6 +1572,9 @@ function createEventLimit(options) {
|
|
|
1409
1572
|
if (options.limits.maxEvents !== void 0 && count >= options.limits.maxEvents) {
|
|
1410
1573
|
resolveLimit("max-events");
|
|
1411
1574
|
}
|
|
1575
|
+
},
|
|
1576
|
+
cleanup: () => {
|
|
1577
|
+
return;
|
|
1412
1578
|
}
|
|
1413
1579
|
};
|
|
1414
1580
|
}
|
|
@@ -1429,5 +1595,15 @@ async function resolveCfHome(options) {
|
|
|
1429
1595
|
}
|
|
1430
1596
|
|
|
1431
1597
|
// src/cli.ts
|
|
1432
|
-
|
|
1598
|
+
try {
|
|
1599
|
+
await main(process4.argv);
|
|
1600
|
+
} catch (error) {
|
|
1601
|
+
process4.stderr.write(`[cf-live-trace] error: ${formatCliError(error)}
|
|
1602
|
+
`);
|
|
1603
|
+
process4.exitCode = 1;
|
|
1604
|
+
}
|
|
1605
|
+
function formatCliError(error) {
|
|
1606
|
+
const message = error instanceof Error ? error.message : String(error);
|
|
1607
|
+
return message.trim().length > 0 ? message.trim() : "Unknown error";
|
|
1608
|
+
}
|
|
1433
1609
|
//# sourceMappingURL=cli.js.map
|