@camstack/system 1.2.461 → 1.2.463
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 +21 -276
- package/dist/addon-runner.mjs +21 -276
- package/dist/{agent-https-Iw3RSQup.mjs → agent-https-B9gbXoJI.mjs} +1 -1
- package/dist/{agent-https-Dnr_nIVx.js → agent-https-DhFIbEwN.js} +1 -1
- 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 +1 -1
- package/dist/builtins/alerts/alerts.addon.mjs +1 -1
- package/dist/builtins/autotrack/index.js +1 -1
- package/dist/builtins/autotrack/index.mjs +1 -1
- package/dist/builtins/backup-orchestrator/backup-orchestrator.addon.d.ts +1 -3
- package/dist/builtins/backup-orchestrator/backup-orchestrator.addon.js +51 -502
- package/dist/builtins/backup-orchestrator/backup-orchestrator.addon.mjs +51 -502
- package/dist/builtins/backup-orchestrator/destination-policy.d.ts +5 -21
- package/dist/builtins/backup-orchestrator/record-kinds.d.ts +0 -2
- package/dist/builtins/backup-orchestrator/schedule-store.d.ts +5 -13
- package/dist/builtins/backup-orchestrator/seed-marker-store.d.ts +9 -19
- 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/cluster-agent/record-kinds.d.ts +0 -1
- package/dist/builtins/composer/composer.addon.js +2 -2
- package/dist/builtins/composer/composer.addon.mjs +2 -2
- package/dist/builtins/console-logging/index.js +1 -1
- package/dist/builtins/console-logging/index.mjs +1 -1
- 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/device-history.addon.js +1 -1
- package/dist/builtins/device-history/device-history.addon.mjs +1 -1
- package/dist/builtins/device-manager/device-manager.addon.js +2 -2
- package/dist/builtins/device-manager/device-manager.addon.mjs +2 -2
- package/dist/builtins/hub-forwarder/index.js +1 -1
- package/dist/builtins/hub-forwarder/index.mjs +1 -1
- package/dist/builtins/keychain/index.js +3 -3
- package/dist/builtins/keychain/index.mjs +3 -3
- 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/auth-schema.d.ts +2 -12
- package/dist/builtins/local-auth/local-auth.addon.js +52 -191
- package/dist/builtins/local-auth/local-auth.addon.mjs +52 -191
- package/dist/builtins/local-auth/oauth-session-manager.d.ts +13 -4
- package/dist/builtins/local-auth/record-kinds.d.ts +1 -1
- 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 +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/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/file-host-protocol.d.ts +0 -9
- 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/owned-sqlite-file.d.ts +0 -8
- package/dist/builtins/sqlite-storage/records/records-sql.d.ts +0 -2
- package/dist/builtins/sqlite-storage/sqlite-settings-backend.d.ts +0 -28
- package/dist/builtins/sqlite-storage/sqlite-settings.addon.d.ts +1 -2
- package/dist/builtins/sqlite-storage/sqlite-settings.addon.js +6 -170
- package/dist/builtins/sqlite-storage/sqlite-settings.addon.mjs +6 -170
- package/dist/builtins/sqlite-storage/storage-admin-provider.d.ts +3 -17
- package/dist/builtins/storage-orchestrator/storage-orchestrator.addon.js +1 -1
- package/dist/builtins/storage-orchestrator/storage-orchestrator.addon.mjs +1 -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 +1 -1
- package/dist/builtins/winston-logging/index.mjs +1 -1
- package/dist/{composition-sources-DNRZWR1j.mjs → composition-sources-CGtooHSL.mjs} +1 -1
- package/dist/{composition-sources-b0e_2I-D.js → composition-sources-oXvmbMHX.js} +1 -1
- package/dist/{constants-6OeJiZgi.js → constants-5mrGZxwS.js} +1 -1
- package/dist/{constants-BnkOdj9Q.mjs → constants-CdutnpL9.mjs} +1 -1
- package/dist/{device-ca-CPTDs--d.js → device-ca-B3xUzps7.js} +1 -1
- package/dist/{device-ca-Bnkw8GyU.mjs → device-ca-DZHKlZlD.mjs} +1 -1
- package/dist/{dist-Wy8cTxg6.mjs → dist-C2OBCa-A.mjs} +40 -80
- package/dist/{dist-Bn-RNanh.js → dist-D9aw_d0G.js} +39 -91
- package/dist/file-host-worker.js +1 -1
- package/dist/file-host-worker.mjs +1 -1
- package/dist/{hub-mdns-ciao-CJu0nhla.mjs → hub-mdns-ciao-Bm09NrMS.mjs} +2 -2
- package/dist/{hub-mdns-ciao-CTBTlia4.js → hub-mdns-ciao-CFlhVKK6.js} +2 -2
- package/dist/index.d.ts +1 -1
- package/dist/index.js +88 -240
- package/dist/index.mjs +89 -236
- package/dist/kernel/index.d.ts +0 -1
- package/dist/kernel/moleculer/runner-addon-settings.d.ts +1 -6
- package/dist/kernel/moleculer/runner-device-settings.d.ts +2 -2
- package/dist/{restore-archive-DM1OBYq4.js → restore-archive-6zkRREHO.js} +1 -1
- package/dist/{restore-archive-CM23Pq9B.mjs → restore-archive-CSOR_tyN.mjs} +1 -1
- package/dist/{retired-settings-keys-D_VwZiDt.js → retired-settings-keys-CGUqX-Oz.js} +0 -6
- package/dist/{retired-settings-keys-Bhwe4ymb.mjs → retired-settings-keys-C_Kjp-Bj.mjs} +1 -1
- package/dist/{wal-maintenance-Bj_MmDkr.mjs → wal-maintenance-Dg6IzSgz.mjs} +0 -0
- package/dist/{wal-maintenance-CaJjuLHq.js → wal-maintenance-jXcOxm2T.js} +0 -0
- package/package.json +1 -1
- package/dist/builtins/sqlite-storage/retired-collections.d.ts +0 -146
- package/dist/kernel/legacy-blob-guard.d.ts +0 -63
package/dist/addon-runner.js
CHANGED
|
@@ -104,7 +104,7 @@ function refusalReportOf(addonId, err) {
|
|
|
104
104
|
}
|
|
105
105
|
//#endregion
|
|
106
106
|
//#region src/kernel/addon-class-resolver.ts
|
|
107
|
-
function isRecord$
|
|
107
|
+
function isRecord$4(value) {
|
|
108
108
|
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
109
109
|
}
|
|
110
110
|
/**
|
|
@@ -128,14 +128,14 @@ function isRecord$5(value) {
|
|
|
128
128
|
function isAddonConstructor(fn) {
|
|
129
129
|
if (typeof fn !== "function") return false;
|
|
130
130
|
const proto = fn.prototype;
|
|
131
|
-
if (!isRecord$
|
|
131
|
+
if (!isRecord$4(proto)) return false;
|
|
132
132
|
return typeof proto["initialize"] === "function";
|
|
133
133
|
}
|
|
134
134
|
function resolveAddonClass(mod) {
|
|
135
135
|
let candidate = mod["default"];
|
|
136
|
-
if (isRecord$
|
|
136
|
+
if (isRecord$4(candidate) && "default" in candidate) candidate = candidate["default"];
|
|
137
137
|
if (isAddonConstructor(candidate)) return candidate;
|
|
138
|
-
if (isRecord$
|
|
138
|
+
if (isRecord$4(candidate)) {
|
|
139
139
|
const fn = Object.values(candidate).find(isAddonConstructor);
|
|
140
140
|
if (fn) return fn;
|
|
141
141
|
}
|
|
@@ -5538,7 +5538,7 @@ var RuntimeStateLoadError = class extends Error {
|
|
|
5538
5538
|
this.name = "RuntimeStateLoadError";
|
|
5539
5539
|
}
|
|
5540
5540
|
};
|
|
5541
|
-
function isRecord$
|
|
5541
|
+
function isRecord$3(value) {
|
|
5542
5542
|
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
5543
5543
|
}
|
|
5544
5544
|
function errorMessage(err) {
|
|
@@ -5569,7 +5569,7 @@ async function loadRuntimeStateOrRefuse(load, logger, target) {
|
|
|
5569
5569
|
} catch (err) {
|
|
5570
5570
|
return refuse(errorMessage(err), err);
|
|
5571
5571
|
}
|
|
5572
|
-
if (!isRecord$
|
|
5572
|
+
if (!isRecord$3(answer)) return refuse(`answered ${answer === null ? "null" : typeof answer}`);
|
|
5573
5573
|
return answer;
|
|
5574
5574
|
}
|
|
5575
5575
|
//#endregion
|
|
@@ -9692,11 +9692,11 @@ function prefixRange(prefix) {
|
|
|
9692
9692
|
}
|
|
9693
9693
|
//#endregion
|
|
9694
9694
|
//#region src/kernel/prefix-walk.ts
|
|
9695
|
-
function isRecord$
|
|
9695
|
+
function isRecord$2(value) {
|
|
9696
9696
|
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
9697
9697
|
}
|
|
9698
9698
|
function unwrapStoredValue(parsed) {
|
|
9699
|
-
if (!isRecord$
|
|
9699
|
+
if (!isRecord$2(parsed) || !("value" in parsed)) return parsed;
|
|
9700
9700
|
return parsed.value;
|
|
9701
9701
|
}
|
|
9702
9702
|
/**
|
|
@@ -10041,7 +10041,7 @@ function createSectionsStore(door) {
|
|
|
10041
10041
|
//#endregion
|
|
10042
10042
|
//#region src/kernel/moleculer/runner-addon-settings.ts
|
|
10043
10043
|
/** @param client the hub's `settingsStore` client; `undefined` makes every call THROW. */
|
|
10044
|
-
function createRunnerAddonSettings(client, addonId
|
|
10044
|
+
function createRunnerAddonSettings(client, addonId) {
|
|
10045
10045
|
if (client === void 0) {
|
|
10046
10046
|
const refuse = async () => {
|
|
10047
10047
|
throw new Error(`settings of "${addonId}": settings store not wired`);
|
|
@@ -10063,22 +10063,10 @@ function createRunnerAddonSettings(client, addonId, before = async () => {}) {
|
|
|
10063
10063
|
};
|
|
10064
10064
|
}
|
|
10065
10065
|
const door = {
|
|
10066
|
-
query:
|
|
10067
|
-
|
|
10068
|
-
|
|
10069
|
-
|
|
10070
|
-
get: async (input) => {
|
|
10071
|
-
await before();
|
|
10072
|
-
return client.get.query(input);
|
|
10073
|
-
},
|
|
10074
|
-
set: async (input) => {
|
|
10075
|
-
await before();
|
|
10076
|
-
return client.set.mutate(input);
|
|
10077
|
-
},
|
|
10078
|
-
transact: async (input) => {
|
|
10079
|
-
await before();
|
|
10080
|
-
return client.transact.mutate(input);
|
|
10081
|
-
}
|
|
10066
|
+
query: (input) => client.query.query(input),
|
|
10067
|
+
get: (input) => client.get.query(input),
|
|
10068
|
+
set: (input) => client.set.mutate(input),
|
|
10069
|
+
transact: (input) => client.transact.mutate(input)
|
|
10082
10070
|
};
|
|
10083
10071
|
const store = createAddonSettingsStore(door, addonId);
|
|
10084
10072
|
const sections = createSectionsStore(door);
|
|
@@ -10119,226 +10107,6 @@ function createRunnerAddonSettings(client, addonId, before = async () => {}) {
|
|
|
10119
10107
|
};
|
|
10120
10108
|
}
|
|
10121
10109
|
//#endregion
|
|
10122
|
-
//#region src/builtins/sqlite-storage/retired-settings-keys.ts
|
|
10123
|
-
/**
|
|
10124
|
-
* The dead keys, per row.
|
|
10125
|
-
*
|
|
10126
|
-
* ## Addressing these rows
|
|
10127
|
-
*
|
|
10128
|
-
* Every namespace below is a FORKED addon, whose `ctx.settings` comes from
|
|
10129
|
-
* `addon-context-factory` and writes `<addonId>:addon-settings` row `root`. The
|
|
10130
|
-
* scoped table is therefore the right target — unlike the hub builtin whose
|
|
10131
|
-
* mis-addressed spec is dissected at {@link RetiredRowSpec}. Confirmed per
|
|
10132
|
-
* namespace against `packages/<pkg>/package.json`'s manifest `id`.
|
|
10133
|
-
*
|
|
10134
|
-
* ## `keys` vs `perNodeKeys` is a data-loss decision, not a style choice
|
|
10135
|
-
*
|
|
10136
|
-
* `perNodeKeys` matches `<key>` AND `<key>@<nodeId>`. That is right for a key
|
|
10137
|
-
* whose per-node copies are all dead (the engine cascade, the decoder
|
|
10138
|
-
* `backend`). It is WRONG for `probedBestHwaccel` / `probedBestAudioBackend`,
|
|
10139
|
-
* where the bare key is unreachable residue but every `@<nodeId>` copy is the
|
|
10140
|
-
* node's live probe result — those go under `keys`, which is exact-match.
|
|
10141
|
-
*
|
|
10142
|
-
* `detection-pipeline` / `addon-settings` / `root` — every key in this row is
|
|
10143
|
-
* dead; the row itself is kept because the addon writes a live key into it
|
|
10144
|
-
* (`videoPipelineSteps`). `pipelineTemplates` is no longer read or written
|
|
10145
|
-
* (templates were removed, D759) and is deliberately NOT listed here: stored
|
|
10146
|
-
* template rows are left exactly as they are.
|
|
10147
|
-
*
|
|
10148
|
-
* - `pipelineSteps` / `pipelineEngine`: the persisted GLOBAL step + engine
|
|
10149
|
-
* seed. Removed with `getGlobalSteps` becoming pure — dispatch builds steps
|
|
10150
|
-
* from the orchestrator's `agentSettings` plus per-camera overrides, and
|
|
10151
|
-
* never consulted the seed. See `addon-pipeline/src/detection-pipeline/provider.ts`.
|
|
10152
|
-
* - `engineRuntime` / `engineBackend` / `engineDevice` / `probedBestEngine`:
|
|
10153
|
-
* the per-node engine CASCADE, removed with the operator-facing engine
|
|
10154
|
-
* election. Each node now runs a device-array of inference pools balanced
|
|
10155
|
-
* per session, and the node-default pool derives live from the node's own
|
|
10156
|
-
* hardware (`resolveAutoEngine`). See
|
|
10157
|
-
* `addon-pipeline/src/detection-pipeline/engine-store-keys.ts`.
|
|
10158
|
-
*/
|
|
10159
|
-
var RETIRED_SETTINGS_KEYS = [
|
|
10160
|
-
{
|
|
10161
|
-
namespace: "detection-pipeline",
|
|
10162
|
-
collection: "addon-settings",
|
|
10163
|
-
row: "root",
|
|
10164
|
-
keys: ["pipelineSteps", "pipelineEngine"],
|
|
10165
|
-
perNodeKeys: [
|
|
10166
|
-
"engineRuntime",
|
|
10167
|
-
"engineBackend",
|
|
10168
|
-
"engineDevice",
|
|
10169
|
-
"probedBestEngine"
|
|
10170
|
-
],
|
|
10171
|
-
reason: "global step/engine seed and the per-node engine cascade — both removed; the live per-camera dispatch path never read either"
|
|
10172
|
-
},
|
|
10173
|
-
{
|
|
10174
|
-
namespace: "pipeline-orchestrator",
|
|
10175
|
-
collection: "addon-settings",
|
|
10176
|
-
row: "root",
|
|
10177
|
-
keys: [
|
|
10178
|
-
"enabledNodes",
|
|
10179
|
-
"enabledDecoderNodes",
|
|
10180
|
-
"enabledAudioNodes",
|
|
10181
|
-
"remoteSourcingNodes",
|
|
10182
|
-
"nativeLeaseTtlMs"
|
|
10183
|
-
],
|
|
10184
|
-
perNodeKeys: ["backend"],
|
|
10185
|
-
reason: "the pre-singleton \"enabled nodes\" role model (node capability now lives per node in agent-settings and is derived by NodeTopology.refresh, never read from this row), `nativeLeaseTtlMs` superseded by `nativeLeaseActivityMs`, and the decoder `backend` selector whose resolver returns DEFAULT_DECODER_BACKEND unconditionally (decoder-backend.ts)"
|
|
10186
|
-
},
|
|
10187
|
-
{
|
|
10188
|
-
namespace: "stream-broker",
|
|
10189
|
-
collection: "addon-settings",
|
|
10190
|
-
row: "root",
|
|
10191
|
-
keys: [
|
|
10192
|
-
"maxDecodeFps",
|
|
10193
|
-
"initialReconnectDelayMs",
|
|
10194
|
-
"maxReconnectDelayMs"
|
|
10195
|
-
],
|
|
10196
|
-
perNodeKeys: [],
|
|
10197
|
-
reason: "three form knobs deleted 2026-08-28 (D272): nothing capped decode fps, and the reconnect ladder has always run on the INITIAL/MAX_RECONNECT_DELAY_MS constants"
|
|
10198
|
-
},
|
|
10199
|
-
{
|
|
10200
|
-
namespace: "embedding-encoder",
|
|
10201
|
-
collection: "addon-settings",
|
|
10202
|
-
row: "root",
|
|
10203
|
-
keys: ["runtime", "backend"],
|
|
10204
|
-
perNodeKeys: [],
|
|
10205
|
-
reason: "two selects deleted 2026-08-28 (D272); their only reference was a withTags log field, and the CUDA/CoreML options named acceleration that has never existed — embedding inference is always ONNX in the embedded Python"
|
|
10206
|
-
},
|
|
10207
|
-
{
|
|
10208
|
-
namespace: "audio-analyzer",
|
|
10209
|
-
collection: "addon-settings",
|
|
10210
|
-
row: "root",
|
|
10211
|
-
keys: ["selectedAudioModel", "probedBestAudioBackend"],
|
|
10212
|
-
perNodeKeys: [],
|
|
10213
|
-
reason: "`selectedAudioModel` deleted 2026-08-28 (D272) — createAudioPipeline takes a backend and no model id, so it never reached inference; the BARE `probedBestAudioBackend` is pre-perNode residue that projectStore already drops (no bare fallback), so no node can ever read it"
|
|
10214
|
-
},
|
|
10215
|
-
{
|
|
10216
|
-
namespace: "decoder-nodeav",
|
|
10217
|
-
collection: "addon-settings",
|
|
10218
|
-
row: "root",
|
|
10219
|
-
keys: ["probedBestHwaccel"],
|
|
10220
|
-
perNodeKeys: [],
|
|
10221
|
-
reason: "bare pre-perNode residue — the live probe result is `probedBestHwaccel@<nodeId>` and `projectStore` deliberately drops the bare key, so nothing can read it"
|
|
10222
|
-
},
|
|
10223
|
-
{
|
|
10224
|
-
namespace: "pipeline-analytics",
|
|
10225
|
-
collection: "addon-settings",
|
|
10226
|
-
row: "root",
|
|
10227
|
-
keys: ["mediaAttachPolicy"],
|
|
10228
|
-
perNodeKeys: [],
|
|
10229
|
-
reason: "deleted 2026-08-28 (D272) — absent from MediaSettingsSchema, so the value was never even resolved, let alone read"
|
|
10230
|
-
}
|
|
10231
|
-
];
|
|
10232
|
-
//#endregion
|
|
10233
|
-
//#region src/kernel/legacy-blob-guard.ts
|
|
10234
|
-
/** Root keys retired long before D870: they never count as "settings still to migrate". */
|
|
10235
|
-
var OWN_RETIRED_ROOT_KEYS = new Set([
|
|
10236
|
-
"recordingConfigs",
|
|
10237
|
-
"recordingExports",
|
|
10238
|
-
"recordingOpsLog",
|
|
10239
|
-
"probeSnapshots",
|
|
10240
|
-
"rtspTokens",
|
|
10241
|
-
"profileMap"
|
|
10242
|
-
]);
|
|
10243
|
-
/** Is `key` of `addonId` a root key that was retired (and must not be migrated)? */
|
|
10244
|
-
function isRetiredRootKey(addonId, key) {
|
|
10245
|
-
if (OWN_RETIRED_ROOT_KEYS.has(key)) return true;
|
|
10246
|
-
return RETIRED_SETTINGS_KEYS.some((spec) => spec.namespace === addonId && (spec.keys.includes(key) || spec.perNodeKeys.some((k) => key === k || key.startsWith(`${k}@`))));
|
|
10247
|
-
}
|
|
10248
|
-
/** Stable `code` of the D870 refusal. */
|
|
10249
|
-
var UNMIGRATED_SETTINGS_CODE = "unmigrated-settings";
|
|
10250
|
-
/** The remedy the refusal (and the update pre-flight) names. */
|
|
10251
|
-
var UNMIGRATED_SETTINGS_REMEDY = "Run scripts/hub/migrate-device-store.ts --copy --apply (D870), then restart the addon.";
|
|
10252
|
-
var UnmigratedSettingsError = class extends AddonRefusedError {
|
|
10253
|
-
constructor(addonId, what) {
|
|
10254
|
-
super(UNMIGRATED_SETTINGS_CODE, `addon "${addonId}" refuses to start: ${what} - the settings it had are still in the per-addon tables and the standard store holds none. Run scripts/hub/migrate-device-store.ts --copy --apply (D870) before starting it.`, UNMIGRATED_SETTINGS_REMEDY);
|
|
10255
|
-
this.name = "UnmigratedSettingsError";
|
|
10256
|
-
}
|
|
10257
|
-
};
|
|
10258
|
-
async function countOf(client, input) {
|
|
10259
|
-
const n = await client.count.query(input);
|
|
10260
|
-
if (typeof n !== "number") throw new Error("settings store answered a non-number to a count");
|
|
10261
|
-
return n;
|
|
10262
|
-
}
|
|
10263
|
-
var LEGACY_PAGE = 500;
|
|
10264
|
-
var LEGACY_PAGE_BUDGET = 200;
|
|
10265
|
-
var ID_TAIL = "";
|
|
10266
|
-
function isRecord$2(value) {
|
|
10267
|
-
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
10268
|
-
}
|
|
10269
|
-
/**
|
|
10270
|
-
* Does the addon's per-device blob table hold a row the copy would actually
|
|
10271
|
-
* migrate - a positive numeric id with a non-empty record? An addon whose rows
|
|
10272
|
-
* the copy skips anyway must not be refused for them.
|
|
10273
|
-
*/
|
|
10274
|
-
async function hasMigratableDeviceRow(client, addonId) {
|
|
10275
|
-
let cursor = "";
|
|
10276
|
-
for (let page = 0; page < LEGACY_PAGE_BUDGET; page++) {
|
|
10277
|
-
const rows = await client.query.query({
|
|
10278
|
-
namespace: addonId,
|
|
10279
|
-
collection: "addon-devices",
|
|
10280
|
-
filter: {
|
|
10281
|
-
whereBetween: { id: [cursor, ID_TAIL] },
|
|
10282
|
-
orderBy: {
|
|
10283
|
-
field: "id",
|
|
10284
|
-
direction: "asc"
|
|
10285
|
-
},
|
|
10286
|
-
limit: LEGACY_PAGE
|
|
10287
|
-
}
|
|
10288
|
-
});
|
|
10289
|
-
if (!Array.isArray(rows)) throw new Error("settings store answered a non-list to a query");
|
|
10290
|
-
let lastId = cursor;
|
|
10291
|
-
for (const row of rows) {
|
|
10292
|
-
if (!isRecord$2(row) || typeof row["id"] !== "string") continue;
|
|
10293
|
-
lastId = row["id"];
|
|
10294
|
-
const id = Number(row["id"]);
|
|
10295
|
-
const data = row["data"];
|
|
10296
|
-
if (Number.isInteger(id) && id > 0 && isRecord$2(data) && Object.keys(data).length > 0) return true;
|
|
10297
|
-
}
|
|
10298
|
-
if (rows.length < LEGACY_PAGE || lastId === cursor) return false;
|
|
10299
|
-
cursor = lastId;
|
|
10300
|
-
}
|
|
10301
|
-
throw new Error(`addon "${addonId}": more legacy blob pages than the guard will read`);
|
|
10302
|
-
}
|
|
10303
|
-
/**
|
|
10304
|
-
* THROWS when the addon has blob settings and the standard store has none of
|
|
10305
|
-
* its own. A store that cannot be asked also throws: it is not "no blobs".
|
|
10306
|
-
*/
|
|
10307
|
-
async function assertLegacyBlobsMigrated(client, addonId, logger) {
|
|
10308
|
-
const legacyDevices = await hasMigratableDeviceRow(client, addonId);
|
|
10309
|
-
const root = await client.get.query({
|
|
10310
|
-
namespace: addonId,
|
|
10311
|
-
collection: "addon-settings",
|
|
10312
|
-
key: "root"
|
|
10313
|
-
});
|
|
10314
|
-
const legacySettings = isRecord$2(root) && Object.keys(root).some((key) => !isRetiredRootKey(addonId, key));
|
|
10315
|
-
if (!legacyDevices && !legacySettings) return;
|
|
10316
|
-
const rangeOf = (prefix) => {
|
|
10317
|
-
const range = prefixRange(prefix);
|
|
10318
|
-
if (range === null) throw new Error(`no id range for addon "${addonId}"`);
|
|
10319
|
-
return { whereBetween: { id: [range.lo, range.hi] } };
|
|
10320
|
-
};
|
|
10321
|
-
const newDevices = await countOf(client, {
|
|
10322
|
-
collection: "addon-device-settings",
|
|
10323
|
-
filter: rangeOf(`${addonId}:`)
|
|
10324
|
-
});
|
|
10325
|
-
const newSettings = await countOf(client, {
|
|
10326
|
-
collection: "addon-settings",
|
|
10327
|
-
filter: rangeOf(`${addonId}.`)
|
|
10328
|
-
});
|
|
10329
|
-
const problems = [];
|
|
10330
|
-
if (legacyDevices && newDevices === 0) problems.push("per-device blobs");
|
|
10331
|
-
if (legacySettings && newSettings === 0) problems.push("an addon settings blob");
|
|
10332
|
-
if (problems.length === 0) return;
|
|
10333
|
-
const error = new UnmigratedSettingsError(addonId, problems.join(" and "));
|
|
10334
|
-
logger.error(error.message, { meta: {
|
|
10335
|
-
addonId,
|
|
10336
|
-
newDevices,
|
|
10337
|
-
newSettings
|
|
10338
|
-
} });
|
|
10339
|
-
throw error;
|
|
10340
|
-
}
|
|
10341
|
-
//#endregion
|
|
10342
10110
|
//#region src/kernel/moleculer/runner-device-settings.ts
|
|
10343
10111
|
/**
|
|
10344
10112
|
* The forked runner's `ctx.settings` device methods (D870).
|
|
@@ -10351,20 +10119,11 @@ async function assertLegacyBlobsMigrated(client, addonId, logger) {
|
|
|
10351
10119
|
* blob per device; a hub-side write to the rows was invisible to it.
|
|
10352
10120
|
*/
|
|
10353
10121
|
/** The door slice the per-device store needs, over a tRPC client. */
|
|
10354
|
-
function doorOverClient(client
|
|
10122
|
+
function doorOverClient(client) {
|
|
10355
10123
|
return {
|
|
10356
|
-
query:
|
|
10357
|
-
|
|
10358
|
-
|
|
10359
|
-
},
|
|
10360
|
-
transact: async (input) => {
|
|
10361
|
-
await before();
|
|
10362
|
-
return client.transact.mutate(input);
|
|
10363
|
-
},
|
|
10364
|
-
deleteWhere: async (input) => {
|
|
10365
|
-
await before();
|
|
10366
|
-
return client.deleteWhere.mutate(input);
|
|
10367
|
-
}
|
|
10124
|
+
query: (input) => client.query.query(input),
|
|
10125
|
+
transact: (input) => client.transact.mutate(input),
|
|
10126
|
+
deleteWhere: (input) => client.deleteWhere.mutate(input)
|
|
10368
10127
|
};
|
|
10369
10128
|
}
|
|
10370
10129
|
/**
|
|
@@ -10372,7 +10131,7 @@ function doorOverClient(client, before = async () => {}) {
|
|
|
10372
10131
|
* runner has none — every call then THROWS: a store that could not be asked
|
|
10373
10132
|
* is not an empty one.
|
|
10374
10133
|
*/
|
|
10375
|
-
function createRunnerDeviceSettings(client, addonId
|
|
10134
|
+
function createRunnerDeviceSettings(client, addonId) {
|
|
10376
10135
|
if (client === void 0) {
|
|
10377
10136
|
const refuse = () => {
|
|
10378
10137
|
throw new Error(`device settings of "${addonId}": settings store not wired`);
|
|
@@ -10385,7 +10144,7 @@ function createRunnerDeviceSettings(client, addonId, before = async () => {}) {
|
|
|
10385
10144
|
clearDeviceStore: async () => refuse()
|
|
10386
10145
|
};
|
|
10387
10146
|
}
|
|
10388
|
-
const store = createDeviceSettingsStore(doorOverClient(client
|
|
10147
|
+
const store = createDeviceSettingsStore(doorOverClient(client), addonId);
|
|
10389
10148
|
return {
|
|
10390
10149
|
readDeviceStore: (deviceId) => readDeviceOrThrow(store, deviceId),
|
|
10391
10150
|
readDeviceStoreBatch: (ids) => store.readBatch(ids),
|
|
@@ -10662,23 +10421,9 @@ async function buildAddonContext(runtime, declaration, dataDir, options) {
|
|
|
10662
10421
|
}
|
|
10663
10422
|
};
|
|
10664
10423
|
const deviceSettingsClient = Reflect.get(api, "settingsStore");
|
|
10665
|
-
let blobsChecked = null;
|
|
10666
|
-
const bootGuard = () => {
|
|
10667
|
-
const client = deviceSettingsClient;
|
|
10668
|
-
if (client === void 0) return Promise.resolve();
|
|
10669
|
-
blobsChecked ??= assertLegacyBlobsMigrated({
|
|
10670
|
-
get: { query: (input) => client.get.query(input) },
|
|
10671
|
-
query: { query: (input) => client.query.query(input) },
|
|
10672
|
-
count: { query: (input) => client.count.query(input) }
|
|
10673
|
-
}, addonId, scopedLogger).catch((err) => {
|
|
10674
|
-
blobsChecked = null;
|
|
10675
|
-
throw err;
|
|
10676
|
-
});
|
|
10677
|
-
return blobsChecked;
|
|
10678
|
-
};
|
|
10679
10424
|
const settingsView = {
|
|
10680
|
-
...createRunnerAddonSettings(deviceSettingsClient, addonId
|
|
10681
|
-
...createRunnerDeviceSettings(deviceSettingsClient, addonId
|
|
10425
|
+
...createRunnerAddonSettings(deviceSettingsClient, addonId),
|
|
10426
|
+
...createRunnerDeviceSettings(deviceSettingsClient, addonId),
|
|
10682
10427
|
async readDeviceRuntimeState(deviceId) {
|
|
10683
10428
|
return readBlob("device-runtime-state", String(deviceId));
|
|
10684
10429
|
},
|