@camstack/addon-pipeline 1.1.41 → 1.1.43

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 (27) 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 +10 -7
  4. package/dist/detection-pipeline/index.mjs +10 -7
  5. package/dist/{dist-v6cKLmU3.mjs → dist-GFd8M6KO.mjs} +9 -1
  6. package/dist/{dist-BJTPkJFw.js → dist-NvwN60Fq.js} +9 -1
  7. package/dist/{frame-handle-plane-BP8YV4sF.js → frame-handle-plane-B3Fxww8H.js} +1 -1
  8. package/dist/{frame-handle-plane-DKAXTtfn.mjs → frame-handle-plane-E_AsR77T.mjs} +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 +47 -9
  12. package/dist/pipeline-runner/index.mjs +47 -9
  13. package/dist/recorder/index.js +19 -12
  14. package/dist/recorder/index.mjs +19 -12
  15. package/dist/session-decode/decode-worker-child.js +341 -28
  16. package/dist/session-decode/decode-worker-child.mjs +341 -28
  17. package/dist/stream-broker/{_virtual_mf-localSharedImportMap___mfe_internal__addon_stream_broker_widgets-C2l0kmD4.mjs → _virtual_mf-localSharedImportMap___mfe_internal__addon_stream_broker_widgets-CeielP5P.mjs} +3 -3
  18. package/dist/stream-broker/{hostInit-DHaCRMjM.mjs → hostInit-DmjqskOR.mjs} +3 -3
  19. package/dist/stream-broker/index.js +96 -63
  20. package/dist/stream-broker/index.mjs +96 -63
  21. package/dist/stream-broker/remoteEntry.js +1 -1
  22. package/embed-dist/assets/{MaskShapeCanvas-DI4BY7W2-B6fza7ic.js → MaskShapeCanvas-DI4BY7W2-CEsPjwzT.js} +1 -1
  23. package/embed-dist/assets/{MotionZonesSettings-NcxxQN8r-Cy-4iTog.js → MotionZonesSettings-NcxxQN8r-D43fIRgB.js} +1 -1
  24. package/embed-dist/assets/{PrivacyMaskSettings-APgPLF7p-CYX33lJb.js → PrivacyMaskSettings-APgPLF7p-C3wJxG8V.js} +1 -1
  25. package/embed-dist/assets/{index-BPkayx9u.js → index-CX-rILhw.js} +4 -4
  26. package/embed-dist/index.html +1 -1
  27. package/package.json +1 -1
@@ -3,7 +3,7 @@ Object.defineProperties(exports, {
3
3
  [Symbol.toStringTag]: { value: "Module" }
4
4
  });
5
5
  const require_model_download_service_C_IHWnXx = require("../model-download-service-C-IHWnXx-DxM2DSns.js");
6
- const require_dist = require("../dist-BJTPkJFw.js");
6
+ const require_dist = require("../dist-NvwN60Fq.js");
7
7
  const require_node_topology_platform = require("../node-topology-platform-CFZ7F4xW.js");
8
8
  let node_fs = require("node:fs");
9
9
  node_fs = require_model_download_service_C_IHWnXx.__toESM(node_fs);
@@ -1,5 +1,5 @@
1
1
  import { t as __require } from "../chunk-BdkLduGY.mjs";
2
- import { C as mapAudioLabelToMacro, I as errMsg, L as BaseAddon, U as hydrateSchema, h as audioAnalyzerCapability, l as HF_BASE_URL, m as audioAnalysisCapability, n as AUDIO_BACKEND_CHOICES, o as DEFAULT_AUDIO_ANALYZER_CONFIG } from "../dist-v6cKLmU3.mjs";
2
+ import { C as mapAudioLabelToMacro, I as errMsg, L as BaseAddon, U as hydrateSchema, h as audioAnalyzerCapability, l as HF_BASE_URL, m as audioAnalysisCapability, n as AUDIO_BACKEND_CHOICES, o as DEFAULT_AUDIO_ANALYZER_CONFIG } from "../dist-GFd8M6KO.mjs";
3
3
  import { t as pickNodePlatformArch } from "../node-topology-platform-BkR_k6WT.mjs";
