@sorisdk/web-audio 0.6.4 → 0.6.7
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 +160 -4
- package/dist/generated/window.d.ts +1 -0
- package/dist/generated/window_bg.js +73 -11
- package/dist/generated/window_bg.wasm +0 -0
- package/dist/generated/window_bg.wasm.d.ts +5 -3
- package/dist/index.d.ts +39 -3
- package/dist/index.js +780 -48
- package/package.json +3 -3
package/README.md
CHANGED
|
@@ -22,7 +22,7 @@ configuration, or Node-based asset server is required:
|
|
|
22
22
|
```html
|
|
23
23
|
<script type="module">
|
|
24
24
|
import { AudioRecognizer } from
|
|
25
|
-
"https://cdn.iplateia.com/web/sorisdk/v0.6.
|
|
25
|
+
"https://cdn.iplateia.com/web/sorisdk/v0.6.7/sori-web-audio.mjs";
|
|
26
26
|
|
|
27
27
|
const recognizer = new AudioRecognizer({
|
|
28
28
|
appId: "YOUR_APP_ID",
|
|
@@ -49,13 +49,39 @@ configuration, or Node-based asset server is required:
|
|
|
49
49
|
```
|
|
50
50
|
|
|
51
51
|
Static URL imports are valid inside `<script type="module">`. Dynamic
|
|
52
|
-
`await import("https://cdn.iplateia.com/web/sorisdk/v0.6.
|
|
52
|
+
`await import("https://cdn.iplateia.com/web/sorisdk/v0.6.7/sori-web-audio.mjs")`
|
|
53
53
|
is an optional alternative when the SDK should be loaded conditionally.
|
|
54
54
|
|
|
55
55
|
Pin an exact version in production. Do not construct a mutable `latest` URL.
|
|
56
56
|
The module loads its versioned WASM assets and the shared
|
|
57
57
|
`https://cdn.iplateia.com/web/sorisdk/model.pack` automatically.
|
|
58
58
|
|
|
59
|
+
The fixed model response and caller-supplied AudioPacks use the matcher's same
|
|
60
|
+
64 MiB browser transport limit by default. A valid oversized `Content-Length`
|
|
61
|
+
is rejected before the body is consumed, and an unknown-length response is
|
|
62
|
+
canceled on the first chunk that crosses the limit. The response is never
|
|
63
|
+
truncated; failures use the deterministic
|
|
64
|
+
`Pack source exceeds maximum size of <limit> bytes` error.
|
|
65
|
+
|
|
66
|
+
Set an intentional shared override through the matcher options when a larger
|
|
67
|
+
pack is required:
|
|
68
|
+
|
|
69
|
+
```ts
|
|
70
|
+
const recognizer = new AudioRecognizer({
|
|
71
|
+
appId: "YOUR_APP_ID",
|
|
72
|
+
ephemeralKey,
|
|
73
|
+
wasm: {
|
|
74
|
+
matcher: {
|
|
75
|
+
maxPackBytes: 96 * 1024 * 1024
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
});
|
|
79
|
+
```
|
|
80
|
+
|
|
81
|
+
The override applies to both the standalone fixed-model response and ordinary
|
|
82
|
+
pack sources. A caller-supplied `embeddedPackLoader` remains a zero-argument
|
|
83
|
+
callback and is not replaced by the standalone loader.
|
|
84
|
+
|
|
59
85
|
The standalone module removes the frontend build/server requirement, but it
|
|
60
86
|
does not remove the trusted server requirement for ephemeral credentials.
|
|
61
87
|
Provide a backend or serverless endpoint for the `ephemeralKey` callback, and
|
|
@@ -93,7 +119,7 @@ An import map can give the standalone URL the npm package name:
|
|
|
93
119
|
<script type="importmap">
|
|
94
120
|
{
|
|
95
121
|
"imports": {
|
|
96
|
-
"@sorisdk/web-audio": "https://cdn.iplateia.com/web/sorisdk/v0.6.
|
|
122
|
+
"@sorisdk/web-audio": "https://cdn.iplateia.com/web/sorisdk/v0.6.7/sori-web-audio.mjs"
|
|
97
123
|
}
|
|
98
124
|
}
|
|
99
125
|
</script>
|
|
@@ -142,7 +168,7 @@ const recognizer = new AudioRecognizer({
|
|
|
142
168
|
});
|
|
143
169
|
|
|
144
170
|
recognizer.on("campaign", (event) => {
|
|
145
|
-
console.log(event.campaign);
|
|
171
|
+
console.log(event.activityId, event.campaign);
|
|
146
172
|
});
|
|
147
173
|
|
|
148
174
|
recognizer.on("error", ({ error }) => {
|
|
@@ -159,6 +185,121 @@ await recognizer.stop();
|
|
|
159
185
|
await recognizer.destroy();
|
|
160
186
|
```
|
|
161
187
|
|
|
188
|
+
## Activity refinement
|
|
189
|
+
|
|
190
|
+
The default `AudioRecognizer` activity reporter represents one ordered,
|
|
191
|
+
continuous material segment and its later audio-marker enrichment as one
|
|
192
|
+
server activity:
|
|
193
|
+
|
|
194
|
+
1. When the coordinator accepts a successful material match, it captures one
|
|
195
|
+
UTC RFC 3339 `recognized_at` value before any asynchronous request mapping,
|
|
196
|
+
header, token, or fetch work.
|
|
197
|
+
2. The initial `POST /api/activity/` includes that timestamp and the exact
|
|
198
|
+
`DetectedMatch.position` integer in milliseconds. With valid
|
|
199
|
+
`matcherSegments` metadata, the position is local to the matched segment.
|
|
200
|
+
3. A marker-free match with an active marker-scan request also includes
|
|
201
|
+
top-level `refinement_expected: true`.
|
|
202
|
+
4. The returned `activity_id` is retained for 30 seconds.
|
|
203
|
+
5. If the same recognition gains `audioMarker.code`, the SDK sends
|
|
204
|
+
`PUT /api/activity/{activity_id}` with the same material and
|
|
205
|
+
`trait.marker`.
|
|
206
|
+
6. The refined `campaign` event keeps the same non-empty `activityId`, so an
|
|
207
|
+
application can replace the earlier campaign row deterministically.
|
|
208
|
+
|
|
209
|
+
A consecutive match for the same material and fingerprint type renews a local
|
|
210
|
+
30-second continuity lease without another POST or campaign event. That local
|
|
211
|
+
lease can keep one segment alive beyond the initial server refinement window,
|
|
212
|
+
but it never extends the original PUT deadline. A marker confirmed anywhere
|
|
213
|
+
inside the segment is sticky: the first confirmation can issue at most one PUT,
|
|
214
|
+
and later marker misses or repeated marker evidence issue no mutation or
|
|
215
|
+
downgrade.
|
|
216
|
+
|
|
217
|
+
A marker present on the first match is included in the POST and does not cause
|
|
218
|
+
a PUT or include `refinement_expected`; that marker-first segment is still
|
|
219
|
+
retained for continuity. Recognition without an active marker scan, plus
|
|
220
|
+
legacy/custom POST-only reporters, also omit the opt-in flag. Custom reporters
|
|
221
|
+
enable segment coalescing only when `refinement` is enabled, preserving legacy
|
|
222
|
+
POST-only behavior otherwise.
|
|
223
|
+
|
|
224
|
+
A different material, an emitted `nomatch`, a gap beyond the continuity lease,
|
|
225
|
+
or stop, clear, destroy, authentication/capture replacement, or reset seals the
|
|
226
|
+
segment. Returning to A after B always creates a new A activity and can never
|
|
227
|
+
refine the earlier A. Marker evidence arriving after a segment is sealed is
|
|
228
|
+
ignored for that segment; create or PUT transport that already started may
|
|
229
|
+
finish under the existing capture, deadline, and cancellation guards.
|
|
230
|
+
|
|
231
|
+
Ordinary fingerprint `match` and marker-state `audiomarker` events remain
|
|
232
|
+
independently observable; coalescing only changes activity mutation and
|
|
233
|
+
campaign delivery. An `audiomarker` event alone does not mean that server
|
|
234
|
+
activity refinement completed.
|
|
235
|
+
|
|
236
|
+
Recognition timing belongs only to the segment's first material POST. Later
|
|
237
|
+
same-material observations update only the internal `lastObservedAt` lease;
|
|
238
|
+
they never replace the first `recognized_at` or `position`. A later marker PUT
|
|
239
|
+
does not include either field, and marker-only events do not create timing
|
|
240
|
+
metadata. `recognized_at` identifies first SDK match acceptance rather than
|
|
241
|
+
HTTP receipt, marker confirmation, refinement, or webhook delivery time. Do not
|
|
242
|
+
derive playback start as `recognized_at - position`: the match is accepted
|
|
243
|
+
after its query window was collected, so that calculation lacks the query
|
|
244
|
+
window's wall-clock anchor.
|
|
245
|
+
|
|
246
|
+
Network and 5xx PUT failures are retried at most twice within the original
|
|
247
|
+
30-second deadline. Server responses 404, 409, and 410 are terminal. An
|
|
248
|
+
expired or failed refinement is dropped and never becomes a second POST.
|
|
249
|
+
Stopping, clearing, destroying, or replacing the authenticated capture clears
|
|
250
|
+
pending refinement identity.
|
|
251
|
+
|
|
252
|
+
Custom `activityReporter` configurations remain POST-only by default. Enable
|
|
253
|
+
refinement explicitly and, if needed, provide operation-specific transport or
|
|
254
|
+
mapping hooks:
|
|
255
|
+
|
|
256
|
+
```ts
|
|
257
|
+
const recognizer = new AudioRecognizer({
|
|
258
|
+
appId: "YOUR_APP_ID",
|
|
259
|
+
ephemeralKey: fetchEphemeralKeyFromYourServer,
|
|
260
|
+
activityReporter: {
|
|
261
|
+
endpoint: "https://example.com/activity/",
|
|
262
|
+
refinement: {
|
|
263
|
+
endpoint: (activityId) =>
|
|
264
|
+
`https://example.com/activity/${encodeURIComponent(activityId)}`,
|
|
265
|
+
maxAttempts: 2,
|
|
266
|
+
shouldRetry: ({ status }) => status === null || status >= 500
|
|
267
|
+
}
|
|
268
|
+
}
|
|
269
|
+
});
|
|
270
|
+
```
|
|
271
|
+
|
|
272
|
+
Existing `mapMatchToRequest` and `mapResponseToCampaign` hooks continue to
|
|
273
|
+
handle POST. Additive refinement hooks can override the PUT payload, response
|
|
274
|
+
mapping, endpoint, headers, fetcher, and retry policy. The stable terminal
|
|
275
|
+
statuses 404, 409, and 410 are never retried even if a custom policy returns
|
|
276
|
+
`true`.
|
|
277
|
+
|
|
278
|
+
`recognized_at` and `position` are optional public request properties for
|
|
279
|
+
source compatibility, but they are SDK-owned transport values. After a custom
|
|
280
|
+
POST mapper returns an eligible material payload, the SDK overwrites any
|
|
281
|
+
conflicting values with the captured recognition timestamp and exact matcher
|
|
282
|
+
position. The SDK removes both properties from all refinement PUT payloads,
|
|
283
|
+
including custom refinement mappings. Existing one-argument POST mappers and
|
|
284
|
+
POST-only transports require no signature changes. Activity responses and
|
|
285
|
+
`campaign` events do not gain timing properties from this request contract.
|
|
286
|
+
|
|
287
|
+
## API endpoint normalization
|
|
288
|
+
|
|
289
|
+
`apiEndpoint` continues to accept a `string` or `URL`. When the SDK derives the
|
|
290
|
+
default authentication and activity URLs, it removes all trailing ASCII `/`
|
|
291
|
+
characters and appends `/auth` or `/activity/` with the existing URL shapes.
|
|
292
|
+
|
|
293
|
+
The endpoint is limited to `MAX_API_ENDPOINT_LENGTH` (32,768 UTF-16 code units).
|
|
294
|
+
The first code unit over that limit throws
|
|
295
|
+
`AudioRecognizer apiEndpoint exceeds maximum length of 32768 UTF-16 code units`
|
|
296
|
+
before trailing-slash scanning or endpoint joining. The SDK rejects the input;
|
|
297
|
+
it never truncates it. An explicitly supplied `apiEndpoint` is length-validated
|
|
298
|
+
during construction even when custom `authEndpoint` and `activityEndpoint`
|
|
299
|
+
values mean its prefix is not used for either join. This resource bound limits
|
|
300
|
+
construction work only. It is not an authentication, authorization, quota, or
|
|
301
|
+
abuse-prevention control.
|
|
302
|
+
|
|
162
303
|
## Session identifiers
|
|
163
304
|
|
|
164
305
|
`AudioRecognizer` creates one pseudonymous session identifier per application
|
|
@@ -244,6 +385,21 @@ const recognizer = new AudioRecognizer({
|
|
|
244
385
|
});
|
|
245
386
|
```
|
|
246
387
|
|
|
388
|
+
Advanced callers that import `@sorisdk/web-audio/generated/window.js`
|
|
389
|
+
directly still use `appendFingerprint(bytes: Uint8Array): void`. Each generated
|
|
390
|
+
window exposes `maxAppendFingerprintByteLength()`, which is the byte length of
|
|
391
|
+
one complete query for that instance. An append exactly at that limit is
|
|
392
|
+
accepted. A larger append throws a `RangeError` before the JavaScript array is
|
|
393
|
+
copied into WASM, with this deterministic message:
|
|
394
|
+
|
|
395
|
+
```text
|
|
396
|
+
Fingerprint append byteLength <actual> exceeds the per-instance limit of <limit> bytes
|
|
397
|
+
```
|
|
398
|
+
|
|
399
|
+
The high-level SDK enforces the same boundary before it invokes the generated
|
|
400
|
+
class. Oversized input is rejected, never truncated or split; normal microphone
|
|
401
|
+
fingerprint chunks and the existing match-window cadence are unchanged.
|
|
402
|
+
|
|
247
403
|
## Integration flow
|
|
248
404
|
|
|
249
405
|
1. Prepare your `appId` and ephemeral key flow.
|
|
@@ -6,6 +6,7 @@ export class WasmFingerprintMatchWindow {
|
|
|
6
6
|
[Symbol.dispose](): void;
|
|
7
7
|
appendFingerprint(bytes: Uint8Array): void;
|
|
8
8
|
hasReadyQuery(): boolean;
|
|
9
|
+
maxAppendFingerprintByteLength(): number;
|
|
9
10
|
constructor(sample_rate: number, afpgen_config: any | null | undefined, match_window_ms: number, match_stride_ms: number);
|
|
10
11
|
reset(): void;
|
|
11
12
|
takeReadyQuery(): any;
|
|
@@ -13,9 +13,10 @@ export class WasmFingerprintMatchWindow {
|
|
|
13
13
|
* @param {Uint8Array} bytes
|
|
14
14
|
*/
|
|
15
15
|
appendFingerprint(bytes) {
|
|
16
|
-
const
|
|
17
|
-
|
|
18
|
-
|
|
16
|
+
const ret = wasm.wasmfingerprintmatchwindow_appendFingerprint(this.__wbg_ptr, bytes);
|
|
17
|
+
if (ret[1]) {
|
|
18
|
+
throw takeFromExternrefTable0(ret[0]);
|
|
19
|
+
}
|
|
19
20
|
}
|
|
20
21
|
/**
|
|
21
22
|
* @returns {boolean}
|
|
@@ -24,6 +25,13 @@ export class WasmFingerprintMatchWindow {
|
|
|
24
25
|
const ret = wasm.wasmfingerprintmatchwindow_hasReadyQuery(this.__wbg_ptr);
|
|
25
26
|
return ret !== 0;
|
|
26
27
|
}
|
|
28
|
+
/**
|
|
29
|
+
* @returns {number}
|
|
30
|
+
*/
|
|
31
|
+
maxAppendFingerprintByteLength() {
|
|
32
|
+
const ret = wasm.wasmfingerprintmatchwindow_maxAppendFingerprintByteLength(this.__wbg_ptr);
|
|
33
|
+
return ret >>> 0;
|
|
34
|
+
}
|
|
27
35
|
/**
|
|
28
36
|
* @param {number} sample_rate
|
|
29
37
|
* @param {any | null | undefined} afpgen_config
|
|
@@ -47,7 +55,10 @@ export class WasmFingerprintMatchWindow {
|
|
|
47
55
|
*/
|
|
48
56
|
takeReadyQuery() {
|
|
49
57
|
const ret = wasm.wasmfingerprintmatchwindow_takeReadyQuery(this.__wbg_ptr);
|
|
50
|
-
|
|
58
|
+
if (ret[2]) {
|
|
59
|
+
throw takeFromExternrefTable0(ret[1]);
|
|
60
|
+
}
|
|
61
|
+
return takeFromExternrefTable0(ret[0]);
|
|
51
62
|
}
|
|
52
63
|
}
|
|
53
64
|
if (Symbol.dispose) WasmFingerprintMatchWindow.prototype[Symbol.dispose] = WasmFingerprintMatchWindow.prototype.free;
|
|
@@ -82,6 +93,10 @@ export function __wbg___wbindgen_in_a5d8b22e52b24dd1(arg0, arg1) {
|
|
|
82
93
|
const ret = arg0 in arg1;
|
|
83
94
|
return ret;
|
|
84
95
|
}
|
|
96
|
+
export function __wbg___wbindgen_is_function_3baa9db1a987f47d(arg0) {
|
|
97
|
+
const ret = typeof(arg0) === 'function';
|
|
98
|
+
return ret;
|
|
99
|
+
}
|
|
85
100
|
export function __wbg___wbindgen_is_null_52ff4ec04186736f(arg0) {
|
|
86
101
|
const ret = arg0 === null;
|
|
87
102
|
return ret;
|
|
@@ -116,6 +131,26 @@ export function __wbg___wbindgen_string_get_7ed5322991caaec5(arg0, arg1) {
|
|
|
116
131
|
export function __wbg___wbindgen_throw_6b64449b9b9ed33c(arg0, arg1) {
|
|
117
132
|
throw new Error(getStringFromWasm0(arg0, arg1));
|
|
118
133
|
}
|
|
134
|
+
export function __wbg_call_14b169f759b26747() { return handleError(function (arg0, arg1) {
|
|
135
|
+
const ret = arg0.call(arg1);
|
|
136
|
+
return ret;
|
|
137
|
+
}, arguments); }
|
|
138
|
+
export function __wbg_call_a24592a6f349a97e() { return handleError(function (arg0, arg1, arg2) {
|
|
139
|
+
const ret = arg0.call(arg1, arg2);
|
|
140
|
+
return ret;
|
|
141
|
+
}, arguments); }
|
|
142
|
+
export function __wbg_getOwnPropertyDescriptor_131bd582a45a6f5d(arg0, arg1) {
|
|
143
|
+
const ret = Object.getOwnPropertyDescriptor(arg0, arg1);
|
|
144
|
+
return ret;
|
|
145
|
+
}
|
|
146
|
+
export function __wbg_getPrototypeOf_a56da9261bbd1e5b(arg0) {
|
|
147
|
+
const ret = Object.getPrototypeOf(arg0);
|
|
148
|
+
return ret;
|
|
149
|
+
}
|
|
150
|
+
export function __wbg_get_6011fa3a58f61074() { return handleError(function (arg0, arg1) {
|
|
151
|
+
const ret = Reflect.get(arg0, arg1);
|
|
152
|
+
return ret;
|
|
153
|
+
}, arguments); }
|
|
119
154
|
export function __wbg_get_with_ref_key_6412cf3094599694(arg0, arg1) {
|
|
120
155
|
const ret = arg0[arg1];
|
|
121
156
|
return ret;
|
|
@@ -152,6 +187,10 @@ export function __wbg_new_0c7403db6e782f19(arg0) {
|
|
|
152
187
|
const ret = new Uint8Array(arg0);
|
|
153
188
|
return ret;
|
|
154
189
|
}
|
|
190
|
+
export function __wbg_new_191521fecb171639(arg0, arg1) {
|
|
191
|
+
const ret = new RangeError(getStringFromWasm0(arg0, arg1));
|
|
192
|
+
return ret;
|
|
193
|
+
}
|
|
155
194
|
export function __wbg_new_from_slice_b5ea43e23f6008c0(arg0, arg1) {
|
|
156
195
|
const ret = new Uint8Array(getArrayU8FromWasm0(arg0, arg1));
|
|
157
196
|
return ret;
|
|
@@ -159,7 +198,28 @@ export function __wbg_new_from_slice_b5ea43e23f6008c0(arg0, arg1) {
|
|
|
159
198
|
export function __wbg_prototypesetcall_a6b02eb00b0f4ce2(arg0, arg1, arg2) {
|
|
160
199
|
Uint8Array.prototype.set.call(getArrayU8FromWasm0(arg0, arg1), arg2);
|
|
161
200
|
}
|
|
201
|
+
export function __wbg_static_accessor_GLOBAL_8cfadc87a297ca02() {
|
|
202
|
+
const ret = typeof global === 'undefined' ? null : global;
|
|
203
|
+
return isLikeNone(ret) ? 0 : addToExternrefTable0(ret);
|
|
204
|
+
}
|
|
205
|
+
export function __wbg_static_accessor_GLOBAL_THIS_602256ae5c8f42cf() {
|
|
206
|
+
const ret = typeof globalThis === 'undefined' ? null : globalThis;
|
|
207
|
+
return isLikeNone(ret) ? 0 : addToExternrefTable0(ret);
|
|
208
|
+
}
|
|
209
|
+
export function __wbg_static_accessor_SELF_e445c1c7484aecc3() {
|
|
210
|
+
const ret = typeof self === 'undefined' ? null : self;
|
|
211
|
+
return isLikeNone(ret) ? 0 : addToExternrefTable0(ret);
|
|
212
|
+
}
|
|
213
|
+
export function __wbg_static_accessor_WINDOW_f20e8576ef1e0f17() {
|
|
214
|
+
const ret = typeof window === 'undefined' ? null : window;
|
|
215
|
+
return isLikeNone(ret) ? 0 : addToExternrefTable0(ret);
|
|
216
|
+
}
|
|
162
217
|
export function __wbindgen_cast_0000000000000001(arg0, arg1) {
|
|
218
|
+
// Cast intrinsic for `Ref(Slice(U8)) -> NamedExternref("Uint8Array")`.
|
|
219
|
+
const ret = getArrayU8FromWasm0(arg0, arg1);
|
|
220
|
+
return ret;
|
|
221
|
+
}
|
|
222
|
+
export function __wbindgen_cast_0000000000000002(arg0, arg1) {
|
|
163
223
|
// Cast intrinsic for `Ref(String) -> Externref`.
|
|
164
224
|
const ret = getStringFromWasm0(arg0, arg1);
|
|
165
225
|
return ret;
|
|
@@ -274,15 +334,17 @@ function getUint8ArrayMemory0() {
|
|
|
274
334
|
return cachedUint8ArrayMemory0;
|
|
275
335
|
}
|
|
276
336
|
|
|
277
|
-
function
|
|
278
|
-
|
|
337
|
+
function handleError(f, args) {
|
|
338
|
+
try {
|
|
339
|
+
return f.apply(this, args);
|
|
340
|
+
} catch (e) {
|
|
341
|
+
const idx = addToExternrefTable0(e);
|
|
342
|
+
wasm.__wbindgen_exn_store(idx);
|
|
343
|
+
}
|
|
279
344
|
}
|
|
280
345
|
|
|
281
|
-
function
|
|
282
|
-
|
|
283
|
-
getUint8ArrayMemory0().set(arg, ptr / 1);
|
|
284
|
-
WASM_VECTOR_LEN = arg.length;
|
|
285
|
-
return ptr;
|
|
346
|
+
function isLikeNone(x) {
|
|
347
|
+
return x === undefined || x === null;
|
|
286
348
|
}
|
|
287
349
|
|
|
288
350
|
function passStringToWasm0(arg, malloc, realloc) {
|
|
Binary file
|
|
@@ -2,14 +2,16 @@
|
|
|
2
2
|
/* eslint-disable */
|
|
3
3
|
export const memory: WebAssembly.Memory;
|
|
4
4
|
export const __wbg_wasmfingerprintmatchwindow_free: (a: number, b: number) => void;
|
|
5
|
-
export const wasmfingerprintmatchwindow_appendFingerprint: (a: number, b: number,
|
|
5
|
+
export const wasmfingerprintmatchwindow_appendFingerprint: (a: number, b: any) => [number, number];
|
|
6
6
|
export const wasmfingerprintmatchwindow_hasReadyQuery: (a: number) => number;
|
|
7
|
+
export const wasmfingerprintmatchwindow_maxAppendFingerprintByteLength: (a: number) => number;
|
|
7
8
|
export const wasmfingerprintmatchwindow_new: (a: number, b: number, c: number, d: number) => [number, number, number];
|
|
8
9
|
export const wasmfingerprintmatchwindow_reset: (a: number) => void;
|
|
9
|
-
export const wasmfingerprintmatchwindow_takeReadyQuery: (a: number) =>
|
|
10
|
+
export const wasmfingerprintmatchwindow_takeReadyQuery: (a: number) => [number, number, number];
|
|
10
11
|
export const __wbindgen_malloc: (a: number, b: number) => number;
|
|
11
12
|
export const __wbindgen_realloc: (a: number, b: number, c: number, d: number) => number;
|
|
12
|
-
export const
|
|
13
|
+
export const __wbindgen_exn_store: (a: number) => void;
|
|
13
14
|
export const __externref_table_alloc: () => number;
|
|
15
|
+
export const __wbindgen_externrefs: WebAssembly.Table;
|
|
14
16
|
export const __externref_table_dealloc: (a: number) => void;
|
|
15
17
|
export const __wbindgen_start: () => void;
|
package/dist/index.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { MatcherEphemeralAuthOptions, InitMatcherOptions, MatcherEphemeralAuthResult, AudioMarkerDetection, PackSource, MatchResult, AudioFingerprintType } from '@sorisdk/matcher';
|
|
1
|
+
import { MatcherEphemeralAuthOptions, InitMatcherOptions, MatcherEphemeralAuthResult, AudioMarkerDetection, PackSource, MatchResult, MatcherSessionOptions, AudioFingerprintType } from '@sorisdk/matcher';
|
|
2
2
|
export { AudioFingerprintType, AudioMarkerConfig, AudioMarkerDetection, PackSource } from '@sorisdk/matcher';
|
|
3
3
|
import { InitAfpgenOptions } from '@sorisdk/afpgen';
|
|
4
4
|
|
|
@@ -62,6 +62,15 @@ interface AudioMarkerEvent {
|
|
|
62
62
|
interface MaterialActivityRequestPayload {
|
|
63
63
|
type: "material";
|
|
64
64
|
material_id: string;
|
|
65
|
+
/** SDK-owned UTC recognition timestamp. Custom mapper values are overwritten on POST. */
|
|
66
|
+
recognized_at?: string;
|
|
67
|
+
/** SDK-owned matcher position in milliseconds. Custom mapper values are overwritten on POST. */
|
|
68
|
+
position?: number;
|
|
69
|
+
refinement_expected?: true;
|
|
70
|
+
trait?: {
|
|
71
|
+
marker?: string;
|
|
72
|
+
[key: string]: unknown;
|
|
73
|
+
};
|
|
65
74
|
metadata?: unknown;
|
|
66
75
|
}
|
|
67
76
|
interface MicrophoneMatcherCampaignEvent {
|
|
@@ -70,6 +79,27 @@ interface MicrophoneMatcherCampaignEvent {
|
|
|
70
79
|
activityId: string | null;
|
|
71
80
|
raw: Record<string, unknown>;
|
|
72
81
|
}
|
|
82
|
+
interface ActivityRefinementRequestContext {
|
|
83
|
+
operation: "refine";
|
|
84
|
+
activityId: string;
|
|
85
|
+
attempt: number;
|
|
86
|
+
deadline: number;
|
|
87
|
+
}
|
|
88
|
+
interface ActivityRefinementFailureContext extends ActivityRefinementRequestContext {
|
|
89
|
+
error: Error;
|
|
90
|
+
status: number | null;
|
|
91
|
+
detail: string | null;
|
|
92
|
+
}
|
|
93
|
+
interface MicrophoneMatcherActivityRefinementOptions {
|
|
94
|
+
endpoint?: string | URL | ((activityId: string) => string | URL | Promise<string | URL>);
|
|
95
|
+
fetch?: typeof fetch;
|
|
96
|
+
headers?: HeadersInit | (() => HeadersInit | Promise<HeadersInit>);
|
|
97
|
+
mapMatchToRequest?: (match: DetectedMatch, context: ActivityRefinementRequestContext) => MaterialActivityRequestPayload | null | Promise<MaterialActivityRequestPayload | null>;
|
|
98
|
+
mapResponseToCampaign?: (response: Record<string, unknown>, match: DetectedMatch, context: ActivityRefinementRequestContext) => MicrophoneMatcherCampaignEvent | null | Promise<MicrophoneMatcherCampaignEvent | null>;
|
|
99
|
+
shouldRetry?: (context: ActivityRefinementFailureContext) => boolean | Promise<boolean>;
|
|
100
|
+
maxAttempts?: number;
|
|
101
|
+
now?: () => number;
|
|
102
|
+
}
|
|
73
103
|
interface MicrophoneMatcherActivityReporterOptions {
|
|
74
104
|
endpoint: string | URL;
|
|
75
105
|
token: string | (() => string | Promise<string>);
|
|
@@ -77,10 +107,11 @@ interface MicrophoneMatcherActivityReporterOptions {
|
|
|
77
107
|
headers?: HeadersInit | (() => HeadersInit | Promise<HeadersInit>);
|
|
78
108
|
mapMatchToRequest?: (match: DetectedMatch) => MaterialActivityRequestPayload | null | Promise<MaterialActivityRequestPayload | null>;
|
|
79
109
|
mapResponseToCampaign?: (response: Record<string, unknown>, match: DetectedMatch) => MicrophoneMatcherCampaignEvent | null | Promise<MicrophoneMatcherCampaignEvent | null>;
|
|
110
|
+
refinement?: false | MicrophoneMatcherActivityRefinementOptions;
|
|
80
111
|
}
|
|
81
112
|
interface CreateMicrophoneMatcherWasmOptions {
|
|
82
113
|
afpgen?: InitAfpgenOptions;
|
|
83
|
-
matcher?: Omit<
|
|
114
|
+
matcher?: Omit<MatcherSessionOptions, "auth">;
|
|
84
115
|
matchWindow?: InitMatchWindowWasmOptions;
|
|
85
116
|
}
|
|
86
117
|
interface CreateMicrophoneMatcherOptions {
|
|
@@ -120,6 +151,7 @@ type MicrophoneMatcherListener<T extends MicrophoneMatcherEventName> = (payload:
|
|
|
120
151
|
type Awaitable<T> = T | Promise<T>;
|
|
121
152
|
type AudioRecognizerMatcherOptions = Omit<CreateMicrophoneMatcherOptions, "activityReporter" | "packSource">;
|
|
122
153
|
declare const DEFAULT_SORI_API_ENDPOINT = "https://console.soriapi.com/api";
|
|
154
|
+
declare const MAX_API_ENDPOINT_LENGTH: number;
|
|
123
155
|
interface AudioRecognizerAuthOptions {
|
|
124
156
|
endpoint: string | URL;
|
|
125
157
|
appId: string;
|
|
@@ -182,6 +214,8 @@ declare class AudioRecognizer {
|
|
|
182
214
|
private setAuthResult;
|
|
183
215
|
}
|
|
184
216
|
|
|
217
|
+
declare const ACTIVITY_REFINEMENT_WINDOW_MS = 30000;
|
|
218
|
+
|
|
185
219
|
declare class MicrophoneMatcher {
|
|
186
220
|
private readonly events;
|
|
187
221
|
private readonly matcherSession;
|
|
@@ -193,6 +227,7 @@ declare class MicrophoneMatcher {
|
|
|
193
227
|
private readonly captureSampleRate;
|
|
194
228
|
private readonly audioGraphFactory;
|
|
195
229
|
private readonly packSource;
|
|
230
|
+
private readonly activityRefinement;
|
|
196
231
|
private readonly options;
|
|
197
232
|
private extractor;
|
|
198
233
|
private graphController;
|
|
@@ -211,6 +246,7 @@ declare class MicrophoneMatcher {
|
|
|
211
246
|
private latestAudioMarker;
|
|
212
247
|
private latestAudioMarkerDetection;
|
|
213
248
|
private audioMarkerRequestId;
|
|
249
|
+
private activityRecognitionId;
|
|
214
250
|
private hopSize;
|
|
215
251
|
private diagnostics;
|
|
216
252
|
constructor(options: CreateMicrophoneMatcherOptions);
|
|
@@ -260,4 +296,4 @@ declare function requestMicrophoneStream(mediaDevices: MediaDevices, mediaConstr
|
|
|
260
296
|
preferredSampleRate?: number;
|
|
261
297
|
}): Promise<MediaStream>;
|
|
262
298
|
|
|
263
|
-
export { type AudioMarkerEvent, AudioRecognizer, type AudioRecognizerAuthOptions, type AudioRecognizerOptions, type AuthenticateAndLoadAudioPackOptions, type AuthenticateAndLoadAudioPackResult, type BrowserAudioPackLoader, type BrowserAudioPackState, type BrowserAudioPackStateStore, type BrowserSessionManager, type CreateLocalStorageAudioPackStoreOptions, type CreateLocalStorageSessionManagerOptions, type CreateMicrophoneMatcherOptions, type CreateMicrophoneMatcherWasmOptions, DEFAULT_BROWSER_AUDIOPACK_VERSION, DEFAULT_SORI_API_ENDPOINT, type DetectedMatch, type MaterialActivityRequestPayload, MicrophoneMatcher, type MicrophoneMatcherActivityReporterOptions, type MicrophoneMatcherCampaignEvent, type MicrophoneMatcherEventMap, type MicrophoneMatcherEventName, type MicrophoneMatcherListener, authenticateAndLoadAudioPack, createLocalStorageAudioPackStore, createLocalStorageSessionManager, createMicrophoneMatcher, requestMicrophoneStream };
|
|
299
|
+
export { ACTIVITY_REFINEMENT_WINDOW_MS, type ActivityRefinementFailureContext, type ActivityRefinementRequestContext, type AudioMarkerEvent, AudioRecognizer, type AudioRecognizerAuthOptions, type AudioRecognizerOptions, type AuthenticateAndLoadAudioPackOptions, type AuthenticateAndLoadAudioPackResult, type BrowserAudioPackLoader, type BrowserAudioPackState, type BrowserAudioPackStateStore, type BrowserSessionManager, type CreateLocalStorageAudioPackStoreOptions, type CreateLocalStorageSessionManagerOptions, type CreateMicrophoneMatcherOptions, type CreateMicrophoneMatcherWasmOptions, DEFAULT_BROWSER_AUDIOPACK_VERSION, DEFAULT_SORI_API_ENDPOINT, type DetectedMatch, MAX_API_ENDPOINT_LENGTH, type MaterialActivityRequestPayload, MicrophoneMatcher, type MicrophoneMatcherActivityRefinementOptions, type MicrophoneMatcherActivityReporterOptions, type MicrophoneMatcherCampaignEvent, type MicrophoneMatcherEventMap, type MicrophoneMatcherEventName, type MicrophoneMatcherListener, authenticateAndLoadAudioPack, createLocalStorageAudioPackStore, createLocalStorageSessionManager, createMicrophoneMatcher, requestMicrophoneStream };
|