@camstack/types 1.2.20 → 1.2.21

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.js CHANGED
@@ -964,14 +964,7 @@ var RecordingConfigSchema = zod.z.object({
964
964
  * windows only — existing sheets are immutable, and each window's index
965
965
  * carries its own tile dims so mixed-preset history renders correctly.
966
966
  */
967
- scrubThumbnails: ScrubThumbnailPresetSchema.optional(),
968
- /**
969
- * OPT-IN thumbnail-strip generation for this camera: every keyframe of the
970
- * low recording saved as a JPEG (the fast-drag scrub depth), a derived
971
- * cache that eviction reclaims with the footage. Absent/false = no strips
972
- * are written and scrub reads exact keyframes at every velocity.
973
- */
974
- stripsEnabled: zod.z.boolean().optional()
967
+ scrubThumbnails: ScrubThumbnailPresetSchema.optional()
975
968
  }).strict();
976
969
  /**
977
970
  * Derive the {@link RecordingStorageModeSchema} summary from the authoritative
@@ -1060,7 +1053,7 @@ var OPS_LOG_DEFAULT_LIMIT = 200;
1060
1053
  /**
1061
1054
  * Entity-relocation job state (storage entity-routing spec, Phase 4).
1062
1055
  *
1063
- * One shape shared by the recorder's `relocateFootage` (segments + strips) and
1056
+ * One shape shared by the recorder's `relocateFootage` (segments) and
1064
1057
  * pipeline-analytics' `relocateMedia` (event media blobs) so the admin Data
1065
1058
  * page renders both movers with one component. Jobs are in-RAM (a restart
1066
1059
  * forgets them — re-running is safe by construction: copy-if-absent, delete
@@ -1082,7 +1075,7 @@ var RelocateJobSchema = zod.z.object({
1082
1075
  toLocationId: zod.z.string(),
1083
1076
  /** Scoped device, or null = every device. */
1084
1077
  deviceId: zod.z.number().nullable(),
1085
- /** What the job moves (owner-addon specific: segments/strips or media). */
1078
+ /** What the job moves (owner-addon specific: segments or media). */
1086
1079
  entities: zod.z.array(zod.z.string()),
1087
1080
  filesMoved: zod.z.number().int(),
1088
1081
  bytesMoved: zod.z.number().int(),