4
4
  import { r as downloadFile } from "../model-download-service-C-IHWnXx-BPy6aoAx.mjs";
5
5
  import * as fs from "node:fs";
@@ -3,7 +3,7 @@ Object.defineProperties(exports, {
3
3
  [Symbol.toStringTag]: { value: "Module" }
4
4
  });
5
5
  const require_model_download_service_C_IHWnXx = require("../model-download-service-C-IHWnXx-DxM2DSns.js");
6
- const require_dist = require("../dist-BJTPkJFw.js");
6
+ const require_dist = require("../dist-NvwN60Fq.js");
7
7
  const require_node_topology_platform = require("../node-topology-platform-CFZ7F4xW.js");
8
8
  let _camstack_shm_ring = require("@camstack/shm-ring");
9
9
  let node_child_process = require("node:child_process");
@@ -3935,12 +3935,15 @@ var PipelineExecutor = class {
3935
3935
  try {
3936
3936
  await this.executeChildren(rootStep.children, mutable, fullFrameJpegProvider, imageWidth, imageHeight, traceBuilder, stepTimings, ctx, poolAgg);
3937
3937
  } catch (err) {
3938
- this.opts.logger?.warn("Pipeline child execution failed — keeping parent detection", { meta: {
3939
- rootStepId: rootStep.stepId,
3940
- parentClass: mutable.macroClass,
3941
- parentScore: mutable.score,
3942
- error: require_dist.errMsg(err)
3943
- } });
3938
+ this.opts.logger?.warn("Pipeline child execution failed — keeping parent detection", {
3939
+ tags: { deviceId },
3940
+ meta: {
3941
+ rootStepId: rootStep.stepId,
3942
+ parentClass: mutable.macroClass,
3943
+ parentScore: mutable.score,
3944
+ error: require_dist.errMsg(err)
3945
+ }
3946
+ });
3944
3947
  }
3945
3948
  firstLevel.push(mutable);
3946
3949
  }
@@ -1,5 +1,5 @@
1
1
  import { t as __require } from "../chunk-BdkLduGY.mjs";
2
- import { H as createEvent, I as errMsg, K as parseJsonUnknown, L as BaseAddon, O as pipelineExecutorCapability, P as supportedRuntimes$1, S as hfModelUrl, U as hydrateSchema, V as EventCategory, Y as sleep, a as COCO_TO_MACRO, b as detectionPipelineCapability, f as YAMNET_TO_MACRO, i as COCO_80_LABELS, j as runtimeDevices$1, r as AUDIO_MACRO_LABELS, t as APPLE_SA_TO_MACRO, v as defaultDeviceFor$1, x as evaluateZoneRules } from "../dist-v6cKLmU3.mjs";
2
+ import { H as createEvent, I as errMsg, K as parseJsonUnknown, L as BaseAddon, O as pipelineExecutorCapability, P as supportedRuntimes$1, S as hfModelUrl, U as hydrateSchema, V as EventCategory, Y as sleep, a as COCO_TO_MACRO, b as detectionPipelineCapability, f as YAMNET_TO_MACRO, i as COCO_80_LABELS, j as runtimeDevices$1, r as AUDIO_MACRO_LABELS, t as APPLE_SA_TO_MACRO, v as defaultDeviceFor$1, x as evaluateZoneRules } from "../dist-GFd8M6KO.mjs";
3
3
  import { t as pickNodePlatformArch } from "../node-topology-platform-BkR_k6WT.mjs";
4
4
  import { a as isModelDownloaded, i as ensureModel, n as deleteModelFromDisk } from "../model-download-service-C-IHWnXx-BPy6aoAx.mjs";
5
5
  import { FrameRingReaderCache } from "@camstack/shm-ring";
