@cloudbitmaps/core 0.16.0 → 0.18.0

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.
@@ -17,6 +17,31 @@ var IntegrityError = class extends CloudRoaringError {
17
17
  };
18
18
  var NotFoundError = class extends CloudRoaringError {
19
19
  };
20
+ var LeaseExpiredError = class extends CloudRoaringError {
21
+ /** Epoch-ms the lease was taken until. */
22
+ until;
23
+ /** `'expired'` when the clock reached `until`, `'released'` after `release()`. */
24
+ reason;
25
+ constructor(message, until, reason) {
26
+ super(message);
27
+ this.until = until;
28
+ this.reason = reason;
29
+ }
30
+ };
31
+ var LeaseLimitError = class extends CloudRoaringError {
32
+ };
33
+ var StaleOperandError = class extends CloudRoaringError {
34
+ code = "stale-operand";
35
+ /** The operand's name in the call that found it stale. */
36
+ operand;
37
+ /** Why it is stale. */
38
+ reason;
39
+ constructor(message, operand, reason) {
40
+ super(message);
41
+ this.operand = operand;
42
+ this.reason = reason;
43
+ }
44
+ };
20
45
  var UnsupportedError = class extends CloudRoaringError {
21
46
  };
22
47
  var CapabilityError = class extends CloudRoaringError {
@@ -45,6 +70,15 @@ function isWriteConflictError(err) {
45
70
  function isTransientError(err) {
46
71
  return hasBrand(err, TRANSIENT_BRAND);
47
72
  }
73
+ function isLeaseExpiredError(err) {
74
+ return isCloudRoaringError(err) && err.name === "LeaseExpiredError";
75
+ }
76
+ function isStaleOperandError(err) {
77
+ return isCloudRoaringError(err) && err.name === "StaleOperandError";
78
+ }
79
+ function isLeaseLimitError(err) {
80
+ return isCloudRoaringError(err) && err.name === "LeaseLimitError";
81
+ }
48
82
  function isNotFoundError(err) {
49
83
  return isCloudRoaringError(err) && err.name === "NotFoundError";
50
84
  }
@@ -112,6 +146,183 @@ function decodeNameFromPath(encoded) {
112
146
  return decodePercent(encoded);
113
147
  }
114
148
 
149
+ // src/core/token.ts
150
+ var INCARNATION_TOKEN = /^([0-9a-f]{32})\.(0|[1-9]\d*)\.([0-9a-f]{16})$/;
151
+ function incarnationOf(token) {
152
+ return INCARNATION_TOKEN.exec(token)?.[1];
153
+ }
154
+ function sameIncarnation(a, b) {
155
+ const ia = incarnationOf(a.token);
156
+ const ib = incarnationOf(b.token);
157
+ if (ia !== void 0 || ib !== void 0) return ia === ib;
158
+ return a.createdAt === b.createdAt;
159
+ }
160
+
161
+ // src/core/leases.ts
162
+ var MAX_LEASE_MS = 14 * 864e5;
163
+ var LEASE_SKEW_MS = 6e4;
164
+ var MAX_LEASES_PER_SEGMENT = 64;
165
+ var MAX_STORED_LEASES = 256;
166
+ var LEASE_CAS_ATTEMPTS = MAX_LEASES_PER_SEGMENT + 8;
167
+ var UNANSWERED_RESENDS = 3;
168
+ var UNANSWERED_BASE_MS = 500;
169
+ var CONFLICT_BASE_MS = 25;
170
+ var CONFLICT_CAP_MS = 400;
171
+ function isLive(entry, now) {
172
+ return now < entry.until + LEASE_SKEW_MS && entry.until <= now + MAX_LEASE_MS + LEASE_SKEW_MS;
173
+ }
174
+ function heldGenerations(record, now) {
175
+ const out = /* @__PURE__ */ new Set();
176
+ for (const e of record?.leases ?? []) if (isLive(e, now)) out.add(e.generation);
177
+ return out;
178
+ }
179
+ function liveLeases(record, now) {
180
+ return (record?.leases ?? []).filter((e) => isLive(e, now));
181
+ }
182
+ var LEASE_ONLY_RETRIES = 2 * MAX_LEASES_PER_SEGMENT + 8;
183
+ var BOOKKEEPING = /* @__PURE__ */ new Set(["token", "updatedAt", "leases"]);
184
+ function stable(value) {
185
+ if (value === void 0) return "u";
186
+ if (value === null || typeof value !== "object") return JSON.stringify(value);
187
+ if (Array.isArray(value)) return `[${value.map(stable).join(",")}]`;
188
+ const o = value;
189
+ const keys = Object.keys(o).filter((k) => o[k] !== void 0).sort();
190
+ return `{${keys.map((k) => `${JSON.stringify(k)}:${stable(o[k])}`).join(",")}}`;
191
+ }
192
+ function onlyLeasesDiffer(held, now, alsoIgnore = []) {
193
+ if (!sameIncarnation(held, now)) return false;
194
+ const skip = /* @__PURE__ */ new Set([...BOOKKEEPING, ...alsoIgnore]);
195
+ const keys = /* @__PURE__ */ new Set([...Object.keys(held), ...Object.keys(now)]);
196
+ for (const k of keys) {
197
+ if (skip.has(k)) continue;
198
+ if (stable(held[k]) !== stable(now[k])) {
199
+ return false;
200
+ }
201
+ }
202
+ return true;
203
+ }
204
+ function leaseChurn(deps) {
205
+ let used = 0;
206
+ return {
207
+ async settle(held, now, reread, alsoIgnore) {
208
+ if (held === null || held === void 0 || now === null) return void 0;
209
+ if (used >= LEASE_ONLY_RETRIES || !onlyLeasesDiffer(held, now, alsoIgnore)) return void 0;
210
+ const bound = Math.min(CONFLICT_BASE_MS * 2 ** Math.min(used, 4), CONFLICT_CAP_MS);
211
+ used += 1;
212
+ const sleep = deps.clock?.sleep;
213
+ if (sleep !== void 0) {
214
+ await sleep.call(deps.clock, Math.floor((deps.rng?.next() ?? 1) * bound));
215
+ }
216
+ return { row: await reread() };
217
+ }
218
+ };
219
+ }
220
+ function listOf(entries) {
221
+ if (entries.length === 0) return void 0;
222
+ return [...entries].sort(
223
+ (a, b) => a.generation !== b.generation ? a.generation - b.generation : a.holder < b.holder ? -1 : a.holder > b.holder ? 1 : 0
224
+ );
225
+ }
226
+ var wait = (deps, bound) => deps.clock.sleep(Math.floor((deps.rng?.next() ?? 1) * bound));
227
+ var heldBy = (row, take) => (row?.leases ?? []).some(
228
+ (e) => e.holder === take.holder && e.generation === take.generation && e.until === take.until
229
+ );
230
+ async function takeLease(ref, deps, take) {
231
+ let row = take.row;
232
+ let held = true;
233
+ let resends = 0;
234
+ let unanswered;
235
+ for (let attempt = 0; attempt < LEASE_CAS_ATTEMPTS; attempt++) {
236
+ if (row === null) row = await deps.registry.get(ref);
237
+ if (row === null || row.status === "destroyed" || row.currentGen === null) {
238
+ throw new NotFoundError(`segment "${ref.segment}" has no generation to lease`);
239
+ }
240
+ if (take.generation > row.currentGen) {
241
+ throw new NotFoundError(
242
+ `segment "${ref.segment}" generation ${take.generation} cannot be leased: it is not a published generation`
243
+ );
244
+ }
245
+ if (take.current && row.currentGen !== take.generation) return "moved";
246
+ if (heldBy(row, take)) return { token: row.token, row };
247
+ const live = liveLeases(row, deps.clock.now()).filter((e) => e.holder !== take.holder);
248
+ if (live.length >= MAX_LEASES_PER_SEGMENT) {
249
+ throw new LeaseLimitError(
250
+ `segment "${ref.segment}" already has ${live.length} live leases, the most one segment records`
251
+ );
252
+ }
253
+ const leases = listOf([
254
+ ...live,
255
+ { holder: take.holder, generation: take.generation, until: take.until }
256
+ ]);
257
+ const against = row;
258
+ try {
259
+ const { token } = await deps.registry.compareAndSwap(
260
+ ref,
261
+ against.token,
262
+ { leases },
263
+ held ? { held: against } : void 0
264
+ );
265
+ return { token, row: against };
266
+ } catch (err) {
267
+ if (isWriteConflictError(err)) {
268
+ row = null;
269
+ held = false;
270
+ await wait(deps, Math.min(CONFLICT_BASE_MS * 2 ** attempt, CONFLICT_CAP_MS));
271
+ continue;
272
+ }
273
+ if (!isTransientError(err)) throw err;
274
+ const now = await deps.registry.get(ref);
275
+ if (heldBy(now, take)) return { token: now.token, row: against };
276
+ if (now !== null && now.token === against.token) {
277
+ if (resends >= UNANSWERED_RESENDS) throw err;
278
+ await wait(deps, UNANSWERED_BASE_MS * 2 ** resends);
279
+ resends += 1;
280
+ unanswered = err;
281
+ }
282
+ row = now;
283
+ held = false;
284
+ if (row === null)
285
+ throw new NotFoundError(`segment "${ref.segment}" has no generation to lease`);
286
+ }
287
+ }
288
+ if (unanswered !== void 0) throw unanswered;
289
+ throw new WriteConflictError(`lease: contention taking a lease on segment "${ref.segment}"`);
290
+ }
291
+ async function releaseLease(ref, deps, holder) {
292
+ let resends = 0;
293
+ let unanswered;
294
+ let row;
295
+ for (let attempt = 0; attempt < LEASE_CAS_ATTEMPTS; attempt++) {
296
+ if (row === void 0) row = await deps.registry.get(ref);
297
+ if (row === null || row.status === "destroyed") return;
298
+ if (!(row.leases ?? []).some((e) => e.holder === holder)) return;
299
+ const against = row;
300
+ const keep = liveLeases(against, deps.clock.now()).filter((e) => e.holder !== holder);
301
+ try {
302
+ await deps.registry.compareAndSwap(ref, against.token, { leases: listOf(keep) });
303
+ return;
304
+ } catch (err) {
305
+ if (isWriteConflictError(err)) {
306
+ row = void 0;
307
+ await wait(deps, Math.min(CONFLICT_BASE_MS * 2 ** attempt, CONFLICT_CAP_MS));
308
+ continue;
309
+ }
310
+ if (!isTransientError(err)) throw err;
311
+ const now = await deps.registry.get(ref);
312
+ if (now === null || !(now.leases ?? []).some((e) => e.holder === holder)) return;
313
+ if (now.token === against.token) {
314
+ if (resends >= UNANSWERED_RESENDS) throw err;
315
+ await wait(deps, UNANSWERED_BASE_MS * 2 ** resends);
316
+ resends += 1;
317
+ unanswered = err;
318
+ }
319
+ row = now;
320
+ }
321
+ }
322
+ if (unanswered !== void 0) throw unanswered;
323
+ throw new WriteConflictError(`lease: contention releasing a lease on segment "${ref.segment}"`);
324
+ }
325
+
115
326
  // src/core/validate.ts
116
327
  var CHUNK_KEY_MAX = 65535;
117
328
  var MAX_NAME_LENGTH = 256;
@@ -263,6 +474,27 @@ function namespacePathPart(namespace) {
263
474
  return namespace === void 0 ? DEFAULT_NAMESPACE : encodeNameForPath(namespace);
264
475
  }
265
476
 
477
+ // src/core/kept-generations.ts
478
+ var MAX_KEPT_GENERATIONS = 64;
479
+ var MAX_STORED_KEPT_GENERATIONS = 256;
480
+ function usableKeptGens(record) {
481
+ const list = record?.keptGens;
482
+ if (record === null || list === void 0 || record.currentGen === null) return void 0;
483
+ for (const g of list) if (g >= record.currentGen) return void 0;
484
+ return list;
485
+ }
486
+ function nextKept(prev, generation, keep) {
487
+ const none = { list: void 0, evict: [] };
488
+ if (keep === void 0 || keep > MAX_KEPT_GENERATIONS) return none;
489
+ if (generation === 0) return { list: [], evict: [] };
490
+ const previous = prev?.currentGen ?? null;
491
+ const known = usableKeptGens(prev);
492
+ if (previous === null || known === void 0) return none;
493
+ const all = [...known, previous];
494
+ const cut = Math.max(0, all.length - keep);
495
+ return { list: all.slice(cut), evict: all.slice(0, cut) };
496
+ }
497
+
266
498
  // src/core/metadata.ts
267
499
  var MAX_METADATA_BYTES = 1024;
268
500
  var MAX_METADATA_KEY_BYTES = 128;
@@ -341,21 +573,9 @@ function metadataFromBytes(bytes, fail) {
341
573
  return Object.freeze(parsed);
342
574
  }
343
575
 
344
- // src/core/token.ts
345
- var INCARNATION_TOKEN = /^([0-9a-f]{32})\.(0|[1-9]\d*)\.([0-9a-f]{16})$/;
346
- function incarnationOf(token) {
347
- return INCARNATION_TOKEN.exec(token)?.[1];
348
- }
349
- function sameIncarnation(a, b) {
350
- const ia = incarnationOf(a.token);
351
- const ib = incarnationOf(b.token);
352
- if (ia !== void 0 || ib !== void 0) return ia === ib;
353
- return a.createdAt === b.createdAt;
354
- }
355
-
356
576
  // src/drivers/_shared/registry.ts
357
577
  var STATUSES = ["active", "destroyed"];
358
- var RECORD_FIELDS = [
578
+ var BASE_FIELDS = [
359
579
  "namespace",
360
580
  "segment",
361
581
  "currentGen",
@@ -369,7 +589,13 @@ var RECORD_FIELDS = [
369
589
  "updatedAt",
370
590
  "token"
371
591
  ];
372
- var SCHEMA_1_RECORD_FIELDS = RECORD_FIELDS.filter((f) => f !== "summary");
592
+ var SCHEMA_3_FIELDS = ["keptGens", "leases"];
593
+ var RECORD_FIELDS = [...BASE_FIELDS, ...SCHEMA_3_FIELDS];
594
+ function fieldsOf(schemaVersion) {
595
+ if (schemaVersion >= 3) return RECORD_FIELDS;
596
+ const base = BASE_FIELDS;
597
+ return schemaVersion === 2 ? base : base.filter((f) => f !== "summary");
598
+ }
373
599
  var ENVELOPE_FIELDS = ["schemaVersion", "deleted", "record"];
374
600
  var MAX_GOVERNANCE_BYTES = 64 * 1024;
375
601
  var MAX_WRAPPED_DEKS = 8;
@@ -514,17 +740,103 @@ function validateSummaryKeys(summary, wrappedDeks) {
514
740
  );
515
741
  }
516
742
  }
743
+ function validateKeptGens(value, isStored, ctx) {
744
+ if (value === void 0) return void 0;
745
+ const fail = (msg) => {
746
+ const where = ctx === void 0 ? "" : `: ${ctx}`;
747
+ throw isStored ? new IntegrityError(`registry record keptGens: ${msg}${where}`) : new ValidationError(`keptGens: ${msg}`);
748
+ };
749
+ if (!Array.isArray(value)) fail("must be an array");
750
+ const list = value;
751
+ const max = isStored ? MAX_STORED_KEPT_GENERATIONS : MAX_KEPT_GENERATIONS;
752
+ if (list.length > max) fail(`has ${list.length} entries, cap ${max}`);
753
+ let last = -1;
754
+ for (const g of list) {
755
+ if (!Number.isSafeInteger(g) || g < 0) {
756
+ fail(`entries must be non-negative safe integers (got ${String(g)})`);
757
+ }
758
+ if (g <= last) fail("entries must be strictly ascending");
759
+ last = g;
760
+ }
761
+ return isStored ? list : Object.freeze([...list]);
762
+ }
763
+ var HOLDER = /^[0-9a-f]{16}$/;
764
+ var LEASE_ENTRY_KEYS = ["holder", "generation", "until"];
765
+ function validateLeases(value, isStored, ctx) {
766
+ if (value === void 0) return void 0;
767
+ const fail = (msg) => {
768
+ const where = ctx === void 0 ? "" : `: ${ctx}`;
769
+ throw isStored ? new IntegrityError(`registry record leases: ${msg}${where}`) : new ValidationError(`leases: ${msg}`);
770
+ };
771
+ if (!Array.isArray(value)) fail("must be an array");
772
+ const list = value;
773
+ const max = MAX_STORED_LEASES;
774
+ if (list.length > max) fail(`has ${list.length} entries, cap ${max}`);
775
+ const seen = /* @__PURE__ */ new Set();
776
+ const out = [];
777
+ for (const e of list) {
778
+ if (typeof e !== "object" || e === null || Array.isArray(e)) fail("an entry must be an object");
779
+ const entry = e;
780
+ const extra = Object.keys(entry).filter((k) => !LEASE_ENTRY_KEYS.includes(k));
781
+ if (extra.length > 0) fail(`an entry carries an undeclared field (${extra.join(", ")})`);
782
+ const { holder, generation, until } = entry;
783
+ if (typeof holder !== "string" || !HOLDER.test(holder)) {
784
+ fail("a holder must be 16 lowercase hex digits");
785
+ }
786
+ if (seen.has(holder)) fail("holders must be unique");
787
+ seen.add(holder);
788
+ for (const [name, n] of [
789
+ ["generation", generation],
790
+ ["until", until]
791
+ ]) {
792
+ if (!Number.isSafeInteger(n) || n < 0) {
793
+ fail(`${name} must be a non-negative safe integer (got ${String(n)})`);
794
+ }
795
+ }
796
+ out.push(
797
+ isStored ? entry : Object.freeze({
798
+ holder,
799
+ generation,
800
+ until
801
+ })
802
+ );
803
+ }
804
+ if (isStored) return out;
805
+ return out.length === 0 ? void 0 : Object.freeze(out);
806
+ }
807
+ function validateLeasesPointer(leases, currentGen) {
808
+ if (leases !== void 0 && leases.length > 0 && currentGen === null) {
809
+ throw new ValidationError("leases: a row with no pointer has no generation to lease");
810
+ }
811
+ }
812
+ function validateKeptGensBelow(keptGens, currentGen) {
813
+ if (keptGens === void 0) return;
814
+ if (currentGen === null) {
815
+ throw new ValidationError(
816
+ "keptGens: a row with no pointer has no generations below it to keep"
817
+ );
818
+ }
819
+ const top = keptGens[keptGens.length - 1];
820
+ if (top !== void 0 && top >= currentGen) {
821
+ throw new ValidationError(
822
+ `keptGens names generation ${top}, which is not below the row's pointer ${currentGen}`
823
+ );
824
+ }
825
+ }
517
826
  function validateNewRegistryRecord(rec) {
518
827
  validateGeneration(rec.currentGen);
519
828
  if (rec.status !== void 0) validateStatus(rec.status);
520
829
  validateWrappedDeks(rec.wrappedDeks, false);
521
830
  validateGovernance(rec.retention, "retention");
522
831
  validateGovernance(rec.residency, "residency");
523
- if (!("summary" in rec)) return rec;
832
+ const keptGens = validateKeptGens(rec.keptGens, false);
833
+ validateKeptGensBelow(keptGens, rec.currentGen);
834
+ const withKept = keptGens === void 0 ? rec : { ...rec, keptGens };
835
+ if (!("summary" in rec)) return withKept;
524
836
  const summary = validateSummary(rec.summary, false);
525
837
  validateSummaryNames(summary, rec.currentGen);
526
838
  validateSummaryKeys(summary, rec.wrappedDeks);
527
- return { ...rec, summary };
839
+ return { ...withKept, summary };
528
840
  }
529
841
  function validateRegistryPatch(patch) {
530
842
  validatePatchGeneration(patch);
@@ -532,10 +844,12 @@ function validateRegistryPatch(patch) {
532
844
  if ("wrappedDeks" in patch) validateWrappedDeks(patch.wrappedDeks, false);
533
845
  if ("retention" in patch) validateGovernance(patch.retention, "retention");
534
846
  if ("residency" in patch) validateGovernance(patch.residency, "residency");
535
- if (!("summary" in patch)) return patch;
536
- return { ...patch, summary: validateSummary(patch.summary, false) };
847
+ const withKept = patch.keptGens === void 0 ? patch : { ...patch, keptGens: validateKeptGens(patch.keptGens, false) };
848
+ const withLeases = "leases" in withKept ? { ...withKept, leases: validateLeases(withKept.leases, false) } : withKept;
849
+ if (!("summary" in patch)) return withLeases;
850
+ return { ...withLeases, summary: validateSummary(patch.summary, false) };
537
851
  }
538
- var REGISTRY_SCHEMA_VERSION = 2;
852
+ var REGISTRY_SCHEMA_VERSION = 3;
539
853
  var OLDEST_REGISTRY_SCHEMA_VERSION = 1;
540
854
  function assertRegistrySchemaVersion(raw, ctx) {
541
855
  if (raw === void 0) {
@@ -644,6 +958,9 @@ function recordFromNew(ref, rec, now, token) {
644
958
  retention: rec.retention,
645
959
  residency: rec.residency,
646
960
  summary: rec.summary,
961
+ keptGens: rec.keptGens,
962
+ // A new row has no holder: a lease is written only against a row that already exists.
963
+ leases: void 0,
647
964
  createdAt: now,
648
965
  updatedAt: now,
649
966
  token
@@ -659,7 +976,7 @@ function assertStoredRecordShape(r, ctx, schemaVersion = REGISTRY_SCHEMA_VERSION
659
976
  if (!STATUSES.includes(r.status)) {
660
977
  throw new IntegrityError(`registry record has an unknown status (${r.status}): ${ctx}`);
661
978
  }
662
- const declared = schemaVersion >= 2 ? RECORD_FIELDS : SCHEMA_1_RECORD_FIELDS;
979
+ const declared = fieldsOf(schemaVersion);
663
980
  const extra = Object.keys(r).filter((k) => !declared.includes(k));
664
981
  if (extra.length > 0) {
665
982
  throw new IntegrityError(
@@ -677,6 +994,8 @@ function assertStoredRecordShape(r, ctx, schemaVersion = REGISTRY_SCHEMA_VERSION
677
994
  }
678
995
  }
679
996
  validateSummary(r.summary, true, ctx);
997
+ validateKeptGens(r.keptGens, true, ctx);
998
+ validateLeases(r.leases, true, ctx);
680
999
  }
681
1000
  function applyRegistryPatch(prev, patch, now, token) {
682
1001
  const currentGen = "currentGen" in patch ? patch.currentGen ?? null : prev.currentGen;
@@ -690,6 +1009,24 @@ function applyRegistryPatch(prev, patch, now, token) {
690
1009
  const kept = currentGen === prev.currentGen ? prev.summary : void 0;
691
1010
  summary = kept !== void 0 && summaryAgreesWithKeys(kept, wrappedDeks) ? kept : void 0;
692
1011
  }
1012
+ let keptGens;
1013
+ if ("keptGens" in patch) {
1014
+ validateKeptGensBelow(patch.keptGens, currentGen);
1015
+ keptGens = patch.keptGens;
1016
+ } else {
1017
+ keptGens = currentGen === prev.currentGen ? prev.keptGens : void 0;
1018
+ }
1019
+ let leases;
1020
+ if ("leases" in patch) {
1021
+ leases = patch.leases;
1022
+ validateLeasesPointer(leases, currentGen);
1023
+ const most = Math.max(MAX_LEASES_PER_SEGMENT, prev.leases?.length ?? 0);
1024
+ if (leases !== void 0 && leases.length > most) {
1025
+ throw new ValidationError(`leases: has ${leases.length} entries, cap ${most}`);
1026
+ }
1027
+ } else {
1028
+ leases = prev.leases;
1029
+ }
693
1030
  return {
694
1031
  namespace: prev.namespace,
695
1032
  segment: prev.segment,
@@ -700,6 +1037,8 @@ function applyRegistryPatch(prev, patch, now, token) {
700
1037
  retention: "retention" in patch ? patch.retention : prev.retention,
701
1038
  residency: "residency" in patch ? patch.residency : prev.residency,
702
1039
  summary,
1040
+ keptGens,
1041
+ leases,
703
1042
  createdAt: prev.createdAt,
704
1043
  updatedAt: now,
705
1044
  token
@@ -730,6 +1069,9 @@ export {
730
1069
  WriteConflictError,
731
1070
  IntegrityError,
732
1071
  NotFoundError,
1072
+ LeaseExpiredError,
1073
+ LeaseLimitError,
1074
+ StaleOperandError,
733
1075
  UnsupportedError,
734
1076
  CapabilityError,
735
1077
  BudgetExceededError,
@@ -738,6 +1080,9 @@ export {
738
1080
  isCloudRoaringError,
739
1081
  isWriteConflictError,
740
1082
  isTransientError,
1083
+ isLeaseExpiredError,
1084
+ isStaleOperandError,
1085
+ isLeaseLimitError,
741
1086
  isNotFoundError,
742
1087
  isIntegrityError,
743
1088
  isValidationError,
@@ -745,6 +1090,20 @@ export {
745
1090
  decodeNameFromKey,
746
1091
  encodeNameForPath,
747
1092
  decodeNameFromPath,
1093
+ MAX_KEPT_GENERATIONS,
1094
+ usableKeptGens,
1095
+ nextKept,
1096
+ incarnationOf,
1097
+ sameIncarnation,
1098
+ MAX_LEASE_MS,
1099
+ LEASE_SKEW_MS,
1100
+ MAX_LEASES_PER_SEGMENT,
1101
+ isLive,
1102
+ heldGenerations,
1103
+ onlyLeasesDiffer,
1104
+ leaseChurn,
1105
+ takeLease,
1106
+ releaseLease,
748
1107
  MAX_NAME_LENGTH,
749
1108
  encodedNameLength,
750
1109
  validateSegmentRef,
@@ -764,8 +1123,6 @@ export {
764
1123
  metadataBytes,
765
1124
  copiedMetadata,
766
1125
  metadataFromBytes,
767
- incarnationOf,
768
- sameIncarnation,
769
1126
  validateNewRegistryRecord,
770
1127
  validateRegistryPatch,
771
1128
  serializeRegistryEnvelope,
@@ -782,4 +1139,4 @@ export {
782
1139
  namespaceKeyPart,
783
1140
  namespacePathPart
784
1141
  };
785
- //# sourceMappingURL=chunk-LFUNPMXZ.js.map
1142
+ //# sourceMappingURL=chunk-CCP4U32U.js.map