@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
@@ -22,7 +22,7 @@ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__ge
22
22
  mod
23
23
  ));
24
24
  Object.defineProperties(exports, { __esModule: { value: true }, [Symbol.toStringTag]: { value: "Module" } });
25
- const index = require("../index-BbPPvoCx.js");
25
+ const index = require("../index-B36NMAdu.js");
26
26
  const fs = require("node:fs");
27
27
  const path = require("node:path");
28
28
  const DEFAULT_CONFIG$1 = {
@@ -1,4 +1,4 @@
1
- import { i as evaluateZoneRules, B as BaseAddon, t as motionDetectionCapability, m as hydrateSchema, D as DeviceType } from "../index-Bmlkm0Fd.mjs";
1
+ import { j as evaluateZoneRules, B as BaseAddon, v as motionDetectionCapability, r as hydrateSchema, D as DeviceType } from "../index-5aYef068.mjs";
2
2
  import { readFileSync } from "node:fs";
3
3
  import { join } from "node:path";
4
4
  const DEFAULT_CONFIG$1 = {
@@ -22,7 +22,7 @@ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__ge
22
22
  mod
23
23
  ));
24
24
  Object.defineProperties(exports, { __esModule: { value: true }, [Symbol.toStringTag]: { value: "Module" } });
25
- const index = require("../index-BbPPvoCx.js");
25
+ const index = require("../index-B36NMAdu.js");
26
26
  const shmRing = require("@camstack/shm-ring");
