@camstack/addon-terminal 0.1.47 → 0.1.48

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 (3) hide show
  1. package/dist/addon.js +121 -13
  2. package/dist/addon.mjs +121 -13
  3. package/package.json +1 -1
package/dist/addon.js CHANGED
@@ -8138,18 +8138,61 @@ var RelocateFootageInputSchema = object({
8138
8138
  * `RecordingConfig.enabled` or camera wrapper bindings. */
8139
8139
  var StorageMigrationLeaseInputSchema = object({ leaseId: string().min(1) });
8140
8140
  var StorageMigrationFootageMoveInputSchema = RelocateFootageInputSchema.extend({ leaseId: string().min(1) });
8141
+ /**
8142
+ * What a `relocateMedia` pass DOES. One engine, three passes — never a second
8143
+ * mover (the engine already walks both collections with a timestamp cursor and
8144
+ * already has a stamp-without-copy path).
8145
+ *
8146
+ * - `move` — the default and the historical behaviour: event-media and
8147
+ * retrain blobs move to `toLocationId` and their rows are
8148
+ * stamped. The enrolled gallery is skipped (D197).
8149
+ * - `seal` — ROWS ONLY, no bytes. Every row whose `locationId` is NULL is
8150
+ * stamped with `toLocationId`. `toLocationId` here is the id the
8151
+ * bytes ALREADY sit on — today's `eventMedia` default — because
8152
+ * a NULL row means "wherever `eventMedia` points *now*", and the
8153
+ * instant a repoint moves that pointer the row reads from the
8154
+ * new disk while its bytes are on the old one.
8155
+ * - `gallery` — the inverse selection of `move`: ONLY the retention-exempt
8156
+ * (enrolled-gallery) rows, which `move` deliberately skips.
8157
+ * `galleryMedia` is `cardinality: 'single'`, so this pass can
8158
+ * never run beside a live second location: it is stop-the-world
8159
+ * by construction, which is acceptable only because the gallery
8160
+ * is a few KB per enrolled sample.
8161
+ */
8162
+ var MediaRelocateModeSchema = _enum([
8163
+ "move",
8164
+ "seal",
8165
+ "gallery"
8166
+ ]);
8141
8167
  var RelocateMediaInputSchema = object({
8142
8168
  toLocationId: string(),
8143
- throttleMbps: number().min(1).max(1e3).optional()
8169
+ throttleMbps: number().min(1).max(1e3).optional(),
8170
+ /** Omitted = `move`, the pre-existing behaviour. */
8171
+ mode: MediaRelocateModeSchema.optional()
8172
+ });
8173
+ /** How many rows still carry NO `locationId` — the population a repoint would
8174
+ * silently re-aim at a disk that does not hold their bytes. Zero is the only
8175
+ * value that permits a non-blocking `eventMedia` cutover. */
8176
+ var UnstampedEventMediaCountSchema = object({
8177
+ media: number().int().nonnegative(),
8178
+ retrainFrames: number().int().nonnegative(),
8179
+ total: number().int().nonnegative()
8144
8180
  });
8145
8181
  var StorageMigrationMediaMoveInputSchema = RelocateMediaInputSchema.extend({ leaseId: string().min(1) });
8146
- /** The independently selectable logical storage classes. `recordings`
8147
- * encompasses the high and mid segment profiles; `recordingsLow` is low
8148
- * segments; `eventMedia` is post-analysis blobs. */
8182
+ /** The independently selectable logical storage classes — every class
8183
+ * `storage.listLocationDeclarations` reports, so an operator never meets a
8184
+ * Zod enum error where they should meet an explanation.
8185
+ *
8186
+ * `recordings` encompasses the high and mid segment profiles; `recordingsLow`
8187
+ * is low segments; `eventMedia` is post-analysis blobs; `galleryMedia` is the
8188
+ * enrolled gallery; `backups` is the system backup archive. The last two have
8189
+ * their own rules — see {@link StorageMigrationFindingCodeSchema}. */
8149
8190
  var StorageMigrationClassSchema = _enum([
8150
8191
  "recordings",
8151
8192
  "recordingsLow",
8152
- "eventMedia"
8193
+ "eventMedia",
8194
+ "backups",
8195
+ "galleryMedia"
8153
8196
  ]);
8154
8197
  /** A destination is always an existing, fully-qualified location id. The
8155
8198
  * migration API intentionally never changes a source location's `basePath`:
@@ -8157,20 +8200,56 @@ var StorageMigrationClassSchema = _enum([
8157
8200
  var StorageMigrationDestinationsSchema = object({
8158
8201
  recordings: string().min(1).optional(),
8159
8202
  recordingsLow: string().min(1).optional(),
8160
- eventMedia: string().min(1).optional()
8203
+ eventMedia: string().min(1).optional(),
8204
+ backups: string().min(1).optional(),
8205
+ galleryMedia: string().min(1).optional()
8161
8206
  }).refine((value) => Object.keys(value).length > 0, { message: "select at least one storage class" });
8207
+ /**
8208
+ * How a migration sequences the cutover against the byte move.
8209
+ *
8210
+ * - `blocking` — the historical order: pause, move every byte, repoint,
8211
+ * resume. Recording is stopped for the whole move. Right
8212
+ * for a small or a cold class, and the only legal mode for
8213
+ * a `cardinality: 'single'` class.
8214
+ * - `nonBlocking` — repoint FIRST, drain behind: seal, pause, repoint,
8215
+ * refresh, resume, then move the past with everything
8216
+ * running. The pause is three bounded instants (a detach +
8217
+ * attach round, a write-gate drain, a lease) instead of one
8218
+ * bounded by bytes. 1.09 TB at 7–14 MB/s is thirty hours of
8219
+ * stopped recording under `blocking`; the same move is
8220
+ * seconds of stopped recording under `nonBlocking`.
8221
+ *
8222
+ * The mode is on the JOB, not only on the input, because `status` is where an
8223
+ * operator finds out which one is running.
8224
+ */
8225
+ var StorageMigrationModeSchema = _enum(["blocking", "nonBlocking"]);
8162
8226
  /** Shared input for planning and starting an orchestrated storage migration. */
8163
8227
  var StorageMigrationInputSchema = object({
8164
8228
  destinations: StorageMigrationDestinationsSchema,
8165
- throttleMbps: number().min(1).max(1e3).optional()
8229
+ throttleMbps: number().min(1).max(1e3).optional(),
8230
+ /** Omitted = `blocking`, which stays the default. */
8231
+ mode: StorageMigrationModeSchema.optional()
8166
8232
  });
8167
- /** The durable coordinator state machine. The only phase that changes default
8168
- * locations is `repointing`, after every selected mover has completed and been
8169
- * verified. */
8233
+ /**
8234
+ * The durable coordinator state machine.
8235
+ *
8236
+ * `blocking`:
8237
+ * planning → pausing → moving → verifying → repointing → refreshing → resuming → done
8238
+ *
8239
+ * `nonBlocking`:
8240
+ * planning → sealing → pausing → repointing → refreshing → resuming → draining → verifying → done
8241
+ *
8242
+ * Same phases, different order plus two new ones — not a second mover.
8243
+ * `sealing` closes the `eventMedia` NULL-row hole BEFORE anything is paused;
8244
+ * `draining` runs the same movers UNLEASED, after every writer is back up.
8245
+ * `repointing` is still the only phase that changes a default location.
8246
+ */
8170
8247
  var StorageMigrationPhaseSchema = _enum([
8171
8248
  "planning",
8249
+ "sealing",
8172
8250
  "pausing",
8173
8251
  "moving",
8252
+ "draining",
8174
8253
  "verifying",
8175
8254
  "repointing",
8176
8255
  "refreshing",
@@ -8195,6 +8274,9 @@ var StorageMigrationMoveSchema = object({
8195
8274
  var StorageMigrationJobSchema = object({
8196
8275
  jobId: string(),
8197
8276
  phase: StorageMigrationPhaseSchema,
8277
+ /** Which order this job is running. `status` is the only place an operator
8278
+ * can tell a seconds-long cutover from a thirty-hour one. */
8279
+ mode: StorageMigrationModeSchema,
8198
8280
  destinations: StorageMigrationDestinationsSchema,
8199
8281
  throttleMbps: number(),
8200
8282
  moves: array(StorageMigrationMoveSchema),
@@ -8207,13 +8289,30 @@ var StorageMigrationJobSchema = object({
8207
8289
  finishedAt: number().nullable(),
8208
8290
  error: string().nullable()
8209
8291
  });
8292
+ var StorageMigrationFindingSchema = object({
8293
+ code: _enum([
8294
+ "sharesDeviceWithSource",
8295
+ "deviceIdentityUnknown",
8296
+ "unstampedEventMediaRows",
8297
+ "blockingOnly",
8298
+ "noMover"
8299
+ ]),
8300
+ storageClass: StorageMigrationClassSchema,
8301
+ /** Human-readable, already carrying the ids and counts. */
8302
+ message: string()
8303
+ });
8210
8304
  var StorageMigrationPlanSchema = object({
8211
8305
  destinations: StorageMigrationDestinationsSchema,
8306
+ /** The mode this plan was built for. A plan is only valid for its mode: the
8307
+ * `eventMedia` seal gate and the single-cardinality refusal both depend on
8308
+ * it. */
8309
+ mode: StorageMigrationModeSchema,
8212
8310
  moves: array(object({
8213
8311
  storageClass: StorageMigrationClassSchema,
8214
8312
  fromLocationId: string(),
8215
8313
  toLocationId: string()
8216
- }))
8314
+ })),
8315
+ findings: array(StorageMigrationFindingSchema)
8217
8316
  });
8218
8317
  /**
8219
8318
  * `StorageLocationType` — an addon-declared id that identifies the *kind* of
@@ -19011,7 +19110,7 @@ DeviceType.Camera, method(object({ deviceId: number() }), array(TrackSchema).rea
19011
19110
  }), method(RelocateMediaInputSchema, object({ jobId: string() }), {
19012
19111
  kind: "mutation",
19013
19112
  auth: "admin"
19014
- }), method(object({}), array(RelocateJobSchema).readonly(), {
19113
+ }), method(object({}), UnstampedEventMediaCountSchema, { auth: "admin" }), method(object({}), array(RelocateJobSchema).readonly(), {
19015
19114
  kind: "query",
19016
19115
  auth: "admin"
19017
19116
  }), method(object({ jobId: string() }), object({ cancelled: boolean() }), {
@@ -21022,7 +21121,10 @@ method(object({
21022
21121
  }), StorageLocationSchema, {
21023
21122
  kind: "mutation",
21024
21123
  auth: "admin"
21025
- }), method(object({ id: string() }), _void(), {
21124
+ }), method(object({
21125
+ id: string(),
21126
+ force: boolean().optional()
21127
+ }), _void(), {
21026
21128
  kind: "mutation",
21027
21129
  auth: "admin"
21028
21130
  }), method(object({ id: string() }), object({
@@ -34921,6 +35023,12 @@ Object.freeze({
34921
35023
  addonId: null,
34922
35024
  access: "create"
34923
35025
  },
35026
+ "pipelineAnalytics.countUnstampedEventMedia": {
35027
+ capName: "pipeline-analytics",
35028
+ capScope: "device",
35029
+ addonId: null,
35030
+ access: "view"
35031
+ },
34924
35032
  "pipelineAnalytics.deleteDeviceEvents": {
34925
35033
  capName: "pipeline-analytics",
34926
35034
  capScope: "device",
package/dist/addon.mjs CHANGED
@@ -8115,18 +8115,61 @@ var RelocateFootageInputSchema = object({
8115
8115
  * `RecordingConfig.enabled` or camera wrapper bindings. */
8116
8116
  var StorageMigrationLeaseInputSchema = object({ leaseId: string().min(1) });
8117
8117
  var StorageMigrationFootageMoveInputSchema = RelocateFootageInputSchema.extend({ leaseId: string().min(1) });
8118
+ /**
8119
+ * What a `relocateMedia` pass DOES. One engine, three passes — never a second
8120
+ * mover (the engine already walks both collections with a timestamp cursor and
8121
+ * already has a stamp-without-copy path).
8122
+ *
8123
+ * - `move` — the default and the historical behaviour: event-media and
8124
+ * retrain blobs move to `toLocationId` and their rows are
8125
+ * stamped. The enrolled gallery is skipped (D197).
8126
+ * - `seal` — ROWS ONLY, no bytes. Every row whose `locationId` is NULL is
8127
+ * stamped with `toLocationId`. `toLocationId` here is the id the
8128
+ * bytes ALREADY sit on — today's `eventMedia` default — because
8129
+ * a NULL row means "wherever `eventMedia` points *now*", and the
8130
+ * instant a repoint moves that pointer the row reads from the
8131
+ * new disk while its bytes are on the old one.
8132
+ * - `gallery` — the inverse selection of `move`: ONLY the retention-exempt
8133
+ * (enrolled-gallery) rows, which `move` deliberately skips.
8134
+ * `galleryMedia` is `cardinality: 'single'`, so this pass can
8135
+ * never run beside a live second location: it is stop-the-world
8136
+ * by construction, which is acceptable only because the gallery
8137
+ * is a few KB per enrolled sample.
8138
+ */
8139
+ var MediaRelocateModeSchema = _enum([
8140
+ "move",
8141
+ "seal",
8142
+ "gallery"
8143
+ ]);
8118
8144
  var RelocateMediaInputSchema = object({
8119
8145
  toLocationId: string(),
8120
- throttleMbps: number().min(1).max(1e3).optional()
8146
+ throttleMbps: number().min(1).max(1e3).optional(),
8147
+ /** Omitted = `move`, the pre-existing behaviour. */
8148
+ mode: MediaRelocateModeSchema.optional()
8149
+ });
8150
+ /** How many rows still carry NO `locationId` — the population a repoint would
8151
+ * silently re-aim at a disk that does not hold their bytes. Zero is the only
8152
+ * value that permits a non-blocking `eventMedia` cutover. */
8153
+ var UnstampedEventMediaCountSchema = object({
8154
+ media: number().int().nonnegative(),
8155
+ retrainFrames: number().int().nonnegative(),
8156
+ total: number().int().nonnegative()
8121
8157
  });
8122
8158
  var StorageMigrationMediaMoveInputSchema = RelocateMediaInputSchema.extend({ leaseId: string().min(1) });
8123
- /** The independently selectable logical storage classes. `recordings`
8124
- * encompasses the high and mid segment profiles; `recordingsLow` is low
8125
- * segments; `eventMedia` is post-analysis blobs. */
8159
+ /** The independently selectable logical storage classes — every class
8160
+ * `storage.listLocationDeclarations` reports, so an operator never meets a
8161
+ * Zod enum error where they should meet an explanation.
8162
+ *
8163
+ * `recordings` encompasses the high and mid segment profiles; `recordingsLow`
8164
+ * is low segments; `eventMedia` is post-analysis blobs; `galleryMedia` is the
8165
+ * enrolled gallery; `backups` is the system backup archive. The last two have
8166
+ * their own rules — see {@link StorageMigrationFindingCodeSchema}. */
8126
8167
  var StorageMigrationClassSchema = _enum([
8127
8168
  "recordings",
8128
8169
  "recordingsLow",
8129
- "eventMedia"
8170
+ "eventMedia",
8171
+ "backups",
8172
+ "galleryMedia"
8130
8173
  ]);
8131
8174
  /** A destination is always an existing, fully-qualified location id. The
8132
8175
  * migration API intentionally never changes a source location's `basePath`:
@@ -8134,20 +8177,56 @@ var StorageMigrationClassSchema = _enum([
8134
8177
  var StorageMigrationDestinationsSchema = object({
8135
8178
  recordings: string().min(1).optional(),
8136
8179
  recordingsLow: string().min(1).optional(),
8137
- eventMedia: string().min(1).optional()
8180
+ eventMedia: string().min(1).optional(),
8181
+ backups: string().min(1).optional(),
8182
+ galleryMedia: string().min(1).optional()
8138
8183
  }).refine((value) => Object.keys(value).length > 0, { message: "select at least one storage class" });
8184
+ /**
8185
+ * How a migration sequences the cutover against the byte move.
8186
+ *
8187
+ * - `blocking` — the historical order: pause, move every byte, repoint,
8188
+ * resume. Recording is stopped for the whole move. Right
8189
+ * for a small or a cold class, and the only legal mode for
8190
+ * a `cardinality: 'single'` class.
8191
+ * - `nonBlocking` — repoint FIRST, drain behind: seal, pause, repoint,
8192
+ * refresh, resume, then move the past with everything
8193
+ * running. The pause is three bounded instants (a detach +
8194
+ * attach round, a write-gate drain, a lease) instead of one
8195
+ * bounded by bytes. 1.09 TB at 7–14 MB/s is thirty hours of
8196
+ * stopped recording under `blocking`; the same move is
8197
+ * seconds of stopped recording under `nonBlocking`.
8198
+ *
8199
+ * The mode is on the JOB, not only on the input, because `status` is where an
8200
+ * operator finds out which one is running.
8201
+ */
8202
+ var StorageMigrationModeSchema = _enum(["blocking", "nonBlocking"]);
8139
8203
  /** Shared input for planning and starting an orchestrated storage migration. */
8140
8204
  var StorageMigrationInputSchema = object({
8141
8205
  destinations: StorageMigrationDestinationsSchema,
8142
- throttleMbps: number().min(1).max(1e3).optional()
8206
+ throttleMbps: number().min(1).max(1e3).optional(),
8207
+ /** Omitted = `blocking`, which stays the default. */
8208
+ mode: StorageMigrationModeSchema.optional()
8143
8209
  });
8144
- /** The durable coordinator state machine. The only phase that changes default
8145
- * locations is `repointing`, after every selected mover has completed and been
8146
- * verified. */
8210
+ /**
8211
+ * The durable coordinator state machine.
8212
+ *
8213
+ * `blocking`:
8214
+ * planning → pausing → moving → verifying → repointing → refreshing → resuming → done
8215
+ *
8216
+ * `nonBlocking`:
8217
+ * planning → sealing → pausing → repointing → refreshing → resuming → draining → verifying → done
8218
+ *
8219
+ * Same phases, different order plus two new ones — not a second mover.
8220
+ * `sealing` closes the `eventMedia` NULL-row hole BEFORE anything is paused;
8221
+ * `draining` runs the same movers UNLEASED, after every writer is back up.
8222
+ * `repointing` is still the only phase that changes a default location.
8223
+ */
8147
8224
  var StorageMigrationPhaseSchema = _enum([
8148
8225
  "planning",
8226
+ "sealing",
8149
8227
  "pausing",
8150
8228
  "moving",
8229
+ "draining",
8151
8230
  "verifying",
8152
8231
  "repointing",
8153
8232
  "refreshing",
@@ -8172,6 +8251,9 @@ var StorageMigrationMoveSchema = object({
8172
8251
  var StorageMigrationJobSchema = object({
8173
8252
  jobId: string(),
8174
8253
  phase: StorageMigrationPhaseSchema,
8254
+ /** Which order this job is running. `status` is the only place an operator
8255
+ * can tell a seconds-long cutover from a thirty-hour one. */
8256
+ mode: StorageMigrationModeSchema,
8175
8257
  destinations: StorageMigrationDestinationsSchema,
8176
8258
  throttleMbps: number(),
8177
8259
  moves: array(StorageMigrationMoveSchema),
@@ -8184,13 +8266,30 @@ var StorageMigrationJobSchema = object({
8184
8266
  finishedAt: number().nullable(),
8185
8267
  error: string().nullable()
8186
8268
  });
8269
+ var StorageMigrationFindingSchema = object({
8270
+ code: _enum([
8271
+ "sharesDeviceWithSource",
8272
+ "deviceIdentityUnknown",
8273
+ "unstampedEventMediaRows",
8274
+ "blockingOnly",
8275
+ "noMover"
8276
+ ]),
8277
+ storageClass: StorageMigrationClassSchema,
8278
+ /** Human-readable, already carrying the ids and counts. */
8279
+ message: string()
8280
+ });
8187
8281
  var StorageMigrationPlanSchema = object({
8188
8282
  destinations: StorageMigrationDestinationsSchema,
8283
+ /** The mode this plan was built for. A plan is only valid for its mode: the
8284
+ * `eventMedia` seal gate and the single-cardinality refusal both depend on
8285
+ * it. */
8286
+ mode: StorageMigrationModeSchema,
8189
8287
  moves: array(object({
8190
8288
  storageClass: StorageMigrationClassSchema,
8191
8289
  fromLocationId: string(),
8192
8290
  toLocationId: string()
8193
- }))
8291
+ })),
8292
+ findings: array(StorageMigrationFindingSchema)
8194
8293
  });
8195
8294
  /**
8196
8295
  * `StorageLocationType` — an addon-declared id that identifies the *kind* of
@@ -18988,7 +19087,7 @@ DeviceType.Camera, method(object({ deviceId: number() }), array(TrackSchema).rea
18988
19087
  }), method(RelocateMediaInputSchema, object({ jobId: string() }), {
18989
19088
  kind: "mutation",
18990
19089
  auth: "admin"
18991
- }), method(object({}), array(RelocateJobSchema).readonly(), {
19090
+ }), method(object({}), UnstampedEventMediaCountSchema, { auth: "admin" }), method(object({}), array(RelocateJobSchema).readonly(), {
18992
19091
  kind: "query",
18993
19092
  auth: "admin"
18994
19093
  }), method(object({ jobId: string() }), object({ cancelled: boolean() }), {
@@ -20999,7 +21098,10 @@ method(object({
20999
21098
  }), StorageLocationSchema, {
21000
21099
  kind: "mutation",
21001
21100
  auth: "admin"
21002
- }), method(object({ id: string() }), _void(), {
21101
+ }), method(object({
21102
+ id: string(),
21103
+ force: boolean().optional()
21104
+ }), _void(), {
21003
21105
  kind: "mutation",
21004
21106
  auth: "admin"
21005
21107
  }), method(object({ id: string() }), object({
@@ -34898,6 +35000,12 @@ Object.freeze({
34898
35000
  addonId: null,
34899
35001
  access: "create"
34900
35002
  },
35003
+ "pipelineAnalytics.countUnstampedEventMedia": {
35004
+ capName: "pipeline-analytics",
35005
+ capScope: "device",
35006
+ addonId: null,
35007
+ access: "view"
35008
+ },
34901
35009
  "pipelineAnalytics.deleteDeviceEvents": {
34902
35010
  capName: "pipeline-analytics",
34903
35011
  capScope: "device",
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@camstack/addon-terminal",
3
- "version": "0.1.47",
3
+ "version": "0.1.48",
4
4
  "description": "Interactive terminal sessions (pty + xterm) as a CamStack addon",
5
5
  "keywords": [
6
6
  "camstack",