@@ -3928,12 +3928,15 @@ var PipelineExecutor = class {
3928
3928
  try {
3929
3929
  await this.executeChildren(rootStep.children, mutable, fullFrameJpegProvider, imageWidth, imageHeight, traceBuilder, stepTimings, ctx, poolAgg);
3930
3930
  } catch (err) {
3931
- this.opts.logger?.warn("Pipeline child execution failed — keeping parent detection", { meta: {
3932
- rootStepId: rootStep.stepId,
3933
- parentClass: mutable.macroClass,
3934
- parentScore: mutable.score,
3935
- error: errMsg(err)
3936
- } });
3931
+ this.opts.logger?.warn("Pipeline child execution failed — keeping parent detection", {
3932
+ tags: { deviceId },
3933
+ meta: {
3934
+ rootStepId: rootStep.stepId,
3935
+ parentClass: mutable.macroClass,
3936
+ parentScore: mutable.score,
3937
+ error: errMsg(err)
3938
+ }
3939
+ });
3937
3940
  }
3938
3941
  firstLevel.push(mutable);
3939
3942
  }
@@ -17971,7 +17971,15 @@ var FrameworkPackageStatusSchema = object({
17971
17971
  latestVersion: string().nullable(),
17972
17972
  hasUpdate: boolean(),
17973
17973
  /** Optional manifest description for the row tooltip. */
17974
- description: string().optional()
17974
+ description: string().optional(),
17975
+ /**
17976
+ * Content build-id (md5 of the resolved `dist/` tree) of the code the hub
17977
+ * ACTUALLY loaded. Framework packages ship code changes without always
17978
+ * bumping `currentVersion`, so semver alone hides "same version, new code".
17979
+ * `null` when the dist can't be hashed (not installed / empty). The admin-UI
17980
+ * surfaces this so a stale-code hub is visible even at an unchanged version.
17981
+ */
17982
+ buildId: string().nullable()
17975
17983
  });
