@camstack/addon-provider-tuya 0.2.45 → 0.2.46

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/addon.js CHANGED
@@ -8823,6 +8823,21 @@ var RelocateJobSchema = object({
8823
8823
  bytesMoved: number().int(),
8824
8824
  /** Total files discovered up front; null while (or when) unknown. */
8825
8825
  filesTotal: number().int().nullable(),
8826
+ /**
8827
+ * Rows this run CORRECTED while moving them — a durable mutation the move
8828
+ * made that nobody asked for, so it is reported where the operator reads the
8829
+ * job rather than only in a log line.
8830
+ *
8831
+ * A footage segment records its byte count in its own NAME, and the durable
8832
+ * hour row derives its aggregates from those names. A file that does not
8833
+ * match its name therefore makes the ledger's sums — and with them quota and
8834
+ * pressure eviction — wrong by the difference, and only a rename can fix it.
8835
+ * On 2026-08-30 one such row also stalled a 110 749-file drain permanently.
8836
+ *
8837
+ * Absent on lanes where the question has no meaning: a media blob's size is
8838
+ * in its row, not in its name, so `MediaRelocateEngine` never reconciles one.
8839
+ */
8840
+ rowsReconciled: number().int().nonnegative().optional(),
8826
8841
  startedAt: number(),
8827
8842
  finishedAt: number().nullable(),
8828
8843
  error: string().nullable()
@@ -8891,14 +8906,42 @@ var RelocateMediaInputSchema = object({
8891
8906
  /** Omitted = `move`, the pre-existing behaviour. */
8892
8907
  mode: MediaRelocateModeSchema.optional()
8893
8908
  });
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()
8909
+ /**
8910
+ * The unstamped population of ONE collection — split, because the gate and the
8911
+ * operator ask two different questions and only one of them has to be cheap.
8912
+ *
8913
+ * `present` is the GATE: "is there at least one row that would be orphaned by a
8914
+ * repoint". It is a single indexed seek to the first matching row, so it stays
8915
+ * answerable on a saturated disk and answers in O(log n) precisely in the state
8916
+ * that matters — after a seal, when the population is empty.
8917
+ *
8918
+ * `rows` is the NUMBER, for the refusal message and the operator's sense of
8919
+ * scale. It is a second, indexed `COUNT(*)`, and `null` means **not
8920
+ * measurable** — never zero. `{ present: true, rows: null }` is a legitimate
8921
+ * and useful answer: "there are some, and this read could not say how many"
8922
+ * still refuses the cutover, which is the whole job.
8923
+ */
8924
+ var UnstampedRowsSchema = object({
8925
+ present: boolean(),
8926
+ rows: number().int().nonnegative().nullable()
8901
8927
  });
8928
+ /**
8929
+ * How many rows still carry NO `locationId` — the population a repoint would
8930
+ * silently re-aim at a disk that does not hold their bytes.
8931
+ *
8932
+ * **`null` = the count could not be taken**, and it is NOT permission to cut
8933
+ * over. The gate opens on a measured absence and on nothing else; an unread
8934
+ * collection and an empty one are different facts, and this repo has already
8935
+ * paid for conflating them (`RelocateResidueSchema`, D295).
8936
+ */
8937
+ var UnstampedEventMediaCountSchema = object({
8938
+ media: UnstampedRowsSchema,
8939
+ retrainFrames: UnstampedRowsSchema,
8940
+ /** True when EITHER collection holds one. The refusal reads this. */
8941
+ anyPresent: boolean(),
8942
+ /** Sum across both, or `null` when either lane could not be counted. */
8943
+ total: number().int().nonnegative().nullable()
8944
+ }).nullable();
8902
8945
  var StorageMigrationMediaMoveInputSchema = RelocateMediaInputSchema.extend({ leaseId: string().min(1) });
8903
8946
  /** The independently selectable logical storage classes — every class
8904
8947
  * `storage.listLocationDeclarations` reports, so an operator never meets a
@@ -9009,6 +9052,10 @@ var StorageMigrationMoveProgressSchema = object({
9009
9052
  /** The archive census — the **M** of "N of M" (D295). `null` = unknowable. */
9010
9053
  filesTotal: number().int().nonnegative().nullable(),
9011
9054
  bytesMoved: number().int().nonnegative(),
9055
+ /** Rows the mover corrected while moving them — see `RelocateJob`. Absent on
9056
+ * a lane that cannot reconcile. A migration that silently rewrote durable
9057
+ * rows would be the same failure as one that silently skipped them. */
9058
+ rowsReconciled: number().int().nonnegative().optional(),
9012
9059
  /** The MOVER's start, not the migration's: a drain restarted after an addon
9013
9060
  * crash gets a new mover, and a rate computed from the migration's start
9014
9061
  * would silently average in the time nothing was running. */
package/dist/addon.mjs CHANGED
@@ -8822,6 +8822,21 @@ var RelocateJobSchema = object({
8822
8822
  bytesMoved: number().int(),
8823
8823
  /** Total files discovered up front; null while (or when) unknown. */
8824
8824
  filesTotal: number().int().nullable(),
8825
+ /**
8826
+ * Rows this run CORRECTED while moving them — a durable mutation the move
8827
+ * made that nobody asked for, so it is reported where the operator reads the
8828
+ * job rather than only in a log line.
8829
+ *
8830
+ * A footage segment records its byte count in its own NAME, and the durable
8831
+ * hour row derives its aggregates from those names. A file that does not
8832
+ * match its name therefore makes the ledger's sums — and with them quota and
8833
+ * pressure eviction — wrong by the difference, and only a rename can fix it.
8834
+ * On 2026-08-30 one such row also stalled a 110 749-file drain permanently.
8835
+ *
8836
+ * Absent on lanes where the question has no meaning: a media blob's size is
8837
+ * in its row, not in its name, so `MediaRelocateEngine` never reconciles one.
8838
+ */
8839
+ rowsReconciled: number().int().nonnegative().optional(),
8825
8840
  startedAt: number(),
8826
8841
  finishedAt: number().nullable(),
8827
8842
  error: string().nullable()
@@ -8890,14 +8905,42 @@ var RelocateMediaInputSchema = object({
8890
8905
  /** Omitted = `move`, the pre-existing behaviour. */
8891
8906
  mode: MediaRelocateModeSchema.optional()
8892
8907
  });
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()
8908
+ /**
8909
+ * The unstamped population of ONE collection — split, because the gate and the
8910
+ * operator ask two different questions and only one of them has to be cheap.
8911
+ *
8912
+ * `present` is the GATE: "is there at least one row that would be orphaned by a
8913
+ * repoint". It is a single indexed seek to the first matching row, so it stays
8914
+ * answerable on a saturated disk and answers in O(log n) precisely in the state
8915
+ * that matters — after a seal, when the population is empty.
8916
+ *
8917
+ * `rows` is the NUMBER, for the refusal message and the operator's sense of
8918
+ * scale. It is a second, indexed `COUNT(*)`, and `null` means **not
8919
+ * measurable** — never zero. `{ present: true, rows: null }` is a legitimate
8920
+ * and useful answer: "there are some, and this read could not say how many"
8921
+ * still refuses the cutover, which is the whole job.
8922
+ */
8923
+ var UnstampedRowsSchema = object({
8924
+ present: boolean(),
8925
+ rows: number().int().nonnegative().nullable()
8900
8926
  });
8927
+ /**
8928
+ * How many rows still carry NO `locationId` — the population a repoint would
8929
+ * silently re-aim at a disk that does not hold their bytes.
8930
+ *
8931
+ * **`null` = the count could not be taken**, and it is NOT permission to cut
8932
+ * over. The gate opens on a measured absence and on nothing else; an unread
8933
+ * collection and an empty one are different facts, and this repo has already
8934
+ * paid for conflating them (`RelocateResidueSchema`, D295).
8935
+ */
8936
+ var UnstampedEventMediaCountSchema = object({
8937
+ media: UnstampedRowsSchema,
8938
+ retrainFrames: UnstampedRowsSchema,
8939
+ /** True when EITHER collection holds one. The refusal reads this. */
8940
+ anyPresent: boolean(),
8941
+ /** Sum across both, or `null` when either lane could not be counted. */
8942
+ total: number().int().nonnegative().nullable()
8943
+ }).nullable();
8901
8944
  var StorageMigrationMediaMoveInputSchema = RelocateMediaInputSchema.extend({ leaseId: string().min(1) });
8902
8945
  /** The independently selectable logical storage classes — every class
8903
8946
  * `storage.listLocationDeclarations` reports, so an operator never meets a
@@ -9008,6 +9051,10 @@ var StorageMigrationMoveProgressSchema = object({
9008
9051
  /** The archive census — the **M** of "N of M" (D295). `null` = unknowable. */
9009
9052
  filesTotal: number().int().nonnegative().nullable(),
9010
9053
  bytesMoved: number().int().nonnegative(),
9054
+ /** Rows the mover corrected while moving them — see `RelocateJob`. Absent on
9055
+ * a lane that cannot reconcile. A migration that silently rewrote durable
9056
+ * rows would be the same failure as one that silently skipped them. */
9057
+ rowsReconciled: number().int().nonnegative().optional(),
9011
9058
  /** The MOVER's start, not the migration's: a drain restarted after an addon
9012
9059
  * crash gets a new mover, and a rate computed from the migration's start
9013
9060
  * would silently average in the time nothing was running. */
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@camstack/addon-provider-tuya",
3
- "version": "0.2.45",
3
+ "version": "0.2.46",
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",