@camstack/addon-mqtt-broker 1.2.45 → 1.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.
@@ -8032,6 +8032,21 @@ var RelocateJobSchema = object({
8032
8032
  bytesMoved: number().int(),
8033
8033
  /** Total files discovered up front; null while (or when) unknown. */
8034
8034
  filesTotal: number().int().nullable(),
8035
+ /**
8036
+ * Rows this run CORRECTED while moving them — a durable mutation the move
8037
+ * made that nobody asked for, so it is reported where the operator reads the
8038
+ * job rather than only in a log line.
8039
+ *
8040
+ * A footage segment records its byte count in its own NAME, and the durable
8041
+ * hour row derives its aggregates from those names. A file that does not
8042
+ * match its name therefore makes the ledger's sums — and with them quota and
8043
+ * pressure eviction — wrong by the difference, and only a rename can fix it.
8044
+ * On 2026-08-30 one such row also stalled a 110 749-file drain permanently.
8045
+ *
8046
+ * Absent on lanes where the question has no meaning: a media blob's size is
8047
+ * in its row, not in its name, so `MediaRelocateEngine` never reconciles one.
8048
+ */
8049
+ rowsReconciled: number().int().nonnegative().optional(),
8035
8050
  startedAt: number(),
8036
8051
  finishedAt: number().nullable(),
8037
8052
  error: string().nullable()
@@ -8100,14 +8115,42 @@ var RelocateMediaInputSchema = object({
8100
8115
  /** Omitted = `move`, the pre-existing behaviour. */
8101
8116
  mode: MediaRelocateModeSchema.optional()
8102
8117
  });
8103
- /** How many rows still carry NO `locationId` — the population a repoint would
8104
- * silently re-aim at a disk that does not hold their bytes. Zero is the only
8105
- * value that permits a non-blocking `eventMedia` cutover. */
8106
- var UnstampedEventMediaCountSchema = object({
8107
- media: number().int().nonnegative(),
8108
- retrainFrames: number().int().nonnegative(),
8109
- total: number().int().nonnegative()
8118
+ /**
8119
+ * The unstamped population of ONE collection — split, because the gate and the
8120
+ * operator ask two different questions and only one of them has to be cheap.
8121
+ *
8122
+ * `present` is the GATE: "is there at least one row that would be orphaned by a
8123
+ * repoint". It is a single indexed seek to the first matching row, so it stays
8124
+ * answerable on a saturated disk and answers in O(log n) precisely in the state
8125
+ * that matters — after a seal, when the population is empty.
8126
+ *
8127
+ * `rows` is the NUMBER, for the refusal message and the operator's sense of
8128
+ * scale. It is a second, indexed `COUNT(*)`, and `null` means **not
8129
+ * measurable** — never zero. `{ present: true, rows: null }` is a legitimate
8130
+ * and useful answer: "there are some, and this read could not say how many"
8131
+ * still refuses the cutover, which is the whole job.
8132
+ */
8133
+ var UnstampedRowsSchema = object({
8134
+ present: boolean(),
8135
+ rows: number().int().nonnegative().nullable()
8110
8136
  });
8137
+ /**
8138
+ * How many rows still carry NO `locationId` — the population a repoint would
8139
+ * silently re-aim at a disk that does not hold their bytes.
8140
+ *
8141
+ * **`null` = the count could not be taken**, and it is NOT permission to cut
8142
+ * over. The gate opens on a measured absence and on nothing else; an unread
8143
+ * collection and an empty one are different facts, and this repo has already
8144
+ * paid for conflating them (`RelocateResidueSchema`, D295).
8145
+ */
8146
+ var UnstampedEventMediaCountSchema = object({
8147
+ media: UnstampedRowsSchema,
8148
+ retrainFrames: UnstampedRowsSchema,
8149
+ /** True when EITHER collection holds one. The refusal reads this. */
8150
+ anyPresent: boolean(),
8151
+ /** Sum across both, or `null` when either lane could not be counted. */
8152
+ total: number().int().nonnegative().nullable()
8153
+ }).nullable();
8111
8154
  var StorageMigrationMediaMoveInputSchema = RelocateMediaInputSchema.extend({ leaseId: string().min(1) });
8112
8155
  /** The independently selectable logical storage classes — every class
8113
8156
  * `storage.listLocationDeclarations` reports, so an operator never meets a
@@ -8218,6 +8261,10 @@ var StorageMigrationMoveProgressSchema = object({
8218
8261
  /** The archive census — the **M** of "N of M" (D295). `null` = unknowable. */
8219
8262
  filesTotal: number().int().nonnegative().nullable(),
8220
8263
  bytesMoved: number().int().nonnegative(),
8264
+ /** Rows the mover corrected while moving them — see `RelocateJob`. Absent on
8265
+ * a lane that cannot reconcile. A migration that silently rewrote durable
8266
+ * rows would be the same failure as one that silently skipped them. */
8267
+ rowsReconciled: number().int().nonnegative().optional(),
8221
8268
  /** The MOVER's start, not the migration's: a drain restarted after an addon
8222
8269
  * crash gets a new mover, and a rate computed from the migration's start
8223
8270
  * would silently average in the time nothing was running. */
@@ -8027,6 +8027,21 @@ var RelocateJobSchema = object({
8027
8027
  bytesMoved: number().int(),
8028
8028
  /** Total files discovered up front; null while (or when) unknown. */
8029
8029
  filesTotal: number().int().nullable(),
8030
+ /**
8031
+ * Rows this run CORRECTED while moving them — a durable mutation the move
8032
+ * made that nobody asked for, so it is reported where the operator reads the
8033
+ * job rather than only in a log line.
8034
+ *
8035
+ * A footage segment records its byte count in its own NAME, and the durable
8036
+ * hour row derives its aggregates from those names. A file that does not
8037
+ * match its name therefore makes the ledger's sums — and with them quota and
8038
+ * pressure eviction — wrong by the difference, and only a rename can fix it.
8039
+ * On 2026-08-30 one such row also stalled a 110 749-file drain permanently.
8040
+ *
8041
+ * Absent on lanes where the question has no meaning: a media blob's size is
8042
+ * in its row, not in its name, so `MediaRelocateEngine` never reconciles one.
8043
+ */
8044
+ rowsReconciled: number().int().nonnegative().optional(),
8030
8045
  startedAt: number(),
8031
8046
  finishedAt: number().nullable(),
8032
8047
  error: string().nullable()
@@ -8095,14 +8110,42 @@ var RelocateMediaInputSchema = object({
8095
8110
  /** Omitted = `move`, the pre-existing behaviour. */
8096
8111
  mode: MediaRelocateModeSchema.optional()
8097
8112
  });
8098
- /** How many rows still carry NO `locationId` — the population a repoint would
8099
- * silently re-aim at a disk that does not hold their bytes. Zero is the only
8100
- * value that permits a non-blocking `eventMedia` cutover. */
8101
- var UnstampedEventMediaCountSchema = object({
8102
- media: number().int().nonnegative(),
8103
- retrainFrames: number().int().nonnegative(),
8104
- total: number().int().nonnegative()
8113
+ /**
8114
+ * The unstamped population of ONE collection — split, because the gate and the
8115
+ * operator ask two different questions and only one of them has to be cheap.
8116
+ *
8117
+ * `present` is the GATE: "is there at least one row that would be orphaned by a
8118
+ * repoint". It is a single indexed seek to the first matching row, so it stays
8119
+ * answerable on a saturated disk and answers in O(log n) precisely in the state
8120
+ * that matters — after a seal, when the population is empty.
8121
+ *
8122
+ * `rows` is the NUMBER, for the refusal message and the operator's sense of
8123
+ * scale. It is a second, indexed `COUNT(*)`, and `null` means **not
8124
+ * measurable** — never zero. `{ present: true, rows: null }` is a legitimate
8125
+ * and useful answer: "there are some, and this read could not say how many"
8126
+ * still refuses the cutover, which is the whole job.
8127
+ */
8128
+ var UnstampedRowsSchema = object({
8129
+ present: boolean(),
8130
+ rows: number().int().nonnegative().nullable()
8105
8131
  });
8132
+ /**
8133
+ * How many rows still carry NO `locationId` — the population a repoint would
8134
+ * silently re-aim at a disk that does not hold their bytes.
8135
+ *
8136
+ * **`null` = the count could not be taken**, and it is NOT permission to cut
8137
+ * over. The gate opens on a measured absence and on nothing else; an unread
8138
+ * collection and an empty one are different facts, and this repo has already
8139
+ * paid for conflating them (`RelocateResidueSchema`, D295).
8140
+ */
8141
+ var UnstampedEventMediaCountSchema = object({
8142
+ media: UnstampedRowsSchema,
8143
+ retrainFrames: UnstampedRowsSchema,
8144
+ /** True when EITHER collection holds one. The refusal reads this. */
8145
+ anyPresent: boolean(),
8146
+ /** Sum across both, or `null` when either lane could not be counted. */
8147
+ total: number().int().nonnegative().nullable()
8148
+ }).nullable();
8106
8149
  var StorageMigrationMediaMoveInputSchema = RelocateMediaInputSchema.extend({ leaseId: string().min(1) });
8107
8150
  /** The independently selectable logical storage classes — every class
8108
8151
  * `storage.listLocationDeclarations` reports, so an operator never meets a
@@ -8213,6 +8256,10 @@ var StorageMigrationMoveProgressSchema = object({
8213
8256
  /** The archive census — the **M** of "N of M" (D295). `null` = unknowable. */
8214
8257
  filesTotal: number().int().nonnegative().nullable(),
8215
8258
  bytesMoved: number().int().nonnegative(),
8259
+ /** Rows the mover corrected while moving them — see `RelocateJob`. Absent on
8260
+ * a lane that cannot reconcile. A migration that silently rewrote durable
8261
+ * rows would be the same failure as one that silently skipped them. */
8262
+ rowsReconciled: number().int().nonnegative().optional(),
8216
8263
  /** The MOVER's start, not the migration's: a drain restarted after an addon
8217
8264
  * crash gets a new mover, and a rate computed from the migration's start
8218
8265
  * would silently average in the time nothing was running. */
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@camstack/addon-mqtt-broker",
3
- "version": "1.2.45",
3
+ "version": "1.2.46",
4
4
  "description": "MQTT broker registry addon for CamStack — manages external broker entries + an optional embedded aedes broker. Consumers spin up their own `mqtt.js` clients via the `mqtt-broker` cap.",
5
5
  "keywords": [
6
6
  "camstack",