@camstack/system 1.2.456 → 1.2.457

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 (117) hide show
  1. package/dist/addon-runner.js +96 -10
  2. package/dist/addon-runner.mjs +96 -10
  3. package/dist/{agent-https-fm4AR8XL.mjs → agent-https-CK9Z4sSR.mjs} +2 -2
  4. package/dist/{agent-https-yjxdfJDA.js → agent-https-CoyOZ3pC.js} +2 -2
  5. package/dist/builtins/addon-pages-aggregator/addon-pages-aggregator.addon.js +1 -1
  6. package/dist/builtins/addon-pages-aggregator/addon-pages-aggregator.addon.mjs +1 -1
  7. package/dist/builtins/addon-widgets-aggregator/addon-widgets-aggregator.addon.js +1 -1
  8. package/dist/builtins/addon-widgets-aggregator/addon-widgets-aggregator.addon.mjs +1 -1
  9. package/dist/builtins/alerts/alerts.addon.js +2 -2
  10. package/dist/builtins/alerts/alerts.addon.mjs +2 -2
  11. package/dist/builtins/autotrack/index.js +1 -1
  12. package/dist/builtins/autotrack/index.mjs +1 -1
  13. package/dist/builtins/backup-orchestrator/backup-orchestrator.addon.js +2 -2
  14. package/dist/builtins/backup-orchestrator/backup-orchestrator.addon.mjs +2 -2
  15. package/dist/builtins/calendars/calendars.addon.js +1 -1
  16. package/dist/builtins/calendars/calendars.addon.mjs +1 -1
  17. package/dist/builtins/camera-grid/index.js +1 -1
  18. package/dist/builtins/camera-grid/index.mjs +1 -1
  19. package/dist/builtins/composer/composer.addon.js +2 -2
  20. package/dist/builtins/composer/composer.addon.mjs +2 -2
  21. package/dist/builtins/console-logging/console-destination.d.ts +1 -2
  22. package/dist/builtins/console-logging/index.js +1 -4
  23. package/dist/builtins/console-logging/index.mjs +1 -4
  24. package/dist/builtins/core-blocks/core-blocks.addon.js +2 -2
  25. package/dist/builtins/core-blocks/core-blocks.addon.mjs +2 -2
  26. package/dist/builtins/device-history/capture/capture-engine.d.ts +6 -0
  27. package/dist/builtins/device-history/device-history.addon.js +441 -83
  28. package/dist/builtins/device-history/device-history.addon.mjs +441 -83
  29. package/dist/builtins/device-history/query/history-query.d.ts +35 -9
  30. package/dist/builtins/device-history/query/point-shape.d.ts +33 -0
  31. package/dist/builtins/device-history/retention/retention.d.ts +1 -1
  32. package/dist/builtins/device-history/rollup/rollup-engine.d.ts +2 -0
  33. package/dist/builtins/device-history/rollup/rollup-math.d.ts +6 -0
  34. package/dist/builtins/device-history/store/history-store.d.ts +7 -0
  35. package/dist/builtins/device-history/store/series-registry.d.ts +26 -1
  36. package/dist/builtins/device-manager/device-manager.addon.js +1 -1
  37. package/dist/builtins/device-manager/device-manager.addon.mjs +1 -1
  38. package/dist/builtins/hub-forwarder/hub-forwarder-destination.d.ts +1 -2
  39. package/dist/builtins/hub-forwarder/index.js +1 -4
  40. package/dist/builtins/hub-forwarder/index.mjs +1 -4
  41. package/dist/builtins/keychain/index.js +4 -4
  42. package/dist/builtins/keychain/index.mjs +4 -4
  43. package/dist/builtins/liveness-monitor/liveness-monitor.addon.js +1 -1
  44. package/dist/builtins/liveness-monitor/liveness-monitor.addon.mjs +1 -1
  45. package/dist/builtins/local-auth/local-auth.addon.js +3 -3
  46. package/dist/builtins/local-auth/local-auth.addon.mjs +3 -3
  47. package/dist/builtins/local-network/local-network.addon.js +2 -2
  48. package/dist/builtins/local-network/local-network.addon.mjs +2 -2
  49. package/dist/builtins/loki-logging/index.js +323 -7
  50. package/dist/builtins/loki-logging/index.mjs +323 -7
  51. package/dist/builtins/loki-logging/loki-destination.d.ts +20 -3
  52. package/dist/builtins/loki-logging/loki-read.d.ts +51 -0
  53. package/dist/builtins/native-metrics/native-metrics.addon.js +290 -112
  54. package/dist/builtins/native-metrics/native-metrics.addon.mjs +290 -112
  55. package/dist/builtins/native-metrics/node-metrics-history-recorder.d.ts +106 -35
  56. package/dist/builtins/platform-probe/index.js +1 -1
  57. package/dist/builtins/platform-probe/index.mjs +1 -1
  58. package/dist/builtins/record-entries/index.js +1 -1
  59. package/dist/builtins/record-entries/index.mjs +1 -1
  60. package/dist/builtins/remote-access-orchestrator/remote-access-orchestrator.addon.js +1 -1
  61. package/dist/builtins/remote-access-orchestrator/remote-access-orchestrator.addon.mjs +1 -1
  62. package/dist/builtins/snapshot/index.js +1 -1
  63. package/dist/builtins/snapshot/index.mjs +1 -1
  64. package/dist/builtins/sqlite-storage/filesystem-storage.addon.js +1 -1
  65. package/dist/builtins/sqlite-storage/filesystem-storage.addon.mjs +1 -1
  66. package/dist/builtins/sqlite-storage/index.js +1 -1
  67. package/dist/builtins/sqlite-storage/index.mjs +1 -1
  68. package/dist/builtins/sqlite-storage/sqlite-settings.addon.js +2 -2
  69. package/dist/builtins/sqlite-storage/sqlite-settings.addon.mjs +2 -2
  70. package/dist/builtins/storage-orchestrator/location-history-recorder.d.ts +76 -0
  71. package/dist/builtins/storage-orchestrator/storage-orchestrator.addon.d.ts +9 -0
  72. package/dist/builtins/storage-orchestrator/storage-orchestrator.addon.js +144 -1
  73. package/dist/builtins/storage-orchestrator/storage-orchestrator.addon.mjs +144 -1
  74. package/dist/builtins/system-config/system-config.addon.js +3 -3
  75. package/dist/builtins/system-config/system-config.addon.mjs +3 -3
  76. package/dist/builtins/winston-logging/index.js +165 -3
  77. package/dist/builtins/winston-logging/index.mjs +165 -3
  78. package/dist/builtins/winston-logging/log-file-cursor.d.ts +12 -0
  79. package/dist/builtins/winston-logging/log-file-index-store.d.ts +11 -0
  80. package/dist/builtins/winston-logging/log-file-index.d.ts +77 -0
  81. package/dist/builtins/winston-logging/log-file-read-client.d.ts +44 -0
  82. package/dist/builtins/winston-logging/log-file-read-protocol.d.ts +41 -0
  83. package/dist/builtins/winston-logging/log-file-read-worker.d.ts +1 -0
  84. package/dist/builtins/winston-logging/log-file-reader.d.ts +51 -0
  85. package/dist/builtins/winston-logging/winston-destination.d.ts +20 -2
  86. package/dist/{composition-sources-Ds0Vr6eD.mjs → composition-sources-B_jeZDRJ.mjs} +1 -1
  87. package/dist/{composition-sources-gB4coDJR.js → composition-sources-qKyvMAvc.js} +1 -1
  88. package/dist/{constants-CavyKfHZ.js → constants-B_X9cWEK.js} +1 -1
  89. package/dist/{constants-i5oD_gLB.mjs → constants-cxKcZRMi.mjs} +1 -1
  90. package/dist/{device-ca-qz1Pmeu1.mjs → device-ca-BB6nHAL5.mjs} +1 -1
  91. package/dist/{device-ca-bpoEr0zG.js → device-ca-CVK3YcR_.js} +1 -1
  92. package/dist/{dist-BpqA2CT0.js → dist-C89nqNnn.js} +471 -47
  93. package/dist/{dist-BSF_C8W2.mjs → dist-Dhux90yB.mjs} +454 -48
  94. package/dist/file-host-worker.js +1 -1
  95. package/dist/file-host-worker.mjs +1 -1
  96. package/dist/{hub-mdns-ciao-CHaGDzyz.mjs → hub-mdns-ciao-B8olZqqd.mjs} +2 -2
  97. package/dist/{hub-mdns-ciao-CZlZRxxA.js → hub-mdns-ciao-DB1Y9agt.js} +2 -2
  98. package/dist/index.d.ts +1 -0
  99. package/dist/index.js +135 -20
  100. package/dist/index.mjs +129 -21
  101. package/dist/kernel/config-schema.d.ts +5 -0
  102. package/dist/kernel/moleculer/accessory-prune-gate.d.ts +55 -0
  103. package/dist/log-file-read-protocol-B7M3X3bT.mjs +785 -0
  104. package/dist/log-file-read-protocol-D0WcLbIV.js +817 -0
  105. package/dist/log-file-read-worker.js +64 -0
  106. package/dist/log-file-read-worker.mjs +64 -0
  107. package/dist/log-read-filter-Bi066jwU.js +134 -0
  108. package/dist/log-read-filter-D7Ev3zm-.mjs +93 -0
  109. package/dist/logging/log-manager.d.ts +10 -6
  110. package/dist/logging/log-read-filter.d.ts +43 -0
  111. package/dist/{phase6-declare-gate-n-IZRklX.js → phase6-declare-gate-BO-_jLh_.js} +1 -1
  112. package/dist/{phase6-declare-gate-B4yfsf2n.mjs → phase6-declare-gate-x9ZCbQJP.mjs} +1 -1
  113. package/dist/{restore-archive-B4QG7XmX.js → restore-archive-4DOUR5Gu.js} +1 -1
  114. package/dist/{restore-archive-BGUM4FKf.mjs → restore-archive-DyOaPeAr.mjs} +1 -1
  115. package/dist/{wal-maintenance-AerF4XE6.mjs → wal-maintenance-BMiX6UIa.mjs} +0 -0
  116. package/dist/{wal-maintenance-CNEs_I94.js → wal-maintenance-DVN-DiVP.js} +0 -0
  117. package/package.json +1 -1
