@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.
Files changed (84) hide show
  1. package/dist/audio-analyzer/index.js +1 -1
  2. package/dist/audio-analyzer/index.mjs +1 -1
  3. package/dist/detection-pipeline/index.js +2 -2
  4. package/dist/detection-pipeline/index.mjs +2 -2
  5. package/dist/{dist-DTvDedJV.mjs → dist-B9_C-QmC.mjs} +323 -38
  6. package/dist/{dist-BNXiD8pH.js → dist-DKrqeIfS.js} +323 -38
  7. package/dist/{event-loop-stall-monitor-RLis0vRd.mjs → event-loop-stall-monitor-BucTbe9v.mjs} +1 -1
  8. package/dist/{event-loop-stall-monitor-DmscRH8r.js → event-loop-stall-monitor-CnJ5JGA2.js} +1 -1
  9. package/dist/motion-wasm/index.js +1 -1
  10. package/dist/motion-wasm/index.mjs +1 -1
  11. package/dist/pipeline-runner/index.js +3 -3
  12. package/dist/pipeline-runner/index.mjs +3 -3
  13. package/dist/recorder/index.js +211 -41
  14. package/dist/recorder/index.mjs +211 -41
  15. package/dist/session-decode/decode-worker-child.js +1 -1
  16. package/dist/session-decode/decode-worker-child.mjs +1 -1
  17. package/dist/stream-broker/_stub.js +2 -2
  18. 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
  19. 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
  20. 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
  21. package/dist/stream-broker/{hostInit-DqexQ1ED.mjs → hostInit-DqLdTCfo.mjs} +3 -3
  22. package/dist/stream-broker/index.js +119 -22
  23. package/dist/stream-broker/index.mjs +119 -22
  24. package/dist/stream-broker/remoteEntry.js +1 -1
  25. package/dist/{worker-protocol-D8ZsVii1.js → worker-protocol-CDkbdSuM.js} +1 -1
  26. package/dist/{worker-protocol-C3pPkCGe.mjs → worker-protocol-CQHY2NeB.mjs} +1 -1
  27. package/package.json +1 -1
  28. package/python/__pycache__/inference_pool.cpython-312.pyc +0 -0
  29. package/python/__pycache__/inference_pool.cpython-313.pyc +0 -0
  30. package/python/__pycache__/inference_pool.cpython-314.pyc +0 -0
  31. package/python/__pycache__/test_inference_pool_backpressure.cpython-314.pyc +0 -0
  32. package/python/__pycache__/test_inference_pool_coreml_cache.cpython-314.pyc +0 -0
  33. package/python/__pycache__/test_inference_pool_device_selection.cpython-314.pyc +0 -0
  34. package/python/__pycache__/test_inference_pool_layout.cpython-314.pyc +0 -0
  35. package/python/__pycache__/test_inference_pool_preprocess.cpython-314.pyc +0 -0
  36. package/python/__pycache__/yamnet_audio.cpython-314.pyc +0 -0
  37. package/python/postprocessors/__pycache__/__init__.cpython-312.pyc +0 -0
  38. package/python/postprocessors/__pycache__/__init__.cpython-313.pyc +0 -0
  39. package/python/postprocessors/__pycache__/__init__.cpython-314.pyc +0 -0
  40. package/python/postprocessors/__pycache__/_safety.cpython-313.pyc +0 -0
  41. package/python/postprocessors/__pycache__/arcface.cpython-312.pyc +0 -0
  42. package/python/postprocessors/__pycache__/arcface.cpython-313.pyc +0 -0
  43. package/python/postprocessors/__pycache__/arcface.cpython-314.pyc +0 -0
  44. package/python/postprocessors/__pycache__/clip.cpython-312.pyc +0 -0
  45. package/python/postprocessors/__pycache__/clip.cpython-313.pyc +0 -0
  46. package/python/postprocessors/__pycache__/clip.cpython-314.pyc +0 -0
  47. package/python/postprocessors/__pycache__/ctc.cpython-312.pyc +0 -0
  48. package/python/postprocessors/__pycache__/ctc.cpython-313.pyc +0 -0
  49. package/python/postprocessors/__pycache__/ctc.cpython-314.pyc +0 -0
  50. package/python/postprocessors/__pycache__/rfdetr.cpython-312.pyc +0 -0
  51. package/python/postprocessors/__pycache__/saliency.cpython-312.pyc +0 -0
  52. package/python/postprocessors/__pycache__/saliency.cpython-313.pyc +0 -0
  53. package/python/postprocessors/__pycache__/saliency.cpython-314.pyc +0 -0
  54. package/python/postprocessors/__pycache__/scrfd.cpython-312.pyc +0 -0
  55. package/python/postprocessors/__pycache__/scrfd.cpython-313.pyc +0 -0
  56. package/python/postprocessors/__pycache__/scrfd.cpython-314.pyc +0 -0
  57. package/python/postprocessors/__pycache__/softmax.cpython-312.pyc +0 -0
  58. package/python/postprocessors/__pycache__/softmax.cpython-313.pyc +0 -0
  59. package/python/postprocessors/__pycache__/softmax.cpython-314.pyc +0 -0
  60. package/python/postprocessors/__pycache__/ssd.cpython-312.pyc +0 -0
  61. package/python/postprocessors/__pycache__/ssd.cpython-313.pyc +0 -0
  62. package/python/postprocessors/__pycache__/ssd.cpython-314.pyc +0 -0
  63. package/python/postprocessors/__pycache__/test_clip.cpython-312-pytest-9.1.1.pyc +0 -0
  64. package/python/postprocessors/__pycache__/test_clip.cpython-313-pytest-9.1.1.pyc +0 -0
  65. package/python/postprocessors/__pycache__/test_ctc.cpython-312-pytest-9.1.1.pyc +0 -0
  66. package/python/postprocessors/__pycache__/test_ctc.cpython-312.pyc +0 -0
  67. package/python/postprocessors/__pycache__/test_ctc.cpython-313-pytest-9.1.1.pyc +0 -0
  68. package/python/postprocessors/__pycache__/test_ctc.cpython-313.pyc +0 -0
  69. package/python/postprocessors/__pycache__/test_rfdetr.cpython-312-pytest-9.1.1.pyc +0 -0
  70. package/python/postprocessors/__pycache__/test_saliency.cpython-312-pytest-9.1.1.pyc +0 -0
  71. package/python/postprocessors/__pycache__/test_saliency.cpython-313-pytest-9.1.1.pyc +0 -0
  72. package/python/postprocessors/__pycache__/test_softmax.cpython-312-pytest-9.1.1.pyc +0 -0
  73. package/python/postprocessors/__pycache__/test_yolo_nms.cpython-312-pytest-9.1.1.pyc +0 -0
  74. package/python/postprocessors/__pycache__/test_yolo_nms.cpython-39.pyc +0 -0
  75. package/python/postprocessors/__pycache__/yamnet.cpython-312.pyc +0 -0
  76. package/python/postprocessors/__pycache__/yamnet.cpython-313.pyc +0 -0
  77. package/python/postprocessors/__pycache__/yamnet.cpython-314.pyc +0 -0
  78. package/python/postprocessors/__pycache__/yolo.cpython-312.pyc +0 -0
  79. package/python/postprocessors/__pycache__/yolo.cpython-313.pyc +0 -0
  80. package/python/postprocessors/__pycache__/yolo.cpython-314.pyc +0 -0
  81. package/python/postprocessors/__pycache__/yolo.cpython-39.pyc +0 -0
  82. package/python/postprocessors/__pycache__/yolo_seg.cpython-312.pyc +0 -0
  83. package/python/postprocessors/__pycache__/yolo_seg.cpython-313.pyc +0 -0
  84. package/python/postprocessors/__pycache__/yolo_seg.cpython-314.pyc +0 -0
