@camstack/system 1.2.57 → 1.2.59

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 (69) hide show
  1. package/dist/addon-runner.js +1 -1
  2. package/dist/addon-runner.mjs +1 -1
  3. package/dist/addon-utils.js +1 -1
  4. package/dist/addon-utils.mjs +1 -1
  5. package/dist/builtins/addon-pages-aggregator/addon-pages-aggregator.addon.js +2 -2
  6. package/dist/builtins/addon-pages-aggregator/addon-pages-aggregator.addon.mjs +2 -2
  7. package/dist/builtins/addon-widgets-aggregator/addon-widgets-aggregator.addon.js +2 -2
  8. package/dist/builtins/addon-widgets-aggregator/addon-widgets-aggregator.addon.mjs +2 -2
  9. package/dist/builtins/alerts/alerts.addon.js +1 -1
  10. package/dist/builtins/alerts/alerts.addon.mjs +1 -1
  11. package/dist/builtins/backup-orchestrator/backup-orchestrator.addon.js +2 -2
  12. package/dist/builtins/backup-orchestrator/backup-orchestrator.addon.mjs +2 -2
  13. package/dist/builtins/console-logging/index.js +1 -1
  14. package/dist/builtins/console-logging/index.mjs +1 -1
  15. package/dist/builtins/core-blocks/core-blocks.addon.js +2 -2
  16. package/dist/builtins/core-blocks/core-blocks.addon.mjs +2 -2
  17. package/dist/builtins/device-manager/device-manager.addon.js +2 -2
  18. package/dist/builtins/device-manager/device-manager.addon.mjs +2 -2
  19. package/dist/builtins/doorbell/binding-mirror.d.ts +65 -0
  20. package/dist/builtins/doorbell/virtual-doorbell.addon.d.ts +56 -11
  21. package/dist/builtins/doorbell/virtual-doorbell.addon.js +248 -26
  22. package/dist/builtins/doorbell/virtual-doorbell.addon.mjs +248 -26
  23. package/dist/builtins/hub-forwarder/index.js +1 -1
  24. package/dist/builtins/hub-forwarder/index.mjs +1 -1
  25. package/dist/builtins/liveness-monitor/liveness-monitor.addon.js +1 -1
  26. package/dist/builtins/liveness-monitor/liveness-monitor.addon.mjs +1 -1
  27. package/dist/builtins/local-auth/local-auth.addon.js +1 -1
  28. package/dist/builtins/local-auth/local-auth.addon.mjs +1 -1
  29. package/dist/builtins/local-network/local-network.addon.js +1 -1
  30. package/dist/builtins/local-network/local-network.addon.mjs +1 -1
  31. package/dist/builtins/loki-logging/index.js +1 -1
  32. package/dist/builtins/loki-logging/index.mjs +1 -1
  33. package/dist/builtins/native-metrics/native-metrics.addon.js +1 -1
  34. package/dist/builtins/native-metrics/native-metrics.addon.mjs +1 -1
  35. package/dist/builtins/platform-probe/index.js +1 -1
  36. package/dist/builtins/platform-probe/index.mjs +1 -1
  37. package/dist/builtins/remote-access-orchestrator/remote-access-orchestrator.addon.js +1 -1
  38. package/dist/builtins/remote-access-orchestrator/remote-access-orchestrator.addon.mjs +1 -1
  39. package/dist/builtins/snapshot/index.js +2 -2
  40. package/dist/builtins/snapshot/index.mjs +2 -2
  41. package/dist/builtins/sqlite-storage/filesystem-storage.addon.js +2 -2
  42. package/dist/builtins/sqlite-storage/filesystem-storage.addon.mjs +2 -2
  43. package/dist/builtins/sqlite-storage/index.d.ts +3 -0
  44. package/dist/builtins/sqlite-storage/index.js +8 -0
  45. package/dist/builtins/sqlite-storage/index.mjs +2 -2
  46. package/dist/builtins/sqlite-storage/retired-settings-keys.d.ts +94 -0
  47. package/dist/builtins/sqlite-storage/sqlite-pragmas.d.ts +85 -0
  48. package/dist/builtins/sqlite-storage/sqlite-settings.addon.d.ts +1 -0
  49. package/dist/builtins/sqlite-storage/sqlite-settings.addon.js +445 -2
  50. package/dist/builtins/sqlite-storage/sqlite-settings.addon.mjs +438 -3
  51. package/dist/builtins/sqlite-storage/wal-maintenance.d.ts +113 -0
  52. package/dist/builtins/storage-orchestrator/storage-orchestrator.addon.js +1 -1
  53. package/dist/builtins/storage-orchestrator/storage-orchestrator.addon.mjs +1 -1
  54. package/dist/builtins/system-config/system-config.addon.js +1 -1
  55. package/dist/builtins/system-config/system-config.addon.mjs +1 -1
  56. package/dist/builtins/winston-logging/index.js +1 -1
  57. package/dist/builtins/winston-logging/index.mjs +1 -1
  58. package/dist/{dist-DhL_zGRT.mjs → dist-BqJJWCS8.mjs} +994 -34
  59. package/dist/{dist-BupxnZOi.js → dist-CV6XTApk.js} +1005 -33
  60. package/dist/index.js +190 -42
  61. package/dist/index.mjs +191 -43
  62. package/dist/kernel/addon-installer.d.ts +55 -7
  63. package/dist/kernel/addon-manifest.d.ts +36 -16
  64. package/dist/kernel/transport/frame-codec.d.ts +43 -2
  65. package/dist/{manifest-python-deps-Ck4-9K9m.mjs → manifest-python-deps-CX5tGRqf.mjs} +95 -10
  66. package/dist/{manifest-python-deps-BqE5j0-O.js → manifest-python-deps-d4acYXVV.js} +95 -10
  67. package/package.json +1 -1
  68. package/dist/{model-download-service-hf0ookyy.js → model-download-service-Cpc6SWzV.js} +1 -1
  69. package/dist/{model-download-service-Cp9f4dk6.mjs → model-download-service-D8B-4ktF.mjs} +1 -1
