@camstack/system 1.2.456 → 1.2.458
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/addon-runner.js +259 -37
- package/dist/addon-runner.mjs +289 -67
- package/dist/{agent-https-fm4AR8XL.mjs → agent-https-CQA3W-3e.mjs} +2 -2
- package/dist/{agent-https-yjxdfJDA.js → agent-https-DOELEug8.js} +2 -2
- package/dist/builtins/addon-pages-aggregator/addon-pages-aggregator.addon.js +1 -1
- package/dist/builtins/addon-pages-aggregator/addon-pages-aggregator.addon.mjs +1 -1
- package/dist/builtins/addon-widgets-aggregator/addon-widgets-aggregator.addon.js +1 -1
- package/dist/builtins/addon-widgets-aggregator/addon-widgets-aggregator.addon.mjs +1 -1
- package/dist/builtins/alerts/alerts.addon.js +2 -2
- package/dist/builtins/alerts/alerts.addon.mjs +2 -2
- package/dist/builtins/autotrack/index.js +1 -1
- package/dist/builtins/autotrack/index.mjs +1 -1
- package/dist/builtins/backup-orchestrator/backup-orchestrator.addon.js +2 -2
- package/dist/builtins/backup-orchestrator/backup-orchestrator.addon.mjs +2 -2
- package/dist/builtins/calendars/calendars.addon.js +1 -1
- package/dist/builtins/calendars/calendars.addon.mjs +1 -1
- package/dist/builtins/camera-grid/index.js +1 -1
- package/dist/builtins/camera-grid/index.mjs +1 -1
- package/dist/builtins/composer/composer.addon.js +2 -2
- package/dist/builtins/composer/composer.addon.mjs +2 -2
- package/dist/builtins/console-logging/console-destination.d.ts +1 -2
- package/dist/builtins/console-logging/index.js +1 -4
- package/dist/builtins/console-logging/index.mjs +1 -4
- package/dist/builtins/core-blocks/core-blocks.addon.js +2 -2
- package/dist/builtins/core-blocks/core-blocks.addon.mjs +2 -2
- package/dist/builtins/device-history/capture/capture-engine.d.ts +6 -0
- package/dist/builtins/device-history/device-history.addon.d.ts +13 -0
- package/dist/builtins/device-history/device-history.addon.js +736 -315
- package/dist/builtins/device-history/device-history.addon.mjs +736 -315
- package/dist/builtins/device-history/ingest/producer-ingest.d.ts +11 -1
- package/dist/builtins/device-history/query/history-query.d.ts +35 -9
- package/dist/builtins/device-history/query/point-shape.d.ts +33 -0
- package/dist/builtins/device-history/retention/retention.d.ts +1 -1
- package/dist/builtins/device-history/rollup/rollup-engine.d.ts +2 -0
- package/dist/builtins/device-history/rollup/rollup-math.d.ts +6 -0
- package/dist/builtins/device-history/store/history-store.d.ts +7 -0
- package/dist/builtins/device-history/store/series-registry.d.ts +26 -1
- package/dist/builtins/device-manager/device-manager.addon.js +1 -1
- package/dist/builtins/device-manager/device-manager.addon.mjs +1 -1
- package/dist/builtins/hub-forwarder/hub-forwarder-destination.d.ts +1 -2
- package/dist/builtins/hub-forwarder/index.js +1 -4
- package/dist/builtins/hub-forwarder/index.mjs +1 -4
- package/dist/builtins/keychain/index.js +4 -4
- package/dist/builtins/keychain/index.mjs +4 -4
- package/dist/builtins/liveness-monitor/liveness-monitor.addon.js +1 -1
- package/dist/builtins/liveness-monitor/liveness-monitor.addon.mjs +1 -1
- package/dist/builtins/local-auth/local-auth.addon.js +3 -3
- package/dist/builtins/local-auth/local-auth.addon.mjs +3 -3
- package/dist/builtins/local-network/local-network.addon.js +2 -2
- package/dist/builtins/local-network/local-network.addon.mjs +2 -2
- package/dist/builtins/loki-logging/index.js +323 -7
- package/dist/builtins/loki-logging/index.mjs +323 -7
- package/dist/builtins/loki-logging/loki-destination.d.ts +20 -3
- package/dist/builtins/loki-logging/loki-read.d.ts +51 -0
- package/dist/builtins/native-metrics/native-metrics.addon.js +290 -112
- package/dist/builtins/native-metrics/native-metrics.addon.mjs +290 -112
- package/dist/builtins/native-metrics/node-metrics-history-recorder.d.ts +106 -35
- package/dist/builtins/platform-probe/coral-accelerators.d.ts +26 -9
- package/dist/builtins/platform-probe/index.js +11 -68
- package/dist/builtins/platform-probe/index.mjs +11 -68
- package/dist/builtins/record-entries/index.js +1 -1
- package/dist/builtins/record-entries/index.mjs +1 -1
- package/dist/builtins/remote-access-orchestrator/remote-access-orchestrator.addon.js +1 -1
- package/dist/builtins/remote-access-orchestrator/remote-access-orchestrator.addon.mjs +1 -1
- package/dist/builtins/snapshot/index.js +1 -1
- package/dist/builtins/snapshot/index.mjs +1 -1
- package/dist/builtins/sqlite-storage/filesystem-storage.addon.js +1 -1
- package/dist/builtins/sqlite-storage/filesystem-storage.addon.mjs +1 -1
- package/dist/builtins/sqlite-storage/index.js +1 -1
- package/dist/builtins/sqlite-storage/index.mjs +1 -1
- package/dist/builtins/sqlite-storage/sqlite-settings.addon.js +2 -2
- package/dist/builtins/sqlite-storage/sqlite-settings.addon.mjs +2 -2
- package/dist/builtins/storage-orchestrator/location-history-recorder.d.ts +76 -0
- package/dist/builtins/storage-orchestrator/storage-orchestrator.addon.d.ts +9 -0
- package/dist/builtins/storage-orchestrator/storage-orchestrator.addon.js +144 -1
- package/dist/builtins/storage-orchestrator/storage-orchestrator.addon.mjs +144 -1
- package/dist/builtins/system-config/system-config.addon.js +3 -3
- package/dist/builtins/system-config/system-config.addon.mjs +3 -3
- package/dist/builtins/winston-logging/index.js +165 -3
- package/dist/builtins/winston-logging/index.mjs +165 -3
- package/dist/builtins/winston-logging/log-file-cursor.d.ts +12 -0
- package/dist/builtins/winston-logging/log-file-index-store.d.ts +11 -0
- package/dist/builtins/winston-logging/log-file-index.d.ts +77 -0
- package/dist/builtins/winston-logging/log-file-read-client.d.ts +44 -0
- package/dist/builtins/winston-logging/log-file-read-protocol.d.ts +41 -0
- package/dist/builtins/winston-logging/log-file-read-worker.d.ts +1 -0
- package/dist/builtins/winston-logging/log-file-reader.d.ts +51 -0
- package/dist/builtins/winston-logging/winston-destination.d.ts +20 -2
- package/dist/{composition-sources-Ds0Vr6eD.mjs → composition-sources-BVguN7VV.mjs} +1 -1
- package/dist/{composition-sources-gB4coDJR.js → composition-sources-DURQNDJ4.js} +1 -1
- package/dist/{constants-i5oD_gLB.mjs → constants-FGjnsE2x.mjs} +1 -1
- package/dist/{constants-CavyKfHZ.js → constants-Njka8Cv6.js} +1 -1
- package/dist/coral-accelerators-Bi_c3Rft.js +175 -0
- package/dist/coral-accelerators-DcnZvctM.mjs +162 -0
- package/dist/{device-ca-bpoEr0zG.js → device-ca-BrVK_5s3.js} +1 -1
- package/dist/{device-ca-qz1Pmeu1.mjs → device-ca-lEaAQ9Xi.mjs} +1 -1
- package/dist/{dist-BpqA2CT0.js → dist-BZQjLPiz.js} +526 -57
- package/dist/{dist-BSF_C8W2.mjs → dist-B_GRPhnY.mjs} +509 -58
- package/dist/file-host-worker.js +1 -1
- package/dist/file-host-worker.mjs +1 -1
- package/dist/{hub-mdns-ciao-CHaGDzyz.mjs → hub-mdns-ciao-Bg2HfTwP.mjs} +2 -2
- package/dist/{hub-mdns-ciao-CZlZRxxA.js → hub-mdns-ciao-nce3TXs_.js} +2 -2
- package/dist/index.d.ts +1 -0
- package/dist/index.js +140 -48
- package/dist/index.mjs +134 -49
- package/dist/kernel/config-schema.d.ts +5 -0
- package/dist/kernel/hwaccel/hwaccel-resolver.d.ts +7 -3
- package/dist/kernel/moleculer/accessory-prune-gate.d.ts +55 -0
- package/dist/log-file-read-protocol-B7M3X3bT.mjs +785 -0
- package/dist/log-file-read-protocol-D0WcLbIV.js +817 -0
- package/dist/log-file-read-worker.js +64 -0
- package/dist/log-file-read-worker.mjs +64 -0
- package/dist/log-read-filter-Bi066jwU.js +134 -0
- package/dist/log-read-filter-D7Ev3zm-.mjs +93 -0
- package/dist/logging/log-manager.d.ts +10 -6
- package/dist/logging/log-read-filter.d.ts +43 -0
- package/dist/{phase6-declare-gate-n-IZRklX.js → phase6-declare-gate-Dag1_WR2.js} +1 -1
- package/dist/{phase6-declare-gate-B4yfsf2n.mjs → phase6-declare-gate-Lb-mrVvz.mjs} +1 -1
- package/dist/{restore-archive-BGUM4FKf.mjs → restore-archive-C7kLDI_0.mjs} +1 -1
- package/dist/{restore-archive-B4QG7XmX.js → restore-archive-FyfZ8YMC.js} +1 -1
- package/dist/{wal-maintenance-CNEs_I94.js → wal-maintenance-DfSIOj24.js} +0 -0
- package/dist/{wal-maintenance-AerF4XE6.mjs → wal-maintenance-Duejh7Lx.mjs} +0 -0
- package/package.json +1 -1
|
@@ -1,22 +1,39 @@
|
|
|
1
1
|
import type { CoralInfo } from "@camstack/types";
|
|
2
2
|
/**
|
|
3
|
-
* Filesystem seam for Coral
|
|
4
|
-
* `AcceleratorFs` pattern in `intel-accelerators.ts` so the classifier
|
|
5
|
-
* pure, unit-testable function over injected reads.
|
|
3
|
+
* Filesystem seam for Coral Edge TPU detection (USB and PCIe/M.2) — mirrors
|
|
4
|
+
* the `AcceleratorFs` pattern in `intel-accelerators.ts` so the classifier
|
|
5
|
+
* stays a pure, unit-testable function over injected reads.
|
|
6
6
|
*/
|
|
7
7
|
export interface CoralFs {
|
|
8
8
|
/** USB device directory names under `/sys/bus/usb/devices` (e.g. `2-4`). */
|
|
9
9
|
listUsbDevices(): readonly string[];
|
|
10
10
|
/** Read a `<sysfsNode>/<attr>` value (idVendor / idProduct), trimmed. */
|
|
11
11
|
readUsbAttr(device: string, attr: string): string;
|
|
12
|
-
/**
|
|
12
|
+
/** PCI function names under `/sys/bus/pci/devices` (e.g. `0000:03:00.0`). */
|
|
13
|
+
listPciDevices(): readonly string[];
|
|
14
|
+
/** Read a PCI function's `vendor` / `device` attribute (e.g. `0x1ac1`), trimmed. */
|
|
15
|
+
readPciAttr(device: string, attr: string): string;
|
|
16
|
+
/** Entry names under `/sys/class/apex` (the gasket/apex driver: `apex_0`, …). */
|
|
17
|
+
listApexClass(): readonly string[];
|
|
18
|
+
/** Whether this process can open a device node for read AND write. */
|
|
19
|
+
canOpen(path: string): boolean;
|
|
20
|
+
/** Whether a filesystem path exists (the libedgetpu delegate, `/dev/apex_N`). */
|
|
13
21
|
exists(path: string): boolean;
|
|
14
22
|
}
|
|
15
23
|
/**
|
|
16
|
-
* Detect
|
|
17
|
-
*
|
|
18
|
-
*
|
|
19
|
-
*
|
|
20
|
-
*
|
|
24
|
+
* Detect Coral Edge TPUs on USB and PCIe/M.2.
|
|
25
|
+
*
|
|
26
|
+
* - USB: every matching USB device counts (multiple Corals run concurrently).
|
|
27
|
+
* - PCIe: the apex driver's units, each usable only if its device node opens;
|
|
28
|
+
* a Coral PCI function the driver did not bind is `driver-missing`.
|
|
29
|
+
* - Fallback: when NO Coral signal of either bus is visible but the libedgetpu
|
|
30
|
+
* delegate is installed (a container whose `/sys` USB view is limited), one
|
|
31
|
+
* USB Coral is assumed — never when a PCI Coral was seen, since the delegate
|
|
32
|
+
* then says nothing about USB.
|
|
33
|
+
*
|
|
34
|
+
* Returns `null` only when no Coral was found at all; a present-but-unusable
|
|
35
|
+
* Coral is reported with its typed reason, never as absent (D393/D315).
|
|
21
36
|
*/
|
|
22
37
|
export declare function classifyCoralAccelerator(fsx: CoralFs): CoralInfo | null;
|
|
38
|
+
/** The real filesystem view: `/sys` for enumeration, `/dev` for access. */
|
|
39
|
+
export declare const nodeCoralFs: CoralFs;
|
|
@@ -3,62 +3,14 @@ Object.defineProperties(exports, {
|
|
|
3
3
|
[Symbol.toStringTag]: { value: "Module" }
|
|
4
4
|
});
|
|
5
5
|
const require_chunk = require("../../chunk-Cek0wNdY.js");
|
|
6
|
-
const require_dist = require("../../dist-
|
|
6
|
+
const require_dist = require("../../dist-BZQjLPiz.js");
|
|
7
|
+
const require_coral_accelerators = require("../../coral-accelerators-Bi_c3Rft.js");
|
|
7
8
|
let node_util = require("node:util");
|
|
8
9
|
let node_os = require("node:os");
|
|
9
10
|
node_os = require_chunk.__toESM(node_os);
|
|
10
11
|
let node_fs = require("node:fs");
|
|
11
12
|
node_fs = require_chunk.__toESM(node_fs);
|
|
12
13
|
let node_child_process = require("node:child_process");
|
|
13
|
-
//#region src/builtins/platform-probe/coral-accelerators.ts
|
|
14
|
-
/**
|
|
15
|
-
* Coral USB Edge TPU USB identifiers.
|
|
16
|
-
*
|
|
17
|
-
* The device enumerates as `1a6e:089a` (Global Unichip) BEFORE the libedgetpu
|
|
18
|
-
* firmware loads, then re-enumerates as `18d1:9302` (Google) AFTER. Either id
|
|
19
|
-
* means a Coral is physically attached, so both count as a positive signal.
|
|
20
|
-
*/
|
|
21
|
-
var CORAL_USB_IDS = [{
|
|
22
|
-
vendor: "1a6e",
|
|
23
|
-
product: "089a"
|
|
24
|
-
}, {
|
|
25
|
-
vendor: "18d1",
|
|
26
|
-
product: "9302"
|
|
27
|
-
}];
|
|
28
|
-
/**
|
|
29
|
-
* Default install path of the libedgetpu delegate on the hub, provisioned
|
|
30
|
-
* out-of-band by `/data/deps/edgetpu-install.sh` (it is a system shared
|
|
31
|
-
* library, not a pip package). Overridable via `CAMSTACK_EDGETPU_LIB` — kept in
|
|
32
|
-
* sync with the Python pool's own default in `inference_pool.py`.
|
|
33
|
-
*/
|
|
34
|
-
var DEFAULT_EDGETPU_LIB = "/data/deps/edgetpu/lib/libedgetpu.so.1";
|
|
35
|
-
/**
|
|
36
|
-
* Detect a Coral USB Edge TPU. Present when EITHER a matching USB device is
|
|
37
|
-
* enumerated OR the libedgetpu delegate is installed (the delegate is the
|
|
38
|
-
* hub-provisioned runtime prerequisite; on a container whose `/sys` USB view is
|
|
39
|
-
* limited, its presence is a reliable operator-intent signal that the Coral is
|
|
40
|
-
* wired through). Returns `null` when neither signal is found.
|
|
41
|
-
*/
|
|
42
|
-
function classifyCoralAccelerator(fsx) {
|
|
43
|
-
let count = 0;
|
|
44
|
-
for (const device of fsx.listUsbDevices()) {
|
|
45
|
-
const vendor = fsx.readUsbAttr(device, "idVendor").toLowerCase();
|
|
46
|
-
const product = fsx.readUsbAttr(device, "idProduct").toLowerCase();
|
|
47
|
-
if (CORAL_USB_IDS.some((id) => id.vendor === vendor && id.product === product)) count++;
|
|
48
|
-
}
|
|
49
|
-
if (count > 0) return {
|
|
50
|
-
type: "coral-edgetpu",
|
|
51
|
-
bus: "usb",
|
|
52
|
-
count
|
|
53
|
-
};
|
|
54
|
-
const libPath = process.env["CAMSTACK_EDGETPU_LIB"] ?? DEFAULT_EDGETPU_LIB;
|
|
55
|
-
if (fsx.exists(libPath)) return {
|
|
56
|
-
type: "coral-edgetpu",
|
|
57
|
-
bus: "usb"
|
|
58
|
-
};
|
|
59
|
-
return null;
|
|
60
|
-
}
|
|
61
|
-
//#endregion
|
|
62
14
|
//#region src/builtins/platform-probe/amd-npu.ts
|
|
63
15
|
var amd_npu_exports = /* @__PURE__ */ require_chunk.__exportAll({
|
|
64
16
|
classifyAmdNpu: () => classifyAmdNpu,
|
|
@@ -462,24 +414,15 @@ var PlatformScorer = class {
|
|
|
462
414
|
} });
|
|
463
415
|
let gpu = null;
|
|
464
416
|
let npu = null;
|
|
465
|
-
const coral = classifyCoralAccelerator(
|
|
466
|
-
|
|
467
|
-
|
|
468
|
-
|
|
469
|
-
|
|
470
|
-
|
|
471
|
-
|
|
472
|
-
}
|
|
473
|
-
|
|
474
|
-
try {
|
|
475
|
-
return node_fs.readFileSync(`/sys/bus/usb/devices/${device}/${attr}`, "utf8").trim();
|
|
476
|
-
} catch {
|
|
477
|
-
return "";
|
|
478
|
-
}
|
|
479
|
-
},
|
|
480
|
-
exists: (p) => node_fs.existsSync(p)
|
|
481
|
-
});
|
|
482
|
-
if (coral) this.logger.info("Coral USB Edge TPU detected", { meta: { bus: coral.bus } });
|
|
417
|
+
const coral = require_coral_accelerators.classifyCoralAccelerator(require_coral_accelerators.nodeCoralFs);
|
|
418
|
+
if (coral) {
|
|
419
|
+
if ((coral.units ?? []).length > 0) this.logger.info("Coral Edge TPU detected", { meta: { units: coral.units } });
|
|
420
|
+
for (const unavailable of coral.unavailable ?? []) this.logger.warn("Coral Edge TPU present but unusable", { meta: {
|
|
421
|
+
bus: unavailable.bus,
|
|
422
|
+
count: unavailable.count,
|
|
423
|
+
reason: unavailable.reason
|
|
424
|
+
} });
|
|
425
|
+
}
|
|
483
426
|
if (platform === "darwin" && arch === "arm64") {
|
|
484
427
|
gpu = {
|
|
485
428
|
type: "apple",
|
|
@@ -1,58 +1,10 @@
|
|
|
1
1
|
import { o as __toESM, r as __exportAll } from "../../chunk-CNf5ZN-e.mjs";
|
|
2
|
-
import {
|
|
2
|
+
import { Ji as emitReadiness, Oa as EventCategory, ni as BaseAddon, sn as enumerateInferenceDevices, ti as errMsg, tr as platformProbeCapability, yr as scoreRuntimes } from "../../dist-B_GRPhnY.mjs";
|
|
3
|
+
import { n as nodeCoralFs, t as classifyCoralAccelerator } from "../../coral-accelerators-DcnZvctM.mjs";
|
|
3
4
|
import { promisify } from "node:util";
|
|
4
5
|
import * as os$1 from "node:os";
|
|
5
6
|
import * as fs from "node:fs";
|
|
6
7
|
import { execFile } from "node:child_process";
|
|
7
|
-
//#region src/builtins/platform-probe/coral-accelerators.ts
|
|
8
|
-
/**
|
|
9
|
-
* Coral USB Edge TPU USB identifiers.
|
|
10
|
-
*
|
|
11
|
-
* The device enumerates as `1a6e:089a` (Global Unichip) BEFORE the libedgetpu
|
|
12
|
-
* firmware loads, then re-enumerates as `18d1:9302` (Google) AFTER. Either id
|
|
13
|
-
* means a Coral is physically attached, so both count as a positive signal.
|
|
14
|
-
*/
|
|
15
|
-
var CORAL_USB_IDS = [{
|
|
16
|
-
vendor: "1a6e",
|
|
17
|
-
product: "089a"
|
|
18
|
-
}, {
|
|
19
|
-
vendor: "18d1",
|
|
20
|
-
product: "9302"
|
|
21
|
-
}];
|
|
22
|
-
/**
|
|
23
|
-
* Default install path of the libedgetpu delegate on the hub, provisioned
|
|
24
|
-
* out-of-band by `/data/deps/edgetpu-install.sh` (it is a system shared
|
|
25
|
-
* library, not a pip package). Overridable via `CAMSTACK_EDGETPU_LIB` — kept in
|
|
26
|
-
* sync with the Python pool's own default in `inference_pool.py`.
|
|
27
|
-
*/
|
|
28
|
-
var DEFAULT_EDGETPU_LIB = "/data/deps/edgetpu/lib/libedgetpu.so.1";
|
|
29
|
-
/**
|
|
30
|
-
* Detect a Coral USB Edge TPU. Present when EITHER a matching USB device is
|
|
31
|
-
* enumerated OR the libedgetpu delegate is installed (the delegate is the
|
|
32
|
-
* hub-provisioned runtime prerequisite; on a container whose `/sys` USB view is
|
|
33
|
-
* limited, its presence is a reliable operator-intent signal that the Coral is
|
|
34
|
-
* wired through). Returns `null` when neither signal is found.
|
|
35
|
-
*/
|
|
36
|
-
function classifyCoralAccelerator(fsx) {
|
|
37
|
-
let count = 0;
|
|
38
|
-
for (const device of fsx.listUsbDevices()) {
|
|
39
|
-
const vendor = fsx.readUsbAttr(device, "idVendor").toLowerCase();
|
|
40
|
-
const product = fsx.readUsbAttr(device, "idProduct").toLowerCase();
|
|
41
|
-
if (CORAL_USB_IDS.some((id) => id.vendor === vendor && id.product === product)) count++;
|
|
42
|
-
}
|
|
43
|
-
if (count > 0) return {
|
|
44
|
-
type: "coral-edgetpu",
|
|
45
|
-
bus: "usb",
|
|
46
|
-
count
|
|
47
|
-
};
|
|
48
|
-
const libPath = process.env["CAMSTACK_EDGETPU_LIB"] ?? DEFAULT_EDGETPU_LIB;
|
|
49
|
-
if (fsx.exists(libPath)) return {
|
|
50
|
-
type: "coral-edgetpu",
|
|
51
|
-
bus: "usb"
|
|
52
|
-
};
|
|
53
|
-
return null;
|
|
54
|
-
}
|
|
55
|
-
//#endregion
|
|
56
8
|
//#region src/builtins/platform-probe/amd-npu.ts
|
|
57
9
|
var amd_npu_exports = /* @__PURE__ */ __exportAll({
|
|
58
10
|
classifyAmdNpu: () => classifyAmdNpu,
|
|
@@ -456,24 +408,15 @@ var PlatformScorer = class {
|
|
|
456
408
|
} });
|
|
457
409
|
let gpu = null;
|
|
458
410
|
let npu = null;
|
|
459
|
-
const coral = classifyCoralAccelerator(
|
|
460
|
-
|
|
461
|
-
|
|
462
|
-
|
|
463
|
-
|
|
464
|
-
|
|
465
|
-
|
|
466
|
-
}
|
|
467
|
-
|
|
468
|
-
try {
|
|
469
|
-
return fs.readFileSync(`/sys/bus/usb/devices/${device}/${attr}`, "utf8").trim();
|
|
470
|
-
} catch {
|
|
471
|
-
return "";
|
|
472
|
-
}
|
|
473
|
-
},
|
|
474
|
-
exists: (p) => fs.existsSync(p)
|
|
475
|
-
});
|
|
476
|
-
if (coral) this.logger.info("Coral USB Edge TPU detected", { meta: { bus: coral.bus } });
|
|
411
|
+
const coral = classifyCoralAccelerator(nodeCoralFs);
|
|
412
|
+
if (coral) {
|
|
413
|
+
if ((coral.units ?? []).length > 0) this.logger.info("Coral Edge TPU detected", { meta: { units: coral.units } });
|
|
414
|
+
for (const unavailable of coral.unavailable ?? []) this.logger.warn("Coral Edge TPU present but unusable", { meta: {
|
|
415
|
+
bus: unavailable.bus,
|
|
416
|
+
count: unavailable.count,
|
|
417
|
+
reason: unavailable.reason
|
|
418
|
+
} });
|
|
419
|
+
}
|
|
477
420
|
if (platform === "darwin" && arch === "arm64") {
|
|
478
421
|
gpu = {
|
|
479
422
|
type: "apple",
|
|
@@ -3,7 +3,7 @@ Object.defineProperties(exports, {
|
|
|
3
3
|
[Symbol.toStringTag]: { value: "Module" }
|
|
4
4
|
});
|
|
5
5
|
require("../../chunk-Cek0wNdY.js");
|
|
6
|
-
const require_dist = require("../../dist-
|
|
6
|
+
const require_dist = require("../../dist-BZQjLPiz.js");
|
|
7
7
|
let zod = require("zod");
|
|
8
8
|
let node_crypto = require("node:crypto");
|
|
9
9
|
//#region src/builtins/record-entries/entries-service.ts
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { fi as InvalidRecordError, ga as recordSecretRef, ir as recordEntriesCapability, ji as UnknownRecordKindError, ni as BaseAddon, oa as mapSecretLeaves } from "../../dist-B_GRPhnY.mjs";
|
|
2
2
|
import { z } from "zod";
|
|
3
3
|
import { randomUUID } from "node:crypto";
|
|
4
4
|
//#region src/builtins/record-entries/entries-service.ts
|
|
@@ -3,7 +3,7 @@ Object.defineProperties(exports, {
|
|
|
3
3
|
[Symbol.toStringTag]: { value: "Module" }
|
|
4
4
|
});
|
|
5
5
|
require("../../chunk-Cek0wNdY.js");
|
|
6
|
-
const require_dist = require("../../dist-
|
|
6
|
+
const require_dist = require("../../dist-BZQjLPiz.js");
|
|
7
7
|
//#region src/builtins/remote-access-orchestrator/enabled-providers-reconcile.ts
|
|
8
8
|
/**
|
|
9
9
|
* Reconcile the durable `enabledProviders` set against authoritative
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { Oa as EventCategory, ni as BaseAddon } from "../../dist-B_GRPhnY.mjs";
|
|
2
2
|
//#region src/builtins/remote-access-orchestrator/enabled-providers-reconcile.ts
|
|
3
3
|
/**
|
|
4
4
|
* Reconcile the durable `enabledProviders` set against authoritative
|
|
@@ -3,7 +3,7 @@ Object.defineProperties(exports, {
|
|
|
3
3
|
[Symbol.toStringTag]: { value: "Module" }
|
|
4
4
|
});
|
|
5
5
|
const require_chunk = require("../../chunk-Cek0wNdY.js");
|
|
6
|
-
const require_dist = require("../../dist-
|
|
6
|
+
const require_dist = require("../../dist-BZQjLPiz.js");
|
|
7
7
|
const require_snapshot_courtesy = require("../../snapshot-courtesy-D_C5-nC0.js");
|
|
8
8
|
let zod = require("zod");
|
|
9
9
|
let node_crypto = require("node:crypto");
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { Cr as snapshotCapability, Oa as EventCategory, Ot as bareAddonId, Qr as DeviceFeature, Qt as deriveBatteryPresence, Wn as memoizePinnedFfmpeg, ei as DeviceType, jr as streamQualityLabel, kt as batteryCapability, ni as BaseAddon, s as BatteryStatusSchema, sa as nodePin, ti as errMsg } from "../../dist-B_GRPhnY.mjs";
|
|
2
2
|
import { i as renderCourtesyOverlayJpeg, n as courtesyCacheKey, r as renderCourtesyJpeg } from "../../snapshot-courtesy-CyFs1M3I.mjs";
|
|
3
3
|
import { z } from "zod";
|
|
4
4
|
import { randomUUID } from "node:crypto";
|
|
@@ -3,7 +3,7 @@ Object.defineProperties(exports, {
|
|
|
3
3
|
[Symbol.toStringTag]: { value: "Module" }
|
|
4
4
|
});
|
|
5
5
|
const require_chunk = require("../../chunk-Cek0wNdY.js");
|
|
6
|
-
const require_dist = require("../../dist-
|
|
6
|
+
const require_dist = require("../../dist-BZQjLPiz.js");
|
|
7
7
|
let node_crypto = require("node:crypto");
|
|
8
8
|
let node_fs_promises = require("node:fs/promises");
|
|
9
9
|
let node_path = require("node:path");
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { hn as filesystemBrowseCapability, kr as storageProviderCapability, ni as BaseAddon } from "../../dist-B_GRPhnY.mjs";
|
|
2
2
|
import { randomUUID } from "node:crypto";
|
|
3
3
|
import { mkdir, readdir, realpath, statfs } from "node:fs/promises";
|
|
4
4
|
import * as path$1 from "node:path";
|
|
@@ -4,7 +4,7 @@ Object.defineProperties(exports, {
|
|
|
4
4
|
});
|
|
5
5
|
require("../../chunk-Cek0wNdY.js");
|
|
6
6
|
const require_builtins_sqlite_storage_filesystem_storage_addon = require("./filesystem-storage.addon.js");
|
|
7
|
-
const require_wal_maintenance = require("../../wal-maintenance-
|
|
7
|
+
const require_wal_maintenance = require("../../wal-maintenance-DfSIOj24.js");
|
|
8
8
|
const require_builtins_sqlite_storage_sqlite_settings_addon = require("./sqlite-settings.addon.js");
|
|
9
9
|
//#region src/builtins/sqlite-storage/config-store.ts
|
|
10
10
|
var ConfigStore = class {
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { FilesystemStorageAddon, t as FilesystemStorageProvider } from "./filesystem-storage.addon.mjs";
|
|
2
|
-
import { A as SQLITE_MMAP_CEILING_BYTES, B as SQLITE_SLOW_CALL_MS, F as sqlitePageCacheKibFor, H as sqliteEngineStorm, I as SQLITE_ENGINE_STORM_WALL_SHARE, L as SQLITE_PROFILE_REPORT_FLOOR_MS, M as SQLITE_PAGE_CACHE_CEILING_KIB, N as SQLITE_PAGE_CACHE_FLOOR_KIB, P as sqliteMmapSizeFor, R as SQLITE_PROFILE_REPORT_INTERVAL_MS, V as SqliteOpProfiler, a as WalMaintenance, i as WAL_MAINTENANCE_INTERVAL_MS, j as SQLITE_MMAP_FLOOR_BYTES, k as SQLITE_JOURNAL_SIZE_LIMIT_BYTES, l as SqliteSettingsBackend, n as WAL_HIGH_WATER_BYTES, r as WAL_IDLE_QUIET_MS, t as WAL_CHECKPOINT_BUSY_TIMEOUT_MS, z as SQLITE_PROFILE_TOP_N } from "../../wal-maintenance-
|
|
2
|
+
import { A as SQLITE_MMAP_CEILING_BYTES, B as SQLITE_SLOW_CALL_MS, F as sqlitePageCacheKibFor, H as sqliteEngineStorm, I as SQLITE_ENGINE_STORM_WALL_SHARE, L as SQLITE_PROFILE_REPORT_FLOOR_MS, M as SQLITE_PAGE_CACHE_CEILING_KIB, N as SQLITE_PAGE_CACHE_FLOOR_KIB, P as sqliteMmapSizeFor, R as SQLITE_PROFILE_REPORT_INTERVAL_MS, V as SqliteOpProfiler, a as WalMaintenance, i as WAL_MAINTENANCE_INTERVAL_MS, j as SQLITE_MMAP_FLOOR_BYTES, k as SQLITE_JOURNAL_SIZE_LIMIT_BYTES, l as SqliteSettingsBackend, n as WAL_HIGH_WATER_BYTES, r as WAL_IDLE_QUIET_MS, t as WAL_CHECKPOINT_BUSY_TIMEOUT_MS, z as SQLITE_PROFILE_TOP_N } from "../../wal-maintenance-Duejh7Lx.mjs";
|
|
3
3
|
import { SqliteSettingsAddon } from "./sqlite-settings.addon.mjs";
|
|
4
4
|
//#region src/builtins/sqlite-storage/config-store.ts
|
|
5
5
|
var ConfigStore = class {
|
|
@@ -3,9 +3,9 @@ Object.defineProperties(exports, {
|
|
|
3
3
|
[Symbol.toStringTag]: { value: "Module" }
|
|
4
4
|
});
|
|
5
5
|
const require_chunk = require("../../chunk-Cek0wNdY.js");
|
|
6
|
-
const require_dist = require("../../dist-
|
|
6
|
+
const require_dist = require("../../dist-BZQjLPiz.js");
|
|
7
7
|
const require_retired_settings_keys = require("../../retired-settings-keys-D_VwZiDt.js");
|
|
8
|
-
const require_wal_maintenance = require("../../wal-maintenance-
|
|
8
|
+
const require_wal_maintenance = require("../../wal-maintenance-DfSIOj24.js");
|
|
9
9
|
const require_sqlite_snapshot_protocol = require("../../sqlite-snapshot-protocol-B9OndqZv.js");
|
|
10
10
|
const require_wal_checkpoint_policy = require("../../wal-checkpoint-policy-d2z2qPqx.js");
|
|
11
11
|
let node_fs_promises = require("node:fs/promises");
|
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { C as DATABASE_SNAPSHOT_TIMEOUT_MS, Jt as databaseSnapshotCapability, Ot as bareAddonId, Rr as vectorStoreCapability, S as DATABASE_SNAPSHOT_SUFFIX, Tr as storageAdminCapability, ar as recordsCapability, ci as DeclarationRefusedError, ji as UnknownRecordKindError, la as normalizeSecretOwner, ma as parseSettingsBrokersAdoptsFrom, ni as BaseAddon, ot as STORAGE_ADMIN_MOVED_COLLECTIONS, pa as parseSettingsArrayAdoptsFrom, pi as NoCallerError, qt as dataStoreProviderCapability, st as STORAGE_ADMIN_SCOPED_BASES, ti as errMsg, vi as RECORD_SWEEP_INTERVAL_MS, w as DATA_STORE_DATABASES, wi as RecordKindDeclarationSchema, x as DATABASE_SNAPSHOT_PARTIAL_SUFFIX, xi as RUNTIME_DEFAULTS } from "../../dist-B_GRPhnY.mjs";
|
|
2
2
|
import { i as retiredKeyStoreOf, n as purgeRetiredSettingsKeys } from "../../retired-settings-keys-Bhwe4ymb.mjs";
|
|
3
|
-
import { C as RecordsEngine, D as callVector, E as callRecords, O as controlTargetOf, S as trustResult, T as callData, _ as collectTransferables, a as WalMaintenance, c as vectorProviderOfOwnedFile, d as CrossDatabaseTransactError, f as DatabaseBusyError, l as SqliteSettingsBackend, m as rehydrateError, o as createVectorIndex, p as DuplicatePlacementError, s as vectorProviderOf, u as CollectionPlacementError, v as isFileHostMessage, w as callControl } from "../../wal-maintenance-
|
|
3
|
+
import { C as RecordsEngine, D as callVector, E as callRecords, O as controlTargetOf, S as trustResult, T as callData, _ as collectTransferables, a as WalMaintenance, c as vectorProviderOfOwnedFile, d as CrossDatabaseTransactError, f as DatabaseBusyError, l as SqliteSettingsBackend, m as rehydrateError, o as createVectorIndex, p as DuplicatePlacementError, s as vectorProviderOf, u as CollectionPlacementError, v as isFileHostMessage, w as callControl } from "../../wal-maintenance-Duejh7Lx.mjs";
|
|
4
4
|
import { r as isSnapshotWorkerMessage } from "../../sqlite-snapshot-protocol-2QaTouWV.mjs";
|
|
5
5
|
import { a as isWorkerMessage, t as WAL_CHECKPOINT_LARGE_PASS_FRAMES } from "../../wal-checkpoint-policy-BahrTtyD.mjs";
|
|
6
6
|
import { createRequire } from "node:module";
|
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Storage-location occupancy over time, through device-history (D850).
|
|
3
|
+
*
|
|
4
|
+
* The figures are the ones `listLocations` already serves, from their own
|
|
5
|
+
* authorities — nothing is measured twice:
|
|
6
|
+
* - the VOLUME (`location-used-percent`, `location-free-bytes`) from the same
|
|
7
|
+
* statfs probe the UI's capacity reads (`readLocalVolumeCapacity`), which
|
|
8
|
+
* answers only for a location THIS node can measure;
|
|
9
|
+
* - what CamStack HOLDS there (`location-owned-bytes`) from the
|
|
10
|
+
* `storage-occupancy` slice (D388).
|
|
11
|
+
*
|
|
12
|
+
* A figure that is unknown is NO point, never 0 (D393, D315): a failed statfs,
|
|
13
|
+
* a remote provider, a location nobody reports owned bytes for.
|
|
14
|
+
*
|
|
15
|
+
* Subject: the node the location lives on (`nodeId`), else the node that
|
|
16
|
+
* measured it. Scope: the location id, so a location keeps one series for life.
|
|
17
|
+
*/
|
|
18
|
+
import type { DeviceHistoryIngestResult, IScopedLogger } from "@camstack/types";
|
|
19
|
+
export declare const LOCATION_HISTORY_NAMES: {
|
|
20
|
+
readonly usedPercent: "location-used-percent";
|
|
21
|
+
readonly freeBytes: "location-free-bytes";
|
|
22
|
+
readonly ownedBytes: "location-owned-bytes";
|
|
23
|
+
};
|
|
24
|
+
/** One location's sweep reading. */
|
|
25
|
+
export interface LocationReading {
|
|
26
|
+
readonly locationId: string;
|
|
27
|
+
readonly nodeId: string;
|
|
28
|
+
/** `null` when this node cannot take a measurement that is about the location. */
|
|
29
|
+
readonly capacity: {
|
|
30
|
+
readonly totalBytes: number;
|
|
31
|
+
readonly availableBytes: number;
|
|
32
|
+
} | null;
|
|
33
|
+
/** `undefined` when no provider reports what CamStack holds there. */
|
|
34
|
+
readonly ownedBytes: number | undefined;
|
|
35
|
+
}
|
|
36
|
+
export interface LocationHistoryPoint {
|
|
37
|
+
readonly key: string;
|
|
38
|
+
readonly subject: {
|
|
39
|
+
readonly kind: "node";
|
|
40
|
+
readonly nodeId: string;
|
|
41
|
+
};
|
|
42
|
+
readonly scope: string;
|
|
43
|
+
readonly ts: number;
|
|
44
|
+
readonly value: number;
|
|
45
|
+
}
|
|
46
|
+
export interface LocationHistoryClient {
|
|
47
|
+
declareSeries(input: {
|
|
48
|
+
name: string;
|
|
49
|
+
subjectKind: "node";
|
|
50
|
+
kind: "gauge";
|
|
51
|
+
displayName: string;
|
|
52
|
+
ingest: "points";
|
|
53
|
+
unit: string;
|
|
54
|
+
}): Promise<{
|
|
55
|
+
key: string;
|
|
56
|
+
}>;
|
|
57
|
+
record(input: {
|
|
58
|
+
points: readonly LocationHistoryPoint[];
|
|
59
|
+
}): Promise<DeviceHistoryIngestResult>;
|
|
60
|
+
}
|
|
61
|
+
export interface LocationHistoryRecorderDeps {
|
|
62
|
+
readonly deviceHistory: LocationHistoryClient;
|
|
63
|
+
readonly logger: IScopedLogger;
|
|
64
|
+
}
|
|
65
|
+
/** One reading per location per this many ms at most (the sweep runs every minute). */
|
|
66
|
+
export declare const LOCATION_HISTORY_MIN_INTERVAL_MS = 6e4;
|
|
67
|
+
export declare class LocationHistoryRecorder {
|
|
68
|
+
private readonly deps;
|
|
69
|
+
private readonly keys;
|
|
70
|
+
private readonly lastAt;
|
|
71
|
+
constructor(deps: LocationHistoryRecorderDeps);
|
|
72
|
+
private ensureDeclared;
|
|
73
|
+
/** The points of one sweep; pure apart from the per-location rate memory. */
|
|
74
|
+
pointsOf(readings: readonly LocationReading[], at: number): readonly LocationHistoryPoint[];
|
|
75
|
+
record(readings: readonly LocationReading[], at: number): Promise<void>;
|
|
76
|
+
}
|
|
@@ -18,6 +18,9 @@ export declare class StorageOrchestratorAddon extends BaseAddon<StorageOrchestra
|
|
|
18
18
|
private occupancySlice;
|
|
19
19
|
private get occupancy();
|
|
20
20
|
private pressureTimer;
|
|
21
|
+
/** Occupancy over time (device-history). Created with the timer that feeds it. */
|
|
22
|
+
private locationHistory;
|
|
23
|
+
private locationHistoryInFlight;
|
|
21
24
|
private pressureSweepInFlight;
|
|
22
25
|
private migration;
|
|
23
26
|
/** Guards every single-location repoint and arbitrates movers per physical root. */
|
|
@@ -108,6 +111,12 @@ export declare class StorageOrchestratorAddon extends BaseAddon<StorageOrchestra
|
|
|
108
111
|
/** Single-flighted pressure sweep — never overlaps a slow eviction round. */
|
|
109
112
|
private runPressureSweep;
|
|
110
113
|
/**
|
|
114
|
+
* One occupancy reading per location this node can read, into device-history.
|
|
115
|
+
* The volume figures come from the same probe `listLocations` serves, the
|
|
116
|
+
* held bytes from the occupancy slice; an unknown figure is no point (D393).
|
|
117
|
+
*/
|
|
118
|
+
private recordLocationHistory;
|
|
119
|
+
/**
|
|
111
120
|
* Sample free space for every managed location and emit NC band edges.
|
|
112
121
|
* A failed capacity read stays `null` and changes no band — never folded to 0 (D393).
|
|
113
122
|
*/
|
|
@@ -3,7 +3,7 @@ Object.defineProperties(exports, {
|
|
|
3
3
|
[Symbol.toStringTag]: { value: "Module" }
|
|
4
4
|
});
|
|
5
5
|
const require_chunk = require("../../chunk-Cek0wNdY.js");
|
|
6
|
-
const require_dist = require("../../dist-
|
|
6
|
+
const require_dist = require("../../dist-BZQjLPiz.js");
|
|
7
7
|
const require_read_all_rows$1 = require("../../read-all-rows-CVoO1ONM.js");
|
|
8
8
|
let zod = require("zod");
|
|
9
9
|
let node_crypto = require("node:crypto");
|
|
@@ -3957,6 +3957,107 @@ var StorageLocationBandMonitor = class {
|
|
|
3957
3957
|
}
|
|
3958
3958
|
};
|
|
3959
3959
|
//#endregion
|
|
3960
|
+
//#region src/builtins/storage-orchestrator/location-history-recorder.ts
|
|
3961
|
+
var LOCATION_HISTORY_NAMES = {
|
|
3962
|
+
usedPercent: "location-used-percent",
|
|
3963
|
+
freeBytes: "location-free-bytes",
|
|
3964
|
+
ownedBytes: "location-owned-bytes"
|
|
3965
|
+
};
|
|
3966
|
+
var DECLARATIONS = [
|
|
3967
|
+
{
|
|
3968
|
+
name: LOCATION_HISTORY_NAMES.usedPercent,
|
|
3969
|
+
displayName: "Location volume used %",
|
|
3970
|
+
unit: "%"
|
|
3971
|
+
},
|
|
3972
|
+
{
|
|
3973
|
+
name: LOCATION_HISTORY_NAMES.freeBytes,
|
|
3974
|
+
displayName: "Location volume free",
|
|
3975
|
+
unit: "bytes"
|
|
3976
|
+
},
|
|
3977
|
+
{
|
|
3978
|
+
name: LOCATION_HISTORY_NAMES.ownedBytes,
|
|
3979
|
+
displayName: "Location held by CamStack",
|
|
3980
|
+
unit: "bytes"
|
|
3981
|
+
}
|
|
3982
|
+
];
|
|
3983
|
+
var LocationHistoryRecorder = class {
|
|
3984
|
+
deps;
|
|
3985
|
+
keys = /* @__PURE__ */ new Map();
|
|
3986
|
+
lastAt = /* @__PURE__ */ new Map();
|
|
3987
|
+
constructor(deps) {
|
|
3988
|
+
this.deps = deps;
|
|
3989
|
+
}
|
|
3990
|
+
async ensureDeclared() {
|
|
3991
|
+
if (this.keys.size === DECLARATIONS.length) return true;
|
|
3992
|
+
try {
|
|
3993
|
+
for (const d of DECLARATIONS) {
|
|
3994
|
+
const { key } = await this.deps.deviceHistory.declareSeries({
|
|
3995
|
+
name: d.name,
|
|
3996
|
+
subjectKind: "node",
|
|
3997
|
+
kind: "gauge",
|
|
3998
|
+
displayName: d.displayName,
|
|
3999
|
+
ingest: "points",
|
|
4000
|
+
unit: d.unit
|
|
4001
|
+
});
|
|
4002
|
+
this.keys.set(d.name, key);
|
|
4003
|
+
}
|
|
4004
|
+
return true;
|
|
4005
|
+
} catch (err) {
|
|
4006
|
+
this.keys.clear();
|
|
4007
|
+
this.deps.logger.warn("storage: location history declare failed — retried next sweep", { meta: { error: err instanceof Error ? err.message : String(err) } });
|
|
4008
|
+
return false;
|
|
4009
|
+
}
|
|
4010
|
+
}
|
|
4011
|
+
/** The points of one sweep; pure apart from the per-location rate memory. */
|
|
4012
|
+
pointsOf(readings, at) {
|
|
4013
|
+
const points = [];
|
|
4014
|
+
for (const r of readings) {
|
|
4015
|
+
const last = this.lastAt.get(r.locationId);
|
|
4016
|
+
if (last !== void 0 && at >= last && at - last < 6e4) continue;
|
|
4017
|
+
const add = (name, value) => {
|
|
4018
|
+
const key = this.keys.get(name);
|
|
4019
|
+
if (key === void 0 || !Number.isFinite(value)) return;
|
|
4020
|
+
points.push({
|
|
4021
|
+
key,
|
|
4022
|
+
subject: {
|
|
4023
|
+
kind: "node",
|
|
4024
|
+
nodeId: r.nodeId
|
|
4025
|
+
},
|
|
4026
|
+
scope: r.locationId,
|
|
4027
|
+
ts: at,
|
|
4028
|
+
value
|
|
4029
|
+
});
|
|
4030
|
+
};
|
|
4031
|
+
const before = points.length;
|
|
4032
|
+
if (r.capacity !== null && r.capacity.totalBytes > 0) {
|
|
4033
|
+
const used = r.capacity.totalBytes - r.capacity.availableBytes;
|
|
4034
|
+
add(LOCATION_HISTORY_NAMES.usedPercent, Math.round(used / r.capacity.totalBytes * 1e3) / 10);
|
|
4035
|
+
add(LOCATION_HISTORY_NAMES.freeBytes, r.capacity.availableBytes);
|
|
4036
|
+
}
|
|
4037
|
+
if (r.ownedBytes !== void 0) add(LOCATION_HISTORY_NAMES.ownedBytes, r.ownedBytes);
|
|
4038
|
+
if (points.length > before) this.lastAt.set(r.locationId, at);
|
|
4039
|
+
}
|
|
4040
|
+
return points;
|
|
4041
|
+
}
|
|
4042
|
+
async record(readings, at) {
|
|
4043
|
+
if (readings.length === 0 || !await this.ensureDeclared()) return;
|
|
4044
|
+
const points = this.pointsOf(readings, at);
|
|
4045
|
+
if (points.length === 0) return;
|
|
4046
|
+
try {
|
|
4047
|
+
const result = await this.deps.deviceHistory.record({ points });
|
|
4048
|
+
if (result.refused.length > 0) {
|
|
4049
|
+
if (result.refused.some((r) => r.reason === "undeclared")) this.keys.clear();
|
|
4050
|
+
this.deps.logger.warn("storage: location history points refused", { meta: {
|
|
4051
|
+
accepted: result.accepted,
|
|
4052
|
+
refused: result.refused
|
|
4053
|
+
} });
|
|
4054
|
+
}
|
|
4055
|
+
} catch (err) {
|
|
4056
|
+
this.deps.logger.warn("storage: location history not stored", { meta: { error: err instanceof Error ? err.message : String(err) } });
|
|
4057
|
+
}
|
|
4058
|
+
}
|
|
4059
|
+
};
|
|
4060
|
+
//#endregion
|
|
3960
4061
|
//#region src/builtins/storage-orchestrator/storage-orchestrator.addon.ts
|
|
3961
4062
|
/**
|
|
3962
4063
|
* `storage-orchestrator` builtin — singleton owner of the consumer-
|
|
@@ -4024,6 +4125,9 @@ var StorageOrchestratorAddon = class extends require_dist.BaseAddon {
|
|
|
4024
4125
|
return this.occupancySlice;
|
|
4025
4126
|
}
|
|
4026
4127
|
pressureTimer = null;
|
|
4128
|
+
/** Occupancy over time (device-history). Created with the timer that feeds it. */
|
|
4129
|
+
locationHistory = null;
|
|
4130
|
+
locationHistoryInFlight = false;
|
|
4027
4131
|
pressureSweepInFlight = false;
|
|
4028
4132
|
migration = null;
|
|
4029
4133
|
/** Guards every single-location repoint and arbitrates movers per physical root. */
|
|
@@ -4440,8 +4544,16 @@ var StorageOrchestratorAddon = class extends require_dist.BaseAddon {
|
|
|
4440
4544
|
}
|
|
4441
4545
|
}
|
|
4442
4546
|
});
|
|
4547
|
+
this.locationHistory = new LocationHistoryRecorder({
|
|
4548
|
+
deviceHistory: {
|
|
4549
|
+
declareSeries: (input) => this.ctx.api.deviceHistory.declareSeries.mutate(input),
|
|
4550
|
+
record: (input) => this.ctx.api.deviceHistory.record.mutate({ points: [...input.points] })
|
|
4551
|
+
},
|
|
4552
|
+
logger: this.ctx.logger
|
|
4553
|
+
});
|
|
4443
4554
|
this.pressureTimer = setInterval(() => {
|
|
4444
4555
|
this.runPressureSweep();
|
|
4556
|
+
this.recordLocationHistory();
|
|
4445
4557
|
}, PRESSURE_SWEEP_INTERVAL_MS);
|
|
4446
4558
|
this.ctx.logger.info("Storage orchestrator initialized");
|
|
4447
4559
|
return [
|
|
@@ -4588,6 +4700,37 @@ var StorageOrchestratorAddon = class extends require_dist.BaseAddon {
|
|
|
4588
4700
|
}
|
|
4589
4701
|
}
|
|
4590
4702
|
/**
|
|
4703
|
+
* One occupancy reading per location this node can read, into device-history.
|
|
4704
|
+
* The volume figures come from the same probe `listLocations` serves, the
|
|
4705
|
+
* held bytes from the occupancy slice; an unknown figure is no point (D393).
|
|
4706
|
+
*/
|
|
4707
|
+
async recordLocationHistory() {
|
|
4708
|
+
const svc = this.service;
|
|
4709
|
+
const recorder = this.locationHistory;
|
|
4710
|
+
if (!svc || !recorder || this.locationHistoryInFlight) return;
|
|
4711
|
+
this.locationHistoryInFlight = true;
|
|
4712
|
+
try {
|
|
4713
|
+
this.occupancy.serveAndRevalidate();
|
|
4714
|
+
const localNode = svc.getLocalNodeId();
|
|
4715
|
+
const readings = [];
|
|
4716
|
+
for (const loc of svc.listLocations()) {
|
|
4717
|
+
if (!require_dist.mayReadLocation(loc) || (loc.nodeId ?? HUB_NODE_ID) !== localNode) continue;
|
|
4718
|
+
const capacity = await this.localCapacityOf(loc).catch(() => null);
|
|
4719
|
+
readings.push({
|
|
4720
|
+
locationId: loc.id,
|
|
4721
|
+
nodeId: localNode,
|
|
4722
|
+
capacity,
|
|
4723
|
+
ownedBytes: this.occupancy.ownedFor(loc.id)?.bytes
|
|
4724
|
+
});
|
|
4725
|
+
}
|
|
4726
|
+
await recorder.record(readings, Date.now());
|
|
4727
|
+
} catch (err) {
|
|
4728
|
+
this.ctxIfReady?.logger.warn("storage: location history pass failed", { meta: { error: err instanceof Error ? err.message : String(err) } });
|
|
4729
|
+
} finally {
|
|
4730
|
+
this.locationHistoryInFlight = false;
|
|
4731
|
+
}
|
|
4732
|
+
}
|
|
4733
|
+
/**
|
|
4591
4734
|
* Sample free space for every managed location and emit NC band edges.
|
|
4592
4735
|
* A failed capacity read stays `null` and changes no band — never folded to 0 (D393).
|
|
4593
4736
|
*/
|