@camstack/addon-pipeline 1.2.186 → 1.2.187

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 (35) hide show
  1. package/dist/audio-analyzer/index.js +2 -2
  2. package/dist/audio-analyzer/index.mjs +2 -2
  3. package/dist/detection-pipeline/index.js +5 -5
  4. package/dist/detection-pipeline/index.mjs +4 -4
  5. package/dist/{dist-yaetDPpW.mjs → dist-HWdaHLLK.mjs} +21 -0
  6. package/dist/{dist-CiVhPNTB.js → dist-e2OKAUGI.js} +21 -0
  7. package/dist/{lazy-sharp-D1PX1Psd.js → lazy-sharp-AJ7newgl.js} +1 -1
  8. package/dist/{local-frame-registry-CANBpRSg.mjs → local-frame-registry-Bki81rM0.mjs} +1 -1
  9. package/dist/{local-frame-registry-D5d1W1Vf.js → local-frame-registry-Cl1VUpx_.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-CCRb0fqW.mjs → node-CwSBH-3M.mjs} +1 -1
  13. package/dist/{node-DGzZLg-c.js → node-Dw6FrDFS.js} +1 -1
  14. package/dist/pipeline-runner/index.js +166 -10
  15. package/dist/pipeline-runner/index.mjs +165 -9
  16. package/dist/{process-memory-BIy4e_mZ.mjs → process-memory-CnTmyk9s.mjs} +1 -1
  17. package/dist/{process-memory-C7f66zUT.js → process-memory-einpgBTr.js} +1 -1
  18. package/dist/recorder/index.js +2 -2
  19. package/dist/recorder/index.mjs +2 -2
  20. package/dist/{segment-demux-js-CViDx3UC.mjs → segment-demux-js-CuNHMubE.mjs} +1 -1
  21. package/dist/{segment-demux-js-CnqYsNPt.js → segment-demux-js-CyCdXcFZ.js} +1 -1
  22. package/dist/session-decode/decode-worker-child.js +2 -2
  23. package/dist/session-decode/decode-worker-child.mjs +1 -1
  24. package/dist/stream-broker/_stub.js +1 -1
  25. package/dist/stream-broker/{_virtual_mf-localSharedImportMap___mfe_internal__addon_stream_broker_widgets-CR6bzoE5.mjs → _virtual_mf-localSharedImportMap___mfe_internal__addon_stream_broker_widgets-CWa6ONcK.mjs} +3 -3
  26. package/dist/stream-broker/{_virtual_mf___mfe_internal__addon_stream_broker_widgets__loadShare___mf_0_camstack_mf_1_ui_mf_2_library__loadShare__.js-BC-nahrU.mjs → _virtual_mf___mfe_internal__addon_stream_broker_widgets__loadShare___mf_0_camstack_mf_1_ui_mf_2_library__loadShare__.js-D5XwN-xi.mjs} +1 -1
  27. package/dist/stream-broker/demux-worker-child.js +1 -1
  28. package/dist/stream-broker/demux-worker-child.mjs +1 -1
  29. package/dist/stream-broker/{hostInit-DgDPe3HR.mjs → hostInit-DUqxWCSo.mjs} +3 -3
  30. package/dist/stream-broker/index.js +70 -48
  31. package/dist/stream-broker/index.mjs +70 -48
  32. package/dist/stream-broker/remoteEntry.js +1 -1
  33. package/dist/{worker-protocol-Db6BWHr-.js → worker-protocol-Bva8nEZO.js} +1 -1
  34. package/dist/{worker-protocol-BcKW7xgG.mjs → worker-protocol-DN1y2Vyk.mjs} +1 -1
  35. package/package.json +1 -1
@@ -1,10 +1,10 @@
1
1
  import { r as __toESM } from "../chunk-DnnnRqeS.mjs";
