@camstack/addon-pipeline 1.2.49 → 1.2.51

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 (32) 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-J2DeRZAN.js → dist-BsBEe_rX.js} +67 -1
  6. package/dist/{dist-CLJKoYEP.mjs → dist-Dkvk5ykl.mjs} +62 -2
  7. package/dist/{event-loop-stall-monitor-B6dqQjiX.mjs → event-loop-stall-monitor-BvtjRcal.mjs} +1 -1
  8. package/dist/{event-loop-stall-monitor-Bkbiw20z.js → event-loop-stall-monitor-DqJXi0_B.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 +127 -114
  12. package/dist/pipeline-runner/index.mjs +127 -114
  13. package/dist/recorder/index.js +91 -4
  14. package/dist/recorder/index.mjs +91 -4
  15. package/dist/session-decode/decode-worker-child.js +57 -13
  16. package/dist/session-decode/decode-worker-child.mjs +57 -13
  17. package/dist/stream-broker/_stub.js +1 -1
  18. package/dist/stream-broker/{_virtual_mf-localSharedImportMap___mfe_internal__addon_stream_broker_widgets-DZikMEgD.mjs → _virtual_mf-localSharedImportMap___mfe_internal__addon_stream_broker_widgets-CUZ0nS_r.mjs} +2 -2
  19. package/dist/stream-broker/_virtual_mf___mfe_internal__addon_stream_broker_widgets__loadShare___mf_0_camstack_mf_1_types__loadShare__.js-Mv3UeZUE.mjs +26 -0
  20. package/dist/stream-broker/{hostInit-i24FVz-3.mjs → hostInit-B8O23a6l.mjs} +2 -2
  21. package/dist/stream-broker/index.js +1 -1
  22. package/dist/stream-broker/index.mjs +1 -1
  23. package/dist/stream-broker/remoteEntry.js +1 -1
  24. package/dist/{worker-protocol-BxPNiino.mjs → worker-protocol-B0c3i2km.mjs} +1 -1
  25. package/dist/{worker-protocol-CNi5srgV.js → worker-protocol-CWhkLkHx.js} +1 -1
  26. package/embed-dist/assets/{MaskShapeCanvas-DI4BY7W2-m7YpaY98.js → MaskShapeCanvas-DI4BY7W2-kAtChdz2.js} +1 -1
  27. package/embed-dist/assets/{MotionZonesSettings-NcxxQN8r-619YTOjy.js → MotionZonesSettings-NcxxQN8r-DEwkvjzt.js} +1 -1
  28. package/embed-dist/assets/{PrivacyMaskSettings-APgPLF7p-B-k8v0O5.js → PrivacyMaskSettings-APgPLF7p-Brv9VL0h.js} +1 -1
  29. package/embed-dist/assets/{index-CYO4OY8_.js → index-Dv7fSuDA.js} +12 -12
  30. package/embed-dist/index.html +1 -1
  31. package/package.json +1 -1
  32. package/dist/stream-broker/_virtual_mf___mfe_internal__addon_stream_broker_widgets__loadShare___mf_0_camstack_mf_1_types__loadShare__.js-Cj2xMupA.mjs +0 -26
@@ -3,7 +3,7 @@ Object.defineProperties(exports, {
3
3
  [Symbol.toStringTag]: { value: "Module" }
4
4
  });
5
5
  const require_chunk = require("../chunk-emK7D4bc.js");
6
- const require_dist = require("../dist-J2DeRZAN.js");
6
+ const require_dist = require("../dist-BsBEe_rX.js");
7
7
  const require_node_topology_platform = require("../node-topology-platform-CFZ7F4xW.js");
8
8
  const require_addon_utils = require("../addon-utils-DveoBR6G.js");
9
9
  let node_fs = require("node:fs");
@@ -1,5 +1,5 @@
1
1
  import { n as __require } from "../chunk-DnnnRqeS.mjs";
2
- import { $ as errMsg, C as audioAnalysisCapability, R as mapAudioLabelToMacro, at as BaseAddon, n as AUDIO_BACKEND_CHOICES, o as DEFAULT_AUDIO_ANALYZER_CONFIG, p as HF_BASE_URL, ut as hydrateSchema, w as audioAnalyzerCapability } from "../dist-CLJKoYEP.mjs";
2
+ import { T as audioAnalyzerCapability, dt as hydrateSchema, et as errMsg, m as HF_BASE_URL, n as AUDIO_BACKEND_CHOICES, o as DEFAULT_AUDIO_ANALYZER_CONFIG, ot as BaseAddon, w as audioAnalysisCapability, z as mapAudioLabelToMacro } from "../dist-Dkvk5ykl.mjs";
3
3
  import { t as pickNodePlatformArch } from "../node-topology-platform-BkR_k6WT.mjs";
4
4
  import { i as downloadFile } from "../addon-utils-QuxtOdK1.mjs";
5
5
  import * as fs from "node:fs";
@@ -3,8 +3,8 @@ Object.defineProperties(exports, {
3
3
  [Symbol.toStringTag]: { value: "Module" }
4
4
  });
5
5
  const require_chunk = require("../chunk-emK7D4bc.js");
6
- const require_dist = require("../dist-J2DeRZAN.js");
7
- const require_event_loop_stall_monitor = require("../event-loop-stall-monitor-Bkbiw20z.js");
6
+ const require_dist = require("../dist-BsBEe_rX.js");
7
+ const require_event_loop_stall_monitor = require("../event-loop-stall-monitor-DqJXi0_B.js");
8
8
  const require_lazy_sharp = require("../lazy-sharp-CcYuXtsa.js");
9
9
  const require_node_topology_platform = require("../node-topology-platform-CFZ7F4xW.js");
10
10
  const require_addon_utils = require("../addon-utils-DveoBR6G.js");
@@ -1,6 +1,6 @@
1
1
  import { n as __require } from "../chunk-DnnnRqeS.mjs";
2
- import { $ as errMsg, At as EventCategory, Et as object, F as enumerateInferenceDevices, I as evaluateZoneRules, J as runtimeDevices$1, M as detectionPipelineCapability, O as defaultDeviceFor$1, Ot as string, U as pipelineExecutorCapability, Z as supportedRuntimes$1, at as BaseAddon, bt as array, ht as parseJsonUnknown, kt as union, l as DEVICE_BACKEND_TO_FORMAT, lt as createEvent, mt as nodePin, t as APPLE_SA_TO_MACRO, ut as hydrateSchema, vt as sleep, x as YAMNET_TO_MACRO } from "../dist-CLJKoYEP.mjs";
3
- import { a as getDefaultModelForFormat, c as getStepDefinition, i as ALL_STEPS, l as resolveModelForFormat, n as startEventLoopStallMonitor, o as getDefaultModelForFormatFromDef, r as ALL_PIPELINE_STEPS, s as getStep } from "../event-loop-stall-monitor-B6dqQjiX.mjs";
2
+ import { At as union, Dt as object, I as enumerateInferenceDevices, L as evaluateZoneRules, N as detectionPipelineCapability, Q as supportedRuntimes$1, S as YAMNET_TO_MACRO, W as pipelineExecutorCapability, Y as runtimeDevices$1, dt as hydrateSchema, et as errMsg, gt as parseJsonUnknown, ht as nodePin, jt as EventCategory, k as defaultDeviceFor$1, kt as string, ot as BaseAddon, t as APPLE_SA_TO_MACRO, u as DEVICE_BACKEND_TO_FORMAT, ut as createEvent, xt as array, yt as sleep } from "../dist-Dkvk5ykl.mjs";
3
+ import { a as getDefaultModelForFormat, c as getStepDefinition, i as ALL_STEPS, l as resolveModelForFormat, n as startEventLoopStallMonitor, o as getDefaultModelForFormatFromDef, r as ALL_PIPELINE_STEPS, s as getStep } from "../event-loop-stall-monitor-BvtjRcal.mjs";
4
4
  import { t as getSharp } from "../lazy-sharp-B-mb8uWx.mjs";
5
5
  import { t as pickNodePlatformArch } from "../node-topology-platform-BkR_k6WT.mjs";
6
6
  import { a as ensureModel, o as isModelDownloaded, r as deleteModelFromDisk } from "../addon-utils-QuxtOdK1.mjs";
@@ -8344,6 +8344,30 @@ var RecordingBandSchema = object({
8344
8344
  postBufferSec: number().min(0).optional()
8345
8345
  });
8346
8346
  /**
8347
+ * The buffers an `events` band uses when it carries NONE — i.e. what the Basic
8348
+ * recording form persists whenever the operator leaves the pre/post inputs
8349
+ * blank, which is the overwhelmingly common case.
8350
+ *
8351
+ * A zero default is NOT a neutral one, and reading the absent field as `0` is
8352
+ * what made two cameras record nothing for weeks: `postBufferSec` is the LIVE
8353
+ * demand window, so `0` means the window is already shut by the time the
8354
+ * trigger is evaluated. There is no instant at which such a band can attach a
8355
+ * writer.
8356
+ *
8357
+ * `postBufferSec` must therefore exceed one segment length plus the attach
8358
+ * latency (ffmpeg spawn + RTSP dial), or the window closes before the first
8359
+ * segment is ever finalized and the camera records nothing anyway. At the 10 s
8360
+ * default segment length, 30 s leaves room for two full segments. `preBufferSec`
8361
+ * is retroactive only — it costs nothing at record time, it merely keeps
8362
+ * already-written segments — so it is set to one segment length.
8363
+ *
8364
+ * An EXPLICIT `0` is left alone: that is an operator statement, not an omission.
8365
+ */
8366
+ var DEFAULT_EVENTS_BAND_BUFFER_SEC = {
8367
+ preBufferSec: 10,
8368
+ postBufferSec: 30
8369
+ };
8370
+ /**
8347
8371
  * Per-device retention overrides. Every field is optional; an unset or `0`
8348
8372
  * value inherits the node-wide recorder default. Only footage-lifetime limits
8349
8373
  * live per-camera: `maxAgeDays` and `maxSizeGb`. The disk-occupancy threshold
@@ -18385,6 +18409,23 @@ var CameraRecordingStatusSchema = object({
18385
18409
  active: boolean(),
18386
18410
  storageBytes: number()
18387
18411
  });
18412
+ /** One stage of the fan-out that could NOT be read, and how long it cost. */
18413
+ var CameraStatusDegradationSchema = object({
18414
+ stage: _enum([
18415
+ "source",
18416
+ "broker",
18417
+ "detection",
18418
+ "recording",
18419
+ "switches"
18420
+ ]),
18421
+ reason: _enum([
18422
+ "timeout",
18423
+ "error",
18424
+ "partial"
18425
+ ]),
18426
+ /** Wall-clock ms spent on the stage before it was abandoned. */
18427
+ elapsedMs: number()
18428
+ });
18388
18429
  /**
18389
18430
  * Aggregated per-camera pipeline status — server-composed, single call.
18390
18431
  *
@@ -18415,9 +18456,28 @@ var CameraStatusSchema = object({
18415
18456
  * differently — a quiet camera that looks identical to a dead one is the
18416
18457
  * silence-reads-as-never-happened trap this repo keeps paying for.
18417
18458
  *
18418
- * Empty when nothing is off. Never contains a switch no provider offers.
18459
+ * Empty when nothing is off, and never contains a switch no provider offers
18460
+ * — but an empty list is only a POSITIVE claim when `degraded` does not name
18461
+ * `'switches'`. When it does, the switch set could not be read and nothing
18462
+ * here may be rendered as "the operator turned nothing off": that is the
18463
+ * D62 failure (a camera we could not read painted as broken) in the very
18464
+ * field that exists to prevent it.
18419
18465
  */
18420
18466
  switchedOff: array(CameraSwitchIdSchema).readonly(),
18467
+ /**
18468
+ * Stages of the bounded fan-out that were CUT SHORT — a timeout or a
18469
+ * rejection — and whose block is therefore `null` because we could not
18470
+ * READ it, not because there is nothing there.
18471
+ *
18472
+ * Without this, three different facts arrive as the same `null`: "the stage
18473
+ * timed out", "the stage failed", and "this camera legitimately has no
18474
+ * decoder / no recording". Every surface that draws a conclusion from a null
18475
+ * block (or from an empty `switchedOff`) must consult this first; a stage
18476
+ * named here supports no conclusion at all, only "unknown".
18477
+ *
18478
+ * Empty on a clean read — the overwhelmingly common case.
18479
+ */
18480
+ degraded: array(CameraStatusDegradationSchema).readonly(),
18421
18481
  /** Unix timestamp (ms) when this snapshot was composed server-side. */
18422
18482
  fetchedAt: number()
18423
18483
  });
