@fugood/node-whisper-wasm 1.0.19 → 1.0.20

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 CHANGED
@@ -1,13 +1,17 @@
1
1
  # @fugood/node-whisper-wasm
2
2
 
3
- Browser WASM package for `@fugood/whisper.node`.
3
+ Browser WASM implementation package for `@fugood/whisper.node`. Application
4
+ code should import `@fugood/whisper.node`; this package is pulled in by the main
5
+ package for browser builds.
4
6
 
5
7
  The package exposes the same high-level context API as the native packages, but
6
8
  model and audio file paths are fetched as URLs and copied into the Emscripten
7
9
  filesystem before inference.
8
10
 
9
11
  ```js
10
- const whisper = await WhisperNodeWasm.initWhisper({
12
+ import { initWhisper } from '@fugood/whisper.node'
13
+
14
+ const whisper = await initWhisper({
11
15
  filePath: 'https://huggingface.co/ggerganov/whisper.cpp/resolve/main/ggml-base.en.bin',
12
16
  useGpu: false,
13
17
  })
@@ -23,18 +27,29 @@ await whisper.release()
23
27
  The WASM build uses pthreads, so browsers must serve the page with COOP/COEP
24
28
  headers and expose `SharedArrayBuffer`. Whisper transcription defaults to up to
25
29
  8 threads based on browser hardware concurrency; pass `maxThreads` to override
26
- it. Browser pages run model loading, transcription, benchmarks, and VAD in a
27
- dedicated worker by default so the UI thread can keep rendering. Use
28
- `configureWasm({ worker: false })` only when you explicitly need the old
29
- in-thread runtime, or pass `workerUrl`, `indexScriptUrl`, and `runtimeScriptUrl`
30
- when serving the package files from custom URLs. Set `useGpu: true` only with a
31
- package built using `GGML_WEBGPU=ON` and a browser that exposes `navigator.gpu`.
32
- VAD currently falls back to CPU in the browser package because the Silero VAD
33
- graph hits unsupported WebGPU ops.
34
-
35
- The default build emits `whisper-node.js` and `whisper-node.wasm`. Use
36
- `bash scripts/build-wasm.sh --single-file` only when you want the WASM binary
37
- embedded into `whisper-node.js`. Modern Emscripten embeds the pthread worker
38
- bootstrap in the main JS file, so a separate `whisper-node.worker.js` is not
39
- expected. The package worker that keeps UI work off the main thread is
40
- `worker.js`.
30
+ it. Browser WASM clamps `maxThreads` to the compiled pool limit of 8. Browser
31
+ pages run model loading, transcription, benchmarks, and VAD in a dedicated
32
+ module worker by default so the UI thread can keep rendering. Use the main
33
+ `whisper.node` package entrypoint in browser code:
34
+
35
+ ```js
36
+ import { configureWasm, initWhisper } from '@fugood/whisper.node'
37
+ ```
38
+
39
+ Use `configureWasm({ worker: false })` only when you explicitly need the
40
+ in-thread runtime, or pass `workerPath`, `jsPath`, and `wasmPath` when serving
41
+ the package files from custom URLs. The older `workerUrl` and
42
+ `runtimeScriptUrl` option names still work. Model downloads are cached in
43
+ browser Cache Storage by default. Pass `cacheModel: false` to disable persistent
44
+ caching, `modelCacheName` to isolate the cache namespace, or `modelCacheKey`
45
+ when the fetch URL is a proxy or signed URL but should reuse the same cached
46
+ model. Set `useGpu: true` only with a package built using `GGML_WEBGPU=ON` and a
47
+ browser that exposes `navigator.gpu`. VAD currently falls back to CPU in the
48
+ browser package because the Silero VAD graph hits unsupported WebGPU ops.
49
+
50
+ The default build emits `wasm/whisper-node.js` and `wasm/whisper-node.wasm`.
51
+ Use `bash scripts/build-wasm.sh --single-file` only when you want the WASM
52
+ binary embedded into `wasm/whisper-node.js`. Modern Emscripten embeds the
53
+ pthread worker bootstrap in the main JS file, so a separate
54
+ `whisper-node.worker.js` is not expected. The package module worker that keeps
55
+ UI work off the main thread is `worker.js`.
package/index.d.ts CHANGED
@@ -4,6 +4,9 @@ export interface NativeContextOptions {
4
4
  useFlashAttn?: boolean
5
5
  useGpu?: boolean
6
6
  maxModelBytes?: number
7
+ cacheModel?: boolean
8
+ modelCacheName?: string
9
+ modelCacheKey?: string
7
10
  worker?: boolean
8
11
  }
9
12
 
@@ -13,6 +16,9 @@ export interface NativeVadContextOptions {
13
16
  useGpu?: boolean
14
17
  nThreads?: number
15
18
  maxModelBytes?: number
19
+ cacheModel?: boolean
20
+ modelCacheName?: string
21
+ modelCacheKey?: string
16
22
  worker?: boolean
17
23
  }
18
24
 
@@ -136,12 +142,18 @@ export interface Module {
136
142
  export interface WasmRuntimeOptions {
137
143
  worker?: boolean
138
144
  workerUrl?: string
145
+ workerPath?: string
139
146
  indexScriptUrl?: string
140
147
  scriptUrl?: string
141
148
  runtimeScriptUrl?: string
149
+ jsPath?: string
150
+ wasmPath?: string
142
151
  locateFileBaseUrl?: string
143
152
  locateFile?: (path: string, prefix: string) => string
144
153
  mainScriptUrlOrBlob?: string | Blob
154
+ modelCacheName?: string
155
+ moduleFactory?: (options?: Record<string, unknown>) => Promise<unknown> | unknown
156
+ moduleOptions?: Record<string, unknown>
145
157
  print?: (text: string) => void
146
158
  printErr?: (text: string) => void
147
159
  }
@@ -149,6 +161,13 @@ export interface WasmRuntimeOptions {
149
161
  export declare const WhisperContext: Module['WhisperContext']
150
162
  export declare const WhisperVadContext: Module['WhisperVadContext']
151
163
  export declare const DEFAULT_WASM_MODEL_SIZE_LIMIT_BYTES: number
164
+ export declare const MAX_WASM_THREADS: number
165
+ export declare const WASM_CONFIG_PATHS: {
166
+ index: string
167
+ js: string
168
+ wasm: string
169
+ worker: string
170
+ }
152
171
 
153
172
  export declare function configureWasm(options: WasmRuntimeOptions): void
154
173
  export declare function loadWasmModule(): Promise<unknown>
@@ -178,6 +197,8 @@ declare const _default: {
178
197
  toggleNativeLog: typeof toggleNativeLog
179
198
  addNativeLogListener: typeof addNativeLogListener
180
199
  DEFAULT_WASM_MODEL_SIZE_LIMIT_BYTES: typeof DEFAULT_WASM_MODEL_SIZE_LIMIT_BYTES
200
+ MAX_WASM_THREADS: typeof MAX_WASM_THREADS
201
+ WASM_CONFIG_PATHS: typeof WASM_CONFIG_PATHS
181
202
  }
182
203
 
183
204
  export default _default
package/index.js CHANGED
@@ -1,33 +1,33 @@
1
- (function (root, factory) {
2
- if (typeof module === 'object' && module.exports) {
3
- module.exports = factory(function () {
4
- return require('./whisper-node.js')
5
- }, root)
6
- } else {
7
- root.WhisperNodeWasm = factory(function () {
8
- return root.createWhisperNodeModule
9
- }, root)
10
- }
11
- })(
1
+ const root =
12
2
  typeof globalThis !== 'undefined'
13
3
  ? globalThis
14
4
  : typeof self !== 'undefined'
15
5
  ? self
16
6
  : typeof window !== 'undefined'
17
7
  ? window
18
- : this,
19
- function (loadModuleFactory, root) {
8
+ : undefined
9
+
10
+ export const WASM_CONFIG_PATHS = {
11
+ index: new URL('./index.js', import.meta.url).href,
12
+ js: new URL('./wasm/whisper-node.js', import.meta.url).href,
13
+ wasm: new URL('./wasm/whisper-node.wasm', import.meta.url).href,
14
+ worker: new URL('./worker.js', import.meta.url).href,
15
+ }
16
+
17
+ const createWhisperNodeApi = function (root) {
20
18
  'use strict'
21
19
 
22
20
  var SAMPLE_RATE = 16000
23
21
  var MIB = 1024 * 1024
24
22
  var FIREFOX_MODEL_LIMIT_BYTES = 256 * MIB
25
23
  var MODEL_MEMORY_RATIO = 0.75
24
+ var MAX_WASM_THREADS = 8
25
+ var DEFAULT_MODEL_CACHE_NAME = 'whisper.node.wasm.models'
26
26
 
27
27
  var runtimePromise = null
28
28
  var runtimeOptions = {}
29
29
  var workerProxyPromise = null
30
- var capturedScriptUrl = getCurrentScriptUrl()
30
+ var capturedScriptUrl = WASM_CONFIG_PATHS.index
31
31
  var modelCache = Object.create(null)
32
32
  var logEnabled = false
33
33
  var logListeners = []
@@ -40,19 +40,8 @@
40
40
  runtimeOptions = Object.assign({}, runtimeOptions, options || {})
41
41
  }
42
42
 
43
- function getCurrentScriptUrl() {
44
- if (
45
- root.document &&
46
- root.document.currentScript &&
47
- root.document.currentScript.src
48
- ) {
49
- return root.document.currentScript.src
50
- }
51
- return null
52
- }
53
-
54
43
  function isBrowserLike() {
55
- return typeof root.window !== 'undefined' || typeof root.importScripts === 'function'
44
+ return typeof root.window !== 'undefined' || typeof root.WorkerGlobalScope !== 'undefined'
56
45
  }
57
46
 
58
47
  function isMainBrowserThread() {
@@ -80,19 +69,27 @@
80
69
  }
81
70
 
82
71
  function getRuntimeScriptUrl(indexScriptUrl) {
83
- var configured = runtimeOptions.runtimeScriptUrl
72
+ var configured = runtimeOptions.jsPath || runtimeOptions.runtimeScriptUrl
84
73
  if (configured) {
85
74
  return resolveUrl(configured, indexScriptUrl)
86
75
  }
87
- return indexScriptUrl ? resolveUrl('whisper-node.js', indexScriptUrl) : null
76
+ return WASM_CONFIG_PATHS.js
77
+ }
78
+
79
+ function getWasmBinaryUrl(runtimeScriptUrl) {
80
+ var configured = runtimeOptions.wasmPath
81
+ if (configured) {
82
+ return resolveUrl(configured, runtimeScriptUrl)
83
+ }
84
+ return WASM_CONFIG_PATHS.wasm
88
85
  }
89
86
 
90
87
  function getWorkerScriptUrl(indexScriptUrl) {
91
- var configured = runtimeOptions.workerUrl
88
+ var configured = runtimeOptions.workerPath || runtimeOptions.workerUrl
92
89
  if (configured) {
93
90
  return resolveUrl(configured, indexScriptUrl)
94
91
  }
95
- return indexScriptUrl ? resolveUrl('worker.js', indexScriptUrl) : null
92
+ return WASM_CONFIG_PATHS.worker
96
93
  }
97
94
 
98
95
  function shouldUseWorker(options) {
@@ -108,11 +105,16 @@
108
105
  var blocked = {
109
106
  worker: true,
110
107
  workerUrl: true,
108
+ workerPath: true,
111
109
  indexScriptUrl: true,
112
110
  scriptUrl: true,
113
111
  runtimeScriptUrl: true,
112
+ jsPath: true,
113
+ wasmPath: true,
114
114
  locateFileBaseUrl: true,
115
115
  locateFile: true,
116
+ moduleFactory: true,
117
+ moduleOptions: true,
116
118
  print: true,
117
119
  printErr: true,
118
120
  mainScriptUrlOrBlob: true,
@@ -151,35 +153,74 @@
151
153
  if (!runtimePromise) {
152
154
  assertThreadSupport()
153
155
 
154
- var moduleFactory = loadModuleFactory()
155
- if (moduleFactory && moduleFactory.default) {
156
- moduleFactory = moduleFactory.default
157
- }
158
- if (typeof moduleFactory !== 'function') {
159
- throw new Error(
160
- 'Failed to load whisper.node WASM runtime. Make sure whisper-node.js is built and loaded before index.js.',
161
- )
162
- }
163
-
164
- var options = Object.assign({}, runtimeOptions)
165
- var userPrint = options.print
166
- var userPrintErr = options.printErr
156
+ runtimePromise = (async function () {
157
+ var indexScriptUrl = getIndexScriptUrl()
158
+ var runtimeScriptUrl = getRuntimeScriptUrl(indexScriptUrl)
159
+ var wasmUrl = getWasmBinaryUrl(runtimeScriptUrl)
160
+ var moduleFactory = runtimeOptions.moduleFactory
161
+
162
+ if (!moduleFactory) {
163
+ var runtimeModule = await import(runtimeScriptUrl)
164
+ moduleFactory =
165
+ runtimeModule.default ||
166
+ runtimeModule.createWhisperNodeModule ||
167
+ runtimeModule
168
+ }
169
+ if (typeof moduleFactory !== 'function') {
170
+ throw new Error(
171
+ 'Failed to load whisper.node WASM runtime. Make sure wasm/whisper-node.js is built and included in the package.',
172
+ )
173
+ }
167
174
 
168
- options.noInitialRun = true
169
- options.print = function (text) {
170
- emitLog('INFO', String(text))
171
- if (typeof userPrint === 'function') {
172
- userPrint(text)
175
+ var options = Object.assign(
176
+ {},
177
+ runtimeOptions.moduleOptions || {},
178
+ runtimeOptions,
179
+ )
180
+ var userPrint = options.print
181
+ var userPrintErr = options.printErr
182
+ var userLocateFile = options.locateFile
183
+ var locateFileBaseUrl =
184
+ options.locateFileBaseUrl || resolveUrl('.', runtimeScriptUrl)
185
+
186
+ delete options.moduleFactory
187
+ delete options.moduleOptions
188
+ delete options.worker
189
+ delete options.workerUrl
190
+ delete options.workerPath
191
+ delete options.indexScriptUrl
192
+ delete options.scriptUrl
193
+ delete options.runtimeScriptUrl
194
+ delete options.jsPath
195
+ delete options.wasmPath
196
+ delete options.locateFileBaseUrl
197
+
198
+ options.noInitialRun = true
199
+ options.mainScriptUrlOrBlob = options.mainScriptUrlOrBlob || runtimeScriptUrl
200
+ options.locateFile = function (path, prefix) {
201
+ if (path === 'whisper-node.wasm' || path.slice(-5) === '.wasm') {
202
+ return wasmUrl
203
+ }
204
+ if (typeof userLocateFile === 'function') {
205
+ return userLocateFile(path, prefix)
206
+ }
207
+ return resolveUrl(path, locateFileBaseUrl || prefix)
173
208
  }
174
- }
175
- options.printErr = function (text) {
176
- emitLog('ERROR', String(text))
177
- if (typeof userPrintErr === 'function') {
178
- userPrintErr(text)
209
+ options.print = function (text) {
210
+ emitLog('INFO', String(text))
211
+ if (typeof userPrint === 'function') {
212
+ userPrint(text)
213
+ }
214
+ }
215
+ options.printErr = function (text) {
216
+ emitLog('ERROR', String(text))
217
+ if (typeof userPrintErr === 'function') {
218
+ userPrintErr(text)
219
+ }
179
220
  }
180
- }
181
221
 
182
- runtimePromise = Promise.resolve(moduleFactory(options))
222
+ return moduleFactory(options)
223
+ })()
183
224
  }
184
225
 
185
226
  return runtimePromise
@@ -213,6 +254,7 @@
213
254
  function createWorkerProxy() {
214
255
  var indexScriptUrl = getIndexScriptUrl()
215
256
  var runtimeScriptUrl = getRuntimeScriptUrl(indexScriptUrl)
257
+ var wasmUrl = getWasmBinaryUrl(runtimeScriptUrl)
216
258
  var workerScriptUrl = getWorkerScriptUrl(indexScriptUrl)
217
259
 
218
260
  if (!indexScriptUrl || !runtimeScriptUrl || !workerScriptUrl) {
@@ -220,6 +262,7 @@
220
262
  }
221
263
 
222
264
  var worker = new root.Worker(workerScriptUrl, {
265
+ type: 'module',
223
266
  name: 'whisper.node.wasm',
224
267
  })
225
268
  var proxy = {
@@ -323,6 +366,7 @@
323
366
  {
324
367
  indexScriptUrl: indexScriptUrl,
325
368
  runtimeScriptUrl: runtimeScriptUrl,
369
+ wasmPath: wasmUrl,
326
370
  runtimeOptions: getWorkerRuntimeOptions(),
327
371
  locateFileBaseUrl:
328
372
  runtimeOptions.locateFileBaseUrl || resolveUrl('.', runtimeScriptUrl),
@@ -366,6 +410,39 @@
366
410
  throw new Error('fetch is required to load models or audio by URL')
367
411
  }
368
412
 
413
+ function getCacheStorage() {
414
+ return root.caches || null
415
+ }
416
+
417
+ function isModelCacheEnabled(options) {
418
+ return !options || options.cacheModel !== false
419
+ }
420
+
421
+ function getModelCacheName(options) {
422
+ return (
423
+ (options && options.modelCacheName) ||
424
+ runtimeOptions.modelCacheName ||
425
+ DEFAULT_MODEL_CACHE_NAME
426
+ )
427
+ }
428
+
429
+ function getModelCacheKey(source, options) {
430
+ var key = (options && options.modelCacheKey) || source
431
+ try {
432
+ return new URL(key, root.location && root.location.href).href
433
+ } catch (_) {
434
+ return key
435
+ }
436
+ }
437
+
438
+ function canUseModelCache(options) {
439
+ return (
440
+ isModelCacheEnabled(options) &&
441
+ !!getCacheStorage() &&
442
+ typeof root.Response === 'function'
443
+ )
444
+ }
445
+
369
446
  function formatBytes(bytes) {
370
447
  if (bytes >= 1024 * MIB) {
371
448
  return (bytes / (1024 * MIB)).toFixed(2) + ' GiB'
@@ -497,6 +574,106 @@
497
574
  return buffer
498
575
  }
499
576
 
577
+ async function readCachedModel(source, limit, options) {
578
+ if (!canUseModelCache(options)) {
579
+ return null
580
+ }
581
+
582
+ var cacheName = getModelCacheName(options)
583
+ var cacheKey = getModelCacheKey(source, options)
584
+
585
+ try {
586
+ var cache = await getCacheStorage().open(cacheName)
587
+ var response = await cache.match(cacheKey)
588
+ if (!response) {
589
+ return null
590
+ }
591
+
592
+ var buffer = await response.arrayBuffer()
593
+ if (limit) {
594
+ assertModelSize(buffer.byteLength, limit, source)
595
+ }
596
+ emitLog('INFO', 'Loaded cached WASM model: ' + source)
597
+ return {
598
+ buffer: buffer,
599
+ cacheHit: true,
600
+ cacheStored: false,
601
+ cacheName: cacheName,
602
+ cacheKey: cacheKey,
603
+ }
604
+ } catch (error) {
605
+ emitLog(
606
+ 'WARN',
607
+ 'Failed to read cached WASM model ' +
608
+ source +
609
+ ': ' +
610
+ (error && error.message ? error.message : String(error)),
611
+ )
612
+ return null
613
+ }
614
+ }
615
+
616
+ async function writeCachedModel(source, buffer, options) {
617
+ if (!canUseModelCache(options)) {
618
+ return {
619
+ cacheStored: false,
620
+ cacheName: null,
621
+ cacheKey: null,
622
+ }
623
+ }
624
+
625
+ var cacheName = getModelCacheName(options)
626
+ var cacheKey = getModelCacheKey(source, options)
627
+
628
+ try {
629
+ var cache = await getCacheStorage().open(cacheName)
630
+ await cache.put(
631
+ cacheKey,
632
+ new root.Response(buffer.slice(0), {
633
+ headers: {
634
+ 'content-type': 'application/octet-stream',
635
+ },
636
+ }),
637
+ )
638
+ emitLog('INFO', 'Cached WASM model download: ' + source)
639
+ return {
640
+ cacheStored: true,
641
+ cacheName: cacheName,
642
+ cacheKey: cacheKey,
643
+ }
644
+ } catch (error) {
645
+ emitLog(
646
+ 'WARN',
647
+ 'Failed to cache WASM model ' +
648
+ source +
649
+ ': ' +
650
+ (error && error.message ? error.message : String(error)),
651
+ )
652
+ return {
653
+ cacheStored: false,
654
+ cacheName: cacheName,
655
+ cacheKey: cacheKey,
656
+ }
657
+ }
658
+ }
659
+
660
+ async function fetchModelArrayBuffer(source, limit, options) {
661
+ var cached = await readCachedModel(source, limit, options)
662
+ if (cached) {
663
+ return cached
664
+ }
665
+
666
+ var buffer = await fetchArrayBuffer(source, limit)
667
+ var cache = await writeCachedModel(source, buffer, options)
668
+ return {
669
+ buffer: buffer,
670
+ cacheHit: false,
671
+ cacheStored: cache.cacheStored,
672
+ cacheName: cache.cacheName,
673
+ cacheKey: cache.cacheKey,
674
+ }
675
+ }
676
+
500
677
  async function ensureModel(runtime, source, kind, options) {
501
678
  if (!source) {
502
679
  throw new Error('Model path is required')
@@ -510,8 +687,8 @@
510
687
  if (!modelCache[cacheKey]) {
511
688
  modelCache[cacheKey] = (async function () {
512
689
  var limit = getModelSizeLimit(runtime, options)
513
- var buffer = await fetchArrayBuffer(source, limit)
514
- var bytes = new Uint8Array(buffer)
690
+ var loaded = await fetchModelArrayBuffer(source, limit, options)
691
+ var bytes = new Uint8Array(loaded.buffer)
515
692
  var virtualPath =
516
693
  '/models/' + kind + '-' + hashString(source) + '-' + basenameFromUrl(source)
517
694
 
@@ -521,6 +698,10 @@
521
698
  return {
522
699
  virtualPath: virtualPath,
523
700
  bytes: bytes.byteLength,
701
+ cacheHit: loaded.cacheHit,
702
+ cacheStored: loaded.cacheStored,
703
+ cacheName: loaded.cacheName,
704
+ cacheKey: loaded.cacheKey,
524
705
  }
525
706
  })()
526
707
  }
@@ -562,8 +743,27 @@
562
743
  return value
563
744
  }
564
745
 
565
- function normalizeTranscribeOptions(options) {
746
+ function normalizeMaxThreads(value) {
747
+ var nThreads = Number(value)
748
+ if (!Number.isFinite(nThreads) || nThreads <= 0) {
749
+ return null
750
+ }
751
+ return Math.max(1, Math.min(MAX_WASM_THREADS, Math.floor(nThreads)))
752
+ }
753
+
754
+ function normalizeThreadOptions(options) {
566
755
  var normalized = Object.assign({}, options || {})
756
+ var maxThreads = normalizeMaxThreads(normalized.maxThreads)
757
+ if (maxThreads) {
758
+ normalized.maxThreads = maxThreads
759
+ } else {
760
+ delete normalized.maxThreads
761
+ }
762
+ return normalized
763
+ }
764
+
765
+ function normalizeTranscribeOptions(options) {
766
+ var normalized = normalizeThreadOptions(options)
567
767
  if (typeof normalized.onProgress !== 'function') {
568
768
  delete normalized.onProgress
569
769
  }
@@ -574,7 +774,7 @@
574
774
  }
575
775
 
576
776
  function splitTranscribeOptions(options) {
577
- var normalized = Object.assign({}, options || {})
777
+ var normalized = normalizeThreadOptions(options)
578
778
  var callbacks = {}
579
779
 
580
780
  if (typeof normalized.onProgress === 'function') {
@@ -966,6 +1166,10 @@
966
1166
  useGpu: useGpu,
967
1167
  useFlashAttn: options.useFlashAttn === true,
968
1168
  bytes: model.bytes,
1169
+ cacheHit: model.cacheHit,
1170
+ cacheStored: model.cacheStored,
1171
+ cacheName: model.cacheName,
1172
+ cacheKey: model.cacheKey,
969
1173
  wasm: true,
970
1174
  })
971
1175
  }
@@ -1168,6 +1372,10 @@
1168
1372
  useGpu: useGpu,
1169
1373
  nThreads: init.nThreads,
1170
1374
  bytes: model.bytes,
1375
+ cacheHit: model.cacheHit,
1376
+ cacheStored: model.cacheStored,
1377
+ cacheName: model.cacheName,
1378
+ cacheKey: model.cacheKey,
1171
1379
  wasm: true,
1172
1380
  })
1173
1381
  }
@@ -1241,10 +1449,32 @@
1241
1449
  toggleNativeLog: toggleNativeLog,
1242
1450
  addNativeLogListener: addNativeLogListener,
1243
1451
  DEFAULT_WASM_MODEL_SIZE_LIMIT_BYTES: 1500 * MIB,
1452
+ MAX_WASM_THREADS: MAX_WASM_THREADS,
1453
+ WASM_CONFIG_PATHS: WASM_CONFIG_PATHS,
1244
1454
  }
1245
1455
 
1246
1456
  api.default = api
1247
1457
 
1248
1458
  return api
1249
- },
1250
- )
1459
+ }
1460
+
1461
+ const api = createWhisperNodeApi(root)
1462
+
1463
+ export const WhisperContext = api.WhisperContext
1464
+ export const WhisperVadContext = api.WhisperVadContext
1465
+ export const DEFAULT_WASM_MODEL_SIZE_LIMIT_BYTES =
1466
+ api.DEFAULT_WASM_MODEL_SIZE_LIMIT_BYTES
1467
+ export const MAX_WASM_THREADS = api.MAX_WASM_THREADS
1468
+ export const configureWasm = api.configureWasm
1469
+ export const loadWasmModule = api.loadWasmModule
1470
+ export const loadWhisperModule = api.loadWhisperModule
1471
+ export const initWhisper = api.initWhisper
1472
+ export const initWhisperVad = api.initWhisperVad
1473
+ export const toggleNativeLog = api.toggleNativeLog
1474
+ export const addNativeLogListener = api.addNativeLogListener
1475
+
1476
+ if (root) {
1477
+ root.WhisperNodeWasm = api
1478
+ }
1479
+
1480
+ export default api
package/package.json CHANGED
@@ -1,7 +1,8 @@
1
1
  {
2
2
  "name": "@fugood/node-whisper-wasm",
3
- "version": "1.0.19",
3
+ "version": "1.0.20",
4
4
  "description": "Browser WASM module for whisper.node",
5
+ "type": "module",
5
6
  "main": "index.js",
6
7
  "browser": "index.js",
7
8
  "types": "index.d.ts",
@@ -39,8 +40,8 @@
39
40
  "index.js",
40
41
  "index.d.ts",
41
42
  "README.md",
42
- "whisper-node.js",
43
43
  "worker.js",
44
- "whisper-node.wasm"
44
+ "wasm/whisper-node.js",
45
+ "wasm/whisper-node.wasm"
45
46
  ]
46
- }
47
+ }