distillate 0.7.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,11 +1,9 @@
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";
1
+ import { _ as hash128KeyInto, a as UnknownHashVariantError, c as assertMinBodyLength, d as readHeader, f as toJSONEnvelope, g as fmix64, h as RLO, i as TruncatedError, l as bytesEqual, m as RHI, n as ChecksumError, o as UnknownVersionError, p as writeFrame, r as SerializationError, s as assertBodyLength, t as BadMagicError, u as fromJSONEnvelope, y as mul64 } from "../serialize-BqIcsR2J.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. */
7
6
  var BinaryFuseBuildError = class extends Error {
8
- /** Discriminates this error from other `Error`s. */
9
7
  name = "BinaryFuseBuildError";
10
8
  };
11
9
  const scratchHash = {
@@ -58,24 +56,10 @@ function computeParams(size) {
58
56
  arrayLength
59
57
  };
60
58
  }
61
- /**
62
- * Bits stored per key by a binary fuse filter over `n` keys at a fingerprint
63
- * width, without building one. Counts `n` as distinct keys, since a built
64
- * filter sizes on its deduped hash count.
65
- *
66
- * @param n - Number of distinct keys.
67
- * @param width - Fingerprint width in bits: `8` for {@link BinaryFuse8}, `16` for {@link BinaryFuse16}.
68
- * @returns Bits per key (`0` for an empty filter).
69
- */
70
59
  function fuseBitsPerKey(n, width) {
71
60
  if (n === 0) return 0;
72
61
  return computeParams(n).arrayLength * width / n;
73
62
  }
