@camstack/addon-pipeline 1.2.137 → 1.2.139

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 (40) hide show
  1. package/dist/audio-analyzer/index.js +38 -86
  2. package/dist/audio-analyzer/index.mjs +36 -84
  3. package/dist/detection-pipeline/index.js +12 -12
  4. package/dist/detection-pipeline/index.mjs +5 -5
  5. package/dist/{dist-g0Or5_pR.mjs → dist-CTmOaCwF.mjs} +163 -3
  6. package/dist/{dist-4EMKvxCp.js → dist-WUZH-lAM.js} +168 -2
  7. package/dist/{event-loop-stall-monitor-CskL9Lgu.mjs → event-loop-stall-monitor-BMtR9qZR.mjs} +1 -1
  8. package/dist/{event-loop-stall-monitor-DDm07Ei6.js → event-loop-stall-monitor-CoM21UjL.js} +1 -1
  9. package/dist/{lazy-sharp-BlA9PxWk.js → lazy-sharp-1WF7ZnxZ.js} +1 -1
  10. package/dist/motion-wasm/index.js +2 -2
  11. package/dist/motion-wasm/index.mjs +1 -1
  12. package/dist/{node-BOHn8gpk.js → node-BAo2ivVu.js} +1 -1
  13. package/dist/{node-Bo1g8hLO.mjs → node-CQcgxO8l.mjs} +1 -1
  14. package/dist/pipeline-runner/index.js +55 -12
  15. package/dist/pipeline-runner/index.mjs +54 -11
  16. package/dist/{process-memory-DmrHWybb.mjs → process-memory-BPEKERfe.mjs} +1 -1
  17. package/dist/{process-memory-C3084DOt.js → process-memory-BZvkQCLP.js} +1 -1
  18. package/dist/recorder/index.js +6 -6
  19. package/dist/recorder/index.mjs +3 -3
  20. package/dist/{segment-demux-js-BrQ_A0oi.js → segment-demux-js-B1L1pfoc.js} +1 -1
  21. package/dist/{segment-demux-js-C-a2pghM.mjs → segment-demux-js-CubhFNwb.mjs} +1 -1
  22. package/dist/session-decode/decode-worker-child.js +115 -5
  23. package/dist/session-decode/decode-worker-child.mjs +114 -4
  24. package/dist/stream-broker/_stub.js +2 -2
  25. package/dist/stream-broker/{_virtual_mf-localSharedImportMap___mfe_internal__addon_stream_broker_widgets-AH6OJ3hJ.mjs → _virtual_mf-localSharedImportMap___mfe_internal__addon_stream_broker_widgets-DJ4k5ZBb.mjs} +3 -3
  26. package/dist/stream-broker/_virtual_mf___mfe_internal__addon_stream_broker_widgets__loadShare___mf_0_camstack_mf_1_types__loadShare__.js-xdmO8wYp.mjs +26 -0
  27. package/dist/stream-broker/_virtual_mf___mfe_internal__addon_stream_broker_widgets__loadShare___mf_0_camstack_mf_1_ui_mf_2_library__loadShare__.js-DPpl_mtg.mjs +26 -0
  28. package/dist/stream-broker/demux-worker-child.js +1 -1
  29. package/dist/stream-broker/demux-worker-child.mjs +1 -1
  30. package/dist/stream-broker/{hostInit-XNyn-FTM.mjs → hostInit-oy-XDnw6.mjs} +3 -3
  31. package/dist/stream-broker/index.js +170 -62
  32. package/dist/stream-broker/index.mjs +170 -62
  33. package/dist/stream-broker/remoteEntry.js +1 -1
  34. package/dist/{worker-protocol-BLfaD5uC.js → worker-protocol-C-0LYdSt.js} +2 -1
  35. package/dist/{worker-protocol-vc8WWhjx.mjs → worker-protocol-DsuI4ifI.mjs} +2 -1
  36. package/package.json +5 -3
  37. package/dist/addon-utils-C6b5Tnia.js +0 -625
  38. package/dist/addon-utils-C8KTuPdE.mjs +0 -583
  39. package/dist/stream-broker/_virtual_mf___mfe_internal__addon_stream_broker_widgets__loadShare___mf_0_camstack_mf_1_types__loadShare__.js-CQyiEd0l.mjs +0 -26
  40. package/dist/stream-broker/_virtual_mf___mfe_internal__addon_stream_broker_widgets__loadShare___mf_0_camstack_mf_1_ui_mf_2_library__loadShare__.js-BrTM_tsb.mjs +0 -26
