@cloudbitmaps/roaring 0.19.0 → 0.19.1

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/index.d.ts CHANGED
@@ -542,10 +542,9 @@ export declare class CloudRoaring {
542
542
  /**
543
543
  * Write `ids` as a **new generation of `dest`** and publish it — the shared body of the `*Into` verbs. An `*Into`
544
544
  * materialisation is a load, and publishes the same way (hard invariant 1): every load that finds a row fences its
545
- * publish on the row's token; a guarded load (the default, since the empty refusal needs the size of the current generation)
546
- * also fences on the pointer it judged (`expectFrom`), and one that found no row fences on that absence instead.
547
- * Only an unguarded load (`allowEmpty: true`, with neither `guard.minRetained` nor `guard.maxGrowth`) onto a segment with no row publishes bare
548
- * forward-only. The destination's previous generation stays readable until the publish lands (readers re-resolve
545
+ * publish on the row's token, and every load that finds none on that absence, guarded or not; a guarded load (the
546
+ * default, since the empty refusal needs the size of the current generation) also fences on the pointer it judged
547
+ * (`expectFrom`). The destination's previous generation stays readable until the publish lands (readers re-resolve
549
548
  * within `cache.genTtlMs`).
550
549
  *
551
550
  * This routes through `loadSegment` rather than writing the generation itself, and that is the whole point
@@ -572,9 +571,10 @@ export declare class CloudRoaring {
572
571
  * **A `WriteConflictError` does not by itself mean nothing was published**, and that is worth knowing
573
572
  * before you write the retry. `'superseded'` covers five different causes — the write-once PUT collided,
574
573
  * the pointer moved, a row appeared where the load found none, the row's token changed, the row was purged —
575
- * and only the first three are the "somebody beat us" the name suggests. A token can also change on a write
576
- * that is not a supersession at all, such as a `setRetention` on the destination. On top of that, the collection pass that runs AFTER a
577
- * successful publish can raise the same error. So: treat it as "re-read the destination and decide",
574
+ * and only the first two are always the "somebody beat us" the name suggests. A row can appear, and a token can
575
+ * change, on a write that is not a supersession at all: a `setRetention` on the destination creates its row when it
576
+ * has none, and rewrites it when it has one. On top of that, the collection pass that runs AFTER a successful
577
+ * publish can raise the same error. So: treat it as "re-read the destination and decide",
578
578
  * never as "the write did not happen".
579
579
  *
580
580
  * **And by default it collects nothing**, unlike `load()`. See the `keep` default below.
package/dist/index.js CHANGED
@@ -661,6 +661,11 @@ var SystemRng = class {
661
661
  };
662
662
  var DEFAULT_CACHE_MAX_CHUNKS = 1024;
663
663
  var DEFAULT_ADMIN_CONCURRENCY = 8;
664
+ function rowVersionOfLive(version) {
665
+ if (version === null) return null;
666
+ const cut = version.lastIndexOf("#");
667
+ return cut < 0 ? version : version.slice(0, cut);
668
+ }
664
669
  function validateConcurrency(concurrency) {
665
670
  if (concurrency !== void 0 && (!Number.isInteger(concurrency) || concurrency < 1)) {
666
671
  throw new ValidationError2(`concurrency must be a positive integer; got ${concurrency}`);
@@ -1176,10 +1181,9 @@ var CloudRoaring = class _CloudRoaring {
1176
1181
  /**
1177
1182
  * Write `ids` as a **new generation of `dest`** and publish it — the shared body of the `*Into` verbs. An `*Into`
1178
1183
  * materialisation is a load, and publishes the same way (hard invariant 1): every load that finds a row fences its
1179
- * publish on the row's token; a guarded load (the default, since the empty refusal needs the size of the current generation)
1180
- * also fences on the pointer it judged (`expectFrom`), and one that found no row fences on that absence instead.
1181
- * Only an unguarded load (`allowEmpty: true`, with neither `guard.minRetained` nor `guard.maxGrowth`) onto a segment with no row publishes bare
1182
- * forward-only. The destination's previous generation stays readable until the publish lands (readers re-resolve
1184
+ * publish on the row's token, and every load that finds none on that absence, guarded or not; a guarded load (the
1185
+ * default, since the empty refusal needs the size of the current generation) also fences on the pointer it judged
1186
+ * (`expectFrom`). The destination's previous generation stays readable until the publish lands (readers re-resolve
1183
1187
  * within `cache.genTtlMs`).
1184
1188
  *
1185
1189
  * This routes through `loadSegment` rather than writing the generation itself, and that is the whole point
@@ -1206,9 +1210,10 @@ var CloudRoaring = class _CloudRoaring {
1206
1210
  * **A `WriteConflictError` does not by itself mean nothing was published**, and that is worth knowing
1207
1211
  * before you write the retry. `'superseded'` covers five different causes — the write-once PUT collided,
1208
1212
  * the pointer moved, a row appeared where the load found none, the row's token changed, the row was purged —
1209
- * and only the first three are the "somebody beat us" the name suggests. A token can also change on a write
1210
- * that is not a supersession at all, such as a `setRetention` on the destination. On top of that, the collection pass that runs AFTER a
1211
- * successful publish can raise the same error. So: treat it as "re-read the destination and decide",
1213
+ * and only the first two are always the "somebody beat us" the name suggests. A row can appear, and a token can
1214
+ * change, on a write that is not a supersession at all: a `setRetention` on the destination creates its row when it
1215
+ * has none, and rewrites it when it has one. On top of that, the collection pass that runs AFTER a successful
1216
+ * publish can raise the same error. So: treat it as "re-read the destination and decide",
1212
1217
  * never as "the write did not happen".
1213
1218
  *
1214
1219
  * **And by default it collects nothing**, unlike `load()`. See the `keep` default below.
@@ -1240,7 +1245,7 @@ var CloudRoaring = class _CloudRoaring {
1240
1245
  if (reason === "superseded") {
1241
1246
  const wrote = result.size > 0 ? `generation ${result.generation} was written and is not current` : `nothing was written \u2014 another writer took generation ${result.generation} first`;
1242
1247
  throw new WriteConflictError(
1243
- `${op}: the destination "${dest.segment}" changed while this materialisation was in flight, so its result is not the destination's current generation: ${wrote}. The pointer may have moved, the row may have been rewritten (a retention policy does this), dropped or purged. Re-read the destination and re-run.`
1248
+ `${op}: the destination "${dest.segment}" changed while this materialisation was in flight, so its result is not the destination's current generation: ${wrote}. The pointer may have moved, the row may have been created or rewritten (a retention policy does either), dropped or purged. Re-read the destination and re-run.`
1244
1249
  );
1245
1250
  }
1246
1251
  return {
@@ -1602,7 +1607,7 @@ var CloudRoaring = class _CloudRoaring {
1602
1607
  if (this.crbmSource !== void 0) {
1603
1608
  const held = await this.crbmSource.currentVersion(ref);
1604
1609
  const listed = rec.currentGen === null ? null : `${rec.currentGen}:${String(rec.token)}`;
1605
- if (held !== listed) this.engine.invalidate(ref);
1610
+ if (rowVersionOfLive(held) !== listed) this.engine.invalidate(ref);
1606
1611
  }
1607
1612
  return await this.engine.has(ref, id) ? { segment: rec.segment, namespace: rec.namespace } : null;
1608
1613
  }