distillate 0.5.0 → 0.6.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/README.md +9 -9
- package/dist/blocked/index.cjs +111 -38
- package/dist/blocked/index.d.cts +40 -3
- package/dist/blocked/index.d.ts +40 -3
- package/dist/blocked/index.js +111 -38
- package/dist/bloom/index.cjs +69 -27
- package/dist/bloom/index.d.cts +34 -2
- package/dist/bloom/index.d.ts +34 -2
- package/dist/bloom/index.js +69 -27
- package/dist/fuse/index.cjs +63 -19
- package/dist/fuse/index.d.cts +34 -2
- package/dist/fuse/index.d.ts +34 -2
- package/dist/fuse/index.js +63 -19
- package/dist/index.cjs +1 -1
- package/dist/index.js +1 -1
- package/dist/{params-J8p3bKq5.cjs → params--8CNXYWu.cjs} +10 -0
- package/dist/{params-ChTRNxM9.js → params-BrWuBC2A.js} +5 -1
- package/dist/serialize-BIIKUHH6.cjs +515 -0
- package/dist/serialize-BnwtzcMw.js +414 -0
- package/dist/serialize-DRKh6QOr.d.cts +15 -0
- package/dist/serialize-DRKh6QOr.d.ts +15 -0
- package/package.json +5 -28
- package/dist/bytes-DCuYtUVS.d.cts +0 -4
- package/dist/bytes-DCuYtUVS.d.ts +0 -4
- package/dist/serialize-BQ2UzZqq.js +0 -354
- package/dist/serialize-fa-pEUGq.cjs +0 -437
package/dist/fuse/index.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { n as BytesLike, t as FilterJSON } from "../serialize-DRKh6QOr.js";
|
|
2
2
|
//#region src/fuse/fuse.d.ts
|
|
3
3
|
/** Thrown when binary fuse construction fails to converge on the key set. */
|
|
4
4
|
declare class BinaryFuseBuildError extends Error {
|
|
@@ -26,6 +26,8 @@ declare abstract class BinaryFuse {
|
|
|
26
26
|
protected constructor(state: FuseState);
|
|
27
27
|
/** Number of distinct keys the filter was built from. */
|
|
28
28
|
get size(): number;
|
|
29
|
+
/** Hash seed selected during construction (may differ from 0 after a peel retry). */
|
|
30
|
+
get seed(): number;
|
|
29
31
|
/** Actual bits stored per key (`0` for an empty filter). */
|
|
30
32
|
get bitsPerKey(): number;
|
|
31
33
|
/**
|
|
@@ -41,6 +43,22 @@ declare abstract class BinaryFuse {
|
|
|
41
43
|
* @returns `true` if present (possibly a false positive); `false` guarantees absence.
|
|
42
44
|
*/
|
|
43
45
|
has(key: BytesLike): boolean;
|
|
46
|
+
/**
|
|
47
|
+
* Tests structural equality: `true` when `other` serializes to identical
|
|
48
|
+
* bytes. A {@link BinaryFuse8} and a {@link BinaryFuse16} are never equal,
|
|
49
|
+
* since their frames carry different type bytes.
|
|
50
|
+
*
|
|
51
|
+
* @param other - The filter to compare against.
|
|
52
|
+
* @returns `true` if the two filters are byte-for-byte identical.
|
|
53
|
+
*/
|
|
54
|
+
equals(other: BinaryFuse8 | BinaryFuse16): boolean;
|
|
55
|
+
/**
|
|
56
|
+
* Serializes the filter to a JSON-friendly envelope wrapping the base64 of
|
|
57
|
+
* the `toBytes` frame.
|
|
58
|
+
*
|
|
59
|
+
* @returns The envelope, readable by the matching `fromJSON`.
|
|
60
|
+
*/
|
|
61
|
+
toJSON(): FilterJSON;
|
|
44
62
|
}
|
|
45
63
|
/**
|
|
46
64
|
* A static 8-bit binary fuse filter: built once from a key set, then immutable.
|
|
@@ -69,6 +87,13 @@ declare class BinaryFuse8 extends BinaryFuse {
|
|
|
69
87
|
* @returns The reconstructed filter.
|
|
70
88
|
*/
|
|
71
89
|
static fromBytes(bytes: Uint8Array): BinaryFuse8;
|
|
90
|
+
/**
|
|
91
|
+
* Restores a filter from its {@link BinaryFuse8.toJSON} envelope.
|
|
92
|
+
*
|
|
93
|
+
* @param value - The JSON envelope.
|
|
94
|
+
* @returns The reconstructed filter.
|
|
95
|
+
*/
|
|
96
|
+
static fromJSON(value: unknown): BinaryFuse8;
|
|
72
97
|
}
|
|
73
98
|
/**
|
|
74
99
|
* A static 16-bit binary fuse filter: like {@link BinaryFuse8} but twice the
|
|
@@ -96,6 +121,13 @@ declare class BinaryFuse16 extends BinaryFuse {
|
|
|
96
121
|
* @returns The reconstructed filter.
|
|
97
122
|
*/
|
|
98
123
|
static fromBytes(bytes: Uint8Array): BinaryFuse16;
|
|
124
|
+
/**
|
|
125
|
+
* Restores a filter from its {@link BinaryFuse16.toJSON} envelope.
|
|
126
|
+
*
|
|
127
|
+
* @param value - The JSON envelope.
|
|
128
|
+
* @returns The reconstructed filter.
|
|
129
|
+
*/
|
|
130
|
+
static fromJSON(value: unknown): BinaryFuse16;
|
|
99
131
|
}
|
|
100
132
|
//#endregion
|
|
101
|
-
export { BinaryFuse16, BinaryFuse8, BinaryFuseBuildError };
|
|
133
|
+
export { BinaryFuse16, BinaryFuse8, BinaryFuseBuildError, type FilterJSON };
|
package/dist/fuse/index.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { a as
|
|
1
|
+
import { a as bytesEqual, c as toJSONEnvelope, d as RLO, f as fmix64, h as mul64, i as assertMinBodyLength, l as writeFrame, n as UnknownHashVariantError, o as fromJSONEnvelope, p as hash128KeyInto, r as assertBodyLength, s as readHeader, t as SerializationError, u as RHI } from "../serialize-BnwtzcMw.js";
|
|
2
2
|
//#region src/fuse/fuse.ts
|
|
3
3
|
const ARITY = 3;
|
|
4
4
|
const TYPE_FUSE8 = 3;
|
|
@@ -9,10 +9,10 @@ var BinaryFuseBuildError = class extends Error {
|
|
|
9
9
|
name = "BinaryFuseBuildError";
|
|
10
10
|
};
|
|
11
11
|
const scratchHash = {
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
12
|
+
w0: 0,
|
|
13
|
+
w1: 0,
|
|
14
|
+
w2: 0,
|
|
15
|
+
w3: 0
|
|
16
16
|
};
|
|
17
17
|
function mixSeed(lo, hi, seed) {
|
|
18
18
|
const l = (lo >>> 0) + (seed >>> 0);
|
|
@@ -135,8 +135,8 @@ function buildState(keys, alloc) {
|
|
|
135
135
|
const seen = /* @__PURE__ */ new Set();
|
|
136
136
|
for (const key of keys) {
|
|
137
137
|
hash128KeyInto(key, 0, scratchHash);
|
|
138
|
-
const lo = scratchHash.
|
|
139
|
-
const hi = scratchHash.
|
|
138
|
+
const lo = scratchHash.w0 >>> 0;
|
|
139
|
+
const hi = scratchHash.w1 >>> 0;
|
|
140
140
|
const id = `${String(lo)},${String(hi)}`;
|
|
141
141
|
if (seen.has(id)) continue;
|
|
142
142
|
seen.add(id);
|
|
@@ -160,14 +160,17 @@ function buildState(keys, alloc) {
|
|
|
160
160
|
};
|
|
161
161
|
}
|
|
162
162
|
function fuseStateFromBytes(bytes, expectedType) {
|
|
163
|
-
const { type, body } = readHeader(bytes);
|
|
163
|
+
const { type, flags, body } = readHeader(bytes);
|
|
164
164
|
if (type !== expectedType) throw new SerializationError(`expected AMQF type ${String(expectedType)}, got ${String(type)}`);
|
|
165
|
+
if ((flags & 15) !== 0) throw new UnknownHashVariantError(`unsupported hash variant ${String(flags & 15)}`);
|
|
165
166
|
assertMinBodyLength(body.length, 16, "fuse");
|
|
166
167
|
const dv = new DataView(body.buffer, body.byteOffset, body.byteLength);
|
|
167
168
|
const seed = dv.getUint32(0, true);
|
|
168
169
|
const seg = dv.getUint32(4, true);
|
|
169
170
|
const segCountLen = dv.getUint32(8, true);
|
|
170
171
|
const size = dv.getUint32(12, true);
|
|
172
|
+
if (seg === 0 || (seg & seg - 1) !== 0 || seg > 1 << 18) throw new SerializationError(`invalid fuse segment length ${String(seg)}`);
|
|
173
|
+
if (segCountLen % seg !== 0) throw new SerializationError(`fuse segment count length ${String(segCountLen)} is not a multiple of segment length ${String(seg)}`);
|
|
171
174
|
const bpe = expectedType === TYPE_FUSE8 ? 1 : 2;
|
|
172
175
|
const expectedArrayLength = size === 0 ? 0 : segCountLen + 2 * seg;
|
|
173
176
|
assertBodyLength(body.length, 16 + expectedArrayLength * bpe, "fuse");
|
|
@@ -211,6 +214,10 @@ var BinaryFuse = class {
|
|
|
211
214
|
get size() {
|
|
212
215
|
return this.#size;
|
|
213
216
|
}
|
|
217
|
+
/** Hash seed selected during construction (may differ from 0 after a peel retry). */
|
|
218
|
+
get seed() {
|
|
219
|
+
return this.#seed;
|
|
220
|
+
}
|
|
214
221
|
/** Actual bits stored per key (`0` for an empty filter). */
|
|
215
222
|
get bitsPerKey() {
|
|
216
223
|
return this.#size === 0 ? 0 : this.#fp.byteLength * 8 / this.#size;
|
|
@@ -222,18 +229,17 @@ var BinaryFuse = class {
|
|
|
222
229
|
*/
|
|
223
230
|
toBytes() {
|
|
224
231
|
const laneBytes = new Uint8Array(this.#fp.buffer, this.#fp.byteOffset, this.#fp.byteLength);
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
dv.setUint32(0, this.#seed, true);
|
|
228
|
-
dv.setUint32(4, this.#seg, true);
|
|
229
|
-
dv.setUint32(8, this.#segCountLen, true);
|
|
230
|
-
dv.setUint32(12, this.#size, true);
|
|
231
|
-
body.set(laneBytes, 16);
|
|
232
|
-
return writeHeader({
|
|
233
|
-
version: 2,
|
|
232
|
+
return writeFrame({
|
|
233
|
+
version: 3,
|
|
234
234
|
type: this.#fp.BYTES_PER_ELEMENT === 1 ? TYPE_FUSE8 : TYPE_FUSE16,
|
|
235
235
|
flags: 0
|
|
236
|
-
}, body)
|
|
236
|
+
}, 16 + laneBytes.length, (body, dv) => {
|
|
237
|
+
dv.setUint32(0, this.#seed, true);
|
|
238
|
+
dv.setUint32(4, this.#seg, true);
|
|
239
|
+
dv.setUint32(8, this.#segCountLen, true);
|
|
240
|
+
dv.setUint32(12, this.#size, true);
|
|
241
|
+
body.set(laneBytes, 16);
|
|
242
|
+
});
|
|
237
243
|
}
|
|
238
244
|
/**
|
|
239
245
|
* Tests whether a key is in the set.
|
|
@@ -244,7 +250,7 @@ var BinaryFuse = class {
|
|
|
244
250
|
has(key) {
|
|
245
251
|
if (this.#fp.length === 0) return false;
|
|
246
252
|
hash128KeyInto(key, 0, scratchHash);
|
|
247
|
-
mixSeed(scratchHash.
|
|
253
|
+
mixSeed(scratchHash.w0 >>> 0, scratchHash.w1 >>> 0, this.#seed);
|
|
248
254
|
const mlo = RLO;
|
|
249
255
|
const mhi = RHI;
|
|
250
256
|
positionsInto(mlo, mhi, this.#seg, this.#segMask, this.#segCountLen, this.#pos);
|
|
@@ -254,6 +260,26 @@ var BinaryFuse = class {
|
|
|
254
260
|
const p2 = this.#pos[2] ?? 0;
|
|
255
261
|
return ((mlo ^ mhi) & mask) === (((this.#fp[p0] ?? 0) ^ (this.#fp[p1] ?? 0) ^ (this.#fp[p2] ?? 0)) & mask);
|
|
256
262
|
}
|
|
263
|
+
/**
|
|
264
|
+
* Tests structural equality: `true` when `other` serializes to identical
|
|
265
|
+
* bytes. A {@link BinaryFuse8} and a {@link BinaryFuse16} are never equal,
|
|
266
|
+
* since their frames carry different type bytes.
|
|
267
|
+
*
|
|
268
|
+
* @param other - The filter to compare against.
|
|
269
|
+
* @returns `true` if the two filters are byte-for-byte identical.
|
|
270
|
+
*/
|
|
271
|
+
equals(other) {
|
|
272
|
+
return bytesEqual(this.toBytes(), other.toBytes());
|
|
273
|
+
}
|
|
274
|
+
/**
|
|
275
|
+
* Serializes the filter to a JSON-friendly envelope wrapping the base64 of
|
|
276
|
+
* the `toBytes` frame.
|
|
277
|
+
*
|
|
278
|
+
* @returns The envelope, readable by the matching `fromJSON`.
|
|
279
|
+
*/
|
|
280
|
+
toJSON() {
|
|
281
|
+
return toJSONEnvelope(this.toBytes());
|
|
282
|
+
}
|
|
257
283
|
};
|
|
258
284
|
/**
|
|
259
285
|
* A static 8-bit binary fuse filter: built once from a key set, then immutable.
|
|
@@ -286,6 +312,15 @@ var BinaryFuse8 = class BinaryFuse8 extends BinaryFuse {
|
|
|
286
312
|
static fromBytes(bytes) {
|
|
287
313
|
return new BinaryFuse8(fuseStateFromBytes(bytes, TYPE_FUSE8));
|
|
288
314
|
}
|
|
315
|
+
/**
|
|
316
|
+
* Restores a filter from its {@link BinaryFuse8.toJSON} envelope.
|
|
317
|
+
*
|
|
318
|
+
* @param value - The JSON envelope.
|
|
319
|
+
* @returns The reconstructed filter.
|
|
320
|
+
*/
|
|
321
|
+
static fromJSON(value) {
|
|
322
|
+
return BinaryFuse8.fromBytes(fromJSONEnvelope(value));
|
|
323
|
+
}
|
|
289
324
|
};
|
|
290
325
|
/**
|
|
291
326
|
* A static 16-bit binary fuse filter: like {@link BinaryFuse8} but twice the
|
|
@@ -317,6 +352,15 @@ var BinaryFuse16 = class BinaryFuse16 extends BinaryFuse {
|
|
|
317
352
|
static fromBytes(bytes) {
|
|
318
353
|
return new BinaryFuse16(fuseStateFromBytes(bytes, TYPE_FUSE16));
|
|
319
354
|
}
|
|
355
|
+
/**
|
|
356
|
+
* Restores a filter from its {@link BinaryFuse16.toJSON} envelope.
|
|
357
|
+
*
|
|
358
|
+
* @param value - The JSON envelope.
|
|
359
|
+
* @returns The reconstructed filter.
|
|
360
|
+
*/
|
|
361
|
+
static fromJSON(value) {
|
|
362
|
+
return BinaryFuse16.fromBytes(fromJSONEnvelope(value));
|
|
363
|
+
}
|
|
320
364
|
};
|
|
321
365
|
//#endregion
|
|
322
366
|
export { BinaryFuse16, BinaryFuse8, BinaryFuseBuildError };
|
package/dist/index.cjs
CHANGED
package/dist/index.js
CHANGED
|
@@ -12,6 +12,10 @@ function assertPositiveInt(value, label) {
|
|
|
12
12
|
function assertPositiveFinite(value, label) {
|
|
13
13
|
if (!Number.isFinite(value) || value <= 0) throw new ParamError(`${label} must be a positive number, got ${String(value)}`);
|
|
14
14
|
}
|
|
15
|
+
/** Asserts `value` is an integer in the uint16 range `[0, 65535]`. */
|
|
16
|
+
function assertUint16(value, label) {
|
|
17
|
+
if (!Number.isInteger(value) || value < 0 || value > 65535) throw new ParamError(`${label} must be a uint16, got ${String(value)}`);
|
|
18
|
+
}
|
|
15
19
|
/** Asserts `value` is an integer in the uint32 range `[0, 2^32 - 1]`. */
|
|
16
20
|
function assertUint32(value, label) {
|
|
17
21
|
if (!Number.isInteger(value) || value < 0 || value > 4294967295) throw new ParamError(`${label} must be a uint32, got ${String(value)}`);
|
|
@@ -45,6 +49,12 @@ Object.defineProperty(exports, "assertProbability", {
|
|
|
45
49
|
return assertProbability;
|
|
46
50
|
}
|
|
47
51
|
});
|
|
52
|
+
Object.defineProperty(exports, "assertUint16", {
|
|
53
|
+
enumerable: true,
|
|
54
|
+
get: function() {
|
|
55
|
+
return assertUint16;
|
|
56
|
+
}
|
|
57
|
+
});
|
|
48
58
|
Object.defineProperty(exports, "assertUint32", {
|
|
49
59
|
enumerable: true,
|
|
50
60
|
get: function() {
|
|
@@ -12,6 +12,10 @@ function assertPositiveInt(value, label) {
|
|
|
12
12
|
function assertPositiveFinite(value, label) {
|
|
13
13
|
if (!Number.isFinite(value) || value <= 0) throw new ParamError(`${label} must be a positive number, got ${String(value)}`);
|
|
14
14
|
}
|
|
15
|
+
/** Asserts `value` is an integer in the uint16 range `[0, 65535]`. */
|
|
16
|
+
function assertUint16(value, label) {
|
|
17
|
+
if (!Number.isInteger(value) || value < 0 || value > 65535) throw new ParamError(`${label} must be a uint16, got ${String(value)}`);
|
|
18
|
+
}
|
|
15
19
|
/** Asserts `value` is an integer in the uint32 range `[0, 2^32 - 1]`. */
|
|
16
20
|
function assertUint32(value, label) {
|
|
17
21
|
if (!Number.isInteger(value) || value < 0 || value > 4294967295) throw new ParamError(`${label} must be a uint32, got ${String(value)}`);
|
|
@@ -21,4 +25,4 @@ function assertProbability(value, label) {
|
|
|
21
25
|
if (!Number.isFinite(value) || value <= 0 || value >= 1) throw new ParamError(`${label} must be in the open interval (0, 1), got ${String(value)}`);
|
|
22
26
|
}
|
|
23
27
|
//#endregion
|
|
24
|
-
export {
|
|
28
|
+
export { assertUint16 as a, assertProbability as i, assertPositiveFinite as n, assertUint32 as o, assertPositiveInt as r, ParamError as t };
|