distillate 0.13.0 → 0.14.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.
Files changed (38) hide show
  1. package/README.md +38 -12
  2. package/dist/blocked/index.cjs +1 -1
  3. package/dist/blocked/index.js +1 -1
  4. package/dist/bloom/index.cjs +3 -4
  5. package/dist/bloom/index.d.cts +12 -2
  6. package/dist/bloom/index.d.ts +12 -2
  7. package/dist/bloom/index.js +2 -3
  8. package/dist/bytes-Be7tq1F7.js +9 -0
  9. package/dist/bytes-D2duG1jq.cjs +14 -0
  10. package/dist/countmin/index.cjs +13 -4
  11. package/dist/countmin/index.d.cts +15 -2
  12. package/dist/countmin/index.d.ts +15 -2
  13. package/dist/countmin/index.js +12 -3
  14. package/dist/cuckoo/index.cjs +1 -1
  15. package/dist/cuckoo/index.js +1 -1
  16. package/dist/fuse/index.cjs +1 -1
  17. package/dist/fuse/index.js +1 -1
  18. package/dist/{hasher-3Cyn7Yg-.js → hasher-DOdmZ-LI.js} +1 -8
  19. package/dist/{hasher-MhY7aQ8F.cjs → hasher-DPXmP7SH.cjs} +2 -9
  20. package/dist/hll/index.cjs +10 -4
  21. package/dist/hll/index.d.cts +13 -2
  22. package/dist/hll/index.d.ts +13 -2
  23. package/dist/hll/index.js +9 -3
  24. package/dist/index.cjs +1 -1
  25. package/dist/index.js +1 -1
  26. package/dist/scalable/index.cjs +5 -6
  27. package/dist/scalable/index.js +2 -3
  28. package/dist/{bitset-QYGqxnEf.cjs → sizing-Ch0SDdza.cjs} +15 -0
  29. package/dist/{bitset-Cf2jwRJX.js → sizing-zxCBlyhO.js} +10 -1
  30. package/dist/topk/index.cjs +423 -0
  31. package/dist/topk/index.d.cts +207 -0
  32. package/dist/topk/index.d.ts +207 -0
  33. package/dist/topk/index.js +411 -0
  34. package/package.json +9 -1
  35. package/dist/sizing-BmKfHf_V.d.cts +0 -34
  36. package/dist/sizing-BmKfHf_V.d.ts +0 -34
  37. package/dist/sizing-D3-_7pdP.js +0 -25
  38. package/dist/sizing-R1pwbzjC.cjs +0 -42
package/README.md CHANGED
@@ -42,20 +42,22 @@ Every push runs a CI smoke matrix that imports the built package on Node 22/24,
42
42
 
43
43
  Each structure ships as its own subpath, so you only bundle what you import.
44
44
 
45
- | Import | Structure | Answers | Use for |
46
- | --------------------- | -------------- | ------------------ | -------------------------------------------------------- |
47
- | `distillate/bloom` | Classic Bloom | seen this key? | Familiar default, migration from `bloom-filters` |
48
- | `distillate/scalable` | Scalable Bloom | seen this key? | Key count unknown or growing; keeps its FPR bound |
49
- | `distillate/blocked` | Blocked Bloom | seen this key? | Faster lookups and a lower FPR for a small space premium |
50
- | `distillate/fuse` | Binary Fuse | seen this key? | Static set built once and queried a lot; least space |
51
- | `distillate/cuckoo` | Cuckoo | seen this key? | Keys come and go; the one filter with delete |
52
- | `distillate/hll` | HyperLogLog | how many distinct? | Counting distinct users, IPs, or keys in fixed space |
53
- | `distillate/countmin` | Count-Min | how many times? | Counting events per key in fixed space |
45
+ | Import | Structure | Answers | Use for |
46
+ | --------------------- | -------------- | ------------------- | -------------------------------------------------------- |
47
+ | `distillate/bloom` | Classic Bloom | seen this key? | Familiar default, migration from `bloom-filters` |
48
+ | `distillate/scalable` | Scalable Bloom | seen this key? | Key count unknown or growing; keeps its FPR bound |
49
+ | `distillate/blocked` | Blocked Bloom | seen this key? | Faster lookups and a lower FPR for a small space premium |
50
+ | `distillate/fuse` | Binary Fuse | seen this key? | Static set built once and queried a lot; least space |
51
+ | `distillate/cuckoo` | Cuckoo | seen this key? | Keys come and go; the one filter with delete |
52
+ | `distillate/hll` | HyperLogLog | how many distinct? | Counting distinct users, IPs, or keys in fixed space |
53
+ | `distillate/countmin` | Count-Min | how many times? | Counting events per key in fixed space |
54
+ | `distillate/topk` | Top-K | which are heaviest? | Finding the most frequent keys in fixed space |
54
55
 
55
56
  The filters are mutable except Binary Fuse, which is built once from the whole
56
- key set. HyperLogLog and Count-Min are sketches rather than filters: neither
57
- reports whether it saw any particular key. HyperLogLog counts distinct keys,
58
- Count-Min counts how often each key appeared.
57
+ key set. HyperLogLog, Count-Min and Top-K are sketches rather than filters:
58
+ none reports whether it saw any particular key. HyperLogLog counts distinct
59
+ keys, Count-Min counts how often each key appeared, and Top-K reports which
60
+ keys appeared most.
59
61
 