@@ -1096,7 +1089,7 @@ var RelocateFootageInputSchema = zod.z.object({
1096
1089
  deviceId: zod.z.number().optional(),
1097
1090
  fromLocationId: zod.z.string(),
1098
1091
  toLocationId: zod.z.string(),
1099
- entities: zod.z.array(zod.z.enum(["segments", "strips"])).optional(),
1092
+ entities: zod.z.array(zod.z.enum(["segments"])).optional(),
1100
1093
  /** Copy throttle in MB/s (default 40) — the drain is a background chore,
1101
1094
  * never allowed to starve live writers. */
1102
1095
  throttleMbps: zod.z.number().min(1).max(1e3).optional()
@@ -17431,6 +17424,296 @@ var decoderCapability = {
17431
17424
  }
17432
17425
  };
17433
17426
  //#endregion
17427
+ //#region src/capabilities/settings-store.cap.ts
17428
+ /**
17429
+ * Query filter for settings-store collections.
17430
+ */
17431
+ var QueryFilterSchema = zod.z.object({
17432
+ where: zod.z.record(zod.z.string(), zod.z.unknown()).optional(),
17433
+ whereIn: zod.z.record(zod.z.string(), zod.z.array(zod.z.unknown())).optional(),
17434
+ whereBetween: zod.z.record(zod.z.string(), zod.z.tuple([zod.z.unknown(), zod.z.unknown()])).optional(),
17435
+ orderBy: zod.z.object({
17436
+ field: zod.z.string(),
17437
+ direction: zod.z.enum(["asc", "desc"])
17438
+ }).optional(),
17439
+ limit: zod.z.number().optional(),
17440
+ offset: zod.z.number().optional()
17441
+ });
17442
+ /** A single stored record: `{ id, data }`. */
17443
+ var SettingsRecordSchema = zod.z.object({
17444
+ id: zod.z.string(),
17445
+ data: zod.z.record(zod.z.string(), zod.z.unknown())
17446
+ });
17447
+ /**
17448
+ * Column declaration for a structured (SQL-backed) collection.
17449
+ *
17450
+ * Logical types — the backend translates each to the matching SQLite
17451
+ * storage class and handles per-type marshaling:
17452
+ * - `TEXT` / `INTEGER` / `REAL` — native SQLite types, pass-through
17453
+ * - `JSON` — TEXT under the hood; serialised on write, parsed on read
17454
+ * - `BOOLEAN` — INTEGER 0/1 under the hood; coerced both directions
17455
+ */
17456
+ var CollectionColumnSchema = zod.z.object({
17457
+ name: zod.z.string(),
17458
+ type: zod.z.enum([
17459
+ "TEXT",
17460
+ "INTEGER",
17461
+ "REAL",
17462
+ "JSON",
17463
+ "BOOLEAN"
17464
+ ]),
17465
+ primaryKey: zod.z.boolean().optional(),
17466
+ notNull: zod.z.boolean().optional(),
17467
+ unique: zod.z.boolean().optional()
17468
+ });
17469
+ var CollectionIndexSchema = zod.z.object({
17470
+ name: zod.z.string(),
17471
+ columns: zod.z.array(zod.z.string()).readonly(),
17472
+ unique: zod.z.boolean().optional()
17473
+ });
17474
+ /**
17475
+ * settings-store — singleton capability for addon-scoped persistence.
17476
+ *
17477
+ * Every method operates within a `collection`. An optional `namespace`
17478
+ * field provides access to additional data spaces beyond the default
17479
+ * addon settings — useful for business data (events, tracks, faces, etc.).
17480
+ *
17481
+ * **Scoping is the CALLER's, and it is opt-in.** The table is
17482
+ * `namespace ? `${namespace}:${collection}` : collection` — nothing
17483
+ * consults the identity of the caller. An earlier version of this comment
17484
+ * claimed the implementation prefixes every collection with the calling
17485
+ * addon's ID and that "addons never see each other's data"; that was never
17486
+ * true, and this same file contradicted it under `declareCollection`. What
17487
+ * exists is `addon-context-factory`, which passes `namespace: addonId` ON
17488
+ * THE ADDON'S BEHALF for the `addon-settings` / `addon-devices` paths only.
17489
+ * Business collections use bare names, and any caller may name any
17490
+ * namespace, or none. Making the door enforce it is tracked separately —
17491
+ * it renames tables, so it needs a migration.
17492
+ *
17493
+ * - `{ collection: 'addon-settings' }` → table `addon-settings`
17494
+ * - `{ namespace: 'my-addon', collection: 'addon-settings' }` →
17495
+ * table `my-addon:addon-settings`
17496
+ *
17497
+ * Served by the **storage-orchestrator** builtin, which dispatches to the
17498
+ * `data-store-provider` engine registered for the collection
17499
+ * (`sqlite-settings`, a SQLite WAL backend, today). One addon owns the
17500
+ * data door; engines sit behind it
17501
+ * ([D44](../../../../docs/decisions/adr-0044.md)).
17502
+ * Addons access it via `ctx.api.settingsStore.*`.
17503
+ */
17504
+ var settingsStoreCapability = {
17505
+ name: "settings-store",
17506
+ scope: "system",
17507
+ mode: "singleton",
17508
+ methods: {
17509
+ /** Get a single value by key from a collection. */
17510
+ get: require_sleep.method(zod.z.object({
17511
+ namespace: zod.z.string().optional(),
17512
+ collection: zod.z.string(),
17513
+ key: zod.z.string()
17514
+ }), zod.z.unknown()),
17515
+ /** Set a value by key in a collection (upsert). */
17516
+ set: require_sleep.method(zod.z.object({
17517
+ namespace: zod.z.string().optional(),
17518
+ collection: zod.z.string(),
17519
+ key: zod.z.string(),
17520
+ value: zod.z.unknown()
17521
+ }), zod.z.void(), { kind: "mutation" }),
17522
+ /** Get all entries matching an optional filter. */
17523
+ query: require_sleep.method(zod.z.object({
17524
+ namespace: zod.z.string().optional(),
17525
+ collection: zod.z.string(),
17526
+ filter: QueryFilterSchema.optional()
17527
+ }), zod.z.array(SettingsRecordSchema).readonly()),
17528
+ /** Insert a new record. */
17529
+ insert: require_sleep.method(zod.z.object({
17530
+ namespace: zod.z.string().optional(),
17531
+ collection: zod.z.string(),
17532
+ record: SettingsRecordSchema
17533
+ }), zod.z.void(), { kind: "mutation" }),
17534
+ /** Update an existing record by ID. */
17535
+ update: require_sleep.method(zod.z.object({
17536
+ namespace: zod.z.string().optional(),
17537
+ collection: zod.z.string(),
17538
+ id: zod.z.string(),
17539
+ data: zod.z.record(zod.z.string(), zod.z.unknown())
17540
+ }), zod.z.void(), { kind: "mutation" }),
17541
+ /** Delete a record by key/ID. */
17542
+ delete: require_sleep.method(zod.z.object({
17543
+ namespace: zod.z.string().optional(),
17544
+ collection: zod.z.string(),
17545
+ key: zod.z.string()
17546
+ }), zod.z.void(), { kind: "mutation" }),
17547
+ /** Count entries in a collection, optionally filtered. */
17548
+ count: require_sleep.method(zod.z.object({
17549
+ namespace: zod.z.string().optional(),
17550
+ collection: zod.z.string(),
17551
+ filter: QueryFilterSchema.optional()
17552
+ }), zod.z.number()),
17553
+ /** Grouped counts per ((field-origin)/bucketSize) bucket, filtered. */
17554
+ histogram: require_sleep.method(zod.z.object({
17555
+ namespace: zod.z.string().optional(),
17556
+ collection: zod.z.string(),
17557
+ field: zod.z.string(),
17558
+ bucketSize: zod.z.number().int().positive(),
17559
+ origin: zod.z.number().int(),
17560
+ filter: QueryFilterSchema.optional()
17561
+ }), zod.z.array(zod.z.object({
17562
+ bucket: zod.z.number().int(),
17563
+ count: zod.z.number().int()
17564
+ })).readonly()),
17565
+ /** Check if a collection is empty. */
17566
+ isEmpty: require_sleep.method(zod.z.object({
17567
+ namespace: zod.z.string().optional(),
17568
+ collection: zod.z.string()
17569
+ }), zod.z.boolean()),
17570
+ /**
17571
+ * Declare a typed (SQL-backed) collection with explicit columns +
17572
+ * indexes. Idempotent: re-declaring an existing collection with the
17573
+ * same shape is a no-op; shape changes (new columns, new indexes)
17574
+ * are applied additively. Subsequent `insert` / `update` / `delete`
17575
+ * / `query` calls on this collection use typed columns instead of
17576
+ * JSON-blob storage — `record.data` fields are spread across
17577
+ * columns, `query.filter.where` matches real columns (no
17578
+ * `json_extract` overhead), `orderBy` uses column indexes.
17579
+ *
17580
+ * Addons call this in `onInitialize` before their first read/write.
17581
+ * Collection names should be namespaced by addon (e.g.
17582
+ * `pipeline-analytics:object-events`) to avoid cross-addon
17583
+ * clashes — no automatic prefix is added.
17584
+ */
17585
+ declareCollection: require_sleep.method(zod.z.object({
17586
+ namespace: zod.z.string().optional(),
17587
+ collection: zod.z.string(),
17588
+ columns: zod.z.array(CollectionColumnSchema).readonly(),
17589
+ indexes: zod.z.array(CollectionIndexSchema).readonly().optional()
17590
+ }), zod.z.void(), { kind: "mutation" })
17591
+ }
17592
+ };
17593
+ //#endregion
17594
+ //#region src/capabilities/data-store-provider.cap.ts
17595
+ /**
17596
+ * What one engine says about itself. The orchestrator uses `kind` to pick
17597
+ * a registrant for a collection; `engineId` is what a log line names when
17598
+ * a call is routed or refused.
17599
+ */
17600
+ var EngineInfoSchema = zod.z.object({
17601
+ engineId: zod.z.string(),
17602
+ /**
17603
+ * `relational` — rows, columns, indexes, the surface `settings-store`
17604
+ * has always described. `vector` — an embedding store answering
17605
+ * similarity queries. A registrant declares exactly one; an engine that
17606
+ * does both registers twice, because "both" would make the routing
17607
+ * decision ambiguous at exactly the point it must not be.
17608
+ */
17609
+ kind: zod.z.enum(["relational", "vector"]),
17610
+ displayName: zod.z.string()
17611
+ });
17612
+ /**
17613
+ * data-store-provider — the engine contract behind the data door.
17614
+ *
17615
+ * The sibling of `storage-provider`, for rows instead of bytes. The
17616
+ * orchestrator (singleton `settings-store` cap, owned by the
17617
+ * storage-orchestrator builtin) dispatches every call to the registrant
17618
+ * that serves the collection.
17619
+ *
17620
+ * `internal: true` — consumed only by the orchestrator. Public consumers
17621
+ * go through `settings-store`; they never see this cap, and an engine
17622
+ * never sees a caller.
17623
+ *
17624
+ * Design notes:
17625
+ * - **Stateless dispatch.** Every method carries its own
17626
+ * `namespace` + `collection`, so an engine keeps no per-caller state
17627
+ * and the orchestrator forwards the payload verbatim. Scoping is a
17628
+ * property of the input, not of the connection — see the note on
17629
+ * `settings-store` about what that does and does not guarantee.
17630
+ * - **One registrant today** (`sqlite-settings`). The collection shape
17631
+ * exists so a second engine is a registration rather than a second
17632
+ * door ([D44](../../../../docs/decisions/adr-0044.md)).
17633
+ *
17634
+ * The method set is deliberately identical to `settings-store`'s: the
17635
+ * orchestrator is a router, not a translator. A capability the door
17636
+ * gains, an engine must be able to answer.
17637
+ */
17638
+ var dataStoreProviderCapability = {
17639
+ name: "data-store-provider",
17640
+ scope: "system",
17641
+ mode: "collection",
17642
+ internal: true,
17643
+ methods: {
17644
+ /** Self-description — how the orchestrator picks a registrant. */
17645
+ getEngineInfo: require_sleep.method(zod.z.void(), EngineInfoSchema),
17646
+ /** Get a single value by key from a collection. */
17647
+ get: require_sleep.method(zod.z.object({
17648
+ namespace: zod.z.string().optional(),
17649
+ collection: zod.z.string(),
17650
+ key: zod.z.string()
17651
+ }), zod.z.unknown()),
17652
+ /** Set a value by key in a collection (upsert). */
17653
+ set: require_sleep.method(zod.z.object({
17654
+ namespace: zod.z.string().optional(),
17655
+ collection: zod.z.string(),
17656
+ key: zod.z.string(),
17657
+ value: zod.z.unknown()
17658
+ }), zod.z.void(), { kind: "mutation" }),
17659
+ /** Get all entries matching an optional filter. */
17660
+ query: require_sleep.method(zod.z.object({
17661
+ namespace: zod.z.string().optional(),
17662
+ collection: zod.z.string(),
17663
+ filter: QueryFilterSchema.optional()
17664
+ }), zod.z.array(SettingsRecordSchema).readonly()),
17665
+ /** Insert a new record. */
17666
+ insert: require_sleep.method(zod.z.object({
17667
+ namespace: zod.z.string().optional(),
17668
+ collection: zod.z.string(),
17669
+ record: SettingsRecordSchema
17670
+ }), zod.z.void(), { kind: "mutation" }),
17671
+ /** Update an existing record by ID. */
17672
+ update: require_sleep.method(zod.z.object({
17673
+ namespace: zod.z.string().optional(),
17674
+ collection: zod.z.string(),
17675
+ id: zod.z.string(),
17676
+ data: zod.z.record(zod.z.string(), zod.z.unknown())
17677
+ }), zod.z.void(), { kind: "mutation" }),
17678
+ /** Delete a record by key/ID. */
17679
+ delete: require_sleep.method(zod.z.object({
17680
+ namespace: zod.z.string().optional(),
17681
+ collection: zod.z.string(),
17682
+ key: zod.z.string()
17683
+ }), zod.z.void(), { kind: "mutation" }),
17684
+ /** Count entries in a collection, optionally filtered. */
17685
+ count: require_sleep.method(zod.z.object({
17686
+ namespace: zod.z.string().optional(),
17687
+ collection: zod.z.string(),
17688
+ filter: QueryFilterSchema.optional()
17689
+ }), zod.z.number()),
17690
+ /** Grouped counts per ((field-origin)/bucketSize) bucket, filtered. */
17691
+ histogram: require_sleep.method(zod.z.object({
17692
+ namespace: zod.z.string().optional(),
17693
+ collection: zod.z.string(),
17694
+ field: zod.z.string(),
17695
+ bucketSize: zod.z.number().int().positive(),
17696
+ origin: zod.z.number().int(),
17697
+ filter: QueryFilterSchema.optional()
17698
+ }), zod.z.array(zod.z.object({
17699
+ bucket: zod.z.number().int(),
17700
+ count: zod.z.number().int()
17701
+ })).readonly()),
17702
+ /** Check if a collection is empty. */
17703
+ isEmpty: require_sleep.method(zod.z.object({
17704
+ namespace: zod.z.string().optional(),
17705
+ collection: zod.z.string()
17706
+ }), zod.z.boolean()),
17707
+ /** Declare a typed (SQL-backed) collection with columns + indexes. */
17708
+ declareCollection: require_sleep.method(zod.z.object({
17709
+ namespace: zod.z.string().optional(),
17710
+ collection: zod.z.string(),
17711
+ columns: zod.z.array(CollectionColumnSchema).readonly(),
17712
+ indexes: zod.z.array(CollectionIndexSchema).readonly().optional()
17713
+ }), zod.z.void(), { kind: "mutation" })
17714
+ }
17715
+ };
17716
+ //#endregion
17434
17717
  //#region src/capabilities/detection-pipeline.cap.ts
17435
17718
  /**
17436
17719
  * detection-pipeline — device-scoped facade over the system
@@ -21913,6 +22196,52 @@ var ServerUpdateStateSchema = zod.z.enum([
21913
22196
  "pending-restart",
21914
22197
  "awaiting-confirmation"
21915
22198
  ]);
22199
+ /**
22200
+ * Verdict of comparing the node's IMMUTABLE baked seed (the Docker image / the
22201
+ * desktop app bundle) against the release the deployment contract would
22202
+ * deliver today. `applyServerUpdate` swaps the data-root closure and NEVER
22203
+ * touches the image, so `runningVersion` can be perfectly current while the
22204
+ * container is weeks old, from a renamed repository nothing rebuilds — which
22205
+ * is exactly what happened on 2026-08-02 (hub on `camstack-server:intel-1.1.74`
22206
+ * while every existing surface said "up to date"). The seed version is the one
22207
+ * image fingerprint a container can see from inside (no docker socket).
22208
+ *
22209
+ * - `in-sync` — seed equals the current release; the node runs the
22210
+ * contract image.
22211
+ * - `behind-patch` — same release series, older patch: the image predates
22212
+ * the current release. Normal between deliberate image
22213
+ * refreshes, but the starter/entrypoint are still old.
22214
+ * - `behind-series` — the seed's major/minor predates the current release
22215
+ * series. The shape of a pinned tag or a dead image
22216
+ * repository; a `docker pull` may fix nothing.
22217
+ * - `ahead` — seed newer than the best-known release (stale registry
22218
+ * check).
22219
+ * - `unknown` — no seed (dev workspace) or nothing to compare against
22220
+ * yet.
22221
+ */
22222
+ var ImageContractStateSchema = zod.z.enum([
22223
+ "in-sync",
22224
+ "behind-patch",
22225
+ "behind-series",
22226
+ "ahead",
22227
+ "unknown"
22228
+ ]);
22229
+ var ImageContractSchema = zod.z.object({
22230
+ state: ImageContractStateSchema,
22231
+ /** The baked seed closure version — the image/app-bundle fingerprint. */
22232
+ seedVersion: zod.z.string().nullable(),
22233
+ /** Best-known version the deployment contract delivers today. */
22234
+ contractVersion: zod.z.string().nullable(),
22235
+ /**
22236
+ * Where `contractVersion` came from: a real registry check (`registry`), or
22237
+ * the node's own running version (`running` — a node can never run code
22238
+ * newer than the newest release, so `seed < running` proves image staleness
22239
+ * even before any registry check has run).
22240
+ */
22241
+ contractSource: zod.z.enum(["registry", "running"]).nullable(),
22242
+ /** One operator-grade sentence: this node runs image X; the contract says Y. */
22243
+ message: zod.z.string()
22244
+ });
21916
22245
  var ServerRollbackInfoSchema = zod.z.object({
21917
22246
  /** The version that failed (or was manually rolled back). */
21918
22247
  fromVersion: zod.z.string(),
@@ -21949,7 +22278,12 @@ var ServerPackageStatusSchema = zod.z.object({
21949
22278
  * versions are being IGNORED. Surfaced as a warning in the UI.
21950
22279
  */
21951
22280
  stateFileCorrupt: zod.z.boolean(),
21952
- lastCheckedAtMs: zod.z.number().nullable()
22281
+ lastCheckedAtMs: zod.z.number().nullable(),
22282
+ /**
22283
+ * Seed-vs-contract verdict (see {@link ImageContractSchema}). Optional for
22284
+ * version skew: an older provider's payload simply omits it.
22285
+ */
22286
+ imageContract: ImageContractSchema.optional()
21953
22287
  });
21954
22288
  var ServerUpdateCheckResultSchema = zod.z.object({
21955
22289
  packageName: zod.z.string(),
@@ -22004,160 +22338,6 @@ version: zod.z.string().optional() }), ServerUpdateActionResultSchema, {
22004
22338
  mount: { kind: "server-provided" }
22005
22339
  };
22006
22340
  //#endregion
22007
- //#region src/capabilities/settings-store.cap.ts
22008
- /**
22009
- * Query filter for settings-store collections.
22010
- */
22011
- var QueryFilterSchema = zod.z.object({
22012
- where: zod.z.record(zod.z.string(), zod.z.unknown()).optional(),
22013
- whereIn: zod.z.record(zod.z.string(), zod.z.array(zod.z.unknown())).optional(),
22014
- whereBetween: zod.z.record(zod.z.string(), zod.z.tuple([zod.z.unknown(), zod.z.unknown()])).optional(),
22015
- orderBy: zod.z.object({
22016
- field: zod.z.string(),
22017
- direction: zod.z.enum(["asc", "desc"])
22018
- }).optional(),
22019
- limit: zod.z.number().optional(),
22020
- offset: zod.z.number().optional()
22021
- });
22022
- /** A single stored record: `{ id, data }`. */
22023
- var SettingsRecordSchema = zod.z.object({
22024
- id: zod.z.string(),
22025
- data: zod.z.record(zod.z.string(), zod.z.unknown())
22026
- });
22027
- /**
22028
- * Column declaration for a structured (SQL-backed) collection.
22029
- *
22030
- * Logical types — the backend translates each to the matching SQLite
22031
- * storage class and handles per-type marshaling:
22032
- * - `TEXT` / `INTEGER` / `REAL` — native SQLite types, pass-through
22033
- * - `JSON` — TEXT under the hood; serialised on write, parsed on read
22034
- * - `BOOLEAN` — INTEGER 0/1 under the hood; coerced both directions
22035
- */
22036
- var CollectionColumnSchema = zod.z.object({
22037
- name: zod.z.string(),
22038
- type: zod.z.enum([
22039
- "TEXT",
22040
- "INTEGER",
22041
- "REAL",
22042
- "JSON",
22043
- "BOOLEAN"
22044
- ]),
22045
- primaryKey: zod.z.boolean().optional(),
22046
- notNull: zod.z.boolean().optional(),
22047
- unique: zod.z.boolean().optional()
22048
- });
22049
- var CollectionIndexSchema = zod.z.object({
22050
- name: zod.z.string(),
22051
- columns: zod.z.array(zod.z.string()).readonly(),
22052
- unique: zod.z.boolean().optional()
22053
- });
22054
- /**
22055
- * settings-store — singleton capability for addon-scoped persistence.
22056
- *
22057
- * Every method operates within a `collection`. An optional `namespace`
22058
- * field provides access to additional data spaces beyond the default
22059
- * addon settings — useful for business data (events, tracks, faces, etc.).
22060
- *
22061
- * Scoping: the implementation prefixes every collection with the calling
22062
- * addon's ID automatically. Addons never see each other's data.
22063
- *
22064
- * - No namespace (default): `"addon-settings"` → `"<addonId>:addon-settings"`
22065
- * - With namespace: `{ namespace: 'events', collection: 'detections' }` →
22066
- * `"<addonId>:events:detections"`
22067
- *
22068
- * Implemented by `@camstack/system/builtins/sqlite-settings` (SQLite WAL backend).
22069
- * Addons access it via `ctx.api.settingsStore.*`.
22070
- */
22071
- var settingsStoreCapability = {
22072
- name: "settings-store",
22073
- scope: "system",
22074
- mode: "singleton",
22075
- methods: {
22076
- /** Get a single value by key from a collection. */
22077
- get: require_sleep.method(zod.z.object({
22078
- namespace: zod.z.string().optional(),
22079
- collection: zod.z.string(),
22080
- key: zod.z.string()
22081
- }), zod.z.unknown()),
22082
- /** Set a value by key in a collection (upsert). */
22083
- set: require_sleep.method(zod.z.object({
22084
- namespace: zod.z.string().optional(),
22085
- collection: zod.z.string(),
22086
- key: zod.z.string(),
22087
- value: zod.z.unknown()
22088
- }), zod.z.void(), { kind: "mutation" }),
22089
- /** Get all entries matching an optional filter. */
22090
- query: require_sleep.method(zod.z.object({
22091
- namespace: zod.z.string().optional(),
22092
- collection: zod.z.string(),
22093
- filter: QueryFilterSchema.optional()
22094
- }), zod.z.array(SettingsRecordSchema).readonly()),
22095
- /** Insert a new record. */
22096
- insert: require_sleep.method(zod.z.object({
22097
- namespace: zod.z.string().optional(),
22098
- collection: zod.z.string(),
22099
- record: SettingsRecordSchema
22100
- }), zod.z.void(), { kind: "mutation" }),
22101
- /** Update an existing record by ID. */
22102
- update: require_sleep.method(zod.z.object({
22103
- namespace: zod.z.string().optional(),
22104
- collection: zod.z.string(),
22105
- id: zod.z.string(),
22106
- data: zod.z.record(zod.z.string(), zod.z.unknown())
22107
- }), zod.z.void(), { kind: "mutation" }),
22108
- /** Delete a record by key/ID. */
22109
- delete: require_sleep.method(zod.z.object({
22110
- namespace: zod.z.string().optional(),
22111
- collection: zod.z.string(),
22112
- key: zod.z.string()
22113
- }), zod.z.void(), { kind: "mutation" }),
22114
- /** Count entries in a collection, optionally filtered. */
22115
- count: require_sleep.method(zod.z.object({
22116
- namespace: zod.z.string().optional(),
22117
- collection: zod.z.string(),
22118
- filter: QueryFilterSchema.optional()
22119
- }), zod.z.number()),
22120
- /** Grouped counts per ((field-origin)/bucketSize) bucket, filtered. */
22121
- histogram: require_sleep.method(zod.z.object({
22122
- namespace: zod.z.string().optional(),
22123
- collection: zod.z.string(),
22124
- field: zod.z.string(),
22125
- bucketSize: zod.z.number().int().positive(),
22126
- origin: zod.z.number().int(),
22127
- filter: QueryFilterSchema.optional()
22128
- }), zod.z.array(zod.z.object({
22129
- bucket: zod.z.number().int(),
22130
- count: zod.z.number().int()
22131
- })).readonly()),
22132
- /** Check if a collection is empty. */
22133
- isEmpty: require_sleep.method(zod.z.object({
22134
- namespace: zod.z.string().optional(),
22135
- collection: zod.z.string()
22136
- }), zod.z.boolean()),
22137
- /**
22138
- * Declare a typed (SQL-backed) collection with explicit columns +
22139
- * indexes. Idempotent: re-declaring an existing collection with the
22140
- * same shape is a no-op; shape changes (new columns, new indexes)
22141
- * are applied additively. Subsequent `insert` / `update` / `delete`
22142
- * / `query` calls on this collection use typed columns instead of
22143
- * JSON-blob storage — `record.data` fields are spread across
22144
- * columns, `query.filter.where` matches real columns (no
22145
- * `json_extract` overhead), `orderBy` uses column indexes.
22146
- *
22147
- * Addons call this in `onInitialize` before their first read/write.
22148
- * Collection names should be namespaced by addon (e.g.
22149
- * `pipeline-analytics:object-events`) to avoid cross-addon
22150
- * clashes — no automatic prefix is added.
22151
- */
22152
- declareCollection: require_sleep.method(zod.z.object({
22153
- namespace: zod.z.string().optional(),
22154
- collection: zod.z.string(),
22155
- columns: zod.z.array(CollectionColumnSchema).readonly(),
22156
- indexes: zod.z.array(CollectionIndexSchema).readonly().optional()
22157
- }), zod.z.void(), { kind: "mutation" })
22158
- }
22159
- };
22160
- //#endregion
22161
22341
  //#region src/capabilities/smtp-provider.cap.ts
22162
22342
  /**
22163
22343
  * `smtp-provider` — pluggable email delivery surface.
@@ -25925,7 +26105,7 @@ var recordingCapability = {
25925
26105
  auth: "admin"
25926
26106
  }),
25927
26107
  /**
25928
- * Move footage (segments and/or strips) from one recordings location to
26108
+ * Move footage (recorded segments) from one recordings location to
25929
26109
  * another — the drain workflow's mover (entity-routing spec Phase 4).
25930
26110
  * Throttled copy → size-verify → delete source → index refresh; resumable
25931
26111
  * by construction (copy-if-absent). Single-flight: one job at a time.
@@ -26840,6 +27020,7 @@ var CAPABILITY_NAMES = {
26840
27020
  control: "control",
26841
27021
  cover: "cover",
26842
27022
  customModelRegistry: "custom-model-registry",
27023
+ dataStoreProvider: "data-store-provider",
26843
27024
  dayNight: "day-night",
26844
27025
  decoder: "decoder",
26845
27026
  detectionPipeline: "detection-pipeline",
@@ -27097,6 +27278,10 @@ var CAPABILITY_ROUTER_KEYS = [
27097
27278
  key: "customModelRegistry",
27098
27279
  name: "custom-model-registry"
27099
27280
  },
27281
+ {
27282
+ key: "dataStoreProvider",
27283
+ name: "data-store-provider"
27284
+ },
27100
27285
  {
27101
27286
  key: "dayNight",
27102
27287
  name: "day-night"
@@ -27569,6 +27754,7 @@ var ALL_CAPABILITY_DEFINITIONS = [
27569
27754
  controlCapability,
27570
27755
  coverCapability,
27571
27756
  customModelRegistryCapability,
27757
+ dataStoreProviderCapability,
27572
27758
  dayNightCapability,
27573
27759
  decoderCapability,
27574
27760
  detectionPipelineCapability,
@@ -28578,6 +28764,72 @@ var METHOD_ACCESS_MAP = Object.freeze({
28578
28764
  addonId: null,
28579
28765
  access: "view"
28580
28766
  },
28767
+ "dataStoreProvider.count": {
28768
+ capName: "data-store-provider",
28769
+ capScope: "system",
28770
+ addonId: null,
28771
+ access: "view"
28772
+ },
28773
+ "dataStoreProvider.declareCollection": {
28774
+ capName: "data-store-provider",
28775
+ capScope: "system",
28776
+ addonId: null,
28777
+ access: "create"
28778
+ },
28779
+ "dataStoreProvider.delete": {
28780
+ capName: "data-store-provider",
28781
+ capScope: "system",
28782
+ addonId: null,
28783
+ access: "delete"
28784
+ },
28785
+ "dataStoreProvider.get": {
28786
+ capName: "data-store-provider",
28787
+ capScope: "system",
28788
+ addonId: null,
28789
+ access: "view"
28790
+ },
28791
+ "dataStoreProvider.getEngineInfo": {
28792
+ capName: "data-store-provider",
28793
+ capScope: "system",
28794
+ addonId: null,
28795
+ access: "view"
28796
+ },
28797
+ "dataStoreProvider.histogram": {
28798
+ capName: "data-store-provider",
28799
+ capScope: "system",
28800
+ addonId: null,
28801
+ access: "view"
28802
+ },
28803
+ "dataStoreProvider.insert": {
28804
+ capName: "data-store-provider",
28805
+ capScope: "system",
28806
+ addonId: null,
28807
+ access: "create"
28808
+ },
28809
+ "dataStoreProvider.isEmpty": {
28810
+ capName: "data-store-provider",
28811
+ capScope: "system",
28812
+ addonId: null,
28813
+ access: "view"
28814
+ },
28815
+ "dataStoreProvider.query": {
28816
+ capName: "data-store-provider",
28817
+ capScope: "system",
28818
+ addonId: null,
28819
+ access: "view"
28820
+ },
28821
+ "dataStoreProvider.set": {
28822
+ capName: "data-store-provider",
28823
+ capScope: "system",
28824
+ addonId: null,
28825
+ access: "create"
28826
+ },
28827
+ "dataStoreProvider.update": {
28828
+ capName: "data-store-provider",
28829
+ capScope: "system",
28830
+ addonId: null,
28831
+ access: "create"
28832
+ },
28581
28833
  "dayNight.getOptions": {
28582
28834
  capName: "day-night",
28583
28835
  capScope: "device",
@@ -32745,6 +32997,7 @@ var KNOWN_CAP_NAMES = [
32745
32997
  "control",
32746
32998
  "cover",
32747
32999
  "custom-model-registry",
33000
+ "data-store-provider",
32748
33001
  "day-night",
32749
33002
  "decoder",
32750
33003
  "device-adoption",
@@ -32907,6 +33160,7 @@ var SYSTEM_CAP_NAMES = [
32907
33160
  "backup",
32908
33161
  "broker",
32909
33162
  "custom-model-registry",
33163
+ "data-store-provider",
32910
33164
  "decoder",
32911
33165
  "device-adoption",
32912
33166
  "device-export",
@@ -33727,6 +33981,7 @@ exports.DEVICE_SETTINGS_CONTRIBUTION_METHODS = require_sleep.DEVICE_SETTINGS_CON
33727
33981
  exports.DEVICE_STATUS_METHOD = require_sleep.DEVICE_STATUS_METHOD;
33728
33982
  exports.DEVICE_TYPE_CONTROL_KIND = DEVICE_TYPE_CONTROL_KIND;
33729
33983
  exports.DEVICE_TYPE_INFO = DEVICE_TYPE_INFO;
33984
+ exports.DataStoreEngineInfoSchema = EngineInfoSchema;
33730
33985
  exports.DayNightModeSchema = DayNightModeSchema;
33731
33986
  exports.DayNightOptionsSchema = DayNightOptionsSchema;
33732
33987
  exports.DayNightSettingsPatchSchema = DayNightSettingsPatchSchema;
@@ -33816,6 +34071,8 @@ exports.HistoryResolutionEnum = HistoryResolutionEnum;
33816
34071
  exports.HumidifierStatusSchema = HumidifierStatusSchema;
33817
34072
  exports.HumiditySensorStatusSchema = HumiditySensorStatusSchema;
33818
34073
  exports.HvacModeSchema = HvacModeSchema;
34074
+ exports.ImageContractSchema = ImageContractSchema;
34075
+ exports.ImageContractStateSchema = ImageContractStateSchema;
33819
34076
  exports.ImageRotateSchema = ImageRotateSchema;
33820
34077
  exports.ImageSettingsOptionsSchema = ImageSettingsOptionsSchema;
33821
34078
  exports.ImageSettingsPatchSchema = ImageSettingsPatchSchema;
@@ -34284,6 +34541,7 @@ exports.createSliceHandle = require_sleep.createSliceHandle;
34284
34541
  exports.createSystemProxy = createSystemProxy;
34285
34542
  exports.customAction = customAction;
34286
34543
  exports.customModelRegistryCapability = customModelRegistryCapability;
34544
+ exports.dataStoreProviderCapability = dataStoreProviderCapability;
34287
34545
  exports.dayNightCapability = dayNightCapability;
34288
34546
  exports.decoderCapability = decoderCapability;
34289
34547
  exports.defaultDeviceFor = defaultDeviceFor;