@camstack/system 1.2.430 → 1.2.432

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 (79) hide show
  1. package/dist/builtins/addon-pages-aggregator/addon-pages-aggregator.addon.js +1 -1
  2. package/dist/builtins/addon-pages-aggregator/addon-pages-aggregator.addon.mjs +1 -1
  3. package/dist/builtins/addon-widgets-aggregator/addon-widgets-aggregator.addon.js +1 -1
  4. package/dist/builtins/addon-widgets-aggregator/addon-widgets-aggregator.addon.mjs +1 -1
  5. package/dist/builtins/alerts/alerts.addon.js +1 -1
  6. package/dist/builtins/alerts/alerts.addon.mjs +1 -1
  7. package/dist/builtins/autotrack/index.js +1 -1
  8. package/dist/builtins/autotrack/index.mjs +1 -1
  9. package/dist/builtins/backup-orchestrator/backup-orchestrator.addon.js +2 -2
  10. package/dist/builtins/backup-orchestrator/backup-orchestrator.addon.mjs +2 -2
  11. package/dist/builtins/calendars/calendars.addon.js +1 -1
  12. package/dist/builtins/calendars/calendars.addon.mjs +1 -1
  13. package/dist/builtins/camera-grid/index.js +1 -1
  14. package/dist/builtins/camera-grid/index.mjs +1 -1
  15. package/dist/builtins/composer/composer.addon.js +2 -2
  16. package/dist/builtins/composer/composer.addon.mjs +2 -2
  17. package/dist/builtins/console-logging/index.js +1 -1
  18. package/dist/builtins/console-logging/index.mjs +1 -1
  19. package/dist/builtins/core-blocks/core-blocks.addon.js +2 -2
  20. package/dist/builtins/core-blocks/core-blocks.addon.mjs +2 -2
  21. package/dist/builtins/device-manager/device-manager.addon.js +2 -2
  22. package/dist/builtins/device-manager/device-manager.addon.mjs +2 -2
  23. package/dist/builtins/hub-forwarder/index.js +1 -1
  24. package/dist/builtins/hub-forwarder/index.mjs +1 -1
  25. package/dist/builtins/keychain/index.js +3 -3
  26. package/dist/builtins/keychain/index.mjs +3 -3
  27. package/dist/builtins/liveness-monitor/liveness-monitor.addon.js +1 -1
  28. package/dist/builtins/liveness-monitor/liveness-monitor.addon.mjs +1 -1
  29. package/dist/builtins/local-auth/local-auth.addon.js +2 -2
  30. package/dist/builtins/local-auth/local-auth.addon.mjs +2 -2
  31. package/dist/builtins/local-network/local-network.addon.js +1 -1
  32. package/dist/builtins/local-network/local-network.addon.mjs +1 -1
  33. package/dist/builtins/loki-logging/index.js +1 -1
  34. package/dist/builtins/loki-logging/index.mjs +1 -1
  35. package/dist/builtins/native-metrics/native-metrics.addon.js +1 -1
  36. package/dist/builtins/native-metrics/native-metrics.addon.mjs +1 -1
  37. package/dist/builtins/platform-probe/index.js +1 -1
  38. package/dist/builtins/platform-probe/index.mjs +1 -1
  39. package/dist/builtins/remote-access-orchestrator/remote-access-orchestrator.addon.js +1 -1
  40. package/dist/builtins/remote-access-orchestrator/remote-access-orchestrator.addon.mjs +1 -1
  41. package/dist/builtins/snapshot/index.js +1 -1
  42. package/dist/builtins/snapshot/index.mjs +1 -1
  43. package/dist/builtins/sqlite-storage/filesystem-storage.addon.js +1 -1
  44. package/dist/builtins/sqlite-storage/filesystem-storage.addon.mjs +1 -1
  45. package/dist/builtins/sqlite-storage/index.js +1 -1
  46. package/dist/builtins/sqlite-storage/index.mjs +1 -1
  47. package/dist/builtins/sqlite-storage/sqlite-settings.addon.js +3 -3
  48. package/dist/builtins/sqlite-storage/sqlite-settings.addon.mjs +3 -3
  49. package/dist/builtins/storage-orchestrator/storage-orchestrator.addon.js +1 -1
  50. package/dist/builtins/storage-orchestrator/storage-orchestrator.addon.mjs +1 -1
  51. package/dist/builtins/system-config/system-config.addon.js +74 -10
  52. package/dist/builtins/system-config/system-config.addon.mjs +74 -11
  53. package/dist/builtins/winston-logging/index.js +1 -1
  54. package/dist/builtins/winston-logging/index.mjs +1 -1
  55. package/dist/{composition-sources-o5MPSlk6.js → composition-sources-CFlUdpO7.js} +1 -1
  56. package/dist/{composition-sources-Cw_TXEq9.mjs → composition-sources-DpbL38z3.mjs} +1 -1
  57. package/dist/{constants-CttE77VF.mjs → constants-B89vjrSm.mjs} +1 -1
  58. package/dist/{constants-BcNaVkvI.js → constants-DfP8V3eX.js} +1 -1
  59. package/dist/{device-ca-B-BTxeCj.mjs → device-ca-4IY98a_-.mjs} +1 -1
  60. package/dist/{device-ca-CKiqh2Iu.js → device-ca-BCyAPmIj.js} +1 -1
  61. package/dist/{dist-DxJdci75.js → dist-BCKOeWu_.js} +317 -1
  62. package/dist/{dist-CXG6muCR.mjs → dist-Bt8GTRHB.mjs} +317 -1
  63. package/dist/file-host-worker.js +1 -1
  64. package/dist/file-host-worker.mjs +1 -1
  65. package/dist/index.js +203 -53
  66. package/dist/index.mjs +198 -55
  67. package/dist/kernel/index.d.ts +4 -2
  68. package/dist/kernel/moleculer/broker-factory.d.ts +28 -2
  69. package/dist/kernel/moleculer/broker-transport-swap.d.ts +43 -0
  70. package/dist/kernel/moleculer/mesh-mtls/mesh-certificate-registry.d.ts +10 -0
  71. package/dist/kernel/moleculer/mesh-mtls/mesh-peer-transport.d.ts +7 -3
  72. package/dist/kernel/moleculer/mesh-mtls/mesh-renewal.d.ts +8 -1
  73. package/dist/{restore-archive-D_wBL1OO.mjs → restore-archive-Bh34W8J8.mjs} +1 -1
  74. package/dist/{restore-archive-CQJNoqRK.js → restore-archive-DhHH7VQp.js} +1 -1
  75. package/dist/{retired-settings-keys-EmDe11cP.mjs → retired-settings-keys-CmcEitC2.mjs} +1 -1
  76. package/dist/{retired-settings-keys-g1oifXxR.js → retired-settings-keys-u3Wwkdrq.js} +1 -1
  77. package/dist/{wal-maintenance-BW1LIHi0.js → wal-maintenance-ChzCPUi2.js} +0 -0
  78. package/dist/{wal-maintenance-vhPZLYuA.mjs → wal-maintenance-uQGuStFW.mjs} +0 -0
  79. package/package.json +2 -2