@@ -32173,6 +32233,12 @@ Object.defineProperty(exports, "DEFAULT_DETAIL_CROP_CONVENTION", {
32173
32233
  return DEFAULT_DETAIL_CROP_CONVENTION;
32174
32234
  }
32175
32235
  });
32236
+ Object.defineProperty(exports, "DEFAULT_EVENTS_BAND_BUFFER_SEC", {
32237
+ enumerable: true,
32238
+ get: function() {
32239
+ return DEFAULT_EVENTS_BAND_BUFFER_SEC;
32240
+ }
32241
+ });
32176
32242
  Object.defineProperty(exports, "DEFAULT_NATIVE_LEASE_SETTINGS", {
32177
32243
  enumerable: true,
32178
32244
  get: function() {
@@ -8344,6 +8344,30 @@ var RecordingBandSchema = object({
8344
8344
  postBufferSec: number().min(0).optional()
8345
8345
  });
8346
8346
  /**
8347
+ * The buffers an `events` band uses when it carries NONE — i.e. what the Basic
8348
+ * recording form persists whenever the operator leaves the pre/post inputs
8349
+ * blank, which is the overwhelmingly common case.
8350
+ *
8351
+ * A zero default is NOT a neutral one, and reading the absent field as `0` is
8352
+ * what made two cameras record nothing for weeks: `postBufferSec` is the LIVE
8353
+ * demand window, so `0` means the window is already shut by the time the
8354
+ * trigger is evaluated. There is no instant at which such a band can attach a
8355
+ * writer.
8356
+ *
8357
+ * `postBufferSec` must therefore exceed one segment length plus the attach
8358
+ * latency (ffmpeg spawn + RTSP dial), or the window closes before the first
8359
+ * segment is ever finalized and the camera records nothing anyway. At the 10 s
8360
+ * default segment length, 30 s leaves room for two full segments. `preBufferSec`
8361
+ * is retroactive only — it costs nothing at record time, it merely keeps
8362
+ * already-written segments — so it is set to one segment length.
8363
+ *
8364
+ * An EXPLICIT `0` is left alone: that is an operator statement, not an omission.
8365
+ */
8366
+ var DEFAULT_EVENTS_BAND_BUFFER_SEC = {
8367
+ preBufferSec: 10,
8368
+ postBufferSec: 30
8369
+ };
8370
+ /**
8347
8371
  * Per-device retention overrides. Every field is optional; an unset or `0`
8348
8372
  * value inherits the node-wide recorder default. Only footage-lifetime limits
8349
8373
  * live per-camera: `maxAgeDays` and `maxSizeGb`. The disk-occupancy threshold
@@ -18385,6 +18409,23 @@ var CameraRecordingStatusSchema = object({
18385
18409
  active: boolean(),
18386
18410
  storageBytes: number()
18387
18411
  });
18412
+ /** One stage of the fan-out that could NOT be read, and how long it cost. */
18413
+ var CameraStatusDegradationSchema = object({
18414
+ stage: _enum([
18415
+ "source",
18416
+ "broker",
18417
+ "detection",
18418
+ "recording",
18419
+ "switches"
18420
+ ]),
18421
+ reason: _enum([
18422
+ "timeout",
18423
+ "error",
18424
+ "partial"
18425
+ ]),
18426
+ /** Wall-clock ms spent on the stage before it was abandoned. */
18427
+ elapsedMs: number()
18428
+ });
18388
18429
  /**
18389
18430
  * Aggregated per-camera pipeline status — server-composed, single call.
18390
18431
  *
@@ -18415,9 +18456,28 @@ var CameraStatusSchema = object({
18415
18456
  * differently — a quiet camera that looks identical to a dead one is the
18416
18457
  * silence-reads-as-never-happened trap this repo keeps paying for.
18417
18458
  *
18418
- * Empty when nothing is off. Never contains a switch no provider offers.
18459
+ * Empty when nothing is off, and never contains a switch no provider offers
18460
+ * — but an empty list is only a POSITIVE claim when `degraded` does not name
18461
+ * `'switches'`. When it does, the switch set could not be read and nothing
18462
+ * here may be rendered as "the operator turned nothing off": that is the
18463
+ * D62 failure (a camera we could not read painted as broken) in the very
18464
+ * field that exists to prevent it.
18419
18465
  */
18420
18466
  switchedOff: array(CameraSwitchIdSchema).readonly(),
18467
+ /**
18468
+ * Stages of the bounded fan-out that were CUT SHORT — a timeout or a
18469
+ * rejection — and whose block is therefore `null` because we could not
18470
+ * READ it, not because there is nothing there.
18471
+ *
18472
+ * Without this, three different facts arrive as the same `null`: "the stage
18473
+ * timed out", "the stage failed", and "this camera legitimately has no
18474
+ * decoder / no recording". Every surface that draws a conclusion from a null
18475
+ * block (or from an empty `switchedOff`) must consult this first; a stage
18476
+ * named here supports no conclusion at all, only "unknown".
18477
+ *
18478
+ * Empty on a clean read — the overwhelmingly common case.
18479
+ */
18480
+ degraded: array(CameraStatusDegradationSchema).readonly(),
18421
18481
  /** Unix timestamp (ms) when this snapshot was composed server-side. */
18422
18482
  fetchedAt: number()
18423
18483
  });
@@ -32113,4 +32173,4 @@ function enumerateInferenceDevices(hw) {
32113
32173
  return out;
32114
32174
  }
32115
32175
  //#endregion
32116
- export { errMsg as $, deriveDetailCropRect as A, EventCategory as At, motionDetectionCapability as B, audioAnalysisCapability as C, lazy as Ct, customAction as D, record as Dt, createHwAccelCache as E, object as Et, enumerateInferenceDevices as F, recordingCapability as G, pickNativeLeaseOverride as H, evaluateZoneRules as I, runtimeDevices as J, recordingExportCapability as K, hfModelUrl as L, detectionPipelineCapability as M, egressTranscodeSharingKey as N, defaultDeviceFor as O, string as Ot, egressTransportFromRequest as P, webrtcSessionCapability as Q, mapAudioLabelToMacro as R, addonWidgetsSourceCapability as S, discriminatedUnion as St, cameraStreamsCapability as T, number as Tt, pipelineExecutorCapability as U, pickDetailCropConvention as V, pipelineRunnerCapability as W, streamBrokerCapability as X, storageEvictableCapability as Y, supportedRuntimes as Z, RATE_CONTROL_RELAXED as _, selectAssignedProfileSlots as _t, COCO_TO_MACRO as a, BaseAddon as at, RingBuffer as b, array as bt, DEFAULT_NATIVE_LEASE_SETTINGS as c, DeviceType as ct, EncodeProfileSchema as d, isEvent as dt, AUDIO_PRESETS as et, ExportRecordSchema as f, makeProfileBrokerId as ft, OpsLogEntrySchema as g, parseProfileBrokerId as gt, NativeLeaseSettingsSchema as h, parseJsonUnknown as ht, COCO_80_LABELS as i, isSoftwareDecode as it, deriveRecordingMode as j, defineCustomActions as k, union as kt, DEVICE_BACKEND_TO_FORMAT as l, createEvent as lt, NativeLeaseAdmissionSchema as m, nodePin as mt, AUDIO_BACKEND_CHOICES as n, buildFfmpegArgs as nt, DEFAULT_AUDIO_ANALYZER_CONFIG as o, CAM_PROFILE_ORDER as ot, HF_BASE_URL as p, makeSourceBrokerId as pt, resolveEgressDecodeHwAccel as q, AUDIO_MACRO_LABELS as r, invocationFromEncodeProfile as rt, DEFAULT_DETAIL_CROP_CONVENTION as s, DeviceFeature as st, APPLE_SA_TO_MACRO as t, Fmp4BoxSplitter as tt, EVENT_PAD_MS as u, hydrateSchema as ut, RATE_CONTROL_TIGHT as v, sleep as vt, audioAnalyzerCapability as w, literal as wt, YAMNET_TO_MACRO as x, boolean as xt, RecordingConfigSchema as y, _enum as yt, maskUrlCredentials as z };
32176
+ export { webrtcSessionCapability as $, defineCustomActions as A, union as At, maskUrlCredentials as B, addonWidgetsSourceCapability as C, discriminatedUnion as Ct, createHwAccelCache as D, object as Dt, cameraStreamsCapability as E, number as Et, egressTransportFromRequest as F, pipelineRunnerCapability as G, pickDetailCropConvention as H, enumerateInferenceDevices as I, resolveEgressDecodeHwAccel as J, recordingCapability as K, evaluateZoneRules as L, deriveRecordingMode as M, detectionPipelineCapability as N, customAction as O, record as Ot, egressTranscodeSharingKey as P, supportedRuntimes as Q, hfModelUrl as R, YAMNET_TO_MACRO as S, boolean as St, audioAnalyzerCapability as T, literal as Tt, pickNativeLeaseOverride as U, motionDetectionCapability as V, pipelineExecutorCapability as W, storageEvictableCapability as X, runtimeDevices as Y, streamBrokerCapability as Z, OpsLogEntrySchema as _, parseProfileBrokerId as _t, COCO_TO_MACRO as a, isSoftwareDecode as at, RecordingConfigSchema as b, _enum as bt, DEFAULT_EVENTS_BAND_BUFFER_SEC as c, DeviceFeature as ct, EVENT_PAD_MS as d, hydrateSchema as dt, errMsg as et, EncodeProfileSchema as f, isEvent as ft, NativeLeaseSettingsSchema as g, parseJsonUnknown as gt, NativeLeaseAdmissionSchema as h, nodePin as ht, COCO_80_LABELS as i, invocationFromEncodeProfile as it, deriveDetailCropRect as j, EventCategory as jt, defaultDeviceFor as k, string as kt, DEFAULT_NATIVE_LEASE_SETTINGS as l, DeviceType as lt, HF_BASE_URL as m, makeSourceBrokerId as mt, AUDIO_BACKEND_CHOICES as n, Fmp4BoxSplitter as nt, DEFAULT_AUDIO_ANALYZER_CONFIG as o, BaseAddon as ot, ExportRecordSchema as p, makeProfileBrokerId as pt, recordingExportCapability as q, AUDIO_MACRO_LABELS as r, buildFfmpegArgs as rt, DEFAULT_DETAIL_CROP_CONVENTION as s, CAM_PROFILE_ORDER as st, APPLE_SA_TO_MACRO as t, AUDIO_PRESETS as tt, DEVICE_BACKEND_TO_FORMAT as u, createEvent as ut, RATE_CONTROL_RELAXED as v, selectAssignedProfileSlots as vt, audioAnalysisCapability as w, lazy as wt, RingBuffer as x, array as xt, RATE_CONTROL_TIGHT as y, sleep as yt, mapAudioLabelToMacro as z };
@@ -1,4 +1,4 @@
1
- import { L as hfModelUrl, a as COCO_TO_MACRO, i as COCO_80_LABELS, r as AUDIO_MACRO_LABELS } from "./dist-CLJKoYEP.mjs";
1
+ import { R as hfModelUrl, a as COCO_TO_MACRO, i as COCO_80_LABELS, r as AUDIO_MACRO_LABELS } from "./dist-Dkvk5ykl.mjs";
2
2
  import { PerformanceObserver } from "node:perf_hooks";
3
3
  //#region src/detection-pipeline/registry/model-catalogs.ts
4
4
  var HF_REPO = "camstack/camstack-models";
@@ -1,4 +1,4 @@
1
- const require_dist = require("./dist-J2DeRZAN.js");
1
+ const require_dist = require("./dist-BsBEe_rX.js");
2
2
  let node_perf_hooks = require("node:perf_hooks");
3
3
  //#region src/detection-pipeline/registry/model-catalogs.ts
4
4
  var HF_REPO = "camstack/camstack-models";
@@ -2,7 +2,7 @@ Object.defineProperties(exports, {
2
2
  __esModule: { value: true },
3
3
  [Symbol.toStringTag]: { value: "Module" }
4
4
  });
5
- const require_dist = require("../dist-J2DeRZAN.js");
5
+ const require_dist = require("../dist-BsBEe_rX.js");
6
6
  const require_lazy_sharp = require("../lazy-sharp-CcYuXtsa.js");
7
7
  let node_fs = require("node:fs");
8
8
  let node_path = require("node:path");
@@ -1,4 +1,4 @@
1
- import { B as motionDetectionCapability, I as evaluateZoneRules, at as BaseAddon, ct as DeviceType, ut as hydrateSchema } from "../dist-CLJKoYEP.mjs";
1
+ import { L as evaluateZoneRules, V as motionDetectionCapability, dt as hydrateSchema, lt as DeviceType, ot as BaseAddon } from "../dist-Dkvk5ykl.mjs";
2
2
  import { t as getSharp } from "../lazy-sharp-B-mb8uWx.mjs";
3
3
  import { readFileSync } from "node:fs";
4
4
  import { join } from "node:path";
@@ -3,9 +3,9 @@ Object.defineProperties(exports, {
3
3
  [Symbol.toStringTag]: { value: "Module" }
4
4
  });
5
5
  const require_chunk = require("../chunk-emK7D4bc.js");
6
- const require_dist = require("../dist-J2DeRZAN.js");
7
- const require_event_loop_stall_monitor = require("../event-loop-stall-monitor-Bkbiw20z.js");
8
- const require_worker_protocol = require("../worker-protocol-CNi5srgV.js");
6
+ const require_dist = require("../dist-BsBEe_rX.js");
7
+ const require_event_loop_stall_monitor = require("../event-loop-stall-monitor-DqJXi0_B.js");
8
+ const require_worker_protocol = require("../worker-protocol-CWhkLkHx.js");
9
9
  const require_hub_hostname = require("../hub-hostname-DAJXlOgV.js");
10
10
  const require_lazy_sharp = require("../lazy-sharp-CcYuXtsa.js");
11
11
  const require_remote_restream = require("../remote-restream-CO36Sr30.js");
@@ -1824,116 +1824,6 @@ var CropConventionSource = class {
1824
1824
  }
1825
1825
  };