@@ -0,0 +1,64 @@
1
+ require("./chunk-Cek0wNdY.js");
2
+ const require_log_file_read_protocol = require("./log-file-read-protocol-D0WcLbIV.js");
3
+ let node_worker_threads = require("node:worker_threads");
4
+ //#region src/builtins/winston-logging/log-file-read-worker.ts
5
+ /**
6
+ * The rotated-file reader thread (D898) — a worker of whichever process runs
7
+ * `winston-logging`, so scanning and indexing a day of logs never runs on that
8
+ * process's event loop.
9
+ *
10
+ * A separate bundle (`dist/log-file-read-worker.js`, wired in
11
+ * `vite.config.ts`). It imports nothing from the kernel: the index, the
12
+ * reader and the shared line filter.
13
+ */
14
+ function isWorkerData(value) {
15
+ return typeof value === "object" && value !== null && "logsDir" in value && typeof value.logsDir === "string" && "backgroundPassMs" in value && typeof value.backgroundPassMs === "number";
16
+ }
17
+ var port = node_worker_threads.parentPort;
18
+ if (port === null || !isWorkerData(node_worker_threads.workerData)) throw new Error("log-file-read-worker: started without a parent port or worker data");
19
+ var data = node_worker_threads.workerData;
20
+ var store = new require_log_file_read_protocol.LogFileIndexStore(data.logsDir);
21
+ var cancels = new require_log_file_read_protocol.CancelBook();
22
+ var stopping = false;
23
+ var passRunning = false;
24
+ async function backgroundPass() {
25
+ if (passRunning || stopping) return;
26
+ passRunning = true;
27
+ try {
28
+ await store.backgroundPass(() => stopping);
29
+ } catch {} finally {
30
+ passRunning = false;
31
+ }
32
+ }
33
+ var timer = data.backgroundPassMs > 0 ? setInterval(() => void backgroundPass(), data.backgroundPassMs) : null;
34
+ if (data.backgroundPassMs > 0) backgroundPass();
35
+ port.on("message", (message) => {
36
+ if (!require_log_file_read_protocol.isToReader(message)) return;
37
+ if (message.type === "stop") {
38
+ stopping = true;
39
+ if (timer !== null) clearInterval(timer);
40
+ port.close();
41
+ return;
42
+ }
43
+ if (message.type === "cancel") {
44
+ cancels.cancel(message.requestId);
45
+ return;
46
+ }
47
+ const { id, query } = message;
48
+ require_log_file_read_protocol.serveRead(data.logsDir, store, cancels, query).then((outcome) => {
49
+ const reply = {
50
+ type: "result",
51
+ id,
52
+ result: outcome.result
53
+ };
54
+ port.postMessage(reply);
55
+ }, (error) => {
56
+ const reply = {
57
+ type: "error",
58
+ id,
59
+ message: error instanceof Error ? error.message : String(error)
60
+ };
61
+ port.postMessage(reply);
62
+ });
63
+ });
64
+ //#endregion
@@ -0,0 +1,64 @@
1
+ import { a as LogFileIndexStore, i as serveRead, r as isToReader, t as CancelBook } from "./log-file-read-protocol-B7M3X3bT.mjs";
2
+ import { parentPort, workerData } from "node:worker_threads";
3
+ //#region src/builtins/winston-logging/log-file-read-worker.ts
4
+ /**
5
+ * The rotated-file reader thread (D898) — a worker of whichever process runs
6
+ * `winston-logging`, so scanning and indexing a day of logs never runs on that
7
+ * process's event loop.
8
+ *
9
+ * A separate bundle (`dist/log-file-read-worker.js`, wired in
10
+ * `vite.config.ts`). It imports nothing from the kernel: the index, the
11
+ * reader and the shared line filter.
12
+ */
13
+ function isWorkerData(value) {
14
+ return typeof value === "object" && value !== null && "logsDir" in value && typeof value.logsDir === "string" && "backgroundPassMs" in value && typeof value.backgroundPassMs === "number";
15
+ }
16
+ var port = parentPort;
17
+ if (port === null || !isWorkerData(workerData)) throw new Error("log-file-read-worker: started without a parent port or worker data");
18
+ var data = workerData;
19
+ var store = new LogFileIndexStore(data.logsDir);
20
+ var cancels = new CancelBook();
21
+ var stopping = false;
22
+ var passRunning = false;
23
+ async function backgroundPass() {
24
+ if (passRunning || stopping) return;
25
+ passRunning = true;
26
+ try {
27
+ await store.backgroundPass(() => stopping);
28
+ } catch {} finally {
29
+ passRunning = false;
30
+ }
31
+ }
32
+ var timer = data.backgroundPassMs > 0 ? setInterval(() => void backgroundPass(), data.backgroundPassMs) : null;
33
+ if (data.backgroundPassMs > 0) backgroundPass();
34
+ port.on("message", (message) => {
35
+ if (!isToReader(message)) return;
36
+ if (message.type === "stop") {
37
+ stopping = true;
38
+ if (timer !== null) clearInterval(timer);
39
+ port.close();
40
+ return;
41
+ }
42
+ if (message.type === "cancel") {
43
+ cancels.cancel(message.requestId);
44
+ return;
45
+ }
46
+ const { id, query } = message;
47
+ serveRead(data.logsDir, store, cancels, query).then((outcome) => {
48
+ const reply = {
49
+ type: "result",
50
+ id,
51
+ result: outcome.result
52
+ };
53
+ port.postMessage(reply);
54
+ }, (error) => {
55
+ const reply = {
56
+ type: "error",
57
+ id,
58
+ message: error instanceof Error ? error.message : String(error)
59
+ };
60
+ port.postMessage(reply);
61
+ });
62
+ });
63
+ //#endregion
64
+ export {};
@@ -0,0 +1,134 @@
1
+ //#region src/logging/log-read-filter.ts
2
+ var LEVEL_RANK = {
3
+ debug: 0,
4
+ info: 1,
5
+ warn: 2,
6
+ error: 3
7
+ };
8
+ function levelRank(level) {
9
+ return level === "debug" || level === "info" || level === "warn" || level === "error" ? LEVEL_RANK[level] : LEVEL_RANK.info;
10
+ }
11
+ /** `provider@1.2.3` / `audio-codec::native-device-ops` → the manifest id. */
12
+ function bareAddonOf(raw) {
13
+ if (typeof raw !== "string" || raw.length === 0) return null;
14
+ let bare = raw.split("@")[0] ?? raw;
15
+ const colon = bare.indexOf("::");
16
+ if (colon >= 0) bare = bare.slice(0, colon);
17
+ return bare;
18
+ }
19
+ /** The node a line is attributed to for the `nodeId` filter and the block index. */
20
+ function originNodeOf(tags) {
21
+ const agentId = tags?.["agentId"];
22
+ if (typeof agentId === "string" && agentId.length > 0) return agentId;
23
+ const nodeId = tags?.["nodeId"];
24
+ if (typeof nodeId === "string" && nodeId.length > 0) {
25
+ const slash = nodeId.indexOf("/");
26
+ return slash === -1 ? nodeId : nodeId.slice(0, slash);
27
+ }
28
+ return null;
29
+ }
30
+ function nodeMatches(tags, want) {
31
+ if (tags === void 0) return false;
32
+ const agentId = tags["agentId"];
33
+ const nodeId = tags["nodeId"];
34
+ if (agentId === want || nodeId === want) return true;
35
+ return typeof nodeId === "string" && nodeId.startsWith(`${want}/`);
36
+ }
37
+ function stringifyValue(value) {
38
+ if (typeof value === "string") return value;
39
+ if (typeof value === "number" || typeof value === "boolean") return String(value);
40
+ try {
41
+ return JSON.stringify(value) ?? "";
42
+ } catch {
43
+ return String(value);
44
+ }
45
+ }
46
+ /** Case-insensitive substring over message, scope, every tag value and every meta value. */
47
+ function lineContainsText(line, needleLower) {
48
+ if (line.message.toLowerCase().includes(needleLower)) return true;
49
+ if (line.scope !== void 0 && line.scope.toLowerCase().includes(needleLower)) return true;
50
+ for (const bag of [line.tags, line.meta]) {
51
+ if (bag === void 0) continue;
52
+ for (const value of Object.values(bag)) {
53
+ if (value === void 0 || value === null) continue;
54
+ if (stringifyValue(value).toLowerCase().includes(needleLower)) return true;
55
+ }
56
+ }
57
+ return false;
58
+ }
59
+ function compileLogFilter(query) {
60
+ const text = query.text?.trim() ?? "";
61
+ return {
62
+ deviceId: query.deviceId ?? null,
63
+ addonId: query.fromAddonId !== void 0 ? bareAddonOf(query.fromAddonId) : null,
64
+ nodeId: query.fromNodeId ?? null,
65
+ tags: query.tags ?? {},
66
+ levelFloor: query.level !== void 0 ? LEVEL_RANK[query.level] : 0,
67
+ textLower: text.length > 0 ? text.toLowerCase() : null,
68
+ since: query.since ?? null,
69
+ until: query.until ?? null
70
+ };
71
+ }
72
+ /** Exact match of one line against the whole filter. */
73
+ function lineMatches(line, filter) {
74
+ if (levelRank(line.level) < filter.levelFloor) return false;
75
+ if (filter.since !== null && line.timestamp < filter.since) return false;
76
+ if (filter.until !== null && line.timestamp > filter.until) return false;
77
+ const tags = line.tags;
78
+ if (filter.deviceId !== null && tags?.["deviceId"] !== filter.deviceId) return false;
79
+ if (filter.addonId !== null && bareAddonOf(tags?.["addonId"]) !== filter.addonId) return false;
80
+ if (filter.nodeId !== null && !nodeMatches(tags, filter.nodeId)) return false;
81
+ for (const [key, want] of Object.entries(filter.tags)) {
82
+ const have = tags?.[key];
83
+ if (have !== want && !(typeof have === "number" && String(have) === String(want))) return false;
84
+ }
85
+ if (filter.textLower !== null && !lineContainsText(line, filter.textLower)) return false;
86
+ return true;
87
+ }
88
+ /** True when the filter constrains nothing — every line matches. */
89
+ function filterIsEmpty(filter) {
90
+ return filter.deviceId === null && filter.addonId === null && filter.nodeId === null && Object.keys(filter.tags).length === 0 && filter.levelFloor === 0 && filter.textLower === null && filter.since === null && filter.until === null;
91
+ }
92
+ //#endregion
93
+ Object.defineProperty(exports, "bareAddonOf", {
94
+ enumerable: true,
95
+ get: function() {
96
+ return bareAddonOf;
97
+ }
98
+ });
99
+ Object.defineProperty(exports, "compileLogFilter", {
100
+ enumerable: true,
101
+ get: function() {
102
+ return compileLogFilter;
103
+ }
104
+ });
105
+ Object.defineProperty(exports, "filterIsEmpty", {
106
+ enumerable: true,
107
+ get: function() {
108
+ return filterIsEmpty;
109
+ }
110
+ });
111
+ Object.defineProperty(exports, "levelRank", {
112
+ enumerable: true,
113
+ get: function() {
114
+ return levelRank;
115
+ }
116
+ });
117
+ Object.defineProperty(exports, "lineContainsText", {
118
+ enumerable: true,
119
+ get: function() {
120
+ return lineContainsText;
121
+ }
122
+ });
123
+ Object.defineProperty(exports, "lineMatches", {
124
+ enumerable: true,
125
+ get: function() {
126
+ return lineMatches;
127
+ }
128
+ });
129
+ Object.defineProperty(exports, "originNodeOf", {
130
+ enumerable: true,
131
+ get: function() {
132
+ return originNodeOf;
133
+ }
134
+ });
@@ -0,0 +1,93 @@
1
+ //#region src/logging/log-read-filter.ts
2
+ var LEVEL_RANK = {
3
+ debug: 0,
4
+ info: 1,
5
+ warn: 2,
6
+ error: 3
7
+ };
8
+ function levelRank(level) {
9
+ return level === "debug" || level === "info" || level === "warn" || level === "error" ? LEVEL_RANK[level] : LEVEL_RANK.info;
10
+ }
11
+ /** `provider@1.2.3` / `audio-codec::native-device-ops` → the manifest id. */
12
+ function bareAddonOf(raw) {
13
+ if (typeof raw !== "string" || raw.length === 0) return null;
14
+ let bare = raw.split("@")[0] ?? raw;
15
+ const colon = bare.indexOf("::");
16
+ if (colon >= 0) bare = bare.slice(0, colon);
17
+ return bare;
18
+ }
19
+ /** The node a line is attributed to for the `nodeId` filter and the block index. */
20
+ function originNodeOf(tags) {
21
+ const agentId = tags?.["agentId"];
22
+ if (typeof agentId === "string" && agentId.length > 0) return agentId;
23
+ const nodeId = tags?.["nodeId"];
24
+ if (typeof nodeId === "string" && nodeId.length > 0) {
25
+ const slash = nodeId.indexOf("/");
26
+ return slash === -1 ? nodeId : nodeId.slice(0, slash);
27
+ }
28
+ return null;
29
+ }
30
+ function nodeMatches(tags, want) {
31
+ if (tags === void 0) return false;
32
+ const agentId = tags["agentId"];
33
+ const nodeId = tags["nodeId"];
34
+ if (agentId === want || nodeId === want) return true;
35
+ return typeof nodeId === "string" && nodeId.startsWith(`${want}/`);
36
+ }
37
+ function stringifyValue(value) {
38
+ if (typeof value === "string") return value;
39
+ if (typeof value === "number" || typeof value === "boolean") return String(value);
40
+ try {
41
+ return JSON.stringify(value) ?? "";
42
+ } catch {
43
+ return String(value);
44
+ }
45
+ }
46
+ /** Case-insensitive substring over message, scope, every tag value and every meta value. */
47
+ function lineContainsText(line, needleLower) {
48
+ if (line.message.toLowerCase().includes(needleLower)) return true;
49
+ if (line.scope !== void 0 && line.scope.toLowerCase().includes(needleLower)) return true;
50
+ for (const bag of [line.tags, line.meta]) {
51
+ if (bag === void 0) continue;
52
+ for (const value of Object.values(bag)) {
53
+ if (value === void 0 || value === null) continue;
54
+ if (stringifyValue(value).toLowerCase().includes(needleLower)) return true;
55
+ }
56
+ }
57
+ return false;
58
+ }
59
+ function compileLogFilter(query) {
60
+ const text = query.text?.trim() ?? "";
61
+ return {
62
+ deviceId: query.deviceId ?? null,
63
+ addonId: query.fromAddonId !== void 0 ? bareAddonOf(query.fromAddonId) : null,
64
+ nodeId: query.fromNodeId ?? null,
65
+ tags: query.tags ?? {},
66
+ levelFloor: query.level !== void 0 ? LEVEL_RANK[query.level] : 0,
67
+ textLower: text.length > 0 ? text.toLowerCase() : null,
68
+ since: query.since ?? null,
69
+ until: query.until ?? null
70
+ };
71
+ }
72
+ /** Exact match of one line against the whole filter. */
73
+ function lineMatches(line, filter) {
74
+ if (levelRank(line.level) < filter.levelFloor) return false;
75
+ if (filter.since !== null && line.timestamp < filter.since) return false;
76
+ if (filter.until !== null && line.timestamp > filter.until) return false;
77
+ const tags = line.tags;
78
+ if (filter.deviceId !== null && tags?.["deviceId"] !== filter.deviceId) return false;
79
+ if (filter.addonId !== null && bareAddonOf(tags?.["addonId"]) !== filter.addonId) return false;
80
+ if (filter.nodeId !== null && !nodeMatches(tags, filter.nodeId)) return false;
81
+ for (const [key, want] of Object.entries(filter.tags)) {
82
+ const have = tags?.[key];
83
+ if (have !== want && !(typeof have === "number" && String(have) === String(want))) return false;
84
+ }
85
+ if (filter.textLower !== null && !lineContainsText(line, filter.textLower)) return false;
86
+ return true;
87
+ }
88
+ /** True when the filter constrains nothing — every line matches. */
89
+ function filterIsEmpty(filter) {
90
+ return filter.deviceId === null && filter.addonId === null && filter.nodeId === null && Object.keys(filter.tags).length === 0 && filter.levelFloor === 0 && filter.textLower === null && filter.since === null && filter.until === null;
91
+ }
92
+ //#endregion
93
+ export { lineContainsText as a, levelRank as i, compileLogFilter as n, lineMatches as o, filterIsEmpty as r, originNodeOf as s, bareAddonOf as t };
@@ -2,12 +2,8 @@ import { type LogEntry, type LogFilter, type LogLevel } from "./log-ring-buffer.
2
2
  import type { LoggingGate } from "./logging-gate.js";
