@rolldown/binding-wasm32-wasi 1.2.7 → 1.2.9

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@rolldown/binding-wasm32-wasi",
3
- "version": "1.2.7",
3
+ "version": "1.2.9",
4
4
  "main": "rolldown-binding.wasi.cjs",
5
5
  "files": [
6
6
  "rolldown-binding.wasm32-wasi.wasm",
@@ -29,6 +29,9 @@
29
29
  "url": "git+https://github.com/rolldown/rolldown.git",
30
30
  "directory": "packages/rolldown"
31
31
  },
32
+ "bugs": {
33
+ "url": "https://github.com/rolldown/rolldown/issues"
34
+ },
32
35
  "publishConfig": {
33
36
  "registry": "https://registry.npmjs.org/",
34
37
  "access": "public"
@@ -37,8 +40,8 @@
37
40
  "browser": "rolldown-binding.wasi-browser.js",
38
41
  "type": "module",
39
42
  "dependencies": {
40
- "@napi-rs/wasm-runtime": "~1.2.3",
41
- "@emnapi/core": "2.0.0-alpha.4",
42
- "@emnapi/runtime": "2.0.0-alpha.4"
43
+ "@napi-rs/wasm-runtime": "~1.2.4",
44
+ "@emnapi/core": "2.0.0-alpha.5",
45
+ "@emnapi/runtime": "2.0.0-alpha.5"
43
46
  }
44
- }
47
+ }
@@ -8,6 +8,55 @@ import {
8
8
  import { createContext as __emnapiCreateContext } from '@emnapi/runtime'
9
9
  import { memfs } from '@napi-rs/wasm-runtime/fs'
10
10
 
11
+ export const __napiBindingTarget = 'wasm32-wasi'
12
+ function __napiStampBindingTarget(exportsObject, target) {
13
+ if (
14
+ Object.prototype.hasOwnProperty.call(exportsObject, '__napiBindingTarget')
15
+ ) {
16
+ if (exportsObject.__napiBindingTarget === target) {
17
+ // Already ours: the root entry aliases the object it loaded, so a WASI
18
+ // fallback candidate — or a `NAPI_RS_NATIVE_LIBRARY_PATH` override that
19
+ // is a generated loader — arrives already stamped with this same value.
20
+ return target
21
+ }
22
+ const error = new Error(
23
+ '`__napiBindingTarget` is reserved by the generated binding loader, but the loaded binding already exports it. Rename the export, e.g. #[napi(js_name = "...")].',
24
+ )
25
+ error.code = 'ERR_NAPI_BINDING_TARGET_CONFLICT'
26
+ throw error
27
+ }
28
+ if (!Object.isExtensible(exportsObject)) {
29
+ // A `#[napi(module_exports)]` hook may seal or freeze this object
30
+ // (`Object::seal` / `Object::freeze`). Reporting the artifact is metadata,
31
+ // never a reason to fail an otherwise successful load, so the stamp is
32
+ // skipped. What a consumer still sees then follows the entry point: the
33
+ // browser and deferred loaders declare `__napiBindingTarget` at module
34
+ // level and go on reporting it, while the CommonJS entries hand back this
35
+ // very object as `module.exports`, so there the value is absent.
36
+ return target
37
+ }
38
+ try {
39
+ // [[Define]], not [[Set]]: an ordinary assignment walks the prototype
40
+ // chain, so an inherited accessor could swallow the value or throw and
41
+ // fail an otherwise successful load. The descriptor is what a successful
42
+ // assignment would have produced.
43
+ Object.defineProperty(exportsObject, '__napiBindingTarget', {
44
+ configurable: true,
45
+ enumerable: true,
46
+ value: target,
47
+ writable: true,
48
+ })
49
+ } catch {
50
+ // Same rule as the non-extensible skip above: reporting the artifact is
51
+ // metadata, never a reason to fail an otherwise successful load. An exotic
52
+ // object (a Proxy whose defineProperty trap refuses) is skipped, not
53
+ // thrown over.
54
+ }
55
+ // The CommonJS loaders assign this return value so `cjs-module-lexer` — and
56
+ // therefore Node's CJS -> ESM named export detection — can see
57
+ // `__napiBindingTarget` statically.
58
+ return target
59
+ }
11
60
 
12
61
  export const { fs: __fs, vol: __volume } = memfs()
13
62
 
@@ -48,20 +97,50 @@ let __emnapiContext
48
97
 
49
98
  const __wasiDisposeSymbol = Symbol.for('napi.rs.wasi.dispose')
50
99
  const __wasiWorkers = new Set()
100
+ // The thread manager has to be reachable *before* anything that can throw
101
+ // during load or registration. Initialization can fail after the pool has
102
+ // already spawned workers, and the rollback still has to mark their
103
+ // terminations as expected — but `__napiModule` is assigned only when
104
+ // instantiation RETURNS, so on exactly that path it is still undefined. A
105
+ // plugin factory runs while the emnapi module is being created, before the
106
+ // wasm is loaded and before any registration function runs, and its context
107
+ // carries the very same manager instance.
108
+ let __wasiThreadManager
109
+
110
+ function __captureWasiThreadManager(context) {
111
+ if (context && context.PThread) {
112
+ __wasiThreadManager = context.PThread
113
+ }
114
+ return {}
115
+ }
116
+
117
+ function __getWasiThreadManager() {
118
+ const manager =
119
+ __wasiThreadManager !== undefined
120
+ ? __wasiThreadManager
121
+ : __napiModule
122
+ ? __napiModule.PThread
123
+ : undefined
124
+ if (manager && typeof manager.terminateWorker === 'function') {
125
+ return manager
126
+ }
127
+ return undefined
128
+ }
51
129
  let __napiInstance
52
130
  let __emnapiContextDestroyed = false
53
131
  let __emnapiContextDestroyPromise
54
132
  let __emnapiWasmEnvCleanupPrepared = false
133
+ let __emnapiWasmEnvCleanupPreparing = false
55
134
  let __emnapiWasmEnvCleanupRan = false
56
135
  let __emnapiWasmEnvCleanupDrained = false
57
136
  let __emnapiWasmEnvCleanupDrainPromise
58
137
  let __wasiDisposed = false
59
138
  let __wasiDisposePromise
60
- let __completeWasiDisposal = function() {}
139
+ let __completeWasiDisposal = function () {}
61
140
  // Overridden by loader flavors that have a last-resort reclaim for a rollback
62
141
  // that stopped short of destroying the context. See
63
142
  // `__rollbackWasiInitialization`.
64
- let __retainWasiRollbackForRetry = function() {}
143
+ let __retainWasiRollbackForRetry = function () {}
65
144
 
66
145
  function __isThenable(value) {
67
146
  return (
@@ -125,13 +204,58 @@ function __attachCleanupErrors(error, cleanupErrors) {
125
204
  return aggregate
126
205
  }
127
206
 
207
+ function __wrapEmnapiContextDestroyForSettlement(
208
+ context,
209
+ prepareEnvCleanup,
210
+ isPreparingEnvCleanup,
211
+ ) {
212
+ let destroy
213
+ try {
214
+ destroy = context.destroy
215
+ } catch {
216
+ return context
217
+ }
218
+ if (typeof destroy !== 'function') {
219
+ return context
220
+ }
221
+ try {
222
+ Object.defineProperty(context, 'destroy', {
223
+ configurable: true,
224
+ enumerable: false,
225
+ writable: true,
226
+ value: function () {
227
+ // Reentered from a promise hook that fired inside the barrier: the
228
+ // frame running it destroys as soon as it returns.
229
+ if (isPreparingEnvCleanup?.()) {
230
+ return
231
+ }
232
+ prepareEnvCleanup?.()
233
+ return Reflect.apply(destroy, this, arguments)
234
+ },
235
+ })
236
+ } catch {}
237
+ return context
238
+ }
239
+
240
+ function __isPreparingWasmEnvCleanup() {
241
+ return __emnapiWasmEnvCleanupPreparing
242
+ }
243
+
128
244
  function __prepareWasmEnvCleanup() {
129
- if (__emnapiWasmEnvCleanupPrepared) {
245
+ if (__emnapiWasmEnvCleanupPrepared || __emnapiWasmEnvCleanupPreparing) {
130
246
  return
131
247
  }
132
248
  const prepare = __napiInstance?.exports?.napi_prepare_wasm_env_cleanup
133
249
  if (typeof prepare === 'function') {
134
- prepare()
250
+ // The addon settles the promises it cancels synchronously, under a
251
+ // non-reentrant lifecycle mutex: anything a promise hook calls from in
252
+ // here must not reach this export again.
253
+ __emnapiWasmEnvCleanupPreparing = true
254
+ try {
255
+ prepare()
256
+ } finally {
257
+ __emnapiWasmEnvCleanupPreparing = false
258
+ }
135
259
  __emnapiWasmEnvCleanupRan = true
136
260
  }
137
261
  __emnapiWasmEnvCleanupPrepared = true
@@ -324,13 +448,80 @@ function __destroyEmnapiContext() {
324
448
  return destroyPromise
325
449
  }
326
450
 
451
+ /**
452
+ * Holds the event loop open until `work` settles.
453
+ *
454
+ * Nothing else can: the pool workers are deliberately unreferenced so an idle
455
+ * binding cannot keep a process alive, and referencing them again for the
456
+ * termination does not hold either — emnapi unreferences a worker the moment it
457
+ * reports `async-thread-ready`, which for a worker that was still starting
458
+ * lands *after* the termination began. Without a handle of its own, an
459
+ * `await dispose()` with nothing else pending exits the process with its
460
+ * promise unsettled, and everything after the `await` is skipped.
461
+ *
462
+ * The timer is cleared as soon as the work settles, so this never outlives the
463
+ * disposal that asked for it.
464
+ */
465
+ function __keepEventLoopAliveUntil(work) {
466
+ const setTimer = globalThis.setInterval
467
+ const clearTimer = globalThis.clearInterval
468
+ if (typeof setTimer !== 'function' || typeof clearTimer !== 'function') {
469
+ return work
470
+ }
471
+ let timer
472
+ try {
473
+ timer = setTimer(function () {}, 50)
474
+ } catch {
475
+ return work
476
+ }
477
+ const release = function () {
478
+ try {
479
+ clearTimer(timer)
480
+ } catch {}
481
+ }
482
+ return work.then(
483
+ (value) => {
484
+ release()
485
+ return value
486
+ },
487
+ (error) => {
488
+ release()
489
+ throw error
490
+ },
491
+ )
492
+ }
493
+
494
+ /**
495
+ * `@emnapi/wasi-threads` counts a worker exit as expected only when its own
496
+ * thread manager performed the termination. A bare `worker.terminate()` reaches
497
+ * the manager's `exit` listener instead, which reports
498
+ * `worker (tid = N) sent an error! ... stopped with exit code 1` and rethrows
499
+ * inside the emit — aborting the `once('exit')` that backs the terminate
500
+ * promise, so disposal never settles and the process dies with an uncaught
501
+ * exception. Mark the termination through the manager first.
502
+ *
503
+ * The manager comes from `__getWasiThreadManager`, not from `__napiModule`:
504
+ * the initialization rollback runs on the one path where instantiation never
505
+ * returned, so `__napiModule` is still undefined there while the workers it
506
+ * spawned are already registered and loaded.
507
+ *
508
+ * Not `terminateAllThreads()`: that one recreates the pool it just shut down.
509
+ */
327
510
  function __terminateWasiWorkers() {
328
511
  const cleanupErrors = []
329
512
  const pending = []
513
+ const threadManager = __getWasiThreadManager()
330
514
 
331
515
  for (const worker of __wasiWorkers) {
332
516
  let result
333
517
  try {
518
+ if (threadManager) {
519
+ threadManager.terminateWorker(worker)
520
+ // `terminateWorker` leaves behind a reporter that logs every message
521
+ // still queued on the port, which Node flushes on exit. Nothing is
522
+ // listening for those any more.
523
+ worker.onmessage = undefined
524
+ }
334
525
  result = worker.terminate()
335
526
  } catch (error) {
336
527
  cleanupErrors.push(error)
@@ -360,7 +551,9 @@ function __terminateWasiWorkers() {
360
551
  )
361
552
  }
362
553
  }
363
- return pending.length > 0 ? Promise.all(pending).then(finish) : finish()
554
+ return pending.length > 0
555
+ ? __keepEventLoopAliveUntil(Promise.all(pending)).then(finish)
556
+ : finish()
364
557
  }
365
558
 
366
559
  function __finishWasiDisposal() {
@@ -561,7 +754,11 @@ let __wasiModule
561
754
  let __napiModule
562
755
 
563
756
  try {
564
- __emnapiContext = __emnapiCreateContext({ autoDestroy: false })
757
+ __emnapiContext = __wrapEmnapiContextDestroyForSettlement(
758
+ __emnapiCreateContext({ autoDestroy: false }),
759
+ __prepareWasmEnvCleanup,
760
+ __isPreparingWasmEnvCleanup,
761
+ )
565
762
  __emnapiContext.suppressDestroy()
566
763
 
567
764
  ;({
@@ -572,7 +769,7 @@ try {
572
769
  context: __emnapiContext,
573
770
  asyncWorkPoolSize: __asyncWorkPoolSize,
574
771
  reuseWorker: { size: __asyncWorkPoolSize + __workerPoolSize },
575
- plugins: [__emnapiAsyncWorkPlugin, __emnapiTSFNPlugin],
772
+ plugins: [__captureWasiThreadManager, __emnapiAsyncWorkPlugin, __emnapiTSFNPlugin],
576
773
  wasi: __wasi,
577
774
  onCreateWorker() {
578
775
  const worker = new Worker(new URL('@rolldown/binding-wasm32-wasi/wasi-worker-browser.mjs', import.meta.url), {
@@ -616,6 +813,12 @@ try {
616
813
  },
617
814
  }))
618
815
  __publishWasiDispose(__napiModule.exports)
816
+ // The default export hands out this object; a named module export does not
817
+ // travel with it, so carry the marker on the binding itself too. After the
818
+ // host install, which hands the same object to addon-provided registration
819
+ // functions that may put anything on it, and inside this `try`, so a claimed
820
+ // name fails the load through the rollback below rather than past it.
821
+ __napiStampBindingTarget(__napiModule.exports, __napiBindingTarget)
619
822
  } catch (error) {
620
823
  const cleanupErrors = await __rollbackWasiInitialization()
621
824
  throw __attachCleanupErrors(error, cleanupErrors)
@@ -670,6 +873,7 @@ export const BindingWatcherEvent = __napiModule.exports.BindingWatcherEvent
670
873
  export const ParallelJsPluginRegistry = __napiModule.exports.ParallelJsPluginRegistry
671
874
  export const TraceSubscriberGuard = __napiModule.exports.TraceSubscriberGuard
672
875
  export const TsconfigCache = __napiModule.exports.TsconfigCache
876
+ export const __internalForcePanic = __napiModule.exports.__internalForcePanic
673
877
  export const BindingAttachDebugInfo = __napiModule.exports.BindingAttachDebugInfo
674
878
  export const BindingBuiltinPluginName = __napiModule.exports.BindingBuiltinPluginName
675
879
  export const BindingChunkModuleOrderBy = __napiModule.exports.BindingChunkModuleOrderBy
@@ -1,9 +1,57 @@
1
- // napi-rs-artifact-metadata:{"version":2,"rootEntry":"binding.cjs","exports":["LegalCommentsMode","minify","minifySync","Severity","ParseResult","ExportExportNameKind","ExportImportNameKind","ExportLocalNameKind","ImportNameKind","parse","parseSync","rawTransferSupported","ResolverFactory","EnforceExtension","ModuleType","sync","HelperMode","isolatedDeclaration","isolatedDeclarationSync","moduleRunnerTransform","moduleRunnerTransformSync","transform","transformSync","BindingBundleEndEventData","BindingBundleErrorEventData","BindingBundler","BindingCallableBuiltinPlugin","BindingChunkingContext","BindingDecodedMap","BindingDevEngine","BindingLoadPluginContext","BindingMagicString","BindingModuleInfo","BindingNormalizedOptions","BindingOutputAsset","BindingOutputChunk","BindingPluginContext","BindingRenderedChunk","BindingRenderedChunkMeta","BindingRenderedModule","BindingSourceMap","BindingTransformPluginContext","BindingWatcher","BindingWatcherBundler","BindingWatcherChangeData","BindingWatcherEvent","ParallelJsPluginRegistry","TraceSubscriberGuard","TsconfigCache","BindingAttachDebugInfo","BindingBuiltinPluginName","BindingChunkModuleOrderBy","BindingErrorStage","BindingLogLevel","BindingPluginOrder","BindingPropertyReadSideEffects","BindingPropertyWriteSideEffects","BindingRebuildStrategy","collapseSourcemaps","enhancedTransform","enhancedTransformSync","FilterTokenKind","getNativeMemoryStats","initTraceSubscriber","registerPlugins","resetNativeMemoryStats","resolveTsconfig","shutdownAsyncRuntime","startAsyncRuntime"],"managedRootEntries":["browser.js","binding.cjs","rolldown-binding.wasm","rolldown-binding.debug.wasm"]}
1
+ // napi-rs-artifact-metadata:{"version":2,"rootEntry":"binding.cjs","exports":["LegalCommentsMode","minify","minifySync","Severity","ParseResult","ExportExportNameKind","ExportImportNameKind","ExportLocalNameKind","ImportNameKind","parse","parseSync","rawTransferSupported","ResolverFactory","EnforceExtension","ModuleType","sync","HelperMode","isolatedDeclaration","isolatedDeclarationSync","moduleRunnerTransform","moduleRunnerTransformSync","transform","transformSync","BindingBundleEndEventData","BindingBundleErrorEventData","BindingBundler","BindingCallableBuiltinPlugin","BindingChunkingContext","BindingDecodedMap","BindingDevEngine","BindingLoadPluginContext","BindingMagicString","BindingModuleInfo","BindingNormalizedOptions","BindingOutputAsset","BindingOutputChunk","BindingPluginContext","BindingRenderedChunk","BindingRenderedChunkMeta","BindingRenderedModule","BindingSourceMap","BindingTransformPluginContext","BindingWatcher","BindingWatcherBundler","BindingWatcherChangeData","BindingWatcherEvent","ParallelJsPluginRegistry","TraceSubscriberGuard","TsconfigCache","__internalForcePanic","BindingAttachDebugInfo","BindingBuiltinPluginName","BindingChunkModuleOrderBy","BindingErrorStage","BindingLogLevel","BindingPluginOrder","BindingPropertyReadSideEffects","BindingPropertyWriteSideEffects","BindingRebuildStrategy","collapseSourcemaps","enhancedTransform","enhancedTransformSync","FilterTokenKind","getNativeMemoryStats","initTraceSubscriber","registerPlugins","resetNativeMemoryStats","resolveTsconfig","shutdownAsyncRuntime","startAsyncRuntime"],"managedRootEntries":["browser.js","binding.cjs","rolldown-binding.wasm","rolldown-binding.debug.wasm"]}
2
2
  /* eslint-disable */
3
- /* prettier-ignore */
4
-
5
3
  /* auto-generated by NAPI-RS */
6
4
 
5
+ const __napiBindingTarget = 'wasm32-wasi'
6
+ function __napiStampBindingTarget(exportsObject, target) {
7
+ if (
8
+ Object.prototype.hasOwnProperty.call(exportsObject, '__napiBindingTarget')
9
+ ) {
10
+ if (exportsObject.__napiBindingTarget === target) {
11
+ // Already ours: the root entry aliases the object it loaded, so a WASI
12
+ // fallback candidate — or a `NAPI_RS_NATIVE_LIBRARY_PATH` override that
13
+ // is a generated loader — arrives already stamped with this same value.
14
+ return target
15
+ }
16
+ const error = new Error(
17
+ '`__napiBindingTarget` is reserved by the generated binding loader, but the loaded binding already exports it. Rename the export, e.g. #[napi(js_name = "...")].',
18
+ )
19
+ error.code = 'ERR_NAPI_BINDING_TARGET_CONFLICT'
20
+ throw error
21
+ }
22
+ if (!Object.isExtensible(exportsObject)) {
23
+ // A `#[napi(module_exports)]` hook may seal or freeze this object
24
+ // (`Object::seal` / `Object::freeze`). Reporting the artifact is metadata,
25
+ // never a reason to fail an otherwise successful load, so the stamp is
26
+ // skipped. What a consumer still sees then follows the entry point: the
27
+ // browser and deferred loaders declare `__napiBindingTarget` at module
28
+ // level and go on reporting it, while the CommonJS entries hand back this
29
+ // very object as `module.exports`, so there the value is absent.
30
+ return target
31
+ }
32
+ try {
33
+ // [[Define]], not [[Set]]: an ordinary assignment walks the prototype
34
+ // chain, so an inherited accessor could swallow the value or throw and
35
+ // fail an otherwise successful load. The descriptor is what a successful
36
+ // assignment would have produced.
37
+ Object.defineProperty(exportsObject, '__napiBindingTarget', {
38
+ configurable: true,
39
+ enumerable: true,
40
+ value: target,
41
+ writable: true,
42
+ })
43
+ } catch {
44
+ // Same rule as the non-extensible skip above: reporting the artifact is
45
+ // metadata, never a reason to fail an otherwise successful load. An exotic
46
+ // object (a Proxy whose defineProperty trap refuses) is skipped, not
47
+ // thrown over.
48
+ }
49
+ // The CommonJS loaders assign this return value so `cjs-module-lexer` — and
50
+ // therefore Node's CJS -> ESM named export detection — can see
51
+ // `__napiBindingTarget` statically.
52
+ return target
53
+ }
54
+
7
55
  const __nodeFs = require('node:fs')
8
56
  const __nodePath = require('node:path')
9
57
  const { WASI: __nodeWASI } = require('node:wasi')
@@ -91,6 +139,7 @@ function __createWasiWorker(filename) {
91
139
  return new Worker(filename, {
92
140
  env: process.env,
93
141
  execArgv: __workerExecArgv,
142
+ workerData: { hostRoot: __hostRoot, rootDir: __rootDir },
94
143
  })
95
144
  } catch (error) {
96
145
  if (!error || error.code !== 'ERR_WORKER_INVALID_EXEC_ARGV') {
@@ -106,14 +155,18 @@ function __createWasiWorker(filename) {
106
155
  }
107
156
  }
108
157
 
109
- const __rootDir = __nodePath.parse(process.cwd()).root
158
+ const __cwd = process.cwd()
159
+ const __rootDir = __nodePath.parse(__cwd).root
160
+ const __hostRoot =
161
+ process.platform === 'android' ? __cwd : __rootDir
110
162
 
111
163
  const __wasi = new __nodeWASI({
112
164
  version: 'preview1',
113
165
  env: process.env,
114
166
  preopens: {
115
- [__rootDir]: __rootDir,
116
- }
167
+ [__rootDir]: __hostRoot,
168
+ [__hostRoot]: __hostRoot,
169
+ },
117
170
  })
118
171
 
119
172
  const __sharedMemory = new WebAssembly.Memory({
@@ -146,20 +199,50 @@ let __emnapiContext
146
199
 
147
200
  const __wasiDisposeSymbol = Symbol.for('napi.rs.wasi.dispose')
148
201
  const __wasiWorkers = new Set()
202
+ // The thread manager has to be reachable *before* anything that can throw
203
+ // during load or registration. Initialization can fail after the pool has
204
+ // already spawned workers, and the rollback still has to mark their
205
+ // terminations as expected — but `__napiModule` is assigned only when
206
+ // instantiation RETURNS, so on exactly that path it is still undefined. A
207
+ // plugin factory runs while the emnapi module is being created, before the
208
+ // wasm is loaded and before any registration function runs, and its context
209
+ // carries the very same manager instance.
210
+ let __wasiThreadManager
211
+
212
+ function __captureWasiThreadManager(context) {
213
+ if (context && context.PThread) {
214
+ __wasiThreadManager = context.PThread
215
+ }
216
+ return {}
217
+ }
218
+
219
+ function __getWasiThreadManager() {
220
+ const manager =
221
+ __wasiThreadManager !== undefined
222
+ ? __wasiThreadManager
223
+ : __napiModule
224
+ ? __napiModule.PThread
225
+ : undefined
226
+ if (manager && typeof manager.terminateWorker === 'function') {
227
+ return manager
228
+ }
229
+ return undefined
230
+ }
149
231
  let __napiInstance
150
232
  let __emnapiContextDestroyed = false
151
233
  let __emnapiContextDestroyPromise
152
234
  let __emnapiWasmEnvCleanupPrepared = false
235
+ let __emnapiWasmEnvCleanupPreparing = false
153
236
  let __emnapiWasmEnvCleanupRan = false
154
237
  let __emnapiWasmEnvCleanupDrained = false
155
238
  let __emnapiWasmEnvCleanupDrainPromise
156
239
  let __wasiDisposed = false
157
240
  let __wasiDisposePromise
158
- let __completeWasiDisposal = function() {}
241
+ let __completeWasiDisposal = function () {}
159
242
  // Overridden by loader flavors that have a last-resort reclaim for a rollback
160
243
  // that stopped short of destroying the context. See
161
244
  // `__rollbackWasiInitialization`.
162
- let __retainWasiRollbackForRetry = function() {}
245
+ let __retainWasiRollbackForRetry = function () {}
163
246
 
164
247
  function __isThenable(value) {
165
248
  return (
@@ -223,13 +306,58 @@ function __attachCleanupErrors(error, cleanupErrors) {
223
306
  return aggregate
224
307
  }
225
308
 
309
+ function __wrapEmnapiContextDestroyForSettlement(
310
+ context,
311
+ prepareEnvCleanup,
312
+ isPreparingEnvCleanup,
313
+ ) {
314
+ let destroy
315
+ try {
316
+ destroy = context.destroy
317
+ } catch {
318
+ return context
319
+ }
320
+ if (typeof destroy !== 'function') {
321
+ return context
322
+ }
323
+ try {
324
+ Object.defineProperty(context, 'destroy', {
325
+ configurable: true,
326
+ enumerable: false,
327
+ writable: true,
328
+ value: function () {
329
+ // Reentered from a promise hook that fired inside the barrier: the
330
+ // frame running it destroys as soon as it returns.
331
+ if (isPreparingEnvCleanup?.()) {
332
+ return
333
+ }
334
+ prepareEnvCleanup?.()
335
+ return Reflect.apply(destroy, this, arguments)
336
+ },
337
+ })
338
+ } catch {}
339
+ return context
340
+ }
341
+
342
+ function __isPreparingWasmEnvCleanup() {
343
+ return __emnapiWasmEnvCleanupPreparing
344
+ }
345
+
226
346
  function __prepareWasmEnvCleanup() {
227
- if (__emnapiWasmEnvCleanupPrepared) {
347
+ if (__emnapiWasmEnvCleanupPrepared || __emnapiWasmEnvCleanupPreparing) {
228
348
  return
229
349
  }
230
350
  const prepare = __napiInstance?.exports?.napi_prepare_wasm_env_cleanup
231
351
  if (typeof prepare === 'function') {
232
- prepare()
352
+ // The addon settles the promises it cancels synchronously, under a
353
+ // non-reentrant lifecycle mutex: anything a promise hook calls from in
354
+ // here must not reach this export again.
355
+ __emnapiWasmEnvCleanupPreparing = true
356
+ try {
357
+ prepare()
358
+ } finally {
359
+ __emnapiWasmEnvCleanupPreparing = false
360
+ }
233
361
  __emnapiWasmEnvCleanupRan = true
234
362
  }
235
363
  __emnapiWasmEnvCleanupPrepared = true
@@ -422,13 +550,80 @@ function __destroyEmnapiContext() {
422
550
  return destroyPromise
423
551
  }
424
552
 
553
+ /**
554
+ * Holds the event loop open until `work` settles.
555
+ *
556
+ * Nothing else can: the pool workers are deliberately unreferenced so an idle
557
+ * binding cannot keep a process alive, and referencing them again for the
558
+ * termination does not hold either — emnapi unreferences a worker the moment it
559
+ * reports `async-thread-ready`, which for a worker that was still starting
560
+ * lands *after* the termination began. Without a handle of its own, an
561
+ * `await dispose()` with nothing else pending exits the process with its
562
+ * promise unsettled, and everything after the `await` is skipped.
563
+ *
564
+ * The timer is cleared as soon as the work settles, so this never outlives the
565
+ * disposal that asked for it.
566
+ */
567
+ function __keepEventLoopAliveUntil(work) {
568
+ const setTimer = globalThis.setInterval
569
+ const clearTimer = globalThis.clearInterval
570
+ if (typeof setTimer !== 'function' || typeof clearTimer !== 'function') {
571
+ return work
572
+ }
573
+ let timer
574
+ try {
575
+ timer = setTimer(function () {}, 50)
576
+ } catch {
577
+ return work
578
+ }
579
+ const release = function () {
580
+ try {
581
+ clearTimer(timer)
582
+ } catch {}
583
+ }
584
+ return work.then(
585
+ (value) => {
586
+ release()
587
+ return value
588
+ },
589
+ (error) => {
590
+ release()
591
+ throw error
592
+ },
593
+ )
594
+ }
595
+
596
+ /**
597
+ * `@emnapi/wasi-threads` counts a worker exit as expected only when its own
598
+ * thread manager performed the termination. A bare `worker.terminate()` reaches
599
+ * the manager's `exit` listener instead, which reports
600
+ * `worker (tid = N) sent an error! ... stopped with exit code 1` and rethrows
601
+ * inside the emit — aborting the `once('exit')` that backs the terminate
602
+ * promise, so disposal never settles and the process dies with an uncaught
603
+ * exception. Mark the termination through the manager first.
604
+ *
605
+ * The manager comes from `__getWasiThreadManager`, not from `__napiModule`:
606
+ * the initialization rollback runs on the one path where instantiation never
607
+ * returned, so `__napiModule` is still undefined there while the workers it
608
+ * spawned are already registered and loaded.
609
+ *
610
+ * Not `terminateAllThreads()`: that one recreates the pool it just shut down.
611
+ */
425
612
  function __terminateWasiWorkers() {
426
613
  const cleanupErrors = []
427
614
  const pending = []
615
+ const threadManager = __getWasiThreadManager()
428
616
 
429
617
  for (const worker of __wasiWorkers) {
430
618
  let result
431
619
  try {
620
+ if (threadManager) {
621
+ threadManager.terminateWorker(worker)
622
+ // `terminateWorker` leaves behind a reporter that logs every message
623
+ // still queued on the port, which Node flushes on exit. Nothing is
624
+ // listening for those any more.
625
+ worker.onmessage = undefined
626
+ }
432
627
  result = worker.terminate()
433
628
  } catch (error) {
434
629
  cleanupErrors.push(error)
@@ -458,7 +653,9 @@ function __terminateWasiWorkers() {
458
653
  )
459
654
  }
460
655
  }
461
- return pending.length > 0 ? Promise.all(pending).then(finish) : finish()
656
+ return pending.length > 0
657
+ ? __keepEventLoopAliveUntil(Promise.all(pending)).then(finish)
658
+ : finish()
462
659
  }
463
660
 
464
661
  function __finishWasiDisposal() {
@@ -828,7 +1025,11 @@ function __captureEmnapiAutoDestroyListener() {
828
1025
  try {
829
1026
  const __finishAutoDestroyCapture = __captureEmnapiAutoDestroyListener()
830
1027
  try {
831
- __emnapiContext = __emnapiCreateContext({ autoDestroy: false })
1028
+ __emnapiContext = __wrapEmnapiContextDestroyForSettlement(
1029
+ __emnapiCreateContext({ autoDestroy: false }),
1030
+ __prepareWasmEnvCleanup,
1031
+ __isPreparingWasmEnvCleanup,
1032
+ )
832
1033
  // emnapi 2.x still registers an unconditional once-listener for
833
1034
  // beforeExit that auto-destroys the context, and suppressDestroy() only
834
1035
  // neutralizes its callback without removing it. This loader owns cleanup
@@ -846,7 +1047,7 @@ try {
846
1047
  napiModule: __napiModule,
847
1048
  } = __emnapiInstantiateNapiModuleSync(__wasmFile, {
848
1049
  context: __emnapiContext,
849
- asyncWorkPoolSize: (function() {
1050
+ asyncWorkPoolSize: (function () {
850
1051
  const threadsSizeFromEnv = Number(process.env.NAPI_RS_ASYNC_WORK_POOL_SIZE ?? process.env.UV_THREADPOOL_SIZE)
851
1052
  // NaN > 0 is false
852
1053
  if (threadsSizeFromEnv > 0) {
@@ -856,7 +1057,7 @@ try {
856
1057
  }
857
1058
  })(),
858
1059
  reuseWorker: true,
859
- plugins: [__emnapiAsyncWorkPlugin, __emnapiTSFNPlugin],
1060
+ plugins: [__captureWasiThreadManager, __emnapiAsyncWorkPlugin, __emnapiTSFNPlugin],
860
1061
  wasi: __wasi,
861
1062
  onCreateWorker() {
862
1063
  const worker = __createWasiWorker(__nodePath.join(__dirname, 'wasi-worker.mjs'))
@@ -871,21 +1072,25 @@ try {
871
1072
  // According to https://github.com/nodejs/node/blob/19e0d472728c79d418b74bddff588bea70a403d0/lib/internal/worker.js#L415,
872
1073
  // a worker is consist of two handles: kPublicPort and kHandle.
873
1074
  {
874
- const kPublicPort = Object.getOwnPropertySymbols(worker).find(s =>
875
- s.toString().includes("kPublicPort")
876
- );
1075
+ const kPublicPort = Object.getOwnPropertySymbols(worker).find((s) =>
1076
+ s.toString().includes('kPublicPort'),
1077
+ )
877
1078
  if (kPublicPort) {
878
- worker[kPublicPort].ref = () => {};
1079
+ worker[kPublicPort].ref = () => {}
879
1080
  }
880
1081
 
881
- const kHandle = Object.getOwnPropertySymbols(worker).find(s =>
882
- s.toString().includes("kHandle")
883
- );
1082
+ const kHandle = Object.getOwnPropertySymbols(worker).find((s) =>
1083
+ s.toString().includes('kHandle'),
1084
+ )
884
1085
  if (kHandle) {
885
- worker[kHandle].ref = () => {};
1086
+ worker[kHandle].ref = () => {}
886
1087
  }
887
1088
 
888
- worker.unref();
1089
+ worker.unref()
1090
+ // These stubs stay in place for the worker's whole life, disposal
1091
+ // included: `__keepEventLoopAliveUntil` is what holds the process open
1092
+ // while a termination is pending, precisely because a worker's own
1093
+ // references cannot be relied on for it.
889
1094
  }
890
1095
  return worker
891
1096
  },
@@ -908,6 +1113,22 @@ try {
908
1113
  },
909
1114
  }))
910
1115
  __publishWasiDispose(__napiModule.exports)
1116
+ // The CommonJS tail below aliases `__napiModule.exports`; a named module
1117
+ // export does not travel with it, so carry the marker on the binding itself
1118
+ // too. Three things pin the stamp to exactly this spot:
1119
+ // - inside this `try`, because the guard throws on a
1120
+ // `#[napi(module_exports)]` hook that claimed the name, and only the
1121
+ // catch below tears the environment — context, workers, exit listener —
1122
+ // back down;
1123
+ // - after the async runtime host install, which hands this same object to
1124
+ // addon-provided registration functions that may put anything on it;
1125
+ // - assigning onto the loader's own `module.exports`, which is still the
1126
+ // original object here, so an addon accessor with a refusing setter is
1127
+ // never written through. `cjs-module-lexer` — Node's CJS -> ESM named
1128
+ // export detection — reads the static `module.exports.<name> =` either
1129
+ // way, and the later `module.exports = __napiModule.exports` does not
1130
+ // undo that.
1131
+ module.exports.__napiBindingTarget = __napiStampBindingTarget(__napiModule.exports, __napiBindingTarget)
911
1132
  __registerWasiExitListener()
912
1133
  } catch (error) {
913
1134
  const rollback = {
@@ -970,6 +1191,7 @@ module.exports.BindingWatcherEvent = __napiModule.exports.BindingWatcherEvent
970
1191
  module.exports.ParallelJsPluginRegistry = __napiModule.exports.ParallelJsPluginRegistry
971
1192
  module.exports.TraceSubscriberGuard = __napiModule.exports.TraceSubscriberGuard
972
1193
  module.exports.TsconfigCache = __napiModule.exports.TsconfigCache
1194
+ module.exports.__internalForcePanic = __napiModule.exports.__internalForcePanic
973
1195
  module.exports.BindingAttachDebugInfo = __napiModule.exports.BindingAttachDebugInfo
974
1196
  module.exports.BindingBuiltinPluginName = __napiModule.exports.BindingBuiltinPluginName
975
1197
  module.exports.BindingChunkModuleOrderBy = __napiModule.exports.BindingChunkModuleOrderBy
@@ -4,6 +4,10 @@ type VoidNullable<T = void> = T | null | undefined | void
4
4
  export type BindingStringOrRegex = string | RegExp
5
5
  export type BindingResult<T> = { errors: BindingError[], isBindingErrors: boolean } | T
6
6
 
7
+
8
+ /** The WASI flavor this loader instantiates. */
9
+ export declare const __napiBindingTarget: 'wasm32-wasi'
10
+
7
11
  export interface CodegenOptions {
8
12
  /**
9
13
  * Remove whitespace.
@@ -11,6 +15,24 @@ export interface CodegenOptions {
11
15
  * @default true
12
16
  */
13
17
  removeWhitespace?: boolean
18
+ /**
19
+ * Escape non-ASCII characters in string literals, untagged template literals, regular
20
+ * expression literals and identifier names.
21
+ *
22
+ * Uses `\uXXXX` for characters up to U+FFFF and `\u{...}` for higher code points.
23
+ * Regular expressions use escaped UTF-16 surrogate pairs for higher code points instead;
24
+ * escaping changes the observable `RegExp.prototype.source` value.
25
+ *
26
+ * Code point escapes (`\u{...}`) require ES2015 or later; this option does not provide
27
+ * ES5-compatible output.
28
+ *
29
+ * Non-ASCII characters are left unescaped in tagged template quasis (whose raw text is
30
+ * observable), JSX names and text, JSX attribute strings, hashbangs and preserved comments.
31
+ * JavaScript expressions inside tagged templates and JSX are escaped normally.
32
+ *
33
+ * @default false
34
+ */
35
+ asciiOnly?: boolean
14
36
  /**
15
37
  * How to handle legal comments (comments containing `@license`, `@preserve`, or starting with `//!`/`/*!`).
16
38
  *
@@ -22,7 +44,7 @@ export interface CodegenOptions {
22
44
  *
23
45
  * @default "none" (when minifying)
24
46
  */
25
- legalComments?: 'none' | 'inline' | 'eof' | 'external' | { linked: string }
47
+ legalComments?: 'none' | 'inline' | 'eof' | 'external' | { linked: string }
26
48
  }
27
49
 
28
50
  export interface CompressOptions {
@@ -117,14 +139,7 @@ export interface LegalCommentsLinked {
117
139
  linked: string
118
140
  }
119
141
 
120
- export type LegalCommentsMode = /** Do not preserve any legal comments. */
121
- 'none'|
122
- /** Preserve all legal comments inline. */
123
- 'inline'|
124
- /** Move all legal comments to the end of the file. */
125
- 'eof'|
126
- /** Extract legal comments without linking. */
127
- 'external';
142
+ export type LegalCommentsMode = 'none' | 'inline' | 'eof' | 'external'
128
143
 
129
144
  export interface MangleOptions {
130
145
  /**
@@ -293,6 +308,7 @@ export interface TreeShakeOptions {
293
308
  */
294
309
  invalidImportSideEffects?: boolean
295
310
  }
311
+
296
312
  export interface Comment {
297
313
  type: 'Line' | 'Block'
298
314
  value: string
@@ -314,9 +330,8 @@ export interface OxcError {
314
330
  codeframe: string | null
315
331
  }
316
332
 
317
- export type Severity = 'Error'|
318
- 'Warning'|
319
- 'Advice';
333
+ export type Severity = 'Error' | 'Warning' | 'Advice'
334
+
320
335
  export declare class ParseResult {
321
336
  get program(): import("@oxc-project/types").Program
322
337
  get module(): EcmaScriptModule
@@ -356,12 +371,7 @@ export interface ExportExportName {
356
371
  end: number | null
357
372
  }
358
373
 
359
- export type ExportExportNameKind = /** `export { name } */
360
- 'Name'|
361
- /** `export default expression` */
362
- 'Default'|
363
- /** `export * from "mod" */
364
- 'None';
374
+ export type ExportExportNameKind = 'Name' | 'Default' | 'None'
365
375
 
366
376
  export interface ExportImportName {
367
377
  kind: ExportImportNameKind
@@ -370,14 +380,7 @@ export interface ExportImportName {
370
380
  end: number | null
371
381
  }
372
382
 
373
- export type ExportImportNameKind = /** `export { name } */
374
- 'Name'|
375
- /** `export * as ns from "mod"` */
376
- 'All'|
377
- /** `export * from "mod"` */
378
- 'AllButDefault'|
379
- /** Does not have a specifier. */
380
- 'None';
383
+ export type ExportImportNameKind = 'Name' | 'All' | 'AllButDefault' | 'None'
381
384
 
382
385
  export interface ExportLocalName {
383
386
  kind: ExportLocalNameKind
@@ -386,15 +389,7 @@ export interface ExportLocalName {
386
389
  end: number | null
387
390
  }
388
391
 
389
- export type ExportLocalNameKind = /** `export { name } */
390
- 'Name'|
391
- /** `export default expression` */
392
- 'Default'|
393
- /**
394
- * If the exported value is not locally accessible from within the module.
395
- * `export default function () {}`
396
- */
397
- 'None';
392
+ export type ExportLocalNameKind = 'Name' | 'Default' | 'None'
398
393
 
399
394
  export interface ImportName {
400
395
  kind: ImportNameKind
@@ -403,12 +398,7 @@ export interface ImportName {
403
398
  end: number | null
404
399
  }
405
400
 
406
- export type ImportNameKind = /** `import { x } from "mod"` */
407
- 'Name'|
408
- /** `import * as ns from "mod"` */
409
- 'NamespaceObject'|
410
- /** `import defaultExport from "mod"` */
411
- 'Default';
401
+ export type ImportNameKind = 'Name' | 'NamespaceObject' | 'Default'
412
402
 
413
403
  /**
414
404
  * Parse JS/TS source asynchronously on a separate thread.
@@ -579,6 +569,7 @@ export interface ValueSpan {
579
569
  start: number
580
570
  end: number
581
571
  }
572
+
582
573
  export declare class ResolverFactory {
583
574
  constructor(options?: NapiResolveOptions | undefined | null)
584
575
  static default(): ResolverFactory
@@ -641,14 +632,10 @@ export interface Builtin {
641
632
  export declare enum EnforceExtension {
642
633
  Auto = 0,
643
634
  Enabled = 1,
644
- Disabled = 2
635
+ Disabled = 2,
645
636
  }
646
637
 
647
- export type ModuleType = 'module'|
648
- 'commonjs'|
649
- 'json'|
650
- 'wasm'|
651
- 'addon';
638
+ export type ModuleType = 'module' | 'commonjs' | 'json' | 'wasm' | 'addon'
652
639
 
653
640
  /**
654
641
  * Module Resolution Options
@@ -886,6 +873,7 @@ export interface TsconfigOptions {
886
873
  */
887
874
  references?: 'auto'
888
875
  }
876
+
889
877
  export interface SourceMap {
890
878
  file?: string
891
879
  mappings: string
@@ -896,6 +884,7 @@ export interface SourceMap {
896
884
  version: number
897
885
  x_google_ignoreList?: Array<number>
898
886
  }
887
+
899
888
  export interface ArrowFunctionsOptions {
900
889
  /**
901
890
  * This option enables the following:
@@ -997,27 +986,7 @@ export interface Es2015Options {
997
986
  arrowFunction?: ArrowFunctionsOptions
998
987
  }
999
988
 
1000
- export type HelperMode = /**
1001
- * Runtime mode (default): Helper functions are imported from a runtime package.
1002
- *
1003
- * Example:
1004
- *
1005
- * ```js
1006
- * import helperName from "@oxc-project/runtime/helpers/helperName";
1007
- * helperName(...arguments);
1008
- * ```
1009
- */
1010
- 'Runtime'|
1011
- /**
1012
- * External mode: Helper functions are accessed from a global `babelHelpers` object.
1013
- *
1014
- * Example:
1015
- *
1016
- * ```js
1017
- * babelHelpers.helperName(...arguments);
1018
- * ```
1019
- */
1020
- 'External';
989
+ export type HelperMode = 'Runtime' | 'External'
1021
990
 
1022
991
  export interface Helpers {
1023
992
  mode?: HelperMode
@@ -1545,6 +1514,7 @@ export interface TypeScriptOptions {
1545
1514
  */
1546
1515
  rewriteImportExtensions?: 'rewrite' | 'remove' | boolean
1547
1516
  }
1517
+
1548
1518
  export declare class BindingBundleEndEventData {
1549
1519
  output: string
1550
1520
  duration: number
@@ -1928,6 +1898,13 @@ export declare class TsconfigCache {
1928
1898
  size(): number
1929
1899
  }
1930
1900
 
1901
+ /**
1902
+ * Panics on purpose. CI calls this to check that a published binding can produce a
1903
+ * symbolicated backtrace from its separately published debug info.
1904
+ * See `scripts/misc/verify-debuginfo.mjs` and internal-docs/panic-symbolication/implementation.md
1905
+ */
1906
+ export declare function __internalForcePanic(): void
1907
+
1931
1908
  export interface AliasItem {
1932
1909
  find: string
1933
1910
  replacements: Array<string | undefined | null>
@@ -1940,7 +1917,7 @@ export interface BindingAssetSource {
1940
1917
  export declare enum BindingAttachDebugInfo {
1941
1918
  None = 0,
1942
1919
  Simple = 1,
1943
- Full = 2
1920
+ Full = 2,
1944
1921
  }
1945
1922
 
1946
1923
  export interface BindingBuiltinPlugin {
@@ -1948,24 +1925,7 @@ export interface BindingBuiltinPlugin {
1948
1925
  options?: unknown
1949
1926
  }
1950
1927
 
1951
- export type BindingBuiltinPluginName = 'builtin:bundle-analyzer'|
1952
- 'builtin:esm-external-require'|
1953
- 'builtin:isolated-declaration'|
1954
- 'builtin:replace'|
1955
- 'builtin:vite-alias'|
1956
- 'builtin:vite-build-import-analysis'|
1957
- 'builtin:vite-dynamic-import-vars'|
1958
- 'builtin:vite-import-glob'|
1959
- 'builtin:vite-json'|
1960
- 'builtin:vite-load-fallback'|
1961
- 'builtin:vite-manifest'|
1962
- 'builtin:vite-module-preload-polyfill'|
1963
- 'builtin:vite-react-refresh-wrapper'|
1964
- 'builtin:vite-reporter'|
1965
- 'builtin:vite-resolve'|
1966
- 'builtin:vite-transform'|
1967
- 'builtin:vite-web-worker-post'|
1968
- 'builtin:oxc-runtime';
1928
+ export type BindingBuiltinPluginName = 'builtin:bundle-analyzer' | 'builtin:esm-external-require' | 'builtin:isolated-declaration' | 'builtin:replace' | 'builtin:vite-alias' | 'builtin:vite-build-import-analysis' | 'builtin:vite-dynamic-import-vars' | 'builtin:vite-import-glob' | 'builtin:vite-json' | 'builtin:vite-load-fallback' | 'builtin:vite-manifest' | 'builtin:vite-module-preload-polyfill' | 'builtin:vite-react-refresh-wrapper' | 'builtin:vite-reporter' | 'builtin:vite-resolve' | 'builtin:vite-transform' | 'builtin:vite-web-worker-post' | 'builtin:oxc-runtime'
1969
1929
 
1970
1930
  export interface BindingBundleAnalyzerPluginConfig {
1971
1931
  /** Output filename for the bundle analysis data (default: "analyze-data.json") */
@@ -2004,6 +1964,7 @@ export interface BindingChecksOptions {
2004
1964
  unresolvedEntry?: boolean
2005
1965
  unresolvedImport?: boolean
2006
1966
  filenameConflict?: boolean
1967
+ moduleLevelDirective?: boolean
2007
1968
  commonJsVariableInEsm?: boolean
2008
1969
  importIsUndefined?: boolean
2009
1970
  emptyImportMeta?: boolean
@@ -2028,7 +1989,7 @@ export interface BindingChunkImportMap {
2028
1989
 
2029
1990
  export declare enum BindingChunkModuleOrderBy {
2030
1991
  ModuleId = 0,
2031
- ExecOrder = 1
1992
+ ExecOrder = 1,
2032
1993
  }
2033
1994
 
2034
1995
  export interface BindingChunkOptimizationOptions {
@@ -2084,6 +2045,7 @@ export interface BindingDevOptions {
2084
2045
  onAdditionalAssets?: undefined | ((output: BindingOutputs) => void | Promise<void>)
2085
2046
  rebuildStrategy?: BindingRebuildStrategy
2086
2047
  watch?: BindingDevWatchOptions
2048
+ hotUpdate?: boolean
2087
2049
  }
2088
2050
 
2089
2051
  export interface BindingDevtoolsOptions {
@@ -2258,8 +2220,8 @@ export interface BindingEnhancedTransformResult {
2258
2220
  }
2259
2221
 
2260
2222
  export type BindingError =
2261
- | { type: 'JsError', field0: Error }
2262
- | { type: 'NativeError', field0: NativeError }
2223
+ | { type: 'JsError'; field0: Error }
2224
+ | { type: 'NativeError'; field0: NativeError }
2263
2225
 
2264
2226
  export interface BindingErrors {
2265
2227
  errors: Array<BindingError>
@@ -2275,8 +2237,7 @@ export interface BindingErrors {
2275
2237
  * on the next page load (HMR generation may itself be buggy). See
2276
2238
  * `internal-docs/dev-engine/implementation.md` §12.
2277
2239
  */
2278
- export type BindingErrorStage = 'Hmr'|
2279
- 'Rebuild';
2240
+ export type BindingErrorStage = 'Hmr' | 'Rebuild'
2280
2241
 
2281
2242
  export interface BindingEsmExternalRequirePluginConfig {
2282
2243
  external: Array<BindingStringOrRegex>
@@ -2317,14 +2278,14 @@ export interface BindingGeneratedCodeOptions {
2317
2278
  }
2318
2279
 
2319
2280
  export type BindingHmrUpdate =
2320
- | { type: 'Patch', code: string, filename: string, sourcemap?: string, sourcemapFilename?: string, /**
2321
- * Stable ids of the changed modules — the `changedIds` of the push envelope.
2322
- * The client walks from these on its own graph.
2323
- */
2324
- changedIds: Array<string>, /** Per-client envelope sequence number. */
2325
- seq: number }
2326
- | { type: 'FullReload', reason?: string }
2327
- | { type: 'Noop' }
2281
+ | { type: 'Patch'; code: string; filename: string; sourcemap?: string; sourcemapFilename?: string; /**
2282
+ * Stable ids of the changed modules — the `changedIds` of the push envelope.
2283
+ * The client walks from these on its own graph.
2284
+ */
2285
+ changedIds: Array<string>; /** Per-client envelope sequence number. */
2286
+ seq: number }
2287
+ | { type: 'FullReload'; reason?: string }
2288
+ | { type: 'Noop' }
2328
2289
 
2329
2290
  export interface BindingHookFilter {
2330
2291
  value?: Array<Array<BindingFilterToken>>
@@ -2419,8 +2380,7 @@ export interface BindingHookResolveIdOutput {
2419
2380
  packageJsonPath?: string | null
2420
2381
  }
2421
2382
 
2422
- export type BindingHookSideEffects =
2423
- boolean | string
2383
+ export type BindingHookSideEffects = boolean | string
2424
2384
 
2425
2385
  export interface BindingHookTransformOutput {
2426
2386
  code?: string
@@ -2445,8 +2405,7 @@ export interface BindingIndentOptions {
2445
2405
  exclude?: Array<Array<number>> | Array<number>
2446
2406
  }
2447
2407
 
2448
- export type BindingInjectImport =
2449
- BindingInjectImportNamed | BindingInjectImportNamespace
2408
+ export type BindingInjectImport = BindingInjectImportNamed | BindingInjectImportNamespace
2450
2409
 
2451
2410
  export interface BindingInjectImportNamed {
2452
2411
  tagNamed: true
@@ -2557,7 +2516,7 @@ export declare enum BindingLogLevel {
2557
2516
  Silent = 0,
2558
2517
  Warn = 1,
2559
2518
  Info = 2,
2560
- Debug = 3
2519
+ Debug = 3,
2561
2520
  }
2562
2521
 
2563
2522
  export interface BindingLogLocation {
@@ -2576,7 +2535,7 @@ export interface BindingMagicStringOptions {
2576
2535
  }
2577
2536
 
2578
2537
  export type BindingMakeAbsoluteExternalsRelative =
2579
- | { type: 'Bool', field0: boolean }
2538
+ | { type: 'Bool'; field0: boolean }
2580
2539
  | { type: 'IfRelativeSource' }
2581
2540
 
2582
2541
  export interface BindingManualCodeSplittingOptions {
@@ -2587,6 +2546,7 @@ export interface BindingManualCodeSplittingOptions {
2587
2546
  maxSize?: number
2588
2547
  minModuleSize?: number
2589
2548
  maxModuleSize?: number
2549
+ internalInvalidateModuleInfoCache?: () => void
2590
2550
  }
2591
2551
 
2592
2552
  export interface BindingMatchGroup {
@@ -2779,7 +2739,7 @@ export interface BindingPluginOptions {
2779
2739
 
2780
2740
  export declare enum BindingPluginOrder {
2781
2741
  Pre = 0,
2782
- Post = 1
2742
+ Post = 1,
2783
2743
  }
2784
2744
 
2785
2745
  /**
@@ -2823,22 +2783,22 @@ export interface BindingPreRenderedAsset {
2823
2783
  }
2824
2784
 
2825
2785
  export type BindingPreserveEntrySignatures =
2826
- | { type: 'Bool', field0: boolean }
2827
- | { type: 'String', field0: string }
2786
+ | { type: 'Bool'; field0: boolean }
2787
+ | { type: 'String'; field0: string }
2828
2788
 
2829
2789
  export declare enum BindingPropertyReadSideEffects {
2830
2790
  Always = 0,
2831
- False = 1
2791
+ False = 1,
2832
2792
  }
2833
2793
 
2834
2794
  export declare enum BindingPropertyWriteSideEffects {
2835
2795
  Always = 0,
2836
- False = 1
2796
+ False = 1,
2837
2797
  }
2838
2798
 
2839
2799
  export declare enum BindingRebuildStrategy {
2840
2800
  Always = 0,
2841
- Never = 1
2801
+ Never = 1,
2842
2802
  }
2843
2803
 
2844
2804
  export interface BindingReplacePluginConfig {
@@ -2849,8 +2809,7 @@ export interface BindingReplacePluginConfig {
2849
2809
  sourcemap?: boolean
2850
2810
  }
2851
2811
 
2852
- export type BindingResolvedExternal =
2853
- boolean | string
2812
+ export type BindingResolvedExternal = boolean | string
2854
2813
 
2855
2814
  export interface BindingResolveOptions {
2856
2815
  alias?: Array<AliasItem>
@@ -3001,8 +2960,7 @@ export interface BindingViteJsonPluginConfig {
3001
2960
  stringify?: BindingViteJsonPluginStringify
3002
2961
  }
3003
2962
 
3004
- export type BindingViteJsonPluginStringify =
3005
- boolean | string
2963
+ export type BindingViteJsonPluginStringify = boolean | string
3006
2964
 
3007
2965
  export interface BindingViteManifestPluginConfig {
3008
2966
  root: string
@@ -3118,18 +3076,7 @@ export interface ExternalMemoryStatus {
3118
3076
  reason?: string
3119
3077
  }
3120
3078
 
3121
- export type FilterTokenKind = 'Id'|
3122
- 'ImporterId'|
3123
- 'Code'|
3124
- 'ModuleType'|
3125
- 'And'|
3126
- 'Or'|
3127
- 'Not'|
3128
- 'Include'|
3129
- 'Exclude'|
3130
- 'CleanUrl'|
3131
- 'QueryKey'|
3132
- 'QueryValue';
3079
+ export type FilterTokenKind = 'Id' | 'ImporterId' | 'Code' | 'ModuleType' | 'And' | 'Or' | 'Not' | 'Include' | 'Exclude' | 'CleanUrl' | 'QueryKey' | 'QueryValue'
3133
3080
 
3134
3081
  /**
3135
3082
  * Returns the Rust-side allocator counters, or `None` when this binding was
Binary file
@@ -23,10 +23,9 @@ const handler = new MessageHandler({
23
23
  // eslint-disable-next-line no-console
24
24
  console.log.apply(console, arguments)
25
25
  },
26
- printErr: function() {
26
+ printErr: function () {
27
27
  // eslint-disable-next-line no-console
28
28
  console.error.apply(console, arguments)
29
-
30
29
  errorOutputs.push([...arguments])
31
30
  },
32
31
  })
package/wasi-worker.mjs CHANGED
@@ -1,10 +1,10 @@
1
- import fs from "node:fs";
2
- import { createRequire } from "node:module";
3
- import { parse } from "node:path";
4
- import { WASI } from "node:wasi";
5
- import { parentPort, Worker } from "node:worker_threads";
1
+ import fs from 'node:fs'
2
+ import { createRequire } from 'node:module'
3
+ import { parse } from 'node:path'
4
+ import { WASI } from 'node:wasi'
5
+ import { parentPort, Worker, workerData } from 'node:worker_threads'
6
6
 
7
- const require = createRequire(import.meta.url);
7
+ const require = createRequire(import.meta.url)
8
8
 
9
9
  const {
10
10
  instantiateNapiModuleSync,
@@ -12,12 +12,12 @@ const {
12
12
  getDefaultContext,
13
13
  emnapiAsyncWorkPlugin,
14
14
  emnapiTSFNPlugin,
15
- } = require("@napi-rs/wasm-runtime");
15
+ } = require('@napi-rs/wasm-runtime')
16
16
 
17
17
  if (parentPort) {
18
- parentPort.on("message", (data) => {
19
- globalThis.onmessage({ data });
20
- });
18
+ parentPort.on('message', (data) => {
19
+ globalThis.onmessage({ data })
20
+ })
21
21
  }
22
22
 
23
23
  Object.assign(globalThis, {
@@ -25,18 +25,25 @@ Object.assign(globalThis, {
25
25
  require,
26
26
  Worker,
27
27
  importScripts: function (f) {
28
- ;(0, eval)(fs.readFileSync(f, "utf8") + "//# sourceURL=" + f);
28
+ // oxlint-disable-next-line no-eval -- WASI importScripts polyfill
29
+ ;(0, eval)(fs.readFileSync(f, 'utf8') + '//# sourceURL=' + f)
29
30
  },
30
31
  postMessage: function (msg) {
31
32
  if (parentPort) {
32
- parentPort.postMessage(msg);
33
+ parentPort.postMessage(msg)
33
34
  }
34
35
  },
35
- });
36
+ })
36
37
 
37
- const emnapiContext = getDefaultContext();
38
+ const emnapiContext = getDefaultContext()
38
39
 
39
- const __rootDir = parse(process.cwd()).root;
40
+ const __cwd = process.cwd()
41
+ const __rootDir =
42
+ (workerData && typeof workerData.rootDir === 'string' && workerData.rootDir) ||
43
+ parse(__cwd).root
44
+ const __hostRoot =
45
+ (workerData && typeof workerData.hostRoot === 'string' && workerData.hostRoot) ||
46
+ (process.platform === 'android' ? __cwd : __rootDir)
40
47
 
41
48
  const handler = new MessageHandler({
42
49
  onLoad({ wasmModule, wasmMemory }) {
@@ -44,9 +51,10 @@ const handler = new MessageHandler({
44
51
  version: 'preview1',
45
52
  env: process.env,
46
53
  preopens: {
47
- [__rootDir]: __rootDir,
54
+ [__rootDir]: __hostRoot,
55
+ [__hostRoot]: __hostRoot,
48
56
  },
49
- });
57
+ })
50
58
 
51
59
  return instantiateNapiModuleSync(wasmModule, {
52
60
  childThread: true,
@@ -62,13 +70,13 @@ const handler = new MessageHandler({
62
70
  ...importObject.env,
63
71
  ...importObject.napi,
64
72
  ...importObject.emnapi,
65
- memory: wasmMemory
66
- };
73
+ memory: wasmMemory,
74
+ }
67
75
  },
68
- });
76
+ })
69
77
  },
70
- });
78
+ })
71
79
 
72
80
  globalThis.onmessage = function (e) {
73
- handler.handle(e);
74
- };
81
+ handler.handle(e)
82
+ }