@huggingface/transformers 3.3.3 → 3.4.1

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.
Files changed (95) hide show
  1. package/README.md +13 -3
  2. package/dist/ort-wasm-simd-threaded.jsep.mjs +124 -115
  3. package/dist/ort-wasm-simd-threaded.jsep.wasm +0 -0
  4. package/dist/transformers.js +2778 -1592
  5. package/dist/transformers.js.map +1 -1
  6. package/dist/transformers.min.js +1 -1
  7. package/dist/transformers.min.js.map +1 -1
  8. package/dist/{transformers.cjs → transformers.node.cjs} +1699 -2530
  9. package/dist/transformers.node.cjs.map +1 -0
  10. package/dist/transformers.node.min.cjs +2 -0
  11. package/dist/transformers.node.min.cjs.map +1 -0
  12. package/dist/transformers.node.min.mjs +2 -0
  13. package/dist/transformers.node.min.mjs.map +1 -0
  14. package/dist/{transformers.mjs → transformers.node.mjs} +1738 -2510
  15. package/dist/transformers.node.mjs.map +1 -0
  16. package/dist/transformers.web.js +35876 -0
  17. package/dist/transformers.web.js.map +1 -0
  18. package/dist/transformers.web.min.js +2 -0
  19. package/dist/transformers.web.min.js.map +1 -0
  20. package/package.json +6 -6
  21. package/src/backends/onnx.js +14 -15
  22. package/src/configs.js +6 -1
  23. package/src/env.js +1 -1
  24. package/src/generation/streamers.js +4 -3
  25. package/src/models/dac/feature_extraction_dac.js +3 -0
  26. package/src/models/encodec/feature_extraction_encodec.js +32 -0
  27. package/src/models/feature_extractors.js +3 -0
  28. package/src/models/idefics3/image_processing_idefics3.js +1 -1
  29. package/src/models/image_processors.js +1 -0
  30. package/src/models/processors.js +2 -0
  31. package/src/models/smolvlm/image_processing_smolvlm.js +2 -0
  32. package/src/models/smolvlm/processing_smolvlm.js +2 -0
  33. package/src/models/snac/feature_extraction_snac.js +3 -0
  34. package/src/models/ultravox/processing_ultravox.js +54 -0
  35. package/src/models/whisper/common_whisper.js +7 -1
  36. package/src/models/whisper/feature_extraction_whisper.js +18 -10
  37. package/src/models.js +546 -78
  38. package/src/pipelines.js +246 -137
  39. package/src/tokenizers.js +42 -28
  40. package/src/transformers.js +1 -0
  41. package/src/utils/audio.js +2 -0
  42. package/src/utils/hub.js +140 -80
  43. package/src/utils/image.js +9 -1
  44. package/src/utils/maths.js +1 -1
  45. package/src/utils/tensor.js +12 -5
  46. package/src/utils/video.js +128 -0
  47. package/types/backends/onnx.d.ts +2 -2
  48. package/types/backends/onnx.d.ts.map +1 -1
  49. package/types/configs.d.ts +1 -1
  50. package/types/configs.d.ts.map +1 -1
  51. package/types/generation/streamers.d.ts.map +1 -1
  52. package/types/models/dac/feature_extraction_dac.d.ts +4 -0
  53. package/types/models/dac/feature_extraction_dac.d.ts.map +1 -0
  54. package/types/models/encodec/feature_extraction_encodec.d.ts +13 -0
  55. package/types/models/encodec/feature_extraction_encodec.d.ts.map +1 -0
  56. package/types/models/feature_extractors.d.ts +3 -0
  57. package/types/models/florence2/processing_florence2.d.ts +1 -1
  58. package/types/models/florence2/processing_florence2.d.ts.map +1 -1
  59. package/types/models/image_processors.d.ts +1 -0
  60. package/types/models/processors.d.ts +2 -0
  61. package/types/models/smolvlm/image_processing_smolvlm.d.ts +2 -0
  62. package/types/models/smolvlm/image_processing_smolvlm.d.ts.map +1 -0
  63. package/types/models/smolvlm/processing_smolvlm.d.ts +2 -0
  64. package/types/models/smolvlm/processing_smolvlm.d.ts.map +1 -0
  65. package/types/models/snac/feature_extraction_snac.d.ts +4 -0
  66. package/types/models/snac/feature_extraction_snac.d.ts.map +1 -0
  67. package/types/models/ultravox/processing_ultravox.d.ts +16 -0
  68. package/types/models/ultravox/processing_ultravox.d.ts.map +1 -0
  69. package/types/models/whisper/common_whisper.d.ts.map +1 -1
  70. package/types/models/whisper/feature_extraction_whisper.d.ts +3 -1
  71. package/types/models/whisper/feature_extraction_whisper.d.ts.map +1 -1
  72. package/types/models.d.ts +180 -4
  73. package/types/models.d.ts.map +1 -1
  74. package/types/pipelines.d.ts +51 -5
  75. package/types/pipelines.d.ts.map +1 -1
  76. package/types/tokenizers.d.ts.map +1 -1
  77. package/types/transformers.d.ts +1 -0
  78. package/types/tsconfig.tsbuildinfo +1 -1
  79. package/types/utils/audio.d.ts.map +1 -1
  80. package/types/utils/hub.d.ts +19 -7
  81. package/types/utils/hub.d.ts.map +1 -1
  82. package/types/utils/image.d.ts +2 -2
  83. package/types/utils/image.d.ts.map +1 -1
  84. package/types/utils/maths.d.ts +2 -2
  85. package/types/utils/maths.d.ts.map +1 -1
  86. package/types/utils/tensor.d.ts +17 -18
  87. package/types/utils/tensor.d.ts.map +1 -1
  88. package/types/utils/video.d.ts +37 -0
  89. package/types/utils/video.d.ts.map +1 -0
  90. package/dist/transformers.cjs.map +0 -1
  91. package/dist/transformers.min.cjs +0 -2
  92. package/dist/transformers.min.cjs.map +0 -1
  93. package/dist/transformers.min.mjs +0 -2
  94. package/dist/transformers.min.mjs.map +0 -1
  95. package/dist/transformers.mjs.map +0 -1