3
3
  import { type PartitionedLogBufferOptions } from "./partitioned-log-buffer.js";
4
4
  import { type IScopedLogger } from "./scoped-logger.js";
5
- export interface ILogDestination {
6
- initialize(): Promise<void>;
7
- shutdown(): Promise<void>;
8
- write(entry: LogEntry): void;
9
- query?(filter: LogFilter): Promise<readonly LogEntry[]>;
10
- }
5
+ import type { ILogDestination } from "@camstack/types";
6
+ export type { ILogDestination };
11
7
  /**
12
8
  * The reserved destination id of the in-memory buffer. Not an addon: the
13
9
  * buffer must exist before any addon loads (boot lines) and it backs
@@ -62,6 +58,14 @@ export declare class LogManager {
62
58
  */
63
59
  private gate;
64
60
  /**
61
+ * Entry identity (D898): `<bootId>.<seq>`, stamped once, here, on every line
62
+ * this process accepts — so the in-memory tail, the live subscription and
63
+ * the rotated file carry the SAME id and a page read from disk dedupes
64
+ * exactly against the lines pushed live.
65
+ */
66
+ private readonly bootId;
67
+ private seq;
68
+ /**
65
69
  * `perAddonCapacity` bounds EACH addon's bucket, not the total — a chatty addon
66
70
  * evicts only its own lines, so quiet addons keep their sparse history.
67
71
  *
@@ -0,0 +1,43 @@
1
+ /**
2
+ * The ONE definition of "does this line match a history read" (D898).
3
+ *
4
+ * Used by every reader — the rotated-file reader in its worker, the Loki
5
+ * reader after LogQL has narrowed the stream, and the hub's in-memory tail —
6
+ * so the same query cannot mean three different things on three sources.
7
+ *
8
+ * It is deliberately free of value imports: the file reader runs it inside a
9
+ * bare worker thread.
10
+ */
11
+ import type { LogReadQuery } from "@camstack/types";
12
+ /** A structurally-typed line: a parsed file row, a ring entry or a Loki line. */
13
+ export interface ReadableLine {
14
+ readonly timestamp: number;
15
+ readonly level: string;
16
+ readonly message: string;
17
+ readonly scope?: string | undefined;
18
+ readonly tags?: Readonly<Record<string, unknown>> | undefined;
19
+ readonly meta?: Readonly<Record<string, unknown>> | undefined;
20
+ }
21
+ export declare function levelRank(level: string): number;
22
+ /** `provider@1.2.3` / `audio-codec::native-device-ops` → the manifest id. */
23
+ export declare function bareAddonOf(raw: unknown): string | null;
24
+ /** The node a line is attributed to for the `nodeId` filter and the block index. */
25
+ export declare function originNodeOf(tags: Readonly<Record<string, unknown>> | undefined): string | null;
26
+ /** Case-insensitive substring over message, scope, every tag value and every meta value. */
27
+ export declare function lineContainsText(line: ReadableLine, needleLower: string): boolean;
28
+ /** The filter half of a {@link LogReadQuery}, normalised once per read. */
29
+ export interface CompiledLogFilter {
30
+ readonly deviceId: number | null;
31
+ readonly addonId: string | null;
32
+ readonly nodeId: string | null;
33
+ readonly tags: Readonly<Record<string, string | number>>;
34
+ readonly levelFloor: number;
35
+ readonly textLower: string | null;
36
+ readonly since: number | null;
37
+ readonly until: number | null;
38
+ }
39
+ export declare function compileLogFilter(query: LogReadQuery): CompiledLogFilter;
40
+ /** Exact match of one line against the whole filter. */
41
+ export declare function lineMatches(line: ReadableLine, filter: CompiledLogFilter): boolean;
42
+ /** True when the filter constrains nothing — every line matches. */
43
+ export declare function filterIsEmpty(filter: CompiledLogFilter): boolean;
@@ -1,4 +1,4 @@
1
- const require_dist = require("./dist-BpqA2CT0.js");
1
+ const require_dist = require("./dist-C89nqNnn.js");
2
2
  //#region src/builtins/records/legacy-table-row-count.ts
