@omote/core 0.5.4 → 0.5.6
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/index.d.mts +26 -0
- package/dist/index.d.ts +26 -0
- package/dist/index.js +146 -68
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +146 -68
- package/dist/index.mjs.map +1 -1
- package/package.json +1 -1
package/dist/index.mjs
CHANGED
|
@@ -510,6 +510,7 @@ var A2EProcessor = class {
|
|
|
510
510
|
this.backend = config.backend;
|
|
511
511
|
this.sampleRate = config.sampleRate ?? 16e3;
|
|
512
512
|
this.chunkSize = config.chunkSize ?? config.backend.chunkSize ?? 16e3;
|
|
513
|
+
this.identityIndex = config.identityIndex ?? 0;
|
|
513
514
|
this.onFrame = config.onFrame;
|
|
514
515
|
this.onError = config.onError;
|
|
515
516
|
this.bufferCapacity = this.chunkSize * 2;
|
|
@@ -717,7 +718,7 @@ var A2EProcessor = class {
|
|
|
717
718
|
const { chunk, timestamp } = this.pendingChunks.shift();
|
|
718
719
|
try {
|
|
719
720
|
const t0 = performance.now();
|
|
720
|
-
const result = await this.backend.infer(chunk);
|
|
721
|
+
const result = await this.backend.infer(chunk, this.identityIndex);
|
|
721
722
|
const inferMs = Math.round(performance.now() - t0);
|
|
722
723
|
const actualDuration = chunk.length / this.sampleRate;
|
|
723
724
|
const actualFrameCount = Math.ceil(actualDuration * FRAME_RATE);
|
|
@@ -1812,6 +1813,16 @@ function getModelCache() {
|
|
|
1812
1813
|
return cacheInstance;
|
|
1813
1814
|
}
|
|
1814
1815
|
var MAX_CACHE_SIZE_BYTES = 500 * 1024 * 1024;
|
|
1816
|
+
function fetchWithTimeout(url, timeoutMs, signal) {
|
|
1817
|
+
const controller = new AbortController();
|
|
1818
|
+
const timer = setTimeout(() => controller.abort(), timeoutMs);
|
|
1819
|
+
const onCallerAbort = () => controller.abort();
|
|
1820
|
+
signal?.addEventListener("abort", onCallerAbort, { once: true });
|
|
1821
|
+
return fetch(url, { signal: controller.signal }).finally(() => {
|
|
1822
|
+
clearTimeout(timer);
|
|
1823
|
+
signal?.removeEventListener("abort", onCallerAbort);
|
|
1824
|
+
});
|
|
1825
|
+
}
|
|
1815
1826
|
async function fetchWithCache(url, optionsOrProgress) {
|
|
1816
1827
|
let options = {};
|
|
1817
1828
|
if (typeof optionsOrProgress === "function") {
|
|
@@ -1865,61 +1876,84 @@ async function fetchWithCache(url, optionsOrProgress) {
|
|
|
1865
1876
|
}
|
|
1866
1877
|
span?.setAttributes({ "fetch.cache_hit": false });
|
|
1867
1878
|
console.log(`[ModelCache] Cache miss, fetching: ${url}`);
|
|
1868
|
-
|
|
1869
|
-
|
|
1870
|
-
|
|
1871
|
-
|
|
1872
|
-
|
|
1873
|
-
|
|
1874
|
-
|
|
1875
|
-
|
|
1876
|
-
|
|
1877
|
-
|
|
1878
|
-
|
|
1879
|
-
}
|
|
1880
|
-
|
|
1881
|
-
const
|
|
1879
|
+
const timeout = options.timeoutMs ?? 12e4;
|
|
1880
|
+
const maxRetries = options.maxRetries ?? 2;
|
|
1881
|
+
let lastError = null;
|
|
1882
|
+
for (let attempt = 0; attempt <= maxRetries; attempt++) {
|
|
1883
|
+
if (options.signal?.aborted) {
|
|
1884
|
+
throw new Error(`Fetch aborted for ${url}`);
|
|
1885
|
+
}
|
|
1886
|
+
if (attempt > 0) {
|
|
1887
|
+
const backoff = Math.min(2e3 * Math.pow(2, attempt - 1), 16e3);
|
|
1888
|
+
console.log(`[ModelCache] Retry ${attempt}/${maxRetries} after ${backoff}ms: ${url}`);
|
|
1889
|
+
await new Promise((r) => setTimeout(r, backoff));
|
|
1890
|
+
}
|
|
1891
|
+
try {
|
|
1892
|
+
const response = await fetchWithTimeout(url, timeout, options.signal);
|
|
1893
|
+
if (!response.ok) {
|
|
1894
|
+
throw new Error(`Failed to fetch ${url}: ${response.status}`);
|
|
1895
|
+
}
|
|
1896
|
+
const contentLength = response.headers.get("content-length");
|
|
1897
|
+
const total = contentLength ? parseInt(contentLength, 10) : 0;
|
|
1898
|
+
const etag = response.headers.get("etag") ?? void 0;
|
|
1899
|
+
const tooLargeForCache = total > MAX_CACHE_SIZE_BYTES;
|
|
1900
|
+
if (tooLargeForCache) {
|
|
1901
|
+
console.log(`[ModelCache] File too large for IndexedDB (${(total / 1024 / 1024).toFixed(0)}MB > 500MB), using HTTP cache only`);
|
|
1902
|
+
}
|
|
1903
|
+
if (!response.body) {
|
|
1904
|
+
const data2 = await response.arrayBuffer();
|
|
1905
|
+
if (!tooLargeForCache) {
|
|
1906
|
+
await cache.set(cacheKey, data2, etag, version);
|
|
1907
|
+
}
|
|
1908
|
+
span?.setAttributes({
|
|
1909
|
+
"fetch.size_bytes": data2.byteLength,
|
|
1910
|
+
"fetch.cached_to_indexeddb": !tooLargeForCache,
|
|
1911
|
+
...attempt > 0 && { "fetch.retry_count": attempt }
|
|
1912
|
+
});
|
|
1913
|
+
span?.end();
|
|
1914
|
+
return data2;
|
|
1915
|
+
}
|
|
1916
|
+
const reader = response.body.getReader();
|
|
1917
|
+
const chunks = [];
|
|
1918
|
+
let loaded = 0;
|
|
1919
|
+
while (true) {
|
|
1920
|
+
const { done, value } = await reader.read();
|
|
1921
|
+
if (done) break;
|
|
1922
|
+
chunks.push(value);
|
|
1923
|
+
loaded += value.length;
|
|
1924
|
+
onProgress?.(loaded, total || loaded);
|
|
1925
|
+
}
|
|
1926
|
+
const data = new Uint8Array(loaded);
|
|
1927
|
+
let offset = 0;
|
|
1928
|
+
for (const chunk of chunks) {
|
|
1929
|
+
data.set(chunk, offset);
|
|
1930
|
+
offset += chunk.length;
|
|
1931
|
+
}
|
|
1932
|
+
const buffer = data.buffer;
|
|
1882
1933
|
if (!tooLargeForCache) {
|
|
1883
|
-
await cache.set(cacheKey,
|
|
1934
|
+
await cache.set(cacheKey, buffer, etag, version);
|
|
1935
|
+
console.log(`[ModelCache] Cached: ${url} (${(buffer.byteLength / 1024 / 1024).toFixed(1)}MB)`);
|
|
1884
1936
|
}
|
|
1885
1937
|
span?.setAttributes({
|
|
1886
|
-
"fetch.size_bytes":
|
|
1887
|
-
"fetch.cached_to_indexeddb": !tooLargeForCache
|
|
1938
|
+
"fetch.size_bytes": buffer.byteLength,
|
|
1939
|
+
"fetch.cached_to_indexeddb": !tooLargeForCache,
|
|
1940
|
+
...attempt > 0 && { "fetch.retry_count": attempt }
|
|
1888
1941
|
});
|
|
1889
1942
|
span?.end();
|
|
1890
|
-
return
|
|
1891
|
-
}
|
|
1892
|
-
|
|
1893
|
-
|
|
1894
|
-
|
|
1895
|
-
|
|
1896
|
-
|
|
1897
|
-
if (
|
|
1898
|
-
|
|
1899
|
-
|
|
1900
|
-
onProgress?.(loaded, total || loaded);
|
|
1901
|
-
}
|
|
1902
|
-
const data = new Uint8Array(loaded);
|
|
1903
|
-
let offset = 0;
|
|
1904
|
-
for (const chunk of chunks) {
|
|
1905
|
-
data.set(chunk, offset);
|
|
1906
|
-
offset += chunk.length;
|
|
1907
|
-
}
|
|
1908
|
-
const buffer = data.buffer;
|
|
1909
|
-
if (!tooLargeForCache) {
|
|
1910
|
-
await cache.set(cacheKey, buffer, etag, version);
|
|
1911
|
-
console.log(`[ModelCache] Cached: ${url} (${(buffer.byteLength / 1024 / 1024).toFixed(1)}MB)`);
|
|
1943
|
+
return buffer;
|
|
1944
|
+
} catch (error) {
|
|
1945
|
+
lastError = error instanceof Error ? error : new Error(String(error));
|
|
1946
|
+
if (options.signal?.aborted) {
|
|
1947
|
+
span?.endWithError(lastError);
|
|
1948
|
+
throw lastError;
|
|
1949
|
+
}
|
|
1950
|
+
if (attempt < maxRetries) {
|
|
1951
|
+
console.warn(`[ModelCache] Attempt ${attempt + 1} failed for ${url}: ${lastError.message}`);
|
|
1952
|
+
}
|
|
1912
1953
|
}
|
|
1913
|
-
span?.setAttributes({
|
|
1914
|
-
"fetch.size_bytes": buffer.byteLength,
|
|
1915
|
-
"fetch.cached_to_indexeddb": !tooLargeForCache
|
|
1916
|
-
});
|
|
1917
|
-
span?.end();
|
|
1918
|
-
return buffer;
|
|
1919
|
-
} catch (error) {
|
|
1920
|
-
span?.endWithError(error instanceof Error ? error : new Error(String(error)));
|
|
1921
|
-
throw error;
|
|
1922
1954
|
}
|
|
1955
|
+
span?.endWithError(lastError);
|
|
1956
|
+
throw lastError;
|
|
1923
1957
|
}
|
|
1924
1958
|
async function preloadModels(urls, onProgress) {
|
|
1925
1959
|
const cache = getModelCache();
|
|
@@ -2168,6 +2202,15 @@ function getSessionOptions(backend) {
|
|
|
2168
2202
|
graphOptimizationLevel: "all"
|
|
2169
2203
|
};
|
|
2170
2204
|
}
|
|
2205
|
+
function withTimeout(promise, ms, label) {
|
|
2206
|
+
return new Promise((resolve, reject) => {
|
|
2207
|
+
const timer = setTimeout(
|
|
2208
|
+
() => reject(new Error(`${label} timed out after ${ms}ms`)),
|
|
2209
|
+
ms
|
|
2210
|
+
);
|
|
2211
|
+
promise.then(resolve, reject).finally(() => clearTimeout(timer));
|
|
2212
|
+
});
|
|
2213
|
+
}
|
|
2171
2214
|
|
|
2172
2215
|
// src/inference/blendshapeUtils.ts
|
|
2173
2216
|
var LAM_BLENDSHAPES = [
|
|
@@ -2440,7 +2483,11 @@ var _Wav2Vec2Inference = class _Wav2Vec2Inference {
|
|
|
2440
2483
|
)
|
|
2441
2484
|
});
|
|
2442
2485
|
try {
|
|
2443
|
-
this.session = await
|
|
2486
|
+
this.session = await withTimeout(
|
|
2487
|
+
this.ort.InferenceSession.create(modelUrl, sessionOptions),
|
|
2488
|
+
18e4,
|
|
2489
|
+
"Wav2Vec2 InferenceSession.create (iOS URL pass-through)"
|
|
2490
|
+
);
|
|
2444
2491
|
} catch (sessionErr) {
|
|
2445
2492
|
logger3.error("iOS: InferenceSession.create() failed", {
|
|
2446
2493
|
error: sessionErr instanceof Error ? sessionErr.message : String(sessionErr),
|
|
@@ -2841,6 +2888,7 @@ var FullFacePipeline = class extends EventEmitter {
|
|
|
2841
2888
|
backend: options.lam,
|
|
2842
2889
|
sampleRate,
|
|
2843
2890
|
chunkSize,
|
|
2891
|
+
identityIndex: options.identityIndex,
|
|
2844
2892
|
onError: (error) => {
|
|
2845
2893
|
logger4.error("A2E inference error", { message: error.message, stack: error.stack });
|
|
2846
2894
|
this.emit("error", error);
|
|
@@ -3527,9 +3575,10 @@ var _SenseVoiceInference = class _SenseVoiceInference {
|
|
|
3527
3575
|
logger5.info("iOS: passing model URL directly to ORT (low-memory path)", {
|
|
3528
3576
|
modelUrl: this.config.modelUrl
|
|
3529
3577
|
});
|
|
3530
|
-
this.session = await
|
|
3531
|
-
this.config.modelUrl,
|
|
3532
|
-
|
|
3578
|
+
this.session = await withTimeout(
|
|
3579
|
+
this.ort.InferenceSession.create(this.config.modelUrl, sessionOptions),
|
|
3580
|
+
18e4,
|
|
3581
|
+
"SenseVoice InferenceSession.create (iOS URL pass-through)"
|
|
3533
3582
|
);
|
|
3534
3583
|
} else {
|
|
3535
3584
|
const cache = getModelCache();
|
|
@@ -3782,6 +3831,12 @@ var WORKER_SCRIPT = `
|
|
|
3782
3831
|
var ort = null;
|
|
3783
3832
|
var session = null;
|
|
3784
3833
|
var tokenMap = null;
|
|
3834
|
+
|
|
3835
|
+
function fetchWithTimeout(url, timeoutMs) {
|
|
3836
|
+
var controller = new AbortController();
|
|
3837
|
+
var timer = setTimeout(function() { controller.abort(); }, timeoutMs);
|
|
3838
|
+
return fetch(url, { signal: controller.signal }).finally(function() { clearTimeout(timer); });
|
|
3839
|
+
}
|
|
3785
3840
|
var negMean = null;
|
|
3786
3841
|
var invStddev = null;
|
|
3787
3842
|
var languageId = 0;
|
|
@@ -4225,7 +4280,7 @@ async function loadOrt(wasmPaths) {
|
|
|
4225
4280
|
var ortUrl = wasmPaths + 'ort.wasm.min.js';
|
|
4226
4281
|
|
|
4227
4282
|
// Load the script by fetching and executing it
|
|
4228
|
-
var response = await
|
|
4283
|
+
var response = await fetchWithTimeout(ortUrl, 30000);
|
|
4229
4284
|
var scriptText = await response.text();
|
|
4230
4285
|
|
|
4231
4286
|
// Create a blob URL for the script
|
|
@@ -4251,7 +4306,7 @@ async function loadOrt(wasmPaths) {
|
|
|
4251
4306
|
*/
|
|
4252
4307
|
async function loadModel(modelUrl, tokensUrl, isIOSDevice, lang, textNorm) {
|
|
4253
4308
|
// 1. Fetch and parse tokens.txt
|
|
4254
|
-
var tokensResponse = await
|
|
4309
|
+
var tokensResponse = await fetchWithTimeout(tokensUrl, 30000);
|
|
4255
4310
|
if (!tokensResponse.ok) {
|
|
4256
4311
|
throw new Error('Failed to fetch tokens.txt: ' + tokensResponse.status + ' ' + tokensResponse.statusText);
|
|
4257
4312
|
}
|
|
@@ -4274,7 +4329,7 @@ async function loadModel(modelUrl, tokensUrl, isIOSDevice, lang, textNorm) {
|
|
|
4274
4329
|
session = await ort.InferenceSession.create(modelUrl, sessionOptions);
|
|
4275
4330
|
} else {
|
|
4276
4331
|
// Desktop: fetch ArrayBuffer for potential caching
|
|
4277
|
-
var modelResponse = await
|
|
4332
|
+
var modelResponse = await fetchWithTimeout(modelUrl, 120000);
|
|
4278
4333
|
if (!modelResponse.ok) {
|
|
4279
4334
|
throw new Error('Failed to fetch model: ' + modelResponse.status + ' ' + modelResponse.statusText);
|
|
4280
4335
|
}
|
|
@@ -4785,6 +4840,12 @@ var WORKER_SCRIPT2 = `
|
|
|
4785
4840
|
|
|
4786
4841
|
var ort = null;
|
|
4787
4842
|
|
|
4843
|
+
function fetchWithTimeout(url, timeoutMs) {
|
|
4844
|
+
var controller = new AbortController();
|
|
4845
|
+
var timer = setTimeout(function() { controller.abort(); }, timeoutMs);
|
|
4846
|
+
return fetch(url, { signal: controller.signal }).finally(function() { clearTimeout(timer); });
|
|
4847
|
+
}
|
|
4848
|
+
|
|
4788
4849
|
// SenseVoice state
|
|
4789
4850
|
var svSession = null;
|
|
4790
4851
|
var svTokenMap = null;
|
|
@@ -5099,7 +5160,7 @@ function symmetrizeBlendshapes(frame) {
|
|
|
5099
5160
|
async function loadOrt(wasmPaths, isIOSDevice) {
|
|
5100
5161
|
if (ort) return;
|
|
5101
5162
|
var ortUrl = wasmPaths + 'ort.wasm.min.js';
|
|
5102
|
-
var response = await
|
|
5163
|
+
var response = await fetchWithTimeout(ortUrl, 30000);
|
|
5103
5164
|
var scriptText = await response.text();
|
|
5104
5165
|
var blob = new Blob([scriptText], { type: 'application/javascript' });
|
|
5105
5166
|
var blobUrl = URL.createObjectURL(blob);
|
|
@@ -5117,7 +5178,7 @@ async function loadOrt(wasmPaths, isIOSDevice) {
|
|
|
5117
5178
|
// \u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550
|
|
5118
5179
|
|
|
5119
5180
|
async function svLoad(msg) {
|
|
5120
|
-
var tokensResponse = await
|
|
5181
|
+
var tokensResponse = await fetchWithTimeout(msg.tokensUrl, 30000);
|
|
5121
5182
|
if (!tokensResponse.ok) throw new Error('Failed to fetch tokens.txt: ' + tokensResponse.status);
|
|
5122
5183
|
var tokensText = await tokensResponse.text();
|
|
5123
5184
|
svTokenMap = parseTokensFile(tokensText);
|
|
@@ -5128,7 +5189,7 @@ async function svLoad(msg) {
|
|
|
5128
5189
|
if (msg.isIOS) {
|
|
5129
5190
|
svSession = await ort.InferenceSession.create(msg.modelUrl, sessionOptions);
|
|
5130
5191
|
} else {
|
|
5131
|
-
var modelResponse = await
|
|
5192
|
+
var modelResponse = await fetchWithTimeout(msg.modelUrl, 120000);
|
|
5132
5193
|
if (!modelResponse.ok) throw new Error('Failed to fetch model: ' + modelResponse.status);
|
|
5133
5194
|
var modelBuffer = await modelResponse.arrayBuffer();
|
|
5134
5195
|
svSession = await ort.InferenceSession.create(new Uint8Array(modelBuffer), sessionOptions);
|
|
@@ -5203,11 +5264,11 @@ async function cpuLoad(msg) {
|
|
|
5203
5264
|
}
|
|
5204
5265
|
cpuSession = await ort.InferenceSession.create(msg.modelUrl, sessionOptions);
|
|
5205
5266
|
} else {
|
|
5206
|
-
var graphResponse = await
|
|
5267
|
+
var graphResponse = await fetchWithTimeout(msg.modelUrl, 120000);
|
|
5207
5268
|
if (!graphResponse.ok) throw new Error('Failed to fetch model graph: ' + graphResponse.status);
|
|
5208
5269
|
var graphBuffer = await graphResponse.arrayBuffer();
|
|
5209
5270
|
if (msg.externalDataUrl && dataFilename) {
|
|
5210
|
-
var dataResponse = await
|
|
5271
|
+
var dataResponse = await fetchWithTimeout(msg.externalDataUrl, 120000);
|
|
5211
5272
|
if (!dataResponse.ok) throw new Error('Failed to fetch external data: ' + dataResponse.status);
|
|
5212
5273
|
var dataBuffer = await dataResponse.arrayBuffer();
|
|
5213
5274
|
sessionOptions.externalData = [{ path: dataFilename, data: new Uint8Array(dataBuffer) }];
|
|
@@ -5259,7 +5320,7 @@ async function vadLoad(msg) {
|
|
|
5259
5320
|
vadChunkSize = vadSampleRate === 16000 ? 512 : 256;
|
|
5260
5321
|
vadContextSize = vadSampleRate === 16000 ? 64 : 32;
|
|
5261
5322
|
|
|
5262
|
-
var response = await
|
|
5323
|
+
var response = await fetchWithTimeout(msg.modelUrl, 60000);
|
|
5263
5324
|
if (!response.ok) throw new Error('Failed to fetch VAD model: ' + response.status);
|
|
5264
5325
|
var modelBuffer = await response.arrayBuffer();
|
|
5265
5326
|
vadSession = await ort.InferenceSession.create(new Uint8Array(modelBuffer), {
|
|
@@ -6107,7 +6168,11 @@ var _Wav2ArkitCpuInference = class _Wav2ArkitCpuInference {
|
|
|
6107
6168
|
// URL string — ORT fetches directly into WASM
|
|
6108
6169
|
}];
|
|
6109
6170
|
}
|
|
6110
|
-
this.session = await
|
|
6171
|
+
this.session = await withTimeout(
|
|
6172
|
+
this.ort.InferenceSession.create(modelUrl, sessionOptions),
|
|
6173
|
+
18e4,
|
|
6174
|
+
"Wav2ArkitCpu InferenceSession.create (iOS URL pass-through)"
|
|
6175
|
+
);
|
|
6111
6176
|
} else {
|
|
6112
6177
|
const cache = getModelCache();
|
|
6113
6178
|
const isCached = await cache.has(modelUrl);
|
|
@@ -6375,6 +6440,12 @@ var WORKER_SCRIPT3 = `
|
|
|
6375
6440
|
var ort = null;
|
|
6376
6441
|
var session = null;
|
|
6377
6442
|
|
|
6443
|
+
function fetchWithTimeout(url, timeoutMs) {
|
|
6444
|
+
var controller = new AbortController();
|
|
6445
|
+
var timer = setTimeout(function() { controller.abort(); }, timeoutMs);
|
|
6446
|
+
return fetch(url, { signal: controller.signal }).finally(function() { clearTimeout(timer); });
|
|
6447
|
+
}
|
|
6448
|
+
|
|
6378
6449
|
// Precomputed symmetric index pairs from LAM_BLENDSHAPES alphabetical ordering
|
|
6379
6450
|
// Used to average left/right blendshape pairs for symmetrized output
|
|
6380
6451
|
const SYMMETRIC_INDEX_PAIRS = [
|
|
@@ -6424,7 +6495,7 @@ async function loadOrt(wasmPaths) {
|
|
|
6424
6495
|
const ortUrl = wasmPaths + 'ort.wasm.min.js';
|
|
6425
6496
|
|
|
6426
6497
|
// Load the script by fetching and executing it
|
|
6427
|
-
const response = await
|
|
6498
|
+
const response = await fetchWithTimeout(ortUrl, 30000);
|
|
6428
6499
|
const scriptText = await response.text();
|
|
6429
6500
|
|
|
6430
6501
|
// Create a blob URL for the script
|
|
@@ -6466,7 +6537,7 @@ async function loadModel(modelUrl, externalDataUrl, isIOS) {
|
|
|
6466
6537
|
session = await ort.InferenceSession.create(modelUrl, sessionOptions);
|
|
6467
6538
|
} else {
|
|
6468
6539
|
// Desktop: fetch model graph as ArrayBuffer
|
|
6469
|
-
const graphResponse = await
|
|
6540
|
+
const graphResponse = await fetchWithTimeout(modelUrl, 120000);
|
|
6470
6541
|
if (!graphResponse.ok) {
|
|
6471
6542
|
throw new Error('Failed to fetch model graph: ' + graphResponse.status + ' ' + graphResponse.statusText);
|
|
6472
6543
|
}
|
|
@@ -6474,7 +6545,7 @@ async function loadModel(modelUrl, externalDataUrl, isIOS) {
|
|
|
6474
6545
|
|
|
6475
6546
|
// Fetch external data file if present
|
|
6476
6547
|
if (externalDataUrl && dataFilename) {
|
|
6477
|
-
const dataResponse = await
|
|
6548
|
+
const dataResponse = await fetchWithTimeout(externalDataUrl, 120000);
|
|
6478
6549
|
if (!dataResponse.ok) {
|
|
6479
6550
|
throw new Error('Failed to fetch external data: ' + dataResponse.status + ' ' + dataResponse.statusText);
|
|
6480
6551
|
}
|
|
@@ -7609,6 +7680,13 @@ var WORKER_SCRIPT4 = `
|
|
|
7609
7680
|
|
|
7610
7681
|
var ort = null;
|
|
7611
7682
|
var session = null;
|
|
7683
|
+
|
|
7684
|
+
function fetchWithTimeout(url, timeoutMs) {
|
|
7685
|
+
var controller = new AbortController();
|
|
7686
|
+
var timer = setTimeout(function() { controller.abort(); }, timeoutMs);
|
|
7687
|
+
return fetch(url, { signal: controller.signal }).finally(function() { clearTimeout(timer); });
|
|
7688
|
+
}
|
|
7689
|
+
|
|
7612
7690
|
var sampleRate = 16000;
|
|
7613
7691
|
var chunkSize = 512;
|
|
7614
7692
|
var contextSize = 64;
|
|
@@ -7624,7 +7702,7 @@ async function loadOrt(wasmPaths) {
|
|
|
7624
7702
|
const ortUrl = wasmPaths + 'ort.wasm.min.js';
|
|
7625
7703
|
|
|
7626
7704
|
// Load the script by fetching and executing it
|
|
7627
|
-
const response = await
|
|
7705
|
+
const response = await fetchWithTimeout(ortUrl, 30000);
|
|
7628
7706
|
const scriptText = await response.text();
|
|
7629
7707
|
|
|
7630
7708
|
// Create a blob URL for the script
|
|
@@ -7654,7 +7732,7 @@ async function loadModel(modelUrl, sr) {
|
|
|
7654
7732
|
contextSize = sr === 16000 ? 64 : 32;
|
|
7655
7733
|
|
|
7656
7734
|
// Fetch model data
|
|
7657
|
-
const response = await
|
|
7735
|
+
const response = await fetchWithTimeout(modelUrl, 60000);
|
|
7658
7736
|
if (!response.ok) {
|
|
7659
7737
|
throw new Error('Failed to fetch model: ' + response.status + ' ' + response.statusText);
|
|
7660
7738
|
}
|