@camstack/system 1.2.27 → 1.2.29
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 +3 -3
- package/dist/addon-runner.mjs +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.d.ts +0 -7
- package/dist/builtins/alerts/alerts.addon.js +47 -25
- package/dist/builtins/alerts/alerts.addon.mjs +47 -25
- package/dist/builtins/alerts/prune-policy.d.ts +44 -0
- package/dist/builtins/backup-orchestrator/backup-orchestrator.addon.js +1 -1
- package/dist/builtins/backup-orchestrator/backup-orchestrator.addon.mjs +1 -1
- package/dist/builtins/console-logging/index.js +1 -1
- package/dist/builtins/console-logging/index.mjs +1 -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/doorbell/virtual-doorbell.addon.js +1 -1
- package/dist/builtins/doorbell/virtual-doorbell.addon.mjs +1 -1
- package/dist/builtins/hub-forwarder/index.js +1 -1
- package/dist/builtins/hub-forwarder/index.mjs +1 -1
- package/dist/builtins/local-auth/local-auth.addon.js +1 -1
- package/dist/builtins/local-auth/local-auth.addon.mjs +1 -1
- package/dist/builtins/local-network/local-network.addon.js +1 -1
- package/dist/builtins/local-network/local-network.addon.mjs +1 -1
- package/dist/builtins/loki-logging/index.js +1 -1
- package/dist/builtins/loki-logging/index.mjs +1 -1
- package/dist/builtins/native-metrics/native-metrics.addon.js +1 -1
- package/dist/builtins/native-metrics/native-metrics.addon.mjs +1 -1
- package/dist/builtins/platform-probe/index.js +1 -1
- package/dist/builtins/platform-probe/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/sqlite-settings-backend.d.ts +7 -1
- package/dist/builtins/sqlite-storage/sqlite-settings.addon.d.ts +8 -2
- package/dist/builtins/sqlite-storage/sqlite-settings.addon.js +22 -4
- package/dist/builtins/sqlite-storage/sqlite-settings.addon.mjs +22 -4
- package/dist/builtins/storage-orchestrator/data-store-dispatch.d.ts +12 -0
- package/dist/builtins/storage-orchestrator/storage-orchestrator.addon.d.ts +18 -7
- package/dist/builtins/storage-orchestrator/storage-orchestrator.addon.js +78 -11
- package/dist/builtins/storage-orchestrator/storage-orchestrator.addon.mjs +78 -11
- package/dist/builtins/system-config/system-config.addon.js +1 -1
- package/dist/builtins/system-config/system-config.addon.mjs +1 -1
- package/dist/builtins/winston-logging/index.js +1 -1
- package/dist/builtins/winston-logging/index.mjs +1 -1
- package/dist/{dist-BXmFvn3h.mjs → dist-B7hOpr5i.mjs} +411 -166
- package/dist/{dist-BxtIzexq.js → dist-CPmFYLqq.js} +416 -165
- package/dist/index.d.ts +2 -0
- package/dist/index.js +106 -2
- package/dist/index.mjs +102 -3
- package/dist/kernel/heap-watch.d.ts +36 -0
- package/dist/kernel/transport/uds-event-bus.d.ts +4 -1
- package/dist/{manifest-python-deps-KZ00cbfP.js → manifest-python-deps-BqE5j0-O.js} +25 -4
- package/dist/{manifest-python-deps-BNOApgK0.mjs → manifest-python-deps-Ck4-9K9m.mjs} +25 -4
- package/package.json +7 -3
|
@@ -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-CPmFYLqq.js");
|
|
7
7
|
let node_crypto = require("node:crypto");
|
|
8
8
|
let better_sqlite3 = require("better-sqlite3");
|
|
9
9
|
better_sqlite3 = require_chunk.__toESM(better_sqlite3);
|
|
@@ -119,6 +119,18 @@ var SqliteSettingsBackend = class SqliteSettingsBackend {
|
|
|
119
119
|
this.db?.close();
|
|
120
120
|
this.db = null;
|
|
121
121
|
}
|
|
122
|
+
/**
|
|
123
|
+
* `data-store-provider` self-description — how the orchestrator names
|
|
124
|
+
* this engine in a log line, and (once collections declare an engine)
|
|
125
|
+
* how it picks between registrants.
|
|
126
|
+
*/
|
|
127
|
+
async getEngineInfo() {
|
|
128
|
+
return {
|
|
129
|
+
engineId: "sqlite",
|
|
130
|
+
kind: "relational",
|
|
131
|
+
displayName: "SQLite (WAL)"
|
|
132
|
+
};
|
|
133
|
+
}
|
|
122
134
|
async get({ namespace, collection, key }) {
|
|
123
135
|
const scoped = this.scopedName(namespace, collection);
|
|
124
136
|
const decl = this.requireDeclared(scoped);
|
|
@@ -605,8 +617,14 @@ var SqliteSettingsBackend = class SqliteSettingsBackend {
|
|
|
605
617
|
//#endregion
|
|
606
618
|
//#region src/builtins/sqlite-storage/sqlite-settings.addon.ts
|
|
607
619
|
/**
|
|
608
|
-
* SQLite Settings addon —
|
|
609
|
-
*
|
|
620
|
+
* SQLite Settings addon — the relational ENGINE behind the data door.
|
|
621
|
+
*
|
|
622
|
+
* Capability: `data-store-provider` (collection, internal). It does not
|
|
623
|
+
* serve `settings-store`: that is the public door, owned by
|
|
624
|
+
* storage-orchestrator, which dispatches here
|
|
625
|
+
* ([D44](../../../../../docs/decisions/adr-0044.md)). Callers reach this
|
|
626
|
+
* engine only through the door — which is the point, because it is what
|
|
627
|
+
* makes the engine replaceable.
|
|
610
628
|
*/
|
|
611
629
|
var SqliteSettingsAddon = class extends require_dist.BaseAddon {
|
|
612
630
|
backend = null;
|
|
@@ -635,7 +653,7 @@ var SqliteSettingsAddon = class extends require_dist.BaseAddon {
|
|
|
635
653
|
await this.backend.initialize();
|
|
636
654
|
this.ctx.logger.info("Initialized successfully");
|
|
637
655
|
return [{
|
|
638
|
-
capability: require_dist.
|
|
656
|
+
capability: require_dist.dataStoreProviderCapability,
|
|
639
657
|
provider: this.backend
|
|
640
658
|
}];
|
|
641
659
|
}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { Dt as parseJsonUnknown, at as errMsg, c as RUNTIME_DEFAULTS, gt as asJsonObject, ot as BaseAddon, x as dataStoreProviderCapability } from "../../dist-B7hOpr5i.mjs";
|
|
2
2
|
import { randomUUID } from "node:crypto";
|
|
3
3
|
import Database from "better-sqlite3";
|
|
4
4
|
//#region src/builtins/sqlite-storage/sqlite-settings-backend.ts
|
|
@@ -113,6 +113,18 @@ var SqliteSettingsBackend = class SqliteSettingsBackend {
|
|
|
113
113
|
this.db?.close();
|
|
114
114
|
this.db = null;
|
|
115
115
|
}
|
|
116
|
+
/**
|
|
117
|
+
* `data-store-provider` self-description — how the orchestrator names
|
|
118
|
+
* this engine in a log line, and (once collections declare an engine)
|
|
119
|
+
* how it picks between registrants.
|
|
120
|
+
*/
|
|
121
|
+
async getEngineInfo() {
|
|
122
|
+
return {
|
|
123
|
+
engineId: "sqlite",
|
|
124
|
+
kind: "relational",
|
|
125
|
+
displayName: "SQLite (WAL)"
|
|
126
|
+
};
|
|
127
|
+
}
|
|
116
128
|
async get({ namespace, collection, key }) {
|
|
117
129
|
const scoped = this.scopedName(namespace, collection);
|
|
118
130
|
const decl = this.requireDeclared(scoped);
|
|
@@ -599,8 +611,14 @@ var SqliteSettingsBackend = class SqliteSettingsBackend {
|
|
|
599
611
|
//#endregion
|
|
600
612
|
//#region src/builtins/sqlite-storage/sqlite-settings.addon.ts
|
|
601
613
|
/**
|
|
602
|
-
* SQLite Settings addon —
|
|
603
|
-
*
|
|
614
|
+
* SQLite Settings addon — the relational ENGINE behind the data door.
|
|
615
|
+
*
|
|
616
|
+
* Capability: `data-store-provider` (collection, internal). It does not
|
|
617
|
+
* serve `settings-store`: that is the public door, owned by
|
|
618
|
+
* storage-orchestrator, which dispatches here
|
|
619
|
+
* ([D44](../../../../../docs/decisions/adr-0044.md)). Callers reach this
|
|
620
|
+
* engine only through the door — which is the point, because it is what
|
|
621
|
+
* makes the engine replaceable.
|
|
604
622
|
*/
|
|
605
623
|
var SqliteSettingsAddon = class extends BaseAddon {
|
|
606
624
|
backend = null;
|
|
@@ -629,7 +647,7 @@ var SqliteSettingsAddon = class extends BaseAddon {
|
|
|
629
647
|
await this.backend.initialize();
|
|
630
648
|
this.ctx.logger.info("Initialized successfully");
|
|
631
649
|
return [{
|
|
632
|
-
capability:
|
|
650
|
+
capability: dataStoreProviderCapability,
|
|
633
651
|
provider: this.backend
|
|
634
652
|
}];
|
|
635
653
|
}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import { IDataStoreProvider, ISettingsStoreProvider } from '@camstack/types';
|
|
2
|
+
/** How the dispatcher reaches the registered engines, read per call. */
|
|
3
|
+
export type GetDataStoreEngines = () => readonly IDataStoreProvider[];
|
|
4
|
+
/**
|
|
5
|
+
* Build the `settings-store` provider that fronts the registered engines.
|
|
6
|
+
*
|
|
7
|
+
* `getEngines` is read on every call, never captured: engines register
|
|
8
|
+
* during boot and a runner respawn replaces the instance, so a snapshot
|
|
9
|
+
* taken at construction time would go stale exactly when an addon crashed
|
|
10
|
+
* and came back.
|
|
11
|
+
*/
|
|
12
|
+
export declare function createDataStoreDispatch(getEngines: GetDataStoreEngines): ISettingsStoreProvider;
|
|
@@ -25,16 +25,27 @@ export declare class StorageOrchestratorAddon extends BaseAddon<StorageOrchestra
|
|
|
25
25
|
protected onInitialize(): Promise<ProviderRegistration[]>;
|
|
26
26
|
protected onShutdown(): Promise<void>;
|
|
27
27
|
/**
|
|
28
|
-
* Resolve the live
|
|
29
|
-
*
|
|
30
|
-
*
|
|
31
|
-
*
|
|
32
|
-
*
|
|
28
|
+
* Resolve the live engine from the capability registry and wrap it in a
|
|
29
|
+
* `SqliteLocationStore`. Returns `null` when no engine has registered
|
|
30
|
+
* yet — the service falls back to in-memory only. Production boot order
|
|
31
|
+
* (`data-store-provider` precedes `storage` in `INFRA_CAPABILITIES`)
|
|
32
|
+
* makes this the rare path.
|
|
33
|
+
*
|
|
34
|
+
* Reads the ENGINE, not the `settings-store` singleton: since D44 this
|
|
35
|
+
* addon *is* that singleton, so asking the registry for it would hand
|
|
36
|
+
* the orchestrator its own dispatcher and route its location table back
|
|
37
|
+
* through itself.
|
|
38
|
+
*
|
|
39
|
+
* The `ensureTable` / `tableInsert` reach-around below is the B2 bypass,
|
|
40
|
+
* still open: those six methods live on the concrete backend and on no
|
|
41
|
+
* cap. Promoting them to the door is a separate task; until then this
|
|
42
|
+
* holds the engine object directly, which only works because the engine
|
|
43
|
+
* is in-process on this node.
|
|
33
44
|
*/
|
|
34
45
|
private resolveLocationStore;
|
|
35
46
|
/**
|
|
36
|
-
* Late-wire the persistence store once
|
|
37
|
-
* Production boot order means the store is usually absent at
|
|
47
|
+
* Late-wire the persistence store once a `data-store-provider` engine
|
|
48
|
+
* registers. Production boot order means the store is usually absent at
|
|
38
49
|
* `onInitialize`; this runs on every `capability:provider-registered`
|
|
39
50
|
* event until it succeeds. Single-flighted + idempotent (the service
|
|
40
51
|
* ignores a second attach). Without this, operator edits (e.g. a
|
|
@@ -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-CPmFYLqq.js");
|
|
7
7
|
let node_path = require("node:path");
|
|
8
8
|
node_path = require_chunk.__toESM(node_path);
|
|
9
9
|
let node_fs_promises = require("node:fs/promises");
|
|
@@ -730,6 +730,53 @@ async function collectProviderInfos(providers, onError) {
|
|
|
730
730
|
return out;
|
|
731
731
|
}
|
|
732
732
|
//#endregion
|
|
733
|
+
//#region src/builtins/storage-orchestrator/data-store-dispatch.ts
|
|
734
|
+
/**
|
|
735
|
+
* Pick the engine to serve a call.
|
|
736
|
+
*
|
|
737
|
+
* Today the rule is "the only one there is". Two cases are refused rather
|
|
738
|
+
* than guessed:
|
|
739
|
+
*
|
|
740
|
+
* - **none registered** — resolving to a no-op would make every read
|
|
741
|
+
* answer `undefined` and every write disappear, which reads exactly
|
|
742
|
+
* like an empty database;
|
|
743
|
+
* - **more than one** — there is no routing rule yet. The `engine` hint
|
|
744
|
+
* on `declareCollection` is what will choose, and until it exists a
|
|
745
|
+
* silent pick would send a collection to whichever engine happened to
|
|
746
|
+
* register first.
|
|
747
|
+
*/
|
|
748
|
+
function resolveEngine(getEngines) {
|
|
749
|
+
const engines = getEngines();
|
|
750
|
+
if (engines.length === 0) throw new Error("settings-store: no data-store-provider engine is registered — the data door has nothing behind it");
|
|
751
|
+
if (engines.length > 1) throw new Error(`settings-store: ${engines.length} data-store-provider engines are registered and there is no routing rule yet — declare the engine on the collection first`);
|
|
752
|
+
const engine = engines[0];
|
|
753
|
+
if (!engine) throw new Error("settings-store: data-store-provider collection yielded an empty entry");
|
|
754
|
+
return engine;
|
|
755
|
+
}
|
|
756
|
+
/**
|
|
757
|
+
* Build the `settings-store` provider that fronts the registered engines.
|
|
758
|
+
*
|
|
759
|
+
* `getEngines` is read on every call, never captured: engines register
|
|
760
|
+
* during boot and a runner respawn replaces the instance, so a snapshot
|
|
761
|
+
* taken at construction time would go stale exactly when an addon crashed
|
|
762
|
+
* and came back.
|
|
763
|
+
*/
|
|
764
|
+
function createDataStoreDispatch(getEngines) {
|
|
765
|
+
const engine = async () => resolveEngine(getEngines);
|
|
766
|
+
return {
|
|
767
|
+
get: async (input) => (await engine()).get(input),
|
|
768
|
+
set: async (input) => (await engine()).set(input),
|
|
769
|
+
query: async (input) => (await engine()).query(input),
|
|
770
|
+
insert: async (input) => (await engine()).insert(input),
|
|
771
|
+
update: async (input) => (await engine()).update(input),
|
|
772
|
+
delete: async (input) => (await engine()).delete(input),
|
|
773
|
+
count: async (input) => (await engine()).count(input),
|
|
774
|
+
histogram: async (input) => (await engine()).histogram(input),
|
|
775
|
+
isEmpty: async (input) => (await engine()).isEmpty(input),
|
|
776
|
+
declareCollection: async (input) => (await engine()).declareCollection(input)
|
|
777
|
+
};
|
|
778
|
+
}
|
|
779
|
+
//#endregion
|
|
733
780
|
//#region src/builtins/storage-orchestrator/storage-pressure-manager.ts
|
|
734
781
|
var DEFAULT_MAX_ROUNDS = 8;
|
|
735
782
|
var DEFAULT_HYSTERESIS_PERCENT = 1;
|
|
@@ -891,6 +938,7 @@ var StoragePressureManager = class {
|
|
|
891
938
|
* Task 7 will migrate consumers off the legacy storage shim.
|
|
892
939
|
*/
|
|
893
940
|
var STORAGE_PROVIDER_CAP_NAME = "storage-provider";
|
|
941
|
+
var DATA_STORE_PROVIDER_CAP_NAME = "data-store-provider";
|
|
894
942
|
var STORAGE_EVICTABLE_CAP_NAME = "storage-evictable";
|
|
895
943
|
/**
|
|
896
944
|
* Single-node default: existing node-local locations live on the hub.
|
|
@@ -935,6 +983,11 @@ var StorageOrchestratorAddon = class extends require_dist.BaseAddon {
|
|
|
935
983
|
if (!reg) return [];
|
|
936
984
|
return reg.getCollection(STORAGE_PROVIDER_CAP_NAME);
|
|
937
985
|
};
|
|
986
|
+
const getEngines = () => {
|
|
987
|
+
const reg = this.ctx.kernel.capabilityRegistry;
|
|
988
|
+
if (!reg) return [];
|
|
989
|
+
return reg.getCollection(DATA_STORE_PROVIDER_CAP_NAME);
|
|
990
|
+
};
|
|
938
991
|
const locationStore = this.resolveLocationStore();
|
|
939
992
|
const service = new StorageOrchestratorService(this.ctx.logger, getProviders, locationStore, this.ctx.kernel.localNodeId ?? "hub", (nodeId) => {
|
|
940
993
|
const proxy = this.ctx.kernel.resolveNodeCapability?.("storage-provider", nodeId);
|
|
@@ -1126,6 +1179,9 @@ var StorageOrchestratorAddon = class extends require_dist.BaseAddon {
|
|
|
1126
1179
|
return [{
|
|
1127
1180
|
capability: require_dist.storageCapability,
|
|
1128
1181
|
provider
|
|
1182
|
+
}, {
|
|
1183
|
+
capability: require_dist.settingsStoreCapability,
|
|
1184
|
+
provider: createDataStoreDispatch(getEngines)
|
|
1129
1185
|
}];
|
|
1130
1186
|
}
|
|
1131
1187
|
async onShutdown() {
|
|
@@ -1142,18 +1198,29 @@ var StorageOrchestratorAddon = class extends require_dist.BaseAddon {
|
|
|
1142
1198
|
this.service = null;
|
|
1143
1199
|
}
|
|
1144
1200
|
/**
|
|
1145
|
-
* Resolve the live
|
|
1146
|
-
*
|
|
1147
|
-
*
|
|
1148
|
-
*
|
|
1149
|
-
*
|
|
1201
|
+
* Resolve the live engine from the capability registry and wrap it in a
|
|
1202
|
+
* `SqliteLocationStore`. Returns `null` when no engine has registered
|
|
1203
|
+
* yet — the service falls back to in-memory only. Production boot order
|
|
1204
|
+
* (`data-store-provider` precedes `storage` in `INFRA_CAPABILITIES`)
|
|
1205
|
+
* makes this the rare path.
|
|
1206
|
+
*
|
|
1207
|
+
* Reads the ENGINE, not the `settings-store` singleton: since D44 this
|
|
1208
|
+
* addon *is* that singleton, so asking the registry for it would hand
|
|
1209
|
+
* the orchestrator its own dispatcher and route its location table back
|
|
1210
|
+
* through itself.
|
|
1211
|
+
*
|
|
1212
|
+
* The `ensureTable` / `tableInsert` reach-around below is the B2 bypass,
|
|
1213
|
+
* still open: those six methods live on the concrete backend and on no
|
|
1214
|
+
* cap. Promoting them to the door is a separate task; until then this
|
|
1215
|
+
* holds the engine object directly, which only works because the engine
|
|
1216
|
+
* is in-process on this node.
|
|
1150
1217
|
*/
|
|
1151
1218
|
resolveLocationStore(quiet = false) {
|
|
1152
1219
|
const reg = this.ctx.kernel.capabilityRegistry;
|
|
1153
1220
|
if (!reg) return null;
|
|
1154
|
-
const backend = reg.
|
|
1221
|
+
const backend = reg.getCollection(DATA_STORE_PROVIDER_CAP_NAME)[0];
|
|
1155
1222
|
if (!backend) {
|
|
1156
|
-
if (!quiet) this.ctx.logger.warn("storage-orchestrator: no
|
|
1223
|
+
if (!quiet) this.ctx.logger.warn("storage-orchestrator: no data-store-provider engine yet — running in-memory until one registers");
|
|
1157
1224
|
return null;
|
|
1158
1225
|
}
|
|
1159
1226
|
if (!backend.ensureTable || !backend.tableInsert) {
|
|
@@ -1163,8 +1230,8 @@ var StorageOrchestratorAddon = class extends require_dist.BaseAddon {
|
|
|
1163
1230
|
return new SqliteLocationStore(backend);
|
|
1164
1231
|
}
|
|
1165
1232
|
/**
|
|
1166
|
-
* Late-wire the persistence store once
|
|
1167
|
-
* Production boot order means the store is usually absent at
|
|
1233
|
+
* Late-wire the persistence store once a `data-store-provider` engine
|
|
1234
|
+
* registers. Production boot order means the store is usually absent at
|
|
1168
1235
|
* `onInitialize`; this runs on every `capability:provider-registered`
|
|
1169
1236
|
* event until it succeeds. Single-flighted + idempotent (the service
|
|
1170
1237
|
* ignores a second attach). Without this, operator edits (e.g. a
|
|
@@ -1178,7 +1245,7 @@ var StorageOrchestratorAddon = class extends require_dist.BaseAddon {
|
|
|
1178
1245
|
if (this.storeWireInFlight) return this.storeWireInFlight;
|
|
1179
1246
|
const store = this.resolveLocationStore(true);
|
|
1180
1247
|
if (!store) return;
|
|
1181
|
-
this.ctx.logger.info("storage-orchestrator:
|
|
1248
|
+
this.ctx.logger.info("storage-orchestrator: data-store engine now available — wiring persistence");
|
|
1182
1249
|
this.storeWireInFlight = service.attachStore(store).then(() => this.seedFromDeclarations()).catch((err) => {
|
|
1183
1250
|
this.ctx.logger.error("storage-orchestrator: attachStore failed", { meta: { error: err instanceof Error ? err.message : String(err) } });
|
|
1184
1251
|
}).finally(() => {
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { $ as storageCapability, Et as parseJsonObject, Z as settingsStoreCapability, d as StorageLocationTypeSchema, ot as BaseAddon } from "../../dist-B7hOpr5i.mjs";
|
|
2
2
|
import * as path$1 from "node:path";
|
|
3
3
|
import * as fs from "node:fs/promises";
|
|
4
4
|
import { buildStorageLocationRegistry } from "@camstack/system";
|
|
@@ -723,6 +723,53 @@ async function collectProviderInfos(providers, onError) {
|
|
|
723
723
|
return out;
|
|
724
724
|
}
|
|
725
725
|
//#endregion
|
|
726
|
+
//#region src/builtins/storage-orchestrator/data-store-dispatch.ts
|
|
727
|
+
/**
|
|
728
|
+
* Pick the engine to serve a call.
|
|
729
|
+
*
|
|
730
|
+
* Today the rule is "the only one there is". Two cases are refused rather
|
|
731
|
+
* than guessed:
|
|
732
|
+
*
|
|
733
|
+
* - **none registered** — resolving to a no-op would make every read
|
|
734
|
+
* answer `undefined` and every write disappear, which reads exactly
|
|
735
|
+
* like an empty database;
|
|
736
|
+
* - **more than one** — there is no routing rule yet. The `engine` hint
|
|
737
|
+
* on `declareCollection` is what will choose, and until it exists a
|
|
738
|
+
* silent pick would send a collection to whichever engine happened to
|
|
739
|
+
* register first.
|
|
740
|
+
*/
|
|
741
|
+
function resolveEngine(getEngines) {
|
|
742
|
+
const engines = getEngines();
|
|
743
|
+
if (engines.length === 0) throw new Error("settings-store: no data-store-provider engine is registered — the data door has nothing behind it");
|
|
744
|
+
if (engines.length > 1) throw new Error(`settings-store: ${engines.length} data-store-provider engines are registered and there is no routing rule yet — declare the engine on the collection first`);
|
|
745
|
+
const engine = engines[0];
|
|
746
|
+
if (!engine) throw new Error("settings-store: data-store-provider collection yielded an empty entry");
|
|
747
|
+
return engine;
|
|
748
|
+
}
|
|
749
|
+
/**
|
|
750
|
+
* Build the `settings-store` provider that fronts the registered engines.
|
|
751
|
+
*
|
|
752
|
+
* `getEngines` is read on every call, never captured: engines register
|
|
753
|
+
* during boot and a runner respawn replaces the instance, so a snapshot
|
|
754
|
+
* taken at construction time would go stale exactly when an addon crashed
|
|
755
|
+
* and came back.
|
|
756
|
+
*/
|
|
757
|
+
function createDataStoreDispatch(getEngines) {
|
|
758
|
+
const engine = async () => resolveEngine(getEngines);
|
|
759
|
+
return {
|
|
760
|
+
get: async (input) => (await engine()).get(input),
|
|
761
|
+
set: async (input) => (await engine()).set(input),
|
|
762
|
+
query: async (input) => (await engine()).query(input),
|
|
763
|
+
insert: async (input) => (await engine()).insert(input),
|
|
764
|
+
update: async (input) => (await engine()).update(input),
|
|
765
|
+
delete: async (input) => (await engine()).delete(input),
|
|
766
|
+
count: async (input) => (await engine()).count(input),
|
|
767
|
+
histogram: async (input) => (await engine()).histogram(input),
|
|
768
|
+
isEmpty: async (input) => (await engine()).isEmpty(input),
|
|
769
|
+
declareCollection: async (input) => (await engine()).declareCollection(input)
|
|
770
|
+
};
|
|
771
|
+
}
|
|
772
|
+
//#endregion
|
|
726
773
|
//#region src/builtins/storage-orchestrator/storage-pressure-manager.ts
|
|
727
774
|
var DEFAULT_MAX_ROUNDS = 8;
|
|
728
775
|
var DEFAULT_HYSTERESIS_PERCENT = 1;
|
|
@@ -884,6 +931,7 @@ var StoragePressureManager = class {
|
|
|
884
931
|
* Task 7 will migrate consumers off the legacy storage shim.
|
|
885
932
|
*/
|
|
886
933
|
var STORAGE_PROVIDER_CAP_NAME = "storage-provider";
|
|
934
|
+
var DATA_STORE_PROVIDER_CAP_NAME = "data-store-provider";
|
|
887
935
|
var STORAGE_EVICTABLE_CAP_NAME = "storage-evictable";
|
|
888
936
|
/**
|
|
889
937
|
* Single-node default: existing node-local locations live on the hub.
|
|
@@ -928,6 +976,11 @@ var StorageOrchestratorAddon = class extends BaseAddon {
|
|
|
928
976
|
if (!reg) return [];
|
|
929
977
|
return reg.getCollection(STORAGE_PROVIDER_CAP_NAME);
|
|
930
978
|
};
|
|
979
|
+
const getEngines = () => {
|
|
980
|
+
const reg = this.ctx.kernel.capabilityRegistry;
|
|
981
|
+
if (!reg) return [];
|
|
982
|
+
return reg.getCollection(DATA_STORE_PROVIDER_CAP_NAME);
|
|
983
|
+
};
|
|
931
984
|
const locationStore = this.resolveLocationStore();
|
|
932
985
|
const service = new StorageOrchestratorService(this.ctx.logger, getProviders, locationStore, this.ctx.kernel.localNodeId ?? "hub", (nodeId) => {
|
|
933
986
|
const proxy = this.ctx.kernel.resolveNodeCapability?.("storage-provider", nodeId);
|
|
@@ -1119,6 +1172,9 @@ var StorageOrchestratorAddon = class extends BaseAddon {
|
|
|
1119
1172
|
return [{
|
|
1120
1173
|
capability: storageCapability,
|
|
1121
1174
|
provider
|
|
1175
|
+
}, {
|
|
1176
|
+
capability: settingsStoreCapability,
|
|
1177
|
+
provider: createDataStoreDispatch(getEngines)
|
|
1122
1178
|
}];
|
|
1123
1179
|
}
|
|
1124
1180
|
async onShutdown() {
|
|
@@ -1135,18 +1191,29 @@ var StorageOrchestratorAddon = class extends BaseAddon {
|
|
|
1135
1191
|
this.service = null;
|
|
1136
1192
|
}
|
|
1137
1193
|
/**
|
|
1138
|
-
* Resolve the live
|
|
1139
|
-
*
|
|
1140
|
-
*
|
|
1141
|
-
*
|
|
1142
|
-
*
|
|
1194
|
+
* Resolve the live engine from the capability registry and wrap it in a
|
|
1195
|
+
* `SqliteLocationStore`. Returns `null` when no engine has registered
|
|
1196
|
+
* yet — the service falls back to in-memory only. Production boot order
|
|
1197
|
+
* (`data-store-provider` precedes `storage` in `INFRA_CAPABILITIES`)
|
|
1198
|
+
* makes this the rare path.
|
|
1199
|
+
*
|
|
1200
|
+
* Reads the ENGINE, not the `settings-store` singleton: since D44 this
|
|
1201
|
+
* addon *is* that singleton, so asking the registry for it would hand
|
|
1202
|
+
* the orchestrator its own dispatcher and route its location table back
|
|
1203
|
+
* through itself.
|
|
1204
|
+
*
|
|
1205
|
+
* The `ensureTable` / `tableInsert` reach-around below is the B2 bypass,
|
|
1206
|
+
* still open: those six methods live on the concrete backend and on no
|
|
1207
|
+
* cap. Promoting them to the door is a separate task; until then this
|
|
1208
|
+
* holds the engine object directly, which only works because the engine
|
|
1209
|
+
* is in-process on this node.
|
|
1143
1210
|
*/
|
|
1144
1211
|
resolveLocationStore(quiet = false) {
|
|
1145
1212
|
const reg = this.ctx.kernel.capabilityRegistry;
|
|
1146
1213
|
if (!reg) return null;
|
|
1147
|
-
const backend = reg.
|
|
1214
|
+
const backend = reg.getCollection(DATA_STORE_PROVIDER_CAP_NAME)[0];
|
|
1148
1215
|
if (!backend) {
|
|
1149
|
-
if (!quiet) this.ctx.logger.warn("storage-orchestrator: no
|
|
1216
|
+
if (!quiet) this.ctx.logger.warn("storage-orchestrator: no data-store-provider engine yet — running in-memory until one registers");
|
|
1150
1217
|
return null;
|
|
1151
1218
|
}
|
|
1152
1219
|
if (!backend.ensureTable || !backend.tableInsert) {
|
|
@@ -1156,8 +1223,8 @@ var StorageOrchestratorAddon = class extends BaseAddon {
|
|
|
1156
1223
|
return new SqliteLocationStore(backend);
|
|
1157
1224
|
}
|
|
1158
1225
|
/**
|
|
1159
|
-
* Late-wire the persistence store once
|
|
1160
|
-
* Production boot order means the store is usually absent at
|
|
1226
|
+
* Late-wire the persistence store once a `data-store-provider` engine
|
|
1227
|
+
* registers. Production boot order means the store is usually absent at
|
|
1161
1228
|
* `onInitialize`; this runs on every `capability:provider-registered`
|
|
1162
1229
|
* event until it succeeds. Single-flighted + idempotent (the service
|
|
1163
1230
|
* ignores a second attach). Without this, operator edits (e.g. a
|
|
@@ -1171,7 +1238,7 @@ var StorageOrchestratorAddon = class extends BaseAddon {
|
|
|
1171
1238
|
if (this.storeWireInFlight) return this.storeWireInFlight;
|
|
1172
1239
|
const store = this.resolveLocationStore(true);
|
|
1173
1240
|
if (!store) return;
|
|
1174
|
-
this.ctx.logger.info("storage-orchestrator:
|
|
1241
|
+
this.ctx.logger.info("storage-orchestrator: data-store engine now available — wiring persistence");
|
|
1175
1242
|
this.storeWireInFlight = service.attachStore(store).then(() => this.seedFromDeclarations()).catch((err) => {
|
|
1176
1243
|
this.ctx.logger.error("storage-orchestrator: attachStore failed", { meta: { error: err instanceof Error ? err.message : String(err) } });
|
|
1177
1244
|
}).finally(() => {
|
|
@@ -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-CPmFYLqq.js");
|
|
7
7
|
//#region src/builtins/system-config/system-config.addon.ts
|
|
8
8
|
/**
|
|
9
9
|
* Built-in `system-config` addon — Phase 4 of the settings redesign.
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { Ct as hydrateSchema, at as errMsg, ot as BaseAddon } from "../../dist-B7hOpr5i.mjs";
|
|
2
2
|
//#region src/builtins/system-config/system-config.addon.ts
|
|
3
3
|
/**
|
|
4
4
|
* Built-in `system-config` addon — Phase 4 of the settings redesign.
|
|
@@ -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-CPmFYLqq.js");
|
|
7
7
|
const require_formatter = require("../../formatter-DqAKDlvN.js");
|
|
8
8
|
let node_path = require("node:path");
|
|
9
9
|
node_path = require_chunk.__toESM(node_path);
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { B as logDestinationCapability, ot as BaseAddon } from "../../dist-B7hOpr5i.mjs";
|
|
2
2
|
import { t as formatLogLine } from "../../formatter-B7qW8bPJ.mjs";
|
|
3
3
|
import * as path$1 from "node:path";
|
|
4
4
|
import path from "node:path";
|