1826
1826
  //#endregion
1827
- //#region src/pipeline-runner/native-lease-settings-source.ts
1828
- /**
1829
- * Where the runner gets the cluster-wide native-frame LEASE knobs.
1830
- *
1831
- * ## Why a settings read and not the attach config
1832
- *
1833
- * Identical reasoning to `crop-convention-source.ts`, and worth restating
1834
- * because the temptation is the same: `RunnerCameraConfig` is the obvious
1835
- * orchestrator→runner channel and it is the wrong one. Eleven call sites build
1836
- * one; a cluster-wide constant threaded through eleven builders eventually
1837
- * reaches ten of them, and the cameras attached by the forgotten builder just
1838
- * quietly run a different lease window. Instead the runner reads the OWNER
1839
- * addon's global settings directly, hub-routed by `AddonCallGateway`, so an
1840
- * agent runner transparently reads the hub-central store with no placement
1841
- * branching.
1842
- *
1843
- * ## Deliberately NOT node-scoped
1844
- *
1845
- * The read passes no `nodeId`. With one, `addon-settings` would project that
1846
- * node's scoped value and two nodes could hold different lease windows for the
1847
- * same camera — so whether a stored crop is native pixels or the ≤640 fallback
1848
- * would depend on where the balancer happened to place it, which is invisible
1849
- * from the stored media.
1850
- *
1851
- * ## What it hands out
1852
- *
1853
- * A {@link NativeLeaseSettingsOverride} — only the knobs the operator SET. The
1854
- * decode worker resolves the rest (env var, then the shipped default); see
1855
- * `session-decode/native-lease-config.ts` for the precedence. Handing out a
1856
- * fully-resolved triple here would erase the "operator set nothing" state and
1857
- * with it the env-var escape hatch.
1858
- */
1859
- /**
1860
- * The addon whose GLOBAL settings own the knobs. `pipeline-orchestrator` is
1861
- * hub-resident and neutral — the same owner as the detail-crop convention and
1862
- * the per-node decoder-backend selector.
1863
- */
1864
- var NATIVE_LEASE_OWNER_ADDON_ID = "pipeline-orchestrator";
1865
- /**
1866
- * Whether two overrides name the same knobs with the same values.
1867
- *
1868
- * **Every knob has to appear here.** This is the equality that decides whether
1869
- * a re-read is ADOPTED at all: a knob missing from the comparison is read from
1870
- * the hub, judged identical, and discarded, so the operator's change never
1871
- * reaches a decode worker and nothing anywhere says so. `admission` shipped
1872
- * missing from this list and did exactly that — the setting was stored, the
1873
- * hub served it, the runner fetched it, and every worker kept spawning with the
1874
- * old value.
1875
- */
1876
- function sameOverride(a, b) {
1877
- return a.ttlMs === b.ttlMs && a.budgetMb === b.budgetMb && a.activityMs === b.activityMs && a.admission === b.admission;
1878
- }
1879
- /**
1880
- * TTL-cached read of the cluster native-lease knobs.
1881
- *
1882
- * {@link current} is synchronous because the fork that consumes it is;
1883
- * {@link refresh} is what talks to the hub, and the runner awaits it on the
1884
- * path that precedes a decode-worker spawn.
1885
- */
1886
- var NativeLeaseSettingsSource = class {
1887
- override = {};
1888
- lastReadAtMs = Number.NEGATIVE_INFINITY;
1889
- inFlight = null;
1890
- logger;
1891
- now;
1892
- ttlMs;
1893
- constructor(options) {
1894
- this.logger = options.logger;
1895
- this.now = options.now ?? (() => Date.now());
1896
- this.ttlMs = options.ttlMs ?? 3e4;
1897
- }
1898
- /** The operator's overrides as last read — `{}` until a read lands. */
1899
- current() {
1900
- return this.override;
1901
- }
1902
- /**
1903
- * Re-read if the cached value has expired. Concurrent callers share one
1904
- * in-flight read; a failure keeps the LAST KNOWN value rather than reverting
1905
- * to `{}`, because a revert would silently hand the next-spawned workers a
1906
- * different RAM profile than the ones already running.
1907
- */
1908
- async refresh(api) {
1909
- if (api === void 0) return this.override;
1910
- if (this.now() - this.lastReadAtMs < this.ttlMs) return this.override;
1911
- this.inFlight ??= this.read(api).finally(() => {
1912
- this.inFlight = null;
1913
- });
1914
- await this.inFlight;
1915
- return this.override;
1916
- }
1917
- async read(api) {
1918
- try {
1919
- const next = require_dist.pickNativeLeaseOverride(await api.addonSettings.getGlobalSettings.query({ addonId: NATIVE_LEASE_OWNER_ADDON_ID }));
1920
- this.lastReadAtMs = this.now();
1921
- if (sameOverride(next, this.override)) return;
1922
- this.logger.info("native lease settings changed — applies to NEW decode sessions", { meta: {
1923
- from: { ...this.override },
1924
- to: { ...next }
1925
- } });
1926
- this.override = next;
1927
- } catch (err) {
1928
- this.logger.warn("native lease settings read failed — keeping the last known value", { meta: {
1929
- owner: NATIVE_LEASE_OWNER_ADDON_ID,
1930
- inUse: { ...this.override },
1931
- error: err instanceof Error ? err.message : String(err)
1932
- } });
1933
- }
1934
- }
1935
- };
1936
- //#endregion
1937
1827
  //#region src/pipeline-runner/detail-subtree.ts