74
- /**
75
- * Peel the 3-hypergraph and assign fingerprints so every key's XOR of its 3
76
- * lanes equals its fingerprint. Retries with a bumped seed on a stall; returns
77
- * the seed that succeeded.
78
- */
79
63
  function buildFingerprints(fp, hashes, params, maxAttempts = 100) {
80
64
  const size = hashes.length / 2;
81
65
  const { seg, segMask, segCountLen, arrayLength } = params;
@@ -86,7 +70,7 @@ function buildFingerprints(fp, hashes, params, maxAttempts = 100) {
86
70
  const orderLo = new Uint32Array(size);
87
71
  const orderHi = new Uint32Array(size);
88
72
  const orderIdx = new Uint32Array(size);
89
- const pos = /* @__PURE__ */ new Uint32Array(3);
73
+ const pos = new Uint32Array(3);
90
74
  for (let attempt = 0; attempt < maxAttempts; attempt++) {
91
75
  const seed = attempt;
92
76
  counts.fill(0);
@@ -145,7 +129,7 @@ function buildFingerprints(fp, hashes, params, maxAttempts = 100) {
145
129
  }
146
130
  function buildState(keys, alloc) {
147
131
  const hashList = [];
148
- const seen = /* @__PURE__ */ new Set();
132
+ const seen = new Set();
149
133
  for (const key of keys) {
150
134
  hash128KeyInto(key, 0, scratchHash);
151
135
  const lo = scratchHash.w0 >>> 0;
@@ -203,10 +187,6 @@ function fuseStateFromBytes(bytes, expectedType) {
203
187
  size
204
188
  };
205
189
  }
206
- /**
207
- * Shared behavior for the static binary fuse filters: an immutable,
208
- * space-efficient membership filter built once from a fixed key set.
209
- */
210
190
  var BinaryFuse = class {
211
191
  #fp;
212
192
  #seed;
@@ -214,7 +194,7 @@ var BinaryFuse = class {
214
194
  #segMask;
215
195
  #segCountLen;
216
196
  #size;
217
- #pos = /* @__PURE__ */ new Uint32Array(3);
197
+ #pos = new Uint32Array(3);
218
198
  constructor(state) {
219
199
  this.#fp = state.fp;
220
200
  this.#seed = state.seed;
@@ -223,23 +203,15 @@ var BinaryFuse = class {
223
203
  this.#segCountLen = state.params.segCountLen;
224
204
  this.#size = state.size;
225
205
  }
226
- /** Number of distinct keys the filter was built from. */
227
206
  get size() {
228
207
  return this.#size;
229
208
  }
230
- /** Hash seed selected during construction (may differ from 0 after a peel retry). */
231
209
  get seed() {
232
210
  return this.#seed;
233
211
  }
234
- /** Actual bits stored per key (`0` for an empty filter). */
235
212
  get bitsPerKey() {
236
213
  return this.#size === 0 ? 0 : this.#fp.byteLength * 8 / this.#size;
237
214
  }
238
- /**
239
- * Serializes the filter to a portable little-endian byte layout.
240
- *
241
- * @returns The serialized filter, readable by the matching `fromBytes`.
242
- */
243
215
  toBytes() {
244
216
  const laneBytes = new Uint8Array(this.#fp.buffer, this.#fp.byteOffset, this.#fp.byteLength);
245
217
  return writeFrame({
@@ -254,12 +226,6 @@ var BinaryFuse = class {
254
226
  body.set(laneBytes, 16);
255
227
  });
256
228
  }
257
- /**
258
- * Tests whether a key is in the set.
259
- *
260
- * @param key - The key to test.
261
- * @returns `true` if present (possibly a false positive); `false` guarantees absence.
262
- */
263
229
  has(key) {
264
230
  if (this.#fp.length === 0) return false;
265
231
  hash128KeyInto(key, 0, scratchHash);
@@ -273,107 +239,34 @@ var BinaryFuse = class {
273
239
  const p2 = this.#pos[2] ?? 0;
274
240
  return ((mlo ^ mhi) & mask) === (((this.#fp[p0] ?? 0) ^ (this.#fp[p1] ?? 0) ^ (this.#fp[p2] ?? 0)) & mask);
275
241
  }
276
- /**
277
- * Tests structural equality: `true` when `other` serializes to identical
278
- * bytes. A {@link BinaryFuse8} and a {@link BinaryFuse16} are never equal,
279
- * since their frames carry different type bytes.
280
- *
281
- * @param other - The filter to compare against.
282
- * @returns `true` if the two filters are byte-for-byte identical.
283
- */
284
242
  equals(other) {
285
243
  return bytesEqual(this.toBytes(), other.toBytes());
286
244
  }
287
- /**
288
- * Serializes the filter to a JSON-friendly envelope wrapping the base64 of
289
- * the `toBytes` frame.
290
- *
291
- * @returns The envelope, readable by the matching `fromJSON`.
292
- */
293
245
  toJSON() {
294
246
  return toJSONEnvelope(this.toBytes());
295
247
  }
296
248
  };
297
- /**
298
- * A static 8-bit binary fuse filter: built once from a key set, then immutable.
299
- * The most space-efficient option (~9 bits/key at ~0.39% false-positive rate).
300
- *
301
- * @example
302
- * ```ts
303
- * const filter = BinaryFuse8.from(["alice", "bob", "carol"]);
304
- * filter.has("alice"); // true
305
- * filter.size; // 3
306
- * ```
307
- */
308
249
  var BinaryFuse8 = class BinaryFuse8 extends BinaryFuse {
309
- /**
310
- * Builds a filter from the given keys; duplicates are ignored.
311
- *
312
- * @param keys - The complete set of keys to store.
313
- * @returns A new immutable filter.
314
- * @throws {@link BinaryFuseBuildError} if construction fails to converge.
315
- */
316
250
  static from(keys) {
317
251
  return new BinaryFuse8(buildState(keys, (n) => new Uint8Array(n)));
318
252
  }
319
- /**
320
- * Restores a filter from its {@link BinaryFuse8.toBytes} serialization.
321
- *
322
- * @param bytes - The serialized filter.
323
- * @returns The reconstructed filter.
324
- */
325
253
  static fromBytes(bytes) {
326
254
  return new BinaryFuse8(fuseStateFromBytes(bytes, TYPE_FUSE8));
327
255
  }
328
- /**
329
- * Restores a filter from its {@link BinaryFuse8.toJSON} envelope.
330
- *
331
- * @param value - The JSON envelope.
332
- * @returns The reconstructed filter.
333
- */
334
256
  static fromJSON(value) {
335
257
  return BinaryFuse8.fromBytes(fromJSONEnvelope(value));
336
258
  }
337
259
  };
338
- /**
339
- * A static 16-bit binary fuse filter: like {@link BinaryFuse8} but twice the
340
- * space (~18 bits/key) for a far lower false-positive rate (~1/65536).
341
- *
342
- * @example
343
- * ```ts
344
- * const filter = BinaryFuse16.from(["alice", "bob", "carol"]);
345
- * filter.has("alice"); // true
346
- * ```
347
- */
348
260
  var BinaryFuse16 = class BinaryFuse16 extends BinaryFuse {
349
- /**
350
- * Builds a filter from the given keys; duplicates are ignored.
351
- *
352
- * @param keys - The complete set of keys to store.
353
- * @returns A new immutable filter.
354
- * @throws {@link BinaryFuseBuildError} if construction fails to converge.
355
- */
356
261
  static from(keys) {
357
262
  return new BinaryFuse16(buildState(keys, (n) => new Uint16Array(n)));
358
263
  }
359
- /**
360
- * Restores a filter from its {@link BinaryFuse16.toBytes} serialization.
361
- *
362
- * @param bytes - The serialized filter.
363
- * @returns The reconstructed filter.
364
- */
365
264
  static fromBytes(bytes) {
366
265
  return new BinaryFuse16(fuseStateFromBytes(bytes, TYPE_FUSE16));
367
266
  }
368
- /**
369
- * Restores a filter from its {@link BinaryFuse16.toJSON} envelope.
370
- *
371
- * @param value - The JSON envelope.
372
- * @returns The reconstructed filter.
373
- */
374
267
  static fromJSON(value) {
375
268
  return BinaryFuse16.fromBytes(fromJSONEnvelope(value));
376
269
  }
377
270
  };
378
271
  //#endregion
379
- export { BinaryFuse16, BinaryFuse8, BinaryFuseBuildError, fuseBitsPerKey };
272
+ export { BadMagicError, BinaryFuse16, BinaryFuse8, BinaryFuseBuildError, ChecksumError, SerializationError, TruncatedError, UnknownHashVariantError, UnknownVersionError, fuseBitsPerKey };
package/dist/index.cjs CHANGED
@@ -1,7 +1,6 @@
1
1
  Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
2
2
  //#endregion
3
3
  //#region src/index.ts
4
- /** The installed `distillate` package version. */
5
- const VERSION = "0.7.0";
4
+ const VERSION = "0.8.0";
6
5
  //#endregion
7
6
  exports.VERSION = VERSION;
package/dist/index.js CHANGED
@@ -1,6 +1,5 @@
1
1
  //#endregion
2
2
  //#region src/index.ts
3
- /** The installed `distillate` package version. */
4
- const VERSION = "0.7.0";
3
+ const VERSION = "0.8.0";
5
4
  //#endregion
6
5
  export { VERSION };
@@ -1,26 +1,19 @@
1
1
  //#region src/core/params.ts
2
- /** Thrown when a structure is constructed with invalid parameters. */
3
2
  var ParamError = class extends RangeError {
4
- /** Discriminates this error from other `Error`s. */
5
3
  name = "ParamError";
6
4
  };
7
- /** Asserts `value` is an integer greater than or equal to 1. */
8
5
  function assertPositiveInt(value, label) {
9
6
  if (!Number.isInteger(value) || value < 1) throw new ParamError(`${label} must be a positive integer, got ${String(value)}`);
10
7
  }
11
- /** Asserts `value` is a finite number greater than 0 (a positive real). */
12
8
  function assertPositiveFinite(value, label) {
13
9
  if (!Number.isFinite(value) || value <= 0) throw new ParamError(`${label} must be a positive number, got ${String(value)}`);
14
10
  }
15
- /** Asserts `value` is an integer in the uint16 range `[0, 65535]`. */
16
11
  function assertUint16(value, label) {
17
12
  if (!Number.isInteger(value) || value < 0 || value > 65535) throw new ParamError(`${label} must be a uint16, got ${String(value)}`);
18
13
  }
19
- /** Asserts `value` is an integer in the uint32 range `[0, 2^32 - 1]`. */
20
14
  function assertUint32(value, label) {
21
15
  if (!Number.isInteger(value) || value < 0 || value > 4294967295) throw new ParamError(`${label} must be a uint32, got ${String(value)}`);
22
16
  }
23
- /** Asserts `value` is a finite number in the open interval `(0, 1)`. */
24
17
  function assertProbability(value, label) {
25
18
  if (!Number.isFinite(value) || value <= 0 || value >= 1) throw new ParamError(`${label} must be in the open interval (0, 1), got ${String(value)}`);
26
19
  }
@@ -1,26 +1,19 @@
1
1
  //#region src/core/params.ts
2
- /** Thrown when a structure is constructed with invalid parameters. */
3
2
  var ParamError = class extends RangeError {
4
- /** Discriminates this error from other `Error`s. */
5
3
  name = "ParamError";
6
4
  };
7
- /** Asserts `value` is an integer greater than or equal to 1. */
8
5
  function assertPositiveInt(value, label) {
9
6
  if (!Number.isInteger(value) || value < 1) throw new ParamError(`${label} must be a positive integer, got ${String(value)}`);
10
7
  }
11
- /** Asserts `value` is a finite number greater than 0 (a positive real). */
12
8
  function assertPositiveFinite(value, label) {
13
9
  if (!Number.isFinite(value) || value <= 0) throw new ParamError(`${label} must be a positive number, got ${String(value)}`);
14
10
  }
15
- /** Asserts `value` is an integer in the uint16 range `[0, 65535]`. */
16
11
  function assertUint16(value, label) {
17
12
  if (!Number.isInteger(value) || value < 0 || value > 65535) throw new ParamError(`${label} must be a uint16, got ${String(value)}`);
18
13
  }
19
- /** Asserts `value` is an integer in the uint32 range `[0, 2^32 - 1]`. */
20
14
  function assertUint32(value, label) {
21
15
  if (!Number.isInteger(value) || value < 0 || value > 4294967295) throw new ParamError(`${label} must be a uint32, got ${String(value)}`);
22
16
  }
23
- /** Asserts `value` is a finite number in the open interval `(0, 1)`. */
24
17
  function assertProbability(value, label) {
25
18
  if (!Number.isFinite(value) || value <= 0 || value >= 1) throw new ParamError(`${label} must be in the open interval (0, 1), got ${String(value)}`);
26
19
  }
@@ -174,7 +174,7 @@ function computeLanes(bytes, seed, len) {
174
174
  LANES.w3 = h4;
175
175
  }
176
176
  const keyEncoder = new TextEncoder();
177
- let keyBuf = /* @__PURE__ */ new Uint8Array(256);
177
+ let keyBuf = new Uint8Array(256);
178
178
  let encBytes = keyBuf;
179
179
  let encLen = 0;
180
180
  function encodeKey(key) {
@@ -216,11 +216,6 @@ function hash32x2Into(key, seed, out) {
216
216
  out[0] = LANES.w0;
217
217
  out[1] = LANES.w1;
218
218
  }
219
- /**
220
- * Derive `count` bucket indices in `[0, range)` from a key using
221
- * Kirsch-Mitzenmacher enhanced double hashing `g_i = h1 + i*h2 + i^2`
222
- * (the RocksDB `+i^2` fix), reduced into range with Lemire multiply-shift.
223
- */
224
219
  function probeInto(key, count, range, seed, out) {
225
220
  keyToLanes(key, seed);
226
221
  const a = LANES.w0;
@@ -230,7 +225,7 @@ function probeInto(key, count, range, seed, out) {
230
225
  //#endregion
231
226
  //#region src/core/base64.ts
232
227
  const ALPHABET = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
233
- const DECODE = (/* @__PURE__ */ new Int16Array(128)).fill(-1);
228
+ const DECODE = new Int16Array(128).fill(-1);
234
229
  for (let i = 0; i < 64; i++) DECODE[ALPHABET.charCodeAt(i)] = i;
235
230
  const sym = (n) => ALPHABET.charAt(n & 63);
236
231
  function toBase64(bytes) {
@@ -312,12 +307,6 @@ function crc32(bytes) {
312
307
  }
313
308
  const HEADER_SIZE = 8;
314
309
  const TRAILER_SIZE = 4;
315
- /**
316
- * Allocates a full frame once, hands `fill` a writable view over the body region
317
- * (and a `DataView` scoped to it), then seals the CRC trailer. The body view
318
- * aliases the frame's buffer, so callers write fields and payload straight into
319
- * the frame with no intermediate body allocation or copy.
320
- */
321
310
  function writeFrame(header, bodyLength, fill) {
322
311
  const frame = new Uint8Array(HEADER_SIZE + bodyLength + TRAILER_SIZE);
323
312
  frame[0] = 65;
@@ -352,7 +341,6 @@ var ChecksumError = class extends SerializationError {
352
341
  name = "ChecksumError";
353
342
  };
354
343
  const JSON_TAG = "distillate";
355
- /** Wraps a serialized frame in the JSON envelope. */
356
344
  function toJSONEnvelope(bytes) {
357
345
  return {
358
346
  $: JSON_TAG,
@@ -360,11 +348,6 @@ function toJSONEnvelope(bytes) {
360
348
  data: toBase64(bytes)
361
349
  };
362
350
  }
363
- /**
364
- * Validates a JSON envelope and returns the raw frame bytes for a structure's
365
- * own `fromBytes` to decode. Throws {@link SerializationError} on any envelope
366
- * defect; the frame itself is checked downstream.
367
- */
368
351
  function fromJSONEnvelope(value) {
369
352
  if (value === null || typeof value !== "object") throw new SerializationError("not a distillate filter JSON object");
370
353
  const o = value;
@@ -377,23 +360,14 @@ function fromJSONEnvelope(value) {
377
360
  throw new SerializationError("envelope data is not valid base64");
378
361
  }
379
362
  }
380
- /** Byte-wise equality of two frames; the basis for structure `equals`. */
381
363
  function bytesEqual(a, b) {
382
364
  if (a.length !== b.length) return false;
383
365
  for (let i = 0; i < a.length; i++) if (a[i] !== b[i]) return false;
384
366
  return true;
385
367
  }
386
- /**
387
- * Asserts a frame body is long enough to hold its fixed params block, so the
388
- * params can be read without running off the end.
389
- */
390
368
  function assertMinBodyLength(actual, min, context) {
391
369
  if (actual < min) throw new TruncatedError(`${context}: body of ${String(actual)} bytes is shorter than the ${String(min)}-byte params block`);
392
370
  }
393
- /**
394
- * Asserts a frame body is exactly the length its declared params imply, so a
395
- * hostile or truncated frame is rejected before any backing store is allocated.
396
- */
397
371
  function assertBodyLength(actual, expected, context) {
398
372
  if (actual !== expected) throw new TruncatedError(`${context}: body of ${String(actual)} bytes does not match the declared params (expected ${String(expected)})`);
399
373
  }
@@ -411,4 +385,4 @@ function readHeader(frame) {
411
385
  };
412
386
  }
413
387
  //#endregion
414
- export { reduce as _, bytesEqual as a, toJSONEnvelope as c, RLO as d, fmix64 as f, probeInto as g, mul64 as h, assertMinBodyLength as i, writeFrame as l, hash32x2Into as m, UnknownHashVariantError as n, fromJSONEnvelope as o, hash128KeyInto as p, assertBodyLength as r, readHeader as s, SerializationError as t, RHI as u };
388
+ export { hash128KeyInto as _, UnknownHashVariantError as a, probeInto as b, assertMinBodyLength as c, readHeader as d, toJSONEnvelope as f, fmix64 as g, RLO as h, TruncatedError as i, bytesEqual as l, RHI as m, ChecksumError as n, UnknownVersionError as o, writeFrame as p, SerializationError as r, assertBodyLength as s, BadMagicError as t, fromJSONEnvelope as u, hash32x2Into as v, reduce as x, mul64 as y };
@@ -174,7 +174,7 @@ function computeLanes(bytes, seed, len) {
174
174
  LANES.w3 = h4;
175
175
  }
176
176
  const keyEncoder = new TextEncoder();
177
- let keyBuf = /* @__PURE__ */ new Uint8Array(256);
177
+ let keyBuf = new Uint8Array(256);
178
178
  let encBytes = keyBuf;
179
179
  let encLen = 0;
180
180
  function encodeKey(key) {
@@ -216,11 +216,6 @@ function hash32x2Into(key, seed, out) {
216
216
  out[0] = LANES.w0;
217
217
  out[1] = LANES.w1;
218
218
  }
219
- /**
220
- * Derive `count` bucket indices in `[0, range)` from a key using
221
- * Kirsch-Mitzenmacher enhanced double hashing `g_i = h1 + i*h2 + i^2`
222
- * (the RocksDB `+i^2` fix), reduced into range with Lemire multiply-shift.
223
- */
224
219
  function probeInto(key, count, range, seed, out) {
225
220
  keyToLanes(key, seed);
226
221
  const a = LANES.w0;
@@ -230,7 +225,7 @@ function probeInto(key, count, range, seed, out) {
230
225
  //#endregion
231
226
  //#region src/core/base64.ts
232
227
  const ALPHABET = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
233
- const DECODE = (/* @__PURE__ */ new Int16Array(128)).fill(-1);
228
+ const DECODE = new Int16Array(128).fill(-1);
234
229
  for (let i = 0; i < 64; i++) DECODE[ALPHABET.charCodeAt(i)] = i;
235
230
  const sym = (n) => ALPHABET.charAt(n & 63);
236
231
  function toBase64(bytes) {
@@ -312,12 +307,6 @@ function crc32(bytes) {
312
307
  }
313
308
  const HEADER_SIZE = 8;
314
309
  const TRAILER_SIZE = 4;
315
- /**
316
- * Allocates a full frame once, hands `fill` a writable view over the body region
317
- * (and a `DataView` scoped to it), then seals the CRC trailer. The body view
318
- * aliases the frame's buffer, so callers write fields and payload straight into
319
- * the frame with no intermediate body allocation or copy.
320
- */
321
310
  function writeFrame(header, bodyLength, fill) {
322
311
  const frame = new Uint8Array(HEADER_SIZE + bodyLength + TRAILER_SIZE);
323
312
  frame[0] = 65;
@@ -352,7 +341,6 @@ var ChecksumError = class extends SerializationError {
352
341
  name = "ChecksumError";
353
342
  };
354
343
  const JSON_TAG = "distillate";
355
- /** Wraps a serialized frame in the JSON envelope. */
356
344
  function toJSONEnvelope(bytes) {
357
345
  return {
358
346
  $: JSON_TAG,
@@ -360,11 +348,6 @@ function toJSONEnvelope(bytes) {
360
348
  data: toBase64(bytes)
361
349
  };
362
350
  }
363
- /**
364
- * Validates a JSON envelope and returns the raw frame bytes for a structure's
365
- * own `fromBytes` to decode. Throws {@link SerializationError} on any envelope
366
- * defect; the frame itself is checked downstream.
367
- */
368
351
  function fromJSONEnvelope(value) {
369
352
  if (value === null || typeof value !== "object") throw new SerializationError("not a distillate filter JSON object");
370
353
  const o = value;
@@ -377,23 +360,14 @@ function fromJSONEnvelope(value) {
377
360
  throw new SerializationError("envelope data is not valid base64");
378
361
  }
379
362
  }
380
- /** Byte-wise equality of two frames; the basis for structure `equals`. */
381
363
  function bytesEqual(a, b) {
382
364
  if (a.length !== b.length) return false;
383
365
  for (let i = 0; i < a.length; i++) if (a[i] !== b[i]) return false;
384
366
  return true;
385
367
  }
386
- /**
387
- * Asserts a frame body is long enough to hold its fixed params block, so the
388
- * params can be read without running off the end.
389
- */
390
368
  function assertMinBodyLength(actual, min, context) {
391
369
  if (actual < min) throw new TruncatedError(`${context}: body of ${String(actual)} bytes is shorter than the ${String(min)}-byte params block`);
392
370
  }
393
- /**
394
- * Asserts a frame body is exactly the length its declared params imply, so a
395
- * hostile or truncated frame is rejected before any backing store is allocated.
396
- */
397
371
  function assertBodyLength(actual, expected, context) {
398
372
  if (actual !== expected) throw new TruncatedError(`${context}: body of ${String(actual)} bytes does not match the declared params (expected ${String(expected)})`);
399
373
  }
@@ -411,6 +385,18 @@ function readHeader(frame) {
411
385
  };
412
386
  }
413
387
  //#endregion
388
+ Object.defineProperty(exports, "BadMagicError", {
389
+ enumerable: true,
390
+ get: function() {
391
+ return BadMagicError;
392
+ }
393
+ });
394
+ Object.defineProperty(exports, "ChecksumError", {
395
+ enumerable: true,
396
+ get: function() {
397
+ return ChecksumError;
398
+ }
399
+ });
414
400
  Object.defineProperty(exports, "RHI", {
415
401
  enumerable: true,
416
402
  get: function() {
@@ -429,12 +415,24 @@ Object.defineProperty(exports, "SerializationError", {
429
415
  return SerializationError;
430
416
  }
431
417
  });
418
+ Object.defineProperty(exports, "TruncatedError", {
419
+ enumerable: true,
420
+ get: function() {
421
+ return TruncatedError;
422
+ }
423
+ });
432
424
  Object.defineProperty(exports, "UnknownHashVariantError", {
433
425
  enumerable: true,
434
426
  get: function() {
435
427
  return UnknownHashVariantError;
436
428
  }
437
429
  });
430
+ Object.defineProperty(exports, "UnknownVersionError", {
431
+ enumerable: true,
432
+ get: function() {
433
+ return UnknownVersionError;
434
+ }
435
+ });
438
436
  Object.defineProperty(exports, "assertBodyLength", {
439
437
  enumerable: true,
440
438
  get: function() {
@@ -0,0 +1,73 @@
1
+ //#region src/core/bytes.d.ts
2
+ type BytesLike = string | Uint8Array | ArrayBuffer;
3
+ //#endregion
4
+ //#region src/core/serialize.d.ts
5
+ /**
6
+ * Base class for every defect `fromBytes` and `fromJSON` reject. Thrown
7
+ * directly when a JSON envelope is malformed: not an object, missing the
8
+ * `"distillate"` tag, missing `data`, or `data` that is not valid base64.
9
+ * Catch this to handle any decode failure at once, or a subclass to tell the
10
+ * causes apart. The input is corrupt or foreign, so discard it; retrying the
11
+ * same bytes cannot succeed.
12
+ */
13
+ declare class SerializationError extends Error {
14
+ /** Discriminates this error from other `Error`s. */
15
+ override readonly name: string;
16
+ }
17
+ /**
18
+ * Thrown when a frame is shorter than its header plus trailer, or when its
19
+ * body length does not match the length its declared params imply. The bytes
20
+ * were cut short in transit or storage; re-fetch the whole frame.
21
+ */
22
+ declare class TruncatedError extends SerializationError {
23
+ /** Discriminates this error from other `Error`s. */
24
+ override readonly name = "TruncatedError";
25
+ }
26
+ /**
27
+ * Thrown when a frame does not start with the four-byte `AMQF` magic, so it
28
+ * was never produced by `toBytes`. Check that the bytes really are a
29
+ * distillate frame and not another payload, a text encoding of one, or a
30
+ * slice taken at the wrong offset.
31
+ */
32
+ declare class BadMagicError extends SerializationError {
33
+ /** Discriminates this error from other `Error`s. */
34
+ override readonly name = "BadMagicError";
35
+ }
36
+ /**
37
+ * Thrown when a frame or JSON envelope declares a format version this release
38
+ * does not read. A reader must be at least as new as the producer, so upgrade
39
+ * `distillate` or re-serialize the data with the version you run.
40
+ */
41
+ declare class UnknownVersionError extends SerializationError {
42
+ /** Discriminates this error from other `Error`s. */
43
+ override readonly name = "UnknownVersionError";
44
+ }
45
+ /**
46
+ * Thrown when a frame's flags nibble names a hash this release cannot
47
+ * reproduce, so its stored bits are unreadable. Rebuild the filter from the
48
+ * source keys with the version you run.
49
+ */
50
+ declare class UnknownHashVariantError extends SerializationError {
51
+ /** Discriminates this error from other `Error`s. */
52
+ override readonly name = "UnknownHashVariantError";
53
+ }
54
+ /**
55
+ * Thrown when a frame's CRC32 trailer does not match its contents, so the
56
+ * bytes were corrupted after they were written. Discard them and re-fetch;
57
+ * the payload cannot be trusted even where it still parses.
58
+ */
59
+ declare class ChecksumError extends SerializationError {
60
+ /** Discriminates this error from other `Error`s. */
61
+ override readonly name = "ChecksumError";
62
+ }
63
+ /** JSON-friendly envelope for a filter: the binary frame, base64-encoded. */
64
+ interface FilterJSON {
65
+ /** Format tag; always `"distillate"`. */
66
+ $: string;
67
+ /** Binary format version. */
68
+ v: number;
69
+ /** Base64 of the `toBytes` frame. */
70
+ data: string;
71
+ }
72
+ //#endregion
73
+ export { TruncatedError as a, BytesLike as c, SerializationError as i, ChecksumError as n, UnknownHashVariantError as o, FilterJSON as r, UnknownVersionError as s, BadMagicError as t };
@@ -0,0 +1,73 @@
1
+ //#region src/core/bytes.d.ts
2
+ type BytesLike = string | Uint8Array | ArrayBuffer;
3
+ //#endregion
4
+ //#region src/core/serialize.d.ts
5
+ /**
6
+ * Base class for every defect `fromBytes` and `fromJSON` reject. Thrown
7
+ * directly when a JSON envelope is malformed: not an object, missing the
8
+ * `"distillate"` tag, missing `data`, or `data` that is not valid base64.
9
+ * Catch this to handle any decode failure at once, or a subclass to tell the
10
+ * causes apart. The input is corrupt or foreign, so discard it; retrying the
11
+ * same bytes cannot succeed.
12
+ */
13
+ declare class SerializationError extends Error {
14
+ /** Discriminates this error from other `Error`s. */
15
+ override readonly name: string;
16
+ }
17
+ /**
18
+ * Thrown when a frame is shorter than its header plus trailer, or when its
19
+ * body length does not match the length its declared params imply. The bytes
20
+ * were cut short in transit or storage; re-fetch the whole frame.
21
+ */
22
+ declare class TruncatedError extends SerializationError {
23
+ /** Discriminates this error from other `Error`s. */
24
+ override readonly name = "TruncatedError";
25
+ }
26
+ /**
27
+ * Thrown when a frame does not start with the four-byte `AMQF` magic, so it
28
+ * was never produced by `toBytes`. Check that the bytes really are a
29
+ * distillate frame and not another payload, a text encoding of one, or a
30
+ * slice taken at the wrong offset.
31
+ */
32
+ declare class BadMagicError extends SerializationError {
33
+ /** Discriminates this error from other `Error`s. */
34
+ override readonly name = "BadMagicError";
35
+ }
36
+ /**
37
+ * Thrown when a frame or JSON envelope declares a format version this release
38
+ * does not read. A reader must be at least as new as the producer, so upgrade
39
+ * `distillate` or re-serialize the data with the version you run.
40
+ */
41
+ declare class UnknownVersionError extends SerializationError {
42
+ /** Discriminates this error from other `Error`s. */
43
+ override readonly name = "UnknownVersionError";
44
+ }
45
+ /**
46
+ * Thrown when a frame's flags nibble names a hash this release cannot
47
+ * reproduce, so its stored bits are unreadable. Rebuild the filter from the
48
+ * source keys with the version you run.
49
+ */
50
+ declare class UnknownHashVariantError extends SerializationError {
51
+ /** Discriminates this error from other `Error`s. */
52
+ override readonly name = "UnknownHashVariantError";
53
+ }
54
+ /**
55
+ * Thrown when a frame's CRC32 trailer does not match its contents, so the
56
+ * bytes were corrupted after they were written. Discard them and re-fetch;
57
+ * the payload cannot be trusted even where it still parses.
58
+ */
59
+ declare class ChecksumError extends SerializationError {
60
+ /** Discriminates this error from other `Error`s. */
61
+ override readonly name = "ChecksumError";
62
+ }
63
+ /** JSON-friendly envelope for a filter: the binary frame, base64-encoded. */
64
+ interface FilterJSON {
65
+ /** Format tag; always `"distillate"`. */
66
+ $: string;
67
+ /** Binary format version. */
68
+ v: number;
69
+ /** Base64 of the `toBytes` frame. */
70
+ data: string;
71
+ }
72
+ //#endregion
73
+ export { TruncatedError as a, BytesLike as c, SerializationError as i, ChecksumError as n, UnknownHashVariantError as o, FilterJSON as r, UnknownVersionError as s, BadMagicError as t };