@camstack/addon-pipeline 1.2.63 → 1.2.65
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 +1 -1
- package/dist/audio-analyzer/index.mjs +1 -1
- package/dist/detection-pipeline/index.js +2 -2
- package/dist/detection-pipeline/index.mjs +2 -2
- package/dist/{dist-DTvDedJV.mjs → dist-B9_C-QmC.mjs} +323 -38
- package/dist/{dist-BNXiD8pH.js → dist-DKrqeIfS.js} +323 -38
- package/dist/{event-loop-stall-monitor-RLis0vRd.mjs → event-loop-stall-monitor-BucTbe9v.mjs} +1 -1
- package/dist/{event-loop-stall-monitor-DmscRH8r.js → event-loop-stall-monitor-CnJ5JGA2.js} +1 -1
- package/dist/motion-wasm/index.js +1 -1
- package/dist/motion-wasm/index.mjs +1 -1
- package/dist/pipeline-runner/index.js +3 -3
- package/dist/pipeline-runner/index.mjs +3 -3
- package/dist/recorder/index.js +211 -41
- package/dist/recorder/index.mjs +211 -41
- package/dist/session-decode/decode-worker-child.js +1 -1
- 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-CFoXGKXX.mjs → _virtual_mf-localSharedImportMap___mfe_internal__addon_stream_broker_widgets-BCyIjQkw.mjs} +3 -3
- package/dist/stream-broker/{_virtual_mf___mfe_internal__addon_stream_broker_widgets__loadShare___mf_0_camstack_mf_1_types__loadShare__.js-Cp3o2Ve6.mjs → _virtual_mf___mfe_internal__addon_stream_broker_widgets__loadShare___mf_0_camstack_mf_1_types__loadShare__.js-C2tu4c14.mjs} +1 -1
- package/dist/stream-broker/{_virtual_mf___mfe_internal__addon_stream_broker_widgets__loadShare___mf_0_camstack_mf_1_ui_mf_2_library__loadShare__.js-Bw7zJGAQ.mjs → _virtual_mf___mfe_internal__addon_stream_broker_widgets__loadShare___mf_0_camstack_mf_1_ui_mf_2_library__loadShare__.js-CJAUKSrT.mjs} +1 -1
- package/dist/stream-broker/{hostInit-DqexQ1ED.mjs → hostInit-DqLdTCfo.mjs} +3 -3
- package/dist/stream-broker/index.js +119 -22
- package/dist/stream-broker/index.mjs +119 -22
- package/dist/stream-broker/remoteEntry.js +1 -1
- package/dist/{worker-protocol-D8ZsVii1.js → worker-protocol-CDkbdSuM.js} +1 -1
- package/dist/{worker-protocol-C3pPkCGe.mjs → worker-protocol-CQHY2NeB.mjs} +1 -1
- package/package.json +1 -1
- package/python/__pycache__/inference_pool.cpython-312.pyc +0 -0
- package/python/__pycache__/inference_pool.cpython-313.pyc +0 -0
- package/python/__pycache__/inference_pool.cpython-314.pyc +0 -0
- package/python/__pycache__/test_inference_pool_backpressure.cpython-314.pyc +0 -0
- package/python/__pycache__/test_inference_pool_coreml_cache.cpython-314.pyc +0 -0
- package/python/__pycache__/test_inference_pool_device_selection.cpython-314.pyc +0 -0
- package/python/__pycache__/test_inference_pool_layout.cpython-314.pyc +0 -0
- package/python/__pycache__/test_inference_pool_preprocess.cpython-314.pyc +0 -0
- package/python/__pycache__/yamnet_audio.cpython-314.pyc +0 -0
- package/python/postprocessors/__pycache__/__init__.cpython-312.pyc +0 -0
- package/python/postprocessors/__pycache__/__init__.cpython-313.pyc +0 -0
- package/python/postprocessors/__pycache__/__init__.cpython-314.pyc +0 -0
- package/python/postprocessors/__pycache__/_safety.cpython-313.pyc +0 -0
- package/python/postprocessors/__pycache__/arcface.cpython-312.pyc +0 -0
- package/python/postprocessors/__pycache__/arcface.cpython-313.pyc +0 -0
- package/python/postprocessors/__pycache__/arcface.cpython-314.pyc +0 -0
- package/python/postprocessors/__pycache__/clip.cpython-312.pyc +0 -0
- package/python/postprocessors/__pycache__/clip.cpython-313.pyc +0 -0
- package/python/postprocessors/__pycache__/clip.cpython-314.pyc +0 -0
- package/python/postprocessors/__pycache__/ctc.cpython-312.pyc +0 -0
- package/python/postprocessors/__pycache__/ctc.cpython-313.pyc +0 -0
- package/python/postprocessors/__pycache__/ctc.cpython-314.pyc +0 -0
- package/python/postprocessors/__pycache__/rfdetr.cpython-312.pyc +0 -0
- package/python/postprocessors/__pycache__/saliency.cpython-312.pyc +0 -0
- package/python/postprocessors/__pycache__/saliency.cpython-313.pyc +0 -0
- package/python/postprocessors/__pycache__/saliency.cpython-314.pyc +0 -0
- package/python/postprocessors/__pycache__/scrfd.cpython-312.pyc +0 -0
- package/python/postprocessors/__pycache__/scrfd.cpython-313.pyc +0 -0
- package/python/postprocessors/__pycache__/scrfd.cpython-314.pyc +0 -0
- package/python/postprocessors/__pycache__/softmax.cpython-312.pyc +0 -0
- package/python/postprocessors/__pycache__/softmax.cpython-313.pyc +0 -0
- package/python/postprocessors/__pycache__/softmax.cpython-314.pyc +0 -0
- package/python/postprocessors/__pycache__/ssd.cpython-312.pyc +0 -0
- package/python/postprocessors/__pycache__/ssd.cpython-313.pyc +0 -0
- package/python/postprocessors/__pycache__/ssd.cpython-314.pyc +0 -0
- package/python/postprocessors/__pycache__/test_clip.cpython-312-pytest-9.1.1.pyc +0 -0
- package/python/postprocessors/__pycache__/test_clip.cpython-313-pytest-9.1.1.pyc +0 -0
- package/python/postprocessors/__pycache__/test_ctc.cpython-312-pytest-9.1.1.pyc +0 -0
- package/python/postprocessors/__pycache__/test_ctc.cpython-312.pyc +0 -0
- package/python/postprocessors/__pycache__/test_ctc.cpython-313-pytest-9.1.1.pyc +0 -0
- package/python/postprocessors/__pycache__/test_ctc.cpython-313.pyc +0 -0
- package/python/postprocessors/__pycache__/test_rfdetr.cpython-312-pytest-9.1.1.pyc +0 -0
- package/python/postprocessors/__pycache__/test_saliency.cpython-312-pytest-9.1.1.pyc +0 -0
- package/python/postprocessors/__pycache__/test_saliency.cpython-313-pytest-9.1.1.pyc +0 -0
- package/python/postprocessors/__pycache__/test_softmax.cpython-312-pytest-9.1.1.pyc +0 -0
- package/python/postprocessors/__pycache__/test_yolo_nms.cpython-312-pytest-9.1.1.pyc +0 -0
- package/python/postprocessors/__pycache__/test_yolo_nms.cpython-39.pyc +0 -0
- package/python/postprocessors/__pycache__/yamnet.cpython-312.pyc +0 -0
- package/python/postprocessors/__pycache__/yamnet.cpython-313.pyc +0 -0
- package/python/postprocessors/__pycache__/yamnet.cpython-314.pyc +0 -0
- package/python/postprocessors/__pycache__/yolo.cpython-312.pyc +0 -0
- package/python/postprocessors/__pycache__/yolo.cpython-313.pyc +0 -0
- package/python/postprocessors/__pycache__/yolo.cpython-314.pyc +0 -0
- package/python/postprocessors/__pycache__/yolo.cpython-39.pyc +0 -0
- package/python/postprocessors/__pycache__/yolo_seg.cpython-312.pyc +0 -0
- package/python/postprocessors/__pycache__/yolo_seg.cpython-313.pyc +0 -0
- package/python/postprocessors/__pycache__/yolo_seg.cpython-314.pyc +0 -0
package/dist/recorder/index.mjs
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { K as recordingCapability, M as deriveRecordingMode, Ot as record, X as storageEvictableCapability, _ as OpsLogEntrySchema, b as RecordingConfigSchema, c as DEFAULT_EVENTS_BAND_BUFFER_SEC, d as EVENT_PAD_MS, dt as hydrateSchema, et as errMsg, ht as nodePin, jt as EventCategory, kt as string, lt as DeviceType, ot as BaseAddon, p as ExportRecordSchema, q as recordingExportCapability, vt as selectAssignedProfileSlots, xt as array } from "../dist-
|
|
1
|
+
import { K as recordingCapability, M as deriveRecordingMode, Ot as record, X as storageEvictableCapability, _ as OpsLogEntrySchema, b as RecordingConfigSchema, c as DEFAULT_EVENTS_BAND_BUFFER_SEC, d as EVENT_PAD_MS, dt as hydrateSchema, et as errMsg, ht as nodePin, jt as EventCategory, kt as string, lt as DeviceType, ot as BaseAddon, p as ExportRecordSchema, q as recordingExportCapability, vt as selectAssignedProfileSlots, xt as array } from "../dist-B9_C-QmC.mjs";
|
|
2
2
|
import { t as resolveHubHostname } from "../hub-hostname-cCknRYKj.mjs";
|
|
3
3
|
import { n as createFileDataPlaneHandler, s as parseRangeHeader, t as contentTypeFor } from "../addon-utils-CZ2xo67g.mjs";
|
|
4
4
|
import { randomUUID } from "node:crypto";
|
|
@@ -2771,12 +2771,28 @@ function buildRecordingProvider(deps) {
|
|
|
2771
2771
|
if (!deps.gifRender) throw new Error("gif rendering unavailable on this node");
|
|
2772
2772
|
return deps.gifRender(input);
|
|
2773
2773
|
},
|
|
2774
|
-
|
|
2774
|
+
pauseForStorageMigration: async ({ leaseId }) => {
|
|
2775
|
+
if (!deps.pauseForStorageMigration) throw new Error("storage migration pause unavailable");
|
|
2776
|
+
await deps.pauseForStorageMigration(leaseId);
|
|
2777
|
+
return { paused: true };
|
|
2778
|
+
},
|
|
2779
|
+
resumeForStorageMigration: async ({ leaseId }) => {
|
|
2780
|
+
if (!deps.resumeForStorageMigration) throw new Error("storage migration resume unavailable");
|
|
2781
|
+
await deps.resumeForStorageMigration(leaseId);
|
|
2782
|
+
return { resumed: true };
|
|
2783
|
+
},
|
|
2784
|
+
refreshStorageLocationsForMigration: async ({ leaseId }) => {
|
|
2785
|
+
if (!deps.refreshStorageLocationsForMigration) throw new Error("storage migration location refresh unavailable");
|
|
2786
|
+
await deps.refreshStorageLocationsForMigration(leaseId);
|
|
2787
|
+
return { refreshed: true };
|
|
2788
|
+
},
|
|
2789
|
+
startStorageMigrationMove: async (input) => {
|
|
2775
2790
|
if (!deps.relocate) throw new Error("relocation unavailable on this node");
|
|
2791
|
+
deps.assertStorageMigrationLease?.(input.leaseId);
|
|
2776
2792
|
return { jobId: deps.relocate.start(input) };
|
|
2777
2793
|
},
|
|
2778
|
-
|
|
2779
|
-
|
|
2794
|
+
getStorageMigrationMoveStatus: async ({ jobId }) => deps.relocate?.list().find((job) => job.jobId === jobId) ?? null,
|
|
2795
|
+
cancelStorageMigrationMove: async ({ jobId }) => ({ cancelled: deps.relocate?.cancel(jobId) ?? false }),
|
|
2780
2796
|
getDeviceSettingsContribution: async ({ deviceId }) => {
|
|
2781
2797
|
if (deps.isCameraDevice && !await deps.isCameraDevice(deviceId)) return null;
|
|
2782
2798
|
return hydrateSchema(buildRecordingDeviceSchema(), {});
|
|
@@ -3388,7 +3404,31 @@ function resolvePlacement(locations, profile) {
|
|
|
3388
3404
|
const writable = locations.filter((l) => !l.readOnly);
|
|
3389
3405
|
if (writable.length === 0) throw new Error("recorder controller: every recordings location is read-only — nowhere to write");
|
|
3390
3406
|
const preferType = profile === "low" ? "recordingsLow" : "recordings";
|
|
3391
|
-
|
|
3407
|
+
const preferred = writable.filter((l) => l.type === preferType);
|
|
3408
|
+
return preferred.find((l) => l.isDefault) ?? preferred[0] ?? writable.find((l) => l.isDefault) ?? writable[0];
|
|
3409
|
+
}
|
|
3410
|
+
/**
|
|
3411
|
+
* Attribute a discovered segment on an aliased physical root by its profile,
|
|
3412
|
+
* not by whichever logical location happened to be hydrated last. Stock
|
|
3413
|
+
* `recordings` and `recordingsLow` deliberately share a root: high/mid belong
|
|
3414
|
+
* to `recordings`, while low belongs to `recordingsLow`.
|
|
3415
|
+
*/
|
|
3416
|
+
function locationForHydratedProfile(aliases, profile) {
|
|
3417
|
+
const preferredType = profile === "low" ? "recordingsLow" : "recordings";
|
|
3418
|
+
const preferred = aliases.filter((location) => location.type === preferredType).toSorted((a, b) => a.id.localeCompare(b.id))[0];
|
|
3419
|
+
const fallback = aliases.toSorted((a, b) => a.id.localeCompare(b.id))[0];
|
|
3420
|
+
if (preferred) return preferred;
|
|
3421
|
+
if (fallback) return fallback;
|
|
3422
|
+
throw new Error("recorder: no location aliases to attribute hydrated profile");
|
|
3423
|
+
}
|
|
3424
|
+
function aliasesByRoot(locations) {
|
|
3425
|
+
const grouped = /* @__PURE__ */ new Map();
|
|
3426
|
+
for (const location of locations) {
|
|
3427
|
+
const aliases = grouped.get(location.root);
|
|
3428
|
+
if (aliases) aliases.push(location);
|
|
3429
|
+
else grouped.set(location.root, [location]);
|
|
3430
|
+
}
|
|
3431
|
+
return grouped;
|
|
3392
3432
|
}
|
|
3393
3433
|
/**
|
|
3394
3434
|
* Resolve every recordings storage location (`recordings` + `recordingsLow`)
|
|
@@ -3405,7 +3445,8 @@ async function resolveRecordingsLocations(api, logger) {
|
|
|
3405
3445
|
location: l.id,
|
|
3406
3446
|
relativePath: ""
|
|
3407
3447
|
}),
|
|
3408
|
-
readOnly: l.config["readOnly"] === true
|
|
3448
|
+
readOnly: l.config["readOnly"] === true,
|
|
3449
|
+
isDefault: l.isDefault
|
|
3409
3450
|
})));
|
|
3410
3451
|
} catch (err) {
|
|
3411
3452
|
logger.warn("recorder: listLocations failed — no recordings locations resolved", { meta: { error: errMsg(err) } });
|
|
@@ -3421,8 +3462,8 @@ async function resolveRecordingsLocations(api, logger) {
|
|
|
3421
3462
|
* (best-effort), so one bad volume never blocks the rest of the hydrate.
|
|
3422
3463
|
*/
|
|
3423
3464
|
async function hydrateDeviceFromStorage(_api, index, deviceId, locations, logger) {
|
|
3424
|
-
for (const
|
|
3425
|
-
const deviceDir = path.join(
|
|
3465
|
+
for (const [root, aliases] of aliasesByRoot(locations)) {
|
|
3466
|
+
const deviceDir = path.join(root, String(deviceId));
|
|
3426
3467
|
let entries;
|
|
3427
3468
|
try {
|
|
3428
3469
|
entries = await promises.readdir(deviceDir, { recursive: true });
|
|
@@ -3430,14 +3471,21 @@ async function hydrateDeviceFromStorage(_api, index, deviceId, locations, logger
|
|
|
3430
3471
|
if (err.code !== "ENOENT") logger.warn("recorder: hydrateDevice walk failed for location", {
|
|
3431
3472
|
tags: { deviceId },
|
|
3432
3473
|
meta: {
|
|
3433
|
-
|
|
3474
|
+
locationIds: aliases.map((location) => location.id),
|
|
3434
3475
|
error: errMsg(err)
|
|
3435
3476
|
}
|
|
3436
3477
|
});
|
|
3437
3478
|
continue;
|
|
3438
3479
|
}
|
|
3439
|
-
const
|
|
3440
|
-
|
|
3480
|
+
const pathsByLocation = /* @__PURE__ */ new Map();
|
|
3481
|
+
for (const entry of entries.filter((entry) => entry.endsWith(".m4s"))) {
|
|
3482
|
+
const relative = `${deviceId}/${entry.split(path.sep).join("/")}`;
|
|
3483
|
+
const location = locationForHydratedProfile(aliases, relative.split("/")[1] ?? "");
|
|
3484
|
+
const paths = pathsByLocation.get(location.id);
|
|
3485
|
+
if (paths) paths.push(relative);
|
|
3486
|
+
else pathsByLocation.set(location.id, [relative]);
|
|
3487
|
+
}
|
|
3488
|
+
for (const [locationId, relPaths] of pathsByLocation) index.hydrateDevice(deviceId, locationId, relPaths);
|
|
3441
3489
|
}
|
|
3442
3490
|
}
|
|
3443
3491
|
/** `<deviceId>/<profile>/YYYY/MM/DD/HH` for an hour bucket (paths are UTC). */
|
|
@@ -3466,8 +3514,8 @@ var HOUR_MS = 36e5;
|
|
|
3466
3514
|
*/
|
|
3467
3515
|
async function hydrateWindowFromStorage(index, deviceId, fromMs, toMs, locations, logger) {
|
|
3468
3516
|
if (index.hydrationOf(deviceId, fromMs, toMs) === "hydrated") return;
|
|
3469
|
-
for (const
|
|
3470
|
-
const deviceDir = path.join(
|
|
3517
|
+
for (const [root, aliases] of aliasesByRoot(locations)) {
|
|
3518
|
+
const deviceDir = path.join(root, String(deviceId));
|
|
3471
3519
|
let profiles;
|
|
3472
3520
|
try {
|
|
3473
3521
|
profiles = (await promises.readdir(deviceDir)).filter((e) => e === "high" || e === "mid" || e === "low");
|
|
@@ -3475,7 +3523,7 @@ async function hydrateWindowFromStorage(index, deviceId, fromMs, toMs, locations
|
|
|
3475
3523
|
if (err.code !== "ENOENT") logger.warn("recorder: hydrateWindow profile listing failed", {
|
|
3476
3524
|
tags: { deviceId },
|
|
3477
3525
|
meta: {
|
|
3478
|
-
|
|
3526
|
+
locationIds: aliases.map((location) => location.id),
|
|
3479
3527
|
error: errMsg(err)
|
|
3480
3528
|
}
|
|
3481
3529
|
});
|
|
@@ -3486,11 +3534,11 @@ async function hydrateWindowFromStorage(index, deviceId, fromMs, toMs, locations
|
|
|
3486
3534
|
const rel = hourDirRelPath(deviceId, profile, hour);
|
|
3487
3535
|
let files;
|
|
3488
3536
|
try {
|
|
3489
|
-
files = await promises.readdir(path.join(
|
|
3537
|
+
files = await promises.readdir(path.join(root, rel));
|
|
3490
3538
|
} catch {
|
|
3491
3539
|
continue;
|
|
3492
3540
|
}
|
|
3493
|
-
index.hydrateHour(deviceId,
|
|
3541
|
+
index.hydrateHour(deviceId, locationForHydratedProfile(aliases, profile).id, hour, files.filter((f) => f.endsWith(".m4s")).map((f) => `${rel}/${f}`));
|
|
3494
3542
|
}
|
|
3495
3543
|
index.markHydrated(deviceId, fromMs, toMs);
|
|
3496
3544
|
}
|
|
@@ -3773,7 +3821,7 @@ async function handleSegmentEntry(outDir, entry, durMs, onFinalized, logger) {
|
|
|
3773
3821
|
logger.debug("segment flat file not on disk yet — will retry", { meta: { path: flatAbsPath } });
|
|
3774
3822
|
return "pending";
|
|
3775
3823
|
}
|
|
3776
|
-
onFinalized(startMs, durMs, flatAbsPath);
|
|
3824
|
+
await onFinalized(startMs, durMs, flatAbsPath);
|
|
3777
3825
|
return "retained";
|
|
3778
3826
|
}
|
|
3779
3827
|
/**
|
|
@@ -3786,11 +3834,11 @@ async function handleSegmentEntry(outDir, entry, durMs, onFinalized, logger) {
|
|
|
3786
3834
|
* inflated by the initial PTS offset). Once `#EXT-X-ENDLIST` appears the tail
|
|
3787
3835
|
* is flushed too — by then it is never the unreliable first segment.
|
|
3788
3836
|
*/
|
|
3789
|
-
function planFinalizations(body, processed) {
|
|
3837
|
+
function planFinalizations(body, processed, forceFinal = false) {
|
|
3790
3838
|
const entries = parseLivePlaylist(body);
|
|
3791
3839
|
const endlist = body.includes("#EXT-X-ENDLIST");
|
|
3792
3840
|
const hw = entries.length < processed ? 0 : processed;
|
|
3793
|
-
const finalizable = endlist ? entries.length : Math.max(0, entries.length - 1);
|
|
3841
|
+
const finalizable = endlist || forceFinal ? entries.length : Math.max(0, entries.length - 1);
|
|
3794
3842
|
const toHandle = [];
|
|
3795
3843
|
for (let i = hw; i < finalizable; i++) {
|
|
3796
3844
|
const entry = entries[i];
|
|
@@ -3818,9 +3866,10 @@ function startSegmentWatcher(deps) {
|
|
|
3818
3866
|
let processed = 0;
|
|
3819
3867
|
let stopped = false;
|
|
3820
3868
|
let ticking = false;
|
|
3869
|
+
let currentTick = null;
|
|
3821
3870
|
let pendingIndex = -1;
|
|
3822
3871
|
let pendingTicks = 0;
|
|
3823
|
-
const tick = async () => {
|
|
3872
|
+
const tick = async (forceFinal = false) => {
|
|
3824
3873
|
if (stopped || ticking) return;
|
|
3825
3874
|
ticking = true;
|
|
3826
3875
|
try {
|
|
@@ -3830,7 +3879,7 @@ function startSegmentWatcher(deps) {
|
|
|
3830
3879
|
} catch {
|
|
3831
3880
|
return;
|
|
3832
3881
|
}
|
|
3833
|
-
const plan = planFinalizations(body, processed);
|
|
3882
|
+
const plan = planFinalizations(body, processed, forceFinal);
|
|
3834
3883
|
let index = plan.from;
|
|
3835
3884
|
for (const { entry, durMs } of plan.toHandle) {
|
|
3836
3885
|
if (await handleSegmentEntry(deps.outDir, entry, durMs, deps.onFinalized, deps.logger) === "pending") {
|
|
@@ -3860,14 +3909,31 @@ function startSegmentWatcher(deps) {
|
|
|
3860
3909
|
ticking = false;
|
|
3861
3910
|
}
|
|
3862
3911
|
};
|
|
3912
|
+
const startTick = (forceFinal = false) => {
|
|
3913
|
+
if (currentTick !== null) return currentTick;
|
|
3914
|
+
const running = tick(forceFinal);
|
|
3915
|
+
currentTick = running;
|
|
3916
|
+
running.then(() => {
|
|
3917
|
+
if (currentTick === running) currentTick = null;
|
|
3918
|
+
}, () => {
|
|
3919
|
+
if (currentTick === running) currentTick = null;
|
|
3920
|
+
});
|
|
3921
|
+
return running;
|
|
3922
|
+
};
|
|
3863
3923
|
const timer = setInterval(() => {
|
|
3864
|
-
|
|
3924
|
+
startTick();
|
|
3865
3925
|
}, deps.intervalMs);
|
|
3866
3926
|
timer.unref?.();
|
|
3867
|
-
return {
|
|
3868
|
-
|
|
3869
|
-
|
|
3870
|
-
|
|
3927
|
+
return {
|
|
3928
|
+
stop() {
|
|
3929
|
+
stopped = true;
|
|
3930
|
+
clearInterval(timer);
|
|
3931
|
+
},
|
|
3932
|
+
flush: async () => {
|
|
3933
|
+
await currentTick;
|
|
3934
|
+
await startTick(true);
|
|
3935
|
+
}
|
|
3936
|
+
};
|
|
3871
3937
|
}
|
|
3872
3938
|
//#endregion
|
|
3873
3939
|
//#region src/recorder/addon/ffmpeg-args.ts
|
|
@@ -3935,6 +4001,8 @@ var SegmentWriter = class {
|
|
|
3935
4001
|
restarts = 0;
|
|
3936
4002
|
restartTimer = null;
|
|
3937
4003
|
startedAt = 0;
|
|
4004
|
+
exitWait = null;
|
|
4005
|
+
resolveExit = null;
|
|
3938
4006
|
constructor(cfg, deps) {
|
|
3939
4007
|
this.cfg = cfg;
|
|
3940
4008
|
this.deps = deps;
|
|
@@ -3944,6 +4012,9 @@ var SegmentWriter = class {
|
|
|
3944
4012
|
const args = buildPassthroughArgs(this.cfg);
|
|
3945
4013
|
const proc = this.deps.spawn(this.deps.ffmpegPath ?? "ffmpeg", args);
|
|
3946
4014
|
this.proc = proc;
|
|
4015
|
+
this.exitWait = new Promise((resolve) => {
|
|
4016
|
+
this.resolveExit = resolve;
|
|
4017
|
+
});
|
|
3947
4018
|
this.startedAt = Date.now();
|
|
3948
4019
|
const stderrTail = [];
|
|
3949
4020
|
proc.stderr?.on("data", (chunk) => {
|
|
@@ -3956,6 +4027,8 @@ var SegmentWriter = class {
|
|
|
3956
4027
|
}
|
|
3957
4028
|
});
|
|
3958
4029
|
proc.on("exit", (code) => {
|
|
4030
|
+
this.resolveExit?.();
|
|
4031
|
+
this.resolveExit = null;
|
|
3959
4032
|
this.proc = null;
|
|
3960
4033
|
if (this.stopped) return;
|
|
3961
4034
|
const ranMs = Date.now() - this.startedAt;
|
|
@@ -3985,12 +4058,22 @@ var SegmentWriter = class {
|
|
|
3985
4058
|
});
|
|
3986
4059
|
}
|
|
3987
4060
|
stop() {
|
|
4061
|
+
this.stopAndWait();
|
|
4062
|
+
}
|
|
4063
|
+
/**
|
|
4064
|
+
* Stop ffmpeg and wait for its exit when the process exposes real child
|
|
4065
|
+
* liveness fields. Test fakes often omit them, in which case stop remains
|
|
4066
|
+
* deliberately synchronous. The recorder keeps its watcher alive until this
|
|
4067
|
+
* promise settles, so a final ENDLIST segment is indexed before migration.
|
|
4068
|
+
*/
|
|
4069
|
+
async stopAndWait() {
|
|
3988
4070
|
this.stopped = true;
|
|
3989
4071
|
if (this.restartTimer) {
|
|
3990
4072
|
clearTimeout(this.restartTimer);
|
|
3991
4073
|
this.restartTimer = null;
|
|
3992
4074
|
}
|
|
3993
4075
|
const proc = this.proc;
|
|
4076
|
+
const exitWait = this.exitWait;
|
|
3994
4077
|
this.proc = null;
|
|
3995
4078
|
if (!proc) return;
|
|
3996
4079
|
try {
|
|
@@ -4001,6 +4084,8 @@ var SegmentWriter = class {
|
|
|
4001
4084
|
proc.kill("SIGKILL");
|
|
4002
4085
|
} catch {}
|
|
4003
4086
|
}, KILL_GRACE_MS).unref?.();
|
|
4087
|
+
if (proc.exitCode === void 0 && proc.signalCode === void 0) return;
|
|
4088
|
+
await exitWait;
|
|
4004
4089
|
}
|
|
4005
4090
|
};
|
|
4006
4091
|
//#endregion
|
|
@@ -4117,6 +4202,9 @@ var RecordingController = class {
|
|
|
4117
4202
|
* a `finally`. Mirrors the decoder-ffmpeg session-creation coalescing guard.
|
|
4118
4203
|
*/
|
|
4119
4204
|
attaching = /* @__PURE__ */ new Set();
|
|
4205
|
+
/** Every attach admitted before a maintenance pause. The pause waits these
|
|
4206
|
+
* promises before it snapshots/drains active writers. */
|
|
4207
|
+
attachingTasks = /* @__PURE__ */ new Map();
|
|
4120
4208
|
/** Latest qualifying trigger timestamps per device — drives `events`-band gating. */
|
|
4121
4209
|
triggers = /* @__PURE__ */ new Map();
|
|
4122
4210
|
/**
|
|
@@ -4136,6 +4224,9 @@ var RecordingController = class {
|
|
|
4136
4224
|
restore = null;
|
|
4137
4225
|
tickTimer = null;
|
|
4138
4226
|
stopped = false;
|
|
4227
|
+
/** A reversible maintenance lease. Unlike `stopped`, it never changes
|
|
4228
|
+
* persisted recording intent and `resume()` restarts normal convergence. */
|
|
4229
|
+
paused = false;
|
|
4139
4230
|
constructor(deps) {
|
|
4140
4231
|
this.deps = deps;
|
|
4141
4232
|
}
|
|
@@ -4200,7 +4291,7 @@ var RecordingController = class {
|
|
|
4200
4291
|
* has already been written by the time this runs.
|
|
4201
4292
|
*/
|
|
4202
4293
|
async onConfigChanged(deviceId) {
|
|
4203
|
-
if (this.stopped) return;
|
|
4294
|
+
if (this.stopped || this.paused) return;
|
|
4204
4295
|
await this.evaluateDevice(deviceId);
|
|
4205
4296
|
}
|
|
4206
4297
|
/**
|
|
@@ -4306,8 +4397,9 @@ var RecordingController = class {
|
|
|
4306
4397
|
* call throws → `ReadinessRestore.attempt` defers → retried on next ready).
|
|
4307
4398
|
*/
|
|
4308
4399
|
async evaluateDevice(deviceId) {
|
|
4309
|
-
if (this.stopped) return;
|
|
4400
|
+
if (this.stopped || this.paused) return;
|
|
4310
4401
|
const config = await this.deps.loadConfig(deviceId);
|
|
4402
|
+
if (this.stopped || this.paused) return;
|
|
4311
4403
|
if (!shouldRecordAt(config, this.triggersFor(deviceId), new Date(this.now()))) {
|
|
4312
4404
|
this.reportUnrecordable(deviceId, config);
|
|
4313
4405
|
await this.detachDevice(deviceId);
|
|
@@ -4318,9 +4410,12 @@ var RecordingController = class {
|
|
|
4318
4410
|
if (this.active.has(deviceId)) return;
|
|
4319
4411
|
if (this.attaching.has(deviceId)) return;
|
|
4320
4412
|
this.attaching.add(deviceId);
|
|
4413
|
+
const attaching = this.performAttach(deviceId, config);
|
|
4414
|
+
this.attachingTasks.set(deviceId, attaching);
|
|
4321
4415
|
try {
|
|
4322
|
-
await
|
|
4416
|
+
await attaching;
|
|
4323
4417
|
} finally {
|
|
4418
|
+
this.attachingTasks.delete(deviceId);
|
|
4324
4419
|
this.attaching.delete(deviceId);
|
|
4325
4420
|
}
|
|
4326
4421
|
}
|
|
@@ -4378,6 +4473,10 @@ var RecordingController = class {
|
|
|
4378
4473
|
for (const r of recordings) await this.teardownProfile(deviceId, r);
|
|
4379
4474
|
throw err;
|
|
4380
4475
|
}
|
|
4476
|
+
if (this.paused) {
|
|
4477
|
+
await Promise.all(recordings.map((recording) => this.teardownProfile(deviceId, recording)));
|
|
4478
|
+
return;
|
|
4479
|
+
}
|
|
4381
4480
|
this.active.set(deviceId, recordings);
|
|
4382
4481
|
this.deps.logger.info("recorder pinned broker source(s) for recording", {
|
|
4383
4482
|
tags: { deviceId },
|
|
@@ -4440,9 +4539,9 @@ var RecordingController = class {
|
|
|
4440
4539
|
watcher: startSegmentWatcher({
|
|
4441
4540
|
outDir,
|
|
4442
4541
|
intervalMs: this.deps.watchIntervalMs > 0 ? this.deps.watchIntervalMs : DEFAULT_WATCH_INTERVAL_MS,
|
|
4443
|
-
onFinalized: (startMs, durMs, flatAbsPath) => {
|
|
4542
|
+
onFinalized: async (startMs, durMs, flatAbsPath) => {
|
|
4444
4543
|
this.lastSegmentAt.set(idleKey(deviceId, profile), this.now());
|
|
4445
|
-
this.handleFinalizedSegment(deviceId, profile, placement, startMs, durMs, flatAbsPath);
|
|
4544
|
+
await this.handleFinalizedSegment(deviceId, profile, placement, startMs, durMs, flatAbsPath);
|
|
4446
4545
|
},
|
|
4447
4546
|
logger: deviceLog
|
|
4448
4547
|
}),
|
|
@@ -4497,10 +4596,13 @@ var RecordingController = class {
|
|
|
4497
4596
|
/** Stop one profile's writer + watcher and release its broker lease. */
|
|
4498
4597
|
async teardownProfile(deviceId, r) {
|
|
4499
4598
|
try {
|
|
4500
|
-
r.
|
|
4599
|
+
await r.writer.stopAndWait();
|
|
4501
4600
|
} catch {}
|
|
4502
4601
|
try {
|
|
4503
|
-
r.
|
|
4602
|
+
await r.watcher.flush?.();
|
|
4603
|
+
} catch {}
|
|
4604
|
+
try {
|
|
4605
|
+
r.watcher.stop();
|
|
4504
4606
|
} catch {}
|
|
4505
4607
|
try {
|
|
4506
4608
|
await withDeadline(this.deps.api.streamBroker.releaseStreamWithCodec.mutate({ pipelineKey: r.pipelineKey }, nodePin(this.deps.ownerNodeId)), RELEASE_RPC_TIMEOUT_MS, "releaseStreamWithCodec");
|
|
@@ -4527,6 +4629,25 @@ var RecordingController = class {
|
|
|
4527
4629
|
meta: { pipelineKeys: recordings.map((r) => r.pipelineKey) }
|
|
4528
4630
|
});
|
|
4529
4631
|
}
|
|
4632
|
+
/** Acquire a reversible maintenance pause without mutating camera settings. */
|
|
4633
|
+
async pause() {
|
|
4634
|
+
if (this.stopped || this.paused) return;
|
|
4635
|
+
this.paused = true;
|
|
4636
|
+
while (this.attachingTasks.size > 0) await Promise.allSettled([...this.attachingTasks.values()]);
|
|
4637
|
+
await Promise.all(Array.from(this.active.keys()).map((deviceId) => this.detachDevice(deviceId)));
|
|
4638
|
+
}
|
|
4639
|
+
/** Release the maintenance pause and converge persisted recording intent. */
|
|
4640
|
+
async resume() {
|
|
4641
|
+
if (this.stopped || !this.paused) return;
|
|
4642
|
+
this.paused = false;
|
|
4643
|
+
let ids = [];
|
|
4644
|
+
try {
|
|
4645
|
+
ids = await this.deps.enabledDeviceIds();
|
|
4646
|
+
} catch (err) {
|
|
4647
|
+
this.deps.logger.warn("recorder: resume could not enumerate configured devices", { meta: { error: errMsg(err) } });
|
|
4648
|
+
}
|
|
4649
|
+
for (const deviceId of ids) await this.evaluateDevice(deviceId);
|
|
4650
|
+
}
|
|
4530
4651
|
/** Tear EVERYTHING down: timer, restore subscription, every writer/watcher/lease. */
|
|
4531
4652
|
async stop() {
|
|
4532
4653
|
this.stopped = true;
|
|
@@ -4749,14 +4870,13 @@ var RelocateEngine = class {
|
|
|
4749
4870
|
if (!from) throw new Error(`unknown source location: ${input.fromLocationId}`);
|
|
4750
4871
|
if (!to) throw new Error(`unknown target location: ${input.toLocationId}`);
|
|
4751
4872
|
if (from.id === to.id) throw new Error("source and target locations are identical");
|
|
4752
|
-
if (from.root === to.root) throw new Error("source and target locations share one root — nothing to move");
|
|
4753
4873
|
if (to.readOnly) throw new Error(`target location is read-only: ${to.id}`);
|
|
4754
4874
|
const job = {
|
|
4755
4875
|
jobId: this.deps.newId(),
|
|
4756
4876
|
state: "running",
|
|
4757
4877
|
fromLocationId: from.id,
|
|
4758
4878
|
toLocationId: to.id,
|
|
4759
|
-
deviceId:
|
|
4879
|
+
deviceId: null,
|
|
4760
4880
|
entities: input.entities ? [...input.entities] : ["segments"],
|
|
4761
4881
|
filesMoved: 0,
|
|
4762
4882
|
bytesMoved: 0,
|
|
@@ -4767,23 +4887,33 @@ var RelocateEngine = class {
|
|
|
4767
4887
|
cancelRequested: false
|
|
4768
4888
|
};
|
|
4769
4889
|
this.jobs.set(job.jobId, job);
|
|
4770
|
-
this.run(job, from, to, input.throttleMbps ?? DEFAULT_THROTTLE_MBPS);
|
|
4890
|
+
this.run(job, from, to, input.throttleMbps ?? DEFAULT_THROTTLE_MBPS, input.footageClass);
|
|
4771
4891
|
return job.jobId;
|
|
4772
4892
|
}
|
|
4773
|
-
async run(job, from, to, throttleMbps) {
|
|
4893
|
+
async run(job, from, to, throttleMbps, footageClass) {
|
|
4774
4894
|
const sleep = this.deps.sleep ?? ((ms) => new Promise((r) => setTimeout(r, ms)));
|
|
4775
4895
|
const bytesPerMs = throttleMbps * 1024 * 1024 / 1e3;
|
|
4776
4896
|
try {
|
|
4777
|
-
const
|
|
4897
|
+
const samePhysicalRoot = await rootsPhysicallySame(from.root, to.root);
|
|
4898
|
+
const segRows = job.entities.includes("segments") === false ? [] : this.deps.index.segmentsOnLocation(from.id).filter((r) => profileBelongsToClass(r.profile, footageClass)).sort((a, b) => a.startMs - b.startMs);
|
|
4778
4899
|
job.filesTotal = segRows.length;
|
|
4779
4900
|
for (const row of segRows) {
|
|
4780
4901
|
if (job.cancelRequested) break;
|
|
4781
|
-
await this.moveSegment(row, from, to);
|
|
4902
|
+
await this.moveSegment(row, from, to, samePhysicalRoot);
|
|
4782
4903
|
job.filesMoved++;
|
|
4783
4904
|
job.bytesMoved += row.bytes;
|
|
4784
4905
|
if (job.filesMoved % PROGRESS_EVERY_FILES === 0) this.deps.onProgress?.(snapshot(job));
|
|
4785
4906
|
await sleep(row.bytes / bytesPerMs);
|
|
4786
4907
|
}
|
|
4908
|
+
async function rootsPhysicallySame(from, to) {
|
|
4909
|
+
if (physicalRootKey(from) === physicalRootKey(to)) return true;
|
|
4910
|
+
try {
|
|
4911
|
+
const [a, b] = await Promise.all([promises.stat(from), promises.stat(to)]);
|
|
4912
|
+
return a.dev === b.dev && a.ino === b.ino;
|
|
4913
|
+
} catch {
|
|
4914
|
+
return false;
|
|
4915
|
+
}
|
|
4916
|
+
}
|
|
4787
4917
|
job.state = job.cancelRequested ? "cancelled" : "done";
|
|
4788
4918
|
} catch (err) {
|
|
4789
4919
|
job.state = "failed";
|
|
@@ -4799,8 +4929,8 @@ var RelocateEngine = class {
|
|
|
4799
4929
|
}
|
|
4800
4930
|
/** Move one segment file and re-point its index row to the target location
|
|
4801
4931
|
* (same location-relative path — the layout is identical on every root). */
|
|
4802
|
-
async moveSegment(row, from, to) {
|
|
4803
|
-
await moveFile(path.join(from.root, row.path), path.join(to.root, row.path), row.bytes);
|
|
4932
|
+
async moveSegment(row, from, to, samePhysicalRoot) {
|
|
4933
|
+
if (!samePhysicalRoot) await moveFile(path.join(from.root, row.path), path.join(to.root, row.path), row.bytes);
|
|
4804
4934
|
this.deps.index.removeSegments([row.path]);
|
|
4805
4935
|
this.deps.index.addSegment({
|
|
4806
4936
|
...row,
|
|
@@ -4808,6 +4938,12 @@ var RelocateEngine = class {
|
|
|
4808
4938
|
});
|
|
4809
4939
|
}
|
|
4810
4940
|
};
|
|
4941
|
+
/** Logical migration classes are profile-derived, never location-derived:
|
|
4942
|
+
* high+mid are `recordings`; low is `recordingsLow`. */
|
|
4943
|
+
var profileBelongsToClass = (profile, footageClass) => {
|
|
4944
|
+
if (footageClass === void 0) return true;
|
|
4945
|
+
return footageClass === "recordingsLow" ? profile === "low" : profile === "high" || profile === "mid";
|
|
4946
|
+
};
|
|
4811
4947
|
//#endregion
|
|
4812
4948
|
//#region src/recorder/addon/footage-render.ts
|
|
4813
4949
|
/**
|
|
@@ -5282,6 +5418,8 @@ var RecorderV2Addon = class extends BaseAddon {
|
|
|
5282
5418
|
/** Periodic footage-retention sweep (owns its timer + single-flight guard).
|
|
5283
5419
|
* Constructed + started in `onHubReachable`, stopped on shutdown. */
|
|
5284
5420
|
retentionSweeper = null;
|
|
5421
|
+
/** Reversible migration pause lease; never reflected in RecordingConfig. */
|
|
5422
|
+
storageMigrationLeaseId = null;
|
|
5285
5423
|
constructor() {
|
|
5286
5424
|
super({ ...DEFAULT_CONFIG });
|
|
5287
5425
|
}
|
|
@@ -5439,6 +5577,10 @@ var RecorderV2Addon = class extends BaseAddon {
|
|
|
5439
5577
|
mfraFor: (deviceId, profile, startMs) => this.mfraTables.get(deviceId, profile, startMs),
|
|
5440
5578
|
hydrateWindow: (deviceId, fromMs, toMs) => hydrateWindowFromStorage(this.index, deviceId, fromMs, toMs, this.resolvedLocations, this.ctx.logger),
|
|
5441
5579
|
onConfigChanged: (deviceId) => this.controller?.onConfigChanged(deviceId) ?? Promise.resolve(),
|
|
5580
|
+
pauseForStorageMigration: (leaseId) => this.pauseForStorageMigration(leaseId),
|
|
5581
|
+
resumeForStorageMigration: (leaseId) => this.resumeForStorageMigration(leaseId),
|
|
5582
|
+
refreshStorageLocationsForMigration: (leaseId) => this.refreshStorageLocationsForMigration(leaseId),
|
|
5583
|
+
assertStorageMigrationLease: (leaseId) => this.assertStorageMigrationLease(leaseId),
|
|
5442
5584
|
dataDir: this.ctx.dataDir,
|
|
5443
5585
|
playbackBaseUrl: () => this.playbackBaseUrl,
|
|
5444
5586
|
isCameraDevice: async (deviceId) => {
|
|
@@ -5827,6 +5969,34 @@ var RecorderV2Addon = class extends BaseAddon {
|
|
|
5827
5969
|
this.resolvedLocations = await resolveRecordingsLocations(this.ctx.api, this.ctx.logger);
|
|
5828
5970
|
return this.resolvedLocations;
|
|
5829
5971
|
}
|
|
5972
|
+
async pauseForStorageMigration(leaseId) {
|
|
5973
|
+
if (this.storageMigrationLeaseId !== null && this.storageMigrationLeaseId !== leaseId) throw new Error("recorder is already paused by another storage migration");
|
|
5974
|
+
if (!this.controller) throw new Error("recorder controller is unavailable for storage migration");
|
|
5975
|
+
this.storageMigrationLeaseId = leaseId;
|
|
5976
|
+
try {
|
|
5977
|
+
await this.controller.pause();
|
|
5978
|
+
} catch (err) {
|
|
5979
|
+
this.storageMigrationLeaseId = null;
|
|
5980
|
+
throw err;
|
|
5981
|
+
}
|
|
5982
|
+
}
|
|
5983
|
+
async resumeForStorageMigration(leaseId) {
|
|
5984
|
+
if (this.storageMigrationLeaseId === null) return;
|
|
5985
|
+
if (this.storageMigrationLeaseId !== leaseId) throw new Error("recorder storage migration lease does not match");
|
|
5986
|
+
try {
|
|
5987
|
+
await this.controller?.resume();
|
|
5988
|
+
} finally {
|
|
5989
|
+
this.storageMigrationLeaseId = null;
|
|
5990
|
+
}
|
|
5991
|
+
}
|
|
5992
|
+
async refreshStorageLocationsForMigration(leaseId) {
|
|
5993
|
+
if (this.storageMigrationLeaseId !== leaseId) throw new Error("recorder storage migration lease does not match");
|
|
5994
|
+
await this.refreshLocations();
|
|
5995
|
+
this.calendar.invalidateAll();
|
|
5996
|
+
}
|
|
5997
|
+
assertStorageMigrationLease(leaseId) {
|
|
5998
|
+
if (this.storageMigrationLeaseId !== leaseId) throw new Error("recorder storage migration lease does not match");
|
|
5999
|
+
}
|
|
5830
6000
|
/**
|
|
5831
6001
|
* Resolve the cluster's camera-source owner. Graceful degrade: the
|
|
5832
6002
|
* `pipeline-orchestrator` cap may not be mounted yet (pre-image-release),
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
|
|
2
2
|
const require_chunk = require("../chunk-emK7D4bc.js");
|
|
3
|
-
const require_worker_protocol = require("../worker-protocol-
|
|
3
|
+
const require_worker_protocol = require("../worker-protocol-CDkbdSuM.js");
|
|
4
4
|
let node_url = require("node:url");
|
|
5
5
|
let node_fs = require("node:fs");
|
|
6
6
|
node_fs = require_chunk.__toESM(node_fs);
|
|
@@ -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-CQHY2NeB.mjs";
|
|
2
2
|
import { pathToFileURL } from "node:url";
|
|
3
3
|
import * as fs from "node:fs";
|
|
4
4
|
import * as path$1 from "node:path";
|
|
@@ -1,8 +1,8 @@
|
|
|
1
|
-
import { a as e, c as t, d as n, i as r, l as i, n as a, o, r as s, s as c, t as l, u } 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, i as r, l as i, n as a, o, r as s, s as c, t as l, u } from "./_virtual_mf___mfe_internal__addon_stream_broker_widgets__loadShare___mf_0_camstack_mf_1_ui_mf_2_library__loadShare__.js-CJAUKSrT.mjs";
|
|
2
2
|
import { a as d, i as f, n as p, o as m, r as h, t as g } from "./_virtual_mf___mfe_internal__addon_stream_broker_widgets__loadShare__react__loadShare__.js-C9j-2lBe.mjs";
|
|
3
3
|
import { n as _, r as v, t as y } from "./_virtual_mf___mfe_internal__addon_stream_broker_widgets__loadShare__react_mf_1_jsx_mf_2_runtime__loadShare__.js-XO0-Pyu6.mjs";
|
|
4
4
|
import { n as b, t as x } from "./_virtual_mf___mfe_internal__addon_stream_broker_widgets__loadShare___mf_0_tanstack_mf_1_react_mf_2_query__loadShare__.js-BO7TIbJV.mjs";
|
|
5
|
-
import { t as S } from "./_virtual_mf___mfe_internal__addon_stream_broker_widgets__loadShare___mf_0_camstack_mf_1_types__loadShare__.js-
|
|
5
|
+
import { t as S } from "./_virtual_mf___mfe_internal__addon_stream_broker_widgets__loadShare___mf_0_camstack_mf_1_types__loadShare__.js-C2tu4c14.mjs";
|
|
6
6
|
//#region ../../node_modules/lucide-react/dist/esm/shared/src/utils.js
|
|
7
7
|
var C = (e) => e.replace(/([a-z0-9])([A-Z])/g, "$1-$2").toLowerCase(), w = (e) => e.replace(/^([A-Z])|[\s-_]+(\w)/g, (e, t, n) => n ? n.toUpperCase() : t.toLowerCase()), T = (e) => {
|
|
8
8
|
let t = w(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.14",
|
|
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.60",
|
|
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.41",
|
|
37
37
|
scope: ["default"],
|
|
38
38
|
loaded: !1,
|
|
39
39
|
from: "addon_stream_broker_widgets",
|