@flanksource/clicky-ui 0.3.47 → 0.3.49
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/README.md +49 -0
- package/dist/comments/CommentSidePanel.cjs +10 -4
- package/dist/comments/CommentSidePanel.cjs.map +1 -1
- package/dist/comments/CommentSidePanel.d.ts +2 -0
- package/dist/comments/CommentSidePanel.d.ts.map +1 -1
- package/dist/comments/CommentSidePanel.js +10 -4
- package/dist/comments/CommentSidePanel.js.map +1 -1
- package/dist/comments/CommentThread.cjs +2 -0
- package/dist/comments/CommentThread.cjs.map +1 -1
- package/dist/comments/CommentThread.d.ts +2 -1
- package/dist/comments/CommentThread.d.ts.map +1 -1
- package/dist/comments/CommentThread.js +2 -0
- package/dist/comments/CommentThread.js.map +1 -1
- package/dist/comments/CommentThreadList.cjs +3 -0
- package/dist/comments/CommentThreadList.cjs.map +1 -1
- package/dist/comments/CommentThreadList.d.ts +3 -1
- package/dist/comments/CommentThreadList.d.ts.map +1 -1
- package/dist/comments/CommentThreadList.js +3 -0
- package/dist/comments/CommentThreadList.js.map +1 -1
- package/dist/data/CodeLine.cjs +4 -2
- package/dist/data/CodeLine.cjs.map +1 -1
- package/dist/data/CodeLine.d.ts.map +1 -1
- package/dist/data/CodeLine.js +4 -2
- package/dist/data/CodeLine.js.map +1 -1
- package/dist/data/DataTable.cjs +18 -8
- package/dist/data/DataTable.cjs.map +1 -1
- package/dist/data/DataTable.d.ts +4 -0
- package/dist/data/DataTable.d.ts.map +1 -1
- package/dist/data/DataTable.js +18 -8
- package/dist/data/DataTable.js.map +1 -1
- package/dist/data/SymbolBadge.cjs +61 -0
- package/dist/data/SymbolBadge.cjs.map +1 -0
- package/dist/data/SymbolBadge.d.ts +21 -0
- package/dist/data/SymbolBadge.d.ts.map +1 -0
- package/dist/data/SymbolBadge.js +61 -0
- package/dist/data/SymbolBadge.js.map +1 -0
- package/dist/data/TaskManager.cjs +183 -159
- package/dist/data/TaskManager.cjs.map +1 -1
- package/dist/data/TaskManager.d.ts +3 -1
- package/dist/data/TaskManager.d.ts.map +1 -1
- package/dist/data/TaskManager.js +185 -161
- package/dist/data/TaskManager.js.map +1 -1
- package/dist/data/TaskManagerButton.cjs +1 -0
- package/dist/data/TaskManagerButton.cjs.map +1 -1
- package/dist/data/TaskManagerButton.js +1 -0
- package/dist/data/TaskManagerButton.js.map +1 -1
- package/dist/data/TaskProgress.cjs +13 -7
- package/dist/data/TaskProgress.cjs.map +1 -1
- package/dist/data/TaskProgress.d.ts +3 -1
- package/dist/data/TaskProgress.d.ts.map +1 -1
- package/dist/data/TaskProgress.js +13 -7
- package/dist/data/TaskProgress.js.map +1 -1
- package/dist/data/test-runner/TestDetailPanel.cjs +26 -12
- package/dist/data/test-runner/TestDetailPanel.cjs.map +1 -1
- package/dist/data/test-runner/TestDetailPanel.d.ts.map +1 -1
- package/dist/data/test-runner/TestDetailPanel.js +27 -13
- package/dist/data/test-runner/TestDetailPanel.js.map +1 -1
- package/dist/data/test-runner/TestRunner.cjs +6 -0
- package/dist/data/test-runner/TestRunner.cjs.map +1 -1
- package/dist/data/test-runner/TestRunner.d.ts +3 -1
- package/dist/data/test-runner/TestRunner.d.ts.map +1 -1
- package/dist/data/test-runner/TestRunner.js +6 -0
- package/dist/data/test-runner/TestRunner.js.map +1 -1
- package/dist/data/test-runner/TestTreeNode.cjs +2 -1
- package/dist/data/test-runner/TestTreeNode.cjs.map +1 -1
- package/dist/data/test-runner/TestTreeNode.d.ts.map +1 -1
- package/dist/data/test-runner/TestTreeNode.js +2 -1
- package/dist/data/test-runner/TestTreeNode.js.map +1 -1
- package/dist/data/test-runner/adapter.cjs +4 -0
- package/dist/data/test-runner/adapter.cjs.map +1 -1
- package/dist/data/test-runner/adapter.d.ts +9 -0
- package/dist/data/test-runner/adapter.d.ts.map +1 -1
- package/dist/data/test-runner/adapter.js +4 -0
- package/dist/data/test-runner/adapter.js.map +1 -1
- package/dist/data/test-runner/context.cjs.map +1 -1
- package/dist/data/test-runner/context.d.ts +2 -0
- package/dist/data/test-runner/context.d.ts.map +1 -1
- package/dist/data/test-runner/context.js.map +1 -1
- package/dist/data/test-runner/index.d.ts +2 -2
- package/dist/data/test-runner/index.d.ts.map +1 -1
- package/dist/data/test-runner/marks.cjs +42 -1
- package/dist/data/test-runner/marks.cjs.map +1 -1
- package/dist/data/test-runner/marks.d.ts +10 -0
- package/dist/data/test-runner/marks.d.ts.map +1 -1
- package/dist/data/test-runner/marks.js +42 -1
- package/dist/data/test-runner/marks.js.map +1 -1
- package/dist/data/traces/ProcessTraceTree.cjs +93 -0
- package/dist/data/traces/ProcessTraceTree.cjs.map +1 -0
- package/dist/data/traces/ProcessTraceTree.d.ts +24 -0
- package/dist/data/traces/ProcessTraceTree.d.ts.map +1 -0
- package/dist/data/traces/ProcessTraceTree.js +93 -0
- package/dist/data/traces/ProcessTraceTree.js.map +1 -0
- package/dist/data/traces/Sparkline.cjs +23 -0
- package/dist/data/traces/Sparkline.cjs.map +1 -0
- package/dist/data/traces/Sparkline.d.ts +13 -0
- package/dist/data/traces/Sparkline.d.ts.map +1 -0
- package/dist/data/traces/Sparkline.js +23 -0
- package/dist/data/traces/Sparkline.js.map +1 -0
- package/dist/data/traces/SqlTraceTable.cjs +104 -0
- package/dist/data/traces/SqlTraceTable.cjs.map +1 -0
- package/dist/data/traces/SqlTraceTable.d.ts +19 -0
- package/dist/data/traces/SqlTraceTable.d.ts.map +1 -0
- package/dist/data/traces/SqlTraceTable.js +104 -0
- package/dist/data/traces/SqlTraceTable.js.map +1 -0
- package/dist/data/traces/TerminalCastPlayer.cjs +162 -0
- package/dist/data/traces/TerminalCastPlayer.cjs.map +1 -0
- package/dist/data/traces/TerminalCastPlayer.d.ts +21 -0
- package/dist/data/traces/TerminalCastPlayer.d.ts.map +1 -0
- package/dist/data/traces/TerminalCastPlayer.js +162 -0
- package/dist/data/traces/TerminalCastPlayer.js.map +1 -0
- package/dist/data/traces/TraceHarView.cjs +15 -0
- package/dist/data/traces/TraceHarView.cjs.map +1 -0
- package/dist/data/traces/TraceHarView.d.ts +13 -0
- package/dist/data/traces/TraceHarView.d.ts.map +1 -0
- package/dist/data/traces/TraceHarView.js +15 -0
- package/dist/data/traces/TraceHarView.js.map +1 -0
- package/dist/data/traces/TraceView.cjs +54 -0
- package/dist/data/traces/TraceView.cjs.map +1 -0
- package/dist/data/traces/TraceView.d.ts +18 -0
- package/dist/data/traces/TraceView.d.ts.map +1 -0
- package/dist/data/traces/TraceView.js +54 -0
- package/dist/data/traces/TraceView.js.map +1 -0
- package/dist/data/traces/cast.cjs +81 -0
- package/dist/data/traces/cast.cjs.map +1 -0
- package/dist/data/traces/cast.d.ts +9 -0
- package/dist/data/traces/cast.d.ts.map +1 -0
- package/dist/data/traces/cast.js +81 -0
- package/dist/data/traces/cast.js.map +1 -0
- package/dist/data/traces/fixtures.d.ts +8 -0
- package/dist/data/traces/fixtures.d.ts.map +1 -0
- package/dist/data/traces/har-adapter.cjs +83 -0
- package/dist/data/traces/har-adapter.cjs.map +1 -0
- package/dist/data/traces/har-adapter.d.ts +13 -0
- package/dist/data/traces/har-adapter.d.ts.map +1 -0
- package/dist/data/traces/har-adapter.js +83 -0
- package/dist/data/traces/har-adapter.js.map +1 -0
- package/dist/data/traces/index.d.ts +12 -0
- package/dist/data/traces/index.d.ts.map +1 -0
- package/dist/data/traces/process-tree.cjs +53 -0
- package/dist/data/traces/process-tree.cjs.map +1 -0
- package/dist/data/traces/process-tree.d.ts +21 -0
- package/dist/data/traces/process-tree.d.ts.map +1 -0
- package/dist/data/traces/process-tree.js +53 -0
- package/dist/data/traces/process-tree.js.map +1 -0
- package/dist/data/traces/sql-trace.cjs +39 -0
- package/dist/data/traces/sql-trace.cjs.map +1 -0
- package/dist/data/traces/sql-trace.d.ts +31 -0
- package/dist/data/traces/sql-trace.d.ts.map +1 -0
- package/dist/data/traces/sql-trace.js +39 -0
- package/dist/data/traces/sql-trace.js.map +1 -0
- package/dist/data/traces/terminal-screen.cjs +270 -0
- package/dist/data/traces/terminal-screen.cjs.map +1 -0
- package/dist/data/traces/terminal-screen.d.ts +45 -0
- package/dist/data/traces/terminal-screen.d.ts.map +1 -0
- package/dist/data/traces/terminal-screen.js +270 -0
- package/dist/data/traces/terminal-screen.js.map +1 -0
- package/dist/data/traces/terminal-timeline.cjs +48 -0
- package/dist/data/traces/terminal-timeline.cjs.map +1 -0
- package/dist/data/traces/terminal-timeline.d.ts +26 -0
- package/dist/data/traces/terminal-timeline.d.ts.map +1 -0
- package/dist/data/traces/terminal-timeline.js +48 -0
- package/dist/data/traces/terminal-timeline.js.map +1 -0
- package/dist/data/traces/types.d.ts +139 -0
- package/dist/data/traces/types.d.ts.map +1 -0
- package/dist/data/verification/VerificationResults.cjs +4 -0
- package/dist/data/verification/VerificationResults.cjs.map +1 -1
- package/dist/data/verification/VerificationResults.d.ts +3 -1
- package/dist/data/verification/VerificationResults.d.ts.map +1 -1
- package/dist/data/verification/VerificationResults.js +4 -0
- package/dist/data/verification/VerificationResults.js.map +1 -1
- package/dist/data/verification/adapterViews.cjs +12 -3
- package/dist/data/verification/adapterViews.cjs.map +1 -1
- package/dist/data/verification/adapterViews.d.ts +4 -1
- package/dist/data/verification/adapterViews.d.ts.map +1 -1
- package/dist/data/verification/adapterViews.js +12 -3
- package/dist/data/verification/adapterViews.js.map +1 -1
- package/dist/data/verification/adapters.cjs +53 -10
- package/dist/data/verification/adapters.cjs.map +1 -1
- package/dist/data/verification/adapters.d.ts +7 -1
- package/dist/data/verification/adapters.d.ts.map +1 -1
- package/dist/data/verification/adapters.js +53 -10
- package/dist/data/verification/adapters.js.map +1 -1
- package/dist/data/verification/index.d.ts +4 -2
- package/dist/data/verification/index.d.ts.map +1 -1
- package/dist/data/verification/stepKind.cjs +217 -0
- package/dist/data/verification/stepKind.cjs.map +1 -0
- package/dist/data/verification/stepKind.d.ts +87 -0
- package/dist/data/verification/stepKind.d.ts.map +1 -0
- package/dist/data/verification/stepKind.js +217 -0
- package/dist/data/verification/stepKind.js.map +1 -0
- package/dist/data/verification/stepKindViews.cjs +111 -0
- package/dist/data/verification/stepKindViews.cjs.map +1 -0
- package/dist/data/verification/stepKindViews.d.ts +18 -0
- package/dist/data/verification/stepKindViews.d.ts.map +1 -0
- package/dist/data/verification/stepKindViews.js +111 -0
- package/dist/data/verification/stepKindViews.js.map +1 -0
- package/dist/data/verification/verifyReportTests.cjs +1 -0
- package/dist/data/verification/verifyReportTests.cjs.map +1 -1
- package/dist/data/verification/verifyReportTests.d.ts +2 -1
- package/dist/data/verification/verifyReportTests.d.ts.map +1 -1
- package/dist/data/verification/verifyReportTests.js +1 -0
- package/dist/data/verification/verifyReportTests.js.map +1 -1
- package/dist/data/version-info.cjs +3 -3
- package/dist/data/version-info.cjs.map +1 -1
- package/dist/data/version-info.js +3 -3
- package/dist/data/version-info.js.map +1 -1
- package/dist/data.cjs +36 -0
- package/dist/data.cjs.map +1 -1
- package/dist/data.d.ts +2 -0
- package/dist/data.d.ts.map +1 -1
- package/dist/data.js +38 -2
- package/dist/data.js.map +1 -1
- package/dist/index.cjs +38 -0
- package/dist/index.cjs.map +1 -1
- package/dist/index.js +40 -2
- package/dist/index.js.map +1 -1
- package/dist/rpc/FilterForm.cjs +9 -0
- package/dist/rpc/FilterForm.cjs.map +1 -1
- package/dist/rpc/FilterForm.d.ts +5 -1
- package/dist/rpc/FilterForm.d.ts.map +1 -1
- package/dist/rpc/FilterForm.js +9 -0
- package/dist/rpc/FilterForm.js.map +1 -1
- package/dist/rpc/OperationArgsForm.cjs +153 -0
- package/dist/rpc/OperationArgsForm.cjs.map +1 -0
- package/dist/rpc/OperationArgsForm.d.ts +16 -0
- package/dist/rpc/OperationArgsForm.d.ts.map +1 -0
- package/dist/rpc/OperationArgsForm.js +153 -0
- package/dist/rpc/OperationArgsForm.js.map +1 -0
- package/dist/rpc/OperationScheduleDialog.cjs +61 -17
- package/dist/rpc/OperationScheduleDialog.cjs.map +1 -1
- package/dist/rpc/OperationScheduleDialog.d.ts +3 -0
- package/dist/rpc/OperationScheduleDialog.d.ts.map +1 -1
- package/dist/rpc/OperationScheduleDialog.js +62 -18
- package/dist/rpc/OperationScheduleDialog.js.map +1 -1
- package/dist/rpc/OperationSchedules.cjs +6 -1
- package/dist/rpc/OperationSchedules.cjs.map +1 -1
- package/dist/rpc/OperationSchedules.d.ts.map +1 -1
- package/dist/rpc/OperationSchedules.js +6 -1
- package/dist/rpc/OperationSchedules.js.map +1 -1
- package/dist/rpc/operation-schedule-model.cjs +0 -7
- package/dist/rpc/operation-schedule-model.cjs.map +1 -1
- package/dist/rpc/operation-schedule-model.d.ts +0 -2
- package/dist/rpc/operation-schedule-model.d.ts.map +1 -1
- package/dist/rpc/operation-schedule-model.js +0 -7
- package/dist/rpc/operation-schedule-model.js.map +1 -1
- package/dist/rpc/operation-schedule-types.d.ts +6 -1
- package/dist/rpc/operation-schedule-types.d.ts.map +1 -1
- package/dist/rpc.cjs +2 -0
- package/dist/rpc.cjs.map +1 -1
- package/dist/rpc.d.ts +1 -0
- package/dist/rpc.d.ts.map +1 -1
- package/dist/rpc.js +2 -0
- package/dist/rpc.js.map +1 -1
- package/dist/styles.css +1 -1
- package/package.json +1 -1
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import { HttpExchangeRow, ProcessNodeRow, ProcessSampleRow, SqlStatementRow, TerminalEvent } from './types.js';
|
|
2
|
+
export declare const httpExchangeRows: HttpExchangeRow[];
|
|
3
|
+
export declare const sqlStatementRows: SqlStatementRow[];
|
|
4
|
+
/** A short build log: colour, a progress line redrawn with a carriage return, a resize, and a settled screen. */
|
|
5
|
+
export declare const terminalEvents: TerminalEvent[];
|
|
6
|
+
export declare const processNodeRows: ProcessNodeRow[];
|
|
7
|
+
export declare const processSampleRows: ProcessSampleRow[];
|
|
8
|
+
//# sourceMappingURL=fixtures.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"fixtures.d.ts","sourceRoot":"","sources":["../../../src/data/traces/fixtures.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,eAAe,EACf,cAAc,EACd,gBAAgB,EAChB,eAAe,EACf,aAAa,EACd,MAAM,SAAS,CAAC;AAEjB,eAAO,MAAM,gBAAgB,EAAE,eAAe,EA8E7C,CAAC;AAEF,eAAO,MAAM,gBAAgB,EAAE,eAAe,EA4D7C,CAAC;AAIF,iHAAiH;AACjH,eAAO,MAAM,cAAc,EAAE,aAAa,EAiBzC,CAAC;AAEF,eAAO,MAAM,eAAe,EAAE,cAAc,EA+D3C,CAAC;AAEF,eAAO,MAAM,iBAAiB,EAAE,gBAAgB,EAQ7C,CAAC"}
|
|
@@ -0,0 +1,83 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
|
|
3
|
+
const format = require("../../lib/format.cjs");
|
|
4
|
+
const REQUEST_BODY_PATH = "request.postData.text";
|
|
5
|
+
const RESPONSE_BODY_PATH = "response.content.text";
|
|
6
|
+
function bodyText(body) {
|
|
7
|
+
if (body === void 0 || body === null) return void 0;
|
|
8
|
+
return typeof body === "string" ? body : JSON.stringify(body, null, 2);
|
|
9
|
+
}
|
|
10
|
+
function mimeTypeOf(body, declared) {
|
|
11
|
+
if (declared) return declared;
|
|
12
|
+
return body !== void 0 && body !== null && typeof body !== "string" ? "application/json" : void 0;
|
|
13
|
+
}
|
|
14
|
+
function headers(list) {
|
|
15
|
+
return list ? { headers: list } : {};
|
|
16
|
+
}
|
|
17
|
+
function requireObject(value, part, row) {
|
|
18
|
+
if (value === void 0 || value === null || typeof value !== "object") {
|
|
19
|
+
throw new Error(`HTTP exchange ${row.method ?? "?"} ${row.url ?? "?"} has no ${part} object`);
|
|
20
|
+
}
|
|
21
|
+
return value;
|
|
22
|
+
}
|
|
23
|
+
function harRequest(request, bodySize) {
|
|
24
|
+
var _a, _b, _c;
|
|
25
|
+
const text = bodyText((_a = request.postData) == null ? void 0 : _a.text);
|
|
26
|
+
return {
|
|
27
|
+
method: request.method,
|
|
28
|
+
url: request.url,
|
|
29
|
+
...request.httpVersion ? { httpVersion: request.httpVersion } : {},
|
|
30
|
+
...headers(request.headers),
|
|
31
|
+
...request.queryString ? { queryString: request.queryString } : {},
|
|
32
|
+
...text !== void 0 ? { postData: { mimeType: mimeTypeOf((_b = request.postData) == null ? void 0 : _b.text, (_c = request.postData) == null ? void 0 : _c.mimeType) ?? "", text } } : {},
|
|
33
|
+
...request.headersSize !== void 0 ? { headersSize: request.headersSize } : {},
|
|
34
|
+
...bodySize !== void 0 ? { bodySize } : {}
|
|
35
|
+
};
|
|
36
|
+
}
|
|
37
|
+
function harResponse(response, text, mimeType, bodySize, truncated) {
|
|
38
|
+
var _a;
|
|
39
|
+
return {
|
|
40
|
+
status: response.status,
|
|
41
|
+
...response.statusText ? { statusText: response.statusText } : {},
|
|
42
|
+
...response.httpVersion ? { httpVersion: response.httpVersion } : {},
|
|
43
|
+
...headers(response.headers),
|
|
44
|
+
content: {
|
|
45
|
+
size: ((_a = response.content) == null ? void 0 : _a.size) ?? bodySize,
|
|
46
|
+
...mimeType ? { mimeType } : {},
|
|
47
|
+
...text !== void 0 ? { text } : {},
|
|
48
|
+
...truncated ? { truncated } : {}
|
|
49
|
+
},
|
|
50
|
+
...response.redirectURL ? { redirectURL: response.redirectURL } : {},
|
|
51
|
+
...response.headersSize !== void 0 ? { headersSize: response.headersSize } : {},
|
|
52
|
+
bodySize
|
|
53
|
+
};
|
|
54
|
+
}
|
|
55
|
+
function tunnelSummary(row) {
|
|
56
|
+
return `Tunnelled CONNECT relayed without decrypting it: ${format.formatBytes(row.bytesIn ?? 0)} in from the server, ${format.formatBytes(row.bytesOut ?? 0)} out from the client.`;
|
|
57
|
+
}
|
|
58
|
+
function exchangeToHarEntry(row, options = {}) {
|
|
59
|
+
var _a, _b, _c, _d;
|
|
60
|
+
const request = requireObject(row.request, "request", row);
|
|
61
|
+
const response = requireObject(row.response, "response", row);
|
|
62
|
+
const cut = new Set(row.truncated ?? []);
|
|
63
|
+
const tunnelled = row.tunnelled === true;
|
|
64
|
+
const responseBody = tunnelled ? tunnelSummary(row) : bodyText((_a = response.content) == null ? void 0 : _a.text);
|
|
65
|
+
const responseMime = tunnelled ? "text/plain" : mimeTypeOf((_b = response.content) == null ? void 0 : _b.text, (_c = response.content) == null ? void 0 : _c.mimeType);
|
|
66
|
+
const responseSize = tunnelled ? row.bytesIn ?? 0 : response.bodySize ?? ((_d = response.content) == null ? void 0 : _d.size) ?? 0;
|
|
67
|
+
return {
|
|
68
|
+
startedDateTime: row.startedAt,
|
|
69
|
+
time: row.durationMs,
|
|
70
|
+
request: harRequest(request, tunnelled ? row.bytesOut ?? 0 : request.bodySize),
|
|
71
|
+
response: harResponse(response, responseBody, responseMime, responseSize, cut.has(RESPONSE_BODY_PATH)),
|
|
72
|
+
...row.timings ? { timings: row.timings } : {},
|
|
73
|
+
...options.id ? { _id: options.id } : {},
|
|
74
|
+
...row.error ? { _error: row.error } : {},
|
|
75
|
+
...row.serverIPAddress ? { serverIPAddress: row.serverIPAddress } : {},
|
|
76
|
+
...tunnelled ? { _tunnelled: true, _bytesIn: row.bytesIn ?? 0, _bytesOut: row.bytesOut ?? 0 } : {},
|
|
77
|
+
...row.comment ? { _comment: row.comment } : {},
|
|
78
|
+
...row.encoding ? { _encoding: row.encoding } : {},
|
|
79
|
+
...cut.has(REQUEST_BODY_PATH) ? { _requestBodyTruncated: true } : {}
|
|
80
|
+
};
|
|
81
|
+
}
|
|
82
|
+
exports.exchangeToHarEntry = exchangeToHarEntry;
|
|
83
|
+
//# sourceMappingURL=har-adapter.cjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"har-adapter.cjs","sources":["../../../src/data/traces/har-adapter.ts"],"sourcesContent":["import { formatBytes } from \"../../lib/format\";\nimport type { HAREntry, HARHeader, HARRequest, HARResponse } from \"../har/types\";\nimport type { HttpExchangeRequest, HttpExchangeResponse, HttpExchangeRow, TraceBodyText } from \"./types\";\n\nconst REQUEST_BODY_PATH = \"request.postData.text\";\nconst RESPONSE_BODY_PATH = \"response.content.text\";\n\nexport type ExchangeToHarEntryOptions = {\n /** Stable per-request id, so an expanded HarPanel row survives a re-render. */\n id?: string;\n};\n\n/** A body as text: stored text verbatim, a body the store parsed into structure as indented JSON. */\nfunction bodyText(body: TraceBodyText | null | undefined): string | undefined {\n if (body === undefined || body === null) return undefined;\n return typeof body === \"string\" ? body : JSON.stringify(body, null, 2);\n}\n\nfunction mimeTypeOf(body: TraceBodyText | null | undefined, declared: string | undefined): string | undefined {\n if (declared) return declared;\n return body !== undefined && body !== null && typeof body !== \"string\" ? \"application/json\" : undefined;\n}\n\nfunction headers(list: HARHeader[] | null | undefined): { headers?: HARHeader[] } {\n return list ? { headers: list } : {};\n}\n\nfunction requireObject<T>(value: T | undefined | null, part: string, row: HttpExchangeRow): T {\n if (value === undefined || value === null || typeof value !== \"object\") {\n throw new Error(`HTTP exchange ${row.method ?? \"?\"} ${row.url ?? \"?\"} has no ${part} object`);\n }\n return value;\n}\n\nfunction harRequest(request: HttpExchangeRequest, bodySize: number | undefined): HARRequest {\n const text = bodyText(request.postData?.text);\n return {\n method: request.method,\n url: request.url,\n ...(request.httpVersion ? { httpVersion: request.httpVersion } : {}),\n ...headers(request.headers),\n ...(request.queryString ? { queryString: request.queryString } : {}),\n ...(text !== undefined\n ? { postData: { mimeType: mimeTypeOf(request.postData?.text, request.postData?.mimeType) ?? \"\", text } }\n : {}),\n ...(request.headersSize !== undefined ? { headersSize: request.headersSize } : {}),\n ...(bodySize !== undefined ? { bodySize } : {}),\n };\n}\n\nfunction harResponse(\n response: HttpExchangeResponse,\n text: string | undefined,\n mimeType: string | undefined,\n bodySize: number,\n truncated: boolean,\n): HARResponse {\n return {\n status: response.status,\n ...(response.statusText ? { statusText: response.statusText } : {}),\n ...(response.httpVersion ? { httpVersion: response.httpVersion } : {}),\n ...headers(response.headers),\n content: {\n size: response.content?.size ?? bodySize,\n ...(mimeType ? { mimeType } : {}),\n ...(text !== undefined ? { text } : {}),\n ...(truncated ? { truncated } : {}),\n },\n ...(response.redirectURL ? { redirectURL: response.redirectURL } : {}),\n ...(response.headersSize !== undefined ? { headersSize: response.headersSize } : {}),\n bodySize,\n };\n}\n\nfunction tunnelSummary(row: HttpExchangeRow): string {\n return `Tunnelled CONNECT relayed without decrypting it: ${formatBytes(row.bytesIn ?? 0)} in from the server, ${formatBytes(row.bytesOut ?? 0)} out from the client.`;\n}\n\n/**\n * Adapts one `http` / `http_proxy` trace row to the HAR entry `HarPanel`\n * renders. A tunnelled CONNECT has no request or response body to show, so its\n * byte counts stand in for the response body and fill the size columns.\n */\nexport function exchangeToHarEntry(row: HttpExchangeRow, options: ExchangeToHarEntryOptions = {}): HAREntry {\n const request = requireObject(row.request, \"request\", row);\n const response = requireObject(row.response, \"response\", row);\n const cut = new Set(row.truncated ?? []);\n const tunnelled = row.tunnelled === true;\n\n const responseBody = tunnelled ? tunnelSummary(row) : bodyText(response.content?.text);\n const responseMime = tunnelled ? \"text/plain\" : mimeTypeOf(response.content?.text, response.content?.mimeType);\n const responseSize = tunnelled ? (row.bytesIn ?? 0) : (response.bodySize ?? response.content?.size ?? 0);\n\n return {\n startedDateTime: row.startedAt,\n time: row.durationMs,\n request: harRequest(request, tunnelled ? (row.bytesOut ?? 0) : request.bodySize),\n response: harResponse(response, responseBody, responseMime, responseSize, cut.has(RESPONSE_BODY_PATH)),\n ...(row.timings ? { timings: row.timings } : {}),\n ...(options.id ? { _id: options.id } : {}),\n ...(row.error ? { _error: row.error } : {}),\n ...(row.serverIPAddress ? { serverIPAddress: row.serverIPAddress } : {}),\n ...(tunnelled ? { _tunnelled: true, _bytesIn: row.bytesIn ?? 0, _bytesOut: row.bytesOut ?? 0 } : {}),\n ...(row.comment ? { _comment: row.comment } : {}),\n ...(row.encoding ? { _encoding: row.encoding } : {}),\n ...(cut.has(REQUEST_BODY_PATH) ? { _requestBodyTruncated: true } : {}),\n };\n}\n"],"names":["formatBytes"],"mappings":"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"}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import { HAREntry } from '../har/types.js';
|
|
2
|
+
import { HttpExchangeRow } from './types.js';
|
|
3
|
+
export type ExchangeToHarEntryOptions = {
|
|
4
|
+
/** Stable per-request id, so an expanded HarPanel row survives a re-render. */
|
|
5
|
+
id?: string;
|
|
6
|
+
};
|
|
7
|
+
/**
|
|
8
|
+
* Adapts one `http` / `http_proxy` trace row to the HAR entry `HarPanel`
|
|
9
|
+
* renders. A tunnelled CONNECT has no request or response body to show, so its
|
|
10
|
+
* byte counts stand in for the response body and fill the size columns.
|
|
11
|
+
*/
|
|
12
|
+
export declare function exchangeToHarEntry(row: HttpExchangeRow, options?: ExchangeToHarEntryOptions): HAREntry;
|
|
13
|
+
//# sourceMappingURL=har-adapter.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"har-adapter.d.ts","sourceRoot":"","sources":["../../../src/data/traces/har-adapter.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,QAAQ,EAAsC,MAAM,cAAc,CAAC;AACjF,OAAO,KAAK,EAA6C,eAAe,EAAiB,MAAM,SAAS,CAAC;AAKzG,MAAM,MAAM,yBAAyB,GAAG;IACtC,+EAA+E;IAC/E,EAAE,CAAC,EAAE,MAAM,CAAC;CACb,CAAC;AAoEF;;;;GAIG;AACH,wBAAgB,kBAAkB,CAAC,GAAG,EAAE,eAAe,EAAE,OAAO,GAAE,yBAA8B,GAAG,QAAQ,CAwB1G"}
|
|
@@ -0,0 +1,83 @@
|
|
|
1
|
+
import { formatBytes } from "../../lib/format.js";
|
|
2
|
+
const REQUEST_BODY_PATH = "request.postData.text";
|
|
3
|
+
const RESPONSE_BODY_PATH = "response.content.text";
|
|
4
|
+
function bodyText(body) {
|
|
5
|
+
if (body === void 0 || body === null) return void 0;
|
|
6
|
+
return typeof body === "string" ? body : JSON.stringify(body, null, 2);
|
|
7
|
+
}
|
|
8
|
+
function mimeTypeOf(body, declared) {
|
|
9
|
+
if (declared) return declared;
|
|
10
|
+
return body !== void 0 && body !== null && typeof body !== "string" ? "application/json" : void 0;
|
|
11
|
+
}
|
|
12
|
+
function headers(list) {
|
|
13
|
+
return list ? { headers: list } : {};
|
|
14
|
+
}
|
|
15
|
+
function requireObject(value, part, row) {
|
|
16
|
+
if (value === void 0 || value === null || typeof value !== "object") {
|
|
17
|
+
throw new Error(`HTTP exchange ${row.method ?? "?"} ${row.url ?? "?"} has no ${part} object`);
|
|
18
|
+
}
|
|
19
|
+
return value;
|
|
20
|
+
}
|
|
21
|
+
function harRequest(request, bodySize) {
|
|
22
|
+
var _a, _b, _c;
|
|
23
|
+
const text = bodyText((_a = request.postData) == null ? void 0 : _a.text);
|
|
24
|
+
return {
|
|
25
|
+
method: request.method,
|
|
26
|
+
url: request.url,
|
|
27
|
+
...request.httpVersion ? { httpVersion: request.httpVersion } : {},
|
|
28
|
+
...headers(request.headers),
|
|
29
|
+
...request.queryString ? { queryString: request.queryString } : {},
|
|
30
|
+
...text !== void 0 ? { postData: { mimeType: mimeTypeOf((_b = request.postData) == null ? void 0 : _b.text, (_c = request.postData) == null ? void 0 : _c.mimeType) ?? "", text } } : {},
|
|
31
|
+
...request.headersSize !== void 0 ? { headersSize: request.headersSize } : {},
|
|
32
|
+
...bodySize !== void 0 ? { bodySize } : {}
|
|
33
|
+
};
|
|
34
|
+
}
|
|
35
|
+
function harResponse(response, text, mimeType, bodySize, truncated) {
|
|
36
|
+
var _a;
|
|
37
|
+
return {
|
|
38
|
+
status: response.status,
|
|
39
|
+
...response.statusText ? { statusText: response.statusText } : {},
|
|
40
|
+
...response.httpVersion ? { httpVersion: response.httpVersion } : {},
|
|
41
|
+
...headers(response.headers),
|
|
42
|
+
content: {
|
|
43
|
+
size: ((_a = response.content) == null ? void 0 : _a.size) ?? bodySize,
|
|
44
|
+
...mimeType ? { mimeType } : {},
|
|
45
|
+
...text !== void 0 ? { text } : {},
|
|
46
|
+
...truncated ? { truncated } : {}
|
|
47
|
+
},
|
|
48
|
+
...response.redirectURL ? { redirectURL: response.redirectURL } : {},
|
|
49
|
+
...response.headersSize !== void 0 ? { headersSize: response.headersSize } : {},
|
|
50
|
+
bodySize
|
|
51
|
+
};
|
|
52
|
+
}
|
|
53
|
+
function tunnelSummary(row) {
|
|
54
|
+
return `Tunnelled CONNECT relayed without decrypting it: ${formatBytes(row.bytesIn ?? 0)} in from the server, ${formatBytes(row.bytesOut ?? 0)} out from the client.`;
|
|
55
|
+
}
|
|
56
|
+
function exchangeToHarEntry(row, options = {}) {
|
|
57
|
+
var _a, _b, _c, _d;
|
|
58
|
+
const request = requireObject(row.request, "request", row);
|
|
59
|
+
const response = requireObject(row.response, "response", row);
|
|
60
|
+
const cut = new Set(row.truncated ?? []);
|
|
61
|
+
const tunnelled = row.tunnelled === true;
|
|
62
|
+
const responseBody = tunnelled ? tunnelSummary(row) : bodyText((_a = response.content) == null ? void 0 : _a.text);
|
|
63
|
+
const responseMime = tunnelled ? "text/plain" : mimeTypeOf((_b = response.content) == null ? void 0 : _b.text, (_c = response.content) == null ? void 0 : _c.mimeType);
|
|
64
|
+
const responseSize = tunnelled ? row.bytesIn ?? 0 : response.bodySize ?? ((_d = response.content) == null ? void 0 : _d.size) ?? 0;
|
|
65
|
+
return {
|
|
66
|
+
startedDateTime: row.startedAt,
|
|
67
|
+
time: row.durationMs,
|
|
68
|
+
request: harRequest(request, tunnelled ? row.bytesOut ?? 0 : request.bodySize),
|
|
69
|
+
response: harResponse(response, responseBody, responseMime, responseSize, cut.has(RESPONSE_BODY_PATH)),
|
|
70
|
+
...row.timings ? { timings: row.timings } : {},
|
|
71
|
+
...options.id ? { _id: options.id } : {},
|
|
72
|
+
...row.error ? { _error: row.error } : {},
|
|
73
|
+
...row.serverIPAddress ? { serverIPAddress: row.serverIPAddress } : {},
|
|
74
|
+
...tunnelled ? { _tunnelled: true, _bytesIn: row.bytesIn ?? 0, _bytesOut: row.bytesOut ?? 0 } : {},
|
|
75
|
+
...row.comment ? { _comment: row.comment } : {},
|
|
76
|
+
...row.encoding ? { _encoding: row.encoding } : {},
|
|
77
|
+
...cut.has(REQUEST_BODY_PATH) ? { _requestBodyTruncated: true } : {}
|
|
78
|
+
};
|
|
79
|
+
}
|
|
80
|
+
export {
|
|
81
|
+
exchangeToHarEntry
|
|
82
|
+
};
|
|
83
|
+
//# sourceMappingURL=har-adapter.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"har-adapter.js","sources":["../../../src/data/traces/har-adapter.ts"],"sourcesContent":["import { formatBytes } from \"../../lib/format\";\nimport type { HAREntry, HARHeader, HARRequest, HARResponse } from \"../har/types\";\nimport type { HttpExchangeRequest, HttpExchangeResponse, HttpExchangeRow, TraceBodyText } from \"./types\";\n\nconst REQUEST_BODY_PATH = \"request.postData.text\";\nconst RESPONSE_BODY_PATH = \"response.content.text\";\n\nexport type ExchangeToHarEntryOptions = {\n /** Stable per-request id, so an expanded HarPanel row survives a re-render. */\n id?: string;\n};\n\n/** A body as text: stored text verbatim, a body the store parsed into structure as indented JSON. */\nfunction bodyText(body: TraceBodyText | null | undefined): string | undefined {\n if (body === undefined || body === null) return undefined;\n return typeof body === \"string\" ? body : JSON.stringify(body, null, 2);\n}\n\nfunction mimeTypeOf(body: TraceBodyText | null | undefined, declared: string | undefined): string | undefined {\n if (declared) return declared;\n return body !== undefined && body !== null && typeof body !== \"string\" ? \"application/json\" : undefined;\n}\n\nfunction headers(list: HARHeader[] | null | undefined): { headers?: HARHeader[] } {\n return list ? { headers: list } : {};\n}\n\nfunction requireObject<T>(value: T | undefined | null, part: string, row: HttpExchangeRow): T {\n if (value === undefined || value === null || typeof value !== \"object\") {\n throw new Error(`HTTP exchange ${row.method ?? \"?\"} ${row.url ?? \"?\"} has no ${part} object`);\n }\n return value;\n}\n\nfunction harRequest(request: HttpExchangeRequest, bodySize: number | undefined): HARRequest {\n const text = bodyText(request.postData?.text);\n return {\n method: request.method,\n url: request.url,\n ...(request.httpVersion ? { httpVersion: request.httpVersion } : {}),\n ...headers(request.headers),\n ...(request.queryString ? { queryString: request.queryString } : {}),\n ...(text !== undefined\n ? { postData: { mimeType: mimeTypeOf(request.postData?.text, request.postData?.mimeType) ?? \"\", text } }\n : {}),\n ...(request.headersSize !== undefined ? { headersSize: request.headersSize } : {}),\n ...(bodySize !== undefined ? { bodySize } : {}),\n };\n}\n\nfunction harResponse(\n response: HttpExchangeResponse,\n text: string | undefined,\n mimeType: string | undefined,\n bodySize: number,\n truncated: boolean,\n): HARResponse {\n return {\n status: response.status,\n ...(response.statusText ? { statusText: response.statusText } : {}),\n ...(response.httpVersion ? { httpVersion: response.httpVersion } : {}),\n ...headers(response.headers),\n content: {\n size: response.content?.size ?? bodySize,\n ...(mimeType ? { mimeType } : {}),\n ...(text !== undefined ? { text } : {}),\n ...(truncated ? { truncated } : {}),\n },\n ...(response.redirectURL ? { redirectURL: response.redirectURL } : {}),\n ...(response.headersSize !== undefined ? { headersSize: response.headersSize } : {}),\n bodySize,\n };\n}\n\nfunction tunnelSummary(row: HttpExchangeRow): string {\n return `Tunnelled CONNECT relayed without decrypting it: ${formatBytes(row.bytesIn ?? 0)} in from the server, ${formatBytes(row.bytesOut ?? 0)} out from the client.`;\n}\n\n/**\n * Adapts one `http` / `http_proxy` trace row to the HAR entry `HarPanel`\n * renders. A tunnelled CONNECT has no request or response body to show, so its\n * byte counts stand in for the response body and fill the size columns.\n */\nexport function exchangeToHarEntry(row: HttpExchangeRow, options: ExchangeToHarEntryOptions = {}): HAREntry {\n const request = requireObject(row.request, \"request\", row);\n const response = requireObject(row.response, \"response\", row);\n const cut = new Set(row.truncated ?? []);\n const tunnelled = row.tunnelled === true;\n\n const responseBody = tunnelled ? tunnelSummary(row) : bodyText(response.content?.text);\n const responseMime = tunnelled ? \"text/plain\" : mimeTypeOf(response.content?.text, response.content?.mimeType);\n const responseSize = tunnelled ? (row.bytesIn ?? 0) : (response.bodySize ?? response.content?.size ?? 0);\n\n return {\n startedDateTime: row.startedAt,\n time: row.durationMs,\n request: harRequest(request, tunnelled ? (row.bytesOut ?? 0) : request.bodySize),\n response: harResponse(response, responseBody, responseMime, responseSize, cut.has(RESPONSE_BODY_PATH)),\n ...(row.timings ? { timings: row.timings } : {}),\n ...(options.id ? { _id: options.id } : {}),\n ...(row.error ? { _error: row.error } : {}),\n ...(row.serverIPAddress ? { serverIPAddress: row.serverIPAddress } : {}),\n ...(tunnelled ? { _tunnelled: true, _bytesIn: row.bytesIn ?? 0, _bytesOut: row.bytesOut ?? 0 } : {}),\n ...(row.comment ? { _comment: row.comment } : {}),\n ...(row.encoding ? { _encoding: row.encoding } : {}),\n ...(cut.has(REQUEST_BODY_PATH) ? { _requestBodyTruncated: true } : {}),\n };\n}\n"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
export { TraceView, type TraceViewProps } from './TraceView.js';
|
|
2
|
+
export { TraceHarView, type TraceHarViewProps } from './TraceHarView.js';
|
|
3
|
+
export { exchangeToHarEntry, type ExchangeToHarEntryOptions } from './har-adapter.js';
|
|
4
|
+
export { SqlTraceTable, type SqlTraceTableProps } from './SqlTraceTable.js';
|
|
5
|
+
export { groupStatements, formatStatementDuration, type SqlDisplayRow } from './sql-trace.js';
|
|
6
|
+
export { TerminalCastPlayer, type TerminalCastPlayerProps } from './TerminalCastPlayer.js';
|
|
7
|
+
export { parseCast } from './cast.js';
|
|
8
|
+
export { ProcessTraceTree, type ProcessTraceTreeProps } from './ProcessTraceTree.js';
|
|
9
|
+
export { buildProcessForest, flattenForest, type ProcessTreeNode } from './process-tree.js';
|
|
10
|
+
export { Sparkline, type SparklineProps } from './Sparkline.js';
|
|
11
|
+
export type { HttpExchangeRequest, HttpExchangeResponse, HttpExchangeRow, ProcessNodeRow, ProcessSampleRow, SqlStatementRow, TerminalEvent, TerminalEventKind, TraceBodyText, TraceRow, } from './types.js';
|
|
12
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/data/traces/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,KAAK,cAAc,EAAE,MAAM,aAAa,CAAC;AAC7D,OAAO,EAAE,YAAY,EAAE,KAAK,iBAAiB,EAAE,MAAM,gBAAgB,CAAC;AACtE,OAAO,EAAE,kBAAkB,EAAE,KAAK,yBAAyB,EAAE,MAAM,eAAe,CAAC;AACnF,OAAO,EAAE,aAAa,EAAE,KAAK,kBAAkB,EAAE,MAAM,iBAAiB,CAAC;AACzE,OAAO,EAAE,eAAe,EAAE,uBAAuB,EAAE,KAAK,aAAa,EAAE,MAAM,aAAa,CAAC;AAC3F,OAAO,EAAE,kBAAkB,EAAE,KAAK,uBAAuB,EAAE,MAAM,sBAAsB,CAAC;AACxF,OAAO,EAAE,SAAS,EAAE,MAAM,QAAQ,CAAC;AACnC,OAAO,EAAE,gBAAgB,EAAE,KAAK,qBAAqB,EAAE,MAAM,oBAAoB,CAAC;AAClF,OAAO,EAAE,kBAAkB,EAAE,aAAa,EAAE,KAAK,eAAe,EAAE,MAAM,gBAAgB,CAAC;AACzF,OAAO,EAAE,SAAS,EAAE,KAAK,cAAc,EAAE,MAAM,aAAa,CAAC;AAC7D,YAAY,EACV,mBAAmB,EACnB,oBAAoB,EACpB,eAAe,EACf,cAAc,EACd,gBAAgB,EAChB,eAAe,EACf,aAAa,EACb,iBAAiB,EACjB,aAAa,EACb,QAAQ,GACT,MAAM,SAAS,CAAC"}
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
|
|
3
|
+
const byStart = (a, b) => Date.parse(a.row.startedAt) - Date.parse(b.row.startedAt) || a.row.pid - b.row.pid;
|
|
4
|
+
function buildProcessForest(rows) {
|
|
5
|
+
const nodes = /* @__PURE__ */ new Map();
|
|
6
|
+
for (const row of rows) {
|
|
7
|
+
if (nodes.has(row.key)) throw new Error(`process tree key "${row.key}" appears twice`);
|
|
8
|
+
nodes.set(row.key, { row, children: [], exited: row.status === "exited" || Boolean(row.exitedAt) });
|
|
9
|
+
}
|
|
10
|
+
const roots = [];
|
|
11
|
+
for (const node of nodes.values()) {
|
|
12
|
+
const parent = node.row.parentKey ? nodes.get(node.row.parentKey) : void 0;
|
|
13
|
+
(parent ? parent.children : roots).push(node);
|
|
14
|
+
}
|
|
15
|
+
roots.sort((a, b) => Number(Boolean(b.row.isRoot)) - Number(Boolean(a.row.isRoot)) || byStart(a, b));
|
|
16
|
+
const reached = flattenForest(roots);
|
|
17
|
+
if (reached.length !== nodes.size) {
|
|
18
|
+
const lost = [...nodes.keys()].filter((key) => !reached.some((node) => node.row.key === key));
|
|
19
|
+
throw new Error(`process tree has a parent cycle among keys ${lost.map((key) => `"${key}"`).join(", ")}`);
|
|
20
|
+
}
|
|
21
|
+
for (const node of nodes.values()) node.children.sort(byStart);
|
|
22
|
+
return roots;
|
|
23
|
+
}
|
|
24
|
+
function flattenForest(roots) {
|
|
25
|
+
const flat = [];
|
|
26
|
+
const visit = (node) => {
|
|
27
|
+
flat.push(node);
|
|
28
|
+
node.children.forEach(visit);
|
|
29
|
+
};
|
|
30
|
+
roots.forEach(visit);
|
|
31
|
+
return flat;
|
|
32
|
+
}
|
|
33
|
+
function cpuSeriesByKey(samples) {
|
|
34
|
+
const byKey = /* @__PURE__ */ new Map();
|
|
35
|
+
for (const sample of samples) byKey.set(sample.key, [...byKey.get(sample.key) ?? [], sample]);
|
|
36
|
+
return new Map(
|
|
37
|
+
[...byKey].map(([key, list]) => [key, list.sort((a, b) => a.tick - b.tick).map((sample) => sample.cpuPercent)])
|
|
38
|
+
);
|
|
39
|
+
}
|
|
40
|
+
function sparklinePoints(values, width, height) {
|
|
41
|
+
if (values.length < 2) return void 0;
|
|
42
|
+
const max = Math.max(...values);
|
|
43
|
+
return values.map((value, index) => {
|
|
44
|
+
const x = index / (values.length - 1) * width;
|
|
45
|
+
const y = max === 0 ? height : height - value / max * height;
|
|
46
|
+
return `${x.toFixed(1)},${y.toFixed(1)}`;
|
|
47
|
+
}).join(" ");
|
|
48
|
+
}
|
|
49
|
+
exports.buildProcessForest = buildProcessForest;
|
|
50
|
+
exports.cpuSeriesByKey = cpuSeriesByKey;
|
|
51
|
+
exports.flattenForest = flattenForest;
|
|
52
|
+
exports.sparklinePoints = sparklinePoints;
|
|
53
|
+
//# sourceMappingURL=process-tree.cjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"process-tree.cjs","sources":["../../../src/data/traces/process-tree.ts"],"sourcesContent":["import type { ProcessNodeRow, ProcessSampleRow } from \"./types\";\n\nexport type ProcessTreeNode = {\n row: ProcessNodeRow;\n children: ProcessTreeNode[];\n /** The process has exited: by its status, or because an exit time was recorded. */\n exited: boolean;\n};\n\nconst byStart = (a: ProcessTreeNode, b: ProcessTreeNode) =>\n Date.parse(a.row.startedAt) - Date.parse(b.row.startedAt) || a.row.pid - b.row.pid;\n\n/**\n * Builds the forest a `process_tree` stream describes: each row under its\n * `parentKey`. A row whose parent was never recorded (the capture began below\n * it) becomes a root. The stream holds each process once, so a repeated key or a\n * parent cycle is a corrupt capture and throws.\n */\nexport function buildProcessForest(rows: ProcessNodeRow[]): ProcessTreeNode[] {\n const nodes = new Map<string, ProcessTreeNode>();\n for (const row of rows) {\n if (nodes.has(row.key)) throw new Error(`process tree key \"${row.key}\" appears twice`);\n nodes.set(row.key, { row, children: [], exited: row.status === \"exited\" || Boolean(row.exitedAt) });\n }\n\n const roots: ProcessTreeNode[] = [];\n for (const node of nodes.values()) {\n const parent = node.row.parentKey ? nodes.get(node.row.parentKey) : undefined;\n (parent ? parent.children : roots).push(node);\n }\n\n roots.sort((a, b) => Number(Boolean(b.row.isRoot)) - Number(Boolean(a.row.isRoot)) || byStart(a, b));\n const reached = flattenForest(roots);\n if (reached.length !== nodes.size) {\n const lost = [...nodes.keys()].filter((key) => !reached.some((node) => node.row.key === key));\n throw new Error(`process tree has a parent cycle among keys ${lost.map((key) => `\"${key}\"`).join(\", \")}`);\n }\n for (const node of nodes.values()) node.children.sort(byStart);\n return roots;\n}\n\n/** The forest depth-first, parents before children. */\nexport function flattenForest(roots: ProcessTreeNode[]): ProcessTreeNode[] {\n const flat: ProcessTreeNode[] = [];\n const visit = (node: ProcessTreeNode) => {\n flat.push(node);\n node.children.forEach(visit);\n };\n roots.forEach(visit);\n return flat;\n}\n\n/** Each process's CPU % over its samples, in tick order. */\nexport function cpuSeriesByKey(samples: ProcessSampleRow[]): Map<string, number[]> {\n const byKey = new Map<string, ProcessSampleRow[]>();\n for (const sample of samples) byKey.set(sample.key, [...(byKey.get(sample.key) ?? []), sample]);\n return new Map(\n [...byKey].map(([key, list]) => [key, list.sort((a, b) => a.tick - b.tick).map((sample) => sample.cpuPercent)]),\n );\n}\n\n/** SVG polyline points for `values` in a `width` x `height` box, zero at the bottom and the maximum at the top. */\nexport function sparklinePoints(values: number[], width: number, height: number): string | undefined {\n if (values.length < 2) return undefined;\n const max = Math.max(...values);\n return values\n .map((value, index) => {\n const x = (index / (values.length - 1)) * width;\n const y = max === 0 ? height : height - (value / max) * height;\n return `${x.toFixed(1)},${y.toFixed(1)}`;\n })\n .join(\" \");\n}\n"],"names":[],"mappings":";;AASA,MAAM,UAAU,CAAC,GAAoB,MACnC,KAAK,MAAM,EAAE,IAAI,SAAS,IAAI,KAAK,MAAM,EAAE,IAAI,SAAS,KAAK,EAAE,IAAI,MAAM,EAAE,IAAI;AAQ1E,SAAS,mBAAmB,MAA2C;AAC5E,QAAM,4BAAY,IAAA;AAClB,aAAW,OAAO,MAAM;AACtB,QAAI,MAAM,IAAI,IAAI,GAAG,EAAG,OAAM,IAAI,MAAM,qBAAqB,IAAI,GAAG,iBAAiB;AACrF,UAAM,IAAI,IAAI,KAAK,EAAE,KAAK,UAAU,CAAA,GAAI,QAAQ,IAAI,WAAW,YAAY,QAAQ,IAAI,QAAQ,GAAG;AAAA,EACpG;AAEA,QAAM,QAA2B,CAAA;AACjC,aAAW,QAAQ,MAAM,UAAU;AACjC,UAAM,SAAS,KAAK,IAAI,YAAY,MAAM,IAAI,KAAK,IAAI,SAAS,IAAI;AACpE,KAAC,SAAS,OAAO,WAAW,OAAO,KAAK,IAAI;AAAA,EAC9C;AAEA,QAAM,KAAK,CAAC,GAAG,MAAM,OAAO,QAAQ,EAAE,IAAI,MAAM,CAAC,IAAI,OAAO,QAAQ,EAAE,IAAI,MAAM,CAAC,KAAK,QAAQ,GAAG,CAAC,CAAC;AACnG,QAAM,UAAU,cAAc,KAAK;AACnC,MAAI,QAAQ,WAAW,MAAM,MAAM;AACjC,UAAM,OAAO,CAAC,GAAG,MAAM,KAAA,CAAM,EAAE,OAAO,CAAC,QAAQ,CAAC,QAAQ,KAAK,CAAC,SAAS,KAAK,IAAI,QAAQ,GAAG,CAAC;AAC5F,UAAM,IAAI,MAAM,8CAA8C,KAAK,IAAI,CAAC,QAAQ,IAAI,GAAG,GAAG,EAAE,KAAK,IAAI,CAAC,EAAE;AAAA,EAC1G;AACA,aAAW,QAAQ,MAAM,OAAA,EAAU,MAAK,SAAS,KAAK,OAAO;AAC7D,SAAO;AACT;AAGO,SAAS,cAAc,OAA6C;AACzE,QAAM,OAA0B,CAAA;AAChC,QAAM,QAAQ,CAAC,SAA0B;AACvC,SAAK,KAAK,IAAI;AACd,SAAK,SAAS,QAAQ,KAAK;AAAA,EAC7B;AACA,QAAM,QAAQ,KAAK;AACnB,SAAO;AACT;AAGO,SAAS,eAAe,SAAoD;AACjF,QAAM,4BAAY,IAAA;AAClB,aAAW,UAAU,QAAS,OAAM,IAAI,OAAO,KAAK,CAAC,GAAI,MAAM,IAAI,OAAO,GAAG,KAAK,CAAA,GAAK,MAAM,CAAC;AAC9F,SAAO,IAAI;AAAA,IACT,CAAC,GAAG,KAAK,EAAE,IAAI,CAAC,CAAC,KAAK,IAAI,MAAM,CAAC,KAAK,KAAK,KAAK,CAAC,GAAG,MAAM,EAAE,OAAO,EAAE,IAAI,EAAE,IAAI,CAAC,WAAW,OAAO,UAAU,CAAC,CAAC;AAAA,EAAA;AAElH;AAGO,SAAS,gBAAgB,QAAkB,OAAe,QAAoC;AACnG,MAAI,OAAO,SAAS,EAAG,QAAO;AAC9B,QAAM,MAAM,KAAK,IAAI,GAAG,MAAM;AAC9B,SAAO,OACJ,IAAI,CAAC,OAAO,UAAU;AACrB,UAAM,IAAK,SAAS,OAAO,SAAS,KAAM;AAC1C,UAAM,IAAI,QAAQ,IAAI,SAAS,SAAU,QAAQ,MAAO;AACxD,WAAO,GAAG,EAAE,QAAQ,CAAC,CAAC,IAAI,EAAE,QAAQ,CAAC,CAAC;AAAA,EACxC,CAAC,EACA,KAAK,GAAG;AACb;;;;;"}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import { ProcessNodeRow, ProcessSampleRow } from './types.js';
|
|
2
|
+
export type ProcessTreeNode = {
|
|
3
|
+
row: ProcessNodeRow;
|
|
4
|
+
children: ProcessTreeNode[];
|
|
5
|
+
/** The process has exited: by its status, or because an exit time was recorded. */
|
|
6
|
+
exited: boolean;
|
|
7
|
+
};
|
|
8
|
+
/**
|
|
9
|
+
* Builds the forest a `process_tree` stream describes: each row under its
|
|
10
|
+
* `parentKey`. A row whose parent was never recorded (the capture began below
|
|
11
|
+
* it) becomes a root. The stream holds each process once, so a repeated key or a
|
|
12
|
+
* parent cycle is a corrupt capture and throws.
|
|
13
|
+
*/
|
|
14
|
+
export declare function buildProcessForest(rows: ProcessNodeRow[]): ProcessTreeNode[];
|
|
15
|
+
/** The forest depth-first, parents before children. */
|
|
16
|
+
export declare function flattenForest(roots: ProcessTreeNode[]): ProcessTreeNode[];
|
|
17
|
+
/** Each process's CPU % over its samples, in tick order. */
|
|
18
|
+
export declare function cpuSeriesByKey(samples: ProcessSampleRow[]): Map<string, number[]>;
|
|
19
|
+
/** SVG polyline points for `values` in a `width` x `height` box, zero at the bottom and the maximum at the top. */
|
|
20
|
+
export declare function sparklinePoints(values: number[], width: number, height: number): string | undefined;
|
|
21
|
+
//# sourceMappingURL=process-tree.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"process-tree.d.ts","sourceRoot":"","sources":["../../../src/data/traces/process-tree.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,cAAc,EAAE,gBAAgB,EAAE,MAAM,SAAS,CAAC;AAEhE,MAAM,MAAM,eAAe,GAAG;IAC5B,GAAG,EAAE,cAAc,CAAC;IACpB,QAAQ,EAAE,eAAe,EAAE,CAAC;IAC5B,mFAAmF;IACnF,MAAM,EAAE,OAAO,CAAC;CACjB,CAAC;AAKF;;;;;GAKG;AACH,wBAAgB,kBAAkB,CAAC,IAAI,EAAE,cAAc,EAAE,GAAG,eAAe,EAAE,CAqB5E;AAED,uDAAuD;AACvD,wBAAgB,aAAa,CAAC,KAAK,EAAE,eAAe,EAAE,GAAG,eAAe,EAAE,CAQzE;AAED,4DAA4D;AAC5D,wBAAgB,cAAc,CAAC,OAAO,EAAE,gBAAgB,EAAE,GAAG,GAAG,CAAC,MAAM,EAAE,MAAM,EAAE,CAAC,CAMjF;AAED,mHAAmH;AACnH,wBAAgB,eAAe,CAAC,MAAM,EAAE,MAAM,EAAE,EAAE,KAAK,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,GAAG,MAAM,GAAG,SAAS,CAUnG"}
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
const byStart = (a, b) => Date.parse(a.row.startedAt) - Date.parse(b.row.startedAt) || a.row.pid - b.row.pid;
|
|
2
|
+
function buildProcessForest(rows) {
|
|
3
|
+
const nodes = /* @__PURE__ */ new Map();
|
|
4
|
+
for (const row of rows) {
|
|
5
|
+
if (nodes.has(row.key)) throw new Error(`process tree key "${row.key}" appears twice`);
|
|
6
|
+
nodes.set(row.key, { row, children: [], exited: row.status === "exited" || Boolean(row.exitedAt) });
|
|
7
|
+
}
|
|
8
|
+
const roots = [];
|
|
9
|
+
for (const node of nodes.values()) {
|
|
10
|
+
const parent = node.row.parentKey ? nodes.get(node.row.parentKey) : void 0;
|
|
11
|
+
(parent ? parent.children : roots).push(node);
|
|
12
|
+
}
|
|
13
|
+
roots.sort((a, b) => Number(Boolean(b.row.isRoot)) - Number(Boolean(a.row.isRoot)) || byStart(a, b));
|
|
14
|
+
const reached = flattenForest(roots);
|
|
15
|
+
if (reached.length !== nodes.size) {
|
|
16
|
+
const lost = [...nodes.keys()].filter((key) => !reached.some((node) => node.row.key === key));
|
|
17
|
+
throw new Error(`process tree has a parent cycle among keys ${lost.map((key) => `"${key}"`).join(", ")}`);
|
|
18
|
+
}
|
|
19
|
+
for (const node of nodes.values()) node.children.sort(byStart);
|
|
20
|
+
return roots;
|
|
21
|
+
}
|
|
22
|
+
function flattenForest(roots) {
|
|
23
|
+
const flat = [];
|
|
24
|
+
const visit = (node) => {
|
|
25
|
+
flat.push(node);
|
|
26
|
+
node.children.forEach(visit);
|
|
27
|
+
};
|
|
28
|
+
roots.forEach(visit);
|
|
29
|
+
return flat;
|
|
30
|
+
}
|
|
31
|
+
function cpuSeriesByKey(samples) {
|
|
32
|
+
const byKey = /* @__PURE__ */ new Map();
|
|
33
|
+
for (const sample of samples) byKey.set(sample.key, [...byKey.get(sample.key) ?? [], sample]);
|
|
34
|
+
return new Map(
|
|
35
|
+
[...byKey].map(([key, list]) => [key, list.sort((a, b) => a.tick - b.tick).map((sample) => sample.cpuPercent)])
|
|
36
|
+
);
|
|
37
|
+
}
|
|
38
|
+
function sparklinePoints(values, width, height) {
|
|
39
|
+
if (values.length < 2) return void 0;
|
|
40
|
+
const max = Math.max(...values);
|
|
41
|
+
return values.map((value, index) => {
|
|
42
|
+
const x = index / (values.length - 1) * width;
|
|
43
|
+
const y = max === 0 ? height : height - value / max * height;
|
|
44
|
+
return `${x.toFixed(1)},${y.toFixed(1)}`;
|
|
45
|
+
}).join(" ");
|
|
46
|
+
}
|
|
47
|
+
export {
|
|
48
|
+
buildProcessForest,
|
|
49
|
+
cpuSeriesByKey,
|
|
50
|
+
flattenForest,
|
|
51
|
+
sparklinePoints
|
|
52
|
+
};
|
|
53
|
+
//# sourceMappingURL=process-tree.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"process-tree.js","sources":["../../../src/data/traces/process-tree.ts"],"sourcesContent":["import type { ProcessNodeRow, ProcessSampleRow } from \"./types\";\n\nexport type ProcessTreeNode = {\n row: ProcessNodeRow;\n children: ProcessTreeNode[];\n /** The process has exited: by its status, or because an exit time was recorded. */\n exited: boolean;\n};\n\nconst byStart = (a: ProcessTreeNode, b: ProcessTreeNode) =>\n Date.parse(a.row.startedAt) - Date.parse(b.row.startedAt) || a.row.pid - b.row.pid;\n\n/**\n * Builds the forest a `process_tree` stream describes: each row under its\n * `parentKey`. A row whose parent was never recorded (the capture began below\n * it) becomes a root. The stream holds each process once, so a repeated key or a\n * parent cycle is a corrupt capture and throws.\n */\nexport function buildProcessForest(rows: ProcessNodeRow[]): ProcessTreeNode[] {\n const nodes = new Map<string, ProcessTreeNode>();\n for (const row of rows) {\n if (nodes.has(row.key)) throw new Error(`process tree key \"${row.key}\" appears twice`);\n nodes.set(row.key, { row, children: [], exited: row.status === \"exited\" || Boolean(row.exitedAt) });\n }\n\n const roots: ProcessTreeNode[] = [];\n for (const node of nodes.values()) {\n const parent = node.row.parentKey ? nodes.get(node.row.parentKey) : undefined;\n (parent ? parent.children : roots).push(node);\n }\n\n roots.sort((a, b) => Number(Boolean(b.row.isRoot)) - Number(Boolean(a.row.isRoot)) || byStart(a, b));\n const reached = flattenForest(roots);\n if (reached.length !== nodes.size) {\n const lost = [...nodes.keys()].filter((key) => !reached.some((node) => node.row.key === key));\n throw new Error(`process tree has a parent cycle among keys ${lost.map((key) => `\"${key}\"`).join(\", \")}`);\n }\n for (const node of nodes.values()) node.children.sort(byStart);\n return roots;\n}\n\n/** The forest depth-first, parents before children. */\nexport function flattenForest(roots: ProcessTreeNode[]): ProcessTreeNode[] {\n const flat: ProcessTreeNode[] = [];\n const visit = (node: ProcessTreeNode) => {\n flat.push(node);\n node.children.forEach(visit);\n };\n roots.forEach(visit);\n return flat;\n}\n\n/** Each process's CPU % over its samples, in tick order. */\nexport function cpuSeriesByKey(samples: ProcessSampleRow[]): Map<string, number[]> {\n const byKey = new Map<string, ProcessSampleRow[]>();\n for (const sample of samples) byKey.set(sample.key, [...(byKey.get(sample.key) ?? []), sample]);\n return new Map(\n [...byKey].map(([key, list]) => [key, list.sort((a, b) => a.tick - b.tick).map((sample) => sample.cpuPercent)]),\n );\n}\n\n/** SVG polyline points for `values` in a `width` x `height` box, zero at the bottom and the maximum at the top. */\nexport function sparklinePoints(values: number[], width: number, height: number): string | undefined {\n if (values.length < 2) return undefined;\n const max = Math.max(...values);\n return values\n .map((value, index) => {\n const x = (index / (values.length - 1)) * width;\n const y = max === 0 ? height : height - (value / max) * height;\n return `${x.toFixed(1)},${y.toFixed(1)}`;\n })\n .join(\" \");\n}\n"],"names":[],"mappings":"AASA,MAAM,UAAU,CAAC,GAAoB,MACnC,KAAK,MAAM,EAAE,IAAI,SAAS,IAAI,KAAK,MAAM,EAAE,IAAI,SAAS,KAAK,EAAE,IAAI,MAAM,EAAE,IAAI;AAQ1E,SAAS,mBAAmB,MAA2C;AAC5E,QAAM,4BAAY,IAAA;AAClB,aAAW,OAAO,MAAM;AACtB,QAAI,MAAM,IAAI,IAAI,GAAG,EAAG,OAAM,IAAI,MAAM,qBAAqB,IAAI,GAAG,iBAAiB;AACrF,UAAM,IAAI,IAAI,KAAK,EAAE,KAAK,UAAU,CAAA,GAAI,QAAQ,IAAI,WAAW,YAAY,QAAQ,IAAI,QAAQ,GAAG;AAAA,EACpG;AAEA,QAAM,QAA2B,CAAA;AACjC,aAAW,QAAQ,MAAM,UAAU;AACjC,UAAM,SAAS,KAAK,IAAI,YAAY,MAAM,IAAI,KAAK,IAAI,SAAS,IAAI;AACpE,KAAC,SAAS,OAAO,WAAW,OAAO,KAAK,IAAI;AAAA,EAC9C;AAEA,QAAM,KAAK,CAAC,GAAG,MAAM,OAAO,QAAQ,EAAE,IAAI,MAAM,CAAC,IAAI,OAAO,QAAQ,EAAE,IAAI,MAAM,CAAC,KAAK,QAAQ,GAAG,CAAC,CAAC;AACnG,QAAM,UAAU,cAAc,KAAK;AACnC,MAAI,QAAQ,WAAW,MAAM,MAAM;AACjC,UAAM,OAAO,CAAC,GAAG,MAAM,KAAA,CAAM,EAAE,OAAO,CAAC,QAAQ,CAAC,QAAQ,KAAK,CAAC,SAAS,KAAK,IAAI,QAAQ,GAAG,CAAC;AAC5F,UAAM,IAAI,MAAM,8CAA8C,KAAK,IAAI,CAAC,QAAQ,IAAI,GAAG,GAAG,EAAE,KAAK,IAAI,CAAC,EAAE;AAAA,EAC1G;AACA,aAAW,QAAQ,MAAM,OAAA,EAAU,MAAK,SAAS,KAAK,OAAO;AAC7D,SAAO;AACT;AAGO,SAAS,cAAc,OAA6C;AACzE,QAAM,OAA0B,CAAA;AAChC,QAAM,QAAQ,CAAC,SAA0B;AACvC,SAAK,KAAK,IAAI;AACd,SAAK,SAAS,QAAQ,KAAK;AAAA,EAC7B;AACA,QAAM,QAAQ,KAAK;AACnB,SAAO;AACT;AAGO,SAAS,eAAe,SAAoD;AACjF,QAAM,4BAAY,IAAA;AAClB,aAAW,UAAU,QAAS,OAAM,IAAI,OAAO,KAAK,CAAC,GAAI,MAAM,IAAI,OAAO,GAAG,KAAK,CAAA,GAAK,MAAM,CAAC;AAC9F,SAAO,IAAI;AAAA,IACT,CAAC,GAAG,KAAK,EAAE,IAAI,CAAC,CAAC,KAAK,IAAI,MAAM,CAAC,KAAK,KAAK,KAAK,CAAC,GAAG,MAAM,EAAE,OAAO,EAAE,IAAI,EAAE,IAAI,CAAC,WAAW,OAAO,UAAU,CAAC,CAAC;AAAA,EAAA;AAElH;AAGO,SAAS,gBAAgB,QAAkB,OAAe,QAAoC;AACnG,MAAI,OAAO,SAAS,EAAG,QAAO;AAC9B,QAAM,MAAM,KAAK,IAAI,GAAG,MAAM;AAC9B,SAAO,OACJ,IAAI,CAAC,OAAO,UAAU;AACrB,UAAM,IAAK,SAAS,OAAO,SAAS,KAAM;AAC1C,UAAM,IAAI,QAAQ,IAAI,SAAS,SAAU,QAAQ,MAAO;AACxD,WAAO,GAAG,EAAE,QAAQ,CAAC,CAAC,IAAI,EAAE,QAAQ,CAAC,CAAC;AAAA,EACxC,CAAC,EACA,KAAK,GAAG;AACb;"}
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
|
|
3
|
+
const format = require("../../lib/format.cjs");
|
|
4
|
+
function formatStatementDuration(ms) {
|
|
5
|
+
if (ms >= 100) return format.formatDuration(ms);
|
|
6
|
+
return `${Number(ms.toFixed(1))} ms`;
|
|
7
|
+
}
|
|
8
|
+
function sumKnownRows(statements) {
|
|
9
|
+
const known = statements.filter((statement) => statement.rows >= 0);
|
|
10
|
+
return known.length === 0 ? -1 : known.reduce((total, statement) => total + statement.rows, 0);
|
|
11
|
+
}
|
|
12
|
+
function toDisplayRow(id, statements) {
|
|
13
|
+
var _a;
|
|
14
|
+
const [first] = statements;
|
|
15
|
+
return {
|
|
16
|
+
id,
|
|
17
|
+
startedAt: first.startedAt,
|
|
18
|
+
op: first.op,
|
|
19
|
+
tables: first.tables,
|
|
20
|
+
sql: first.sql,
|
|
21
|
+
durationMs: statements.reduce((total, statement) => total + statement.durationMs, 0),
|
|
22
|
+
rows: sumKnownRows(statements),
|
|
23
|
+
error: ((_a = statements.find((statement) => statement.error)) == null ? void 0 : _a.error) ?? "",
|
|
24
|
+
failed: statements.filter((statement) => statement.error).length,
|
|
25
|
+
count: statements.length,
|
|
26
|
+
occurrences: statements
|
|
27
|
+
};
|
|
28
|
+
}
|
|
29
|
+
function groupStatements(statements, options) {
|
|
30
|
+
const groups = /* @__PURE__ */ new Map();
|
|
31
|
+
statements.forEach((statement, index) => {
|
|
32
|
+
const key = options.group && statement.repeatKey ? `repeat:${statement.repeatKey}` : `row:${index}`;
|
|
33
|
+
groups.set(key, [...groups.get(key) ?? [], statement]);
|
|
34
|
+
});
|
|
35
|
+
return [...groups].map(([key, members]) => toDisplayRow(key, members));
|
|
36
|
+
}
|
|
37
|
+
exports.formatStatementDuration = formatStatementDuration;
|
|
38
|
+
exports.groupStatements = groupStatements;
|
|
39
|
+
//# sourceMappingURL=sql-trace.cjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"sql-trace.cjs","sources":["../../../src/data/traces/sql-trace.ts"],"sourcesContent":["import { formatDuration } from \"../../lib/format\";\nimport type { SqlStatementRow } from \"./types\";\n\n/** One table row: a statement, or every execution of statements sharing a `repeatKey`. */\nexport type SqlDisplayRow = {\n id: string;\n startedAt: string;\n op: string;\n tables: string[];\n sql: string;\n /** Total of the executions. */\n durationMs: number;\n /** Rows the executions returned, or -1 when no driver could tell. */\n rows: number;\n /** The first error among the executions, or \"\". */\n error: string;\n /** How many executions returned an error. */\n failed: number;\n /** How many executions the row stands for. */\n count: number;\n occurrences: SqlStatementRow[];\n};\n\n/** A statement's duration: sub-100ms values keep a decimal (a fast query is 0.9 ms, not 1 ms), longer ones read as elsewhere. */\nexport function formatStatementDuration(ms: number): string {\n if (ms >= 100) return formatDuration(ms);\n return `${Number(ms.toFixed(1))} ms`;\n}\n\nfunction sumKnownRows(statements: SqlStatementRow[]): number {\n const known = statements.filter((statement) => statement.rows >= 0);\n return known.length === 0 ? -1 : known.reduce((total, statement) => total + statement.rows, 0);\n}\n\nfunction toDisplayRow(id: string, statements: SqlStatementRow[]): SqlDisplayRow {\n const [first] = statements as [SqlStatementRow, ...SqlStatementRow[]];\n return {\n id,\n startedAt: first.startedAt,\n op: first.op,\n tables: first.tables,\n sql: first.sql,\n durationMs: statements.reduce((total, statement) => total + statement.durationMs, 0),\n rows: sumKnownRows(statements),\n error: statements.find((statement) => statement.error)?.error ?? \"\",\n failed: statements.filter((statement) => statement.error).length,\n count: statements.length,\n occurrences: statements,\n };\n}\n\n/**\n * Turns statements into table rows. With `group`, statements sharing a\n * non-empty `repeatKey` (the same statement run with different values) become\n * one row, placed where the first of them ran.\n */\nexport function groupStatements(statements: SqlStatementRow[], options: { group: boolean }): SqlDisplayRow[] {\n const groups = new Map<string, SqlStatementRow[]>();\n statements.forEach((statement, index) => {\n const key = options.group && statement.repeatKey ? `repeat:${statement.repeatKey}` : `row:${index}`;\n groups.set(key, [...(groups.get(key) ?? []), statement]);\n });\n return [...groups].map(([key, members]) => toDisplayRow(key, members));\n}\n"],"names":["formatDuration"],"mappings":";;;AAwBO,SAAS,wBAAwB,IAAoB;AAC1D,MAAI,MAAM,IAAK,QAAOA,OAAAA,eAAe,EAAE;AACvC,SAAO,GAAG,OAAO,GAAG,QAAQ,CAAC,CAAC,CAAC;AACjC;AAEA,SAAS,aAAa,YAAuC;AAC3D,QAAM,QAAQ,WAAW,OAAO,CAAC,cAAc,UAAU,QAAQ,CAAC;AAClE,SAAO,MAAM,WAAW,IAAI,KAAK,MAAM,OAAO,CAAC,OAAO,cAAc,QAAQ,UAAU,MAAM,CAAC;AAC/F;AAEA,SAAS,aAAa,IAAY,YAA8C;;AAC9E,QAAM,CAAC,KAAK,IAAI;AAChB,SAAO;AAAA,IACL;AAAA,IACA,WAAW,MAAM;AAAA,IACjB,IAAI,MAAM;AAAA,IACV,QAAQ,MAAM;AAAA,IACd,KAAK,MAAM;AAAA,IACX,YAAY,WAAW,OAAO,CAAC,OAAO,cAAc,QAAQ,UAAU,YAAY,CAAC;AAAA,IACnF,MAAM,aAAa,UAAU;AAAA,IAC7B,SAAO,gBAAW,KAAK,CAAC,cAAc,UAAU,KAAK,MAA9C,mBAAiD,UAAS;AAAA,IACjE,QAAQ,WAAW,OAAO,CAAC,cAAc,UAAU,KAAK,EAAE;AAAA,IAC1D,OAAO,WAAW;AAAA,IAClB,aAAa;AAAA,EAAA;AAEjB;AAOO,SAAS,gBAAgB,YAA+B,SAA8C;AAC3G,QAAM,6BAAa,IAAA;AACnB,aAAW,QAAQ,CAAC,WAAW,UAAU;AACvC,UAAM,MAAM,QAAQ,SAAS,UAAU,YAAY,UAAU,UAAU,SAAS,KAAK,OAAO,KAAK;AACjG,WAAO,IAAI,KAAK,CAAC,GAAI,OAAO,IAAI,GAAG,KAAK,IAAK,SAAS,CAAC;AAAA,EACzD,CAAC;AACD,SAAO,CAAC,GAAG,MAAM,EAAE,IAAI,CAAC,CAAC,KAAK,OAAO,MAAM,aAAa,KAAK,OAAO,CAAC;AACvE;;;"}
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
import { SqlStatementRow } from './types.js';
|
|
2
|
+
/** One table row: a statement, or every execution of statements sharing a `repeatKey`. */
|
|
3
|
+
export type SqlDisplayRow = {
|
|
4
|
+
id: string;
|
|
5
|
+
startedAt: string;
|
|
6
|
+
op: string;
|
|
7
|
+
tables: string[];
|
|
8
|
+
sql: string;
|
|
9
|
+
/** Total of the executions. */
|
|
10
|
+
durationMs: number;
|
|
11
|
+
/** Rows the executions returned, or -1 when no driver could tell. */
|
|
12
|
+
rows: number;
|
|
13
|
+
/** The first error among the executions, or "". */
|
|
14
|
+
error: string;
|
|
15
|
+
/** How many executions returned an error. */
|
|
16
|
+
failed: number;
|
|
17
|
+
/** How many executions the row stands for. */
|
|
18
|
+
count: number;
|
|
19
|
+
occurrences: SqlStatementRow[];
|
|
20
|
+
};
|
|
21
|
+
/** A statement's duration: sub-100ms values keep a decimal (a fast query is 0.9 ms, not 1 ms), longer ones read as elsewhere. */
|
|
22
|
+
export declare function formatStatementDuration(ms: number): string;
|
|
23
|
+
/**
|
|
24
|
+
* Turns statements into table rows. With `group`, statements sharing a
|
|
25
|
+
* non-empty `repeatKey` (the same statement run with different values) become
|
|
26
|
+
* one row, placed where the first of them ran.
|
|
27
|
+
*/
|
|
28
|
+
export declare function groupStatements(statements: SqlStatementRow[], options: {
|
|
29
|
+
group: boolean;
|
|
30
|
+
}): SqlDisplayRow[];
|
|
31
|
+
//# sourceMappingURL=sql-trace.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"sql-trace.d.ts","sourceRoot":"","sources":["../../../src/data/traces/sql-trace.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,SAAS,CAAC;AAE/C,0FAA0F;AAC1F,MAAM,MAAM,aAAa,GAAG;IAC1B,EAAE,EAAE,MAAM,CAAC;IACX,SAAS,EAAE,MAAM,CAAC;IAClB,EAAE,EAAE,MAAM,CAAC;IACX,MAAM,EAAE,MAAM,EAAE,CAAC;IACjB,GAAG,EAAE,MAAM,CAAC;IACZ,+BAA+B;IAC/B,UAAU,EAAE,MAAM,CAAC;IACnB,qEAAqE;IACrE,IAAI,EAAE,MAAM,CAAC;IACb,mDAAmD;IACnD,KAAK,EAAE,MAAM,CAAC;IACd,6CAA6C;IAC7C,MAAM,EAAE,MAAM,CAAC;IACf,8CAA8C;IAC9C,KAAK,EAAE,MAAM,CAAC;IACd,WAAW,EAAE,eAAe,EAAE,CAAC;CAChC,CAAC;AAEF,iIAAiI;AACjI,wBAAgB,uBAAuB,CAAC,EAAE,EAAE,MAAM,GAAG,MAAM,CAG1D;AAwBD;;;;GAIG;AACH,wBAAgB,eAAe,CAAC,UAAU,EAAE,eAAe,EAAE,EAAE,OAAO,EAAE;IAAE,KAAK,EAAE,OAAO,CAAA;CAAE,GAAG,aAAa,EAAE,CAO3G"}
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
import { formatDuration } from "../../lib/format.js";
|
|
2
|
+
function formatStatementDuration(ms) {
|
|
3
|
+
if (ms >= 100) return formatDuration(ms);
|
|
4
|
+
return `${Number(ms.toFixed(1))} ms`;
|
|
5
|
+
}
|
|
6
|
+
function sumKnownRows(statements) {
|
|
7
|
+
const known = statements.filter((statement) => statement.rows >= 0);
|
|
8
|
+
return known.length === 0 ? -1 : known.reduce((total, statement) => total + statement.rows, 0);
|
|
9
|
+
}
|
|
10
|
+
function toDisplayRow(id, statements) {
|
|
11
|
+
var _a;
|
|
12
|
+
const [first] = statements;
|
|
13
|
+
return {
|
|
14
|
+
id,
|
|
15
|
+
startedAt: first.startedAt,
|
|
16
|
+
op: first.op,
|
|
17
|
+
tables: first.tables,
|
|
18
|
+
sql: first.sql,
|
|
19
|
+
durationMs: statements.reduce((total, statement) => total + statement.durationMs, 0),
|
|
20
|
+
rows: sumKnownRows(statements),
|
|
21
|
+
error: ((_a = statements.find((statement) => statement.error)) == null ? void 0 : _a.error) ?? "",
|
|
22
|
+
failed: statements.filter((statement) => statement.error).length,
|
|
23
|
+
count: statements.length,
|
|
24
|
+
occurrences: statements
|
|
25
|
+
};
|
|
26
|
+
}
|
|
27
|
+
function groupStatements(statements, options) {
|
|
28
|
+
const groups = /* @__PURE__ */ new Map();
|
|
29
|
+
statements.forEach((statement, index) => {
|
|
30
|
+
const key = options.group && statement.repeatKey ? `repeat:${statement.repeatKey}` : `row:${index}`;
|
|
31
|
+
groups.set(key, [...groups.get(key) ?? [], statement]);
|
|
32
|
+
});
|
|
33
|
+
return [...groups].map(([key, members]) => toDisplayRow(key, members));
|
|
34
|
+
}
|
|
35
|
+
export {
|
|
36
|
+
formatStatementDuration,
|
|
37
|
+
groupStatements
|
|
38
|
+
};
|
|
39
|
+
//# sourceMappingURL=sql-trace.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"sql-trace.js","sources":["../../../src/data/traces/sql-trace.ts"],"sourcesContent":["import { formatDuration } from \"../../lib/format\";\nimport type { SqlStatementRow } from \"./types\";\n\n/** One table row: a statement, or every execution of statements sharing a `repeatKey`. */\nexport type SqlDisplayRow = {\n id: string;\n startedAt: string;\n op: string;\n tables: string[];\n sql: string;\n /** Total of the executions. */\n durationMs: number;\n /** Rows the executions returned, or -1 when no driver could tell. */\n rows: number;\n /** The first error among the executions, or \"\". */\n error: string;\n /** How many executions returned an error. */\n failed: number;\n /** How many executions the row stands for. */\n count: number;\n occurrences: SqlStatementRow[];\n};\n\n/** A statement's duration: sub-100ms values keep a decimal (a fast query is 0.9 ms, not 1 ms), longer ones read as elsewhere. */\nexport function formatStatementDuration(ms: number): string {\n if (ms >= 100) return formatDuration(ms);\n return `${Number(ms.toFixed(1))} ms`;\n}\n\nfunction sumKnownRows(statements: SqlStatementRow[]): number {\n const known = statements.filter((statement) => statement.rows >= 0);\n return known.length === 0 ? -1 : known.reduce((total, statement) => total + statement.rows, 0);\n}\n\nfunction toDisplayRow(id: string, statements: SqlStatementRow[]): SqlDisplayRow {\n const [first] = statements as [SqlStatementRow, ...SqlStatementRow[]];\n return {\n id,\n startedAt: first.startedAt,\n op: first.op,\n tables: first.tables,\n sql: first.sql,\n durationMs: statements.reduce((total, statement) => total + statement.durationMs, 0),\n rows: sumKnownRows(statements),\n error: statements.find((statement) => statement.error)?.error ?? \"\",\n failed: statements.filter((statement) => statement.error).length,\n count: statements.length,\n occurrences: statements,\n };\n}\n\n/**\n * Turns statements into table rows. With `group`, statements sharing a\n * non-empty `repeatKey` (the same statement run with different values) become\n * one row, placed where the first of them ran.\n */\nexport function groupStatements(statements: SqlStatementRow[], options: { group: boolean }): SqlDisplayRow[] {\n const groups = new Map<string, SqlStatementRow[]>();\n statements.forEach((statement, index) => {\n const key = options.group && statement.repeatKey ? `repeat:${statement.repeatKey}` : `row:${index}`;\n groups.set(key, [...(groups.get(key) ?? []), statement]);\n });\n return [...groups].map(([key, members]) => toDisplayRow(key, members));\n}\n"],"names":[],"mappings":";AAwBO,SAAS,wBAAwB,IAAoB;AAC1D,MAAI,MAAM,IAAK,QAAO,eAAe,EAAE;AACvC,SAAO,GAAG,OAAO,GAAG,QAAQ,CAAC,CAAC,CAAC;AACjC;AAEA,SAAS,aAAa,YAAuC;AAC3D,QAAM,QAAQ,WAAW,OAAO,CAAC,cAAc,UAAU,QAAQ,CAAC;AAClE,SAAO,MAAM,WAAW,IAAI,KAAK,MAAM,OAAO,CAAC,OAAO,cAAc,QAAQ,UAAU,MAAM,CAAC;AAC/F;AAEA,SAAS,aAAa,IAAY,YAA8C;;AAC9E,QAAM,CAAC,KAAK,IAAI;AAChB,SAAO;AAAA,IACL;AAAA,IACA,WAAW,MAAM;AAAA,IACjB,IAAI,MAAM;AAAA,IACV,QAAQ,MAAM;AAAA,IACd,KAAK,MAAM;AAAA,IACX,YAAY,WAAW,OAAO,CAAC,OAAO,cAAc,QAAQ,UAAU,YAAY,CAAC;AAAA,IACnF,MAAM,aAAa,UAAU;AAAA,IAC7B,SAAO,gBAAW,KAAK,CAAC,cAAc,UAAU,KAAK,MAA9C,mBAAiD,UAAS;AAAA,IACjE,QAAQ,WAAW,OAAO,CAAC,cAAc,UAAU,KAAK,EAAE;AAAA,IAC1D,OAAO,WAAW;AAAA,IAClB,aAAa;AAAA,EAAA;AAEjB;AAOO,SAAS,gBAAgB,YAA+B,SAA8C;AAC3G,QAAM,6BAAa,IAAA;AACnB,aAAW,QAAQ,CAAC,WAAW,UAAU;AACvC,UAAM,MAAM,QAAQ,SAAS,UAAU,YAAY,UAAU,UAAU,SAAS,KAAK,OAAO,KAAK;AACjG,WAAO,IAAI,KAAK,CAAC,GAAI,OAAO,IAAI,GAAG,KAAK,IAAK,SAAS,CAAC;AAAA,EACzD,CAAC;AACD,SAAO,CAAC,GAAG,MAAM,EAAE,IAAI,CAAC,CAAC,KAAK,OAAO,MAAM,aAAa,KAAK,OAAO,CAAC;AACvE;"}
|