@camstack/addon-notifiers 1.2.10 → 1.2.12

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 +348 -109
  2. package/dist/addon.mjs +348 -109
  3. package/package.json +1 -1
package/dist/addon.js CHANGED
@@ -29,7 +29,7 @@ let node_fs = require("node:fs");
29
29
  let node_path = require("node:path");
30
30
  node_path = __toESM(node_path);
31
31
  let node_url = require("node:url");
32
- //#region ../types/dist/event-category-Bz24uP1U.mjs
32
+ //#region ../types/dist/event-category-41fKf-q9.mjs
33
33
  var EventCategory = /* @__PURE__ */ function(EventCategory) {
34
34
  EventCategory["SystemBoot"] = "system.boot";
35
35
  EventCategory["SystemAddonsReady"] = "system.addons-ready";
@@ -89,6 +89,26 @@ var EventCategory = /* @__PURE__ */ function(EventCategory) {
89
89
  */
90
90
  EventCategory["AddonRetryScheduled"] = "addon.retry-scheduled";
91
91
  /**
92
+ * A liveness invariant of this node is false — it has no devices, every
93
+ * camera is offline, or a camera that was recording has stopped producing
94
+ * segments. Emitted by the `liveness-monitor` builtin, once per fault (the
95
+ * `findingId` is stable across ticks), only after its boot grace period.
96
+ * AlertCenter raises a persistent operator-visible alert.
97
+ *
98
+ * It exists because on 2026-08-03 the hub ran four hours with zero devices
99
+ * and zero recordings while every surface stayed quiet.
100
+ *
101
+ * Payload: `{ findingId, severity, title, message, deviceId? }`.
102
+ */
103
+ EventCategory["SystemLivenessFailed"] = "system.liveness-failed";
104
+ /**
105
+ * A previously reported liveness fault is true again. AlertCenter dismisses
106
+ * the matching `SystemLivenessFailed` alert.
107
+ *
108
+ * Payload: `{ findingId }`.
109
+ */
110
+ EventCategory["SystemLivenessRecovered"] = "system.liveness-recovered";
111
+ /**
92
112
  * Monitor is attempting to reload a failed addon NOW. UI uses this
93
113
  * to show a spinner during the retry attempt. Same transient nature
94
114
  * as AddonRetryScheduled.
@@ -7456,14 +7476,7 @@ var RecordingConfigSchema = object({
7456
7476
  * windows only — existing sheets are immutable, and each window's index
7457
7477
  * carries its own tile dims so mixed-preset history renders correctly.
7458
7478
  */
7459
- scrubThumbnails: ScrubThumbnailPresetSchema.optional(),
7460
- /**
7461
- * OPT-IN thumbnail-strip generation for this camera: every keyframe of the
7462
- * low recording saved as a JPEG (the fast-drag scrub depth), a derived
7463
- * cache that eviction reclaims with the footage. Absent/false = no strips
7464
- * are written and scrub reads exact keyframes at every velocity.
7465
- */
7466
- stripsEnabled: boolean().optional()
7479
+ scrubThumbnails: ScrubThumbnailPresetSchema.optional()
7467
7480
  }).strict();
7468
7481
  /**
7469
7482
  * Ops-log — the durable, append-only operations audit shared by the
@@ -7525,7 +7538,7 @@ var OpsLogQueryInputSchema = object({
7525
7538
  /**
7526
7539
  * Entity-relocation job state (storage entity-routing spec, Phase 4).
7527
7540
  *
7528
- * One shape shared by the recorder's `relocateFootage` (segments + strips) and
7541
+ * One shape shared by the recorder's `relocateFootage` (segments) and
7529
7542
  * pipeline-analytics' `relocateMedia` (event media blobs) so the admin Data
7530
7543
  * page renders both movers with one component. Jobs are in-RAM (a restart
7531
7544
  * forgets them — re-running is safe by construction: copy-if-absent, delete
@@ -7547,7 +7560,7 @@ var RelocateJobSchema = object({
7547
7560
  toLocationId: string(),
7548
7561
  /** Scoped device, or null = every device. */
7549
7562
  deviceId: number().nullable(),
7550
- /** What the job moves (owner-addon specific: segments/strips or media). */
7563
+ /** What the job moves (owner-addon specific: segments or media). */
7551
7564
  entities: array(string()),
7552
7565
  filesMoved: number().int(),
7553
7566
  bytesMoved: number().int(),