1938
1828
  /** Did the native-lease fetch report a miss (rather than return pixels)? */
1939
1829
  function isNativeCropMiss(fetch) {
@@ -2508,6 +2398,116 @@ function resolveNativeCropSource(isFullFrame, nativeHit) {
2508
2398
  return isFullFrame ? "ram-fullframe" : "miss";
2509
2399
  }
2510
2400
  //#endregion
2401
+ //#region src/pipeline-runner/native-lease-settings-source.ts
2402
+ /**
2403
+ * Where the runner gets the cluster-wide native-frame LEASE knobs.
2404
+ *
2405
+ * ## Why a settings read and not the attach config
2406
+ *
2407
+ * Identical reasoning to `crop-convention-source.ts`, and worth restating
2408
+ * because the temptation is the same: `RunnerCameraConfig` is the obvious
2409
+ * orchestrator→runner channel and it is the wrong one. Eleven call sites build
2410
+ * one; a cluster-wide constant threaded through eleven builders eventually
2411
+ * reaches ten of them, and the cameras attached by the forgotten builder just
2412
+ * quietly run a different lease window. Instead the runner reads the OWNER
2413
+ * addon's global settings directly, hub-routed by `AddonCallGateway`, so an
2414
+ * agent runner transparently reads the hub-central store with no placement
2415
+ * branching.
2416
+ *
2417
+ * ## Deliberately NOT node-scoped
2418
+ *
2419
+ * The read passes no `nodeId`. With one, `addon-settings` would project that
2420
+ * node's scoped value and two nodes could hold different lease windows for the
2421
+ * same camera — so whether a stored crop is native pixels or the ≤640 fallback
2422
+ * would depend on where the balancer happened to place it, which is invisible
2423
+ * from the stored media.
2424
+ *
2425
+ * ## What it hands out
2426
+ *
2427
+ * A {@link NativeLeaseSettingsOverride} — only the knobs the operator SET. The
2428
+ * decode worker resolves the rest (env var, then the shipped default); see
2429
+ * `session-decode/native-lease-config.ts` for the precedence. Handing out a
2430
+ * fully-resolved triple here would erase the "operator set nothing" state and
2431
+ * with it the env-var escape hatch.
2432
+ */
2433
+ /**
2434
+ * The addon whose GLOBAL settings own the knobs. `pipeline-orchestrator` is
2435
+ * hub-resident and neutral — the same owner as the detail-crop convention and
2436
+ * the per-node decoder-backend selector.
2437
+ */
2438
+ var NATIVE_LEASE_OWNER_ADDON_ID = "pipeline-orchestrator";
2439
+ /**
2440
+ * Whether two overrides name the same knobs with the same values.
2441
+ *
2442
+ * **Every knob has to appear here.** This is the equality that decides whether
2443
+ * a re-read is ADOPTED at all: a knob missing from the comparison is read from
2444
+ * the hub, judged identical, and discarded, so the operator's change never
2445
+ * reaches a decode worker and nothing anywhere says so. `admission` shipped
2446
+ * missing from this list and did exactly that — the setting was stored, the
2447
+ * hub served it, the runner fetched it, and every worker kept spawning with the
2448
+ * old value.
2449
+ */
2450
+ function sameOverride(a, b) {
2451
+ return a.ttlMs === b.ttlMs && a.budgetMb === b.budgetMb && a.activityMs === b.activityMs && a.admission === b.admission;
2452
+ }
2453
+ /**
2454
+ * TTL-cached read of the cluster native-lease knobs.
2455
+ *
2456
+ * {@link current} is synchronous because the fork that consumes it is;
2457
+ * {@link refresh} is what talks to the hub, and the runner awaits it on the
2458
+ * path that precedes a decode-worker spawn.
2459
+ */
2460
+ var NativeLeaseSettingsSource = class {
2461
+ override = {};
2462
+ lastReadAtMs = Number.NEGATIVE_INFINITY;
2463
+ inFlight = null;
2464
+ logger;
2465
+ now;
2466
+ ttlMs;
2467
+ constructor(options) {
2468
+ this.logger = options.logger;
2469
+ this.now = options.now ?? (() => Date.now());
2470
+ this.ttlMs = options.ttlMs ?? 3e4;
2471
+ }
2472
+ /** The operator's overrides as last read — `{}` until a read lands. */
2473
+ current() {
2474
+ return this.override;
2475
+ }
2476
+ /**
2477
+ * Re-read if the cached value has expired. Concurrent callers share one
2478
+ * in-flight read; a failure keeps the LAST KNOWN value rather than reverting
2479
+ * to `{}`, because a revert would silently hand the next-spawned workers a
2480
+ * different RAM profile than the ones already running.
2481
+ */
2482
+ async refresh(api) {
2483
+ if (api === void 0) return this.override;
2484
+ if (this.now() - this.lastReadAtMs < this.ttlMs) return this.override;
2485
+ this.inFlight ??= this.read(api).finally(() => {
2486
+ this.inFlight = null;
2487
+ });
2488
+ await this.inFlight;
2489
+ return this.override;
2490
+ }
2491
+ async read(api) {
2492
+ try {
2493
+ const next = require_dist.pickNativeLeaseOverride(await api.addonSettings.getGlobalSettings.query({ addonId: NATIVE_LEASE_OWNER_ADDON_ID }));
2494
+ this.lastReadAtMs = this.now();
2495
+ if (sameOverride(next, this.override)) return;
2496
+ this.logger.info("native lease settings changed — applies to NEW decode sessions", { meta: {
2497
+ from: { ...this.override },
2498
+ to: { ...next }
2499
+ } });
2500
+ this.override = next;
2501
+ } catch (err) {
2502
+ this.logger.warn("native lease settings read failed — keeping the last known value", { meta: {
2503
+ owner: NATIVE_LEASE_OWNER_ADDON_ID,
2504
+ inUse: { ...this.override },
2505
+ error: err instanceof Error ? err.message : String(err)
2506
+ } });
2507
+ }
2508
+ }
2509
+ };
2510
+ //#endregion
2511
2511
  //#region src/pipeline-runner/frame-governor.ts
2512
2512
  var FrameGovernor = class {
2513
2513
  config;
@@ -4986,7 +4986,20 @@ var PipelineRunnerAddon = class PipelineRunnerAddon extends require_dist.BaseAdd
4986
4986
  if (resolved.tier === "native" && resolved.pixels !== null) return this.encodeNativeCropResult(resolved.pixels, resolved.tier, input.encodeJpeg);
4987
4987
  if (resolved.tier !== "ram-fullframe") return null;
4988
4988
  const crop = this.retainedFrames?.crop(input.handle, input.bbox, input.maxWidth);
4989
- if (!crop) return null;
4989
+ if (!crop) {
4990
+ this.ctx?.logger.warn("native full-frame miss — the retained store no longer holds this frame", {
4991
+ tags: { deviceId: this.nativeCropRegistry.deviceIdFor(input.handle) ?? -1 },
4992
+ meta: {
4993
+ handle: `${input.handle.shmId}#${input.handle.slot}#${input.handle.seq}`,
4994
+ handleNodeId: input.handle.nodeId,
4995
+ nativeMissReason: resolved.missReason,
4996
+ nativeHandleAgeMs: resolved.handleAgeMs,
4997
+ maxWidth: input.maxWidth ?? null,
4998
+ hint: "both the native lease and the retained-frame window have closed for this frame — the detail dispatch that asked for it produces NO crop"
4999
+ }
5000
+ });
5001
+ return null;
5002
+ }
4990
5003
  return this.encodeNativeCropResult({
4991
5004
  bytes: crop.bytes,
4992
5005
  width: crop.width,