@camstack/addon-provider-dreame 0.2.78 → 0.2.79

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 (3) hide show
  1. package/dist/addon.js +125 -127
  2. package/dist/addon.mjs +125 -127
  3. package/package.json +1 -1
package/dist/addon.js CHANGED
@@ -60288,111 +60288,6 @@ var CameraSwitchGroupSchema = object({
60288
60288
  fetchedAt: number()
60289
60289
  });
60290
60290
  /**
60291
- * Per-component log CHANNELS — the gate a hot path consults, and the registry
60292
- * an addon declares its channels in.
60293
- *
60294
- * ## Two axes, deliberately separated
60295
- *
60296
- * - **DECLARATION** — which channels exist. Only the addon knows:
60297
- * `stream-broker` knows webrtc/ICE/RTP, `provider-reolink` knows
60298
- * baichuan/handshake. A hand-wired central list rots at the first addition,
60299
- * and rots silently. So a channel is declared where it is consulted, and the
60300
- * `log-channels` capability enumerates the declarations.
60301
- * - **VALUE** — at which level, for which scope, until when. That stays ONE
60302
- * thing: the logging settings document on the `system` cap. Two authorities
60303
- * over the values is the exact defect
60304
- * `docs/design/plans/2026-08-26-logging-per-componente.md` was written to
60305
- * remove; re-introducing it from the cure side would be grotesque.
60306
- *
60307
- * Nothing in this file reads a clock, an env var or a store. The registry is
60308
- * a MIRROR: it is moved only by {@link LogChannelRegistry.apply}, called off
60309
- * the hot path with a value somebody actually read, and by
60310
- * {@link LogChannelRegistry.tick}, called on a timer. A store read that fails
60311
- * never reaches here, so it can neither disarm an armed channel nor arm a
60312
- * disarmed one (D49).
60313
- *
60314
- * ## The canonical call shape
60315
- *
60316
- * ```ts
60317
- * if (CH_RTP.on && CH_RTP.wants(deviceId)) {
60318
- * CH_RTP.log(logger, 'rtp subscriber added', { tags: { deviceId }, meta: { ssrc } })
60319
- * }
60320
- * ```
60321
- *
60322
- * `on` is a plain boolean FIELD — never a getter — and it is the FIRST thing
60323
- * read. Disarmed, a call site costs one load and one branch, and the `extras`
60324
- * object literal is never constructed because it lives inside the branch. It
60325
- * is the same shape already proven in production at `stream-broker.ts:1650`,
60326
- * and the same discipline `LoggingGate.allowsDestination` uses for the
60327
- * destination floor (measured at 1.93 ns/call when off).
60328
- *
60329
- * ## Why a channel emits at `info`
60330
- *
60331
- * `loki-logging.addon.ts` pins the destination default at `info` and
60332
- * `loki-destination.ts` drops everything below it, so a line emitted at
60333
- * `debug` never reaches Loki and the hub's in-memory ring only holds ~35
60334
- * minutes. A diagnostic that cannot be read an hour later is worse than no
60335
- * diagnostic, because it looks done. {@link LogChannelGate.log} therefore
60336
- * emits at the channel's declared level, whose schema floor is `info`.
60337
- */
60338
- /**
60339
- * The level a channel writes at once armed.
60340
- *
60341
- * `debug` is absent ON PURPOSE and not by omission: below `info` the line does
60342
- * not leave the process for Loki, and the whole point of arming a channel is
60343
- * to read it later.
60344
- */
60345
- var LogChannelLevelSchema = _enum([
60346
- "info",
60347
- "warn",
60348
- "error"
60349
- ]);
60350
- /**
60351
- * What an addon declares about one channel. No value, no state — a
60352
- * declaration is inert.
60353
- */
60354
- var LogChannelDescriptorSchema = object({
60355
- /**
60356
- * Dotted `area.thing`, unique across the workspace. `area` is conventionally
60357
- * the addon's short name so an operator reading a channel list can tell who
60358
- * owns it without a second lookup.
60359
- */
60360
- name: string().min(3).regex(/^[a-z0-9-]+(\.[a-z0-9-]+)+$/, "a channel name is dotted lower-kebab, e.g. area.thing"),
60361
- /** One sentence: what the operator will SEE after arming it. */
60362
- description: string().min(1),
60363
- /** The level its lines are emitted at. Never below `info`. */
60364
- defaultLevel: LogChannelLevelSchema,
60365
- /**
60366
- * Whether this channel can be narrowed to a camera.
60367
- *
60368
- * `true` is a PROMISE with two halves, and both must hold: the gate is
60369
- * consulted with the numeric device id, AND every line the channel admits
60370
- * carries `tags: { deviceId }` with that same numeric id. The second half is
60371
- * what makes `| json | deviceId="617"` work in Loki — `loki-payload.ts`
60372
- * keeps `deviceId` out of the stream labels for cardinality, so the tag in
60373
- * the body is the only way to filter.
60374
- *
60375
- * A channel whose lines carry the device only in `meta` (or not at all) is
60376
- * declared `false`. Declaring it `true` anyway would be a lie the UI repeats:
60377
- * the operator narrows to one camera, sees nothing, and concludes the code
60378
- * path was never taken.
60379
- */
60380
- perDevice: boolean()
60381
- });
60382
- /**
60383
- * An armed window over one channel, as the document hands it to a mirror.
60384
- *
60385
- * A window is a DEADLINE, never a flag (ADR-0244): a channel somebody forgot
60386
- * expires by itself, which is the one failure a boolean cannot avoid.
60387
- */
60388
- var LogChannelWindowSchema = object({
60389
- channel: string().min(1),
60390
- /** Epoch ms the window closes at. */
60391
- armedUntilMs: number(),
60392
- /** `null` = every camera. A non-empty list narrows to those numeric ids. */
60393
- deviceIds: array(number().int()).readonly().nullable()
60394
- });
60395
- /**
60396
60291
  * Ops-log — the durable, append-only operations audit shared by the
60397
60292
  * recordings and events management surfaces.
60398
60293
  *
@@ -61338,8 +61233,11 @@ var StorageLocationTypeSchema = string().regex(/^[a-z][a-zA-Z0-9-]*$/);
61338
61233
  * `STORAGE_LOCATION_CARDINALITY` map has been removed.
61339
61234
  *
61340
61235
  * `id` is a stable namespaced string of the form `<type>:<slug>`.
61341
- * The default location for a type uses `id === <type>:default` by
61342
- * convention (the bare type ref like `'backups'` resolves to it).
61236
+ * The seed names its first instance `<type>:default` — a NAME, not a flag.
61237
+ * There is no default location any more (D383): `enabled` is the whole write
61238
+ * model, and a bare type ref resolves to the sole location of the type, or —
61239
+ * transitionally, only while legacy NULL-stamped rows exist — to the row whose
61240
+ * slug is `default`.
61343
61241
  *
61344
61242
  * `isSystem` is a legacy persisted flag. Seed still creates the initial
61345
61243
  * `<type>:default` locations; the flag is no longer a lock, a badge, or a
@@ -61360,21 +61258,20 @@ var StorageLocationSchema = object({
61360
61258
  * flag at upsert time, not here (the schema is provider-agnostic).
61361
61259
  */
