@camstack/system 1.2.84 → 1.2.86
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 +1 -1
- package/dist/addon-runner.mjs +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/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/core-blocks/core-blocks.addon.js +1 -1
- package/dist/builtins/core-blocks/core-blocks.addon.mjs +1 -1
- package/dist/builtins/device-manager/device-manager.addon.js +32 -2
- package/dist/builtins/device-manager/device-manager.addon.mjs +32 -2
- package/dist/builtins/device-manager/device-meta-actions.d.ts +12 -0
- 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/liveness-monitor/liveness-monitor.addon.js +1 -1
- package/dist/builtins/liveness-monitor/liveness-monitor.addon.mjs +1 -1
- package/dist/builtins/local-auth/local-auth.addon.js +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 +66 -11
- package/dist/builtins/snapshot/index.mjs +66 -11
- package/dist/builtins/snapshot/snapshot.addon.d.ts +39 -3
- 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.addon.js +1 -1
- package/dist/builtins/sqlite-storage/sqlite-settings.addon.mjs +1 -1
- 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 +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-BAwlOEUy.mjs → dist-B90N7AWO.mjs} +575 -34
- package/dist/{dist-CQy9KjsL.js → dist-BV5Bug9t.js} +575 -34
- package/dist/index.js +73 -16
- package/dist/index.mjs +73 -16
- package/dist/kernel/addon-installer.d.ts +49 -5
- package/dist/kernel/moleculer/event-bus-core.d.ts +47 -1
- package/dist/kernel/transport/child-cap-protocol.d.ts +32 -0
- package/dist/kernel/transport/hub-cap-forward.d.ts +8 -0
- package/dist/kernel/transport/parent-unowned-call.d.ts +19 -0
- package/dist/{manifest-python-deps-DG_LLcZF.js → manifest-python-deps-C0zkl1Ae.js} +133 -53
- package/dist/{manifest-python-deps-C1DMs1J9.mjs → manifest-python-deps-fWzdEasI.mjs} +133 -53
- package/package.json +6 -1
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { Ft as nodePin, Ht as EventCategory, St as DeviceType, bt as DeviceFeature, dt as streamQualityLabel, gt as BaseAddon, ht as errMsg, i as BatteryStatusSchema, st as snapshotCapability, w as bareAddonId } from "../../dist-
|
|
1
|
+
import { Ft as nodePin, Ht as EventCategory, St as DeviceType, bt as DeviceFeature, dt as streamQualityLabel, gt as BaseAddon, ht as errMsg, i as BatteryStatusSchema, st as snapshotCapability, w as bareAddonId } from "../../dist-B90N7AWO.mjs";
|
|
2
2
|
import { z } from "zod";
|
|
3
3
|
import { randomUUID } from "node:crypto";
|
|
4
4
|
import { signExpiringUrl, verifyExpiringUrl } from "@camstack/types/node";
|
|
@@ -865,6 +865,11 @@ var SnapshotAddon = class SnapshotAddon extends BaseAddon {
|
|
|
865
865
|
* currently holding, which is a fleet-wide blank grid after each restart. */
|
|
866
866
|
linkSecret = null;
|
|
867
867
|
/**
|
|
868
|
+
* In-flight `serveLinkDataPlane` attempt, so the retry below cannot start a
|
|
869
|
+
* second one while the first is still awaiting the settings store.
|
|
870
|
+
*/
|
|
871
|
+
linkPlaneAttempt = null;
|
|
872
|
+
/**
|
|
868
873
|
* How a full frame becomes a card-sized one. Defaults to the real ffmpeg
|
|
869
874
|
* resize; injectable so the wrapper's own logic is testable without spawning a
|
|
870
875
|
* process for every fixture. `JpegResizer` was declared for exactly this and
|
|
@@ -893,7 +898,7 @@ var SnapshotAddon = class SnapshotAddon extends BaseAddon {
|
|
|
893
898
|
if (typeof deviceId === "number") this.evictRemovedDevice(deviceId, "device-unregistered");
|
|
894
899
|
});
|
|
895
900
|
await this.serveMediaDataPlane();
|
|
896
|
-
await this.
|
|
901
|
+
await this.ensureLinkDataPlane();
|
|
897
902
|
return [{
|
|
898
903
|
capability: snapshotCapability,
|
|
899
904
|
provider
|
|
@@ -926,6 +931,33 @@ var SnapshotAddon = class SnapshotAddon extends BaseAddon {
|
|
|
926
931
|
}
|
|
927
932
|
}
|
|
928
933
|
/**
|
|
934
|
+
* Serve the link plane if it is not already served — at init, and again on
|
|
935
|
+
* the first `getSnapshotLinks` after an attempt that could not finish.
|
|
936
|
+
*
|
|
937
|
+
* The retry is not defensive padding, it is the whole reason this wrapper
|
|
938
|
+
* exists. The plane needs a persisted signing secret, and the secret needs
|
|
939
|
+
* the settings store; this addon now boots in its OWN process, so "the store
|
|
940
|
+
* is not answering yet" is a state it can genuinely observe. A one-shot
|
|
941
|
+
* attempt turns that instant into a permanent condition: `linkDataPlane`
|
|
942
|
+
* stays null, every `getSnapshotLinks` row answers `url: null`, and every
|
|
943
|
+
* tile on every grid stays blank until someone restarts the runner. Nothing
|
|
944
|
+
* in the logs would say why, because nothing failed twice.
|
|
945
|
+
*
|
|
946
|
+
* Single-flighted: a burst of link requests joins one attempt.
|
|
947
|
+
*/
|
|
948
|
+
async ensureLinkDataPlane() {
|
|
949
|
+
if (this.linkDataPlane !== null) return;
|
|
950
|
+
if (this.linkPlaneAttempt !== null) {
|
|
951
|
+
await this.linkPlaneAttempt;
|
|
952
|
+
return;
|
|
953
|
+
}
|
|
954
|
+
const attempt = this.serveLinkDataPlane().finally(() => {
|
|
955
|
+
this.linkPlaneAttempt = null;
|
|
956
|
+
});
|
|
957
|
+
this.linkPlaneAttempt = attempt;
|
|
958
|
+
await attempt;
|
|
959
|
+
}
|
|
960
|
+
/**
|
|
929
961
|
* Serve the PUBLIC link plane: `GET /addon/snapshot/link/<deviceId>.jpg?w&v&exp&sig`.
|
|
930
962
|
*
|
|
931
963
|
* `access: 'public'` is deliberate and is the only interesting decision here.
|
|
@@ -994,20 +1026,42 @@ var SnapshotAddon = class SnapshotAddon extends BaseAddon {
|
|
|
994
1026
|
linkRoutePrefix() {
|
|
995
1027
|
return `/addon/${bareAddonId(this.ctx.id)}/link`;
|
|
996
1028
|
}
|
|
997
|
-
/**
|
|
998
|
-
*
|
|
999
|
-
*
|
|
1029
|
+
/**
|
|
1030
|
+
* Mint-once-and-persist the signing secret. Null when it cannot be
|
|
1031
|
+
* ESTABLISHED — a secret held only in memory would break every outstanding
|
|
1032
|
+
* link on restart, so no plane is better than a plane whose links die
|
|
1033
|
+
* unpredictably.
|
|
1034
|
+
*
|
|
1035
|
+
* A null is never cached, so the next `getSnapshotLinks` tries again. That
|
|
1036
|
+
* matters now the wrapper runs in its own process: the settings store can be
|
|
1037
|
+
* a moment behind at boot, and this used to be a one-shot.
|
|
1038
|
+
*
|
|
1039
|
+
* The read-back is the gate. `state.get()` cannot distinguish "no secret
|
|
1040
|
+
* yet" from "the store could not be read" — `readAddonStoreWithRetry` gives
|
|
1041
|
+
* up and answers `{}` — so a store that is merely slow reads as empty and
|
|
1042
|
+
* this would mint a SECOND secret over a perfectly good first one, silently
|
|
1043
|
+
* invalidating every link a client is holding. Reading back what we just
|
|
1044
|
+
* wrote is the only evidence available at this layer that the store is
|
|
1045
|
+
* actually answering, and a mismatch means it is not.
|
|
1046
|
+
*/
|
|
1000
1047
|
async ensureLinkSecret() {
|
|
1001
1048
|
if (this.linkSecret !== null) return this.linkSecret;
|
|
1002
1049
|
try {
|
|
1003
1050
|
const state = this.state("snapshotLinkSecret", z.string(), "");
|
|
1004
|
-
|
|
1005
|
-
if (
|
|
1006
|
-
|
|
1007
|
-
|
|
1051
|
+
const stored = await state.get();
|
|
1052
|
+
if (stored !== "") {
|
|
1053
|
+
this.linkSecret = stored;
|
|
1054
|
+
return stored;
|
|
1055
|
+
}
|
|
1056
|
+
const minted = randomUUID().replace(/-/g, "");
|
|
1057
|
+
await state.set(minted);
|
|
1058
|
+
const confirmed = await state.get();
|
|
1059
|
+
if (confirmed !== minted) {
|
|
1060
|
+
this.ctx.logger.warn("snapshot: link secret did not persist — deferring the link plane rather than signing with a secret that will not survive", { meta: { confirmedEmpty: confirmed === "" } });
|
|
1061
|
+
return null;
|
|
1008
1062
|
}
|
|
1009
|
-
this.linkSecret =
|
|
1010
|
-
return
|
|
1063
|
+
this.linkSecret = minted;
|
|
1064
|
+
return minted;
|
|
1011
1065
|
} catch (err) {
|
|
1012
1066
|
this.ctx.logger.warn("snapshot: could not establish link signing secret", { meta: { error: errMsg(err) } });
|
|
1013
1067
|
return null;
|
|
@@ -1038,6 +1092,7 @@ var SnapshotAddon = class SnapshotAddon extends BaseAddon {
|
|
|
1038
1092
|
* forward.
|
|
1039
1093
|
*/
|
|
1040
1094
|
async getSnapshotLinks(input) {
|
|
1095
|
+
await this.ensureLinkDataPlane();
|
|
1041
1096
|
const secret = await this.ensureLinkSecret();
|
|
1042
1097
|
const expMs = snapshotLinkExpiry(Date.now(), SNAPSHOT_LINK_TTL_MS);
|
|
1043
1098
|
const served = this.linkDataPlane !== null && secret !== null;
|
|
@@ -81,6 +81,11 @@ export declare class SnapshotAddon extends BaseAddon<SnapshotAddonConfig> {
|
|
|
81
81
|
* secret that rolled on every boot would invalidate every link a client is
|
|
82
82
|
* currently holding, which is a fleet-wide blank grid after each restart. */
|
|
83
83
|
private linkSecret;
|
|
84
|
+
/**
|
|
85
|
+
* In-flight `serveLinkDataPlane` attempt, so the retry below cannot start a
|
|
86
|
+
* second one while the first is still awaiting the settings store.
|
|
87
|
+
*/
|
|
88
|
+
private linkPlaneAttempt;
|
|
84
89
|
/**
|
|
85
90
|
* How a full frame becomes a card-sized one. Defaults to the real ffmpeg
|
|
86
91
|
* resize; injectable so the wrapper's own logic is testable without spawning a
|
|
@@ -101,6 +106,22 @@ export declare class SnapshotAddon extends BaseAddon<SnapshotAddonConfig> {
|
|
|
101
106
|
* base64 path.
|
|
102
107
|
*/
|
|
103
108
|
private serveMediaDataPlane;
|
|
109
|
+
/**
|
|
110
|
+
* Serve the link plane if it is not already served — at init, and again on
|
|
111
|
+
* the first `getSnapshotLinks` after an attempt that could not finish.
|
|
112
|
+
*
|
|
113
|
+
* The retry is not defensive padding, it is the whole reason this wrapper
|
|
114
|
+
* exists. The plane needs a persisted signing secret, and the secret needs
|
|
115
|
+
* the settings store; this addon now boots in its OWN process, so "the store
|
|
116
|
+
* is not answering yet" is a state it can genuinely observe. A one-shot
|
|
117
|
+
* attempt turns that instant into a permanent condition: `linkDataPlane`
|
|
118
|
+
* stays null, every `getSnapshotLinks` row answers `url: null`, and every
|
|
119
|
+
* tile on every grid stays blank until someone restarts the runner. Nothing
|
|
120
|
+
* in the logs would say why, because nothing failed twice.
|
|
121
|
+
*
|
|
122
|
+
* Single-flighted: a burst of link requests joins one attempt.
|
|
123
|
+
*/
|
|
124
|
+
private ensureLinkDataPlane;
|
|
104
125
|
/**
|
|
105
126
|
* Serve the PUBLIC link plane: `GET /addon/snapshot/link/<deviceId>.jpg?w&v&exp&sig`.
|
|
106
127
|
*
|
|
@@ -128,9 +149,24 @@ export declare class SnapshotAddon extends BaseAddon<SnapshotAddonConfig> {
|
|
|
128
149
|
*/
|
|
129
150
|
private handleLinkRequest;
|
|
130
151
|
private linkRoutePrefix;
|
|
131
|
-
/**
|
|
132
|
-
*
|
|
133
|
-
*
|
|
152
|
+
/**
|
|
153
|
+
* Mint-once-and-persist the signing secret. Null when it cannot be
|
|
154
|
+
* ESTABLISHED — a secret held only in memory would break every outstanding
|
|
155
|
+
* link on restart, so no plane is better than a plane whose links die
|
|
156
|
+
* unpredictably.
|
|
157
|
+
*
|
|
158
|
+
* A null is never cached, so the next `getSnapshotLinks` tries again. That
|
|
159
|
+
* matters now the wrapper runs in its own process: the settings store can be
|
|
160
|
+
* a moment behind at boot, and this used to be a one-shot.
|
|
161
|
+
*
|
|
162
|
+
* The read-back is the gate. `state.get()` cannot distinguish "no secret
|
|
163
|
+
* yet" from "the store could not be read" — `readAddonStoreWithRetry` gives
|
|
164
|
+
* up and answers `{}` — so a store that is merely slow reads as empty and
|
|
165
|
+
* this would mint a SECOND secret over a perfectly good first one, silently
|
|
166
|
+
* invalidating every link a client is holding. Reading back what we just
|
|
167
|
+
* wrote is the only evidence available at this layer that the store is
|
|
168
|
+
* actually answering, and a mismatch means it is not.
|
|
169
|
+
*/
|
|
134
170
|
private ensureLinkSecret;
|
|
135
171
|
/**
|
|
136
172
|
* Mint signed links for the tiles a surface is rendering — and, in the same
|
|
@@ -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-BV5Bug9t.js");
|
|
7
7
|
let node_crypto = require("node:crypto");
|
|
8
8
|
let node_fs_promises = require("node:fs/promises");
|
|
9
9
|
let node_path = require("node:path");
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { gt as BaseAddon, ut as storageProviderCapability, z as filesystemBrowseCapability } from "../../dist-
|
|
1
|
+
import { gt as BaseAddon, ut as storageProviderCapability, z as filesystemBrowseCapability } from "../../dist-B90N7AWO.mjs";
|
|
2
2
|
import { randomUUID } from "node:crypto";
|
|
3
3
|
import { mkdir, readdir, realpath, statfs } from "node:fs/promises";
|
|
4
4
|
import * as path$1 from "node:path";
|
|
@@ -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-BV5Bug9t.js");
|
|
7
7
|
let node_crypto = require("node:crypto");
|
|
8
8
|
let node_fs = require("node:fs");
|
|
9
9
|
let node_module = require("node:module");
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { A as decodeVectorBase64, Et as asJsonObject, Lt as parseJsonUnknown, f as RUNTIME_DEFAULTS, gt as BaseAddon, ht as errMsg, k as dataStoreProviderCapability, mt as vectorStoreCapability, pt as vectorDimFromBase64, w as bareAddonId } from "../../dist-
|
|
1
|
+
import { A as decodeVectorBase64, Et as asJsonObject, Lt as parseJsonUnknown, f as RUNTIME_DEFAULTS, gt as BaseAddon, ht as errMsg, k as dataStoreProviderCapability, mt as vectorStoreCapability, pt as vectorDimFromBase64, w as bareAddonId } from "../../dist-B90N7AWO.mjs";
|
|
2
2
|
import { createRequire } from "node:module";
|
|
3
3
|
import { randomUUID } from "node:crypto";
|
|
4
4
|
import { statSync } from "node:fs";
|
|
@@ -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-BV5Bug9t.js");
|
|
7
7
|
let node_crypto = require("node:crypto");
|
|
8
8
|
let node_fs_promises = require("node:fs/promises");
|
|
9
9
|
node_fs_promises = require_chunk.__toESM(node_fs_promises);
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { It as parseJsonObject, ct as storageCapability, g as StorageMigrationJobSchema, gt as BaseAddon, h as StorageLocationTypeSchema, lt as storageMigrationCapability, ot as settingsStoreCapability } from "../../dist-
|
|
1
|
+
import { It as parseJsonObject, ct as storageCapability, g as StorageMigrationJobSchema, gt as BaseAddon, h as StorageLocationTypeSchema, lt as storageMigrationCapability, ot as settingsStoreCapability } from "../../dist-B90N7AWO.mjs";
|
|
2
2
|
import { randomUUID } from "node:crypto";
|
|
3
3
|
import * as fs from "node:fs/promises";
|
|
4
4
|
import * as path$1 from "node:path";
|
|
@@ -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-BV5Bug9t.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 { Nt as hydrateSchema, gt as BaseAddon, ht as errMsg } from "../../dist-
|
|
1
|
+
import { Nt as hydrateSchema, gt as BaseAddon, ht as errMsg } from "../../dist-B90N7AWO.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-BV5Bug9t.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 { J as logDestinationCapability, gt as BaseAddon } from "../../dist-
|
|
1
|
+
import { J as logDestinationCapability, gt as BaseAddon } from "../../dist-B90N7AWO.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";
|