2
- import { $t as record, At as BOOT_RECOVERY_BACKOFF_MS, Bt as nodePin, C as RATE_CONTROL_RELAXED, Ct as webrtcSessionCapability, D as RingBuffer, Dt as buildFfmpegArgs$1, F as createHwAccelCache, Ft as createEvent, G as egressTranscodeSharingKey, Gt as _enum, Ht as parseProfileBrokerId, I as createLogChannelsProvider, Jt as discriminatedUnion, K as egressTransportFromRequest, Kt as array, Lt as isEvent, Mt as CAM_PROFILE_ORDER, N as batteryCapability, Nt as DeviceFeature, Ot as invocationFromEncodeProfile, P as cameraStreamsCapability, Pt as DeviceType, Qt as object, R as declareLogChannel, Rt as makeProfileBrokerId, Tt as AUDIO_PRESETS, V as deriveBatteryPresence, Xt as literal, Zt as number, en as string, et as loadContributionCapability, gt as resolveEgressDecodeHwAccel, h as EncodeProfileSchema, i as BatteryStatusSchema, jt as BaseAddon, k as addonWidgetsSourceCapability, kt as isSoftwareDecode, nn as EventCategory, qt as boolean, rt as maskUrlCredentials, tn as union, tt as logChannelsCapability, w as RATE_CONTROL_TIGHT, wt as errMsg, xt as streamBrokerCapability, zt as makeSourceBrokerId } from "../dist-yaetDPpW.mjs";
3
- import { i as NO_COST_CLAIM, n as Fmp4FragmentChild, r as Fmp4FragmentPlane, t as ChildCostRegistry } from "../node-CCRb0fqW.mjs";
2
+ import { $t as record, At as BOOT_RECOVERY_BACKOFF_MS, Bt as nodePin, C as RATE_CONTROL_RELAXED, Ct as webrtcSessionCapability, D as RingBuffer, Dt as buildFfmpegArgs$1, F as createHwAccelCache, Ft as createEvent, G as egressTranscodeSharingKey, Gt as _enum, Ht as parseProfileBrokerId, I as createLogChannelsProvider, Jt as discriminatedUnion, K as egressTransportFromRequest, Kt as array, Lt as isEvent, Mt as CAM_PROFILE_ORDER, N as batteryCapability, Nt as DeviceFeature, Ot as invocationFromEncodeProfile, P as cameraStreamsCapability, Pt as DeviceType, Qt as object, R as declareLogChannel, Rt as makeProfileBrokerId, Tt as AUDIO_PRESETS, V as deriveBatteryPresence, Xt as literal, Zt as number, en as string, et as loadContributionCapability, gt as resolveEgressDecodeHwAccel, h as EncodeProfileSchema, i as BatteryStatusSchema, jt as BaseAddon, k as addonWidgetsSourceCapability, kt as isSoftwareDecode, nn as EventCategory, qt as boolean, rt as maskUrlCredentials, tn as union, tt as logChannelsCapability, w as RATE_CONTROL_TIGHT, wt as errMsg, xt as streamBrokerCapability, zt as makeSourceBrokerId } from "../dist-HWdaHLLK.mjs";
3
+ import { i as NO_COST_CLAIM, n as Fmp4FragmentChild, r as Fmp4FragmentPlane, t as ChildCostRegistry } from "../node-CwSBH-3M.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-CViDx3UC.mjs";
7
+ import { i as require_mp4box_all, n as demuxSegmentPreferJs, r as runFfmpegOnce, t as demuxSegmentFullJs } from "../segment-demux-js-CuNHMubE.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";
@@ -23478,6 +23478,27 @@ var AdaptiveController = class {
23478
23478
  this.healthySince = now;
23479
23479
  }
23480
23480
  };
23481
+ var PLAYBACK_PROFILE_FALLBACK_ORDER = [
23482
+ "high",
23483
+ "mid",
23484
+ "low"
23485
+ ];
23486
+ function profileSearchOrder(requested) {
23487
+ return [requested, ...PLAYBACK_PROFILE_FALLBACK_ORDER.filter((p) => p !== requested)];
23488
+ }
23489
+ /**
23490
+ * Where the feeder would snap this gap to — the next covered start, else the
23491
+ * last ms of the footage behind — or `null` when the tier records nothing.
23492
+ * The same rule as `resolveSnapTarget` in the feeder, kept in step by test.
23493
+ */
23494
+ function gapSnapTargetMs(gap) {
23495
+ return gap.nearestEdgeMs ?? (typeof gap.prevEndMs === "number" ? gap.prevEndMs - 1 : null);
23496
+ }
23497
+ /** True when a seek at `epochMs` on this tier would play, not `gap`. */
23498
+ function gapReachable(gap, epochMs) {
23499
+ const target = gapSnapTargetMs(gap);
23500
+ return target !== null && Math.abs(target - epochMs) <= 12e4;
23501
+ }
23481
23502
  //#endregion
23482
23503
  //#region src/stream-broker/recorded/control-protocol.ts
23483
23504
  var ControlMessageSchema = discriminatedUnion("t", [
@@ -23564,6 +23585,15 @@ var ServerMessageSchema = discriminatedUnion("t", [
23564
23585
  "mid",
23565
23586
  "low"
23566
23587
  ])
23588
+ }),
23589
+ object({
23590
+ t: literal("servedProfile"),
23591
+ profile: _enum([
23592
+ "high",
23593
+ "mid",
23594
+ "low"
23595
+ ]),
23596
+ requested: string()
23567
23597
  })
23568
23598
  ]);
