@wizeworks/lens-hub 0.0.0-stage → 0.3.0-alpha.1

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.
Files changed (115) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +60 -2
  3. package/dist/api.d.ts +20 -0
  4. package/dist/api.d.ts.map +1 -0
  5. package/dist/api.js +90 -0
  6. package/dist/api.js.map +1 -0
  7. package/dist/auth.d.ts +9 -0
  8. package/dist/auth.d.ts.map +1 -0
  9. package/dist/auth.js +55 -0
  10. package/dist/auth.js.map +1 -0
  11. package/dist/body.d.ts +9 -0
  12. package/dist/body.d.ts.map +1 -0
  13. package/dist/body.js +25 -0
  14. package/dist/body.js.map +1 -0
  15. package/dist/cli-args.d.ts +10 -0
  16. package/dist/cli-args.d.ts.map +1 -0
  17. package/dist/cli-args.js +63 -0
  18. package/dist/cli-args.js.map +1 -0
  19. package/dist/cli.d.ts +3 -0
  20. package/dist/cli.d.ts.map +1 -0
  21. package/dist/cli.js +35 -0
  22. package/dist/cli.js.map +1 -0
  23. package/dist/data.d.ts +17 -0
  24. package/dist/data.d.ts.map +1 -0
  25. package/dist/data.js +39 -0
  26. package/dist/data.js.map +1 -0
  27. package/dist/hub.d.ts +14 -0
  28. package/dist/hub.d.ts.map +1 -0
  29. package/dist/hub.js +89 -0
  30. package/dist/hub.js.map +1 -0
  31. package/dist/import.d.ts +4 -0
  32. package/dist/import.d.ts.map +1 -0
  33. package/dist/import.js +41 -0
  34. package/dist/import.js.map +1 -0
  35. package/dist/index.d.ts +7 -0
  36. package/dist/index.d.ts.map +1 -0
  37. package/dist/index.js +3 -0
  38. package/dist/index.js.map +1 -0
  39. package/dist/ingest.d.ts +9 -0
  40. package/dist/ingest.d.ts.map +1 -0
  41. package/dist/ingest.js +83 -0
  42. package/dist/ingest.js.map +1 -0
  43. package/dist/kit.d.ts +10 -0
  44. package/dist/kit.d.ts.map +1 -0
  45. package/dist/kit.js +8 -0
  46. package/dist/kit.js.map +1 -0
  47. package/dist/mcp.d.ts +4 -0
  48. package/dist/mcp.d.ts.map +1 -0
  49. package/dist/mcp.js +18 -0
  50. package/dist/mcp.js.map +1 -0
  51. package/dist/metrics-read.d.ts +12 -0
  52. package/dist/metrics-read.d.ts.map +1 -0
  53. package/dist/metrics-read.js +18 -0
  54. package/dist/metrics-read.js.map +1 -0
  55. package/dist/metrics-write.d.ts +12 -0
  56. package/dist/metrics-write.d.ts.map +1 -0
  57. package/dist/metrics-write.js +107 -0
  58. package/dist/metrics-write.js.map +1 -0
  59. package/dist/models-api.d.ts +5 -0
  60. package/dist/models-api.d.ts.map +1 -0
  61. package/dist/models-api.js +36 -0
  62. package/dist/models-api.js.map +1 -0
  63. package/dist/options.d.ts +36 -0
  64. package/dist/options.d.ts.map +1 -0
  65. package/dist/options.js +22 -0
  66. package/dist/options.js.map +1 -0
  67. package/dist/otlp/index.d.ts +8 -0
  68. package/dist/otlp/index.d.ts.map +1 -0
  69. package/dist/otlp/index.js +41 -0
  70. package/dist/otlp/index.js.map +1 -0
  71. package/dist/otlp/logs.d.ts +24 -0
  72. package/dist/otlp/logs.d.ts.map +1 -0
  73. package/dist/otlp/logs.js +44 -0
  74. package/dist/otlp/logs.js.map +1 -0
  75. package/dist/otlp/metrics.d.ts +59 -0
  76. package/dist/otlp/metrics.d.ts.map +1 -0
  77. package/dist/otlp/metrics.js +73 -0
  78. package/dist/otlp/metrics.js.map +1 -0
  79. package/dist/otlp/proto.d.ts +14 -0
  80. package/dist/otlp/proto.d.ts.map +1 -0
  81. package/dist/otlp/proto.js +132 -0
  82. package/dist/otlp/proto.js.map +1 -0
  83. package/dist/otlp/spans.d.ts +33 -0
  84. package/dist/otlp/spans.d.ts.map +1 -0
  85. package/dist/otlp/spans.js +80 -0
  86. package/dist/otlp/spans.js.map +1 -0
  87. package/dist/otlp/values.d.ts +40 -0
  88. package/dist/otlp/values.d.ts.map +1 -0
  89. package/dist/otlp/values.js +78 -0
  90. package/dist/otlp/values.js.map +1 -0
  91. package/dist/scale-exec.d.ts +10 -0
  92. package/dist/scale-exec.d.ts.map +1 -0
  93. package/dist/scale-exec.js +22 -0
  94. package/dist/scale-exec.js.map +1 -0
  95. package/dist/schema-scale.d.ts +7 -0
  96. package/dist/schema-scale.d.ts.map +1 -0
  97. package/dist/schema-scale.js +99 -0
  98. package/dist/schema-scale.js.map +1 -0
  99. package/dist/schema.d.ts +13 -0
  100. package/dist/schema.d.ts.map +1 -0
  101. package/dist/schema.js +49 -0
  102. package/dist/schema.js.map +1 -0
  103. package/dist/settle.d.ts +28 -0
  104. package/dist/settle.d.ts.map +1 -0
  105. package/dist/settle.js +103 -0
  106. package/dist/settle.js.map +1 -0
  107. package/dist/store-read.d.ts +27 -0
  108. package/dist/store-read.d.ts.map +1 -0
  109. package/dist/store-read.js +74 -0
  110. package/dist/store-read.js.map +1 -0
  111. package/dist/store.d.ts +42 -0
  112. package/dist/store.d.ts.map +1 -0
  113. package/dist/store.js +118 -0
  114. package/dist/store.js.map +1 -0
  115. package/package.json +64 -3