package/src/tokenizers.js CHANGED
@@ -995,6 +995,8 @@ class Normalizer extends Callable {
995
995
  return new Replace(config);
996
996
  case 'NFC':
997
997
  return new NFC(config);
998
+ case 'NFD':
999
+ return new NFD(config);
998
1000
  case 'NFKC':
999
1001
  return new NFKC(config);
1000
1002
  case 'NFKD':
@@ -1053,50 +1055,62 @@ class Replace extends Normalizer {
1053
1055
  }
1054
1056
 
1055
1057
  /**
1056
- * A normalizer that applies Unicode normalization form C (NFC) to the input text.
1058
+ * A normalizer that applies Unicode normalization to the input text.
1057
1059
  * @extends Normalizer
1060
+ * @abstract
1058
1061
  */
1059
- class NFC extends Normalizer {
1062
+ class UnicodeNormalizer extends Normalizer {
1063
+ /**
1064
+ * @type {string} The Unicode normalization form to apply.
1065
+ * Should be one of: 'NFC', 'NFD', 'NFKC', or 'NFKD'.
1066
+ */
1067
+ form = undefined;
1068
+
1060
1069
  /**
1061
- * Normalize the input text by applying Unicode normalization form C (NFC).
1070
+ * Normalize the input text by applying Unicode normalization.
1062
1071
  * @param {string} text The input text to be normalized.
1063
1072
  * @returns {string} The normalized text.
1064
1073
  */
1065
1074
  normalize(text) {
1066
- text = text.normalize('NFC')
1075
+ text = text.normalize(this.form)
1067
1076
  return text;
1068
1077
  }
1069
1078
  }
1070
1079
 
1071
1080
  /**
1072
- * NFKC Normalizer.
1073
- * @extends Normalizer
1081
+ * A normalizer that applies Unicode normalization form C (NFC) to the input text.
1082
+ * Canonical Decomposition, followed by Canonical Composition.
1083
+ * @extends UnicodeNormalizer
1074
1084
  */
1075
- class NFKC extends Normalizer {
1076
- /**
1077
- * Normalize text using NFKC normalization.
1078
- * @param {string} text The text to be normalized.
1079
- * @returns {string} The normalized text.
1080
- */
1081
- normalize(text) {
1082
- text = text.normalize('NFKC')
1083
- return text;
1084
- }
1085
+ class NFC extends UnicodeNormalizer {
1086
+ form = 'NFC';
1085
1087
  }
1088
+
1086
1089
  /**
1087
- * NFKD Normalizer.
1088
- * @extends Normalizer
1090
+ * A normalizer that applies Unicode normalization form D (NFD) to the input text.
1091
+ * Canonical Decomposition.
1092
+ * @extends UnicodeNormalizer
1089
1093
  */
1090
- class NFKD extends Normalizer {
1091
- /**
1092
- * Normalize text using NFKD normalization.
1093
- * @param {string} text The text to be normalized.
1094
- * @returns {string} The normalized text.
1095
- */
1096
- normalize(text) {
1097
- text = text.normalize('NFKD')
1098
- return text;
1099
- }
1094
+ class NFD extends UnicodeNormalizer {
1095
+ form = 'NFD';
1096
+ }
1097
+
1098
+ /**
1099
+ * A normalizer that applies Unicode normalization form KC (NFKC) to the input text.
1100
+ * Compatibility Decomposition, followed by Canonical Composition.
1101
+ * @extends UnicodeNormalizer
1102
+ */
1103
+ class NFKC extends UnicodeNormalizer {
1104
+ form = 'NFKC';
1105
+ }
1106
+
1107
+ /**
1108
+ * A normalizer that applies Unicode normalization form KD (NFKD) to the input text.
1109
+ * Compatibility Decomposition.
1110
+ * @extends UnicodeNormalizer
1111
+ */
1112
+ class NFKD extends UnicodeNormalizer {
1113
+ form = 'NFKD';
1100
1114
  }
1101
1115
 
1102
1116
  /**
@@ -20,6 +20,7 @@ export * from './configs.js';
20
20
 
21
21
  export * from './utils/audio.js';
22
22
  export * from './utils/image.js';
23
+ export * from './utils/video.js';
23
24
  export * from './utils/tensor.js';
24
25
  export * from './utils/maths.js';
25
26
 
@@ -150,6 +150,7 @@ function hertz_to_mel(freq, mel_scale = "htk") {
150
150
  throw new Error('mel_scale should be one of "htk", "slaney" or "kaldi".');
151
151
  }
152
152
 
153
+ // @ts-expect-error ts(2322)
153
154
  return typeof freq === 'number' ? fn(freq) : freq.map(x => fn(x));
154
155
  }
155
156
 
@@ -173,6 +174,7 @@ function mel_to_hertz(mels, mel_scale = "htk") {
173
174
  throw new Error('mel_scale should be one of "htk", "slaney" or "kaldi".');
174
175
  }
175
176
 
177
+ // @ts-expect-error ts(2322)
176
178
  return typeof mels === 'number' ? fn(mels) : mels.map(x => fn(x));
177
179
  }
178
180
 
package/src/utils/hub.js CHANGED
@@ -8,9 +8,16 @@
8
8
  import fs from 'fs';
9
9
  import path from 'path';
10
10
 
11
- import { env } from '../env.js';
11
+ import { apis, env } from '../env.js';
12
12
  import { dispatchCallback } from './core.js';
13
13
 
14
+ /**
15
+ * @typedef {boolean|number} ExternalData Whether to load the model using the external data format (used for models >= 2GB in size).
16
+ * If `true`, the model will be loaded using the external data format.
17
+ * If a number, this many chunks will be loaded using the external data format (of the form: "model.onnx_data[_{chunk_number}]").
18
+ */
19
+ export const MAX_EXTERNAL_DATA_CHUNKS = 100;
20
+
14
21
  /**
15
22
  * @typedef {Object} PretrainedOptions Options for loading a pretrained model.
16
23
  * @property {import('./core.js').ProgressCallback} [progress_callback=null] If specified, this function will be called during model construction, to provide the user with progress updates.
@@ -31,7 +38,7 @@ import { dispatchCallback } from './core.js';
31
38
  * @property {string} [model_file_name=null] If specified, load the model with this name (excluding the .onnx suffix). Currently only valid for encoder- or decoder-only models.
32
39
  * @property {import("./devices.js").DeviceType|Record<string, import("./devices.js").DeviceType>} [device=null] The device to run the model on. If not specified, the device will be chosen from the environment settings.
33
40
  * @property {import("./dtypes.js").DataType|Record<string, import("./dtypes.js").DataType>} [dtype=null] The data type to use for the model. If not specified, the data type will be chosen from the environment settings.
34
- * @property {boolean|Record<string, boolean>} [use_external_data_format=false] Whether to load the model using the external data format (used for models >= 2GB in size).
41
+ * @property {ExternalData|Record<string, ExternalData>} [use_external_data_format=false] Whether to load the model using the external data format (used for models >= 2GB in size).
35
42
  * @property {import('onnxruntime-common').InferenceSession.SessionOptions} [session_options] (Optional) User-specified session options passed to the runtime. If not provided, suitable defaults will be chosen.
36
43
  */
37
44
 
@@ -57,7 +64,7 @@ class FileResponse {
57
64
 
58
65
  /**
59
66
  * Creates a new `FileResponse` object.
60
- * @param {string|URL} filePath
67
+ * @param {string} filePath
61
68
  */
62
69
  constructor(filePath) {
63
70
  this.filePath = filePath;
@@ -73,13 +80,15 @@ class FileResponse {
73
80
 
74
81
  this.updateContentType();
75
82
 
76
- let self = this;
83
+ const stream = fs.createReadStream(filePath);
77
84
  this.body = new ReadableStream({
78
85
  start(controller) {
79
- self.arrayBuffer().then(buffer => {
80
- controller.enqueue(new Uint8Array(buffer));
81
- controller.close();
82
- })
86
+ stream.on('data', (chunk) => controller.enqueue(chunk));
87
+ stream.on('end', () => controller.close());
88
+ stream.on('error', (err) => controller.error(err));
89
+ },
90
+ cancel() {
91
+ stream.destroy();
83
92
  }
84
93
  });
85
94
  } else {
@@ -190,7 +199,7 @@ function isValidUrl(string, protocols = null, validHosts = null) {
190
199
  export async function getFile(urlOrPath) {
191
200
 
192
201
  if (env.useFS && !isValidUrl(urlOrPath, ['http:', 'https:', 'blob:'])) {
193
- return new FileResponse(urlOrPath);
202
+ return new FileResponse(urlOrPath.toString());
194
203
 
195
204
  } else if (typeof process !== 'undefined' && process?.release?.name === 'node') {
196
205
  const IS_CI = !!process.env?.TESTING_REMOTELY;
@@ -281,20 +290,52 @@ class FileCache {
281
290
  /**
282
291
  * Adds the given response to the cache.
283
292
  * @param {string} request
284
- * @param {Response|FileResponse} response
293
+ * @param {Response} response
294
+ * @param {(data: {progress: number, loaded: number, total: number}) => void} [progress_callback] Optional.
295
+ * The function to call with progress updates
285
296
  * @returns {Promise<void>}
286
297
  */
287
- async put(request, response) {
288
- const buffer = Buffer.from(await response.arrayBuffer());
289
-
290
- let outputPath = path.join(this.path, request);
298
+ async put(request, response, progress_callback = undefined) {
299
+ let filePath = path.join(this.path, request);
291
300
 
292
301
  try {
293
- await fs.promises.mkdir(path.dirname(outputPath), { recursive: true });
294
- await fs.promises.writeFile(outputPath, buffer);
302
+ const contentLength = response.headers.get('Content-Length');
303
+ const total = parseInt(contentLength ?? '0');
304
+ let loaded = 0;
305
+
306
+ await fs.promises.mkdir(path.dirname(filePath), { recursive: true });
307
+ const fileStream = fs.createWriteStream(filePath);
308
+ const reader = response.body.getReader();
309
+
310
+ while (true) {
311
+ const { done, value } = await reader.read();
312
+ if (done) {
313
+ break;
314
+ }
315
+
316
+ await new Promise((resolve, reject) => {
317
+ fileStream.write(value, (err) => {
318
+ if (err) {
319
+ reject(err);
320
+ return;
321
+ }
322
+ resolve();
323
+ });
324
+ });
325
+
326
+ loaded += value.length;
327
+ const progress = total ? (loaded / total) * 100 : 0;
328
+
329
+ progress_callback?.({ progress, loaded, total });
330
+ }
295
331
 
296
- } catch (err) {
297
- console.warn('An error occurred while writing the file to cache:', err)
332
+ fileStream.close();
333
+ } catch (error) {
334
+ // Clean up the file if an error occurred during download
335
+ try {
336
+ await fs.promises.unlink(filePath);
337
+ } catch { }
338
+ throw error;
298
339
  }
299
340
  }
300
341
 
@@ -325,21 +366,21 @@ async function tryCache(cache, ...names) {
325
366
  }
326
367
 
327
368
  /**
328
- *
329
369
  * Retrieves a file from either a remote URL using the Fetch API or from the local file system using the FileSystem API.
330
370
  * If the filesystem is available and `env.useCache = true`, the file will be downloaded and cached.
331
- *
371
+ *
332
372
  * @param {string} path_or_repo_id This can be either:
333
373
  * - a string, the *model id* of a model repo on huggingface.co.
334
374
  * - a path to a *directory* potentially containing the file.
335
375
  * @param {string} filename The name of the file to locate in `path_or_repo`.
336
376
  * @param {boolean} [fatal=true] Whether to throw an error if the file is not found.
337
377
  * @param {PretrainedOptions} [options] An object containing optional parameters.
338
- *
378
+ * @param {boolean} [return_path=false] Whether to return the path of the file instead of the file content.
379
+ *
339
380
  * @throws Will throw an error if the file is not found and `fatal` is true.
340
- * @returns {Promise<Uint8Array>} A Promise that resolves with the file content as a buffer.
381
+ * @returns {Promise<string|Uint8Array>} A Promise that resolves with the file content as a Uint8Array if `return_path` is false, or the file path as a string if `return_path` is true.
341
382
  */
342
- export async function getModelFile(path_or_repo_id, filename, fatal = true, options = {}) {
383
+ export async function getModelFile(path_or_repo_id, filename, fatal = true, options = {}, return_path = false) {
343
384
 
344
385
  if (!env.allowLocalModels) {
345
386
  // User has disabled local models, so we just make sure other settings are correct.
@@ -403,8 +444,9 @@ export async function getModelFile(path_or_repo_id, filename, fatal = true, opti
403
444
  const revision = options.revision ?? 'main';
404
445
 
405
446
  let requestURL = pathJoin(path_or_repo_id, filename);
406
- let localPath = pathJoin(env.localModelPath, requestURL);
447
+ let cachePath = pathJoin(env.localModelPath, requestURL);
407
448
 
449
+ let localPath = requestURL;
408
450
  let remoteURL = pathJoin(
409
451
  env.remoteHost,
410
452
  env.remotePathTemplate
@@ -433,7 +475,7 @@ export async function getModelFile(path_or_repo_id, filename, fatal = true, opti
433
475
  // 1. We first try to get from cache using the local path. In some environments (like deno),
434
476
  // non-URL cache keys are not allowed. In these cases, `response` will be undefined.
435
477
  // 2. If no response is found, we try to get from cache using the remote URL or file system cache.
436
- response = await tryCache(cache, localPath, proposedCacheKey);
478
+ response = await tryCache(cache, cachePath, proposedCacheKey);
437
479
  }
438
480
 
439
481
  const cacheHit = response !== undefined;
@@ -455,9 +497,9 @@ export async function getModelFile(path_or_repo_id, filename, fatal = true, opti
455
497
  console.warn(`Unable to load from local path "${localPath}": "${e}"`);
456
498
  }
457
499
  } else if (options.local_files_only) {
458
- throw new Error(`\`local_files_only=true\`, but attempted to load a remote file from: ${requestURL}.`);
500
+ throw new Error(`\`local_files_only=true\`, but attempted to load a remote file from: ${localPath}.`);
459
501
  } else if (!env.allowRemoteModels) {
460
- throw new Error(`\`env.allowRemoteModels=false\`, but attempted to load a remote file from: ${requestURL}.`);
502
+ throw new Error(`\`env.allowRemoteModels=false\`, but attempted to load a remote file from: ${localPath}.`);
461
503
  }
462
504
  }
463
505
 
@@ -504,41 +546,45 @@ export async function getModelFile(path_or_repo_id, filename, fatal = true, opti
504
546
  file: filename
505
547
  })
506
548
 
507
- /** @type {Uint8Array} */
508
- let buffer;
509
-
510
- if (!options.progress_callback) {
511
- // If no progress callback is specified, we can use the `.arrayBuffer()`
512
- // method to read the response.
513
- buffer = new Uint8Array(await response.arrayBuffer());
514
-
515
- } else if (
516
- cacheHit // The item is being read from the cache
517
- &&
518
- typeof navigator !== 'undefined' && /firefox/i.test(navigator.userAgent) // We are in Firefox
519
- ) {
520
- // Due to bug in Firefox, we cannot display progress when loading from cache.
521
- // Fortunately, since this should be instantaneous, this should not impact users too much.
522
- buffer = new Uint8Array(await response.arrayBuffer());
523
-
524
- // For completeness, we still fire the final progress callback
525
- dispatchCallback(options.progress_callback, {
526
- status: 'progress',
527
- name: path_or_repo_id,
528
- file: filename,
529
- progress: 100,
530
- loaded: buffer.length,
531
- total: buffer.length,
532
- })
533
- } else {
534
- buffer = await readResponse(response, data => {
549
+ let result;
550
+ if (!(apis.IS_NODE_ENV && return_path)) {
551
+ /** @type {Uint8Array} */
552
+ let buffer;
553
+
554
+ if (!options.progress_callback) {
555
+ // If no progress callback is specified, we can use the `.arrayBuffer()`
556
+ // method to read the response.
557
+ buffer = new Uint8Array(await response.arrayBuffer());
558
+
559
+ } else if (
560
+ cacheHit // The item is being read from the cache
561
+ &&
562
+ typeof navigator !== 'undefined' && /firefox/i.test(navigator.userAgent) // We are in Firefox
563
+ ) {
564
+ // Due to bug in Firefox, we cannot display progress when loading from cache.
565
+ // Fortunately, since this should be instantaneous, this should not impact users too much.
566
+ buffer = new Uint8Array(await response.arrayBuffer());
567
+
568
+ // For completeness, we still fire the final progress callback
535
569
  dispatchCallback(options.progress_callback, {
536
570
  status: 'progress',
537
571
  name: path_or_repo_id,
538
572
  file: filename,
539
- ...data,
573
+ progress: 100,
574
+ loaded: buffer.length,
575
+ total: buffer.length,
540
576
  })
541
- })
577
+ } else {
578
+ buffer = await readResponse(response, data => {
579
+ dispatchCallback(options.progress_callback, {
580
+ status: 'progress',
581
+ name: path_or_repo_id,
582
+ file: filename,
583
+ ...data,
584
+ })
585
+ })
586
+ }
587
+ result = buffer;
542
588
  }
543
589
 
544
590
  if (
@@ -549,25 +595,43 @@ export async function getModelFile(path_or_repo_id, filename, fatal = true, opti
549
595
  // Check again whether request is in cache. If not, we add the response to the cache
550
596
  (await cache.match(cacheKey) === undefined)
551
597
  ) {
552
- // NOTE: We use `new Response(buffer, ...)` instead of `response.clone()` to handle LFS files
553
- await cache.put(cacheKey, new Response(buffer, {
554
- headers: response.headers
555
- }))
556
- .catch(err => {
557
- // Do not crash if unable to add to cache (e.g., QuotaExceededError).
558
- // Rather, log a warning and proceed with execution.
559
- console.warn(`Unable to add response to browser cache: ${err}.`);
560
- });
561
-
598
+ if (!result) {
599
+ // We haven't yet read the response body, so we need to do so now.
600
+ await cache.put(cacheKey, /** @type {Response} */(response), options.progress_callback);
601
+ } else {
602
+ // NOTE: We use `new Response(buffer, ...)` instead of `response.clone()` to handle LFS files
603
+ await cache.put(cacheKey, new Response(result, {
604
+ headers: response.headers
605
+ }))
606
+ .catch(err => {
607
+ // Do not crash if unable to add to cache (e.g., QuotaExceededError).
608
+ // Rather, log a warning and proceed with execution.
609
+ console.warn(`Unable to add response to browser cache: ${err}.`);
610
+ });
611
+ }
562
612
  }
563
-
564
613
  dispatchCallback(options.progress_callback, {
565
614
  status: 'done',
566
615
  name: path_or_repo_id,
567
616
  file: filename
568
617
  });
569
618
 
570
- return buffer;
619
+ if (result) {
620
+ if (return_path) {
621
+ throw new Error("Cannot return path in a browser environment.")
622
+ }
623
+ return result;
624
+ }
625
+ if (response instanceof FileResponse) {
626
+ return response.filePath;
627
+ }
628
+
629
+ const path = await cache.match(cacheKey);
630
+ if (path instanceof FileResponse) {
631
+ return path.filePath;
632
+ }
633
+ throw new Error("Unable to return path for response.");
634
+
571
635
  }
572
636
 
573
637
  /**
@@ -581,14 +645,14 @@ export async function getModelFile(path_or_repo_id, filename, fatal = true, opti
581
645
  * @throws Will throw an error if the file is not found and `fatal` is true.
582
646
  */
583
647
  export async function getModelJSON(modelPath, fileName, fatal = true, options = {}) {
584
- let buffer = await getModelFile(modelPath, fileName, fatal, options);
648
+ const buffer = await getModelFile(modelPath, fileName, fatal, options, false);
585
649
  if (buffer === null) {
586
650
  // Return empty object
587
651
  return {}
588
652
  }
589
653
 
590
- let decoder = new TextDecoder('utf-8');
591
- let jsonData = decoder.decode(buffer);
654
+ const decoder = new TextDecoder('utf-8');
655
+ const jsonData = decoder.decode(/** @type {Uint8Array} */(buffer));
592
656
 
593
657
  return JSON.parse(jsonData);
594
658
  }
@@ -614,30 +678,26 @@ async function readResponse(response, progress_callback) {
614
678
  const { done, value } = await reader.read();
615
679
  if (done) return;
616
680
 
617
- let newLoaded = loaded + value.length;
681
+ const newLoaded = loaded + value.length;
618
682
  if (newLoaded > total) {
619
683
  total = newLoaded;
620
684
 
621
685
  // Adding the new data will overflow buffer.
622
686
  // In this case, we extend the buffer
623
- let newBuffer = new Uint8Array(total);
687
+ const newBuffer = new Uint8Array(total);
624
688
 
625
689
  // copy contents
626
690
  newBuffer.set(buffer);
627
691
 
628
692
  buffer = newBuffer;
629
693
  }
630
- buffer.set(value, loaded)
694
+ buffer.set(value, loaded);
631
695
  loaded = newLoaded;
632
696
 
633
697
  const progress = (loaded / total) * 100;
634
698
 
635
699
  // Call your function here
636
- progress_callback({
637
- progress: progress,
638
- loaded: loaded,
639
- total: total,
640
- })
700
+ progress_callback({ progress, loaded, total });
641
701
 
642
702
  return read();
643
703
  }
@@ -100,7 +100,7 @@ export class RawImage {
100
100
 
101
101
  /**
102
102
  * Helper method for reading an image from a variety of input types.
103
- * @param {RawImage|string|URL} input
103
+ * @param {RawImage|string|URL|Blob|HTMLCanvasElement|OffscreenCanvas} input
104
104
  * @returns The image object.
105
105
  *
106
106
  * **Example:** Read image from a URL.
@@ -119,6 +119,14 @@ export class RawImage {
119
119
  return input;
120
120
  } else if (typeof input === 'string' || input instanceof URL) {
121
121
  return await this.fromURL(input);
122
+ } else if (input instanceof Blob) {
123
+ return await this.fromBlob(input);
124
+ } else if (
125
+ (typeof HTMLCanvasElement !== "undefined" && input instanceof HTMLCanvasElement)
126
+ ||
127
+ (typeof OffscreenCanvas !== "undefined" && input instanceof OffscreenCanvas)
128
+ ) {
129
+ return this.fromCanvas(input);
122
130
  } else {
123
131
  throw new Error(`Unsupported input type: ${typeof input}`);
124
132
  }
@@ -9,7 +9,7 @@
9
9
  */
10
10
 
11
11
  /**
12
- * @typedef {Int8Array | Uint8Array | Uint8ClampedArray | Int16Array | Uint16Array | Int32Array | Uint32Array | Float32Array | Float64Array} TypedArray
12
+ * @typedef {Int8Array | Uint8Array | Uint8ClampedArray | Int16Array | Uint16Array | Int32Array | Uint32Array | Float16Array | Float32Array | Float64Array} TypedArray
13
13
  * @typedef {BigInt64Array | BigUint64Array} BigTypedArray
14
14
  * @typedef {TypedArray | BigTypedArray} AnyTypedArray
15
15
  */
@@ -20,9 +20,11 @@ import {
20
20
 
21
21
  import { TensorOpRegistry } from '../ops/registry.js';
22
22
 
23
- const DataTypeMap = Object.freeze({
23
+ export const DataTypeMap = Object.freeze({
24
24
  float32: Float32Array,
25
- float16: Uint16Array,
25
+ // @ts-ignore ts(2552) Limited availability of Float16Array across browsers:
26
+ // https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Float16Array
27
+ float16: typeof Float16Array !== "undefined" ? Float16Array: Uint16Array,
26
28
  float64: Float64Array,
27
29
  string: Array, // string[]
28
30
  int8: Int8Array,
@@ -89,8 +91,9 @@ export class Tensor {
89
91
  // Create new tensor
90
92
  this.ort_tensor = new ONNXTensor(
91
93
  /** @type {DataType} */(args[0]),
94
+ // @ts-expect-error ts(2769) Type 'number' is not assignable to type 'bigint'.
92
95
  /** @type {Exclude<import('./maths.js').AnyTypedArray, Uint8ClampedArray>} */(args[1]),
93
- args[2]
96
+ args[2],
94
97
  );
95
98
  }
96
99
 
@@ -1179,8 +1182,12 @@ function calc_unsqueeze_dims(dims, dim) {
1179
1182
  * @private
1180
1183
  */
1181
1184
  function safeIndex(index, size, dimension = null, boundsCheck = true) {
1182
- if (boundsCheck && (index < -size || index >= size)) {
1183
- throw new Error(`IndexError: index ${index} is out of bounds for dimension${dimension === null ? '' : ' ' + dimension} with size ${size}`);
1185
+ if (index < -size || index >= size) {
1186
+ if (boundsCheck) {
1187
+ throw new Error(`IndexError: index ${index} is out of bounds for dimension${dimension === null ? '' : ' ' + dimension} with size ${size}`);
1188
+ } else {
1189
+ return index < -size ? 0 : size;
1190
+ }
1184
1191
  }
1185
1192
 
1186
1193
  if (index < 0) {