23569
23599
  function parseControlMessage(raw) {
@@ -24367,30 +24397,6 @@ var SCRUB_ACK_TIMEOUT_MS = 2e3;
24367
24397
  /** Minimum gap between two lines of the same pathological kind, per drag. */
24368
24398
  var SCRUB_PATHOLOGY_LOG_INTERVAL_MS = 1e3;
24369
24399
  /**
24370
- * How far a `gap` locate may be SNAPPED onto real footage.
24371
- *
24372
- * A snap is a CORRECTION — the playhead landed a moment outside coverage and
24373
- * the operator plainly means the footage beside it — not a SEARCH for wherever
24374
- * footage happens to exist. The distinction is not cosmetic, because the index
24375
- * that answers `locate` cannot tell "there is no footage here" apart from "I
24376
- * have not walked this far back yet": it is rebuilt by walking the archive on
24377
- * every recorder start, and that walk takes minutes.
24378
- *
24379
- * Production 2026-08-02: the recorder had restarted 9 minutes earlier, so
24380
- * `locate` answered `gap` for the whole timeline with a `nearestEdgeMs` 6
24381
- * minutes to 23 HOURS away. Unbounded snapping turned every seek and every drag
24382
- * tick into a segment read against the addon that was busy re-walking, each one
24383
- * blew the 8 s budget, and both surfaces died. Bounded, all of those answer
24384
- * `gap` for free — exactly as they did before snapping existed.
24385
- *
24386
- * 120 s covers the real cases by a wide margin: an inter-segment crack is
24387
- * 11–17 ms, and the dead band between two recording bands measured 48 s. Beyond
24388
- * that the server is answering a question the viewer did not ask; the viewer
24389
- * holds the coverage ranges and can offer "jump to nearest footage" as an
24390
- * action instead.
24391
- */
24392
- var SNAP_MAX_DISTANCE_MS = 12e4;
24393
- /**
24394
24400
  * Decide where a `gap` locate should snap: forward to the next footage edge,
24395
24401
  * else backward onto the last ms of the footage behind (`prevEndMs − 1`, which
24396
24402
  * also hops the 11–17 ms inter-segment cracks). Rejects a candidate further than
@@ -24401,7 +24407,7 @@ function resolveSnapTarget(loc, requestedMs) {
24401
24407
  const snapMs = loc.nearestEdgeMs ?? (typeof loc.prevEndMs === "number" ? loc.prevEndMs - 1 : null);
24402
24408
  if (snapMs === null) return { kind: "none" };
24403
24409
  const distanceMs = Math.abs(snapMs - requestedMs);
24404
- if (distanceMs > SNAP_MAX_DISTANCE_MS) return {
24410
+ if (distanceMs > 12e4) return {
24405
24411
  kind: "too-far",
24406
24412
  snapMs,
24407
24413
  distanceMs
@@ -26663,22 +26669,6 @@ var RecordedFeeder = class {
26663
26669
  }
26664
26670
  };
26665
26671
  //#endregion
26666
- //#region src/stream-broker/recorded/playback-profile-fallback.ts
26667
- /**
26668
- * Recorded playback is pinned to one profile (no adaptive ladder). When the
26669
- * viewer asks for `mid` (auto/adaptive default) but the camera only kept
26670
- * `high` — typical of events-mode — locate must try the other tiers before
26671
- * reporting a gap.
26672
- */
26673
- var PLAYBACK_PROFILE_FALLBACK_ORDER = [
26674
- "high",
26675
- "mid",
26676
- "low"
26677
- ];
26678
- function profileSearchOrder(requested) {
26679
- return [requested, ...PLAYBACK_PROFILE_FALLBACK_ORDER.filter((p) => p !== requested)];
26680
- }
26681
- //#endregion
26682
26672
  //#region src/stream-broker/recorded/timeline-session.ts
26683
26673
  /**
26684
26674
  * Per-viewer coordinator over one broker WebRTC session. Owns the playback mode
@@ -26694,6 +26684,12 @@ var TimelineSession = class {
26694
26684
  mode = "live";
26695
26685
  feeder = null;
26696
26686
  profile = "mid";
26687
+ /**
26688
+ * What the CLIENT asked for, kept apart from what is playing: a seek
26689
+ * re-resolves from the request, so a range where High exists again gets
26690
+ * High back instead of inheriting the Mid the previous seek fell to.
26691
+ */
26692
+ requestedProfile = "mid";
26697
26693
  /** Transport rate belongs to the session, not to one profile-specific feeder.
26698
26694
  * Scrub pins `low`; release restores the selected playback profile and may
26699
26695
  * therefore rebuild the feeder. Carrying the rate keeps a paused scrub
@@ -26726,14 +26722,15 @@ var TimelineSession = class {
26726
26722
  this.emitLiveProfile();
26727
26723
  switch (msg.t) {
26728
26724
  case "playRecorded":
26725
+ this.requestedProfile = msg.profile;
26729
26726
  await this.playAt(msg.epoch, msg.profile, { travelFromMs: this.lastPositionMs });
26730
26727
  break;
26731
26728
  case "seek":
26732
- await this.playAt(msg.epoch, this.profile, { travelFromMs: this.lastPositionMs });
26729
+ await this.playAt(msg.epoch, this.requestedProfile, { travelFromMs: this.lastPositionMs });
26733
26730
  break;
26734
26731
  case "scrubCommit":
26735
- if (msg.dragId !== void 0) await this.playAt(msg.epoch, this.profile, { dragId: msg.dragId });
26736
- else await this.playAt(msg.epoch, this.profile);
26732
+ if (msg.dragId !== void 0) await this.playAt(msg.epoch, this.requestedProfile, { dragId: msg.dragId });
26733
+ else await this.playAt(msg.epoch, this.requestedProfile);
26737
26734
  break;
26738
26735
  case "scrubStart":
26739
26736
  (this.mode === "recorded" && this.feeder ? this.feeder : this.enterRecorded()).beginScrub(msg.dragId);
@@ -26757,6 +26754,7 @@ var TimelineSession = class {
26757
26754
  if (this.mode === "recorded") this.feeder?.stepFrame(msg.dir);
26758
26755
  break;
26759
26756
  case "setProfile":
26757
+ this.requestedProfile = msg.profile;
26760
26758
  if (msg.profile === this.profile) break;
26761
26759
  this.profile = msg.profile;
26762
26760
  if (this.mode === "recorded") this.enterRecorded();
@@ -26786,6 +26784,7 @@ var TimelineSession = class {
26786
26784
  */
26787
26785
  async playAt(epochMs, requestedProfile, opts) {
26788
26786
  const profile = await this.resolveProfile(requestedProfile, epochMs);
26787
+ this.reportServedProfile(profile, requestedProfile);
26789
26788
  const profileChanged = profile !== this.profile;
26790
26789
  this.profile = profile;
26791
26790
  const feeder = this.mode === "recorded" && this.feeder && !profileChanged ? this.feeder : this.enterRecorded();
@@ -26838,13 +26837,36 @@ var TimelineSession = class {
26838
26837
  continue;
26839
26838
  }
26840
26839
  if (loc.kind === "segment") return profile;
26841
- if (withFootage === null && loc.nearestEdgeMs !== null) {
26840
+ if (withFootage === null && gapReachable(loc, epochMs)) {
26842
26841
  if (profile === requested) return profile;
26843
26842
  withFootage = profile;
26844
26843
  }
26845
26844
  }
26846
26845
  return withFootage ?? requested;
26847
26846
  }
26847
+ /** The (served, requested) pair last told to the client, or null. */
26848
+ lastServedReport = null;
26849
+ /**
26850
+ * Never a silent switch (D62 spirit): the client learns which tier it is
26851
+ * watching whenever the pair changes — including the seek that gets the
26852
+ * requested tier back. Sent only when the served tier is one the wire
26853
+ * schema names; a session default outside the ladder is not reported.
26854
+ */
26855
+ reportServedProfile(profile, requested) {
26856
+ const key = `${profile}<${requested}`;
26857
+ if (key === this.lastServedReport) return;
26858
+ if (profile === requested && this.lastServedReport === null) {
26859
+ this.lastServedReport = key;
26860
+ return;
26861
+ }
26862
+ if (profile !== "high" && profile !== "mid" && profile !== "low") return;
26863
+ this.lastServedReport = key;
26864
+ this.deps.session.sendControl(serializeServerMessage({
26865
+ t: "servedProfile",
26866
+ profile,
26867
+ requested
26868
+ }));
26869
+ }
26848
26870
  goLive() {
26849
26871
  this.feeder?.dispose();
26850
26872
  this.feeder = null;
@@ -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-CR6bzoE5.mjs")).catch((e) => {
33
+ return l ||= d(() => import("./_virtual_mf-localSharedImportMap___mfe_internal__addon_stream_broker_widgets-CWa6ONcK.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-CiVhPNTB.js");
1
+ const require_dist = require("./dist-e2OKAUGI.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.
@@ -1,4 +1,4 @@
1
- import { b as NativeLeaseSettingsSchema, p as DEFAULT_NATIVE_LEASE_SETTINGS, y as NativeLeaseAdmissionSchema } from "./dist-yaetDPpW.mjs";
1
+ import { b as NativeLeaseSettingsSchema, p as DEFAULT_NATIVE_LEASE_SETTINGS, y as NativeLeaseAdmissionSchema } from "./dist-HWdaHLLK.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.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@camstack/addon-pipeline",
3
- "version": "1.2.186",
3
+ "version": "1.2.187",
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",