@@ -1,10 +1,10 @@
1
1
  import { r as __toESM } from "../chunk-DnnnRqeS.mjs";
2
- import { $ as loadContributionCapability, $t as union, At as CAM_PROFILE_ORDER, Bt as parseProfileBrokerId, C as RATE_CONTROL_RELAXED, Ct as errMsg, D as RingBuffer, Dt as invocationFromEncodeProfile, Et as buildFfmpegArgs$1, F as createHwAccelCache, Ft as isEvent, G as egressTranscodeSharingKey, Gt as boolean, I as createLogChannelsProvider, It as makeProfileBrokerId, Jt as literal, K as egressTransportFromRequest, Kt as discriminatedUnion, Lt as makeSourceBrokerId, Mt as DeviceType, N as batteryCapability, Nt as createEvent, Ot as isSoftwareDecode, P as cameraStreamsCapability, Qt as string, R as declareLogChannel, Rt as nodePin, St as webrtcSessionCapability, Ut as _enum, V as deriveBatteryPresence, Wt as array, Xt as object, Yt as number, Zt as record, bt as streamBrokerCapability, en as EventCategory, et as logChannelsCapability, g as EncodeProfileSchema, ht as resolveEgressDecodeHwAccel, i as BatteryStatusSchema, jt as DeviceFeature, k as addonWidgetsSourceCapability, kt as BaseAddon, nt as maskUrlCredentials, w as RATE_CONTROL_TIGHT, wt as AUDIO_PRESETS } from "../dist-g0Or5_pR.mjs";
3
- import { i as NO_COST_CLAIM, n as Fmp4FragmentChild, r as Fmp4FragmentPlane, t as ChildCostRegistry } from "../node-Bo1g8hLO.mjs";
2
+ import { $ as loadContributionCapability, $t as string, At as BaseAddon, C as RATE_CONTROL_RELAXED, Ct as errMsg, D as RingBuffer, Dt as invocationFromEncodeProfile, Et as buildFfmpegArgs$1, F as createHwAccelCache, G as egressTranscodeSharingKey, Gt as array, I as createLogChannelsProvider, It as isEvent, K as egressTransportFromRequest, Kt as boolean, Lt as makeProfileBrokerId, Mt as DeviceFeature, N as batteryCapability, Nt as DeviceType, Ot as isSoftwareDecode, P as cameraStreamsCapability, Pt as createEvent, Qt as record, R as declareLogChannel, Rt as makeSourceBrokerId, St as webrtcSessionCapability, V as deriveBatteryPresence, Vt as parseProfileBrokerId, Wt as _enum, Xt as number, Yt as literal, Zt as object, bt as streamBrokerCapability, en as union, et as logChannelsCapability, g as EncodeProfileSchema, ht as resolveEgressDecodeHwAccel, i as BatteryStatusSchema, jt as CAM_PROFILE_ORDER, k as addonWidgetsSourceCapability, kt as BOOT_RECOVERY_BACKOFF_MS, nt as maskUrlCredentials, qt as discriminatedUnion, tn as EventCategory, w as RATE_CONTROL_TIGHT, wt as AUDIO_PRESETS, zt as nodePin } from "../dist-CTmOaCwF.mjs";
3
+ import { i as NO_COST_CLAIM, n as Fmp4FragmentChild, r as Fmp4FragmentPlane, t as ChildCostRegistry } from "../node-CQcgxO8l.mjs";
4
4
  import { t as parseRestreamPath } from "../restream-intent-B4BXZra7.mjs";
5
5
  import { n as profileForStreamId } from "../remote-restream-BeHi78PZ.mjs";
6
6
  import { n as RowMapStore, t as retireRootKeys } from "../retire-root-keys-DMolfhsP.mjs";
7
- import { i as require_mp4box_all, n as demuxSegmentPreferJs, r as runFfmpegOnce, t as demuxSegmentFullJs } from "../segment-demux-js-C-a2pghM.mjs";
7
+ import { i as require_mp4box_all, n as demuxSegmentPreferJs, r as runFfmpegOnce, t as demuxSegmentFullJs } from "../segment-demux-js-CubhFNwb.mjs";
8
8
  import { createRequire } from "node:module";
9
9
  import * as crypto$1 from "node:crypto";
10
10
  import crypto, { createHash, randomBytes, randomUUID } from "node:crypto";
