distillate 0.1.0 → 0.1.2

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.
@@ -1,23 +1,81 @@
1
1
  import { t as BytesLike } from "../bytes-DCuYtUVS.js";
2
2
  //#region src/bloom/bloom.d.ts
3
+ /** Thrown when an operation requires two filters built with identical parameters. */
3
4
  declare class BloomParamMismatchError extends Error {
5
+ /** Discriminates this error from other `Error`s. */
4
6
  override readonly name = "BloomParamMismatchError";
5
7
  }
8
+ /** Low-level Bloom filter parameters. */
6
9
  interface BloomParams {
10
+ /** Number of bits in the filter. */
7
11
  m: number;
12
+ /** Number of hash probes per key. */
8
13
  k: number;
14
+ /** Hash seed; defaults to `0`. */
9
15
  seed?: number;
10
16
  }
17
+ /**
18
+ * A classic Bloom filter: a space-efficient set with a tunable false-positive
19
+ * rate and zero false negatives.
20
+ *
21
+ * @example
22
+ * ```ts
23
+ * const filter = BloomFilter.create(100_000, 0.01);
24
+ * filter.add("alice");
25
+ * filter.has("alice"); // true
26
+ * filter.has("bob"); // false (or a ~1% false positive)
27
+ * ```
28
+ */
11
29
  declare class BloomFilter {
12
30
  #private;
31
+ /**
32
+ * Creates a filter sized for `n` expected keys at a target false-positive rate.
33
+ *
34
+ * @param n - Expected number of keys.
35
+ * @param epsilon - Target false-positive rate, e.g. `0.01` for 1%.
36
+ * @returns A new, empty filter.
37
+ */
13
38
  static create(n: number, epsilon: number): BloomFilter;
39
+ /**
40
+ * Restores a filter from its {@link BloomFilter.toBytes} serialization.
41
+ *
42
+ * @param bytes - The serialized filter.
43
+ * @returns The reconstructed filter.
44
+ */
14
45
  static fromBytes(bytes: Uint8Array): BloomFilter;
46
+ /**
47
+ * Constructs a filter from low-level {@link BloomParams}. Prefer
48
+ * {@link BloomFilter.create} unless restoring a specific configuration.
49
+ */
15
50
  constructor({ m, k, seed }: BloomParams);
16
51
  /** Analytic design bits-per-key `m / n`. */
17
52
  get bitsPerKey(): number;
53
+ /**
54
+ * Serializes the filter to a portable little-endian byte layout.
55
+ *
56
+ * @returns The serialized filter, readable by {@link BloomFilter.fromBytes}.
57
+ */
18
58
  toBytes(): Uint8Array;
59
+ /**
60
+ * Returns a new filter containing the union of this filter and `other`.
61
+ *
62
+ * @param other - A filter built with identical parameters.
63
+ * @returns A new filter reporting membership for keys in either input.
64
+ * @throws {@link BloomParamMismatchError} if the parameters differ.
65
+ */
19
66
  union(other: BloomFilter): BloomFilter;
67
+ /**
68
+ * Adds a key to the set.
69
+ *
70
+ * @param key - The key to insert, as a string or bytes.
71
+ */
20
72
  add(key: BytesLike): void;
73
+ /**
74
+ * Tests whether a key is in the set.
75
+ *
76
+ * @param key - The key to test.
77
+ * @returns `true` if present (possibly a false positive); `false` guarantees absence.
78
+ */
21
79
  has(key: BytesLike): boolean;
22
80
  }
23
81
  //#endregion
@@ -1,4 +1,4 @@
1
- import { a as probeInto, n as readHeader, r as writeHeader } from "../serialize-E_4WyueA.js";
1
+ import { a as probeInto, n as readHeader, r as writeHeader } from "../serialize-5XQ5y_R-.js";
2
2
  //#region src/core/bitset.ts