@@ -7561,7 +7574,7 @@ var RelocateFootageInputSchema = object({
7561
7574
  deviceId: number().optional(),
7562
7575
  fromLocationId: string(),
7563
7576
  toLocationId: string(),
7564
- entities: array(_enum(["segments", "strips"])).optional(),
7577
+ entities: array(_enum(["segments"])).optional(),
7565
7578
  /** Copy throttle in MB/s (default 40) — the drain is a background chore,
7566
7579
  * never allowed to starve live writers. */
7567
7580
  throttleMbps: number().min(1).max(1e3).optional()
@@ -15457,6 +15470,210 @@ method(object({ codec: string() }), boolean()), method(_void(), object({
15457
15470
  kind: "mutation",
15458
15471
  auth: "admin"
15459
15472
  });
15473
+ /**
15474
+ * Query filter for settings-store collections.
15475
+ */
15476
+ var QueryFilterSchema = object({
15477
+ where: record(string(), unknown()).optional(),
15478
+ whereIn: record(string(), array(unknown())).optional(),
15479
+ whereBetween: record(string(), tuple([unknown(), unknown()])).optional(),
15480
+ orderBy: object({
15481
+ field: string(),
15482
+ direction: _enum(["asc", "desc"])
15483
+ }).optional(),
15484
+ limit: number().optional(),
15485
+ offset: number().optional()
15486
+ });
15487
+ /**
15488
+ * The predicate half of a filter, for BULK MUTATIONS.
15489
+ *
15490
+ * Deliberately not `QueryFilterSchema`: `orderBy` / `limit` / `offset` have no
15491
+ * meaning for a statement that rewrites a set, and accepting them would invite
15492
+ * a caller to believe `limit` bounds the damage. Every field is optional here
15493
+ * only so the shape stays composable — the implementation REJECTS a filter
15494
+ * that compiles to no predicate, because that is the whole collection.
15495
+ */
15496
+ var MutationFilterSchema = object({
15497
+ where: record(string(), unknown()).optional(),
15498
+ whereIn: record(string(), array(unknown())).optional(),
15499
+ whereBetween: record(string(), tuple([unknown(), unknown()])).optional()
15500
+ });
15501
+ /** A single stored record: `{ id, data }`. */
15502
+ var SettingsRecordSchema = object({
15503
+ id: string(),
15504
+ data: record(string(), unknown())
15505
+ });
15506
+ /**
15507
+ * Column declaration for a structured (SQL-backed) collection.
15508
+ *
15509
+ * Logical types — the backend translates each to the matching SQLite
15510
+ * storage class and handles per-type marshaling:
15511
+ * - `TEXT` / `INTEGER` / `REAL` — native SQLite types, pass-through
15512
+ * - `JSON` — TEXT under the hood; serialised on write, parsed on read
15513
+ * - `BOOLEAN` — INTEGER 0/1 under the hood; coerced both directions
15514
+ */
15515
+ var CollectionColumnSchema = object({
15516
+ name: string(),
15517
+ type: _enum([
15518
+ "TEXT",
15519
+ "INTEGER",
15520
+ "REAL",
15521
+ "JSON",
15522
+ "BOOLEAN"
15523
+ ]),
15524
+ primaryKey: boolean().optional(),
15525
+ notNull: boolean().optional(),
15526
+ unique: boolean().optional(),
15527
+ /**
15528
+ * Column DEFAULT. Required for B2: the four `ensureTable` consumers declare
15529
+ * columns like `enabled INTEGER NOT NULL DEFAULT 1`, and without this the
15530
+ * collection surface simply cannot express their existing tables — which is
15531
+ * why they were still on the uncapped `table*` API.
15532
+ */
15533
+ defaultValue: union([
15534
+ string(),
15535
+ number(),
15536
+ boolean()
15537
+ ]).optional()
15538
+ });
15539
+ var CollectionIndexSchema = object({
15540
+ name: string(),
15541
+ columns: array(string()).readonly(),
15542
+ unique: boolean().optional()
15543
+ });
15544
+ method(object({
15545
+ namespace: string().optional(),
15546
+ collection: string(),
15547
+ key: string()
15548
+ }), unknown()), method(object({
15549
+ namespace: string().optional(),
15550
+ collection: string(),
15551
+ key: string(),
15552
+ value: unknown()
15553
+ }), _void(), { kind: "mutation" }), method(object({
15554
+ namespace: string().optional(),
15555
+ collection: string(),
15556
+ filter: QueryFilterSchema.optional()
15557
+ }), array(SettingsRecordSchema).readonly()), method(object({
15558
+ namespace: string().optional(),
15559
+ collection: string(),
15560
+ record: SettingsRecordSchema
15561
+ }), _void(), { kind: "mutation" }), method(object({
15562
+ namespace: string().optional(),
15563
+ collection: string(),
15564
+ id: string(),
15565
+ data: record(string(), unknown())
15566
+ }), _void(), { kind: "mutation" }), method(object({
15567
+ namespace: string().optional(),
15568
+ collection: string(),
15569
+ key: string()
15570
+ }), _void(), { kind: "mutation" }), method(object({
15571
+ namespace: string().optional(),
15572
+ collection: string(),
15573
+ filter: MutationFilterSchema
15574
+ }), object({ deleted: number().int() }), { kind: "mutation" }), method(object({
15575
+ namespace: string().optional(),
15576
+ collection: string(),
15577
+ filter: MutationFilterSchema,
15578
+ data: record(string(), unknown())
15579
+ }), object({ updated: number().int() }), { kind: "mutation" }), method(object({
15580
+ namespace: string().optional(),
15581
+ collection: string(),
15582
+ filter: QueryFilterSchema.optional()
15583
+ }), number()), method(object({
15584
+ namespace: string().optional(),
15585
+ collection: string(),
15586
+ field: string(),
15587
+ bucketSize: number().int().positive(),
15588
+ origin: number().int(),
15589
+ filter: QueryFilterSchema.optional()
15590
+ }), array(object({
15591
+ bucket: number().int(),
15592
+ count: number().int()
15593
+ })).readonly()), method(object({
15594
+ namespace: string().optional(),
15595
+ collection: string()
15596
+ }), boolean()), method(object({
15597
+ namespace: string().optional(),
15598
+ collection: string(),
15599
+ columns: array(CollectionColumnSchema).readonly(),
15600
+ indexes: array(CollectionIndexSchema).readonly().optional()
15601
+ }), _void(), { kind: "mutation" });
15602
+ /**
15603
+ * What one engine says about itself. The orchestrator uses `kind` to pick
15604
+ * a registrant for a collection; `engineId` is what a log line names when
15605
+ * a call is routed or refused.
15606
+ */
15607
+ var EngineInfoSchema = object({
15608
+ engineId: string(),
15609
+ /**
15610
+ * `relational` — rows, columns, indexes, the surface `settings-store`
15611
+ * has always described. `vector` — an embedding store answering
15612
+ * similarity queries. A registrant declares exactly one; an engine that
15613
+ * does both registers twice, because "both" would make the routing
15614
+ * decision ambiguous at exactly the point it must not be.
15615
+ */
15616
+ kind: _enum(["relational", "vector"]),
15617
+ displayName: string()
15618
+ });
15619
+ method(_void(), EngineInfoSchema), method(object({
15620
+ namespace: string().optional(),
15621
+ collection: string(),
15622
+ key: string()
15623
+ }), unknown()), method(object({
15624
+ namespace: string().optional(),
15625
+ collection: string(),
15626
+ key: string(),
15627
+ value: unknown()
15628
+ }), _void(), { kind: "mutation" }), method(object({
15629
+ namespace: string().optional(),
15630
+ collection: string(),
15631
+ filter: QueryFilterSchema.optional()
15632
+ }), array(SettingsRecordSchema).readonly()), method(object({
15633
+ namespace: string().optional(),
15634
+ collection: string(),
15635
+ record: SettingsRecordSchema
15636
+ }), _void(), { kind: "mutation" }), method(object({
15637
+ namespace: string().optional(),
15638
+ collection: string(),
15639
+ id: string(),
15640
+ data: record(string(), unknown())
15641
+ }), _void(), { kind: "mutation" }), method(object({
15642
+ namespace: string().optional(),
15643
+ collection: string(),
15644
+ key: string()
15645
+ }), _void(), { kind: "mutation" }), method(object({
15646
+ namespace: string().optional(),
15647
+ collection: string(),
15648
+ filter: MutationFilterSchema
15649
+ }), object({ deleted: number().int() }), { kind: "mutation" }), method(object({
15650
+ namespace: string().optional(),
15651
+ collection: string(),
15652
+ filter: MutationFilterSchema,
15653
+ data: record(string(), unknown())
15654
+ }), object({ updated: number().int() }), { kind: "mutation" }), method(object({
15655
+ namespace: string().optional(),
15656
+ collection: string(),
15657
+ filter: QueryFilterSchema.optional()
15658
+ }), number()), method(object({
15659
+ namespace: string().optional(),
15660
+ collection: string(),
15661
+ field: string(),
15662
+ bucketSize: number().int().positive(),
15663
+ origin: number().int(),
15664
+ filter: QueryFilterSchema.optional()
15665
+ }), array(object({
15666
+ bucket: number().int(),
15667
+ count: number().int()
15668
+ })).readonly()), method(object({
15669
+ namespace: string().optional(),
15670
+ collection: string()
15671
+ }), boolean()), method(object({
15672
+ namespace: string().optional(),
15673
+ collection: string(),
15674
+ columns: array(CollectionColumnSchema).readonly(),
15675
+ indexes: array(CollectionIndexSchema).readonly().optional()
15676
+ }), _void(), { kind: "mutation" });
15460
15677
  DeviceType.Camera;
15461
15678
  /**
15462
15679
  * `device-adoption` — generic discovery + adoption surface,
@@ -18703,6 +18920,28 @@ var ServerUpdateStateSchema = _enum([
18703
18920
  "pending-restart",
18704
18921
  "awaiting-confirmation"
18705
18922
  ]);
18923
+ var ImageContractSchema = object({
18924
+ state: _enum([
18925
+ "in-sync",
18926
+ "behind-patch",
18927
+ "behind-series",
18928
+ "ahead",
18929
+ "unknown"
18930
+ ]),
18931
+ /** The baked seed closure version — the image/app-bundle fingerprint. */
18932
+ seedVersion: string().nullable(),
18933
+ /** Best-known version the deployment contract delivers today. */
18934
+ contractVersion: string().nullable(),
18935
+ /**
18936
+ * Where `contractVersion` came from: a real registry check (`registry`), or
18937
+ * the node's own running version (`running` — a node can never run code
18938
+ * newer than the newest release, so `seed < running` proves image staleness
18939
+ * even before any registry check has run).
18940
+ */
18941
+ contractSource: _enum(["registry", "running"]).nullable(),
18942
+ /** One operator-grade sentence: this node runs image X; the contract says Y. */
18943
+ message: string()
18944
+ });
18706
18945
  var ServerRollbackInfoSchema = object({
18707
18946
  /** The version that failed (or was manually rolled back). */
18708
18947
  fromVersion: string(),
@@ -18739,7 +18978,12 @@ var ServerPackageStatusSchema = object({
18739
18978
  * versions are being IGNORED. Surfaced as a warning in the UI.
18740
18979
  */
18741
18980
  stateFileCorrupt: boolean(),
18742
- lastCheckedAtMs: number().nullable()
18981
+ lastCheckedAtMs: number().nullable(),
18982
+ /**
18983
+ * Seed-vs-contract verdict (see {@link ImageContractSchema}). Optional for
18984
+ * version skew: an older provider's payload simply omits it.
18985
+ */
18986
+ imageContract: ImageContractSchema.optional()
18743
18987
  });
18744
18988
  var ServerUpdateCheckResultSchema = object({
18745
18989
  packageName: string(),
@@ -18774,101 +19018,6 @@ version: string().optional() }), ServerUpdateActionResultSchema, {
18774
19018
  auth: "admin"
18775
19019
  });
18776
19020
  /**
18777
- * Query filter for settings-store collections.
18778
- */
18779
- var QueryFilterSchema = object({
18780
- where: record(string(), unknown()).optional(),
18781
- whereIn: record(string(), array(unknown())).optional(),
18782
- whereBetween: record(string(), tuple([unknown(), unknown()])).optional(),
18783
- orderBy: object({
18784
- field: string(),
18785
- direction: _enum(["asc", "desc"])
18786
- }).optional(),
18787
- limit: number().optional(),
18788
- offset: number().optional()
18789
- });
18790
- /** A single stored record: `{ id, data }`. */
18791
- var SettingsRecordSchema = object({
18792
- id: string(),
18793
- data: record(string(), unknown())
18794
- });
18795
- /**
18796
- * Column declaration for a structured (SQL-backed) collection.
18797
- *
18798
- * Logical types — the backend translates each to the matching SQLite
18799
- * storage class and handles per-type marshaling:
18800
- * - `TEXT` / `INTEGER` / `REAL` — native SQLite types, pass-through
18801
- * - `JSON` — TEXT under the hood; serialised on write, parsed on read
18802
- * - `BOOLEAN` — INTEGER 0/1 under the hood; coerced both directions
18803
- */
18804
- var CollectionColumnSchema = object({
18805
- name: string(),
18806
- type: _enum([
18807
- "TEXT",
18808
- "INTEGER",
18809
- "REAL",
18810
- "JSON",
18811
- "BOOLEAN"
18812
- ]),
18813
- primaryKey: boolean().optional(),
18814
- notNull: boolean().optional(),
18815
- unique: boolean().optional()
18816
- });
18817
- var CollectionIndexSchema = object({
18818
- name: string(),
18819
- columns: array(string()).readonly(),
18820
- unique: boolean().optional()
18821
- });
18822
- method(object({
18823
- namespace: string().optional(),
18824
- collection: string(),
18825
- key: string()
18826
- }), unknown()), method(object({
18827
- namespace: string().optional(),
18828
- collection: string(),
18829
- key: string(),
18830
- value: unknown()
18831
- }), _void(), { kind: "mutation" }), method(object({
18832
- namespace: string().optional(),
18833
- collection: string(),
18834
- filter: QueryFilterSchema.optional()
18835
- }), array(SettingsRecordSchema).readonly()), method(object({
18836
- namespace: string().optional(),
18837
- collection: string(),
18838
- record: SettingsRecordSchema
18839
- }), _void(), { kind: "mutation" }), method(object({
18840
- namespace: string().optional(),
18841
- collection: string(),
18842
- id: string(),
18843
- data: record(string(), unknown())
18844
- }), _void(), { kind: "mutation" }), method(object({
18845
- namespace: string().optional(),
18846
- collection: string(),
18847
- key: string()
18848
- }), _void(), { kind: "mutation" }), method(object({
18849
- namespace: string().optional(),
18850
- collection: string(),
18851
- filter: QueryFilterSchema.optional()
18852
- }), number()), method(object({
18853
- namespace: string().optional(),
18854
- collection: string(),
18855
- field: string(),
18856
- bucketSize: number().int().positive(),
18857
- origin: number().int(),
18858
- filter: QueryFilterSchema.optional()
18859
- }), array(object({
18860
- bucket: number().int(),
18861
- count: number().int()
18862
- })).readonly()), method(object({
18863
- namespace: string().optional(),
18864
- collection: string()
18865
- }), boolean()), method(object({
18866
- namespace: string().optional(),
18867
- collection: string(),
18868
- columns: array(CollectionColumnSchema).readonly(),
18869
- indexes: array(CollectionIndexSchema).readonly().optional()
18870
- }), _void(), { kind: "mutation" });
18871
- /**
18872
19021
  * `smtp-provider` — pluggable email delivery surface.
18873
19022
  *
18874
19023
  * Collection cap: a deployment may install multiple SMTP relays (e.g.
@@ -22767,6 +22916,84 @@ Object.freeze({
22767
22916
  addonId: null,
22768
22917
  access: "view"
22769
22918
  },
22919
+ "dataStoreProvider.count": {
22920
+ capName: "data-store-provider",
22921
+ capScope: "system",
22922
+ addonId: null,
22923
+ access: "view"
22924
+ },
22925
+ "dataStoreProvider.declareCollection": {
22926
+ capName: "data-store-provider",
22927
+ capScope: "system",
22928
+ addonId: null,
22929
+ access: "create"
22930
+ },
22931
+ "dataStoreProvider.delete": {
22932
+ capName: "data-store-provider",
22933
+ capScope: "system",
22934
+ addonId: null,
22935
+ access: "delete"
22936
+ },
22937
+ "dataStoreProvider.deleteWhere": {
22938
+ capName: "data-store-provider",
22939
+ capScope: "system",
22940
+ addonId: null,
22941
+ access: "delete"
22942
+ },
22943
+ "dataStoreProvider.get": {
22944
+ capName: "data-store-provider",
22945
+ capScope: "system",
22946
+ addonId: null,
22947
+ access: "view"
22948
+ },
22949
+ "dataStoreProvider.getEngineInfo": {
22950
+ capName: "data-store-provider",
22951
+ capScope: "system",
22952
+ addonId: null,
22953
+ access: "view"
22954
+ },
22955
+ "dataStoreProvider.histogram": {
22956
+ capName: "data-store-provider",
22957
+ capScope: "system",
22958
+ addonId: null,
22959
+ access: "view"
22960
+ },
22961
+ "dataStoreProvider.insert": {
22962
+ capName: "data-store-provider",
22963
+ capScope: "system",
22964
+ addonId: null,
22965
+ access: "create"
22966
+ },
22967
+ "dataStoreProvider.isEmpty": {
22968
+ capName: "data-store-provider",
22969
+ capScope: "system",
22970
+ addonId: null,
22971
+ access: "view"
22972
+ },
22973
+ "dataStoreProvider.query": {
22974
+ capName: "data-store-provider",
22975
+ capScope: "system",
22976
+ addonId: null,
22977
+ access: "view"
22978
+ },
22979
+ "dataStoreProvider.set": {
22980
+ capName: "data-store-provider",
22981
+ capScope: "system",
22982
+ addonId: null,
22983
+ access: "create"
22984
+ },
22985
+ "dataStoreProvider.update": {
22986
+ capName: "data-store-provider",
22987
+ capScope: "system",
22988
+ addonId: null,
22989
+ access: "create"
22990
+ },
22991
+ "dataStoreProvider.updateWhere": {
22992
+ capName: "data-store-provider",
22993
+ capScope: "system",
22994
+ addonId: null,
22995
+ access: "create"
22996
+ },
22770
22997
  "dayNight.getOptions": {
22771
22998
  capName: "day-night",
22772
22999
  capScope: "device",
@@ -25845,6 +26072,12 @@ Object.freeze({
25845
26072
  addonId: null,
25846
26073
  access: "delete"
25847
26074
  },
26075
+ "settingsStore.deleteWhere": {
26076
+ capName: "settings-store",
26077
+ capScope: "system",
26078
+ addonId: null,
26079
+ access: "delete"
26080
+ },
25848
26081
  "settingsStore.get": {
25849
26082
  capName: "settings-store",
25850
26083
  capScope: "system",
@@ -25887,6 +26120,12 @@ Object.freeze({
25887
26120
  addonId: null,
25888
26121
  access: "create"
25889
26122
  },
26123
+ "settingsStore.updateWhere": {
26124
+ capName: "settings-store",
26125
+ capScope: "system",
26126
+ addonId: null,
26127
+ access: "create"
26128
+ },
25890
26129
  "smtpProvider.getStatus": {
25891
26130
  capName: "smtp-provider",
25892
26131
  capScope: "system",
@@ -29945,7 +30184,7 @@ function createMemorySettingsStorePort() {
29945
30184
  * the store persists whatever it is handed verbatim.
29946
30185
  */
29947
30186
  /** The default collection name (see `settings-store` addonId-prefix note). */
29948
- var TARGETS_COLLECTION = "notification-targets";
30187
+ var TARGETS_COLLECTION = "notifiers:notification-targets";
29949
30188
  /** KV JSON-blob shape — a single `data` column routes the row through the
29950
30189
  * settings backend's canonical key/value path (id TEXT PK, data TEXT). */
29951
30190
  var KV_BLOB_COLUMNS = [{
package/dist/addon.mjs CHANGED
@@ -2,7 +2,7 @@ import { brotliCompressSync, deflateSync, gzipSync } from "node:zlib";
2
2
  import { readFileSync } from "node:fs";
3
3
  import path from "node:path";
4
4
  import { fileURLToPath } from "node:url";
5
- //#region ../types/dist/event-category-Bz24uP1U.mjs
5
+ //#region ../types/dist/event-category-41fKf-q9.mjs
6
6
  var EventCategory = /* @__PURE__ */ function(EventCategory) {
7
7
  EventCategory["SystemBoot"] = "system.boot";
8
8
  EventCategory["SystemAddonsReady"] = "system.addons-ready";
@@ -62,6 +62,26 @@ var EventCategory = /* @__PURE__ */ function(EventCategory) {
62
62
  */
63
63
  EventCategory["AddonRetryScheduled"] = "addon.retry-scheduled";
64
64
  /**
65
+ * A liveness invariant of this node is false — it has no devices, every
66
+ * camera is offline, or a camera that was recording has stopped producing
67
+ * segments. Emitted by the `liveness-monitor` builtin, once per fault (the
68
+ * `findingId` is stable across ticks), only after its boot grace period.
69
+ * AlertCenter raises a persistent operator-visible alert.
70
+ *
71
+ * It exists because on 2026-08-03 the hub ran four hours with zero devices
72
+ * and zero recordings while every surface stayed quiet.
73
+ *
74
+ * Payload: `{ findingId, severity, title, message, deviceId? }`.
75
+ */
76
+ EventCategory["SystemLivenessFailed"] = "system.liveness-failed";
77
+ /**
78
+ * A previously reported liveness fault is true again. AlertCenter dismisses
79
+ * the matching `SystemLivenessFailed` alert.
80
+ *
81
+ * Payload: `{ findingId }`.
82
+ */
83
+ EventCategory["SystemLivenessRecovered"] = "system.liveness-recovered";
84
+ /**
65
85
  * Monitor is attempting to reload a failed addon NOW. UI uses this
66
86
  * to show a spinner during the retry attempt. Same transient nature
67
87
  * as AddonRetryScheduled.
@@ -7429,14 +7449,7 @@ var RecordingConfigSchema = object({
7429
7449
  * windows only — existing sheets are immutable, and each window's index
7430
7450
  * carries its own tile dims so mixed-preset history renders correctly.
7431
7451
  */
7432
- scrubThumbnails: ScrubThumbnailPresetSchema.optional(),
7433
- /**
7434
- * OPT-IN thumbnail-strip generation for this camera: every keyframe of the
7435
- * low recording saved as a JPEG (the fast-drag scrub depth), a derived
7436
- * cache that eviction reclaims with the footage. Absent/false = no strips
7437
- * are written and scrub reads exact keyframes at every velocity.
7438
- */
7439
- stripsEnabled: boolean().optional()
7452
+ scrubThumbnails: ScrubThumbnailPresetSchema.optional()
7440
7453
  }).strict();
7441
7454
  /**
7442
7455
  * Ops-log — the durable, append-only operations audit shared by the
@@ -7498,7 +7511,7 @@ var OpsLogQueryInputSchema = object({
7498
7511
  /**
7499
7512
  * Entity-relocation job state (storage entity-routing spec, Phase 4).
7500
7513
  *
7501
- * One shape shared by the recorder's `relocateFootage` (segments + strips) and
7514
+ * One shape shared by the recorder's `relocateFootage` (segments) and
7502
7515
  * pipeline-analytics' `relocateMedia` (event media blobs) so the admin Data
7503
7516
  * page renders both movers with one component. Jobs are in-RAM (a restart
7504
7517
  * forgets them — re-running is safe by construction: copy-if-absent, delete
@@ -7520,7 +7533,7 @@ var RelocateJobSchema = object({
7520
7533
  toLocationId: string(),
7521
7534
  /** Scoped device, or null = every device. */
7522
7535
  deviceId: number().nullable(),
7523
- /** What the job moves (owner-addon specific: segments/strips or media). */
7536
+ /** What the job moves (owner-addon specific: segments or media). */
7524
7537
  entities: array(string()),
7525
7538
  filesMoved: number().int(),
7526
7539
  bytesMoved: number().int(),
@@ -7534,7 +7547,7 @@ var RelocateFootageInputSchema = object({
7534
7547
  deviceId: number().optional(),
7535
7548
  fromLocationId: string(),
7536
7549
  toLocationId: string(),
7537
- entities: array(_enum(["segments", "strips"])).optional(),
7550
+ entities: array(_enum(["segments"])).optional(),
7538
7551
  /** Copy throttle in MB/s (default 40) — the drain is a background chore,
7539
7552
  * never allowed to starve live writers. */
7540
7553
  throttleMbps: number().min(1).max(1e3).optional()
@@ -15430,6 +15443,210 @@ method(object({ codec: string() }), boolean()), method(_void(), object({
15430
15443
  kind: "mutation",
15431
15444
  auth: "admin"
15432
15445
  });
15446
+ /**
15447
+ * Query filter for settings-store collections.
15448
+ */
15449
+ var QueryFilterSchema = object({
15450
+ where: record(string(), unknown()).optional(),
15451
+ whereIn: record(string(), array(unknown())).optional(),
15452
+ whereBetween: record(string(), tuple([unknown(), unknown()])).optional(),
15453
+ orderBy: object({
15454
+ field: string(),
15455
+ direction: _enum(["asc", "desc"])
15456
+ }).optional(),
15457
+ limit: number().optional(),
15458
+ offset: number().optional()
15459
+ });
15460
+ /**
15461
+ * The predicate half of a filter, for BULK MUTATIONS.
15462
+ *
15463
+ * Deliberately not `QueryFilterSchema`: `orderBy` / `limit` / `offset` have no
15464
+ * meaning for a statement that rewrites a set, and accepting them would invite
15465
+ * a caller to believe `limit` bounds the damage. Every field is optional here
15466
+ * only so the shape stays composable — the implementation REJECTS a filter
15467
+ * that compiles to no predicate, because that is the whole collection.
15468
+ */
15469
+ var MutationFilterSchema = object({
15470
+ where: record(string(), unknown()).optional(),
15471
+ whereIn: record(string(), array(unknown())).optional(),
15472
+ whereBetween: record(string(), tuple([unknown(), unknown()])).optional()
15473
+ });
15474
+ /** A single stored record: `{ id, data }`. */
15475
+ var SettingsRecordSchema = object({
15476
+ id: string(),
15477
+ data: record(string(), unknown())
15478
+ });
15479
+ /**
15480
+ * Column declaration for a structured (SQL-backed) collection.
15481
+ *
15482
+ * Logical types — the backend translates each to the matching SQLite
15483
+ * storage class and handles per-type marshaling:
15484
+ * - `TEXT` / `INTEGER` / `REAL` — native SQLite types, pass-through
15485
+ * - `JSON` — TEXT under the hood; serialised on write, parsed on read
15486
+ * - `BOOLEAN` — INTEGER 0/1 under the hood; coerced both directions
15487
+ */
15488
+ var CollectionColumnSchema = object({
15489
+ name: string(),
15490
+ type: _enum([
15491
+ "TEXT",
15492
+ "INTEGER",
15493
+ "REAL",
15494
+ "JSON",
15495
+ "BOOLEAN"
15496
+ ]),
15497
+ primaryKey: boolean().optional(),
15498
+ notNull: boolean().optional(),
15499
+ unique: boolean().optional(),
15500
+ /**
15501
+ * Column DEFAULT. Required for B2: the four `ensureTable` consumers declare
15502
+ * columns like `enabled INTEGER NOT NULL DEFAULT 1`, and without this the
15503
+ * collection surface simply cannot express their existing tables — which is
15504
+ * why they were still on the uncapped `table*` API.
15505
+ */
15506
+ defaultValue: union([
15507
+ string(),
15508
+ number(),
15509
+ boolean()
15510
+ ]).optional()
15511
+ });
15512
+ var CollectionIndexSchema = object({
15513
+ name: string(),
15514
+ columns: array(string()).readonly(),
15515
+ unique: boolean().optional()
15516
+ });
15517
+ method(object({
15518
+ namespace: string().optional(),
15519
+ collection: string(),
15520
+ key: string()
15521
+ }), unknown()), method(object({
15522
+ namespace: string().optional(),
15523
+ collection: string(),
15524
+ key: string(),
15525
+ value: unknown()
15526
+ }), _void(), { kind: "mutation" }), method(object({
15527
+ namespace: string().optional(),
15528
+ collection: string(),
15529
+ filter: QueryFilterSchema.optional()
15530
+ }), array(SettingsRecordSchema).readonly()), method(object({
15531
+ namespace: string().optional(),
15532
+ collection: string(),
15533
+ record: SettingsRecordSchema
15534
+ }), _void(), { kind: "mutation" }), method(object({
15535
+ namespace: string().optional(),
15536
+ collection: string(),
15537
+ id: string(),
15538
+ data: record(string(), unknown())
15539
+ }), _void(), { kind: "mutation" }), method(object({
15540
+ namespace: string().optional(),
15541
+ collection: string(),
15542
+ key: string()
15543
+ }), _void(), { kind: "mutation" }), method(object({
15544
+ namespace: string().optional(),
15545
+ collection: string(),
15546
+ filter: MutationFilterSchema
15547
+ }), object({ deleted: number().int() }), { kind: "mutation" }), method(object({
15548
+ namespace: string().optional(),
15549
+ collection: string(),
15550
+ filter: MutationFilterSchema,
15551
+ data: record(string(), unknown())
15552
+ }), object({ updated: number().int() }), { kind: "mutation" }), method(object({
15553
+ namespace: string().optional(),
15554
+ collection: string(),
15555
+ filter: QueryFilterSchema.optional()
15556
+ }), number()), method(object({
15557
+ namespace: string().optional(),
15558
+ collection: string(),
15559
+ field: string(),
15560
+ bucketSize: number().int().positive(),
15561
+ origin: number().int(),
15562
+ filter: QueryFilterSchema.optional()
15563
+ }), array(object({
15564
+ bucket: number().int(),
15565
+ count: number().int()
15566
+ })).readonly()), method(object({
15567
+ namespace: string().optional(),
15568
+ collection: string()
15569
+ }), boolean()), method(object({
15570
+ namespace: string().optional(),
15571
+ collection: string(),
15572
+ columns: array(CollectionColumnSchema).readonly(),
15573
+ indexes: array(CollectionIndexSchema).readonly().optional()
15574
+ }), _void(), { kind: "mutation" });
15575
+ /**
15576
+ * What one engine says about itself. The orchestrator uses `kind` to pick
15577
+ * a registrant for a collection; `engineId` is what a log line names when
15578
+ * a call is routed or refused.
15579
+ */
15580
+ var EngineInfoSchema = object({
15581
+ engineId: string(),
15582
+ /**
15583
+ * `relational` — rows, columns, indexes, the surface `settings-store`
15584
+ * has always described. `vector` — an embedding store answering
15585
+ * similarity queries. A registrant declares exactly one; an engine that
15586
+ * does both registers twice, because "both" would make the routing
15587
+ * decision ambiguous at exactly the point it must not be.
15588
+ */
15589
+ kind: _enum(["relational", "vector"]),
15590
+ displayName: string()
15591
+ });
15592
+ method(_void(), EngineInfoSchema), method(object({
15593
+ namespace: string().optional(),
15594
+ collection: string(),
15595
+ key: string()
15596
+ }), unknown()), method(object({
15597
+ namespace: string().optional(),
15598
+ collection: string(),
15599
+ key: string(),
15600
+ value: unknown()
15601
+ }), _void(), { kind: "mutation" }), method(object({
15602
+ namespace: string().optional(),
15603
+ collection: string(),
15604
+ filter: QueryFilterSchema.optional()
15605
+ }), array(SettingsRecordSchema).readonly()), method(object({
15606
+ namespace: string().optional(),
15607
+ collection: string(),
15608
+ record: SettingsRecordSchema
15609
+ }), _void(), { kind: "mutation" }), method(object({
15610
+ namespace: string().optional(),
15611
+ collection: string(),
15612
+ id: string(),
15613
+ data: record(string(), unknown())
15614
+ }), _void(), { kind: "mutation" }), method(object({
15615
+ namespace: string().optional(),
15616
+ collection: string(),
15617
+ key: string()
15618
+ }), _void(), { kind: "mutation" }), method(object({
15619
+ namespace: string().optional(),
15620
+ collection: string(),
15621
+ filter: MutationFilterSchema
15622
+ }), object({ deleted: number().int() }), { kind: "mutation" }), method(object({
15623
+ namespace: string().optional(),
15624
+ collection: string(),
15625
+ filter: MutationFilterSchema,
15626
+ data: record(string(), unknown())
15627
+ }), object({ updated: number().int() }), { kind: "mutation" }), method(object({
15628
+ namespace: string().optional(),
15629
+ collection: string(),
15630
+ filter: QueryFilterSchema.optional()
15631
+ }), number()), method(object({
15632
+ namespace: string().optional(),
15633
+ collection: string(),
15634
+ field: string(),
15635
+ bucketSize: number().int().positive(),
15636
+ origin: number().int(),
15637
+ filter: QueryFilterSchema.optional()
15638
+ }), array(object({
15639
+ bucket: number().int(),
15640
+ count: number().int()
15641
+ })).readonly()), method(object({
15642
+ namespace: string().optional(),
15643
+ collection: string()
15644
+ }), boolean()), method(object({
15645
+ namespace: string().optional(),
15646
+ collection: string(),
15647
+ columns: array(CollectionColumnSchema).readonly(),
15648
+ indexes: array(CollectionIndexSchema).readonly().optional()
15649
+ }), _void(), { kind: "mutation" });
15433
15650
  DeviceType.Camera;
15434
15651
  /**
15435
15652
  * `device-adoption` — generic discovery + adoption surface,
@@ -18676,6 +18893,28 @@ var ServerUpdateStateSchema = _enum([
18676
18893
  "pending-restart",
18677
18894
  "awaiting-confirmation"
18678
18895
  ]);
18896
+ var ImageContractSchema = object({
18897
+ state: _enum([
18898
+ "in-sync",
18899
+ "behind-patch",
18900
+ "behind-series",
18901
+ "ahead",
18902
+ "unknown"
18903
+ ]),
18904
+ /** The baked seed closure version — the image/app-bundle fingerprint. */
18905
+ seedVersion: string().nullable(),
18906
+ /** Best-known version the deployment contract delivers today. */
18907
+ contractVersion: string().nullable(),
18908
+ /**
18909
+ * Where `contractVersion` came from: a real registry check (`registry`), or
18910
+ * the node's own running version (`running` — a node can never run code
18911
+ * newer than the newest release, so `seed < running` proves image staleness
18912
+ * even before any registry check has run).
18913
+ */
18914
+ contractSource: _enum(["registry", "running"]).nullable(),
18915
+ /** One operator-grade sentence: this node runs image X; the contract says Y. */
18916
+ message: string()
18917
+ });
18679
18918
  var ServerRollbackInfoSchema = object({
18680
18919
  /** The version that failed (or was manually rolled back). */
18681
18920
  fromVersion: string(),
@@ -18712,7 +18951,12 @@ var ServerPackageStatusSchema = object({
18712
18951
  * versions are being IGNORED. Surfaced as a warning in the UI.
18713
18952
  */
18714
18953
  stateFileCorrupt: boolean(),
18715
- lastCheckedAtMs: number().nullable()
18954
+ lastCheckedAtMs: number().nullable(),
18955
+ /**
18956
+ * Seed-vs-contract verdict (see {@link ImageContractSchema}). Optional for
18957
+ * version skew: an older provider's payload simply omits it.
18958
+ */
18959
+ imageContract: ImageContractSchema.optional()
18716
18960
  });
18717
18961
  var ServerUpdateCheckResultSchema = object({
18718
18962
  packageName: string(),
@@ -18747,101 +18991,6 @@ version: string().optional() }), ServerUpdateActionResultSchema, {
18747
18991
  auth: "admin"
18748
18992
  });
18749
18993
  /**
18750
- * Query filter for settings-store collections.
18751
- */
18752
- var QueryFilterSchema = object({
18753
- where: record(string(), unknown()).optional(),
18754
- whereIn: record(string(), array(unknown())).optional(),
18755
- whereBetween: record(string(), tuple([unknown(), unknown()])).optional(),
18756
- orderBy: object({
18757
- field: string(),
18758
- direction: _enum(["asc", "desc"])
18759
- }).optional(),
18760
- limit: number().optional(),
18761
- offset: number().optional()
18762
- });
18763
- /** A single stored record: `{ id, data }`. */
18764
- var SettingsRecordSchema = object({
18765
- id: string(),
18766
- data: record(string(), unknown())
18767
- });
18768
- /**
18769
- * Column declaration for a structured (SQL-backed) collection.
18770
- *
18771
- * Logical types — the backend translates each to the matching SQLite
18772
- * storage class and handles per-type marshaling:
18773
- * - `TEXT` / `INTEGER` / `REAL` — native SQLite types, pass-through
18774
- * - `JSON` — TEXT under the hood; serialised on write, parsed on read
18775
- * - `BOOLEAN` — INTEGER 0/1 under the hood; coerced both directions
18776
- */
18777
- var CollectionColumnSchema = object({
18778
- name: string(),
18779
- type: _enum([
18780
- "TEXT",
18781
- "INTEGER",
18782
- "REAL",
18783
- "JSON",
18784
- "BOOLEAN"
18785
- ]),
18786
- primaryKey: boolean().optional(),
18787
- notNull: boolean().optional(),
18788
- unique: boolean().optional()
18789
- });
18790
- var CollectionIndexSchema = object({
18791
- name: string(),
18792
- columns: array(string()).readonly(),
18793
- unique: boolean().optional()
18794
- });
18795
- method(object({
18796
- namespace: string().optional(),
18797
- collection: string(),
18798
- key: string()
18799
- }), unknown()), method(object({
18800
- namespace: string().optional(),
18801
- collection: string(),
18802
- key: string(),
18803
- value: unknown()
18804
- }), _void(), { kind: "mutation" }), method(object({
18805
- namespace: string().optional(),
18806
- collection: string(),
18807
- filter: QueryFilterSchema.optional()
18808
- }), array(SettingsRecordSchema).readonly()), method(object({
18809
- namespace: string().optional(),
18810
- collection: string(),
18811
- record: SettingsRecordSchema
18812
- }), _void(), { kind: "mutation" }), method(object({
18813
- namespace: string().optional(),
18814
- collection: string(),
18815
- id: string(),
18816
- data: record(string(), unknown())
18817
- }), _void(), { kind: "mutation" }), method(object({
18818
- namespace: string().optional(),
18819
- collection: string(),
18820
- key: string()
18821
- }), _void(), { kind: "mutation" }), method(object({
18822
- namespace: string().optional(),
18823
- collection: string(),
18824
- filter: QueryFilterSchema.optional()
18825
- }), number()), method(object({
18826
- namespace: string().optional(),
18827
- collection: string(),
18828
- field: string(),
18829
- bucketSize: number().int().positive(),
18830
- origin: number().int(),
18831
- filter: QueryFilterSchema.optional()
18832
- }), array(object({
18833
- bucket: number().int(),
18834
- count: number().int()
18835
- })).readonly()), method(object({
18836
- namespace: string().optional(),
18837
- collection: string()
18838
- }), boolean()), method(object({
18839
- namespace: string().optional(),
18840
- collection: string(),
18841
- columns: array(CollectionColumnSchema).readonly(),
18842
- indexes: array(CollectionIndexSchema).readonly().optional()
18843
- }), _void(), { kind: "mutation" });
18844
- /**
18845
18994
  * `smtp-provider` — pluggable email delivery surface.
18846
18995
  *
18847
18996
  * Collection cap: a deployment may install multiple SMTP relays (e.g.
@@ -22740,6 +22889,84 @@ Object.freeze({
22740
22889
  addonId: null,
22741
22890
  access: "view"
22742
22891
  },
22892
+ "dataStoreProvider.count": {
22893
+ capName: "data-store-provider",
22894
+ capScope: "system",
22895
+ addonId: null,
22896
+ access: "view"
22897
+ },
22898
+ "dataStoreProvider.declareCollection": {
22899
+ capName: "data-store-provider",
22900
+ capScope: "system",
22901
+ addonId: null,
22902
+ access: "create"
22903
+ },
22904
+ "dataStoreProvider.delete": {
22905
+ capName: "data-store-provider",
22906
+ capScope: "system",
22907
+ addonId: null,
22908
+ access: "delete"
22909
+ },
22910
+ "dataStoreProvider.deleteWhere": {
22911
+ capName: "data-store-provider",
22912
+ capScope: "system",
22913
+ addonId: null,
22914
+ access: "delete"
22915
+ },
22916
+ "dataStoreProvider.get": {
22917
+ capName: "data-store-provider",
22918
+ capScope: "system",
22919
+ addonId: null,
22920
+ access: "view"
22921
+ },
22922
+ "dataStoreProvider.getEngineInfo": {
22923
+ capName: "data-store-provider",
22924
+ capScope: "system",
22925
+ addonId: null,
22926
+ access: "view"
22927
+ },
22928
+ "dataStoreProvider.histogram": {
22929
+ capName: "data-store-provider",
22930
+ capScope: "system",
22931
+ addonId: null,
22932
+ access: "view"
22933
+ },
22934
+ "dataStoreProvider.insert": {
22935
+ capName: "data-store-provider",
22936
+ capScope: "system",
22937
+ addonId: null,
22938
+ access: "create"
22939
+ },
22940
+ "dataStoreProvider.isEmpty": {
22941
+ capName: "data-store-provider",
22942
+ capScope: "system",
22943
+ addonId: null,
22944
+ access: "view"
22945
+ },
22946
+ "dataStoreProvider.query": {
22947
+ capName: "data-store-provider",
22948
+ capScope: "system",
22949
+ addonId: null,
22950
+ access: "view"
22951
+ },
22952
+ "dataStoreProvider.set": {
22953
+ capName: "data-store-provider",
22954
+ capScope: "system",
22955
+ addonId: null,
22956
+ access: "create"
22957
+ },
22958
+ "dataStoreProvider.update": {
22959
+ capName: "data-store-provider",
22960
+ capScope: "system",
22961
+ addonId: null,
22962
+ access: "create"
22963
+ },
22964
+ "dataStoreProvider.updateWhere": {
22965
+ capName: "data-store-provider",
22966
+ capScope: "system",
22967
+ addonId: null,
22968
+ access: "create"
22969
+ },
22743
22970
  "dayNight.getOptions": {
22744
22971
  capName: "day-night",
22745
22972
  capScope: "device",
@@ -25818,6 +26045,12 @@ Object.freeze({
25818
26045
  addonId: null,
25819
26046
  access: "delete"
25820
26047
  },
26048
+ "settingsStore.deleteWhere": {
26049
+ capName: "settings-store",
26050
+ capScope: "system",
26051
+ addonId: null,
26052
+ access: "delete"
26053
+ },
25821
26054
  "settingsStore.get": {
25822
26055
  capName: "settings-store",
25823
26056
  capScope: "system",
@@ -25860,6 +26093,12 @@ Object.freeze({
25860
26093
  addonId: null,
25861
26094
  access: "create"
25862
26095
  },
26096
+ "settingsStore.updateWhere": {
26097
+ capName: "settings-store",
26098
+ capScope: "system",
26099
+ addonId: null,
26100
+ access: "create"
26101
+ },
25863
26102
  "smtpProvider.getStatus": {
25864
26103
  capName: "smtp-provider",
25865
26104
  capScope: "system",
@@ -29918,7 +30157,7 @@ function createMemorySettingsStorePort() {
29918
30157
  * the store persists whatever it is handed verbatim.
29919
30158
  */
29920
30159
  /** The default collection name (see `settings-store` addonId-prefix note). */
29921
- var TARGETS_COLLECTION = "notification-targets";
30160
+ var TARGETS_COLLECTION = "notifiers:notification-targets";
29922
30161
  /** KV JSON-blob shape — a single `data` column routes the row through the
29923
30162
  * settings backend's canonical key/value path (id TEXT PK, data TEXT). */
29924
30163
  var KV_BLOB_COLUMNS = [{
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@camstack/addon-notifiers",
3
- "version": "1.2.10",
3
+ "version": "1.2.12",
4
4
  "description": "System notifiers addon for CamStack — a `notification-output` collection provider hosting per-kind notifier adapters (ntfy, pushover, gotify, telegram, discord, webhook, zentik).",
5
5
  "keywords": [
6
6
  "camstack",