60
62
  ### Classic Bloom (`distillate/bloom`)
61
63
 
@@ -189,6 +191,30 @@ hits.union(other).count("/login"); // 7
189
191
 
190
192
  Also: `equals`, `toBytes` / `fromBytes`, `toJSON` / `fromJSON`, `error()`, `epsilon`, `delta`, `width`, `depth`, `countMinSizing(epsilon, delta)`, and a low-level `new CountMinSketch({ width, depth, seed })`.
191
193
 
194
+ ### Top-K (`distillate/topk`)
195
+
196
+ A **sketch** that lists the keys seen most often, in a table fixed by the error you ask for rather than by how many keys arrive. A key it holds never reads below its true count, and any key heavier than `error()` is guaranteed to be held. Full API and the bound: [Top-K guide](https://distillate.akxp.net/guides/topk/).
197
+
198
+ ```ts
199
+ import { TopK } from "distillate/topk";
200
+
201
+ const routes = TopK.create(0.01); // error factor
202
+ routes.add("/login", 5);
203
+ routes.add("/signup", 2);
204
+ routes.add("/about");
205
+
206
+ const decoder = new TextDecoder();
207
+ routes
208
+ .top(2)
209
+ .map((e) => decoder.decode(e.key))
210
+ .join(); // "/login,/signup"
211
+ routes.count("/login"); // 5
212
+ ```
213
+
214
+ Keys come back as `Uint8Array`, exactly as recorded, so a serialized Top-K sketch holds your keys verbatim, unlike every other frame here. `union` combines sketches soundly but, unlike Count-Min's, not byte for byte as one sketch fed both streams.
215
+
216
+ Also: `equals`, `toBytes` / `fromBytes`, `toJSON` / `fromJSON`, `total`, `error()`, `epsilon`, `capacity`, `topKSizing(epsilon)`, and a low-level `new TopK({ capacity, seed })`.
217
+
192
218
  ## Performance
193
219
 
194
220
  Classic Bloom head-to-head at a **matched 1% false-positive rate** over the same 100k keys, measured by identical code (cross-library harness, node v24.14.1, Apple M5):
@@ -1,5 +1,5 @@
1
1
  Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
2
- const require_hasher = require("../hasher-MhY7aQ8F.cjs");
2
+ const require_hasher = require("../hasher-DPXmP7SH.cjs");
3
3
  const require_serialize = require("../serialize-CHikZ4GH.cjs");
4
4
  const require_params = require("../params-UTZbJ22c.cjs");
5
5
  //#region src/blocked/blocked.ts
@@ -1,4 +1,4 @@
1
- import { a as hash32x2Into, u as reduce } from "../hasher-3Cyn7Yg-.js";
1
+ import { a as hash32x2Into, u as reduce } from "../hasher-DOdmZ-LI.js";
2
2
  import { a as TruncatedError, c as assertBodyLength, d as bytesEqual, f as fromJSONEnvelope, g as writeFrame, h as toJSONEnvelope, i as SerializationError, l as assertMinBodyLength, m as readHeader, n as ChecksumError, o as UnknownHashVariantError, r as ReservedBitsError, s as UnknownVersionError, t as BadMagicError, u as assertParamsPadding } from "../serialize-CMSYFym-.js";
3
3
  import { i as assertProbability, n as assertPositiveFinite, o as assertUint32, r as assertPositiveInt, t as ParamError } from "../params-CeajSrwv.js";
4
4
  //#region src/blocked/blocked.ts
@@ -1,9 +1,8 @@
1
1
  Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
2
- const require_bitset = require("../bitset-QYGqxnEf.cjs");
3
- const require_hasher = require("../hasher-MhY7aQ8F.cjs");
2
+ const require_sizing = require("../sizing-Ch0SDdza.cjs");
3
+ const require_hasher = require("../hasher-DPXmP7SH.cjs");
4
4
  const require_serialize = require("../serialize-CHikZ4GH.cjs");
5
5
  const require_params = require("../params-UTZbJ22c.cjs");
6
- const require_sizing = require("../sizing-R1pwbzjC.cjs");
7
6
  //#region src/bloom/bloom.ts
8
7
  const TYPE = 1;
9
8
  const PARAMS_SIZE = 16;
@@ -64,7 +63,7 @@ var BloomFilter = class BloomFilter {
64
63
  require_params.assertPositiveInt(n, "n");
65
64
  require_params.assertUint32(n, "n");
66
65
  }
67
- this.#bits = new require_bitset.BitSet(m);
66
+ this.#bits = new require_sizing.BitSet(m);
68
67
  this.#m = m;
69
68
  this.#k = k;
70
69
  this.#seed = seed;
@@ -1,7 +1,6 @@
1
1
  import { t as BytesLike } from "../bytes-DCuYtUVS.cjs";
2
2
  import { a as ReservedBitsError, c as UnknownHashVariantError, l as UnknownVersionError, n as ChecksumError, o as SerializationError, r as FilterJSON, s as TruncatedError, t as BadMagicError } from "../serialize--xR6vGSW.cjs";
3
3
  import { t as ParamError } from "../params-DnqJBqLS.cjs";
4
- import { i as bloomSizing, t as BloomSizing } from "../sizing-BmKfHf_V.cjs";
5
4
  //#region src/bloom/bloom.d.ts
6
5
  /** Thrown when an operation requires two filters built with identical parameters. */
7
6
  export declare class BloomParamMismatchError extends Error {
@@ -144,4 +143,15 @@ export declare class BloomFilter {
144
143
  has(key: BytesLike): boolean;
145
144
  }
146
145
  //#endregion
147
- export { BadMagicError, type BloomParams, type BloomSizing, ChecksumError, type FilterJSON, ParamError, ReservedBitsError, SerializationError, TruncatedError, UnknownHashVariantError, UnknownVersionError, bloomSizing };
146
+ //#region src/core/sizing.d.ts
147
+ /** Bloom filter geometry: the `BloomParams` fields a sizing solve determines. */
148
+ interface BloomSizing {
149
+ /** Number of bits in the filter. */
150
+ m: number;
151
+ /** Number of hash probes per key. */
152
+ k: number;
153
+ }
154
+ /** Optimal Bloom-filter sizing: `m` bits and `k` hashes for `n` items at target FPR `epsilon`. */
155
+ export declare function bloomSizing(n: number, epsilon: number): BloomSizing;
156
+ //#endregion
157
+ export { BadMagicError, type BloomParams, type BloomSizing, ChecksumError, type FilterJSON, ParamError, ReservedBitsError, SerializationError, TruncatedError, UnknownHashVariantError, UnknownVersionError };
@@ -1,7 +1,6 @@
1
1
  import { t as BytesLike } from "../bytes-DCuYtUVS.js";
2
2
  import { a as ReservedBitsError, c as UnknownHashVariantError, l as UnknownVersionError, n as ChecksumError, o as SerializationError, r as FilterJSON, s as TruncatedError, t as BadMagicError } from "../serialize--xR6vGSW.js";
3
3
  import { t as ParamError } from "../params-DnqJBqLS.js";
4
- import { i as bloomSizing, t as BloomSizing } from "../sizing-BmKfHf_V.js";
5
4
  //#region src/bloom/bloom.d.ts
6
5
  /** Thrown when an operation requires two filters built with identical parameters. */
7
6
  export declare class BloomParamMismatchError extends Error {
@@ -144,4 +143,15 @@ export declare class BloomFilter {
144
143
  has(key: BytesLike): boolean;
145
144
  }
146
145
  //#endregion
147
- export { BadMagicError, type BloomParams, type BloomSizing, ChecksumError, type FilterJSON, ParamError, ReservedBitsError, SerializationError, TruncatedError, UnknownHashVariantError, UnknownVersionError, bloomSizing };
146
+ //#region src/core/sizing.d.ts
147
+ /** Bloom filter geometry: the `BloomParams` fields a sizing solve determines. */
148
+ interface BloomSizing {
149
+ /** Number of bits in the filter. */
150
+ m: number;
151
+ /** Number of hash probes per key. */
152
+ k: number;
153
+ }
154
+ /** Optimal Bloom-filter sizing: `m` bits and `k` hashes for `n` items at target FPR `epsilon`. */
155
+ export declare function bloomSizing(n: number, epsilon: number): BloomSizing;
156
+ //#endregion
157
+ export { BadMagicError, type BloomParams, type BloomSizing, ChecksumError, type FilterJSON, ParamError, ReservedBitsError, SerializationError, TruncatedError, UnknownHashVariantError, UnknownVersionError };
@@ -1,8 +1,7 @@
1
- import { t as BitSet } from "../bitset-Cf2jwRJX.js";
2
- import { c as probeInto } from "../hasher-3Cyn7Yg-.js";
1
+ import { n as BitSet, t as bloomSizing } from "../sizing-zxCBlyhO.js";
2
+ import { c as probeInto } from "../hasher-DOdmZ-LI.js";
3
3
  import { a as TruncatedError, c as assertBodyLength, d as bytesEqual, f as fromJSONEnvelope, g as writeFrame, h as toJSONEnvelope, i as SerializationError, l as assertMinBodyLength, m as readHeader, n as ChecksumError, o as UnknownHashVariantError, r as ReservedBitsError, s as UnknownVersionError, t as BadMagicError, u as assertParamsPadding } from "../serialize-CMSYFym-.js";
4
4
  import { a as assertUint16, i as assertProbability, o as assertUint32, r as assertPositiveInt, t as ParamError } from "../params-CeajSrwv.js";
5
- import { t as bloomSizing } from "../sizing-D3-_7pdP.js";
6
5
  //#region src/bloom/bloom.ts
7
6
  const TYPE = 1;
8
7
  const PARAMS_SIZE = 16;
@@ -0,0 +1,9 @@
1
+ //#region src/core/bytes.ts
2
+ const encoder = new TextEncoder();
3
+ function normalize(input) {
4
+ if (typeof input === "string") return encoder.encode(input);
5
+ if (input instanceof Uint8Array) return input;
6
+ return new Uint8Array(input);
7
+ }
8
+ //#endregion
9
+ export { normalize as t };
@@ -0,0 +1,14 @@
1
+ //#region src/core/bytes.ts
2
+ const encoder = new TextEncoder();
3
+ function normalize(input) {
4
+ if (typeof input === "string") return encoder.encode(input);
5
+ if (input instanceof Uint8Array) return input;
6
+ return new Uint8Array(input);
7
+ }
8
+ //#endregion
9
+ Object.defineProperty(exports, "normalize", {
10
+ enumerable: true,
11
+ get: function() {
12
+ return normalize;
13
+ }
14
+ });
@@ -1,8 +1,17 @@
1
1
  Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
2
- const require_hasher = require("../hasher-MhY7aQ8F.cjs");
2
+ const require_hasher = require("../hasher-DPXmP7SH.cjs");
3
3
  const require_serialize = require("../serialize-CHikZ4GH.cjs");
4
4
  const require_params = require("../params-UTZbJ22c.cjs");
5
- const require_sizing = require("../sizing-R1pwbzjC.cjs");
5
+ //#region src/countmin/sizing.ts
6
+ function countMinSizing(epsilon, delta) {
7
+ require_params.assertProbability(epsilon, "epsilon");
8
+ require_params.assertProbability(delta, "delta");
9
+ return {
10
+ width: Math.ceil(Math.E / epsilon),
11
+ depth: Math.ceil(Math.log(1 / delta))
12
+ };
13
+ }
14
+ //#endregion
6
15
  //#region src/countmin/countmin.ts
7
16
  const TYPE = 8;
8
17
  const PARAMS_SIZE = 16;
@@ -37,7 +46,7 @@ var CountMinSketch = class CountMinSketch {
37
46
  static create(epsilon, delta, options = {}) {
38
47
  return new CountMinSketch({
39
48
  ...options,
40
- ...require_sizing.countMinSizing(epsilon, delta)
49
+ ...countMinSizing(epsilon, delta)
41
50
  });
42
51
  }
43
52
  static from(keys, epsilon, delta, options = {}) {
@@ -191,4 +200,4 @@ exports.SerializationError = require_serialize.SerializationError;
191
200
  exports.TruncatedError = require_serialize.TruncatedError;
192
201
  exports.UnknownHashVariantError = require_serialize.UnknownHashVariantError;
193
202
  exports.UnknownVersionError = require_serialize.UnknownVersionError;
194
- exports.countMinSizing = require_sizing.countMinSizing;
203
+ exports.countMinSizing = countMinSizing;
@@ -1,7 +1,6 @@
1
1
  import { t as BytesLike } from "../bytes-DCuYtUVS.cjs";
2
2
  import { a as ReservedBitsError, c as UnknownHashVariantError, l as UnknownVersionError, n as ChecksumError, o as SerializationError, r as FilterJSON, s as TruncatedError, t as BadMagicError } from "../serialize--xR6vGSW.cjs";
3
3
  import { t as ParamError } from "../params-DnqJBqLS.cjs";
4
- import { a as countMinSizing, n as CountMinSizing } from "../sizing-BmKfHf_V.cjs";
5
4
  //#region src/countmin/countmin.d.ts
6
5
  /** Thrown when an operation requires two sketches built with identical parameters. */
7
6
  export declare class CountMinParamMismatchError extends Error {
@@ -175,4 +174,18 @@ export declare class CountMinSketch {
175
174
  count(key: BytesLike): number;
176
175
  }
177
176
  //#endregion
178
- export { BadMagicError, ChecksumError, type CountMinOptions, type CountMinParams, type CountMinSizing, type FilterJSON, ParamError, ReservedBitsError, SerializationError, TruncatedError, UnknownHashVariantError, UnknownVersionError, countMinSizing };
177
+ //#region src/countmin/sizing.d.ts
178
+ /** Count-Min geometry: the `CountMinParams` fields a sizing solve determines. */
179
+ interface CountMinSizing {
180
+ /** Counters per row. */
181
+ width: number;
182
+ /** Number of rows, one probe each. */
183
+ depth: number;
184
+ }
185
+ /**
186
+ * Count-Min sizing: `width` columns and `depth` rows for an estimate at most
187
+ * `epsilon * total` above the true count, with probability `1 - delta`.
188
+ */
189
+ export declare function countMinSizing(epsilon: number, delta: number): CountMinSizing;
190
+ //#endregion
191
+ export { BadMagicError, ChecksumError, type CountMinOptions, type CountMinParams, type CountMinSizing, type FilterJSON, ParamError, ReservedBitsError, SerializationError, TruncatedError, UnknownHashVariantError, UnknownVersionError };
@@ -1,7 +1,6 @@
1
1
  import { t as BytesLike } from "../bytes-DCuYtUVS.js";
2
2
  import { a as ReservedBitsError, c as UnknownHashVariantError, l as UnknownVersionError, n as ChecksumError, o as SerializationError, r as FilterJSON, s as TruncatedError, t as BadMagicError } from "../serialize--xR6vGSW.js";
3
3
  import { t as ParamError } from "../params-DnqJBqLS.js";
4
- import { a as countMinSizing, n as CountMinSizing } from "../sizing-BmKfHf_V.js";
5
4
  //#region src/countmin/countmin.d.ts
6
5
  /** Thrown when an operation requires two sketches built with identical parameters. */
7
6
  export declare class CountMinParamMismatchError extends Error {
@@ -175,4 +174,18 @@ export declare class CountMinSketch {
175
174
  count(key: BytesLike): number;
176
175
  }
177
176
  //#endregion
178
- export { BadMagicError, ChecksumError, type CountMinOptions, type CountMinParams, type CountMinSizing, type FilterJSON, ParamError, ReservedBitsError, SerializationError, TruncatedError, UnknownHashVariantError, UnknownVersionError, countMinSizing };
177
+ //#region src/countmin/sizing.d.ts
178
+ /** Count-Min geometry: the `CountMinParams` fields a sizing solve determines. */
179
+ interface CountMinSizing {
180
+ /** Counters per row. */
181
+ width: number;
182
+ /** Number of rows, one probe each. */
183
+ depth: number;
184
+ }
185
+ /**
186
+ * Count-Min sizing: `width` columns and `depth` rows for an estimate at most
187
+ * `epsilon * total` above the true count, with probability `1 - delta`.
188
+ */
189
+ export declare function countMinSizing(epsilon: number, delta: number): CountMinSizing;
190
+ //#endregion
191
+ export { BadMagicError, ChecksumError, type CountMinOptions, type CountMinParams, type CountMinSizing, type FilterJSON, ParamError, ReservedBitsError, SerializationError, TruncatedError, UnknownHashVariantError, UnknownVersionError };
@@ -1,7 +1,16 @@
1
- import { a as hash32x2Into, s as probeAt } from "../hasher-3Cyn7Yg-.js";
1
+ import { a as hash32x2Into, s as probeAt } from "../hasher-DOdmZ-LI.js";
2
2
  import { a as TruncatedError, c as assertBodyLength, d as bytesEqual, f as fromJSONEnvelope, g as writeFrame, h as toJSONEnvelope, i as SerializationError, l as assertMinBodyLength, m as readHeader, n as ChecksumError, o as UnknownHashVariantError, r as ReservedBitsError, s as UnknownVersionError, t as BadMagicError, u as assertParamsPadding } from "../serialize-CMSYFym-.js";
3
- import { o as assertUint32, r as assertPositiveInt, t as ParamError } from "../params-CeajSrwv.js";
4
- import { n as countMinSizing } from "../sizing-D3-_7pdP.js";
3
+ import { i as assertProbability, o as assertUint32, r as assertPositiveInt, t as ParamError } from "../params-CeajSrwv.js";
4
+ //#region src/countmin/sizing.ts
5
+ function countMinSizing(epsilon, delta) {
6
+ assertProbability(epsilon, "epsilon");
7
+ assertProbability(delta, "delta");
8
+ return {
9
+ width: Math.ceil(Math.E / epsilon),
10
+ depth: Math.ceil(Math.log(1 / delta))
11
+ };
12
+ }
13
+ //#endregion
5
14
  //#region src/countmin/countmin.ts
6
15
  const TYPE = 8;
7
16
  const PARAMS_SIZE = 16;
@@ -1,5 +1,5 @@
1
1
  Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
2
- const require_hasher = require("../hasher-MhY7aQ8F.cjs");
2
+ const require_hasher = require("../hasher-DPXmP7SH.cjs");
3
3
  const require_serialize = require("../serialize-CHikZ4GH.cjs");
4
4
  const require_params = require("../params-UTZbJ22c.cjs");
5
5
  function cuckooSizing(n, epsilon) {
@@ -1,4 +1,4 @@
1
- import { i as hash128KeyInto, u as reduce } from "../hasher-3Cyn7Yg-.js";
1
+ import { i as hash128KeyInto, u as reduce } from "../hasher-DOdmZ-LI.js";
2
2
  import { a as TruncatedError, c as assertBodyLength, d as bytesEqual, f as fromJSONEnvelope, g as writeFrame, h as toJSONEnvelope, i as SerializationError, l as assertMinBodyLength, m as readHeader, n as ChecksumError, o as UnknownHashVariantError, r as ReservedBitsError, s as UnknownVersionError, t as BadMagicError, u as assertParamsPadding } from "../serialize-CMSYFym-.js";
3
3
  import { i as assertProbability, o as assertUint32, r as assertPositiveInt, t as ParamError } from "../params-CeajSrwv.js";
4
4
  function cuckooSizing(n, epsilon) {
@@ -1,5 +1,5 @@
1
1
  Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
2
- const require_hasher = require("../hasher-MhY7aQ8F.cjs");
2
+ const require_hasher = require("../hasher-DPXmP7SH.cjs");
3
3
  const require_serialize = require("../serialize-CHikZ4GH.cjs");
4
4
  //#region src/fuse/fuse.ts
5
5
  const ARITY = 3;
@@ -1,4 +1,4 @@
1
- import { i as hash128KeyInto, n as RLO, o as mul64, r as fmix64, t as RHI } from "../hasher-3Cyn7Yg-.js";
1
+ import { i as hash128KeyInto, n as RLO, o as mul64, r as fmix64, t as RHI } from "../hasher-DOdmZ-LI.js";
2
2
  import { a as TruncatedError, c as assertBodyLength, d as bytesEqual, f as fromJSONEnvelope, g as writeFrame, h as toJSONEnvelope, i as SerializationError, l as assertMinBodyLength, m as readHeader, n as ChecksumError, o as UnknownHashVariantError, r as ReservedBitsError, s as UnknownVersionError, t as BadMagicError } from "../serialize-CMSYFym-.js";
3
3
  //#region src/fuse/fuse.ts
4
4
  const ARITY = 3;
@@ -1,11 +1,4 @@
1
- //#region src/core/bytes.ts
2
- const encoder = new TextEncoder();
3
- function normalize(input) {
4
- if (typeof input === "string") return encoder.encode(input);
5
- if (input instanceof Uint8Array) return input;
6
- return new Uint8Array(input);
7
- }
8
- //#endregion
1
+ import { t as normalize } from "./bytes-Be7tq1F7.js";
9
2
  //#region src/core/hasher.ts
10
3
  let RLO = 0;
11
4
  let RHI = 0;
@@ -1,11 +1,4 @@
1
- //#region src/core/bytes.ts
2
- const encoder = new TextEncoder();
3
- function normalize(input) {
4
- if (typeof input === "string") return encoder.encode(input);
5
- if (input instanceof Uint8Array) return input;
6
- return new Uint8Array(input);
7
- }
8
- //#endregion
1
+ const require_bytes = require("./bytes-D2duG1jq.cjs");
9
2
  //#region src/core/hasher.ts
10
3
  let RLO = 0;
11
4
  let RHI = 0;
@@ -185,7 +178,7 @@ function encodeKey(key) {
185
178
  encBytes = keyBuf;
186
179
  return;
187
180
  }
188
- encBytes = normalize(key);
181
+ encBytes = require_bytes.normalize(key);
189
182
  encLen = encBytes.length;
190
183
  }
191
184
  function keyToLanes(key, seed) {
@@ -1,8 +1,14 @@
1
1
  Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
2
- const require_hasher = require("../hasher-MhY7aQ8F.cjs");
2
+ const require_hasher = require("../hasher-DPXmP7SH.cjs");
3
3
  const require_serialize = require("../serialize-CHikZ4GH.cjs");
4
4
  const require_params = require("../params-UTZbJ22c.cjs");
5
- const require_sizing = require("../sizing-R1pwbzjC.cjs");
5
+ function hllSizing(relativeError) {
6
+ require_params.assertProbability(relativeError, "relativeError");
7
+ const p = Math.max(4, Math.ceil(2 * Math.log2(1.04 / relativeError)));
8
+ if (p > 18) throw new require_params.ParamError(`relativeError ${String(relativeError)} needs precision ${String(p)}, above the maximum ${String(18)}`);
9
+ return { p };
10
+ }
11
+ //#endregion
6
12
  //#region src/hll/estimate.ts
7
13
  const ALPHA_INF = .5 / Math.LN2;
8
14
  function sigma(x) {
@@ -171,7 +177,7 @@ var HyperLogLog = class HyperLogLog {
171
177
  this.#sparse = new Int32Array(sparseCapacity(this.#registers));
172
178
  }
173
179
  static create(relativeError) {
174
- return new HyperLogLog(require_sizing.hllSizing(relativeError));
180
+ return new HyperLogLog(hllSizing(relativeError));
175
181
  }
176
182
  static from(keys, relativeError) {
177
183
  const sketch = HyperLogLog.create(relativeError);
@@ -363,4 +369,4 @@ exports.SerializationError = require_serialize.SerializationError;
363
369
  exports.TruncatedError = require_serialize.TruncatedError;
364
370
  exports.UnknownHashVariantError = require_serialize.UnknownHashVariantError;
365
371
  exports.UnknownVersionError = require_serialize.UnknownVersionError;
366
- exports.hllSizing = require_sizing.hllSizing;
372
+ exports.hllSizing = hllSizing;
@@ -1,7 +1,6 @@
1
1
  import { t as BytesLike } from "../bytes-DCuYtUVS.cjs";
2
2
  import { a as ReservedBitsError, c as UnknownHashVariantError, l as UnknownVersionError, n as ChecksumError, o as SerializationError, r as FilterJSON, s as TruncatedError, t as BadMagicError } from "../serialize--xR6vGSW.cjs";
3
3
  import { t as ParamError } from "../params-DnqJBqLS.cjs";
4
- import { o as hllSizing, r as HllSizing } from "../sizing-BmKfHf_V.cjs";
5
4
  //#region src/hll/hll.d.ts
6
5
  /** Construction parameters for a {@link HyperLogLog} sketch. */
7
6
  interface HllParams {
@@ -117,4 +116,16 @@ export declare class HyperLogLog {
117
116
  count(): number;
118
117
  }
119
118
  //#endregion
120
- export { BadMagicError, ChecksumError, type FilterJSON, type HllParams, type HllSizing, ParamError, ReservedBitsError, SerializationError, TruncatedError, UnknownHashVariantError, UnknownVersionError, hllSizing };
119
+ //#region src/hll/sizing.d.ts
120
+ /** HyperLogLog geometry: the `HllParams` fields a sizing solve determines. */
121
+ interface HllSizing {
122
+ /** Precision: the sketch holds `2 ** p` registers. */
123
+ p: number;
124
+ }
125
+ /**
126
+ * Smallest precision whose standard error `1.04 / sqrt(2 ** p)` meets
127
+ * `relativeError`. Throws {@link ParamError} when even `HLL_MAX_P` cannot.
128
+ */
129
+ export declare function hllSizing(relativeError: number): HllSizing;
130
+ //#endregion
131
+ export { BadMagicError, ChecksumError, type FilterJSON, type HllParams, type HllSizing, ParamError, ReservedBitsError, SerializationError, TruncatedError, UnknownHashVariantError, UnknownVersionError };
@@ -1,7 +1,6 @@
1
1
  import { t as BytesLike } from "../bytes-DCuYtUVS.js";
2
2
  import { a as ReservedBitsError, c as UnknownHashVariantError, l as UnknownVersionError, n as ChecksumError, o as SerializationError, r as FilterJSON, s as TruncatedError, t as BadMagicError } from "../serialize--xR6vGSW.js";
3
3
  import { t as ParamError } from "../params-DnqJBqLS.js";
4
- import { o as hllSizing, r as HllSizing } from "../sizing-BmKfHf_V.js";
5
4
  //#region src/hll/hll.d.ts
6
5
  /** Construction parameters for a {@link HyperLogLog} sketch. */
7
6
  interface HllParams {
@@ -117,4 +116,16 @@ export declare class HyperLogLog {
117
116
  count(): number;
118
117
  }
119
118
  //#endregion
120
- export { BadMagicError, ChecksumError, type FilterJSON, type HllParams, type HllSizing, ParamError, ReservedBitsError, SerializationError, TruncatedError, UnknownHashVariantError, UnknownVersionError, hllSizing };
119
+ //#region src/hll/sizing.d.ts
120
+ /** HyperLogLog geometry: the `HllParams` fields a sizing solve determines. */
121
+ interface HllSizing {
122
+ /** Precision: the sketch holds `2 ** p` registers. */
123
+ p: number;
124
+ }
125
+ /**
126
+ * Smallest precision whose standard error `1.04 / sqrt(2 ** p)` meets
127
+ * `relativeError`. Throws {@link ParamError} when even `HLL_MAX_P` cannot.
128
+ */
129
+ export declare function hllSizing(relativeError: number): HllSizing;
130
+ //#endregion
131
+ export { BadMagicError, ChecksumError, type FilterJSON, type HllParams, type HllSizing, ParamError, ReservedBitsError, SerializationError, TruncatedError, UnknownHashVariantError, UnknownVersionError };
package/dist/hll/index.js CHANGED
@@ -1,7 +1,13 @@
1
- import { i as hash128KeyInto } from "../hasher-3Cyn7Yg-.js";
1
+ import { i as hash128KeyInto } from "../hasher-DOdmZ-LI.js";
2
2
  import { a as TruncatedError, c as assertBodyLength, f as fromJSONEnvelope, g as writeFrame, h as toJSONEnvelope, i as SerializationError, l as assertMinBodyLength, m as readHeader, n as ChecksumError, o as UnknownHashVariantError, r as ReservedBitsError, s as UnknownVersionError, t as BadMagicError, u as assertParamsPadding } from "../serialize-CMSYFym-.js";
3
- import { o as assertUint32, t as ParamError } from "../params-CeajSrwv.js";
4
- import { r as hllSizing } from "../sizing-D3-_7pdP.js";
3
+ import { i as assertProbability, o as assertUint32, t as ParamError } from "../params-CeajSrwv.js";
4
+ function hllSizing(relativeError) {
5
+ assertProbability(relativeError, "relativeError");
6
+ const p = Math.max(4, Math.ceil(2 * Math.log2(1.04 / relativeError)));
7
+ if (p > 18) throw new ParamError(`relativeError ${String(relativeError)} needs precision ${String(p)}, above the maximum ${String(18)}`);
8
+ return { p };
9
+ }
10
+ //#endregion
5
11
  //#region src/hll/estimate.ts
6
12
  const ALPHA_INF = .5 / Math.LN2;
7
13
  function sigma(x) {
package/dist/index.cjs CHANGED
@@ -1,6 +1,6 @@
1
1
  Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
2
2
  //#endregion
3
3
  //#region src/index.ts
4
- const VERSION = "0.13.0";
4
+ const VERSION = "0.14.0";
5
5
  //#endregion
6
6
  exports.VERSION = VERSION;
package/dist/index.js CHANGED
@@ -1,5 +1,5 @@
1
1
  //#endregion
2
2
  //#region src/index.ts
3
- const VERSION = "0.13.0";
3
+ const VERSION = "0.14.0";
4
4
  //#endregion
5
5
  export { VERSION };
@@ -1,9 +1,8 @@
1
1
  Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
2
- const require_bitset = require("../bitset-QYGqxnEf.cjs");
3
- const require_hasher = require("../hasher-MhY7aQ8F.cjs");
2
+ const require_sizing = require("../sizing-Ch0SDdza.cjs");
3
+ const require_hasher = require("../hasher-DPXmP7SH.cjs");
4
4
  const require_serialize = require("../serialize-CHikZ4GH.cjs");
5
5
  const require_params = require("../params-UTZbJ22c.cjs");
6
- const require_sizing = require("../sizing-R1pwbzjC.cjs");
7
6
  //#region src/scalable/scalable.ts
8
7
  const MAX_BITS = 4294967295;
9
8
  const TYPE = 6;
@@ -35,7 +34,7 @@ function readStages(body, entries, start) {
35
34
  let at = start;
36
35
  return entries.map((entry, i) => {
37
36
  const length = Math.ceil(entry.m / 8);
38
- const bits = new require_bitset.BitSet(entry.m);
37
+ const bits = new require_sizing.BitSet(entry.m);
39
38
  bits.bytes.set(body.subarray(at, at + length));
40
39
  for (let j = at + length; j < at + padded8(length); j++) if (body[j] !== 0) throw new require_serialize.SerializationError(`scalable: stage ${String(i)} bit padding is not zero`);
41
40
  at += padded8(length);
@@ -103,7 +102,7 @@ var ScalableBloomFilter = class ScalableBloomFilter {
103
102
  }
104
103
  #open({ capacity, m, k }) {
105
104
  const stage = {
106
- bits: new require_bitset.BitSet(m),
105
+ bits: new require_sizing.BitSet(m),
107
106
  m,
108
107
  k,
109
108
  capacity,
@@ -206,7 +205,7 @@ var ScalableBloomFilter = class ScalableBloomFilter {
206
205
  this.#assertMergeable(other);
207
206
  const [longer, shorter] = this.#stages.length >= other.#stages.length ? [this.#stages, other.#stages] : [other.#stages, this.#stages];
208
207
  const stages = longer.map((stage, i) => {
209
- const bits = new require_bitset.BitSet(stage.m);
208
+ const bits = new require_sizing.BitSet(stage.m);
210
209
  bits.bytes.set(stage.bits.bytes);
211
210
  const twin = shorter[i];
212
211
  if (twin) {
@@ -1,8 +1,7 @@
1
- import { t as BitSet } from "../bitset-Cf2jwRJX.js";
2
- import { i as hash128KeyInto, l as probeLanesInto, s as probeAt } from "../hasher-3Cyn7Yg-.js";
1
+ import { n as BitSet, t as bloomSizing } from "../sizing-zxCBlyhO.js";
2
+ import { i as hash128KeyInto, l as probeLanesInto, s as probeAt } from "../hasher-DOdmZ-LI.js";
3
3
  import { a as TruncatedError, c as assertBodyLength, d as bytesEqual, f as fromJSONEnvelope, g as writeFrame, h as toJSONEnvelope, i as SerializationError, l as assertMinBodyLength, m as readHeader, n as ChecksumError, o as UnknownHashVariantError, r as ReservedBitsError, s as UnknownVersionError, t as BadMagicError, u as assertParamsPadding } from "../serialize-CMSYFym-.js";
4
4
  import { i as assertProbability, o as assertUint32, r as assertPositiveInt, t as ParamError } from "../params-CeajSrwv.js";
5
- import { t as bloomSizing } from "../sizing-D3-_7pdP.js";
6
5
  //#region src/scalable/scalable.ts
7
6
  const MAX_BITS = 4294967295;
8
7
  const TYPE = 6;
@@ -29,9 +29,24 @@ var BitSet = class {
29
29
  }
30
30
  };
31
31
  //#endregion
32
+ //#region src/core/sizing.ts
33
+ function bloomSizing(n, epsilon) {
34
+ const m = Math.ceil(-n * Math.log(epsilon) / (Math.LN2 * Math.LN2));
35
+ return {
36
+ m,
37
+ k: Math.max(1, Math.round(m / n * Math.LN2))
38
+ };
39
+ }
40
+ //#endregion
32
41
  Object.defineProperty(exports, "BitSet", {
33
42
  enumerable: true,
34
43
  get: function() {
35
44
  return BitSet;
36
45
  }
37
46
  });
47
+ Object.defineProperty(exports, "bloomSizing", {
48
+ enumerable: true,
49
+ get: function() {
50
+ return bloomSizing;
51
+ }
52
+ });
@@ -29,4 +29,13 @@ var BitSet = class {
29
29
  }
30
30
  };
31
31
  //#endregion
32
- export { BitSet as t };
32
+ //#region src/core/sizing.ts
33
+ function bloomSizing(n, epsilon) {
34
+ const m = Math.ceil(-n * Math.log(epsilon) / (Math.LN2 * Math.LN2));
35
+ return {
36
+ m,
37
+ k: Math.max(1, Math.round(m / n * Math.LN2))
38
+ };
39
+ }
40
+ //#endregion
41
+ export { BitSet as n, bloomSizing as t };