3
3
  var BitSetRangeError = class extends RangeError {
4
4
  name = "BitSetRangeError";
@@ -47,9 +47,23 @@ function optimal(n, epsilon) {
47
47
  //#endregion
48
48
  //#region src/bloom/bloom.ts
49
49
  const TYPE = 1;
50
+ /** Thrown when an operation requires two filters built with identical parameters. */
50
51
  var BloomParamMismatchError = class extends Error {
52
+ /** Discriminates this error from other `Error`s. */
51
53
  name = "BloomParamMismatchError";
52
54
  };
55
+ /**
56
+ * A classic Bloom filter: a space-efficient set with a tunable false-positive
57
+ * rate and zero false negatives.
58
+ *
59
+ * @example
60
+ * ```ts
61
+ * const filter = BloomFilter.create(100_000, 0.01);
62
+ * filter.add("alice");
63
+ * filter.has("alice"); // true
64
+ * filter.has("bob"); // false (or a ~1% false positive)
65
+ * ```
66
+ */
53
67
  var BloomFilter = class BloomFilter {
54
68
  #bits;
55
69
  #m;
@@ -57,11 +71,24 @@ var BloomFilter = class BloomFilter {
57
71
  #seed;
58
72
  #scratch;
59
73
  #n;
74
+ /**
75
+ * Creates a filter sized for `n` expected keys at a target false-positive rate.
76
+ *
77
+ * @param n - Expected number of keys.
78
+ * @param epsilon - Target false-positive rate, e.g. `0.01` for 1%.
79
+ * @returns A new, empty filter.
80
+ */
60
81
  static create(n, epsilon) {
61
82
  const f = new BloomFilter(optimal(n, epsilon));
62
83
  f.#n = n;
63
84
  return f;
64
85
  }
86
+ /**
87
+ * Restores a filter from its {@link BloomFilter.toBytes} serialization.
88
+ *
89
+ * @param bytes - The serialized filter.
90
+ * @returns The reconstructed filter.
91
+ */
65
92
  static fromBytes(bytes) {
66
93
  const { body } = readHeader(bytes);
67
94
  const dv = new DataView(body.buffer, body.byteOffset, body.byteLength);
@@ -76,6 +103,10 @@ var BloomFilter = class BloomFilter {
76
103
  f.#bits.bytes.set(body.subarray(9));
77
104
  return f;
78
105
  }
106
+ /**
107
+ * Constructs a filter from low-level {@link BloomParams}. Prefer
108
+ * {@link BloomFilter.create} unless restoring a specific configuration.
109
+ */
79
110
  constructor({ m, k, seed = 0 }) {
80
111
  this.#bits = new BitSet(m);
81
112
  this.#m = m;
@@ -88,6 +119,11 @@ var BloomFilter = class BloomFilter {
88
119
  get bitsPerKey() {
89
120
  return this.#m / this.#n;
90
121
  }
122
+ /**
123
+ * Serializes the filter to a portable little-endian byte layout.
124
+ *
125
+ * @returns The serialized filter, readable by {@link BloomFilter.fromBytes}.
126
+ */
91
127
  toBytes() {
92
128
  const payload = this.#bits.bytes;
93
129
  const body = new Uint8Array(9 + payload.length);
@@ -102,6 +138,13 @@ var BloomFilter = class BloomFilter {
102
138
  flags: 0
103
139
  }, body);
104
140
  }
141
+ /**
142
+ * Returns a new filter containing the union of this filter and `other`.
143
+ *
144
+ * @param other - A filter built with identical parameters.
145
+ * @returns A new filter reporting membership for keys in either input.
146
+ * @throws {@link BloomParamMismatchError} if the parameters differ.
147
+ */
105
148
  union(other) {
106
149
  if (this.#m !== other.#m || this.#k !== other.#k || this.#seed !== other.#seed) throw new BloomParamMismatchError("cannot union Bloom filters whose parameters do not match");
107
150
  const a = this.#bits.bytes;
@@ -116,10 +159,21 @@ var BloomFilter = class BloomFilter {
116
159
  r.#bits.bytes.set(merged);
117
160
  return r;
118
161
  }
162
+ /**
163
+ * Adds a key to the set.
164
+ *
165
+ * @param key - The key to insert, as a string or bytes.
166
+ */
119
167
  add(key) {
120
168
  probeInto(key, this.#k, this.#m, this.#seed, this.#scratch);
121
169
  for (let i = 0; i < this.#k; i++) this.#bits.set(this.#scratch[i] ?? 0);
122
170
  }
171
+ /**
172
+ * Tests whether a key is in the set.
173
+ *
174
+ * @param key - The key to test.
175
+ * @returns `true` if present (possibly a false positive); `false` guarantees absence.
176
+ */
123
177
  has(key) {
124
178
  probeInto(key, this.#k, this.#m, this.#seed, this.#scratch);
125
179
  for (let i = 0; i < this.#k; i++) if (!this.#bits.get(this.#scratch[i] ?? 0)) return false;
@@ -1,14 +1,22 @@
1
1
  Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
2
- const require_serialize = require("../serialize-C5rwVPvv.cjs");
2
+ const require_serialize = require("../serialize-CHHDM4TQ.cjs");
3
3
  //#region src/fuse/fuse.ts
4
4
  const ARITY = 3;
5
5
  const TYPE_FUSE8 = 3;
6
6
  const TYPE_FUSE16 = 4;
7
+ /** Thrown when binary fuse construction fails to converge on the key set. */
7
8
  var BinaryFuseBuildError = class extends Error {
9
+ /** Discriminates this error from other `Error`s. */
8
10
  name = "BinaryFuseBuildError";
9
11
  };
10
12
  let RLO = 0;
11
13
  let RHI = 0;
14
+ const scratchHash = {
15
+ h1lo: 0,
16
+ h1hi: 0,
17
+ h2lo: 0,
18
+ h2hi: 0
19
+ };
12
20
  function mul64(alo, ahi, blo, bhi) {
13
21
  const a0 = alo & 65535;
14
22
  const a1 = alo >>> 16;
@@ -175,9 +183,9 @@ function buildState(keys, alloc) {
175
183
  const hashList = [];
176
184
  const seen = /* @__PURE__ */ new Set();
177
185
  for (const key of keys) {
178
- const { h1lo, h1hi } = require_serialize.hash128(require_serialize.normalize(key), 0);
179
- const lo = h1lo >>> 0;
180
- const hi = h1hi >>> 0;
186
+ require_serialize.hash128KeyInto(key, 0, scratchHash);
187
+ const lo = scratchHash.h1lo >>> 0;
188
+ const hi = scratchHash.h1hi >>> 0;
181
189
  const id = `${String(lo)},${String(hi)}`;
182
190
  if (seen.has(id)) continue;
183
191
  seen.add(id);
@@ -225,6 +233,10 @@ function fuseStateFromBytes(bytes, expectedType) {
225
233
  size
226
234
  };
227
235
  }
236
+ /**
237
+ * Shared behavior for the static binary fuse filters: an immutable,
238
+ * space-efficient membership filter built once from a fixed key set.
239
+ */
228
240
  var BinaryFuse = class {
229
241
  #fp;
230
242
  #seed;
@@ -241,12 +253,19 @@ var BinaryFuse = class {
241
253
  this.#segCountLen = state.params.segCountLen;
242
254
  this.#size = state.size;
243
255
  }
256
+ /** Number of distinct keys the filter was built from. */
244
257
  get size() {
245
258
  return this.#size;
246
259
  }
260
+ /** Actual bits stored per key (`0` for an empty filter). */
247
261
  get bitsPerKey() {
248
262
  return this.#size === 0 ? 0 : this.#fp.byteLength * 8 / this.#size;
249
263
  }
264
+ /**
265
+ * Serializes the filter to a portable little-endian byte layout.
266
+ *
267
+ * @returns The serialized filter, readable by the matching `fromBytes`.
268
+ */
250
269
  toBytes() {
251
270
  const laneBytes = new Uint8Array(this.#fp.buffer, this.#fp.byteOffset, this.#fp.byteLength);
252
271
  const body = new Uint8Array(16 + laneBytes.length);
@@ -262,10 +281,16 @@ var BinaryFuse = class {
262
281
  flags: 0
263
282
  }, body);
264
283
  }
284
+ /**
285
+ * Tests whether a key is in the set.
286
+ *
287
+ * @param key - The key to test.
288
+ * @returns `true` if present (possibly a false positive); `false` guarantees absence.
289
+ */
265
290
  has(key) {
266
291
  if (this.#fp.length === 0) return false;
267
- const { h1lo, h1hi } = require_serialize.hash128(require_serialize.normalize(key), 0);
268
- mixSeed(h1lo >>> 0, h1hi >>> 0, this.#seed);
292
+ require_serialize.hash128KeyInto(key, 0, scratchHash);
293
+ mixSeed(scratchHash.h1lo >>> 0, scratchHash.h1hi >>> 0, this.#seed);
269
294
  const mlo = RLO;
270
295
  const mhi = RHI;
271
296
  positionsInto(mlo, mhi, this.#seg, this.#segMask, this.#segCountLen, this.#pos);
@@ -276,18 +301,65 @@ var BinaryFuse = class {
276
301
  return ((mlo ^ mhi) & mask) === (((this.#fp[p0] ?? 0) ^ (this.#fp[p1] ?? 0) ^ (this.#fp[p2] ?? 0)) & mask);
277
302
  }
278
303
  };
304
+ /**
305
+ * A static 8-bit binary fuse filter: built once from a key set, then immutable.
306
+ * The most space-efficient option (~9 bits/key at ~0.39% false-positive rate).
307
+ *
308
+ * @example
309
+ * ```ts
310
+ * const filter = BinaryFuse8.from(["alice", "bob", "carol"]);
311
+ * filter.has("alice"); // true
312
+ * filter.size; // 3
313
+ * ```
314
+ */
279
315
  var BinaryFuse8 = class BinaryFuse8 extends BinaryFuse {
316
+ /**
317
+ * Builds a filter from the given keys; duplicates are ignored.
318
+ *
319
+ * @param keys - The complete set of keys to store.
320
+ * @returns A new immutable filter.
321
+ * @throws {@link BinaryFuseBuildError} if construction fails to converge.
322
+ */
280
323
  static from(keys) {
281
324
  return new BinaryFuse8(buildState(keys, (n) => new Uint8Array(n)));
282
325
  }
326
+ /**
327
+ * Restores a filter from its {@link BinaryFuse8.toBytes} serialization.
328
+ *
329
+ * @param bytes - The serialized filter.
330
+ * @returns The reconstructed filter.
331
+ */
283
332
  static fromBytes(bytes) {
284
333
  return new BinaryFuse8(fuseStateFromBytes(bytes, TYPE_FUSE8));
285
334
  }
286
335
  };
336
+ /**
337
+ * A static 16-bit binary fuse filter: like {@link BinaryFuse8} but twice the
338
+ * space (~18 bits/key) for a far lower false-positive rate (~1/65536).
339
+ *
340
+ * @example
341
+ * ```ts
342
+ * const filter = BinaryFuse16.from(["alice", "bob", "carol"]);
343
+ * filter.has("alice"); // true
344
+ * ```
345
+ */
287
346
  var BinaryFuse16 = class BinaryFuse16 extends BinaryFuse {
347
+ /**
348
+ * Builds a filter from the given keys; duplicates are ignored.
349
+ *
350
+ * @param keys - The complete set of keys to store.
351
+ * @returns A new immutable filter.
352
+ * @throws {@link BinaryFuseBuildError} if construction fails to converge.
353
+ */
288
354
  static from(keys) {
289
355
  return new BinaryFuse16(buildState(keys, (n) => new Uint16Array(n)));
290
356
  }
357
+ /**
358
+ * Restores a filter from its {@link BinaryFuse16.toBytes} serialization.
359
+ *
360
+ * @param bytes - The serialized filter.
361
+ * @returns The reconstructed filter.
362
+ */
291
363
  static fromBytes(bytes) {
292
364
  return new BinaryFuse16(fuseStateFromBytes(bytes, TYPE_FUSE16));
293
365
  }
@@ -1,6 +1,8 @@
1
1
  import { t as BytesLike } from "../bytes-DCuYtUVS.cjs";
2
2
  //#region src/fuse/fuse.d.ts
3
+ /** Thrown when binary fuse construction fails to converge on the key set. */
3
4
  declare class BinaryFuseBuildError extends Error {
5
+ /** Discriminates this error from other `Error`s. */
4
6
  override readonly name = "BinaryFuseBuildError";
5
7
  }
6
8
  interface FuseParams {
@@ -15,20 +17,84 @@ interface FuseState {
15
17
  params: FuseParams;
16
18
  size: number;
17
19
  }
20
+ /**
21
+ * Shared behavior for the static binary fuse filters: an immutable,
22
+ * space-efficient membership filter built once from a fixed key set.
23
+ */
18
24
  declare abstract class BinaryFuse {
19
25
  #private;
20
26
  protected constructor(state: FuseState);
27
+ /** Number of distinct keys the filter was built from. */
21
28
  get size(): number;
29
+ /** Actual bits stored per key (`0` for an empty filter). */
22
30
  get bitsPerKey(): number;
31
+ /**
32
+ * Serializes the filter to a portable little-endian byte layout.
33
+ *
34
+ * @returns The serialized filter, readable by the matching `fromBytes`.
35
+ */
23
36
  toBytes(): Uint8Array;
37
+ /**
38
+ * Tests whether a key is in the set.
39
+ *
40
+ * @param key - The key to test.
41
+ * @returns `true` if present (possibly a false positive); `false` guarantees absence.
42
+ */
24
43
  has(key: BytesLike): boolean;
25
44
  }
45
+ /**
46
+ * A static 8-bit binary fuse filter: built once from a key set, then immutable.
47
+ * The most space-efficient option (~9 bits/key at ~0.39% false-positive rate).
48
+ *
49
+ * @example
50
+ * ```ts
51
+ * const filter = BinaryFuse8.from(["alice", "bob", "carol"]);
52
+ * filter.has("alice"); // true
53
+ * filter.size; // 3
54
+ * ```
55
+ */
26
56
  declare class BinaryFuse8 extends BinaryFuse {
57
+ /**
58
+ * Builds a filter from the given keys; duplicates are ignored.
59
+ *
60
+ * @param keys - The complete set of keys to store.
61
+ * @returns A new immutable filter.
62
+ * @throws {@link BinaryFuseBuildError} if construction fails to converge.
63
+ */
27
64
  static from(keys: Iterable<BytesLike>): BinaryFuse8;
65
+ /**
66
+ * Restores a filter from its {@link BinaryFuse8.toBytes} serialization.
67
+ *
68
+ * @param bytes - The serialized filter.
69
+ * @returns The reconstructed filter.
70
+ */
28
71
  static fromBytes(bytes: Uint8Array): BinaryFuse8;
29
72
  }
73
+ /**
74
+ * A static 16-bit binary fuse filter: like {@link BinaryFuse8} but twice the
75
+ * space (~18 bits/key) for a far lower false-positive rate (~1/65536).
76
+ *
77
+ * @example
78
+ * ```ts
79
+ * const filter = BinaryFuse16.from(["alice", "bob", "carol"]);
80
+ * filter.has("alice"); // true
81
+ * ```
82
+ */
30
83
  declare class BinaryFuse16 extends BinaryFuse {
84
+ /**
85
+ * Builds a filter from the given keys; duplicates are ignored.
86
+ *
87
+ * @param keys - The complete set of keys to store.
88
+ * @returns A new immutable filter.
89
+ * @throws {@link BinaryFuseBuildError} if construction fails to converge.
90
+ */
31
91
  static from(keys: Iterable<BytesLike>): BinaryFuse16;
92
+ /**
93
+ * Restores a filter from its {@link BinaryFuse16.toBytes} serialization.
94
+ *
95
+ * @param bytes - The serialized filter.
96
+ * @returns The reconstructed filter.
97
+ */
32
98
  static fromBytes(bytes: Uint8Array): BinaryFuse16;
33
99
  }
34
100
  //#endregion
@@ -1,6 +1,8 @@
1
1
  import { t as BytesLike } from "../bytes-DCuYtUVS.js";
2
2
  //#region src/fuse/fuse.d.ts
3
+ /** Thrown when binary fuse construction fails to converge on the key set. */
3
4
  declare class BinaryFuseBuildError extends Error {
5
+ /** Discriminates this error from other `Error`s. */
4
6
  override readonly name = "BinaryFuseBuildError";
5
7
  }
6
8
  interface FuseParams {
@@ -15,20 +17,84 @@ interface FuseState {
15
17
  params: FuseParams;
16
18
  size: number;
17
19
  }
20
+ /**
21
+ * Shared behavior for the static binary fuse filters: an immutable,
22
+ * space-efficient membership filter built once from a fixed key set.
23
+ */
18
24
  declare abstract class BinaryFuse {
19
25
  #private;
20
26
  protected constructor(state: FuseState);
27
+ /** Number of distinct keys the filter was built from. */
21
28
  get size(): number;
29
+ /** Actual bits stored per key (`0` for an empty filter). */
22
30
  get bitsPerKey(): number;
31
+ /**
32
+ * Serializes the filter to a portable little-endian byte layout.
33
+ *
34
+ * @returns The serialized filter, readable by the matching `fromBytes`.
35
+ */
23
36
  toBytes(): Uint8Array;
37
+ /**
38
+ * Tests whether a key is in the set.
39
+ *
40
+ * @param key - The key to test.
41
+ * @returns `true` if present (possibly a false positive); `false` guarantees absence.
42
+ */
24
43
  has(key: BytesLike): boolean;
25
44
  }
45
+ /**
46
+ * A static 8-bit binary fuse filter: built once from a key set, then immutable.
47
+ * The most space-efficient option (~9 bits/key at ~0.39% false-positive rate).
48
+ *
49
+ * @example
50
+ * ```ts
51
+ * const filter = BinaryFuse8.from(["alice", "bob", "carol"]);
52
+ * filter.has("alice"); // true
53
+ * filter.size; // 3
54
+ * ```
55
+ */
26
56
  declare class BinaryFuse8 extends BinaryFuse {
57
+ /**
58
+ * Builds a filter from the given keys; duplicates are ignored.
59
+ *
60
+ * @param keys - The complete set of keys to store.
61
+ * @returns A new immutable filter.
62
+ * @throws {@link BinaryFuseBuildError} if construction fails to converge.
63
+ */
27
64
  static from(keys: Iterable<BytesLike>): BinaryFuse8;
65
+ /**
66
+ * Restores a filter from its {@link BinaryFuse8.toBytes} serialization.
67
+ *
68
+ * @param bytes - The serialized filter.
69
+ * @returns The reconstructed filter.
70
+ */
28
71
  static fromBytes(bytes: Uint8Array): BinaryFuse8;
29
72
  }
73
+ /**
74
+ * A static 16-bit binary fuse filter: like {@link BinaryFuse8} but twice the
75
+ * space (~18 bits/key) for a far lower false-positive rate (~1/65536).
76
+ *
77
+ * @example
78
+ * ```ts
79
+ * const filter = BinaryFuse16.from(["alice", "bob", "carol"]);
80
+ * filter.has("alice"); // true
81
+ * ```
82
+ */
30
83
  declare class BinaryFuse16 extends BinaryFuse {
84
+ /**
85
+ * Builds a filter from the given keys; duplicates are ignored.
86
+ *
87
+ * @param keys - The complete set of keys to store.
88
+ * @returns A new immutable filter.
89
+ * @throws {@link BinaryFuseBuildError} if construction fails to converge.
90
+ */
31
91
  static from(keys: Iterable<BytesLike>): BinaryFuse16;
92
+ /**
93
+ * Restores a filter from its {@link BinaryFuse16.toBytes} serialization.
94
+ *
95
+ * @param bytes - The serialized filter.
96
+ * @returns The reconstructed filter.
97
+ */
32
98
  static fromBytes(bytes: Uint8Array): BinaryFuse16;
33
99
  }
34
100
  //#endregion
@@ -1,13 +1,21 @@
1
- import { i as hash128, n as readHeader, r as writeHeader, s as normalize, t as SerializationError } from "../serialize-E_4WyueA.js";
1
+ import { i as hash128KeyInto, n as readHeader, r as writeHeader, t as SerializationError } from "../serialize-5XQ5y_R-.js";
2
2
  //#region src/fuse/fuse.ts
3
3
  const ARITY = 3;
4
4
  const TYPE_FUSE8 = 3;
5
5
  const TYPE_FUSE16 = 4;
6
+ /** Thrown when binary fuse construction fails to converge on the key set. */
6
7
  var BinaryFuseBuildError = class extends Error {
8
+ /** Discriminates this error from other `Error`s. */
7
9
  name = "BinaryFuseBuildError";
8
10
  };
9
11
  let RLO = 0;
10
12
  let RHI = 0;
13
+ const scratchHash = {
14
+ h1lo: 0,
15
+ h1hi: 0,
16
+ h2lo: 0,
17
+ h2hi: 0
18
+ };
11
19
  function mul64(alo, ahi, blo, bhi) {
12
20
  const a0 = alo & 65535;
13
21
  const a1 = alo >>> 16;
@@ -174,9 +182,9 @@ function buildState(keys, alloc) {
174
182
  const hashList = [];
175
183
  const seen = /* @__PURE__ */ new Set();
176
184
  for (const key of keys) {
177
- const { h1lo, h1hi } = hash128(normalize(key), 0);
178
- const lo = h1lo >>> 0;
179
- const hi = h1hi >>> 0;
185
+ hash128KeyInto(key, 0, scratchHash);
186
+ const lo = scratchHash.h1lo >>> 0;
187
+ const hi = scratchHash.h1hi >>> 0;
180
188
  const id = `${String(lo)},${String(hi)}`;
181
189
  if (seen.has(id)) continue;
182
190
  seen.add(id);
@@ -224,6 +232,10 @@ function fuseStateFromBytes(bytes, expectedType) {
224
232
  size
225
233
  };
226
234
  }
235
+ /**
236
+ * Shared behavior for the static binary fuse filters: an immutable,
237
+ * space-efficient membership filter built once from a fixed key set.
238
+ */
227
239
  var BinaryFuse = class {
228
240
  #fp;
229
241
  #seed;
@@ -240,12 +252,19 @@ var BinaryFuse = class {
240
252
  this.#segCountLen = state.params.segCountLen;
241
253
  this.#size = state.size;
242
254
  }
255
+ /** Number of distinct keys the filter was built from. */
243
256
  get size() {
244
257
  return this.#size;
245
258
  }
259
+ /** Actual bits stored per key (`0` for an empty filter). */
246
260
  get bitsPerKey() {
247
261
  return this.#size === 0 ? 0 : this.#fp.byteLength * 8 / this.#size;
248
262
  }
263
+ /**
264
+ * Serializes the filter to a portable little-endian byte layout.
265
+ *
266
+ * @returns The serialized filter, readable by the matching `fromBytes`.
267
+ */
249
268
  toBytes() {
250
269
  const laneBytes = new Uint8Array(this.#fp.buffer, this.#fp.byteOffset, this.#fp.byteLength);
251
270
  const body = new Uint8Array(16 + laneBytes.length);
@@ -261,10 +280,16 @@ var BinaryFuse = class {
261
280
  flags: 0
262
281
  }, body);
263
282
  }
283
+ /**
284
+ * Tests whether a key is in the set.
285
+ *
286
+ * @param key - The key to test.
287
+ * @returns `true` if present (possibly a false positive); `false` guarantees absence.
288
+ */
264
289
  has(key) {
265
290
  if (this.#fp.length === 0) return false;
266
- const { h1lo, h1hi } = hash128(normalize(key), 0);
267
- mixSeed(h1lo >>> 0, h1hi >>> 0, this.#seed);
291
+ hash128KeyInto(key, 0, scratchHash);
292
+ mixSeed(scratchHash.h1lo >>> 0, scratchHash.h1hi >>> 0, this.#seed);
268
293
  const mlo = RLO;
269
294
  const mhi = RHI;
270
295
  positionsInto(mlo, mhi, this.#seg, this.#segMask, this.#segCountLen, this.#pos);
@@ -275,18 +300,65 @@ var BinaryFuse = class {
275
300
  return ((mlo ^ mhi) & mask) === (((this.#fp[p0] ?? 0) ^ (this.#fp[p1] ?? 0) ^ (this.#fp[p2] ?? 0)) & mask);
276
301
  }
277
302
  };
303
+ /**
304
+ * A static 8-bit binary fuse filter: built once from a key set, then immutable.
305
+ * The most space-efficient option (~9 bits/key at ~0.39% false-positive rate).
306
+ *
307
+ * @example
308
+ * ```ts
309
+ * const filter = BinaryFuse8.from(["alice", "bob", "carol"]);
310
+ * filter.has("alice"); // true
311
+ * filter.size; // 3
312
+ * ```
313
+ */
278
314
  var BinaryFuse8 = class BinaryFuse8 extends BinaryFuse {
315
+ /**
316
+ * Builds a filter from the given keys; duplicates are ignored.
317
+ *
318
+ * @param keys - The complete set of keys to store.
319
+ * @returns A new immutable filter.
320
+ * @throws {@link BinaryFuseBuildError} if construction fails to converge.
321
+ */
279
322
  static from(keys) {
280
323
  return new BinaryFuse8(buildState(keys, (n) => new Uint8Array(n)));
281
324
  }
325
+ /**
326
+ * Restores a filter from its {@link BinaryFuse8.toBytes} serialization.
327
+ *
328
+ * @param bytes - The serialized filter.
329
+ * @returns The reconstructed filter.
330
+ */
282
331
  static fromBytes(bytes) {
283
332
  return new BinaryFuse8(fuseStateFromBytes(bytes, TYPE_FUSE8));
284
333
  }
285
334
  };
335
+ /**
336
+ * A static 16-bit binary fuse filter: like {@link BinaryFuse8} but twice the
337
+ * space (~18 bits/key) for a far lower false-positive rate (~1/65536).
338
+ *
339
+ * @example
340
+ * ```ts
341
+ * const filter = BinaryFuse16.from(["alice", "bob", "carol"]);
342
+ * filter.has("alice"); // true
343
+ * ```
344
+ */
286
345
  var BinaryFuse16 = class BinaryFuse16 extends BinaryFuse {
346
+ /**
347
+ * Builds a filter from the given keys; duplicates are ignored.
348
+ *
349
+ * @param keys - The complete set of keys to store.
350
+ * @returns A new immutable filter.
351
+ * @throws {@link BinaryFuseBuildError} if construction fails to converge.
352
+ */
287
353
  static from(keys) {
288
354
  return new BinaryFuse16(buildState(keys, (n) => new Uint16Array(n)));
289
355
  }
356
+ /**
357
+ * Restores a filter from its {@link BinaryFuse16.toBytes} serialization.
358
+ *
359
+ * @param bytes - The serialized filter.
360
+ * @returns The reconstructed filter.
361
+ */
290
362
  static fromBytes(bytes) {
291
363
  return new BinaryFuse16(fuseStateFromBytes(bytes, TYPE_FUSE16));
292
364
  }
package/dist/index.cjs CHANGED
@@ -1,5 +1,7 @@
1
1
  Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
2
+ //#endregion
2
3
  //#region src/index.ts
3
- const VERSION = "0.1.0";
4
+ /** The installed `distillate` package version. */
5
+ const VERSION = "0.1.2";
4
6
  //#endregion
5
7
  exports.VERSION = VERSION;
package/dist/index.d.cts CHANGED
@@ -1,4 +1,5 @@
1
1
  //#region src/index.d.ts
2
- declare const VERSION = "0.1.0";
2
+ /** The installed `distillate` package version. */
3
+ declare const VERSION: string;
3
4
  //#endregion
4
5
  export { VERSION };