@sorisdk/matcher 0.1.4 → 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/generated/core.d.ts +3 -0
- package/dist/generated/core_bg.js +50 -0
- package/dist/generated/core_bg.wasm +0 -0
- package/dist/generated/core_bg.wasm.d.ts +3 -0
- package/dist/index.d.ts +35 -1
- package/dist/index.js +118 -1
- package/package.json +1 -1
package/dist/generated/core.d.ts
CHANGED
|
@@ -12,6 +12,7 @@ export class WasmMatcherDatabase {
|
|
|
12
12
|
loadPackBytesAppend(bytes: Uint8Array): void;
|
|
13
13
|
constructor();
|
|
14
14
|
removeEntry(name: string): void;
|
|
15
|
+
setEntryVariantMetadata(name: string, encoded_metadata: string): void;
|
|
15
16
|
readonly length: number;
|
|
16
17
|
}
|
|
17
18
|
|
|
@@ -19,7 +20,9 @@ export class WasmMatcherEngine {
|
|
|
19
20
|
free(): void;
|
|
20
21
|
[Symbol.dispose](): void;
|
|
21
22
|
bestMatch(database: WasmMatcherDatabase, query: Uint8Array, config?: any | null): any;
|
|
23
|
+
bestMatchWithVariants(database: WasmMatcherDatabase, query: Uint8Array, pitch_query: any, config?: any | null, variant_config?: any | null): any;
|
|
22
24
|
matchQuery(database: WasmMatcherDatabase, query: Uint8Array, config?: any | null): any;
|
|
25
|
+
matchQueryWithVariants(database: WasmMatcherDatabase, query: Uint8Array, pitch_query: any, config?: any | null, variant_config?: any | null): any;
|
|
23
26
|
constructor();
|
|
24
27
|
resetDistinctMatchState(): void;
|
|
25
28
|
}
|
|
@@ -102,6 +102,20 @@ export class WasmMatcherDatabase {
|
|
|
102
102
|
throw takeFromExternrefTable0(ret[0]);
|
|
103
103
|
}
|
|
104
104
|
}
|
|
105
|
+
/**
|
|
106
|
+
* @param {string} name
|
|
107
|
+
* @param {string} encoded_metadata
|
|
108
|
+
*/
|
|
109
|
+
setEntryVariantMetadata(name, encoded_metadata) {
|
|
110
|
+
const ptr0 = passStringToWasm0(name, wasm.__wbindgen_malloc, wasm.__wbindgen_realloc);
|
|
111
|
+
const len0 = WASM_VECTOR_LEN;
|
|
112
|
+
const ptr1 = passStringToWasm0(encoded_metadata, wasm.__wbindgen_malloc, wasm.__wbindgen_realloc);
|
|
113
|
+
const len1 = WASM_VECTOR_LEN;
|
|
114
|
+
const ret = wasm.wasmmatcherdatabase_setEntryVariantMetadata(this.__wbg_ptr, ptr0, len0, ptr1, len1);
|
|
115
|
+
if (ret[1]) {
|
|
116
|
+
throw takeFromExternrefTable0(ret[0]);
|
|
117
|
+
}
|
|
118
|
+
}
|
|
105
119
|
}
|
|
106
120
|
if (Symbol.dispose) WasmMatcherDatabase.prototype[Symbol.dispose] = WasmMatcherDatabase.prototype.free;
|
|
107
121
|
|
|
@@ -132,6 +146,24 @@ export class WasmMatcherEngine {
|
|
|
132
146
|
}
|
|
133
147
|
return takeFromExternrefTable0(ret[0]);
|
|
134
148
|
}
|
|
149
|
+
/**
|
|
150
|
+
* @param {WasmMatcherDatabase} database
|
|
151
|
+
* @param {Uint8Array} query
|
|
152
|
+
* @param {any} pitch_query
|
|
153
|
+
* @param {any | null} [config]
|
|
154
|
+
* @param {any | null} [variant_config]
|
|
155
|
+
* @returns {any}
|
|
156
|
+
*/
|
|
157
|
+
bestMatchWithVariants(database, query, pitch_query, config, variant_config) {
|
|
158
|
+
_assertClass(database, WasmMatcherDatabase);
|
|
159
|
+
const ptr0 = passArray8ToWasm0(query, wasm.__wbindgen_malloc);
|
|
160
|
+
const len0 = WASM_VECTOR_LEN;
|
|
161
|
+
const ret = wasm.wasmmatcherengine_bestMatchWithVariants(this.__wbg_ptr, database.__wbg_ptr, ptr0, len0, pitch_query, isLikeNone(config) ? 0 : addToExternrefTable0(config), isLikeNone(variant_config) ? 0 : addToExternrefTable0(variant_config));
|
|
162
|
+
if (ret[2]) {
|
|
163
|
+
throw takeFromExternrefTable0(ret[1]);
|
|
164
|
+
}
|
|
165
|
+
return takeFromExternrefTable0(ret[0]);
|
|
166
|
+
}
|
|
135
167
|
/**
|
|
136
168
|
* @param {WasmMatcherDatabase} database
|
|
137
169
|
* @param {Uint8Array} query
|
|
@@ -148,6 +180,24 @@ export class WasmMatcherEngine {
|
|
|
148
180
|
}
|
|
149
181
|
return takeFromExternrefTable0(ret[0]);
|
|
150
182
|
}
|
|
183
|
+
/**
|
|
184
|
+
* @param {WasmMatcherDatabase} database
|
|
185
|
+
* @param {Uint8Array} query
|
|
186
|
+
* @param {any} pitch_query
|
|
187
|
+
* @param {any | null} [config]
|
|
188
|
+
* @param {any | null} [variant_config]
|
|
189
|
+
* @returns {any}
|
|
190
|
+
*/
|
|
191
|
+
matchQueryWithVariants(database, query, pitch_query, config, variant_config) {
|
|
192
|
+
_assertClass(database, WasmMatcherDatabase);
|
|
193
|
+
const ptr0 = passArray8ToWasm0(query, wasm.__wbindgen_malloc);
|
|
194
|
+
const len0 = WASM_VECTOR_LEN;
|
|
195
|
+
const ret = wasm.wasmmatcherengine_matchQueryWithVariants(this.__wbg_ptr, database.__wbg_ptr, ptr0, len0, pitch_query, isLikeNone(config) ? 0 : addToExternrefTable0(config), isLikeNone(variant_config) ? 0 : addToExternrefTable0(variant_config));
|
|
196
|
+
if (ret[2]) {
|
|
197
|
+
throw takeFromExternrefTable0(ret[1]);
|
|
198
|
+
}
|
|
199
|
+
return takeFromExternrefTable0(ret[0]);
|
|
200
|
+
}
|
|
151
201
|
constructor() {
|
|
152
202
|
const ret = wasm.wasmmatcherengine_new();
|
|
153
203
|
this.__wbg_ptr = ret >>> 0;
|
|
Binary file
|
|
@@ -12,8 +12,11 @@ export const wasmmatcherdatabase_loadPackBytes: (a: number, b: number, c: number
|
|
|
12
12
|
export const wasmmatcherdatabase_loadPackBytesAppend: (a: number, b: number, c: number) => [number, number];
|
|
13
13
|
export const wasmmatcherdatabase_new: () => number;
|
|
14
14
|
export const wasmmatcherdatabase_removeEntry: (a: number, b: number, c: number) => [number, number];
|
|
15
|
+
export const wasmmatcherdatabase_setEntryVariantMetadata: (a: number, b: number, c: number, d: number, e: number) => [number, number];
|
|
15
16
|
export const wasmmatcherengine_bestMatch: (a: number, b: number, c: number, d: number, e: number) => [number, number, number];
|
|
17
|
+
export const wasmmatcherengine_bestMatchWithVariants: (a: number, b: number, c: number, d: number, e: any, f: number, g: number) => [number, number, number];
|
|
16
18
|
export const wasmmatcherengine_matchQuery: (a: number, b: number, c: number, d: number, e: number) => [number, number, number];
|
|
19
|
+
export const wasmmatcherengine_matchQueryWithVariants: (a: number, b: number, c: number, d: number, e: any, f: number, g: number) => [number, number, number];
|
|
17
20
|
export const wasmmatcherengine_new: () => number;
|
|
18
21
|
export const wasmmatcherengine_resetDistinctMatchState: (a: number) => void;
|
|
19
22
|
export const init_matcher_wasm: () => void;
|
package/dist/index.d.ts
CHANGED
|
@@ -8,6 +8,33 @@ interface MatchConfig {
|
|
|
8
8
|
scoreThreshold?: number;
|
|
9
9
|
gapThreshold?: number;
|
|
10
10
|
}
|
|
11
|
+
interface VariantMatchQuery {
|
|
12
|
+
estimatedPitchRatio?: number | null;
|
|
13
|
+
pitchConfidence?: number | null;
|
|
14
|
+
}
|
|
15
|
+
interface VariantMatchConfig {
|
|
16
|
+
minConfidence?: number;
|
|
17
|
+
defaultToleranceRatio?: number;
|
|
18
|
+
minRatioMargin?: number;
|
|
19
|
+
candidateLimit?: number;
|
|
20
|
+
}
|
|
21
|
+
type VariantDecisionStatus = "variant" | "variant_unknown" | "no_variant";
|
|
22
|
+
interface VariantDecision {
|
|
23
|
+
status: VariantDecisionStatus;
|
|
24
|
+
reason?: string | null;
|
|
25
|
+
canonicalMaterialId?: string | null;
|
|
26
|
+
matchedEntryName?: string | null;
|
|
27
|
+
variantId?: string | null;
|
|
28
|
+
variantLabel?: string | null;
|
|
29
|
+
nominalRatio?: number | null;
|
|
30
|
+
estimatedPitchRatio?: number | null;
|
|
31
|
+
pitchConfidence?: number | null;
|
|
32
|
+
ratioError?: number | null;
|
|
33
|
+
pitchScore?: number | null;
|
|
34
|
+
toleranceMinRatio?: number | null;
|
|
35
|
+
toleranceMaxRatio?: number | null;
|
|
36
|
+
candidateCount: number;
|
|
37
|
+
}
|
|
11
38
|
interface EntryMetadata {
|
|
12
39
|
id?: string | null;
|
|
13
40
|
name?: string | null;
|
|
@@ -22,6 +49,10 @@ interface MatchResult {
|
|
|
22
49
|
position: number;
|
|
23
50
|
afpType: AudioFingerprintType;
|
|
24
51
|
}
|
|
52
|
+
interface VariantMatch {
|
|
53
|
+
matchResult: MatchResult;
|
|
54
|
+
variant: VariantDecision;
|
|
55
|
+
}
|
|
25
56
|
type PackSource = Uint8Array | ArrayBuffer | Blob | Response | Request | string | URL;
|
|
26
57
|
type MatcherSessionEventMap = {
|
|
27
58
|
ready: {
|
|
@@ -134,11 +165,14 @@ declare class MatcherSession {
|
|
|
134
165
|
loadPack(source: PackSource): Promise<void>;
|
|
135
166
|
addEntry(name: string, afpType: AudioFingerprintType, fingerprint: Uint8Array): Promise<void>;
|
|
136
167
|
addOrReplace(name: string, afpType: AudioFingerprintType, fingerprint: Uint8Array, metadata?: EntryMetadata | null): Promise<void>;
|
|
168
|
+
setEntryVariantMetadata(name: string, encodedMetadata: string): Promise<void>;
|
|
137
169
|
removeEntry(name: string): Promise<void>;
|
|
138
170
|
clear(): Promise<void>;
|
|
139
171
|
getEntryMetadata(name: string): Promise<EntryMetadata | null>;
|
|
140
172
|
match(query: Uint8Array, config?: MatchConfig): Promise<MatchResult[]>;
|
|
141
173
|
bestMatch(query: Uint8Array, config?: MatchConfig): Promise<MatchResult | null>;
|
|
174
|
+
matchWithVariants(query: Uint8Array, pitchQuery: VariantMatchQuery, config?: MatchConfig, variantConfig?: VariantMatchConfig): Promise<VariantMatch[]>;
|
|
175
|
+
bestMatchWithVariants(query: Uint8Array, pitchQuery: VariantMatchQuery, config?: MatchConfig, variantConfig?: VariantMatchConfig): Promise<VariantMatch | null>;
|
|
142
176
|
destroy(): void;
|
|
143
177
|
private bootstrap;
|
|
144
178
|
private ensureLiveReady;
|
|
@@ -151,4 +185,4 @@ declare function __setMatcherWasmModuleForTests(moduleLike: unknown): void;
|
|
|
151
185
|
declare function __setMatcherEmbeddedPackForTests(bytes: Uint8Array): void;
|
|
152
186
|
declare function __resetMatcherWasmForTests(): void;
|
|
153
187
|
|
|
154
|
-
export { AudioFingerprintType, 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, __resetMatcherWasmForTests, __setMatcherEmbeddedPackForTests, __setMatcherWasmModuleForTests, initMatcher };
|
|
188
|
+
export { AudioFingerprintType, 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 VariantDecision, type VariantDecisionStatus, type VariantMatch, type VariantMatchConfig, type VariantMatchQuery, __resetMatcherWasmForTests, __setMatcherEmbeddedPackForTests, __setMatcherWasmModuleForTests, initMatcher };
|
package/dist/index.js
CHANGED
|
@@ -358,6 +358,13 @@ var WrappedDatabase = class {
|
|
|
358
358
|
}
|
|
359
359
|
return normalizeEntryMetadata(raw);
|
|
360
360
|
}
|
|
361
|
+
setEntryVariantMetadata(name, encodedMetadata) {
|
|
362
|
+
const fn = getCallable(this.inner, ["setEntryVariantMetadata", "set_entry_variant_metadata"]);
|
|
363
|
+
if (!fn) {
|
|
364
|
+
throw new Error("WASM database is missing setEntryVariantMetadata-compatible method");
|
|
365
|
+
}
|
|
366
|
+
fn.call(this.inner, name, encodedMetadata);
|
|
367
|
+
}
|
|
361
368
|
destroy() {
|
|
362
369
|
const fn = getCallable(this.inner, ["destroy", "free"]);
|
|
363
370
|
if (fn) {
|
|
@@ -403,6 +410,31 @@ var WrappedMatcher = class {
|
|
|
403
410
|
}
|
|
404
411
|
return normalizeResult(raw);
|
|
405
412
|
}
|
|
413
|
+
findMatchesWithVariants(database, query, pitchQuery, config, variantConfig) {
|
|
414
|
+
const fn = getCallable(this.inner, [
|
|
415
|
+
"findMatchesWithVariants",
|
|
416
|
+
"matchQueryWithVariants",
|
|
417
|
+
"match_query_with_variants"
|
|
418
|
+
]);
|
|
419
|
+
if (!fn) {
|
|
420
|
+
throw new Error("WASM matcher is missing findMatchesWithVariants-compatible method");
|
|
421
|
+
}
|
|
422
|
+
const dbRecord = typeof database.raw === "function" ? database.raw() : database;
|
|
423
|
+
const rawResults = fn.call(this.inner, dbRecord, query, pitchQuery, config, variantConfig);
|
|
424
|
+
return normalizeVariantMatches(rawResults ?? []);
|
|
425
|
+
}
|
|
426
|
+
bestMatchWithVariants(database, query, pitchQuery, config, variantConfig) {
|
|
427
|
+
const fn = getCallable(this.inner, [
|
|
428
|
+
"bestMatchWithVariants",
|
|
429
|
+
"best_match_with_variants"
|
|
430
|
+
]);
|
|
431
|
+
if (!fn) {
|
|
432
|
+
throw new Error("WASM matcher is missing bestMatchWithVariants-compatible method");
|
|
433
|
+
}
|
|
434
|
+
const dbRecord = typeof database.raw === "function" ? database.raw() : database;
|
|
435
|
+
const raw = fn.call(this.inner, dbRecord, query, pitchQuery, config, variantConfig);
|
|
436
|
+
return raw && typeof raw === "object" ? normalizeVariantMatch(raw) : null;
|
|
437
|
+
}
|
|
406
438
|
resetDistinctMatchState() {
|
|
407
439
|
const fn = getCallable(this.inner, ["resetDistinctMatchState", "reset_distinct_match_state"]);
|
|
408
440
|
fn?.call(this.inner);
|
|
@@ -423,7 +455,35 @@ function normalizeResult(raw) {
|
|
|
423
455
|
afpType
|
|
424
456
|
};
|
|
425
457
|
}
|
|
458
|
+
function normalizeVariantMatch(raw) {
|
|
459
|
+
const rawMatch = raw.matchResult ?? raw.match;
|
|
460
|
+
const rawVariant = raw.variant ?? {};
|
|
461
|
+
return {
|
|
462
|
+
matchResult: normalizeResult(rawMatch),
|
|
463
|
+
variant: {
|
|
464
|
+
...rawVariant,
|
|
465
|
+
status: String(rawVariant.status),
|
|
466
|
+
candidateCount: Number(rawVariant.candidateCount ?? 0)
|
|
467
|
+
}
|
|
468
|
+
};
|
|
469
|
+
}
|
|
470
|
+
function isMapLike(raw) {
|
|
471
|
+
return raw instanceof Map || Object.prototype.toString.call(raw) === "[object Map]" && typeof raw.entries === "function";
|
|
472
|
+
}
|
|
473
|
+
function toEntryMetadataRecord(raw) {
|
|
474
|
+
if (isMapLike(raw)) {
|
|
475
|
+
const entries = [];
|
|
476
|
+
for (const [key, value] of raw.entries()) {
|
|
477
|
+
if (typeof key === "string") {
|
|
478
|
+
entries.push([key, value]);
|
|
479
|
+
}
|
|
480
|
+
}
|
|
481
|
+
return Object.fromEntries(entries);
|
|
482
|
+
}
|
|
483
|
+
return raw;
|
|
484
|
+
}
|
|
426
485
|
function normalizeEntryMetadata(raw) {
|
|
486
|
+
const metadata = toEntryMetadataRecord(raw);
|
|
427
487
|
const {
|
|
428
488
|
_id: legacyId,
|
|
429
489
|
id,
|
|
@@ -433,7 +493,7 @@ function normalizeEntryMetadata(raw) {
|
|
|
433
493
|
name,
|
|
434
494
|
image,
|
|
435
495
|
...rest
|
|
436
|
-
} =
|
|
496
|
+
} = metadata;
|
|
437
497
|
return {
|
|
438
498
|
...rest,
|
|
439
499
|
...id !== void 0 || legacyId !== void 0 ? { id: String(id ?? legacyId) } : {},
|
|
@@ -446,6 +506,9 @@ function normalizeEntryMetadata(raw) {
|
|
|
446
506
|
function normalizeResults(rawResults) {
|
|
447
507
|
return rawResults.filter((item) => typeof item === "object" && item !== null).map((item) => normalizeResult(item));
|
|
448
508
|
}
|
|
509
|
+
function normalizeVariantMatches(rawResults) {
|
|
510
|
+
return rawResults.filter((item) => typeof item === "object" && item !== null).map((item) => normalizeVariantMatch(item));
|
|
511
|
+
}
|
|
449
512
|
function isInternallyDuplicatedBestMatch(result) {
|
|
450
513
|
return Boolean(
|
|
451
514
|
result && typeof result === "object" && result[INTERNAL_DUPLICATE_MATCH_FLAG] === true
|
|
@@ -603,6 +666,16 @@ var MatcherSession = class {
|
|
|
603
666
|
handleError(this.events, "addOrReplace", error);
|
|
604
667
|
}
|
|
605
668
|
}
|
|
669
|
+
async setEntryVariantMetadata(name, encodedMetadata) {
|
|
670
|
+
try {
|
|
671
|
+
await this.ensureLiveReady();
|
|
672
|
+
this.databaseOrThrow().setEntryVariantMetadata(name, encodedMetadata);
|
|
673
|
+
this.distinctMatchDeduper.reset();
|
|
674
|
+
this.matcher?.resetDistinctMatchState?.();
|
|
675
|
+
} catch (error) {
|
|
676
|
+
handleError(this.events, "setEntryVariantMetadata", error);
|
|
677
|
+
}
|
|
678
|
+
}
|
|
606
679
|
async removeEntry(name) {
|
|
607
680
|
try {
|
|
608
681
|
await this.ensureLiveReady();
|
|
@@ -658,6 +731,50 @@ var MatcherSession = class {
|
|
|
658
731
|
handleError(this.events, "bestMatch", error);
|
|
659
732
|
}
|
|
660
733
|
}
|
|
734
|
+
async matchWithVariants(query, pitchQuery, config, variantConfig) {
|
|
735
|
+
try {
|
|
736
|
+
await this.ensureLiveReady();
|
|
737
|
+
const safeQuery = toUint8ArrayCopy(query);
|
|
738
|
+
this.events.emit("querystart", { queryByteLength: safeQuery.byteLength });
|
|
739
|
+
const results = this.matcherOrThrow().findMatchesWithVariants(
|
|
740
|
+
this.databaseOrThrow(),
|
|
741
|
+
safeQuery,
|
|
742
|
+
pitchQuery,
|
|
743
|
+
config,
|
|
744
|
+
variantConfig
|
|
745
|
+
);
|
|
746
|
+
this.emitDistinctMatchEvent(
|
|
747
|
+
results[0]?.matchResult ?? null,
|
|
748
|
+
safeQuery.byteLength,
|
|
749
|
+
results.map((result) => result.matchResult)
|
|
750
|
+
);
|
|
751
|
+
return results;
|
|
752
|
+
} catch (error) {
|
|
753
|
+
handleError(this.events, "matchWithVariants", error);
|
|
754
|
+
}
|
|
755
|
+
}
|
|
756
|
+
async bestMatchWithVariants(query, pitchQuery, config, variantConfig) {
|
|
757
|
+
try {
|
|
758
|
+
await this.ensureLiveReady();
|
|
759
|
+
const safeQuery = toUint8ArrayCopy(query);
|
|
760
|
+
this.events.emit("querystart", { queryByteLength: safeQuery.byteLength });
|
|
761
|
+
const best = this.matcherOrThrow().bestMatchWithVariants(
|
|
762
|
+
this.databaseOrThrow(),
|
|
763
|
+
safeQuery,
|
|
764
|
+
pitchQuery,
|
|
765
|
+
config,
|
|
766
|
+
variantConfig
|
|
767
|
+
);
|
|
768
|
+
this.emitDistinctMatchEvent(
|
|
769
|
+
best?.matchResult ?? null,
|
|
770
|
+
safeQuery.byteLength,
|
|
771
|
+
best ? [best.matchResult] : []
|
|
772
|
+
);
|
|
773
|
+
return best;
|
|
774
|
+
} catch (error) {
|
|
775
|
+
handleError(this.events, "bestMatchWithVariants", error);
|
|
776
|
+
}
|
|
777
|
+
}
|
|
661
778
|
destroy() {
|
|
662
779
|
if (this.destroyed) {
|
|
663
780
|
return;
|