@@ -1,5 +1,5 @@
1
1
  import { r as __toESM, t as __commonJSMin } from "../chunk-DnnnRqeS.mjs";
2
- import { $ as webrtcSessionCapability, At as union, B as maskUrlCredentials, C as addonWidgetsSourceCapability, Ct as discriminatedUnion, D as createHwAccelCache, Dt as object, E as cameraStreamsCapability, Et as number, F as egressTransportFromRequest, J as resolveEgressDecodeHwAccel, Ot as record, P as egressTranscodeSharingKey, St as boolean, Tt as literal, Z as streamBrokerCapability, _t as parseProfileBrokerId, at as isSoftwareDecode, bt as _enum, ct as DeviceFeature, et as errMsg, f as EncodeProfileSchema, ft as isEvent, ht as nodePin, it as invocationFromEncodeProfile, jt as EventCategory, kt as string, lt as DeviceType, mt as makeSourceBrokerId, nt as Fmp4BoxSplitter, ot as BaseAddon, pt as makeProfileBrokerId, rt as buildFfmpegArgs$1, st as CAM_PROFILE_ORDER, tt as AUDIO_PRESETS, ut as createEvent, v as RATE_CONTROL_RELAXED, x as RingBuffer, xt as array, y as RATE_CONTROL_TIGHT } from "../dist-DTvDedJV.mjs";
2
+ import { $ as webrtcSessionCapability, At as union, B as maskUrlCredentials, C as addonWidgetsSourceCapability, Ct as discriminatedUnion, D as createHwAccelCache, Dt as object, E as cameraStreamsCapability, Et as number, F as egressTransportFromRequest, J as resolveEgressDecodeHwAccel, Ot as record, P as egressTranscodeSharingKey, St as boolean, Tt as literal, Z as streamBrokerCapability, _t as parseProfileBrokerId, at as isSoftwareDecode, bt as _enum, ct as DeviceFeature, et as errMsg, f as EncodeProfileSchema, ft as isEvent, ht as nodePin, it as invocationFromEncodeProfile, jt as EventCategory, kt as string, lt as DeviceType, mt as makeSourceBrokerId, nt as Fmp4BoxSplitter, ot as BaseAddon, pt as makeProfileBrokerId, rt as buildFfmpegArgs$1, st as CAM_PROFILE_ORDER, tt as AUDIO_PRESETS, ut as createEvent, v as RATE_CONTROL_RELAXED, x as RingBuffer, xt as array, y as RATE_CONTROL_TIGHT } from "../dist-B9_C-QmC.mjs";
3
3
  import { n as profileForStreamId } from "../remote-restream-BeHi78PZ.mjs";