@@ -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-BupxnZOi.js");
6
+ const require_dist = require("../../dist-CV6XTApk.js");
7
7
  const require_formatter = require("../../formatter-DqAKDlvN.js");
8
8
  //#region src/builtins/hub-forwarder/hub-forwarder-destination.ts
9
9
  var DEFAULT_OUTBOUND_BUFFER_SIZE = 500;
@@ -1,4 +1,4 @@
1
- import { U as logDestinationCapability, dt as BaseAddon } from "../../dist-DhL_zGRT.mjs";
1
+ import { G as logDestinationCapability, pt as BaseAddon } from "../../dist-BqJJWCS8.mjs";
2
2
  import { t as formatLogLine } from "../../formatter-B7qW8bPJ.mjs";
3
3
  //#region src/builtins/hub-forwarder/hub-forwarder-destination.ts
4
4
  var DEFAULT_OUTBOUND_BUFFER_SIZE = 500;
@@ -1,6 +1,6 @@
1
1
  Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
2
2
  require("../../chunk-Cek0wNdY.js");
3
- const require_dist = require("../../dist-BupxnZOi.js");
3
+ const require_dist = require("../../dist-CV6XTApk.js");
4
4
  //#region src/builtins/liveness-monitor/liveness-checks.ts
5
5
  var NO_DEVICES = "liveness:no-devices";
6
6
  var ALL_OFFLINE = "liveness:all-devices-offline";
@@ -1,4 +1,4 @@
1
- import { Lt as EventCategory, dt as BaseAddon, ut as errMsg, wt as createEvent } from "../../dist-DhL_zGRT.mjs";
1
+ import { Et as createEvent, ft as errMsg, pt as BaseAddon, zt as EventCategory } from "../../dist-BqJJWCS8.mjs";
2
2
  //#region src/builtins/liveness-monitor/liveness-checks.ts
3
3
  var NO_DEVICES = "liveness:no-devices";
4
4
  var ALL_OFFLINE = "liveness:all-devices-offline";
@@ -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-BupxnZOi.js");
6
+ const require_dist = require("../../dist-CV6XTApk.js");
7
7
  let node_crypto = require("node:crypto");
8
8
  node_crypto = require_chunk.__toESM(node_crypto);
9
9
  let crypto$1 = require("crypto");
@@ -1,5 +1,5 @@
1
1
  import { i as __require, o as __toESM, t as __commonJSMin } from "../../chunk-CNf5ZN-e.mjs";