package/dist/hub.js ADDED
@@ -0,0 +1,89 @@
1
+ import { createRequire } from "node:module";
2
+ import { createServer } from "node:http";
3
+ import { handleMcp, resolveUiDir, sendJson, serveUi, setCors } from "@wizeworks/lens-node/kit";
4
+ import { parseJson, readBody } from "./body.js";
5
+ import { acceptTokenLink, deny, isAllowed } from "./auth.js";
6
+ import { handleApi } from "./api.js";
7
+ import { HubData } from "./data.js";
8
+ import { hubMcpSource } from "./mcp.js";
9
+ import { resolveHubOptions } from "./options.js";
10
+ import { handleOtlp, otlpSignalOf } from "./otlp/index.js";
11
+ import { settleQuietly } from "./settle.js";
12
+ import { HubStore } from "./store.js";
13
+ const require = createRequire(import.meta.url);
14
+ export const HUB_VERSION = require("../package.json").version;
15
+ const BASE = "/_wizelens";
16
+ const PRUNE_MS = 60_000;
17
+ const SETTLE_MS = 2_000;
18
+ async function routeBase(c, sub, req, res, url) {
19
+ const method = req.method ?? "GET";
20
+ if (sub.startsWith("api/"))
21
+ return handleApi(c, sub, req, res, url);
22
+ if (sub === "mcp") {
23
+ if (!c.o.enableMcp)
24
+ return sendJson(res, 404, { error: "MCP is off. Start the hub with --mcp." });
25
+ const body = method === "POST" ? parseJson(await readBody(req)) : undefined;
26
+ return handleMcp(hubMcpSource(c.data, c.o.name, c.version, c.o.audit), req, res, body);
27
+ }
28
+ if (method !== "GET" && method !== "HEAD")
29
+ return void res.writeHead(405).end();
30
+ if (acceptTokenLink(url, c.o.token, res))
31
+ return;
32
+ if (!isAllowed(req, c.o.token))
33
+ return deny(res, false, url);
34
+ await serveUi(c.uiDir, sub, res);
35
+ }
36
+ async function route(c, req, res) {
37
+ const url = new URL(req.url ?? "/", "http://hub.local");
38
+ const path = url.pathname;
39
+ setCors(res);
40
+ if (req.method === "OPTIONS")
41
+ return void res.writeHead(204).end();
42
+ if (path === "/healthz")
43
+ return void res.writeHead(200, { "Content-Type": "text/plain" }).end("ok");
44
+ if (path === "/" || path === BASE)
45
+ return void res.writeHead(302, { Location: `${BASE}/${url.search}` }).end();
46
+ const signal = otlpSignalOf(path);
47
+ const isUi = path.startsWith(`${BASE}/`) && !path.startsWith(`${BASE}/api/`) && path !== `${BASE}/mcp`;
48
+ if (!isUi && !isAllowed(req, c.o.token))
49
+ return deny(res, true, url);
50
+ if (signal && req.method === "POST")
51
+ return handleOtlp(signal, req, res, (w) => c.data.write(w), c.o.redactKeys);
52
+ if (path.startsWith(`${BASE}/`))
53
+ return routeBase(c, path.slice(BASE.length + 1), req, res, url);
54
+ sendJson(res, 404, { error: "not found" });
55
+ }
56
+ /** Create the local hub: one place for the traces of every service, with the dashboard, the API, OTLP, and MCP. */
57
+ export function createHub(options = {}) {
58
+ const o = resolveHubOptions(options);
59
+ const store = new HubStore({ path: o.storagePath === "memory" ? ":memory:" : o.storagePath, maxTraces: o.maxTraces, maxAgeMs: o.maxAgeMs, maxMetricPoints: o.maxMetricPoints, now: o.now });
60
+ const data = new HubData(store);
61
+ const c = { data, o, version: HUB_VERSION, startedMs: o.now(), uiDir: resolveUiDir(o.uiDir) };
62
+ const server = createServer((req, res) => {
63
+ route(c, req, res).catch(() => !res.headersSent && sendJson(res, 500, { error: "internal error" }));
64
+ });
65
+ store.prune();
66
+ const timer = setInterval(() => store.prune(), PRUNE_MS);
67
+ timer.unref();
68
+ const settler = setInterval(() => settleQuietly(store), SETTLE_MS);
69
+ settler.unref();
70
+ return {
71
+ server,
72
+ data,
73
+ listen: () => new Promise((resolve, reject) => {
74
+ server.once("error", reject);
75
+ server.listen(o.port, o.host, () => {
76
+ const { port } = server.address();
77
+ const local = ["0.0.0.0", "::", "127.0.0.1", "::1"].includes(o.host);
78
+ resolve(`http://${local ? "localhost" : o.host}:${port}`);
79
+ });
80
+ }),
81
+ close: () => new Promise((resolve) => {
82
+ clearInterval(timer);
83
+ clearInterval(settler);
84
+ server.closeAllConnections?.();
85
+ server.close(() => (store.close(), resolve()));
86
+ }),
87
+ };
88
+ }
89
+ //# sourceMappingURL=hub.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"hub.js","sourceRoot":"","sources":["../src/hub.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,4 @@
1
+ import type { HubData } from "./data.js";
2
+ /** Copy every trace from an add-on's `.wizelens/traces.db` into the hub. Returns how many traces were copied. */
3
+ export declare function importAddonFile(data: HubData, path: string): number;
4
+ //# sourceMappingURL=import.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"import.d.ts","sourceRoot":"","sources":["../src/import.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAkBzC,iHAAiH;AACjH,wBAAgB,eAAe,CAAC,IAAI,EAAE,OAAO,EAAE,IAAI,EAAE,MAAM,GAAG,MAAM,CAuBnE"}
package/dist/import.js ADDED
@@ -0,0 +1,41 @@
1
+ import { DatabaseSync } from "node:sqlite";
2
+ const BATCH = 200;
3
+ const parseList = (json) => {
4
+ try {
5
+ const v = JSON.parse(json);
6
+ return Array.isArray(v) ? v.filter((x) => typeof x === "string") : [];
7
+ }
8
+ catch {
9
+ return [];
10
+ }
11
+ };
12
+ /** Copy every trace from an add-on's `.wizelens/traces.db` into the hub. Returns how many traces were copied. */
13
+ export function importAddonFile(data, path) {
14
+ const db = new DatabaseSync(path, { readOnly: true });
15
+ try {
16
+ const meta = db.prepare("SELECT value FROM meta WHERE key = 'service'").get();
17
+ const sender = { service: meta?.value ?? "imported" };
18
+ const traces = db.prepare("SELECT trace_id, remotes FROM traces ORDER BY start_ms").all();
19
+ const spansOf = db.prepare("SELECT json FROM spans WHERE trace_id = ?");
20
+ const logsOf = db.prepare("SELECT json FROM logs WHERE trace_id = ? ORDER BY seq");
21
+ for (let i = 0; i < traces.length; i += BATCH) {
22
+ const spans = [];
23
+ const logs = [];
24
+ const remotes = [];
25
+ for (const t of traces.slice(i, i + BATCH)) {
26
+ for (const r of spansOf.all(t.trace_id))
27
+ spans.push(JSON.parse(r.json));
28
+ for (const r of logsOf.all(t.trace_id))
29
+ logs.push({ traceId: t.trace_id, log: JSON.parse(r.json) });
30
+ for (const endpoint of parseList(t.remotes))
31
+ remotes.push({ traceId: t.trace_id, endpoint });
32
+ }
33
+ data.write({ sender, via: "addon", spans, logs, remotes });
34
+ }
35
+ return traces.length;
36
+ }
37
+ finally {
38
+ db.close();
39
+ }
40
+ }
41
+ //# sourceMappingURL=import.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"import.js","sourceRoot":"","sources":["../src/import.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAI3C,MAAM,KAAK,GAAG,GAAG,CAAC;AAOlB,MAAM,SAAS,GAAG,CAAC,IAAY,EAAY,EAAE;IAC3C,IAAI,CAAC;QACH,MAAM,CAAC,GAAG,IAAI,CAAC,KAAK,CAAC,IAAI,CAAY,CAAC;QACtC,OAAO,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,EAAe,EAAE,CAAC,OAAO,CAAC,KAAK,QAAQ,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC;IACrF,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,EAAE,CAAC;IACZ,CAAC;AACH,CAAC,CAAC;AAEF,iHAAiH;AACjH,MAAM,UAAU,eAAe,CAAC,IAAa,EAAE,IAAY;IACzD,MAAM,EAAE,GAAG,IAAI,YAAY,CAAC,IAAI,EAAE,EAAE,QAAQ,EAAE,IAAI,EAAE,CAAC,CAAC;IACtD,IAAI,CAAC;QACH,MAAM,IAAI,GAAG,EAAE,CAAC,OAAO,CAAC,8CAA8C,CAAC,CAAC,GAAG,EAAmC,CAAC;QAC/G,MAAM,MAAM,GAAG,EAAE,OAAO,EAAE,IAAI,EAAE,KAAK,IAAI,UAAU,EAAE,CAAC;QACtD,MAAM,MAAM,GAAG,EAAE,CAAC,OAAO,CAAC,wDAAwD,CAAC,CAAC,GAAG,EAA2B,CAAC;QACnH,MAAM,OAAO,GAAG,EAAE,CAAC,OAAO,CAAC,2CAA2C,CAAC,CAAC;QACxE,MAAM,MAAM,GAAG,EAAE,CAAC,OAAO,CAAC,uDAAuD,CAAC,CAAC;QACnF,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,MAAM,CAAC,MAAM,EAAE,CAAC,IAAI,KAAK,EAAE,CAAC;YAC9C,MAAM,KAAK,GAAW,EAAE,CAAC;YACzB,MAAM,IAAI,GAAa,EAAE,CAAC;YAC1B,MAAM,OAAO,GAAgB,EAAE,CAAC;YAChC,KAAK,MAAM,CAAC,IAAI,MAAM,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,GAAG,KAAK,CAAC,EAAE,CAAC;gBAC3C,KAAK,MAAM,CAAC,IAAI,OAAO,CAAC,GAAG,CAAC,CAAC,CAAC,QAAQ,CAAuB;oBAAE,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,IAAI,CAAS,CAAC,CAAC;gBACtG,KAAK,MAAM,CAAC,IAAI,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC,QAAQ,CAAuB;oBAAE,IAAI,CAAC,IAAI,CAAC,EAAE,OAAO,EAAE,CAAC,CAAC,QAAQ,EAAE,GAAG,EAAE,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,IAAI,CAAc,EAAE,CAAC,CAAC;gBACvI,KAAK,MAAM,QAAQ,IAAI,SAAS,CAAC,CAAC,CAAC,OAAO,CAAC;oBAAE,OAAO,CAAC,IAAI,CAAC,EAAE,OAAO,EAAE,CAAC,CAAC,QAAQ,EAAE,QAAQ,EAAE,CAAC,CAAC;YAC/F,CAAC;YACD,IAAI,CAAC,KAAK,CAAC,EAAE,MAAM,EAAE,GAAG,EAAE,OAAO,EAAE,KAAK,EAAE,IAAI,EAAE,OAAO,EAAE,CAAC,CAAC;QAC7D,CAAC;QACD,OAAO,MAAM,CAAC,MAAM,CAAC;IACvB,CAAC;YAAS,CAAC;QACT,EAAE,CAAC,KAAK,EAAE,CAAC;IACb,CAAC;AACH,CAAC"}
@@ -0,0 +1,7 @@
1
+ export { createHub, HUB_VERSION } from "./hub.js";
2
+ export type { Hub } from "./hub.js";
3
+ export type { HubOptions } from "./options.js";
4
+ export { HubStore } from "./store.js";
5
+ export type { HubStoreOptions, HubWrite } from "./store.js";
6
+ export type * from "@wizeworks/lens-core";
7
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,WAAW,EAAE,MAAM,UAAU,CAAC;AAClD,YAAY,EAAE,GAAG,EAAE,MAAM,UAAU,CAAC;AACpC,YAAY,EAAE,UAAU,EAAE,MAAM,cAAc,CAAC;AAC/C,OAAO,EAAE,QAAQ,EAAE,MAAM,YAAY,CAAC;AACtC,YAAY,EAAE,eAAe,EAAE,QAAQ,EAAE,MAAM,YAAY,CAAC;AAC5D,mBAAmB,sBAAsB,CAAC"}
package/dist/index.js ADDED
@@ -0,0 +1,3 @@
1
+ export { createHub, HUB_VERSION } from "./hub.js";
2
+ export { HubStore } from "./store.js";
3
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,WAAW,EAAE,MAAM,UAAU,CAAC;AAGlD,OAAO,EAAE,QAAQ,EAAE,MAAM,YAAY,CAAC"}
@@ -0,0 +1,9 @@
1
+ import { type HubLog, type HubSender } from "@wizeworks/lens-core";
2
+ import type { HubWrite } from "./store.js";
3
+ /** The sender block of a batch. Null without a service name. */
4
+ export declare function parseSender(raw: unknown): HubSender | null;
5
+ /** One log line from a batch. Null when it is not valid. */
6
+ export declare function parseLog(raw: unknown, service: string, redactKeys: readonly string[]): HubLog | null;
7
+ /** Check and redact one `api/ingest` body. Null when the sender is missing. */
8
+ export declare function parseIngest(raw: unknown, redactKeys: readonly string[]): HubWrite | null;
9
+ //# sourceMappingURL=ingest.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ingest.d.ts","sourceRoot":"","sources":["../src/ingest.ts"],"names":[],"mappings":"AAAA,OAAO,EAEL,KAAK,MAAM,EAEX,KAAK,SAAS,EAMf,MAAM,sBAAsB,CAAC;AAE9B,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,YAAY,CAAC;AAW3C,gEAAgE;AAChE,wBAAgB,WAAW,CAAC,GAAG,EAAE,OAAO,GAAG,SAAS,GAAG,IAAI,CAe1D;AAQD,4DAA4D;AAC5D,wBAAgB,QAAQ,CAAC,GAAG,EAAE,OAAO,EAAE,OAAO,EAAE,MAAM,EAAE,UAAU,EAAE,SAAS,MAAM,EAAE,GAAG,MAAM,GAAG,IAAI,CAcpG;AAUD,+EAA+E;AAC/E,wBAAgB,WAAW,CAAC,GAAG,EAAE,OAAO,EAAE,UAAU,EAAE,SAAS,MAAM,EAAE,GAAG,QAAQ,GAAG,IAAI,CAmBxF"}
package/dist/ingest.js ADDED
@@ -0,0 +1,83 @@
1
+ import { redactAttributes, sanitizeMetricPoint, toAttributeValue, } from "@wizeworks/lens-core";
2
+ import { sanitizeClientSpan } from "@wizeworks/lens-node/kit";
3
+ const MAX_ITEMS = 5000;
4
+ const HEX32 = /^[0-9a-f]{32}$/;
5
+ const HEX16 = /^[0-9a-f]{16}$/;
6
+ const LEVELS = ["trace", "debug", "info", "warn", "error", "critical"];
7
+ const text = (v, max) => (typeof v === "string" && v ? v.slice(0, max) : undefined);
8
+ const list = (v) => (Array.isArray(v) ? v.slice(0, MAX_ITEMS) : []);
9
+ const isUrl = (v) => typeof v === "string" && v.length <= 500 && /^https?:\/\/[^\s]+$/i.test(v);
10
+ /** The sender block of a batch. Null without a service name. */
11
+ export function parseSender(raw) {
12
+ if (!raw || typeof raw !== "object")
13
+ return null;
14
+ const s = raw;
15
+ const service = text(s.service, 100);
16
+ if (!service)
17
+ return null;
18
+ return {
19
+ service,
20
+ project: text(s.project, 100),
21
+ version: text(s.version, 50),
22
+ runtime: text(s.runtime, 100),
23
+ environment: text(s.environment, 50),
24
+ host: text(s.host, 100),
25
+ endpoint: isUrl(s.endpoint) ? s.endpoint.replace(/\/+$/, "") : undefined,
26
+ startedMs: Number.isFinite(s.startedMs) ? Number(s.startedMs) : undefined,
27
+ };
28
+ }
29
+ function toAttributes(raw, redactKeys) {
30
+ const out = {};
31
+ if (raw && typeof raw === "object")
32
+ for (const [k, v] of Object.entries(raw))
33
+ out[k] = toAttributeValue(v);
34
+ return redactAttributes(out, redactKeys);
35
+ }
36
+ /** One log line from a batch. Null when it is not valid. */
37
+ export function parseLog(raw, service, redactKeys) {
38
+ if (!raw || typeof raw !== "object")
39
+ return null;
40
+ const { traceId, log } = raw;
41
+ if (typeof traceId !== "string" || !HEX32.test(traceId) || !log || typeof log !== "object")
42
+ return null;
43
+ const record = {
44
+ timeMs: Number(log.timeMs) || 0,
45
+ level: LEVELS.includes(log.level) ? log.level : "info",
46
+ category: text(log.category, 200) ?? "app",
47
+ message: typeof log.message === "string" ? log.message.slice(0, 10_000) : "",
48
+ service: text(log.service, 100) ?? service,
49
+ spanId: typeof log.spanId === "string" && HEX16.test(log.spanId) ? log.spanId : null,
50
+ attributes: toAttributes(log.attributes, redactKeys),
51
+ };
52
+ return { traceId, log: record };
53
+ }
54
+ function parseRemote(raw) {
55
+ const r = raw;
56
+ if (!r || typeof r.traceId !== "string" || !HEX32.test(r.traceId) || !isUrl(r.endpoint))
57
+ return null;
58
+ return { traceId: r.traceId, endpoint: r.endpoint.replace(/\/+$/, "") };
59
+ }
60
+ const notNull = (v) => v !== null;
61
+ /** Check and redact one `api/ingest` body. Null when the sender is missing. */
62
+ export function parseIngest(raw, redactKeys) {
63
+ const body = raw;
64
+ const sender = parseSender(body?.sender);
65
+ if (!body || !sender)
66
+ return null;
67
+ const spans = list(body.spans)
68
+ .map((s) => sanitizeClientSpan(s, redactKeys))
69
+ .filter(notNull);
70
+ return {
71
+ sender,
72
+ via: "addon",
73
+ spans,
74
+ logs: list(body.logs)
75
+ .map((l) => parseLog(l, sender.service, redactKeys))
76
+ .filter(notNull),
77
+ remotes: list(body.remotes).map(parseRemote).filter(notNull),
78
+ metrics: list(body.metrics)
79
+ .map((p) => sanitizeMetricPoint(p, redactKeys, sender.service))
80
+ .filter(notNull),
81
+ };
82
+ }
83
+ //# sourceMappingURL=ingest.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ingest.js","sourceRoot":"","sources":["../src/ingest.ts"],"names":[],"mappings":"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"}
package/dist/kit.d.ts ADDED
@@ -0,0 +1,10 @@
1
+ export { handleOtlp, otlpSignalOf } from "./otlp/index.js";
2
+ export type { OtlpSignal } from "./otlp/index.js";
3
+ export { parseIngest } from "./ingest.js";
4
+ export { isProtobuf, MAX_BODY, parseJson, readBody } from "./body.js";
5
+ export { parseDuration } from "./cli-args.js";
6
+ export type { HubWrite } from "./store.js";
7
+ export { fromExponential, pointsOf, writesFromMetrics } from "./otlp/metrics.js";
8
+ export type { OtlpMetric, OtlpResourceMetrics } from "./otlp/metrics.js";
9
+ export { encodeMetrics } from "./otlp/proto.js";
10
+ //# sourceMappingURL=kit.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"kit.d.ts","sourceRoot":"","sources":["../src/kit.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,UAAU,EAAE,YAAY,EAAE,MAAM,iBAAiB,CAAC;AAC3D,YAAY,EAAE,UAAU,EAAE,MAAM,iBAAiB,CAAC;AAClD,OAAO,EAAE,WAAW,EAAE,MAAM,aAAa,CAAC;AAC1C,OAAO,EAAE,UAAU,EAAE,QAAQ,EAAE,SAAS,EAAE,QAAQ,EAAE,MAAM,WAAW,CAAC;AACtE,OAAO,EAAE,aAAa,EAAE,MAAM,eAAe,CAAC;AAC9C,YAAY,EAAE,QAAQ,EAAE,MAAM,YAAY,CAAC;AAC3C,OAAO,EAAE,eAAe,EAAE,QAAQ,EAAE,iBAAiB,EAAE,MAAM,mBAAmB,CAAC;AACjF,YAAY,EAAE,UAAU,EAAE,mBAAmB,EAAE,MAAM,mBAAmB,CAAC;AACzE,OAAO,EAAE,aAAa,EAAE,MAAM,iBAAiB,CAAC"}
package/dist/kit.js ADDED
@@ -0,0 +1,8 @@
1
+ // Building blocks for the WizeLens cloud (@wizeworks/lens-cloud). Not a stable public API.
2
+ export { handleOtlp, otlpSignalOf } from "./otlp/index.js";
3
+ export { parseIngest } from "./ingest.js";
4
+ export { isProtobuf, MAX_BODY, parseJson, readBody } from "./body.js";
5
+ export { parseDuration } from "./cli-args.js";
6
+ export { fromExponential, pointsOf, writesFromMetrics } from "./otlp/metrics.js";
7
+ export { encodeMetrics } from "./otlp/proto.js";
8
+ //# sourceMappingURL=kit.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"kit.js","sourceRoot":"","sources":["../src/kit.ts"],"names":[],"mappings":"AAAA,2FAA2F;AAC3F,OAAO,EAAE,UAAU,EAAE,YAAY,EAAE,MAAM,iBAAiB,CAAC;AAE3D,OAAO,EAAE,WAAW,EAAE,MAAM,aAAa,CAAC;AAC1C,OAAO,EAAE,UAAU,EAAE,QAAQ,EAAE,SAAS,EAAE,QAAQ,EAAE,MAAM,WAAW,CAAC;AACtE,OAAO,EAAE,aAAa,EAAE,MAAM,eAAe,CAAC;AAE9C,OAAO,EAAE,eAAe,EAAE,QAAQ,EAAE,iBAAiB,EAAE,MAAM,mBAAmB,CAAC;AAEjF,OAAO,EAAE,aAAa,EAAE,MAAM,iBAAiB,CAAC"}
package/dist/mcp.d.ts ADDED
@@ -0,0 +1,4 @@
1
+ import { type McpDataSource } from "@wizeworks/lens-node/kit";
2
+ import type { HubData } from "./data.js";
3
+ export declare function hubMcpSource(data: HubData, name: string, version: string, audit: (line: string) => void): McpDataSource;
4
+ //# sourceMappingURL=mcp.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"mcp.d.ts","sourceRoot":"","sources":["../src/mcp.ts"],"names":[],"mappings":"AAAA,OAAO,EAA6C,KAAK,aAAa,EAAE,MAAM,0BAA0B,CAAC;AACzG,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAMzC,wBAAgB,YAAY,CAAC,IAAI,EAAE,OAAO,EAAE,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,EAAE,KAAK,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,IAAI,GAAG,aAAa,CAYvH"}
package/dist/mcp.js ADDED
@@ -0,0 +1,18 @@
1
+ import { DEFAULT_N_PLUS_ONE, DEFAULT_SLOW_QUERY_MS } from "@wizeworks/lens-node/kit";
2
+ import { metricsPage } from "./metrics-read.js";
3
+ /** Recent traces the MCP tools search through. */
4
+ const MCP_RECENT = 2000;
5
+ export function hubMcpSource(data, name, version, audit) {
6
+ return {
7
+ service: name,
8
+ version,
9
+ slowQueryMs: DEFAULT_SLOW_QUERY_MS,
10
+ nPlusOneThreshold: DEFAULT_N_PLUS_ONE,
11
+ list: (limit) => data.summaries({ limit }),
12
+ all: () => data.traces({ limit: MCP_RECENT }),
13
+ get: (traceId, federate) => data.getTrace(traceId, federate),
14
+ audit,
15
+ metrics: (range, params) => metricsPage(data.store.db, range, {}, params, data.store.now()),
16
+ };
17
+ }
18
+ //# sourceMappingURL=mcp.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"mcp.js","sourceRoot":"","sources":["../src/mcp.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,kBAAkB,EAAE,qBAAqB,EAAsB,MAAM,0BAA0B,CAAC;AAEzG,OAAO,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAC;AAEhD,kDAAkD;AAClD,MAAM,UAAU,GAAG,IAAI,CAAC;AAExB,MAAM,UAAU,YAAY,CAAC,IAAa,EAAE,IAAY,EAAE,OAAe,EAAE,KAA6B;IACtG,OAAO;QACL,OAAO,EAAE,IAAI;QACb,OAAO;QACP,WAAW,EAAE,qBAAqB;QAClC,iBAAiB,EAAE,kBAAkB;QACrC,IAAI,EAAE,CAAC,KAAK,EAAE,EAAE,CAAC,IAAI,CAAC,SAAS,CAAC,EAAE,KAAK,EAAE,CAAC;QAC1C,GAAG,EAAE,GAAG,EAAE,CAAC,IAAI,CAAC,MAAM,CAAC,EAAE,KAAK,EAAE,UAAU,EAAE,CAAC;QAC7C,GAAG,EAAE,CAAC,OAAO,EAAE,QAAQ,EAAE,EAAE,CAAC,IAAI,CAAC,QAAQ,CAAC,OAAO,EAAE,QAAQ,CAAC;QAC5D,KAAK;QACL,OAAO,EAAE,CAAC,KAAK,EAAE,MAAM,EAAE,EAAE,CAAC,WAAW,CAAC,IAAI,CAAC,KAAK,CAAC,EAAE,EAAE,KAAK,EAAE,EAAE,EAAE,MAAM,EAAE,IAAI,CAAC,KAAK,CAAC,GAAG,EAAE,CAAC;KAC5F,CAAC;AACJ,CAAC"}
@@ -0,0 +1,12 @@
1
+ import type { DatabaseSync } from "node:sqlite";
2
+ import { type MetricsModel, type TimeRange } from "@wizeworks/lens-core";
3
+ export interface MetricScope {
4
+ project?: string;
5
+ env?: string;
6
+ }
7
+ /** Parameters the metrics model reads; the range and scope are taken out. */
8
+ export declare function metricParams(p: URLSearchParams): Record<string, string>;
9
+ export declare const rangeOf: (v: string | null | undefined, fallback?: TimeRange) => TimeRange;
10
+ /** The metrics page for a scope and range, from the metric rollup tiers. */
11
+ export declare function metricsPage(db: DatabaseSync, range: TimeRange, scope: MetricScope, params: Record<string, string>, now: number): MetricsModel;
12
+ //# sourceMappingURL=metrics-read.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"metrics-read.d.ts","sourceRoot":"","sources":["../src/metrics-read.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,YAAY,EAAiB,MAAM,aAAa,CAAC;AAC/D,OAAO,EAA2D,KAAK,YAAY,EAAiC,KAAK,SAAS,EAAE,MAAM,sBAAsB,CAAC;AAEjK,MAAM,WAAW,WAAW;IAC1B,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,GAAG,CAAC,EAAE,MAAM,CAAC;CACd;AAED,6EAA6E;AAC7E,wBAAgB,YAAY,CAAC,CAAC,EAAE,eAAe,GAAG,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAOvE;AAED,eAAO,MAAM,OAAO,MAAO,MAAM,GAAG,IAAI,GAAG,SAAS,aAAY,SAAS,KAAU,SAAiD,CAAC;AAErI,4EAA4E;AAC5E,wBAAgB,WAAW,CAAC,EAAE,EAAE,YAAY,EAAE,KAAK,EAAE,SAAS,EAAE,KAAK,EAAE,WAAW,EAAE,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,EAAE,GAAG,EAAE,MAAM,GAAG,YAAY,CAG7I"}
@@ -0,0 +1,18 @@
1
+ import { alignNow, isTimeRange, metricPageSteps, metricsModelOf, runMetricSync } from "@wizeworks/lens-core";
2
+ /** Parameters the metrics model reads; the range and scope are taken out. */
3
+ export function metricParams(p) {
4
+ const out = {};
5
+ for (const k of ["metric", "service", "group", "stat", "q"]) {
6
+ const v = p.get(k);
7
+ if (v)
8
+ out[k] = v.slice(0, 200);
9
+ }
10
+ return out;
11
+ }
12
+ export const rangeOf = (v, fallback = "1h") => (v && isTimeRange(v) ? v : fallback);
13
+ /** The metrics page for a scope and range, from the metric rollup tiers. */
14
+ export function metricsPage(db, range, scope, params, now) {
15
+ const steps = metricPageSteps("sqlite", { project: scope.project || undefined, env: scope.env || undefined }, range, alignNow(now), params);
16
+ return metricsModelOf(runMetricSync(steps, (q) => db.prepare(q.sql).all(...q.args)));
17
+ }
18
+ //# sourceMappingURL=metrics-read.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"metrics-read.js","sourceRoot":"","sources":["../src/metrics-read.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,QAAQ,EAAE,WAAW,EAAE,eAAe,EAAsC,cAAc,EAAE,aAAa,EAAkB,MAAM,sBAAsB,CAAC;AAOjK,6EAA6E;AAC7E,MAAM,UAAU,YAAY,CAAC,CAAkB;IAC7C,MAAM,GAAG,GAA2B,EAAE,CAAC;IACvC,KAAK,MAAM,CAAC,IAAI,CAAC,QAAQ,EAAE,SAAS,EAAE,OAAO,EAAE,MAAM,EAAE,GAAG,CAAC,EAAE,CAAC;QAC5D,MAAM,CAAC,GAAG,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC;QACnB,IAAI,CAAC;YAAE,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,KAAK,CAAC,CAAC,EAAE,GAAG,CAAC,CAAC;IAClC,CAAC;IACD,OAAO,GAAG,CAAC;AACb,CAAC;AAED,MAAM,CAAC,MAAM,OAAO,GAAG,CAAC,CAA4B,EAAE,QAAQ,GAAc,IAAI,EAAa,EAAE,CAAC,CAAC,CAAC,IAAI,WAAW,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC;AAErI,4EAA4E;AAC5E,MAAM,UAAU,WAAW,CAAC,EAAgB,EAAE,KAAgB,EAAE,KAAkB,EAAE,MAA8B,EAAE,GAAW;IAC7H,MAAM,KAAK,GAAG,eAAe,CAAC,QAAQ,EAAE,EAAE,OAAO,EAAE,KAAK,CAAC,OAAO,IAAI,SAAS,EAAE,GAAG,EAAE,KAAK,CAAC,GAAG,IAAI,SAAS,EAAE,EAAE,KAAK,EAAE,QAAQ,CAAC,GAAG,CAAC,EAAE,MAAM,CAAC,CAAC;IAC5I,OAAO,cAAc,CAAC,aAAa,CAAC,KAAK,EAAE,CAAC,CAAC,EAAE,EAAE,CAAC,EAAE,CAAC,OAAO,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,GAAG,CAAC,GAAI,CAAC,CAAC,IAAwB,CAAe,CAAC,CAAC,CAAC;AAC1H,CAAC"}
@@ -0,0 +1,12 @@
1
+ import type { DatabaseSync } from "node:sqlite";
2
+ import { type MetricPoint, type MetricSeriesWrite, type MetricState } from "@wizeworks/lens-core";
3
+ /** Write a batch's series from the given states; `seriesSql` upserts the series, or only adds missing ones (backfill). */
4
+ export declare function writeMetricGroups(db: DatabaseSync, project: string, env: string, groups: Map<string, MetricPoint[]>, states: Map<string, MetricState | null>, now: number, seriesSql: string): MetricSeriesWrite[];
5
+ export declare const metricKeyOf: (p: MetricPoint) => string;
6
+ /** Add one batch's points to the metric tiers and series state, in the caller's transaction. */
7
+ export declare function writeMetricRollups(db: DatabaseSync, project: string, env: string, points: readonly MetricPoint[], now: number): void;
8
+ /** Drop tier buckets past their keep (10 s and 5 min tiers) or the hub's age limit (1 h tier and series state), then backfill a slice. */
9
+ export declare function pruneMetricRollups(db: DatabaseSync, now: number, maxAgeMs: number): void;
10
+ /** Hub files from before metric rollups: roll up their raw points, oldest first, for at most `budgetMs` per call. */
11
+ export declare function backfillMetricRollups(db: DatabaseSync, now: number, budgetMs?: number): void;
12
+ //# sourceMappingURL=metrics-write.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"metrics-write.d.ts","sourceRoot":"","sources":["../src/metrics-write.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,YAAY,EAAgC,MAAM,aAAa,CAAC;AAC9E,OAAO,EAQL,KAAK,WAAW,EAChB,KAAK,iBAAiB,EAItB,KAAK,WAAW,EAQjB,MAAM,sBAAsB,CAAC;AAkC9B,0HAA0H;AAC1H,wBAAgB,iBAAiB,CAAC,EAAE,EAAE,YAAY,EAAE,OAAO,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,EAAE,MAAM,EAAE,GAAG,CAAC,MAAM,EAAE,WAAW,EAAE,CAAC,EAAE,MAAM,EAAE,GAAG,CAAC,MAAM,EAAE,WAAW,GAAG,IAAI,CAAC,EAAE,GAAG,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,GAAG,iBAAiB,EAAE,CAOlN;AAED,eAAO,MAAM,WAAW,MAAO,WAAW,KAAG,MAAiC,CAAC;AAE/E,gGAAgG;AAChG,wBAAgB,kBAAkB,CAAC,EAAE,EAAE,YAAY,EAAE,OAAO,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,EAAE,MAAM,EAAE,SAAS,WAAW,EAAE,EAAE,GAAG,EAAE,MAAM,GAAG,IAAI,CAIpI;AAED,0IAA0I;AAC1I,wBAAgB,kBAAkB,CAAC,EAAE,EAAE,YAAY,EAAE,GAAG,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,GAAG,IAAI,CAIxF;AA0CD,qHAAqH;AACrH,wBAAgB,qBAAqB,CAAC,EAAE,EAAE,YAAY,EAAE,GAAG,EAAE,MAAM,EAAE,QAAQ,SAAM,GAAG,IAAI,CAYzF"}
@@ -0,0 +1,107 @@
1
+ import { createHash } from "node:crypto";
2
+ import { groupMetricSeries, mergeStoredHists, metricBatchWrites, metricHistOfColumns, metricHistStateSql, metricSeriesInsertSql, metricSeriesUpsertSql, metricSeriesValues, tierCutoff, metricStateOfColumns, metricStateSql, metricTierUpsertSql, metricTierValues, seriesKeyOf, TIERS, } from "@wizeworks/lens-core";
3
+ // Metric rollups at ingest (docs/CONTRACT.md, "Hub storage"): points never change, so tiers are written with the raw points.
4
+ const hashKey = (text) => createHash("sha1").update(text).digest("hex");
5
+ const statements = new WeakMap();
6
+ function prepared(db, sql) {
7
+ const map = statements.get(db) ?? new Map();
8
+ statements.set(db, map);
9
+ const hit = map.get(sql);
10
+ if (hit)
11
+ return hit;
12
+ const st = db.prepare(sql);
13
+ map.set(sql, st);
14
+ return st;
15
+ }
16
+ const all = (db, q) => prepared(db, q.sql).all(...q.args);
17
+ function statesOf(db, project, env, keys) {
18
+ return new Map(all(db, metricStateSql("sqlite", project, env, keys)).map((r) => [String(r.series_key), metricStateOfColumns(r)]));
19
+ }
20
+ /** The stored histograms of the tier buckets this batch adds histogram counts to. */
21
+ function storedHists(db, project, env, tiers) {
22
+ const stored = new Map();
23
+ for (const tier of TIERS) {
24
+ const mine = tiers.filter((t) => t.tier === tier && t.row.hist);
25
+ if (mine.length === 0)
26
+ continue;
27
+ const q = metricHistStateSql("sqlite", tier, project, env, [...new Set(mine.map((t) => t.key))], [...new Set(mine.map((t) => t.bucket))]);
28
+ for (const r of all(db, q))
29
+ stored.set(`${tier.name} ${r.series_key} ${r.bucket_ms}`, metricHistOfColumns(r));
30
+ }
31
+ return (t) => stored.get(`${t.tier.name} ${t.key} ${t.bucket}`) ?? null;
32
+ }
33
+ /** Write a batch's series from the given states; `seriesSql` upserts the series, or only adds missing ones (backfill). */
34
+ export function writeMetricGroups(db, project, env, groups, states, now, seriesSql) {
35
+ const { series, tiers } = metricBatchWrites(groups, states, now);
36
+ mergeStoredHists(tiers, storedHists(db, project, env, tiers));
37
+ for (const t of tiers)
38
+ prepared(db, metricTierUpsertSql("sqlite", t.tier, 1)).run(...metricTierValues("sqlite", project, env, t));
39
+ const upsert = prepared(db, seriesSql);
40
+ for (const s of series)
41
+ upsert.run(...metricSeriesValues("sqlite", project, env, s));
42
+ return series;
43
+ }
44
+ export const metricKeyOf = (p) => hashKey(seriesKeyOf(p));
45
+ /** Add one batch's points to the metric tiers and series state, in the caller's transaction. */
46
+ export function writeMetricRollups(db, project, env, points, now) {
47
+ if (points.length === 0)
48
+ return;
49
+ const groups = groupMetricSeries(points, metricKeyOf);
50
+ writeMetricGroups(db, project, env, groups, statesOf(db, project, env, [...groups.keys()]), now, metricSeriesUpsertSql("sqlite", 1));
51
+ }
52
+ /** Drop tier buckets past their keep (10 s and 5 min tiers) or the hub's age limit (1 h tier and series state), then backfill a slice. */
53
+ export function pruneMetricRollups(db, now, maxAgeMs) {
54
+ for (const t of TIERS)
55
+ prepared(db, `DELETE FROM metric_${t.name} WHERE bucket_ms <= ?`).run(tierCutoff(t, now, t.keepMs ?? maxAgeMs));
56
+ prepared(db, "DELETE FROM metric_series WHERE last_ms < ?").run(now - maxAgeMs);
57
+ backfillMetricRollups(db, now);
58
+ }
59
+ const BACKFILL = "metric_backfill";
60
+ const BACKFILL_ROWS = 5_000;
61
+ const setMeta = (db, value) => prepared(db, "INSERT OR REPLACE INTO meta (key, value) VALUES (?, ?)").run(BACKFILL, value);
62
+ /** The backfill in progress. A file whose series already have rollups, or that has no points, needs none. */
63
+ function backfillJob(db) {
64
+ const row = prepared(db, "SELECT value FROM meta WHERE key = ?").get(BACKFILL);
65
+ if (row)
66
+ return row.value === "done" ? null : JSON.parse(row.value);
67
+ const live = prepared(db, "SELECT 1 AS x FROM metric_series LIMIT 1").get() !== undefined;
68
+ const max = prepared(db, "SELECT max(rowid) AS m FROM metrics").get().m;
69
+ if (!live && max !== null)
70
+ return { upto: max, after: 0, states: {} };
71
+ setMeta(db, "done");
72
+ return null;
73
+ }
74
+ /** Roll up one slice of old raw points, per scope, carrying the backfill's own series state between slices. */
75
+ function backfillSlice(db, rows, job, now) {
76
+ const scopes = new Map();
77
+ for (const r of rows) {
78
+ const key = `${r.project}${r.env}`;
79
+ const list = scopes.get(key) ?? [];
80
+ scopes.set(key, list);
81
+ list.push(JSON.parse(r.json));
82
+ }
83
+ for (const [scope, points] of scopes) {
84
+ const [project = "", env = ""] = scope.split("");
85
+ const groups = groupMetricSeries(points, metricKeyOf);
86
+ const states = new Map([...groups.keys()].map((k) => [k, job.states[`${scope}${k}`] ?? null]));
87
+ for (const w of writeMetricGroups(db, project, env, groups, states, now, metricSeriesInsertSql("sqlite", 1)))
88
+ job.states[`${scope}${w.key}`] = w.state;
89
+ }
90
+ }
91
+ /** Hub files from before metric rollups: roll up their raw points, oldest first, for at most `budgetMs` per call. */
92
+ export function backfillMetricRollups(db, now, budgetMs = 500) {
93
+ const job = backfillJob(db);
94
+ if (!job)
95
+ return;
96
+ const end = Date.now() + budgetMs;
97
+ const next = prepared(db, "SELECT rowid AS id, project, env, json FROM metrics WHERE rowid > ? AND rowid <= ? ORDER BY rowid LIMIT ?");
98
+ while (Date.now() < end) {
99
+ const rows = next.all(job.after, job.upto, BACKFILL_ROWS);
100
+ if (rows.length === 0)
101
+ return void setMeta(db, "done");
102
+ backfillSlice(db, rows, job, now);
103
+ job.after = rows.at(-1).id;
104
+ }
105
+ setMeta(db, JSON.stringify(job));
106
+ }
107
+ //# sourceMappingURL=metrics-write.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"metrics-write.js","sourceRoot":"","sources":["../src/metrics-write.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,5 @@
1
+ import type { ServerResponse } from "node:http";
2
+ import type { ApiContext } from "./api.js";
3
+ /** `GET api/models/<page>?range=&project=&env=&...`: one page's numbers, from the hub's stats tables. */
4
+ export declare function sendPageModel(c: ApiContext, page: string, p: URLSearchParams, res: ServerResponse): Promise<void>;
5
+ //# sourceMappingURL=models-api.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"models-api.d.ts","sourceRoot":"","sources":["../src/models-api.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,WAAW,CAAC;AAGhD,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,UAAU,CAAC;AAe3C,yGAAyG;AACzG,wBAAsB,aAAa,CAAC,CAAC,EAAE,UAAU,EAAE,IAAI,EAAE,MAAM,EAAE,CAAC,EAAE,eAAe,EAAE,GAAG,EAAE,cAAc,GAAG,OAAO,CAAC,IAAI,CAAC,CAgBvH"}
@@ -0,0 +1,36 @@
1
+ import { alignNow, FACT_SLOW_QUERY_MS, isPageName, isTimeRange, pageContext, runPage, TIME_RANGES } from "@wizeworks/lens-core";
2
+ import { sendJson } from "@wizeworks/lens-node/kit";
3
+ import { hubExecutor, hubSettling } from "./scale-exec.js";
4
+ const CACHE_MAX = 200;
5
+ const RESERVED = new Set(["project", "range", "env"]);
6
+ const cache = new Map();
7
+ /** Model parameters: every query value except the ones that pick the data. */
8
+ const paramsOf = (p) => Object.fromEntries([...p].filter(([k]) => !RESERVED.has(k)).map(([k, v]) => [k, v.slice(0, 500)]).sort());
9
+ function remember(key, value) {
10
+ if (cache.size >= CACHE_MAX)
11
+ cache.delete(cache.keys().next().value);
12
+ cache.set(key, value);
13
+ }
14
+ /** `GET api/models/<page>?range=&project=&env=&...`: one page's numbers, from the hub's stats tables. */
15
+ export async function sendPageModel(c, page, p, res) {
16
+ if (!isPageName(page))
17
+ return sendJson(res, 404, { error: `No model named "${page}".` });
18
+ const range = p.get("range") ?? "24h";
19
+ if (!isTimeRange(range))
20
+ return sendJson(res, 400, { error: `Unknown range "${range}".` });
21
+ const store = c.data.store;
22
+ if (TIME_RANGES[range].ms > store.maxAgeMs)
23
+ return sendJson(res, 400, { error: "This range is longer than the hub keeps data." });
24
+ const scope = { project: p.get("project") || undefined, env: p.get("env") || undefined };
25
+ const params = paramsOf(p);
26
+ const now = alignNow(c.o.now());
27
+ // Stats only change when traces settle or leave, so the settle counter keys the cache.
28
+ const key = JSON.stringify([page, range, scope, params, now, store.settleGen]);
29
+ if (cache.has(key))
30
+ return sendJson(res, 200, cache.get(key));
31
+ const ctx = pageContext(range, now, params, { slowQueryMs: FACT_SLOW_QUERY_MS }, hubSettling(store, scope));
32
+ const value = await runPage(page, ctx, hubExecutor(store, scope, c.data.keepRemote));
33
+ remember(key, value);
34
+ sendJson(res, 200, value);
35
+ }
36
+ //# sourceMappingURL=models-api.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"models-api.js","sourceRoot":"","sources":["../src/models-api.ts"],"names":[],"mappings":"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"}