@camstack/system 1.2.443 → 1.2.445
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/assets/record-entries/icon.svg +8 -0
- package/dist/addon-runner.js +81 -42
- package/dist/addon-runner.mjs +82 -43
- package/dist/{agent-https-DlpTMDqA.js → agent-https-CiOW0-sj.js} +810 -12
- package/dist/{agent-https-U0d4uvn2.mjs → agent-https-D4Q8iFNd.mjs} +697 -13
- package/dist/auth/admin-token-manager.d.ts +9 -3
- package/dist/auth/api-key-manager.d.ts +9 -3
- package/dist/auth/auth-audit-log.d.ts +9 -3
- package/dist/auth/device-credential-manager.d.ts +5 -1
- package/dist/auth/external-identity-manager.d.ts +8 -21
- package/dist/auth/login-session-manager.d.ts +11 -3
- package/dist/auth/scoped-token-manager.d.ts +8 -52
- package/dist/auth/totp-manager.d.ts +11 -3
- package/dist/auth/user-manager.d.ts +10 -17
- 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/alert-store.d.ts +32 -0
- package/dist/builtins/alerts/alerts.addon.d.ts +19 -4
- package/dist/builtins/alerts/alerts.addon.js +331 -159
- package/dist/builtins/alerts/alerts.addon.mjs +330 -159
- package/dist/builtins/alerts/record-kinds.d.ts +15 -0
- package/dist/builtins/autotrack/index.js +1 -1
- package/dist/builtins/autotrack/index.mjs +1 -1
- package/dist/builtins/backup-orchestrator/backup-orchestrator.addon.d.ts +1 -0
- package/dist/builtins/backup-orchestrator/backup-orchestrator.addon.js +134 -193
- package/dist/builtins/backup-orchestrator/backup-orchestrator.addon.mjs +134 -193
- package/dist/builtins/backup-orchestrator/destination-policy.d.ts +4 -2
- package/dist/builtins/backup-orchestrator/encryption-key-store.d.ts +4 -2
- package/dist/builtins/backup-orchestrator/record-kinds.d.ts +58 -0
- package/dist/builtins/backup-orchestrator/schedule-store.d.ts +4 -2
- package/dist/builtins/backup-orchestrator/seed-marker-store.d.ts +4 -2
- package/dist/builtins/calendars/calendar-prefs-store.d.ts +13 -5
- package/dist/builtins/calendars/calendars.addon.d.ts +2 -2
- package/dist/builtins/calendars/calendars.addon.js +67 -64
- package/dist/builtins/calendars/calendars.addon.mjs +59 -64
- package/dist/builtins/calendars/record-kinds.d.ts +18 -0
- package/dist/builtins/camera-grid/index.js +1 -1
- package/dist/builtins/camera-grid/index.mjs +1 -1
- package/dist/builtins/cluster-agent/record-kinds.d.ts +36 -0
- package/dist/builtins/composer/composer.addon.js +2 -2
- package/dist/builtins/composer/composer.addon.mjs +2 -2
- package/dist/builtins/console-logging/index.js +1 -1
- package/dist/builtins/console-logging/index.mjs +1 -1
- package/dist/builtins/core-blocks/block-settings-store.d.ts +8 -4
- package/dist/builtins/core-blocks/core-block-store.d.ts +8 -16
- package/dist/builtins/core-blocks/core-blocks.addon.js +85 -112
- package/dist/builtins/core-blocks/core-blocks.addon.mjs +86 -113
- package/dist/builtins/core-blocks/index.mjs +1 -1
- package/dist/builtins/core-blocks/record-kinds.d.ts +26 -0
- package/dist/builtins/device-manager/device-manager.addon.js +111 -187
- package/dist/builtins/device-manager/device-manager.addon.mjs +110 -187
- package/dist/builtins/device-manager/device-tombstone-store.d.ts +9 -48
- package/dist/builtins/device-manager/record-kinds.d.ts +14 -0
- package/dist/builtins/hub-forwarder/index.js +1 -1
- package/dist/builtins/hub-forwarder/index.mjs +1 -1
- package/dist/builtins/keychain/index.js +152 -22
- package/dist/builtins/keychain/index.mjs +152 -22
- package/dist/builtins/keychain/keychain-service.d.ts +3 -2
- package/dist/builtins/keychain/keychain-store.d.ts +13 -2
- package/dist/builtins/keychain/record-kinds.d.ts +16 -0
- package/dist/builtins/liveness-monitor/liveness-monitor.addon.js +1 -1
- package/dist/builtins/liveness-monitor/liveness-monitor.addon.mjs +1 -1
- package/dist/builtins/local-auth/auth-schema.d.ts +3 -1
- package/dist/builtins/local-auth/local-auth.addon.js +2903 -2123
- package/dist/builtins/local-auth/local-auth.addon.mjs +2904 -2124
- package/dist/builtins/local-auth/oauth-session-manager.d.ts +8 -48
- package/dist/builtins/local-auth/record-kinds.d.ts +141 -0
- package/dist/builtins/local-network/local-network.addon.js +2 -2
- package/dist/builtins/local-network/local-network.addon.mjs +2 -2
- 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/record-entries/entries-service.d.ts +42 -0
- package/dist/builtins/record-entries/index.d.ts +1 -0
- package/dist/builtins/record-entries/index.js +142 -0
- package/dist/builtins/record-entries/index.mjs +136 -0
- package/dist/builtins/record-entries/record-entries.addon.d.ts +13 -0
- package/dist/builtins/records/legacy-table-row-count.d.ts +5 -0
- package/dist/builtins/records/phase6-declare-gate.d.ts +28 -0
- package/dist/builtins/records-isolated.d.ts +10 -0
- 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/file-host-client.d.ts +2 -0
- package/dist/builtins/sqlite-storage/file-host-handlers.d.ts +4 -0
- package/dist/builtins/sqlite-storage/file-host-protocol.d.ts +7 -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/index.js +1 -1
- package/dist/builtins/sqlite-storage/index.mjs +1 -1
- package/dist/builtins/sqlite-storage/integration-record-kinds.d.ts +30 -0
- package/dist/builtins/sqlite-storage/integration-registry.d.ts +10 -16
- package/dist/builtins/sqlite-storage/owned-sqlite-file.d.ts +7 -0
- package/dist/builtins/sqlite-storage/placement-router.d.ts +5 -0
- package/dist/builtins/sqlite-storage/records/count-settings-array-legacy.d.ts +5 -0
- package/dist/builtins/sqlite-storage/records/count-settings-brokers-legacy.d.ts +6 -0
- package/dist/builtins/sqlite-storage/records/records-catalog.d.ts +29 -0
- package/dist/builtins/sqlite-storage/records/records-engine-types.d.ts +51 -0
- package/dist/builtins/sqlite-storage/records/records-engine.d.ts +94 -0
- package/dist/builtins/sqlite-storage/records/records-explain.d.ts +18 -0
- package/dist/builtins/sqlite-storage/records/records-plan.d.ts +90 -0
- package/dist/builtins/sqlite-storage/records/records-probe.d.ts +33 -0
- package/dist/builtins/sqlite-storage/records/records-provider.d.ts +63 -0
- package/dist/builtins/sqlite-storage/records/records-rows.d.ts +46 -0
- package/dist/builtins/sqlite-storage/records/records-sql.d.ts +41 -0
- package/dist/builtins/sqlite-storage/sqlite-settings-backend.d.ts +17 -10
- package/dist/builtins/sqlite-storage/sqlite-settings.addon.d.ts +8 -0
- package/dist/builtins/sqlite-storage/sqlite-settings.addon.js +446 -5
- package/dist/builtins/sqlite-storage/sqlite-settings.addon.mjs +446 -5
- package/dist/builtins/sqlite-storage/storage-admin-provider.d.ts +15 -1
- package/dist/builtins/storage-orchestrator/drain-state-store.d.ts +5 -2
- package/dist/builtins/storage-orchestrator/location-store.d.ts +7 -2
- package/dist/builtins/storage-orchestrator/record-kinds.d.ts +38 -0
- package/dist/builtins/storage-orchestrator/storage-orchestrator.addon.d.ts +2 -0
- package/dist/builtins/storage-orchestrator/storage-orchestrator.addon.js +196 -5
- package/dist/builtins/storage-orchestrator/storage-orchestrator.addon.mjs +195 -6
- package/dist/builtins/system-config/record-kinds.d.ts +32 -0
- package/dist/builtins/system-config/system-config.addon.js +53 -618
- package/dist/builtins/system-config/system-config.addon.mjs +29 -577
- package/dist/builtins/winston-logging/index.js +1 -1
- package/dist/builtins/winston-logging/index.mjs +1 -1
- package/dist/{composition-sources-C8tUG2uL.mjs → composition-sources-BMt5cFYb.mjs} +1 -1
- package/dist/{composition-sources-BUXX1e8j.js → composition-sources-D3fi9Xns.js} +1 -1
- package/dist/{constants-CGwVaAV3.mjs → constants-BMHCxRzb.mjs} +1 -1
- package/dist/{constants-DWmm7_of.js → constants-Br879Axi.js} +1 -1
- package/dist/{device-ca-DGayRmC0.js → device-ca-CnJ_va7i.js} +1 -1
- package/dist/{device-ca-DBfiJ_SB.mjs → device-ca-T8osSMos.mjs} +1 -1
- package/dist/{dist-Bxt_S-9a.mjs → dist-BNunRyXT.mjs} +1133 -93
- package/dist/{dist-D9qT3jHr.js → dist-DgOG8flk.js} +1354 -92
- package/dist/file-host-worker.js +11 -1
- package/dist/file-host-worker.mjs +11 -1
- package/dist/{hub-mdns-ciao-B-wk9nzx.js → hub-mdns-ciao-BIkTHq-n.js} +2 -2
- package/dist/{hub-mdns-ciao-DpPcQDg-.mjs → hub-mdns-ciao-D16oRQ9K.mjs} +2 -2
- package/dist/index.d.ts +7 -0
- package/dist/index.js +3111 -2806
- package/dist/index.mjs +3083 -2795
- package/dist/kernel/index.d.ts +2 -0
- package/dist/kernel/moleculer/event-bus.d.ts +3 -1
- package/dist/kernel/moleculer/mesh-mtls/mesh-certificate-registry.d.ts +5 -1
- package/dist/kernel/moleculer/records-api-transport.d.ts +9 -0
- package/dist/kernel/moleculer/remote-logger.d.ts +2 -2
- package/dist/kernel/settings-view-types.d.ts +0 -7
- package/dist/kernel/transport/cap-route-resolver.d.ts +9 -38
- package/dist/phase6-declare-gate-Ci1-8uUn.js +98 -0
- package/dist/phase6-declare-gate-tkKOEitw.mjs +93 -0
- package/dist/read-all-rows-CVoO1ONM.js +29 -0
- package/dist/read-all-rows-TaPqdWNF.mjs +25 -0
- package/dist/records/read-all-rows.d.ts +6 -0
- package/dist/{restore-archive-9CGgeBzD.mjs → restore-archive-DR9MtO7J.mjs} +339 -9
- package/dist/{restore-archive-BMNXwWWD.js → restore-archive-DjJnCgap.js} +353 -5
- package/dist/tls/agent-https-names.d.ts +9 -13
- package/dist/{wal-maintenance-cRHR4rUY.js → wal-maintenance-CODGqhKY.js} +0 -0
- package/dist/{wal-maintenance-sIB32ONp.mjs → wal-maintenance-CfvgtQ7C.mjs} +0 -0
- package/package.json +22 -1
|
@@ -1,4 +1,6 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { Ci as createEvent, Di as defineRecordKinds, Lr as errMsg, Rr as BaseAddon, ft as alertsCapability, i as AlertSchema, la as EventCategory } from "../../dist-BNunRyXT.mjs";
|
|
2
|
+
import { t as require_read_all_rows } from "../../read-all-rows-TaPqdWNF.mjs";
|
|
3
|
+
import { t as resolvePhase6UseRecordsPathForHub } from "../../phase6-declare-gate-tkKOEitw.mjs";
|
|
2
4
|
//#region src/builtins/alerts/critical-push.ts
|
|
3
5
|
/** Alert categories that are critical system findings. */
|
|
4
6
|
var CRITICAL_CATEGORIES = new Set([
|
|
@@ -277,6 +279,210 @@ function runnerPushLine(record) {
|
|
|
277
279
|
return record.state === "refused" ? `${where}: refused to start. ${record.remedy ?? "See the Addons page."}` : `${where}: stopped after repeated crashes. Restart it from the Addons page.`;
|
|
278
280
|
}
|
|
279
281
|
//#endregion
|
|
282
|
+
//#region src/builtins/alerts/record-kinds.ts
|
|
283
|
+
var import_read_all_rows = require_read_all_rows();
|
|
284
|
+
/**
|
|
285
|
+
* Record kinds owned by alert-center (records plan phase 4).
|
|
286
|
+
*/
|
|
287
|
+
/** Legacy collection / adoptsFrom target (canonical KV before phase 4). */
|
|
288
|
+
var ALERTS_COLLECTION = "alerts";
|
|
289
|
+
var _alertCenterRecordKinds = defineRecordKinds({ alerts: {
|
|
290
|
+
schema: AlertSchema.omit({ id: true }),
|
|
291
|
+
class: "audit",
|
|
292
|
+
writeTrigger: "EventBus categories the alert center tracks, operator mark read/dismiss, and model-download progress merges",
|
|
293
|
+
device: "none",
|
|
294
|
+
at: "none",
|
|
295
|
+
indexes: [
|
|
296
|
+
{
|
|
297
|
+
name: "read",
|
|
298
|
+
fields: ["read"]
|
|
299
|
+
},
|
|
300
|
+
{
|
|
301
|
+
name: "created_at",
|
|
302
|
+
fields: ["createdAt"]
|
|
303
|
+
},
|
|
304
|
+
{
|
|
305
|
+
name: "updated_at",
|
|
306
|
+
fields: ["updatedAt"]
|
|
307
|
+
}
|
|
308
|
+
],
|
|
309
|
+
retention: {
|
|
310
|
+
owner: "alert-center",
|
|
311
|
+
reason: "maxAlerts cap and retentionDays enforced on write (enforceMaxAlerts / enforceRetention); read alerts preferred when trimming overflow"
|
|
312
|
+
},
|
|
313
|
+
adoptsFrom: ALERTS_COLLECTION
|
|
314
|
+
} });
|
|
315
|
+
var alertCenterRecordKinds = _alertCenterRecordKinds;
|
|
316
|
+
/** Narrow kind for `records.kind()` — `IsolatedRecordKinds` string index is `| undefined`. */
|
|
317
|
+
var alertsRecordKind = _alertCenterRecordKinds.alerts;
|
|
318
|
+
//#endregion
|
|
319
|
+
//#region src/builtins/alerts/alert-store.ts
|
|
320
|
+
function toRecord(row) {
|
|
321
|
+
return {
|
|
322
|
+
id: row.id,
|
|
323
|
+
data: row.data
|
|
324
|
+
};
|
|
325
|
+
}
|
|
326
|
+
function toRecordFromLegacy(row) {
|
|
327
|
+
return {
|
|
328
|
+
id: row.id,
|
|
329
|
+
data: row.data
|
|
330
|
+
};
|
|
331
|
+
}
|
|
332
|
+
function isRecord(value) {
|
|
333
|
+
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
334
|
+
}
|
|
335
|
+
function legacyGetData(value) {
|
|
336
|
+
if (!isRecord(value)) return null;
|
|
337
|
+
if ("data" in value) {
|
|
338
|
+
const data = value.data;
|
|
339
|
+
return isRecord(data) ? data : null;
|
|
340
|
+
}
|
|
341
|
+
return value;
|
|
342
|
+
}
|
|
343
|
+
var AlertStore = class AlertStore {
|
|
344
|
+
kind;
|
|
345
|
+
legacyStore;
|
|
346
|
+
constructor(kind, legacyStore) {
|
|
347
|
+
this.kind = kind;
|
|
348
|
+
this.legacyStore = legacyStore;
|
|
349
|
+
}
|
|
350
|
+
static of(records) {
|
|
351
|
+
return new AlertStore(records.kind(alertsRecordKind), null);
|
|
352
|
+
}
|
|
353
|
+
static legacy(store) {
|
|
354
|
+
return new AlertStore(null, store);
|
|
355
|
+
}
|
|
356
|
+
async legacyRows() {
|
|
357
|
+
const store = this.legacyStore;
|
|
358
|
+
if (store === null) return [];
|
|
359
|
+
return (await store.query.query({
|
|
360
|
+
collection: ALERTS_COLLECTION,
|
|
361
|
+
filter: {}
|
|
362
|
+
})).map((row) => toRecordFromLegacy({
|
|
363
|
+
id: row.id,
|
|
364
|
+
data: row.data
|
|
365
|
+
}));
|
|
366
|
+
}
|
|
367
|
+
async list(filter) {
|
|
368
|
+
let out;
|
|
369
|
+
const kind = this.kind;
|
|
370
|
+
if (kind !== null) out = (await (0, import_read_all_rows.readAllRows)(kind, { order: "id" })).map(toRecord);
|
|
371
|
+
else out = [...await this.legacyRows()];
|
|
372
|
+
if (filter?.unreadOnly === true) out = out.filter((r) => r.data["read"] === false);
|
|
373
|
+
out.sort((a, b) => Number(b.data["updatedAt"] ?? 0) - Number(a.data["updatedAt"] ?? 0));
|
|
374
|
+
const limit = filter?.limit ?? 100;
|
|
375
|
+
return out.slice(0, limit);
|
|
376
|
+
}
|
|
377
|
+
async countUnread() {
|
|
378
|
+
return (await this.list({
|
|
379
|
+
unreadOnly: true,
|
|
380
|
+
limit: 1e4
|
|
381
|
+
})).length;
|
|
382
|
+
}
|
|
383
|
+
async countAll() {
|
|
384
|
+
const kind = this.kind;
|
|
385
|
+
if (kind !== null) return (await (0, import_read_all_rows.readAllRows)(kind)).length;
|
|
386
|
+
return (await this.legacyRows()).length;
|
|
387
|
+
}
|
|
388
|
+
async getData(id) {
|
|
389
|
+
const kind = this.kind;
|
|
390
|
+
if (kind !== null) {
|
|
391
|
+
const row = await kind.get(id);
|
|
392
|
+
if (row === null) return null;
|
|
393
|
+
return row.data;
|
|
394
|
+
}
|
|
395
|
+
const store = this.legacyStore;
|
|
396
|
+
if (store === null) return null;
|
|
397
|
+
return legacyGetData(await store.get.query({
|
|
398
|
+
collection: ALERTS_COLLECTION,
|
|
399
|
+
key: id
|
|
400
|
+
}));
|
|
401
|
+
}
|
|
402
|
+
async mergeUpdate(id, patch) {
|
|
403
|
+
const existing = await this.getData(id);
|
|
404
|
+
if (existing === null) return;
|
|
405
|
+
await this.putRaw(id, {
|
|
406
|
+
...existing,
|
|
407
|
+
...patch
|
|
408
|
+
});
|
|
409
|
+
}
|
|
410
|
+
async persist(alert) {
|
|
411
|
+
const { id, ...body } = alert;
|
|
412
|
+
const data = alertsRecordKind.schema.parse(body);
|
|
413
|
+
const kind = this.kind;
|
|
414
|
+
if (kind !== null) {
|
|
415
|
+
await kind.put({
|
|
416
|
+
id,
|
|
417
|
+
data
|
|
418
|
+
});
|
|
419
|
+
return;
|
|
420
|
+
}
|
|
421
|
+
await this.putRaw(id, {
|
|
422
|
+
...body,
|
|
423
|
+
id
|
|
424
|
+
});
|
|
425
|
+
}
|
|
426
|
+
async putRaw(id, data) {
|
|
427
|
+
const { id: _drop, ...body } = AlertSchema.parse({
|
|
428
|
+
id,
|
|
429
|
+
...data
|
|
430
|
+
});
|
|
431
|
+
const kind = this.kind;
|
|
432
|
+
if (kind !== null) {
|
|
433
|
+
await kind.put({
|
|
434
|
+
id,
|
|
435
|
+
data: body
|
|
436
|
+
});
|
|
437
|
+
return;
|
|
438
|
+
}
|
|
439
|
+
const store = this.legacyStore;
|
|
440
|
+
if (store === null) return;
|
|
441
|
+
await store.set.mutate({
|
|
442
|
+
collection: ALERTS_COLLECTION,
|
|
443
|
+
key: id,
|
|
444
|
+
value: {
|
|
445
|
+
id,
|
|
446
|
+
...body
|
|
447
|
+
}
|
|
448
|
+
});
|
|
449
|
+
}
|
|
450
|
+
async delete(id) {
|
|
451
|
+
const kind = this.kind;
|
|
452
|
+
if (kind !== null) {
|
|
453
|
+
await kind.delete(id);
|
|
454
|
+
return;
|
|
455
|
+
}
|
|
456
|
+
const store = this.legacyStore;
|
|
457
|
+
if (store === null) return;
|
|
458
|
+
await store.delete.mutate({
|
|
459
|
+
collection: ALERTS_COLLECTION,
|
|
460
|
+
key: id
|
|
461
|
+
});
|
|
462
|
+
}
|
|
463
|
+
async listAllByCreatedAtAsc() {
|
|
464
|
+
const kind = this.kind;
|
|
465
|
+
let out;
|
|
466
|
+
if (kind !== null) out = (await (0, import_read_all_rows.readAllRows)(kind)).map(toRecord);
|
|
467
|
+
else out = [...await this.legacyRows()];
|
|
468
|
+
out.sort((a, b) => Number(a.data["createdAt"] ?? 0) - Number(b.data["createdAt"] ?? 0));
|
|
469
|
+
return out;
|
|
470
|
+
}
|
|
471
|
+
async listRecent(limit) {
|
|
472
|
+
const kind = this.kind;
|
|
473
|
+
let out;
|
|
474
|
+
if (kind !== null) out = (await (0, import_read_all_rows.readAllRows)(kind, { order: "id" })).map(toRecord);
|
|
475
|
+
else out = [...await this.legacyRows()];
|
|
476
|
+
out.sort((a, b) => Number(b.data["updatedAt"] ?? 0) - Number(a.data["updatedAt"] ?? 0));
|
|
477
|
+
return out.slice(0, limit);
|
|
478
|
+
}
|
|
479
|
+
async findWhereDataField(field, value) {
|
|
480
|
+
const kind = this.kind;
|
|
481
|
+
if (kind !== null) return (await (0, import_read_all_rows.readAllRows)(kind)).filter((r) => r.data[field] === value).map(toRecord);
|
|
482
|
+
return (await this.legacyRows()).filter((r) => r.data[field] === value);
|
|
483
|
+
}
|
|
484
|
+
};
|
|
485
|
+
//#endregion
|
|
280
486
|
//#region src/builtins/alerts/alerts.addon.ts
|
|
281
487
|
var CATEGORY_MAPPINGS = {
|
|
282
488
|
"addon.crashed": {
|
|
@@ -384,6 +590,21 @@ var SILENT_TRACKED_CATEGORIES = [
|
|
|
384
590
|
"system.liveness-recovered",
|
|
385
591
|
"stream.online"
|
|
386
592
|
];
|
|
593
|
+
/** The `stream.offline` reasons that are an outage (D883) — mirrors the broker's `isStreamOutageReason`. */
|
|
594
|
+
var STREAM_OUTAGE_REASONS = [
|
|
595
|
+
"stale-timeout",
|
|
596
|
+
"wake-timeout",
|
|
597
|
+
"connection-error",
|
|
598
|
+
"battery-unreachable"
|
|
599
|
+
];
|
|
600
|
+
/** The streams an offline event covers: its list, else the one stream it names. */
|
|
601
|
+
function streamIdsOf(listed, fallback) {
|
|
602
|
+
if (Array.isArray(listed)) {
|
|
603
|
+
const ids = listed.filter((id) => typeof id === "string");
|
|
604
|
+
if (ids.length > 0) return ids;
|
|
605
|
+
}
|
|
606
|
+
return fallback !== void 0 ? [fallback] : [];
|
|
607
|
+
}
|
|
387
608
|
var TRACKED_CATEGORIES = [...Object.keys(CATEGORY_MAPPINGS), ...SILENT_TRACKED_CATEGORIES];
|
|
388
609
|
/**
|
|
389
610
|
* `[ALERT-CENTER-EVENTS]` — rate limiting. Events that fire thousands of
|
|
@@ -434,13 +655,18 @@ var DEFAULT_CONFIG = {
|
|
|
434
655
|
maxAlerts: 500,
|
|
435
656
|
retentionDays: 30,
|
|
436
657
|
criticalPushEnabled: true,
|
|
437
|
-
criticalPushTargetIds:
|
|
658
|
+
criticalPushTargetIds: []
|
|
438
659
|
};
|
|
660
|
+
/** Accept the live `string[]` shape and the pre-multiselect CSV string. */
|
|
661
|
+
function normalizeCriticalPushTargetIds(raw) {
|
|
662
|
+
if (Array.isArray(raw)) return raw.filter((id) => typeof id === "string" && id.trim().length > 0).map((id) => id.trim());
|
|
663
|
+
if (typeof raw === "string" && raw.trim().length > 0) return raw.split(",").map((id) => id.trim()).filter((id) => id.length > 0);
|
|
664
|
+
return [];
|
|
665
|
+
}
|
|
439
666
|
/** One burst of critical findings (a whole boot of refused runners) is ONE digest push. */
|
|
440
667
|
var PUSH_COALESCE_MS = 2e3;
|
|
441
668
|
/** Addons whose (re)start is a reason to retry pending critical pushes. */
|
|
442
669
|
var PUSH_RECONCILE_ADDONS = new Set(["notifiers", "notification-center"]);
|
|
443
|
-
var ALERTS_COLLECTION = "alerts";
|
|
444
670
|
var EVENT_SOURCE = {
|
|
445
671
|
type: "addon",
|
|
446
672
|
id: "alert-center"
|
|
@@ -461,6 +687,7 @@ function toPrunable(record) {
|
|
|
461
687
|
};
|
|
462
688
|
}
|
|
463
689
|
var AlertCenterAddon = class extends BaseAddon {
|
|
690
|
+
alertStore = null;
|
|
464
691
|
unsubscribers = [];
|
|
465
692
|
/** How long a burst of critical findings is gathered into one digest push. */
|
|
466
693
|
pushCoalesceMs;
|
|
@@ -475,6 +702,11 @@ var AlertCenterAddon = class extends BaseAddon {
|
|
|
475
702
|
*/
|
|
476
703
|
rateLimitCounters = /* @__PURE__ */ new Map();
|
|
477
704
|
async onInitialize() {
|
|
705
|
+
const records = this.ctx.records;
|
|
706
|
+
const store = this.ctx.api?.settingsStore;
|
|
707
|
+
const useRecords = records !== void 0 && store !== void 0 && await resolvePhase6UseRecordsPathForHub(this.ctx, "alert-center", alertCenterRecordKinds, ["alerts"]);
|
|
708
|
+
this.alertStore = useRecords && records !== void 0 ? AlertStore.of(records) : store === void 0 ? null : AlertStore.legacy(store);
|
|
709
|
+
if (this.alertStore === null) throw new Error("alert-center needs ctx.records or settings-store on the hub");
|
|
478
710
|
const alertsProvider = {
|
|
479
711
|
emit: (alert) => this.emitAlert(alert),
|
|
480
712
|
update: (input) => this.updateAlert(input.alertId, input.patch),
|
|
@@ -493,6 +725,8 @@ var AlertCenterAddon = class extends BaseAddon {
|
|
|
493
725
|
}
|
|
494
726
|
this.unsubscribers = unsubs;
|
|
495
727
|
this.reconcilePendingPushes();
|
|
728
|
+
this.dismissLegacyStreamCards(void 0);
|
|
729
|
+
this.migrateCriticalPushTargetIds();
|
|
496
730
|
this.ctx.logger.info("Initialized", { meta: { trackedCategoriesCount: TRACKED_CATEGORIES.length } });
|
|
497
731
|
return [{
|
|
498
732
|
capability: alertsCapability,
|
|
@@ -540,43 +774,28 @@ var AlertCenterAddon = class extends BaseAddon {
|
|
|
540
774
|
type: "boolean",
|
|
541
775
|
key: "criticalPushEnabled",
|
|
542
776
|
label: "Push critical system alerts",
|
|
543
|
-
description: "A runner that failed or refused to start, or a node whose runners are degraded, is pushed straight to the notifier targets
|
|
777
|
+
description: "A runner that failed or refused to start, or a node whose runners are degraded, is pushed straight to the notifier targets — even when Notification Center is down. This path does not use notification rules.",
|
|
544
778
|
default: true
|
|
545
779
|
}),
|
|
546
780
|
this.field({
|
|
547
|
-
type: "
|
|
781
|
+
type: "notification-target-multiselect",
|
|
548
782
|
key: "criticalPushTargetIds",
|
|
549
783
|
label: "Critical push targets",
|
|
550
|
-
description: "
|
|
551
|
-
default:
|
|
784
|
+
description: "Notifier targets that receive critical system alerts. Empty = every enabled shared (not personal) target.",
|
|
785
|
+
default: []
|
|
552
786
|
})
|
|
553
787
|
]
|
|
554
788
|
}] });
|
|
555
789
|
}
|
|
556
790
|
async listAlerts(filter) {
|
|
557
|
-
const
|
|
558
|
-
if (
|
|
559
|
-
|
|
560
|
-
if (filter?.unreadOnly) whereClause.read = false;
|
|
561
|
-
return (await backend.query.query({
|
|
562
|
-
collection: ALERTS_COLLECTION,
|
|
563
|
-
filter: {
|
|
564
|
-
where: Object.keys(whereClause).length > 0 ? whereClause : void 0,
|
|
565
|
-
orderBy: {
|
|
566
|
-
field: "updatedAt",
|
|
567
|
-
direction: "desc"
|
|
568
|
-
},
|
|
569
|
-
limit: filter?.limit ?? 100
|
|
570
|
-
}
|
|
571
|
-
})).map(parseAlert);
|
|
791
|
+
const store = this.alertStore;
|
|
792
|
+
if (store === null) return [];
|
|
793
|
+
return (await store.list(filter)).map(parseAlert);
|
|
572
794
|
}
|
|
573
795
|
async getUnreadCount() {
|
|
574
|
-
const
|
|
575
|
-
if (
|
|
576
|
-
return
|
|
577
|
-
collection: ALERTS_COLLECTION,
|
|
578
|
-
filter: { where: { read: false } }
|
|
579
|
-
});
|
|
796
|
+
const store = this.alertStore;
|
|
797
|
+
if (store === null) return 0;
|
|
798
|
+
return store.countUnread();
|
|
580
799
|
}
|
|
581
800
|
async markRead(alertId) {
|
|
582
801
|
await this.mergeUpdate(alertId, {
|
|
@@ -585,11 +804,11 @@ var AlertCenterAddon = class extends BaseAddon {
|
|
|
585
804
|
});
|
|
586
805
|
}
|
|
587
806
|
async markAllRead() {
|
|
588
|
-
const
|
|
589
|
-
if (
|
|
590
|
-
const unread = await
|
|
591
|
-
|
|
592
|
-
|
|
807
|
+
const store = this.alertStore;
|
|
808
|
+
if (store === null) return;
|
|
809
|
+
const unread = await store.list({
|
|
810
|
+
unreadOnly: true,
|
|
811
|
+
limit: 1e4
|
|
593
812
|
});
|
|
594
813
|
const now = Date.now();
|
|
595
814
|
for (const record of unread) await this.mergeUpdate(record.id, {
|
|
@@ -686,14 +905,14 @@ var AlertCenterAddon = class extends BaseAddon {
|
|
|
686
905
|
}
|
|
687
906
|
}
|
|
688
907
|
async readRunnerRecord(alertId) {
|
|
689
|
-
const
|
|
690
|
-
if (
|
|
691
|
-
const raw = await
|
|
692
|
-
|
|
693
|
-
|
|
908
|
+
const store = this.alertStore;
|
|
909
|
+
if (store === null) return null;
|
|
910
|
+
const raw = await store.getData(alertId);
|
|
911
|
+
if (raw === null) return null;
|
|
912
|
+
const alert = AlertSchema.safeParse({
|
|
913
|
+
id: alertId,
|
|
914
|
+
...raw
|
|
694
915
|
});
|
|
695
|
-
if (raw === null || raw === void 0 || typeof raw !== "object") return null;
|
|
696
|
-
const alert = AlertSchema.safeParse(raw);
|
|
697
916
|
if (!alert.success || alert.data.status === "dismissed") return null;
|
|
698
917
|
return parseRunnerRecord(alert.data.metadata?.["runner"]);
|
|
699
918
|
}
|
|
@@ -821,13 +1040,10 @@ var AlertCenterAddon = class extends BaseAddon {
|
|
|
821
1040
|
});
|
|
822
1041
|
}
|
|
823
1042
|
async readAlertRaw(alertId) {
|
|
824
|
-
const
|
|
825
|
-
if (
|
|
826
|
-
const raw = await
|
|
827
|
-
|
|
828
|
-
key: alertId
|
|
829
|
-
});
|
|
830
|
-
if (raw === null || raw === void 0 || typeof raw !== "object") return null;
|
|
1043
|
+
const store = this.alertStore;
|
|
1044
|
+
if (store === null) return null;
|
|
1045
|
+
const raw = await store.getData(alertId);
|
|
1046
|
+
if (raw === null) return null;
|
|
831
1047
|
const rec = Object.fromEntries(Object.entries(raw));
|
|
832
1048
|
const meta = rec["metadata"];
|
|
833
1049
|
const push = typeof meta === "object" && meta !== null && !Array.isArray(meta) ? meta["push"] : void 0;
|
|
@@ -845,9 +1061,19 @@ var AlertCenterAddon = class extends BaseAddon {
|
|
|
845
1061
|
pushPolicy() {
|
|
846
1062
|
return {
|
|
847
1063
|
enabled: this.config.criticalPushEnabled,
|
|
848
|
-
targetIds: this.config.criticalPushTargetIds
|
|
1064
|
+
targetIds: normalizeCriticalPushTargetIds(this.config.criticalPushTargetIds)
|
|
849
1065
|
};
|
|
850
1066
|
}
|
|
1067
|
+
/** Rewrite a legacy CSV `criticalPushTargetIds` string into `string[]`. */
|
|
1068
|
+
async migrateCriticalPushTargetIds() {
|
|
1069
|
+
const raw = this.config.criticalPushTargetIds;
|
|
1070
|
+
if (typeof raw !== "string") return;
|
|
1071
|
+
try {
|
|
1072
|
+
await this.updateGlobalSettings({ criticalPushTargetIds: normalizeCriticalPushTargetIds(raw) });
|
|
1073
|
+
} catch (err) {
|
|
1074
|
+
this.ctx.logger.warn("criticalPushTargetIds CSV migration failed", { meta: { error: err instanceof Error ? err.message : String(err) } });
|
|
1075
|
+
}
|
|
1076
|
+
}
|
|
851
1077
|
pushPorts() {
|
|
852
1078
|
const api = this.ctx.api;
|
|
853
1079
|
return {
|
|
@@ -924,27 +1150,16 @@ var AlertCenterAddon = class extends BaseAddon {
|
|
|
924
1150
|
return this.pushChain;
|
|
925
1151
|
}
|
|
926
1152
|
async storePushState(alertId, push) {
|
|
927
|
-
const
|
|
928
|
-
if (
|
|
929
|
-
const raw = await
|
|
930
|
-
|
|
931
|
-
|
|
932
|
-
});
|
|
933
|
-
if (raw === null || raw === void 0 || typeof raw !== "object") return;
|
|
934
|
-
const existing = Object.fromEntries(Object.entries(raw));
|
|
935
|
-
const meta = existing["metadata"];
|
|
1153
|
+
const store = this.alertStore;
|
|
1154
|
+
if (store === null) return;
|
|
1155
|
+
const raw = await store.getData(alertId);
|
|
1156
|
+
if (raw === null) return;
|
|
1157
|
+
const meta = raw["metadata"];
|
|
936
1158
|
const metadata = typeof meta === "object" && meta !== null && !Array.isArray(meta) ? meta : {};
|
|
937
|
-
await
|
|
938
|
-
|
|
939
|
-
|
|
940
|
-
|
|
941
|
-
...existing,
|
|
942
|
-
metadata: {
|
|
943
|
-
...metadata,
|
|
944
|
-
push
|
|
945
|
-
}
|
|
946
|
-
}
|
|
947
|
-
});
|
|
1159
|
+
await store.mergeUpdate(alertId, { metadata: {
|
|
1160
|
+
...metadata,
|
|
1161
|
+
push
|
|
1162
|
+
} });
|
|
948
1163
|
}
|
|
949
1164
|
/**
|
|
950
1165
|
* Retry every critical alert whose push is still pending - at boot and when
|
|
@@ -952,19 +1167,10 @@ var AlertCenterAddon = class extends BaseAddon {
|
|
|
952
1167
|
* delivered is skipped by its key, so reconciling never sends twice.
|
|
953
1168
|
*/
|
|
954
1169
|
async reconcilePendingPushes() {
|
|
955
|
-
const
|
|
956
|
-
if (
|
|
1170
|
+
const store = this.alertStore;
|
|
1171
|
+
if (store === null) return;
|
|
957
1172
|
try {
|
|
958
|
-
const rows = await
|
|
959
|
-
collection: ALERTS_COLLECTION,
|
|
960
|
-
filter: {
|
|
961
|
-
orderBy: {
|
|
962
|
-
field: "updatedAt",
|
|
963
|
-
direction: "desc"
|
|
964
|
-
},
|
|
965
|
-
limit: 500
|
|
966
|
-
}
|
|
967
|
-
});
|
|
1173
|
+
const rows = await store.listRecent(500);
|
|
968
1174
|
for (const row of rows) {
|
|
969
1175
|
const parsed = AlertSchema.safeParse({
|
|
970
1176
|
id: row.id,
|
|
@@ -991,12 +1197,9 @@ var AlertCenterAddon = class extends BaseAddon {
|
|
|
991
1197
|
const modelId = data.modelId ?? "unknown";
|
|
992
1198
|
const progress = data.progress ?? 0;
|
|
993
1199
|
const stableId = `model-download:${modelId}`;
|
|
994
|
-
const
|
|
995
|
-
if (
|
|
996
|
-
if (
|
|
997
|
-
collection: ALERTS_COLLECTION,
|
|
998
|
-
filter: { where: { id: stableId } }
|
|
999
|
-
})).length > 0) {
|
|
1200
|
+
const store = this.alertStore;
|
|
1201
|
+
if (store === null) return;
|
|
1202
|
+
if (await store.getData(stableId) !== null) {
|
|
1000
1203
|
const now = Date.now();
|
|
1001
1204
|
if (progress >= 100) {
|
|
1002
1205
|
await this.mergeUpdate(stableId, {
|
|
@@ -1197,23 +1400,26 @@ var AlertCenterAddon = class extends BaseAddon {
|
|
|
1197
1400
|
}
|
|
1198
1401
|
}
|
|
1199
1402
|
/**
|
|
1200
|
-
* Stream offline — ONLY `stale-timeout
|
|
1201
|
-
*
|
|
1403
|
+
* Stream offline — ONLY an outage reason counts: `stale-timeout`, or one of
|
|
1404
|
+
* the battery failures (`wake-timeout`, `connection-error`,
|
|
1405
|
+
* `battery-unreachable`). Suspend / destroy / idle dial are deliberate and
|
|
1406
|
+
* must not ring the bell (same gate NC uses). One card per DEVICE (D883).
|
|
1202
1407
|
*/
|
|
1203
1408
|
async handleStreamOffline(event) {
|
|
1204
1409
|
const reason = event.data["reason"];
|
|
1205
|
-
if (reason !== "
|
|
1410
|
+
if (typeof reason !== "string" || !STREAM_OUTAGE_REASONS.includes(reason)) return;
|
|
1206
1411
|
const deviceId = event.data["deviceId"];
|
|
1207
1412
|
const camStreamId = event.data["camStreamId"];
|
|
1208
|
-
if (typeof deviceId !== "number"
|
|
1413
|
+
if (typeof deviceId !== "number") return;
|
|
1414
|
+
const camStreamIds = streamIdsOf(event.data["camStreamIds"], typeof camStreamId === "string" ? camStreamId : void 0);
|
|
1209
1415
|
const name = await this.resolveDeviceName(deviceId);
|
|
1210
1416
|
const label = name ?? `Camera ${String(deviceId)}`;
|
|
1211
1417
|
const alert = {
|
|
1212
|
-
id: `stream-offline:${String(deviceId)}
|
|
1418
|
+
id: `stream-offline:${String(deviceId)}`,
|
|
1213
1419
|
category: EventCategory.StreamOffline,
|
|
1214
1420
|
severity: "warning",
|
|
1215
1421
|
title: "Stream offline",
|
|
1216
|
-
message: `${label} — ${
|
|
1422
|
+
message: `${label} — ${camStreamIds.length > 0 ? camStreamIds.join(", ") : "its stream"} stopped sending video (${reason}).`,
|
|
1217
1423
|
status: "active",
|
|
1218
1424
|
read: false,
|
|
1219
1425
|
createdAt: Date.now(),
|
|
@@ -1225,6 +1431,7 @@ var AlertCenterAddon = class extends BaseAddon {
|
|
|
1225
1431
|
metadata: {
|
|
1226
1432
|
deviceId,
|
|
1227
1433
|
camStreamId,
|
|
1434
|
+
camStreamIds,
|
|
1228
1435
|
reason,
|
|
1229
1436
|
...name !== void 0 ? { name } : {}
|
|
1230
1437
|
}
|
|
@@ -1234,9 +1441,9 @@ var AlertCenterAddon = class extends BaseAddon {
|
|
|
1234
1441
|
/** Stream online after an outage — drop the matching offline card. */
|
|
1235
1442
|
async handleStreamOnline(event) {
|
|
1236
1443
|
const deviceId = event.data["deviceId"];
|
|
1237
|
-
|
|
1238
|
-
|
|
1239
|
-
|
|
1444
|
+
if (typeof deviceId !== "number") return;
|
|
1445
|
+
const stableId = `stream-offline:${String(deviceId)}`;
|
|
1446
|
+
await this.dismissLegacyStreamCards(deviceId);
|
|
1240
1447
|
try {
|
|
1241
1448
|
await this.dismiss(stableId);
|
|
1242
1449
|
} catch (err) {
|
|
@@ -1246,6 +1453,19 @@ var AlertCenterAddon = class extends BaseAddon {
|
|
|
1246
1453
|
} });
|
|
1247
1454
|
}
|
|
1248
1455
|
}
|
|
1456
|
+
/**
|
|
1457
|
+
* Dismiss the pre-D883 per-cam-stream cards (`stream-offline:<deviceId>:<stream>`)
|
|
1458
|
+
* of one device, or of every device when none is named. They can never meet
|
|
1459
|
+
* their `stream.online` under the per-device id.
|
|
1460
|
+
*/
|
|
1461
|
+
async dismissLegacyStreamCards(deviceId) {
|
|
1462
|
+
try {
|
|
1463
|
+
const pattern = deviceId === void 0 ? /^stream-offline:\d+:.+/ : new RegExp(`^stream-offline:${String(deviceId)}:.+`);
|
|
1464
|
+
for (const alert of await this.listAlerts({ limit: 1e3 })) if (alert.status === "active" && pattern.test(alert.id)) await this.dismiss(alert.id);
|
|
1465
|
+
} catch (err) {
|
|
1466
|
+
this.ctx.logger?.debug("legacy stream cards: sweep failed", { meta: { error: errMsg(err) } });
|
|
1467
|
+
}
|
|
1468
|
+
}
|
|
1249
1469
|
async resolveDeviceName(deviceId) {
|
|
1250
1470
|
try {
|
|
1251
1471
|
const device = await this.ctx.api.deviceManager.getDevice.query({ deviceId });
|
|
@@ -1320,45 +1540,14 @@ var AlertCenterAddon = class extends BaseAddon {
|
|
|
1320
1540
|
* so we must read the existing record, merge the patch, and write back.
|
|
1321
1541
|
*/
|
|
1322
1542
|
async mergeUpdate(id, patch) {
|
|
1323
|
-
const
|
|
1324
|
-
if (
|
|
1325
|
-
|
|
1326
|
-
collection: ALERTS_COLLECTION,
|
|
1327
|
-
key: id
|
|
1328
|
-
});
|
|
1329
|
-
if (raw === null || raw === void 0 || typeof raw !== "object") return;
|
|
1330
|
-
const existing = Object.fromEntries(Object.entries(raw));
|
|
1331
|
-
await backend.set.mutate({
|
|
1332
|
-
collection: ALERTS_COLLECTION,
|
|
1333
|
-
key: id,
|
|
1334
|
-
value: {
|
|
1335
|
-
...existing,
|
|
1336
|
-
...patch
|
|
1337
|
-
}
|
|
1338
|
-
});
|
|
1543
|
+
const store = this.alertStore;
|
|
1544
|
+
if (store === null) return;
|
|
1545
|
+
await store.mergeUpdate(id, patch);
|
|
1339
1546
|
}
|
|
1340
1547
|
async persistAlert(alert) {
|
|
1341
|
-
const
|
|
1342
|
-
if (
|
|
1343
|
-
|
|
1344
|
-
id: alert.id,
|
|
1345
|
-
category: alert.category,
|
|
1346
|
-
severity: alert.severity,
|
|
1347
|
-
title: alert.title,
|
|
1348
|
-
message: alert.message,
|
|
1349
|
-
status: alert.status,
|
|
1350
|
-
read: alert.read,
|
|
1351
|
-
createdAt: alert.createdAt,
|
|
1352
|
-
updatedAt: alert.updatedAt,
|
|
1353
|
-
...alert.progress !== void 0 ? { progress: alert.progress } : {},
|
|
1354
|
-
...alert.source ? { source: alert.source } : {},
|
|
1355
|
-
...alert.metadata ? { metadata: alert.metadata } : {}
|
|
1356
|
-
};
|
|
1357
|
-
await backend.set.mutate({
|
|
1358
|
-
collection: ALERTS_COLLECTION,
|
|
1359
|
-
key: alert.id,
|
|
1360
|
-
value: data
|
|
1361
|
-
});
|
|
1548
|
+
const store = this.alertStore;
|
|
1549
|
+
if (store === null) return;
|
|
1550
|
+
await store.persist(alert);
|
|
1362
1551
|
}
|
|
1363
1552
|
emitAlertCreatedEvent(alert) {
|
|
1364
1553
|
this.ctx.eventBus?.emit(createEvent("alert.created", EVENT_SOURCE, {
|
|
@@ -1378,36 +1567,18 @@ var AlertCenterAddon = class extends BaseAddon {
|
|
|
1378
1567
|
}));
|
|
1379
1568
|
}
|
|
1380
1569
|
async enforceMaxAlerts() {
|
|
1381
|
-
const
|
|
1382
|
-
if (
|
|
1383
|
-
if (await
|
|
1384
|
-
const all = await
|
|
1385
|
-
|
|
1386
|
-
filter: { orderBy: {
|
|
1387
|
-
field: "createdAt",
|
|
1388
|
-
direction: "asc"
|
|
1389
|
-
} }
|
|
1390
|
-
});
|
|
1391
|
-
for (const id of selectOverflow(all.map(toPrunable), this.config.maxAlerts)) await backend.delete.mutate({
|
|
1392
|
-
collection: ALERTS_COLLECTION,
|
|
1393
|
-
key: id
|
|
1394
|
-
});
|
|
1570
|
+
const store = this.alertStore;
|
|
1571
|
+
if (store === null) return;
|
|
1572
|
+
if (await store.countAll() <= this.config.maxAlerts) return;
|
|
1573
|
+
const all = await store.listAllByCreatedAtAsc();
|
|
1574
|
+
for (const id of selectOverflow(all.map(toPrunable), this.config.maxAlerts)) await store.delete(id);
|
|
1395
1575
|
}
|
|
1396
1576
|
async enforceRetention() {
|
|
1397
|
-
const
|
|
1398
|
-
if (
|
|
1577
|
+
const store = this.alertStore;
|
|
1578
|
+
if (store === null) return;
|
|
1399
1579
|
const cutoff = Date.now() - this.config.retentionDays * 24 * 60 * 60 * 1e3;
|
|
1400
|
-
const all = await
|
|
1401
|
-
|
|
1402
|
-
filter: { orderBy: {
|
|
1403
|
-
field: "createdAt",
|
|
1404
|
-
direction: "asc"
|
|
1405
|
-
} }
|
|
1406
|
-
});
|
|
1407
|
-
for (const id of selectExpired(all.map(toPrunable), cutoff)) await backend.delete.mutate({
|
|
1408
|
-
collection: ALERTS_COLLECTION,
|
|
1409
|
-
key: id
|
|
1410
|
-
});
|
|
1580
|
+
const all = await store.listAllByCreatedAtAsc();
|
|
1581
|
+
for (const id of selectExpired(all.map(toPrunable), cutoff)) await store.delete(id);
|
|
1411
1582
|
}
|
|
1412
1583
|
};
|
|
1413
1584
|
//#endregion
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Record kinds owned by alert-center (records plan phase 4).
|
|
3
|
+
*/
|
|
4
|
+
import { type Alert, type DefinedRecordKind } from "@camstack/types";
|
|
5
|
+
import { z } from "zod";
|
|
6
|
+
/** Legacy collection / adoptsFrom target (canonical KV before phase 4). */
|
|
7
|
+
export declare const ALERTS_COLLECTION = "alerts";
|
|
8
|
+
export type AlertBody = Omit<Alert, "id">;
|
|
9
|
+
export declare const AlertBodySchema: z.ZodType<AlertBody>;
|
|
10
|
+
export type AlertCenterRecordKindsMap = {
|
|
11
|
+
readonly alerts: DefinedRecordKind<z.ZodType<AlertBody>>;
|
|
12
|
+
};
|
|
13
|
+
export declare const alertCenterRecordKinds: AlertCenterRecordKindsMap;
|
|
14
|
+
/** Narrow kind for `records.kind()` — `IsolatedRecordKinds` string index is `| undefined`. */
|
|
15
|
+
export declare const alertsRecordKind: DefinedRecordKind<z.ZodType<AlertBody>>;
|
|
@@ -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-DgOG8flk.js");
|
|
7
7
|
//#region src/builtins/autotrack/autotrack-config.ts
|
|
8
8
|
var DEFAULT_AUTOTRACK_LOOP_CONFIG = {
|
|
9
9
|
deadZoneFraction: .5,
|