@camstack/addon-pipeline 0.1.19 → 0.1.20

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 (66) hide show
  1. package/dist/audio-analyzer/index.js +5 -2
  2. package/dist/audio-analyzer/index.js.map +1 -1
  3. package/dist/audio-analyzer/index.mjs +5 -2
  4. package/dist/audio-analyzer/index.mjs.map +1 -1
  5. package/dist/audio-codec-nodeav/index.js +1 -1
  6. package/dist/audio-codec-nodeav/index.mjs +1 -1
  7. package/dist/decoder-nodeav/index.js +2 -2
  8. package/dist/decoder-nodeav/index.mjs +2 -2
  9. package/dist/detection-pipeline/index.js +25 -25
  10. package/dist/detection-pipeline/index.js.map +1 -1
  11. package/dist/detection-pipeline/index.mjs +25 -25
  12. package/dist/detection-pipeline/index.mjs.map +1 -1
  13. package/dist/{index-Bmlkm0Fd.mjs → index-5aYef068.mjs} +3601 -770
  14. package/dist/index-5aYef068.mjs.map +1 -0
  15. package/dist/{index-BbPPvoCx.js → index-B36NMAdu.js} +3577 -746
  16. package/dist/index-B36NMAdu.js.map +1 -0
  17. package/dist/{index-D_cl0Qqb.js → index-CMcx_k6Y.js} +48 -48
  18. package/dist/{index-D_cl0Qqb.js.map → index-CMcx_k6Y.js.map} +1 -1
  19. package/dist/{index-UbcdLS7a.mjs → index-CYb7cFrv.mjs} +46 -46
  20. package/dist/{index-UbcdLS7a.mjs.map → index-CYb7cFrv.mjs.map} +1 -1
  21. package/dist/motion-wasm/index.js +1 -1
  22. package/dist/motion-wasm/index.mjs +1 -1
  23. package/dist/pipeline-runner/index.js +74 -77
  24. package/dist/pipeline-runner/index.js.map +1 -1
  25. package/dist/pipeline-runner/index.mjs +74 -77
  26. package/dist/pipeline-runner/index.mjs.map +1 -1
  27. package/dist/recorder/index.js +2209 -0
  28. package/dist/recorder/index.js.map +1 -0
  29. package/dist/recorder/index.mjs +2209 -0
  30. package/dist/recorder/index.mjs.map +1 -0
  31. package/dist/stream-broker/@mf-types/compiled-types/stream-broker/widgets/FfmpegParamsField.d.ts +41 -0
  32. package/dist/stream-broker/@mf-types/compiled-types/stream-broker/widgets/GeometryBuilder.d.ts +54 -0
  33. package/dist/stream-broker/@mf-types/compiled-types/stream-broker/widgets/format-ua.d.ts +13 -0
  34. package/dist/stream-broker/@mf-types/compiled-types/stream-broker/widgets/index.d.ts +2 -0
  35. package/dist/stream-broker/@mf-types.zip +0 -0
  36. package/dist/stream-broker/{__mfe_internal__addon_stream_broker_widgets__loadShare___mf_0_camstack_mf_1_sdk__loadShare__.mjs-h5aXOPSA.mjs → __mfe_internal__addon_stream_broker_widgets__loadShare___mf_0_camstack_mf_1_sdk__loadShare__.mjs-lantnv8e.mjs} +1 -1
  37. package/dist/stream-broker/__mfe_internal__addon_stream_broker_widgets__loadShare___mf_0_camstack_mf_1_types__loadShare__.mjs-DJ3UNg7O.mjs +30 -0
  38. package/dist/stream-broker/__mfe_internal__addon_stream_broker_widgets__loadShare___mf_0_camstack_mf_1_ui_mf_2_library__loadShare__.mjs-CYXy_bhS.mjs +21 -0
  39. package/dist/stream-broker/{__mfe_internal__addon_stream_broker_widgets__loadShare__react__loadShare__.mjs-BsB2G7oY.mjs → __mfe_internal__addon_stream_broker_widgets__loadShare__react__loadShare__.mjs-CaDEYBIU.mjs} +8 -7
  40. package/dist/stream-broker/{__mfe_internal__addon_stream_broker_widgets__loadShare__react__loadShare__.mjs_commonjs-proxy-xrRiPUpA.mjs → __mfe_internal__addon_stream_broker_widgets__loadShare__react__loadShare__.mjs_commonjs-proxy-D6EROtlA.mjs} +1 -1
  41. package/dist/stream-broker/{__mfe_internal__addon_stream_broker_widgets__loadShare__react_mf_1_jsx_mf_2_runtime__loadShare__.mjs-gBEZsQrp.mjs → __mfe_internal__addon_stream_broker_widgets__loadShare__react_mf_1_jsx_mf_2_runtime__loadShare__.mjs-x6pP3Ghk.mjs} +2 -2
  42. package/dist/stream-broker/{__mfe_internal__addon_stream_broker_widgets__loadShare__react_mf_2_dom__loadShare__.mjs_commonjs-proxy-C0E2yCzO.mjs → __mfe_internal__addon_stream_broker_widgets__loadShare__react_mf_2_dom__loadShare__.mjs_commonjs-proxy-CcnN6sbA.mjs} +1 -1
  43. package/dist/stream-broker/_stub.js +963 -333
  44. package/dist/stream-broker/{_virtual_mf-localSharedImportMap___mfe_internal__addon_stream_broker_widgets-CupRlwqG.mjs → _virtual_mf-localSharedImportMap___mfe_internal__addon_stream_broker_widgets-CL9DR49k.mjs} +6 -6
  45. package/dist/stream-broker/{client-NPZqorv9.mjs → client-BvTmMOQu.mjs} +2 -2
  46. package/dist/stream-broker/{hostInit-Bh4w7o5_.mjs → hostInit-ChmiMPS0.mjs} +12 -12
  47. package/dist/stream-broker/{index-D_1p2K9B.mjs → index-BxsFuFmE.mjs} +24 -24
  48. package/dist/stream-broker/{index-mX3Kgiv1.mjs → index-C-248uOU.mjs} +2 -2
  49. package/dist/stream-broker/{index-2Qp8vT3w.mjs → index-C05B6jqp.mjs} +1 -1
  50. package/dist/stream-broker/index-DOJoSShD.mjs +67784 -0
  51. package/dist/stream-broker/{index-Dy2V7VOm.mjs → index-DtOI1aTU.mjs} +10112 -5987
  52. package/dist/stream-broker/{index-Cc6QBqMk.mjs → index-oMq6ilgR.mjs} +253 -267
  53. package/dist/stream-broker/{index-BBcZvb5t.mjs → index-vIWZQBIL.mjs} +1 -1
  54. package/dist/stream-broker/index.js +3168 -543
  55. package/dist/stream-broker/index.js.map +1 -1
  56. package/dist/stream-broker/index.mjs +3172 -546
  57. package/dist/stream-broker/index.mjs.map +1 -1
  58. package/dist/stream-broker/{jsx-runtime-lb0mH5st.mjs → jsx-runtime-BRT_HL0A.mjs} +1 -1
  59. package/dist/stream-broker/remoteEntry.js +1 -1
  60. package/dist/stream-broker/{schemas-ClCuS4qa.mjs → schemas-B7L0qZtq.mjs} +411 -406
  61. package/package.json +51 -3
  62. package/dist/index-BbPPvoCx.js.map +0 -1
  63. package/dist/index-Bmlkm0Fd.mjs.map +0 -1
  64. package/dist/stream-broker/__mfe_internal__addon_stream_broker_widgets__loadShare___mf_0_camstack_mf_1_types__loadShare__.mjs-NjF4kxzW.mjs +0 -19
  65. package/dist/stream-broker/__mfe_internal__addon_stream_broker_widgets__loadShare___mf_0_camstack_mf_1_ui_mf_2_library__loadShare__.mjs-BAv_5ISf.mjs +0 -20
  66. package/dist/stream-broker/index-CIJue-4t.mjs +0 -37880