4
4
  import { createRequire } from "node:module";
5
5
  import * as crypto$1 from "node:crypto";
@@ -14694,9 +14694,67 @@ var StreamBrokerManager = class StreamBrokerManager {
14694
14694
  setProfileMapPersister(persister) {
14695
14695
  this.profileMapPersister = persister;
14696
14696
  }
14697
- loadPersistedProfileMap(entries) {
14697
+ /**
14698
+ * Rehydrate the persisted profile map, then reconcile it against the live
14699
+ * device registry — a blob written before a camera was deleted otherwise
14700
+ * resurrects that camera's slots on every boot.
14701
+ *
14702
+ * Call AFTER `setProfileMapPersister` / `setApiAccess`: the prune persists
14703
+ * what it drops, and reads the registry to decide what to drop.
14704
+ */
14705
+ async loadPersistedProfileMap(entries) {
14698
14706
  this.assignments.clear();
14699
14707
  for (const [k, v] of entries) this.assignments.set(k, v);
14708
+ await this.pruneAssignmentsForRemovedDevices();
14709
+ }
14710
+ /**
14711
+ * Drop assignments for devices the registry no longer knows.
14712
+ *
14713
+ * Deletion decided by a fallible read, so every way the read can be WRONG
14714
+ * skips the prune outright (D49): no api yet, a failed enumeration, or an
14715
+ * empty enumeration standing next to persisted assignments — that last one
14716
+ * is device-restore not having run, and believing it would wipe the whole
14717
+ * fleet's slot map on one bad boot. Nothing here is retried: the next boot
14718
+ * reads the same blob, and A3 already removes a device at the moment it is
14719
+ * deleted.
14720
+ */
14721
+ async pruneAssignmentsForRemovedDevices() {
14722
+ const persistedCount = this.assignments.size;
14723
+ if (persistedCount === 0) return;
14724
+ const api = this.api;
14725
+ if (!api) {
14726
+ this.logger.warn("profile-map prune skipped — no api access", { meta: { persistedCount } });
14727
+ return;
14728
+ }
14729
+ let devices;
14730
+ try {
14731
+ devices = await api.deviceManager.listAll.query({});
14732
+ } catch (err) {
14733
+ this.logger.warn("profile-map prune skipped — deviceManager.listAll failed", { meta: {
14734
+ persistedCount,
14735
+ error: errMsg(err)
14736
+ } });
14737
+ return;
14738
+ }
14739
+ if (devices.length === 0) {
14740
+ this.logger.warn("profile-map prune skipped — device enumeration came back empty", { meta: { persistedCount } });
14741
+ return;
14742
+ }
14743
+ const known = new Set(devices.map((d) => d.id));
14744
+ const dropped = [...this.assignments.keys()].filter((deviceId) => !known.has(deviceId));
14745
+ if (dropped.length === 0) {
14746
+ this.logger.debug("profile-map prune: every persisted device still exists", { meta: { persistedCount } });
14747
+ return;
14748
+ }
14749
+ for (const deviceId of dropped) {
14750
+ this.assignments.delete(deviceId);
14751
+ this.logger.debug("profile-map prune dropped a device that no longer exists", { tags: { deviceId } });
14752
+ }
14753
+ this.persistProfileMap();
14754
+ this.logger.info("profile-map prune — dropped assignments for devices that no longer exist", { meta: {
14755
+ dropped,
14756
+ remaining: this.assignments.size
14757
+ } });
14700
14758
  }
14701
14759
  getRtspRestreamProvider() {
14702
14760
  return this.rtspProvider;
@@ -15140,12 +15198,32 @@ var StreamBrokerManager = class StreamBrokerManager {
15140
15198
  }
15141
15199
  async retractDeviceNow(deviceId, opts) {
15142
15200
  const existing = this.cameraStreams.get(deviceId);
15143
- if (!existing) return;
15144
- for (const camStreamId of Array.from(existing.keys())) await this.retractCameraStream({
15201
+ if (existing) for (const camStreamId of Array.from(existing.keys())) await this.retractCameraStream({
15145
15202
  deviceId,
15146
15203
  camStreamId,
15147
15204
  preserveAssignment: opts.preserveAssignments === true
15148
15205
  });
15206
+ if (opts.purgeAssignments === true) this.purgeDeviceAssignments(deviceId);
15207
+ }
15208
+ /**
15209
+ * Forget a device's profile-slot assignments and persist the shrunk map.
15210
+ *
15211
+ * Reachable only from the PERMANENT-removal path. A deleted device that
15212
+ * keeps its entry stays in `listAllProfileSlots` for the life of the
15213
+ * process AND is written straight back into the persisted `profileMap`
15214
+ * blob, so it returns at every boot — which is how 3217/3218 outlived
15215
+ * their cameras.
15216
+ */
15217
+ purgeDeviceAssignments(deviceId) {
15218
+ const existing = this.assignments.get(deviceId);
15219
+ if (!existing) return;
15220
+ const profiles = CAM_PROFILE_ORDER.filter((profile) => existing.map[profile] !== void 0);
15221
+ this.assignments.delete(deviceId);
15222
+ this.persistProfileMap();
15223
+ this.logger.info("device removed — dropping its profile-slot assignments", {
15224
+ tags: { deviceId },
15225
+ meta: { profiles }
15226
+ });
15149
15227
  }
15150
15228
  async runDeviceCatalogOperation(deviceId, operation) {
15151
15229
  const previous = this.deviceCatalogOperations.get(deviceId) ?? Promise.resolve();
@@ -33597,6 +33675,17 @@ var StreamBrokerAddon = class extends BaseAddon {
33597
33675
  });
33598
33676
  });
33599
33677
  const profileMapState = this.state("profileMap", ProfileMapSchema, {});
33678
+ const profileMapPersister = (assignments) => {
33679
+ const obj = {};
33680
+ for (const [deviceId, assignment] of assignments) obj[`${deviceId}`] = {
33681
+ map: { ...assignment.map },
33682
+ auto: assignment.auto
33683
+ };
33684
+ profileMapState.set(obj).catch((err) => {
33685
+ this.ctx.logger.warn("Failed to persist profile map", { meta: { error: errMsg(err) } });
33686
+ });
33687
+ };
33688
+ this.brokerManager.setProfileMapPersister(profileMapPersister);
33600
33689
  try {
33601
33690
  const obj = await profileMapState.get();
33602
33691
  const loaded = /* @__PURE__ */ new Map();
@@ -33613,22 +33702,11 @@ var StreamBrokerAddon = class extends BaseAddon {
33613
33702
  auto: val.auto
33614
33703
  });
33615
33704
  }
33616
- this.brokerManager.loadPersistedProfileMap(loaded);
33705
+ await this.brokerManager.loadPersistedProfileMap(loaded);
33617
33706
  this.ctx.logger.info("Loaded persisted profile map", { meta: { deviceCount: loaded.size } });
33618
33707
  } catch (err) {
33619
33708
  this.ctx.logger.warn("Failed to load profile map", { meta: { error: errMsg(err) } });
33620
33709
  }
33621
- const profileMapPersister = (assignments) => {
33622
- const obj = {};
33623
- for (const [deviceId, assignment] of assignments) obj[`${deviceId}`] = {
33624
- map: { ...assignment.map },
33625
- auto: assignment.auto
33626
- };
33627
- profileMapState.set(obj).catch((err) => {
33628
- this.ctx.logger.warn("Failed to persist profile map", { meta: { error: errMsg(err) } });
33629
- });
33630
- };
33631
- this.brokerManager.setProfileMapPersister(profileMapPersister);
33632
33710
  const probeSnapshotsState = this.state("probeSnapshots", ProbedSnapshotMapSchema, {});
33633
33711
  this.probeSnapshotsState = probeSnapshotsState;
33634
33712
  try {
@@ -33710,12 +33788,7 @@ var StreamBrokerAddon = class extends BaseAddon {
33710
33788
  });
33711
33789
  this.subscribe({ category: EventCategory.DeviceUnregistered }, (event) => {
33712
33790
  const deviceId = event.data.deviceId;
33713
- if (typeof deviceId === "number") this.brokerManager?.retractDevice(deviceId, { preserveAssignments: true }).catch((err) => {
33714
- this.ctx.logger.warn("device retract failed", {
33715
- tags: { deviceId },
33716
- meta: { error: errMsg(err) }
33717
- });
33718
- });
33791
+ if (typeof deviceId === "number") this.handleDeviceRemoved(deviceId);
33719
33792
  });
33720
33793
  this.subscribe({ category: EventCategory.StreamParamsChanged }, (event) => {
33721
33794
  const deviceId = event.data.deviceId;
@@ -33917,6 +33990,30 @@ var StreamBrokerAddon = class extends BaseAddon {
33917
33990
  this.brokerManager = null;
33918
33991
  }
33919
33992
  /**
33993
+ * A device was PERMANENTLY removed (`DeviceUnregistered`).
33994
+ *
33995
+ * Retracts its cam-streams AND purges its profile-slot assignments.
33996
+ * `preserveAssignments` alone is the provider-restart contract — the streams
33997
+ * come back and the operator's manual slot choices must survive — but a
33998
+ * DELETED device that keeps its assignments stays in `listAllProfileSlots`
33999
+ * for the life of the process and is written straight back into the
34000
+ * persisted `profileMap` blob, so it returns at every boot. Live ids
34001
+ * 3217/3218 outlived their cameras exactly that way.
34002
+ */
34003
+ async handleDeviceRemoved(deviceId) {
34004
+ try {
34005
+ await this.brokerManager?.retractDevice(deviceId, {
34006
+ preserveAssignments: true,
34007
+ purgeAssignments: true
34008
+ });
34009
+ } catch (err) {
34010
+ this.ctx.logger.warn("device retract failed", {
34011
+ tags: { deviceId },
34012
+ meta: { error: errMsg(err) }
34013
+ });
34014
+ }
34015
+ }
34016
+ /**
33920
34017
  * Emit one `stream-broker.metrics-snapshot` event per active broker.
33921
34018
  * BrokerStats already aggregates everything UI consumers need
33922
34019
  * (status, fps, bitrate, codec, subscriber count). Skipped when no
@@ -30,7 +30,7 @@ async function d(e) {
30
30
  }
31
31
  }
32
32
  async function f() {
33
- return l ||= d(() => import("./_virtual_mf-localSharedImportMap___mfe_internal__addon_stream_broker_widgets-CFoXGKXX.mjs")).catch((e) => {
33
+ return l ||= d(() => import("./_virtual_mf-localSharedImportMap___mfe_internal__addon_stream_broker_widgets-BCyIjQkw.mjs")).catch((e) => {
34
34
  throw l = void 0, e;
35
35
  }), l;
36
36
  }
@@ -1,4 +1,4 @@
1
- const require_dist = require("./dist-BNXiD8pH.js");
1
+ const require_dist = require("./dist-DKrqeIfS.js");
2
2
  //#region src/session-decode/native-lease-config.ts
3
3
  /**
4
4
  * Resolution of the native-frame lease knobs for one decode worker.
@@ -1,4 +1,4 @@
1
- import { g as NativeLeaseSettingsSchema, h as NativeLeaseAdmissionSchema, l as DEFAULT_NATIVE_LEASE_SETTINGS } from "./dist-DTvDedJV.mjs";
1
+ import { g as NativeLeaseSettingsSchema, h as NativeLeaseAdmissionSchema, l as DEFAULT_NATIVE_LEASE_SETTINGS } from "./dist-B9_C-QmC.mjs";
2
2
  //#region src/session-decode/native-lease-config.ts
3
3
  /**
4
4
  * Resolution of the native-frame lease knobs for one decode worker.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@camstack/addon-pipeline",
3
- "version": "1.2.63",
3
+ "version": "1.2.65",
4
4
  "description": "Pipeline bundle — runner, detection, motion, audio + stream broker. Multi-entry npm package shipping pipeline addons under a single bundle.",
5
5
  "keywords": [
6
6
  "camstack",