3
3
  /** Row count for a physical settings-db table (matches the records engine `legacyRowCount`). */
4
4
  function legacyTableRowCountFromList(tables, collection) {
@@ -1,4 +1,4 @@
1
- import { Vi as declarationsOf } from "./dist-BSF_C8W2.mjs";
1
+ import { Wi as declarationsOf } from "./dist-Dhux90yB.mjs";
2
2
  //#region src/builtins/records/legacy-table-row-count.ts
3
3
  /** Row count for a physical settings-db table (matches the records engine `legacyRowCount`). */
4
4
  function legacyTableRowCountFromList(tables, collection) {
@@ -1,5 +1,5 @@
1
1
  const require_chunk = require("./chunk-Cek0wNdY.js");
2
- const require_dist = require("./dist-BpqA2CT0.js");
2
+ const require_dist = require("./dist-C89nqNnn.js");
3
3
  const require_read_all_rows$1 = require("./read-all-rows-CVoO1ONM.js");
4
4
  let zod = require("zod");
5
5
  let node_crypto = require("node:crypto");
@@ -1,4 +1,4 @@
1
- import { M as DataStoreDatabaseSchema, S as DATABASE_SNAPSHOT_SUFFIX, Ui as defineRecordKinds } from "./dist-BSF_C8W2.mjs";
1
+ import { Ki as defineRecordKinds, N as DataStoreDatabaseSchema, S as DATABASE_SNAPSHOT_SUFFIX } from "./dist-Dhux90yB.mjs";
2
2
  import { t as require_read_all_rows } from "./read-all-rows-TaPqdWNF.mjs";
3
3
  import { z } from "zod";
4
4
  import { createCipheriv, createDecipheriv, createHash, createPrivateKey, createPublicKey, diffieHellman, generateKeyPairSync, hkdfSync, randomBytes } from "node:crypto";
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@camstack/system",
3
- "version": "1.2.456",
3
+ "version": "1.2.457",
4
4
  "description": "Core addon for CamStack — builtins, pipeline, process management, auth, logging, events",
5
5
  "keywords": [
6
6
  "camstack",