@cloudbitmaps/core 0.9.0 → 0.11.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.
Files changed (132) hide show
  1. package/NOTICE +4 -4
  2. package/README.md +33 -16
  3. package/dist/chunk-5OMC5U7U.js +508 -0
  4. package/dist/chunk-5OMC5U7U.js.map +7 -0
  5. package/dist/core/audit.d.ts +128 -0
  6. package/dist/core/bit-route.d.ts +21 -0
  7. package/dist/core/blob.d.ts +34 -0
  8. package/dist/core/budget.d.ts +68 -0
  9. package/dist/core/codec.d.ts +122 -0
  10. package/dist/core/concurrency.d.ts +15 -0
  11. package/dist/core/consistency.d.ts +73 -0
  12. package/dist/core/cooperative.d.ts +78 -0
  13. package/dist/core/cost.d.ts +254 -0
  14. package/dist/core/crbm/crc32c.d.ts +10 -0
  15. package/dist/core/crbm/format.d.ts +114 -0
  16. package/dist/core/crbm/reader.d.ts +86 -0
  17. package/dist/core/crbm/varint.d.ts +13 -0
  18. package/dist/core/crbm/writer.d.ts +39 -0
  19. package/dist/core/crbm-storage-source.d.ts +522 -0
  20. package/dist/core/crypto.d.ts +80 -0
  21. package/dist/core/determinism.d.ts +42 -0
  22. package/dist/core/discover.d.ts +77 -0
  23. package/dist/core/due-index.d.ts +53 -0
  24. package/dist/core/engine.d.ts +246 -0
  25. package/dist/core/erase-id.d.ts +176 -0
  26. package/dist/core/erasure.d.ts +185 -0
  27. package/dist/core/errors.d.ts +113 -0
  28. package/dist/core/generation-gc.d.ts +56 -0
  29. package/dist/core/keys.d.ts +23 -0
  30. package/dist/core/load.d.ts +121 -0
  31. package/dist/core/lru.d.ts +69 -0
  32. package/dist/core/metrics.d.ts +136 -0
  33. package/dist/core/name-codec.d.ts +69 -0
  34. package/dist/core/pinned-storage-source.d.ts +90 -0
  35. package/dist/core/ports.d.ts +423 -0
  36. package/dist/core/reader-defaults.d.ts +18 -0
  37. package/dist/core/registry-scan.d.ts +47 -0
  38. package/dist/core/retention-sweep.d.ts +198 -0
  39. package/dist/core/retention.d.ts +67 -0
  40. package/dist/core/retry.d.ts +69 -0
  41. package/dist/core/rollback.d.ts +75 -0
  42. package/dist/core/validate.d.ts +44 -0
  43. package/dist/driver-kit.d.ts +9 -0
  44. package/dist/driver-kit.js +275 -0
  45. package/dist/driver-kit.js.map +7 -0
  46. package/dist/drivers/_shared/keys.d.ts +26 -0
  47. package/dist/drivers/_shared/object-registry-keys.d.ts +28 -0
  48. package/dist/drivers/_shared/object-registry.d.ts +89 -0
  49. package/dist/drivers/_shared/registry.d.ts +66 -0
  50. package/dist/drivers/backends.d.ts +43 -0
  51. package/dist/drivers/crypto.d.ts +38 -0
  52. package/dist/drivers/localfs/fs-util.d.ts +21 -0
  53. package/dist/drivers/localfs/paths.d.ts +33 -0
  54. package/dist/drivers/localfs/registry.d.ts +28 -0
  55. package/dist/drivers/localfs/storage.d.ts +19 -0
  56. package/dist/drivers/memory.d.ts +49 -0
  57. package/dist/drivers/retry/retrying-chunk-source.d.ts +59 -0
  58. package/dist/export/index.d.ts +93 -0
  59. package/dist/index.d.ts +76 -2760
  60. package/dist/index.js +3527 -3133
  61. package/dist/index.js.map +7 -1
  62. package/dist/testing/fuzz-core.d.ts +14 -0
  63. package/package.json +19 -115
  64. package/dist/azure/index.cjs +0 -368
  65. package/dist/azure/index.cjs.map +0 -1
  66. package/dist/azure/index.d.cts +0 -48
  67. package/dist/azure/index.d.ts +0 -48
  68. package/dist/azure/index.js +0 -304
  69. package/dist/azure/index.js.map +0 -1
  70. package/dist/cassandra/index.cjs +0 -265
  71. package/dist/cassandra/index.cjs.map +0 -1
  72. package/dist/cassandra/index.d.cts +0 -52
  73. package/dist/cassandra/index.d.ts +0 -52
  74. package/dist/cassandra/index.js +0 -204
  75. package/dist/cassandra/index.js.map +0 -1
  76. package/dist/chunk-7LMLYSVJ.js +0 -43
  77. package/dist/chunk-7LMLYSVJ.js.map +0 -1
  78. package/dist/chunk-BD22WDAN.js +0 -230
  79. package/dist/chunk-BD22WDAN.js.map +0 -1
  80. package/dist/chunk-NUIDEEFZ.js +0 -91
  81. package/dist/chunk-NUIDEEFZ.js.map +0 -1
  82. package/dist/chunk-OZ6LAFV4.js +0 -6
  83. package/dist/chunk-OZ6LAFV4.js.map +0 -1
  84. package/dist/chunk-SNJVZ227.js +0 -35
  85. package/dist/chunk-SNJVZ227.js.map +0 -1
  86. package/dist/dynamodb/index.cjs +0 -767
  87. package/dist/dynamodb/index.cjs.map +0 -1
  88. package/dist/dynamodb/index.d.cts +0 -106
  89. package/dist/dynamodb/index.d.ts +0 -106
  90. package/dist/dynamodb/index.js +0 -469
  91. package/dist/dynamodb/index.js.map +0 -1
  92. package/dist/gcs/index.cjs +0 -343
  93. package/dist/gcs/index.cjs.map +0 -1
  94. package/dist/gcs/index.d.cts +0 -46
  95. package/dist/gcs/index.d.ts +0 -46
  96. package/dist/gcs/index.js +0 -279
  97. package/dist/gcs/index.js.map +0 -1
  98. package/dist/index.cjs +0 -4990
  99. package/dist/index.cjs.map +0 -1
  100. package/dist/index.d.cts +0 -2761
  101. package/dist/mongodb/index.cjs +0 -260
  102. package/dist/mongodb/index.cjs.map +0 -1
  103. package/dist/mongodb/index.d.cts +0 -45
  104. package/dist/mongodb/index.d.ts +0 -45
  105. package/dist/mongodb/index.js +0 -199
  106. package/dist/mongodb/index.js.map +0 -1
  107. package/dist/mysql/index.cjs +0 -281
  108. package/dist/mysql/index.cjs.map +0 -1
  109. package/dist/mysql/index.d.cts +0 -56
  110. package/dist/mysql/index.d.ts +0 -56
  111. package/dist/mysql/index.js +0 -211
  112. package/dist/mysql/index.js.map +0 -1
  113. package/dist/ports-CvcvJWf6.d.cts +0 -395
  114. package/dist/ports-CvcvJWf6.d.ts +0 -395
  115. package/dist/postgres/index.cjs +0 -273
  116. package/dist/postgres/index.cjs.map +0 -1
  117. package/dist/postgres/index.d.cts +0 -54
  118. package/dist/postgres/index.d.ts +0 -54
  119. package/dist/postgres/index.js +0 -203
  120. package/dist/postgres/index.js.map +0 -1
  121. package/dist/redis/index.cjs +0 -257
  122. package/dist/redis/index.cjs.map +0 -1
  123. package/dist/redis/index.d.cts +0 -42
  124. package/dist/redis/index.d.ts +0 -42
  125. package/dist/redis/index.js +0 -197
  126. package/dist/redis/index.js.map +0 -1
  127. package/dist/s3/index.cjs +0 -918
  128. package/dist/s3/index.cjs.map +0 -1
  129. package/dist/s3/index.d.cts +0 -112
  130. package/dist/s3/index.d.ts +0 -112
  131. package/dist/s3/index.js +0 -555
  132. package/dist/s3/index.js.map +0 -1
