@sorisdk/matcher 0.6.10 → 0.6.11
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 +2 -0
- package/dist/generated/core_bg.js +32 -0
- package/dist/generated/core_bg.wasm +0 -0
- package/dist/generated/core_bg.wasm.d.ts +3 -1
- package/dist/index.d.ts +24 -1
- package/dist/index.js +94 -0
- package/package.json +1 -1
package/dist/generated/core.d.ts
CHANGED
|
@@ -22,6 +22,7 @@ export class WasmMatcherEngine {
|
|
|
22
22
|
free(): void;
|
|
23
23
|
[Symbol.dispose](): void;
|
|
24
24
|
bestMatch(database: WasmMatcherDatabase, query: Uint8Array, config?: any | null): any;
|
|
25
|
+
bestMatchChecked(database: WasmMatcherDatabase, query: Uint8Array, config?: any | null): any;
|
|
25
26
|
bestMatchWithVariants(database: WasmMatcherDatabase, query: Uint8Array, pitch_query: any, config?: any | null, variant_config?: any | null): any;
|
|
26
27
|
detectAudioMarker(pcm16_le: Uint8Array, sample_rate: number, config?: any | null): any;
|
|
27
28
|
detectAudioMarkerWithLimits(pcm16_le: Uint8Array, sample_rate: number, config?: any | null, limits?: any | null): any;
|
|
@@ -33,6 +34,7 @@ export class WasmMatcherEngine {
|
|
|
33
34
|
extractPitchReference(pcm16_le: Uint8Array, sample_rate: number): any;
|
|
34
35
|
extractSpectralShiftReference(pcm16_le: Uint8Array, sample_rate: number): any;
|
|
35
36
|
matchQuery(database: WasmMatcherDatabase, query: Uint8Array, config?: any | null): any;
|
|
37
|
+
matchQueryChecked(database: WasmMatcherDatabase, query: Uint8Array, config?: any | null): any;
|
|
36
38
|
matchQueryWithVariants(database: WasmMatcherDatabase, query: Uint8Array, pitch_query: any, config?: any | null, variant_config?: any | null): any;
|
|
37
39
|
constructor();
|
|
38
40
|
/**
|
|
@@ -170,6 +170,22 @@ export class WasmMatcherEngine {
|
|
|
170
170
|
}
|
|
171
171
|
return takeFromExternrefTable0(ret[0]);
|
|
172
172
|
}
|
|
173
|
+
/**
|
|
174
|
+
* @param {WasmMatcherDatabase} database
|
|
175
|
+
* @param {Uint8Array} query
|
|
176
|
+
* @param {any | null} [config]
|
|
177
|
+
* @returns {any}
|
|
178
|
+
*/
|
|
179
|
+
bestMatchChecked(database, query, config) {
|
|
180
|
+
_assertClass(database, WasmMatcherDatabase);
|
|
181
|
+
const ptr0 = passArray8ToWasm0(query, wasm.__wbindgen_malloc);
|
|
182
|
+
const len0 = WASM_VECTOR_LEN;
|
|
183
|
+
const ret = wasm.wasmmatcherengine_bestMatchChecked(this.__wbg_ptr, database.__wbg_ptr, ptr0, len0, isLikeNone(config) ? 0 : addToExternrefTable0(config));
|
|
184
|
+
if (ret[2]) {
|
|
185
|
+
throw takeFromExternrefTable0(ret[1]);
|
|
186
|
+
}
|
|
187
|
+
return takeFromExternrefTable0(ret[0]);
|
|
188
|
+
}
|
|
173
189
|
/**
|
|
174
190
|
* @param {WasmMatcherDatabase} database
|
|
175
191
|
* @param {Uint8Array} query
|
|
@@ -335,6 +351,22 @@ export class WasmMatcherEngine {
|
|
|
335
351
|
}
|
|
336
352
|
return takeFromExternrefTable0(ret[0]);
|
|
337
353
|
}
|
|
354
|
+
/**
|
|
355
|
+
* @param {WasmMatcherDatabase} database
|
|
356
|
+
* @param {Uint8Array} query
|
|
357
|
+
* @param {any | null} [config]
|
|
358
|
+
* @returns {any}
|
|
359
|
+
*/
|
|
360
|
+
matchQueryChecked(database, query, config) {
|
|
361
|
+
_assertClass(database, WasmMatcherDatabase);
|
|
362
|
+
const ptr0 = passArray8ToWasm0(query, wasm.__wbindgen_malloc);
|
|
363
|
+
const len0 = WASM_VECTOR_LEN;
|
|
364
|
+
const ret = wasm.wasmmatcherengine_matchQueryChecked(this.__wbg_ptr, database.__wbg_ptr, ptr0, len0, isLikeNone(config) ? 0 : addToExternrefTable0(config));
|
|
365
|
+
if (ret[2]) {
|
|
366
|
+
throw takeFromExternrefTable0(ret[1]);
|
|
367
|
+
}
|
|
368
|
+
return takeFromExternrefTable0(ret[0]);
|
|
369
|
+
}
|
|
338
370
|
/**
|
|
339
371
|
* @param {WasmMatcherDatabase} database
|
|
340
372
|
* @param {Uint8Array} query
|
|
Binary file
|
|
@@ -25,6 +25,7 @@ export const wasmmatcherdatabase_new: () => number;
|
|
|
25
25
|
export const wasmmatcherdatabase_removeEntry: (a: number, b: number, c: number) => [number, number];
|
|
26
26
|
export const wasmmatcherdatabase_setEntryVariantMetadata: (a: number, b: number, c: number, d: number, e: number) => [number, number];
|
|
27
27
|
export const wasmmatcherengine_bestMatch: (a: number, b: number, c: number, d: number, e: number) => [number, number, number];
|
|
28
|
+
export const wasmmatcherengine_bestMatchChecked: (a: number, b: number, c: number, d: number, e: number) => [number, number, number];
|
|
28
29
|
export const wasmmatcherengine_bestMatchWithVariants: (a: number, b: number, c: number, d: number, e: any, f: number, g: number) => [number, number, number];
|
|
29
30
|
export const wasmmatcherengine_detectAudioMarker: (a: number, b: any, c: number, d: number) => [number, number, number];
|
|
30
31
|
export const wasmmatcherengine_detectAudioMarkerWithLimits: (a: number, b: any, c: number, d: number, e: number) => [number, number, number];
|
|
@@ -35,9 +36,10 @@ export const wasmmatcherengine_estimatePitchRatioAgainstSpectralFeatures: (a: nu
|
|
|
35
36
|
export const wasmmatcherengine_extractPitchReference: (a: number, b: number, c: number, d: number) => [number, number, number];
|
|
36
37
|
export const wasmmatcherengine_extractSpectralShiftReference: (a: number, b: number, c: number, d: number) => [number, number, number];
|
|
37
38
|
export const wasmmatcherengine_matchQuery: (a: number, b: number, c: number, d: number, e: number) => [number, number, number];
|
|
39
|
+
export const wasmmatcherengine_matchQueryChecked: (a: number, b: number, c: number, d: number, e: number) => [number, number, number];
|
|
38
40
|
export const wasmmatcherengine_matchQueryWithVariants: (a: number, b: number, c: number, d: number, e: any, f: number, g: number) => [number, number, number];
|
|
39
|
-
export const wasmmatcherengine_resetDistinctMatchState: (a: number) => void;
|
|
40
41
|
export const wasmmatcherengine_new: () => number;
|
|
42
|
+
export const wasmmatcherengine_resetDistinctMatchState: (a: number) => void;
|
|
41
43
|
export const init_matcher_wasm: () => void;
|
|
42
44
|
export const detectPatternMark: (a: any, b: number, c: number) => [number, number, number];
|
|
43
45
|
export const wasmmatcherengine_detectPatternMark: (a: number, b: any, c: number, d: number) => [number, number, number];
|
package/dist/index.d.ts
CHANGED
|
@@ -142,6 +142,24 @@ interface MatchResult {
|
|
|
142
142
|
durationMillis?: number;
|
|
143
143
|
afpType: AudioFingerprintType;
|
|
144
144
|
}
|
|
145
|
+
type TimingCoordinateSpace = "entry_local" | "segment_local" | "unavailable";
|
|
146
|
+
type TimingUnavailableReason = "rejected_metadata" | "invalidated_metadata" | "incompatible_geometry" | "ambiguous_clock" | "out_of_range" | "window_origin_underflow" | "inconsistent_windows";
|
|
147
|
+
interface MatchTiming {
|
|
148
|
+
coordinateSpace: TimingCoordinateSpace;
|
|
149
|
+
/** Null when timing normalization failed. */
|
|
150
|
+
positionMillis: number | null;
|
|
151
|
+
durationMillis: number | null;
|
|
152
|
+
segmentIndex: number | null;
|
|
153
|
+
reason: TimingUnavailableReason | null;
|
|
154
|
+
}
|
|
155
|
+
interface CheckedMatchResult {
|
|
156
|
+
name: string;
|
|
157
|
+
score: number;
|
|
158
|
+
afpType: AudioFingerprintType;
|
|
159
|
+
/** Diagnostic entry offset only; consumers should use timing. */
|
|
160
|
+
rawPositionMillis: number;
|
|
161
|
+
timing: MatchTiming;
|
|
162
|
+
}
|
|
145
163
|
interface VariantMatch {
|
|
146
164
|
matchResult: MatchResult;
|
|
147
165
|
variant: VariantDecision;
|
|
@@ -273,6 +291,11 @@ declare class MatcherSession {
|
|
|
273
291
|
clear(): Promise<void>;
|
|
274
292
|
getEntryMetadata(name: string): Promise<EntryMetadata | null>;
|
|
275
293
|
match(query: Uint8Array, config?: MatchConfig): Promise<MatchResult[]>;
|
|
294
|
+
/**
|
|
295
|
+
* Read one observation with explicit timing coordinates. This direct accessor
|
|
296
|
+
* does not emit legacy match events or update recognition deduplication state.
|
|
297
|
+
*/
|
|
298
|
+
bestMatchChecked(query: Uint8Array, config?: MatchConfig): Promise<CheckedMatchResult | null>;
|
|
276
299
|
bestMatch(query: Uint8Array, config?: MatchConfig): Promise<MatchResult | null>;
|
|
277
300
|
estimatePitchRatio(pcm16Le: Uint8Array, sampleRate: number): Promise<PitchRatioEstimate>;
|
|
278
301
|
extractPitchReference(pcm16Le: Uint8Array, sampleRate: number): Promise<PitchReferenceEstimate>;
|
|
@@ -304,4 +327,4 @@ declare function __resetMatcherWasmForTests(): void;
|
|
|
304
327
|
/** Maximum gap between successful observations in one continuous material run. */
|
|
305
328
|
declare const MATCH_CONTINUITY_GAP_MS = 30000;
|
|
306
329
|
|
|
307
|
-
export { AUDIO_MARKER_INPUT_BUDGET_EXCEEDED_REASON, AUDIO_MARKER_WORK_BUDGET_EXCEEDED_REASON, AUDIO_MARKER_WORK_OVERFLOW_REASON, AudioFingerprintType, type AudioMarkerCode, type AudioMarkerConfig, type AudioMarkerDetection, type AudioMarkerLevelDiagnostics, type AudioMarkerLevelPolicy, type AudioMarkerLimits, DEFAULT_MAX_AUDIO_MARKER_DURATION_MILLIS, DEFAULT_MAX_AUDIO_MARKER_PCM_BYTES, DEFAULT_MAX_AUDIO_MARKER_SAMPLES, DEFAULT_MAX_AUDIO_MARKER_WORK_UNITS, DEFAULT_MAX_PACK_BYTES, type EntryMetadata, type InitMatcherOptions, type InitMatcherResult, MATCH_CONTINUITY_GAP_MS, 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 };
|
|
330
|
+
export { AUDIO_MARKER_INPUT_BUDGET_EXCEEDED_REASON, AUDIO_MARKER_WORK_BUDGET_EXCEEDED_REASON, AUDIO_MARKER_WORK_OVERFLOW_REASON, AudioFingerprintType, type AudioMarkerCode, type AudioMarkerConfig, type AudioMarkerDetection, type AudioMarkerLevelDiagnostics, type AudioMarkerLevelPolicy, type AudioMarkerLimits, type CheckedMatchResult, DEFAULT_MAX_AUDIO_MARKER_DURATION_MILLIS, DEFAULT_MAX_AUDIO_MARKER_PCM_BYTES, DEFAULT_MAX_AUDIO_MARKER_SAMPLES, DEFAULT_MAX_AUDIO_MARKER_WORK_UNITS, DEFAULT_MAX_PACK_BYTES, type EntryMetadata, type InitMatcherOptions, type InitMatcherResult, MATCH_CONTINUITY_GAP_MS, type MatchConfig, type MatchResult, type MatchTiming, type MatcherEphemeralAuthOptions, type MatcherEphemeralAuthResult, type MatcherEphemeralKeyExchangeMetadata, type MatcherEphemeralKeyExchangeOptions, MatcherSession, type MatcherSessionEventMap, type MatcherSessionEventName, type MatcherSessionListener, type MatcherSessionOptions, type PackSource, type PitchRatioEstimate, type PitchReferenceEstimate, type TimingCoordinateSpace, type TimingUnavailableReason, type VariantDecision, type VariantDecisionStatus, type VariantMatch, type VariantMatchConfig, type VariantMatchQuery, __resetMatcherWasmForTests, __setMatcherEmbeddedPackForTests, __setMatcherWasmModuleForTests, initMatcher };
|
package/dist/index.js
CHANGED
|
@@ -478,6 +478,28 @@ var WrappedDatabase = class {
|
|
|
478
478
|
var WrappedMatcher = class {
|
|
479
479
|
constructor(inner) {
|
|
480
480
|
this.inner = inner;
|
|
481
|
+
const findMatchesCheckedFn = getCallable(this.inner, [
|
|
482
|
+
"findMatchesChecked",
|
|
483
|
+
"find_matches_checked",
|
|
484
|
+
"matchQueryChecked",
|
|
485
|
+
"match_query_checked"
|
|
486
|
+
]);
|
|
487
|
+
if (findMatchesCheckedFn) {
|
|
488
|
+
this.findMatchesChecked = (database, query, config) => {
|
|
489
|
+
const dbRecord = typeof database.raw === "function" ? database.raw() : database;
|
|
490
|
+
const raw = findMatchesCheckedFn.call(this.inner, dbRecord, query, config);
|
|
491
|
+
if (!Array.isArray(raw)) throw new Error("Invalid checked match results");
|
|
492
|
+
return raw.map(normalizeCheckedResult);
|
|
493
|
+
};
|
|
494
|
+
}
|
|
495
|
+
const bestMatchCheckedFn = getCallable(this.inner, ["bestMatchChecked", "best_match_checked"]);
|
|
496
|
+
if (bestMatchCheckedFn) {
|
|
497
|
+
this.bestMatchChecked = (database, query, config) => {
|
|
498
|
+
const dbRecord = typeof database.raw === "function" ? database.raw() : database;
|
|
499
|
+
const raw = bestMatchCheckedFn.call(this.inner, dbRecord, query, config);
|
|
500
|
+
return raw == null ? null : normalizeCheckedResult(raw);
|
|
501
|
+
};
|
|
502
|
+
}
|
|
481
503
|
const estimatePitchRatioFn = getCallable(this.inner, [
|
|
482
504
|
"estimatePitchRatio",
|
|
483
505
|
"estimate_pitch_ratio"
|
|
@@ -555,6 +577,8 @@ var WrappedMatcher = class {
|
|
|
555
577
|
}
|
|
556
578
|
}
|
|
557
579
|
inner;
|
|
580
|
+
findMatchesChecked;
|
|
581
|
+
bestMatchChecked;
|
|
558
582
|
estimatePitchRatio;
|
|
559
583
|
extractPitchReference;
|
|
560
584
|
estimatePitchRatioAgainstReference;
|
|
@@ -645,6 +669,56 @@ function normalizeResult(raw) {
|
|
|
645
669
|
}
|
|
646
670
|
return result;
|
|
647
671
|
}
|
|
672
|
+
var TIMING_UNAVAILABLE_REASONS = /* @__PURE__ */ new Set([
|
|
673
|
+
"rejected_metadata",
|
|
674
|
+
"invalidated_metadata",
|
|
675
|
+
"incompatible_geometry",
|
|
676
|
+
"ambiguous_clock",
|
|
677
|
+
"out_of_range",
|
|
678
|
+
"window_origin_underflow",
|
|
679
|
+
"inconsistent_windows"
|
|
680
|
+
]);
|
|
681
|
+
function normalizeCheckedResult(raw) {
|
|
682
|
+
const invalid = () => new Error("Invalid checked match result");
|
|
683
|
+
if (!raw || typeof raw !== "object") {
|
|
684
|
+
throw invalid();
|
|
685
|
+
}
|
|
686
|
+
const record = raw;
|
|
687
|
+
if (!record.timing || typeof record.timing !== "object") {
|
|
688
|
+
throw invalid();
|
|
689
|
+
}
|
|
690
|
+
const source = record.timing;
|
|
691
|
+
const integer = (camel, snake) => {
|
|
692
|
+
const value = camel ?? snake;
|
|
693
|
+
if (value == null) return null;
|
|
694
|
+
if (typeof value !== "number" || !Number.isSafeInteger(value) || value < 0) {
|
|
695
|
+
throw invalid();
|
|
696
|
+
}
|
|
697
|
+
return value;
|
|
698
|
+
};
|
|
699
|
+
const coordinateSpace = source.coordinateSpace ?? source.coordinate_space;
|
|
700
|
+
const timing = {
|
|
701
|
+
coordinateSpace,
|
|
702
|
+
positionMillis: integer(source.positionMillis, source.position_millis),
|
|
703
|
+
durationMillis: integer(source.durationMillis, source.duration_millis),
|
|
704
|
+
segmentIndex: integer(source.segmentIndex, source.segment_index),
|
|
705
|
+
reason: source.reason ?? null
|
|
706
|
+
};
|
|
707
|
+
const available = timing.reason === null && timing.positionMillis !== null;
|
|
708
|
+
const validTiming = coordinateSpace === "unavailable" ? timing.positionMillis === null && timing.durationMillis === null && timing.segmentIndex === null && TIMING_UNAVAILABLE_REASONS.has(timing.reason) : coordinateSpace === "entry_local" ? available && timing.durationMillis === null && timing.segmentIndex === null : coordinateSpace === "segment_local" && available && timing.durationMillis !== null && timing.segmentIndex !== null && timing.positionMillis < timing.durationMillis;
|
|
709
|
+
const rawPositionMillis = integer(record.rawPositionMillis, record.raw_position_millis);
|
|
710
|
+
const afpType = record.afpType ?? record.afp_type;
|
|
711
|
+
if (!validTiming || typeof record.name !== "string" || record.name.length === 0 || typeof record.score !== "number" || !Number.isFinite(record.score) || record.score < 0 || ![1, 2, 4].includes(afpType) || rawPositionMillis === null) {
|
|
712
|
+
throw invalid();
|
|
713
|
+
}
|
|
714
|
+
return {
|
|
715
|
+
name: record.name,
|
|
716
|
+
score: record.score,
|
|
717
|
+
afpType,
|
|
718
|
+
rawPositionMillis,
|
|
719
|
+
timing
|
|
720
|
+
};
|
|
721
|
+
}
|
|
648
722
|
function normalizeVariantMatch(raw) {
|
|
649
723
|
const rawMatch = raw.matchResult ?? raw.match;
|
|
650
724
|
const rawVariant = raw.variant ?? {};
|
|
@@ -1265,6 +1339,26 @@ var MatcherSession = class {
|
|
|
1265
1339
|
handleError(this.events, "match", error);
|
|
1266
1340
|
}
|
|
1267
1341
|
}
|
|
1342
|
+
/**
|
|
1343
|
+
* Read one observation with explicit timing coordinates. This direct accessor
|
|
1344
|
+
* does not emit legacy match events or update recognition deduplication state.
|
|
1345
|
+
*/
|
|
1346
|
+
async bestMatchChecked(query, config) {
|
|
1347
|
+
const generation = this.recognitionGeneration;
|
|
1348
|
+
try {
|
|
1349
|
+
await this.ensureLiveReady();
|
|
1350
|
+
if (generation !== this.recognitionGeneration) return null;
|
|
1351
|
+
const safeQuery = toUint8ArrayCopy(query);
|
|
1352
|
+
const matcher = this.matcherOrThrow();
|
|
1353
|
+
if (!matcher.bestMatchChecked) {
|
|
1354
|
+
throw new Error("WASM matcher is missing bestMatchChecked; upgrade the WASM assets");
|
|
1355
|
+
}
|
|
1356
|
+
if (generation !== this.recognitionGeneration || this.destroyed) return null;
|
|
1357
|
+
return matcher.bestMatchChecked(this.databaseOrThrow(), safeQuery, config);
|
|
1358
|
+
} catch (error) {
|
|
1359
|
+
handleError(this.events, "bestMatchChecked", error);
|
|
1360
|
+
}
|
|
1361
|
+
}
|
|
1268
1362
|
async bestMatch(query, config) {
|
|
1269
1363
|
const generation = this.recognitionGeneration;
|
|
1270
1364
|
try {
|