@cloudbitmaps/core 0.4.1 → 0.5.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.
- package/dist/index.cjs +20 -6
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +19 -7
- package/dist/index.d.ts +19 -7
- package/dist/index.js +20 -6
- package/dist/index.js.map +1 -1
- package/dist/mysql/index.cjs.map +1 -1
- package/dist/mysql/index.js.map +1 -1
- package/dist/postgres/index.cjs.map +1 -1
- package/dist/postgres/index.js.map +1 -1
- package/package.json +1 -1
package/dist/index.d.cts
CHANGED
|
@@ -7,7 +7,7 @@ export { o as BufferReader, p as BufferSink, q as GovernanceMeta, r as NO_ROW, s
|
|
|
7
7
|
* `core/` is **codec-agnostic**: `SegmentEngine`, compaction, and the `.crbm` read/write helpers only ever
|
|
8
8
|
* construct and combine bitmaps through the {@link CodecInterface} factory + the {@link CodecBitmap} value type
|
|
9
9
|
* defined here — never a concrete implementation. The flagship codec is roaring (`roaringCodec`, today in
|
|
10
|
-
* `core/bitmap.ts`; it moves to `@cloudbitmaps/roaring` when the package split lands); `@cloudbitmaps/
|
|
10
|
+
* `core/bitmap.ts`; it moves to `@cloudbitmaps/roaring` when the package split lands); `@cloudbitmaps/bitset`
|
|
11
11
|
* (plain bitset) and `@cloudbitmaps/soaring` plug in behind the same seam with zero engine or driver changes.
|
|
12
12
|
*
|
|
13
13
|
* **Homogeneity contract:** a single store uses a single codec, so every {@link CodecBitmap} an operation sees
|
|
@@ -18,7 +18,7 @@ export { o as BufferReader, p as BufferSink, q as GovernanceMeta, r as NO_ROW, s
|
|
|
18
18
|
* mints the cache per store, so this cannot arise in normal use.)
|
|
19
19
|
*
|
|
20
20
|
* **Interface surface = exactly what the engine needs**, kept general enough for the known fast-follow codecs
|
|
21
|
-
* (positional/rank-select access + raw-bitset interop that `@cloudbitmaps/
|
|
21
|
+
* (positional/rank-select access + raw-bitset interop that `@cloudbitmaps/bitset` will add live on that
|
|
22
22
|
* package's own extended value type, not here — the engine never calls them). The one codec-linked concern
|
|
23
23
|
* this seam intentionally leaves in the format layer is the `.crbm` **serialization id** (`ROARING_PORTABLE_ID`
|
|
24
24
|
* in `crbm/format.ts`): it is stamped in the footer and validated on read, and generalizes to a per-codec id
|
|
@@ -2131,11 +2131,23 @@ declare function runConsistencyCheck(deps: {
|
|
|
2131
2131
|
* I/O of their own); the wrapped driver is responsible for *classifying* its transient faults (raising
|
|
2132
2132
|
* {@link TransientError}); these decorators decide *whether and when* to retry.
|
|
2133
2133
|
*
|
|
2134
|
-
* **Streaming methods
|
|
2135
|
-
*
|
|
2136
|
-
*
|
|
2137
|
-
*
|
|
2138
|
-
*
|
|
2134
|
+
* **Streaming methods split into two shapes**, and the difference is deliberate — a partially-consumed async
|
|
2135
|
+
* iterator cannot be resumed mid-stream (it would re-yield earlier items), so each method picks between
|
|
2136
|
+
* buffering and bounded memory:
|
|
2137
|
+
*
|
|
2138
|
+
* · `RetryingColdDriver.list` / `RetryingRegistryDriver.list` **buffer**, inside `withRetry`, so the whole
|
|
2139
|
+
* enumeration is retried by re-running it from the start. Both are discovery scans over a generation or
|
|
2140
|
+
* namespace listing, where the result set is small and whole-scan retry is worth the memory.
|
|
2141
|
+
* · `RetryingWarmDriver.listChunks` does **not** buffer. It retries only until the first row arrives and
|
|
2142
|
+
* then streams live, because buffering it defeated the engine's resident-memory bound outright — see the
|
|
2143
|
+
* measured account on the method itself. A mid-stream fault therefore propagates rather than being
|
|
2144
|
+
* retried, which is the documented trade there.
|
|
2145
|
+
*
|
|
2146
|
+
* Point methods are retried in place, with nothing to buffer.
|
|
2147
|
+
*
|
|
2148
|
+
* (This paragraph previously said streaming methods buffer, full stop. That described `listChunks` as it was
|
|
2149
|
+
* before the bound was fixed, and the stale wording had also been copied into the Postgres and MySQL warm
|
|
2150
|
+
* drivers — so three comments promised a mid-stream resilience that the hot read path does not have.)
|
|
2139
2151
|
*
|
|
2140
2152
|
* What is **not** retried here: {@link WriteConflictError} (OCC — the engine's read-modify-write loop owns
|
|
2141
2153
|
* that; a blind replay would re-apply against a stale token), and every deterministic error
|
package/dist/index.d.ts
CHANGED
|
@@ -7,7 +7,7 @@ export { o as BufferReader, p as BufferSink, q as GovernanceMeta, r as NO_ROW, s
|
|
|
7
7
|
* `core/` is **codec-agnostic**: `SegmentEngine`, compaction, and the `.crbm` read/write helpers only ever
|
|
8
8
|
* construct and combine bitmaps through the {@link CodecInterface} factory + the {@link CodecBitmap} value type
|
|
9
9
|
* defined here — never a concrete implementation. The flagship codec is roaring (`roaringCodec`, today in
|
|
10
|
-
* `core/bitmap.ts`; it moves to `@cloudbitmaps/roaring` when the package split lands); `@cloudbitmaps/
|
|
10
|
+
* `core/bitmap.ts`; it moves to `@cloudbitmaps/roaring` when the package split lands); `@cloudbitmaps/bitset`
|
|
11
11
|
* (plain bitset) and `@cloudbitmaps/soaring` plug in behind the same seam with zero engine or driver changes.
|
|
12
12
|
*
|
|
13
13
|
* **Homogeneity contract:** a single store uses a single codec, so every {@link CodecBitmap} an operation sees
|
|
@@ -18,7 +18,7 @@ export { o as BufferReader, p as BufferSink, q as GovernanceMeta, r as NO_ROW, s
|
|
|
18
18
|
* mints the cache per store, so this cannot arise in normal use.)
|
|
19
19
|
*
|
|
20
20
|
* **Interface surface = exactly what the engine needs**, kept general enough for the known fast-follow codecs
|
|
21
|
-
* (positional/rank-select access + raw-bitset interop that `@cloudbitmaps/
|
|
21
|
+
* (positional/rank-select access + raw-bitset interop that `@cloudbitmaps/bitset` will add live on that
|
|
22
22
|
* package's own extended value type, not here — the engine never calls them). The one codec-linked concern
|
|
23
23
|
* this seam intentionally leaves in the format layer is the `.crbm` **serialization id** (`ROARING_PORTABLE_ID`
|
|
24
24
|
* in `crbm/format.ts`): it is stamped in the footer and validated on read, and generalizes to a per-codec id
|
|
@@ -2131,11 +2131,23 @@ declare function runConsistencyCheck(deps: {
|
|
|
2131
2131
|
* I/O of their own); the wrapped driver is responsible for *classifying* its transient faults (raising
|
|
2132
2132
|
* {@link TransientError}); these decorators decide *whether and when* to retry.
|
|
2133
2133
|
*
|
|
2134
|
-
* **Streaming methods
|
|
2135
|
-
*
|
|
2136
|
-
*
|
|
2137
|
-
*
|
|
2138
|
-
*
|
|
2134
|
+
* **Streaming methods split into two shapes**, and the difference is deliberate — a partially-consumed async
|
|
2135
|
+
* iterator cannot be resumed mid-stream (it would re-yield earlier items), so each method picks between
|
|
2136
|
+
* buffering and bounded memory:
|
|
2137
|
+
*
|
|
2138
|
+
* · `RetryingColdDriver.list` / `RetryingRegistryDriver.list` **buffer**, inside `withRetry`, so the whole
|
|
2139
|
+
* enumeration is retried by re-running it from the start. Both are discovery scans over a generation or
|
|
2140
|
+
* namespace listing, where the result set is small and whole-scan retry is worth the memory.
|
|
2141
|
+
* · `RetryingWarmDriver.listChunks` does **not** buffer. It retries only until the first row arrives and
|
|
2142
|
+
* then streams live, because buffering it defeated the engine's resident-memory bound outright — see the
|
|
2143
|
+
* measured account on the method itself. A mid-stream fault therefore propagates rather than being
|
|
2144
|
+
* retried, which is the documented trade there.
|
|
2145
|
+
*
|
|
2146
|
+
* Point methods are retried in place, with nothing to buffer.
|
|
2147
|
+
*
|
|
2148
|
+
* (This paragraph previously said streaming methods buffer, full stop. That described `listChunks` as it was
|
|
2149
|
+
* before the bound was fixed, and the stale wording had also been copied into the Postgres and MySQL warm
|
|
2150
|
+
* drivers — so three comments promised a mid-stream resilience that the hot read path does not have.)
|
|
2139
2151
|
*
|
|
2140
2152
|
* What is **not** retried here: {@link WriteConflictError} (OCC — the engine's read-modify-write loop owns
|
|
2141
2153
|
* that; a blind replay would re-apply against a stale token), and every deterministic error
|
package/dist/index.js
CHANGED
|
@@ -2108,6 +2108,10 @@ async function publishGeneration(registry, key, options = {}) {
|
|
|
2108
2108
|
currentGen: key.generation,
|
|
2109
2109
|
wrappedDeks: options.wrappedDeks
|
|
2110
2110
|
});
|
|
2111
|
+
} else if (record.status === "destroyed") {
|
|
2112
|
+
throw new ValidationError(
|
|
2113
|
+
`segment "${key.segment}" was destroyed (crypto-shredded) while generation ${key.generation} was being written \u2014 refusing to publish it; the written object is unreadable. Use a new segment.`
|
|
2114
|
+
);
|
|
2111
2115
|
} else if (record.currentGen > key.generation) {
|
|
2112
2116
|
return false;
|
|
2113
2117
|
} else if (record.currentGen === key.generation) {
|
|
@@ -3730,12 +3734,13 @@ async function shredSegment(ref, deps, allowCleartext) {
|
|
|
3730
3734
|
}
|
|
3731
3735
|
async function eraseWarm(warm, ref) {
|
|
3732
3736
|
let deleted = 0;
|
|
3737
|
+
let conflicts = 0;
|
|
3733
3738
|
for (let pass = 0; pass < MAX_WARM_PASSES; pass++) {
|
|
3739
|
+
conflicts = 0;
|
|
3734
3740
|
const rows = [];
|
|
3735
3741
|
for await (const row of warm.listChunks(ref))
|
|
3736
3742
|
rows.push({ chunkKey: row.chunkKey, token: row.token });
|
|
3737
3743
|
if (rows.length === 0) break;
|
|
3738
|
-
let conflicts = 0;
|
|
3739
3744
|
for (const { chunkKey, token } of rows) {
|
|
3740
3745
|
const chunkRef = { namespace: ref.namespace, segment: ref.segment, chunkKey };
|
|
3741
3746
|
try {
|
|
@@ -3748,6 +3753,11 @@ async function eraseWarm(warm, ref) {
|
|
|
3748
3753
|
}
|
|
3749
3754
|
if (conflicts === 0) break;
|
|
3750
3755
|
}
|
|
3756
|
+
if (conflicts > 0) {
|
|
3757
|
+
throw new WriteConflictError(
|
|
3758
|
+
`destroySegment: ${conflicts} warm row(s) of "${ref.segment}" were rewritten during every one of ${MAX_WARM_PASSES} erase passes \u2014 the segment was NOT destroyed and its cleartext warm deltas are still readable. Stop writes to this segment and retry.`
|
|
3759
|
+
);
|
|
3760
|
+
}
|
|
3751
3761
|
return deleted;
|
|
3752
3762
|
}
|
|
3753
3763
|
|
|
@@ -3878,11 +3888,15 @@ var RetryingWarmDriver = class {
|
|
|
3878
3888
|
this.deps
|
|
3879
3889
|
);
|
|
3880
3890
|
if (started.first.done === true) return;
|
|
3881
|
-
|
|
3882
|
-
|
|
3883
|
-
|
|
3884
|
-
|
|
3885
|
-
|
|
3891
|
+
try {
|
|
3892
|
+
yield started.first.value;
|
|
3893
|
+
for (; ; ) {
|
|
3894
|
+
const next = await started.iterator.next();
|
|
3895
|
+
if (next.done === true) return;
|
|
3896
|
+
yield next.value;
|
|
3897
|
+
}
|
|
3898
|
+
} finally {
|
|
3899
|
+
await started.iterator.return?.();
|
|
3886
3900
|
}
|
|
3887
3901
|
}
|
|
3888
3902
|
};
|