@camstack/addon-provider-tuya 0.2.42 → 0.2.43

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
@@ -8859,18 +8859,61 @@ var RelocateFootageInputSchema = object({
8859
8859
  * `RecordingConfig.enabled` or camera wrapper bindings. */
8860
8860
  var StorageMigrationLeaseInputSchema = object({ leaseId: string().min(1) });
8861
8861
  var StorageMigrationFootageMoveInputSchema = RelocateFootageInputSchema.extend({ leaseId: string().min(1) });
8862
+ /**
8863
+ * What a `relocateMedia` pass DOES. One engine, three passes — never a second
8864
+ * mover (the engine already walks both collections with a timestamp cursor and
8865
+ * already has a stamp-without-copy path).
8866
+ *
8867
+ * - `move` — the default and the historical behaviour: event-media and
8868
+ * retrain blobs move to `toLocationId` and their rows are
8869
+ * stamped. The enrolled gallery is skipped (D197).
8870
+ * - `seal` — ROWS ONLY, no bytes. Every row whose `locationId` is NULL is
8871
+ * stamped with `toLocationId`. `toLocationId` here is the id the
8872
+ * bytes ALREADY sit on — today's `eventMedia` default — because
8873
+ * a NULL row means "wherever `eventMedia` points *now*", and the
8874
+ * instant a repoint moves that pointer the row reads from the
8875
+ * new disk while its bytes are on the old one.
8876
+ * - `gallery` — the inverse selection of `move`: ONLY the retention-exempt
8877
+ * (enrolled-gallery) rows, which `move` deliberately skips.
8878
+ * `galleryMedia` is `cardinality: 'single'`, so this pass can
8879
+ * never run beside a live second location: it is stop-the-world
8880
+ * by construction, which is acceptable only because the gallery
8881
+ * is a few KB per enrolled sample.
8882
+ */
8883
+ var MediaRelocateModeSchema = _enum([
8884
+ "move",
8885
+ "seal",
8886
+ "gallery"
8887
+ ]);
8862
8888
  var RelocateMediaInputSchema = object({
8863
8889
  toLocationId: string(),
8864
- throttleMbps: number().min(1).max(1e3).optional()
8890
+ throttleMbps: number().min(1).max(1e3).optional(),
8891
+ /** Omitted = `move`, the pre-existing behaviour. */
8892
+ mode: MediaRelocateModeSchema.optional()
8893
+ });
8894
+ /** How many rows still carry NO `locationId` — the population a repoint would
8895
+ * silently re-aim at a disk that does not hold their bytes. Zero is the only
8896
+ * value that permits a non-blocking `eventMedia` cutover. */
8897
+ var UnstampedEventMediaCountSchema = object({
8898
+ media: number().int().nonnegative(),
8899
+ retrainFrames: number().int().nonnegative(),
8900
+ total: number().int().nonnegative()
8865
8901
  });
8866
8902
  var StorageMigrationMediaMoveInputSchema = RelocateMediaInputSchema.extend({ leaseId: string().min(1) });
8867
- /** The independently selectable logical storage classes. `recordings`
8868
- * encompasses the high and mid segment profiles; `recordingsLow` is low
8869
- * segments; `eventMedia` is post-analysis blobs. */
8903
+ /** The independently selectable logical storage classes — every class
8904
+ * `storage.listLocationDeclarations` reports, so an operator never meets a
8905
+ * Zod enum error where they should meet an explanation.
8906
+ *
8907
+ * `recordings` encompasses the high and mid segment profiles; `recordingsLow`
8908
+ * is low segments; `eventMedia` is post-analysis blobs; `galleryMedia` is the
8909
+ * enrolled gallery; `backups` is the system backup archive. The last two have
8910
+ * their own rules — see {@link StorageMigrationFindingCodeSchema}. */
8870
8911
  var StorageMigrationClassSchema = _enum([
8871
8912
  "recordings",
8872
8913
  "recordingsLow",
8873
- "eventMedia"
8914
+ "eventMedia",
8915
+ "backups",
8916
+ "galleryMedia"
8874
8917
  ]);
8875
8918
  /** A destination is always an existing, fully-qualified location id. The
8876
8919
  * migration API intentionally never changes a source location's `basePath`:
@@ -8878,20 +8921,56 @@ var StorageMigrationClassSchema = _enum([
8878
8921
  var StorageMigrationDestinationsSchema = object({
8879
8922
  recordings: string().min(1).optional(),
8880
8923
  recordingsLow: string().min(1).optional(),
8881
- eventMedia: string().min(1).optional()
8924
+ eventMedia: string().min(1).optional(),
8925
+ backups: string().min(1).optional(),
8926
+ galleryMedia: string().min(1).optional()
8882
8927
  }).refine((value) => Object.keys(value).length > 0, { message: "select at least one storage class" });
8928
+ /**
8929
+ * How a migration sequences the cutover against the byte move.
8930
+ *
8931
+ * - `blocking` — the historical order: pause, move every byte, repoint,
8932
+ * resume. Recording is stopped for the whole move. Right
8933
+ * for a small or a cold class, and the only legal mode for
8934
+ * a `cardinality: 'single'` class.
8935
+ * - `nonBlocking` — repoint FIRST, drain behind: seal, pause, repoint,
8936
+ * refresh, resume, then move the past with everything
8937
+ * running. The pause is three bounded instants (a detach +
8938
+ * attach round, a write-gate drain, a lease) instead of one
8939
+ * bounded by bytes. 1.09 TB at 7–14 MB/s is thirty hours of
8940
+ * stopped recording under `blocking`; the same move is
8941
+ * seconds of stopped recording under `nonBlocking`.
8942
+ *
8943
+ * The mode is on the JOB, not only on the input, because `status` is where an
8944
+ * operator finds out which one is running.
8945
+ */
8946
+ var StorageMigrationModeSchema = _enum(["blocking", "nonBlocking"]);
8883
8947
  /** Shared input for planning and starting an orchestrated storage migration. */
8884
8948
  var StorageMigrationInputSchema = object({
8885
8949
  destinations: StorageMigrationDestinationsSchema,
8886
- throttleMbps: number().min(1).max(1e3).optional()
8950
+ throttleMbps: number().min(1).max(1e3).optional(),
8951
+ /** Omitted = `blocking`, which stays the default. */
8952
+ mode: StorageMigrationModeSchema.optional()
8887
8953
  });
8888
- /** The durable coordinator state machine. The only phase that changes default
8889
- * locations is `repointing`, after every selected mover has completed and been
8890
- * verified. */
8954
+ /**
8955
+ * The durable coordinator state machine.
8956
+ *
8957
+ * `blocking`:
8958
+ * planning → pausing → moving → verifying → repointing → refreshing → resuming → done
8959
+ *
8960
+ * `nonBlocking`:
8961
+ * planning → sealing → pausing → repointing → refreshing → resuming → draining → verifying → done
8962
+ *
8963
+ * Same phases, different order plus two new ones — not a second mover.
8964
+ * `sealing` closes the `eventMedia` NULL-row hole BEFORE anything is paused;
8965
+ * `draining` runs the same movers UNLEASED, after every writer is back up.
8966
+ * `repointing` is still the only phase that changes a default location.
8967
+ */
8891
8968
  var StorageMigrationPhaseSchema = _enum([
8892
8969
  "planning",
8970
+ "sealing",
8893
8971
  "pausing",
8894
8972
  "moving",
8973
+ "draining",
8895
8974
  "verifying",
8896
8975
  "repointing",
8897
8976
  "refreshing",
@@ -8916,6 +8995,9 @@ var StorageMigrationMoveSchema = object({
8916
8995
  var StorageMigrationJobSchema = object({
8917
8996
  jobId: string(),
8918
8997
  phase: StorageMigrationPhaseSchema,
8998
+ /** Which order this job is running. `status` is the only place an operator
8999
+ * can tell a seconds-long cutover from a thirty-hour one. */
9000
+ mode: StorageMigrationModeSchema,
8919
9001
  destinations: StorageMigrationDestinationsSchema,
8920
9002
  throttleMbps: number(),
8921
9003
  moves: array(StorageMigrationMoveSchema),
@@ -8928,13 +9010,30 @@ var StorageMigrationJobSchema = object({
8928
9010
  finishedAt: number().nullable(),
8929
9011
  error: string().nullable()
8930
9012
  });
9013
+ var StorageMigrationFindingSchema = object({
9014
+ code: _enum([
9015
+ "sharesDeviceWithSource",
9016
+ "deviceIdentityUnknown",
9017
+ "unstampedEventMediaRows",
9018
+ "blockingOnly",
9019
+ "noMover"
9020
+ ]),
9021
+ storageClass: StorageMigrationClassSchema,
9022
+ /** Human-readable, already carrying the ids and counts. */
9023
+ message: string()
9024
+ });
8931
9025
  var StorageMigrationPlanSchema = object({
8932
9026
  destinations: StorageMigrationDestinationsSchema,
9027
+ /** The mode this plan was built for. A plan is only valid for its mode: the
9028
+ * `eventMedia` seal gate and the single-cardinality refusal both depend on
9029
+ * it. */
9030
+ mode: StorageMigrationModeSchema,
8933
9031
  moves: array(object({
8934
9032
  storageClass: StorageMigrationClassSchema,
8935
9033
  fromLocationId: string(),
8936
9034
  toLocationId: string()
8937
- }))
9035
+ })),
9036
+ findings: array(StorageMigrationFindingSchema)
8938
9037
  });
8939
9038
  /**
8940
9039
  * `StorageLocationType` — an addon-declared id that identifies the *kind* of
@@ -19804,7 +19903,7 @@ DeviceType.Camera, method(object({ deviceId: number() }), array(TrackSchema).rea
19804
19903
  }), method(RelocateMediaInputSchema, object({ jobId: string() }), {
19805
19904
  kind: "mutation",
19806
19905
  auth: "admin"
19807
- }), method(object({}), array(RelocateJobSchema).readonly(), {
19906
+ }), method(object({}), UnstampedEventMediaCountSchema, { auth: "admin" }), method(object({}), array(RelocateJobSchema).readonly(), {
19808
19907
  kind: "query",
19809
19908
  auth: "admin"
19810
19909
  }), method(object({ jobId: string() }), object({ cancelled: boolean() }), {
@@ -21711,7 +21810,10 @@ method(object({
21711
21810
  }), StorageLocationSchema, {
21712
21811
  kind: "mutation",
21713
21812
  auth: "admin"
21714
- }), method(object({ id: string() }), _void(), {
21813
+ }), method(object({
21814
+ id: string(),
21815
+ force: boolean().optional()
21816
+ }), _void(), {
21715
21817
  kind: "mutation",
21716
21818
  auth: "admin"
21717
21819
  }), method(object({ id: string() }), object({
@@ -35576,6 +35678,12 @@ Object.freeze({
35576
35678
  addonId: null,
35577
35679
  access: "create"
35578
35680
  },
35681
+ "pipelineAnalytics.countUnstampedEventMedia": {
35682
+ capName: "pipeline-analytics",
35683
+ capScope: "device",
35684
+ addonId: null,
35685
+ access: "view"
35686
+ },
35579
35687
  "pipelineAnalytics.deleteDeviceEvents": {
35580
35688
  capName: "pipeline-analytics",
35581
35689
  capScope: "device",
package/dist/addon.mjs CHANGED
@@ -8858,18 +8858,61 @@ var RelocateFootageInputSchema = object({
8858
8858
  * `RecordingConfig.enabled` or camera wrapper bindings. */
8859
8859
  var StorageMigrationLeaseInputSchema = object({ leaseId: string().min(1) });
8860
8860
  var StorageMigrationFootageMoveInputSchema = RelocateFootageInputSchema.extend({ leaseId: string().min(1) });
8861
+ /**
8862
+ * What a `relocateMedia` pass DOES. One engine, three passes — never a second
8863
+ * mover (the engine already walks both collections with a timestamp cursor and
8864
+ * already has a stamp-without-copy path).
8865
+ *
8866
+ * - `move` — the default and the historical behaviour: event-media and
8867
+ * retrain blobs move to `toLocationId` and their rows are
8868
+ * stamped. The enrolled gallery is skipped (D197).
8869
+ * - `seal` — ROWS ONLY, no bytes. Every row whose `locationId` is NULL is
8870
+ * stamped with `toLocationId`. `toLocationId` here is the id the
8871
+ * bytes ALREADY sit on — today's `eventMedia` default — because
8872
+ * a NULL row means "wherever `eventMedia` points *now*", and the
8873
+ * instant a repoint moves that pointer the row reads from the
8874
+ * new disk while its bytes are on the old one.
8875
+ * - `gallery` — the inverse selection of `move`: ONLY the retention-exempt
8876
+ * (enrolled-gallery) rows, which `move` deliberately skips.
8877
+ * `galleryMedia` is `cardinality: 'single'`, so this pass can
8878
+ * never run beside a live second location: it is stop-the-world
8879
+ * by construction, which is acceptable only because the gallery
8880
+ * is a few KB per enrolled sample.
8881
+ */
8882
+ var MediaRelocateModeSchema = _enum([
8883
+ "move",
8884
+ "seal",
8885
+ "gallery"
8886
+ ]);
8861
8887
  var RelocateMediaInputSchema = object({
8862
8888
  toLocationId: string(),
8863
- throttleMbps: number().min(1).max(1e3).optional()
8889
+ throttleMbps: number().min(1).max(1e3).optional(),
8890
+ /** Omitted = `move`, the pre-existing behaviour. */
8891
+ mode: MediaRelocateModeSchema.optional()
8892
+ });
8893
+ /** How many rows still carry NO `locationId` — the population a repoint would
8894
+ * silently re-aim at a disk that does not hold their bytes. Zero is the only
8895
+ * value that permits a non-blocking `eventMedia` cutover. */
8896
+ var UnstampedEventMediaCountSchema = object({
8897
+ media: number().int().nonnegative(),
8898
+ retrainFrames: number().int().nonnegative(),
8899
+ total: number().int().nonnegative()
8864
8900
  });
8865
8901
  var StorageMigrationMediaMoveInputSchema = RelocateMediaInputSchema.extend({ leaseId: string().min(1) });
8866
- /** The independently selectable logical storage classes. `recordings`
8867
- * encompasses the high and mid segment profiles; `recordingsLow` is low
8868
- * segments; `eventMedia` is post-analysis blobs. */
8902
+ /** The independently selectable logical storage classes — every class
8903
+ * `storage.listLocationDeclarations` reports, so an operator never meets a
8904
+ * Zod enum error where they should meet an explanation.
8905
+ *
8906
+ * `recordings` encompasses the high and mid segment profiles; `recordingsLow`
8907
+ * is low segments; `eventMedia` is post-analysis blobs; `galleryMedia` is the
8908
+ * enrolled gallery; `backups` is the system backup archive. The last two have
8909
+ * their own rules — see {@link StorageMigrationFindingCodeSchema}. */
8869
8910
  var StorageMigrationClassSchema = _enum([
8870
8911
  "recordings",
8871
8912
  "recordingsLow",
8872
- "eventMedia"
8913
+ "eventMedia",
8914
+ "backups",
8915
+ "galleryMedia"
8873
8916
  ]);
8874
8917
  /** A destination is always an existing, fully-qualified location id. The
8875
8918
  * migration API intentionally never changes a source location's `basePath`:
@@ -8877,20 +8920,56 @@ var StorageMigrationClassSchema = _enum([
8877
8920
  var StorageMigrationDestinationsSchema = object({
8878
8921
  recordings: string().min(1).optional(),
8879
8922
  recordingsLow: string().min(1).optional(),
8880
- eventMedia: string().min(1).optional()
8923
+ eventMedia: string().min(1).optional(),
8924
+ backups: string().min(1).optional(),
8925
+ galleryMedia: string().min(1).optional()
8881
8926
  }).refine((value) => Object.keys(value).length > 0, { message: "select at least one storage class" });
8927
+ /**
8928
+ * How a migration sequences the cutover against the byte move.
8929
+ *
8930
+ * - `blocking` — the historical order: pause, move every byte, repoint,
8931
+ * resume. Recording is stopped for the whole move. Right
8932
+ * for a small or a cold class, and the only legal mode for
8933
+ * a `cardinality: 'single'` class.
8934
+ * - `nonBlocking` — repoint FIRST, drain behind: seal, pause, repoint,
8935
+ * refresh, resume, then move the past with everything
8936
+ * running. The pause is three bounded instants (a detach +
8937
+ * attach round, a write-gate drain, a lease) instead of one
8938
+ * bounded by bytes. 1.09 TB at 7–14 MB/s is thirty hours of
8939
+ * stopped recording under `blocking`; the same move is
8940
+ * seconds of stopped recording under `nonBlocking`.
8941
+ *
8942
+ * The mode is on the JOB, not only on the input, because `status` is where an
8943
+ * operator finds out which one is running.
8944
+ */
8945
+ var StorageMigrationModeSchema = _enum(["blocking", "nonBlocking"]);
8882
8946
  /** Shared input for planning and starting an orchestrated storage migration. */
8883
8947
  var StorageMigrationInputSchema = object({
8884
8948
  destinations: StorageMigrationDestinationsSchema,
8885
- throttleMbps: number().min(1).max(1e3).optional()
8949
+ throttleMbps: number().min(1).max(1e3).optional(),
8950
+ /** Omitted = `blocking`, which stays the default. */
8951
+ mode: StorageMigrationModeSchema.optional()
8886
8952
  });
8887
- /** The durable coordinator state machine. The only phase that changes default
8888
- * locations is `repointing`, after every selected mover has completed and been
8889
- * verified. */
8953
+ /**
8954
+ * The durable coordinator state machine.
8955
+ *
8956
+ * `blocking`:
8957
+ * planning → pausing → moving → verifying → repointing → refreshing → resuming → done
8958
+ *
8959
+ * `nonBlocking`:
8960
+ * planning → sealing → pausing → repointing → refreshing → resuming → draining → verifying → done
8961
+ *
8962
+ * Same phases, different order plus two new ones — not a second mover.
8963
+ * `sealing` closes the `eventMedia` NULL-row hole BEFORE anything is paused;
8964
+ * `draining` runs the same movers UNLEASED, after every writer is back up.
8965
+ * `repointing` is still the only phase that changes a default location.
8966
+ */
8890
8967
  var StorageMigrationPhaseSchema = _enum([
8891
8968
  "planning",
8969
+ "sealing",
8892
8970
  "pausing",
8893
8971
  "moving",
8972
+ "draining",
8894
8973
  "verifying",
8895
8974
  "repointing",
8896
8975
  "refreshing",
@@ -8915,6 +8994,9 @@ var StorageMigrationMoveSchema = object({
8915
8994
  var StorageMigrationJobSchema = object({
8916
8995
  jobId: string(),
8917
8996
  phase: StorageMigrationPhaseSchema,
8997
+ /** Which order this job is running. `status` is the only place an operator
8998
+ * can tell a seconds-long cutover from a thirty-hour one. */
8999
+ mode: StorageMigrationModeSchema,
8918
9000
  destinations: StorageMigrationDestinationsSchema,
8919
9001
  throttleMbps: number(),
8920
9002
  moves: array(StorageMigrationMoveSchema),
@@ -8927,13 +9009,30 @@ var StorageMigrationJobSchema = object({
8927
9009
  finishedAt: number().nullable(),
8928
9010
  error: string().nullable()
8929
9011
  });
9012
+ var StorageMigrationFindingSchema = object({
9013
+ code: _enum([
9014
+ "sharesDeviceWithSource",
9015
+ "deviceIdentityUnknown",
9016
+ "unstampedEventMediaRows",
9017
+ "blockingOnly",
9018
+ "noMover"
9019
+ ]),
9020
+ storageClass: StorageMigrationClassSchema,
9021
+ /** Human-readable, already carrying the ids and counts. */
9022
+ message: string()
9023
+ });
8930
9024
  var StorageMigrationPlanSchema = object({
8931
9025
  destinations: StorageMigrationDestinationsSchema,
9026
+ /** The mode this plan was built for. A plan is only valid for its mode: the
9027
+ * `eventMedia` seal gate and the single-cardinality refusal both depend on
9028
+ * it. */
9029
+ mode: StorageMigrationModeSchema,
8932
9030
  moves: array(object({
8933
9031
  storageClass: StorageMigrationClassSchema,
8934
9032
  fromLocationId: string(),
8935
9033
  toLocationId: string()
8936
- }))
9034
+ })),
9035
+ findings: array(StorageMigrationFindingSchema)
8937
9036
  });
8938
9037
  /**
8939
9038
  * `StorageLocationType` — an addon-declared id that identifies the *kind* of
@@ -19803,7 +19902,7 @@ DeviceType.Camera, method(object({ deviceId: number() }), array(TrackSchema).rea
19803
19902
  }), method(RelocateMediaInputSchema, object({ jobId: string() }), {
19804
19903
  kind: "mutation",
19805
19904
  auth: "admin"
19806
- }), method(object({}), array(RelocateJobSchema).readonly(), {
19905
+ }), method(object({}), UnstampedEventMediaCountSchema, { auth: "admin" }), method(object({}), array(RelocateJobSchema).readonly(), {
19807
19906
  kind: "query",
19808
19907
  auth: "admin"
19809
19908
  }), method(object({ jobId: string() }), object({ cancelled: boolean() }), {
@@ -21710,7 +21809,10 @@ method(object({
21710
21809
  }), StorageLocationSchema, {
21711
21810
  kind: "mutation",
21712
21811
  auth: "admin"
21713
- }), method(object({ id: string() }), _void(), {
21812
+ }), method(object({
21813
+ id: string(),
21814
+ force: boolean().optional()
21815
+ }), _void(), {
21714
21816
  kind: "mutation",
21715
21817
  auth: "admin"
21716
21818
  }), method(object({ id: string() }), object({
@@ -35575,6 +35677,12 @@ Object.freeze({
35575
35677
  addonId: null,
35576
35678
  access: "create"
35577
35679
  },
35680
+ "pipelineAnalytics.countUnstampedEventMedia": {
35681
+ capName: "pipeline-analytics",
35682
+ capScope: "device",
35683
+ addonId: null,
35684
+ access: "view"
35685
+ },
35578
35686
  "pipelineAnalytics.deleteDeviceEvents": {
35579
35687
  capName: "pipeline-analytics",
35580
35688
  capScope: "device",
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@camstack/addon-provider-tuya",
3
- "version": "0.2.42",
3
+ "version": "0.2.43",
4
4
  "description": "Tuya / Smart Life device-provider addon for CamStack — account-onboarded (Tuya IoT cloud fetch of device localKeys) + LOCAL DP control via the @apocaliss92/nodetuya encrypted-LAN client, exposing switch / water-heater-family kettle entities",
5
5
  "keywords": [
6
6
  "camstack",