@awsless/cli 0.1.11 → 0.1.13
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/bin.js +578 -182
- package/dist/handlers/icon.js +1 -15
- package/dist/handlers/pubsub-publisher.js +3 -17
- package/dist/handlers/pubsub-server.js +26 -48
- package/dist/test-global-setup.js +1 -5
- package/package.json +19 -19
package/dist/bin.js
CHANGED
|
@@ -6,60 +6,39 @@ var __defProp = Object.defineProperty;
|
|
|
6
6
|
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
7
7
|
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
8
8
|
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
9
|
-
function __accessProp(key) {
|
|
10
|
-
return this[key];
|
|
11
|
-
}
|
|
12
|
-
var __toESMCache_node;
|
|
13
|
-
var __toESMCache_esm;
|
|
14
9
|
var __toESM = (mod, isNodeMode, target) => {
|
|
15
|
-
var canCache = mod != null && typeof mod === "object";
|
|
16
|
-
if (canCache) {
|
|
17
|
-
var cache = isNodeMode ? __toESMCache_node ??= new WeakMap : __toESMCache_esm ??= new WeakMap;
|
|
18
|
-
var cached = cache.get(mod);
|
|
19
|
-
if (cached)
|
|
20
|
-
return cached;
|
|
21
|
-
}
|
|
22
10
|
target = mod != null ? __create(__getProtoOf(mod)) : {};
|
|
23
11
|
const to = isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target;
|
|
24
12
|
for (let key of __getOwnPropNames(mod))
|
|
25
13
|
if (!__hasOwnProp.call(to, key))
|
|
26
14
|
__defProp(to, key, {
|
|
27
|
-
get:
|
|
15
|
+
get: () => mod[key],
|
|
28
16
|
enumerable: true
|
|
29
17
|
});
|
|
30
|
-
if (canCache)
|
|
31
|
-
cache.set(mod, to);
|
|
32
18
|
return to;
|
|
33
19
|
};
|
|
20
|
+
var __moduleCache = /* @__PURE__ */ new WeakMap;
|
|
34
21
|
var __toCommonJS = (from) => {
|
|
35
|
-
var entry =
|
|
22
|
+
var entry = __moduleCache.get(from), desc;
|
|
36
23
|
if (entry)
|
|
37
24
|
return entry;
|
|
38
25
|
entry = __defProp({}, "__esModule", { value: true });
|
|
39
|
-
if (from && typeof from === "object" || typeof from === "function")
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable
|
|
45
|
-
});
|
|
46
|
-
}
|
|
26
|
+
if (from && typeof from === "object" || typeof from === "function")
|
|
27
|
+
__getOwnPropNames(from).map((key) => !__hasOwnProp.call(entry, key) && __defProp(entry, key, {
|
|
28
|
+
get: () => from[key],
|
|
29
|
+
enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable
|
|
30
|
+
}));
|
|
47
31
|
__moduleCache.set(from, entry);
|
|
48
32
|
return entry;
|
|
49
33
|
};
|
|
50
|
-
var __moduleCache;
|
|
51
34
|
var __commonJS = (cb, mod) => () => (mod || cb((mod = { exports: {} }).exports, mod), mod.exports);
|
|
52
|
-
var __returnValue = (v) => v;
|
|
53
|
-
function __exportSetter(name, newValue) {
|
|
54
|
-
this[name] = __returnValue.bind(null, newValue);
|
|
55
|
-
}
|
|
56
35
|
var __export = (target, all) => {
|
|
57
36
|
for (var name in all)
|
|
58
37
|
__defProp(target, name, {
|
|
59
38
|
get: all[name],
|
|
60
39
|
enumerable: true,
|
|
61
40
|
configurable: true,
|
|
62
|
-
set:
|
|
41
|
+
set: (newValue) => all[name] = () => newValue
|
|
63
42
|
});
|
|
64
43
|
};
|
|
65
44
|
var __esm = (fn, res) => () => (fn && (res = fn(fn = 0)), res);
|
|
@@ -853,7 +832,7 @@ Expecting one of '${allowedValues.join("', '")}'`);
|
|
|
853
832
|
this._exitCallback = (err) => {
|
|
854
833
|
if (err.code !== "commander.executeSubCommandAsync") {
|
|
855
834
|
throw err;
|
|
856
|
-
}
|
|
835
|
+
} else {}
|
|
857
836
|
};
|
|
858
837
|
}
|
|
859
838
|
return this;
|
|
@@ -3090,7 +3069,7 @@ var require_cell = __commonJS((exports, module) => {
|
|
|
3090
3069
|
let content = utils.truncate(this.content, 10, this.truncate);
|
|
3091
3070
|
if (!lineNum) {
|
|
3092
3071
|
info(`${this.y}-${this.x}: ${this.rowSpan - lineNum}x${this.colSpan} Cell ${content}`);
|
|
3093
|
-
}
|
|
3072
|
+
} else {}
|
|
3094
3073
|
let padLen = Math.max(this.height - this.lines.length, 0);
|
|
3095
3074
|
let padTop;
|
|
3096
3075
|
switch (this.vAlign) {
|
|
@@ -26859,7 +26838,7 @@ var require_node_gyp_build_optional_packages = __commonJS((exports, module) => {
|
|
|
26859
26838
|
|
|
26860
26839
|
// ../../node_modules/.pnpm/msgpackr-extract@3.0.4/node_modules/msgpackr-extract/index.js
|
|
26861
26840
|
var require_msgpackr_extract = __commonJS((exports, module) => {
|
|
26862
|
-
var __dirname = "/Users/
|
|
26841
|
+
var __dirname = "/Users/ivandasilveira/Sites/@awsless/node_modules/.pnpm/msgpackr-extract@3.0.4/node_modules/msgpackr-extract";
|
|
26863
26842
|
module.exports = require_node_gyp_build_optional_packages()(__dirname);
|
|
26864
26843
|
});
|
|
26865
26844
|
|
|
@@ -39727,7 +39706,7 @@ var require_src3 = __commonJS((exports) => {
|
|
|
39727
39706
|
|
|
39728
39707
|
// ../../node_modules/.pnpm/@grpc+grpc-js@1.12.6/node_modules/@grpc/grpc-js/build/src/channelz.js
|
|
39729
39708
|
var require_channelz = __commonJS((exports) => {
|
|
39730
|
-
var __dirname = "/Users/
|
|
39709
|
+
var __dirname = "/Users/ivandasilveira/Sites/@awsless/node_modules/.pnpm/@grpc+grpc-js@1.12.6/node_modules/@grpc/grpc-js/build/src";
|
|
39731
39710
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
39732
39711
|
exports.registerChannelzSocket = exports.registerChannelzServer = exports.registerChannelzSubchannel = exports.registerChannelzChannel = exports.ChannelzCallTrackerStub = exports.ChannelzCallTracker = exports.ChannelzChildrenTrackerStub = exports.ChannelzChildrenTracker = exports.ChannelzTrace = exports.ChannelzTraceStub = undefined;
|
|
39733
39712
|
exports.unregisterChannelzRef = unregisterChannelzRef;
|
|
@@ -57231,7 +57210,7 @@ var require_zipEntries = __commonJS((exports, module) => {
|
|
|
57231
57210
|
if (this.centralDirRecords !== this.files.length) {
|
|
57232
57211
|
if (this.centralDirRecords !== 0 && this.files.length === 0) {
|
|
57233
57212
|
throw new Error("Corrupted zip or bug: expected " + this.centralDirRecords + " records in central dir, got " + this.files.length);
|
|
57234
|
-
}
|
|
57213
|
+
} else {}
|
|
57235
57214
|
}
|
|
57236
57215
|
},
|
|
57237
57216
|
readEndOfCentral: function() {
|
|
@@ -74452,7 +74431,7 @@ WD9f
|
|
|
74452
74431
|
|
|
74453
74432
|
// ../../node_modules/.pnpm/ioredis@5.10.1_supports-color@8.1.1/node_modules/ioredis/built/utils/index.js
|
|
74454
74433
|
var require_utils5 = __commonJS((exports) => {
|
|
74455
|
-
var __dirname = "/Users/
|
|
74434
|
+
var __dirname = "/Users/ivandasilveira/Sites/@awsless/node_modules/.pnpm/ioredis@5.10.1_supports-color@8.1.1/node_modules/ioredis/built/utils";
|
|
74456
74435
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
74457
74436
|
exports.noop = exports.defaults = exports.Debug = exports.getPackageMeta = exports.zipMap = exports.CONNECTION_CLOSED_ERROR_MSG = exports.shuffle = exports.sample = exports.resolveTLSProfile = exports.parseURL = exports.optimizeErrorStack = exports.toArg = exports.convertMapToArray = exports.convertObjectToArray = exports.timeout = exports.packObject = exports.isInt = exports.wrapMultiResult = exports.convertBufferToString = undefined;
|
|
74458
74437
|
var fs_1 = __require("fs");
|
|
@@ -74738,7 +74717,7 @@ var require_argumentParsers = __commonJS((exports) => {
|
|
|
74738
74717
|
|
|
74739
74718
|
// ../../node_modules/.pnpm/ioredis@5.10.1_supports-color@8.1.1/node_modules/ioredis/built/Command.js
|
|
74740
74719
|
var require_Command = __commonJS((exports) => {
|
|
74741
|
-
var __dirname = "/Users/
|
|
74720
|
+
var __dirname = "/Users/ivandasilveira/Sites/@awsless/node_modules/.pnpm/ioredis@5.10.1_supports-color@8.1.1/node_modules/ioredis/built";
|
|
74742
74721
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
74743
74722
|
var commands_1 = require_built();
|
|
74744
74723
|
var calculateSlot = require_lib4();
|
|
@@ -95385,7 +95364,7 @@ var require_db_util = __commonJS((exports) => {
|
|
|
95385
95364
|
|
|
95386
95365
|
// ../../node_modules/.pnpm/redis-memory-server@0.16.1_supports-color@8.1.1/node_modules/redis-memory-server/lib/util/RedisInstance.js
|
|
95387
95366
|
var require_RedisInstance = __commonJS((exports) => {
|
|
95388
|
-
var __dirname = "/Users/
|
|
95367
|
+
var __dirname = "/Users/ivandasilveira/Sites/@awsless/node_modules/.pnpm/redis-memory-server@0.16.1_supports-color@8.1.1/node_modules/redis-memory-server/lib/util";
|
|
95389
95368
|
var __awaiter = exports && exports.__awaiter || function(thisArg, _arguments, P3, generator) {
|
|
95390
95369
|
function adopt(value) {
|
|
95391
95370
|
return value instanceof P3 ? value : new P3(function(resolve3) {
|
|
@@ -101299,7 +101278,7 @@ var require_unbzip2_stream = __commonJS((exports, module) => {
|
|
|
101299
101278
|
stream2.queue(d5);
|
|
101300
101279
|
if (d5 !== null) {
|
|
101301
101280
|
outlength += d5.length;
|
|
101302
|
-
}
|
|
101281
|
+
} else {}
|
|
101303
101282
|
});
|
|
101304
101283
|
} catch (e4) {
|
|
101305
101284
|
stream2.emit("error", e4);
|
|
@@ -114515,7 +114494,7 @@ var getSanitizedDevTypeScriptVersion = (version2 = "") => {
|
|
|
114515
114494
|
};
|
|
114516
114495
|
|
|
114517
114496
|
// ../../node_modules/.pnpm/@aws-sdk+util-user-agent-node@3.973.14_aws-crt@1.30.0_supports-color@8.1.1_/node_modules/@aws-sdk/util-user-agent-node/dist-es/getTypeScriptUserAgentPair.js
|
|
114518
|
-
var __dirname = "/Users/
|
|
114497
|
+
var __dirname = "/Users/ivandasilveira/Sites/@awsless/node_modules/.pnpm/@aws-sdk+util-user-agent-node@3.973.14_aws-crt@1.30.0_supports-color@8.1.1_/node_modules/@aws-sdk/util-user-agent-node/dist-es";
|
|
114519
114498
|
var tscVersion;
|
|
114520
114499
|
var TS_PACKAGE_JSON = join7("node_modules", "typescript", "package.json");
|
|
114521
114500
|
var getTypeScriptUserAgentPair = async () => {
|
|
@@ -131592,17 +131571,6 @@ var $forEachNodeInTopologicalOrder = sort.forEachNodeInTopologicalOrder;
|
|
|
131592
131571
|
var $topologicalSort = sort.topologicalSort;
|
|
131593
131572
|
var $topologicalGenerations = sort.topologicalGenerations;
|
|
131594
131573
|
var $forEachTopologicalGeneration = sort.forEachTopologicalGeneration;
|
|
131595
|
-
// ../../node_modules/.pnpm/uuid@11.1.0/node_modules/uuid/dist/esm/sha1.js
|
|
131596
|
-
import { createHash as createHash3 } from "crypto";
|
|
131597
|
-
function sha1(bytes) {
|
|
131598
|
-
if (Array.isArray(bytes)) {
|
|
131599
|
-
bytes = Buffer.from(bytes);
|
|
131600
|
-
} else if (typeof bytes === "string") {
|
|
131601
|
-
bytes = Buffer.from(bytes, "utf8");
|
|
131602
|
-
}
|
|
131603
|
-
return createHash3("sha1").update(bytes).digest();
|
|
131604
|
-
}
|
|
131605
|
-
var sha1_default = sha1;
|
|
131606
131574
|
|
|
131607
131575
|
// ../../node_modules/.pnpm/uuid@11.1.0/node_modules/uuid/dist/esm/regex.js
|
|
131608
131576
|
var regex_default = /^(?:[0-9a-f]{8}-[0-9a-f]{4}-[1-8][0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$/i;
|
|
@@ -131668,6 +131636,18 @@ function v35(version2, hash, value, namespace, buf, offset) {
|
|
|
131668
131636
|
return unsafeStringify(bytes);
|
|
131669
131637
|
}
|
|
131670
131638
|
|
|
131639
|
+
// ../../node_modules/.pnpm/uuid@11.1.0/node_modules/uuid/dist/esm/sha1.js
|
|
131640
|
+
import { createHash as createHash3 } from "crypto";
|
|
131641
|
+
function sha1(bytes) {
|
|
131642
|
+
if (Array.isArray(bytes)) {
|
|
131643
|
+
bytes = Buffer.from(bytes);
|
|
131644
|
+
} else if (typeof bytes === "string") {
|
|
131645
|
+
bytes = Buffer.from(bytes, "utf8");
|
|
131646
|
+
}
|
|
131647
|
+
return createHash3("sha1").update(bytes).digest();
|
|
131648
|
+
}
|
|
131649
|
+
var sha1_default = sha1;
|
|
131650
|
+
|
|
131671
131651
|
// ../../node_modules/.pnpm/uuid@11.1.0/node_modules/uuid/dist/esm/v5.js
|
|
131672
131652
|
function v5(value, namespace, buf, offset) {
|
|
131673
131653
|
return v35(80, sha1_default, value, namespace, buf, offset);
|
|
@@ -141133,6 +141113,8 @@ if (!nativeAccelerationDisabled) {
|
|
|
141133
141113
|
try {
|
|
141134
141114
|
if (true)
|
|
141135
141115
|
extractor = require_msgpackr_extract();
|
|
141116
|
+
else
|
|
141117
|
+
;
|
|
141136
141118
|
if (extractor)
|
|
141137
141119
|
setExtractor(extractor.extractStrings);
|
|
141138
141120
|
} catch (error3) {}
|
|
@@ -155087,8 +155069,19 @@ import { readFile as readFile12 } from "fs/promises";
|
|
|
155087
155069
|
import { createServer as createServer2 } from "http";
|
|
155088
155070
|
|
|
155089
155071
|
// src/dev/util.ts
|
|
155072
|
+
import { randomBytes } from "crypto";
|
|
155090
155073
|
import { createServer } from "net";
|
|
155091
155074
|
var LOCAL_ACCOUNT_ID = "000000000000";
|
|
155075
|
+
var TRACE_HEADER = "x-awsless-trace";
|
|
155076
|
+
var traceId = () => randomBytes(4).toString("hex");
|
|
155077
|
+
var formatTraceHeader = (trace) => `${trace.traceId}:${trace.spanId}`;
|
|
155078
|
+
var parseTraceHeader = (value) => {
|
|
155079
|
+
if (typeof value !== "string") {
|
|
155080
|
+
return;
|
|
155081
|
+
}
|
|
155082
|
+
const [traceId2, spanId] = value.split(":");
|
|
155083
|
+
return traceId2 && spanId ? { traceId: traceId2, spanId } : undefined;
|
|
155084
|
+
};
|
|
155092
155085
|
var readBody = (req) => {
|
|
155093
155086
|
return new Promise((resolve3, reject) => {
|
|
155094
155087
|
const chunks = [];
|
|
@@ -157381,7 +157374,7 @@ var createSnsServer = (props) => {
|
|
|
157381
157374
|
let closeServer;
|
|
157382
157375
|
let dispatch;
|
|
157383
157376
|
let reportFailure;
|
|
157384
|
-
const publish2 = (input) => {
|
|
157377
|
+
const publish2 = (input, trace) => {
|
|
157385
157378
|
const messageId = randomUUID4();
|
|
157386
157379
|
for (const capture of props?.captures ?? []) {
|
|
157387
157380
|
if (capture(input)) {
|
|
@@ -157414,7 +157407,7 @@ var createSnsServer = (props) => {
|
|
|
157414
157407
|
]
|
|
157415
157408
|
};
|
|
157416
157409
|
setImmediate(() => {
|
|
157417
|
-
dispatch?.(event).catch((error3) => {
|
|
157410
|
+
dispatch?.(event, trace).catch((error3) => {
|
|
157418
157411
|
reportFailure?.({ kind: "async", event, error: error3 });
|
|
157419
157412
|
});
|
|
157420
157413
|
});
|
|
@@ -157445,7 +157438,7 @@ var createSnsServer = (props) => {
|
|
|
157445
157438
|
res.end(`The local dev sns emulator only supports Publish, got: ${action}`);
|
|
157446
157439
|
return;
|
|
157447
157440
|
}
|
|
157448
|
-
const messageId = publish2(input);
|
|
157441
|
+
const messageId = publish2(input, parseTraceHeader(req.headers[TRACE_HEADER]));
|
|
157449
157442
|
if (isJson) {
|
|
157450
157443
|
res.writeHead(200, { "content-type": "application/x-amz-json-1.0" });
|
|
157451
157444
|
res.end(JSON.stringify({ MessageId: messageId }));
|
|
@@ -158283,7 +158276,7 @@ var startDevRouter = async (props) => {
|
|
|
158283
158276
|
const sourceIp = server2.requestIP(request)?.address ?? "127.0.0.1";
|
|
158284
158277
|
let result;
|
|
158285
158278
|
try {
|
|
158286
|
-
result = await props.dispatch(formatWebEvent(request, route, body, url, sourceIp));
|
|
158279
|
+
result = await props.dispatch(formatWebEvent(request, route, body, url, sourceIp), parseTraceHeader(request.headers.get(TRACE_HEADER)));
|
|
158287
158280
|
} catch (error3) {
|
|
158288
158281
|
props.onError?.(error3, route.routeKey);
|
|
158289
158282
|
const detail = error3 instanceof Error ? error3.stack ?? error3.message : String(error3);
|
|
@@ -158445,7 +158438,7 @@ var createRestServer = (props) => {
|
|
|
158445
158438
|
},
|
|
158446
158439
|
body: body.length > 0 ? body.toString("base64") : undefined,
|
|
158447
158440
|
isBase64Encoded: body.length > 0
|
|
158448
|
-
});
|
|
158441
|
+
}, parseTraceHeader(req.headers[TRACE_HEADER]));
|
|
158449
158442
|
writeWebResponse(res, result);
|
|
158450
158443
|
};
|
|
158451
158444
|
return {
|
|
@@ -159802,12 +159795,12 @@ var tableOnDev = async (ctx) => {
|
|
|
159802
159795
|
if (props.stream) {
|
|
159803
159796
|
const routeKey = formatRouteKey(stackName, "table", id);
|
|
159804
159797
|
const eventSourceARN = `arn:aws:dynamodb:${ctx.appConfig.region}:000000000000:table/${name}/stream/local`;
|
|
159805
|
-
const unsubscribe = server.onStreamRecord(name, (record) => {
|
|
159798
|
+
const unsubscribe = server.onStreamRecord(name, (record, context) => {
|
|
159806
159799
|
if (isWiping()) {
|
|
159807
159800
|
return;
|
|
159808
159801
|
}
|
|
159809
159802
|
const event = { Records: [{ ...record, eventSourceARN }] };
|
|
159810
|
-
dispatch(event).catch((error3) => {
|
|
159803
|
+
dispatch(event, parseTraceHeader(context)).catch((error3) => {
|
|
159811
159804
|
reportFailure({
|
|
159812
159805
|
kind: "stream",
|
|
159813
159806
|
routeKey,
|
|
@@ -160026,8 +160019,9 @@ var createSchedulerServer = () => {
|
|
|
160026
160019
|
const name = decodeURIComponent(match3[1]);
|
|
160027
160020
|
const input = JSON.parse(body.toString() || "{}");
|
|
160028
160021
|
const payload = input.Target?.Input ? JSON.parse(input.Target.Input) : {};
|
|
160022
|
+
const trace = parseTraceHeader(req.headers[TRACE_HEADER]);
|
|
160029
160023
|
setImmediate(() => {
|
|
160030
|
-
dispatch?.(payload).catch((error3) => {
|
|
160024
|
+
dispatch?.(payload, trace).catch((error3) => {
|
|
160031
160025
|
const routeKey = payload?.["$awsless-route"];
|
|
160032
160026
|
reportFailure?.({
|
|
160033
160027
|
kind: "async",
|
|
@@ -166599,7 +166593,7 @@ var createS3Server = (props) => {
|
|
|
166599
166593
|
let closeServer;
|
|
166600
166594
|
let dispatch;
|
|
166601
166595
|
let reportFailure;
|
|
166602
|
-
const notify = (eventName, bucket, key, size2, eTag) => {
|
|
166596
|
+
const notify = (eventName, bucket, key, size2, eTag, trace) => {
|
|
166603
166597
|
for (const rule of props.rules) {
|
|
166604
166598
|
const matches = rule.events.some((event2) => {
|
|
166605
166599
|
const type2 = event2.replace(/^s3:/, "");
|
|
@@ -166634,7 +166628,7 @@ var createS3Server = (props) => {
|
|
|
166634
166628
|
}
|
|
166635
166629
|
]
|
|
166636
166630
|
};
|
|
166637
|
-
dispatch?.(event).catch((error3) => {
|
|
166631
|
+
dispatch?.(event, trace).catch((error3) => {
|
|
166638
166632
|
reportFailure?.({ kind: "async", routeKey: rule.id, event, error: error3 });
|
|
166639
166633
|
});
|
|
166640
166634
|
}
|
|
@@ -166701,7 +166695,7 @@ var createS3Server = (props) => {
|
|
|
166701
166695
|
const eTag = createHash22("md5").update(body).digest("hex");
|
|
166702
166696
|
res.writeHead(200, { etag: `"${eTag}"` });
|
|
166703
166697
|
res.end();
|
|
166704
|
-
notify("ObjectCreated:Put", bucket, key, body.length, eTag);
|
|
166698
|
+
notify("ObjectCreated:Put", bucket, key, body.length, eTag, parseTraceHeader(req.headers[TRACE_HEADER]));
|
|
166705
166699
|
return;
|
|
166706
166700
|
}
|
|
166707
166701
|
if (req.method === "GET" || req.method === "HEAD") {
|
|
@@ -166724,7 +166718,7 @@ var createS3Server = (props) => {
|
|
|
166724
166718
|
await rm10(file2, { force: true });
|
|
166725
166719
|
res.writeHead(204);
|
|
166726
166720
|
res.end();
|
|
166727
|
-
notify("ObjectRemoved:Delete", bucket, key, 0, "");
|
|
166721
|
+
notify("ObjectRemoved:Delete", bucket, key, 0, "", parseTraceHeader(req.headers[TRACE_HEADER]));
|
|
166728
166722
|
return;
|
|
166729
166723
|
}
|
|
166730
166724
|
res.writeHead(501, { "content-type": "application/xml" });
|
|
@@ -166814,7 +166808,7 @@ var createSqsServer = (props) => {
|
|
|
166814
166808
|
}
|
|
166815
166809
|
return stores.get(queue);
|
|
166816
166810
|
};
|
|
166817
|
-
const deliver = (queue, input, messageId) => {
|
|
166811
|
+
const deliver = (queue, input, messageId, trace) => {
|
|
166818
166812
|
const now = Date.now();
|
|
166819
166813
|
if (props.queues.get(queue) === undefined) {
|
|
166820
166814
|
storeOf(queue).push({
|
|
@@ -166848,7 +166842,7 @@ var createSqsServer = (props) => {
|
|
|
166848
166842
|
]
|
|
166849
166843
|
};
|
|
166850
166844
|
const send = () => {
|
|
166851
|
-
dispatch?.(event).catch((error3) => {
|
|
166845
|
+
dispatch?.(event, trace).catch((error3) => {
|
|
166852
166846
|
let body = input.MessageBody;
|
|
166853
166847
|
try {
|
|
166854
166848
|
body = JSON.parse(input.MessageBody ?? "");
|
|
@@ -166894,16 +166888,16 @@ var createSqsServer = (props) => {
|
|
|
166894
166888
|
QueueUrl: queueUrl(input.QueueName)
|
|
166895
166889
|
};
|
|
166896
166890
|
},
|
|
166897
|
-
SendMessage(input) {
|
|
166891
|
+
SendMessage(input, _signal, trace) {
|
|
166898
166892
|
const queue = queueFromUrl(input.QueueUrl);
|
|
166899
166893
|
if (!queue) {
|
|
166900
166894
|
throw new Error(`Unknown local queue: ${input.QueueUrl}`);
|
|
166901
166895
|
}
|
|
166902
166896
|
const messageId = randomUUID8();
|
|
166903
|
-
deliver(queue, input, messageId);
|
|
166897
|
+
deliver(queue, input, messageId, trace);
|
|
166904
166898
|
return sendResult(input, messageId);
|
|
166905
166899
|
},
|
|
166906
|
-
SendMessageBatch(input) {
|
|
166900
|
+
SendMessageBatch(input, _signal, trace) {
|
|
166907
166901
|
const queue = queueFromUrl(input.QueueUrl);
|
|
166908
166902
|
if (!queue) {
|
|
166909
166903
|
throw new Error(`Unknown local queue: ${input.QueueUrl}`);
|
|
@@ -166911,7 +166905,7 @@ var createSqsServer = (props) => {
|
|
|
166911
166905
|
return {
|
|
166912
166906
|
Successful: (input.Entries ?? []).map((entry) => {
|
|
166913
166907
|
const messageId = randomUUID8();
|
|
166914
|
-
deliver(queue, entry, messageId);
|
|
166908
|
+
deliver(queue, entry, messageId, trace);
|
|
166915
166909
|
return {
|
|
166916
166910
|
Id: entry.Id,
|
|
166917
166911
|
...sendResult(entry, messageId)
|
|
@@ -167043,7 +167037,7 @@ var createSqsServer = (props) => {
|
|
|
167043
167037
|
if (!action) {
|
|
167044
167038
|
throw new Error(`The local dev sqs emulator does not support: ${target2}`);
|
|
167045
167039
|
}
|
|
167046
|
-
const result = await action(JSON.parse(body.toString() || "{}"), abort.signal);
|
|
167040
|
+
const result = await action(JSON.parse(body.toString() || "{}"), abort.signal, parseTraceHeader(req.headers[TRACE_HEADER]));
|
|
167047
167041
|
if (res.writableEnded || res.destroyed) {
|
|
167048
167042
|
return;
|
|
167049
167043
|
}
|
|
@@ -167341,12 +167335,90 @@ class WorkerError extends Error {
|
|
|
167341
167335
|
}
|
|
167342
167336
|
}
|
|
167343
167337
|
}
|
|
167344
|
-
var WORKER_ENTRY = `import {
|
|
167338
|
+
var WORKER_ENTRY = `import { AsyncLocalStorage } from 'node:async_hooks'
|
|
167339
|
+
import http from 'node:http'
|
|
167340
|
+
import https from 'node:https'
|
|
167341
|
+
import { createServer } from 'node:http'
|
|
167342
|
+
import { syncBuiltinESMExports } from 'node:module'
|
|
167345
167343
|
import { format } from 'node:util'
|
|
167346
167344
|
|
|
167347
167345
|
let handler
|
|
167348
167346
|
let getCurrentRoute = () => undefined
|
|
167349
167347
|
|
|
167348
|
+
// The trace of the running invocation, set per dispatch by the dev
|
|
167349
|
+
// server. The async context keeps it accurate under concurrent
|
|
167350
|
+
// requests, exactly like the route context.
|
|
167351
|
+
const traceContext = new AsyncLocalStorage()
|
|
167352
|
+
|
|
167353
|
+
const isLoopback = host => host === '127.0.0.1' || host === 'localhost' || host === '::1'
|
|
167354
|
+
|
|
167355
|
+
// Outgoing requests to the local emulators carry the active trace as a
|
|
167356
|
+
// header, so a queue send or task invoke made by a handler links the
|
|
167357
|
+
// dispatch it causes back to this invocation. Only loopback targets:
|
|
167358
|
+
// a request to a real external api must never see the header.
|
|
167359
|
+
const injectTrace = module => {
|
|
167360
|
+
const original = module.request
|
|
167361
|
+
|
|
167362
|
+
module.request = function (...args) {
|
|
167363
|
+
const trace = traceContext.getStore()
|
|
167364
|
+
|
|
167365
|
+
if (trace) {
|
|
167366
|
+
// request(url[, options][, callback]) or request(options[, callback])
|
|
167367
|
+
const index = typeof args[0] === 'string' || args[0] instanceof URL ? 1 : 0
|
|
167368
|
+
let url
|
|
167369
|
+
|
|
167370
|
+
try {
|
|
167371
|
+
url = index === 1 ? new URL(String(args[0])) : undefined
|
|
167372
|
+
} catch (_) {}
|
|
167373
|
+
|
|
167374
|
+
let options = args[index]
|
|
167375
|
+
|
|
167376
|
+
if (typeof options === 'function' || options === undefined) {
|
|
167377
|
+
args.splice(index, 0, {})
|
|
167378
|
+
options = args[index]
|
|
167379
|
+
}
|
|
167380
|
+
|
|
167381
|
+
const host = String(url?.hostname ?? options.hostname ?? options.host ?? '').split(':')[0]
|
|
167382
|
+
|
|
167383
|
+
if (isLoopback(host)) {
|
|
167384
|
+
args[index] = { ...options, headers: { ...options.headers, 'x-awsless-trace': trace } }
|
|
167385
|
+
}
|
|
167386
|
+
}
|
|
167387
|
+
|
|
167388
|
+
return original.apply(this, args)
|
|
167389
|
+
}
|
|
167390
|
+
}
|
|
167391
|
+
|
|
167392
|
+
injectTrace(http)
|
|
167393
|
+
injectTrace(https)
|
|
167394
|
+
|
|
167395
|
+
// The aws sdk grabs request via ESM named imports (like
|
|
167396
|
+
// "const { request } = await import('node:http')"), and ESM named
|
|
167397
|
+
// exports of builtins are snapshots - the sync pushes the patched
|
|
167398
|
+
// functions into those bindings too.
|
|
167399
|
+
syncBuiltinESMExports()
|
|
167400
|
+
|
|
167401
|
+
const originalFetch = globalThis.fetch
|
|
167402
|
+
|
|
167403
|
+
globalThis.fetch = (input, init) => {
|
|
167404
|
+
const trace = traceContext.getStore()
|
|
167405
|
+
|
|
167406
|
+
if (trace) {
|
|
167407
|
+
try {
|
|
167408
|
+
const url = new URL(input instanceof Request ? input.url : String(input))
|
|
167409
|
+
|
|
167410
|
+
if (isLoopback(url.hostname)) {
|
|
167411
|
+
const headers = new Headers(init?.headers ?? (input instanceof Request ? input.headers : undefined))
|
|
167412
|
+
|
|
167413
|
+
headers.set('x-awsless-trace', trace)
|
|
167414
|
+
init = { ...init, headers }
|
|
167415
|
+
}
|
|
167416
|
+
} catch (_) {}
|
|
167417
|
+
}
|
|
167418
|
+
|
|
167419
|
+
return originalFetch(input, init)
|
|
167420
|
+
}
|
|
167421
|
+
|
|
167350
167422
|
// Every console call writes ONE framed record: an invisible \\x1f
|
|
167351
167423
|
// marker with the active bundle route & the json-encoded text, so
|
|
167352
167424
|
// multi-line output stays a single log entry downstream. The route
|
|
@@ -167392,12 +167464,12 @@ const server = createServer((req, res) => {
|
|
|
167392
167464
|
let response
|
|
167393
167465
|
|
|
167394
167466
|
try {
|
|
167395
|
-
const { event, context } = JSON.parse(Buffer.concat(chunks).toString())
|
|
167467
|
+
const { event, context, trace } = JSON.parse(Buffer.concat(chunks).toString())
|
|
167396
167468
|
|
|
167397
167469
|
// Fabricate the parts of the lambda context that only exist
|
|
167398
167470
|
// at runtime, like the remaining time counter.
|
|
167399
167471
|
const started = Date.now()
|
|
167400
|
-
const
|
|
167472
|
+
const run = () => handler(event, {
|
|
167401
167473
|
functionName: process.env.AWS_LAMBDA_FUNCTION_NAME,
|
|
167402
167474
|
functionVersion: process.env.AWS_LAMBDA_FUNCTION_VERSION,
|
|
167403
167475
|
memoryLimitInMB: '512',
|
|
@@ -167406,6 +167478,8 @@ const server = createServer((req, res) => {
|
|
|
167406
167478
|
...context,
|
|
167407
167479
|
})
|
|
167408
167480
|
|
|
167481
|
+
const result = await (trace ? traceContext.run(trace, run) : run())
|
|
167482
|
+
|
|
167409
167483
|
response = { result: typeof result === 'undefined' ? null : result }
|
|
167410
167484
|
} catch (error) {
|
|
167411
167485
|
response = {
|
|
@@ -167537,7 +167611,7 @@ var createBundleWorker = (props) => {
|
|
|
167537
167611
|
await doStop();
|
|
167538
167612
|
await doStart();
|
|
167539
167613
|
}),
|
|
167540
|
-
async dispatch(event) {
|
|
167614
|
+
async dispatch(event, trace) {
|
|
167541
167615
|
if (workers.length === 0) {
|
|
167542
167616
|
throw new Error("The bundle worker is not running.");
|
|
167543
167617
|
}
|
|
@@ -167546,7 +167620,7 @@ var createBundleWorker = (props) => {
|
|
|
167546
167620
|
try {
|
|
167547
167621
|
const res = await fetch(`http://127.0.0.1:${worker.port}`, {
|
|
167548
167622
|
method: "POST",
|
|
167549
|
-
body: JSON.stringify({ event, context })
|
|
167623
|
+
body: JSON.stringify({ event, context, trace })
|
|
167550
167624
|
});
|
|
167551
167625
|
const body = await res.json();
|
|
167552
167626
|
if (body.error) {
|
|
@@ -167569,36 +167643,51 @@ var dashboardHtml = `<!doctype html>
|
|
|
167569
167643
|
<title>awsless dev</title>
|
|
167570
167644
|
<style>
|
|
167571
167645
|
:root {
|
|
167572
|
-
--bg:
|
|
167573
|
-
--panel:
|
|
167574
|
-
--
|
|
167575
|
-
--
|
|
167576
|
-
--
|
|
167646
|
+
--bg: hsl(220 20% 5% / 1);
|
|
167647
|
+
--panel: hsl(220 20% 8%);
|
|
167648
|
+
--hover: hsl(220 20% 12%);
|
|
167649
|
+
--border: hsl(220 18% 15%);
|
|
167650
|
+
--border-strong: hsl(220 16% 22%);
|
|
167651
|
+
--text: #ecedf2;
|
|
167652
|
+
--muted: #8b90a1;
|
|
167577
167653
|
--accent: #ff9000;
|
|
167578
|
-
--good: #
|
|
167579
|
-
--bad: #
|
|
167654
|
+
--good: #3dd68c;
|
|
167655
|
+
--bad: #ff6166;
|
|
167656
|
+
--font-sans: -apple-system, BlinkMacSystemFont, 'Segoe UI', 'Inter', Helvetica, Arial, sans-serif;
|
|
167657
|
+
--font-mono: ui-monospace, 'SF Mono', SFMono-Regular, Menlo, Consolas, monospace;
|
|
167580
167658
|
font-size: 14px;
|
|
167659
|
+
color-scheme: dark;
|
|
167581
167660
|
}
|
|
167582
167661
|
* { box-sizing: border-box; }
|
|
167662
|
+
::selection { background: rgb(255 144 0 / 25%); }
|
|
167663
|
+
::-webkit-scrollbar { width: 8px; height: 8px; }
|
|
167664
|
+
::-webkit-scrollbar-track { background: transparent; }
|
|
167665
|
+
::-webkit-scrollbar-thumb { background: rgb(255 255 255 / 10%); border-radius: 999px; }
|
|
167666
|
+
::-webkit-scrollbar-thumb:hover { background: rgb(255 255 255 / 18%); }
|
|
167667
|
+
:focus-visible { outline: 2px solid rgb(255 144 0 / 55%); outline-offset: 1px; }
|
|
167583
167668
|
body {
|
|
167584
167669
|
margin: 0;
|
|
167585
|
-
font-family:
|
|
167670
|
+
font-family: var(--font-sans);
|
|
167671
|
+
-webkit-font-smoothing: antialiased;
|
|
167586
167672
|
background: var(--bg);
|
|
167587
167673
|
color: var(--text);
|
|
167588
167674
|
display: grid;
|
|
167589
|
-
grid-template-columns:
|
|
167675
|
+
grid-template-columns: 232px 1fr;
|
|
167590
167676
|
height: 100vh;
|
|
167591
167677
|
}
|
|
167592
|
-
body.with-events { grid-template-columns:
|
|
167678
|
+
body.with-events { grid-template-columns: 232px 1fr 320px; }
|
|
167679
|
+
button { transition: background 0.15s ease, border-color 0.15s ease, color 0.15s ease; }
|
|
167680
|
+
input, select, textarea { transition: border-color 0.15s ease, box-shadow 0.15s ease; }
|
|
167593
167681
|
aside {
|
|
167594
167682
|
border-left: 1px solid var(--border);
|
|
167595
167683
|
overflow-y: auto;
|
|
167596
167684
|
padding: 12px;
|
|
167597
167685
|
}
|
|
167598
167686
|
aside h3 {
|
|
167599
|
-
font-size:
|
|
167687
|
+
font-size: 10px;
|
|
167688
|
+
font-weight: 500;
|
|
167600
167689
|
text-transform: uppercase;
|
|
167601
|
-
letter-spacing:
|
|
167690
|
+
letter-spacing: 0.08em;
|
|
167602
167691
|
color: var(--muted);
|
|
167603
167692
|
margin: 8px 8px 12px;
|
|
167604
167693
|
}
|
|
@@ -167606,34 +167695,45 @@ var dashboardHtml = `<!doctype html>
|
|
|
167606
167695
|
border-bottom: 1px solid var(--border);
|
|
167607
167696
|
padding: 8px;
|
|
167608
167697
|
font-size: 12px;
|
|
167698
|
+
font-family: var(--font-mono);
|
|
167609
167699
|
}
|
|
167700
|
+
aside .event:last-child { border-bottom: none; }
|
|
167610
167701
|
aside .event .head { display: flex; gap: 8px; align-items: baseline; }
|
|
167611
167702
|
aside .event .time { color: var(--muted); }
|
|
167612
|
-
aside .event .topic { font-weight:
|
|
167703
|
+
aside .event .topic { font-weight: 600; }
|
|
167613
167704
|
aside .event .type { color: var(--muted); }
|
|
167614
167705
|
aside .event .body {
|
|
167615
167706
|
color: var(--muted);
|
|
167616
167707
|
margin-top: 4px;
|
|
167617
|
-
|
|
167708
|
+
white-space: nowrap;
|
|
167709
|
+
overflow: hidden;
|
|
167710
|
+
text-overflow: ellipsis;
|
|
167711
|
+
}
|
|
167712
|
+
/* Hovering an event unfolds its payload in place, fully wrapped -
|
|
167713
|
+
the same behavior as the activity feed. */
|
|
167714
|
+
aside .event:hover .body {
|
|
167618
167715
|
white-space: pre-wrap;
|
|
167716
|
+
overflow: visible;
|
|
167717
|
+
word-break: break-word;
|
|
167619
167718
|
}
|
|
167620
167719
|
aside .empty { padding: 8px; }
|
|
167621
167720
|
.logs {
|
|
167622
167721
|
background: var(--panel);
|
|
167623
167722
|
border: 1px solid var(--border);
|
|
167624
|
-
border-radius:
|
|
167625
|
-
padding:
|
|
167723
|
+
border-radius: 10px;
|
|
167724
|
+
padding: 10px 12px;
|
|
167626
167725
|
margin-top: 8px;
|
|
167627
167726
|
max-height: 420px;
|
|
167628
167727
|
overflow-y: auto;
|
|
167629
167728
|
font-size: 12px;
|
|
167729
|
+
font-family: var(--font-mono);
|
|
167630
167730
|
}
|
|
167631
167731
|
.logs .line { display: flex; gap: 8px; padding: 1px 0; }
|
|
167632
167732
|
.logs .time { color: var(--muted); flex-shrink: 0; }
|
|
167633
167733
|
.logs .route { color: var(--accent); word-break: break-all; }
|
|
167634
167734
|
.logs .text { white-space: pre-wrap; word-break: break-word; }
|
|
167635
167735
|
.logs .line.error .text, .logs .entry.error .text { color: var(--bad); }
|
|
167636
|
-
.logs .entry { padding:
|
|
167736
|
+
.logs .entry { padding: 6px 0; }
|
|
167637
167737
|
.logs .entry + .entry, .logs .line + .entry, .logs .entry + .line { border-top: 1px solid var(--border); }
|
|
167638
167738
|
.logs .entry .meta { display: flex; gap: 8px; margin-bottom: 2px; }
|
|
167639
167739
|
/* Every group is its own card, with a shared grid inside: the name
|
|
@@ -167643,8 +167743,8 @@ var dashboardHtml = `<!doctype html>
|
|
|
167643
167743
|
.config-group {
|
|
167644
167744
|
background: var(--panel);
|
|
167645
167745
|
border: 1px solid var(--border);
|
|
167646
|
-
border-radius:
|
|
167647
|
-
padding:
|
|
167746
|
+
border-radius: 10px;
|
|
167747
|
+
padding: 16px 18px;
|
|
167648
167748
|
}
|
|
167649
167749
|
.config-group h3 { margin: 0 0 12px; }
|
|
167650
167750
|
.config-fields {
|
|
@@ -167654,7 +167754,7 @@ var dashboardHtml = `<!doctype html>
|
|
|
167654
167754
|
align-items: center;
|
|
167655
167755
|
}
|
|
167656
167756
|
.config-fields .field { display: contents; }
|
|
167657
|
-
.config-fields .name { color: var(--muted); overflow-wrap: anywhere; }
|
|
167757
|
+
.config-fields .name { color: var(--muted); overflow-wrap: anywhere; font-family: var(--font-mono); font-size: 12.5px; }
|
|
167658
167758
|
.config-fields input {
|
|
167659
167759
|
background: var(--bg);
|
|
167660
167760
|
color: var(--text);
|
|
@@ -167663,17 +167763,23 @@ var dashboardHtml = `<!doctype html>
|
|
|
167663
167763
|
padding: 6px 10px;
|
|
167664
167764
|
font: inherit;
|
|
167665
167765
|
}
|
|
167766
|
+
.config-fields input:hover { border-color: var(--border-strong); }
|
|
167767
|
+
.config-fields input:focus { border-color: #5b6272; box-shadow: 0 0 0 3px rgb(255 255 255 / 14%); outline: none; }
|
|
167666
167768
|
.config-fields input::placeholder { color: var(--muted); }
|
|
167667
167769
|
.groups { display: flex; flex-wrap: wrap; gap: 4px 16px; }
|
|
167668
167770
|
.groups .group { display: flex; align-items: center; gap: 4px; cursor: pointer; }
|
|
167669
167771
|
nav {
|
|
167670
167772
|
border-right: 1px solid var(--border);
|
|
167671
167773
|
overflow-y: auto;
|
|
167672
|
-
padding: 12px;
|
|
167774
|
+
padding: 14px 12px;
|
|
167775
|
+
/* The menu scrolls, but never shows a permanent scrollbar. */
|
|
167776
|
+
scrollbar-width: none;
|
|
167673
167777
|
}
|
|
167778
|
+
nav::-webkit-scrollbar { display: none; }
|
|
167674
167779
|
nav h1 {
|
|
167675
167780
|
font-size: 15px;
|
|
167676
|
-
|
|
167781
|
+
font-family: var(--font-mono);
|
|
167782
|
+
margin: 4px 8px 18px;
|
|
167677
167783
|
cursor: pointer;
|
|
167678
167784
|
}
|
|
167679
167785
|
/* The same two-tone logo as the cli: bold AWS in the brand orange,
|
|
@@ -167683,25 +167789,27 @@ var dashboardHtml = `<!doctype html>
|
|
|
167683
167789
|
nav h1 .cmd { color: var(--muted); font-weight: normal; }
|
|
167684
167790
|
nav h3 {
|
|
167685
167791
|
font-size: 10px;
|
|
167792
|
+
font-weight: 500;
|
|
167686
167793
|
text-transform: uppercase;
|
|
167687
|
-
letter-spacing:
|
|
167794
|
+
letter-spacing: 0.08em;
|
|
167688
167795
|
color: var(--muted);
|
|
167689
|
-
margin:
|
|
167796
|
+
margin: 18px 8px 6px;
|
|
167690
167797
|
}
|
|
167691
167798
|
nav button {
|
|
167692
167799
|
display: flex;
|
|
167693
167800
|
align-items: center;
|
|
167694
|
-
gap:
|
|
167801
|
+
gap: 9px;
|
|
167695
167802
|
width: 100%;
|
|
167696
167803
|
background: none;
|
|
167697
167804
|
border: none;
|
|
167698
|
-
color: var(--
|
|
167805
|
+
color: var(--muted);
|
|
167699
167806
|
font: inherit;
|
|
167807
|
+
font-size: 13.5px;
|
|
167700
167808
|
padding: 6px 8px;
|
|
167701
167809
|
border-radius: 6px;
|
|
167702
167810
|
cursor: pointer;
|
|
167703
167811
|
}
|
|
167704
|
-
nav button .count { margin-left: auto; }
|
|
167812
|
+
nav button .count { margin-left: auto; font-size: 12px; }
|
|
167705
167813
|
nav button.reseed { margin-top: auto; color: var(--muted); }
|
|
167706
167814
|
nav button.reseed:disabled { cursor: default; }
|
|
167707
167815
|
.icon {
|
|
@@ -167710,34 +167818,37 @@ var dashboardHtml = `<!doctype html>
|
|
|
167710
167818
|
flex-shrink: 0;
|
|
167711
167819
|
display: inline-flex;
|
|
167712
167820
|
color: var(--muted);
|
|
167821
|
+
transition: color 0.15s ease;
|
|
167713
167822
|
}
|
|
167714
167823
|
.icon svg { width: 100%; height: 100%; }
|
|
167715
167824
|
nav button.active .icon, .row:hover .icon { color: var(--accent); }
|
|
167716
|
-
main h2 { display: flex; align-items: center; gap:
|
|
167717
|
-
main h2 .icon { width:
|
|
167718
|
-
nav button:hover { background: var(--
|
|
167719
|
-
nav button.active { background: var(--
|
|
167825
|
+
main h2 { display: flex; align-items: center; gap: 9px; }
|
|
167826
|
+
main h2 .icon { width: 18px; height: 18px; }
|
|
167827
|
+
nav button:hover { background: var(--hover); color: var(--text); }
|
|
167828
|
+
nav button.active { background: var(--hover); color: var(--text); }
|
|
167720
167829
|
nav button .count { color: var(--muted); }
|
|
167721
|
-
main { padding:
|
|
167722
|
-
main h2 { margin: 0 0 4px; font-size:
|
|
167723
|
-
main .detail { color: var(--muted); margin-bottom: 16px; word-break: break-all; }
|
|
167830
|
+
main { padding: 24px 28px; overflow-y: auto; }
|
|
167831
|
+
main h2 { margin: 0 0 4px; font-size: 18px; font-weight: 600; letter-spacing: -0.01em; }
|
|
167832
|
+
main .detail { color: var(--muted); margin-bottom: 16px; word-break: break-all; font-size: 13px; }
|
|
167724
167833
|
main .back {
|
|
167725
167834
|
display: inline-block;
|
|
167726
167835
|
background: none;
|
|
167727
167836
|
border: none;
|
|
167728
167837
|
color: var(--muted);
|
|
167729
167838
|
font: inherit;
|
|
167839
|
+
font-size: 13px;
|
|
167730
167840
|
padding: 0;
|
|
167731
167841
|
margin-bottom: 12px;
|
|
167732
167842
|
cursor: pointer;
|
|
167733
167843
|
}
|
|
167734
|
-
main .back:hover { color: var(--
|
|
167844
|
+
main .back:hover { color: var(--text); }
|
|
167735
167845
|
main h3 {
|
|
167736
167846
|
font-size: 11px;
|
|
167847
|
+
font-weight: 500;
|
|
167737
167848
|
text-transform: uppercase;
|
|
167738
|
-
letter-spacing:
|
|
167849
|
+
letter-spacing: 0.08em;
|
|
167739
167850
|
color: var(--muted);
|
|
167740
|
-
margin:
|
|
167851
|
+
margin: 26px 0 8px;
|
|
167741
167852
|
}
|
|
167742
167853
|
.feed .row { cursor: default; }
|
|
167743
167854
|
.feed .empty { padding: 8px; }
|
|
@@ -167750,9 +167861,15 @@ var dashboardHtml = `<!doctype html>
|
|
|
167750
167861
|
padding: 6px 10px;
|
|
167751
167862
|
font: inherit;
|
|
167752
167863
|
}
|
|
167864
|
+
.filters input:hover, .filters select:hover { border-color: var(--border-strong); }
|
|
167865
|
+
.filters input:focus, .filters select:focus {
|
|
167866
|
+
border-color: #5b6272;
|
|
167867
|
+
box-shadow: 0 0 0 3px rgb(255 255 255 / 14%);
|
|
167868
|
+
outline: none;
|
|
167869
|
+
}
|
|
167753
167870
|
.filters input { flex: 1; }
|
|
167754
167871
|
.filters input::placeholder { color: var(--muted); }
|
|
167755
|
-
.filters .count { color: var(--muted); align-self: center; white-space: nowrap; }
|
|
167872
|
+
.filters .count { color: var(--muted); align-self: center; white-space: nowrap; font-size: 13px; }
|
|
167756
167873
|
/* The stack & name columns share one grid across every row, so the
|
|
167757
167874
|
names line up no matter how long each stack name is. */
|
|
167758
167875
|
.rows { display: grid; grid-template-columns: fit-content(280px) 1fr auto; }
|
|
@@ -167766,15 +167883,29 @@ var dashboardHtml = `<!doctype html>
|
|
|
167766
167883
|
text-align: left;
|
|
167767
167884
|
background: none;
|
|
167768
167885
|
border: none;
|
|
167769
|
-
border-bottom: 1px solid var(--border);
|
|
167770
167886
|
color: var(--text);
|
|
167771
167887
|
font: inherit;
|
|
167772
|
-
padding:
|
|
167888
|
+
padding: 9px 10px;
|
|
167773
167889
|
cursor: pointer;
|
|
167890
|
+
border-radius: 8px;
|
|
167891
|
+
position: relative;
|
|
167892
|
+
transition: background 0.15s ease;
|
|
167893
|
+
}
|
|
167894
|
+
/* The separator is its own straight hairline instead of a border,
|
|
167895
|
+
so the rounded hover highlight never bends the line at the ends. */
|
|
167896
|
+
.row::after {
|
|
167897
|
+
content: '';
|
|
167898
|
+
position: absolute;
|
|
167899
|
+
left: 0;
|
|
167900
|
+
right: 0;
|
|
167901
|
+
bottom: 0;
|
|
167902
|
+
height: 1px;
|
|
167903
|
+
background: var(--border);
|
|
167774
167904
|
}
|
|
167775
|
-
.row:
|
|
167905
|
+
.row:last-child::after { display: none; }
|
|
167906
|
+
.row:hover { background: var(--hover); }
|
|
167776
167907
|
a.row { text-decoration: none; }
|
|
167777
|
-
.health { display: flex; flex-wrap: wrap; gap: 8px; margin:
|
|
167908
|
+
.health { display: flex; flex-wrap: wrap; gap: 8px; margin: 14px 0 4px; }
|
|
167778
167909
|
.health .chip {
|
|
167779
167910
|
display: inline-flex;
|
|
167780
167911
|
align-items: center;
|
|
@@ -167784,9 +167915,16 @@ var dashboardHtml = `<!doctype html>
|
|
|
167784
167915
|
border-radius: 999px;
|
|
167785
167916
|
padding: 4px 12px;
|
|
167786
167917
|
font-size: 12px;
|
|
167918
|
+
font-family: var(--font-mono);
|
|
167787
167919
|
}
|
|
167788
|
-
.health .dot {
|
|
167789
|
-
|
|
167920
|
+
.health .dot {
|
|
167921
|
+
width: 7px;
|
|
167922
|
+
height: 7px;
|
|
167923
|
+
border-radius: 50%;
|
|
167924
|
+
background: var(--good);
|
|
167925
|
+
flex-shrink: 0;
|
|
167926
|
+
}
|
|
167927
|
+
.health .chip.down { border-color: rgb(255 97 102 / 45%); background: rgb(255 97 102 / 8%); }
|
|
167790
167928
|
.health .chip.down .dot { background: var(--bad); }
|
|
167791
167929
|
.health .chip .detail-text { color: var(--muted); }
|
|
167792
167930
|
.home-cols {
|
|
@@ -167795,20 +167933,68 @@ var dashboardHtml = `<!doctype html>
|
|
|
167795
167933
|
gap: 0 20px;
|
|
167796
167934
|
align-items: start;
|
|
167797
167935
|
}
|
|
167798
|
-
|
|
167799
|
-
.
|
|
167936
|
+
.logs .route.link { cursor: pointer; }
|
|
167937
|
+
.logs .route.link:hover { text-decoration: underline; }
|
|
167938
|
+
.logs .took { color: var(--muted); margin-left: auto; flex-shrink: 0; }
|
|
167939
|
+
.logs .payload {
|
|
167940
|
+
color: var(--muted);
|
|
167941
|
+
white-space: nowrap;
|
|
167942
|
+
overflow: hidden;
|
|
167943
|
+
text-overflow: ellipsis;
|
|
167944
|
+
}
|
|
167945
|
+
/* Hovering an entry unfolds its payload in place, fully wrapped. */
|
|
167946
|
+
.logs .entry:hover .payload {
|
|
167947
|
+
white-space: pre-wrap;
|
|
167948
|
+
overflow: visible;
|
|
167949
|
+
word-break: break-word;
|
|
167950
|
+
}
|
|
167951
|
+
/* The trace chip appears once a dispatch has trace siblings & opens
|
|
167952
|
+
the trace tree of the whole request chain. */
|
|
167953
|
+
.logs .trace-link {
|
|
167954
|
+
color: var(--accent);
|
|
167955
|
+
cursor: pointer;
|
|
167956
|
+
flex-shrink: 0;
|
|
167957
|
+
}
|
|
167958
|
+
.logs .trace-link:hover { text-decoration: underline; }
|
|
167959
|
+
.overlay {
|
|
167960
|
+
position: fixed;
|
|
167961
|
+
inset: 0;
|
|
167962
|
+
background: rgb(0 0 0 / 60%);
|
|
167963
|
+
backdrop-filter: blur(6px);
|
|
167964
|
+
-webkit-backdrop-filter: blur(6px);
|
|
167965
|
+
display: flex;
|
|
167966
|
+
align-items: center;
|
|
167967
|
+
justify-content: center;
|
|
167968
|
+
z-index: 50;
|
|
167969
|
+
}
|
|
167970
|
+
.overlay .modal {
|
|
167800
167971
|
background: var(--panel);
|
|
167801
|
-
border: 1px solid var(--border);
|
|
167802
|
-
border-radius:
|
|
167803
|
-
|
|
167804
|
-
|
|
167805
|
-
max-height:
|
|
167972
|
+
border: 1px solid var(--border-strong);
|
|
167973
|
+
border-radius: 12px;
|
|
167974
|
+
box-shadow: 0 12px 48px rgb(0 0 0 / 60%);
|
|
167975
|
+
width: min(760px, 92vw);
|
|
167976
|
+
max-height: 82vh;
|
|
167806
167977
|
overflow-y: auto;
|
|
167807
|
-
|
|
167978
|
+
padding: 18px 22px;
|
|
167979
|
+
}
|
|
167980
|
+
.overlay .modal-head { display: flex; align-items: baseline; gap: 10px; }
|
|
167981
|
+
.overlay .modal-head h3 { margin: 0; font-family: var(--font-mono); }
|
|
167982
|
+
.overlay .modal-head .detail { color: var(--muted); font-size: 12px; }
|
|
167983
|
+
.overlay .modal-head button {
|
|
167984
|
+
margin-left: auto;
|
|
167985
|
+
background: none;
|
|
167986
|
+
border: none;
|
|
167987
|
+
color: var(--muted);
|
|
167988
|
+
font-size: 16px;
|
|
167989
|
+
cursor: pointer;
|
|
167990
|
+
border-radius: 6px;
|
|
167991
|
+
padding: 2px 8px;
|
|
167808
167992
|
}
|
|
167809
|
-
.
|
|
167810
|
-
|
|
167811
|
-
|
|
167993
|
+
.overlay .modal-head button:hover { color: var(--text); background: var(--hover); }
|
|
167994
|
+
/* The tree rows reuse the log entry format, the guide marks the
|
|
167995
|
+
parent-child steps of the chain. */
|
|
167996
|
+
.trace-tree { max-height: none; }
|
|
167997
|
+
.trace-tree .entry .guide { color: var(--muted); flex-shrink: 0; }
|
|
167812
167998
|
.row.problem .id { color: var(--bad); }
|
|
167813
167999
|
.empty.good { color: var(--good); }
|
|
167814
168000
|
.row .stack {
|
|
@@ -167817,13 +168003,17 @@ var dashboardHtml = `<!doctype html>
|
|
|
167817
168003
|
overflow: hidden;
|
|
167818
168004
|
text-overflow: ellipsis;
|
|
167819
168005
|
white-space: nowrap;
|
|
168006
|
+
font-family: var(--font-mono);
|
|
168007
|
+
font-size: 12.5px;
|
|
167820
168008
|
}
|
|
167821
168009
|
.row .id {
|
|
167822
|
-
font-weight:
|
|
168010
|
+
font-weight: 500;
|
|
167823
168011
|
min-width: 0;
|
|
167824
168012
|
overflow: hidden;
|
|
167825
168013
|
text-overflow: ellipsis;
|
|
167826
168014
|
white-space: nowrap;
|
|
168015
|
+
font-family: var(--font-mono);
|
|
168016
|
+
font-size: 12.5px;
|
|
167827
168017
|
}
|
|
167828
168018
|
.row .info {
|
|
167829
168019
|
color: var(--muted);
|
|
@@ -167832,13 +168022,14 @@ var dashboardHtml = `<!doctype html>
|
|
|
167832
168022
|
text-overflow: ellipsis;
|
|
167833
168023
|
white-space: nowrap;
|
|
167834
168024
|
max-width: 100%;
|
|
168025
|
+
font-size: 12.5px;
|
|
167835
168026
|
}
|
|
167836
168027
|
.email-body {
|
|
167837
168028
|
width: 100%;
|
|
167838
168029
|
min-height: 480px;
|
|
167839
168030
|
background: #fff;
|
|
167840
168031
|
border: 1px solid var(--border);
|
|
167841
|
-
border-radius:
|
|
168032
|
+
border-radius: 10px;
|
|
167842
168033
|
margin-top: 12px;
|
|
167843
168034
|
}
|
|
167844
168035
|
textarea {
|
|
@@ -167847,47 +168038,58 @@ var dashboardHtml = `<!doctype html>
|
|
|
167847
168038
|
background: var(--panel);
|
|
167848
168039
|
color: var(--text);
|
|
167849
168040
|
border: 1px solid var(--border);
|
|
167850
|
-
border-radius:
|
|
167851
|
-
padding:
|
|
167852
|
-
font:
|
|
168041
|
+
border-radius: 10px;
|
|
168042
|
+
padding: 12px;
|
|
168043
|
+
font-family: var(--font-mono);
|
|
168044
|
+
font-size: 12.5px;
|
|
167853
168045
|
resize: vertical;
|
|
167854
168046
|
}
|
|
168047
|
+
textarea:hover { border-color: var(--border-strong); }
|
|
168048
|
+
textarea:focus { border-color: #5b6272; box-shadow: 0 0 0 3px rgb(255 255 255 / 14%); outline: none; }
|
|
167855
168049
|
.actions { margin: 12px 0; display: flex; gap: 8px; align-items: center; }
|
|
167856
|
-
.actions .status { color: var(--muted); }
|
|
168050
|
+
.actions .status { color: var(--muted); font-size: 13px; }
|
|
168051
|
+
/* Action buttons in the x.ai style: white pill primary, outlined
|
|
168052
|
+
ghost secondary. */
|
|
167857
168053
|
button.primary {
|
|
167858
|
-
background:
|
|
167859
|
-
color: #
|
|
168054
|
+
background: #fff;
|
|
168055
|
+
color: #0a0a0a;
|
|
167860
168056
|
border: none;
|
|
167861
|
-
border-radius:
|
|
167862
|
-
padding: 7px
|
|
168057
|
+
border-radius: 999px;
|
|
168058
|
+
padding: 7px 18px;
|
|
167863
168059
|
font: inherit;
|
|
167864
|
-
font-weight:
|
|
168060
|
+
font-weight: 500;
|
|
167865
168061
|
cursor: pointer;
|
|
167866
168062
|
}
|
|
168063
|
+
button.primary:hover { background: #d9d9de; }
|
|
167867
168064
|
button.primary:disabled { opacity: 0.5; cursor: wait; }
|
|
167868
168065
|
button.secondary {
|
|
167869
|
-
background:
|
|
168066
|
+
background: transparent;
|
|
167870
168067
|
color: var(--text);
|
|
167871
|
-
border: 1px solid var(--border);
|
|
167872
|
-
border-radius:
|
|
167873
|
-
padding: 6px
|
|
168068
|
+
border: 1px solid var(--border-strong);
|
|
168069
|
+
border-radius: 999px;
|
|
168070
|
+
padding: 6px 18px;
|
|
167874
168071
|
font: inherit;
|
|
167875
168072
|
cursor: pointer;
|
|
167876
168073
|
}
|
|
168074
|
+
button.secondary:hover { background: var(--hover); border-color: #3d3d44; }
|
|
167877
168075
|
pre.result {
|
|
167878
168076
|
background: var(--panel);
|
|
167879
168077
|
border: 1px solid var(--border);
|
|
167880
|
-
border-radius:
|
|
167881
|
-
padding: 12px;
|
|
168078
|
+
border-radius: 10px;
|
|
168079
|
+
padding: 12px 14px;
|
|
167882
168080
|
overflow-x: auto;
|
|
167883
168081
|
white-space: pre-wrap;
|
|
167884
168082
|
word-break: break-word;
|
|
168083
|
+
font-family: var(--font-mono);
|
|
168084
|
+
font-size: 12.5px;
|
|
167885
168085
|
}
|
|
167886
|
-
pre.result.error { border-color:
|
|
167887
|
-
|
|
168086
|
+
pre.result.error { border-color: rgb(255 97 102 / 45%); color: var(--bad); }
|
|
168087
|
+
/* Tables in the vercel style: horizontal hairlines only, quiet
|
|
168088
|
+
uppercase headers. */
|
|
168089
|
+
table { border-collapse: collapse; width: 100%; font-family: var(--font-mono); font-size: 12.5px; }
|
|
167888
168090
|
th, td {
|
|
167889
|
-
border: 1px solid var(--border);
|
|
167890
|
-
padding:
|
|
168091
|
+
border-bottom: 1px solid var(--border);
|
|
168092
|
+
padding: 8px 12px;
|
|
167891
168093
|
text-align: left;
|
|
167892
168094
|
vertical-align: top;
|
|
167893
168095
|
max-width: 360px;
|
|
@@ -167895,7 +168097,16 @@ var dashboardHtml = `<!doctype html>
|
|
|
167895
168097
|
text-overflow: ellipsis;
|
|
167896
168098
|
white-space: nowrap;
|
|
167897
168099
|
}
|
|
167898
|
-
th {
|
|
168100
|
+
th {
|
|
168101
|
+
color: var(--muted);
|
|
168102
|
+
font-weight: 500;
|
|
168103
|
+
font-family: var(--font-sans);
|
|
168104
|
+
font-size: 11px;
|
|
168105
|
+
text-transform: uppercase;
|
|
168106
|
+
letter-spacing: 0.08em;
|
|
168107
|
+
}
|
|
168108
|
+
tbody tr { transition: background 0.15s ease; }
|
|
168109
|
+
tbody tr:hover { background: var(--hover); }
|
|
167899
168110
|
td:hover { white-space: normal; word-break: break-all; }
|
|
167900
168111
|
.empty { color: var(--muted); }
|
|
167901
168112
|
</style>
|
|
@@ -168320,6 +168531,50 @@ const rpcPanel = (main, r) => {
|
|
|
168320
168531
|
// A terminal-style view streaming a resource's live event channel,
|
|
168321
168532
|
// like the dev server output of a site. The bus replays the recent
|
|
168322
168533
|
// lines, so the boot output shows even when the panel opens later.
|
|
168534
|
+
// Resolve a feed label back to its resource: route keys match
|
|
168535
|
+
// directly, while queue/stream/topic labels carry the physical name
|
|
168536
|
+
// their resource lists as its detail.
|
|
168537
|
+
const findRouteResource = route => {
|
|
168538
|
+
const direct = state.resources.find(r => r.routeKey === route)
|
|
168539
|
+
|
|
168540
|
+
if (direct) {
|
|
168541
|
+
return direct
|
|
168542
|
+
}
|
|
168543
|
+
|
|
168544
|
+
const [kind, name] = route.split(' ')
|
|
168545
|
+
|
|
168546
|
+
if (!name) {
|
|
168547
|
+
return undefined
|
|
168548
|
+
}
|
|
168549
|
+
|
|
168550
|
+
if (kind === 'queue') {
|
|
168551
|
+
return state.resources.find(r => r.kind === 'queue' && r.detail === name)
|
|
168552
|
+
}
|
|
168553
|
+
|
|
168554
|
+
if (kind === 'stream') {
|
|
168555
|
+
return state.resources.find(r => r.kind === 'table' && r.detail === name)
|
|
168556
|
+
}
|
|
168557
|
+
|
|
168558
|
+
if (kind === 'topic') {
|
|
168559
|
+
return state.resources.find(r => r.kind === 'topic' && r.detail === name)
|
|
168560
|
+
}
|
|
168561
|
+
|
|
168562
|
+
return undefined
|
|
168563
|
+
}
|
|
168564
|
+
|
|
168565
|
+
// A route tag that links through to its resource, shared by the log
|
|
168566
|
+
// feeds & the activity feed.
|
|
168567
|
+
const routeTag = route => {
|
|
168568
|
+
const resource = findRouteResource(route)
|
|
168569
|
+
const tag = $('span', { className: 'route' + (resource ? ' link' : ''), title: route }, route)
|
|
168570
|
+
|
|
168571
|
+
if (resource) {
|
|
168572
|
+
tag.onclick = () => selectResource(resource)
|
|
168573
|
+
}
|
|
168574
|
+
|
|
168575
|
+
return tag
|
|
168576
|
+
}
|
|
168577
|
+
|
|
168323
168578
|
const attachLogFeed = (main, channel, route, title = 'Logs') => {
|
|
168324
168579
|
if (title) {
|
|
168325
168580
|
main.append($('h3', {}, title))
|
|
@@ -168351,7 +168606,7 @@ const attachLogFeed = (main, channel, route, title = 'Logs') => {
|
|
|
168351
168606
|
feed.append($('div', { className: 'entry' + error }, [
|
|
168352
168607
|
$('div', { className: 'meta' }, [
|
|
168353
168608
|
$('span', { className: 'time' }, new Date(data.date).toLocaleTimeString()),
|
|
168354
|
-
showRoute ?
|
|
168609
|
+
showRoute ? routeTag(data.route) : '',
|
|
168355
168610
|
]),
|
|
168356
168611
|
$('div', { className: 'text' }, data.line),
|
|
168357
168612
|
]))
|
|
@@ -169202,15 +169457,21 @@ const render = () => {
|
|
|
169202
169457
|
nav.append(reseed)
|
|
169203
169458
|
}
|
|
169204
169459
|
|
|
169460
|
+
// Every view renders into its own container: navigating detaches
|
|
169461
|
+
// the old one, so a slow async panel (like a table scan) finishing
|
|
169462
|
+
// after the switch appends into a dead node instead of the screen.
|
|
169205
169463
|
const main = document.getElementById('main')
|
|
169206
169464
|
main.innerHTML = ''
|
|
169207
169465
|
|
|
169466
|
+
const page = $('div')
|
|
169467
|
+
main.append(page)
|
|
169468
|
+
|
|
169208
169469
|
if (view.resource) {
|
|
169209
|
-
renderResource(
|
|
169470
|
+
renderResource(page)
|
|
169210
169471
|
} else if (view.kind) {
|
|
169211
|
-
renderList(
|
|
169472
|
+
renderList(page)
|
|
169212
169473
|
} else {
|
|
169213
|
-
renderHome(
|
|
169474
|
+
renderHome(page)
|
|
169214
169475
|
}
|
|
169215
169476
|
}
|
|
169216
169477
|
|
|
@@ -169357,35 +169618,139 @@ const renderHome = main => {
|
|
|
169357
169618
|
|
|
169358
169619
|
activityCol.append($('h3', {}, 'Activity'))
|
|
169359
169620
|
|
|
169360
|
-
const
|
|
169361
|
-
|
|
169362
|
-
|
|
169621
|
+
const activityFeed = $('div', { className: 'logs' }, $('p', { className: 'empty' }, 'Nothing ran yet.'))
|
|
169622
|
+
activityCol.append(activityFeed)
|
|
169623
|
+
|
|
169624
|
+
// The recent dispatches kept as data, not just DOM - the trace tree
|
|
169625
|
+
// renders straight from this buffer. It outlives the visible feed,
|
|
169626
|
+
// so a chain's early spans stay renderable after the feed pruned them.
|
|
169627
|
+
const activityData = []
|
|
169628
|
+
const traceCounts = new Map()
|
|
169629
|
+
|
|
169630
|
+
const closeTrace = () => {
|
|
169631
|
+
document.querySelector('.overlay')?.remove()
|
|
169632
|
+
}
|
|
169633
|
+
|
|
169634
|
+
// The trace tree: the whole request chain of one trace as nested
|
|
169635
|
+
// spans - what ran, what caused it, how long each step took & where
|
|
169636
|
+
// it failed. Children hang under their caller in dispatch order.
|
|
169637
|
+
const openTrace = traceId => {
|
|
169638
|
+
closeTrace()
|
|
169639
|
+
|
|
169640
|
+
const entries = activityData.filter(entry => entry.trace === traceId)
|
|
169641
|
+
|
|
169642
|
+
if (entries.length === 0) {
|
|
169643
|
+
return
|
|
169644
|
+
}
|
|
169645
|
+
|
|
169646
|
+
const started = Math.min(...entries.map(entry => entry.date))
|
|
169647
|
+
const ended = Math.max(...entries.map(entry => entry.date + entry.ms))
|
|
169648
|
+
const failed = entries.some(entry => !entry.ok)
|
|
169649
|
+
|
|
169650
|
+
const tree = $('div', { className: 'logs trace-tree' })
|
|
169651
|
+
const spans = new Set(entries.map(entry => entry.span))
|
|
169652
|
+
|
|
169653
|
+
// A span whose parent already fell out of the buffer renders as
|
|
169654
|
+
// its own root instead of vanishing.
|
|
169655
|
+
const roots = entries.filter(entry => !entry.parent || !spans.has(entry.parent))
|
|
169656
|
+
|
|
169657
|
+
const renderSpan = (entry, depth) => {
|
|
169658
|
+
const guide = $('span', { className: 'guide' }, '\\u2514')
|
|
169659
|
+
guide.style.paddingLeft = ((depth - 1) * 18) + 'px'
|
|
169660
|
+
|
|
169661
|
+
tree.append($('div', { className: 'entry' + (entry.ok ? '' : ' error') }, [
|
|
169662
|
+
$('div', { className: 'meta' }, [
|
|
169663
|
+
depth > 0 ? guide : '',
|
|
169664
|
+
$('span', { className: 'time' }, new Date(entry.date).toLocaleTimeString()),
|
|
169665
|
+
routeTag(entry.route),
|
|
169666
|
+
$('span', { className: 'took' }, (entry.ok ? '' : '\\u2717 ') + entry.ms + 'ms'),
|
|
169667
|
+
]),
|
|
169668
|
+
entry.ok ? '' : $('div', { className: 'text', title: entry.error ?? '' }, entry.error ?? 'failed'),
|
|
169669
|
+
entry.payload ? $('div', { className: 'payload' }, entry.payload) : '',
|
|
169670
|
+
]))
|
|
169671
|
+
|
|
169672
|
+
for (const child of entries.filter(other => other.parent === entry.span)) {
|
|
169673
|
+
renderSpan(child, depth + 1)
|
|
169674
|
+
}
|
|
169675
|
+
}
|
|
169676
|
+
|
|
169677
|
+
for (const root of roots) {
|
|
169678
|
+
renderSpan(root, 0)
|
|
169679
|
+
}
|
|
169680
|
+
|
|
169681
|
+
const close = $('button', { title: 'Close' }, '\\u2715')
|
|
169682
|
+
const overlay = $('div', { className: 'overlay' }, $('div', { className: 'modal' }, [
|
|
169683
|
+
$('div', { className: 'modal-head' }, [
|
|
169684
|
+
$('h3', {}, 'Trace ' + traceId),
|
|
169685
|
+
$('span', { className: 'detail' },
|
|
169686
|
+
entries.length + ' spans \\u00b7 ' + (ended - started) + 'ms' + (failed ? ' \\u00b7 failed' : '')),
|
|
169687
|
+
close,
|
|
169688
|
+
]),
|
|
169689
|
+
tree,
|
|
169690
|
+
]))
|
|
169691
|
+
|
|
169692
|
+
close.onclick = closeTrace
|
|
169693
|
+
overlay.onclick = event => {
|
|
169694
|
+
if (event.target === overlay) closeTrace()
|
|
169695
|
+
}
|
|
169363
169696
|
|
|
169364
|
-
|
|
169365
|
-
|
|
169697
|
+
document.body.append(overlay)
|
|
169698
|
+
}
|
|
169366
169699
|
|
|
169367
|
-
const
|
|
169700
|
+
const traceChip = traceId => {
|
|
169701
|
+
const chip = $('span', { className: 'trace-link', title: 'View the whole request chain' }, 'trace')
|
|
169702
|
+
chip.onclick = () => openTrace(traceId)
|
|
169703
|
+
return chip
|
|
169704
|
+
}
|
|
169705
|
+
|
|
169706
|
+
// A lone dispatch shows no chip - once a second span of its trace
|
|
169707
|
+
// arrives, every entry of the chain gets one, retroactively.
|
|
169708
|
+
const markTraced = traceId => {
|
|
169709
|
+
for (const entry of activityFeed.querySelectorAll('[data-trace="' + traceId + '"]')) {
|
|
169710
|
+
if (!entry.querySelector('.trace-link')) {
|
|
169711
|
+
entry.querySelector('.meta')?.append(traceChip(traceId))
|
|
169712
|
+
}
|
|
169713
|
+
}
|
|
169714
|
+
}
|
|
169368
169715
|
|
|
169369
169716
|
const activityRow = data => {
|
|
169370
|
-
|
|
169717
|
+
activityFeed.querySelector('.empty')?.remove()
|
|
169718
|
+
|
|
169719
|
+
activityData.push(data)
|
|
169720
|
+
|
|
169721
|
+
while (activityData.length > 200) {
|
|
169722
|
+
activityData.shift()
|
|
169723
|
+
}
|
|
169371
169724
|
|
|
169372
|
-
|
|
169373
|
-
|
|
169374
|
-
|
|
169375
|
-
|
|
169376
|
-
$('
|
|
169725
|
+
// The same entry format as the log feeds: meta header with the
|
|
169726
|
+
// linked route tag & the duration, the payload truncated on its
|
|
169727
|
+
// own line with the full value on hover.
|
|
169728
|
+
const row = $('div', { className: 'entry' + (data.ok ? '' : ' error') }, [
|
|
169729
|
+
$('div', { className: 'meta' }, [
|
|
169730
|
+
$('span', { className: 'time' }, new Date(data.date).toLocaleTimeString()),
|
|
169731
|
+
routeTag(data.route),
|
|
169732
|
+
$('span', { className: 'took' }, (data.ok ? '' : '\\u2717 ') + data.ms + 'ms'),
|
|
169733
|
+
]),
|
|
169734
|
+
data.ok ? '' : $('div', { className: 'text', title: data.error ?? '' }, data.error ?? 'failed'),
|
|
169735
|
+
data.payload ? $('div', { className: 'payload' }, data.payload) : '',
|
|
169377
169736
|
])
|
|
169378
169737
|
|
|
169379
|
-
if (
|
|
169380
|
-
row.
|
|
169738
|
+
if (data.trace) {
|
|
169739
|
+
row.setAttribute('data-trace', data.trace)
|
|
169740
|
+
traceCounts.set(data.trace, (traceCounts.get(data.trace) ?? 0) + 1)
|
|
169381
169741
|
}
|
|
169382
169742
|
|
|
169383
|
-
|
|
169384
|
-
activityRows.push(row)
|
|
169743
|
+
activityFeed.append(row)
|
|
169385
169744
|
|
|
169386
|
-
|
|
169387
|
-
|
|
169745
|
+
if (data.trace && traceCounts.get(data.trace) > 1) {
|
|
169746
|
+
markTraced(data.trace)
|
|
169388
169747
|
}
|
|
169748
|
+
|
|
169749
|
+
while (activityFeed.children.length > 50) {
|
|
169750
|
+
activityFeed.firstChild.remove()
|
|
169751
|
+
}
|
|
169752
|
+
|
|
169753
|
+
activityFeed.scrollTop = activityFeed.scrollHeight
|
|
169389
169754
|
}
|
|
169390
169755
|
|
|
169391
169756
|
const activitySource = new EventSource('/api/events?channel=activity')
|
|
@@ -169403,6 +169768,7 @@ const renderHome = main => {
|
|
|
169403
169768
|
|
|
169404
169769
|
cleanupPanel = () => {
|
|
169405
169770
|
clearInterval(uptimeTimer)
|
|
169771
|
+
closeTrace()
|
|
169406
169772
|
healthSource.close()
|
|
169407
169773
|
problemSource.close()
|
|
169408
169774
|
activitySource.close()
|
|
@@ -169435,6 +169801,7 @@ try {
|
|
|
169435
169801
|
id: route.pattern,
|
|
169436
169802
|
stack: route.routeKey ? route.routeKey.split(':')[0] : undefined,
|
|
169437
169803
|
router: route.routerId,
|
|
169804
|
+
routeKey: route.routeKey,
|
|
169438
169805
|
detail: route.routeKey ?? ('proxy \u2192 ' + route.proxy),
|
|
169439
169806
|
url: 'http://localhost:' + state.routerPorts[route.routerId] + route.pattern.split('{')[0].replace(/\\*$/, ''),
|
|
169440
169807
|
})),
|
|
@@ -169833,7 +170200,8 @@ var createFailureReporter = (props) => {
|
|
|
169833
170200
|
return;
|
|
169834
170201
|
}
|
|
169835
170202
|
const event = JSON.parse(stringify5(format4(report)));
|
|
169836
|
-
|
|
170203
|
+
const parent = report.error?.trace;
|
|
170204
|
+
props.dispatch(formatRoutePayload2(CONSUMER_ROUTE, event), parent).catch((error3) => {
|
|
169837
170205
|
props.log(`The on-failure consumer itself failed: ${error3 instanceof Error ? error3.message : String(error3)}`);
|
|
169838
170206
|
});
|
|
169839
170207
|
};
|
|
@@ -169906,10 +170274,11 @@ var createLambdaServer = (props) => {
|
|
|
169906
170274
|
}
|
|
169907
170275
|
const type2 = String(req.headers["x-amz-invocation-type"] ?? "RequestResponse");
|
|
169908
170276
|
const event = JSON.parse(body.toString() || "{}");
|
|
170277
|
+
const trace = parseTraceHeader(req.headers[TRACE_HEADER]);
|
|
169909
170278
|
if (type2 === "Event") {
|
|
169910
170279
|
res.writeHead(202, { "content-type": "application/json" });
|
|
169911
170280
|
res.end();
|
|
169912
|
-
dispatch?.(event).catch((error3) => {
|
|
170281
|
+
dispatch?.(event, trace).catch((error3) => {
|
|
169913
170282
|
const routeKey = event?.["$awsless-route"];
|
|
169914
170283
|
reportFailure?.({
|
|
169915
170284
|
kind: "async",
|
|
@@ -169921,7 +170290,7 @@ var createLambdaServer = (props) => {
|
|
|
169921
170290
|
return;
|
|
169922
170291
|
}
|
|
169923
170292
|
try {
|
|
169924
|
-
const result = await dispatch?.(event);
|
|
170293
|
+
const result = await dispatch?.(event, trace);
|
|
169925
170294
|
res.writeHead(200, { "content-type": "application/json" });
|
|
169926
170295
|
res.end(typeof result === "undefined" || result === null ? "" : JSON.stringify(result));
|
|
169927
170296
|
} catch (error3) {
|
|
@@ -170193,21 +170562,48 @@ var startDev = async (props) => {
|
|
|
170193
170562
|
}
|
|
170194
170563
|
return "invoke";
|
|
170195
170564
|
};
|
|
170196
|
-
const
|
|
170565
|
+
const describePayload = (event) => {
|
|
170566
|
+
let payload = "";
|
|
170567
|
+
try {
|
|
170568
|
+
const envelope = event;
|
|
170569
|
+
const inner = typeof envelope?.["$awsless-route"] === "string" ? envelope.event : event;
|
|
170570
|
+
payload = JSON.stringify(inner) ?? "";
|
|
170571
|
+
} catch (_4) {}
|
|
170572
|
+
return payload.length > 1000 ? payload.slice(0, 1000) + "\u2026" : payload;
|
|
170573
|
+
};
|
|
170574
|
+
const dispatch = async (event, parent) => {
|
|
170197
170575
|
await ensureFresh();
|
|
170198
170576
|
const started = Date.now();
|
|
170199
170577
|
const route = describeDispatch(event);
|
|
170578
|
+
const payload = describePayload(event);
|
|
170579
|
+
const trace = { traceId: parent?.traceId ?? traceId(), spanId: traceId() };
|
|
170200
170580
|
try {
|
|
170201
|
-
const result = await worker.dispatch(event);
|
|
170202
|
-
dev.events.emit("activity", {
|
|
170581
|
+
const result = await worker.dispatch(event, formatTraceHeader(trace));
|
|
170582
|
+
dev.events.emit("activity", {
|
|
170583
|
+
date: started,
|
|
170584
|
+
route,
|
|
170585
|
+
payload,
|
|
170586
|
+
ms: Date.now() - started,
|
|
170587
|
+
ok: true,
|
|
170588
|
+
trace: trace.traceId,
|
|
170589
|
+
span: trace.spanId,
|
|
170590
|
+
parent: parent?.spanId
|
|
170591
|
+
});
|
|
170203
170592
|
return result;
|
|
170204
170593
|
} catch (error3) {
|
|
170594
|
+
if (error3 instanceof Error) {
|
|
170595
|
+
error3.trace = trace;
|
|
170596
|
+
}
|
|
170205
170597
|
dev.events.emit("activity", {
|
|
170206
170598
|
date: started,
|
|
170207
170599
|
route,
|
|
170600
|
+
payload,
|
|
170208
170601
|
ms: Date.now() - started,
|
|
170209
170602
|
ok: false,
|
|
170210
|
-
error: error3 instanceof Error ? error3.message : String(error3)
|
|
170603
|
+
error: error3 instanceof Error ? error3.message : String(error3),
|
|
170604
|
+
trace: trace.traceId,
|
|
170605
|
+
span: trace.spanId,
|
|
170606
|
+
parent: parent?.spanId
|
|
170211
170607
|
});
|
|
170212
170608
|
throw error3;
|
|
170213
170609
|
}
|
|
@@ -177712,7 +178108,7 @@ ${job.error.stack.split(`
|
|
|
177712
178108
|
stream2.shift();
|
|
177713
178109
|
} else if (stream2.length > 0) {
|
|
177714
178110
|
this._BOMseen = true;
|
|
177715
|
-
}
|
|
178111
|
+
} else {}
|
|
177716
178112
|
}
|
|
177717
178113
|
return codePointsToString(stream2);
|
|
177718
178114
|
}
|