@camstack/system 1.2.155 → 1.2.157
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/addon-runner.js +1 -1
- package/dist/addon-runner.mjs +1 -1
- 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.js +1 -1
- package/dist/builtins/alerts/alerts.addon.mjs +1 -1
- package/dist/builtins/backup-orchestrator/backup-orchestrator.addon.js +1 -1
- package/dist/builtins/backup-orchestrator/backup-orchestrator.addon.mjs +1 -1
- package/dist/builtins/console-logging/index.js +1 -1
- package/dist/builtins/console-logging/index.mjs +1 -1
- package/dist/builtins/core-blocks/core-blocks.addon.js +1 -1
- package/dist/builtins/core-blocks/core-blocks.addon.mjs +1 -1
- package/dist/builtins/device-manager/device-manager.addon.js +2 -2
- package/dist/builtins/device-manager/device-manager.addon.mjs +2 -2
- 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/liveness-monitor.addon.js +1 -1
- package/dist/builtins/liveness-monitor/liveness-monitor.addon.mjs +1 -1
- package/dist/builtins/local-auth/local-auth.addon.js +1 -1
- package/dist/builtins/local-auth/local-auth.addon.mjs +1 -1
- package/dist/builtins/local-network/local-network.addon.js +1 -1
- package/dist/builtins/local-network/local-network.addon.mjs +1 -1
- package/dist/builtins/loki-logging/index.js +1 -1
- package/dist/builtins/loki-logging/index.mjs +1 -1
- package/dist/builtins/native-metrics/native-metrics.addon.js +1 -1
- package/dist/builtins/native-metrics/native-metrics.addon.mjs +1 -1
- package/dist/builtins/platform-probe/index.js +1 -1
- package/dist/builtins/platform-probe/index.mjs +1 -1
- package/dist/builtins/remote-access-orchestrator/remote-access-orchestrator.addon.js +1 -1
- package/dist/builtins/remote-access-orchestrator/remote-access-orchestrator.addon.mjs +1 -1
- package/dist/builtins/snapshot/index.js +1 -1
- package/dist/builtins/snapshot/index.mjs +1 -1
- package/dist/builtins/sqlite-storage/filesystem-storage.addon.js +1 -1
- package/dist/builtins/sqlite-storage/filesystem-storage.addon.mjs +1 -1
- package/dist/builtins/sqlite-storage/sqlite-settings.addon.js +0 -0
- package/dist/builtins/sqlite-storage/sqlite-settings.addon.mjs +0 -0
- package/dist/builtins/storage-orchestrator/storage-migration-coordinator.d.ts +101 -1
- package/dist/builtins/storage-orchestrator/storage-orchestrator.addon.d.ts +24 -0
- package/dist/builtins/storage-orchestrator/storage-orchestrator.addon.js +349 -40
- package/dist/builtins/storage-orchestrator/storage-orchestrator.addon.mjs +349 -40
- package/dist/builtins/storage-orchestrator/storage-orchestrator.service.d.ts +37 -1
- 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-BPlfW-CG.js → dist-CDgIzo82.js} +169 -12
- package/dist/{dist-D_NyUV6Y.mjs → dist-LvKus-mT.mjs} +169 -12
- package/dist/index.js +66 -14
- package/dist/index.mjs +66 -14
- package/dist/kernel/config-manager.d.ts +31 -0
- package/dist/kernel/settings-door-view.d.ts +2 -2
- package/dist/{manifest-python-deps-BiWtkFGY.mjs → manifest-python-deps-CD14Pv0-.mjs} +1 -1
- package/dist/{manifest-python-deps-w48vOhGR.js → manifest-python-deps-DVODn-qc.js} +1 -1
- package/dist/{retired-settings-keys-DBY6ebwV.js → retired-settings-keys-BfAzWvPC.js} +1 -1
- package/dist/{retired-settings-keys-Bq1Tb84I.mjs → retired-settings-keys-CV4QVdXj.mjs} +1 -1
- package/package.json +1 -1
|
@@ -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-CDgIzo82.js");
|
|
7
7
|
//#region src/builtins/system-config/system-config.addon.ts
|
|
8
8
|
/**
|
|
9
9
|
* Built-in `system-config` addon — Phase 4 of the settings redesign.
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { Kt as hydrateSchema, Ot as errMsg, kt as BaseAddon } from "../../dist-
|
|
1
|
+
import { Kt as hydrateSchema, Ot as errMsg, kt as BaseAddon } from "../../dist-LvKus-mT.mjs";
|
|
2
2
|
//#region src/builtins/system-config/system-config.addon.ts
|
|
3
3
|
/**
|
|
4
4
|
* Built-in `system-config` addon — Phase 4 of the settings redesign.
|
|
@@ -3,7 +3,7 @@ Object.defineProperties(exports, {
|
|
|
3
3
|
[Symbol.toStringTag]: { value: "Module" }
|
|
4
4
|
});
|
|
5
5
|
const require_chunk = require("../../chunk-Cek0wNdY.js");
|
|
6
|
-
const require_dist = require("../../dist-
|
|
6
|
+
const require_dist = require("../../dist-CDgIzo82.js");
|
|
7
7
|
const require_formatter = require("../../formatter-DqAKDlvN.js");
|
|
8
8
|
let node_path = require("node:path");
|
|
9
9
|
node_path = require_chunk.__toESM(node_path);
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { kt as BaseAddon, rt as logDestinationCapability } from "../../dist-
|
|
1
|
+
import { kt as BaseAddon, rt as logDestinationCapability } from "../../dist-LvKus-mT.mjs";
|
|
2
2
|
import { t as formatLogLine } from "../../formatter-B7qW8bPJ.mjs";
|
|
3
3
|
import * as path$1 from "node:path";
|
|
4
4
|
import path from "node:path";
|
|
@@ -4166,18 +4166,61 @@ var RelocateFootageInputSchema = zod.z.object({
|
|
|
4166
4166
|
* `RecordingConfig.enabled` or camera wrapper bindings. */
|
|
4167
4167
|
var StorageMigrationLeaseInputSchema = zod.z.object({ leaseId: zod.z.string().min(1) });
|
|
4168
4168
|
var StorageMigrationFootageMoveInputSchema = RelocateFootageInputSchema.extend({ leaseId: zod.z.string().min(1) });
|
|
4169
|
+
/**
|
|
4170
|
+
* What a `relocateMedia` pass DOES. One engine, three passes — never a second
|
|
4171
|
+
* mover (the engine already walks both collections with a timestamp cursor and
|
|
4172
|
+
* already has a stamp-without-copy path).
|
|
4173
|
+
*
|
|
4174
|
+
* - `move` — the default and the historical behaviour: event-media and
|
|
4175
|
+
* retrain blobs move to `toLocationId` and their rows are
|
|
4176
|
+
* stamped. The enrolled gallery is skipped (D197).
|
|
4177
|
+
* - `seal` — ROWS ONLY, no bytes. Every row whose `locationId` is NULL is
|
|
4178
|
+
* stamped with `toLocationId`. `toLocationId` here is the id the
|
|
4179
|
+
* bytes ALREADY sit on — today's `eventMedia` default — because
|
|
4180
|
+
* a NULL row means "wherever `eventMedia` points *now*", and the
|
|
4181
|
+
* instant a repoint moves that pointer the row reads from the
|
|
4182
|
+
* new disk while its bytes are on the old one.
|
|
4183
|
+
* - `gallery` — the inverse selection of `move`: ONLY the retention-exempt
|
|
4184
|
+
* (enrolled-gallery) rows, which `move` deliberately skips.
|
|
4185
|
+
* `galleryMedia` is `cardinality: 'single'`, so this pass can
|
|
4186
|
+
* never run beside a live second location: it is stop-the-world
|
|
4187
|
+
* by construction, which is acceptable only because the gallery
|
|
4188
|
+
* is a few KB per enrolled sample.
|
|
4189
|
+
*/
|
|
4190
|
+
var MediaRelocateModeSchema = zod.z.enum([
|
|
4191
|
+
"move",
|
|
4192
|
+
"seal",
|
|
4193
|
+
"gallery"
|
|
4194
|
+
]);
|
|
4169
4195
|
var RelocateMediaInputSchema = zod.z.object({
|
|
4170
4196
|
toLocationId: zod.z.string(),
|
|
4171
|
-
throttleMbps: zod.z.number().min(1).max(1e3).optional()
|
|
4197
|
+
throttleMbps: zod.z.number().min(1).max(1e3).optional(),
|
|
4198
|
+
/** Omitted = `move`, the pre-existing behaviour. */
|
|
4199
|
+
mode: MediaRelocateModeSchema.optional()
|
|
4200
|
+
});
|
|
4201
|
+
/** How many rows still carry NO `locationId` — the population a repoint would
|
|
4202
|
+
* silently re-aim at a disk that does not hold their bytes. Zero is the only
|
|
4203
|
+
* value that permits a non-blocking `eventMedia` cutover. */
|
|
4204
|
+
var UnstampedEventMediaCountSchema = zod.z.object({
|
|
4205
|
+
media: zod.z.number().int().nonnegative(),
|
|
4206
|
+
retrainFrames: zod.z.number().int().nonnegative(),
|
|
4207
|
+
total: zod.z.number().int().nonnegative()
|
|
4172
4208
|
});
|
|
4173
4209
|
var StorageMigrationMediaMoveInputSchema = RelocateMediaInputSchema.extend({ leaseId: zod.z.string().min(1) });
|
|
4174
|
-
/** The independently selectable logical storage classes
|
|
4175
|
-
*
|
|
4176
|
-
*
|
|
4210
|
+
/** The independently selectable logical storage classes — every class
|
|
4211
|
+
* `storage.listLocationDeclarations` reports, so an operator never meets a
|
|
4212
|
+
* Zod enum error where they should meet an explanation.
|
|
4213
|
+
*
|
|
4214
|
+
* `recordings` encompasses the high and mid segment profiles; `recordingsLow`
|
|
4215
|
+
* is low segments; `eventMedia` is post-analysis blobs; `galleryMedia` is the
|
|
4216
|
+
* enrolled gallery; `backups` is the system backup archive. The last two have
|
|
4217
|
+
* their own rules — see {@link StorageMigrationFindingCodeSchema}. */
|
|
4177
4218
|
var StorageMigrationClassSchema = zod.z.enum([
|
|
4178
4219
|
"recordings",
|
|
4179
4220
|
"recordingsLow",
|
|
4180
|
-
"eventMedia"
|
|
4221
|
+
"eventMedia",
|
|
4222
|
+
"backups",
|
|
4223
|
+
"galleryMedia"
|
|
4181
4224
|
]);
|
|
4182
4225
|
/** A destination is always an existing, fully-qualified location id. The
|
|
4183
4226
|
* migration API intentionally never changes a source location's `basePath`:
|
|
@@ -4185,20 +4228,56 @@ var StorageMigrationClassSchema = zod.z.enum([
|
|
|
4185
4228
|
var StorageMigrationDestinationsSchema = zod.z.object({
|
|
4186
4229
|
recordings: zod.z.string().min(1).optional(),
|
|
4187
4230
|
recordingsLow: zod.z.string().min(1).optional(),
|
|
4188
|
-
eventMedia: zod.z.string().min(1).optional()
|
|
4231
|
+
eventMedia: zod.z.string().min(1).optional(),
|
|
4232
|
+
backups: zod.z.string().min(1).optional(),
|
|
4233
|
+
galleryMedia: zod.z.string().min(1).optional()
|
|
4189
4234
|
}).refine((value) => Object.keys(value).length > 0, { message: "select at least one storage class" });
|
|
4235
|
+
/**
|
|
4236
|
+
* How a migration sequences the cutover against the byte move.
|
|
4237
|
+
*
|
|
4238
|
+
* - `blocking` — the historical order: pause, move every byte, repoint,
|
|
4239
|
+
* resume. Recording is stopped for the whole move. Right
|
|
4240
|
+
* for a small or a cold class, and the only legal mode for
|
|
4241
|
+
* a `cardinality: 'single'` class.
|
|
4242
|
+
* - `nonBlocking` — repoint FIRST, drain behind: seal, pause, repoint,
|
|
4243
|
+
* refresh, resume, then move the past with everything
|
|
4244
|
+
* running. The pause is three bounded instants (a detach +
|
|
4245
|
+
* attach round, a write-gate drain, a lease) instead of one
|
|
4246
|
+
* bounded by bytes. 1.09 TB at 7–14 MB/s is thirty hours of
|
|
4247
|
+
* stopped recording under `blocking`; the same move is
|
|
4248
|
+
* seconds of stopped recording under `nonBlocking`.
|
|
4249
|
+
*
|
|
4250
|
+
* The mode is on the JOB, not only on the input, because `status` is where an
|
|
4251
|
+
* operator finds out which one is running.
|
|
4252
|
+
*/
|
|
4253
|
+
var StorageMigrationModeSchema = zod.z.enum(["blocking", "nonBlocking"]);
|
|
4190
4254
|
/** Shared input for planning and starting an orchestrated storage migration. */
|
|
4191
4255
|
var StorageMigrationInputSchema = zod.z.object({
|
|
4192
4256
|
destinations: StorageMigrationDestinationsSchema,
|
|
4193
|
-
throttleMbps: zod.z.number().min(1).max(1e3).optional()
|
|
4257
|
+
throttleMbps: zod.z.number().min(1).max(1e3).optional(),
|
|
4258
|
+
/** Omitted = `blocking`, which stays the default. */
|
|
4259
|
+
mode: StorageMigrationModeSchema.optional()
|
|
4194
4260
|
});
|
|
4195
|
-
/**
|
|
4196
|
-
*
|
|
4197
|
-
*
|
|
4261
|
+
/**
|
|
4262
|
+
* The durable coordinator state machine.
|
|
4263
|
+
*
|
|
4264
|
+
* `blocking`:
|
|
4265
|
+
* planning → pausing → moving → verifying → repointing → refreshing → resuming → done
|
|
4266
|
+
*
|
|
4267
|
+
* `nonBlocking`:
|
|
4268
|
+
* planning → sealing → pausing → repointing → refreshing → resuming → draining → verifying → done
|
|
4269
|
+
*
|
|
4270
|
+
* Same phases, different order plus two new ones — not a second mover.
|
|
4271
|
+
* `sealing` closes the `eventMedia` NULL-row hole BEFORE anything is paused;
|
|
4272
|
+
* `draining` runs the same movers UNLEASED, after every writer is back up.
|
|
4273
|
+
* `repointing` is still the only phase that changes a default location.
|
|
4274
|
+
*/
|
|
4198
4275
|
var StorageMigrationPhaseSchema = zod.z.enum([
|
|
4199
4276
|
"planning",
|
|
4277
|
+
"sealing",
|
|
4200
4278
|
"pausing",
|
|
4201
4279
|
"moving",
|
|
4280
|
+
"draining",
|
|
4202
4281
|
"verifying",
|
|
4203
4282
|
"repointing",
|
|
4204
4283
|
"refreshing",
|
|
@@ -4223,6 +4302,9 @@ var StorageMigrationMoveSchema = zod.z.object({
|
|
|
4223
4302
|
var StorageMigrationJobSchema = zod.z.object({
|
|
4224
4303
|
jobId: zod.z.string(),
|
|
4225
4304
|
phase: StorageMigrationPhaseSchema,
|
|
4305
|
+
/** Which order this job is running. `status` is the only place an operator
|
|
4306
|
+
* can tell a seconds-long cutover from a thirty-hour one. */
|
|
4307
|
+
mode: StorageMigrationModeSchema,
|
|
4226
4308
|
destinations: StorageMigrationDestinationsSchema,
|
|
4227
4309
|
throttleMbps: zod.z.number(),
|
|
4228
4310
|
moves: zod.z.array(StorageMigrationMoveSchema),
|
|
@@ -4235,13 +4317,54 @@ var StorageMigrationJobSchema = zod.z.object({
|
|
|
4235
4317
|
finishedAt: zod.z.number().nullable(),
|
|
4236
4318
|
error: zod.z.string().nullable()
|
|
4237
4319
|
});
|
|
4320
|
+
/**
|
|
4321
|
+
* What the planner NOTICED but did not refuse.
|
|
4322
|
+
*
|
|
4323
|
+
* A refusal throws — the operator cannot miss it. A finding is the other half:
|
|
4324
|
+
* something true about this plan that changes what the operator should expect,
|
|
4325
|
+
* surfaced where they read it rather than in a document they will not open.
|
|
4326
|
+
*
|
|
4327
|
+
* - `sharesDeviceWithSource` — the destination realpath's to the same place as
|
|
4328
|
+
* the source. The move will be a row re-stamp, not a byte move, and it buys
|
|
4329
|
+
* no redundancy. NOTE: this is PATH identity, not `st_dev` — two distinct
|
|
4330
|
+
* directories on one filesystem are NOT detected. See
|
|
4331
|
+
* `deviceIdentityUnknown`.
|
|
4332
|
+
* - `deviceIdentityUnknown` — a location carries a `nodeId` other than this
|
|
4333
|
+
* one (or has no `basePath`), so its realpath cannot be taken here and the
|
|
4334
|
+
* same-device question was not answered at all. Stated rather than assumed
|
|
4335
|
+
* clear: a check that silently never fires is worse than no check.
|
|
4336
|
+
* - `unstampedEventMediaRows` — how many `eventMedia`/retrain rows still carry
|
|
4337
|
+
* no `locationId`. Non-zero refuses a `nonBlocking` cutover.
|
|
4338
|
+
* - `blockingOnly` — this class is `cardinality: 'single'`, so it can never
|
|
4339
|
+
* span two locations and can only ever be moved stop-the-world.
|
|
4340
|
+
* - `noMover` — the class is selectable and planned, but no addon owns a mover
|
|
4341
|
+
* for it. The migration cannot move its bytes.
|
|
4342
|
+
*/
|
|
4343
|
+
var StorageMigrationFindingCodeSchema = zod.z.enum([
|
|
4344
|
+
"sharesDeviceWithSource",
|
|
4345
|
+
"deviceIdentityUnknown",
|
|
4346
|
+
"unstampedEventMediaRows",
|
|
4347
|
+
"blockingOnly",
|
|
4348
|
+
"noMover"
|
|
4349
|
+
]);
|
|
4350
|
+
var StorageMigrationFindingSchema = zod.z.object({
|
|
4351
|
+
code: StorageMigrationFindingCodeSchema,
|
|
4352
|
+
storageClass: StorageMigrationClassSchema,
|
|
4353
|
+
/** Human-readable, already carrying the ids and counts. */
|
|
4354
|
+
message: zod.z.string()
|
|
4355
|
+
});
|
|
4238
4356
|
var StorageMigrationPlanSchema = zod.z.object({
|
|
4239
4357
|
destinations: StorageMigrationDestinationsSchema,
|
|
4358
|
+
/** The mode this plan was built for. A plan is only valid for its mode: the
|
|
4359
|
+
* `eventMedia` seal gate and the single-cardinality refusal both depend on
|
|
4360
|
+
* it. */
|
|
4361
|
+
mode: StorageMigrationModeSchema,
|
|
4240
4362
|
moves: zod.z.array(zod.z.object({
|
|
4241
4363
|
storageClass: StorageMigrationClassSchema,
|
|
4242
4364
|
fromLocationId: zod.z.string(),
|
|
4243
4365
|
toLocationId: zod.z.string()
|
|
4244
|
-
}))
|
|
4366
|
+
})),
|
|
4367
|
+
findings: zod.z.array(StorageMigrationFindingSchema)
|
|
4245
4368
|
});
|
|
4246
4369
|
/**
|
|
4247
4370
|
* `StorageLocationType` — an addon-declared id that identifies the *kind* of
|
|
@@ -17867,6 +17990,17 @@ var pipelineAnalyticsCapability = {
|
|
|
17867
17990
|
kind: "mutation",
|
|
17868
17991
|
auth: "admin"
|
|
17869
17992
|
}),
|
|
17993
|
+
/**
|
|
17994
|
+
* How many media / retrain rows still carry NO `locationId`.
|
|
17995
|
+
*
|
|
17996
|
+
* A NULL row means "wherever `eventMedia` points NOW", so the instant a
|
|
17997
|
+
* repoint moves that pointer every such row reads from the new disk while
|
|
17998
|
+
* its bytes are on the old one — the archive goes dark until a drain
|
|
17999
|
+
* happens to stamp it. This count is what the migration planner's
|
|
18000
|
+
* non-blocking gate reads; `relocateMedia({ mode: 'seal' })` is what drives
|
|
18001
|
+
* it to zero.
|
|
18002
|
+
*/
|
|
18003
|
+
countUnstampedEventMedia: method(zod.z.object({}), UnstampedEventMediaCountSchema, { auth: "admin" }),
|
|
17870
18004
|
/** Every relocate job this addon knows about, newest first (in RAM: the
|
|
17871
18005
|
* move is resumable, so a lost list costs nothing but the display). */
|
|
17872
18006
|
listRelocateMediaJobs: method(zod.z.object({}), zod.z.array(RelocateJobSchema).readonly(), {
|
|
@@ -20718,7 +20852,24 @@ var storageCapability = {
|
|
|
20718
20852
|
kind: "mutation",
|
|
20719
20853
|
auth: "admin"
|
|
20720
20854
|
}),
|
|
20721
|
-
|
|
20855
|
+
/**
|
|
20856
|
+
* Remove a location record. REFUSES a location that still holds data —
|
|
20857
|
+
* deleting a drained location whose durable rows still name it is how this
|
|
20858
|
+
* hub acquired 2 131 ghost `recordings:high` segments, and playback does
|
|
20859
|
+
* not stat, so the operator sees a silent black window rather than an
|
|
20860
|
+
* error.
|
|
20861
|
+
*
|
|
20862
|
+
* `force` exists because the occupancy check is BEST-EFFORT and refuses on
|
|
20863
|
+
* "unknown" as well as on "occupied" (a read that fails must not authorise
|
|
20864
|
+
* a destruction — D49). A location on a removed disk, on another node, or
|
|
20865
|
+
* behind a remote provider answers "unknown" forever, and a refusal an
|
|
20866
|
+
* operator cannot override is its own failure mode. `force: true` is
|
|
20867
|
+
* logged, loudly, with what the check saw.
|
|
20868
|
+
*/
|
|
20869
|
+
deleteLocation: method(zod.z.object({
|
|
20870
|
+
id: zod.z.string(),
|
|
20871
|
+
force: zod.z.boolean().optional()
|
|
20872
|
+
}), zod.z.void(), {
|
|
20722
20873
|
kind: "mutation",
|
|
20723
20874
|
auth: "admin"
|
|
20724
20875
|
}),
|
|
@@ -36071,6 +36222,12 @@ var METHOD_ACCESS_MAP = Object.freeze({
|
|
|
36071
36222
|
addonId: null,
|
|
36072
36223
|
access: "create"
|
|
36073
36224
|
},
|
|
36225
|
+
"pipelineAnalytics.countUnstampedEventMedia": {
|
|
36226
|
+
capName: "pipeline-analytics",
|
|
36227
|
+
capScope: "device",
|
|
36228
|
+
addonId: null,
|
|
36229
|
+
access: "view"
|
|
36230
|
+
},
|
|
36074
36231
|
"pipelineAnalytics.deleteDeviceEvents": {
|
|
36075
36232
|
capName: "pipeline-analytics",
|
|
36076
36233
|
capScope: "device",
|
|
@@ -4166,18 +4166,61 @@ var RelocateFootageInputSchema = z.object({
|
|
|
4166
4166
|
* `RecordingConfig.enabled` or camera wrapper bindings. */
|
|
4167
4167
|
var StorageMigrationLeaseInputSchema = z.object({ leaseId: z.string().min(1) });
|
|
4168
4168
|
var StorageMigrationFootageMoveInputSchema = RelocateFootageInputSchema.extend({ leaseId: z.string().min(1) });
|
|
4169
|
+
/**
|
|
4170
|
+
* What a `relocateMedia` pass DOES. One engine, three passes — never a second
|
|
4171
|
+
* mover (the engine already walks both collections with a timestamp cursor and
|
|
4172
|
+
* already has a stamp-without-copy path).
|
|
4173
|
+
*
|
|
4174
|
+
* - `move` — the default and the historical behaviour: event-media and
|
|
4175
|
+
* retrain blobs move to `toLocationId` and their rows are
|
|
4176
|
+
* stamped. The enrolled gallery is skipped (D197).
|
|
4177
|
+
* - `seal` — ROWS ONLY, no bytes. Every row whose `locationId` is NULL is
|
|
4178
|
+
* stamped with `toLocationId`. `toLocationId` here is the id the
|
|
4179
|
+
* bytes ALREADY sit on — today's `eventMedia` default — because
|
|
4180
|
+
* a NULL row means "wherever `eventMedia` points *now*", and the
|
|
4181
|
+
* instant a repoint moves that pointer the row reads from the
|
|
4182
|
+
* new disk while its bytes are on the old one.
|
|
4183
|
+
* - `gallery` — the inverse selection of `move`: ONLY the retention-exempt
|
|
4184
|
+
* (enrolled-gallery) rows, which `move` deliberately skips.
|
|
4185
|
+
* `galleryMedia` is `cardinality: 'single'`, so this pass can
|
|
4186
|
+
* never run beside a live second location: it is stop-the-world
|
|
4187
|
+
* by construction, which is acceptable only because the gallery
|
|
4188
|
+
* is a few KB per enrolled sample.
|
|
4189
|
+
*/
|
|
4190
|
+
var MediaRelocateModeSchema = z.enum([
|
|
4191
|
+
"move",
|
|
4192
|
+
"seal",
|
|
4193
|
+
"gallery"
|
|
4194
|
+
]);
|
|
4169
4195
|
var RelocateMediaInputSchema = z.object({
|
|
4170
4196
|
toLocationId: z.string(),
|
|
4171
|
-
throttleMbps: z.number().min(1).max(1e3).optional()
|
|
4197
|
+
throttleMbps: z.number().min(1).max(1e3).optional(),
|
|
4198
|
+
/** Omitted = `move`, the pre-existing behaviour. */
|
|
4199
|
+
mode: MediaRelocateModeSchema.optional()
|
|
4200
|
+
});
|
|
4201
|
+
/** How many rows still carry NO `locationId` — the population a repoint would
|
|
4202
|
+
* silently re-aim at a disk that does not hold their bytes. Zero is the only
|
|
4203
|
+
* value that permits a non-blocking `eventMedia` cutover. */
|
|
4204
|
+
var UnstampedEventMediaCountSchema = z.object({
|
|
4205
|
+
media: z.number().int().nonnegative(),
|
|
4206
|
+
retrainFrames: z.number().int().nonnegative(),
|
|
4207
|
+
total: z.number().int().nonnegative()
|
|
4172
4208
|
});
|
|
4173
4209
|
var StorageMigrationMediaMoveInputSchema = RelocateMediaInputSchema.extend({ leaseId: z.string().min(1) });
|
|
4174
|
-
/** The independently selectable logical storage classes
|
|
4175
|
-
*
|
|
4176
|
-
*
|
|
4210
|
+
/** The independently selectable logical storage classes — every class
|
|
4211
|
+
* `storage.listLocationDeclarations` reports, so an operator never meets a
|
|
4212
|
+
* Zod enum error where they should meet an explanation.
|
|
4213
|
+
*
|
|
4214
|
+
* `recordings` encompasses the high and mid segment profiles; `recordingsLow`
|
|
4215
|
+
* is low segments; `eventMedia` is post-analysis blobs; `galleryMedia` is the
|
|
4216
|
+
* enrolled gallery; `backups` is the system backup archive. The last two have
|
|
4217
|
+
* their own rules — see {@link StorageMigrationFindingCodeSchema}. */
|
|
4177
4218
|
var StorageMigrationClassSchema = z.enum([
|
|
4178
4219
|
"recordings",
|
|
4179
4220
|
"recordingsLow",
|
|
4180
|
-
"eventMedia"
|
|
4221
|
+
"eventMedia",
|
|
4222
|
+
"backups",
|
|
4223
|
+
"galleryMedia"
|
|
4181
4224
|
]);
|
|
4182
4225
|
/** A destination is always an existing, fully-qualified location id. The
|
|
4183
4226
|
* migration API intentionally never changes a source location's `basePath`:
|
|
@@ -4185,20 +4228,56 @@ var StorageMigrationClassSchema = z.enum([
|
|
|
4185
4228
|
var StorageMigrationDestinationsSchema = z.object({
|
|
4186
4229
|
recordings: z.string().min(1).optional(),
|
|
4187
4230
|
recordingsLow: z.string().min(1).optional(),
|
|
4188
|
-
eventMedia: z.string().min(1).optional()
|
|
4231
|
+
eventMedia: z.string().min(1).optional(),
|
|
4232
|
+
backups: z.string().min(1).optional(),
|
|
4233
|
+
galleryMedia: z.string().min(1).optional()
|
|
4189
4234
|
}).refine((value) => Object.keys(value).length > 0, { message: "select at least one storage class" });
|
|
4235
|
+
/**
|
|
4236
|
+
* How a migration sequences the cutover against the byte move.
|
|
4237
|
+
*
|
|
4238
|
+
* - `blocking` — the historical order: pause, move every byte, repoint,
|
|
4239
|
+
* resume. Recording is stopped for the whole move. Right
|
|
4240
|
+
* for a small or a cold class, and the only legal mode for
|
|
4241
|
+
* a `cardinality: 'single'` class.
|
|
4242
|
+
* - `nonBlocking` — repoint FIRST, drain behind: seal, pause, repoint,
|
|
4243
|
+
* refresh, resume, then move the past with everything
|
|
4244
|
+
* running. The pause is three bounded instants (a detach +
|
|
4245
|
+
* attach round, a write-gate drain, a lease) instead of one
|
|
4246
|
+
* bounded by bytes. 1.09 TB at 7–14 MB/s is thirty hours of
|
|
4247
|
+
* stopped recording under `blocking`; the same move is
|
|
4248
|
+
* seconds of stopped recording under `nonBlocking`.
|
|
4249
|
+
*
|
|
4250
|
+
* The mode is on the JOB, not only on the input, because `status` is where an
|
|
4251
|
+
* operator finds out which one is running.
|
|
4252
|
+
*/
|
|
4253
|
+
var StorageMigrationModeSchema = z.enum(["blocking", "nonBlocking"]);
|
|
4190
4254
|
/** Shared input for planning and starting an orchestrated storage migration. */
|
|
4191
4255
|
var StorageMigrationInputSchema = z.object({
|
|
4192
4256
|
destinations: StorageMigrationDestinationsSchema,
|
|
4193
|
-
throttleMbps: z.number().min(1).max(1e3).optional()
|
|
4257
|
+
throttleMbps: z.number().min(1).max(1e3).optional(),
|
|
4258
|
+
/** Omitted = `blocking`, which stays the default. */
|
|
4259
|
+
mode: StorageMigrationModeSchema.optional()
|
|
4194
4260
|
});
|
|
4195
|
-
/**
|
|
4196
|
-
*
|
|
4197
|
-
*
|
|
4261
|
+
/**
|
|
4262
|
+
* The durable coordinator state machine.
|
|
4263
|
+
*
|
|
4264
|
+
* `blocking`:
|
|
4265
|
+
* planning → pausing → moving → verifying → repointing → refreshing → resuming → done
|
|
4266
|
+
*
|
|
4267
|
+
* `nonBlocking`:
|
|
4268
|
+
* planning → sealing → pausing → repointing → refreshing → resuming → draining → verifying → done
|
|
4269
|
+
*
|
|
4270
|
+
* Same phases, different order plus two new ones — not a second mover.
|
|
4271
|
+
* `sealing` closes the `eventMedia` NULL-row hole BEFORE anything is paused;
|
|
4272
|
+
* `draining` runs the same movers UNLEASED, after every writer is back up.
|
|
4273
|
+
* `repointing` is still the only phase that changes a default location.
|
|
4274
|
+
*/
|
|
4198
4275
|
var StorageMigrationPhaseSchema = z.enum([
|
|
4199
4276
|
"planning",
|
|
4277
|
+
"sealing",
|
|
4200
4278
|
"pausing",
|
|
4201
4279
|
"moving",
|
|
4280
|
+
"draining",
|
|
4202
4281
|
"verifying",
|
|
4203
4282
|
"repointing",
|
|
4204
4283
|
"refreshing",
|
|
@@ -4223,6 +4302,9 @@ var StorageMigrationMoveSchema = z.object({
|
|
|
4223
4302
|
var StorageMigrationJobSchema = z.object({
|
|
4224
4303
|
jobId: z.string(),
|
|
4225
4304
|
phase: StorageMigrationPhaseSchema,
|
|
4305
|
+
/** Which order this job is running. `status` is the only place an operator
|
|
4306
|
+
* can tell a seconds-long cutover from a thirty-hour one. */
|
|
4307
|
+
mode: StorageMigrationModeSchema,
|
|
4226
4308
|
destinations: StorageMigrationDestinationsSchema,
|
|
4227
4309
|
throttleMbps: z.number(),
|
|
4228
4310
|
moves: z.array(StorageMigrationMoveSchema),
|
|
@@ -4235,13 +4317,54 @@ var StorageMigrationJobSchema = z.object({
|
|
|
4235
4317
|
finishedAt: z.number().nullable(),
|
|
4236
4318
|
error: z.string().nullable()
|
|
4237
4319
|
});
|
|
4320
|
+
/**
|
|
4321
|
+
* What the planner NOTICED but did not refuse.
|
|
4322
|
+
*
|
|
4323
|
+
* A refusal throws — the operator cannot miss it. A finding is the other half:
|
|
4324
|
+
* something true about this plan that changes what the operator should expect,
|
|
4325
|
+
* surfaced where they read it rather than in a document they will not open.
|
|
4326
|
+
*
|
|
4327
|
+
* - `sharesDeviceWithSource` — the destination realpath's to the same place as
|
|
4328
|
+
* the source. The move will be a row re-stamp, not a byte move, and it buys
|
|
4329
|
+
* no redundancy. NOTE: this is PATH identity, not `st_dev` — two distinct
|
|
4330
|
+
* directories on one filesystem are NOT detected. See
|
|
4331
|
+
* `deviceIdentityUnknown`.
|
|
4332
|
+
* - `deviceIdentityUnknown` — a location carries a `nodeId` other than this
|
|
4333
|
+
* one (or has no `basePath`), so its realpath cannot be taken here and the
|
|
4334
|
+
* same-device question was not answered at all. Stated rather than assumed
|
|
4335
|
+
* clear: a check that silently never fires is worse than no check.
|
|
4336
|
+
* - `unstampedEventMediaRows` — how many `eventMedia`/retrain rows still carry
|
|
4337
|
+
* no `locationId`. Non-zero refuses a `nonBlocking` cutover.
|
|
4338
|
+
* - `blockingOnly` — this class is `cardinality: 'single'`, so it can never
|
|
4339
|
+
* span two locations and can only ever be moved stop-the-world.
|
|
4340
|
+
* - `noMover` — the class is selectable and planned, but no addon owns a mover
|
|
4341
|
+
* for it. The migration cannot move its bytes.
|
|
4342
|
+
*/
|
|
4343
|
+
var StorageMigrationFindingCodeSchema = z.enum([
|
|
4344
|
+
"sharesDeviceWithSource",
|
|
4345
|
+
"deviceIdentityUnknown",
|
|
4346
|
+
"unstampedEventMediaRows",
|
|
4347
|
+
"blockingOnly",
|
|
4348
|
+
"noMover"
|
|
4349
|
+
]);
|
|
4350
|
+
var StorageMigrationFindingSchema = z.object({
|
|
4351
|
+
code: StorageMigrationFindingCodeSchema,
|
|
4352
|
+
storageClass: StorageMigrationClassSchema,
|
|
4353
|
+
/** Human-readable, already carrying the ids and counts. */
|
|
4354
|
+
message: z.string()
|
|
4355
|
+
});
|
|
4238
4356
|
var StorageMigrationPlanSchema = z.object({
|
|
4239
4357
|
destinations: StorageMigrationDestinationsSchema,
|
|
4358
|
+
/** The mode this plan was built for. A plan is only valid for its mode: the
|
|
4359
|
+
* `eventMedia` seal gate and the single-cardinality refusal both depend on
|
|
4360
|
+
* it. */
|
|
4361
|
+
mode: StorageMigrationModeSchema,
|
|
4240
4362
|
moves: z.array(z.object({
|
|
4241
4363
|
storageClass: StorageMigrationClassSchema,
|
|
4242
4364
|
fromLocationId: z.string(),
|
|
4243
4365
|
toLocationId: z.string()
|
|
4244
|
-
}))
|
|
4366
|
+
})),
|
|
4367
|
+
findings: z.array(StorageMigrationFindingSchema)
|
|
4245
4368
|
});
|
|
4246
4369
|
/**
|
|
4247
4370
|
* `StorageLocationType` — an addon-declared id that identifies the *kind* of
|
|
@@ -17867,6 +17990,17 @@ var pipelineAnalyticsCapability = {
|
|
|
17867
17990
|
kind: "mutation",
|
|
17868
17991
|
auth: "admin"
|
|
17869
17992
|
}),
|
|
17993
|
+
/**
|
|
17994
|
+
* How many media / retrain rows still carry NO `locationId`.
|
|
17995
|
+
*
|
|
17996
|
+
* A NULL row means "wherever `eventMedia` points NOW", so the instant a
|
|
17997
|
+
* repoint moves that pointer every such row reads from the new disk while
|
|
17998
|
+
* its bytes are on the old one — the archive goes dark until a drain
|
|
17999
|
+
* happens to stamp it. This count is what the migration planner's
|
|
18000
|
+
* non-blocking gate reads; `relocateMedia({ mode: 'seal' })` is what drives
|
|
18001
|
+
* it to zero.
|
|
18002
|
+
*/
|
|
18003
|
+
countUnstampedEventMedia: method(z.object({}), UnstampedEventMediaCountSchema, { auth: "admin" }),
|
|
17870
18004
|
/** Every relocate job this addon knows about, newest first (in RAM: the
|
|
17871
18005
|
* move is resumable, so a lost list costs nothing but the display). */
|
|
17872
18006
|
listRelocateMediaJobs: method(z.object({}), z.array(RelocateJobSchema).readonly(), {
|
|
@@ -20718,7 +20852,24 @@ var storageCapability = {
|
|
|
20718
20852
|
kind: "mutation",
|
|
20719
20853
|
auth: "admin"
|
|
20720
20854
|
}),
|
|
20721
|
-
|
|
20855
|
+
/**
|
|
20856
|
+
* Remove a location record. REFUSES a location that still holds data —
|
|
20857
|
+
* deleting a drained location whose durable rows still name it is how this
|
|
20858
|
+
* hub acquired 2 131 ghost `recordings:high` segments, and playback does
|
|
20859
|
+
* not stat, so the operator sees a silent black window rather than an
|
|
20860
|
+
* error.
|
|
20861
|
+
*
|
|
20862
|
+
* `force` exists because the occupancy check is BEST-EFFORT and refuses on
|
|
20863
|
+
* "unknown" as well as on "occupied" (a read that fails must not authorise
|
|
20864
|
+
* a destruction — D49). A location on a removed disk, on another node, or
|
|
20865
|
+
* behind a remote provider answers "unknown" forever, and a refusal an
|
|
20866
|
+
* operator cannot override is its own failure mode. `force: true` is
|
|
20867
|
+
* logged, loudly, with what the check saw.
|
|
20868
|
+
*/
|
|
20869
|
+
deleteLocation: method(z.object({
|
|
20870
|
+
id: z.string(),
|
|
20871
|
+
force: z.boolean().optional()
|
|
20872
|
+
}), z.void(), {
|
|
20722
20873
|
kind: "mutation",
|
|
20723
20874
|
auth: "admin"
|
|
20724
20875
|
}),
|
|
@@ -36071,6 +36222,12 @@ var METHOD_ACCESS_MAP = Object.freeze({
|
|
|
36071
36222
|
addonId: null,
|
|
36072
36223
|
access: "create"
|
|
36073
36224
|
},
|
|
36225
|
+
"pipelineAnalytics.countUnstampedEventMedia": {
|
|
36226
|
+
capName: "pipeline-analytics",
|
|
36227
|
+
capScope: "device",
|
|
36228
|
+
addonId: null,
|
|
36229
|
+
access: "view"
|
|
36230
|
+
},
|
|
36074
36231
|
"pipelineAnalytics.deleteDeviceEvents": {
|
|
36075
36232
|
capName: "pipeline-analytics",
|
|
36076
36233
|
capScope: "device",
|
package/dist/index.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
|
|
2
2
|
const require_chunk = require("./chunk-Cek0wNdY.js");
|
|
3
|
-
const require_dist = require("./dist-
|
|
3
|
+
const require_dist = require("./dist-CDgIzo82.js");
|
|
4
4
|
const require_builtins_alerts_alerts_addon = require("./builtins/alerts/alerts.addon.js");
|
|
5
5
|
require("./builtins/alerts/index.js");
|
|
6
6
|
const require_formatter = require("./formatter-DqAKDlvN.js");
|
|
@@ -26,7 +26,7 @@ require("./builtins/system-config/index.js");
|
|
|
26
26
|
const require_builtins_winston_logging_index = require("./builtins/winston-logging/index.js");
|
|
27
27
|
const require_file_data_plane = require("./file-data-plane-DO8KbxCe.js");
|
|
28
28
|
const require_tls$1 = require("./tls-BxQlomxd.js");
|
|
29
|
-
const require_manifest_python_deps = require("./manifest-python-deps-
|
|
29
|
+
const require_manifest_python_deps = require("./manifest-python-deps-DVODn-qc.js");
|
|
30
30
|
const require_resource_monitor = require("./resource-monitor-CdnzxBLP.js");
|
|
31
31
|
const require_custom_action_registry = require("./custom-action-registry-jY0NOZK8.js");
|
|
32
32
|
let zod = require("zod");
|
|
@@ -9612,20 +9612,63 @@ var ConfigManager = class ConfigManager {
|
|
|
9612
9612
|
if (this.settingsStore === null) return;
|
|
9613
9613
|
this.settingsStore.clearDeviceRuntimeState(deviceId);
|
|
9614
9614
|
}
|
|
9615
|
+
/**
|
|
9616
|
+
* The addon's `ctx.settings`.
|
|
9617
|
+
*
|
|
9618
|
+
* The backend is chosen on EVERY call, never frozen when the view is built.
|
|
9619
|
+
* That is not a nicety: `settings-store` is owned by `storage-orchestrator`,
|
|
9620
|
+
* so the door is wired by `registerProvider` STRICTLY AFTER that addon's
|
|
9621
|
+
* context — and therefore its settings view — already exists. A view bound at
|
|
9622
|
+
* construction handed the door's own owner the sync-store backend, whose
|
|
9623
|
+
* writes throw for the whole life of the process once `sqlite-settings` runs
|
|
9624
|
+
* isolated (D181: no sync `ISettingsStore` reaches hub-main, only the async
|
|
9625
|
+
* door). Reads were worse than the writes: they answered `{}` in silence.
|
|
9626
|
+
* That is what made `storageMigration.start` fail on its first durable write
|
|
9627
|
+
* while every other addon's persistence worked. See D294.
|
|
9628
|
+
*/
|
|
9615
9629
|
createSettingsView(addonId) {
|
|
9616
|
-
|
|
9630
|
+
const storeBacked = this.createStoreSettingsView(addonId);
|
|
9631
|
+
let doorBacked = null;
|
|
9632
|
+
let doorBackedSource = null;
|
|
9633
|
+
const active = () => {
|
|
9634
|
+
if (this.settingsStore !== null) return storeBacked;
|
|
9617
9635
|
const door = this.settingsDoor;
|
|
9618
|
-
|
|
9619
|
-
|
|
9620
|
-
|
|
9621
|
-
|
|
9622
|
-
|
|
9623
|
-
|
|
9624
|
-
|
|
9625
|
-
|
|
9626
|
-
|
|
9627
|
-
|
|
9628
|
-
|
|
9636
|
+
if (door === null) return storeBacked;
|
|
9637
|
+
if (doorBacked === null || doorBackedSource !== door) {
|
|
9638
|
+
doorBackedSource = door;
|
|
9639
|
+
doorBacked = this.createDoorBackedSettingsView(addonId, door);
|
|
9640
|
+
}
|
|
9641
|
+
return doorBacked;
|
|
9642
|
+
};
|
|
9643
|
+
return {
|
|
9644
|
+
readAddonStore: () => active().readAddonStore(),
|
|
9645
|
+
writeAddonStore: (patch) => active().writeAddonStore(patch),
|
|
9646
|
+
readDeviceStore: (deviceId) => active().readDeviceStore(deviceId),
|
|
9647
|
+
readDeviceStoreBatch: (deviceIds) => active().readDeviceStoreBatch(deviceIds),
|
|
9648
|
+
writeDeviceStore: (deviceId, patch) => active().writeDeviceStore(deviceId, patch),
|
|
9649
|
+
clearDeviceStore: (deviceId) => active().clearDeviceStore(deviceId),
|
|
9650
|
+
getSection: (section) => active().getSection(section),
|
|
9651
|
+
setSection: (section, patch) => active().setSection(section, patch),
|
|
9652
|
+
readDeviceRuntimeState: (deviceId) => active().readDeviceRuntimeState(deviceId),
|
|
9653
|
+
writeDeviceRuntimeState: (deviceId, data) => active().writeDeviceRuntimeState(deviceId, data),
|
|
9654
|
+
clearDeviceRuntimeState: (deviceId) => active().clearDeviceRuntimeState(deviceId)
|
|
9655
|
+
};
|
|
9656
|
+
}
|
|
9657
|
+
/** The async-door backend of {@link createSettingsView}. */
|
|
9658
|
+
createDoorBackedSettingsView(addonId, door) {
|
|
9659
|
+
return createDoorSettingsView(addonId, door, {
|
|
9660
|
+
getSection: (section) => this.getSection(section),
|
|
9661
|
+
setSection: async (section, patch) => {
|
|
9662
|
+
for (const [key, value] of Object.entries(patch)) await door.set({
|
|
9663
|
+
collection: "system-settings",
|
|
9664
|
+
key: `${section}.${key}`,
|
|
9665
|
+
value
|
|
9666
|
+
});
|
|
9667
|
+
}
|
|
9668
|
+
});
|
|
9669
|
+
}
|
|
9670
|
+
/** The sync-`ISettingsStore` backend of {@link createSettingsView}. */
|
|
9671
|
+
createStoreSettingsView(addonId) {
|
|
9629
9672
|
const cm = this;
|
|
9630
9673
|
return {
|
|
9631
9674
|
async readAddonStore() {
|
|
@@ -9641,6 +9684,15 @@ var ConfigManager = class ConfigManager {
|
|
|
9641
9684
|
async readDeviceStore(deviceId) {
|
|
9642
9685
|
return cm.getAddonDevice(addonId, String(deviceId));
|
|
9643
9686
|
},
|
|
9687
|
+
async readDeviceStoreBatch(deviceIds) {
|
|
9688
|
+
const out = /* @__PURE__ */ new Map();
|
|
9689
|
+
for (const deviceId of deviceIds) try {
|
|
9690
|
+
out.set(deviceId, cm.getAddonDevice(addonId, String(deviceId)));
|
|
9691
|
+
} catch {
|
|
9692
|
+
out.set(deviceId, {});
|
|
9693
|
+
}
|
|
9694
|
+
return out;
|
|
9695
|
+
},
|
|
9644
9696
|
async writeDeviceStore(deviceId, patch) {
|
|
9645
9697
|
const key = String(deviceId);
|
|
9646
9698
|
const existing = cm.getAddonDevice(addonId, key);
|