@camstack/system 1.2.27 → 1.2.29
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/addon-runner.js +3 -3
- package/dist/addon-runner.mjs +2 -2
- package/dist/builtins/addon-pages-aggregator/addon-pages-aggregator.addon.js +1 -1
- package/dist/builtins/addon-pages-aggregator/addon-pages-aggregator.addon.mjs +1 -1
- package/dist/builtins/addon-widgets-aggregator/addon-widgets-aggregator.addon.js +1 -1
- package/dist/builtins/addon-widgets-aggregator/addon-widgets-aggregator.addon.mjs +1 -1
- package/dist/builtins/alerts/alerts.addon.d.ts +0 -7
- package/dist/builtins/alerts/alerts.addon.js +47 -25
- package/dist/builtins/alerts/alerts.addon.mjs +47 -25
- package/dist/builtins/alerts/prune-policy.d.ts +44 -0
- package/dist/builtins/backup-orchestrator/backup-orchestrator.addon.js +1 -1
- package/dist/builtins/backup-orchestrator/backup-orchestrator.addon.mjs +1 -1
- package/dist/builtins/console-logging/index.js +1 -1
- package/dist/builtins/console-logging/index.mjs +1 -1
- package/dist/builtins/device-manager/device-manager.addon.js +1 -1
- package/dist/builtins/device-manager/device-manager.addon.mjs +1 -1
- package/dist/builtins/doorbell/virtual-doorbell.addon.js +1 -1
- package/dist/builtins/doorbell/virtual-doorbell.addon.mjs +1 -1
- package/dist/builtins/hub-forwarder/index.js +1 -1
- package/dist/builtins/hub-forwarder/index.mjs +1 -1
- package/dist/builtins/local-auth/local-auth.addon.js +1 -1
- package/dist/builtins/local-auth/local-auth.addon.mjs +1 -1
- package/dist/builtins/local-network/local-network.addon.js +1 -1
- package/dist/builtins/local-network/local-network.addon.mjs +1 -1
- package/dist/builtins/loki-logging/index.js +1 -1
- package/dist/builtins/loki-logging/index.mjs +1 -1
- package/dist/builtins/native-metrics/native-metrics.addon.js +1 -1
- package/dist/builtins/native-metrics/native-metrics.addon.mjs +1 -1
- package/dist/builtins/platform-probe/index.js +1 -1
- package/dist/builtins/platform-probe/index.mjs +1 -1
- package/dist/builtins/remote-access-orchestrator/remote-access-orchestrator.addon.js +1 -1
- package/dist/builtins/remote-access-orchestrator/remote-access-orchestrator.addon.mjs +1 -1
- package/dist/builtins/snapshot/index.js +1 -1
- package/dist/builtins/snapshot/index.mjs +1 -1
- package/dist/builtins/sqlite-storage/filesystem-storage.addon.js +1 -1
- package/dist/builtins/sqlite-storage/filesystem-storage.addon.mjs +1 -1
- package/dist/builtins/sqlite-storage/sqlite-settings-backend.d.ts +7 -1
- package/dist/builtins/sqlite-storage/sqlite-settings.addon.d.ts +8 -2
- package/dist/builtins/sqlite-storage/sqlite-settings.addon.js +22 -4
- package/dist/builtins/sqlite-storage/sqlite-settings.addon.mjs +22 -4
- package/dist/builtins/storage-orchestrator/data-store-dispatch.d.ts +12 -0
- package/dist/builtins/storage-orchestrator/storage-orchestrator.addon.d.ts +18 -7
- package/dist/builtins/storage-orchestrator/storage-orchestrator.addon.js +78 -11
- package/dist/builtins/storage-orchestrator/storage-orchestrator.addon.mjs +78 -11
- package/dist/builtins/system-config/system-config.addon.js +1 -1
- package/dist/builtins/system-config/system-config.addon.mjs +1 -1
- package/dist/builtins/winston-logging/index.js +1 -1
- package/dist/builtins/winston-logging/index.mjs +1 -1
- package/dist/{dist-BXmFvn3h.mjs → dist-B7hOpr5i.mjs} +411 -166
- package/dist/{dist-BxtIzexq.js → dist-CPmFYLqq.js} +416 -165
- package/dist/index.d.ts +2 -0
- package/dist/index.js +106 -2
- package/dist/index.mjs +102 -3
- package/dist/kernel/heap-watch.d.ts +36 -0
- package/dist/kernel/transport/uds-event-bus.d.ts +4 -1
- package/dist/{manifest-python-deps-KZ00cbfP.js → manifest-python-deps-BqE5j0-O.js} +25 -4
- package/dist/{manifest-python-deps-BNOApgK0.mjs → manifest-python-deps-Ck4-9K9m.mjs} +25 -4
- package/package.json +7 -3
|
@@ -3381,14 +3381,7 @@ var RecordingConfigSchema = zod.z.object({
|
|
|
3381
3381
|
* windows only — existing sheets are immutable, and each window's index
|
|
3382
3382
|
* carries its own tile dims so mixed-preset history renders correctly.
|
|
3383
3383
|
*/
|
|
3384
|
-
scrubThumbnails: ScrubThumbnailPresetSchema.optional()
|
|
3385
|
-
/**
|
|
3386
|
-
* OPT-IN thumbnail-strip generation for this camera: every keyframe of the
|
|
3387
|
-
* low recording saved as a JPEG (the fast-drag scrub depth), a derived
|
|
3388
|
-
* cache that eviction reclaims with the footage. Absent/false = no strips
|
|
3389
|
-
* are written and scrub reads exact keyframes at every velocity.
|
|
3390
|
-
*/
|
|
3391
|
-
stripsEnabled: zod.z.boolean().optional()
|
|
3384
|
+
scrubThumbnails: ScrubThumbnailPresetSchema.optional()
|
|
3392
3385
|
}).strict();
|
|
3393
3386
|
/**
|
|
3394
3387
|
* Ops-log — the durable, append-only operations audit shared by the
|
|
@@ -3450,7 +3443,7 @@ var OpsLogQueryInputSchema = zod.z.object({
|
|
|
3450
3443
|
/**
|
|
3451
3444
|
* Entity-relocation job state (storage entity-routing spec, Phase 4).
|
|
3452
3445
|
*
|
|
3453
|
-
* One shape shared by the recorder's `relocateFootage` (segments
|
|
3446
|
+
* One shape shared by the recorder's `relocateFootage` (segments) and
|
|
3454
3447
|
* pipeline-analytics' `relocateMedia` (event media blobs) so the admin Data
|
|
3455
3448
|
* page renders both movers with one component. Jobs are in-RAM (a restart
|
|
3456
3449
|
* forgets them — re-running is safe by construction: copy-if-absent, delete
|
|
@@ -3472,7 +3465,7 @@ var RelocateJobSchema = zod.z.object({
|
|
|
3472
3465
|
toLocationId: zod.z.string(),
|
|
3473
3466
|
/** Scoped device, or null = every device. */
|
|
3474
3467
|
deviceId: zod.z.number().nullable(),
|
|
3475
|
-
/** What the job moves (owner-addon specific: segments
|
|
3468
|
+
/** What the job moves (owner-addon specific: segments or media). */
|
|
3476
3469
|
entities: zod.z.array(zod.z.string()),
|
|
3477
3470
|
filesMoved: zod.z.number().int(),
|
|
3478
3471
|
bytesMoved: zod.z.number().int(),
|
|
@@ -3486,7 +3479,7 @@ var RelocateFootageInputSchema = zod.z.object({
|
|
|
3486
3479
|
deviceId: zod.z.number().optional(),
|
|
3487
3480
|
fromLocationId: zod.z.string(),
|
|
3488
3481
|
toLocationId: zod.z.string(),
|
|
3489
|
-
entities: zod.z.array(zod.z.enum(["segments"
|
|
3482
|
+
entities: zod.z.array(zod.z.enum(["segments"])).optional(),
|
|
3490
3483
|
/** Copy throttle in MB/s (default 40) — the drain is a background chore,
|
|
3491
3484
|
* never allowed to starve live writers. */
|
|
3492
3485
|
throttleMbps: zod.z.number().min(1).max(1e3).optional()
|
|
@@ -14538,6 +14531,292 @@ var decoderCapability = {
|
|
|
14538
14531
|
}
|
|
14539
14532
|
};
|
|
14540
14533
|
/**
|
|
14534
|
+
* Query filter for settings-store collections.
|
|
14535
|
+
*/
|
|
14536
|
+
var QueryFilterSchema = zod.z.object({
|
|
14537
|
+
where: zod.z.record(zod.z.string(), zod.z.unknown()).optional(),
|
|
14538
|
+
whereIn: zod.z.record(zod.z.string(), zod.z.array(zod.z.unknown())).optional(),
|
|
14539
|
+
whereBetween: zod.z.record(zod.z.string(), zod.z.tuple([zod.z.unknown(), zod.z.unknown()])).optional(),
|
|
14540
|
+
orderBy: zod.z.object({
|
|
14541
|
+
field: zod.z.string(),
|
|
14542
|
+
direction: zod.z.enum(["asc", "desc"])
|
|
14543
|
+
}).optional(),
|
|
14544
|
+
limit: zod.z.number().optional(),
|
|
14545
|
+
offset: zod.z.number().optional()
|
|
14546
|
+
});
|
|
14547
|
+
/** A single stored record: `{ id, data }`. */
|
|
14548
|
+
var SettingsRecordSchema = zod.z.object({
|
|
14549
|
+
id: zod.z.string(),
|
|
14550
|
+
data: zod.z.record(zod.z.string(), zod.z.unknown())
|
|
14551
|
+
});
|
|
14552
|
+
/**
|
|
14553
|
+
* Column declaration for a structured (SQL-backed) collection.
|
|
14554
|
+
*
|
|
14555
|
+
* Logical types — the backend translates each to the matching SQLite
|
|
14556
|
+
* storage class and handles per-type marshaling:
|
|
14557
|
+
* - `TEXT` / `INTEGER` / `REAL` — native SQLite types, pass-through
|
|
14558
|
+
* - `JSON` — TEXT under the hood; serialised on write, parsed on read
|
|
14559
|
+
* - `BOOLEAN` — INTEGER 0/1 under the hood; coerced both directions
|
|
14560
|
+
*/
|
|
14561
|
+
var CollectionColumnSchema = zod.z.object({
|
|
14562
|
+
name: zod.z.string(),
|
|
14563
|
+
type: zod.z.enum([
|
|
14564
|
+
"TEXT",
|
|
14565
|
+
"INTEGER",
|
|
14566
|
+
"REAL",
|
|
14567
|
+
"JSON",
|
|
14568
|
+
"BOOLEAN"
|
|
14569
|
+
]),
|
|
14570
|
+
primaryKey: zod.z.boolean().optional(),
|
|
14571
|
+
notNull: zod.z.boolean().optional(),
|
|
14572
|
+
unique: zod.z.boolean().optional()
|
|
14573
|
+
});
|
|
14574
|
+
var CollectionIndexSchema = zod.z.object({
|
|
14575
|
+
name: zod.z.string(),
|
|
14576
|
+
columns: zod.z.array(zod.z.string()).readonly(),
|
|
14577
|
+
unique: zod.z.boolean().optional()
|
|
14578
|
+
});
|
|
14579
|
+
/**
|
|
14580
|
+
* settings-store — singleton capability for addon-scoped persistence.
|
|
14581
|
+
*
|
|
14582
|
+
* Every method operates within a `collection`. An optional `namespace`
|
|
14583
|
+
* field provides access to additional data spaces beyond the default
|
|
14584
|
+
* addon settings — useful for business data (events, tracks, faces, etc.).
|
|
14585
|
+
*
|
|
14586
|
+
* **Scoping is the CALLER's, and it is opt-in.** The table is
|
|
14587
|
+
* `namespace ? `${namespace}:${collection}` : collection` — nothing
|
|
14588
|
+
* consults the identity of the caller. An earlier version of this comment
|
|
14589
|
+
* claimed the implementation prefixes every collection with the calling
|
|
14590
|
+
* addon's ID and that "addons never see each other's data"; that was never
|
|
14591
|
+
* true, and this same file contradicted it under `declareCollection`. What
|
|
14592
|
+
* exists is `addon-context-factory`, which passes `namespace: addonId` ON
|
|
14593
|
+
* THE ADDON'S BEHALF for the `addon-settings` / `addon-devices` paths only.
|
|
14594
|
+
* Business collections use bare names, and any caller may name any
|
|
14595
|
+
* namespace, or none. Making the door enforce it is tracked separately —
|
|
14596
|
+
* it renames tables, so it needs a migration.
|
|
14597
|
+
*
|
|
14598
|
+
* - `{ collection: 'addon-settings' }` → table `addon-settings`
|
|
14599
|
+
* - `{ namespace: 'my-addon', collection: 'addon-settings' }` →
|
|
14600
|
+
* table `my-addon:addon-settings`
|
|
14601
|
+
*
|
|
14602
|
+
* Served by the **storage-orchestrator** builtin, which dispatches to the
|
|
14603
|
+
* `data-store-provider` engine registered for the collection
|
|
14604
|
+
* (`sqlite-settings`, a SQLite WAL backend, today). One addon owns the
|
|
14605
|
+
* data door; engines sit behind it
|
|
14606
|
+
* ([D44](../../../../docs/decisions/adr-0044.md)).
|
|
14607
|
+
* Addons access it via `ctx.api.settingsStore.*`.
|
|
14608
|
+
*/
|
|
14609
|
+
var settingsStoreCapability = {
|
|
14610
|
+
name: "settings-store",
|
|
14611
|
+
scope: "system",
|
|
14612
|
+
mode: "singleton",
|
|
14613
|
+
methods: {
|
|
14614
|
+
/** Get a single value by key from a collection. */
|
|
14615
|
+
get: method(zod.z.object({
|
|
14616
|
+
namespace: zod.z.string().optional(),
|
|
14617
|
+
collection: zod.z.string(),
|
|
14618
|
+
key: zod.z.string()
|
|
14619
|
+
}), zod.z.unknown()),
|
|
14620
|
+
/** Set a value by key in a collection (upsert). */
|
|
14621
|
+
set: method(zod.z.object({
|
|
14622
|
+
namespace: zod.z.string().optional(),
|
|
14623
|
+
collection: zod.z.string(),
|
|
14624
|
+
key: zod.z.string(),
|
|
14625
|
+
value: zod.z.unknown()
|
|
14626
|
+
}), zod.z.void(), { kind: "mutation" }),
|
|
14627
|
+
/** Get all entries matching an optional filter. */
|
|
14628
|
+
query: method(zod.z.object({
|
|
14629
|
+
namespace: zod.z.string().optional(),
|
|
14630
|
+
collection: zod.z.string(),
|
|
14631
|
+
filter: QueryFilterSchema.optional()
|
|
14632
|
+
}), zod.z.array(SettingsRecordSchema).readonly()),
|
|
14633
|
+
/** Insert a new record. */
|
|
14634
|
+
insert: method(zod.z.object({
|
|
14635
|
+
namespace: zod.z.string().optional(),
|
|
14636
|
+
collection: zod.z.string(),
|
|
14637
|
+
record: SettingsRecordSchema
|
|
14638
|
+
}), zod.z.void(), { kind: "mutation" }),
|
|
14639
|
+
/** Update an existing record by ID. */
|
|
14640
|
+
update: method(zod.z.object({
|
|
14641
|
+
namespace: zod.z.string().optional(),
|
|
14642
|
+
collection: zod.z.string(),
|
|
14643
|
+
id: zod.z.string(),
|
|
14644
|
+
data: zod.z.record(zod.z.string(), zod.z.unknown())
|
|
14645
|
+
}), zod.z.void(), { kind: "mutation" }),
|
|
14646
|
+
/** Delete a record by key/ID. */
|
|
14647
|
+
delete: method(zod.z.object({
|
|
14648
|
+
namespace: zod.z.string().optional(),
|
|
14649
|
+
collection: zod.z.string(),
|
|
14650
|
+
key: zod.z.string()
|
|
14651
|
+
}), zod.z.void(), { kind: "mutation" }),
|
|
14652
|
+
/** Count entries in a collection, optionally filtered. */
|
|
14653
|
+
count: method(zod.z.object({
|
|
14654
|
+
namespace: zod.z.string().optional(),
|
|
14655
|
+
collection: zod.z.string(),
|
|
14656
|
+
filter: QueryFilterSchema.optional()
|
|
14657
|
+
}), zod.z.number()),
|
|
14658
|
+
/** Grouped counts per ((field-origin)/bucketSize) bucket, filtered. */
|
|
14659
|
+
histogram: method(zod.z.object({
|
|
14660
|
+
namespace: zod.z.string().optional(),
|
|
14661
|
+
collection: zod.z.string(),
|
|
14662
|
+
field: zod.z.string(),
|
|
14663
|
+
bucketSize: zod.z.number().int().positive(),
|
|
14664
|
+
origin: zod.z.number().int(),
|
|
14665
|
+
filter: QueryFilterSchema.optional()
|
|
14666
|
+
}), zod.z.array(zod.z.object({
|
|
14667
|
+
bucket: zod.z.number().int(),
|
|
14668
|
+
count: zod.z.number().int()
|
|
14669
|
+
})).readonly()),
|
|
14670
|
+
/** Check if a collection is empty. */
|
|
14671
|
+
isEmpty: method(zod.z.object({
|
|
14672
|
+
namespace: zod.z.string().optional(),
|
|
14673
|
+
collection: zod.z.string()
|
|
14674
|
+
}), zod.z.boolean()),
|
|
14675
|
+
/**
|
|
14676
|
+
* Declare a typed (SQL-backed) collection with explicit columns +
|
|
14677
|
+
* indexes. Idempotent: re-declaring an existing collection with the
|
|
14678
|
+
* same shape is a no-op; shape changes (new columns, new indexes)
|
|
14679
|
+
* are applied additively. Subsequent `insert` / `update` / `delete`
|
|
14680
|
+
* / `query` calls on this collection use typed columns instead of
|
|
14681
|
+
* JSON-blob storage — `record.data` fields are spread across
|
|
14682
|
+
* columns, `query.filter.where` matches real columns (no
|
|
14683
|
+
* `json_extract` overhead), `orderBy` uses column indexes.
|
|
14684
|
+
*
|
|
14685
|
+
* Addons call this in `onInitialize` before their first read/write.
|
|
14686
|
+
* Collection names should be namespaced by addon (e.g.
|
|
14687
|
+
* `pipeline-analytics:object-events`) to avoid cross-addon
|
|
14688
|
+
* clashes — no automatic prefix is added.
|
|
14689
|
+
*/
|
|
14690
|
+
declareCollection: method(zod.z.object({
|
|
14691
|
+
namespace: zod.z.string().optional(),
|
|
14692
|
+
collection: zod.z.string(),
|
|
14693
|
+
columns: zod.z.array(CollectionColumnSchema).readonly(),
|
|
14694
|
+
indexes: zod.z.array(CollectionIndexSchema).readonly().optional()
|
|
14695
|
+
}), zod.z.void(), { kind: "mutation" })
|
|
14696
|
+
}
|
|
14697
|
+
};
|
|
14698
|
+
/**
|
|
14699
|
+
* What one engine says about itself. The orchestrator uses `kind` to pick
|
|
14700
|
+
* a registrant for a collection; `engineId` is what a log line names when
|
|
14701
|
+
* a call is routed or refused.
|
|
14702
|
+
*/
|
|
14703
|
+
var EngineInfoSchema = zod.z.object({
|
|
14704
|
+
engineId: zod.z.string(),
|
|
14705
|
+
/**
|
|
14706
|
+
* `relational` — rows, columns, indexes, the surface `settings-store`
|
|
14707
|
+
* has always described. `vector` — an embedding store answering
|
|
14708
|
+
* similarity queries. A registrant declares exactly one; an engine that
|
|
14709
|
+
* does both registers twice, because "both" would make the routing
|
|
14710
|
+
* decision ambiguous at exactly the point it must not be.
|
|
14711
|
+
*/
|
|
14712
|
+
kind: zod.z.enum(["relational", "vector"]),
|
|
14713
|
+
displayName: zod.z.string()
|
|
14714
|
+
});
|
|
14715
|
+
/**
|
|
14716
|
+
* data-store-provider — the engine contract behind the data door.
|
|
14717
|
+
*
|
|
14718
|
+
* The sibling of `storage-provider`, for rows instead of bytes. The
|
|
14719
|
+
* orchestrator (singleton `settings-store` cap, owned by the
|
|
14720
|
+
* storage-orchestrator builtin) dispatches every call to the registrant
|
|
14721
|
+
* that serves the collection.
|
|
14722
|
+
*
|
|
14723
|
+
* `internal: true` — consumed only by the orchestrator. Public consumers
|
|
14724
|
+
* go through `settings-store`; they never see this cap, and an engine
|
|
14725
|
+
* never sees a caller.
|
|
14726
|
+
*
|
|
14727
|
+
* Design notes:
|
|
14728
|
+
* - **Stateless dispatch.** Every method carries its own
|
|
14729
|
+
* `namespace` + `collection`, so an engine keeps no per-caller state
|
|
14730
|
+
* and the orchestrator forwards the payload verbatim. Scoping is a
|
|
14731
|
+
* property of the input, not of the connection — see the note on
|
|
14732
|
+
* `settings-store` about what that does and does not guarantee.
|
|
14733
|
+
* - **One registrant today** (`sqlite-settings`). The collection shape
|
|
14734
|
+
* exists so a second engine is a registration rather than a second
|
|
14735
|
+
* door ([D44](../../../../docs/decisions/adr-0044.md)).
|
|
14736
|
+
*
|
|
14737
|
+
* The method set is deliberately identical to `settings-store`'s: the
|
|
14738
|
+
* orchestrator is a router, not a translator. A capability the door
|
|
14739
|
+
* gains, an engine must be able to answer.
|
|
14740
|
+
*/
|
|
14741
|
+
var dataStoreProviderCapability = {
|
|
14742
|
+
name: "data-store-provider",
|
|
14743
|
+
scope: "system",
|
|
14744
|
+
mode: "collection",
|
|
14745
|
+
internal: true,
|
|
14746
|
+
methods: {
|
|
14747
|
+
/** Self-description — how the orchestrator picks a registrant. */
|
|
14748
|
+
getEngineInfo: method(zod.z.void(), EngineInfoSchema),
|
|
14749
|
+
/** Get a single value by key from a collection. */
|
|
14750
|
+
get: method(zod.z.object({
|
|
14751
|
+
namespace: zod.z.string().optional(),
|
|
14752
|
+
collection: zod.z.string(),
|
|
14753
|
+
key: zod.z.string()
|
|
14754
|
+
}), zod.z.unknown()),
|
|
14755
|
+
/** Set a value by key in a collection (upsert). */
|
|
14756
|
+
set: method(zod.z.object({
|
|
14757
|
+
namespace: zod.z.string().optional(),
|
|
14758
|
+
collection: zod.z.string(),
|
|
14759
|
+
key: zod.z.string(),
|
|
14760
|
+
value: zod.z.unknown()
|
|
14761
|
+
}), zod.z.void(), { kind: "mutation" }),
|
|
14762
|
+
/** Get all entries matching an optional filter. */
|
|
14763
|
+
query: method(zod.z.object({
|
|
14764
|
+
namespace: zod.z.string().optional(),
|
|
14765
|
+
collection: zod.z.string(),
|
|
14766
|
+
filter: QueryFilterSchema.optional()
|
|
14767
|
+
}), zod.z.array(SettingsRecordSchema).readonly()),
|
|
14768
|
+
/** Insert a new record. */
|
|
14769
|
+
insert: method(zod.z.object({
|
|
14770
|
+
namespace: zod.z.string().optional(),
|
|
14771
|
+
collection: zod.z.string(),
|
|
14772
|
+
record: SettingsRecordSchema
|
|
14773
|
+
}), zod.z.void(), { kind: "mutation" }),
|
|
14774
|
+
/** Update an existing record by ID. */
|
|
14775
|
+
update: method(zod.z.object({
|
|
14776
|
+
namespace: zod.z.string().optional(),
|
|
14777
|
+
collection: zod.z.string(),
|
|
14778
|
+
id: zod.z.string(),
|
|
14779
|
+
data: zod.z.record(zod.z.string(), zod.z.unknown())
|
|
14780
|
+
}), zod.z.void(), { kind: "mutation" }),
|
|
14781
|
+
/** Delete a record by key/ID. */
|
|
14782
|
+
delete: method(zod.z.object({
|
|
14783
|
+
namespace: zod.z.string().optional(),
|
|
14784
|
+
collection: zod.z.string(),
|
|
14785
|
+
key: zod.z.string()
|
|
14786
|
+
}), zod.z.void(), { kind: "mutation" }),
|
|
14787
|
+
/** Count entries in a collection, optionally filtered. */
|
|
14788
|
+
count: method(zod.z.object({
|
|
14789
|
+
namespace: zod.z.string().optional(),
|
|
14790
|
+
collection: zod.z.string(),
|
|
14791
|
+
filter: QueryFilterSchema.optional()
|
|
14792
|
+
}), zod.z.number()),
|
|
14793
|
+
/** Grouped counts per ((field-origin)/bucketSize) bucket, filtered. */
|
|
14794
|
+
histogram: method(zod.z.object({
|
|
14795
|
+
namespace: zod.z.string().optional(),
|
|
14796
|
+
collection: zod.z.string(),
|
|
14797
|
+
field: zod.z.string(),
|
|
14798
|
+
bucketSize: zod.z.number().int().positive(),
|
|
14799
|
+
origin: zod.z.number().int(),
|
|
14800
|
+
filter: QueryFilterSchema.optional()
|
|
14801
|
+
}), zod.z.array(zod.z.object({
|
|
14802
|
+
bucket: zod.z.number().int(),
|
|
14803
|
+
count: zod.z.number().int()
|
|
14804
|
+
})).readonly()),
|
|
14805
|
+
/** Check if a collection is empty. */
|
|
14806
|
+
isEmpty: method(zod.z.object({
|
|
14807
|
+
namespace: zod.z.string().optional(),
|
|
14808
|
+
collection: zod.z.string()
|
|
14809
|
+
}), zod.z.boolean()),
|
|
14810
|
+
/** Declare a typed (SQL-backed) collection with columns + indexes. */
|
|
14811
|
+
declareCollection: method(zod.z.object({
|
|
14812
|
+
namespace: zod.z.string().optional(),
|
|
14813
|
+
collection: zod.z.string(),
|
|
14814
|
+
columns: zod.z.array(CollectionColumnSchema).readonly(),
|
|
14815
|
+
indexes: zod.z.array(CollectionIndexSchema).readonly().optional()
|
|
14816
|
+
}), zod.z.void(), { kind: "mutation" })
|
|
14817
|
+
}
|
|
14818
|
+
};
|
|
14819
|
+
/**
|
|
14541
14820
|
* detection-pipeline — device-scoped facade over the system
|
|
14542
14821
|
* `pipeline-executor`.
|
|
14543
14822
|
*
|
|
@@ -18926,6 +19205,52 @@ var ServerUpdateStateSchema = zod.z.enum([
|
|
|
18926
19205
|
"pending-restart",
|
|
18927
19206
|
"awaiting-confirmation"
|
|
18928
19207
|
]);
|
|
19208
|
+
/**
|
|
19209
|
+
* Verdict of comparing the node's IMMUTABLE baked seed (the Docker image / the
|
|
19210
|
+
* desktop app bundle) against the release the deployment contract would
|
|
19211
|
+
* deliver today. `applyServerUpdate` swaps the data-root closure and NEVER
|
|
19212
|
+
* touches the image, so `runningVersion` can be perfectly current while the
|
|
19213
|
+
* container is weeks old, from a renamed repository nothing rebuilds — which
|
|
19214
|
+
* is exactly what happened on 2026-08-02 (hub on `camstack-server:intel-1.1.74`
|
|
19215
|
+
* while every existing surface said "up to date"). The seed version is the one
|
|
19216
|
+
* image fingerprint a container can see from inside (no docker socket).
|
|
19217
|
+
*
|
|
19218
|
+
* - `in-sync` — seed equals the current release; the node runs the
|
|
19219
|
+
* contract image.
|
|
19220
|
+
* - `behind-patch` — same release series, older patch: the image predates
|
|
19221
|
+
* the current release. Normal between deliberate image
|
|
19222
|
+
* refreshes, but the starter/entrypoint are still old.
|
|
19223
|
+
* - `behind-series` — the seed's major/minor predates the current release
|
|
19224
|
+
* series. The shape of a pinned tag or a dead image
|
|
19225
|
+
* repository; a `docker pull` may fix nothing.
|
|
19226
|
+
* - `ahead` — seed newer than the best-known release (stale registry
|
|
19227
|
+
* check).
|
|
19228
|
+
* - `unknown` — no seed (dev workspace) or nothing to compare against
|
|
19229
|
+
* yet.
|
|
19230
|
+
*/
|
|
19231
|
+
var ImageContractStateSchema = zod.z.enum([
|
|
19232
|
+
"in-sync",
|
|
19233
|
+
"behind-patch",
|
|
19234
|
+
"behind-series",
|
|
19235
|
+
"ahead",
|
|
19236
|
+
"unknown"
|
|
19237
|
+
]);
|
|
19238
|
+
var ImageContractSchema = zod.z.object({
|
|
19239
|
+
state: ImageContractStateSchema,
|
|
19240
|
+
/** The baked seed closure version — the image/app-bundle fingerprint. */
|
|
19241
|
+
seedVersion: zod.z.string().nullable(),
|
|
19242
|
+
/** Best-known version the deployment contract delivers today. */
|
|
19243
|
+
contractVersion: zod.z.string().nullable(),
|
|
19244
|
+
/**
|
|
19245
|
+
* Where `contractVersion` came from: a real registry check (`registry`), or
|
|
19246
|
+
* the node's own running version (`running` — a node can never run code
|
|
19247
|
+
* newer than the newest release, so `seed < running` proves image staleness
|
|
19248
|
+
* even before any registry check has run).
|
|
19249
|
+
*/
|
|
19250
|
+
contractSource: zod.z.enum(["registry", "running"]).nullable(),
|
|
19251
|
+
/** One operator-grade sentence: this node runs image X; the contract says Y. */
|
|
19252
|
+
message: zod.z.string()
|
|
19253
|
+
});
|
|
18929
19254
|
var ServerRollbackInfoSchema = zod.z.object({
|
|
18930
19255
|
/** The version that failed (or was manually rolled back). */
|
|
18931
19256
|
fromVersion: zod.z.string(),
|
|
@@ -18962,7 +19287,12 @@ var ServerPackageStatusSchema = zod.z.object({
|
|
|
18962
19287
|
* versions are being IGNORED. Surfaced as a warning in the UI.
|
|
18963
19288
|
*/
|
|
18964
19289
|
stateFileCorrupt: zod.z.boolean(),
|
|
18965
|
-
lastCheckedAtMs: zod.z.number().nullable()
|
|
19290
|
+
lastCheckedAtMs: zod.z.number().nullable(),
|
|
19291
|
+
/**
|
|
19292
|
+
* Seed-vs-contract verdict (see {@link ImageContractSchema}). Optional for
|
|
19293
|
+
* version skew: an older provider's payload simply omits it.
|
|
19294
|
+
*/
|
|
19295
|
+
imageContract: ImageContractSchema.optional()
|
|
18966
19296
|
});
|
|
18967
19297
|
var ServerUpdateCheckResultSchema = zod.z.object({
|
|
18968
19298
|
packageName: zod.z.string(),
|
|
@@ -19017,158 +19347,6 @@ version: zod.z.string().optional() }), ServerUpdateActionResultSchema, {
|
|
|
19017
19347
|
mount: { kind: "server-provided" }
|
|
19018
19348
|
};
|
|
19019
19349
|
/**
|
|
19020
|
-
* Query filter for settings-store collections.
|
|
19021
|
-
*/
|
|
19022
|
-
var QueryFilterSchema = zod.z.object({
|
|
19023
|
-
where: zod.z.record(zod.z.string(), zod.z.unknown()).optional(),
|
|
19024
|
-
whereIn: zod.z.record(zod.z.string(), zod.z.array(zod.z.unknown())).optional(),
|
|
19025
|
-
whereBetween: zod.z.record(zod.z.string(), zod.z.tuple([zod.z.unknown(), zod.z.unknown()])).optional(),
|
|
19026
|
-
orderBy: zod.z.object({
|
|
19027
|
-
field: zod.z.string(),
|
|
19028
|
-
direction: zod.z.enum(["asc", "desc"])
|
|
19029
|
-
}).optional(),
|
|
19030
|
-
limit: zod.z.number().optional(),
|
|
19031
|
-
offset: zod.z.number().optional()
|
|
19032
|
-
});
|
|
19033
|
-
/** A single stored record: `{ id, data }`. */
|
|
19034
|
-
var SettingsRecordSchema = zod.z.object({
|
|
19035
|
-
id: zod.z.string(),
|
|
19036
|
-
data: zod.z.record(zod.z.string(), zod.z.unknown())
|
|
19037
|
-
});
|
|
19038
|
-
/**
|
|
19039
|
-
* Column declaration for a structured (SQL-backed) collection.
|
|
19040
|
-
*
|
|
19041
|
-
* Logical types — the backend translates each to the matching SQLite
|
|
19042
|
-
* storage class and handles per-type marshaling:
|
|
19043
|
-
* - `TEXT` / `INTEGER` / `REAL` — native SQLite types, pass-through
|
|
19044
|
-
* - `JSON` — TEXT under the hood; serialised on write, parsed on read
|
|
19045
|
-
* - `BOOLEAN` — INTEGER 0/1 under the hood; coerced both directions
|
|
19046
|
-
*/
|
|
19047
|
-
var CollectionColumnSchema = zod.z.object({
|
|
19048
|
-
name: zod.z.string(),
|
|
19049
|
-
type: zod.z.enum([
|
|
19050
|
-
"TEXT",
|
|
19051
|
-
"INTEGER",
|
|
19052
|
-
"REAL",
|
|
19053
|
-
"JSON",
|
|
19054
|
-
"BOOLEAN"
|
|
19055
|
-
]),
|
|
19056
|
-
primaryKey: zod.z.boolean().optional(),
|
|
19057
|
-
notNull: zod.z.boolean().optional(),
|
|
19058
|
-
unique: zod.z.boolean().optional()
|
|
19059
|
-
});
|
|
19060
|
-
var CollectionIndexSchema = zod.z.object({
|
|
19061
|
-
name: zod.z.string(),
|
|
19062
|
-
columns: zod.z.array(zod.z.string()).readonly(),
|
|
19063
|
-
unique: zod.z.boolean().optional()
|
|
19064
|
-
});
|
|
19065
|
-
/**
|
|
19066
|
-
* settings-store — singleton capability for addon-scoped persistence.
|
|
19067
|
-
*
|
|
19068
|
-
* Every method operates within a `collection`. An optional `namespace`
|
|
19069
|
-
* field provides access to additional data spaces beyond the default
|
|
19070
|
-
* addon settings — useful for business data (events, tracks, faces, etc.).
|
|
19071
|
-
*
|
|
19072
|
-
* Scoping: the implementation prefixes every collection with the calling
|
|
19073
|
-
* addon's ID automatically. Addons never see each other's data.
|
|
19074
|
-
*
|
|
19075
|
-
* - No namespace (default): `"addon-settings"` → `"<addonId>:addon-settings"`
|
|
19076
|
-
* - With namespace: `{ namespace: 'events', collection: 'detections' }` →
|
|
19077
|
-
* `"<addonId>:events:detections"`
|
|
19078
|
-
*
|
|
19079
|
-
* Implemented by `@camstack/system/builtins/sqlite-settings` (SQLite WAL backend).
|
|
19080
|
-
* Addons access it via `ctx.api.settingsStore.*`.
|
|
19081
|
-
*/
|
|
19082
|
-
var settingsStoreCapability = {
|
|
19083
|
-
name: "settings-store",
|
|
19084
|
-
scope: "system",
|
|
19085
|
-
mode: "singleton",
|
|
19086
|
-
methods: {
|
|
19087
|
-
/** Get a single value by key from a collection. */
|
|
19088
|
-
get: method(zod.z.object({
|
|
19089
|
-
namespace: zod.z.string().optional(),
|
|
19090
|
-
collection: zod.z.string(),
|
|
19091
|
-
key: zod.z.string()
|
|
19092
|
-
}), zod.z.unknown()),
|
|
19093
|
-
/** Set a value by key in a collection (upsert). */
|
|
19094
|
-
set: method(zod.z.object({
|
|
19095
|
-
namespace: zod.z.string().optional(),
|
|
19096
|
-
collection: zod.z.string(),
|
|
19097
|
-
key: zod.z.string(),
|
|
19098
|
-
value: zod.z.unknown()
|
|
19099
|
-
}), zod.z.void(), { kind: "mutation" }),
|
|
19100
|
-
/** Get all entries matching an optional filter. */
|
|
19101
|
-
query: method(zod.z.object({
|
|
19102
|
-
namespace: zod.z.string().optional(),
|
|
19103
|
-
collection: zod.z.string(),
|
|
19104
|
-
filter: QueryFilterSchema.optional()
|
|
19105
|
-
}), zod.z.array(SettingsRecordSchema).readonly()),
|
|
19106
|
-
/** Insert a new record. */
|
|
19107
|
-
insert: method(zod.z.object({
|
|
19108
|
-
namespace: zod.z.string().optional(),
|
|
19109
|
-
collection: zod.z.string(),
|
|
19110
|
-
record: SettingsRecordSchema
|
|
19111
|
-
}), zod.z.void(), { kind: "mutation" }),
|
|
19112
|
-
/** Update an existing record by ID. */
|
|
19113
|
-
update: method(zod.z.object({
|
|
19114
|
-
namespace: zod.z.string().optional(),
|
|
19115
|
-
collection: zod.z.string(),
|
|
19116
|
-
id: zod.z.string(),
|
|
19117
|
-
data: zod.z.record(zod.z.string(), zod.z.unknown())
|
|
19118
|
-
}), zod.z.void(), { kind: "mutation" }),
|
|
19119
|
-
/** Delete a record by key/ID. */
|
|
19120
|
-
delete: method(zod.z.object({
|
|
19121
|
-
namespace: zod.z.string().optional(),
|
|
19122
|
-
collection: zod.z.string(),
|
|
19123
|
-
key: zod.z.string()
|
|
19124
|
-
}), zod.z.void(), { kind: "mutation" }),
|
|
19125
|
-
/** Count entries in a collection, optionally filtered. */
|
|
19126
|
-
count: method(zod.z.object({
|
|
19127
|
-
namespace: zod.z.string().optional(),
|
|
19128
|
-
collection: zod.z.string(),
|
|
19129
|
-
filter: QueryFilterSchema.optional()
|
|
19130
|
-
}), zod.z.number()),
|
|
19131
|
-
/** Grouped counts per ((field-origin)/bucketSize) bucket, filtered. */
|
|
19132
|
-
histogram: method(zod.z.object({
|
|
19133
|
-
namespace: zod.z.string().optional(),
|
|
19134
|
-
collection: zod.z.string(),
|
|
19135
|
-
field: zod.z.string(),
|
|
19136
|
-
bucketSize: zod.z.number().int().positive(),
|
|
19137
|
-
origin: zod.z.number().int(),
|
|
19138
|
-
filter: QueryFilterSchema.optional()
|
|
19139
|
-
}), zod.z.array(zod.z.object({
|
|
19140
|
-
bucket: zod.z.number().int(),
|
|
19141
|
-
count: zod.z.number().int()
|
|
19142
|
-
})).readonly()),
|
|
19143
|
-
/** Check if a collection is empty. */
|
|
19144
|
-
isEmpty: method(zod.z.object({
|
|
19145
|
-
namespace: zod.z.string().optional(),
|
|
19146
|
-
collection: zod.z.string()
|
|
19147
|
-
}), zod.z.boolean()),
|
|
19148
|
-
/**
|
|
19149
|
-
* Declare a typed (SQL-backed) collection with explicit columns +
|
|
19150
|
-
* indexes. Idempotent: re-declaring an existing collection with the
|
|
19151
|
-
* same shape is a no-op; shape changes (new columns, new indexes)
|
|
19152
|
-
* are applied additively. Subsequent `insert` / `update` / `delete`
|
|
19153
|
-
* / `query` calls on this collection use typed columns instead of
|
|
19154
|
-
* JSON-blob storage — `record.data` fields are spread across
|
|
19155
|
-
* columns, `query.filter.where` matches real columns (no
|
|
19156
|
-
* `json_extract` overhead), `orderBy` uses column indexes.
|
|
19157
|
-
*
|
|
19158
|
-
* Addons call this in `onInitialize` before their first read/write.
|
|
19159
|
-
* Collection names should be namespaced by addon (e.g.
|
|
19160
|
-
* `pipeline-analytics:object-events`) to avoid cross-addon
|
|
19161
|
-
* clashes — no automatic prefix is added.
|
|
19162
|
-
*/
|
|
19163
|
-
declareCollection: method(zod.z.object({
|
|
19164
|
-
namespace: zod.z.string().optional(),
|
|
19165
|
-
collection: zod.z.string(),
|
|
19166
|
-
columns: zod.z.array(CollectionColumnSchema).readonly(),
|
|
19167
|
-
indexes: zod.z.array(CollectionIndexSchema).readonly().optional()
|
|
19168
|
-
}), zod.z.void(), { kind: "mutation" })
|
|
19169
|
-
}
|
|
19170
|
-
};
|
|
19171
|
-
/**
|
|
19172
19350
|
* `smtp-provider` — pluggable email delivery surface.
|
|
19173
19351
|
*
|
|
19174
19352
|
* Collection cap: a deployment may install multiple SMTP relays (e.g.
|
|
@@ -22878,7 +23056,7 @@ var recordingCapability = {
|
|
|
22878
23056
|
auth: "admin"
|
|
22879
23057
|
}),
|
|
22880
23058
|
/**
|
|
22881
|
-
* Move footage (segments
|
|
23059
|
+
* Move footage (recorded segments) from one recordings location to
|
|
22882
23060
|
* another — the drain workflow's mover (entity-routing spec Phase 4).
|
|
22883
23061
|
* Throttled copy → size-verify → delete source → index refresh; resumable
|
|
22884
23062
|
* by construction (copy-if-absent). Single-flight: one job at a time.
|
|
@@ -23761,6 +23939,7 @@ var ALL_CAPABILITY_DEFINITIONS = [
|
|
|
23761
23939
|
controlCapability,
|
|
23762
23940
|
coverCapability,
|
|
23763
23941
|
customModelRegistryCapability,
|
|
23942
|
+
dataStoreProviderCapability,
|
|
23764
23943
|
dayNightCapability,
|
|
23765
23944
|
decoderCapability,
|
|
23766
23945
|
detectionPipelineCapability,
|
|
@@ -24766,6 +24945,72 @@ var METHOD_ACCESS_MAP = Object.freeze({
|
|
|
24766
24945
|
addonId: null,
|
|
24767
24946
|
access: "view"
|
|
24768
24947
|
},
|
|
24948
|
+
"dataStoreProvider.count": {
|
|
24949
|
+
capName: "data-store-provider",
|
|
24950
|
+
capScope: "system",
|
|
24951
|
+
addonId: null,
|
|
24952
|
+
access: "view"
|
|
24953
|
+
},
|
|
24954
|
+
"dataStoreProvider.declareCollection": {
|
|
24955
|
+
capName: "data-store-provider",
|
|
24956
|
+
capScope: "system",
|
|
24957
|
+
addonId: null,
|
|
24958
|
+
access: "create"
|
|
24959
|
+
},
|
|
24960
|
+
"dataStoreProvider.delete": {
|
|
24961
|
+
capName: "data-store-provider",
|
|
24962
|
+
capScope: "system",
|
|
24963
|
+
addonId: null,
|
|
24964
|
+
access: "delete"
|
|
24965
|
+
},
|
|
24966
|
+
"dataStoreProvider.get": {
|
|
24967
|
+
capName: "data-store-provider",
|
|
24968
|
+
capScope: "system",
|
|
24969
|
+
addonId: null,
|
|
24970
|
+
access: "view"
|
|
24971
|
+
},
|
|
24972
|
+
"dataStoreProvider.getEngineInfo": {
|
|
24973
|
+
capName: "data-store-provider",
|
|
24974
|
+
capScope: "system",
|
|
24975
|
+
addonId: null,
|
|
24976
|
+
access: "view"
|
|
24977
|
+
},
|
|
24978
|
+
"dataStoreProvider.histogram": {
|
|
24979
|
+
capName: "data-store-provider",
|
|
24980
|
+
capScope: "system",
|
|
24981
|
+
addonId: null,
|
|
24982
|
+
access: "view"
|
|
24983
|
+
},
|
|
24984
|
+
"dataStoreProvider.insert": {
|
|
24985
|
+
capName: "data-store-provider",
|
|
24986
|
+
capScope: "system",
|
|
24987
|
+
addonId: null,
|
|
24988
|
+
access: "create"
|
|
24989
|
+
},
|
|
24990
|
+
"dataStoreProvider.isEmpty": {
|
|
24991
|
+
capName: "data-store-provider",
|
|
24992
|
+
capScope: "system",
|
|
24993
|
+
addonId: null,
|
|
24994
|
+
access: "view"
|
|
24995
|
+
},
|
|
24996
|
+
"dataStoreProvider.query": {
|
|
24997
|
+
capName: "data-store-provider",
|
|
24998
|
+
capScope: "system",
|
|
24999
|
+
addonId: null,
|
|
25000
|
+
access: "view"
|
|
25001
|
+
},
|
|
25002
|
+
"dataStoreProvider.set": {
|
|
25003
|
+
capName: "data-store-provider",
|
|
25004
|
+
capScope: "system",
|
|
25005
|
+
addonId: null,
|
|
25006
|
+
access: "create"
|
|
25007
|
+
},
|
|
25008
|
+
"dataStoreProvider.update": {
|
|
25009
|
+
capName: "data-store-provider",
|
|
25010
|
+
capScope: "system",
|
|
25011
|
+
addonId: null,
|
|
25012
|
+
access: "create"
|
|
25013
|
+
},
|
|
24769
25014
|
"dayNight.getOptions": {
|
|
24770
25015
|
capName: "day-night",
|
|
24771
25016
|
capScope: "device",
|
|
@@ -29234,6 +29479,12 @@ Object.defineProperty(exports, "createEvent", {
|
|
|
29234
29479
|
return createEvent;
|
|
29235
29480
|
}
|
|
29236
29481
|
});
|
|
29482
|
+
Object.defineProperty(exports, "dataStoreProviderCapability", {
|
|
29483
|
+
enumerable: true,
|
|
29484
|
+
get: function() {
|
|
29485
|
+
return dataStoreProviderCapability;
|
|
29486
|
+
}
|
|
29487
|
+
});
|
|
29237
29488
|
Object.defineProperty(exports, "deviceManagerCapability", {
|
|
29238
29489
|
enumerable: true,
|
|
29239
29490
|
get: function() {
|
package/dist/index.d.ts
CHANGED
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
export { startHeapWatch, buildHeapSample, HEAP_WATCH_INTERVAL_MS, HEAP_WATCH_WARN_RATIO, } from './kernel/heap-watch.js';
|
|
2
|
+
export type { HeapSample, HeapWatchSink } from './kernel/heap-watch.js';
|
|
1
3
|
export { ensureBinary, downloadBinary, findInPath, getPlatformInfo, buildBinaryPath, ensureFfmpeg, getFfmpegDownloadUrl, ensurePython, installPythonPackages, installPythonRequirements, getPythonDownloadUrl, PYTHON_VERSION, } from '@camstack/types/node';
|
|
2
4
|
export type { PlatformInfo } from '@camstack/types/node';
|
|
3
5
|
export { ALL_CAPABILITY_DEFINITIONS, METHOD_ACCESS_MAP, expandCapMethods, isArrayOutputSchema, isCollectionArrayMethod, addonSettingsCapability, DEVICE_SETTINGS_CONTRIBUTION_METHODS, DEVICE_STATUS_METHOD, } from '@camstack/types';
|