2
- import { d as ScopedTokenSchema, dt as BaseAddon, ot as userManagementCapability, p as UserRecordSchema, r as ApiKeyRecordSchema, y as authProviderCapability } from "../../dist-DhL_zGRT.mjs";
2
+ import { ct as userManagementCapability, d as ScopedTokenSchema, p as UserRecordSchema, pt as BaseAddon, r as ApiKeyRecordSchema, y as authProviderCapability } from "../../dist-BqJJWCS8.mjs";
3
3
  import * as crypto$1 from "node:crypto";
4
4
  import { randomUUID } from "node:crypto";
5
5
  import nodeCrypto from "crypto";
@@ -1,6 +1,6 @@
1
1
  Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
2
2
  const require_chunk = require("../../chunk-Cek0wNdY.js");
3
- const require_dist = require("../../dist-BupxnZOi.js");
3
+ const require_dist = require("../../dist-CV6XTApk.js");
4
4
  let node_os = require("node:os");
5
5
  node_os = require_chunk.__toESM(node_os);
6
6
  //#region src/builtins/local-network/local-network.addon.ts
@@ -1,4 +1,4 @@
1
- import { H as localNetworkCapability, Lt as EventCategory, dt as BaseAddon } from "../../dist-DhL_zGRT.mjs";
1
+ import { W as localNetworkCapability, pt as BaseAddon, zt as EventCategory } from "../../dist-BqJJWCS8.mjs";
2
2
  import * as os from "node:os";
3
3
  //#region src/builtins/local-network/local-network.addon.ts