@@ -2242,6 +2242,20 @@ function appendAudioMediaBlock(videoSdp, audioBlock) {
2242
2242
  return `${videoSdp.replace(/[\r\n]+$/, "")}\r\n${audioBlock}\r\n`;
2243
2243
  }
2244
2244
  //#endregion
2245
+ //#region src/stream-broker/rtsp/join-burst-admission.ts
2246
+ /**
2247
+ * Decide whether this session may take this burst.
2248
+ *
2249
+ * Pure and total: no clock, no logger, no restreamer state. The restreamer maps
2250
+ * the result onto its counters and its `continue`.
2251
+ */
2252
+ function admitJoinBurst(input) {
2253
+ if (input.muted && !input.detectionIntent) return !input.fromRing || input.spanMs > input.liveEdgeMaxSpanMs ? "live-edge" : "none";
2254
+ if (!input.detectionIntent && input.spanMs > input.bound.maxSpanMs) return "span";
2255
+ if (input.packets > input.bound.maxPackets) return "packets";
2256
+ return "none";
2257
+ }
2258
+ //#endregion
2245
2259
  //#region src/stream-broker/rtsp/rtsp-types.ts
2246
2260
  /** RTSP method constants. */
2247
2261
  var RTSP_METHODS = [
@@ -2868,8 +2882,6 @@ var RtspRestreamer = class {
2868
2882
  if (ready.length === 0) return;
2869
2883
  const preRollPlans = /* @__PURE__ */ new Map();
2870
2884
  const bound = this.currentPrimeBound();
2871
- const overSpan = spanMs > bound.maxSpanMs;
2872
- const overPackets = primePackets.length > bound.maxPackets;
2873
2885
  /**
2874
2886
  * Resolve (and memoize) the plan for one intent.
2875
2887
  *
@@ -2935,14 +2947,18 @@ var RtspRestreamer = class {
2935
2947
  continue;
2936
2948
  }
2937
2949
  }
2938
- if (session.isMuted() && !detectionIntent) {
2939
- if (!fromRing || spanMs > LIVE_EDGE_MAX_SPAN_MS) {
2940
- this.dropsWithheldMutedLiveEdge++;
2941
- withheld++;
2942
- continue;
2943
- }
2944
- } else if (overSpan || overPackets) {
2945
- if (overSpan) this.dropsWithheldSpan++;
2950
+ const withhold = admitJoinBurst({
2951
+ muted: session.isMuted(),
2952
+ detectionIntent,
2953
+ fromRing,
2954
+ spanMs,
2955
+ packets: primePackets.length,
2956
+ bound,
2957
+ liveEdgeMaxSpanMs: LIVE_EDGE_MAX_SPAN_MS
2958
+ });
2959
+ if (withhold !== "none") {
2960
+ if (withhold === "live-edge") this.dropsWithheldMutedLiveEdge++;
2961
+ else if (withhold === "span") this.dropsWithheldSpan++;
2946
2962
  else this.dropsWithheldPackets++;
2947
2963
  withheld++;
2948
2964
  continue;
@@ -4128,6 +4144,90 @@ function buildAudioCodecCapApi(api) {
4128
4144
  flushEncode: (input) => router.flushEncode.mutate(input)
4129
4145
  };
4130
4146
  }
4147
+ //#endregion
4148
+ //#region src/stream-broker/stream-broker/catalog-pull-backoff.ts
4149
+ /**
4150
+ * CATALOG-PULL BACKOFF — how often the broker asks a camera whose
4151
+ * `stream-catalog` pull keeps failing.
4152
+ *
4153
+ * ## What this exists to stop
4154
+ *
4155
+ * 2026-08-25, device 3629 ("Videocamera porta retro", Reolink). Its Baichuan
4156
+ * session expired under a socket that stayed open, so every
4157
+ * `stream-catalog.getCatalog` answered `buildVideoStreamOptions failed …
4158
+ * responseCode 400`. The reconcile poll asked again 30 s later. And again. For
4159
+ * 35 minutes, ~70 identical failures, each one a login attempt, a 10 s timeout
4160
+ * budget and a `debug` line nobody was reading.
4161
+ *
4162
+ * The fleet was never at risk from that camera — `reconcileAllCatalogs` fans
4163
+ * out with `Promise.allSettled` and `reconcileDeviceCatalogNow` catches its own
4164
+ * pull, so exactly one device was omitted (that isolation is frozen by
4165
+ * `scripts/check-catalog-per-device-isolation.ts`). What was wrong is that the
4166
+ * omission was invisible and the retry was a flat 30 s hammer that could not
4167
+ * have recovered anyway.
4168
+ *
4169
+ * ## The shape
4170
+ *
4171
+ * The ladder is {@link BOOT_RECOVERY_BACKOFF_MS} — the repo's ONE retry
4172
+ * schedule for work that can fail for reasons that pass: two cheap attempts
4173
+ * (15 s, 60 s) for a blip, then the long tail (5 m → 90 m) for a camera that
4174
+ * is genuinely gone.
4175
+ *
4176
+ * ## The one place this DIVERGES from boot recovery, and why
4177
+ *
4178
+ * The boot ladder ENDS: it runs out and manual re-arm is the only path. This
4179
+ * one CLAMPS at the last rung and keeps asking every 90 minutes forever.
4180
+ *
4181
+ * Boot recovery can end because a human is present — a node that just booted
4182
+ * wrong is a node someone is looking at. A camera whose session expired at
4183
+ * 03:00 has nobody. The reconcile poll is the ONLY thing that will ever ask it
4184
+ * again: no event fires when a camera silently starts working, and a device
4185
+ * that never re-enters the catalog is a device with no broker, no recording
4186
+ * and no detection, permanently. Ending the chain would convert a transient
4187
+ * session expiry into a permanent outage — precisely the failure it is meant
4188
+ * to bound. A 90-minute floor is not a spin: it is ~16 pulls a day for one
4189
+ * broken camera, against 2 880 before this.
4190
+ */
4191
+ /**
4192
+ * The rung the ladder settles on. Read off the shared schedule rather than
4193
+ * written down twice; the literal only keeps the expression total for a
4194
+ * hypothetically empty ladder, and is not the clamp.
4195
+ */
4196
+ var LAST_RUNG_MS = BOOT_RECOVERY_BACKOFF_MS[BOOT_RECOVERY_BACKOFF_MS.length - 1] ?? 90 * 6e4;
4197
+ /**
4198
+ * Delay before the next poll-driven attempt, given how many pulls in a row
4199
+ * have now failed (1 = the first failure).
4200
+ *
4201
+ * Clamped at the last rung rather than exhausted — see the module doc.
4202
+ */
4203
+ function catalogPullRetryDelayMs(consecutiveFailures) {
4204
+ return BOOT_RECOVERY_BACKOFF_MS[Math.max(consecutiveFailures, 1) - 1] ?? LAST_RUNG_MS;
4205
+ }
4206
+ /**
4207
+ * Advance the failure memory after one more failed pull.
4208
+ *
4209
+ * @param previous state before this failure, or `undefined` for the first one
4210
+ * @param nowMs wall clock at the moment of the failure
4211
+ */
4212
+ function nextCatalogPullFailureState(previous, nowMs) {
4213
+ const consecutiveFailures = (previous?.consecutiveFailures ?? 0) + 1;
4214
+ return {
4215
+ consecutiveFailures,
4216
+ nextAttemptAtMs: nowMs + catalogPullRetryDelayMs(consecutiveFailures)
4217
+ };
4218
+ }
4219
+ /**
4220
+ * May a POLL-driven pull run for this device right now?
4221
+ *
4222
+ * Only the poll is gated. An event-driven reconcile (device registered,
4223
+ * stream params changed) is EVIDENCE that something moved and always
4224
+ * attempts — a backoff that ignores new information is just a slower way of
4225
+ * being wrong.
4226
+ */
4227
+ function mayAttemptPolledCatalogPull(state, nowMs) {
4228
+ if (state === void 0) return true;
4229
+ return nowMs >= state.nextAttemptAtMs;
4230
+ }
4131
4231
  /**
4132
4232
  * Minimum gap between two re-dials of the same device. A re-dial costs a
4133
4233
  * ~2 s video interruption on every source of the camera; at the 30 s
@@ -10863,6 +10963,16 @@ var StreamPipeServer = class {
10863
10963
  //#endregion
10864
10964
  //#region src/stream-broker/stream-broker/stream-broker.ts
10865
10965
  var UNKNOWN_ATTRIBUTION = { kind: "unknown" };
10966
+ /**
10967
+ * RTSP reconnect backoff — CONSTANTS, and there is no operator knob.
10968
+ *
10969
+ * A "Reconnection" settings section once offered `initialReconnectDelayMs` /
10970
+ * `maxReconnectDelayMs` and described the exponential backoff below. Nothing
10971
+ * ever read either field: the backoff has always run on these two numbers, so
10972
+ * the section was a form that changed nothing. It was deleted on 2026-08-28
10973
+ * (D272) rather than wired, because the reconnect ladder is a transport
10974
+ * property the operator has no way to reason about — not a tuning surface.
10975
+ */
10866
10976
  var INITIAL_RECONNECT_DELAY_MS = 1e3;
10867
10977
  var MAX_RECONNECT_DELAY_MS = 3e4;
10868
10978
  /** Grace period before suspending after last consumer leaves. */
@@ -14642,6 +14752,13 @@ var StreamBrokerManager = class StreamBrokerManager {
14642
14752
  deviceOverridePersister = null;
14643
14753
  profileMapPersister = null;
14644
14754
  deviceCatalogOperations = /* @__PURE__ */ new Map();
14755
+ /**
14756
+ * Devices whose `stream-catalog` pull is currently failing, and when the
14757
+ * POLL may ask again. Absent = healthy; an entry is deleted the moment a
14758
+ * pull succeeds. See `catalog-pull-backoff.ts` for the ladder and for the
14759
+ * outage that put it here.
14760
+ */
14761
+ catalogPullFailures = /* @__PURE__ */ new Map();
14645
14762
  eventBus = null;
14646
14763
  /**
14647
14764
  * Per-broker stream health flag set by the watchdog. `undefined`
@@ -16193,26 +16310,54 @@ var StreamBrokerManager = class StreamBrokerManager {
16193
16310
  /**
16194
16311
  * Pull one camera's `stream-catalog` and reconcile its cam-streams: upsert
16195
16312
  * every descriptor, retract any cam-stream no longer in the catalog. A pull
16196
- * that throws (provider mid-restart, no `stream-catalog` cap) is skipped
16197
- * the poll retries. An EMPTY catalog is also skipped rather than tearing
16198
- * down (a provider probe can transiently return none); genuine removal flows
16199
- * through the device-unregistered path.
16313
+ * that throws (provider mid-restart, no `stream-catalog` cap, a camera whose
16314
+ * session died) omits THIS DEVICE ONLY — it is logged at `warn` with the
16315
+ * device's id and re-asked on the `catalog-pull-backoff.ts` ladder. An EMPTY
16316
+ * catalog is also skipped rather than tearing down (a provider probe can
16317
+ * transiently return none); genuine removal flows through the
16318
+ * device-unregistered path.
16319
+ *
16320
+ * `trigger` decides whether the backoff applies — see
16321
+ * {@link CatalogReconcileTrigger}. It defaults to `'event'` (always attempt)
16322
+ * so only the caller that actually repeats forever pays the throttle.
16200
16323
  */
16201
- async reconcileDeviceCatalog(deviceId) {
16202
- await this.runDeviceCatalogOperation(deviceId, () => this.reconcileDeviceCatalogNow(deviceId));
16324
+ async reconcileDeviceCatalog(deviceId, trigger = "event") {
16325
+ await this.runDeviceCatalogOperation(deviceId, () => this.reconcileDeviceCatalogNow(deviceId, trigger));
16203
16326
  }
16204
- async reconcileDeviceCatalogNow(deviceId) {
16327
+ async reconcileDeviceCatalogNow(deviceId, trigger) {
16205
16328
  if (!this.api) return;
16329
+ const failure = this.catalogPullFailures.get(deviceId);
16330
+ if (trigger === "poll" && !mayAttemptPolledCatalogPull(failure, Date.now())) {
16331
+ this.logger.debug("reconcileDeviceCatalog: skipped — device is on catalog-pull backoff", {
16332
+ tags: { deviceId },
16333
+ meta: {
16334
+ consecutiveFailures: failure?.consecutiveFailures ?? 0,
16335
+ nextAttemptInMs: Math.max(0, (failure?.nextAttemptAtMs ?? 0) - Date.now())
16336
+ }
16337
+ });
16338
+ return;
16339
+ }
16206
16340
  let descriptors;
16207
16341
  try {
16208
16342
  descriptors = await this.withCatalogTimeout(this.api.streamCatalog.getCatalog.query({ deviceId }), deviceId) ?? [];
16209
16343
  } catch (err) {
16210
- this.logger.debug("reconcileDeviceCatalog: stream-catalog pull failed — will retry", {
16344
+ const next = nextCatalogPullFailureState(this.catalogPullFailures.get(deviceId), Date.now());
16345
+ this.catalogPullFailures.set(deviceId, next);
16346
+ this.logger.warn("stream-catalog pull failed — device omitted from this catalog reconcile", {
16211
16347
  tags: { deviceId },
16212
- meta: { error: errMsg(err) }
16348
+ meta: {
16349
+ trigger,
16350
+ consecutiveFailures: next.consecutiveFailures,
16351
+ retryInMs: catalogPullRetryDelayMs(next.consecutiveFailures),
16352
+ error: errMsg(err)
16353
+ }
16213
16354
  });
16214
16355
  return;
16215
16356
  }
16357
+ if (this.catalogPullFailures.delete(deviceId)) this.logger.info("stream-catalog pull recovered — device is back in the catalog", {
16358
+ tags: { deviceId },
16359
+ meta: { descriptors: descriptors.length }
16360
+ });
16216
16361
  if (descriptors.length === 0) return;
16217
16362
  const keep = new Set(descriptors.map((d) => d.camStreamId));
16218
16363
  await this.publishCatalog(deviceId, descriptors);
@@ -16247,10 +16392,11 @@ var StreamBrokerManager = class StreamBrokerManager {
16247
16392
  await this.releaseDisabledDeviceBrokers(d.id, firstSeen);
16248
16393
  } else this.disabledDevices.delete(d.id);
16249
16394
  const live = cameras.filter((d) => !d.disabled);
16250
- await Promise.allSettled(live.map((d) => this.reconcileDeviceCatalog(d.id)));
16395
+ await Promise.allSettled(live.map((d) => this.reconcileDeviceCatalog(d.id, "poll")));
16251
16396
  await Promise.allSettled(live.map((d) => this.reconcileDeviceAudioPlane(d.id)));
16252
16397
  const liveIds = new Set(live.map((d) => d.id));
16253
16398
  for (const deviceId of [...this.audioPlaneState.keys()]) if (!liveIds.has(deviceId)) this.audioPlaneState.delete(deviceId);
16399
+ for (const deviceId of [...this.catalogPullFailures.keys()]) if (!liveIds.has(deviceId)) this.catalogPullFailures.delete(deviceId);
16254
16400
  }
16255
16401
  /**
16256
16402
  * ONE device's audio-plane reconcile pass. See `audio-plane-reconcile.ts`
@@ -16392,6 +16538,7 @@ var StreamBrokerManager = class StreamBrokerManager {
16392
16538
  await this.runDeviceCatalogOperation(deviceId, () => this.retractDeviceNow(deviceId, opts));
16393
16539
  }
16394
16540
  async retractDeviceNow(deviceId, opts) {
16541
+ this.catalogPullFailures.delete(deviceId);
16395
16542
  const existing = this.cameraStreams.get(deviceId);
16396
16543
  if (existing) for (const camStreamId of Array.from(existing.keys())) await this.retractCameraStream({
16397
16544
  deviceId,
@@ -29093,9 +29240,6 @@ var StreamBrokerAddon = class extends BaseAddon {
29093
29240
  super({
29094
29241
  defaultPreBufferSec: 10,
29095
29242
  rtspPort: 8554,
29096
- maxDecodeFps: 5,
29097
- initialReconnectDelayMs: 1e3,
29098
- maxReconnectDelayMs: 3e4,
29099
29243
  catalogReconcileIntervalSec: 30,
29100
29244
  joinBurstMaxSpanMs: DEFAULT_PRIME_BURST_BOUND.maxSpanMs,
29101
29245
  preRollMs: 0,
@@ -29703,16 +29847,6 @@ var StreamBrokerAddon = class extends BaseAddon {
29703
29847
  step: 1,
29704
29848
  default: 8554
29705
29849
  },
29706
- {
29707
- type: "number",
29708
- key: "maxDecodeFps",
29709
- label: "Max Decode FPS",
29710
- description: "Maximum frames per second for decoded stream subscribers",
29711
- min: 1,
29712
- max: 30,
29713
- step: 1,
29714
- default: 5
29715
- },
29716
29850
  {
29717
29851
  type: "select",
29718
29852
  key: "hwaccel",
@@ -29779,32 +29913,6 @@ var StreamBrokerAddon = class extends BaseAddon {
29779
29913
  unit: "s"
29780
29914
  }
29781
29915
  ]
29782
- }, {
29783
- id: "stream-broker-reconnect",
29784
- title: "Reconnection",
29785
- description: "Controls how quickly the broker retries a failed RTSP connection (exponential backoff).",
29786
- columns: 2,
29787
- fields: [{
29788
- type: "number",
29789
- key: "initialReconnectDelayMs",
29790
- label: "Initial Reconnect Delay",
29791
- description: "First retry delay after a stream disconnect",
29792
- min: 100,
29793
- max: 1e4,
29794
- step: 100,
29795
- default: 1e3,
29796
- unit: "ms"
29797
- }, {
29798
- type: "number",
29799
- key: "maxReconnectDelayMs",
29800
- label: "Max Reconnect Delay",
29801
- description: "Upper bound for exponential backoff between retries",
29802
- min: 1e3,
29803
- max: 12e4,
29804
- step: 1e3,
29805
- default: 3e4,
29806
- unit: "ms"
29807
- }]
29808
29916
  }] });
29809
29917
  }
29810
29918
  };
@@ -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-AH6OJ3hJ.mjs")).catch((e) => {
33
+ return l ||= d(() => import("./_virtual_mf-localSharedImportMap___mfe_internal__addon_stream_broker_widgets-DJ4k5ZBb.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-4EMKvxCp.js");
1
+ const require_dist = require("./dist-WUZH-lAM.js");
2
2
  //#region src/session-decode/native-lease-config.ts
3
3
  /**
4
4
  * Resolution of the native-frame hold / tile knobs for one decode worker.
@@ -253,6 +253,7 @@ function isWorkerReply(value) {
253
253
  case "ended": return true;
254
254
  case "error": return typeof value.message === "string" && (value.frameId === void 0 || isFiniteNumber(value.frameId));
255
255
  case "log": return isWorkerLogLevel(value.level) && typeof value.message === "string";
256
+ case "dialTiming": return isFiniteNumber(value.hwContextMs) && isFiniteNumber(value.demuxerOpenMs) && isFiniteNumber(value.decoderCreateMs) && isFiniteNumber(value.firstDecodeMs) && typeof value.streamInfoProbed === "boolean";
256
257
  default: return false;
257
258
  }
258
259
  }
@@ -1,4 +1,4 @@
1
- import { b as NativeLeaseSettingsSchema, p as DEFAULT_NATIVE_LEASE_SETTINGS, y as NativeLeaseAdmissionSchema } from "./dist-g0Or5_pR.mjs";
1
+ import { b as NativeLeaseSettingsSchema, p as DEFAULT_NATIVE_LEASE_SETTINGS, y as NativeLeaseAdmissionSchema } from "./dist-CTmOaCwF.mjs";
2
2
  //#region src/session-decode/native-lease-config.ts
3
3
  /**
4
4
  * Resolution of the native-frame hold / tile knobs for one decode worker.
@@ -253,6 +253,7 @@ function isWorkerReply(value) {
253
253
  case "ended": return true;
254
254
  case "error": return typeof value.message === "string" && (value.frameId === void 0 || isFiniteNumber(value.frameId));
255
255
  case "log": return isWorkerLogLevel(value.level) && typeof value.message === "string";
256
+ case "dialTiming": return isFiniteNumber(value.hwContextMs) && isFiniteNumber(value.demuxerOpenMs) && isFiniteNumber(value.decoderCreateMs) && isFiniteNumber(value.firstDecodeMs) && typeof value.streamInfoProbed === "boolean";
256
257
  default: return false;
257
258
  }
258
259
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@camstack/addon-pipeline",
3
- "version": "1.2.137",
3
+ "version": "1.2.139",
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",
@@ -109,7 +109,8 @@
109
109
  "execution": {
110
110
  "placement": "any-node",
111
111
  "heapProfile": "heavy",
112
- "group": "detection"
112
+ "group": "detection",
113
+ "rssBudgetMb": 1536
113
114
  },
114
115
  "protected": true,
115
116
  "icon": "assets/icon.svg",
@@ -152,7 +153,8 @@
152
153
  "entry": "./dist/audio-analyzer/index.js",
153
154
  "execution": {
154
155
  "placement": "any-node",
155
- "heapProfile": "heavy"
156
+ "heapProfile": "heavy",
157
+ "rssBudgetMb": 512
156
158
  },
157
159
  "capabilities": [
158
160
  {