@@ -1,4 +1,4 @@
1
- import { e as errMsg, o as object, s as string, _ as _enum, l as lazy, a as array, b as boolean, n as number, d as defineCustomActions, c as customAction, B as BaseAddon, E as EventCategory, p as pipelineRunnerCapability, f as createEvent } from "../index-Bmlkm0Fd.mjs";
1
+ import { e as errMsg, o as object, s as string, _ as _enum, l as lazy, a as array, b as boolean, n as number, d as defineCustomActions, c as customAction, B as BaseAddon, E as EventCategory, p as pipelineRunnerCapability, m as makeSourceBrokerId, f as createEvent } from "../index-5aYef068.mjs";
2
2
  import { FrameRingReaderCache } from "@camstack/shm-ring";
3
3
  class FrameQueue {
4
4
  /**
@@ -606,36 +606,87 @@ class PipelineRunner {
606
606
  const PULL_MAX_COUNT = 4;
607
607
  const MIN_POLL_INTERVAL_MS = 20;
608
608
  const FALLBACK_POLL_INTERVAL_MS = 200;
609
+ const INITIAL_SUBSCRIBE_RETRY_BACKOFF_MS = 250;
610
+ const MAX_SUBSCRIBE_RETRY_BACKOFF_MS = 5e3;
609
611
  async function startFrameHandlePoller(options) {
610
- const { api, brokerId, format, maxFps, tag, onFrame, logger } = options;
611
- let result;
612
- try {
613
- result = await api.streamBroker.subscribeFrames.mutate({
614
- brokerId,
615
- format,
616
- maxFps,
617
- tag
618
- });
619
- } catch (err) {
620
- logger.warn("frame-handle poller: subscribeFrames failed", {
621
- meta: { brokerId, format, tag, error: errMsg(err) }
622
- });
623
- return null;
612
+ const lifecycle = {
613
+ stopped: false,
614
+ retryTimer: void 0,
615
+ activeTeardown: null
616
+ };
617
+ const teardown = () => {
618
+ if (lifecycle.stopped) return;
619
+ lifecycle.stopped = true;
620
+ if (lifecycle.retryTimer) {
621
+ clearTimeout(lifecycle.retryTimer);
622
+ lifecycle.retryTimer = void 0;
623
+ }
624
+ lifecycle.activeTeardown?.();
625
+ };
626
+ void subscribeWithRetry(options, lifecycle);
627
+ return teardown;
628
+ }
629
+ async function subscribeWithRetry(options, lifecycle) {
630
+ const { api, brokerId, format, maxFps, tag, logger } = options;
631
+ let backoffMs = INITIAL_SUBSCRIBE_RETRY_BACKOFF_MS;
632
+ let attempt = 0;
633
+ while (!lifecycle.stopped) {
634
+ attempt += 1;
635
+ try {
636
+ const result = await api.streamBroker.subscribeFrames.mutate({
637
+ brokerId,
638
+ format,
639
+ maxFps,
640
+ tag
641
+ });
642
+ if (lifecycle.stopped) {
643
+ await api.streamBroker.unsubscribeFrames.mutate({ subscriptionId: result.subscriptionId }).catch((err) => {
644
+ logger.warn("frame-handle poller: late unsubscribe failed", {
645
+ meta: { brokerId, subscriptionId: result.subscriptionId, error: errMsg(err) }
646
+ });
647
+ });
648
+ return;
649
+ }
650
+ lifecycle.activeTeardown = startPolling(options, result.subscriptionId, result.maxFps, lifecycle);
651
+ return;
652
+ } catch (err) {
653
+ if (lifecycle.stopped) return;
654
+ if (attempt === 1) {
655
+ logger.warn("frame-handle poller: subscribeFrames failed, retrying", {
656
+ meta: { brokerId, format, tag, error: errMsg(err), nextRetryInMs: backoffMs }
657
+ });
658
+ } else {
659
+ logger.debug("frame-handle poller: subscribeFrames still failing", {
660
+ meta: { brokerId, format, tag, attempt, error: errMsg(err), nextRetryInMs: backoffMs }
661
+ });
662
+ }
663
+ await sleep(backoffMs, lifecycle);
664
+ backoffMs = Math.min(MAX_SUBSCRIBE_RETRY_BACKOFF_MS, backoffMs * 2);
665
+ }
624
666
  }
625
- const { subscriptionId } = result;
667
+ }
668
+ function sleep(ms, lifecycle) {
669
+ return new Promise((resolve) => {
670
+ lifecycle.retryTimer = setTimeout(() => {
671
+ lifecycle.retryTimer = void 0;
672
+ resolve();
673
+ }, ms);
674
+ });
675
+ }
676
+ function startPolling(options, subscriptionId, resolvedMaxFps, lifecycle) {
677
+ const { api, brokerId, onFrame, logger } = options;
626
678
  const readers = new FrameRingReaderCache(logger);
627
- const pollIntervalMs = result.maxFps > 0 ? Math.max(MIN_POLL_INTERVAL_MS, Math.round(1e3 / result.maxFps)) : FALLBACK_POLL_INTERVAL_MS;
628
- let stopped = false;
679
+ const pollIntervalMs = resolvedMaxFps > 0 ? Math.max(MIN_POLL_INTERVAL_MS, Math.round(1e3 / resolvedMaxFps)) : FALLBACK_POLL_INTERVAL_MS;
629
680
  let timer;
630
681
  const tick = async () => {
631
- if (stopped) return;
682
+ if (lifecycle.stopped) return;
632
683
  try {
633
684
  const handles = await api.streamBroker.pullFrameHandles.query({
634
685
  subscriptionId,
635
686
  maxCount: PULL_MAX_COUNT
636
687
  });
637
688
  for (const handle of handles) {
638
- if (stopped) break;
689
+ if (lifecycle.stopped) break;
639
690
  const frame = readers.read(handle);
640
691
  if (frame) onFrame(frame, handle);
641
692
  }
@@ -644,14 +695,12 @@ async function startFrameHandlePoller(options) {
644
695
  meta: { brokerId, subscriptionId, error: errMsg(err) }
645
696
  });
646
697
  }
647
- if (!stopped) {
698
+ if (!lifecycle.stopped) {
648
699
  timer = setTimeout(() => void tick(), pollIntervalMs);
649
700
  }
650
701
  };
651
702
  void tick();
652
703
  return () => {
653
- if (stopped) return;
654
- stopped = true;
655
704
  if (timer) {
656
705
  clearTimeout(timer);
657
706
  timer = void 0;
@@ -767,14 +816,12 @@ function toFrameInput(frame) {
767
816
  timestamp: frame.timestamp
768
817
  };
769
818
  }
770
- const STEP_LOG_INTERVAL_MS = 3e4;
771
819
  const METRICS_SNAPSHOT_INTERVAL_MS = 1e3;
772
820
  const METRICS_HEARTBEAT_MS = 3e4;
773
821
  class PipelineRunnerAddon extends BaseAddon {
774
822
  runner = null;
775
823
  attached = /* @__PURE__ */ new Map();
776
824
  nodeId = "unknown";
777
- stepLogTimer = null;
778
825
  metricsSnapshotTimer = null;
779
826
  unsubMotionEvents = null;
780
827
  /** Last analyzer-detected state per device — gates the
@@ -879,7 +926,6 @@ class PipelineRunnerAddon extends BaseAddon {
879
926
  }
880
927
  );
881
928
  }
882
- this.stepLogTimer = setInterval(() => this.logAttachedSteps(), STEP_LOG_INTERVAL_MS);
883
929
  this.metricsSnapshotTimer = setInterval(
884
930
  () => this.emitMetricsSnapshot(),
885
931
  METRICS_SNAPSHOT_INTERVAL_MS
@@ -899,10 +945,6 @@ class PipelineRunnerAddon extends BaseAddon {
899
945
  clearInterval(this.metricsSnapshotTimer);
900
946
  this.metricsSnapshotTimer = null;
901
947
  }
902
- if (this.stepLogTimer) {
903
- clearInterval(this.stepLogTimer);
904
- this.stepLogTimer = null;
905
- }
906
948
  if (this.benchFrameSweeper) {
907
949
  clearInterval(this.benchFrameSweeper);
908
950
  this.benchFrameSweeper = null;
@@ -1302,51 +1344,6 @@ class PipelineRunnerAddon extends BaseAddon {
1302
1344
  this.runner?.reportMotion(input.deviceId, input.detected, input.source, input.regions);
1303
1345
  return { success: true };
1304
1346
  }
1305
- /**
1306
- * Periodic per-camera step roster dump. Once every
1307
- * STEP_LOG_INTERVAL_MS (30s) emits one log line per attached camera
1308
- * with the configured detection step tree + audio classifier branch
1309
- * so an operator looking at the agent log can quickly see what each
1310
- * camera is currently running without crossing tRPC. Skips when no
1311
- * cameras are attached so quiet dev runs stay silent.
1312
- */
1313
- logAttachedSteps() {
1314
- if (this.attached.size === 0) return;
1315
- for (const [deviceId, attachment] of this.attached) {
1316
- const cfg = attachment.config;
1317
- const detectionSteps = cfg.steps && cfg.steps.length > 0 ? this.flattenSteps(cfg.steps).filter((s) => s.enabled) : [];
1318
- const detectionLabel = detectionSteps.length > 0 ? detectionSteps.map((s) => `${s.addonId}/${s.modelId}`).join(" → ") : "<none>";
1319
- const audioLabel = cfg.audio && cfg.audio.enabled ? `${cfg.audio.engine.runtime}/${cfg.audio.engine.backend}/${cfg.audio.modelId}` : "<off>";
1320
- const engineLabel = cfg.engine ? `${cfg.engine.runtime}/${cfg.engine.backend}${cfg.engine.device ? `/${cfg.engine.device}` : ""}` : "<unset>";
1321
- this.ctx.logger.info("Camera pipeline roster", {
1322
- tags: { deviceId },
1323
- meta: {
1324
- phase: "roster",
1325
- intervalSec: STEP_LOG_INTERVAL_MS / 1e3,
1326
- pipelineEnabled: cfg.pipelineEnabled,
1327
- motionSources: cfg.motionSources,
1328
- motionFps: cfg.motionFps,
1329
- detectionFps: cfg.detectionFps,
1330
- engine: engineLabel,
1331
- videoSteps: detectionLabel,
1332
- videoStepCount: detectionSteps.length,
1333
- audio: audioLabel
1334
- }
1335
- });
1336
- }
1337
- }
1338
- /** Recursively flatten the step tree → ordered list of every node. */
1339
- flattenSteps(steps) {
1340
- const out = [];
1341
- const walk = (s) => {
1342
- out.push(s);
1343
- if (s.children) {
1344
- for (const c of s.children) walk(c);
1345
- }
1346
- };
1347
- for (const s of steps) walk(s);
1348
- return out;
1349
- }
1350
1347
  detachInternal(deviceId) {
1351
1348
  const attachment = this.attached.get(deviceId);
1352
1349
  if (!attachment) return;
@@ -1471,7 +1468,7 @@ class PipelineRunnerAddon extends BaseAddon {
1471
1468
  }
1472
1469
  return startFrameHandlePoller({
1473
1470
  api,
1474
- brokerId: `${config.deviceId}/${config.motionStreamId}`,
1471
+ brokerId: makeSourceBrokerId(config.deviceId, config.motionStreamId),
1475
1472
  format: "gray",
1476
1473
  maxFps: config.motionFps,
1477
1474
  tag: "motion",
@@ -1557,7 +1554,7 @@ class PipelineRunnerAddon extends BaseAddon {
1557
1554
  }
1558
1555
  return startFrameHandlePoller({
1559
1556
  api,
1560
- brokerId: `${config.deviceId}/${config.detectionStreamId}`,
1557
+ brokerId: makeSourceBrokerId(config.deviceId, config.detectionStreamId),
1561
1558
  format: "rgb",
1562
1559
  maxFps: config.detectionFps,
1563
1560
  tag: "detection",