@camstack/server 1.2.34 → 1.2.36
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.
|
@@ -2261,11 +2261,41 @@ class AddonRegistryService {
|
|
|
2261
2261
|
if (!provider)
|
|
2262
2262
|
return;
|
|
2263
2263
|
this.activeSettingsBackend = provider;
|
|
2264
|
-
|
|
2265
|
-
|
|
2264
|
+
// ConfigManager needs the SYNC legacy surface (`getAllAddon`,
|
|
2265
|
+
// `setAddonDevice`, …), which is not part of the cap. Since D44 the
|
|
2266
|
+
// `settings-store` provider is the storage-orchestrator's
|
|
2267
|
+
// DISPATCHER, and a dispatcher has none of those methods — so this
|
|
2268
|
+
// predicate started returning false and ConfigManager was left
|
|
2269
|
+
// without a store. Nothing said so: `readAddonStore()` then answered
|
|
2270
|
+
// `{}` for every addon, device-manager restored ZERO devices, and no
|
|
2271
|
+
// camera published a stream. Fall back to the ENGINE behind the door
|
|
2272
|
+
// (`data-store-provider` — the SQLite backend does implement both
|
|
2273
|
+
// surfaces), the same move `storage-orchestrator` makes for its
|
|
2274
|
+
// location store. And if neither can serve it, SAY SO: this is the
|
|
2275
|
+
// branch whose silence cost an evening.
|
|
2276
|
+
const syncStore = isSettingsStore(provider)
|
|
2277
|
+
? provider
|
|
2278
|
+
: this.capabilityRegistry
|
|
2279
|
+
.getCollection('data-store-provider')
|
|
2280
|
+
.find((engine) => isSettingsStore(engine));
|
|
2281
|
+
if (syncStore) {
|
|
2282
|
+
this.configService.setSettingsStore(syncStore);
|
|
2283
|
+
}
|
|
2284
|
+
else {
|
|
2285
|
+
this.logger.error('settings-store provider does not implement the sync ConfigManager surface and no data-store-provider engine does either — every addon store reads empty, devices will NOT be restored', { meta: { addonId, phase: 'v2' } });
|
|
2266
2286
|
}
|
|
2267
2287
|
this.storageService.setSettingsBackend(provider);
|
|
2268
|
-
|
|
2288
|
+
// The registry needs the DOOR's own shape, not `ISettingsBackend`.
|
|
2289
|
+
// `CapabilityProviderMap` still types this cap as the hand-written
|
|
2290
|
+
// interface, which has drifted from the cap definition it is meant
|
|
2291
|
+
// to describe — it never grew `deleteWhere` / `updateWhere`. The
|
|
2292
|
+
// same provider object satisfies both; reconciling the two types is
|
|
2293
|
+
// its own change (it makes `query` / `insert` non-generic for every
|
|
2294
|
+
// `ISettingsBackend` consumer in the backend).
|
|
2295
|
+
const store = this.capabilityRegistry.getProviderByAddon('settings-store', addonId);
|
|
2296
|
+
if (!store)
|
|
2297
|
+
return;
|
|
2298
|
+
this.integrationRegistry = new system_4.IntegrationRegistry(store);
|
|
2269
2299
|
void this.integrationRegistry.initialize().then(() => {
|
|
2270
2300
|
this.logger.info('IntegrationRegistry initialized', { meta: { phase: 'v2' } });
|
|
2271
2301
|
});
|
package/dist/launcher.js
CHANGED
|
@@ -413,6 +413,28 @@ async function launch() {
|
|
|
413
413
|
Module._initPaths();
|
|
414
414
|
console.log(`[launcher] NODE_PATH extended with: ${extraNodePaths.join(sep)}`);
|
|
415
415
|
}
|
|
416
|
+
// WHICH COPY did this node just commit to? ([D45](../../../docs/decisions/adr-0045.md))
|
|
417
|
+
//
|
|
418
|
+
// A node can hold several copies of a host-provided package — the image seed
|
|
419
|
+
// under /opt, a legacy /data/framework on NODE_PATH, the active closure, an
|
|
420
|
+
// installed copy under /data/addons. Which one wins is a resolution outcome,
|
|
421
|
+
// and on 2026-08-03 three consecutive deductions about it were each disproved
|
|
422
|
+
// by the next measurement, while every status surface reported the version of
|
|
423
|
+
// a copy nobody was running. Resolution happens HERE, right after NODE_PATH
|
|
424
|
+
// is final and before the runtime imports anything — so this is the one place
|
|
425
|
+
// that can answer it, and it costs a stat call per package.
|
|
426
|
+
//
|
|
427
|
+
// A version number without a path is not evidence. Log both.
|
|
428
|
+
for (const pkg of ['@camstack/system', '@camstack/types']) {
|
|
429
|
+
try {
|
|
430
|
+
const resolved = require.resolve(`${pkg}/package.json`);
|
|
431
|
+
const version = JSON.parse(fs.readFileSync(resolved, 'utf-8')).version;
|
|
432
|
+
console.log(`[launcher] resolved ${pkg}@${String(version)} from ${resolved}`);
|
|
433
|
+
}
|
|
434
|
+
catch (err) {
|
|
435
|
+
console.warn(`[launcher] could NOT resolve ${pkg}: ${err instanceof Error ? err.message : String(err)}`);
|
|
436
|
+
}
|
|
437
|
+
}
|
|
416
438
|
// Now safe to load the role's runtime entry (both have static imports from
|
|
417
439
|
// @camstack/system, resolved only after the framework dir + NODE_PATH setup
|
|
418
440
|
// above). The agent boots from THIS same @camstack/server closure — there is
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@camstack/server",
|
|
3
|
-
"version": "1.2.
|
|
3
|
+
"version": "1.2.36",
|
|
4
4
|
"private": false,
|
|
5
5
|
"files": [
|
|
6
6
|
"dist",
|
|
@@ -40,11 +40,11 @@
|
|
|
40
40
|
"@camstack/addon-notifiers": "1.2.11",
|
|
41
41
|
"@camstack/addon-pipeline": "1.2.39",
|
|
42
42
|
"@camstack/addon-pipeline-orchestrator": "1.2.19",
|
|
43
|
-
"@camstack/addon-post-analysis": "1.2.
|
|
43
|
+
"@camstack/addon-post-analysis": "1.2.24",
|
|
44
44
|
"@camstack/sdk": "1.2.9",
|
|
45
45
|
"@camstack/shm-ring": "1.1.9",
|
|
46
|
-
"@camstack/system": "1.2.
|
|
47
|
-
"@camstack/types": "1.2.
|
|
46
|
+
"@camstack/system": "1.2.31",
|
|
47
|
+
"@camstack/types": "1.2.23",
|
|
48
48
|
"@camstack/ui-library": "1.2.18",
|
|
49
49
|
"@fastify/compress": "^9.0.0",
|
|
50
50
|
"@fastify/cookie": "^11.0.2",
|