4
4
  /**
@@ -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-BupxnZOi.js");
6
+ const require_dist = require("../../dist-CV6XTApk.js");
7
7
  //#region src/builtins/loki-logging/loki-payload.ts
8
8
  /**
9
9
  * Loki rejects a label name that is not a valid Prometheus label
@@ -1,4 +1,4 @@
1
- import { U as logDestinationCapability, dt as BaseAddon } from "../../dist-DhL_zGRT.mjs";
1
+ import { G as logDestinationCapability, pt as BaseAddon } from "../../dist-BqJJWCS8.mjs";
2
2
  //#region src/builtins/loki-logging/loki-payload.ts
3
3
  /**
4
4
  * Loki rejects a label name that is not a valid Prometheus label
@@ -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-BupxnZOi.js");
6
+ const require_dist = require("../../dist-CV6XTApk.js");
7
7
  let node_fs = require("node:fs");
8
8
  node_fs = require_chunk.__toESM(node_fs);
9
9
  let node_child_process = require("node:child_process");
@@ -1,4 +1,4 @@
1
- import { K as metricsProviderCapability, Lt as EventCategory, dt as BaseAddon, wt as createEvent } from "../../dist-DhL_zGRT.mjs";
1
+ import { Et as createEvent, J as metricsProviderCapability, pt as BaseAddon, zt as EventCategory } from "../../dist-BqJJWCS8.mjs";
2
2
  import * as fs from "node:fs";
3
3
  import { execFile, execFileSync } from "node:child_process";
4
4
  import { promisify } from "node:util";
@@ -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-BupxnZOi.js");
6
+ const require_dist = require("../../dist-CV6XTApk.js");
7
7
  let node_fs = require("node:fs");
8
8
  node_fs = require_chunk.__toESM(node_fs);
9
9
  let node_child_process = require("node:child_process");
@@ -1,5 +1,5 @@
1
1
  import { o as __toESM } from "../../chunk-CNf5ZN-e.mjs";
2
- import { Et as emitReadiness, Lt as EventCategory, Q as scoreRuntimes, X as platformProbeCapability, dt as BaseAddon, k as enumerateInferenceDevices, ut as errMsg } from "../../dist-DhL_zGRT.mjs";
2
+ import { A as enumerateInferenceDevices, Ot as emitReadiness, Q as platformProbeCapability, et as scoreRuntimes, ft as errMsg, pt as BaseAddon, zt as EventCategory } from "../../dist-BqJJWCS8.mjs";
3
3
  import * as fs from "node:fs";
4
4
  import { execFile } from "node:child_process";
5
5
  import { promisify } from "node:util";
@@ -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-BupxnZOi.js");
6
+ const require_dist = require("../../dist-CV6XTApk.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 { Lt as EventCategory, dt as BaseAddon } from "../../dist-DhL_zGRT.mjs";
1
+ import { pt as BaseAddon, zt as EventCategory } from "../../dist-BqJJWCS8.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
  require("../../chunk-Cek0wNdY.js");
6
- const require_dist = require("../../dist-BupxnZOi.js");
6
+ const require_dist = require("../../dist-CV6XTApk.js");
7
7
  let node_child_process = require("node:child_process");
8
8
  //#region src/builtins/snapshot/snapshot-coalescing.ts
9
9
  /**
@@ -604,7 +604,7 @@ var SnapshotAddon = class SnapshotAddon extends require_dist.BaseAddon {
604
604
  access: "authenticated",
605
605
  handler
606
606
  }) ?? null;
607
- this.ctx.logger.info("snapshot media data-plane served", { meta: { baseUrl: this.mediaDataPlane ? `/addon/${this.ctx.id}/media` : "(no dataPlane facility)" } });
607
+ this.ctx.logger.info("snapshot media data-plane served", { meta: { baseUrl: this.mediaDataPlane ? `/addon/${require_dist.bareAddonId(this.ctx.id)}/media` : "(no dataPlane facility)" } });
608
608
  } catch (err) {
609
609
  this.ctx.logger.warn("snapshot media data-plane failed to serve", { meta: { error: require_dist.errMsg(err) } });
610
610
  this.mediaDataPlane = null;
@@ -1,4 +1,4 @@
1
- import { At as nodePin, _t as DeviceType, dt as BaseAddon, ht as DeviceFeature, i as BatteryStatusSchema, it as streamQualityLabel, tt as snapshotCapability, ut as errMsg } from "../../dist-DhL_zGRT.mjs";
1
+ import { Mt as nodePin, _t as DeviceFeature, ft as errMsg, i as BatteryStatusSchema, ot as streamQualityLabel, pt as BaseAddon, rt as snapshotCapability, x as bareAddonId, yt as DeviceType } from "../../dist-BqJJWCS8.mjs";
2
2
  import { execFile, spawn } from "node:child_process";
3
3
  //#region src/builtins/snapshot/snapshot-coalescing.ts
4
4
  /**
@@ -599,7 +599,7 @@ var SnapshotAddon = class SnapshotAddon extends BaseAddon {
599
599
  access: "authenticated",
600
600
  handler
601
601
  }) ?? null;
602
- this.ctx.logger.info("snapshot media data-plane served", { meta: { baseUrl: this.mediaDataPlane ? `/addon/${this.ctx.id}/media` : "(no dataPlane facility)" } });
602
+ this.ctx.logger.info("snapshot media data-plane served", { meta: { baseUrl: this.mediaDataPlane ? `/addon/${bareAddonId(this.ctx.id)}/media` : "(no dataPlane facility)" } });
603
603
  } catch (err) {
604
604
  this.ctx.logger.warn("snapshot media data-plane failed to serve", { meta: { error: errMsg(err) } });
605
605
  this.mediaDataPlane = null;
@@ -3,12 +3,12 @@ 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-BupxnZOi.js");
6
+ const require_dist = require("../../dist-CV6XTApk.js");
7
+ let node_crypto = require("node:crypto");
7
8
  let node_fs = require("node:fs");
8
9
  node_fs = require_chunk.__toESM(node_fs);
9
10
  let node_path = require("node:path");
10
11
  node_path = require_chunk.__toESM(node_path);
11
- let node_crypto = require("node:crypto");
12
12
  let node_os = require("node:os");
13
13
  let node_fs_promises = require("node:fs/promises");
14
14
  //#region src/builtins/sqlite-storage/path-guard.ts
@@ -1,8 +1,8 @@
1
- import { P as filesystemBrowseCapability, dt as BaseAddon, rt as storageProviderCapability } from "../../dist-DhL_zGRT.mjs";
1
+ import { F as filesystemBrowseCapability, at as storageProviderCapability, pt as BaseAddon } from "../../dist-BqJJWCS8.mjs";
2
+ import { randomUUID } from "node:crypto";
2
3
  import * as fs from "node:fs";
3
4
  import * as path$1 from "node:path";
4
5
  import { basename, dirname, join, resolve, sep } from "node:path";
5
- import { randomUUID } from "node:crypto";
6
6
  import { homedir } from "node:os";
7
7
  import { mkdir, readdir, realpath, statfs } from "node:fs/promises";
8
8
  //#region src/builtins/sqlite-storage/path-guard.ts
@@ -3,5 +3,8 @@ export type { DeviceRow } from './device-store.js';
3
3
  export { DeviceStore } from './device-store.js';
4
4
  export { FilesystemStorageAddon, FilesystemStorageAddon as default, } from './filesystem-storage.addon.js';
5
5
  export { FilesystemStorageProvider } from './filesystem-storage-provider.js';
6
+ export { SQLITE_JOURNAL_SIZE_LIMIT_BYTES, SQLITE_MMAP_SIZE_BYTES, SQLITE_PAGE_CACHE_KIB, } from './sqlite-pragmas.js';
6
7
  export { SqliteSettingsAddon } from './sqlite-settings.addon.js';
7
8
  export { SqliteSettingsBackend } from './sqlite-settings-backend.js';
9
+ export type { WalMaintenanceOptions, WalMaintenanceOutcome } from './wal-maintenance.js';
10
+ export { WAL_CHECKPOINT_BUSY_TIMEOUT_MS, WAL_HIGH_WATER_BYTES, WAL_IDLE_QUIET_MS, WAL_MAINTENANCE_INTERVAL_MS, WalMaintenance, } from './wal-maintenance.js';
@@ -57,6 +57,14 @@ exports.DeviceStore = DeviceStore;
57
57
  exports.DeviceStore$1 = DeviceStore;
58
58
  exports.FilesystemStorageAddon = require_builtins_sqlite_storage_filesystem_storage_addon.FilesystemStorageAddon;
59
59
  exports.FilesystemStorageProvider = require_builtins_sqlite_storage_filesystem_storage_addon.FilesystemStorageProvider;
60
+ exports.SQLITE_JOURNAL_SIZE_LIMIT_BYTES = require_builtins_sqlite_storage_sqlite_settings_addon.SQLITE_JOURNAL_SIZE_LIMIT_BYTES;
61
+ exports.SQLITE_MMAP_SIZE_BYTES = require_builtins_sqlite_storage_sqlite_settings_addon.SQLITE_MMAP_SIZE_BYTES;
62
+ exports.SQLITE_PAGE_CACHE_KIB = require_builtins_sqlite_storage_sqlite_settings_addon.SQLITE_PAGE_CACHE_KIB;
60
63
  exports.SqliteSettingsAddon = require_builtins_sqlite_storage_sqlite_settings_addon.SqliteSettingsAddon;
61
64
  exports.SqliteSettingsBackend = require_builtins_sqlite_storage_sqlite_settings_addon.SqliteSettingsBackend;
65
+ exports.WAL_CHECKPOINT_BUSY_TIMEOUT_MS = require_builtins_sqlite_storage_sqlite_settings_addon.WAL_CHECKPOINT_BUSY_TIMEOUT_MS;
66
+ exports.WAL_HIGH_WATER_BYTES = require_builtins_sqlite_storage_sqlite_settings_addon.WAL_HIGH_WATER_BYTES;
67
+ exports.WAL_IDLE_QUIET_MS = require_builtins_sqlite_storage_sqlite_settings_addon.WAL_IDLE_QUIET_MS;
68
+ exports.WAL_MAINTENANCE_INTERVAL_MS = require_builtins_sqlite_storage_sqlite_settings_addon.WAL_MAINTENANCE_INTERVAL_MS;
69
+ exports.WalMaintenance = require_builtins_sqlite_storage_sqlite_settings_addon.WalMaintenance;
62
70
  exports.default = require_builtins_sqlite_storage_filesystem_storage_addon.FilesystemStorageAddon;
@@ -1,5 +1,5 @@
1
1
  import { FilesystemStorageAddon, t as FilesystemStorageProvider } from "./filesystem-storage.addon.mjs";
2
- import { SqliteSettingsAddon, t as SqliteSettingsBackend } from "./sqlite-settings.addon.mjs";
2
+ import { SqliteSettingsAddon, a as WalMaintenance, c as SQLITE_MMAP_SIZE_BYTES, i as WAL_MAINTENANCE_INTERVAL_MS, l as SQLITE_PAGE_CACHE_KIB, n as WAL_HIGH_WATER_BYTES, o as SqliteSettingsBackend, r as WAL_IDLE_QUIET_MS, s as SQLITE_JOURNAL_SIZE_LIMIT_BYTES, t as WAL_CHECKPOINT_BUSY_TIMEOUT_MS } from "./sqlite-settings.addon.mjs";
3
3
  //#region src/builtins/sqlite-storage/config-store.ts
4
4
  var ConfigStore = class {
5
5
  db;
@@ -46,4 +46,4 @@ var DeviceStore = class {
46
46
  }
47
47
  };
48
48
  //#endregion
49
- export { ConfigStore, DeviceStore, FilesystemStorageAddon, FilesystemStorageAddon as default, FilesystemStorageProvider, SqliteSettingsAddon, SqliteSettingsBackend };
49
+ export { ConfigStore, DeviceStore, FilesystemStorageAddon, FilesystemStorageAddon as default, FilesystemStorageProvider, SQLITE_JOURNAL_SIZE_LIMIT_BYTES, SQLITE_MMAP_SIZE_BYTES, SQLITE_PAGE_CACHE_KIB, SqliteSettingsAddon, SqliteSettingsBackend, WAL_CHECKPOINT_BUSY_TIMEOUT_MS, WAL_HIGH_WATER_BYTES, WAL_IDLE_QUIET_MS, WAL_MAINTENANCE_INTERVAL_MS, WalMaintenance };
@@ -0,0 +1,94 @@
1
+ import { ISettingsBackend, SettingsCollection } from '@camstack/types';
2
+ /** One retired-key declaration, scoped to a single store row. */
3
+ export interface RetiredKeySpec {
4
+ /** Addon id owning the store (the settings-store namespace). */
5
+ readonly namespace: string;
6
+ /** Collection inside that namespace, e.g. `addon-settings`. */
7
+ readonly collection: SettingsCollection;
8
+ /** Row id inside the collection, e.g. `root`. */
9
+ readonly row: string;
10
+ /** Keys retired verbatim. Matched exactly. */
11
+ readonly keys: readonly string[];
12
+ /**
13
+ * Keys retired in both their bare form and their per-node form
14
+ * (`<key>@<nodeId>`), which is how `nodeScopedKey` persists a
15
+ * `perNode: true` schema field.
16
+ */
17
+ readonly perNodeKeys: readonly string[];
18
+ /** Why they are dead — cited in the record, not re-derived at the call site. */
19
+ readonly reason: string;
20
+ }
21
+ /** What a purge pass deleted from one row. */
22
+ export interface RetiredKeyPurgeResult {
23
+ readonly addon: string;
24
+ readonly collection: string;
25
+ readonly row: string;
26
+ readonly keys: readonly string[];
27
+ }
28
+ /** The store access the purge needs. Narrow on purpose — trivially fakeable. */
29
+ export interface RetiredKeyStore {
30
+ /** Current row value, or `null` when the row does not exist. Throws on fault. */
31
+ read(spec: RetiredKeySpec): Promise<Record<string, unknown> | null>;
32
+ /** Replace the row with `value`. */
33
+ write(spec: RetiredKeySpec, value: Record<string, unknown>): Promise<void>;
34
+ }
35
+ /**
36
+ * Is THIS node the one whose settings store is the cluster's authority?
37
+ *
38
+ * Mirrors `resolveNodeRole` (server/backend `node-role.ts`) — unset or `'hub'`
39
+ * means hub, which is the launcher's own default. It is duplicated rather than
40
+ * imported because `@camstack/system` is a dependency OF the backend, not the
41
+ * other way round; the parse is four lines and the env var is the contract.
42
+ *
43
+ * Anything else answers `false`. Skipping where the purge should have run is a
44
+ * missed cleanup the next hub boot fixes; running where it should not have is a
45
+ * write to a store this node does not own. Only one of those is recoverable.
46
+ */
47
+ export declare function settingsStoreIsAuthoritativeHere(env: NodeJS.ProcessEnv): boolean;
48
+ /** The logging surface the purge uses — a structural subset of `IScopedLogger`. */
49
+ export interface RetiredKeyLogger {
50
+ info(message: string, context?: {
51
+ readonly meta?: Record<string, unknown>;
52
+ }): void;
53
+ warn(message: string, context?: {
54
+ readonly meta?: Record<string, unknown>;
55
+ }): void;
56
+ }
57
+ /**
58
+ * The dead keys, per row.
59
+ *
60
+ * `detection-pipeline` / `addon-settings` / `root` — every key in this row is
61
+ * dead; the row itself is kept because the addon writes live keys into it
62
+ * (`pipelineTemplates`, `videoPipelineSteps`).
63
+ *
64
+ * - `pipelineSteps` / `pipelineEngine`: the persisted GLOBAL step + engine
65
+ * seed. Removed with `getGlobalSteps` becoming pure — dispatch builds steps
66
+ * from the orchestrator's `agentSettings` plus per-camera overrides, and
67
+ * never consulted the seed. See `addon-pipeline/src/detection-pipeline/provider.ts`.
68
+ * - `engineRuntime` / `engineBackend` / `engineDevice` / `probedBestEngine`:
69
+ * the per-node engine CASCADE, removed with the operator-facing engine
70
+ * election. Each node now runs a device-array of inference pools balanced
71
+ * per session, and the node-default pool derives live from the node's own
72
+ * hardware (`resolveAutoEngine`). See
73
+ * `addon-pipeline/src/detection-pipeline/engine-store-keys.ts`.
74
+ */
75
+ export declare const RETIRED_SETTINGS_KEYS: readonly RetiredKeySpec[];
76
+ /**
77
+ * Adapt the settings backend to {@link RetiredKeyStore}.
78
+ *
79
+ * `get` answering a non-object (missing row) is a MISS, not a fault: it maps to
80
+ * `null` and the purge skips the row. A backend throw propagates, which is what
81
+ * routes it to the "read failed, row left untouched" branch.
82
+ */
83
+ export declare function retiredKeyStoreOf(backend: ISettingsBackend): RetiredKeyStore;
84
+ /** Keys of `blob` that `spec` retires. Pure. */
85
+ export declare function planRetiredKeyPurge(blob: Readonly<Record<string, unknown>>, spec: RetiredKeySpec): readonly string[];
86
+ /**
87
+ * Delete every retired key present in the declared rows — on the hub.
88
+ *
89
+ * Off the authoritative node this is a no-op that touches nothing and says
90
+ * nothing (see the module header). Returns one entry per row that actually
91
+ * changed — empty when the store is already clean, which is the steady state
92
+ * after the first boot that ran it.
93
+ */
94
+ export declare function purgeRetiredSettingsKeys(store: RetiredKeyStore, logger: RetiredKeyLogger, specs?: readonly RetiredKeySpec[], env?: NodeJS.ProcessEnv): Promise<readonly RetiredKeyPurgeResult[]>;
@@ -0,0 +1,85 @@
1
+ /**
2
+ * Connection tuning for the hub's SQLite database.
3
+ *
4
+ * Every number here is sized against a MEASURED database, not a blog post.
5
+ * On the live hub (2026-08-06), 20 Hz syscall sampling of hub-main put **210
6
+ * of 2,561 samples inside `pread64`** — 161 on `camstack.db` and 49 on
7
+ * `camstack.db-wal`, all 4 KiB page reads, i.e. page-cache misses. That is
8
+ * 8.2% of wall-clock and ~20% during bursts, on the single thread that also
9
+ * serves every tRPC request. fds 79/81 of hub-main were the two files, so the
10
+ * cost is proven in-process rather than inferred.
11
+ *
12
+ * The database was **130 MB** with a **249 MB** WAL high-water mark. Its
13
+ * tenants are not settings: the analytics event/track/media stores and the
14
+ * sqlite-vec index all live in this one file.
15
+ */
16
+ /**
17
+ * Page cache, in KiB (SQLite reads a NEGATIVE `cache_size` as KiB rather than
18
+ * as a page count, which is what makes it independent of `page_size`).
19
+ *
20
+ * -65536 = **64 MiB**. Sized from the 130 MB file: the hot working set is the
21
+ * B-tree interior pages plus the indexes the analytics queries walk, which is
22
+ * a fraction of the total — 64 MiB covers roughly half the file outright, so a
23
+ * repeated query stops re-reading the same 4 KiB pages from disk. Going to the
24
+ * full 130 MB would buy the tail of a cold table scan for twice the resident
25
+ * cost; going smaller leaves the measured miss rate roughly where it is.
26
+ *
27
+ * Why the build default is not enough: better-sqlite3 compiles with
28
+ * `SQLITE_DEFAULT_CACHE_SIZE=-16000`, so the starting point is ~16 MiB — 8x
29
+ * short of the file, not the ~2 MiB stock SQLite default. This is a 4x
30
+ * increase, not a 32x one.
31
+ *
32
+ * Cost: 64 MiB of malloc'd C memory, ONE connection's worth (better-sqlite3
33
+ * holds a single handle and the vector index shares it). It is off-heap, so it
34
+ * does not move V8's heap ceiling — the thing that produced the hub's previous
35
+ * OOM.
36
+ */
37
+ export declare const SQLITE_PAGE_CACHE_KIB = -65536;
38
+ /**
39
+ * Memory-mapped I/O window, in bytes. 268435456 = **256 MiB**.
40
+ *
41
+ * Chosen to exceed the 130 MB database with room for it to roughly double, so
42
+ * the whole main file can be mapped. Pages then arrive as minor faults against
43
+ * the OS page cache instead of `pread64` syscalls — which is precisely the
44
+ * 161-sample half of the measurement. It also means a page evicted from
45
+ * SQLite's own cache is usually still resident in the OS cache, so the two
46
+ * knobs compound rather than duplicate.
47
+ *
48
+ * Two honest caveats:
49
+ * - SQLite **never mmaps the WAL**. The 49 WAL samples are not addressed
50
+ * here; they are addressed by keeping the WAL small (see
51
+ * {@link SQLITE_JOURNAL_SIZE_LIMIT_BYTES} and `wal-maintenance.ts`).
52
+ * - With mmap, an I/O error on a mapped page surfaces as SIGBUS rather than a
53
+ * catchable SQLite error. The pragma is asserted in
54
+ * `__tests__/sqlite-pragmas.spec.ts` by reading it back, so a build that
55
+ * ignores it (`SQLITE_MAX_MMAP_SIZE=0`) fails loudly instead of quietly
56
+ * doing nothing.
57
+ */
58
+ export declare const SQLITE_MMAP_SIZE_BYTES = 268435456;
59
+ /**
60
+ * Upper bound on the WAL file left on disk after a checkpoint resets it, in
61
+ * bytes. 67108864 = **64 MiB**.
62
+ *
63
+ * This is the passive half of the WAL fix and it carries no stall risk at all:
64
+ * it takes no lock and blocks nothing. It only says "when a checkpoint has
65
+ * already succeeded, truncate the file rather than leaving the space
66
+ * allocated". Without it, a WAL that spiked once stays spiked — which is how
67
+ * a 130 MB database ends up with a 249 MB sidecar.
68
+ *
69
+ * 64 MiB is deliberately well above the ~4 MiB `wal_autocheckpoint` threshold
70
+ * (1000 pages), so ordinary operation never touches this ceiling and the file
71
+ * is not being repeatedly truncated and re-grown.
72
+ */
73
+ export declare const SQLITE_JOURNAL_SIZE_LIMIT_BYTES = 67108864;
74
+ /**
75
+ * `synchronous` is deliberately NOT set here.
76
+ *
77
+ * better-sqlite3 compiles with `SQLITE_DEFAULT_WAL_SYNCHRONOUS=1`, so a WAL
78
+ * database is **already** at `NORMAL`. Writing `PRAGMA synchronous = NORMAL`
79
+ * would be a no-op that reads, forever after, like a durability decision
80
+ * somebody made — the kind of leftover that is worse than nothing because it
81
+ * looks like verification. `__tests__/sqlite-pragmas.spec.ts` asserts the
82
+ * effective value instead, so a dependency bump that changes the default is
83
+ * caught rather than assumed.
84
+ */
85
+ export declare const SQLITE_SYNCHRONOUS_IS_BUILD_DEFAULT = true;
@@ -20,6 +20,7 @@ import { SqliteVecVectorIndex } from './vector-index-vec.js';
20
20
  export declare class SqliteSettingsAddon extends BaseAddon {
21
21
  private backend;
22
22
  private vectorIndex;
23
+ private walMaintenance;
23
24
  constructor();
24
25
  protected onInitialize(): Promise<ProviderRegistration[]>;
25
26
  protected onShutdown(): Promise<void>;