@camstack/system 1.2.10 → 1.2.11

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.
@@ -759,25 +759,31 @@ var SnapshotAddon = class SnapshotAddon extends require_dist.BaseAddon {
759
759
  this.captureFlight.invalidatePrefix(`${input.deviceId}:`);
760
760
  }
761
761
  /**
762
- * Non-throwing probe of the device's battery cap. Returns true only
763
- * when a battery native is registered AND its current status says
764
- * `sleeping: true`. Any error (no provider, native absent, getStatus
765
- * missing, RPC timeout) is swallowed and treated as "awake" — we'd
766
- * rather pay a wake-up than strand the caller on a cache that's
767
- * semantically stale. Debug-logged for observability.
762
+ * Sleep state from the device-state MIRROR, not from a cap round-trip.
768
763
  *
769
- * Cheap: a battery provider serves this from its runtime-state slice,
770
- * so the probe costs one RPC and zero camera traffic. Only consulted
771
- * on the path that would otherwise CAPTURE a fresh cache hit
772
- * returns before we get here.
764
+ * `fetchDevice(id).state.battery` is a `SliceHandle` over the hub's
765
+ * runtime-state mirror: a local read, no RPC, no failure branch to get
766
+ * wrong. It is the same mirror that feeds the battery badge elsewhere
767
+ * in the UI, so if the operator can see "sleeping" on screen, this
768
+ * sees it too. (Both spec harnesses already model exactly this wiring
769
+ * — like the orphaned doc comment above, it outlived the gate it was
770
+ * built for.)
771
+ *
772
+ * `undefined` slice → the device has no battery state we know of →
773
+ * treated as awake. The caller has already established the device is
774
+ * battery-operated from its feature flags, so this only decides
775
+ * WHETHER IT IS ASLEEP, never whether it has a battery.
776
+ *
777
+ * Only consulted on the path that would otherwise CAPTURE — a fresh
778
+ * cache hit returns before we get here.
773
779
  */
774
780
  async isDeviceSleeping(deviceId) {
775
781
  try {
776
- const raw = await this.ctx.api.battery.getStatus.query({ deviceId });
782
+ const raw = (await this.ctx.fetchDevice(deviceId)).state.battery.value;
777
783
  const parsed = require_dist.BatteryStatusSchema.safeParse(raw);
778
784
  return parsed.success && parsed.data.sleeping;
779
785
  } catch (err) {
780
- this.ctx.logger.debug("snapshot: battery sleep probe failed — assuming awake", {
786
+ this.ctx.logger.warn("snapshot: battery mirror read failed — assuming awake", {
781
787
  tags: { deviceId },
782
788
  meta: { error: require_dist.errMsg(err) }
783
789
  });
@@ -754,25 +754,31 @@ var SnapshotAddon = class SnapshotAddon extends BaseAddon {
754
754
  this.captureFlight.invalidatePrefix(`${input.deviceId}:`);
755
755
  }
756
756
  /**
757
- * Non-throwing probe of the device's battery cap. Returns true only
758
- * when a battery native is registered AND its current status says
759
- * `sleeping: true`. Any error (no provider, native absent, getStatus
760
- * missing, RPC timeout) is swallowed and treated as "awake" — we'd
761
- * rather pay a wake-up than strand the caller on a cache that's
762
- * semantically stale. Debug-logged for observability.
757
+ * Sleep state from the device-state MIRROR, not from a cap round-trip.
763
758
  *
764
- * Cheap: a battery provider serves this from its runtime-state slice,
765
- * so the probe costs one RPC and zero camera traffic. Only consulted
766
- * on the path that would otherwise CAPTURE a fresh cache hit
767
- * returns before we get here.
759
+ * `fetchDevice(id).state.battery` is a `SliceHandle` over the hub's
760
+ * runtime-state mirror: a local read, no RPC, no failure branch to get
761
+ * wrong. It is the same mirror that feeds the battery badge elsewhere
762
+ * in the UI, so if the operator can see "sleeping" on screen, this
763
+ * sees it too. (Both spec harnesses already model exactly this wiring
764
+ * — like the orphaned doc comment above, it outlived the gate it was
765
+ * built for.)
766
+ *
767
+ * `undefined` slice → the device has no battery state we know of →
768
+ * treated as awake. The caller has already established the device is
769
+ * battery-operated from its feature flags, so this only decides
770
+ * WHETHER IT IS ASLEEP, never whether it has a battery.
771
+ *
772
+ * Only consulted on the path that would otherwise CAPTURE — a fresh
773
+ * cache hit returns before we get here.
768
774
  */
769
775
  async isDeviceSleeping(deviceId) {
770
776
  try {
771
- const raw = await this.ctx.api.battery.getStatus.query({ deviceId });
777
+ const raw = (await this.ctx.fetchDevice(deviceId)).state.battery.value;
772
778
  const parsed = BatteryStatusSchema.safeParse(raw);
773
779
  return parsed.success && parsed.data.sleeping;
774
780
  } catch (err) {
775
- this.ctx.logger.debug("snapshot: battery sleep probe failed — assuming awake", {
781
+ this.ctx.logger.warn("snapshot: battery mirror read failed — assuming awake", {
776
782
  tags: { deviceId },
777
783
  meta: { error: errMsg(err) }
778
784
  });
@@ -170,17 +170,23 @@ export declare class SnapshotAddon extends BaseAddon<SnapshotAddonConfig> {
170
170
  private runGrabWithResumeRetry;
171
171
  private invalidateCache;
172
172
  /**
173
- * Non-throwing probe of the device's battery cap. Returns true only
174
- * when a battery native is registered AND its current status says
175
- * `sleeping: true`. Any error (no provider, native absent, getStatus
176
- * missing, RPC timeout) is swallowed and treated as "awake" — we'd
177
- * rather pay a wake-up than strand the caller on a cache that's
178
- * semantically stale. Debug-logged for observability.
173
+ * Sleep state from the device-state MIRROR, not from a cap round-trip.
179
174
  *
180
- * Cheap: a battery provider serves this from its runtime-state slice,
181
- * so the probe costs one RPC and zero camera traffic. Only consulted
182
- * on the path that would otherwise CAPTURE a fresh cache hit
183
- * returns before we get here.
175
+ * `fetchDevice(id).state.battery` is a `SliceHandle` over the hub's
176
+ * runtime-state mirror: a local read, no RPC, no failure branch to get
177
+ * wrong. It is the same mirror that feeds the battery badge elsewhere
178
+ * in the UI, so if the operator can see "sleeping" on screen, this
179
+ * sees it too. (Both spec harnesses already model exactly this wiring
180
+ * — like the orphaned doc comment above, it outlived the gate it was
181
+ * built for.)
182
+ *
183
+ * `undefined` slice → the device has no battery state we know of →
184
+ * treated as awake. The caller has already established the device is
185
+ * battery-operated from its feature flags, so this only decides
186
+ * WHETHER IT IS ASLEEP, never whether it has a battery.
187
+ *
188
+ * Only consulted on the path that would otherwise CAPTURE — a fresh
189
+ * cache hit returns before we get here.
184
190
  */
185
191
  private isDeviceSleeping;
186
192
  /**
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@camstack/system",
3
- "version": "1.2.10",
3
+ "version": "1.2.11",
4
4
  "description": "Core addon for CamStack — builtins, pipeline, process management, auth, logging, events",
5
5
  "keywords": [
6
6
  "camstack",