distillate 0.6.0 → 0.8.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.
@@ -1,6 +1,6 @@
1
1
  Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
2
- const require_serialize = require("../serialize-BIIKUHH6.cjs");
3
- const require_params = require("../params--8CNXYWu.cjs");
2
+ const require_serialize = require("../serialize-CXnRWItH.cjs");
3
+ const require_params = require("../params-UTZbJ22c.cjs");
4
4
  //#region src/core/bitset.ts
5
5
  var BitSetRangeError = class extends RangeError {
6
6
  name = "BitSetRangeError";
@@ -33,8 +33,7 @@ var BitSet = class {
33
33
  };
34
34
  //#endregion
35
35
  //#region src/core/sizing.ts
36
- /** Optimal Bloom-filter sizing: `m` bits and `k` hashes for `n` items at target FPR `epsilon`. */
37
- function optimal(n, epsilon) {
36
+ function bloomSizing(n, epsilon) {
38
37
  const m = Math.ceil(-n * Math.log(epsilon) / (Math.LN2 * Math.LN2));
39
38
  return {
40
39
  m,
@@ -44,23 +43,9 @@ function optimal(n, epsilon) {
44
43
  //#endregion
45
44
  //#region src/bloom/bloom.ts
46
45
  const TYPE = 1;
47
- /** Thrown when an operation requires two filters built with identical parameters. */
48
46
  var BloomParamMismatchError = class extends Error {
49
- /** Discriminates this error from other `Error`s. */
50
47
  name = "BloomParamMismatchError";
51
48
  };
52
- /**
53
- * A classic Bloom filter: a space-efficient set with a tunable false-positive
54
- * rate and zero false negatives.
55
- *
56
- * @example
57
- * ```ts
58
- * const filter = BloomFilter.create(100_000, 0.01);
59
- * filter.add("alice");
60
- * filter.has("alice"); // true
61
- * filter.has("bob"); // false (or a ~1% false positive)
62
- * ```
63
- */
64
49
  var BloomFilter = class BloomFilter {
65
50
  #bits;
66
51
  #m;
@@ -68,40 +53,18 @@ var BloomFilter = class BloomFilter {
68
53
  #seed;
69
54
  #scratch;
70
55
  #n;
71
- /**
72
- * Creates a filter sized for `n` expected keys at a target false-positive rate.
73
- *
74
- * @param n - Expected number of keys.
75
- * @param epsilon - Target false-positive rate, e.g. `0.01` for 1%.
76
- * @returns A new, empty filter.
77
- */
78
56
  static create(n, epsilon) {
79
57
  require_params.assertPositiveInt(n, "n");
80
58
  require_params.assertUint32(n, "n");
81
59
  require_params.assertProbability(epsilon, "epsilon");
82
- return BloomFilter.#withN(optimal(n, epsilon), n);
60
+ return BloomFilter.#withN(bloomSizing(n, epsilon), n);
83
61
  }
84
- /**
85
- * Builds a filter from `keys`, sized for their count at the target
86
- * false-positive rate. The ergonomic entry point when the key set is already
87
- * in hand; use {@link BloomFilter.create} to size for a count known ahead.
88
- *
89
- * @param keys - The keys to insert.
90
- * @param epsilon - Target false-positive rate, e.g. `0.01` for 1%.
91
- * @returns A new filter containing every key.
92
- */
93
62
  static from(keys, epsilon) {
94
63
  const arr = [...keys];
95
64
  const f = BloomFilter.create(Math.max(1, arr.length), epsilon);
96
65
  for (const k of arr) f.add(k);
97
66
  return f;
98
67
  }
99
- /**
100
- * Restores a filter from its {@link BloomFilter.toBytes} serialization.
101
- *
102
- * @param bytes - The serialized filter.
103
- * @returns The reconstructed filter.
104
- */
105
68
  static fromBytes(bytes) {
106
69
  const { type, flags, body } = require_serialize.readHeader(bytes);
107
70
  if (type !== TYPE) throw new require_serialize.SerializationError(`expected AMQF type ${String(TYPE)}, got ${String(type)}`);
@@ -121,10 +84,6 @@ var BloomFilter = class BloomFilter {
121
84
  f.#bits.bytes.set(body.subarray(14));
122
85
  return f;
123
86
  }
124
- /**
125
- * Constructs a filter from low-level {@link BloomParams}. Prefer
126
- * {@link BloomFilter.create} unless restoring a specific configuration.
127
- */
128
87
  constructor({ m, k, seed = 0 }) {
129
88
  require_params.assertPositiveInt(m, "m");
130
89
  require_params.assertUint32(m, "m");
@@ -143,41 +102,24 @@ var BloomFilter = class BloomFilter {
143
102
  f.#n = n;
144
103
  return f;
145
104
  }
146
- /** Number of bits in the filter. */
147
105
  get m() {
148
106
  return this.#m;
149
107
  }
150
- /** Number of hash probes per key. */
151
108
  get k() {
152
109
  return this.#k;
153
110
  }
154
- /** Hash seed. */
155
111
  get seed() {
156
112
  return this.#seed;
157
113
  }
158
- /** Number of bits currently set. */
159
114
  get length() {
160
115
  return this.#bits.count();
161
116
  }
162
- /** Analytic design bits-per-key `m / n`. */
163
117
  get bitsPerKey() {
164
118
  return this.#m / this.#n;
165
119
  }
166
- /**
167
- * Estimates the current false-positive rate from the actual fill,
168
- * `(length / m) ** k`. This reflects how full the filter is right now, not
169
- * the design target; it rises as keys are added.
170
- *
171
- * @returns The estimated false-positive rate, `0` for an empty filter.
172
- */
173
120
  rate() {
174
121
  return (this.length / this.#m) ** this.#k;
175
122
  }
176
- /**
177
- * Serializes the filter to a portable little-endian byte layout.
178
- *
179
- * @returns The serialized filter, readable by {@link BloomFilter.fromBytes}.
180
- */
181
123
  toBytes() {
182
124
  const payload = this.#bits.bytes;
183
125
  return require_serialize.writeFrame({
@@ -192,41 +134,15 @@ var BloomFilter = class BloomFilter {
192
134
  body.set(payload, 14);
193
135
  });
194
136
  }
195
- /**
196
- * Tests structural equality: `true` when `other` serializes to identical
197
- * bytes, meaning identical parameters and set bits.
198
- *
199
- * @param other - The filter to compare against.
200
- * @returns `true` if the two filters are byte-for-byte identical.
201
- */
202
137
  equals(other) {
203
138
  return require_serialize.bytesEqual(this.toBytes(), other.toBytes());
204
139
  }
205
- /**
206
- * Serializes the filter to a JSON-friendly envelope wrapping the base64 of
207
- * {@link BloomFilter.toBytes}.
208
- *
209
- * @returns The envelope, readable by {@link BloomFilter.fromJSON}.
210
- */
211
140
  toJSON() {
212
141
  return require_serialize.toJSONEnvelope(this.toBytes());
213
142
  }
214
- /**
215
- * Restores a filter from its {@link BloomFilter.toJSON} envelope.
216
- *
217
- * @param value - The JSON envelope.
218
- * @returns The reconstructed filter.
219
- */
220
143
  static fromJSON(value) {
221
144
  return BloomFilter.fromBytes(require_serialize.fromJSONEnvelope(value));
222
145
  }
223
- /**
224
- * Returns a new filter containing the union of this filter and `other`.
225
- *
226
- * @param other - A filter built with identical parameters.
227
- * @returns A new filter reporting membership for keys in either input.
228
- * @throws {@link BloomParamMismatchError} if the parameters differ.
229
- */
230
146
  union(other) {
231
147
  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");
232
148
  const a = this.#bits.bytes;
@@ -241,21 +157,10 @@ var BloomFilter = class BloomFilter {
241
157
  r.#bits.bytes.set(merged);
242
158
  return r;
243
159
  }
244
- /**
245
- * Adds a key to the set.
246
- *
247
- * @param key - The key to insert, as a string or bytes.
248
- */
249
160
  add(key) {
250
161
  require_serialize.probeInto(key, this.#k, this.#m, this.#seed, this.#scratch);
251
162
  for (let i = 0; i < this.#k; i++) this.#bits.set(this.#scratch[i] ?? 0);
252
163
  }
253
- /**
254
- * Tests whether a key is in the set.
255
- *
256
- * @param key - The key to test.
257
- * @returns `true` if present (possibly a false positive); `false` guarantees absence.
258
- */
259
164
  has(key) {
260
165
  require_serialize.probeInto(key, this.#k, this.#m, this.#seed, this.#scratch);
261
166
  for (let i = 0; i < this.#k; i++) if (!this.#bits.get(this.#scratch[i] ?? 0)) return false;
@@ -263,6 +168,13 @@ var BloomFilter = class BloomFilter {
263
168
  }
264
169
  };
265
170
  //#endregion
171
+ exports.BadMagicError = require_serialize.BadMagicError;
266
172
  exports.BloomFilter = BloomFilter;
267
173
  exports.BloomParamMismatchError = BloomParamMismatchError;
174
+ exports.ChecksumError = require_serialize.ChecksumError;
268
175
  exports.ParamError = require_params.ParamError;
176
+ exports.SerializationError = require_serialize.SerializationError;
177
+ exports.TruncatedError = require_serialize.TruncatedError;
178
+ exports.UnknownHashVariantError = require_serialize.UnknownHashVariantError;
179
+ exports.UnknownVersionError = require_serialize.UnknownVersionError;
180
+ exports.bloomSizing = bloomSizing;
@@ -1,4 +1,4 @@
1
- import { n as BytesLike, t as FilterJSON } from "../serialize-DRKh6QOr.cjs";
1
+ import { a as TruncatedError, c as BytesLike, i as SerializationError, n as ChecksumError, o as UnknownHashVariantError, r as FilterJSON, s as UnknownVersionError, t as BadMagicError } from "../serialize-ChyWpB9F.cjs";
2
2
  import { t as ParamError } from "../params-DnqJBqLS.cjs";
3
3
  //#region src/bloom/bloom.d.ts
4
4
  /** Thrown when an operation requires two filters built with identical parameters. */
@@ -128,4 +128,15 @@ declare class BloomFilter {
128
128
  has(key: BytesLike): boolean;
129
129
  }
130
130
  //#endregion
131
- export { BloomFilter, BloomParamMismatchError, type BloomParams, type FilterJSON, ParamError };
131
+ //#region src/core/sizing.d.ts
132
+ /** Bloom filter geometry: the `BloomParams` fields a sizing solve determines. */
133
+ interface BloomSizing {
134
+ /** Number of bits in the filter. */
135
+ m: number;
136
+ /** Number of hash probes per key. */
137
+ k: number;
138
+ }
139
+ /** Optimal Bloom-filter sizing: `m` bits and `k` hashes for `n` items at target FPR `epsilon`. */
140
+ declare function bloomSizing(n: number, epsilon: number): BloomSizing;
141
+ //#endregion
142
+ export { BadMagicError, BloomFilter, BloomParamMismatchError, type BloomParams, type BloomSizing, ChecksumError, type FilterJSON, ParamError, SerializationError, TruncatedError, UnknownHashVariantError, UnknownVersionError, bloomSizing };
@@ -1,4 +1,4 @@
1
- import { n as BytesLike, t as FilterJSON } from "../serialize-DRKh6QOr.js";
1
+ import { a as TruncatedError, c as BytesLike, i as SerializationError, n as ChecksumError, o as UnknownHashVariantError, r as FilterJSON, s as UnknownVersionError, t as BadMagicError } from "../serialize-ChyWpB9F.js";
2
2
  import { t as ParamError } from "../params-DnqJBqLS.js";
3
3
  //#region src/bloom/bloom.d.ts
4
4
  /** Thrown when an operation requires two filters built with identical parameters. */
@@ -128,4 +128,15 @@ declare class BloomFilter {
128
128
  has(key: BytesLike): boolean;
129
129
  }
130
130
  //#endregion
131
- export { BloomFilter, BloomParamMismatchError, type BloomParams, type FilterJSON, ParamError };
131
+ //#region src/core/sizing.d.ts
132
+ /** Bloom filter geometry: the `BloomParams` fields a sizing solve determines. */
133
+ interface BloomSizing {
134
+ /** Number of bits in the filter. */
135
+ m: number;
136
+ /** Number of hash probes per key. */
137
+ k: number;
138
+ }
139
+ /** Optimal Bloom-filter sizing: `m` bits and `k` hashes for `n` items at target FPR `epsilon`. */
140
+ declare function bloomSizing(n: number, epsilon: number): BloomSizing;
141
+ //#endregion
142
+ export { BadMagicError, BloomFilter, BloomParamMismatchError, type BloomParams, type BloomSizing, ChecksumError, type FilterJSON, ParamError, SerializationError, TruncatedError, UnknownHashVariantError, UnknownVersionError, bloomSizing };
@@ -1,5 +1,5 @@
1
- import { a as bytesEqual, c as toJSONEnvelope, g as probeInto, i as assertMinBodyLength, l as writeFrame, n as UnknownHashVariantError, o as fromJSONEnvelope, r as assertBodyLength, s as readHeader, t as SerializationError } from "../serialize-BnwtzcMw.js";
2
- import { a as assertUint16, i as assertProbability, o as assertUint32, r as assertPositiveInt, t as ParamError } from "../params-BrWuBC2A.js";
1
+ import { a as UnknownHashVariantError, b as probeInto, c as assertMinBodyLength, d as readHeader, f as toJSONEnvelope, i as TruncatedError, l as bytesEqual, n as ChecksumError, o as UnknownVersionError, p as writeFrame, r as SerializationError, s as assertBodyLength, t as BadMagicError, u as fromJSONEnvelope } from "../serialize-BqIcsR2J.js";
2
+ import { a as assertUint16, i as assertProbability, o as assertUint32, r as assertPositiveInt, t as ParamError } from "../params-CeajSrwv.js";
3
3
  //#region src/core/bitset.ts
4
4
  var BitSetRangeError = class extends RangeError {
5
5
  name = "BitSetRangeError";
@@ -32,8 +32,7 @@ var BitSet = class {
32
32
  };
33
33
  //#endregion
34
34
  //#region src/core/sizing.ts
35
- /** Optimal Bloom-filter sizing: `m` bits and `k` hashes for `n` items at target FPR `epsilon`. */
36
- function optimal(n, epsilon) {
35
+ function bloomSizing(n, epsilon) {
37
36
  const m = Math.ceil(-n * Math.log(epsilon) / (Math.LN2 * Math.LN2));
38
37
  return {
39
38
  m,
@@ -43,23 +42,9 @@ function optimal(n, epsilon) {
43
42
  //#endregion
44
43
  //#region src/bloom/bloom.ts
45
44
  const TYPE = 1;
46
- /** Thrown when an operation requires two filters built with identical parameters. */
47
45
  var BloomParamMismatchError = class extends Error {
48
- /** Discriminates this error from other `Error`s. */
49
46
  name = "BloomParamMismatchError";
50
47
  };
51
- /**
52
- * A classic Bloom filter: a space-efficient set with a tunable false-positive
53
- * rate and zero false negatives.
54
- *
55
- * @example
56
- * ```ts
57
- * const filter = BloomFilter.create(100_000, 0.01);
58
- * filter.add("alice");
59
- * filter.has("alice"); // true
60
- * filter.has("bob"); // false (or a ~1% false positive)
61
- * ```
62
- */
63
48
  var BloomFilter = class BloomFilter {
64
49
  #bits;
65
50
  #m;
@@ -67,40 +52,18 @@ var BloomFilter = class BloomFilter {
67
52
  #seed;
68
53
  #scratch;
69
54
  #n;
70
- /**
71
- * Creates a filter sized for `n` expected keys at a target false-positive rate.
72
- *
73
- * @param n - Expected number of keys.
74
- * @param epsilon - Target false-positive rate, e.g. `0.01` for 1%.
75
- * @returns A new, empty filter.
76
- */
77
55
  static create(n, epsilon) {
78
56
  assertPositiveInt(n, "n");
79
57
  assertUint32(n, "n");
80
58
  assertProbability(epsilon, "epsilon");
81
- return BloomFilter.#withN(optimal(n, epsilon), n);
59
+ return BloomFilter.#withN(bloomSizing(n, epsilon), n);
82
60
  }
83
- /**
84
- * Builds a filter from `keys`, sized for their count at the target
85
- * false-positive rate. The ergonomic entry point when the key set is already
86
- * in hand; use {@link BloomFilter.create} to size for a count known ahead.
87
- *
88
- * @param keys - The keys to insert.
89
- * @param epsilon - Target false-positive rate, e.g. `0.01` for 1%.
90
- * @returns A new filter containing every key.
91
- */
92
61
  static from(keys, epsilon) {
93
62
  const arr = [...keys];
94
63
  const f = BloomFilter.create(Math.max(1, arr.length), epsilon);
95
64
  for (const k of arr) f.add(k);
96
65
  return f;
97
66
  }
98
- /**
99
- * Restores a filter from its {@link BloomFilter.toBytes} serialization.
100
- *
101
- * @param bytes - The serialized filter.
102
- * @returns The reconstructed filter.
103
- */
104
67
  static fromBytes(bytes) {
105
68
  const { type, flags, body } = readHeader(bytes);
106
69
  if (type !== TYPE) throw new SerializationError(`expected AMQF type ${String(TYPE)}, got ${String(type)}`);
@@ -120,10 +83,6 @@ var BloomFilter = class BloomFilter {
120
83
  f.#bits.bytes.set(body.subarray(14));
121
84
  return f;
122
85
  }
123
- /**
124
- * Constructs a filter from low-level {@link BloomParams}. Prefer
125
- * {@link BloomFilter.create} unless restoring a specific configuration.
126
- */
127
86
  constructor({ m, k, seed = 0 }) {
128
87
  assertPositiveInt(m, "m");
129
88
  assertUint32(m, "m");
@@ -142,41 +101,24 @@ var BloomFilter = class BloomFilter {
142
101
  f.#n = n;
143
102
  return f;
144
103
  }
145
- /** Number of bits in the filter. */
146
104
  get m() {
147
105
  return this.#m;
148
106
  }
149
- /** Number of hash probes per key. */
150
107
  get k() {
151
108
  return this.#k;
152
109
  }
153
- /** Hash seed. */
154
110
  get seed() {
155
111
  return this.#seed;
156
112
  }
157
- /** Number of bits currently set. */
158
113
  get length() {
159
114
  return this.#bits.count();
160
115
  }
161
- /** Analytic design bits-per-key `m / n`. */
162
116
  get bitsPerKey() {
163
117
  return this.#m / this.#n;
164
118
  }
165
- /**
166
- * Estimates the current false-positive rate from the actual fill,
167
- * `(length / m) ** k`. This reflects how full the filter is right now, not
168
- * the design target; it rises as keys are added.
169
- *
170
- * @returns The estimated false-positive rate, `0` for an empty filter.
171
- */
172
119
  rate() {
173
120
  return (this.length / this.#m) ** this.#k;
174
121
  }
175
- /**
176
- * Serializes the filter to a portable little-endian byte layout.
177
- *
178
- * @returns The serialized filter, readable by {@link BloomFilter.fromBytes}.
179
- */
180
122
  toBytes() {
181
123
  const payload = this.#bits.bytes;
182
124
  return writeFrame({
@@ -191,41 +133,15 @@ var BloomFilter = class BloomFilter {
191
133
  body.set(payload, 14);
192
134
  });
193
135
  }
194
- /**
195
- * Tests structural equality: `true` when `other` serializes to identical
196
- * bytes, meaning identical parameters and set bits.
197
- *
198
- * @param other - The filter to compare against.
199
- * @returns `true` if the two filters are byte-for-byte identical.
200
- */
201
136
  equals(other) {
202
137
  return bytesEqual(this.toBytes(), other.toBytes());
203
138
  }
204
- /**
205
- * Serializes the filter to a JSON-friendly envelope wrapping the base64 of
206
- * {@link BloomFilter.toBytes}.
207
- *
208
- * @returns The envelope, readable by {@link BloomFilter.fromJSON}.
209
- */
210
139
  toJSON() {
211
140
  return toJSONEnvelope(this.toBytes());
212
141
  }
213
- /**
214
- * Restores a filter from its {@link BloomFilter.toJSON} envelope.
215
- *
216
- * @param value - The JSON envelope.
217
- * @returns The reconstructed filter.
218
- */
219
142
  static fromJSON(value) {
220
143
  return BloomFilter.fromBytes(fromJSONEnvelope(value));
221
144
  }
222
- /**
223
- * Returns a new filter containing the union of this filter and `other`.
224
- *
225
- * @param other - A filter built with identical parameters.
226
- * @returns A new filter reporting membership for keys in either input.
227
- * @throws {@link BloomParamMismatchError} if the parameters differ.
228
- */
229
145
  union(other) {
230
146
  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");
231
147
  const a = this.#bits.bytes;
@@ -240,21 +156,10 @@ var BloomFilter = class BloomFilter {
240
156
  r.#bits.bytes.set(merged);
241
157
  return r;
242
158
  }
243
- /**
244
- * Adds a key to the set.
245
- *
246
- * @param key - The key to insert, as a string or bytes.
247
- */
248
159
  add(key) {
249
160
  probeInto(key, this.#k, this.#m, this.#seed, this.#scratch);
250
161
  for (let i = 0; i < this.#k; i++) this.#bits.set(this.#scratch[i] ?? 0);
251
162
  }
252
- /**
253
- * Tests whether a key is in the set.
254
- *
255
- * @param key - The key to test.
256
- * @returns `true` if present (possibly a false positive); `false` guarantees absence.
257
- */
258
163
  has(key) {
259
164
  probeInto(key, this.#k, this.#m, this.#seed, this.#scratch);
260
165
  for (let i = 0; i < this.#k; i++) if (!this.#bits.get(this.#scratch[i] ?? 0)) return false;
@@ -262,4 +167,4 @@ var BloomFilter = class BloomFilter {
262
167
  }
263
168
  };
264
169
  //#endregion
265
- export { BloomFilter, BloomParamMismatchError, ParamError };
170
+ export { BadMagicError, BloomFilter, BloomParamMismatchError, ChecksumError, ParamError, SerializationError, TruncatedError, UnknownHashVariantError, UnknownVersionError, bloomSizing };
@@ -1,12 +1,10 @@
1
1
  Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
2
- const require_serialize = require("../serialize-BIIKUHH6.cjs");
2
+ const require_serialize = require("../serialize-CXnRWItH.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. */
8
7
  var BinaryFuseBuildError = class extends Error {
9
- /** Discriminates this error from other `Error`s. */
10
8
  name = "BinaryFuseBuildError";
11
9
  };
12
10
  const scratchHash = {
@@ -59,11 +57,10 @@ function computeParams(size) {
59
57
  arrayLength
60
58
  };
61
59
  }
62
- /**
63
- * Peel the 3-hypergraph and assign fingerprints so every key's XOR of its 3
64
- * lanes equals its fingerprint. Retries with a bumped seed on a stall; returns
65
- * the seed that succeeded.
66
- */
60
+ function fuseBitsPerKey(n, width) {
61
+ if (n === 0) return 0;
62
+ return computeParams(n).arrayLength * width / n;
63
+ }
67
64
  function buildFingerprints(fp, hashes, params, maxAttempts = 100) {
68
65
  const size = hashes.length / 2;
69
66
  const { seg, segMask, segCountLen, arrayLength } = params;
@@ -74,7 +71,7 @@ function buildFingerprints(fp, hashes, params, maxAttempts = 100) {
74
71
  const orderLo = new Uint32Array(size);
75
72
  const orderHi = new Uint32Array(size);
76
73
  const orderIdx = new Uint32Array(size);
77
- const pos = /* @__PURE__ */ new Uint32Array(3);
74
+ const pos = new Uint32Array(3);
78
75
  for (let attempt = 0; attempt < maxAttempts; attempt++) {
79
76
  const seed = attempt;
80
77
  counts.fill(0);
@@ -133,7 +130,7 @@ function buildFingerprints(fp, hashes, params, maxAttempts = 100) {
133
130
  }
134
131
  function buildState(keys, alloc) {
135
132
  const hashList = [];
136
- const seen = /* @__PURE__ */ new Set();
133
+ const seen = new Set();
137
134
  for (const key of keys) {
138
135
  require_serialize.hash128KeyInto(key, 0, scratchHash);
139
136
  const lo = scratchHash.w0 >>> 0;
@@ -191,10 +188,6 @@ function fuseStateFromBytes(bytes, expectedType) {
191
188
  size
192
189
  };
193
190
  }
194
- /**
195
- * Shared behavior for the static binary fuse filters: an immutable,
196
- * space-efficient membership filter built once from a fixed key set.
197
- */
198
191
  var BinaryFuse = class {
199
192
  #fp;
200
193
  #seed;
@@ -202,7 +195,7 @@ var BinaryFuse = class {
202
195
  #segMask;
203
196
  #segCountLen;
204
197
  #size;
205
- #pos = /* @__PURE__ */ new Uint32Array(3);
198
+ #pos = new Uint32Array(3);
206
199
  constructor(state) {
207
200
  this.#fp = state.fp;
208
201
  this.#seed = state.seed;
@@ -211,23 +204,15 @@ var BinaryFuse = class {
211
204
  this.#segCountLen = state.params.segCountLen;
212
205
  this.#size = state.size;
213
206
  }
214
- /** Number of distinct keys the filter was built from. */
215
207
  get size() {
216
208
  return this.#size;
217
209
  }
218
- /** Hash seed selected during construction (may differ from 0 after a peel retry). */
219
210
  get seed() {
220
211
  return this.#seed;
221
212
  }
222
- /** Actual bits stored per key (`0` for an empty filter). */
223
213
  get bitsPerKey() {
224
214
  return this.#size === 0 ? 0 : this.#fp.byteLength * 8 / this.#size;
225
215
  }
226
- /**
227
- * Serializes the filter to a portable little-endian byte layout.
228
- *
229
- * @returns The serialized filter, readable by the matching `fromBytes`.
230
- */
231
216
  toBytes() {
232
217
  const laneBytes = new Uint8Array(this.#fp.buffer, this.#fp.byteOffset, this.#fp.byteLength);
233
218
  return require_serialize.writeFrame({
@@ -242,12 +227,6 @@ var BinaryFuse = class {
242
227
  body.set(laneBytes, 16);
243
228
  });
244
229
  }
245
- /**
246
- * Tests whether a key is in the set.
247
- *
248
- * @param key - The key to test.
249
- * @returns `true` if present (possibly a false positive); `false` guarantees absence.
250
- */
251
230
  has(key) {
252
231
  if (this.#fp.length === 0) return false;
253
232
  require_serialize.hash128KeyInto(key, 0, scratchHash);
@@ -261,109 +240,43 @@ var BinaryFuse = class {
261
240
  const p2 = this.#pos[2] ?? 0;
262
241
  return ((mlo ^ mhi) & mask) === (((this.#fp[p0] ?? 0) ^ (this.#fp[p1] ?? 0) ^ (this.#fp[p2] ?? 0)) & mask);
263
242
  }
264
- /**
265
- * Tests structural equality: `true` when `other` serializes to identical
266
- * bytes. A {@link BinaryFuse8} and a {@link BinaryFuse16} are never equal,
267
- * since their frames carry different type bytes.
268
- *
269
- * @param other - The filter to compare against.
270
- * @returns `true` if the two filters are byte-for-byte identical.
271
- */
272
243
  equals(other) {
273
244
  return require_serialize.bytesEqual(this.toBytes(), other.toBytes());
274
245
  }
275
- /**
276
- * Serializes the filter to a JSON-friendly envelope wrapping the base64 of
277
- * the `toBytes` frame.
278
- *
279
- * @returns The envelope, readable by the matching `fromJSON`.
280
- */
281
246
  toJSON() {
282
247
  return require_serialize.toJSONEnvelope(this.toBytes());
283
248
  }
284
249
  };
285
- /**
286
- * A static 8-bit binary fuse filter: built once from a key set, then immutable.
287
- * The most space-efficient option (~9 bits/key at ~0.39% false-positive rate).
288
- *
289
- * @example
290
- * ```ts
291
- * const filter = BinaryFuse8.from(["alice", "bob", "carol"]);
292
- * filter.has("alice"); // true
293
- * filter.size; // 3
294
- * ```
295
- */
296
250
  var BinaryFuse8 = class BinaryFuse8 extends BinaryFuse {
297
- /**
298
- * Builds a filter from the given keys; duplicates are ignored.
299
- *
300
- * @param keys - The complete set of keys to store.
301
- * @returns A new immutable filter.
302
- * @throws {@link BinaryFuseBuildError} if construction fails to converge.
303
- */
304
251
  static from(keys) {
305
252
  return new BinaryFuse8(buildState(keys, (n) => new Uint8Array(n)));
306
253
  }
307
- /**
308
- * Restores a filter from its {@link BinaryFuse8.toBytes} serialization.
309
- *
310
- * @param bytes - The serialized filter.
311
- * @returns The reconstructed filter.
312
- */
313
254
  static fromBytes(bytes) {
314
255
  return new BinaryFuse8(fuseStateFromBytes(bytes, TYPE_FUSE8));
315
256
  }
316
- /**
317
- * Restores a filter from its {@link BinaryFuse8.toJSON} envelope.
318
- *
319
- * @param value - The JSON envelope.
320
- * @returns The reconstructed filter.
321
- */
322
257
  static fromJSON(value) {
323
258
  return BinaryFuse8.fromBytes(require_serialize.fromJSONEnvelope(value));
324
259
  }
325
260
  };
326
- /**
327
- * A static 16-bit binary fuse filter: like {@link BinaryFuse8} but twice the
328
- * space (~18 bits/key) for a far lower false-positive rate (~1/65536).
329
- *
330
- * @example
331
- * ```ts
332
- * const filter = BinaryFuse16.from(["alice", "bob", "carol"]);
333
- * filter.has("alice"); // true
334
- * ```
335
- */
336
261
  var BinaryFuse16 = class BinaryFuse16 extends BinaryFuse {
337
- /**
338
- * Builds a filter from the given keys; duplicates are ignored.
339
- *
340
- * @param keys - The complete set of keys to store.
341
- * @returns A new immutable filter.
342
- * @throws {@link BinaryFuseBuildError} if construction fails to converge.
343
- */
344
262
  static from(keys) {
345
263
  return new BinaryFuse16(buildState(keys, (n) => new Uint16Array(n)));
346
264
  }
347
- /**
348
- * Restores a filter from its {@link BinaryFuse16.toBytes} serialization.
349
- *
350
- * @param bytes - The serialized filter.
351
- * @returns The reconstructed filter.
352
- */
353
265
  static fromBytes(bytes) {
354
266
  return new BinaryFuse16(fuseStateFromBytes(bytes, TYPE_FUSE16));
355
267
  }
356
- /**
357
- * Restores a filter from its {@link BinaryFuse16.toJSON} envelope.
358
- *
359
- * @param value - The JSON envelope.
360
- * @returns The reconstructed filter.
361
- */
362
268
  static fromJSON(value) {
363
269
  return BinaryFuse16.fromBytes(require_serialize.fromJSONEnvelope(value));
364
270
  }
365
271
  };
366
272
  //#endregion
273
+ exports.BadMagicError = require_serialize.BadMagicError;
367
274
  exports.BinaryFuse16 = BinaryFuse16;
368
275
  exports.BinaryFuse8 = BinaryFuse8;
369
276
  exports.BinaryFuseBuildError = BinaryFuseBuildError;
277
+ exports.ChecksumError = require_serialize.ChecksumError;
278
+ exports.SerializationError = require_serialize.SerializationError;
279
+ exports.TruncatedError = require_serialize.TruncatedError;
280
+ exports.UnknownHashVariantError = require_serialize.UnknownHashVariantError;
281
+ exports.UnknownVersionError = require_serialize.UnknownVersionError;
282
+ exports.fuseBitsPerKey = fuseBitsPerKey;