@sorisdk/matcher 0.6.2 → 0.6.4
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/README.md +20 -0
- package/dist/generated/core.d.ts +2 -0
- package/dist/generated/core_bg.js +28 -0
- package/dist/generated/core_bg.wasm +0 -0
- package/dist/generated/core_bg.wasm.d.ts +2 -0
- package/dist/index.d.ts +11 -1
- package/dist/index.js +113 -15
- package/package.json +2 -2
package/README.md
CHANGED
|
@@ -67,6 +67,26 @@ const session = new MatcherSession({
|
|
|
67
67
|
- `string`
|
|
68
68
|
- `URL`
|
|
69
69
|
|
|
70
|
+
Pack loading is bounded and transactional. Browser sources are limited to
|
|
71
|
+
64 MiB by default: a valid oversized `Content-Length` is rejected before the
|
|
72
|
+
body is consumed, and streamed/chunked responses are canceled when their bytes
|
|
73
|
+
cross the same limit. The Rust/WASM parser independently enforces its aggregate
|
|
74
|
+
pack, instruction, entry-buffer, and footer limits. Any failed load preserves
|
|
75
|
+
the session's previous database.
|
|
76
|
+
|
|
77
|
+
Set an intentional browser-source override when constructing the session:
|
|
78
|
+
|
|
79
|
+
```ts
|
|
80
|
+
const session = new MatcherSession({
|
|
81
|
+
maxPackBytes: 96 * 1024 * 1024
|
|
82
|
+
});
|
|
83
|
+
```
|
|
84
|
+
|
|
85
|
+
`DEFAULT_MAX_PACK_BYTES` exports the 64 MiB default for applications that need
|
|
86
|
+
to align their own transport controls. The same override is passed to the
|
|
87
|
+
Rust/WASM total-input budget; instruction, cumulative-entry, footer, and
|
|
88
|
+
per-entry limits remain independently enforced.
|
|
89
|
+
|
|
70
90
|
If you want campaign events and browser recognition flow on top of matching, use `@sorisdk/web-audio`.
|
|
71
91
|
|
|
72
92
|
## Metadata lookup
|
package/dist/generated/core.d.ts
CHANGED
|
@@ -10,6 +10,8 @@ export class WasmMatcherDatabase {
|
|
|
10
10
|
getEntryMetadata(name: string): any;
|
|
11
11
|
loadPackBytes(bytes: Uint8Array): void;
|
|
12
12
|
loadPackBytesAppend(bytes: Uint8Array): void;
|
|
13
|
+
loadPackBytesAppendWithMaxBytes(bytes: Uint8Array, max_pack_bytes: number): void;
|
|
14
|
+
loadPackBytesWithMaxBytes(bytes: Uint8Array, max_pack_bytes: number): void;
|
|
13
15
|
constructor();
|
|
14
16
|
removeEntry(name: string): void;
|
|
15
17
|
setEntryVariantMetadata(name: string, encoded_metadata: string): void;
|
|
@@ -85,6 +85,30 @@ export class WasmMatcherDatabase {
|
|
|
85
85
|
throw takeFromExternrefTable0(ret[0]);
|
|
86
86
|
}
|
|
87
87
|
}
|
|
88
|
+
/**
|
|
89
|
+
* @param {Uint8Array} bytes
|
|
90
|
+
* @param {number} max_pack_bytes
|
|
91
|
+
*/
|
|
92
|
+
loadPackBytesAppendWithMaxBytes(bytes, max_pack_bytes) {
|
|
93
|
+
const ptr0 = passArray8ToWasm0(bytes, wasm.__wbindgen_malloc);
|
|
94
|
+
const len0 = WASM_VECTOR_LEN;
|
|
95
|
+
const ret = wasm.wasmmatcherdatabase_loadPackBytesAppendWithMaxBytes(this.__wbg_ptr, ptr0, len0, max_pack_bytes);
|
|
96
|
+
if (ret[1]) {
|
|
97
|
+
throw takeFromExternrefTable0(ret[0]);
|
|
98
|
+
}
|
|
99
|
+
}
|
|
100
|
+
/**
|
|
101
|
+
* @param {Uint8Array} bytes
|
|
102
|
+
* @param {number} max_pack_bytes
|
|
103
|
+
*/
|
|
104
|
+
loadPackBytesWithMaxBytes(bytes, max_pack_bytes) {
|
|
105
|
+
const ptr0 = passArray8ToWasm0(bytes, wasm.__wbindgen_malloc);
|
|
106
|
+
const len0 = WASM_VECTOR_LEN;
|
|
107
|
+
const ret = wasm.wasmmatcherdatabase_loadPackBytesWithMaxBytes(this.__wbg_ptr, ptr0, len0, max_pack_bytes);
|
|
108
|
+
if (ret[1]) {
|
|
109
|
+
throw takeFromExternrefTable0(ret[0]);
|
|
110
|
+
}
|
|
111
|
+
}
|
|
88
112
|
constructor() {
|
|
89
113
|
const ret = wasm.wasmmatcherdatabase_new();
|
|
90
114
|
this.__wbg_ptr = ret >>> 0;
|
|
@@ -618,6 +642,10 @@ export function __wbg_new_227d7c05414eb861() {
|
|
|
618
642
|
const ret = new Error();
|
|
619
643
|
return ret;
|
|
620
644
|
}
|
|
645
|
+
export function __wbg_new_24a82d8799c298c3(arg0, arg1) {
|
|
646
|
+
const ret = new TypeError(getStringFromWasm0(arg0, arg1));
|
|
647
|
+
return ret;
|
|
648
|
+
}
|
|
621
649
|
export function __wbg_new_34d45cc8e36aaead() {
|
|
622
650
|
const ret = new Map();
|
|
623
651
|
return ret;
|
|
Binary file
|
|
@@ -17,6 +17,8 @@ export const wasmmatcherdatabase_getEntryMetadata: (a: number, b: number, c: num
|
|
|
17
17
|
export const wasmmatcherdatabase_length: (a: number) => number;
|
|
18
18
|
export const wasmmatcherdatabase_loadPackBytes: (a: number, b: number, c: number) => [number, number];
|
|
19
19
|
export const wasmmatcherdatabase_loadPackBytesAppend: (a: number, b: number, c: number) => [number, number];
|
|
20
|
+
export const wasmmatcherdatabase_loadPackBytesAppendWithMaxBytes: (a: number, b: number, c: number, d: number) => [number, number];
|
|
21
|
+
export const wasmmatcherdatabase_loadPackBytesWithMaxBytes: (a: number, b: number, c: number, d: number) => [number, number];
|
|
20
22
|
export const wasmmatcherdatabase_new: () => number;
|
|
21
23
|
export const wasmmatcherdatabase_removeEntry: (a: number, b: number, c: number) => [number, number];
|
|
22
24
|
export const wasmmatcherdatabase_setEntryVariantMetadata: (a: number, b: number, c: number, d: number, e: number) => [number, number];
|
package/dist/index.d.ts
CHANGED
|
@@ -139,6 +139,8 @@ type MatcherSessionEventName = keyof MatcherSessionEventMap;
|
|
|
139
139
|
type MatcherSessionListener<T extends MatcherSessionEventName> = (payload: MatcherSessionEventMap[T]) => void;
|
|
140
140
|
|
|
141
141
|
type FetchLike = (input: string | URL | Request, init?: RequestInit) => Promise<Response>;
|
|
142
|
+
/** Default browser-side ceiling for one AudioPack response or byte source (64 MiB). */
|
|
143
|
+
declare const DEFAULT_MAX_PACK_BYTES: number;
|
|
142
144
|
|
|
143
145
|
interface MatcherEphemeralKeyExchangeOptions {
|
|
144
146
|
endpoint: string | URL;
|
|
@@ -192,22 +194,28 @@ interface InitMatcherOptions {
|
|
|
192
194
|
loader?: () => Promise<unknown>;
|
|
193
195
|
wasmModule?: unknown;
|
|
194
196
|
wasmInitInput?: unknown;
|
|
197
|
+
embeddedPackLoader?: () => Promise<Uint8Array>;
|
|
195
198
|
auth?: MatcherEphemeralAuthOptions;
|
|
196
199
|
}
|
|
197
200
|
interface MatcherSessionOptions extends InitMatcherOptions {
|
|
198
201
|
fetch?: FetchLike;
|
|
202
|
+
/** Browser-side maximum for one pack source before it reaches WASM. Defaults to 64 MiB. */
|
|
203
|
+
maxPackBytes?: number;
|
|
199
204
|
}
|
|
200
205
|
type InitMatcherResult = MatcherEphemeralAuthResult;
|
|
201
206
|
declare function initMatcher(options?: InitMatcherOptions): Promise<InitMatcherResult | void>;
|
|
202
207
|
declare class MatcherSession {
|
|
203
208
|
private readonly events;
|
|
204
209
|
private readonly fetcher?;
|
|
210
|
+
private readonly maxPackBytes;
|
|
205
211
|
private readonly initOptions;
|
|
212
|
+
private readonly embeddedPackLoader?;
|
|
206
213
|
private readyPromise;
|
|
207
214
|
private bindings;
|
|
208
215
|
private database;
|
|
209
216
|
private matcher;
|
|
210
217
|
private destroyed;
|
|
218
|
+
private packLoadTail;
|
|
211
219
|
private readonly distinctMatchDeduper;
|
|
212
220
|
constructor(options?: MatcherSessionOptions);
|
|
213
221
|
on<T extends MatcherSessionEventName>(eventName: T, listener: MatcherSessionListener<T>): this;
|
|
@@ -215,6 +223,7 @@ declare class MatcherSession {
|
|
|
215
223
|
once<T extends MatcherSessionEventName>(eventName: T, listener: MatcherSessionListener<T>): this;
|
|
216
224
|
ready(): Promise<void>;
|
|
217
225
|
loadPack(source: PackSource): Promise<void>;
|
|
226
|
+
private loadPackExclusive;
|
|
218
227
|
addEntry(name: string, afpType: AudioFingerprintType, fingerprint: Uint8Array): Promise<void>;
|
|
219
228
|
addOrReplace(name: string, afpType: AudioFingerprintType, fingerprint: Uint8Array, metadata?: EntryMetadata | null): Promise<void>;
|
|
220
229
|
setEntryVariantMetadata(name: string, encodedMetadata: string): Promise<void>;
|
|
@@ -235,6 +244,7 @@ declare class MatcherSession {
|
|
|
235
244
|
private ensureLiveReady;
|
|
236
245
|
private ensureNotDestroyed;
|
|
237
246
|
private matcherOrThrow;
|
|
247
|
+
private bindingsOrThrow;
|
|
238
248
|
private databaseOrThrow;
|
|
239
249
|
private emitDistinctMatchEvent;
|
|
240
250
|
}
|
|
@@ -242,4 +252,4 @@ declare function __setMatcherWasmModuleForTests(moduleLike: unknown): void;
|
|
|
242
252
|
declare function __setMatcherEmbeddedPackForTests(bytes: Uint8Array): void;
|
|
243
253
|
declare function __resetMatcherWasmForTests(): void;
|
|
244
254
|
|
|
245
|
-
export { AudioFingerprintType, type AudioMarkerCode, type AudioMarkerConfig, type AudioMarkerDetection, type EntryMetadata, type InitMatcherOptions, type InitMatcherResult, type MatchConfig, type MatchResult, type MatcherEphemeralAuthOptions, type MatcherEphemeralAuthResult, type MatcherEphemeralKeyExchangeMetadata, type MatcherEphemeralKeyExchangeOptions, MatcherSession, type MatcherSessionEventMap, type MatcherSessionEventName, type MatcherSessionListener, type MatcherSessionOptions, type PackSource, type PitchRatioEstimate, type PitchReferenceEstimate, type VariantDecision, type VariantDecisionStatus, type VariantMatch, type VariantMatchConfig, type VariantMatchQuery, __resetMatcherWasmForTests, __setMatcherEmbeddedPackForTests, __setMatcherWasmModuleForTests, initMatcher };
|
|
255
|
+
export { AudioFingerprintType, type AudioMarkerCode, type AudioMarkerConfig, type AudioMarkerDetection, DEFAULT_MAX_PACK_BYTES, type EntryMetadata, type InitMatcherOptions, type InitMatcherResult, type MatchConfig, type MatchResult, type MatcherEphemeralAuthOptions, type MatcherEphemeralAuthResult, type MatcherEphemeralKeyExchangeMetadata, type MatcherEphemeralKeyExchangeOptions, MatcherSession, type MatcherSessionEventMap, type MatcherSessionEventName, type MatcherSessionListener, type MatcherSessionOptions, type PackSource, type PitchRatioEstimate, type PitchReferenceEstimate, type VariantDecision, type VariantDecisionStatus, type VariantMatch, type VariantMatchConfig, type VariantMatchQuery, __resetMatcherWasmForTests, __setMatcherEmbeddedPackForTests, __setMatcherWasmModuleForTests, initMatcher };
|
package/dist/index.js
CHANGED
|
@@ -174,6 +174,7 @@ function __resetEmbeddedPackLoaderForTests() {
|
|
|
174
174
|
}
|
|
175
175
|
|
|
176
176
|
// src/source.ts
|
|
177
|
+
var DEFAULT_MAX_PACK_BYTES = 64 * 1024 * 1024;
|
|
177
178
|
function hasCtor(name) {
|
|
178
179
|
return typeof globalThis[name] !== "undefined";
|
|
179
180
|
}
|
|
@@ -183,6 +184,20 @@ function copyToUint8Array(input) {
|
|
|
183
184
|
function toUint8Array(buffer) {
|
|
184
185
|
return new Uint8Array(buffer.slice(0));
|
|
185
186
|
}
|
|
187
|
+
function validateMaxPackBytes(maxPackBytes) {
|
|
188
|
+
if (!Number.isSafeInteger(maxPackBytes) || maxPackBytes <= 0 || maxPackBytes > 4294967295) {
|
|
189
|
+
throw new Error("maxPackBytes must be a positive 32-bit unsigned integer");
|
|
190
|
+
}
|
|
191
|
+
return maxPackBytes;
|
|
192
|
+
}
|
|
193
|
+
function packSizeError(maxPackBytes) {
|
|
194
|
+
return new Error(`Pack source exceeds maximum size of ${maxPackBytes} bytes`);
|
|
195
|
+
}
|
|
196
|
+
function assertKnownByteLength(byteLength, maxPackBytes) {
|
|
197
|
+
if (byteLength > maxPackBytes) {
|
|
198
|
+
throw packSizeError(maxPackBytes);
|
|
199
|
+
}
|
|
200
|
+
}
|
|
186
201
|
function classifyPackSource(source) {
|
|
187
202
|
if (source instanceof Uint8Array) {
|
|
188
203
|
return "uint8array";
|
|
@@ -216,29 +231,68 @@ function resolveFetch3(fetcher) {
|
|
|
216
231
|
}
|
|
217
232
|
return globalThis.fetch.bind(globalThis);
|
|
218
233
|
}
|
|
219
|
-
async function readResponseAsBytes(response) {
|
|
234
|
+
async function readResponseAsBytes(response, maxPackBytes) {
|
|
220
235
|
if (!response.ok) {
|
|
221
236
|
throw new Error(`Failed to load pack: HTTP ${response.status}`);
|
|
222
237
|
}
|
|
223
|
-
|
|
238
|
+
const contentLength = response.headers.get("content-length");
|
|
239
|
+
if (contentLength !== null && /^\d+$/.test(contentLength.trim())) {
|
|
240
|
+
const declaredLength = Number(contentLength);
|
|
241
|
+
if (Number.isSafeInteger(declaredLength)) {
|
|
242
|
+
assertKnownByteLength(declaredLength, maxPackBytes);
|
|
243
|
+
}
|
|
244
|
+
}
|
|
245
|
+
if (!response.body) {
|
|
246
|
+
return new Uint8Array();
|
|
247
|
+
}
|
|
248
|
+
const reader = response.body.getReader();
|
|
249
|
+
const chunks = [];
|
|
250
|
+
let byteLength = 0;
|
|
251
|
+
try {
|
|
252
|
+
while (true) {
|
|
253
|
+
const { done, value } = await reader.read();
|
|
254
|
+
if (done) {
|
|
255
|
+
break;
|
|
256
|
+
}
|
|
257
|
+
byteLength += value.byteLength;
|
|
258
|
+
if (byteLength > maxPackBytes) {
|
|
259
|
+
await reader.cancel();
|
|
260
|
+
throw packSizeError(maxPackBytes);
|
|
261
|
+
}
|
|
262
|
+
chunks.push(value);
|
|
263
|
+
}
|
|
264
|
+
} finally {
|
|
265
|
+
reader.releaseLock();
|
|
266
|
+
}
|
|
267
|
+
const bytes = new Uint8Array(byteLength);
|
|
268
|
+
let offset = 0;
|
|
269
|
+
for (const chunk of chunks) {
|
|
270
|
+
bytes.set(chunk, offset);
|
|
271
|
+
offset += chunk.byteLength;
|
|
272
|
+
}
|
|
273
|
+
return bytes;
|
|
224
274
|
}
|
|
225
|
-
async function normalizePackSource(source, fetcher) {
|
|
275
|
+
async function normalizePackSource(source, fetcher, maxPackBytes = DEFAULT_MAX_PACK_BYTES) {
|
|
276
|
+
maxPackBytes = validateMaxPackBytes(maxPackBytes);
|
|
226
277
|
const sourceType = classifyPackSource(source);
|
|
227
278
|
if (source instanceof Uint8Array) {
|
|
279
|
+
assertKnownByteLength(source.byteLength, maxPackBytes);
|
|
228
280
|
return { sourceType, bytes: copyToUint8Array(source) };
|
|
229
281
|
}
|
|
230
282
|
if (source instanceof ArrayBuffer) {
|
|
283
|
+
assertKnownByteLength(source.byteLength, maxPackBytes);
|
|
231
284
|
return { sourceType, bytes: toUint8Array(source) };
|
|
232
285
|
}
|
|
233
286
|
if (hasCtor("Blob") && source instanceof Blob) {
|
|
287
|
+
assertKnownByteLength(source.size, maxPackBytes);
|
|
234
288
|
return { sourceType, bytes: toUint8Array(await source.arrayBuffer()) };
|
|
235
289
|
}
|
|
236
290
|
if (hasCtor("Response") && source instanceof Response) {
|
|
237
|
-
return { sourceType, bytes: await readResponseAsBytes(source) };
|
|
291
|
+
return { sourceType, bytes: await readResponseAsBytes(source, maxPackBytes) };
|
|
238
292
|
}
|
|
239
293
|
if (typeof source === "string" || source instanceof URL || hasCtor("Request") && source instanceof Request) {
|
|
240
294
|
const response = await resolveFetch3(fetcher)(source);
|
|
241
|
-
return { sourceType, bytes: await readResponseAsBytes(response) };
|
|
295
|
+
return { sourceType, bytes: await readResponseAsBytes(response, maxPackBytes) };
|
|
242
296
|
}
|
|
243
297
|
throw new Error("Unsupported pack source type");
|
|
244
298
|
}
|
|
@@ -297,6 +351,7 @@ var WrappedDatabase = class {
|
|
|
297
351
|
constructor(inner) {
|
|
298
352
|
this.inner = inner;
|
|
299
353
|
}
|
|
354
|
+
inner;
|
|
300
355
|
raw() {
|
|
301
356
|
return this.inner;
|
|
302
357
|
}
|
|
@@ -328,7 +383,15 @@ var WrappedDatabase = class {
|
|
|
328
383
|
}
|
|
329
384
|
fn.call(this.inner);
|
|
330
385
|
}
|
|
331
|
-
loadPackBytes(bytes) {
|
|
386
|
+
loadPackBytes(bytes, maxPackBytes) {
|
|
387
|
+
const limitedFn = getCallable(this.inner, [
|
|
388
|
+
"loadPackBytesWithMaxBytes",
|
|
389
|
+
"load_pack_bytes_with_max_bytes"
|
|
390
|
+
]);
|
|
391
|
+
if (maxPackBytes !== void 0 && limitedFn) {
|
|
392
|
+
limitedFn.call(this.inner, bytes, maxPackBytes);
|
|
393
|
+
return;
|
|
394
|
+
}
|
|
332
395
|
const fn = getCallable(this.inner, [
|
|
333
396
|
"loadPackBytes",
|
|
334
397
|
"loadPack",
|
|
@@ -340,7 +403,15 @@ var WrappedDatabase = class {
|
|
|
340
403
|
}
|
|
341
404
|
fn.call(this.inner, bytes);
|
|
342
405
|
}
|
|
343
|
-
loadPackBytesAppend(bytes) {
|
|
406
|
+
loadPackBytesAppend(bytes, maxPackBytes) {
|
|
407
|
+
const limitedFn = getCallable(this.inner, [
|
|
408
|
+
"loadPackBytesAppendWithMaxBytes",
|
|
409
|
+
"load_pack_bytes_append_with_max_bytes"
|
|
410
|
+
]);
|
|
411
|
+
if (maxPackBytes !== void 0 && limitedFn) {
|
|
412
|
+
limitedFn.call(this.inner, bytes, maxPackBytes);
|
|
413
|
+
return;
|
|
414
|
+
}
|
|
344
415
|
const appendFn = getCallable(this.inner, ["loadPackBytesAppend", "load_pack_bytes_append"]);
|
|
345
416
|
if (!appendFn) {
|
|
346
417
|
throw new Error("WASM database is missing loadPackBytesAppend-compatible method");
|
|
@@ -434,6 +505,7 @@ var WrappedMatcher = class {
|
|
|
434
505
|
);
|
|
435
506
|
}
|
|
436
507
|
}
|
|
508
|
+
inner;
|
|
437
509
|
estimatePitchRatio;
|
|
438
510
|
extractPitchReference;
|
|
439
511
|
estimatePitchRatioAgainstReference;
|
|
@@ -844,19 +916,25 @@ async function initMatcher(options) {
|
|
|
844
916
|
var MatcherSession = class {
|
|
845
917
|
events = new TypedEventEmitter();
|
|
846
918
|
fetcher;
|
|
919
|
+
maxPackBytes;
|
|
847
920
|
initOptions;
|
|
921
|
+
embeddedPackLoader;
|
|
848
922
|
readyPromise;
|
|
849
923
|
bindings = null;
|
|
850
924
|
database = null;
|
|
851
925
|
matcher = null;
|
|
852
926
|
destroyed = false;
|
|
927
|
+
packLoadTail = Promise.resolve();
|
|
853
928
|
distinctMatchDeduper = new DistinctMatchDeduper();
|
|
854
929
|
constructor(options) {
|
|
855
930
|
this.fetcher = options?.fetch;
|
|
931
|
+
this.maxPackBytes = options?.maxPackBytes ?? DEFAULT_MAX_PACK_BYTES;
|
|
932
|
+
this.embeddedPackLoader = options?.embeddedPackLoader;
|
|
856
933
|
this.initOptions = {
|
|
857
934
|
loader: options?.loader,
|
|
858
935
|
wasmModule: options?.wasmModule,
|
|
859
|
-
wasmInitInput: options?.wasmInitInput
|
|
936
|
+
wasmInitInput: options?.wasmInitInput,
|
|
937
|
+
embeddedPackLoader: options?.embeddedPackLoader
|
|
860
938
|
};
|
|
861
939
|
this.readyPromise = this.bootstrap();
|
|
862
940
|
}
|
|
@@ -875,17 +953,30 @@ var MatcherSession = class {
|
|
|
875
953
|
async ready() {
|
|
876
954
|
await this.readyPromise;
|
|
877
955
|
}
|
|
878
|
-
|
|
956
|
+
loadPack(source) {
|
|
957
|
+
const load = this.packLoadTail.then(() => this.loadPackExclusive(source));
|
|
958
|
+
this.packLoadTail = load.catch(() => void 0);
|
|
959
|
+
return load;
|
|
960
|
+
}
|
|
961
|
+
async loadPackExclusive(source) {
|
|
879
962
|
try {
|
|
880
963
|
await this.ensureLiveReady();
|
|
881
964
|
const sourceType = classifyPackSource(source);
|
|
882
965
|
this.events.emit("packloadstart", { sourceType });
|
|
883
|
-
const
|
|
884
|
-
const normalized = await normalizePackSource(source, this.fetcher);
|
|
885
|
-
const embeddedPackBytes = await loadEmbeddedPackBytes();
|
|
886
|
-
|
|
887
|
-
|
|
888
|
-
|
|
966
|
+
const previousDatabase = this.databaseOrThrow();
|
|
967
|
+
const normalized = await normalizePackSource(source, this.fetcher, this.maxPackBytes);
|
|
968
|
+
const embeddedPackBytes = this.embeddedPackLoader ? await this.embeddedPackLoader() : await loadEmbeddedPackBytes();
|
|
969
|
+
const bindings = this.bindingsOrThrow();
|
|
970
|
+
const stagedDatabase = bindings.createDatabase();
|
|
971
|
+
try {
|
|
972
|
+
stagedDatabase.loadPackBytes(embeddedPackBytes);
|
|
973
|
+
stagedDatabase.loadPackBytesAppend(normalized.bytes, this.maxPackBytes);
|
|
974
|
+
} catch (error) {
|
|
975
|
+
stagedDatabase.destroy();
|
|
976
|
+
throw error;
|
|
977
|
+
}
|
|
978
|
+
this.database = stagedDatabase;
|
|
979
|
+
previousDatabase.destroy();
|
|
889
980
|
this.distinctMatchDeduper.reset();
|
|
890
981
|
this.matcher?.resetDistinctMatchState?.();
|
|
891
982
|
this.events.emit("packload", {
|
|
@@ -1187,6 +1278,12 @@ var MatcherSession = class {
|
|
|
1187
1278
|
}
|
|
1188
1279
|
return this.matcher;
|
|
1189
1280
|
}
|
|
1281
|
+
bindingsOrThrow() {
|
|
1282
|
+
if (!this.bindings) {
|
|
1283
|
+
throw new Error("Matcher bindings are not initialized");
|
|
1284
|
+
}
|
|
1285
|
+
return this.bindings;
|
|
1286
|
+
}
|
|
1190
1287
|
databaseOrThrow() {
|
|
1191
1288
|
if (!this.database) {
|
|
1192
1289
|
throw new Error("Database is not initialized");
|
|
@@ -1226,6 +1323,7 @@ var AudioFingerprintType = /* @__PURE__ */ ((AudioFingerprintType2) => {
|
|
|
1226
1323
|
})(AudioFingerprintType || {});
|
|
1227
1324
|
export {
|
|
1228
1325
|
AudioFingerprintType,
|
|
1326
|
+
DEFAULT_MAX_PACK_BYTES,
|
|
1229
1327
|
MatcherSession,
|
|
1230
1328
|
__resetMatcherWasmForTests,
|
|
1231
1329
|
__setMatcherEmbeddedPackForTests,
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@sorisdk/matcher",
|
|
3
|
-
"version": "0.6.
|
|
3
|
+
"version": "0.6.4",
|
|
4
4
|
"description": "Browser WASM SDK for audio fingerprint matching",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "./dist/index.js",
|
|
@@ -35,7 +35,7 @@
|
|
|
35
35
|
"devDependencies": {
|
|
36
36
|
"tsup": "^8.5.0",
|
|
37
37
|
"typescript": "^5.8.3",
|
|
38
|
-
"vitest": "^3.2.
|
|
38
|
+
"vitest": "^3.2.6"
|
|
39
39
|
},
|
|
40
40
|
"scripts": {
|
|
41
41
|
"build:wasm": "node ../../scripts/build-wasm-package.mjs matcher",
|