@@ -718,7 +718,7 @@ var EventCategory = /* @__PURE__ */ function(EventCategory) {
718
718
  return EventCategory;
719
719
  }({});
720
720
  //#endregion
721
- //#region ../types/dist/sleep-DxJdzHni.mjs
721
+ //#region ../types/dist/sleep--g-h2_c_.mjs
722
722
  /**
723
723
  * The audio chunk plane's byte format, and the ONE expansion from a coded
724
724
  * window to float samples (D455).
@@ -16213,6 +16213,241 @@ var keychainCapability = {
16213
16213
  getState: method(zod.z.object({}), KeychainStateSchema, { auth: "admin" })
16214
16214
  }
16215
16215
  };
16216
+ /**
16217
+ * device-history — the ONE mechanism for numeric history (D850).
16218
+ *
16219
+ * A device value is recorded because its capability says so (the `history`
16220
+ * block of a `*.cap.ts`, captured hub-side from `DeviceStateChanged`); any
16221
+ * other series is DECLARED by the addon that produces it and fed with points
16222
+ * (`record`) or closed five-minute buckets (`recordBuckets`). Rollups 5m / 1h /
16223
+ * 1d are computed here and nowhere else. Storage is `history.db` (D851).
16224
+ *
16225
+ * Who the PRODUCER is: `declareSeries`, `record` and `recordBuckets` are owner
16226
+ * checked against the `callerAddonId` the transport stamps into a call that
16227
+ * crossed a process (never in an input schema, so a session cannot supply it).
16228
+ * A call with no stamp is refused `not-owner`. The methods are `admin` so a
16229
+ * non-admin session never reaches them; an addon's `ctx.api` call bypasses the
16230
+ * tier by design.
16231
+ */
16232
+ /** Whose history: a real device, or a cluster node (load, memory). */
16233
+ var DeviceHistorySubjectSchema = zod.z.discriminatedUnion("kind", [zod.z.object({
16234
+ kind: zod.z.literal("device"),
16235
+ deviceId: zod.z.number().int()
16236
+ }), zod.z.object({
16237
+ kind: zod.z.literal("node"),
16238
+ nodeId: zod.z.string().min(1)
16239
+ })]);
16240
+ var DeviceHistoryKindSchema = zod.z.enum([
16241
+ "gauge",
16242
+ "counter",
16243
+ "boolean"
16244
+ ]);
16245
+ var DeviceHistoryResolutionSchema = zod.z.enum([
16246
+ "raw",
16247
+ "5m",
16248
+ "1h",
16249
+ "1d"
16250
+ ]);
16251
+ /** Why a producer's point or bucket was not stored. Counted, never silent (D391). */
16252
+ var DeviceHistoryRefusalReasonSchema = zod.z.enum([
16253
+ "undeclared",
16254
+ "not-owner",
16255
+ "opted-out",
16256
+ "not-a-real-device",
16257
+ "rate",
16258
+ "ingest-mismatch",
16259
+ "out-of-range"
16260
+ ]);
16261
+ var RefusalSchema = zod.z.object({
16262
+ key: zod.z.string(),
16263
+ reason: DeviceHistoryRefusalReasonSchema,
16264
+ count: zod.z.number().int()
16265
+ });
16266
+ var IngestResultSchema = zod.z.object({
16267
+ accepted: zod.z.number().int(),
16268
+ refused: zod.z.array(RefusalSchema).readonly()
16269
+ });
16270
+ var SeriesInfoSchema = zod.z.object({
16271
+ key: zod.z.string(),
16272
+ scope: zod.z.string(),
16273
+ kind: DeviceHistoryKindSchema,
16274
+ /** `null` is unknown (a `unitFrom` series whose device does not state a unit right now), never a guess. */
16275
+ unit: zod.z.string().nullable(),
16276
+ displayName: zod.z.string(),
16277
+ source: zod.z.enum(["cap", "addon"]),
16278
+ firstTs: zod.z.number(),
16279
+ lastTs: zod.z.number()
16280
+ });
16281
+ var QueryPointSchema = zod.z.object({
16282
+ /** Raw: the point's time. Rollup: the bucket start. */
16283
+ t: zod.z.number(),
16284
+ samples: zod.z.number().int(),
16285
+ /** `sum / samples`. */
16286
+ mean: zod.z.number().nullable(),
16287
+ /** Time-weighted mean (`tw_sum / tw_ms`); `null` for bucket-ingested series. For a boolean: the fraction of time true. */
16288
+ twMean: zod.z.number().nullable(),
16289
+ min: zod.z.number(),
16290
+ max: zod.z.number(),
16291
+ /** `null` is unknown, never zero (D393). */
16292
+ last: zod.z.number().nullable()
16293
+ });
16294
+ var QuerySeriesSchema = zod.z.object({
16295
+ scope: zod.z.string(),
16296
+ /** The last point STRICTLY BEFORE `from` in the chosen tier, so a step chart can start at the held value. */
16297
+ before: zod.z.object({
16298
+ t: zod.z.number(),
16299
+ value: zod.z.number().nullable()
16300
+ }).nullable(),
16301
+ points: zod.z.array(QueryPointSchema).readonly()
16302
+ });
16303
+ /** The window part of a query, shared by the device and node forms. */
16304
+ var QueryWindowShape = {
16305
+ key: zod.z.string(),
16306
+ scope: zod.z.string().optional(),
16307
+ from: zod.z.number(),
16308
+ to: zod.z.number(),
16309
+ resolution: zod.z.union([DeviceHistoryResolutionSchema, zod.z.literal("auto")]).default("auto"),
16310
+ maxPoints: zod.z.number().int().positive().max(5e3).default(1e3)
16311
+ };
16312
+ var QueryResultSchema = zod.z.object({
16313
+ resolution: DeviceHistoryResolutionSchema,
16314
+ series: zod.z.array(QuerySeriesSchema).readonly(),
16315
+ truncated: zod.z.boolean()
16316
+ });
16317
+ var TierStatusSchema = zod.z.object({
16318
+ tier: DeviceHistoryResolutionSchema,
16319
+ /** `null` until the first background count answered. */
16320
+ rows: zod.z.number().int().nullable(),
16321
+ /** `rows` times a fixed per-row estimate — approximate, labelled so. */
16322
+ approxBytes: zod.z.number().nullable(),
16323
+ countedAt: zod.z.number().nullable()
16324
+ });
16325
+ /** Operator/diagnostic view: rows per tier, last runs, refusals and drops since boot. */
16326
+ var DeviceHistoryStatusSchema = zod.z.object({
16327
+ startedAt: zod.z.number(),
16328
+ /** The store is declared, series loaded and the first reconcile has answered. */
16329
+ ready: zod.z.boolean(),
16330
+ series: zod.z.number().int(),
16331
+ metrics: zod.z.number().int(),
16332
+ optedOutDevices: zod.z.number().int(),
16333
+ tiers: zod.z.array(TierStatusSchema).readonly(),
16334
+ capture: zod.z.object({
16335
+ eventsSeen: zod.z.number().int(),
16336
+ pointsEmitted: zod.z.number().int(),
16337
+ pointsWritten: zod.z.number().int(),
16338
+ pointsDropped: zod.z.number().int(),
16339
+ bufferDepth: zod.z.number().int(),
16340
+ trailingEmitted: zod.z.number().int(),
16341
+ reconciledPoints: zod.z.number().int(),
16342
+ reconcileRuns: zod.z.number().int(),
16343
+ reconcileFailures: zod.z.number().int(),
16344
+ lastReconcileAt: zod.z.number().nullable(),
16345
+ lastFlushAt: zod.z.number().nullable(),
16346
+ flushFailures: zod.z.number().int(),
16347
+ skipped: zod.z.record(zod.z.string(), zod.z.number().int())
16348
+ }),
16349
+ ingest: zod.z.object({
16350
+ accepted: zod.z.number().int(),
16351
+ refused: zod.z.record(zod.z.string(), zod.z.number().int())
16352
+ }),
16353
+ rollup: zod.z.object({
16354
+ last5mAt: zod.z.number().nullable(),
16355
+ last1hAt: zod.z.number().nullable(),
16356
+ last1dAt: zod.z.number().nullable(),
16357
+ errors: zod.z.number().int(),
16358
+ dirty5m: zod.z.number().int(),
16359
+ dirty1h: zod.z.number().int(),
16360
+ dirty1d: zod.z.number().int()
16361
+ }),
16362
+ retention: zod.z.object({
16363
+ lastRunAt: zod.z.number().nullable(),
16364
+ deleted: zod.z.record(zod.z.string(), zod.z.number().int()),
16365
+ purgedSeries: zod.z.number().int()
16366
+ }),
16367
+ directory: zod.z.object({
16368
+ devices: zod.z.number().int(),
16369
+ lastRefreshAt: zod.z.number().nullable()
16370
+ })
16371
+ });
16372
+ var deviceHistoryCapability = {
16373
+ name: "device-history",
16374
+ scope: "system",
16375
+ mode: "singleton",
16376
+ methods: {
16377
+ /**
16378
+ * The series a DEVICE has, and their span. `deviceId` is a flat top-level field
16379
+ * on purpose: the generated device selector (and so the scope gate) only sees
16380
+ * top-level ids, and a nested `subject.deviceId` would let a principal limited
16381
+ * to one device read another's history. Node series are the admin-only
16382
+ * `listNodeSeries` / `queryNode`.
16383
+ */
16384
+ listSeries: method(zod.z.object({ deviceId: zod.z.number().int() }), zod.z.array(SeriesInfoSchema).readonly()),
16385
+ listNodeSeries: method(zod.z.object({ nodeId: zod.z.string().min(1) }), zod.z.array(SeriesInfoSchema).readonly(), { auth: "admin" }),
16386
+ /**
16387
+ * One series (or every scope of it) at one resolution. `auto` picks the
16388
+ * finest tier whose retention covers `from` and whose point count fits
16389
+ * `maxPoints`; when even the coarsest tier does not fit, the newest
16390
+ * `maxPoints` points are returned and `truncated` is true.
16391
+ */
16392
+ query: method(zod.z.object({
16393
+ deviceId: zod.z.number().int(),
16394
+ ...QueryWindowShape
16395
+ }), QueryResultSchema),
16396
+ queryNode: method(zod.z.object({
16397
+ nodeId: zod.z.string().min(1),
16398
+ ...QueryWindowShape
16399
+ }), QueryResultSchema, { auth: "admin" }),
16400
+ /** Producer: declare (idempotent) a series key this addon owns: `addon:<callerAddonId>/<name>`. */
16401
+ declareSeries: method(zod.z.object({
16402
+ name: zod.z.string().regex(/^[a-z0-9-]+$/),
16403
+ subjectKind: zod.z.enum(["device", "node"]),
16404
+ kind: DeviceHistoryKindSchema,
16405
+ unit: zod.z.string().optional(),
16406
+ displayName: zod.z.string().min(1),
16407
+ ingest: zod.z.enum(["points", "buckets"])
16408
+ }), zod.z.object({ key: zod.z.string() }), {
16409
+ kind: "mutation",
16410
+ auth: "admin"
16411
+ }),
16412
+ /** Producer: points. Low rate: at most one per 10 s per series, sustained. */
16413
+ record: method(zod.z.object({ points: zod.z.array(zod.z.object({
16414
+ key: zod.z.string(),
16415
+ subject: DeviceHistorySubjectSchema,
16416
+ scope: zod.z.string().default(""),
16417
+ ts: zod.z.number(),
16418
+ value: zod.z.number()
16419
+ })).max(5e3) }), IngestResultSchema, {
16420
+ kind: "mutation",
16421
+ auth: "admin"
16422
+ }),
16423
+ /** Producer: CLOSED five-minute buckets. Idempotent upsert keyed (series, bucketStart). */
16424
+ recordBuckets: method(zod.z.object({ buckets: zod.z.array(zod.z.object({
16425
+ key: zod.z.string(),
16426
+ subject: DeviceHistorySubjectSchema,
16427
+ scope: zod.z.string().default(""),
16428
+ bucketStart: zod.z.number(),
16429
+ samples: zod.z.number().int().positive(),
16430
+ sum: zod.z.number(),
16431
+ min: zod.z.number(),
16432
+ max: zod.z.number(),
16433
+ last: zod.z.number().nullable(),
16434
+ lastTs: zod.z.number().nullable()
16435
+ })).max(5e3) }), IngestResultSchema, {
16436
+ kind: "mutation",
16437
+ auth: "admin"
16438
+ }),
16439
+ /** Per-device opt-out. This addon IS the authority: the switch stores nothing elsewhere (D62). */
16440
+ getDeviceEnabled: method(zod.z.object({ deviceId: zod.z.number().int() }), zod.z.object({ enabled: zod.z.boolean() })),
16441
+ setDeviceEnabled: method(zod.z.object({
16442
+ deviceId: zod.z.number().int(),
16443
+ enabled: zod.z.boolean()
16444
+ }), zod.z.object({ enabled: zod.z.boolean() }), {
16445
+ kind: "mutation",
16446
+ auth: "admin"
16447
+ }),
16448
+ getStatus: method(zod.z.object({}), DeviceHistoryStatusSchema, { auth: "admin" })
16449
+ }
16450
+ };
16216
16451
  var DeviceCaStatusSchema = zod.z.discriminatedUnion("state", [
16217
16452
  zod.z.object({ state: zod.z.literal("absent") }),
16218
16453
  zod.z.object({
@@ -74293,6 +74528,66 @@ var METHOD_ACCESS_MAP = Object.freeze({
74293
74528
  addonId: null,
74294
74529
  access: "create"
74295
74530
  },
74531
+ "deviceHistory.declareSeries": {
74532
+ capName: "device-history",
74533
+ capScope: "system",
74534
+ addonId: null,
74535
+ access: "create"
74536
+ },
74537
+ "deviceHistory.getDeviceEnabled": {
74538
+ capName: "device-history",
74539
+ capScope: "system",
74540
+ addonId: null,
74541
+ access: "view"
74542
+ },
74543
+ "deviceHistory.getStatus": {
74544
+ capName: "device-history",
74545
+ capScope: "system",
74546
+ addonId: null,
74547
+ access: "view"
74548
+ },
74549
+ "deviceHistory.listNodeSeries": {
74550
+ capName: "device-history",
74551
+ capScope: "system",
74552
+ addonId: null,
74553
+ access: "view"
74554
+ },
74555
+ "deviceHistory.listSeries": {
74556
+ capName: "device-history",
74557
+ capScope: "system",
74558
+ addonId: null,
74559
+ access: "view"
74560
+ },
74561
+ "deviceHistory.query": {
74562
+ capName: "device-history",
74563
+ capScope: "system",
74564
+ addonId: null,
74565
+ access: "view"
74566
+ },
74567
+ "deviceHistory.queryNode": {
74568
+ capName: "device-history",
74569
+ capScope: "system",
74570
+ addonId: null,
74571
+ access: "view"
74572
+ },
74573
+ "deviceHistory.record": {
74574
+ capName: "device-history",
74575
+ capScope: "system",
74576
+ addonId: null,
74577
+ access: "create"
74578
+ },
74579
+ "deviceHistory.recordBuckets": {
74580
+ capName: "device-history",
74581
+ capScope: "system",
74582
+ addonId: null,
74583
+ access: "create"
74584
+ },
74585
+ "deviceHistory.setDeviceEnabled": {
74586
+ capName: "device-history",
74587
+ capScope: "system",
74588
+ addonId: null,
74589
+ access: "create"
74590
+ },
74296
74591
  "deviceManager.addLocation": {
74297
74592
  capName: "device-manager",
74298
74593
  capScope: "system",
@@ -80763,6 +81058,7 @@ var ALL_CAPABILITY_DEFINITIONS = [
80763
81058
  deviceDiscoveryCapability,
80764
81059
  deviceExportCapability,
80765
81060
  deviceExtensionCapability,
81061
+ deviceHistoryCapability,
80766
81062
  deviceManagerCapability,
80767
81063
  deviceOpsCapability,
80768
81064
  deviceProviderCapability,
@@ -81346,6 +81642,26 @@ Object.freeze({
81346
81642
  form: "single",
81347
81643
  optional: false
81348
81644
  }],
81645
+ "deviceHistory.getDeviceEnabled": [{
81646
+ name: "deviceId",
81647
+ form: "single",
81648
+ optional: false
81649
+ }],
81650
+ "deviceHistory.listSeries": [{
81651
+ name: "deviceId",
81652
+ form: "single",
81653
+ optional: false
81654
+ }],
81655
+ "deviceHistory.query": [{
81656
+ name: "deviceId",
81657
+ form: "single",
81658
+ optional: false
81659
+ }],
81660
+ "deviceHistory.setDeviceEnabled": [{
81661
+ name: "deviceId",
81662
+ form: "single",
81663
+ optional: false
81664
+ }],
81349
81665
  "deviceManager.adoptionRelease": [{
81350
81666
  name: "camDeviceId",
81351
81667
  form: "single",
@@ -718,7 +718,7 @@ var EventCategory = /* @__PURE__ */ function(EventCategory) {
718
718
  return EventCategory;
719
719
  }({});
720
720
  //#endregion
721
- //#region ../types/dist/sleep-DxJdzHni.mjs
721
+ //#region ../types/dist/sleep--g-h2_c_.mjs
722
722
  /**
723
723
  * The audio chunk plane's byte format, and the ONE expansion from a coded
724
724
  * window to float samples (D455).
@@ -16213,6 +16213,241 @@ var keychainCapability = {
16213
16213
  getState: method(z.object({}), KeychainStateSchema, { auth: "admin" })
16214
16214
  }
16215
16215
  };
16216
+ /**
16217
+ * device-history — the ONE mechanism for numeric history (D850).
16218
+ *
16219
+ * A device value is recorded because its capability says so (the `history`
16220
+ * block of a `*.cap.ts`, captured hub-side from `DeviceStateChanged`); any
16221
+ * other series is DECLARED by the addon that produces it and fed with points
16222
+ * (`record`) or closed five-minute buckets (`recordBuckets`). Rollups 5m / 1h /
16223
+ * 1d are computed here and nowhere else. Storage is `history.db` (D851).
16224
+ *
16225
+ * Who the PRODUCER is: `declareSeries`, `record` and `recordBuckets` are owner
16226
+ * checked against the `callerAddonId` the transport stamps into a call that
16227
+ * crossed a process (never in an input schema, so a session cannot supply it).
16228
+ * A call with no stamp is refused `not-owner`. The methods are `admin` so a
16229
+ * non-admin session never reaches them; an addon's `ctx.api` call bypasses the
16230
+ * tier by design.
16231
+ */
16232
+ /** Whose history: a real device, or a cluster node (load, memory). */
16233
+ var DeviceHistorySubjectSchema = z.discriminatedUnion("kind", [z.object({
16234
+ kind: z.literal("device"),
16235
+ deviceId: z.number().int()
16236
+ }), z.object({
16237
+ kind: z.literal("node"),
16238
+ nodeId: z.string().min(1)
16239
+ })]);
16240
+ var DeviceHistoryKindSchema = z.enum([
16241
+ "gauge",
16242
+ "counter",
16243
+ "boolean"
16244
+ ]);
16245
+ var DeviceHistoryResolutionSchema = z.enum([
16246
+ "raw",
16247
+ "5m",
16248
+ "1h",
16249
+ "1d"
16250
+ ]);
16251
+ /** Why a producer's point or bucket was not stored. Counted, never silent (D391). */
16252
+ var DeviceHistoryRefusalReasonSchema = z.enum([
16253
+ "undeclared",
16254
+ "not-owner",
16255
+ "opted-out",
16256
+ "not-a-real-device",
16257
+ "rate",
16258
+ "ingest-mismatch",
16259
+ "out-of-range"
16260
+ ]);
16261
+ var RefusalSchema = z.object({
16262
+ key: z.string(),
16263
+ reason: DeviceHistoryRefusalReasonSchema,
16264
+ count: z.number().int()
16265
+ });
16266
+ var IngestResultSchema = z.object({
16267
+ accepted: z.number().int(),
16268
+ refused: z.array(RefusalSchema).readonly()
16269
+ });
16270
+ var SeriesInfoSchema = z.object({
16271
+ key: z.string(),
16272
+ scope: z.string(),
16273
+ kind: DeviceHistoryKindSchema,
16274
+ /** `null` is unknown (a `unitFrom` series whose device does not state a unit right now), never a guess. */
16275
+ unit: z.string().nullable(),
16276
+ displayName: z.string(),
16277
+ source: z.enum(["cap", "addon"]),
16278
+ firstTs: z.number(),
16279
+ lastTs: z.number()
16280
+ });
16281
+ var QueryPointSchema = z.object({
16282
+ /** Raw: the point's time. Rollup: the bucket start. */
16283
+ t: z.number(),
16284
+ samples: z.number().int(),
16285
+ /** `sum / samples`. */
16286
+ mean: z.number().nullable(),
16287
+ /** Time-weighted mean (`tw_sum / tw_ms`); `null` for bucket-ingested series. For a boolean: the fraction of time true. */
16288
+ twMean: z.number().nullable(),
16289
+ min: z.number(),
16290
+ max: z.number(),
16291
+ /** `null` is unknown, never zero (D393). */
16292
+ last: z.number().nullable()
16293
+ });
16294
+ var QuerySeriesSchema = z.object({
16295
+ scope: z.string(),
16296
+ /** The last point STRICTLY BEFORE `from` in the chosen tier, so a step chart can start at the held value. */
16297
+ before: z.object({
16298
+ t: z.number(),
16299
+ value: z.number().nullable()
16300
+ }).nullable(),
16301
+ points: z.array(QueryPointSchema).readonly()
16302
+ });
16303
+ /** The window part of a query, shared by the device and node forms. */
16304
+ var QueryWindowShape = {
16305
+ key: z.string(),
16306
+ scope: z.string().optional(),
16307
+ from: z.number(),
16308
+ to: z.number(),
16309
+ resolution: z.union([DeviceHistoryResolutionSchema, z.literal("auto")]).default("auto"),
16310
+ maxPoints: z.number().int().positive().max(5e3).default(1e3)
16311
+ };
16312
+ var QueryResultSchema = z.object({
16313
+ resolution: DeviceHistoryResolutionSchema,
16314
+ series: z.array(QuerySeriesSchema).readonly(),
16315
+ truncated: z.boolean()
16316
+ });
16317
+ var TierStatusSchema = z.object({
16318
+ tier: DeviceHistoryResolutionSchema,
16319
+ /** `null` until the first background count answered. */
16320
+ rows: z.number().int().nullable(),
16321
+ /** `rows` times a fixed per-row estimate — approximate, labelled so. */
16322
+ approxBytes: z.number().nullable(),
16323
+ countedAt: z.number().nullable()
16324
+ });
16325
+ /** Operator/diagnostic view: rows per tier, last runs, refusals and drops since boot. */
16326
+ var DeviceHistoryStatusSchema = z.object({
16327
+ startedAt: z.number(),
16328
+ /** The store is declared, series loaded and the first reconcile has answered. */
16329
+ ready: z.boolean(),
16330
+ series: z.number().int(),
16331
+ metrics: z.number().int(),
16332
+ optedOutDevices: z.number().int(),
16333
+ tiers: z.array(TierStatusSchema).readonly(),
16334
+ capture: z.object({
16335
+ eventsSeen: z.number().int(),
16336
+ pointsEmitted: z.number().int(),
16337
+ pointsWritten: z.number().int(),
16338
+ pointsDropped: z.number().int(),
16339
+ bufferDepth: z.number().int(),
16340
+ trailingEmitted: z.number().int(),
16341
+ reconciledPoints: z.number().int(),
16342
+ reconcileRuns: z.number().int(),
16343
+ reconcileFailures: z.number().int(),
16344
+ lastReconcileAt: z.number().nullable(),
16345
+ lastFlushAt: z.number().nullable(),
16346
+ flushFailures: z.number().int(),
16347
+ skipped: z.record(z.string(), z.number().int())
16348
+ }),
16349
+ ingest: z.object({
16350
+ accepted: z.number().int(),
16351
+ refused: z.record(z.string(), z.number().int())
16352
+ }),
16353
+ rollup: z.object({
16354
+ last5mAt: z.number().nullable(),
16355
+ last1hAt: z.number().nullable(),
16356
+ last1dAt: z.number().nullable(),
16357
+ errors: z.number().int(),
16358
+ dirty5m: z.number().int(),
16359
+ dirty1h: z.number().int(),
16360
+ dirty1d: z.number().int()
16361
+ }),
16362
+ retention: z.object({
16363
+ lastRunAt: z.number().nullable(),
16364
+ deleted: z.record(z.string(), z.number().int()),
16365
+ purgedSeries: z.number().int()
16366
+ }),
16367
+ directory: z.object({
16368
+ devices: z.number().int(),
16369
+ lastRefreshAt: z.number().nullable()
16370
+ })
16371
+ });
16372
+ var deviceHistoryCapability = {
16373
+ name: "device-history",
16374
+ scope: "system",
16375
+ mode: "singleton",
16376
+ methods: {
16377
+ /**
16378
+ * The series a DEVICE has, and their span. `deviceId` is a flat top-level field
16379
+ * on purpose: the generated device selector (and so the scope gate) only sees
16380
+ * top-level ids, and a nested `subject.deviceId` would let a principal limited
16381
+ * to one device read another's history. Node series are the admin-only
16382
+ * `listNodeSeries` / `queryNode`.
16383
+ */
16384
+ listSeries: method(z.object({ deviceId: z.number().int() }), z.array(SeriesInfoSchema).readonly()),
16385
+ listNodeSeries: method(z.object({ nodeId: z.string().min(1) }), z.array(SeriesInfoSchema).readonly(), { auth: "admin" }),
16386
+ /**
16387
+ * One series (or every scope of it) at one resolution. `auto` picks the
16388
+ * finest tier whose retention covers `from` and whose point count fits
16389
+ * `maxPoints`; when even the coarsest tier does not fit, the newest
16390
+ * `maxPoints` points are returned and `truncated` is true.
16391
+ */
16392
+ query: method(z.object({
16393
+ deviceId: z.number().int(),
16394
+ ...QueryWindowShape
16395
+ }), QueryResultSchema),
16396
+ queryNode: method(z.object({
16397
+ nodeId: z.string().min(1),
16398
+ ...QueryWindowShape
16399
+ }), QueryResultSchema, { auth: "admin" }),
16400
+ /** Producer: declare (idempotent) a series key this addon owns: `addon:<callerAddonId>/<name>`. */
16401
+ declareSeries: method(z.object({
16402
+ name: z.string().regex(/^[a-z0-9-]+$/),
16403
+ subjectKind: z.enum(["device", "node"]),
16404
+ kind: DeviceHistoryKindSchema,
16405
+ unit: z.string().optional(),
16406
+ displayName: z.string().min(1),
16407
+ ingest: z.enum(["points", "buckets"])
16408
+ }), z.object({ key: z.string() }), {
16409
+ kind: "mutation",
16410
+ auth: "admin"
16411
+ }),
16412
+ /** Producer: points. Low rate: at most one per 10 s per series, sustained. */
16413
+ record: method(z.object({ points: z.array(z.object({
16414
+ key: z.string(),
16415
+ subject: DeviceHistorySubjectSchema,
16416
+ scope: z.string().default(""),
16417
+ ts: z.number(),
16418
+ value: z.number()
16419
+ })).max(5e3) }), IngestResultSchema, {
16420
+ kind: "mutation",
16421
+ auth: "admin"
16422
+ }),
16423
+ /** Producer: CLOSED five-minute buckets. Idempotent upsert keyed (series, bucketStart). */
16424
+ recordBuckets: method(z.object({ buckets: z.array(z.object({
16425
+ key: z.string(),
16426
+ subject: DeviceHistorySubjectSchema,
16427
+ scope: z.string().default(""),
16428
+ bucketStart: z.number(),
16429
+ samples: z.number().int().positive(),
16430
+ sum: z.number(),
16431
+ min: z.number(),
16432
+ max: z.number(),
16433
+ last: z.number().nullable(),
16434
+ lastTs: z.number().nullable()
16435
+ })).max(5e3) }), IngestResultSchema, {
16436
+ kind: "mutation",
16437
+ auth: "admin"
16438
+ }),
16439
+ /** Per-device opt-out. This addon IS the authority: the switch stores nothing elsewhere (D62). */
16440
+ getDeviceEnabled: method(z.object({ deviceId: z.number().int() }), z.object({ enabled: z.boolean() })),
16441
+ setDeviceEnabled: method(z.object({
16442
+ deviceId: z.number().int(),
16443
+ enabled: z.boolean()
16444
+ }), z.object({ enabled: z.boolean() }), {
16445
+ kind: "mutation",
16446
+ auth: "admin"
16447
+ }),
16448
+ getStatus: method(z.object({}), DeviceHistoryStatusSchema, { auth: "admin" })
16449
+ }
16450
+ };
16216
16451
  var DeviceCaStatusSchema = z.discriminatedUnion("state", [
16217
16452
  z.object({ state: z.literal("absent") }),
16218
16453
  z.object({
@@ -74293,6 +74528,66 @@ var METHOD_ACCESS_MAP = Object.freeze({
74293
74528
  addonId: null,
74294
74529
  access: "create"
74295
74530
  },
74531
+ "deviceHistory.declareSeries": {
74532
+ capName: "device-history",
74533
+ capScope: "system",
74534
+ addonId: null,
74535
+ access: "create"
74536
+ },
74537
+ "deviceHistory.getDeviceEnabled": {
74538
+ capName: "device-history",
74539
+ capScope: "system",
74540
+ addonId: null,
74541
+ access: "view"
74542
+ },
74543
+ "deviceHistory.getStatus": {
74544
+ capName: "device-history",
74545
+ capScope: "system",
74546
+ addonId: null,
74547
+ access: "view"
74548
+ },
74549
+ "deviceHistory.listNodeSeries": {
74550
+ capName: "device-history",
74551
+ capScope: "system",
74552
+ addonId: null,
74553
+ access: "view"
74554
+ },
74555
+ "deviceHistory.listSeries": {
74556
+ capName: "device-history",
74557
+ capScope: "system",
74558
+ addonId: null,
74559
+ access: "view"
74560
+ },
74561
+ "deviceHistory.query": {
74562
+ capName: "device-history",
74563
+ capScope: "system",
74564
+ addonId: null,
74565
+ access: "view"
74566
+ },
74567
+ "deviceHistory.queryNode": {
74568
+ capName: "device-history",
74569
+ capScope: "system",
74570
+ addonId: null,
74571
+ access: "view"
74572
+ },
74573
+ "deviceHistory.record": {
74574
+ capName: "device-history",
74575
+ capScope: "system",
74576
+ addonId: null,
74577
+ access: "create"
74578
+ },
74579
+ "deviceHistory.recordBuckets": {
74580
+ capName: "device-history",
74581
+ capScope: "system",
74582
+ addonId: null,
74583
+ access: "create"
74584
+ },
74585
+ "deviceHistory.setDeviceEnabled": {
74586
+ capName: "device-history",
74587
+ capScope: "system",
74588
+ addonId: null,
74589
+ access: "create"
74590
+ },
74296
74591
  "deviceManager.addLocation": {
74297
74592
  capName: "device-manager",
74298
74593
  capScope: "system",
@@ -80763,6 +81058,7 @@ var ALL_CAPABILITY_DEFINITIONS = [
80763
81058
  deviceDiscoveryCapability,
80764
81059
  deviceExportCapability,
80765
81060
  deviceExtensionCapability,
81061
+ deviceHistoryCapability,
80766
81062
  deviceManagerCapability,
80767
81063
  deviceOpsCapability,
80768
81064
  deviceProviderCapability,
@@ -81346,6 +81642,26 @@ Object.freeze({
81346
81642
  form: "single",
81347
81643
  optional: false
81348
81644
  }],
81645
+ "deviceHistory.getDeviceEnabled": [{
81646
+ name: "deviceId",
81647
+ form: "single",
81648
+ optional: false
81649
+ }],
81650
+ "deviceHistory.listSeries": [{
81651
+ name: "deviceId",
81652
+ form: "single",
81653
+ optional: false
81654
+ }],
81655
+ "deviceHistory.query": [{
81656
+ name: "deviceId",
81657
+ form: "single",
81658
+ optional: false
81659
+ }],
81660
+ "deviceHistory.setDeviceEnabled": [{
81661
+ name: "deviceId",
81662
+ form: "single",
81663
+ optional: false
81664
+ }],
81349
81665
  "deviceManager.adoptionRelease": [{
81350
81666
  name: "camDeviceId",
81351
81667
  form: "single",