@camstack/addon-provider-reolink 1.2.145 → 1.2.146

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.
package/dist/addon.js CHANGED
@@ -5390,7 +5390,7 @@ var ZodIssueCode = {
5390
5390
  var ZodFirstPartyTypeKind;
5391
5391
  ZodFirstPartyTypeKind || (ZodFirstPartyTypeKind = {});
5392
5392
  //#endregion
5393
- //#region ../types/dist/sleep-CopaBJss.mjs
5393
+ //#region ../types/dist/sleep-7AN_Txmu.mjs
5394
5394
  /**
5395
5395
  * The audio chunk plane's byte format, and the ONE expansion from a coded
5396
5396
  * window to float samples (D455).
@@ -5590,12 +5590,6 @@ Object.fromEntries([
5590
5590
  icon: "circle-dot",
5591
5591
  order: 40
5592
5592
  },
5593
- {
5594
- id: "clips",
5595
- label: "Clips",
5596
- icon: "clapperboard",
5597
- order: 41
5598
- },
5599
5593
  {
5600
5594
  id: "engine",
5601
5595
  label: "Inference Engine",
@@ -25421,17 +25415,31 @@ var videoclipsCapability = {
25421
25415
  * `device-config-widget-wrapped-binding.spec.ts` pins that a `kind:'wrapped'`
25422
25416
  * binding entry derives the same section a native one does.
25423
25417
  *
25424
- * `topTab` because the browser owns the whole pane (a day's clips, a source
25425
- * list and a player), exactly as `ptz` does; the widget itself is
25426
- * `host/clips-browser` in ui-library's `HOST_WIDGETS`.
25418
+ * **It is a SECTION of the Recording tab, at the end of it — not a tab of
25419
+ * its own.** It shipped as a `clips` top-tab and the operator rejected the
25420
+ * placement: *"utilizzerei la stessa tab recordings, lì abbiamo già tutto il
25421
+ * necessario, una nuova sezione alla fine per le clips"*. The Recording tab
25422
+ * already holds the recorder's panel, the schedule bands and the unified
25423
+ * retention policy; footage the camera itself holds is the same question,
25424
+ * asked of a different store. `order: 100` puts it after all of them with
25425
+ * room left in front. The `clips` entry in `WELL_KNOWN_TABS` went with it —
25426
+ * a well-known id nobody declares is an invitation to mint the tab again.
25427
+ *
25428
+ * `topTab` stays: the browser owns a pane (a day's tiles, a source list and
25429
+ * a player) and the Config tab's inner bar has no room for one. The widget
25430
+ * itself is `host/clips-browser` in ui-library's `HOST_WIDGETS`, and because
25431
+ * the admin Recordings page renders every `location:'top-tab'` +
25432
+ * `tab:'recording'` section behind its camera picker
25433
+ * (`CameraRecordingSettingsSection`), this declaration lands the section on
25434
+ * BOTH surfaces with no second wiring.
25427
25435
  */
25428
25436
  deviceConfig: { ui: {
25429
25437
  kind: "widget",
25430
25438
  widgetId: "host/clips-browser",
25431
- tab: "clips",
25439
+ tab: "recording",
25432
25440
  topTab: true,
25433
25441
  label: "Clips",
25434
- order: 0
25442
+ order: 100
25435
25443
  } },
25436
25444
  methods: {
25437
25445
  listClips: method(object({
@@ -25440,13 +25448,23 @@ var videoclipsCapability = {
25440
25448
  until: number(),
25441
25449
  limit: number().int().positive().optional(),
25442
25450
  /**
25443
- * View filter over {@link ClipSourceSchema.source} values — the
25444
- * picker's selection, forwarded so a provider need not list what
25445
- * nobody is looking at. ABSENT means every source this camera has,
25446
- * which is the honest default for a surface whose whole point is that
25447
- * nothing is hidden (D554 3). A provider with one source ignores it.
25451
+ * WHICH provider to ask — the `addonId` a {@link ClipSourceSchema} row
25452
+ * carries, never a source id and never a list.
25453
+ *
25454
+ * Absent means the device's BOUND provider, which is CamStack on every
25455
+ * camera today because that is what `deviceManager.getBindings`
25456
+ * answers with. A provider the device is not bound to is refused by
25457
+ * name rather than answered by another one (D552's
25458
+ * `rejectUnresolvedAddonPin` rule).
25459
+ *
25460
+ * It replaced `sources?: string[]`, a VIEW filter over source ids that
25461
+ * assumed the answer was a fan-out over everything a camera has. The
25462
+ * operator settled otherwise on 2026-09-20 — *"il get videoclips
25463
+ * prendere un provider opzionale, di default va su camstack"*,
25464
+ * *"l'utilizzatore è uno solo"* — so the list is asked of one provider
25465
+ * at a time and there is nothing to filter out of it.
25448
25466
  */
25449
- sources: array(string()).optional()
25467
+ provider: string().optional()
25450
25468
  }), array(ClipSchema).readonly(), {
25451
25469
  kind: "query",
25452
25470
  auth: "protected"
@@ -147455,6 +147473,21 @@ var ClipArtifactStore = class {
147455
147473
  }
147456
147474
  };
147457
147475
  //#endregion
147476
+ //#region src/clips/clip-addressing.ts
147477
+ /** Does addressing this camera's catalog REQUIRE a persisted uid? */
147478
+ function uidIsRequired(subject) {
147479
+ return subject.isHubChild;
147480
+ }
147481
+ /**
147482
+ * Is this camera unaddressable for want of a uid? The gate every catalog,
147483
+ * still and byte read runs — and the only one that may answer `uid-missing`.
147484
+ */
147485
+ function uidIsMissing(subject) {
147486
+ return uidIsRequired(subject) && subject.uid === void 0;
147487
+ }
147488
+ /** The one wording for the refusal, so two surfaces cannot disagree about it. */
147489
+ var UID_MISSING_REASON = "uid-missing: the hub selects a child by uid, and this camera has none persisted.";
147490
+ //#endregion
147458
147491
  //#region src/clips/clip-catalog-cache.ts
147459
147492
  /**
147460
147493
  * The per-`(device, day)` clip catalog cache.
@@ -148633,7 +148666,7 @@ function createReolinkVideoclipsProvider(deps) {
148633
148666
  });
148634
148667
  return cached;
148635
148668
  }
148636
- if (device.uid === void 0) {
148669
+ if (uidIsMissing(device)) {
148637
148670
  deps.logger.warn("videoclips: no uid for this camera — its catalog cannot be addressed", {
148638
148671
  tags,
148639
148672
  meta: {
@@ -148643,7 +148676,7 @@ function createReolinkVideoclipsProvider(deps) {
148643
148676
  });
148644
148677
  noteHealth(device.deviceId, CLIP_SOURCE_ONBOARD, {
148645
148678
  state: "unreachable",
148646
- reason: "uid-missing: this camera has no persisted uid, and on a hub the uid is what selects the child (the hub’s own uid addresses no catalog)."
148679
+ reason: UID_MISSING_REASON
148647
148680
  });
148648
148681
  return [];
148649
148682
  }
@@ -148777,7 +148810,8 @@ function createReolinkVideoclipsProvider(deps) {
148777
148810
  const readHubEvents = async (device, since, until) => {
148778
148811
  const tags = { deviceId: device.deviceId };
148779
148812
  if (!device.isHubChild) return [];
148780
- if (device.uid === void 0) {
148813
+ const uid = device.uid;
148814
+ if (uid === void 0) {
148781
148815
  deps.logger.warn("videoclips: no uid for this camera — the hub cannot be asked about it", {
148782
148816
  tags,
148783
148817
  meta: {
@@ -148787,7 +148821,7 @@ function createReolinkVideoclipsProvider(deps) {
148787
148821
  });
148788
148822
  noteHealth(device.deviceId, CLIP_SOURCE_ONBOARD, {
148789
148823
  state: "unreachable",
148790
- reason: "uid-missing: the hub selects a child by uid, and this camera has none persisted."
148824
+ reason: UID_MISSING_REASON
148791
148825
  });
148792
148826
  return [];
148793
148827
  }
@@ -148815,7 +148849,7 @@ function createReolinkVideoclipsProvider(deps) {
148815
148849
  let joined = [];
148816
148850
  try {
148817
148851
  const rows = await listEventRows(api, {
148818
- uid: device.uid,
148852
+ uid,
148819
148853
  channel: device.channel,
148820
148854
  timeZone: device.timeZone,
148821
148855
  since,
@@ -148950,11 +148984,10 @@ function createReolinkVideoclipsProvider(deps) {
148950
148984
  availability: await resolveAvailability(device, via)
148951
148985
  }];
148952
148986
  },
148953
- listClips: async ({ deviceId, since, until, limit, sources }) => {
148987
+ listClips: async ({ deviceId, since, until, limit }) => {
148954
148988
  const device = await deps.resolveDevice(deviceId);
148955
148989
  if (device === null) return [];
148956
148990
  const tags = { deviceId };
148957
- if (sources !== void 0 && !sources.includes("native:reolink:onboard")) return [];
148958
148991
  const via = viaFor(device);
148959
148992
  const ordered = (via === "events" ? await (async () => {
148960
148993
  const events = await readHubEvents(device, since, until);
@@ -149022,17 +149055,17 @@ function createReolinkVideoclipsProvider(deps) {
149022
149055
  async function resolveAvailability(device, via) {
149023
149056
  const known = health.get(healthKey(device.deviceId, CLIP_SOURCE_ONBOARD))?.availability;
149024
149057
  if (known !== void 0) return known;
149025
- if (via === "events") return device.uid === void 0 ? {
149058
+ if (via === "events") return uidIsMissing(device) ? {
149026
149059
  state: "unreachable",
149027
- reason: "uid-missing: the hub selects a child by uid, and this camera has none persisted."
149060
+ reason: UID_MISSING_REASON
149028
149061
  } : { state: "ok" };
149029
149062
  if (device.isBattery && device.sleeping && !device.isHubChild) return {
149030
149063
  state: "sleeping",
149031
149064
  reason: "A read would wake this camera. Nothing has been listed yet."
149032
149065
  };
149033
- if (device.uid === void 0) return {
149066
+ if (uidIsMissing(device)) return {
149034
149067
  state: "unreachable",
149035
- reason: "uid-missing: this camera has no persisted uid to address its catalog with."
149068
+ reason: UID_MISSING_REASON
149036
149069
  };
149037
149070
  try {
149038
149071
  if ((await readStorageState(await device.getApi())).state === "absent") return {
@@ -149085,9 +149118,9 @@ function createClipService(deps) {
149085
149118
  ok: false,
149086
149119
  reason: "sleeping: a still would wake this standalone battery camera"
149087
149120
  };
149088
- if (device.uid === void 0) return {
149121
+ if (uidIsMissing(device)) return {
149089
149122
  ok: false,
149090
- reason: "uid-missing: this camera’s stills cannot be addressed"
149123
+ reason: UID_MISSING_REASON
149091
149124
  };
149092
149125
  const row = rowFor(deviceId, clipKey);
149093
149126
  if (row === null) return {
@@ -149104,7 +149137,7 @@ function createClipService(deps) {
149104
149137
  time: new Date(row.startMs),
149105
149138
  endTime: new Date(row.endMs),
149106
149139
  snapType: "sub",
149107
- uid: device.uid,
149140
+ ...device.uid === void 0 ? {} : { uid: device.uid },
149108
149141
  isNvr: device.isHubChild,
149109
149142
  timeZone: device.timeZone
149110
149143
  });
package/dist/addon.mjs CHANGED
@@ -5385,7 +5385,7 @@ var ZodIssueCode = {
5385
5385
  var ZodFirstPartyTypeKind;
5386
5386
  ZodFirstPartyTypeKind || (ZodFirstPartyTypeKind = {});
5387
5387
  //#endregion
5388
- //#region ../types/dist/sleep-CopaBJss.mjs
5388
+ //#region ../types/dist/sleep-7AN_Txmu.mjs
5389
5389
  /**
5390
5390
  * The audio chunk plane's byte format, and the ONE expansion from a coded
5391
5391
  * window to float samples (D455).
@@ -5585,12 +5585,6 @@ Object.fromEntries([
5585
5585
  icon: "circle-dot",
5586
5586
  order: 40
5587
5587
  },
5588
- {
5589
- id: "clips",
5590
- label: "Clips",
5591
- icon: "clapperboard",
5592
- order: 41
5593
- },
5594
5588
  {
5595
5589
  id: "engine",
5596
5590
  label: "Inference Engine",
@@ -25416,17 +25410,31 @@ var videoclipsCapability = {
25416
25410
  * `device-config-widget-wrapped-binding.spec.ts` pins that a `kind:'wrapped'`
25417
25411
  * binding entry derives the same section a native one does.
25418
25412
  *
25419
- * `topTab` because the browser owns the whole pane (a day's clips, a source
25420
- * list and a player), exactly as `ptz` does; the widget itself is
25421
- * `host/clips-browser` in ui-library's `HOST_WIDGETS`.
25413
+ * **It is a SECTION of the Recording tab, at the end of it — not a tab of
25414
+ * its own.** It shipped as a `clips` top-tab and the operator rejected the
25415
+ * placement: *"utilizzerei la stessa tab recordings, lì abbiamo già tutto il
25416
+ * necessario, una nuova sezione alla fine per le clips"*. The Recording tab
25417
+ * already holds the recorder's panel, the schedule bands and the unified
25418
+ * retention policy; footage the camera itself holds is the same question,
25419
+ * asked of a different store. `order: 100` puts it after all of them with
25420
+ * room left in front. The `clips` entry in `WELL_KNOWN_TABS` went with it —
25421
+ * a well-known id nobody declares is an invitation to mint the tab again.
25422
+ *
25423
+ * `topTab` stays: the browser owns a pane (a day's tiles, a source list and
25424
+ * a player) and the Config tab's inner bar has no room for one. The widget
25425
+ * itself is `host/clips-browser` in ui-library's `HOST_WIDGETS`, and because
25426
+ * the admin Recordings page renders every `location:'top-tab'` +
25427
+ * `tab:'recording'` section behind its camera picker
25428
+ * (`CameraRecordingSettingsSection`), this declaration lands the section on
25429
+ * BOTH surfaces with no second wiring.
25422
25430
  */
25423
25431
  deviceConfig: { ui: {
25424
25432
  kind: "widget",
25425
25433
  widgetId: "host/clips-browser",
25426
- tab: "clips",
25434
+ tab: "recording",
25427
25435
  topTab: true,
25428
25436
  label: "Clips",
25429
- order: 0
25437
+ order: 100
25430
25438
  } },
25431
25439
  methods: {
25432
25440
  listClips: method(object({
@@ -25435,13 +25443,23 @@ var videoclipsCapability = {
25435
25443
  until: number(),
25436
25444
  limit: number().int().positive().optional(),
25437
25445
  /**
25438
- * View filter over {@link ClipSourceSchema.source} values — the
25439
- * picker's selection, forwarded so a provider need not list what
25440
- * nobody is looking at. ABSENT means every source this camera has,
25441
- * which is the honest default for a surface whose whole point is that
25442
- * nothing is hidden (D554 3). A provider with one source ignores it.
25446
+ * WHICH provider to ask — the `addonId` a {@link ClipSourceSchema} row
25447
+ * carries, never a source id and never a list.
25448
+ *
25449
+ * Absent means the device's BOUND provider, which is CamStack on every
25450
+ * camera today because that is what `deviceManager.getBindings`
25451
+ * answers with. A provider the device is not bound to is refused by
25452
+ * name rather than answered by another one (D552's
25453
+ * `rejectUnresolvedAddonPin` rule).
25454
+ *
25455
+ * It replaced `sources?: string[]`, a VIEW filter over source ids that
25456
+ * assumed the answer was a fan-out over everything a camera has. The
25457
+ * operator settled otherwise on 2026-09-20 — *"il get videoclips
25458
+ * prendere un provider opzionale, di default va su camstack"*,
25459
+ * *"l'utilizzatore è uno solo"* — so the list is asked of one provider
25460
+ * at a time and there is nothing to filter out of it.
25443
25461
  */
25444
- sources: array(string()).optional()
25462
+ provider: string().optional()
25445
25463
  }), array(ClipSchema).readonly(), {
25446
25464
  kind: "query",
25447
25465
  auth: "protected"
@@ -147450,6 +147468,21 @@ var ClipArtifactStore = class {
147450
147468
  }
147451
147469
  };
147452
147470
  //#endregion
147471
+ //#region src/clips/clip-addressing.ts
147472
+ /** Does addressing this camera's catalog REQUIRE a persisted uid? */
147473
+ function uidIsRequired(subject) {
147474
+ return subject.isHubChild;
147475
+ }
147476
+ /**
147477
+ * Is this camera unaddressable for want of a uid? The gate every catalog,
147478
+ * still and byte read runs — and the only one that may answer `uid-missing`.
147479
+ */
147480
+ function uidIsMissing(subject) {
147481
+ return uidIsRequired(subject) && subject.uid === void 0;
147482
+ }
147483
+ /** The one wording for the refusal, so two surfaces cannot disagree about it. */
147484
+ var UID_MISSING_REASON = "uid-missing: the hub selects a child by uid, and this camera has none persisted.";
147485
+ //#endregion
147453
147486
  //#region src/clips/clip-catalog-cache.ts
147454
147487
  /**
147455
147488
  * The per-`(device, day)` clip catalog cache.
@@ -148628,7 +148661,7 @@ function createReolinkVideoclipsProvider(deps) {
148628
148661
  });
148629
148662
  return cached;
148630
148663
  }
148631
- if (device.uid === void 0) {
148664
+ if (uidIsMissing(device)) {
148632
148665
  deps.logger.warn("videoclips: no uid for this camera — its catalog cannot be addressed", {
148633
148666
  tags,
148634
148667
  meta: {
@@ -148638,7 +148671,7 @@ function createReolinkVideoclipsProvider(deps) {
148638
148671
  });
148639
148672
  noteHealth(device.deviceId, CLIP_SOURCE_ONBOARD, {
148640
148673
  state: "unreachable",
148641
- reason: "uid-missing: this camera has no persisted uid, and on a hub the uid is what selects the child (the hub’s own uid addresses no catalog)."
148674
+ reason: UID_MISSING_REASON
148642
148675
  });
148643
148676
  return [];
148644
148677
  }
@@ -148772,7 +148805,8 @@ function createReolinkVideoclipsProvider(deps) {
148772
148805
  const readHubEvents = async (device, since, until) => {
148773
148806
  const tags = { deviceId: device.deviceId };
148774
148807
  if (!device.isHubChild) return [];
148775
- if (device.uid === void 0) {
148808
+ const uid = device.uid;
148809
+ if (uid === void 0) {
148776
148810
  deps.logger.warn("videoclips: no uid for this camera — the hub cannot be asked about it", {
148777
148811
  tags,
148778
148812
  meta: {
@@ -148782,7 +148816,7 @@ function createReolinkVideoclipsProvider(deps) {
148782
148816
  });
148783
148817
  noteHealth(device.deviceId, CLIP_SOURCE_ONBOARD, {
148784
148818
  state: "unreachable",
148785
- reason: "uid-missing: the hub selects a child by uid, and this camera has none persisted."
148819
+ reason: UID_MISSING_REASON
148786
148820
  });
148787
148821
  return [];
148788
148822
  }
@@ -148810,7 +148844,7 @@ function createReolinkVideoclipsProvider(deps) {
148810
148844
  let joined = [];
148811
148845
  try {
148812
148846
  const rows = await listEventRows(api, {
148813
- uid: device.uid,
148847
+ uid,
148814
148848
  channel: device.channel,
148815
148849
  timeZone: device.timeZone,
148816
148850
  since,
@@ -148945,11 +148979,10 @@ function createReolinkVideoclipsProvider(deps) {
148945
148979
  availability: await resolveAvailability(device, via)
148946
148980
  }];
148947
148981
  },
148948
- listClips: async ({ deviceId, since, until, limit, sources }) => {
148982
+ listClips: async ({ deviceId, since, until, limit }) => {
148949
148983
  const device = await deps.resolveDevice(deviceId);
148950
148984
  if (device === null) return [];
148951
148985
  const tags = { deviceId };
148952
- if (sources !== void 0 && !sources.includes("native:reolink:onboard")) return [];
148953
148986
  const via = viaFor(device);
148954
148987
  const ordered = (via === "events" ? await (async () => {
148955
148988
  const events = await readHubEvents(device, since, until);
@@ -149017,17 +149050,17 @@ function createReolinkVideoclipsProvider(deps) {
149017
149050
  async function resolveAvailability(device, via) {
149018
149051
  const known = health.get(healthKey(device.deviceId, CLIP_SOURCE_ONBOARD))?.availability;
149019
149052
  if (known !== void 0) return known;
149020
- if (via === "events") return device.uid === void 0 ? {
149053
+ if (via === "events") return uidIsMissing(device) ? {
149021
149054
  state: "unreachable",
149022
- reason: "uid-missing: the hub selects a child by uid, and this camera has none persisted."
149055
+ reason: UID_MISSING_REASON
149023
149056
  } : { state: "ok" };
149024
149057
  if (device.isBattery && device.sleeping && !device.isHubChild) return {
149025
149058
  state: "sleeping",
149026
149059
  reason: "A read would wake this camera. Nothing has been listed yet."
149027
149060
  };
149028
- if (device.uid === void 0) return {
149061
+ if (uidIsMissing(device)) return {
149029
149062
  state: "unreachable",
149030
- reason: "uid-missing: this camera has no persisted uid to address its catalog with."
149063
+ reason: UID_MISSING_REASON
149031
149064
  };
149032
149065
  try {
149033
149066
  if ((await readStorageState(await device.getApi())).state === "absent") return {
@@ -149080,9 +149113,9 @@ function createClipService(deps) {
149080
149113
  ok: false,
149081
149114
  reason: "sleeping: a still would wake this standalone battery camera"
149082
149115
  };
149083
- if (device.uid === void 0) return {
149116
+ if (uidIsMissing(device)) return {
149084
149117
  ok: false,
149085
- reason: "uid-missing: this camera’s stills cannot be addressed"
149118
+ reason: UID_MISSING_REASON
149086
149119
  };
149087
149120
  const row = rowFor(deviceId, clipKey);
149088
149121
  if (row === null) return {
@@ -149099,7 +149132,7 @@ function createClipService(deps) {
149099
149132
  time: new Date(row.startMs),
149100
149133
  endTime: new Date(row.endMs),
149101
149134
  snapType: "sub",
149102
- uid: device.uid,
149135
+ ...device.uid === void 0 ? {} : { uid: device.uid },
149103
149136
  isNvr: device.isHubChild,
149104
149137
  timeZone: device.timeZone
149105
149138
  });
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@camstack/addon-provider-reolink",
3
- "version": "1.2.145",
3
+ "version": "1.2.146",
4
4
  "description": "Reolink camera device provider addon for CamStack — native Baichuan protocol",
5
5
  "keywords": [
6
6
  "camstack",