61362
61260
  nodeId: string().optional(),
61363
- isDefault: boolean().default(false),
61364
61261
  isSystem: boolean().default(false),
61365
61262
  /**
61366
- * Operator opt-in: whether consumers that BALANCE across several locations
61367
- * of a type may write here. Recordings reads it today; event media and
61368
- * backups are the next consumers, which is why the flag lives on the
61369
- * location rather than in any one addon's store — nothing has to be
61370
- * extended to add the next consumer.
61263
+ * THE write switch, and the only one (D383). `enabled: true` means every
61264
+ * consumer that chooses a write target for this type may write here, and all
61265
+ * enabled locations of a type are used TOGETHER; `false` means read-only —
61266
+ * still read, still played back, still age-swept, still drained, never
61267
+ * written.
61371
61268
  *
61372
- * OPTIONAL, and ABSENT MEANS ACTIVE. Every location persisted before the
61373
- * flag existed reads back with no flag and keeps working exactly as before;
61374
- * that is the whole compat story, and it is why no migration ships with it.
61375
- * A newly CREATED sibling is stamped `false` by the orchestrator (creating a
61376
- * disk must not silently start writing to it); the default of a type is
61377
- * always stamped `true`.
61269
+ * OPTIONAL only for the wire: an upsert that omits it means "leave what is
61270
+ * stored" on an update and "born inert unless it is the first location of its
61271
+ * type" on a create. On a PERSISTED row absence is legacy and it means
61272
+ * enabled — {@link isLocationEnabled} is the one place that says so, and the
61273
+ * orchestrator stamps every flagless row `true` once at hydrate so absence
61274
+ * stops existing rather than being re-derived on every read.
61378
61275
  */
