@camstack/types 1.2.141 → 1.2.143
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.js +1 -1
- package/dist/addon.mjs +1 -1
- package/dist/capabilities/backup.cap.d.ts +149 -7
- package/dist/capabilities/device-manager.cap.d.ts +7 -0
- package/dist/capabilities/device-provider.cap.d.ts +30 -0
- package/dist/capabilities/index.d.ts +1 -1
- package/dist/capabilities/stream-broker.cap.d.ts +31 -0
- package/dist/device/base-device-provider.d.ts +67 -1
- package/dist/device/device-restore-retry.d.ts +93 -0
- package/dist/device/index.d.ts +3 -1
- package/dist/generated/addon-api.d.ts +28 -0
- package/dist/generated/device-proxy.d.ts +3 -1
- package/dist/generated/method-access-map.d.ts +1 -1
- package/dist/generated/method-device-selectors.d.ts +2 -2
- package/dist/generated/system-proxy.d.ts +1 -1
- package/dist/index.d.ts +3 -1
- package/dist/index.js +581 -26
- package/dist/index.mjs +575 -27
- package/dist/{sleep-C1mz-ocE.mjs → sleep-B195W080.mjs} +2 -0
- package/dist/{sleep-BwGJ_wL_.js → sleep-jdpPltQH.js} +2 -0
- package/package.json +1 -1
package/dist/addon.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
|
|
2
2
|
const require_event_category = require("./event-category-BaEgqJNv.js");
|
|
3
|
-
const require_sleep = require("./sleep-
|
|
3
|
+
const require_sleep = require("./sleep-jdpPltQH.js");
|
|
4
4
|
const require_err_msg = require("./err-msg-COpsHMw2.js");
|
|
5
5
|
//#region src/generated/cap-input-defaults.ts
|
|
6
6
|
/**
|
package/dist/addon.mjs
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { t as EventCategory } from "./event-category-BZL-fdNj.mjs";
|
|
2
|
-
import { B as ReadinessRegistry, E as adminUiCapability, L as nodePin, R as readNodePin, St as emitReadiness, T as DeviceType, V as ReadinessTimeoutError, W as scopeKey, _t as DisposerChain, a as asJsonObject, b as deviceOpsCapability, d as BOOT_RECOVERY_BACKOFF_MS, f as DEVICE_SCOPED_CAPS, gt as DATAPLANE_SECRET_HEADER, h as createEventBusSliceSource, j as expandCapMethods, m as createDeviceProxy, p as isDeviceScopedCap, s as asString, t as sleep, u as parseJsonUnknown, vt as BaseAddon, x as viewerUiCapability, yt as normalizeAddonInitResult } from "./sleep-
|
|
2
|
+
import { B as ReadinessRegistry, E as adminUiCapability, L as nodePin, R as readNodePin, St as emitReadiness, T as DeviceType, V as ReadinessTimeoutError, W as scopeKey, _t as DisposerChain, a as asJsonObject, b as deviceOpsCapability, d as BOOT_RECOVERY_BACKOFF_MS, f as DEVICE_SCOPED_CAPS, gt as DATAPLANE_SECRET_HEADER, h as createEventBusSliceSource, j as expandCapMethods, m as createDeviceProxy, p as isDeviceScopedCap, s as asString, t as sleep, u as parseJsonUnknown, vt as BaseAddon, x as viewerUiCapability, yt as normalizeAddonInitResult } from "./sleep-B195W080.mjs";
|
|
3
3
|
import { t as errMsg } from "./err-msg-IQTHeDzc.mjs";
|
|
4
4
|
//#region src/generated/cap-input-defaults.ts
|
|
5
5
|
/**
|
|
@@ -111,6 +111,82 @@ declare const LocationStatSchema: z.ZodObject<{
|
|
|
111
111
|
fileCount: z.ZodNumber;
|
|
112
112
|
present: z.ZodBoolean;
|
|
113
113
|
}, z.core.$strip>;
|
|
114
|
+
/** Lifecycle of a backup run. Terminal states: succeeded / failed / cancelled. */
|
|
115
|
+
declare const BackupRunStateSchema: z.ZodEnum<{
|
|
116
|
+
failed: "failed";
|
|
117
|
+
running: "running";
|
|
118
|
+
queued: "queued";
|
|
119
|
+
cancelled: "cancelled";
|
|
120
|
+
succeeded: "succeeded";
|
|
121
|
+
}>;
|
|
122
|
+
/**
|
|
123
|
+
* Where a running backup currently is. `queued` before it starts,
|
|
124
|
+
* `building` while the tar.gz is being staged, `uploading` during the
|
|
125
|
+
* per-destination fan-out, `done` once terminal.
|
|
126
|
+
*/
|
|
127
|
+
declare const BackupRunPhaseSchema: z.ZodEnum<{
|
|
128
|
+
queued: "queued";
|
|
129
|
+
done: "done";
|
|
130
|
+
building: "building";
|
|
131
|
+
uploading: "uploading";
|
|
132
|
+
}>;
|
|
133
|
+
/**
|
|
134
|
+
* Observable state of one backup run — readable WHILE it runs via
|
|
135
|
+
* `backup.listRuns`. This is what makes the execution queue and
|
|
136
|
+
* `backup.cancel` usable: the 2026-09-04 incident (two concurrent
|
|
137
|
+
* multi-GB builds, staging 5.1 GB → 18 GB, load 62) was only
|
|
138
|
+
* diagnosable with `du` because nothing reported that runs existed or
|
|
139
|
+
* how large the staged archive had grown.
|
|
140
|
+
*/
|
|
141
|
+
declare const BackupRunSchema: z.ZodObject<{
|
|
142
|
+
id: z.ZodString;
|
|
143
|
+
state: z.ZodEnum<{
|
|
144
|
+
failed: "failed";
|
|
145
|
+
running: "running";
|
|
146
|
+
queued: "queued";
|
|
147
|
+
cancelled: "cancelled";
|
|
148
|
+
succeeded: "succeeded";
|
|
149
|
+
}>;
|
|
150
|
+
phase: z.ZodEnum<{
|
|
151
|
+
queued: "queued";
|
|
152
|
+
done: "done";
|
|
153
|
+
building: "building";
|
|
154
|
+
uploading: "uploading";
|
|
155
|
+
}>;
|
|
156
|
+
destinationIds: z.ZodReadonly<z.ZodArray<z.ZodString>>;
|
|
157
|
+
label: z.ZodOptional<z.ZodString>;
|
|
158
|
+
requestedAt: z.ZodNumber;
|
|
159
|
+
startedAt: z.ZodOptional<z.ZodNumber>;
|
|
160
|
+
finishedAt: z.ZodOptional<z.ZodNumber>;
|
|
161
|
+
stagedBytes: z.ZodNumber;
|
|
162
|
+
archiveSizeBytes: z.ZodOptional<z.ZodNumber>;
|
|
163
|
+
uploadedBytes: z.ZodNumber;
|
|
164
|
+
completedDestinationIds: z.ZodReadonly<z.ZodArray<z.ZodString>>;
|
|
165
|
+
failedDestinationIds: z.ZodReadonly<z.ZodArray<z.ZodString>>;
|
|
166
|
+
error: z.ZodOptional<z.ZodString>;
|
|
167
|
+
queuePosition: z.ZodOptional<z.ZodNumber>;
|
|
168
|
+
}, z.core.$strip>;
|
|
169
|
+
/**
|
|
170
|
+
* Result of `backup.trigger`. The call still resolves when the run
|
|
171
|
+
* terminates (compat with schedule-driven runs and the admin UI), but
|
|
172
|
+
* it now names the run and says whether it had to WAIT: a trigger that
|
|
173
|
+
* arrives while another run is in flight is enqueued (or joined onto
|
|
174
|
+
* an identical already-queued run), never started concurrently.
|
|
175
|
+
*/
|
|
176
|
+
declare const BackupTriggerResultSchema: z.ZodObject<{
|
|
177
|
+
runId: z.ZodString;
|
|
178
|
+
queued: z.ZodBoolean;
|
|
179
|
+
joined: z.ZodBoolean;
|
|
180
|
+
cancelled: z.ZodBoolean;
|
|
181
|
+
entries: z.ZodReadonly<z.ZodArray<z.ZodObject<{
|
|
182
|
+
id: z.ZodString;
|
|
183
|
+
destinationId: z.ZodOptional<z.ZodString>;
|
|
184
|
+
label: z.ZodOptional<z.ZodString>;
|
|
185
|
+
createdAt: z.ZodNumber;
|
|
186
|
+
sizeBytes: z.ZodNumber;
|
|
187
|
+
locations: z.ZodOptional<z.ZodArray<z.ZodString>>;
|
|
188
|
+
}, z.core.$strip>>>;
|
|
189
|
+
}, z.core.$strip>;
|
|
114
190
|
/**
|
|
115
191
|
* A backup schedule — the N:M "entry" that binds one cron cadence to a
|
|
116
192
|
* SET of destination locations. Supersedes the per-location cron on
|
|
@@ -176,20 +252,82 @@ export declare const backupCapability: {
|
|
|
176
252
|
* Trigger a backup. Without `destinations` the orchestrator fans
|
|
177
253
|
* out to every destination flagged as enabled in the routing
|
|
178
254
|
* config; with it, only the listed addons receive the archive.
|
|
255
|
+
*
|
|
256
|
+
* At most ONE backup run executes at a time — the source tree and
|
|
257
|
+
* the staging disk are shared by every run, so a second trigger
|
|
258
|
+
* while one is in flight is enqueued (or joined onto an identical
|
|
259
|
+
* queued run) and the result says so. See D342.
|
|
179
260
|
*/
|
|
180
261
|
readonly trigger: import("./capability-definition.js").CapabilityMethodSchema<z.ZodOptional<z.ZodObject<{
|
|
181
262
|
destinations: z.ZodOptional<z.ZodArray<z.ZodString>>;
|
|
182
263
|
locations: z.ZodOptional<z.ZodArray<z.ZodString>>;
|
|
183
264
|
label: z.ZodOptional<z.ZodString>;
|
|
184
265
|
retentionCount: z.ZodOptional<z.ZodNumber>;
|
|
185
|
-
}, z.core.$strip>>, z.
|
|
266
|
+
}, z.core.$strip>>, z.ZodObject<{
|
|
267
|
+
runId: z.ZodString;
|
|
268
|
+
queued: z.ZodBoolean;
|
|
269
|
+
joined: z.ZodBoolean;
|
|
270
|
+
cancelled: z.ZodBoolean;
|
|
271
|
+
entries: z.ZodReadonly<z.ZodArray<z.ZodObject<{
|
|
272
|
+
id: z.ZodString;
|
|
273
|
+
destinationId: z.ZodOptional<z.ZodString>;
|
|
274
|
+
label: z.ZodOptional<z.ZodString>;
|
|
275
|
+
createdAt: z.ZodNumber;
|
|
276
|
+
sizeBytes: z.ZodNumber;
|
|
277
|
+
locations: z.ZodOptional<z.ZodArray<z.ZodString>>;
|
|
278
|
+
}, z.core.$strip>>>;
|
|
279
|
+
}, z.core.$strip>, "mutation">;
|
|
280
|
+
/**
|
|
281
|
+
* Every run the orchestrator knows about, in EXECUTION order: the
|
|
282
|
+
* running run first, then queued runs in the exact order they will
|
|
283
|
+
* execute (each with `queuePosition`, 1 = next), then the bounded
|
|
284
|
+
* finished history newest-first. Only one run executes at a time
|
|
285
|
+
* (D342) — the queued section IS the line. Each run carries live
|
|
286
|
+
* phase + byte counters so a runaway build is visible in seconds,
|
|
287
|
+
* not via `du`.
|
|
288
|
+
*/
|
|
289
|
+
readonly listRuns: import("./capability-definition.js").CapabilityMethodSchema<z.ZodVoid, z.ZodReadonly<z.ZodArray<z.ZodObject<{
|
|
186
290
|
id: z.ZodString;
|
|
187
|
-
|
|
291
|
+
state: z.ZodEnum<{
|
|
292
|
+
failed: "failed";
|
|
293
|
+
running: "running";
|
|
294
|
+
queued: "queued";
|
|
295
|
+
cancelled: "cancelled";
|
|
296
|
+
succeeded: "succeeded";
|
|
297
|
+
}>;
|
|
298
|
+
phase: z.ZodEnum<{
|
|
299
|
+
queued: "queued";
|
|
300
|
+
done: "done";
|
|
301
|
+
building: "building";
|
|
302
|
+
uploading: "uploading";
|
|
303
|
+
}>;
|
|
304
|
+
destinationIds: z.ZodReadonly<z.ZodArray<z.ZodString>>;
|
|
188
305
|
label: z.ZodOptional<z.ZodString>;
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
306
|
+
requestedAt: z.ZodNumber;
|
|
307
|
+
startedAt: z.ZodOptional<z.ZodNumber>;
|
|
308
|
+
finishedAt: z.ZodOptional<z.ZodNumber>;
|
|
309
|
+
stagedBytes: z.ZodNumber;
|
|
310
|
+
archiveSizeBytes: z.ZodOptional<z.ZodNumber>;
|
|
311
|
+
uploadedBytes: z.ZodNumber;
|
|
312
|
+
completedDestinationIds: z.ZodReadonly<z.ZodArray<z.ZodString>>;
|
|
313
|
+
failedDestinationIds: z.ZodReadonly<z.ZodArray<z.ZodString>>;
|
|
314
|
+
error: z.ZodOptional<z.ZodString>;
|
|
315
|
+
queuePosition: z.ZodOptional<z.ZodNumber>;
|
|
316
|
+
}, z.core.$strip>>>, import("./capability-definition.js").CapabilityMethodKind>;
|
|
317
|
+
/**
|
|
318
|
+
* Stop a backup run. Mirrors `storage-migration.cancel` semantics:
|
|
319
|
+
* id in, `{ cancelled }` out — `false` when the run is unknown or
|
|
320
|
+
* already terminal. A QUEUED run is removed before it ever starts;
|
|
321
|
+
* the RUNNING run has its tar/upload stream actually aborted, the
|
|
322
|
+
* half-written staging archive is deleted, and the in-flight
|
|
323
|
+
* destination upload is aborted server-side (partial discarded).
|
|
324
|
+
* Destinations that already completed keep their archive.
|
|
325
|
+
*/
|
|
326
|
+
readonly cancel: import("./capability-definition.js").CapabilityMethodSchema<z.ZodObject<{
|
|
327
|
+
runId: z.ZodString;
|
|
328
|
+
}, z.core.$strip>, z.ZodObject<{
|
|
329
|
+
cancelled: z.ZodBoolean;
|
|
330
|
+
}, z.core.$strip>, "mutation">;
|
|
193
331
|
/** Union of every destination's archives, each tagged with `destinationId`. */
|
|
194
332
|
readonly list: import("./capability-definition.js").CapabilityMethodSchema<z.ZodVoid, z.ZodReadonly<z.ZodArray<z.ZodObject<{
|
|
195
333
|
id: z.ZodString;
|
|
@@ -337,4 +475,8 @@ export declare const backupCapability: {
|
|
|
337
475
|
};
|
|
338
476
|
};
|
|
339
477
|
export type IBackupProvider = InferProvider<typeof backupCapability>;
|
|
340
|
-
export { ArchiveEntrySchema, ArchiveManifestSchema, BackupArchiveEntrySchema, BackupDestinationInfoSchema, BackupEntrySchema, BackupScheduleSchema, BackupSubDestinationInfoSchema, LocationStatSchema, };
|
|
478
|
+
export { ArchiveEntrySchema, ArchiveManifestSchema, BackupArchiveEntrySchema, BackupDestinationInfoSchema, BackupEntrySchema, BackupRunPhaseSchema, BackupRunSchema, BackupRunStateSchema, BackupScheduleSchema, BackupSubDestinationInfoSchema, BackupTriggerResultSchema, LocationStatSchema, };
|
|
479
|
+
export type BackupRunState = z.infer<typeof BackupRunStateSchema>;
|
|
480
|
+
export type BackupRunPhase = z.infer<typeof BackupRunPhaseSchema>;
|
|
481
|
+
export type BackupRun = z.infer<typeof BackupRunSchema>;
|
|
482
|
+
export type BackupTriggerResult = z.infer<typeof BackupTriggerResultSchema>;
|
|
@@ -349,6 +349,13 @@ export declare const deviceManagerCapability: {
|
|
|
349
349
|
* `sourceStillLive` names what stayed live; empty is the only value that
|
|
350
350
|
* means the old hardware is quiet. The migration proceeds either way —
|
|
351
351
|
* refusing would refuse the case this exists for.
|
|
352
|
+
*
|
|
353
|
+
* **Safe to retry.** A duplicate call while a migration involving either
|
|
354
|
+
* device is in flight is REFUSED, never queued; a repeat of a swap that
|
|
355
|
+
* already completed (matched against the `addonId`/`stableId` fingerprint
|
|
356
|
+
* the swap left on the rows, within 15 min) is a no-op returning the
|
|
357
|
+
* original report. A blind re-run can no longer silently undo the
|
|
358
|
+
* migration it retried.
|
|
352
359
|
*/
|
|
353
360
|
readonly migrateDevice: import("./capability-definition.js").CapabilityMethodSchema<z.ZodObject<{
|
|
354
361
|
sourceId: z.ZodNumber;
|
|
@@ -82,6 +82,36 @@ export declare const deviceProviderCapability: {
|
|
|
82
82
|
name: z.ZodString;
|
|
83
83
|
type: z.ZodString;
|
|
84
84
|
}, z.core.$strip>>, import("./capability-definition.js").CapabilityMethodKind>;
|
|
85
|
+
/**
|
|
86
|
+
* Tear down and reconstruct ONE device in place from its persisted rows —
|
|
87
|
+
* touching no other device this provider owns.
|
|
88
|
+
*
|
|
89
|
+
* The primitive `deviceManager.migrateDevice` uses to flush the two
|
|
90
|
+
* migrated numbers: after `swapIds` the runner's live instance still
|
|
91
|
+
* carries the PRE-swap numeric id (baked into the object, its native-cap
|
|
92
|
+
* registrations and its log tags), and a live object cannot be renumbered.
|
|
93
|
+
* Before this method the only flush was restarting the whole owning addon
|
|
94
|
+
* — which took every camera the provider owns down with it (28 devices
|
|
95
|
+
* for one migrated camera, measured 2026-09-04, and the morning of the
|
|
96
|
+
* same day ~27 devices' native caps did not come back on their own).
|
|
97
|
+
*
|
|
98
|
+
* Keyed by `stableId`, deliberately: the numeric id is exactly the thing
|
|
99
|
+
* that changes. The reply carries the id the device answers on NOW.
|
|
100
|
+
* Implemented once in `BaseDeviceProvider` — decommission the live
|
|
101
|
+
* instance (if any), then re-create from the persisted row: the same
|
|
102
|
+
* teardown/rehydrate pair every graceful shutdown + boot already uses.
|
|
103
|
+
* An RPC, never an event: a dropped event would leave the runner writing
|
|
104
|
+
* against the wrong camera (D8).
|
|
105
|
+
*
|
|
106
|
+
* Construction can dial hardware, and the migrated source is
|
|
107
|
+
* characteristically dead — the timeout covers a full activate window
|
|
108
|
+
* rather than the 60 s default.
|
|
109
|
+
*/
|
|
110
|
+
readonly reloadDevice: import("./capability-definition.js").CapabilityMethodSchema<z.ZodObject<{
|
|
111
|
+
stableId: z.ZodString;
|
|
112
|
+
}, z.core.$strip>, z.ZodObject<{
|
|
113
|
+
deviceId: z.ZodNumber;
|
|
114
|
+
}, z.core.$strip>, "mutation">;
|
|
85
115
|
readonly supportsDiscovery: import("./capability-definition.js").CapabilityMethodSchema<z.ZodObject<{}, z.core.$strip>, z.ZodBoolean, import("./capability-definition.js").CapabilityMethodKind>;
|
|
86
116
|
/**
|
|
87
117
|
* Run a network scan. `params` carries optional provider-specific scan
|
|
@@ -31,7 +31,7 @@ export type { AudioAnalyzerGlobalConfig, AudioBackendChoice, IAudioAnalyzerProvi
|
|
|
31
31
|
export { AUDIO_BACKEND_CHOICES, AudioAnalysisResultSchema, AudioAnalysisSettingsSchema, AudioClassificationResultSchema, audioAnalyzerCapability, DEFAULT_AUDIO_ANALYZER_CONFIG, } from './audio-analyzer.cap.js';
|
|
32
32
|
export { AudioCodecInfoSchema, AudioDecodeSessionConfigSchema, AudioEncodedChunkSchema, AudioEncodeSessionConfigSchema, AudioPcmChunkSchema, audioCodecCapability, type IAudioCodecCapProvider, PcmSampleFormatSchema, } from './audio-codec.cap.js';
|
|
33
33
|
export { AuthResultSchema, authProviderCapability } from './auth-provider.cap.js';
|
|
34
|
-
export { ArchiveEntrySchema, ArchiveManifestSchema, BackupDestinationInfoSchema, BackupEntrySchema, backupCapability, type IBackupProvider, LocationStatSchema, } from './backup.cap.js';
|
|
34
|
+
export { ArchiveEntrySchema, ArchiveManifestSchema, BackupDestinationInfoSchema, BackupEntrySchema, type BackupRun, type BackupRunPhase, BackupRunPhaseSchema, BackupRunSchema, type BackupRunState, BackupRunStateSchema, type BackupTriggerResult, BackupTriggerResultSchema, backupCapability, type IBackupProvider, LocationStatSchema, } from './backup.cap.js';
|
|
35
35
|
export { BrokerAddInputSchema, BrokerGetStateInputSchema, type BrokerInfo as UnifiedBrokerInfo, BrokerInfoSchema as UnifiedBrokerInfoSchema, type BrokerProviderInfo, BrokerProviderInfoSchema, BrokerPublishInputSchema, BrokerRegistryStatusSchema, type BrokerStatus as UnifiedBrokerStatus, BrokerStatusEnum, BrokerSubscribeInputSchema, BrokerSubscribeResultSchema, BrokerTestConnectionResultSchema, BrokerUnsubscribeInputSchema, brokerCapability, type IBrokerProvider, } from './broker.cap.js';
|
|
36
36
|
export { cameraPipelineConfigCapability, type ICameraPipelineConfigProvider, } from './camera-pipeline-config.cap.js';
|
|
37
37
|
export { cameraStreamsCapability, type ICameraStreamsProvider, type PickedCamStream, PickedCamStreamSchema, PickStreamPreferencesSchema, PickStreamRequirementsSchema, type StreamCodec, StreamCodecSchema, } from './camera-streams.cap.js';
|
|
@@ -643,6 +643,37 @@ export declare const streamBrokerCapability: {
|
|
|
643
643
|
}, z.core.$strip>, z.ZodObject<{
|
|
644
644
|
success: z.ZodLiteral<true>;
|
|
645
645
|
}, z.core.$strip>, "mutation">;
|
|
646
|
+
/**
|
|
647
|
+
* The HARDWARE behind a device number was replaced
|
|
648
|
+
* (`deviceManager.migrateDevice`). Forget every piece of broker state that
|
|
649
|
+
* described the old box, so the next catalog pull derives everything from
|
|
650
|
+
* the camera that is actually there:
|
|
651
|
+
*
|
|
652
|
+
* - every `derived:*` stream definition — a derived is authored against a
|
|
653
|
+
* specific profile layout, and against the wrong hardware its feeder
|
|
654
|
+
* respawns forever (observed at attempt 2732 on the live hub,
|
|
655
|
+
* 2026-09-01);
|
|
656
|
+
* - the profile-slot assignment entry, PURGED (not unassigned — unassign
|
|
657
|
+
* marks the slot manual, which would pin the stale choice instead of
|
|
658
|
+
* letting `computeInitialAssignment` re-derive it);
|
|
659
|
+
* - the probe snapshots (`<deviceId>/…` — probed codec/resolution of the
|
|
660
|
+
* old hardware);
|
|
661
|
+
* - the persisted RTSP token rows for the device's brokers (keyed
|
|
662
|
+
* `<deviceId>/<camStreamId>`; the stream ids change with the hardware,
|
|
663
|
+
* so the rows are dead URLs).
|
|
664
|
+
*
|
|
665
|
+
* An RPC, deliberately — an event is telemetry and may be dropped (D8),
|
|
666
|
+
* and a dropped forget leaves a feeder respawning against a stream that
|
|
667
|
+
* does not exist.
|
|
668
|
+
*/
|
|
669
|
+
readonly forgetDeviceHardware: import("./capability-definition.js").CapabilityMethodSchema<z.ZodObject<{
|
|
670
|
+
deviceId: z.ZodNumber;
|
|
671
|
+
}, z.core.$strip>, z.ZodObject<{
|
|
672
|
+
derivedStreamsDeleted: z.ZodReadonly<z.ZodArray<z.ZodString>>;
|
|
673
|
+
assignmentsPurged: z.ZodBoolean;
|
|
674
|
+
probeSnapshotsDropped: z.ZodNumber;
|
|
675
|
+
rtspTokenRowsDeleted: z.ZodNumber;
|
|
676
|
+
}, z.core.$strip>, "mutation">;
|
|
646
677
|
/**
|
|
647
678
|
* Render a short GIF or MP4 from the broker's PRE-BUFFER around an instant.
|
|
648
679
|
*
|
|
@@ -4,6 +4,7 @@ import type { ConfigUISchema } from '../interfaces/config-ui.js';
|
|
|
4
4
|
import type { IDevice } from './device.js';
|
|
5
5
|
import type { DeviceConstructor } from './device-context.js';
|
|
6
6
|
import type { CreateDeviceSpec, SavedDevice } from './device-management.js';
|
|
7
|
+
import type { PermanentRestoreFailure } from './device-restore-retry.js';
|
|
7
8
|
import { DeviceType } from './device-type.js';
|
|
8
9
|
import type { SourceInfo } from './source-info.js';
|
|
9
10
|
export interface DiscoveryCandidate {
|
|
@@ -38,6 +39,19 @@ export interface ProviderStatus {
|
|
|
38
39
|
readonly deviceCount: number;
|
|
39
40
|
readonly error?: string;
|
|
40
41
|
}
|
|
42
|
+
/**
|
|
43
|
+
* Outcome of an `onRestoreDevices` pass. Optional for back-compat:
|
|
44
|
+
* providers with custom overrides may keep returning `void` — they
|
|
45
|
+
* just don't get the accurate summary log (or the bounded retry the
|
|
46
|
+
* default implementation wires up, see D347).
|
|
47
|
+
*/
|
|
48
|
+
export interface DeviceRestoreReport {
|
|
49
|
+
/** Rows registered during the initial pass. */
|
|
50
|
+
readonly restoredCount: number;
|
|
51
|
+
/** Rows that failed the initial pass and were handed to the bounded
|
|
52
|
+
* background retry. */
|
|
53
|
+
readonly failedCount: number;
|
|
54
|
+
}
|
|
41
55
|
export interface FieldProbeResult {
|
|
42
56
|
readonly status: 'ok' | 'error';
|
|
43
57
|
readonly labels?: readonly string[];
|
|
@@ -147,6 +161,52 @@ export declare abstract class BaseDeviceProvider<TConfig extends object = Record
|
|
|
147
161
|
formValues?: Record<string, unknown>;
|
|
148
162
|
}): Promise<FieldProbeResult>;
|
|
149
163
|
restoreDevices(savedDevices: readonly SavedDevice[]): Promise<void>;
|
|
164
|
+
/** Retry schedule. Overridable (tests use millisecond delays). */
|
|
165
|
+
protected readonly restoreRetryDelaysMs: readonly number[];
|
|
166
|
+
/** Retry lane width. See `device-restore-retry.ts` for why retries
|
|
167
|
+
* never re-stampede full-width while the initial pass does (D167). */
|
|
168
|
+
protected readonly restoreRetryConcurrency: number;
|
|
169
|
+
private _restoreRetryScheduler;
|
|
170
|
+
private _restoreRetryCompletion;
|
|
171
|
+
private readonly _permanentRestoreFailures;
|
|
172
|
+
/** Settles when the background retry rounds finish (or `null` when
|
|
173
|
+
* nothing failed). Exposed for tests and subclass diagnostics —
|
|
174
|
+
* boot NEVER awaits this: the runner's post-init handshake goes out
|
|
175
|
+
* with the devices that restored, and a late success is announced
|
|
176
|
+
* through the `native-cap-change` → `updateCaps` path. */
|
|
177
|
+
protected get restoreRetryCompletion(): Promise<void> | null;
|
|
178
|
+
/** Devices that exhausted the retry bound this process lifetime. */
|
|
179
|
+
protected get permanentRestoreFailures(): readonly PermanentRestoreFailure[];
|
|
180
|
+
/** One-line operator-facing summary for `getStatus().error`, or
|
|
181
|
+
* `null` when every device restored. */
|
|
182
|
+
protected restoreFailureSummary(): string | null;
|
|
183
|
+
private cancelRestoreRetries;
|
|
184
|
+
private recordPermanentRestoreFailure;
|
|
185
|
+
private scheduleRestoreRetries;
|
|
186
|
+
/**
|
|
187
|
+
* Tear down and reconstruct ONE device from its persisted rows — the
|
|
188
|
+
* `deviceProvider.reloadDevice` cap method. Persistence is never touched,
|
|
189
|
+
* and no other device this provider owns is disturbed.
|
|
190
|
+
*
|
|
191
|
+
* Keyed by `stableId` because the caller's whole reason to be here is that
|
|
192
|
+
* the NUMERIC id changed (`deviceManager.migrateDevice` swapped it): the
|
|
193
|
+
* fresh instance resolves its id through `allocateDeviceId`, which returns
|
|
194
|
+
* whatever number the row carries NOW. The teardown is `decommission` —
|
|
195
|
+
* exactly what a graceful shutdown runs per device (fires `removeDevice()`,
|
|
196
|
+
* unregisters native caps, drops the registry entry) — and the rebuild is
|
|
197
|
+
* the boot restore's own `create()` path, including its pass 2: first-class
|
|
198
|
+
* children (hub-adopted cameras under an NVR) are decommissioned with the
|
|
199
|
+
* parent by the cascade and must be re-created explicitly, because only
|
|
200
|
+
* accessory children come back through `getAccessoryChildren()`.
|
|
201
|
+
*
|
|
202
|
+
* Reloading an accessory child directly is refused (no device class) —
|
|
203
|
+
* reload its parent instead.
|
|
204
|
+
*/
|
|
205
|
+
reloadDevice(input: {
|
|
206
|
+
stableId: string;
|
|
207
|
+
}): Promise<{
|
|
208
|
+
deviceId: number;
|
|
209
|
+
}>;
|
|
150
210
|
/**
|
|
151
211
|
* Concrete device classes this provider can spawn, keyed by
|
|
152
212
|
* `DeviceType`. Used by:
|
|
@@ -196,8 +256,14 @@ export declare abstract class BaseDeviceProvider<TConfig extends object = Record
|
|
|
196
256
|
* accessory-spawn flow handles via the parent's
|
|
197
257
|
* `getAccessoryChildren()`. Override only when the default doesn't
|
|
198
258
|
* fit.
|
|
259
|
+
*
|
|
260
|
+
* A row that fails either pass is NOT terminal (D347): it is handed
|
|
261
|
+
* to a bounded background retry (`DeviceRestoreRetryScheduler`).
|
|
262
|
+
* Only after the bound is exhausted is the device marked permanently
|
|
263
|
+
* failed — logged at ERROR with `tags.deviceId` and surfaced via
|
|
264
|
+
* `getStatus().error`.
|
|
199
265
|
*/
|
|
200
|
-
protected onRestoreDevices(savedDevices: readonly SavedDevice[]): Promise<void>;
|
|
266
|
+
protected onRestoreDevices(savedDevices: readonly SavedDevice[]): Promise<DeviceRestoreReport | void>;
|
|
201
267
|
/** Convert an IDevice to the flat DeviceSummary for the cap router. */
|
|
202
268
|
protected toSummary(device: IDevice): DeviceSummary;
|
|
203
269
|
}
|
|
@@ -0,0 +1,93 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Bounded retry for failed per-device boot restores (D347).
|
|
3
|
+
*
|
|
4
|
+
* WHY: a provider runner's boot restore is a full-width fan-out of
|
|
5
|
+
* independent `kernel.devices.create()` dials (D167). When the hub is
|
|
6
|
+
* briefly busy (a migration holding device-manager, a starved event
|
|
7
|
+
* loop) whole batches of those dials time out together at the UDS
|
|
8
|
+
* transport's 60 s default — and until D347 a failed restore was
|
|
9
|
+
* TERMINAL: the device's native caps never entered the worker map,
|
|
10
|
+
* `updateCaps` never announced them, and every route answered
|
|
11
|
+
* "binding not yet in LocalChildRegistry" for the life of the process.
|
|
12
|
+
* 27 cameras were off the air for 20 minutes on 2026-09-04 because of
|
|
13
|
+
* exactly this; the devices were healthy and merely lost a race.
|
|
14
|
+
*
|
|
15
|
+
* The scheduler distinguishes "not yet" from "never":
|
|
16
|
+
* - **not yet** — a bounded number of retries with growing delays
|
|
17
|
+
* (`DEVICE_RESTORE_RETRY_DELAYS_MS`). A retry that succeeds flows
|
|
18
|
+
* through the runner's `native-cap-change` listener, so the
|
|
19
|
+
* device's caps are announced via `updateCaps` even though the
|
|
20
|
+
* post-init handshake has long passed.
|
|
21
|
+
* - **never** — after the last round the device is handed to
|
|
22
|
+
* `onPermanentFailure` with its attempt count and last error, and
|
|
23
|
+
* nothing retries it again (CrashSupervisor's discipline, D6:
|
|
24
|
+
* bounded, then terminally failed and VISIBLE — the provider
|
|
25
|
+
* surfaces it via `getStatus().error` and an ERROR log tagged
|
|
26
|
+
* `deviceId`).
|
|
27
|
+
*
|
|
28
|
+
* Retry width is bounded (`DEVICE_RESTORE_RETRY_CONCURRENCY`): the
|
|
29
|
+
* devices being retried already failed TOGETHER, which is evidence of
|
|
30
|
+
* hub congestion — re-stampeding the full set recreates the collision.
|
|
31
|
+
* The INITIAL fan-out stays full-width (D167 measured a lane cap
|
|
32
|
+
* costing 6.5 min on a healthy boot); only the retry lanes are capped,
|
|
33
|
+
* so a large fleet's happy-path boot is byte-for-byte unchanged.
|
|
34
|
+
*
|
|
35
|
+
* Cancellation (`cancel()`) is for shutdown: pending entries are NOT
|
|
36
|
+
* marked permanently failed — the process is going away and the next
|
|
37
|
+
* boot re-runs the restore from the persisted rows.
|
|
38
|
+
*/
|
|
39
|
+
import type { IScopedLogger } from '../interfaces/logging.js';
|
|
40
|
+
import type { SavedDevice } from './device-management.js';
|
|
41
|
+
/**
|
|
42
|
+
* Delays before retry rounds 1..N — the round count IS the bound.
|
|
43
|
+
* 10 s catches "the hub was busy for a moment"; the full schedule
|
|
44
|
+
* (10 + 30 + 90 s of waiting, plus up to one 60 s transport timeout
|
|
45
|
+
* per attempt) covers a device-manager lock held for minutes — the
|
|
46
|
+
* 2026-09-04 outage's migration hold was ~3.5 min.
|
|
47
|
+
*/
|
|
48
|
+
export declare const DEVICE_RESTORE_RETRY_DELAYS_MS: readonly number[];
|
|
49
|
+
/** Lane width for retry rounds. See module docblock — retries are
|
|
50
|
+
* evidence of congestion, so they never re-stampede full-width. */
|
|
51
|
+
export declare const DEVICE_RESTORE_RETRY_CONCURRENCY = 4;
|
|
52
|
+
/** One device that failed its initial restore attempt. */
|
|
53
|
+
export interface InitialRestoreFailure {
|
|
54
|
+
readonly saved: SavedDevice;
|
|
55
|
+
readonly error: string;
|
|
56
|
+
}
|
|
57
|
+
/** A device that exhausted the retry bound. Kept by the provider for
|
|
58
|
+
* the life of the process and surfaced via `getStatus().error`. */
|
|
59
|
+
export interface PermanentRestoreFailure {
|
|
60
|
+
readonly deviceId: number;
|
|
61
|
+
readonly stableId: string;
|
|
62
|
+
readonly type: string;
|
|
63
|
+
/** Total attempts made, including the initial restore. */
|
|
64
|
+
readonly attempts: number;
|
|
65
|
+
readonly lastError: string;
|
|
66
|
+
/** Epoch ms of the final failed attempt. */
|
|
67
|
+
readonly failedAt: number;
|
|
68
|
+
}
|
|
69
|
+
/** Attempts one device restore. Throws on failure; resolving means the
|
|
70
|
+
* device is registered (or already was). */
|
|
71
|
+
export type RestoreAttemptFn = (saved: SavedDevice) => Promise<void>;
|
|
72
|
+
export type PermanentRestoreFailureHandler = (failure: PermanentRestoreFailure) => void;
|
|
73
|
+
export interface DeviceRestoreRetrySchedulerOptions {
|
|
74
|
+
readonly logger: IScopedLogger;
|
|
75
|
+
readonly attempt: RestoreAttemptFn;
|
|
76
|
+
readonly onPermanentFailure: PermanentRestoreFailureHandler;
|
|
77
|
+
readonly delaysMs?: readonly number[];
|
|
78
|
+
readonly concurrency?: number;
|
|
79
|
+
readonly now?: () => number;
|
|
80
|
+
}
|
|
81
|
+
export declare class DeviceRestoreRetryScheduler {
|
|
82
|
+
#private;
|
|
83
|
+
constructor(options: DeviceRestoreRetrySchedulerOptions);
|
|
84
|
+
/** Stop retrying (shutdown). Pending entries are NOT marked
|
|
85
|
+
* permanently failed — the next boot restores them from disk. */
|
|
86
|
+
cancel(): void;
|
|
87
|
+
/**
|
|
88
|
+
* Run the bounded retry rounds. Resolves when every entry has either
|
|
89
|
+
* restored, been marked permanently failed, or the scheduler was
|
|
90
|
+
* cancelled. Never rejects.
|
|
91
|
+
*/
|
|
92
|
+
run(initialFailures: readonly InitialRestoreFailure[]): Promise<readonly PermanentRestoreFailure[]>;
|
|
93
|
+
}
|
package/dist/device/index.d.ts
CHANGED
|
@@ -1,8 +1,10 @@
|
|
|
1
1
|
export { ACCESSORY_LABEL, AccessoryKind, type AccessoryKindValue, accessoryStableId, } from './accessory.js';
|
|
2
2
|
export type { AccessoryChildSpec } from './base-device.js';
|
|
3
3
|
export { BaseDevice } from './base-device.js';
|
|
4
|
-
export type { DeviceSummary, DiscoveryCandidate, FieldProbeResult, ProviderStatus, } from './base-device-provider.js';
|
|
4
|
+
export type { DeviceRestoreReport, DeviceSummary, DiscoveryCandidate, FieldProbeResult, ProviderStatus, } from './base-device-provider.js';
|
|
5
5
|
export { BaseDeviceProvider, toDeviceSummary } from './base-device-provider.js';
|
|
6
|
+
export type { DeviceRestoreRetrySchedulerOptions, InitialRestoreFailure, PermanentRestoreFailure, PermanentRestoreFailureHandler, RestoreAttemptFn, } from './device-restore-retry.js';
|
|
7
|
+
export { DEVICE_RESTORE_RETRY_CONCURRENCY, DEVICE_RESTORE_RETRY_DELAYS_MS, DeviceRestoreRetryScheduler, } from './device-restore-retry.js';
|
|
6
8
|
export type { ICameraDevice, StreamSourceEntry } from './camera-device.js';
|
|
7
9
|
export type { DeclarationPlacement, DeclaredDeviceOutcome, DeclaredDevicePorts, DeclaredDeviceRow, DeclaredDevicesResult, DeclaredDevicesSpec, DeclaredIntegrationRow, DeviceDeclaration, } from './declared-device.js';
|
|
8
10
|
export { DECLARED_DEVICE_SWEEP_LIMIT, DECLARED_INTEGRATION_FIXED_KEY, DeclaredDevices, declarationOwnerNodeId, } from './declared-device.js';
|
|
@@ -870,6 +870,20 @@ export type AppRouter = TrpcCoreRouter<{
|
|
|
870
870
|
output: z.infer<typeof backupCapability.methods.trigger.output>;
|
|
871
871
|
meta: object;
|
|
872
872
|
}>;
|
|
873
|
+
listRuns: TRPCQueryProcedure<{
|
|
874
|
+
input: {
|
|
875
|
+
nodeId?: string | undefined;
|
|
876
|
+
} | undefined;
|
|
877
|
+
output: z.infer<typeof backupCapability.methods.listRuns.output>;
|
|
878
|
+
meta: object;
|
|
879
|
+
}>;
|
|
880
|
+
cancel: TRPCMutationProcedure<{
|
|
881
|
+
input: {
|
|
882
|
+
[x: string]: unknown;
|
|
883
|
+
} & z.input<typeof backupCapability.methods.cancel.input>;
|
|
884
|
+
output: z.infer<typeof backupCapability.methods.cancel.output>;
|
|
885
|
+
meta: object;
|
|
886
|
+
}>;
|
|
873
887
|
list: TRPCQueryProcedure<{
|
|
874
888
|
input: {
|
|
875
889
|
nodeId?: string | undefined;
|
|
@@ -2681,6 +2695,13 @@ export type AppRouter = TrpcCoreRouter<{
|
|
|
2681
2695
|
output: z.infer<typeof deviceProviderCapability.methods.getDevices.output>;
|
|
2682
2696
|
meta: object;
|
|
2683
2697
|
}>;
|
|
2698
|
+
reloadDevice: TRPCMutationProcedure<{
|
|
2699
|
+
input: {
|
|
2700
|
+
[x: string]: unknown;
|
|
2701
|
+
} & z.input<typeof deviceProviderCapability.methods.reloadDevice.input>;
|
|
2702
|
+
output: z.infer<typeof deviceProviderCapability.methods.reloadDevice.output>;
|
|
2703
|
+
meta: object;
|
|
2704
|
+
}>;
|
|
2684
2705
|
supportsDiscovery: TRPCQueryProcedure<{
|
|
2685
2706
|
input: {
|
|
2686
2707
|
[x: string]: unknown;
|
|
@@ -7568,6 +7589,13 @@ export type AppRouter = TrpcCoreRouter<{
|
|
|
7568
7589
|
output: z.infer<typeof streamBrokerCapability.methods.unassignProfile.output>;
|
|
7569
7590
|
meta: object;
|
|
7570
7591
|
}>;
|
|
7592
|
+
forgetDeviceHardware: TRPCMutationProcedure<{
|
|
7593
|
+
input: {
|
|
7594
|
+
[x: string]: unknown;
|
|
7595
|
+
} & z.input<typeof streamBrokerCapability.methods.forgetDeviceHardware.input>;
|
|
7596
|
+
output: z.infer<typeof streamBrokerCapability.methods.forgetDeviceHardware.output>;
|
|
7597
|
+
meta: object;
|
|
7598
|
+
}>;
|
|
7571
7599
|
renderPreBufferClip: TRPCMutationProcedure<{
|
|
7572
7600
|
input: {
|
|
7573
7601
|
[x: string]: unknown;
|
|
@@ -87,6 +87,7 @@ import type { cameraPipelineConfigCapability } from '../capabilities/camera-pipe
|
|
|
87
87
|
import type { deviceAdoptionCapability } from '../capabilities/device-adoption.cap.js';
|
|
88
88
|
import type { deviceExportCapability } from '../capabilities/device-export.cap.js';
|
|
89
89
|
import type { deviceManagerCapability } from '../capabilities/device-manager.cap.js';
|
|
90
|
+
import type { deviceProviderCapability } from '../capabilities/device-provider.cap.js';
|
|
90
91
|
import type { deviceStateCapability } from '../capabilities/device-state.cap.js';
|
|
91
92
|
import type { faceGalleryCapability } from '../capabilities/face-gallery.cap.js';
|
|
92
93
|
import type { networkQualityCapability } from '../capabilities/network-quality.cap.js';
|
|
@@ -272,6 +273,7 @@ export interface DeviceProxy {
|
|
|
272
273
|
readonly deviceAdoption: Pick<InferDeviceProxyCap<typeof deviceAdoptionCapability>, 'getStatus'>;
|
|
273
274
|
readonly deviceExport: Pick<InferDeviceProxyCap<typeof deviceExportCapability>, 'getDeviceSettingsContribution' | 'getDeviceLiveContribution' | 'applyDeviceSettingsPatch'>;
|
|
274
275
|
readonly deviceManager: Pick<InferDeviceProxyCap<typeof deviceManagerCapability>, 'loadConfig' | 'loadRuntimeState' | 'loadMeta' | 'setName' | 'setLocation' | 'setType' | 'setIntegrationId' | 'setLinkDeviceId' | 'setPrimaryChildEntityId' | 'setChildLayout' | 'setDisplay' | 'getWireableFields' | 'setRole' | 'applyInitialMeta' | 'setMetadata' | 'setDisabled' | 'getDevice' | 'getLinkedDevices' | 'getStreamSources' | 'getConfigSchema' | 'getSettingsSchema' | 'updateConfig' | 'enable' | 'disable' | 'remove' | 'getStreamProfileMap' | 'setStreamProfileMap' | 'probeStreams' | 'getBindings' | 'setWrapperActive' | 'getDeviceSettingsAggregate' | 'getDeviceLiveInfoAggregate' | 'getDeviceAggregate' | 'runDeviceAction' | 'updateDeviceField' | 'updateDeviceFieldsBatch' | 'testField' | 'getDeviceStatusAggregate' | 'getDeviceSettingsContribution' | 'getDeviceLiveContribution' | 'applyDeviceSettingsPatch'>;
|
|
276
|
+
readonly deviceProvider: Pick<InferDeviceProxyCap<typeof deviceProviderCapability>, 'reloadDevice'>;
|
|
275
277
|
readonly deviceState: Pick<InferDeviceProxyCap<typeof deviceStateCapability>, 'getSnapshot' | 'getCapSlice' | 'setCapSlice'>;
|
|
276
278
|
readonly faceGallery: Pick<InferDeviceProxyCap<typeof faceGalleryCapability>, 'listRecentFaces' | 'getFaceByTrack'>;
|
|
277
279
|
readonly networkQuality: Pick<InferDeviceProxyCap<typeof networkQualityCapability>, 'getDeviceStats' | 'reportClientStats'>;
|
|
@@ -282,7 +284,7 @@ export interface DeviceProxy {
|
|
|
282
284
|
readonly plateGallery: Pick<InferDeviceProxyCap<typeof plateGalleryCapability>, 'listPlates' | 'getPlateByTrack'>;
|
|
283
285
|
readonly recording: Pick<InferDeviceProxyCap<typeof recordingCapability>, 'getAvailability' | 'getDaysWithRecordings' | 'getPlaybackManifest' | 'getDeviceConfig' | 'locateSegment' | 'readSegmentBytes' | 'readGopBytes' | 'readWindowBytes' | 'setDeviceConfig' | 'rescanStorage' | 'pruneFootage' | 'deleteFootprint' | 'renderGif' | 'renderClip' | 'getStatus' | 'getDeviceSettingsContribution' | 'getDeviceLiveContribution' | 'applyDeviceSettingsPatch'>;
|
|
284
286
|
readonly recordingExport: Pick<InferDeviceProxyCap<typeof recordingExportCapability>, 'listExports'>;
|
|
285
|
-
readonly streamBroker: Pick<InferDeviceProxyCap<typeof streamBrokerCapability>, 'publishCameraStream' | 'retractCameraStream' | 'assignProfile' | 'unassignProfile' | 'renderPreBufferClip' | 'produceEventMedia' | 'restartProfile' | 'getDeviceAudioMute' | 'setDeviceAudioMute' | 'getDeviceSettingsContribution' | 'getDeviceLiveContribution' | 'applyDeviceSettingsPatch'>;
|
|
287
|
+
readonly streamBroker: Pick<InferDeviceProxyCap<typeof streamBrokerCapability>, 'publishCameraStream' | 'retractCameraStream' | 'assignProfile' | 'unassignProfile' | 'forgetDeviceHardware' | 'renderPreBufferClip' | 'produceEventMedia' | 'restartProfile' | 'getDeviceAudioMute' | 'setDeviceAudioMute' | 'getDeviceSettingsContribution' | 'getDeviceLiveContribution' | 'applyDeviceSettingsPatch'>;
|
|
286
288
|
}
|
|
287
289
|
/**
|
|
288
290
|
* Build a DeviceProxy that pre-binds deviceId + nodeId on every method call
|
|
@@ -6,7 +6,7 @@
|
|
|
6
6
|
* scope+access check inside `protectedProcedure` (see
|
|
7
7
|
* `server/backend/src/api/trpc/trpc.middleware.ts`).
|
|
8
8
|
*
|
|
9
|
-
* Coverage:
|
|
9
|
+
* Coverage: 1006 method paths across 126 capabilities.
|
|
10
10
|
*/
|
|
11
11
|
import type { CapabilityMethodAccess } from '../capabilities/capability-definition.js';
|
|
12
12
|
export interface MethodAccessRecord {
|
|
@@ -6,8 +6,8 @@
|
|
|
6
6
|
* system-scope cap that takes a deviceId was previously never device-filtered
|
|
7
7
|
* — see the generator header).
|
|
8
8
|
*
|
|
9
|
-
* Coverage:
|
|
10
|
-
*
|
|
9
|
+
* Coverage: 355 methods carry a device reference, of which
|
|
10
|
+
* 134 are on SYSTEM-scope caps.
|
|
11
11
|
*
|
|
12
12
|
* Top-level fields, number arrays, and one-level arrays of objects carrying
|
|
13
13
|
* a numeric device field (targets[].deviceId) are all mapped; the matcher
|
|
@@ -61,7 +61,7 @@ export interface SystemProxy {
|
|
|
61
61
|
readonly alerts: Pick<InferProvider<typeof alertsCapability>, 'emit' | 'update' | 'list' | 'getUnreadCount' | 'markRead' | 'markAllRead' | 'dismiss'>;
|
|
62
62
|
readonly audioAnalyzer: Pick<InferProvider<typeof audioAnalyzerCapability>, 'analyseChunk' | 'classify' | 'isReady' | 'dispose' | 'reprobeAudioEngine'>;
|
|
63
63
|
readonly audioCodec: Pick<InferProvider<typeof audioCodecCapability>, 'listSupportedCodecs' | 'canHandle' | 'createDecodeSession' | 'createEncodeSession' | 'closeSession' | 'pushEncodedFrame' | 'pullPcm' | 'pushPcm' | 'pullEncoded' | 'flushEncode' | 'listActiveSessions'>;
|
|
64
|
-
readonly backup: Pick<InferProvider<typeof backupCapability>, 'listDestinations' | 'trigger' | 'list' | 'listLocations' | 'getEntries' | 'restore' | 'delete' | 'listArchives' | 'upsertDestinationPolicy' | 'previewSchedule' | 'listSchedules' | 'upsertSchedule' | 'deleteSchedule'>;
|
|
64
|
+
readonly backup: Pick<InferProvider<typeof backupCapability>, 'listDestinations' | 'trigger' | 'listRuns' | 'cancel' | 'list' | 'listLocations' | 'getEntries' | 'restore' | 'delete' | 'listArchives' | 'upsertDestinationPolicy' | 'previewSchedule' | 'listSchedules' | 'upsertSchedule' | 'deleteSchedule'>;
|
|
65
65
|
readonly broker: Pick<InferProvider<typeof brokerCapability>, 'list' | 'get' | 'listProviders' | 'add' | 'remove' | 'testConnection' | 'getSettings' | 'setSettings' | 'getBrokerConfig' | 'getSettingsSchema' | 'testSettings' | 'publish' | 'subscribe' | 'unsubscribe' | 'getState' | 'getStatus'>;
|
|
66
66
|
readonly connectionTest: Pick<InferProvider<typeof connectionTestCapability>, 'testSettings' | 'describeTest'>;
|
|
67
67
|
readonly coreBlocks: Pick<InferProvider<typeof coreBlocksCapability>, 'list' | 'get' | 'create' | 'update' | 'delete' | 'setEnabled' | 'restart' | 'compile' | 'getTypeDefs'>;
|
package/dist/index.d.ts
CHANGED
|
@@ -141,8 +141,10 @@ export type { AccessoryKindValue } from './device/accessory.js';
|
|
|
141
141
|
export { ACCESSORY_LABEL, AccessoryKind, accessoryStableId, } from './device/accessory.js';
|
|
142
142
|
export type { AccessoryChildSpec } from './device/base-device.js';
|
|
143
143
|
export { BaseDevice } from './device/base-device.js';
|
|
144
|
-
export type { DeviceSummary, DiscoveryCandidate, FieldProbeResult, } from './device/base-device-provider.js';
|
|
144
|
+
export type { DeviceRestoreReport, DeviceSummary, DiscoveryCandidate, FieldProbeResult, } from './device/base-device-provider.js';
|
|
145
145
|
export { BaseDeviceProvider, toDeviceSummary } from './device/base-device-provider.js';
|
|
146
|
+
export type { DeviceRestoreRetrySchedulerOptions, InitialRestoreFailure, PermanentRestoreFailure, PermanentRestoreFailureHandler, RestoreAttemptFn, } from './device/device-restore-retry.js';
|
|
147
|
+
export { DEVICE_RESTORE_RETRY_CONCURRENCY, DEVICE_RESTORE_RETRY_DELAYS_MS, DeviceRestoreRetryScheduler, } from './device/device-restore-retry.js';
|
|
146
148
|
export type { BatteryPresence, BatteryPresenceInput } from './device/battery-presence.js';
|
|
147
149
|
export { BATTERY_UNREACHABLE_AFTER_MS, deriveBatteryPresence, isBatteryPresenceFault, } from './device/battery-presence.js';
|
|
148
150
|
export type { ICameraDevice, StreamSourceEntry } from './device/camera-device.js';
|