@@ -0,0 +1,21 @@
1
+ /** True when `err` is a Node system error with the given `code` (e.g. `'ENOENT'`, `'EEXIST'`). */
2
+ export declare const isCode: (err: unknown, code: string) => boolean;
3
+ export declare const isFsTransient: (err: unknown) => boolean;
4
+ /**
5
+ * Reclassify a transient filesystem fault as a retryable {@link TransientError}, so the store's read retry can
6
+ * ride it out and a write's caller can tell it from a deterministic failure; everything else — including the
7
+ * driver's own typed errors — propagates unchanged.
8
+ */
9
+ export declare const mapFsError: (err: unknown) => unknown;
10
+ /**
11
+ * `O_NOFOLLOW` where the platform supports it (absent on Windows → 0). OR it into an `open` flag set so a
12
+ * symlink **at the final path component** is refused rather than followed outside the storage root.
13
+ * Containment of symlinked *directory* components assumes the root itself is not attacker-writable.
14
+ */
15
+ export declare const O_NOFOLLOW: number;
16
+ /**
17
+ * Best-effort parent-directory fsync, so a just-published `rename`/`link` survives a crash. Without it the
18
+ * directory entry can still be in the page cache when power goes: the generation's bytes are durable and
19
+ * the name pointing at them is not, which is the one way a published generation can come back missing.
20
+ */
21
+ export declare function fsyncDir(dir: string): Promise<void>;
@@ -0,0 +1,33 @@
1
+ import type { GenKey, SegmentRef } from '../../core/ports.js';
2
+ /** Directory holding all of a namespace's segment objects. */
3
+ export declare function segmentsDir(root: string, ref: SegmentRef): string;
4
+ /** Absolute path of one `.crbm` generation object. */
5
+ export declare function storageObjectPath(root: string, key: GenKey): string;
6
+ /** Filename pattern for a segment's generations: `<segment>.<gen>.crbm`. */
7
+ export declare function storageObjectFilename(segment: string, generation: number): string;
8
+ /** Parse a generation number out of a `<segment>.<gen>.crbm` filename, or `null` if it doesn't match. */
9
+ export declare function parseGeneration(segment: string, filename: string): number | null;
10
+ /** Directory holding a namespace's registry rows (one file per segment). */
11
+ export declare function registryDir(root: string, namespace: string | undefined): string;
12
+ /** Absolute path of one segment's registry row file: `<ns>/registry/<segment>.reg`. */
13
+ export declare function registryRowPath(root: string, ref: SegmentRef): string;
14
+ /**
15
+ * Parse a segment name out of a `<segment>.reg` filename, or `null` if it doesn't match — including any
16
+ * file whose stem isn't a valid segment name. A strict parser means a stray or planted `.reg` file makes
17
+ * `list()` *skip* it, never abort the whole enumeration on a boundary throw.
18
+ */
19
+ export declare function parseRegistryRow(filename: string): string | null;
20
+ /**
21
+ * Parse a namespace out of a directory name under the storage root, or `null` if it was not written by us.
22
+ *
23
+ * The inverse of the `namespacePathPart(ns)` that {@link segmentsDir} and {@link registryDir}
24
+ * write. A fleet-wide scan enumerates these directories, so getting it wrong does not fail one segment — it
25
+ * aborts the whole enumeration, taking the consistency check, the retention sweep and subject erasure with it.
26
+ *
27
+ * Like {@link parseRegistryRow} this requires the encoding to **round-trip**, so a planted literal `tenant:acme`
28
+ * directory sitting next to the driver's own `tenant%3Aacme` is skipped rather than reported as a namespace
29
+ * whose rows then resolve to the other directory. `_default` maps back to "no namespace".
30
+ */
31
+ export declare function parseNamespaceDir(entry: string): {
32
+ namespace: string | undefined;
33
+ } | null;
@@ -0,0 +1,28 @@
1
+ import type { IRegistryDriver, NewRegistryRecord, RegCaps, RegistryPatch, RegistryRecord, SegmentRef, Token } from '../../core/ports.js';
2
+ /** Entries in the process-wide row-lock map; the map is empty whenever no registry operation is in flight. */
3
+ export declare function localFsRowLockCount(): number;
4
+ export interface LocalFsRegistryDriverOptions {
5
+ /** Injected clock for `createdAt`/`updatedAt`; defaults to `Date.now`. */
6
+ readonly now?: () => number;
7
+ }
8
+ export declare class LocalFsRegistryDriver implements IRegistryDriver {
9
+ private readonly root;
10
+ private readonly now;
11
+ constructor(root: string, options?: LocalFsRegistryDriverOptions);
12
+ capabilities(): RegCaps;
13
+ get(ref: SegmentRef): Promise<RegistryRecord | null>;
14
+ create(ref: SegmentRef, record: NewRegistryRecord): Promise<{
15
+ token: Token;
16
+ }>;
17
+ compareAndSwap(ref: SegmentRef, expected: Token, patch: RegistryPatch): Promise<{
18
+ token: Token;
19
+ }>;
20
+ list(namespace?: string): AsyncIterable<RegistryRecord>;
21
+ delete(ref: SegmentRef, expected?: Token): Promise<void>;
22
+ /** Namespaces to scan: just the one requested, or every namespace dir under the root. */
23
+ private namespaceDirs;
24
+ private readRow;
25
+ private writeRow;
26
+ /** Serialize callbacks for a row so read-modify-write is atomic across every instance in the process. */
27
+ private withRowLock;
28
+ }
@@ -0,0 +1,19 @@
1
+ import type { BlobSink } from '../../core/blob.js';
2
+ import type { StorageCaps, GenKey, IStorageDriver, SegmentRef } from '../../core/ports.js';
3
+ export declare class LocalFsStorageDriver implements IStorageDriver {
4
+ private readonly root;
5
+ constructor(root: string);
6
+ capabilities(): StorageCaps;
7
+ putImmutable(key: GenKey, write: (sink: BlobSink) => Promise<void>): Promise<{
8
+ size: number;
9
+ sha256: string;
10
+ }>;
11
+ getRange(key: GenKey, offset: number, length: number): Promise<Uint8Array>;
12
+ getTail(key: GenKey, maxBytes: number): Promise<{
13
+ bytes: Uint8Array;
14
+ size: number;
15
+ }>;
16
+ delete(key: GenKey): Promise<void>;
17
+ list(ref: SegmentRef): AsyncIterable<GenKey>;
18
+ private openRead;
19
+ }
@@ -0,0 +1,49 @@
1
+ import type { BlobSink } from '../core/blob.js';
2
+ import type { StorageCaps, GenKey, IStorageDriver, IRegistryDriver, NewRegistryRecord, RegCaps, RegistryPatch, RegistryRecord, SegmentRef, Token } from '../core/ports.js';
3
+ export interface MemoryRegistryDriverOptions {
4
+ /** Injected clock for `createdAt`/`updatedAt`; defaults to `Date.now` (drivers may use ambient time). */
5
+ readonly now?: () => number;
6
+ }
7
+ /**
8
+ * In-memory {@link IRegistryDriver} — one record per segment under OCC. The token is a single global,
9
+ * monotonic, never-reused counter (so a record recreated after `delete` always gets a strictly-greater
10
+ * token → ABA-safe even though `delete` removes the row physically).
11
+ */
12
+ export declare class MemoryRegistryDriver implements IRegistryDriver {
13
+ private readonly rows;
14
+ private readonly now;
15
+ private seq;
16
+ constructor(options?: MemoryRegistryDriverOptions);
17
+ private nextToken;
18
+ capabilities(): RegCaps;
19
+ get(ref: SegmentRef): Promise<RegistryRecord | null>;
20
+ create(ref: SegmentRef, record: NewRegistryRecord): Promise<{
21
+ token: Token;
22
+ }>;
23
+ compareAndSwap(ref: SegmentRef, expected: Token, patch: RegistryPatch): Promise<{
24
+ token: Token;
25
+ }>;
26
+ list(namespace?: string): AsyncIterable<RegistryRecord>;
27
+ delete(ref: SegmentRef, expected?: Token): Promise<void>;
28
+ }
29
+ /**
30
+ * In-memory {@link IStorageDriver} — write-once immutable generation objects as opaque bytes. A "dumb byte
31
+ * mover" (understands neither roaring nor `.crbm`), so it's a faithful storage backend for tests and a zero-setup
32
+ * local storage tier. Mirrors the LocalFs/S3 contract (write-once, range/tail reads).
33
+ */
34
+ export declare class MemoryStorageDriver implements IStorageDriver {
35
+ private readonly objects;
36
+ capabilities(): StorageCaps;
37
+ putImmutable(key: GenKey, write: (sink: BlobSink) => Promise<void>): Promise<{
38
+ size: number;
39
+ sha256: string;
40
+ }>;
41
+ getRange(key: GenKey, offset: number, length: number): Promise<Uint8Array>;
42
+ getTail(key: GenKey, maxBytes: number): Promise<{
43
+ bytes: Uint8Array;
44
+ size: number;
45
+ }>;
46
+ delete(key: GenKey): Promise<void>;
47
+ list(ref: SegmentRef): AsyncIterable<GenKey>;
48
+ private require;
49
+ }
@@ -0,0 +1,59 @@
1
+ /**
2
+ * The store's read retry.
3
+ *
4
+ * {@link RetryingStorageChunkSource} wraps a {@link StorageChunkSource} so every read it serves retries
5
+ * **transient** faults with bounded, jittered backoff, through the one shared `core/retry` primitive, so every
6
+ * backend (S3, GCS, Azure Blob, LocalFS, …) inherits the same policy instead of each rolling its own. `CloudRoaring`
7
+ * wraps the source it reads segment data through in one — a `StorageChunkSource` passed as `storage` included, so
8
+ * wrapping that one first multiplies each read's attempts — and a pinned handle's source too, unless it is built
9
+ * with `retry: false`.
10
+ * Pure composition over the port (no SDK, no I/O of its own); the driver under the source is responsible for
11
+ * *classifying* its transient faults (raising {@link TransientError}), and this wrapper decides *whether and when*
12
+ * to retry.
13
+ *
14
+ * **Reads only, on purpose.** A read changes nothing, so running it again is safe. A write is not: a conditional put
15
+ * or compare-and-swap that lands and then loses its response would, replayed, find its own write already there and
16
+ * report it as a conflict. So nothing here wraps a write, and the store's writes and admin calls report a transient
17
+ * fault to their caller, who re-runs the call or checks what landed.
18
+ *
19
+ * What is **not** retried: every deterministic error (`ValidationError`/`IntegrityError`/`NotFoundError`/…).
20
+ * Default classifier: {@link isTransientError}.
21
+ */
22
+ import type { Clock, Rng } from '../../core/determinism.js';
23
+ import type { RetryPolicy } from '../../core/retry.js';
24
+ import type { ChunkRef, StorageChunkSource, SegmentRef, SegmentSize } from '../../core/ports.js';
25
+ export interface RetryingOptions {
26
+ readonly clock: Clock;
27
+ readonly rng: Rng;
28
+ /** Defaults to {@link DEFAULT_RETRY_POLICY}. */
29
+ readonly policy?: RetryPolicy;
30
+ /** Override which errors are retryable. Default: {@link isTransientError} (any `TransientError`). */
31
+ readonly isRetryable?: (err: unknown) => boolean;
32
+ /** Observability hook fired before each backoff wait. */
33
+ readonly onRetry?: (info: {
34
+ attempt: number;
35
+ delayMs: number;
36
+ err: unknown;
37
+ }) => void;
38
+ }
39
+ /** Wrap a storage chunk source so its reads retry transient faults. */
40
+ export declare class RetryingStorageChunkSource implements StorageChunkSource {
41
+ private readonly inner;
42
+ private readonly policy;
43
+ private readonly deps;
44
+ /** Present only when the inner source supports it — so capability detection stays honest. */
45
+ readonly sizeOf?: (ref: SegmentRef) => Promise<SegmentSize | null>;
46
+ readonly cardinalities?: (ref: SegmentRef) => Promise<ReadonlyMap<number, number> | null>;
47
+ readonly currentGeneration?: (ref: SegmentRef) => Promise<number | null>;
48
+ readonly invalidate?: (ref: SegmentRef) => void;
49
+ readonly exists?: (ref: SegmentRef) => Promise<boolean>;
50
+ readonly currentVersion?: (ref: SegmentRef) => Promise<string | null>;
51
+ /**
52
+ * Forwarded, not retried: a property, with no request behind it. Without it the grounded cost report priced a
53
+ * retrying store's refresh at the default TTL whatever the store was configured with.
54
+ */
55
+ get pointerRefreshMs(): number | undefined;
56
+ constructor(inner: StorageChunkSource, opts: RetryingOptions);
57
+ getChunk(ref: ChunkRef): Promise<Uint8Array | null>;
58
+ listChunkKeys(ref: SegmentRef): Promise<number[]>;
59
+ }
@@ -0,0 +1,93 @@
1
+ import type { CodecInterface } from '../core/codec.js';
2
+ import type { IRegistryDriver, SegmentRef } from '../core/ports.js';
3
+ /** Output format for {@link runExport} / `CloudRoaring.exportSegments`. */
4
+ export type ExportFormat = 'roaring' | 'ndjson';
5
+ /** A writer for one segment's output — inject a filesystem file, an S3 upload, stdout, or a test buffer. */
6
+ export interface ExportWriter {
7
+ /** Append bytes (called one or more times; for `ndjson`, batched line chunks; for `roaring`, once). */
8
+ write(bytes: Uint8Array): Promise<void> | void;
9
+ /** **Commit** the output — called once, only on success (all bytes written). Finalize/flush/rename here. */
10
+ close(): Promise<void> | void;
11
+ /**
12
+ * **Discard** a partial output — called instead of `close()` if a fault occurs mid-segment, so a truncated file
13
+ * never masquerades as complete (e.g. delete the temp file). Optional; sinks with nothing to undo can omit it.
14
+ */
15
+ abort?(): Promise<void> | void;
16
+ }
17
+ /** A destination the export writes each segment to. `ext` is `.roaring` or `.ndjson`. */
18
+ export interface ExportSink {
19
+ open(ref: SegmentRef, ext: string): Promise<ExportWriter> | ExportWriter;
20
+ }
21
+ export interface ExportOptions {
22
+ /** Output format; defaults to `'roaring'`. */
23
+ readonly format?: ExportFormat;
24
+ /**
25
+ * Bitmap codec that builds the exported bitmap for the `'roaring'` format. Optional in the type; a **flavor**'s
26
+ * store passes its own (see `requireCodec`). Not needed for `'ndjson'`, which streams plain ids.
27
+ */
28
+ readonly codec?: CodecInterface;
29
+ /** Scope the export to one namespace; omit to export every registered segment. */
30
+ readonly namespace?: string;
31
+ /** `ndjson` flush threshold in ~bytes (ids are ASCII, so ≈ chars); defaults to 64 KiB. */
32
+ readonly ndjsonBatchBytes?: number;
33
+ }
34
+ /** Per-segment result recorded in the {@link ExportManifest}. */
35
+ export interface ExportedSegment {
36
+ readonly segment: string;
37
+ readonly namespace?: string;
38
+ /** Ids written (the segment's effective cardinality at export time). */
39
+ readonly count: number;
40
+ /** Bytes written to the sink for this segment. */
41
+ readonly bytes: number;
42
+ }
43
+ /**
44
+ * A segment that could **not** be exported — recorded rather than aborting the whole run (fault isolation), so a
45
+ * single corrupt/undecryptable segment never blocks the rest of the dump.
46
+ */
47
+ export interface ExportFailure {
48
+ readonly segment: string;
49
+ readonly namespace?: string;
50
+ /** Why it failed (an error message) — e.g. a corrupt storage object, or an encrypted segment with no keystore. */
51
+ readonly error: string;
52
+ }
53
+ /** What {@link runExport} produced — a self-describing summary the CLI persists as `manifest.json`. */
54
+ export interface ExportManifest {
55
+ /** Schema version of this manifest shape (currently `1`) — insurance for evolving the format post-1.0. */
56
+ readonly version: number;
57
+ readonly format: ExportFormat;
58
+ readonly totalSegments: number;
59
+ readonly totalIds: number;
60
+ readonly segments: readonly ExportedSegment[];
61
+ /**
62
+ * Segments that could not be read (empty when everything succeeded). Its presence in the manifest is the point:
63
+ * "a manifest exists" ⇒ the run finished, **not** that every segment succeeded — always check this list.
64
+ */
65
+ readonly failed: readonly ExportFailure[];
66
+ }
67
+ /** The minimal read surface the export needs from a store — a `CloudRoaring` satisfies this structurally. */
68
+ export interface SegmentReader {
69
+ segment(name: string, options?: {
70
+ namespace?: string;
71
+ }): {
72
+ iterate(): AsyncIterable<number>;
73
+ };
74
+ }
75
+ /**
76
+ * Export every registered segment's current generation through `sink`. Enumerates via `registry`, reads via
77
+ * `reader` (the store). Returns a manifest. `CloudRoaring.exportSegments` is the
78
+ * public entry — it calls this with its own store + registry (so enumeration and the read path provably share one
79
+ * registry).
80
+ *
81
+ * **Fault isolation:** a per-segment read/write fault aborts that segment's partial (so a truncated file never
82
+ * looks complete), records it in `failed`, and the run continues — one bad segment never blocks the rest. A
83
+ * `close()` fault is likewise recorded (never triggering `abort()` — they're mutually exclusive).
84
+ *
85
+ * Re-running overwrites the segments it re-exports but does **not** prune files for segments that have since
86
+ * disappeared — export to a fresh directory for a clean dump. For a *current* image, run against a
87
+ * freshly-constructed store: a store's storage source re-resolves each segment's generation on a short TTL, or, with
88
+ * no registry, with `cache.genTtlMs: 0`, or built without a clock, only when an eviction, a sweep or an invalidation
89
+ * makes it, so a long-lived store may export a view one load behind, or more. Each segment is read live, not pinned:
90
+ * a publish while a long segment exports can re-resolve it part-way, and its file then holds chunks of two
91
+ * generations, each whole and verified. For one generation per file, export from a quiet window.
92
+ */
93
+ export declare function runExport(reader: SegmentReader, registry: IRegistryDriver, sink: ExportSink, options?: ExportOptions): Promise<ExportManifest>;