61379
61276
  enabled: boolean().optional(),
61380
61277
  /** COMPUTED at read time by the orchestrator (statfs of the backing volume
@@ -61387,10 +61284,12 @@ var StorageLocationSchema = object({
61387
61284
  createdAt: number(),
61388
61285
  updatedAt: number()
61389
61286
  });
61287
+ object({ isDefault: boolean().optional() });
61390
61288
  /**
61391
61289
  * Reference accepted by consumer-facing `api.storage.*` calls.
61392
61290
  * Either:
61393
- * - a `StorageLocationType` (e.g. `'backups'`) → orchestrator resolves to the default of that type
61291
+ * - a `StorageLocationType` (e.g. `'backups'`) → the sole location of that type
61292
+ * (transitionally, the `<type>:default`-slugged row when several exist)
61394
61293
  * - a fully-qualified id (e.g. `'backups:nas-01'`) → addresses a specific instance
61395
61294
  *
61396
61295
  * The orchestrator's `resolveRef(ref)` handles both cases.
@@ -61566,6 +61465,111 @@ var DecoderSessionConfigSchema = object({
61566
61465
  */
61567
61466
  debug: boolean().optional()
61568
61467
  });
61468
+ /**
61469
+ * Per-component log CHANNELS — the gate a hot path consults, and the registry
61470
+ * an addon declares its channels in.
61471
+ *
61472
+ * ## Two axes, deliberately separated
61473
+ *
61474
+ * - **DECLARATION** — which channels exist. Only the addon knows:
61475
+ * `stream-broker` knows webrtc/ICE/RTP, `provider-reolink` knows
61476
+ * baichuan/handshake. A hand-wired central list rots at the first addition,
61477
+ * and rots silently. So a channel is declared where it is consulted, and the
61478
+ * `log-channels` capability enumerates the declarations.
61479
+ * - **VALUE** — at which level, for which scope, until when. That stays ONE
61480
+ * thing: the logging settings document on the `system` cap. Two authorities
61481
+ * over the values is the exact defect
61482
+ * `docs/design/plans/2026-08-26-logging-per-componente.md` was written to
61483
+ * remove; re-introducing it from the cure side would be grotesque.
61484
+ *
61485
+ * Nothing in this file reads a clock, an env var or a store. The registry is
61486
+ * a MIRROR: it is moved only by {@link LogChannelRegistry.apply}, called off
61487
+ * the hot path with a value somebody actually read, and by
61488
+ * {@link LogChannelRegistry.tick}, called on a timer. A store read that fails
61489
+ * never reaches here, so it can neither disarm an armed channel nor arm a
61490
+ * disarmed one (D49).
61491
+ *
61492
+ * ## The canonical call shape
61493
+ *
61494
+ * ```ts
61495
+ * if (CH_RTP.on && CH_RTP.wants(deviceId)) {
61496
+ * CH_RTP.log(logger, 'rtp subscriber added', { tags: { deviceId }, meta: { ssrc } })
61497
+ * }
61498
+ * ```
61499
+ *
61500
+ * `on` is a plain boolean FIELD — never a getter — and it is the FIRST thing
61501
+ * read. Disarmed, a call site costs one load and one branch, and the `extras`
61502
+ * object literal is never constructed because it lives inside the branch. It
61503
+ * is the same shape already proven in production at `stream-broker.ts:1650`,
61504
+ * and the same discipline `LoggingGate.allowsDestination` uses for the
61505
+ * destination floor (measured at 1.93 ns/call when off).
61506
+ *
61507
+ * ## Why a channel emits at `info`
61508
+ *
61509
+ * `loki-logging.addon.ts` pins the destination default at `info` and
61510
+ * `loki-destination.ts` drops everything below it, so a line emitted at
61511
+ * `debug` never reaches Loki and the hub's in-memory ring only holds ~35
61512
+ * minutes. A diagnostic that cannot be read an hour later is worse than no
61513
+ * diagnostic, because it looks done. {@link LogChannelGate.log} therefore
61514
+ * emits at the channel's declared level, whose schema floor is `info`.
61515
+ */
61516
+ /**
61517
+ * The level a channel writes at once armed.
61518
+ *
61519
+ * `debug` is absent ON PURPOSE and not by omission: below `info` the line does
61520
+ * not leave the process for Loki, and the whole point of arming a channel is
61521
+ * to read it later.
61522
+ */
61523
+ var LogChannelLevelSchema = _enum([
61524
+ "info",
61525
+ "warn",
61526
+ "error"
61527
+ ]);
61528
+ /**
61529
+ * What an addon declares about one channel. No value, no state — a
61530
+ * declaration is inert.
61531
+ */
61532
+ var LogChannelDescriptorSchema = object({
61533
+ /**
61534
+ * Dotted `area.thing`, unique across the workspace. `area` is conventionally
61535
+ * the addon's short name so an operator reading a channel list can tell who
61536
+ * owns it without a second lookup.
61537
+ */
61538
+ name: string().min(3).regex(/^[a-z0-9-]+(\.[a-z0-9-]+)+$/, "a channel name is dotted lower-kebab, e.g. area.thing"),
61539
+ /** One sentence: what the operator will SEE after arming it. */
61540
+ description: string().min(1),
61541
+ /** The level its lines are emitted at. Never below `info`. */
61542
+ defaultLevel: LogChannelLevelSchema,
61543
+ /**
61544
+ * Whether this channel can be narrowed to a camera.
61545
+ *
61546
+ * `true` is a PROMISE with two halves, and both must hold: the gate is
61547
+ * consulted with the numeric device id, AND every line the channel admits
61548
+ * carries `tags: { deviceId }` with that same numeric id. The second half is
61549
+ * what makes `| json | deviceId="617"` work in Loki — `loki-payload.ts`
61550
+ * keeps `deviceId` out of the stream labels for cardinality, so the tag in
61551
+ * the body is the only way to filter.
61552
+ *
61553
+ * A channel whose lines carry the device only in `meta` (or not at all) is
61554
+ * declared `false`. Declaring it `true` anyway would be a lie the UI repeats:
61555
+ * the operator narrows to one camera, sees nothing, and concludes the code
61556
+ * path was never taken.
61557
+ */
61558
+ perDevice: boolean()
61559
+ });
61560
+ /**
61561
+ * An armed window over one channel, as the document hands it to a mirror.
61562
+ *
61563
+ * A window is a DEADLINE, never a flag (ADR-0244): a channel somebody forgot
61564
+ * expires by itself, which is the one failure a boolean cannot avoid.
61565
+ */
61566
+ var LogChannelWindowSchema = object({
61567
+ channel: string().min(1),
61568
+ /** Epoch ms the window closes at. */
61569
+ armedUntilMs: number(),
61570
+ /** `null` = every camera. A non-empty list narrows to those numeric ids. */
61571
+ deviceIds: array(number().int()).readonly().nullable()
61572
+ });
61569
61573
  var MODEL_FORMATS = [
61570
61574
  "onnx",
61571
61575
  "coreml",
@@ -74615,7 +74619,7 @@ method(object({
74615
74619
  downloadId: string(),
74616
74620
  offset: number(),
74617
74621
  length: number()
74618
- }), _instanceof(Uint8Array)), method(object({ downloadId: string() }), _void(), { kind: "mutation" }), method(object({ type: StorageLocationTypeSchema.optional() }), array(StorageLocationSchema).readonly()), method(object({ type: StorageLocationTypeSchema }), StorageLocationSchema.nullable()), method(_void(), array(StorageLocationDeclarationSchema).readonly()), method(StorageLocationSchema.omit({
74622
+ }), _instanceof(Uint8Array)), method(object({ downloadId: string() }), _void(), { kind: "mutation" }), method(object({ type: StorageLocationTypeSchema.optional() }), array(StorageLocationSchema).readonly()), method(_void(), array(StorageLocationDeclarationSchema).readonly()), method(StorageLocationSchema.omit({
74619
74623
  createdAt: true,
74620
74624
  updatedAt: true
74621
74625
  }), StorageLocationSchema, {
@@ -91633,12 +91637,6 @@ Object.freeze({
91633
91637
  addonId: null,
91634
91638
  access: "view"
91635
91639
  },
91636
- "storage.getDefaultLocation": {
91637
- capName: "storage",
91638
- capScope: "system",
91639
- addonId: null,
91640
- access: "view"
91641
- },
91642
91640
  "storage.list": {
91643
91641
  capName: "storage",
91644
91642
  capScope: "system",
package/dist/addon.mjs CHANGED
@@ -60285,111 +60285,6 @@ var CameraSwitchGroupSchema = object({
60285
60285
  fetchedAt: number()
60286
60286
  });
60287
60287
  /**
60288
- * Per-component log CHANNELS — the gate a hot path consults, and the registry
60289
- * an addon declares its channels in.
60290
- *
60291
- * ## Two axes, deliberately separated
60292
- *
60293
- * - **DECLARATION** — which channels exist. Only the addon knows:
60294
- * `stream-broker` knows webrtc/ICE/RTP, `provider-reolink` knows
60295
- * baichuan/handshake. A hand-wired central list rots at the first addition,
60296
- * and rots silently. So a channel is declared where it is consulted, and the
60297
- * `log-channels` capability enumerates the declarations.
60298
- * - **VALUE** — at which level, for which scope, until when. That stays ONE
60299
- * thing: the logging settings document on the `system` cap. Two authorities
60300
- * over the values is the exact defect
60301
- * `docs/design/plans/2026-08-26-logging-per-componente.md` was written to
60302
- * remove; re-introducing it from the cure side would be grotesque.
60303
- *
60304
- * Nothing in this file reads a clock, an env var or a store. The registry is
60305
- * a MIRROR: it is moved only by {@link LogChannelRegistry.apply}, called off
60306
- * the hot path with a value somebody actually read, and by
60307
- * {@link LogChannelRegistry.tick}, called on a timer. A store read that fails
60308
- * never reaches here, so it can neither disarm an armed channel nor arm a
60309
- * disarmed one (D49).
60310
- *
60311
- * ## The canonical call shape
60312
- *
60313
- * ```ts
60314
- * if (CH_RTP.on && CH_RTP.wants(deviceId)) {
60315
- * CH_RTP.log(logger, 'rtp subscriber added', { tags: { deviceId }, meta: { ssrc } })
60316
- * }
60317
- * ```
60318
- *
60319
- * `on` is a plain boolean FIELD — never a getter — and it is the FIRST thing
60320
- * read. Disarmed, a call site costs one load and one branch, and the `extras`
60321
- * object literal is never constructed because it lives inside the branch. It
60322
- * is the same shape already proven in production at `stream-broker.ts:1650`,
60323
- * and the same discipline `LoggingGate.allowsDestination` uses for the
60324
- * destination floor (measured at 1.93 ns/call when off).
60325
- *
60326
- * ## Why a channel emits at `info`
60327
- *
60328
- * `loki-logging.addon.ts` pins the destination default at `info` and
60329
- * `loki-destination.ts` drops everything below it, so a line emitted at
60330
- * `debug` never reaches Loki and the hub's in-memory ring only holds ~35
60331
- * minutes. A diagnostic that cannot be read an hour later is worse than no
60332
- * diagnostic, because it looks done. {@link LogChannelGate.log} therefore
60333
- * emits at the channel's declared level, whose schema floor is `info`.
60334
- */
60335
- /**
60336
- * The level a channel writes at once armed.
60337
- *
60338
- * `debug` is absent ON PURPOSE and not by omission: below `info` the line does
60339
- * not leave the process for Loki, and the whole point of arming a channel is
60340
- * to read it later.
60341
- */
60342
- var LogChannelLevelSchema = _enum([
60343
- "info",
60344
- "warn",
60345
- "error"
60346
- ]);
60347
- /**
60348
- * What an addon declares about one channel. No value, no state — a
60349
- * declaration is inert.
60350
- */
60351
- var LogChannelDescriptorSchema = object({
60352
- /**
60353
- * Dotted `area.thing`, unique across the workspace. `area` is conventionally
60354
- * the addon's short name so an operator reading a channel list can tell who
60355
- * owns it without a second lookup.
60356
- */
60357
- name: string().min(3).regex(/^[a-z0-9-]+(\.[a-z0-9-]+)+$/, "a channel name is dotted lower-kebab, e.g. area.thing"),
60358
- /** One sentence: what the operator will SEE after arming it. */
60359
- description: string().min(1),
60360
- /** The level its lines are emitted at. Never below `info`. */
60361
- defaultLevel: LogChannelLevelSchema,
60362
- /**
60363
- * Whether this channel can be narrowed to a camera.
60364
- *
60365
- * `true` is a PROMISE with two halves, and both must hold: the gate is
60366
- * consulted with the numeric device id, AND every line the channel admits
60367
- * carries `tags: { deviceId }` with that same numeric id. The second half is
60368
- * what makes `| json | deviceId="617"` work in Loki — `loki-payload.ts`
60369
- * keeps `deviceId` out of the stream labels for cardinality, so the tag in
60370
- * the body is the only way to filter.
60371
- *
60372
- * A channel whose lines carry the device only in `meta` (or not at all) is
60373
- * declared `false`. Declaring it `true` anyway would be a lie the UI repeats:
60374
- * the operator narrows to one camera, sees nothing, and concludes the code
60375
- * path was never taken.
60376
- */
60377
- perDevice: boolean()
60378
- });
60379
- /**
60380
- * An armed window over one channel, as the document hands it to a mirror.
60381
- *
60382
- * A window is a DEADLINE, never a flag (ADR-0244): a channel somebody forgot
60383
- * expires by itself, which is the one failure a boolean cannot avoid.
60384
- */
60385
- var LogChannelWindowSchema = object({
60386
- channel: string().min(1),
60387
- /** Epoch ms the window closes at. */
60388
- armedUntilMs: number(),
60389
- /** `null` = every camera. A non-empty list narrows to those numeric ids. */
60390
- deviceIds: array(number().int()).readonly().nullable()
60391
- });
60392
- /**
60393
60288
  * Ops-log — the durable, append-only operations audit shared by the
60394
60289
  * recordings and events management surfaces.
60395
60290
  *
@@ -61335,8 +61230,11 @@ var StorageLocationTypeSchema = string().regex(/^[a-z][a-zA-Z0-9-]*$/);
61335
61230
  * `STORAGE_LOCATION_CARDINALITY` map has been removed.
61336
61231
  *
61337
61232
  * `id` is a stable namespaced string of the form `<type>:<slug>`.
61338
- * The default location for a type uses `id === <type>:default` by
61339
- * convention (the bare type ref like `'backups'` resolves to it).
61233
+ * The seed names its first instance `<type>:default` — a NAME, not a flag.
61234
+ * There is no default location any more (D383): `enabled` is the whole write
61235
+ * model, and a bare type ref resolves to the sole location of the type, or —
61236
+ * transitionally, only while legacy NULL-stamped rows exist — to the row whose
61237
+ * slug is `default`.
61340
61238
  *
61341
61239
  * `isSystem` is a legacy persisted flag. Seed still creates the initial
61342
61240
  * `<type>:default` locations; the flag is no longer a lock, a badge, or a
@@ -61357,21 +61255,20 @@ var StorageLocationSchema = object({
61357
61255
  * flag at upsert time, not here (the schema is provider-agnostic).
61358
61256
  */
61359
61257
  nodeId: string().optional(),
61360
- isDefault: boolean().default(false),
61361
61258
  isSystem: boolean().default(false),
61362
61259
  /**
61363
- * Operator opt-in: whether consumers that BALANCE across several locations
61364
- * of a type may write here. Recordings reads it today; event media and
61365
- * backups are the next consumers, which is why the flag lives on the
61366
- * location rather than in any one addon's store — nothing has to be
61367
- * extended to add the next consumer.
61260
+ * THE write switch, and the only one (D383). `enabled: true` means every
61261
+ * consumer that chooses a write target for this type may write here, and all
61262
+ * enabled locations of a type are used TOGETHER; `false` means read-only —
61263
+ * still read, still played back, still age-swept, still drained, never
61264
+ * written.
61368
61265
  *
61369
- * OPTIONAL, and ABSENT MEANS ACTIVE. Every location persisted before the
61370
- * flag existed reads back with no flag and keeps working exactly as before;
61371
- * that is the whole compat story, and it is why no migration ships with it.
61372
- * A newly CREATED sibling is stamped `false` by the orchestrator (creating a
61373
- * disk must not silently start writing to it); the default of a type is
61374
- * always stamped `true`.
61266
+ * OPTIONAL only for the wire: an upsert that omits it means "leave what is
61267
+ * stored" on an update and "born inert unless it is the first location of its
61268
+ * type" on a create. On a PERSISTED row absence is legacy and it means
61269
+ * enabled — {@link isLocationEnabled} is the one place that says so, and the
61270
+ * orchestrator stamps every flagless row `true` once at hydrate so absence
61271
+ * stops existing rather than being re-derived on every read.
61375
61272
  */
61376
61273
  enabled: boolean().optional(),
61377
61274
  /** COMPUTED at read time by the orchestrator (statfs of the backing volume
@@ -61384,10 +61281,12 @@ var StorageLocationSchema = object({
61384
61281
  createdAt: number(),
61385
61282
  updatedAt: number()
61386
61283
  });
61284
+ object({ isDefault: boolean().optional() });
61387
61285
  /**
61388
61286
  * Reference accepted by consumer-facing `api.storage.*` calls.
61389
61287
  * Either:
61390
- * - a `StorageLocationType` (e.g. `'backups'`) → orchestrator resolves to the default of that type
61288
+ * - a `StorageLocationType` (e.g. `'backups'`) → the sole location of that type
61289
+ * (transitionally, the `<type>:default`-slugged row when several exist)
61391
61290
  * - a fully-qualified id (e.g. `'backups:nas-01'`) → addresses a specific instance
61392
61291
  *
61393
61292
  * The orchestrator's `resolveRef(ref)` handles both cases.
@@ -61563,6 +61462,111 @@ var DecoderSessionConfigSchema = object({
61563
61462
  */
61564
61463
  debug: boolean().optional()
61565
61464
  });
61465
+ /**
61466
+ * Per-component log CHANNELS — the gate a hot path consults, and the registry
61467
+ * an addon declares its channels in.
61468
+ *
61469
+ * ## Two axes, deliberately separated
61470
+ *
61471
+ * - **DECLARATION** — which channels exist. Only the addon knows:
61472
+ * `stream-broker` knows webrtc/ICE/RTP, `provider-reolink` knows
61473
+ * baichuan/handshake. A hand-wired central list rots at the first addition,
61474
+ * and rots silently. So a channel is declared where it is consulted, and the
61475
+ * `log-channels` capability enumerates the declarations.
61476
+ * - **VALUE** — at which level, for which scope, until when. That stays ONE
61477
+ * thing: the logging settings document on the `system` cap. Two authorities
61478
+ * over the values is the exact defect
61479
+ * `docs/design/plans/2026-08-26-logging-per-componente.md` was written to
61480
+ * remove; re-introducing it from the cure side would be grotesque.
61481
+ *
61482
+ * Nothing in this file reads a clock, an env var or a store. The registry is
61483
+ * a MIRROR: it is moved only by {@link LogChannelRegistry.apply}, called off
61484
+ * the hot path with a value somebody actually read, and by
61485
+ * {@link LogChannelRegistry.tick}, called on a timer. A store read that fails
61486
+ * never reaches here, so it can neither disarm an armed channel nor arm a
61487
+ * disarmed one (D49).
61488
+ *
61489
+ * ## The canonical call shape
61490
+ *
61491
+ * ```ts
61492
+ * if (CH_RTP.on && CH_RTP.wants(deviceId)) {
61493
+ * CH_RTP.log(logger, 'rtp subscriber added', { tags: { deviceId }, meta: { ssrc } })
61494
+ * }
61495
+ * ```
61496
+ *
61497
+ * `on` is a plain boolean FIELD — never a getter — and it is the FIRST thing
61498
+ * read. Disarmed, a call site costs one load and one branch, and the `extras`
61499
+ * object literal is never constructed because it lives inside the branch. It
61500
+ * is the same shape already proven in production at `stream-broker.ts:1650`,
61501
+ * and the same discipline `LoggingGate.allowsDestination` uses for the
61502
+ * destination floor (measured at 1.93 ns/call when off).
61503
+ *
61504
+ * ## Why a channel emits at `info`
61505
+ *
61506
+ * `loki-logging.addon.ts` pins the destination default at `info` and
61507
+ * `loki-destination.ts` drops everything below it, so a line emitted at
61508
+ * `debug` never reaches Loki and the hub's in-memory ring only holds ~35
61509
+ * minutes. A diagnostic that cannot be read an hour later is worse than no
61510
+ * diagnostic, because it looks done. {@link LogChannelGate.log} therefore
61511
+ * emits at the channel's declared level, whose schema floor is `info`.
61512
+ */
61513
+ /**
61514
+ * The level a channel writes at once armed.
61515
+ *
61516
+ * `debug` is absent ON PURPOSE and not by omission: below `info` the line does
61517
+ * not leave the process for Loki, and the whole point of arming a channel is
61518
+ * to read it later.
61519
+ */
61520
+ var LogChannelLevelSchema = _enum([
61521
+ "info",
61522
+ "warn",
61523
+ "error"
61524
+ ]);
61525
+ /**
61526
+ * What an addon declares about one channel. No value, no state — a
61527
+ * declaration is inert.
61528
+ */
61529
+ var LogChannelDescriptorSchema = object({
61530
+ /**
61531
+ * Dotted `area.thing`, unique across the workspace. `area` is conventionally
61532
+ * the addon's short name so an operator reading a channel list can tell who
61533
+ * owns it without a second lookup.
61534
+ */
61535
+ name: string().min(3).regex(/^[a-z0-9-]+(\.[a-z0-9-]+)+$/, "a channel name is dotted lower-kebab, e.g. area.thing"),
61536
+ /** One sentence: what the operator will SEE after arming it. */
61537
+ description: string().min(1),
61538
+ /** The level its lines are emitted at. Never below `info`. */
61539
+ defaultLevel: LogChannelLevelSchema,
61540
+ /**
61541
+ * Whether this channel can be narrowed to a camera.
61542
+ *
61543
+ * `true` is a PROMISE with two halves, and both must hold: the gate is
61544
+ * consulted with the numeric device id, AND every line the channel admits
61545
+ * carries `tags: { deviceId }` with that same numeric id. The second half is
61546
+ * what makes `| json | deviceId="617"` work in Loki — `loki-payload.ts`
61547
+ * keeps `deviceId` out of the stream labels for cardinality, so the tag in
61548
+ * the body is the only way to filter.
61549
+ *
61550
+ * A channel whose lines carry the device only in `meta` (or not at all) is
61551
+ * declared `false`. Declaring it `true` anyway would be a lie the UI repeats:
61552
+ * the operator narrows to one camera, sees nothing, and concludes the code
61553
+ * path was never taken.
61554
+ */
61555
+ perDevice: boolean()
61556
+ });
61557
+ /**
61558
+ * An armed window over one channel, as the document hands it to a mirror.
61559
+ *
61560
+ * A window is a DEADLINE, never a flag (ADR-0244): a channel somebody forgot
61561
+ * expires by itself, which is the one failure a boolean cannot avoid.
61562
+ */
61563
+ var LogChannelWindowSchema = object({
61564
+ channel: string().min(1),
61565
+ /** Epoch ms the window closes at. */
61566
+ armedUntilMs: number(),
61567
+ /** `null` = every camera. A non-empty list narrows to those numeric ids. */
61568
+ deviceIds: array(number().int()).readonly().nullable()
61569
+ });
61566
61570
  var MODEL_FORMATS = [
61567
61571
  "onnx",
61568
61572
  "coreml",
@@ -74612,7 +74616,7 @@ method(object({
74612
74616
  downloadId: string(),
74613
74617
  offset: number(),
74614
74618
  length: number()
74615
- }), _instanceof(Uint8Array)), method(object({ downloadId: string() }), _void(), { kind: "mutation" }), method(object({ type: StorageLocationTypeSchema.optional() }), array(StorageLocationSchema).readonly()), method(object({ type: StorageLocationTypeSchema }), StorageLocationSchema.nullable()), method(_void(), array(StorageLocationDeclarationSchema).readonly()), method(StorageLocationSchema.omit({
74619
+ }), _instanceof(Uint8Array)), method(object({ downloadId: string() }), _void(), { kind: "mutation" }), method(object({ type: StorageLocationTypeSchema.optional() }), array(StorageLocationSchema).readonly()), method(_void(), array(StorageLocationDeclarationSchema).readonly()), method(StorageLocationSchema.omit({
74616
74620
  createdAt: true,
74617
74621
  updatedAt: true
74618
74622
  }), StorageLocationSchema, {
@@ -91630,12 +91634,6 @@ Object.freeze({
91630
91634
  addonId: null,
91631
91635
  access: "view"
91632
91636
  },
91633
- "storage.getDefaultLocation": {
91634
- capName: "storage",
91635
- capScope: "system",
91636
- addonId: null,
91637
- access: "view"
91638
- },
91639
91637
  "storage.list": {
91640
91638
  capName: "storage",
91641
91639
  capScope: "system",
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@camstack/addon-provider-dreame",
3
- "version": "0.2.78",
3
+ "version": "0.2.79",
4
4
  "description": "Dreame robot-vacuum / lawn-mower device-provider addon for CamStack — wraps the @apocaliss92/nodedreame Dreamehome cloud client",
5
5
  "keywords": [
6
6
  "camstack",