27
27
  class FrameQueue {
28
28
  /**
@@ -630,36 +630,87 @@ class PipelineRunner {
630
630
  const PULL_MAX_COUNT = 4;
631
631
  const MIN_POLL_INTERVAL_MS = 20;
632
632
  const FALLBACK_POLL_INTERVAL_MS = 200;
633
+ const INITIAL_SUBSCRIBE_RETRY_BACKOFF_MS = 250;
634
+ const MAX_SUBSCRIBE_RETRY_BACKOFF_MS = 5e3;
633
635
  async function startFrameHandlePoller(options) {
634
- const { api, brokerId, format, maxFps, tag, onFrame, logger } = options;
635
- let result;
636
- try {
637
- result = await api.streamBroker.subscribeFrames.mutate({
638
- brokerId,
639
- format,
640
- maxFps,
641
- tag
642
- });
643
- } catch (err) {
644
- logger.warn("frame-handle poller: subscribeFrames failed", {
645
- meta: { brokerId, format, tag, error: index.errMsg(err) }
646
- });
647
- return null;
636
+ const lifecycle = {
637
+ stopped: false,
638
+ retryTimer: void 0,
639
+ activeTeardown: null
640
+ };
641
+ const teardown = () => {
642
+ if (lifecycle.stopped) return;
643
+ lifecycle.stopped = true;
644
+ if (lifecycle.retryTimer) {
645
+ clearTimeout(lifecycle.retryTimer);
646
+ lifecycle.retryTimer = void 0;
647
+ }
648
+ lifecycle.activeTeardown?.();
649
+ };
650
+ void subscribeWithRetry(options, lifecycle);
651
+ return teardown;
652
+ }
653
+ async function subscribeWithRetry(options, lifecycle) {
654
+ const { api, brokerId, format, maxFps, tag, logger } = options;
655
+ let backoffMs = INITIAL_SUBSCRIBE_RETRY_BACKOFF_MS;
656
+ let attempt = 0;
657
+ while (!lifecycle.stopped) {
658
+ attempt += 1;
659
+ try {
660
+ const result = await api.streamBroker.subscribeFrames.mutate({
661
+ brokerId,
662
+ format,
663
+ maxFps,
664
+ tag
665
+ });
666
+ if (lifecycle.stopped) {
667
+ await api.streamBroker.unsubscribeFrames.mutate({ subscriptionId: result.subscriptionId }).catch((err) => {
668
+ logger.warn("frame-handle poller: late unsubscribe failed", {
669
+ meta: { brokerId, subscriptionId: result.subscriptionId, error: index.errMsg(err) }
670
+ });
671
+ });
672
+ return;
673
+ }
674
+ lifecycle.activeTeardown = startPolling(options, result.subscriptionId, result.maxFps, lifecycle);
675
+ return;
676
+ } catch (err) {
677
+ if (lifecycle.stopped) return;
678
+ if (attempt === 1) {
679
+ logger.warn("frame-handle poller: subscribeFrames failed, retrying", {
680
+ meta: { brokerId, format, tag, error: index.errMsg(err), nextRetryInMs: backoffMs }
681
+ });
682
+ } else {
683
+ logger.debug("frame-handle poller: subscribeFrames still failing", {
684
+ meta: { brokerId, format, tag, attempt, error: index.errMsg(err), nextRetryInMs: backoffMs }
685
+ });
686
+ }
687
+ await sleep(backoffMs, lifecycle);
688
+ backoffMs = Math.min(MAX_SUBSCRIBE_RETRY_BACKOFF_MS, backoffMs * 2);
689
+ }
648
690
  }
649
- const { subscriptionId } = result;
691
+ }
692
+ function sleep(ms, lifecycle) {
693
+ return new Promise((resolve) => {
694
+ lifecycle.retryTimer = setTimeout(() => {
695
+ lifecycle.retryTimer = void 0;
696
+ resolve();
697
+ }, ms);
698
+ });
699
+ }
700
+ function startPolling(options, subscriptionId, resolvedMaxFps, lifecycle) {
701
+ const { api, brokerId, onFrame, logger } = options;
650
702
  const readers = new shmRing.FrameRingReaderCache(logger);
651
- const pollIntervalMs = result.maxFps > 0 ? Math.max(MIN_POLL_INTERVAL_MS, Math.round(1e3 / result.maxFps)) : FALLBACK_POLL_INTERVAL_MS;
652
- let stopped = false;
703
+ const pollIntervalMs = resolvedMaxFps > 0 ? Math.max(MIN_POLL_INTERVAL_MS, Math.round(1e3 / resolvedMaxFps)) : FALLBACK_POLL_INTERVAL_MS;
653
704
  let timer;
654
705
  const tick = async () => {
655
- if (stopped) return;
706
+ if (lifecycle.stopped) return;
656
707
  try {
657
708
  const handles = await api.streamBroker.pullFrameHandles.query({
658
709
  subscriptionId,
659
710
  maxCount: PULL_MAX_COUNT
660
711
  });
661
712
  for (const handle of handles) {
662
- if (stopped) break;
713
+ if (lifecycle.stopped) break;
663
714
  const frame = readers.read(handle);
664
715
  if (frame) onFrame(frame, handle);
665
716
  }
@@ -668,14 +719,12 @@ async function startFrameHandlePoller(options) {
668
719
  meta: { brokerId, subscriptionId, error: index.errMsg(err) }
669
720
  });
670
721
  }
671
- if (!stopped) {
722
+ if (!lifecycle.stopped) {
672
723
  timer = setTimeout(() => void tick(), pollIntervalMs);
673
724
  }
674
725
  };
675
726
  void tick();
676
727
  return () => {
677
- if (stopped) return;
678
- stopped = true;
679
728
  if (timer) {
680
729
  clearTimeout(timer);
681
730
  timer = void 0;
@@ -791,14 +840,12 @@ function toFrameInput(frame) {
791
840
  timestamp: frame.timestamp
792
841
  };
793
842
  }
794
- const STEP_LOG_INTERVAL_MS = 3e4;
795
843
  const METRICS_SNAPSHOT_INTERVAL_MS = 1e3;
796
844
  const METRICS_HEARTBEAT_MS = 3e4;
797
845
  class PipelineRunnerAddon extends index.BaseAddon {
798
846
  runner = null;
799
847
  attached = /* @__PURE__ */ new Map();
800
848
  nodeId = "unknown";
801
- stepLogTimer = null;
802
849
  metricsSnapshotTimer = null;
803
850
  unsubMotionEvents = null;
804
851
  /** Last analyzer-detected state per device — gates the
@@ -903,7 +950,6 @@ class PipelineRunnerAddon extends index.BaseAddon {
903
950
  }
904
951
  );
905
952
  }
906
- this.stepLogTimer = setInterval(() => this.logAttachedSteps(), STEP_LOG_INTERVAL_MS);
907
953
  this.metricsSnapshotTimer = setInterval(
908
954
  () => this.emitMetricsSnapshot(),
909
955
  METRICS_SNAPSHOT_INTERVAL_MS
@@ -923,10 +969,6 @@ class PipelineRunnerAddon extends index.BaseAddon {
923
969
  clearInterval(this.metricsSnapshotTimer);
924
970
  this.metricsSnapshotTimer = null;
925
971
  }
926
- if (this.stepLogTimer) {
927
- clearInterval(this.stepLogTimer);
928
- this.stepLogTimer = null;
929
- }
930
972
  if (this.benchFrameSweeper) {
931
973
  clearInterval(this.benchFrameSweeper);
932
974
  this.benchFrameSweeper = null;
@@ -1326,51 +1368,6 @@ class PipelineRunnerAddon extends index.BaseAddon {
1326
1368
  this.runner?.reportMotion(input.deviceId, input.detected, input.source, input.regions);
1327
1369
  return { success: true };
1328
1370
  }
1329
- /**
1330
- * Periodic per-camera step roster dump. Once every
1331
- * STEP_LOG_INTERVAL_MS (30s) emits one log line per attached camera
1332
- * with the configured detection step tree + audio classifier branch
1333
- * so an operator looking at the agent log can quickly see what each
1334
- * camera is currently running without crossing tRPC. Skips when no
1335
- * cameras are attached so quiet dev runs stay silent.
1336
- */
1337
- logAttachedSteps() {
1338
- if (this.attached.size === 0) return;
1339
- for (const [deviceId, attachment] of this.attached) {
1340
- const cfg = attachment.config;
1341
- const detectionSteps = cfg.steps && cfg.steps.length > 0 ? this.flattenSteps(cfg.steps).filter((s) => s.enabled) : [];
1342
- const detectionLabel = detectionSteps.length > 0 ? detectionSteps.map((s) => `${s.addonId}/${s.modelId}`).join(" → ") : "<none>";
1343
- const audioLabel = cfg.audio && cfg.audio.enabled ? `${cfg.audio.engine.runtime}/${cfg.audio.engine.backend}/${cfg.audio.modelId}` : "<off>";
1344
- const engineLabel = cfg.engine ? `${cfg.engine.runtime}/${cfg.engine.backend}${cfg.engine.device ? `/${cfg.engine.device}` : ""}` : "<unset>";
1345
- this.ctx.logger.info("Camera pipeline roster", {
1346
- tags: { deviceId },
1347
- meta: {
1348
- phase: "roster",
1349
- intervalSec: STEP_LOG_INTERVAL_MS / 1e3,
1350
- pipelineEnabled: cfg.pipelineEnabled,
1351
- motionSources: cfg.motionSources,
1352
- motionFps: cfg.motionFps,
1353
- detectionFps: cfg.detectionFps,
1354
- engine: engineLabel,
1355
- videoSteps: detectionLabel,
1356
- videoStepCount: detectionSteps.length,
1357
- audio: audioLabel
1358
- }
1359
- });
1360
- }
1361
- }
1362
- /** Recursively flatten the step tree → ordered list of every node. */
1363
- flattenSteps(steps) {
1364
- const out = [];
1365
- const walk = (s) => {
1366
- out.push(s);
1367
- if (s.children) {
1368
- for (const c of s.children) walk(c);
1369
- }
1370
- };
1371
- for (const s of steps) walk(s);
1372
- return out;
1373
- }
1374
1371
  detachInternal(deviceId) {
1375
1372
  const attachment = this.attached.get(deviceId);
1376
1373
  if (!attachment) return;
@@ -1495,7 +1492,7 @@ class PipelineRunnerAddon extends index.BaseAddon {
1495
1492
  }
1496
1493
  return startFrameHandlePoller({
1497
1494
  api,
1498
- brokerId: `${config.deviceId}/${config.motionStreamId}`,
1495
+ brokerId: index.makeSourceBrokerId(config.deviceId, config.motionStreamId),
1499
1496
  format: "gray",
1500
1497
  maxFps: config.motionFps,
1501
1498
  tag: "motion",
@@ -1581,7 +1578,7 @@ class PipelineRunnerAddon extends index.BaseAddon {
1581
1578
  }
1582
1579
  return startFrameHandlePoller({
1583
1580
  api,
1584
- brokerId: `${config.deviceId}/${config.detectionStreamId}`,
1581
+ brokerId: index.makeSourceBrokerId(config.deviceId, config.detectionStreamId),
1585
1582
  format: "rgb",
1586
1583
  maxFps: config.detectionFps,
1587
1584
  tag: "detection",