@camstack/system 1.2.30 → 1.2.32
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/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 +10 -0
- package/dist/builtins/alerts/alerts.addon.js +60 -1
- package/dist/builtins/alerts/alerts.addon.mjs +60 -1
- package/dist/builtins/backup-orchestrator/backup-orchestrator.addon.js +135 -92
- package/dist/builtins/backup-orchestrator/backup-orchestrator.addon.mjs +135 -92
- package/dist/builtins/backup-orchestrator/destination-policy.d.ts +12 -14
- package/dist/builtins/backup-orchestrator/schedule-store.d.ts +6 -6
- 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/liveness-monitor/index.d.ts +2 -0
- package/dist/builtins/liveness-monitor/index.js +6 -0
- package/dist/builtins/liveness-monitor/index.mjs +2 -0
- package/dist/builtins/liveness-monitor/liveness-checks.d.ts +67 -0
- package/dist/builtins/liveness-monitor/liveness-monitor.addon.d.ts +32 -0
- package/dist/builtins/liveness-monitor/liveness-monitor.addon.js +216 -0
- package/dist/builtins/liveness-monitor/liveness-monitor.addon.mjs +212 -0
- 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/integration-registry.d.ts +3 -3
- package/dist/builtins/sqlite-storage/sqlite-settings-backend.d.ts +6 -8
- package/dist/builtins/sqlite-storage/sqlite-settings.addon.js +3 -25
- package/dist/builtins/sqlite-storage/sqlite-settings.addon.mjs +3 -25
- package/dist/builtins/storage-orchestrator/location-store.d.ts +17 -24
- package/dist/builtins/storage-orchestrator/storage-orchestrator.addon.d.ts +0 -6
- package/dist/builtins/storage-orchestrator/storage-orchestrator.addon.js +130 -121
- package/dist/builtins/storage-orchestrator/storage-orchestrator.addon.mjs +130 -121
- 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-Dr_P0DOB.mjs → dist-BL_FHWPP.mjs} +33 -2
- package/dist/{dist-VIwdvws5.js → dist-CSs1A90r.js} +33 -2
- package/dist/index.d.ts +1 -0
- package/dist/index.js +365 -224
- package/dist/index.mjs +365 -225
- package/package.json +10 -1
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { Mt as EventCategory, ot as BaseAddon, y as backupCapability } from "../../dist-
|
|
1
|
+
import { Mt as EventCategory, ot as BaseAddon, y as backupCapability } from "../../dist-BL_FHWPP.mjs";
|
|
2
2
|
import * as fs from "node:fs";
|
|
3
3
|
import Kt from "node:fs";
|
|
4
4
|
import * as path$1 from "node:path";
|
|
@@ -4189,8 +4189,8 @@ function previewNextRuns(cron, count, after) {
|
|
|
4189
4189
|
}
|
|
4190
4190
|
//#endregion
|
|
4191
4191
|
//#region src/builtins/backup-orchestrator/destination-policy.ts
|
|
4192
|
-
var
|
|
4193
|
-
var
|
|
4192
|
+
var BACKUP_DESTINATION_POLICIES = "backup_destination_policies";
|
|
4193
|
+
var BACKUP_DESTINATION_POLICIES_COLUMNS = [
|
|
4194
4194
|
{
|
|
4195
4195
|
name: "location_id",
|
|
4196
4196
|
type: "TEXT",
|
|
@@ -4220,64 +4220,81 @@ var BACKUP_DESTINATION_POLICIES_SCHEMA = { columns: [
|
|
|
4220
4220
|
name: "last_run_at",
|
|
4221
4221
|
type: "INTEGER"
|
|
4222
4222
|
}
|
|
4223
|
-
]
|
|
4223
|
+
];
|
|
4224
4224
|
var BackupDestinationPolicyService = class {
|
|
4225
|
-
|
|
4226
|
-
|
|
4227
|
-
constructor(
|
|
4228
|
-
this.
|
|
4225
|
+
store;
|
|
4226
|
+
declared = false;
|
|
4227
|
+
constructor(store) {
|
|
4228
|
+
this.store = store;
|
|
4229
4229
|
}
|
|
4230
4230
|
/**
|
|
4231
|
-
* Lazy `
|
|
4232
|
-
*
|
|
4233
|
-
*
|
|
4234
|
-
*
|
|
4235
|
-
* `initialize()` step that callers could forget.
|
|
4231
|
+
* Lazy `declareCollection` — called from every read/write path.
|
|
4232
|
+
* `declareCollection` is idempotent, so repeated calls collapse to a no-op
|
|
4233
|
+
* after the first. This keeps the constructor synchronous and avoids a
|
|
4234
|
+
* separate `initialize()` step that callers could forget.
|
|
4236
4235
|
*/
|
|
4237
4236
|
async initialize() {
|
|
4238
|
-
await this.
|
|
4237
|
+
await this.ensureDeclared();
|
|
4239
4238
|
}
|
|
4240
|
-
async
|
|
4241
|
-
if (this.
|
|
4242
|
-
|
|
4243
|
-
|
|
4244
|
-
|
|
4239
|
+
async ensureDeclared() {
|
|
4240
|
+
if (this.declared) return;
|
|
4241
|
+
await this.store.declareCollection({
|
|
4242
|
+
collection: BACKUP_DESTINATION_POLICIES,
|
|
4243
|
+
columns: BACKUP_DESTINATION_POLICIES_COLUMNS
|
|
4244
|
+
});
|
|
4245
|
+
this.declared = true;
|
|
4245
4246
|
}
|
|
4246
4247
|
async list() {
|
|
4247
|
-
await this.
|
|
4248
|
-
|
|
4249
|
-
|
|
4250
|
-
|
|
4251
|
-
|
|
4252
|
-
|
|
4248
|
+
await this.ensureDeclared();
|
|
4249
|
+
const rows = await this.store.query({
|
|
4250
|
+
collection: BACKUP_DESTINATION_POLICIES,
|
|
4251
|
+
filter: { orderBy: {
|
|
4252
|
+
field: "location_id",
|
|
4253
|
+
direction: "asc"
|
|
4254
|
+
} }
|
|
4255
|
+
});
|
|
4253
4256
|
const out = [];
|
|
4254
4257
|
for (const row of rows) {
|
|
4255
|
-
const mapped = mapRowToPolicy(row);
|
|
4258
|
+
const mapped = mapRowToPolicy(row.data);
|
|
4256
4259
|
if (mapped) out.push(mapped);
|
|
4257
4260
|
}
|
|
4258
4261
|
return out;
|
|
4259
4262
|
}
|
|
4260
4263
|
async get(locationId) {
|
|
4261
|
-
await this.
|
|
4262
|
-
|
|
4263
|
-
|
|
4264
|
-
|
|
4264
|
+
await this.ensureDeclared();
|
|
4265
|
+
const rows = await this.store.query({
|
|
4266
|
+
collection: BACKUP_DESTINATION_POLICIES,
|
|
4267
|
+
filter: {
|
|
4268
|
+
where: { location_id: locationId },
|
|
4269
|
+
limit: 1
|
|
4270
|
+
}
|
|
4271
|
+
});
|
|
4272
|
+
return rows[0] ? mapRowToPolicy(rows[0].data) : null;
|
|
4265
4273
|
}
|
|
4266
4274
|
/**
|
|
4267
|
-
* Replace-or-insert. Implemented as
|
|
4268
|
-
* `SqliteLocationStore` contract
|
|
4269
|
-
* `tableUpdate` still work.
|
|
4275
|
+
* Replace-or-insert. Implemented as delete + insert, mirroring the
|
|
4276
|
+
* `SqliteLocationStore` contract.
|
|
4270
4277
|
*/
|
|
4271
4278
|
async upsert(p) {
|
|
4272
|
-
await this.
|
|
4273
|
-
|
|
4274
|
-
|
|
4275
|
-
|
|
4279
|
+
await this.ensureDeclared();
|
|
4280
|
+
await this.store.deleteWhere({
|
|
4281
|
+
collection: BACKUP_DESTINATION_POLICIES,
|
|
4282
|
+
filter: { where: { location_id: p.locationId } }
|
|
4283
|
+
});
|
|
4284
|
+
await this.store.insert({
|
|
4285
|
+
collection: BACKUP_DESTINATION_POLICIES,
|
|
4286
|
+
record: {
|
|
4287
|
+
id: p.locationId,
|
|
4288
|
+
data: mapPolicyToRow(p)
|
|
4289
|
+
}
|
|
4290
|
+
});
|
|
4276
4291
|
}
|
|
4277
4292
|
async delete(locationId) {
|
|
4278
|
-
await this.
|
|
4279
|
-
|
|
4280
|
-
|
|
4293
|
+
await this.ensureDeclared();
|
|
4294
|
+
await this.store.deleteWhere({
|
|
4295
|
+
collection: BACKUP_DESTINATION_POLICIES,
|
|
4296
|
+
filter: { where: { location_id: locationId } }
|
|
4297
|
+
});
|
|
4281
4298
|
}
|
|
4282
4299
|
/**
|
|
4283
4300
|
* Auto-create a default policy for a `backups` location seen for the
|
|
@@ -4558,8 +4575,8 @@ var LocationManifestLock = class {
|
|
|
4558
4575
|
};
|
|
4559
4576
|
//#endregion
|
|
4560
4577
|
//#region src/builtins/backup-orchestrator/schedule-store.ts
|
|
4561
|
-
var
|
|
4562
|
-
var
|
|
4578
|
+
var BACKUP_SCHEDULES = "backup_schedules";
|
|
4579
|
+
var BACKUP_SCHEDULES_COLUMNS = [
|
|
4563
4580
|
{
|
|
4564
4581
|
name: "id",
|
|
4565
4582
|
type: "TEXT",
|
|
@@ -4585,7 +4602,7 @@ var BACKUP_SCHEDULES_SCHEMA = { columns: [
|
|
|
4585
4602
|
},
|
|
4586
4603
|
{
|
|
4587
4604
|
name: "location_ids",
|
|
4588
|
-
type: "
|
|
4605
|
+
type: "JSON",
|
|
4589
4606
|
notNull: true,
|
|
4590
4607
|
defaultValue: "[]"
|
|
4591
4608
|
},
|
|
@@ -4597,59 +4614,78 @@ var BACKUP_SCHEDULES_SCHEMA = { columns: [
|
|
|
4597
4614
|
},
|
|
4598
4615
|
{
|
|
4599
4616
|
name: "data_sources",
|
|
4600
|
-
type: "
|
|
4617
|
+
type: "JSON"
|
|
4601
4618
|
},
|
|
4602
4619
|
{
|
|
4603
4620
|
name: "last_run_at",
|
|
4604
4621
|
type: "INTEGER"
|
|
4605
4622
|
}
|
|
4606
|
-
]
|
|
4623
|
+
];
|
|
4607
4624
|
var BackupScheduleService = class {
|
|
4608
|
-
|
|
4609
|
-
|
|
4610
|
-
constructor(
|
|
4611
|
-
this.
|
|
4625
|
+
store;
|
|
4626
|
+
declared = false;
|
|
4627
|
+
constructor(store) {
|
|
4628
|
+
this.store = store;
|
|
4612
4629
|
}
|
|
4613
4630
|
async initialize() {
|
|
4614
|
-
await this.
|
|
4631
|
+
await this.ensureDeclared();
|
|
4615
4632
|
}
|
|
4616
|
-
async
|
|
4617
|
-
if (this.
|
|
4618
|
-
|
|
4619
|
-
|
|
4620
|
-
|
|
4633
|
+
async ensureDeclared() {
|
|
4634
|
+
if (this.declared) return;
|
|
4635
|
+
await this.store.declareCollection({
|
|
4636
|
+
collection: BACKUP_SCHEDULES,
|
|
4637
|
+
columns: BACKUP_SCHEDULES_COLUMNS
|
|
4638
|
+
});
|
|
4639
|
+
this.declared = true;
|
|
4621
4640
|
}
|
|
4622
4641
|
async list() {
|
|
4623
|
-
await this.
|
|
4624
|
-
|
|
4625
|
-
|
|
4626
|
-
|
|
4627
|
-
|
|
4628
|
-
|
|
4642
|
+
await this.ensureDeclared();
|
|
4643
|
+
const rows = await this.store.query({
|
|
4644
|
+
collection: BACKUP_SCHEDULES,
|
|
4645
|
+
filter: { orderBy: {
|
|
4646
|
+
field: "id",
|
|
4647
|
+
direction: "asc"
|
|
4648
|
+
} }
|
|
4649
|
+
});
|
|
4629
4650
|
const out = [];
|
|
4630
4651
|
for (const row of rows) {
|
|
4631
|
-
const mapped = mapRowToSchedule(row);
|
|
4652
|
+
const mapped = mapRowToSchedule(row.data);
|
|
4632
4653
|
if (mapped) out.push(mapped);
|
|
4633
4654
|
}
|
|
4634
4655
|
return out;
|
|
4635
4656
|
}
|
|
4636
4657
|
async get(id) {
|
|
4637
|
-
await this.
|
|
4638
|
-
|
|
4639
|
-
|
|
4640
|
-
|
|
4658
|
+
await this.ensureDeclared();
|
|
4659
|
+
const rows = await this.store.query({
|
|
4660
|
+
collection: BACKUP_SCHEDULES,
|
|
4661
|
+
filter: {
|
|
4662
|
+
where: { id },
|
|
4663
|
+
limit: 1
|
|
4664
|
+
}
|
|
4665
|
+
});
|
|
4666
|
+
return rows[0] ? mapRowToSchedule(rows[0].data) : null;
|
|
4641
4667
|
}
|
|
4642
4668
|
/** Replace-or-insert (delete + insert — mirrors the policy store). */
|
|
4643
4669
|
async upsert(s) {
|
|
4644
|
-
await this.
|
|
4645
|
-
|
|
4646
|
-
|
|
4647
|
-
|
|
4670
|
+
await this.ensureDeclared();
|
|
4671
|
+
await this.store.deleteWhere({
|
|
4672
|
+
collection: BACKUP_SCHEDULES,
|
|
4673
|
+
filter: { where: { id: s.id } }
|
|
4674
|
+
});
|
|
4675
|
+
await this.store.insert({
|
|
4676
|
+
collection: BACKUP_SCHEDULES,
|
|
4677
|
+
record: {
|
|
4678
|
+
id: s.id,
|
|
4679
|
+
data: mapScheduleToRow(s)
|
|
4680
|
+
}
|
|
4681
|
+
});
|
|
4648
4682
|
}
|
|
4649
4683
|
async delete(id) {
|
|
4650
|
-
await this.
|
|
4651
|
-
|
|
4652
|
-
|
|
4684
|
+
await this.ensureDeclared();
|
|
4685
|
+
await this.store.deleteWhere({
|
|
4686
|
+
collection: BACKUP_SCHEDULES,
|
|
4687
|
+
filter: { where: { id } }
|
|
4688
|
+
});
|
|
4653
4689
|
}
|
|
4654
4690
|
};
|
|
4655
4691
|
function mapScheduleToRow(s) {
|
|
@@ -4658,27 +4694,36 @@ function mapScheduleToRow(s) {
|
|
|
4658
4694
|
label: s.label,
|
|
4659
4695
|
cron: s.cron,
|
|
4660
4696
|
enabled: s.enabled ? 1 : 0,
|
|
4661
|
-
location_ids:
|
|
4697
|
+
location_ids: [...s.locationIds],
|
|
4662
4698
|
retention_count: s.retentionCount,
|
|
4663
|
-
data_sources: s.dataSources ?
|
|
4699
|
+
data_sources: s.dataSources ? [...s.dataSources] : null,
|
|
4664
4700
|
last_run_at: s.lastRunAt ?? null
|
|
4665
4701
|
};
|
|
4666
4702
|
}
|
|
4703
|
+
/**
|
|
4704
|
+
* `location_ids` / `data_sources` are `JSON` columns, so the surface hands
|
|
4705
|
+
* back real arrays. A STRING still arrives for rows an older build wrote and
|
|
4706
|
+
* nothing has rewritten since — a schedule whose fan-out set silently read as
|
|
4707
|
+
* empty would back up to nowhere, so both shapes are accepted.
|
|
4708
|
+
*/
|
|
4667
4709
|
function parseStringArray(raw) {
|
|
4668
|
-
|
|
4710
|
+
const value = typeof raw === "string" ? tryParseJson(raw) : raw;
|
|
4711
|
+
if (!Array.isArray(value)) return [];
|
|
4712
|
+
return value.filter((v) => typeof v === "string");
|
|
4713
|
+
}
|
|
4714
|
+
function tryParseJson(raw) {
|
|
4715
|
+
if (raw.length === 0) return null;
|
|
4669
4716
|
try {
|
|
4670
|
-
|
|
4671
|
-
if (!Array.isArray(parsed)) return [];
|
|
4672
|
-
return parsed.filter((v) => typeof v === "string");
|
|
4717
|
+
return JSON.parse(raw);
|
|
4673
4718
|
} catch {
|
|
4674
|
-
return
|
|
4719
|
+
return null;
|
|
4675
4720
|
}
|
|
4676
4721
|
}
|
|
4677
4722
|
function mapRowToSchedule(row) {
|
|
4678
4723
|
const id = String(row["id"] ?? "");
|
|
4679
4724
|
if (!id) return null;
|
|
4680
4725
|
const dataSourcesRaw = row["data_sources"];
|
|
4681
|
-
const dataSources =
|
|
4726
|
+
const dataSources = dataSourcesRaw === null || dataSourcesRaw === void 0 ? void 0 : parseStringArray(dataSourcesRaw);
|
|
4682
4727
|
const lastRunRaw = row["last_run_at"];
|
|
4683
4728
|
const lastRunAt = typeof lastRunRaw === "number" && lastRunRaw > 0 ? lastRunRaw : void 0;
|
|
4684
4729
|
return {
|
|
@@ -5436,24 +5481,22 @@ var BackupOrchestratorAddon = class extends BaseAddon {
|
|
|
5436
5481
|
resolveScheduleService() {
|
|
5437
5482
|
const reg = this.ctx.kernel.capabilityRegistry;
|
|
5438
5483
|
if (!reg) return null;
|
|
5439
|
-
const
|
|
5440
|
-
if (!
|
|
5441
|
-
|
|
5442
|
-
|
|
5484
|
+
const store = reg.getSingleton("settings-store");
|
|
5485
|
+
if (!store) {
|
|
5486
|
+
this.ctx.logger.warn("backup-orchestrator: no settings-store provider — backup schedules will not persist");
|
|
5487
|
+
return null;
|
|
5488
|
+
}
|
|
5489
|
+
return new BackupScheduleService(store);
|
|
5443
5490
|
}
|
|
5444
5491
|
resolvePolicyService() {
|
|
5445
5492
|
const reg = this.ctx.kernel.capabilityRegistry;
|
|
5446
5493
|
if (!reg) return null;
|
|
5447
|
-
const
|
|
5448
|
-
if (!
|
|
5494
|
+
const store = reg.getSingleton("settings-store");
|
|
5495
|
+
if (!store) {
|
|
5449
5496
|
this.ctx.logger.warn("backup-orchestrator: no settings-store provider — destination policies will not persist");
|
|
5450
5497
|
return null;
|
|
5451
5498
|
}
|
|
5452
|
-
|
|
5453
|
-
this.ctx.logger.warn("backup-orchestrator: settings backend lacks structured-table support — destination policies will not persist");
|
|
5454
|
-
return null;
|
|
5455
|
-
}
|
|
5456
|
-
return new BackupDestinationPolicyService(backend);
|
|
5499
|
+
return new BackupDestinationPolicyService(store);
|
|
5457
5500
|
}
|
|
5458
5501
|
/**
|
|
5459
5502
|
* Narrow `ctx.api.storage` to the subset the manifest helpers need.
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { CollectionColumn, ISettingsStoreProvider } from '@camstack/types';
|
|
2
2
|
/**
|
|
3
3
|
* Per-`backups`-location policy. `locationId` is the foreign-key into
|
|
4
4
|
* the storage orchestrator's `storage_locations` table.
|
|
@@ -30,26 +30,24 @@ export interface BackupDestinationPolicy {
|
|
|
30
30
|
/** ms-epoch of the last successful backup completion to this destination. */
|
|
31
31
|
readonly lastRunAt?: number;
|
|
32
32
|
}
|
|
33
|
-
export declare const
|
|
33
|
+
export declare const BACKUP_DESTINATION_POLICIES_COLUMNS: readonly CollectionColumn[];
|
|
34
34
|
export declare class BackupDestinationPolicyService {
|
|
35
|
-
private readonly
|
|
36
|
-
private
|
|
37
|
-
constructor(
|
|
35
|
+
private readonly store;
|
|
36
|
+
private declared;
|
|
37
|
+
constructor(store: ISettingsStoreProvider);
|
|
38
38
|
/**
|
|
39
|
-
* Lazy `
|
|
40
|
-
*
|
|
41
|
-
*
|
|
42
|
-
*
|
|
43
|
-
* `initialize()` step that callers could forget.
|
|
39
|
+
* Lazy `declareCollection` — called from every read/write path.
|
|
40
|
+
* `declareCollection` is idempotent, so repeated calls collapse to a no-op
|
|
41
|
+
* after the first. This keeps the constructor synchronous and avoids a
|
|
42
|
+
* separate `initialize()` step that callers could forget.
|
|
44
43
|
*/
|
|
45
44
|
initialize(): Promise<void>;
|
|
46
|
-
private
|
|
45
|
+
private ensureDeclared;
|
|
47
46
|
list(): Promise<readonly BackupDestinationPolicy[]>;
|
|
48
47
|
get(locationId: string): Promise<BackupDestinationPolicy | null>;
|
|
49
48
|
/**
|
|
50
|
-
* Replace-or-insert. Implemented as
|
|
51
|
-
* `SqliteLocationStore` contract
|
|
52
|
-
* `tableUpdate` still work.
|
|
49
|
+
* Replace-or-insert. Implemented as delete + insert, mirroring the
|
|
50
|
+
* `SqliteLocationStore` contract.
|
|
53
51
|
*/
|
|
54
52
|
upsert(p: BackupDestinationPolicy): Promise<void>;
|
|
55
53
|
delete(locationId: string): Promise<void>;
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { CollectionColumn, ISettingsStoreProvider } from '@camstack/types';
|
|
2
2
|
/**
|
|
3
3
|
* A backup schedule row.
|
|
4
4
|
*
|
|
@@ -18,13 +18,13 @@ export interface BackupSchedule {
|
|
|
18
18
|
/** ms-epoch of the last successful run. */
|
|
19
19
|
readonly lastRunAt?: number;
|
|
20
20
|
}
|
|
21
|
-
export declare const
|
|
21
|
+
export declare const BACKUP_SCHEDULES_COLUMNS: readonly CollectionColumn[];
|
|
22
22
|
export declare class BackupScheduleService {
|
|
23
|
-
private readonly
|
|
24
|
-
private
|
|
25
|
-
constructor(
|
|
23
|
+
private readonly store;
|
|
24
|
+
private declared;
|
|
25
|
+
constructor(store: ISettingsStoreProvider);
|
|
26
26
|
initialize(): Promise<void>;
|
|
27
|
-
private
|
|
27
|
+
private ensureDeclared;
|
|
28
28
|
list(): Promise<readonly BackupSchedule[]>;
|
|
29
29
|
get(id: string): Promise<BackupSchedule | null>;
|
|
30
30
|
/** Replace-or-insert (delete + insert — mirrors the policy store). */
|
|
@@ -3,7 +3,7 @@ Object.defineProperties(exports, {
|
|
|
3
3
|
[Symbol.toStringTag]: { value: "Module" }
|
|
4
4
|
});
|
|
5
5
|
require("../../chunk-Cek0wNdY.js");
|
|
6
|
-
const require_dist = require("../../dist-
|
|
6
|
+
const require_dist = require("../../dist-CSs1A90r.js");
|
|
7
7
|
const require_formatter = require("../../formatter-DqAKDlvN.js");
|
|
8
8
|
//#region src/builtins/console-logging/console-destination.ts
|
|
9
9
|
var LEVEL_RANK = {
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { B as logDestinationCapability, ot as BaseAddon } from "../../dist-
|
|
1
|
+
import { B as logDestinationCapability, ot as BaseAddon } from "../../dist-BL_FHWPP.mjs";
|
|
2
2
|
import { t as formatLogLine } from "../../formatter-B7qW8bPJ.mjs";
|
|
3
3
|
//#region src/builtins/console-logging/console-destination.ts
|
|
4
4
|
var LEVEL_RANK = {
|
|
@@ -3,7 +3,7 @@ Object.defineProperties(exports, {
|
|
|
3
3
|
[Symbol.toStringTag]: { value: "Module" }
|
|
4
4
|
});
|
|
5
5
|
require("../../chunk-Cek0wNdY.js");
|
|
6
|
-
const require_dist = require("../../dist-
|
|
6
|
+
const require_dist = require("../../dist-CSs1A90r.js");
|
|
7
7
|
let _camstack_types_node = require("@camstack/types/node");
|
|
8
8
|
let zod = require("zod");
|
|
9
9
|
let node_crypto = require("node:crypto");
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { C as deviceStateCapability, D as enumerateItemArrayFields, K as parseStreamParamsFormPatch, M as getByPath, Mt as EventCategory, O as enumerateSchemaFields, S as deviceManagerCapability, W as normalizeUnit, X as setByPath, _ as applyTransform, a as CAP_NAMES_WITH_STATUS, at as errMsg, b as buildStreamParamsConfigSchema, dt as DeviceRole, ft as DeviceType, ht as WELL_KNOWN_TAB_MAP, it as validateExpressionSource, jt as sleep, k as evaluateLinkExpression, l as STREAM_PROFILE_META, nt as toExpressionValue, o as DeviceStatusSchema, ot as BaseAddon, t as ALL_CAPABILITY_DEFINITIONS, ut as DeviceFeature, w as deviceStatusCapability, wt as isDeviceConfigCap } from "../../dist-
|
|
1
|
+
import { C as deviceStateCapability, D as enumerateItemArrayFields, K as parseStreamParamsFormPatch, M as getByPath, Mt as EventCategory, O as enumerateSchemaFields, S as deviceManagerCapability, W as normalizeUnit, X as setByPath, _ as applyTransform, a as CAP_NAMES_WITH_STATUS, at as errMsg, b as buildStreamParamsConfigSchema, dt as DeviceRole, ft as DeviceType, ht as WELL_KNOWN_TAB_MAP, it as validateExpressionSource, jt as sleep, k as evaluateLinkExpression, l as STREAM_PROFILE_META, nt as toExpressionValue, o as DeviceStatusSchema, ot as BaseAddon, t as ALL_CAPABILITY_DEFINITIONS, ut as DeviceFeature, w as deviceStatusCapability, wt as isDeviceConfigCap } from "../../dist-BL_FHWPP.mjs";
|
|
2
2
|
import { canonicalDeviceFingerprint } from "@camstack/types/node";
|
|
3
3
|
import { z } from "zod";
|
|
4
4
|
import { randomUUID } from "node:crypto";
|
|
@@ -3,7 +3,7 @@ Object.defineProperties(exports, {
|
|
|
3
3
|
[Symbol.toStringTag]: { value: "Module" }
|
|
4
4
|
});
|
|
5
5
|
require("../../chunk-Cek0wNdY.js");
|
|
6
|
-
const require_dist = require("../../dist-
|
|
6
|
+
const require_dist = require("../../dist-CSs1A90r.js");
|
|
7
7
|
//#region src/builtins/doorbell/trigger-engine.ts
|
|
8
8
|
/**
|
|
9
9
|
* Pure trigger logic for the virtual-doorbell builtin — edge detection over
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { Mt as EventCategory, T as doorbellCapability, at as errMsg, ft as DeviceType, ot as BaseAddon, yt as createEvent } from "../../dist-
|
|
1
|
+
import { Mt as EventCategory, T as doorbellCapability, at as errMsg, ft as DeviceType, ot as BaseAddon, yt as createEvent } from "../../dist-BL_FHWPP.mjs";
|
|
2
2
|
//#region src/builtins/doorbell/trigger-engine.ts
|
|
3
3
|
/**
|
|
4
4
|
* Pure trigger logic for the virtual-doorbell builtin — edge detection over
|
|
@@ -3,7 +3,7 @@ Object.defineProperties(exports, {
|
|
|
3
3
|
[Symbol.toStringTag]: { value: "Module" }
|
|
4
4
|
});
|
|
5
5
|
require("../../chunk-Cek0wNdY.js");
|
|
6
|
-
const require_dist = require("../../dist-
|
|
6
|
+
const require_dist = require("../../dist-CSs1A90r.js");
|
|
7
7
|
const require_formatter = require("../../formatter-DqAKDlvN.js");
|
|
8
8
|
//#region src/builtins/hub-forwarder/hub-forwarder-destination.ts
|
|
9
9
|
var DEFAULT_OUTBOUND_BUFFER_SIZE = 500;
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { B as logDestinationCapability, ot as BaseAddon } from "../../dist-
|
|
1
|
+
import { B as logDestinationCapability, ot as BaseAddon } from "../../dist-BL_FHWPP.mjs";
|
|
2
2
|
import { t as formatLogLine } from "../../formatter-B7qW8bPJ.mjs";
|
|
3
3
|
//#region src/builtins/hub-forwarder/hub-forwarder-destination.ts
|
|
4
4
|
var DEFAULT_OUTBOUND_BUFFER_SIZE = 500;
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
|
|
2
|
+
require("../../chunk-Cek0wNdY.js");
|
|
3
|
+
const require_builtins_liveness_monitor_liveness_monitor_addon = require("./liveness-monitor.addon.js");
|
|
4
|
+
exports.LivenessMonitorAddon = require_builtins_liveness_monitor_liveness_monitor_addon.LivenessMonitorAddon;
|
|
5
|
+
exports.evaluateLiveness = require_builtins_liveness_monitor_liveness_monitor_addon.evaluateLiveness;
|
|
6
|
+
exports.isLivenessFindingId = require_builtins_liveness_monitor_liveness_monitor_addon.isLivenessFindingId;
|
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The liveness invariants, as pure functions.
|
|
3
|
+
*
|
|
4
|
+
* On 2026-08-03 the hub ran for four hours with zero devices, zero published
|
|
5
|
+
* streams and zero recordings, and nothing said a word. Three separate defects
|
|
6
|
+
* caused it — optional chaining that no-oped, an `if` with no `else`, a JSON
|
|
7
|
+
* parse that returned `{}` — and each was silent at the point of failure. All
|
|
8
|
+
* three were fixed and a log line added at each. This module exists for the
|
|
9
|
+
* CLASS rather than the instances: assert what must be true of a working node,
|
|
10
|
+
* and report when it is not.
|
|
11
|
+
*
|
|
12
|
+
* **Every check here is unambiguous, on purpose.** An alert that fires on a
|
|
13
|
+
* quiet night is one an operator learns to ignore, and an ignored alert is
|
|
14
|
+
* worse than no alert. So "the pipeline emitted no tracks recently" is NOT a
|
|
15
|
+
* check — a camera can legitimately see nothing for hours — while "a camera
|
|
16
|
+
* that has been recording all day stopped producing segments" is: continuous
|
|
17
|
+
* recording produces segments whether or not anything moves.
|
|
18
|
+
*
|
|
19
|
+
* I/O lives in the addon; everything here is a function of facts, so the
|
|
20
|
+
* outage can be replayed in a test.
|
|
21
|
+
*/
|
|
22
|
+
/** What the monitor learned about one camera this tick. */
|
|
23
|
+
export interface CameraFootage {
|
|
24
|
+
readonly deviceId: number;
|
|
25
|
+
readonly online: boolean;
|
|
26
|
+
/**
|
|
27
|
+
* ms-epoch of the newest recorded segment within the lookback window, or
|
|
28
|
+
* `null` when the camera has produced NO footage in it.
|
|
29
|
+
*
|
|
30
|
+
* `null` means "this camera does not record" and is deliberately not a
|
|
31
|
+
* finding — it is what makes the check self-calibrating. Nothing has to be
|
|
32
|
+
* told which cameras are supposed to record: a camera that was recording and
|
|
33
|
+
* stopped is a fault, a camera that never records is a configuration.
|
|
34
|
+
*/
|
|
35
|
+
readonly lastSegmentMs: number | null;
|
|
36
|
+
}
|
|
37
|
+
export interface LivenessFacts {
|
|
38
|
+
readonly nowMs: number;
|
|
39
|
+
/** Every device the node knows about, cameras and accessories alike. */
|
|
40
|
+
readonly deviceCount: number;
|
|
41
|
+
readonly cameras: readonly CameraFootage[];
|
|
42
|
+
/** How long a recording camera may stay silent before it is a fault. */
|
|
43
|
+
readonly staleAfterMs: number;
|
|
44
|
+
}
|
|
45
|
+
export interface LivenessFinding {
|
|
46
|
+
/**
|
|
47
|
+
* Stable across ticks, so an ongoing fault UPDATES one alert instead of
|
|
48
|
+
* producing a new one every minute. Same contract as the kernel's
|
|
49
|
+
* `addon-load-failed:<packageName>` ids.
|
|
50
|
+
*/
|
|
51
|
+
readonly id: string;
|
|
52
|
+
readonly severity: 'error' | 'warning';
|
|
53
|
+
readonly title: string;
|
|
54
|
+
readonly message: string;
|
|
55
|
+
/** Present on per-camera findings. Always the numeric id. */
|
|
56
|
+
readonly deviceId?: number;
|
|
57
|
+
}
|
|
58
|
+
/**
|
|
59
|
+
* Evaluate every invariant against one tick's facts.
|
|
60
|
+
*
|
|
61
|
+
* Ordered most-fundamental first, and it STOPS at "no devices": when the node
|
|
62
|
+
* has nothing, every camera is also silent, and reporting twelve consequences
|
|
63
|
+
* of one cause is how an operator ends up reading none of them.
|
|
64
|
+
*/
|
|
65
|
+
export declare function evaluateLiveness(facts: LivenessFacts): readonly LivenessFinding[];
|
|
66
|
+
/** Every finding id this module can produce, for the recovery sweep. */
|
|
67
|
+
export declare function isLivenessFindingId(id: string): boolean;
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
import { BaseAddon, ProviderRegistration } from '@camstack/types';
|
|
2
|
+
import { LivenessFinding } from './liveness-checks.js';
|
|
3
|
+
interface LivenessMonitorConfig extends Record<string, unknown> {
|
|
4
|
+
readonly staleAfterMs?: number;
|
|
5
|
+
}
|
|
6
|
+
export declare class LivenessMonitorAddon extends BaseAddon<LivenessMonitorConfig> {
|
|
7
|
+
private tickTimer;
|
|
8
|
+
private startedAtMs;
|
|
9
|
+
/** Finding ids currently reported, so recovery can be detected and announced. */
|
|
10
|
+
private active;
|
|
11
|
+
constructor();
|
|
12
|
+
protected onInitialize(): Promise<ProviderRegistration[]>;
|
|
13
|
+
protected onShutdown(): Promise<void>;
|
|
14
|
+
/**
|
|
15
|
+
* One evaluation. Public so a test or an operator-facing action can force it
|
|
16
|
+
* without waiting out the interval.
|
|
17
|
+
*/
|
|
18
|
+
tick(): Promise<readonly LivenessFinding[]>;
|
|
19
|
+
/** Read the facts through the cap surface. Changes nothing. */
|
|
20
|
+
private gather;
|
|
21
|
+
/**
|
|
22
|
+
* Newest segment for a camera, or null when it has produced none in a day.
|
|
23
|
+
*
|
|
24
|
+
* Two steps on purpose: the healthy case asks only for the recent window,
|
|
25
|
+
* which is a handful of ranges, and only a camera that looks silent pays for
|
|
26
|
+
* the 24-hour lookback that decides whether it records at all.
|
|
27
|
+
*/
|
|
28
|
+
private lastSegmentMs;
|
|
29
|
+
/** Announce new faults and recoveries; say nothing about an unchanged fault. */
|
|
30
|
+
private report;
|
|
31
|
+
}
|
|
32
|
+
export {};
|