@camstack/addon-agent-ui 1.2.42 → 1.2.44

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.
Files changed (2) hide show
  1. package/dist/addon.js +128 -20
  2. package/package.json +1 -1
package/dist/addon.js CHANGED
@@ -8042,18 +8042,61 @@ var RelocateFootageInputSchema = object({
8042
8042
  * `RecordingConfig.enabled` or camera wrapper bindings. */
8043
8043
  var StorageMigrationLeaseInputSchema = object({ leaseId: string().min(1) });
8044
8044
  var StorageMigrationFootageMoveInputSchema = RelocateFootageInputSchema.extend({ leaseId: string().min(1) });
8045
+ /**
8046
+ * What a `relocateMedia` pass DOES. One engine, three passes — never a second
8047
+ * mover (the engine already walks both collections with a timestamp cursor and
8048
+ * already has a stamp-without-copy path).
8049
+ *
8050
+ * - `move` — the default and the historical behaviour: event-media and
8051
+ * retrain blobs move to `toLocationId` and their rows are
8052
+ * stamped. The enrolled gallery is skipped (D197).
8053
+ * - `seal` — ROWS ONLY, no bytes. Every row whose `locationId` is NULL is
8054
+ * stamped with `toLocationId`. `toLocationId` here is the id the
8055
+ * bytes ALREADY sit on — today's `eventMedia` default — because
8056
+ * a NULL row means "wherever `eventMedia` points *now*", and the
8057
+ * instant a repoint moves that pointer the row reads from the
8058
+ * new disk while its bytes are on the old one.
8059
+ * - `gallery` — the inverse selection of `move`: ONLY the retention-exempt
8060
+ * (enrolled-gallery) rows, which `move` deliberately skips.
8061
+ * `galleryMedia` is `cardinality: 'single'`, so this pass can
8062
+ * never run beside a live second location: it is stop-the-world
8063
+ * by construction, which is acceptable only because the gallery
8064
+ * is a few KB per enrolled sample.
8065
+ */
8066
+ var MediaRelocateModeSchema = _enum([
8067
+ "move",
8068
+ "seal",
8069
+ "gallery"
8070
+ ]);
8045
8071
  var RelocateMediaInputSchema = object({
8046
8072
  toLocationId: string(),
8047
- throttleMbps: number().min(1).max(1e3).optional()
8073
+ throttleMbps: number().min(1).max(1e3).optional(),
8074
+ /** Omitted = `move`, the pre-existing behaviour. */
8075
+ mode: MediaRelocateModeSchema.optional()
8076
+ });
8077
+ /** How many rows still carry NO `locationId` — the population a repoint would
8078
+ * silently re-aim at a disk that does not hold their bytes. Zero is the only
8079
+ * value that permits a non-blocking `eventMedia` cutover. */
8080
+ var UnstampedEventMediaCountSchema = object({
8081
+ media: number().int().nonnegative(),
8082
+ retrainFrames: number().int().nonnegative(),
8083
+ total: number().int().nonnegative()
8048
8084
  });
8049
8085
  var StorageMigrationMediaMoveInputSchema = RelocateMediaInputSchema.extend({ leaseId: string().min(1) });
8050
- /** The independently selectable logical storage classes. `recordings`
8051
- * encompasses the high and mid segment profiles; `recordingsLow` is low
8052
- * segments; `eventMedia` is post-analysis blobs. */
8086
+ /** The independently selectable logical storage classes — every class
8087
+ * `storage.listLocationDeclarations` reports, so an operator never meets a
8088
+ * Zod enum error where they should meet an explanation.
8089
+ *
8090
+ * `recordings` encompasses the high and mid segment profiles; `recordingsLow`
8091
+ * is low segments; `eventMedia` is post-analysis blobs; `galleryMedia` is the
8092
+ * enrolled gallery; `backups` is the system backup archive. The last two have
8093
+ * their own rules — see {@link StorageMigrationFindingCodeSchema}. */
8053
8094
  var StorageMigrationClassSchema = _enum([
8054
8095
  "recordings",
8055
8096
  "recordingsLow",
8056
- "eventMedia"
8097
+ "eventMedia",
8098
+ "backups",
8099
+ "galleryMedia"
8057
8100
  ]);
8058
8101
  /** A destination is always an existing, fully-qualified location id. The
8059
8102
  * migration API intentionally never changes a source location's `basePath`:
@@ -8061,20 +8104,56 @@ var StorageMigrationClassSchema = _enum([
8061
8104
  var StorageMigrationDestinationsSchema = object({
8062
8105
  recordings: string().min(1).optional(),
8063
8106
  recordingsLow: string().min(1).optional(),
8064
- eventMedia: string().min(1).optional()
8107
+ eventMedia: string().min(1).optional(),
8108
+ backups: string().min(1).optional(),
8109
+ galleryMedia: string().min(1).optional()
8065
8110
  }).refine((value) => Object.keys(value).length > 0, { message: "select at least one storage class" });
8111
+ /**
8112
+ * How a migration sequences the cutover against the byte move.
8113
+ *
8114
+ * - `blocking` — the historical order: pause, move every byte, repoint,
8115
+ * resume. Recording is stopped for the whole move. Right
8116
+ * for a small or a cold class, and the only legal mode for
8117
+ * a `cardinality: 'single'` class.
8118
+ * - `nonBlocking` — repoint FIRST, drain behind: seal, pause, repoint,
8119
+ * refresh, resume, then move the past with everything
8120
+ * running. The pause is three bounded instants (a detach +
8121
+ * attach round, a write-gate drain, a lease) instead of one
8122
+ * bounded by bytes. 1.09 TB at 7–14 MB/s is thirty hours of
8123
+ * stopped recording under `blocking`; the same move is
8124
+ * seconds of stopped recording under `nonBlocking`.
8125
+ *
8126
+ * The mode is on the JOB, not only on the input, because `status` is where an
8127
+ * operator finds out which one is running.
8128
+ */
8129
+ var StorageMigrationModeSchema = _enum(["blocking", "nonBlocking"]);
8066
8130
  /** Shared input for planning and starting an orchestrated storage migration. */
8067
8131
  var StorageMigrationInputSchema = object({
8068
8132
  destinations: StorageMigrationDestinationsSchema,
8069
- throttleMbps: number().min(1).max(1e3).optional()
8133
+ throttleMbps: number().min(1).max(1e3).optional(),
8134
+ /** Omitted = `blocking`, which stays the default. */
8135
+ mode: StorageMigrationModeSchema.optional()
8070
8136
  });
8071
- /** The durable coordinator state machine. The only phase that changes default
8072
- * locations is `repointing`, after every selected mover has completed and been
8073
- * verified. */
8137
+ /**
8138
+ * The durable coordinator state machine.
8139
+ *
8140
+ * `blocking`:
8141
+ * planning → pausing → moving → verifying → repointing → refreshing → resuming → done
8142
+ *
8143
+ * `nonBlocking`:
8144
+ * planning → sealing → pausing → repointing → refreshing → resuming → draining → verifying → done
8145
+ *
8146
+ * Same phases, different order plus two new ones — not a second mover.
8147
+ * `sealing` closes the `eventMedia` NULL-row hole BEFORE anything is paused;
8148
+ * `draining` runs the same movers UNLEASED, after every writer is back up.
8149
+ * `repointing` is still the only phase that changes a default location.
8150
+ */
8074
8151
  var StorageMigrationPhaseSchema = _enum([
8075
8152
  "planning",
8153
+ "sealing",
8076
8154
  "pausing",
8077
8155
  "moving",
8156
+ "draining",
8078
8157
  "verifying",
8079
8158
  "repointing",
8080
8159
  "refreshing",
@@ -8099,6 +8178,9 @@ var StorageMigrationMoveSchema = object({
8099
8178
  var StorageMigrationJobSchema = object({
8100
8179
  jobId: string(),
8101
8180
  phase: StorageMigrationPhaseSchema,
8181
+ /** Which order this job is running. `status` is the only place an operator
8182
+ * can tell a seconds-long cutover from a thirty-hour one. */
8183
+ mode: StorageMigrationModeSchema,
8102
8184
  destinations: StorageMigrationDestinationsSchema,
8103
8185
  throttleMbps: number(),
8104
8186
  moves: array(StorageMigrationMoveSchema),
@@ -8111,13 +8193,30 @@ var StorageMigrationJobSchema = object({
8111
8193
  finishedAt: number().nullable(),
8112
8194
  error: string().nullable()
8113
8195
  });
8196
+ var StorageMigrationFindingSchema = object({
8197
+ code: _enum([
8198
+ "sharesDeviceWithSource",
8199
+ "deviceIdentityUnknown",
8200
+ "unstampedEventMediaRows",
8201
+ "blockingOnly",
8202
+ "noMover"
8203
+ ]),
8204
+ storageClass: StorageMigrationClassSchema,
8205
+ /** Human-readable, already carrying the ids and counts. */
8206
+ message: string()
8207
+ });
8114
8208
  var StorageMigrationPlanSchema = object({
8115
8209
  destinations: StorageMigrationDestinationsSchema,
8210
+ /** The mode this plan was built for. A plan is only valid for its mode: the
8211
+ * `eventMedia` seal gate and the single-cardinality refusal both depend on
8212
+ * it. */
8213
+ mode: StorageMigrationModeSchema,
8116
8214
  moves: array(object({
8117
8215
  storageClass: StorageMigrationClassSchema,
8118
8216
  fromLocationId: string(),
8119
8217
  toLocationId: string()
8120
- }))
8218
+ })),
8219
+ findings: array(StorageMigrationFindingSchema)
8121
8220
  });
8122
8221
  /**
8123
8222
  * `StorageLocationType` — an addon-declared id that identifies the *kind* of
@@ -18628,7 +18727,7 @@ DeviceType.Camera, method(object({ deviceId: number() }), array(TrackSchema).rea
18628
18727
  }), method(RelocateMediaInputSchema, object({ jobId: string() }), {
18629
18728
  kind: "mutation",
18630
18729
  auth: "admin"
18631
- }), method(object({}), array(RelocateJobSchema).readonly(), {
18730
+ }), method(object({}), UnstampedEventMediaCountSchema, { auth: "admin" }), method(object({}), array(RelocateJobSchema).readonly(), {
18632
18731
  kind: "query",
18633
18732
  auth: "admin"
18634
18733
  }), method(object({ jobId: string() }), object({ cancelled: boolean() }), {
@@ -20535,7 +20634,10 @@ method(object({
20535
20634
  }), StorageLocationSchema, {
20536
20635
  kind: "mutation",
20537
20636
  auth: "admin"
20538
- }), method(object({ id: string() }), _void(), {
20637
+ }), method(object({
20638
+ id: string(),
20639
+ force: boolean().optional()
20640
+ }), _void(), {
20539
20641
  kind: "mutation",
20540
20642
  auth: "admin"
20541
20643
  }), method(object({ id: string() }), object({
@@ -23621,23 +23723,23 @@ DeviceType.Camera, method(object({ deviceId: number() }), object({
23621
23723
  sdpOffer: string()
23622
23724
  }), {
23623
23725
  kind: "mutation",
23624
- auth: "admin"
23726
+ auth: "protected"
23625
23727
  }), method(object({
23626
23728
  deviceId: number(),
23627
23729
  sessionId: string(),
23628
23730
  sdpAnswer: string()
23629
23731
  }), _void(), {
23630
23732
  kind: "mutation",
23631
- auth: "admin"
23733
+ auth: "protected"
23632
23734
  }), method(object({
23633
23735
  deviceId: number(),
23634
23736
  sessionId: string()
23635
23737
  }), _void(), {
23636
23738
  kind: "mutation",
23637
- auth: "admin"
23739
+ auth: "protected"
23638
23740
  }), method(object({ deviceId: number() }), object({ sessionId: string() }), {
23639
23741
  kind: "mutation",
23640
- auth: "admin"
23742
+ auth: "protected"
23641
23743
  }), method(object({
23642
23744
  deviceId: number(),
23643
23745
  /** Audio bytes for ONE frame, base64-encoded so the payload
@@ -23656,10 +23758,10 @@ DeviceType.Camera, method(object({ deviceId: number() }), object({
23656
23758
  sequenceNumber: number().int()
23657
23759
  }), object({ accepted: boolean() }), {
23658
23760
  kind: "mutation",
23659
- auth: "admin"
23761
+ auth: "protected"
23660
23762
  }), method(object({ deviceId: number() }), _void(), {
23661
23763
  kind: "mutation",
23662
- auth: "admin"
23764
+ auth: "protected"
23663
23765
  }), object({
23664
23766
  deviceId: number(),
23665
23767
  status: IntercomStatusSchema
@@ -31008,6 +31110,12 @@ Object.freeze({
31008
31110
  addonId: null,
31009
31111
  access: "create"
31010
31112
  },
31113
+ "pipelineAnalytics.countUnstampedEventMedia": {
31114
+ capName: "pipeline-analytics",
31115
+ capScope: "device",
31116
+ addonId: null,
31117
+ access: "view"
31118
+ },
31011
31119
  "pipelineAnalytics.deleteDeviceEvents": {
31012
31120
  capName: "pipeline-analytics",
31013
31121
  capScope: "device",
@@ -35997,7 +36105,7 @@ var AgentUIAddon = class extends BaseAddon {
35997
36105
  capability: adminUiCapability,
35998
36106
  provider: {
35999
36107
  getStaticDir: async () => ({ staticDir: path.resolve(__dirname) }),
36000
- getVersion: async () => ({ version: "1.2.42" })
36108
+ getVersion: async () => ({ version: "1.2.44" })
36001
36109
  }
36002
36110
  }];
36003
36111
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@camstack/addon-agent-ui",
3
- "version": "1.2.42",
3
+ "version": "1.2.44",
4
4
  "description": "Agent UI — lightweight status dashboard served by every agent node",
5
5
  "keywords": [
6
6
  "camstack",