distillate 0.3.0 → 0.4.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/blocked/index.cjs +6 -3
- package/dist/blocked/index.js +6 -3
- package/dist/bloom/index.cjs +16 -10
- package/dist/bloom/index.js +16 -10
- package/dist/fuse/index.cjs +6 -3
- package/dist/fuse/index.js +6 -3
- package/dist/index.cjs +1 -1
- package/dist/index.js +1 -1
- package/dist/{serialize-CHHDM4TQ.cjs → serialize-DPdiySxq.cjs} +27 -1
- package/dist/{serialize-5XQ5y_R-.js → serialize-DkkBKDT0.js} +16 -2
- package/package.json +1 -1
package/dist/blocked/index.cjs
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
|
|
2
|
-
const require_serialize = require("../serialize-
|
|
2
|
+
const require_serialize = require("../serialize-DPdiySxq.cjs");
|
|
3
3
|
const require_params = require("../params-J8p3bKq5.cjs");
|
|
4
4
|
//#region src/blocked/blocked.ts
|
|
5
5
|
const TYPE = 2;
|
|
@@ -104,11 +104,14 @@ var BlockedBloomFilter = class BlockedBloomFilter {
|
|
|
104
104
|
* @returns The reconstructed filter.
|
|
105
105
|
*/
|
|
106
106
|
static fromBytes(bytes) {
|
|
107
|
-
const { body } = require_serialize.readHeader(bytes);
|
|
107
|
+
const { type, body } = require_serialize.readHeader(bytes);
|
|
108
|
+
if (type !== TYPE) throw new require_serialize.SerializationError(`expected AMQF type ${String(TYPE)}, got ${String(type)}`);
|
|
109
|
+
require_serialize.assertMinBodyLength(body.length, 12, "blocked");
|
|
108
110
|
const dv = new DataView(body.buffer, body.byteOffset, body.byteLength);
|
|
109
111
|
const numBlocks = dv.getUint32(0, true);
|
|
110
112
|
const seed = dv.getUint32(4, true);
|
|
111
113
|
const n = dv.getUint32(8, true);
|
|
114
|
+
require_serialize.assertBodyLength(body.length, 12 + numBlocks * 32, "blocked");
|
|
112
115
|
const f = new BlockedBloomFilter({
|
|
113
116
|
bitsPerKey: 256,
|
|
114
117
|
capacity: numBlocks,
|
|
@@ -132,7 +135,7 @@ var BlockedBloomFilter = class BlockedBloomFilter {
|
|
|
132
135
|
dv.setUint32(8, this.#n, true);
|
|
133
136
|
body.set(lanes, 12);
|
|
134
137
|
return require_serialize.writeHeader({
|
|
135
|
-
version:
|
|
138
|
+
version: 2,
|
|
136
139
|
type: TYPE,
|
|
137
140
|
flags: 0
|
|
138
141
|
}, body);
|
package/dist/blocked/index.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { i as
|
|
1
|
+
import { a as writeHeader, c as reduce, i as readHeader, n as assertBodyLength, o as hash128KeyInto, r as assertMinBodyLength, t as SerializationError } from "../serialize-DkkBKDT0.js";
|
|
2
2
|
import { a as assertUint32, i as assertProbability, n as assertPositiveFinite, r as assertPositiveInt, t as ParamError } from "../params-ChTRNxM9.js";
|
|
3
3
|
//#region src/blocked/blocked.ts
|
|
4
4
|
const TYPE = 2;
|
|
@@ -103,11 +103,14 @@ var BlockedBloomFilter = class BlockedBloomFilter {
|
|
|
103
103
|
* @returns The reconstructed filter.
|
|
104
104
|
*/
|
|
105
105
|
static fromBytes(bytes) {
|
|
106
|
-
const { body } = readHeader(bytes);
|
|
106
|
+
const { type, body } = readHeader(bytes);
|
|
107
|
+
if (type !== TYPE) throw new SerializationError(`expected AMQF type ${String(TYPE)}, got ${String(type)}`);
|
|
108
|
+
assertMinBodyLength(body.length, 12, "blocked");
|
|
107
109
|
const dv = new DataView(body.buffer, body.byteOffset, body.byteLength);
|
|
108
110
|
const numBlocks = dv.getUint32(0, true);
|
|
109
111
|
const seed = dv.getUint32(4, true);
|
|
110
112
|
const n = dv.getUint32(8, true);
|
|
113
|
+
assertBodyLength(body.length, 12 + numBlocks * 32, "blocked");
|
|
111
114
|
const f = new BlockedBloomFilter({
|
|
112
115
|
bitsPerKey: 256,
|
|
113
116
|
capacity: numBlocks,
|
|
@@ -131,7 +134,7 @@ var BlockedBloomFilter = class BlockedBloomFilter {
|
|
|
131
134
|
dv.setUint32(8, this.#n, true);
|
|
132
135
|
body.set(lanes, 12);
|
|
133
136
|
return writeHeader({
|
|
134
|
-
version:
|
|
137
|
+
version: 2,
|
|
135
138
|
type: TYPE,
|
|
136
139
|
flags: 0
|
|
137
140
|
}, body);
|
package/dist/bloom/index.cjs
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
|
|
2
|
-
const require_serialize = require("../serialize-
|
|
2
|
+
const require_serialize = require("../serialize-DPdiySxq.cjs");
|
|
3
3
|
const require_params = require("../params-J8p3bKq5.cjs");
|
|
4
4
|
//#region src/core/bitset.ts
|
|
5
5
|
var BitSetRangeError = class extends RangeError {
|
|
@@ -94,17 +94,22 @@ var BloomFilter = class BloomFilter {
|
|
|
94
94
|
* @returns The reconstructed filter.
|
|
95
95
|
*/
|
|
96
96
|
static fromBytes(bytes) {
|
|
97
|
-
const { body } = require_serialize.readHeader(bytes);
|
|
97
|
+
const { type, body } = require_serialize.readHeader(bytes);
|
|
98
|
+
if (type !== TYPE) throw new require_serialize.SerializationError(`expected AMQF type ${String(TYPE)}, got ${String(type)}`);
|
|
99
|
+
require_serialize.assertMinBodyLength(body.length, 14, "bloom");
|
|
98
100
|
const dv = new DataView(body.buffer, body.byteOffset, body.byteLength);
|
|
99
101
|
const m = dv.getUint32(0, true);
|
|
100
|
-
const k =
|
|
101
|
-
const seed = dv.getUint32(
|
|
102
|
+
const k = dv.getUint16(4, true);
|
|
103
|
+
const seed = dv.getUint32(6, true);
|
|
104
|
+
const n = dv.getUint32(10, true);
|
|
105
|
+
require_serialize.assertBodyLength(body.length, 14 + Math.ceil(m / 8), "bloom");
|
|
102
106
|
const f = new BloomFilter({
|
|
103
107
|
m,
|
|
104
108
|
k,
|
|
105
109
|
seed
|
|
106
110
|
});
|
|
107
|
-
f.#
|
|
111
|
+
f.#n = n;
|
|
112
|
+
f.#bits.bytes.set(body.subarray(14));
|
|
108
113
|
return f;
|
|
109
114
|
}
|
|
110
115
|
/**
|
|
@@ -159,14 +164,15 @@ var BloomFilter = class BloomFilter {
|
|
|
159
164
|
*/
|
|
160
165
|
toBytes() {
|
|
161
166
|
const payload = this.#bits.bytes;
|
|
162
|
-
const body = new Uint8Array(
|
|
167
|
+
const body = new Uint8Array(14 + payload.length);
|
|
163
168
|
const dv = new DataView(body.buffer, body.byteOffset, body.byteLength);
|
|
164
169
|
dv.setUint32(0, this.#m, true);
|
|
165
|
-
|
|
166
|
-
dv.setUint32(
|
|
167
|
-
|
|
170
|
+
dv.setUint16(4, this.#k, true);
|
|
171
|
+
dv.setUint32(6, this.#seed, true);
|
|
172
|
+
dv.setUint32(10, this.#n, true);
|
|
173
|
+
body.set(payload, 14);
|
|
168
174
|
return require_serialize.writeHeader({
|
|
169
|
-
version:
|
|
175
|
+
version: 2,
|
|
170
176
|
type: TYPE,
|
|
171
177
|
flags: 0
|
|
172
178
|
}, body);
|
package/dist/bloom/index.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { a as
|
|
1
|
+
import { a as writeHeader, i as readHeader, n as assertBodyLength, r as assertMinBodyLength, s as probeInto, t as SerializationError } from "../serialize-DkkBKDT0.js";
|
|
2
2
|
import { a as assertUint32, i as assertProbability, r as assertPositiveInt, t as ParamError } from "../params-ChTRNxM9.js";
|
|
3
3
|
//#region src/core/bitset.ts
|
|
4
4
|
var BitSetRangeError = class extends RangeError {
|
|
@@ -93,17 +93,22 @@ var BloomFilter = class BloomFilter {
|
|
|
93
93
|
* @returns The reconstructed filter.
|
|
94
94
|
*/
|
|
95
95
|
static fromBytes(bytes) {
|
|
96
|
-
const { body } = readHeader(bytes);
|
|
96
|
+
const { type, body } = readHeader(bytes);
|
|
97
|
+
if (type !== TYPE) throw new SerializationError(`expected AMQF type ${String(TYPE)}, got ${String(type)}`);
|
|
98
|
+
assertMinBodyLength(body.length, 14, "bloom");
|
|
97
99
|
const dv = new DataView(body.buffer, body.byteOffset, body.byteLength);
|
|
98
100
|
const m = dv.getUint32(0, true);
|
|
99
|
-
const k =
|
|
100
|
-
const seed = dv.getUint32(
|
|
101
|
+
const k = dv.getUint16(4, true);
|
|
102
|
+
const seed = dv.getUint32(6, true);
|
|
103
|
+
const n = dv.getUint32(10, true);
|
|
104
|
+
assertBodyLength(body.length, 14 + Math.ceil(m / 8), "bloom");
|
|
101
105
|
const f = new BloomFilter({
|
|
102
106
|
m,
|
|
103
107
|
k,
|
|
104
108
|
seed
|
|
105
109
|
});
|
|
106
|
-
f.#
|
|
110
|
+
f.#n = n;
|
|
111
|
+
f.#bits.bytes.set(body.subarray(14));
|
|
107
112
|
return f;
|
|
108
113
|
}
|
|
109
114
|
/**
|
|
@@ -158,14 +163,15 @@ var BloomFilter = class BloomFilter {
|
|
|
158
163
|
*/
|
|
159
164
|
toBytes() {
|
|
160
165
|
const payload = this.#bits.bytes;
|
|
161
|
-
const body = new Uint8Array(
|
|
166
|
+
const body = new Uint8Array(14 + payload.length);
|
|
162
167
|
const dv = new DataView(body.buffer, body.byteOffset, body.byteLength);
|
|
163
168
|
dv.setUint32(0, this.#m, true);
|
|
164
|
-
|
|
165
|
-
dv.setUint32(
|
|
166
|
-
|
|
169
|
+
dv.setUint16(4, this.#k, true);
|
|
170
|
+
dv.setUint32(6, this.#seed, true);
|
|
171
|
+
dv.setUint32(10, this.#n, true);
|
|
172
|
+
body.set(payload, 14);
|
|
167
173
|
return writeHeader({
|
|
168
|
-
version:
|
|
174
|
+
version: 2,
|
|
169
175
|
type: TYPE,
|
|
170
176
|
flags: 0
|
|
171
177
|
}, body);
|
package/dist/fuse/index.cjs
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
|
|
2
|
-
const require_serialize = require("../serialize-
|
|
2
|
+
const require_serialize = require("../serialize-DPdiySxq.cjs");
|
|
3
3
|
//#region src/fuse/fuse.ts
|
|
4
4
|
const ARITY = 3;
|
|
5
5
|
const TYPE_FUSE8 = 3;
|
|
@@ -211,13 +211,16 @@ function buildState(keys, alloc) {
|
|
|
211
211
|
function fuseStateFromBytes(bytes, expectedType) {
|
|
212
212
|
const { type, body } = require_serialize.readHeader(bytes);
|
|
213
213
|
if (type !== expectedType) throw new require_serialize.SerializationError(`expected AMQF type ${String(expectedType)}, got ${String(type)}`);
|
|
214
|
+
require_serialize.assertMinBodyLength(body.length, 16, "fuse");
|
|
214
215
|
const dv = new DataView(body.buffer, body.byteOffset, body.byteLength);
|
|
215
216
|
const seed = dv.getUint32(0, true);
|
|
216
217
|
const seg = dv.getUint32(4, true);
|
|
217
218
|
const segCountLen = dv.getUint32(8, true);
|
|
218
219
|
const size = dv.getUint32(12, true);
|
|
219
|
-
const laneBytes = body.subarray(16);
|
|
220
220
|
const bpe = expectedType === TYPE_FUSE8 ? 1 : 2;
|
|
221
|
+
const expectedArrayLength = size === 0 ? 0 : segCountLen + 2 * seg;
|
|
222
|
+
require_serialize.assertBodyLength(body.length, 16 + expectedArrayLength * bpe, "fuse");
|
|
223
|
+
const laneBytes = body.subarray(16);
|
|
221
224
|
const arrayLength = laneBytes.length / bpe;
|
|
222
225
|
const fp = bpe === 1 ? new Uint8Array(arrayLength) : new Uint16Array(arrayLength);
|
|
223
226
|
new Uint8Array(fp.buffer).set(laneBytes);
|
|
@@ -276,7 +279,7 @@ var BinaryFuse = class {
|
|
|
276
279
|
dv.setUint32(12, this.#size, true);
|
|
277
280
|
body.set(laneBytes, 16);
|
|
278
281
|
return require_serialize.writeHeader({
|
|
279
|
-
version:
|
|
282
|
+
version: 2,
|
|
280
283
|
type: this.#fp.BYTES_PER_ELEMENT === 1 ? TYPE_FUSE8 : TYPE_FUSE16,
|
|
281
284
|
flags: 0
|
|
282
285
|
}, body);
|
package/dist/fuse/index.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { i as
|
|
1
|
+
import { a as writeHeader, i as readHeader, n as assertBodyLength, o as hash128KeyInto, r as assertMinBodyLength, t as SerializationError } from "../serialize-DkkBKDT0.js";
|
|
2
2
|
//#region src/fuse/fuse.ts
|
|
3
3
|
const ARITY = 3;
|
|
4
4
|
const TYPE_FUSE8 = 3;
|
|
@@ -210,13 +210,16 @@ function buildState(keys, alloc) {
|
|
|
210
210
|
function fuseStateFromBytes(bytes, expectedType) {
|
|
211
211
|
const { type, body } = readHeader(bytes);
|
|
212
212
|
if (type !== expectedType) throw new SerializationError(`expected AMQF type ${String(expectedType)}, got ${String(type)}`);
|
|
213
|
+
assertMinBodyLength(body.length, 16, "fuse");
|
|
213
214
|
const dv = new DataView(body.buffer, body.byteOffset, body.byteLength);
|
|
214
215
|
const seed = dv.getUint32(0, true);
|
|
215
216
|
const seg = dv.getUint32(4, true);
|
|
216
217
|
const segCountLen = dv.getUint32(8, true);
|
|
217
218
|
const size = dv.getUint32(12, true);
|
|
218
|
-
const laneBytes = body.subarray(16);
|
|
219
219
|
const bpe = expectedType === TYPE_FUSE8 ? 1 : 2;
|
|
220
|
+
const expectedArrayLength = size === 0 ? 0 : segCountLen + 2 * seg;
|
|
221
|
+
assertBodyLength(body.length, 16 + expectedArrayLength * bpe, "fuse");
|
|
222
|
+
const laneBytes = body.subarray(16);
|
|
220
223
|
const arrayLength = laneBytes.length / bpe;
|
|
221
224
|
const fp = bpe === 1 ? new Uint8Array(arrayLength) : new Uint16Array(arrayLength);
|
|
222
225
|
new Uint8Array(fp.buffer).set(laneBytes);
|
|
@@ -275,7 +278,7 @@ var BinaryFuse = class {
|
|
|
275
278
|
dv.setUint32(12, this.#size, true);
|
|
276
279
|
body.set(laneBytes, 16);
|
|
277
280
|
return writeHeader({
|
|
278
|
-
version:
|
|
281
|
+
version: 2,
|
|
279
282
|
type: this.#fp.BYTES_PER_ELEMENT === 1 ? TYPE_FUSE8 : TYPE_FUSE16,
|
|
280
283
|
flags: 0
|
|
281
284
|
}, body);
|
package/dist/index.cjs
CHANGED
package/dist/index.js
CHANGED
|
@@ -277,11 +277,25 @@ var UnknownVersionError = class extends SerializationError {
|
|
|
277
277
|
var ChecksumError = class extends SerializationError {
|
|
278
278
|
name = "ChecksumError";
|
|
279
279
|
};
|
|
280
|
+
/**
|
|
281
|
+
* Asserts a frame body is long enough to hold its fixed params block, so the
|
|
282
|
+
* params can be read without running off the end.
|
|
283
|
+
*/
|
|
284
|
+
function assertMinBodyLength(actual, min, context) {
|
|
285
|
+
if (actual < min) throw new TruncatedError(`${context}: body of ${String(actual)} bytes is shorter than the ${String(min)}-byte params block`);
|
|
286
|
+
}
|
|
287
|
+
/**
|
|
288
|
+
* Asserts a frame body is exactly the length its declared params imply, so a
|
|
289
|
+
* hostile or truncated frame is rejected before any backing store is allocated.
|
|
290
|
+
*/
|
|
291
|
+
function assertBodyLength(actual, expected, context) {
|
|
292
|
+
if (actual !== expected) throw new TruncatedError(`${context}: body of ${String(actual)} bytes does not match the declared params (expected ${String(expected)})`);
|
|
293
|
+
}
|
|
280
294
|
function readHeader(frame) {
|
|
281
295
|
if (frame.length < 12) throw new TruncatedError(`frame of ${String(frame.length)} bytes is shorter than the minimum ${String(12)}`);
|
|
282
296
|
if (frame[0] !== 65 || frame[1] !== 77 || frame[2] !== 81 || frame[3] !== 70) throw new BadMagicError("frame does not start with the AMQF magic");
|
|
283
297
|
const version = frame[4] ?? 0;
|
|
284
|
-
if (version !==
|
|
298
|
+
if (version !== 2) throw new UnknownVersionError(`unsupported format version ${String(version)}`);
|
|
285
299
|
if (new DataView(frame.buffer, frame.byteOffset, frame.byteLength).getUint32(frame.length - TRAILER_SIZE, true) !== crc32(frame.subarray(0, frame.length - TRAILER_SIZE))) throw new ChecksumError("frame CRC32 does not match its contents");
|
|
286
300
|
return {
|
|
287
301
|
version,
|
|
@@ -297,6 +311,18 @@ Object.defineProperty(exports, "SerializationError", {
|
|
|
297
311
|
return SerializationError;
|
|
298
312
|
}
|
|
299
313
|
});
|
|
314
|
+
Object.defineProperty(exports, "assertBodyLength", {
|
|
315
|
+
enumerable: true,
|
|
316
|
+
get: function() {
|
|
317
|
+
return assertBodyLength;
|
|
318
|
+
}
|
|
319
|
+
});
|
|
320
|
+
Object.defineProperty(exports, "assertMinBodyLength", {
|
|
321
|
+
enumerable: true,
|
|
322
|
+
get: function() {
|
|
323
|
+
return assertMinBodyLength;
|
|
324
|
+
}
|
|
325
|
+
});
|
|
300
326
|
Object.defineProperty(exports, "hash128KeyInto", {
|
|
301
327
|
enumerable: true,
|
|
302
328
|
get: function() {
|
|
@@ -277,11 +277,25 @@ var UnknownVersionError = class extends SerializationError {
|
|
|
277
277
|
var ChecksumError = class extends SerializationError {
|
|
278
278
|
name = "ChecksumError";
|
|
279
279
|
};
|
|
280
|
+
/**
|
|
281
|
+
* Asserts a frame body is long enough to hold its fixed params block, so the
|
|
282
|
+
* params can be read without running off the end.
|
|
283
|
+
*/
|
|
284
|
+
function assertMinBodyLength(actual, min, context) {
|
|
285
|
+
if (actual < min) throw new TruncatedError(`${context}: body of ${String(actual)} bytes is shorter than the ${String(min)}-byte params block`);
|
|
286
|
+
}
|
|
287
|
+
/**
|
|
288
|
+
* Asserts a frame body is exactly the length its declared params imply, so a
|
|
289
|
+
* hostile or truncated frame is rejected before any backing store is allocated.
|
|
290
|
+
*/
|
|
291
|
+
function assertBodyLength(actual, expected, context) {
|
|
292
|
+
if (actual !== expected) throw new TruncatedError(`${context}: body of ${String(actual)} bytes does not match the declared params (expected ${String(expected)})`);
|
|
293
|
+
}
|
|
280
294
|
function readHeader(frame) {
|
|
281
295
|
if (frame.length < 12) throw new TruncatedError(`frame of ${String(frame.length)} bytes is shorter than the minimum ${String(12)}`);
|
|
282
296
|
if (frame[0] !== 65 || frame[1] !== 77 || frame[2] !== 81 || frame[3] !== 70) throw new BadMagicError("frame does not start with the AMQF magic");
|
|
283
297
|
const version = frame[4] ?? 0;
|
|
284
|
-
if (version !==
|
|
298
|
+
if (version !== 2) throw new UnknownVersionError(`unsupported format version ${String(version)}`);
|
|
285
299
|
if (new DataView(frame.buffer, frame.byteOffset, frame.byteLength).getUint32(frame.length - TRAILER_SIZE, true) !== crc32(frame.subarray(0, frame.length - TRAILER_SIZE))) throw new ChecksumError("frame CRC32 does not match its contents");
|
|
286
300
|
return {
|
|
287
301
|
version,
|
|
@@ -291,4 +305,4 @@ function readHeader(frame) {
|
|
|
291
305
|
};
|
|
292
306
|
}
|
|
293
307
|
//#endregion
|
|
294
|
-
export {
|
|
308
|
+
export { writeHeader as a, reduce as c, readHeader as i, assertBodyLength as n, hash128KeyInto as o, assertMinBodyLength as r, probeInto as s, SerializationError as t };
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "distillate",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.4.0",
|
|
4
4
|
"description": "Probabilistic data structures for JavaScript. Space-efficient, approximate-membership filters (Bloom, Blocked Bloom, Binary Fuse) with tunable error and a portable binary format; zero dependencies, universal.",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"bloom-filter",
|