17976
17984
  var LogStreamEntrySchema = object({
17977
17985
  timestamp: string(),
@@ -17971,7 +17971,15 @@ var FrameworkPackageStatusSchema = object({
17971
17971
  latestVersion: string().nullable(),
17972
17972
  hasUpdate: boolean(),
17973
17973
  /** Optional manifest description for the row tooltip. */
17974
- description: string().optional()
17974
+ description: string().optional(),
17975
+ /**
17976
+ * Content build-id (md5 of the resolved `dist/` tree) of the code the hub
17977
+ * ACTUALLY loaded. Framework packages ship code changes without always
17978
+ * bumping `currentVersion`, so semver alone hides "same version, new code".
17979
+ * `null` when the dist can't be hashed (not installed / empty). The admin-UI
17980
+ * surfaces this so a stale-code hub is visible even at an unchanged version.
17981
+ */
17982
+ buildId: string().nullable()
17975
17983
  });
17976
17984
  var LogStreamEntrySchema = object({
17977
17985
  timestamp: string(),
@@ -1,4 +1,4 @@
1
- const require_dist = require("./dist-BJTPkJFw.js");
1
+ const require_dist = require("./dist-NvwN60Fq.js");
2
2
  let node_crypto = require("node:crypto");
3
3
  //#region src/stream-broker/stream-broker/decoder-session-proxy.ts
4
4
  /**
@@ -1,4 +1,4 @@
1
- import { I as errMsg, d as RingBuffer } from "./dist-v6cKLmU3.mjs";
1
+ import { I as errMsg, d as RingBuffer } from "./dist-GFd8M6KO.mjs";
2
2
  import { randomUUID } from "node:crypto";
3
3
  //#region src/stream-broker/stream-broker/decoder-session-proxy.ts
4
4
  /**
@@ -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-BJTPkJFw.js");
5
+ const require_dist = require("../dist-NvwN60Fq.js");
6
6
  let _camstack_shm_ring = require("@camstack/shm-ring");
7
7
  let node_fs = require("node:fs");
8
8
  let node_path = require("node:path");
@@ -1,4 +1,4 @@
1
- import { B as DeviceType, E as motionDetectionCapability, L as BaseAddon, U as hydrateSchema, x as evaluateZoneRules } from "../dist-v6cKLmU3.mjs";
1
+ import { B as DeviceType, E as motionDetectionCapability, L as BaseAddon, U as hydrateSchema, x as evaluateZoneRules } from "../dist-GFd8M6KO.mjs";
2
2
  import { FrameRingReaderCache } from "@camstack/shm-ring";
3
3
  import { readFileSync } from "node:fs";
4
4
  import { join } from "node:path";
@@ -2,8 +2,8 @@ Object.defineProperties(exports, {
2
2
  __esModule: { value: true },
3
3
  [Symbol.toStringTag]: { value: "Module" }
4
4
  });
5
- const require_dist = require("../dist-BJTPkJFw.js");
6
- const require_frame_handle_plane = require("../frame-handle-plane-BP8YV4sF.js");
5
+ const require_dist = require("../dist-NvwN60Fq.js");
6
+ const require_frame_handle_plane = require("../frame-handle-plane-B3Fxww8H.js");
7
7
  const require_hub_hostname = require("../hub-hostname-DAJXlOgV.js");
8
8
  const require_worker_protocol = require("../worker-protocol-BCfO8gUF.js");
9
9
  let _camstack_shm_ring = require("@camstack/shm-ring");
@@ -1966,6 +1966,20 @@ var DEFAULT_CONFIG = {
1966
1966
  maxConcurrentDecodeSpawns: 3
1967
1967
  };
1968
1968
  /**
1969
+ * Camera attachment record kept by the runner addon. Holds the original
1970
+ * RunnerCameraConfig for introspection via `getLocalCameras` plus the
1971
+ * live broker subscription handles needed to tear down on detach.
1972
+ */
1973
+ /**
1974
+ * Keep-warm grace after the motion gate closes before the per-session
1975
+ * detection decode worker is actually torn down. Motion re-firing inside
1976
+ * this window REUSES the warm worker instead of re-forking it — killing the
1977
+ * spawn/teardown churn (and its cold-start latency spike) that on-motion
1978
+ * cameras produced when every gate open/close forked and killed a worker.
1979
+ * Mirrors Scrypted's decode-fork ~15s idle-timeout.
1980
+ */
1981
+ var DETECTION_KEEPWARM_MS = 15e3;
1982
+ /**
1969
1983
  * Pure decision helper: returns `true` when a dynamic frame-diff analyzer
1970
1984
  * subscription should be opened for an onboard-motion camera.
1971
1985
  *
@@ -2247,6 +2261,10 @@ var PipelineRunnerAddon = class extends require_dist.BaseAddon {
2247
2261
  this.runner = null;
2248
2262
  }
2249
2263
  for (const attachment of this.attached.values()) {
2264
+ if (attachment.detectionKeepWarmTimer !== null) {
2265
+ clearTimeout(attachment.detectionKeepWarmTimer);
2266
+ attachment.detectionKeepWarmTimer = null;
2267
+ }
2250
2268
  attachment.motionUnsubscribe?.();
2251
2269
  attachment.detectionUnsubscribe?.();
2252
2270
  }
@@ -2595,7 +2613,8 @@ var PipelineRunnerAddon = class extends require_dist.BaseAddon {
2595
2613
  const attachment = {
2596
2614
  config,
2597
2615
  motionUnsubscribe: null,
2598
- detectionUnsubscribe: null
2616
+ detectionUnsubscribe: null,
2617
+ detectionKeepWarmTimer: null
2599
2618
  };
2600
2619
  this.attached.set(config.deviceId, attachment);
2601
2620
  runner.registerCamera(config.deviceId, {
@@ -2636,6 +2655,10 @@ var PipelineRunnerAddon = class extends require_dist.BaseAddon {
2636
2655
  const attachment = this.attached.get(deviceId);
2637
2656
  if (!attachment) return;
2638
2657
  this.clearOnboardAnalyzer(deviceId);
2658
+ if (attachment.detectionKeepWarmTimer !== null) {
2659
+ clearTimeout(attachment.detectionKeepWarmTimer);
2660
+ attachment.detectionKeepWarmTimer = null;
2661
+ }
2639
2662
  attachment.motionUnsubscribe?.();
2640
2663
  attachment.detectionUnsubscribe?.();
2641
2664
  const remotePlane = this.remotePlanes.get(deviceId);
@@ -3064,12 +3087,27 @@ var PipelineRunnerAddon = class extends require_dist.BaseAddon {
3064
3087
  handleDetectionStreamChange(deviceId, action) {
3065
3088
  const attachment = this.attached.get(deviceId);
3066
3089
  if (!attachment) return;
3067
- if (action === "subscribe") this.subscribeDetectionFrames(attachment.config).then((unsub) => {
3068
- attachment.detectionUnsubscribe = unsub;
3069
- });
3070
- else {
3071
- attachment.detectionUnsubscribe?.();
3072
- attachment.detectionUnsubscribe = null;
3090
+ if (action === "subscribe") {
3091
+ if (attachment.detectionKeepWarmTimer !== null) {
3092
+ clearTimeout(attachment.detectionKeepWarmTimer);
3093
+ attachment.detectionKeepWarmTimer = null;
3094
+ }
3095
+ if (attachment.detectionUnsubscribe !== null) return;
3096
+ this.subscribeDetectionFrames(attachment.config).then((unsub) => {
3097
+ if (!this.attached.has(deviceId)) {
3098
+ unsub?.();
3099
+ return;
3100
+ }
3101
+ attachment.detectionUnsubscribe = unsub;
3102
+ });
3103
+ } else {
3104
+ if (attachment.detectionKeepWarmTimer !== null) return;
3105
+ if (attachment.detectionUnsubscribe === null) return;
3106
+ attachment.detectionKeepWarmTimer = setTimeout(() => {
3107
+ attachment.detectionKeepWarmTimer = null;
3108
+ attachment.detectionUnsubscribe?.();
3109
+ attachment.detectionUnsubscribe = null;
3110
+ }, DETECTION_KEEPWARM_MS);
3073
3111
  }
3074
3112
  }
3075
3113
  /**
@@ -1,5 +1,5 @@
1
- import { D as nodePin, G as makeSourceBrokerId, H as createEvent, I as errMsg, L as BaseAddon, Q as boolean, V as EventCategory, X as _enum, Z as array, _ as customAction, at as string, et as lazy, k as pipelineRunnerCapability, nt as number, rt as object, y as defineCustomActions } from "../dist-v6cKLmU3.mjs";
2
- import { t as FrameHandlePlane } from "../frame-handle-plane-DKAXTtfn.mjs";
1
+ import { D as nodePin, G as makeSourceBrokerId, H as createEvent, I as errMsg, L as BaseAddon, Q as boolean, V as EventCategory, X as _enum, Z as array, _ as customAction, at as string, et as lazy, k as pipelineRunnerCapability, nt as number, rt as object, y as defineCustomActions } from "../dist-GFd8M6KO.mjs";
2
+ import { t as FrameHandlePlane } from "../frame-handle-plane-E_AsR77T.mjs";
3
3
  import { t as resolveHubHostname } from "../hub-hostname-cCknRYKj.mjs";
4
4
  import { t as isWorkerReply } from "../worker-protocol-pk7qdYXt.mjs";
5
5
  import { FrameRingReaderCache } from "@camstack/shm-ring";
@@ -1962,6 +1962,20 @@ var DEFAULT_CONFIG = {
1962
1962
  maxConcurrentDecodeSpawns: 3
1963
1963
  };
1964
1964
  /**
1965
+ * Camera attachment record kept by the runner addon. Holds the original
1966
+ * RunnerCameraConfig for introspection via `getLocalCameras` plus the
1967
+ * live broker subscription handles needed to tear down on detach.
1968
+ */
1969
+ /**
1970
+ * Keep-warm grace after the motion gate closes before the per-session
1971
+ * detection decode worker is actually torn down. Motion re-firing inside
1972
+ * this window REUSES the warm worker instead of re-forking it — killing the
1973
+ * spawn/teardown churn (and its cold-start latency spike) that on-motion
1974
+ * cameras produced when every gate open/close forked and killed a worker.
1975
+ * Mirrors Scrypted's decode-fork ~15s idle-timeout.
1976
+ */
1977
+ var DETECTION_KEEPWARM_MS = 15e3;
1978
+ /**
1965
1979
  * Pure decision helper: returns `true` when a dynamic frame-diff analyzer
1966
1980
  * subscription should be opened for an onboard-motion camera.
1967
1981
  *
@@ -2243,6 +2257,10 @@ var PipelineRunnerAddon = class extends BaseAddon {
2243
2257
  this.runner = null;
2244
2258
  }
2245
2259
  for (const attachment of this.attached.values()) {
2260
+ if (attachment.detectionKeepWarmTimer !== null) {
2261
+ clearTimeout(attachment.detectionKeepWarmTimer);
2262
+ attachment.detectionKeepWarmTimer = null;
2263
+ }
2246
2264
  attachment.motionUnsubscribe?.();
2247
2265
  attachment.detectionUnsubscribe?.();
2248
2266
  }
@@ -2591,7 +2609,8 @@ var PipelineRunnerAddon = class extends BaseAddon {
2591
2609
  const attachment = {
2592
2610
  config,
2593
2611
  motionUnsubscribe: null,
2594
- detectionUnsubscribe: null
2612
+ detectionUnsubscribe: null,
2613
+ detectionKeepWarmTimer: null
2595
2614
  };
2596
2615
  this.attached.set(config.deviceId, attachment);
2597
2616
  runner.registerCamera(config.deviceId, {
@@ -2632,6 +2651,10 @@ var PipelineRunnerAddon = class extends BaseAddon {
2632
2651
  const attachment = this.attached.get(deviceId);
2633
2652
  if (!attachment) return;
2634
2653
  this.clearOnboardAnalyzer(deviceId);
2654
+ if (attachment.detectionKeepWarmTimer !== null) {
2655
+ clearTimeout(attachment.detectionKeepWarmTimer);
2656
+ attachment.detectionKeepWarmTimer = null;
2657
+ }
2635
2658
  attachment.motionUnsubscribe?.();
2636
2659
  attachment.detectionUnsubscribe?.();
2637
2660
  const remotePlane = this.remotePlanes.get(deviceId);
@@ -3060,12 +3083,27 @@ var PipelineRunnerAddon = class extends BaseAddon {
3060
3083
  handleDetectionStreamChange(deviceId, action) {
3061
3084
  const attachment = this.attached.get(deviceId);
3062
3085
  if (!attachment) return;
3063
- if (action === "subscribe") this.subscribeDetectionFrames(attachment.config).then((unsub) => {
3064
- attachment.detectionUnsubscribe = unsub;
3065
- });
3066
- else {
3067
- attachment.detectionUnsubscribe?.();
3068
- attachment.detectionUnsubscribe = null;
3086
+ if (action === "subscribe") {
3087
+ if (attachment.detectionKeepWarmTimer !== null) {
3088
+ clearTimeout(attachment.detectionKeepWarmTimer);
3089
+ attachment.detectionKeepWarmTimer = null;
3090
+ }
3091
+ if (attachment.detectionUnsubscribe !== null) return;
3092
+ this.subscribeDetectionFrames(attachment.config).then((unsub) => {
3093
+ if (!this.attached.has(deviceId)) {
3094
+ unsub?.();
3095
+ return;
3096
+ }
3097
+ attachment.detectionUnsubscribe = unsub;
3098
+ });
3099
+ } else {
3100
+ if (attachment.detectionKeepWarmTimer !== null) return;
3101
+ if (attachment.detectionUnsubscribe === null) return;
3102
+ attachment.detectionKeepWarmTimer = setTimeout(() => {
3103
+ attachment.detectionKeepWarmTimer = null;
3104
+ attachment.detectionUnsubscribe?.();
3105
+ attachment.detectionUnsubscribe = null;
3106
+ }, DETECTION_KEEPWARM_MS);
3069
3107
  }
3070
3108
  }
3071
3109
  /**
@@ -1,5 +1,5 @@
1
1
  const require_model_download_service_C_IHWnXx = require("../model-download-service-C-IHWnXx-DxM2DSns.js");
2
- const require_dist = require("../dist-BJTPkJFw.js");
2
+ const require_dist = require("../dist-NvwN60Fq.js");
3
3
  const require_hub_hostname = require("../hub-hostname-DAJXlOgV.js");
4
4
  let node_child_process = require("node:child_process");
5
5
  let node_fs = require("node:fs");
@@ -448,13 +448,16 @@ async function runRedundancyJanitor(deps) {
448
448
  files += vrows.length;
449
449
  bytes += reclaimed;
450
450
  } catch (err) {
451
- deps.logger.warn("janitor: evict failed (skipping)", { meta: {
452
- deviceId,
453
- profile,
454
- location,
455
- count: vrows.length,
456
- error: err instanceof Error ? err.message : String(err)
457
- } });
451
+ deps.logger.warn("janitor: evict failed (skipping)", {
452
+ tags: { deviceId },
453
+ meta: {
454
+ deviceId,
455
+ profile,
456
+ location,
457
+ count: vrows.length,
458
+ error: err instanceof Error ? err.message : String(err)
459
+ }
460
+ });
458
461
  }
459
462
  }
460
463
  }
@@ -1091,9 +1094,12 @@ function buildRecordingProvider(deps) {
1091
1094
  return require_dist.hydrateSchema(buildRecordingDeviceSchema(), {});
1092
1095
  },
1093
1096
  getDeviceLiveContribution: async () => null,
1094
- applyDeviceSettingsPatch: async ({ patch }) => {
1097
+ applyDeviceSettingsPatch: async ({ deviceId, patch }) => {
1095
1098
  const keys = Object.keys(patch ?? {});
1096
- if (keys.length > 0) deps.logger.debug("recorder: ignoring legacy settings patch (widget owns settings)", { meta: { keys } });
1099
+ if (keys.length > 0) deps.logger.debug("recorder: ignoring legacy settings patch (widget owns settings)", {
1100
+ tags: { deviceId },
1101
+ meta: { keys }
1102
+ });
1097
1103
  return { success: true };
1098
1104
  }
1099
1105
  };
@@ -1880,13 +1886,14 @@ var RecordingController = class {
1880
1886
  }));
1881
1887
  const outDir = node_path.default.join(placement.root, STAGING_DIR_NAME, String(deviceId), profile);
1882
1888
  await node_fs.promises.mkdir(outDir, { recursive: true });
1889
+ const deviceLog = this.deps.logger.withTags({ deviceId });
1883
1890
  const writer = new SegmentWriter({
1884
1891
  rtspUrl: source.url,
1885
1892
  outDir,
1886
1893
  segmentSeconds
1887
1894
  }, {
1888
1895
  spawn: this.deps.spawn,
1889
- logger: this.deps.logger,
1896
+ logger: deviceLog,
1890
1897
  onGaveUp: () => {
1891
1898
  this.recoverWriterGaveUp(deviceId);
1892
1899
  }
@@ -1901,7 +1908,7 @@ var RecordingController = class {
1901
1908
  onFinalized: (startMs, durMs, flatAbsPath) => {
1902
1909
  this.handleFinalizedSegment(deviceId, profile, placement, startMs, durMs, flatAbsPath);
1903
1910
  },
1904
- logger: this.deps.logger
1911
+ logger: deviceLog
1905
1912
  }),
1906
1913
  pipelineKey: source.pipelineKey,
1907
1914
  outDir
@@ -1,4 +1,4 @@
1
- import { A as recordingCapability, B as DeviceType, I as errMsg, J as selectAssignedProfileSlots, L as BaseAddon, M as storageEvictableCapability, T as migrateConfigToBands, U as hydrateSchema, V as EventCategory, at as string, it as record, s as EVENT_PAD_MS, u as RecordingConfigSchema } from "../dist-v6cKLmU3.mjs";
1
+ import { A as recordingCapability, B as DeviceType, I as errMsg, J as selectAssignedProfileSlots, L as BaseAddon, M as storageEvictableCapability, T as migrateConfigToBands, U as hydrateSchema, V as EventCategory, at as string, it as record, s as EVENT_PAD_MS, u as RecordingConfigSchema } from "../dist-GFd8M6KO.mjs";
2
2
  import { t as resolveHubHostname } from "../hub-hostname-cCknRYKj.mjs";
3
3
  import { t as createFileDataPlaneHandler } from "../model-download-service-C-IHWnXx-BPy6aoAx.mjs";
4
4
  import { spawn } from "node:child_process";
@@ -447,13 +447,16 @@ async function runRedundancyJanitor(deps) {
447
447
  files += vrows.length;
448
448
  bytes += reclaimed;
449
449
  } catch (err) {
450
- deps.logger.warn("janitor: evict failed (skipping)", { meta: {
451
- deviceId,
452
- profile,
453
- location,
454
- count: vrows.length,
455
- error: err instanceof Error ? err.message : String(err)
456
- } });
450
+ deps.logger.warn("janitor: evict failed (skipping)", {
451
+ tags: { deviceId },
452
+ meta: {
453
+ deviceId,
454
+ profile,
455
+ location,
456
+ count: vrows.length,
457
+ error: err instanceof Error ? err.message : String(err)
458
+ }
459
+ });
457
460
  }
458
461
  }
459
462
  }
@@ -1090,9 +1093,12 @@ function buildRecordingProvider(deps) {
1090
1093
  return hydrateSchema(buildRecordingDeviceSchema(), {});
1091
1094
  },
1092
1095
  getDeviceLiveContribution: async () => null,
1093
- applyDeviceSettingsPatch: async ({ patch }) => {
1096
+ applyDeviceSettingsPatch: async ({ deviceId, patch }) => {
1094
1097
  const keys = Object.keys(patch ?? {});
1095
- if (keys.length > 0) deps.logger.debug("recorder: ignoring legacy settings patch (widget owns settings)", { meta: { keys } });
1098
+ if (keys.length > 0) deps.logger.debug("recorder: ignoring legacy settings patch (widget owns settings)", {
1099
+ tags: { deviceId },
1100
+ meta: { keys }
1101
+ });
1096
1102
  return { success: true };
1097
1103
  }
1098
1104
  };
@@ -1879,13 +1885,14 @@ var RecordingController = class {
1879
1885
  }));
1880
1886
  const outDir = path.join(placement.root, STAGING_DIR_NAME, String(deviceId), profile);
1881
1887
  await promises.mkdir(outDir, { recursive: true });
1888
+ const deviceLog = this.deps.logger.withTags({ deviceId });
1882
1889
  const writer = new SegmentWriter({
1883
1890
  rtspUrl: source.url,
1884
1891
  outDir,
1885
1892
  segmentSeconds
1886
1893
  }, {
1887
1894
  spawn: this.deps.spawn,
1888
- logger: this.deps.logger,
1895
+ logger: deviceLog,
1889
1896
  onGaveUp: () => {
1890
1897
  this.recoverWriterGaveUp(deviceId);
1891
1898
  }
@@ -1900,7 +1907,7 @@ var RecordingController = class {
1900
1907
  onFinalized: (startMs, durMs, flatAbsPath) => {
1901
1908
  this.handleFinalizedSegment(deviceId, profile, placement, startMs, durMs, flatAbsPath);
1902
1909
  },
1903
- logger: this.deps.logger
1910
+ logger: deviceLog
1904
1911
  }),
1905
1912
  pipelineKey: source.pipelineKey,
1906
1913
  outDir