@camstack/addon-pipeline 1.2.171 → 1.2.172
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/audio-analyzer/index.js +2 -2
- package/dist/audio-analyzer/index.mjs +2 -2
- package/dist/detection-pipeline/index.js +5 -5
- package/dist/detection-pipeline/index.mjs +4 -4
- package/dist/{dist-D0liXHO7.mjs → dist-A-CKFNg9.mjs} +142 -1
- package/dist/{dist-M39Js6iu.js → dist-CpmqDTel.js} +142 -1
- package/dist/{lazy-sharp-CO-c2L9_.js → lazy-sharp-c_IKosOs.js} +1 -1
- package/dist/{local-frame-registry-CHUbcz6r.js → local-frame-registry-CHzo5v0z.js} +1 -1
- package/dist/{local-frame-registry--_WjAPa2.mjs → local-frame-registry-DuEPtfBk.mjs} +1 -1
- package/dist/motion-wasm/index.js +2 -2
- package/dist/motion-wasm/index.mjs +1 -1
- package/dist/{node-CQ6VBSrE.mjs → node-CNhb6GOd.mjs} +1 -1
- package/dist/{node-Byy6tlFm.js → node-DudW4uSe.js} +1 -1
- package/dist/pipeline-runner/index.js +63 -6
- package/dist/pipeline-runner/index.mjs +62 -5
- package/dist/{process-memory-CH3OIHHe.js → process-memory-CcWK6O93.js} +1 -1
- package/dist/{process-memory-DjLHImhM.mjs → process-memory-DVPPoQS1.mjs} +1 -1
- package/dist/recorder/index.js +97 -13
- package/dist/recorder/index.mjs +97 -13
- package/dist/{segment-demux-js-Bmy3u2VM.mjs → segment-demux-js-B0MPr5g4.mjs} +1 -1
- package/dist/{segment-demux-js-B0KzROD9.js → segment-demux-js-ChcjdSdF.js} +1 -1
- package/dist/session-decode/decode-worker-child.js +2 -2
- package/dist/session-decode/decode-worker-child.mjs +1 -1
- package/dist/stream-broker/_stub.js +2 -2
- package/dist/stream-broker/{_virtual_mf-localSharedImportMap___mfe_internal__addon_stream_broker_widgets-CN6ybZtQ.mjs → _virtual_mf-localSharedImportMap___mfe_internal__addon_stream_broker_widgets-DDhnhOI4.mjs} +3 -3
- package/dist/stream-broker/_virtual_mf___mfe_internal__addon_stream_broker_widgets__loadShare___mf_0_camstack_mf_1_types__loadShare__.js-BVpZlsT7.mjs +26 -0
- package/dist/stream-broker/_virtual_mf___mfe_internal__addon_stream_broker_widgets__loadShare___mf_0_camstack_mf_1_ui_mf_2_library__loadShare__.js-CwP-r0hs.mjs +26 -0
- package/dist/stream-broker/demux-worker-child.js +1 -1
- package/dist/stream-broker/demux-worker-child.mjs +1 -1
- package/dist/stream-broker/{hostInit-Dq40Ieaf.mjs → hostInit-CrI9kLNo.mjs} +3 -3
- package/dist/stream-broker/index.js +87 -4
- package/dist/stream-broker/index.mjs +87 -4
- package/dist/stream-broker/remoteEntry.js +1 -1
- package/dist/{worker-protocol-CAWMqnxs.mjs → worker-protocol-BuUyu8aI.mjs} +1 -1
- package/dist/{worker-protocol-NB-CjUQf.js → worker-protocol-IC_mPIhk.js} +1 -1
- package/package.json +8 -1
- package/dist/stream-broker/_virtual_mf___mfe_internal__addon_stream_broker_widgets__loadShare___mf_0_camstack_mf_1_types__loadShare__.js-BjYSKqCM.mjs +0 -26
- package/dist/stream-broker/_virtual_mf___mfe_internal__addon_stream_broker_widgets__loadShare___mf_0_camstack_mf_1_ui_mf_2_library__loadShare__.js-E0nHxt6U.mjs +0 -26
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
import { B as defineCustomActions, Bt as nodePin, Ft as createEvent, Gt as _enum, H as deriveDetailCropRect, Kt as array, L as customAction, Qt as object, X as failureContributionCapability, Xt as literal, Yt as lazy, Zt as number, _ as FailureCounters, en as string, et as loadContributionCapability, ft as pipelineRunnerCapability, jt as BaseAddon, lt as pickDetailCropConvention, m as DEVICE_BACKEND_TO_FORMAT, nn as EventCategory, p as DEFAULT_NATIVE_LEASE_SETTINGS, qt as boolean, u as DEFAULT_DETAIL_CROP_CONVENTION, ut as pickNativeLeaseOverride, wt as errMsg } from "../dist-
|
|
2
|
-
import { i as NO_COST_CLAIM, t as ChildCostRegistry } from "../node-
|
|
3
|
-
import { c as getStepDefinition, n as resolveFrameViewGeometry, t as localFrameRegistry } from "../local-frame-registry
|
|
4
|
-
import { a as nativeLeaseSettingEnv, t as isWorkerReply } from "../worker-protocol-
|
|
1
|
+
import { B as defineCustomActions, Bt as nodePin, Ft as createEvent, Gt as _enum, H as deriveDetailCropRect, Kt as array, L as customAction, Qt as object, X as failureContributionCapability, Xt as literal, Yt as lazy, Zt as number, _ as FailureCounters, en as string, et as loadContributionCapability, ft as pipelineRunnerCapability, jt as BaseAddon, lt as pickDetailCropConvention, m as DEVICE_BACKEND_TO_FORMAT, nn as EventCategory, p as DEFAULT_NATIVE_LEASE_SETTINGS, qt as boolean, u as DEFAULT_DETAIL_CROP_CONVENTION, ut as pickNativeLeaseOverride, wt as errMsg } from "../dist-A-CKFNg9.mjs";
|
|
2
|
+
import { i as NO_COST_CLAIM, t as ChildCostRegistry } from "../node-CNhb6GOd.mjs";
|
|
3
|
+
import { c as getStepDefinition, n as resolveFrameViewGeometry, t as localFrameRegistry } from "../local-frame-registry-DuEPtfBk.mjs";
|
|
4
|
+
import { a as nativeLeaseSettingEnv, t as isWorkerReply } from "../worker-protocol-BuUyu8aI.mjs";
|
|
5
5
|
import { t as resolveHubHostname } from "../hub-hostname-cCknRYKj.mjs";
|
|
6
6
|
import { t as getSharp } from "../lazy-sharp-DXsqwpph.mjs";
|
|
7
7
|
import { n as withDetectionIntent } from "../restream-intent-B4BXZra7.mjs";
|
|
@@ -12,6 +12,51 @@ import sharp from "sharp";
|
|
|
12
12
|
import { fileURLToPath } from "node:url";
|
|
13
13
|
import { PerformanceObserver } from "node:perf_hooks";
|
|
14
14
|
import * as os from "node:os";
|
|
15
|
+
//#region src/pipeline-runner/first-detection-frame.ts
|
|
16
|
+
/**
|
|
17
|
+
* How long a camera waits, after `attachCamera`, before a decoded frame
|
|
18
|
+
* actually reaches the detection queue.
|
|
19
|
+
*
|
|
20
|
+
* The orchestrator already measures `session motion → attach latency` and it
|
|
21
|
+
* is small — 11, 13 and 18 ms across three consecutive sessions on the same
|
|
22
|
+
* camera. What nothing measured is the NEXT leg: from the attach to the first
|
|
23
|
+
* frame the detector is given. An operator reporting "detection starts late"
|
|
24
|
+
* is describing that leg, and answering them required reading the timestamps
|
|
25
|
+
* of unrelated INFO lines and inferring — which produced a wrong first answer
|
|
26
|
+
* (the absence of a `frame processed` line means the frame produced nothing
|
|
27
|
+
* notable, not that no frame arrived).
|
|
28
|
+
*
|
|
29
|
+
* One number, once per attach, so a slow start is a value rather than an
|
|
30
|
+
* inference.
|
|
31
|
+
*/
|
|
32
|
+
/** Pending attach marks, keyed by device. */
|
|
33
|
+
var FirstDetectionFrameTimer = class {
|
|
34
|
+
attachedAt = /* @__PURE__ */ new Map();
|
|
35
|
+
/** A camera attached. Replaces any pending mark: the newest attach is the
|
|
36
|
+
* one the next frame belongs to. */
|
|
37
|
+
markAttached(deviceId, nowMs) {
|
|
38
|
+
this.attachedAt.set(deviceId, nowMs);
|
|
39
|
+
}
|
|
40
|
+
/**
|
|
41
|
+
* A decoded frame was admitted to the detection queue. Returns the elapsed
|
|
42
|
+
* ms since the attach the FIRST time it is called after one, and `null`
|
|
43
|
+
* every time after — so the caller logs once per attach, not once per frame.
|
|
44
|
+
*/
|
|
45
|
+
takeLatency(deviceId, nowMs) {
|
|
46
|
+
const at = this.attachedAt.get(deviceId);
|
|
47
|
+
if (at === void 0) return null;
|
|
48
|
+
this.attachedAt.delete(deviceId);
|
|
49
|
+
return Math.max(0, nowMs - at);
|
|
50
|
+
}
|
|
51
|
+
/** A camera detached with no frame ever admitted — drop the mark so the
|
|
52
|
+
* NEXT attach is not measured from this one. Returns whether one was
|
|
53
|
+
* pending, which is itself the interesting fact: a session that ran and
|
|
54
|
+
* fed the detector nothing. */
|
|
55
|
+
forget(deviceId) {
|
|
56
|
+
return this.attachedAt.delete(deviceId);
|
|
57
|
+
}
|
|
58
|
+
};
|
|
59
|
+
//#endregion
|
|
15
60
|
//#region src/session-decode/fork-decode-worker.ts
|
|
16
61
|
/** Absolute path to the built decode-worker child entry (a vite build entry). */
|
|
17
62
|
var CHILD_ENTRY_PATH = fileURLToPath(new URL("../session-decode/decode-worker-child.js", import.meta.url));
|
|
@@ -6427,6 +6472,8 @@ var PipelineRunnerAddon = class PipelineRunnerAddon extends BaseAddon {
|
|
|
6427
6472
|
if (config.motionSources.includes("analyzer")) attachment.motionUnsubscribe = await this.subscribeMotionFrames(config);
|
|
6428
6473
|
const stepsCount = config.steps?.length ?? 0;
|
|
6429
6474
|
const dispatch = stepsCount > 0 ? `runPipeline(${stepsCount}step${stepsCount === 1 ? "" : "s"})` : config.steps !== void 0 ? "skip(0steps)" : "runFrame(legacy)";
|
|
6475
|
+
const engineLabel = "node-local";
|
|
6476
|
+
this.firstDetectionFrame.markAttached(config.deviceId, Date.now());
|
|
6430
6477
|
this.ctx.logger.info("attachCamera", {
|
|
6431
6478
|
tags: { deviceId: config.deviceId },
|
|
6432
6479
|
meta: {
|
|
@@ -6436,7 +6483,7 @@ var PipelineRunnerAddon = class PipelineRunnerAddon extends BaseAddon {
|
|
|
6436
6483
|
detectionFps: config.detectionFps,
|
|
6437
6484
|
motionSources: config.motionSources,
|
|
6438
6485
|
dispatch,
|
|
6439
|
-
engine:
|
|
6486
|
+
engine: engineLabel
|
|
6440
6487
|
}
|
|
6441
6488
|
});
|
|
6442
6489
|
return { success: true };
|
|
@@ -7285,10 +7332,20 @@ var PipelineRunnerAddon = class PipelineRunnerAddon extends BaseAddon {
|
|
|
7285
7332
|
* no second dial, no second decode, no GPU). Mirrors the shm shared-motion
|
|
7286
7333
|
* seam (`subscribeMotionFrames` `shared` branch).
|
|
7287
7334
|
*/
|
|
7335
|
+
/** Attach → first decoded detection frame, one line per attach. See
|
|
7336
|
+
* {@link FirstDetectionFrameTimer}. */
|
|
7337
|
+
firstDetectionFrame = new FirstDetectionFrameTimer();
|
|
7288
7338
|
enqueueSharedDetectionFrame(deviceId, frame, handle, reservation) {
|
|
7289
7339
|
const runner = this.runner;
|
|
7290
7340
|
if (!runner) return false;
|
|
7291
7341
|
const admitted = reservation ? reservation.detection && runner.enqueueReservedDetectionFrame(deviceId, frame, handle) : runner.enqueueDetectionFrame(deviceId, frame, handle);
|
|
7342
|
+
if (admitted) {
|
|
7343
|
+
const latencyMs = this.firstDetectionFrame.takeLatency(deviceId, Date.now());
|
|
7344
|
+
if (latencyMs !== null) this.ctx?.logger.info("session-decode: first detection frame after attach", {
|
|
7345
|
+
tags: { deviceId },
|
|
7346
|
+
meta: { latencyMs }
|
|
7347
|
+
});
|
|
7348
|
+
}
|
|
7292
7349
|
if (reservation?.motion) runner.enqueueMotionFrame(deviceId, rgbFrameToGrayFrame(frame), void 0);
|
|
7293
7350
|
else if (!reservation) {
|
|
7294
7351
|
const sink = this.sharedMotionSinks.get(deviceId);
|
package/dist/recorder/index.js
CHANGED
|
@@ -2,8 +2,8 @@ Object.defineProperties(exports, {
|
|
|
2
2
|
__esModule: { value: true },
|
|
3
3
|
[Symbol.toStringTag]: { value: "Module" }
|
|
4
4
|
});
|
|
5
|
-
const require_dist = require("../dist-
|
|
6
|
-
const require_node = require("../node-
|
|
5
|
+
const require_dist = require("../dist-CpmqDTel.js");
|
|
6
|
+
const require_node = require("../node-DudW4uSe.js");
|
|
7
7
|
const require_hub_hostname = require("../hub-hostname-DAJXlOgV.js");
|
|
8
8
|
const require_restream_intent = require("../restream-intent-Cv9x3jmu.js");
|
|
9
9
|
const require_event_loop_stall_monitor = require("../event-loop-stall-monitor-DaUBcb13.js");
|
|
@@ -5077,6 +5077,48 @@ function buildExportArgs(input) {
|
|
|
5077
5077
|
* queue behind each other.
|
|
5078
5078
|
*/
|
|
5079
5079
|
/**
|
|
5080
|
+
* The storage class export MP4s live in: `artifacts`, SHARED with the
|
|
5081
|
+
* notification-center's artifact shelf (operator 2026-09-04: one generic
|
|
5082
|
+
* class, not one per producer — D341), a declared SINGLETON. Never the addon
|
|
5083
|
+
* data dir: 8.4 GB of operator-exported clips sat in
|
|
5084
|
+
* `addons-data/recorder/exports`, inside every system backup, invisible to
|
|
5085
|
+
* occupancy and relocation, on the constrained appdata disk. And never a
|
|
5086
|
+
* `recordings`-class subtree: footage classes are quota-capped and swept, and
|
|
5087
|
+
* an export is something the operator DELIBERATELY created — its only
|
|
5088
|
+
* retention is its own (`expiresAt` chosen at creation + delete-after-
|
|
5089
|
+
* download), enforced by the export janitor and nothing else. Sharing the
|
|
5090
|
+
* LOCATION with the notification shelf never means sharing a SWEEP: each
|
|
5091
|
+
* tenant walks only its own subtree.
|
|
5092
|
+
*
|
|
5093
|
+
* Declared by BOTH consuming addons with identical cardinality — the
|
|
5094
|
+
* registry throws at kernel boot on a conflict, and each addon's pinning
|
|
5095
|
+
* spec holds its side of the agreement.
|
|
5096
|
+
*/
|
|
5097
|
+
var ARTIFACTS_MEDIA_LOCATION = "artifacts";
|
|
5098
|
+
/**
|
|
5099
|
+
* `<root>/<deviceId>/exports/` — the exports TENANT subtree, DEVICE-FIRST
|
|
5100
|
+
* like the notification shelf's `<root>/<deviceId>/nc-artifacts/…` (operator
|
|
5101
|
+
* 2026-09-04: one directory per camera answers "what does this camera hold",
|
|
5102
|
+
* and per-device occupancy is uniform across both tenants). The ONE
|
|
5103
|
+
* derivation of the tenant dir — export MP4s, source playlists and the
|
|
5104
|
+
* ffconcat sidecar all live here; nothing may join the path a second way.
|
|
5105
|
+
*/
|
|
5106
|
+
function exportTenantDirFor(root, deviceId) {
|
|
5107
|
+
return node_path.default.join(root, String(deviceId), "exports");
|
|
5108
|
+
}
|
|
5109
|
+
/**
|
|
5110
|
+
* `<root>/<deviceId>/exports/<exportId>.mp4` — the ONE derivation of an
|
|
5111
|
+
* export's file path, via {@link exportTenantDirFor}. Rows store no path, so
|
|
5112
|
+
* repointing the class root moves the whole library while every row keeps
|
|
5113
|
+
* resolving. A `null` root (location not yet resolved, or unresolvable)
|
|
5114
|
+
* REFUSES: falling back to the addon data dir is the failure mode this class
|
|
5115
|
+
* exists to end (D341).
|
|
5116
|
+
*/
|
|
5117
|
+
function exportOutPathFor(root, deviceId, exportId) {
|
|
5118
|
+
if (root === null) throw new Error("artifacts storage location is not resolved — exports refuse rather than fall back to the addon data dir (D341)");
|
|
5119
|
+
return node_path.default.join(exportTenantDirFor(root, deviceId), `${exportId}.mp4`);
|
|
5120
|
+
}
|
|
5121
|
+
/**
|
|
5080
5122
|
* @durable class=ledger owner=recorder
|
|
5081
5123
|
* write="one row per export job, inserted by `createExport` and rewritten by the
|
|
5082
5124
|
* render engine's progress/state patches and by the download hook"
|
|
@@ -7404,18 +7446,21 @@ function buildRecordingProvider(deps) {
|
|
|
7404
7446
|
*/
|
|
7405
7447
|
/**
|
|
7406
7448
|
* Absolute path of ONE export's source playlist:
|
|
7407
|
-
* `<
|
|
7408
|
-
*
|
|
7449
|
+
* `<root>/<deviceId>/exports/<exportId>.src.m3u8` — inside the exports
|
|
7450
|
+
* TENANT subtree of the shared `artifacts` class root, derived through
|
|
7451
|
+
* {@link exportTenantDirFor} so no caller can join the path a second way.
|
|
7452
|
+
* Unique per export id, so two concurrent renders (and any concurrent
|
|
7453
|
+
* playback request) never share a file.
|
|
7409
7454
|
*/
|
|
7410
7455
|
function exportSourcePlaylistPath(exportsDir, deviceId, exportId) {
|
|
7411
|
-
return node_path.default.join(exportsDir,
|
|
7456
|
+
return node_path.default.join(exportTenantDirFor(exportsDir, deviceId), `${exportId}.src.m3u8`);
|
|
7412
7457
|
}
|
|
7413
7458
|
/**
|
|
7414
7459
|
* Absolute path of the same export's FFCONCAT list — the timelapse pass-1
|
|
7415
7460
|
* input (`buildConcatPassArgs`). Sibling of the m3u8, same uniqueness rules.
|
|
7416
7461
|
*/
|
|
7417
7462
|
function exportSourceConcatPath(exportsDir, deviceId, exportId) {
|
|
7418
|
-
return node_path.default.join(exportsDir,
|
|
7463
|
+
return node_path.default.join(exportTenantDirFor(exportsDir, deviceId), `${exportId}.src.ffconcat`);
|
|
7419
7464
|
}
|
|
7420
7465
|
/**
|
|
7421
7466
|
* Write the export's source playlist and return it, or null when no segment of
|
|
@@ -16377,6 +16422,14 @@ var RecorderV2Addon = class extends require_dist.BaseAddon {
|
|
|
16377
16422
|
* Every other node stays fully inert — registers no providers, serves no
|
|
16378
16423
|
* playback, runs no controller. Resolved in `onInitialize`. */
|
|
16379
16424
|
isRecordingNode = true;
|
|
16425
|
+
/**
|
|
16426
|
+
* Resolved root of the shared `artifacts` storage location — the export
|
|
16427
|
+
* MP4s' home and the GIF/clip render scratch. `null` until `onHubReachable`
|
|
16428
|
+
* resolves it (and forever if the location is unreachable): every consumer
|
|
16429
|
+
* then REFUSES with a named error instead of falling back to the addon data
|
|
16430
|
+
* dir (D341).
|
|
16431
|
+
*/
|
|
16432
|
+
exportsRoot = null;
|
|
16380
16433
|
index = new RecordingIndex();
|
|
16381
16434
|
/**
|
|
16382
16435
|
* Stops the GC-attributing stall monitor armed in {@link onInitialize}.
|
|
@@ -16792,12 +16845,12 @@ var RecorderV2Addon = class extends require_dist.BaseAddon {
|
|
|
16792
16845
|
relocate: relocateEngine,
|
|
16793
16846
|
gifRender: (input) => renderGif({
|
|
16794
16847
|
deps: recordingDeps,
|
|
16795
|
-
exportsDir:
|
|
16848
|
+
exportsDir: this.exportsDirOrThrow(),
|
|
16796
16849
|
spawn: node_child_process.spawn
|
|
16797
16850
|
}, input),
|
|
16798
16851
|
clipRender: (input) => renderClip({
|
|
16799
16852
|
deps: recordingDeps,
|
|
16800
|
-
exportsDir:
|
|
16853
|
+
exportsDir: this.exportsDirOrThrow(),
|
|
16801
16854
|
spawn: node_child_process.spawn
|
|
16802
16855
|
}, input),
|
|
16803
16856
|
locations: () => this.resolvedLocations,
|
|
@@ -16912,8 +16965,7 @@ var RecorderV2Addon = class extends require_dist.BaseAddon {
|
|
|
16912
16965
|
}
|
|
16913
16966
|
});
|
|
16914
16967
|
const exportsState = this.exportsStore();
|
|
16915
|
-
const
|
|
16916
|
-
const exportOutPath = (rec) => node_path.default.join(exportsDir, String(rec.deviceId), `${rec.id}.mp4`);
|
|
16968
|
+
const exportOutPath = (rec) => exportOutPathFor(this.exportsRoot, rec.deviceId, rec.id);
|
|
16917
16969
|
const removeExportFile = async (p) => {
|
|
16918
16970
|
await node_fs.promises.rm(p, { force: true });
|
|
16919
16971
|
};
|
|
@@ -16925,7 +16977,7 @@ var RecorderV2Addon = class extends require_dist.BaseAddon {
|
|
|
16925
16977
|
await node_fs.promises.mkdir(node_path.default.dirname(exportOutPath(rec)), { recursive: true });
|
|
16926
16978
|
return writeExportSourcePlaylist({
|
|
16927
16979
|
deps: recordingDeps,
|
|
16928
|
-
exportsDir,
|
|
16980
|
+
exportsDir: this.exportsDirOrThrow(),
|
|
16929
16981
|
exportId: rec.id,
|
|
16930
16982
|
deviceId: rec.deviceId,
|
|
16931
16983
|
profile: rec.profile,
|
|
@@ -17160,6 +17212,18 @@ var RecorderV2Addon = class extends require_dist.BaseAddon {
|
|
|
17160
17212
|
async onHubReachable() {
|
|
17161
17213
|
if (!this.isRecordingNode) return;
|
|
17162
17214
|
await this.refreshLocations();
|
|
17215
|
+
try {
|
|
17216
|
+
this.exportsRoot = await this.ctx.api.storage.resolve.query({
|
|
17217
|
+
location: ARTIFACTS_MEDIA_LOCATION,
|
|
17218
|
+
relativePath: ""
|
|
17219
|
+
});
|
|
17220
|
+
} catch (err) {
|
|
17221
|
+
this.ctx.logger.error("artifacts storage location is NOT available — exports, GIF and clip renders will REFUSE until it is", { meta: {
|
|
17222
|
+
location: ARTIFACTS_MEDIA_LOCATION,
|
|
17223
|
+
error: require_dist.errMsg(err),
|
|
17224
|
+
hint: "the declaration is seeded when a storage-provider registers; restart this node so the manifest is re-read, or create an artifacts location. Refusing is deliberate — the addon data dir carries no media (D341)."
|
|
17225
|
+
} });
|
|
17226
|
+
}
|
|
17163
17227
|
if (this.resolvedLocations.length === 0) {
|
|
17164
17228
|
this.ctx.logger.warn("recorder: no recordings storage locations resolved — index not hydrated");
|
|
17165
17229
|
return;
|
|
@@ -17393,6 +17457,10 @@ var RecorderV2Addon = class extends require_dist.BaseAddon {
|
|
|
17393
17457
|
async bootstrapExports() {
|
|
17394
17458
|
const engine = this.exportEngine;
|
|
17395
17459
|
if (!engine) return;
|
|
17460
|
+
if (this.exportsRoot === null) {
|
|
17461
|
+
this.ctx.logger.warn("recorder: exports bootstrap skipped — artifacts location unresolved");
|
|
17462
|
+
return;
|
|
17463
|
+
}
|
|
17396
17464
|
try {
|
|
17397
17465
|
await reconcileInterruptedExports({
|
|
17398
17466
|
state: this.exportsStore(),
|
|
@@ -17947,11 +18015,21 @@ var RecorderV2Addon = class extends require_dist.BaseAddon {
|
|
|
17947
18015
|
placementStore() {
|
|
17948
18016
|
return this.state(RECORDING_PLACEMENT_KEY, RecordingPlacementBlobSchema, EMPTY_PLACEMENT);
|
|
17949
18017
|
}
|
|
18018
|
+
/** The artifacts class ROOT, or a NAMED refusal — never an invented path.
|
|
18019
|
+
* Every export-side path (MP4s, playlists, render scratch) derives from it
|
|
18020
|
+
* through `exportTenantDirFor` → `<root>/<deviceId>/exports/…`, beside
|
|
18021
|
+
* (never inside) the notification shelf's `<root>/<deviceId>/nc-artifacts/…`
|
|
18022
|
+
* sibling (D341). No consumer joins the path a second way. */
|
|
18023
|
+
exportsDirOrThrow() {
|
|
18024
|
+
const root = this.exportsRoot;
|
|
18025
|
+
if (root === null) throw new Error("artifacts storage location is not resolved — exports and footage renders refuse rather than fall back to the addon data dir (D341)");
|
|
18026
|
+
return root;
|
|
18027
|
+
}
|
|
17950
18028
|
/** Retention deps shared by the sweep and the download-complete hook. */
|
|
17951
18029
|
exportJanitorDeps() {
|
|
17952
18030
|
return {
|
|
17953
18031
|
state: this.exportsStore(),
|
|
17954
|
-
outPath: (rec) =>
|
|
18032
|
+
outPath: (rec) => exportOutPathFor(this.exportsRoot, rec.deviceId, rec.id),
|
|
17955
18033
|
removeFile: async (p) => {
|
|
17956
18034
|
await node_fs.promises.rm(p, { force: true });
|
|
17957
18035
|
}
|
|
@@ -18007,7 +18085,13 @@ var RecorderV2Addon = class extends require_dist.BaseAddon {
|
|
|
18007
18085
|
res.writeHead(404).end();
|
|
18008
18086
|
return;
|
|
18009
18087
|
}
|
|
18010
|
-
|
|
18088
|
+
let absPath;
|
|
18089
|
+
try {
|
|
18090
|
+
absPath = outPath(rec);
|
|
18091
|
+
} catch {
|
|
18092
|
+
res.writeHead(503).end();
|
|
18093
|
+
return;
|
|
18094
|
+
}
|
|
18011
18095
|
let size;
|
|
18012
18096
|
try {
|
|
18013
18097
|
const st = await node_fs.promises.stat(absPath);
|
package/dist/recorder/index.mjs
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { $ as isFirstLevelMacroClass, $t as record, B as defineCustomActions, Bt as nodePin, E as RecordingConfigSchema, Gt as _enum, It as hydrateSchema, J as evaluateSensorEdge, Kt as array, L as customAction, N as batteryCapability, Nt as DeviceFeature, Pt as DeviceType, Qt as object, T as RECORDING_EXPORT_MAX_READ_BYTES, U as deriveRecordingMode, Ut as selectAssignedProfileSlots, V as deriveBatteryPresence, Wt as sleep$1, Zt as number, bt as storageEvictableCapability, d as DEFAULT_EVENTS_BAND_BUFFER_SEC, en as string, et as loadContributionCapability, g as ExportRecordSchema, i as BatteryStatusSchema, jt as BaseAddon, mt as recordingExportCapability, nn as EventCategory, pt as recordingCapability, qt as boolean, vt as resolveRecordingProfiles, wt as errMsg, x as OpsLogEntrySchema } from "../dist-
|
|
2
|
-
import { i as NO_COST_CLAIM, t as ChildCostRegistry } from "../node-
|
|
1
|
+
import { $ as isFirstLevelMacroClass, $t as record, B as defineCustomActions, Bt as nodePin, E as RecordingConfigSchema, Gt as _enum, It as hydrateSchema, J as evaluateSensorEdge, Kt as array, L as customAction, N as batteryCapability, Nt as DeviceFeature, Pt as DeviceType, Qt as object, T as RECORDING_EXPORT_MAX_READ_BYTES, U as deriveRecordingMode, Ut as selectAssignedProfileSlots, V as deriveBatteryPresence, Wt as sleep$1, Zt as number, bt as storageEvictableCapability, d as DEFAULT_EVENTS_BAND_BUFFER_SEC, en as string, et as loadContributionCapability, g as ExportRecordSchema, i as BatteryStatusSchema, jt as BaseAddon, mt as recordingExportCapability, nn as EventCategory, pt as recordingCapability, qt as boolean, vt as resolveRecordingProfiles, wt as errMsg, x as OpsLogEntrySchema } from "../dist-A-CKFNg9.mjs";
|
|
2
|
+
import { i as NO_COST_CLAIM, t as ChildCostRegistry } from "../node-CNhb6GOd.mjs";
|
|
3
3
|
import { t as resolveHubHostname } from "../hub-hostname-cCknRYKj.mjs";
|
|
4
4
|
import { r as withRecordingIntent } from "../restream-intent-B4BXZra7.mjs";
|
|
5
5
|
import { n as startEventLoopStallMonitor } from "../event-loop-stall-monitor-DXLNBMkY.mjs";
|
|
@@ -5071,6 +5071,48 @@ function buildExportArgs(input) {
|
|
|
5071
5071
|
* queue behind each other.
|
|
5072
5072
|
*/
|
|
5073
5073
|
/**
|
|
5074
|
+
* The storage class export MP4s live in: `artifacts`, SHARED with the
|
|
5075
|
+
* notification-center's artifact shelf (operator 2026-09-04: one generic
|
|
5076
|
+
* class, not one per producer — D341), a declared SINGLETON. Never the addon
|
|
5077
|
+
* data dir: 8.4 GB of operator-exported clips sat in
|
|
5078
|
+
* `addons-data/recorder/exports`, inside every system backup, invisible to
|
|
5079
|
+
* occupancy and relocation, on the constrained appdata disk. And never a
|
|
5080
|
+
* `recordings`-class subtree: footage classes are quota-capped and swept, and
|
|
5081
|
+
* an export is something the operator DELIBERATELY created — its only
|
|
5082
|
+
* retention is its own (`expiresAt` chosen at creation + delete-after-
|
|
5083
|
+
* download), enforced by the export janitor and nothing else. Sharing the
|
|
5084
|
+
* LOCATION with the notification shelf never means sharing a SWEEP: each
|
|
5085
|
+
* tenant walks only its own subtree.
|
|
5086
|
+
*
|
|
5087
|
+
* Declared by BOTH consuming addons with identical cardinality — the
|
|
5088
|
+
* registry throws at kernel boot on a conflict, and each addon's pinning
|
|
5089
|
+
* spec holds its side of the agreement.
|
|
5090
|
+
*/
|
|
5091
|
+
var ARTIFACTS_MEDIA_LOCATION = "artifacts";
|
|
5092
|
+
/**
|
|
5093
|
+
* `<root>/<deviceId>/exports/` — the exports TENANT subtree, DEVICE-FIRST
|
|
5094
|
+
* like the notification shelf's `<root>/<deviceId>/nc-artifacts/…` (operator
|
|
5095
|
+
* 2026-09-04: one directory per camera answers "what does this camera hold",
|
|
5096
|
+
* and per-device occupancy is uniform across both tenants). The ONE
|
|
5097
|
+
* derivation of the tenant dir — export MP4s, source playlists and the
|
|
5098
|
+
* ffconcat sidecar all live here; nothing may join the path a second way.
|
|
5099
|
+
*/
|
|
5100
|
+
function exportTenantDirFor(root, deviceId) {
|
|
5101
|
+
return path.join(root, String(deviceId), "exports");
|
|
5102
|
+
}
|
|
5103
|
+
/**
|
|
5104
|
+
* `<root>/<deviceId>/exports/<exportId>.mp4` — the ONE derivation of an
|
|
5105
|
+
* export's file path, via {@link exportTenantDirFor}. Rows store no path, so
|
|
5106
|
+
* repointing the class root moves the whole library while every row keeps
|
|
5107
|
+
* resolving. A `null` root (location not yet resolved, or unresolvable)
|
|
5108
|
+
* REFUSES: falling back to the addon data dir is the failure mode this class
|
|
5109
|
+
* exists to end (D341).
|
|
5110
|
+
*/
|
|
5111
|
+
function exportOutPathFor(root, deviceId, exportId) {
|
|
5112
|
+
if (root === null) throw new Error("artifacts storage location is not resolved — exports refuse rather than fall back to the addon data dir (D341)");
|
|
5113
|
+
return path.join(exportTenantDirFor(root, deviceId), `${exportId}.mp4`);
|
|
5114
|
+
}
|
|
5115
|
+
/**
|
|
5074
5116
|
* @durable class=ledger owner=recorder
|
|
5075
5117
|
* write="one row per export job, inserted by `createExport` and rewritten by the
|
|
5076
5118
|
* render engine's progress/state patches and by the download hook"
|
|
@@ -7398,18 +7440,21 @@ function buildRecordingProvider(deps) {
|
|
|
7398
7440
|
*/
|
|
7399
7441
|
/**
|
|
7400
7442
|
* Absolute path of ONE export's source playlist:
|
|
7401
|
-
* `<
|
|
7402
|
-
*
|
|
7443
|
+
* `<root>/<deviceId>/exports/<exportId>.src.m3u8` — inside the exports
|
|
7444
|
+
* TENANT subtree of the shared `artifacts` class root, derived through
|
|
7445
|
+
* {@link exportTenantDirFor} so no caller can join the path a second way.
|
|
7446
|
+
* Unique per export id, so two concurrent renders (and any concurrent
|
|
7447
|
+
* playback request) never share a file.
|
|
7403
7448
|
*/
|
|
7404
7449
|
function exportSourcePlaylistPath(exportsDir, deviceId, exportId) {
|
|
7405
|
-
return path.join(exportsDir,
|
|
7450
|
+
return path.join(exportTenantDirFor(exportsDir, deviceId), `${exportId}.src.m3u8`);
|
|
7406
7451
|
}
|
|
7407
7452
|
/**
|
|
7408
7453
|
* Absolute path of the same export's FFCONCAT list — the timelapse pass-1
|
|
7409
7454
|
* input (`buildConcatPassArgs`). Sibling of the m3u8, same uniqueness rules.
|
|
7410
7455
|
*/
|
|
7411
7456
|
function exportSourceConcatPath(exportsDir, deviceId, exportId) {
|
|
7412
|
-
return path.join(exportsDir,
|
|
7457
|
+
return path.join(exportTenantDirFor(exportsDir, deviceId), `${exportId}.src.ffconcat`);
|
|
7413
7458
|
}
|
|
7414
7459
|
/**
|
|
7415
7460
|
* Write the export's source playlist and return it, or null when no segment of
|
|
@@ -16371,6 +16416,14 @@ var RecorderV2Addon = class extends BaseAddon {
|
|
|
16371
16416
|
* Every other node stays fully inert — registers no providers, serves no
|
|
16372
16417
|
* playback, runs no controller. Resolved in `onInitialize`. */
|
|
16373
16418
|
isRecordingNode = true;
|
|
16419
|
+
/**
|
|
16420
|
+
* Resolved root of the shared `artifacts` storage location — the export
|
|
16421
|
+
* MP4s' home and the GIF/clip render scratch. `null` until `onHubReachable`
|
|
16422
|
+
* resolves it (and forever if the location is unreachable): every consumer
|
|
16423
|
+
* then REFUSES with a named error instead of falling back to the addon data
|
|
16424
|
+
* dir (D341).
|
|
16425
|
+
*/
|
|
16426
|
+
exportsRoot = null;
|
|
16374
16427
|
index = new RecordingIndex();
|
|
16375
16428
|
/**
|
|
16376
16429
|
* Stops the GC-attributing stall monitor armed in {@link onInitialize}.
|
|
@@ -16786,12 +16839,12 @@ var RecorderV2Addon = class extends BaseAddon {
|
|
|
16786
16839
|
relocate: relocateEngine,
|
|
16787
16840
|
gifRender: (input) => renderGif({
|
|
16788
16841
|
deps: recordingDeps,
|
|
16789
|
-
exportsDir:
|
|
16842
|
+
exportsDir: this.exportsDirOrThrow(),
|
|
16790
16843
|
spawn
|
|
16791
16844
|
}, input),
|
|
16792
16845
|
clipRender: (input) => renderClip({
|
|
16793
16846
|
deps: recordingDeps,
|
|
16794
|
-
exportsDir:
|
|
16847
|
+
exportsDir: this.exportsDirOrThrow(),
|
|
16795
16848
|
spawn
|
|
16796
16849
|
}, input),
|
|
16797
16850
|
locations: () => this.resolvedLocations,
|
|
@@ -16906,8 +16959,7 @@ var RecorderV2Addon = class extends BaseAddon {
|
|
|
16906
16959
|
}
|
|
16907
16960
|
});
|
|
16908
16961
|
const exportsState = this.exportsStore();
|
|
16909
|
-
const
|
|
16910
|
-
const exportOutPath = (rec) => path.join(exportsDir, String(rec.deviceId), `${rec.id}.mp4`);
|
|
16962
|
+
const exportOutPath = (rec) => exportOutPathFor(this.exportsRoot, rec.deviceId, rec.id);
|
|
16911
16963
|
const removeExportFile = async (p) => {
|
|
16912
16964
|
await promises.rm(p, { force: true });
|
|
16913
16965
|
};
|
|
@@ -16919,7 +16971,7 @@ var RecorderV2Addon = class extends BaseAddon {
|
|
|
16919
16971
|
await promises.mkdir(path.dirname(exportOutPath(rec)), { recursive: true });
|
|
16920
16972
|
return writeExportSourcePlaylist({
|
|
16921
16973
|
deps: recordingDeps,
|
|
16922
|
-
exportsDir,
|
|
16974
|
+
exportsDir: this.exportsDirOrThrow(),
|
|
16923
16975
|
exportId: rec.id,
|
|
16924
16976
|
deviceId: rec.deviceId,
|
|
16925
16977
|
profile: rec.profile,
|
|
@@ -17154,6 +17206,18 @@ var RecorderV2Addon = class extends BaseAddon {
|
|
|
17154
17206
|
async onHubReachable() {
|
|
17155
17207
|
if (!this.isRecordingNode) return;
|
|
17156
17208
|
await this.refreshLocations();
|
|
17209
|
+
try {
|
|
17210
|
+
this.exportsRoot = await this.ctx.api.storage.resolve.query({
|
|
17211
|
+
location: ARTIFACTS_MEDIA_LOCATION,
|
|
17212
|
+
relativePath: ""
|
|
17213
|
+
});
|
|
17214
|
+
} catch (err) {
|
|
17215
|
+
this.ctx.logger.error("artifacts storage location is NOT available — exports, GIF and clip renders will REFUSE until it is", { meta: {
|
|
17216
|
+
location: ARTIFACTS_MEDIA_LOCATION,
|
|
17217
|
+
error: errMsg(err),
|
|
17218
|
+
hint: "the declaration is seeded when a storage-provider registers; restart this node so the manifest is re-read, or create an artifacts location. Refusing is deliberate — the addon data dir carries no media (D341)."
|
|
17219
|
+
} });
|
|
17220
|
+
}
|
|
17157
17221
|
if (this.resolvedLocations.length === 0) {
|
|
17158
17222
|
this.ctx.logger.warn("recorder: no recordings storage locations resolved — index not hydrated");
|
|
17159
17223
|
return;
|
|
@@ -17387,6 +17451,10 @@ var RecorderV2Addon = class extends BaseAddon {
|
|
|
17387
17451
|
async bootstrapExports() {
|
|
17388
17452
|
const engine = this.exportEngine;
|
|
17389
17453
|
if (!engine) return;
|
|
17454
|
+
if (this.exportsRoot === null) {
|
|
17455
|
+
this.ctx.logger.warn("recorder: exports bootstrap skipped — artifacts location unresolved");
|
|
17456
|
+
return;
|
|
17457
|
+
}
|
|
17390
17458
|
try {
|
|
17391
17459
|
await reconcileInterruptedExports({
|
|
17392
17460
|
state: this.exportsStore(),
|
|
@@ -17941,11 +18009,21 @@ var RecorderV2Addon = class extends BaseAddon {
|
|
|
17941
18009
|
placementStore() {
|
|
17942
18010
|
return this.state(RECORDING_PLACEMENT_KEY, RecordingPlacementBlobSchema, EMPTY_PLACEMENT);
|
|
17943
18011
|
}
|
|
18012
|
+
/** The artifacts class ROOT, or a NAMED refusal — never an invented path.
|
|
18013
|
+
* Every export-side path (MP4s, playlists, render scratch) derives from it
|
|
18014
|
+
* through `exportTenantDirFor` → `<root>/<deviceId>/exports/…`, beside
|
|
18015
|
+
* (never inside) the notification shelf's `<root>/<deviceId>/nc-artifacts/…`
|
|
18016
|
+
* sibling (D341). No consumer joins the path a second way. */
|
|
18017
|
+
exportsDirOrThrow() {
|
|
18018
|
+
const root = this.exportsRoot;
|
|
18019
|
+
if (root === null) throw new Error("artifacts storage location is not resolved — exports and footage renders refuse rather than fall back to the addon data dir (D341)");
|
|
18020
|
+
return root;
|
|
18021
|
+
}
|
|
17944
18022
|
/** Retention deps shared by the sweep and the download-complete hook. */
|
|
17945
18023
|
exportJanitorDeps() {
|
|
17946
18024
|
return {
|
|
17947
18025
|
state: this.exportsStore(),
|
|
17948
|
-
outPath: (rec) =>
|
|
18026
|
+
outPath: (rec) => exportOutPathFor(this.exportsRoot, rec.deviceId, rec.id),
|
|
17949
18027
|
removeFile: async (p) => {
|
|
17950
18028
|
await promises.rm(p, { force: true });
|
|
17951
18029
|
}
|
|
@@ -18001,7 +18079,13 @@ var RecorderV2Addon = class extends BaseAddon {
|
|
|
18001
18079
|
res.writeHead(404).end();
|
|
18002
18080
|
return;
|
|
18003
18081
|
}
|
|
18004
|
-
|
|
18082
|
+
let absPath;
|
|
18083
|
+
try {
|
|
18084
|
+
absPath = outPath(rec);
|
|
18085
|
+
} catch {
|
|
18086
|
+
res.writeHead(503).end();
|
|
18087
|
+
return;
|
|
18088
|
+
}
|
|
18005
18089
|
let size;
|
|
18006
18090
|
try {
|
|
18007
18091
|
const st = await promises.stat(absPath);
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { r as __toESM, t as __commonJSMin } from "./chunk-DnnnRqeS.mjs";
|
|
2
|
-
import { wt as errMsg } from "./dist-
|
|
2
|
+
import { wt as errMsg } from "./dist-A-CKFNg9.mjs";
|
|
3
3
|
import { spawn } from "node:child_process";
|
|
4
4
|
//#region ../../node_modules/mp4box/dist/mp4box.all.js
|
|
5
5
|
var require_mp4box_all = /* @__PURE__ */ __commonJSMin(((exports) => {
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
const require_dist = require("./dist-
|
|
1
|
+
const require_dist = require("./dist-CpmqDTel.js");
|
|
2
2
|
let node_child_process = require("node:child_process");
|
|
3
3
|
//#region ../../node_modules/mp4box/dist/mp4box.all.js
|
|
4
4
|
var require_mp4box_all = /* @__PURE__ */ require_dist.__commonJSMin(((exports) => {
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
|
|
2
|
-
const require_worker_protocol = require("../worker-protocol-
|
|
3
|
-
const require_lazy_sharp = require("../lazy-sharp-
|
|
2
|
+
const require_worker_protocol = require("../worker-protocol-IC_mPIhk.js");
|
|
3
|
+
const require_lazy_sharp = require("../lazy-sharp-c_IKosOs.js");
|
|
4
4
|
//#region src/session-decode/color-conversion.ts
|
|
5
5
|
/**
|
|
6
6
|
* Explicit YUV→RGB colorspace/range resolution for the session-decode worker.
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { i as formatNativeLeaseKnobs, n as isWorkerRequest, o as resolveNativeLeaseKnobs, r as logLevelForLine } from "../worker-protocol-
|
|
1
|
+
import { i as formatNativeLeaseKnobs, n as isWorkerRequest, o as resolveNativeLeaseKnobs, r as logLevelForLine } from "../worker-protocol-BuUyu8aI.mjs";
|
|
2
2
|
import { n as setSharpWarnSink, r as hostExternalEntryUrls, t as getSharp } from "../lazy-sharp-DXsqwpph.mjs";
|
|
3
3
|
//#region src/session-decode/color-conversion.ts
|
|
4
4
|
/**
|
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
import { a as e, c as t, d as n, f as r, i, l as a, n as o, o as s, p as c, r as l, s as u, t as d, u as f } from "./_virtual_mf___mfe_internal__addon_stream_broker_widgets__loadShare___mf_0_camstack_mf_1_ui_mf_2_library__loadShare__.js-
|
|
1
|
+
import { a as e, c as t, d as n, f as r, i, l as a, n as o, o as s, p as c, r as l, s as u, t as d, u as f } from "./_virtual_mf___mfe_internal__addon_stream_broker_widgets__loadShare___mf_0_camstack_mf_1_ui_mf_2_library__loadShare__.js-CwP-r0hs.mjs";
|
|
2
2
|
import { a as p, i as m, n as h, o as g, r as _, t as v } from "./_virtual_mf___mfe_internal__addon_stream_broker_widgets__loadShare__react__loadShare__.js-C9j-2lBe.mjs";
|
|
3
3
|
import { n as y, r as b, t as x } from "./_virtual_mf___mfe_internal__addon_stream_broker_widgets__loadShare__react_mf_1_jsx_mf_2_runtime__loadShare__.js-XO0-Pyu6.mjs";
|
|
4
|
-
import { t as S } from "./_virtual_mf___mfe_internal__addon_stream_broker_widgets__loadShare___mf_0_camstack_mf_1_types__loadShare__.js-
|
|
4
|
+
import { t as S } from "./_virtual_mf___mfe_internal__addon_stream_broker_widgets__loadShare___mf_0_camstack_mf_1_types__loadShare__.js-BVpZlsT7.mjs";
|
|
5
5
|
import { n as C, t as w } from "./_virtual_mf___mfe_internal__addon_stream_broker_widgets__loadShare___mf_0_tanstack_mf_1_react_mf_2_query__loadShare__.js-BO7TIbJV.mjs";
|
|
6
6
|
//#region ../../node_modules/lucide-react/dist/esm/shared/src/utils.js
|
|
7
7
|
var T = (e) => e.replace(/([a-z0-9])([A-Z])/g, "$1-$2").toLowerCase(), E = (e) => e.replace(/^([A-Z])|[\s-_]+(\w)/g, (e, t, n) => n ? n.toUpperCase() : t.toLowerCase()), D = (e) => {
|
|
@@ -3,7 +3,7 @@ import "./dist-CYZr2fwk.mjs";
|
|
|
3
3
|
var e = {
|
|
4
4
|
"@camstack/sdk": {
|
|
5
5
|
name: "@camstack/sdk",
|
|
6
|
-
version: "1.2.
|
|
6
|
+
version: "1.2.62",
|
|
7
7
|
scope: ["default"],
|
|
8
8
|
loaded: !1,
|
|
9
9
|
from: "addon_stream_broker_widgets",
|
|
@@ -18,7 +18,7 @@ var e = {
|
|
|
18
18
|
},
|
|
19
19
|
"@camstack/types": {
|
|
20
20
|
name: "@camstack/types",
|
|
21
|
-
version: "1.2.
|
|
21
|
+
version: "1.2.142",
|
|
22
22
|
scope: ["default"],
|
|
23
23
|
loaded: !1,
|
|
24
24
|
from: "addon_stream_broker_widgets",
|
|
@@ -33,7 +33,7 @@ var e = {
|
|
|
33
33
|
},
|
|
34
34
|
"@camstack/ui-library": {
|
|
35
35
|
name: "@camstack/ui-library",
|
|
36
|
-
version: "1.2.
|
|
36
|
+
version: "1.2.108",
|
|
37
37
|
scope: ["default"],
|
|
38
38
|
loaded: !1,
|
|
39
39
|
from: "addon_stream_broker_widgets",
|