@napi-rs/cli 3.0.0-alpha.1 → 3.0.0-alpha.10

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 (177) hide show
  1. package/dist/api/artifacts.js +5 -2
  2. package/dist/api/artifacts.js.map +1 -0
  3. package/dist/api/build.d.ts +1 -1
  4. package/dist/api/build.js +129 -35
  5. package/dist/api/build.js.map +1 -0
  6. package/dist/api/create-npm-dirs.js +1 -0
  7. package/dist/api/create-npm-dirs.js.map +1 -0
  8. package/dist/api/load-wasi-template.d.ts +1 -0
  9. package/dist/api/load-wasi-template.js +60 -0
  10. package/dist/api/load-wasi-template.js.map +1 -0
  11. package/dist/api/new.js +2 -1
  12. package/dist/api/new.js.map +1 -0
  13. package/dist/api/pre-publish.js +1 -0
  14. package/dist/api/pre-publish.js.map +1 -0
  15. package/dist/api/rename.js +1 -0
  16. package/dist/api/rename.js.map +1 -0
  17. package/dist/api/templates/.gitignore.d.ts +1 -1
  18. package/dist/api/templates/.gitignore.js +2 -0
  19. package/dist/api/templates/.gitignore.js.map +1 -0
  20. package/dist/api/templates/.npmignore.js +1 -0
  21. package/dist/api/templates/.npmignore.js.map +1 -0
  22. package/dist/api/templates/build.rs.js +1 -0
  23. package/dist/api/templates/build.rs.js.map +1 -0
  24. package/dist/api/templates/cargo.toml.js +1 -0
  25. package/dist/api/templates/cargo.toml.js.map +1 -0
  26. package/dist/api/templates/ci-template.js +69 -57
  27. package/dist/api/templates/ci-template.js.map +1 -0
  28. package/dist/api/templates/ci.yml.d.ts +1 -1
  29. package/dist/api/templates/ci.yml.js +10 -3
  30. package/dist/api/templates/ci.yml.js.map +1 -0
  31. package/dist/api/templates/index.js +1 -0
  32. package/dist/api/templates/index.js.map +1 -0
  33. package/dist/api/templates/js-binding.d.ts +1 -1
  34. package/dist/api/templates/js-binding.js +278 -109
  35. package/dist/api/templates/js-binding.js.map +1 -0
  36. package/dist/api/templates/lib.rs.js +2 -4
  37. package/dist/api/templates/lib.rs.js.map +1 -0
  38. package/dist/api/templates/package.json.js +30 -28
  39. package/dist/api/templates/package.json.js.map +1 -0
  40. package/dist/api/universalize.js +1 -0
  41. package/dist/api/universalize.js.map +1 -0
  42. package/dist/api/version.js +1 -0
  43. package/dist/api/version.js.map +1 -0
  44. package/dist/api/wasi-worker-template.d.ts +1 -0
  45. package/dist/api/wasi-worker-template.js +53 -0
  46. package/dist/api/wasi-worker-template.js.map +1 -0
  47. package/dist/cli.js +1 -0
  48. package/dist/cli.js.map +1 -0
  49. package/dist/commands/artifacts.js +1 -0
  50. package/dist/commands/artifacts.js.map +1 -0
  51. package/dist/commands/build.js +1 -0
  52. package/dist/commands/build.js.map +1 -0
  53. package/dist/commands/create-npm-dirs.js +1 -0
  54. package/dist/commands/create-npm-dirs.js.map +1 -0
  55. package/dist/commands/help.js +1 -0
  56. package/dist/commands/help.js.map +1 -0
  57. package/dist/commands/new.js +2 -4
  58. package/dist/commands/new.js.map +1 -0
  59. package/dist/commands/pre-publish.js +1 -0
  60. package/dist/commands/pre-publish.js.map +1 -0
  61. package/dist/commands/rename.js +1 -0
  62. package/dist/commands/rename.js.map +1 -0
  63. package/dist/commands/universalize.js +1 -0
  64. package/dist/commands/universalize.js.map +1 -0
  65. package/dist/commands/version.js +1 -0
  66. package/dist/commands/version.js.map +1 -0
  67. package/dist/def/artifacts.js +1 -0
  68. package/dist/def/artifacts.js.map +1 -0
  69. package/dist/def/build.d.ts +18 -0
  70. package/dist/def/build.js +13 -0
  71. package/dist/def/build.js.map +1 -0
  72. package/dist/def/create-npm-dirs.js +1 -0
  73. package/dist/def/create-npm-dirs.js.map +1 -0
  74. package/dist/def/new.js +1 -0
  75. package/dist/def/new.js.map +1 -0
  76. package/dist/def/pre-publish.js +1 -0
  77. package/dist/def/pre-publish.js.map +1 -0
  78. package/dist/def/rename.js +1 -0
  79. package/dist/def/rename.js.map +1 -0
  80. package/dist/def/universalize.js +1 -0
  81. package/dist/def/universalize.js.map +1 -0
  82. package/dist/def/version.js +1 -0
  83. package/dist/def/version.js.map +1 -0
  84. package/dist/index.cjs +3205 -7977
  85. package/dist/index.d.ts +1 -0
  86. package/dist/index.js +2 -0
  87. package/dist/index.js.map +1 -0
  88. package/dist/utils/__tests__/target.spec.js +1 -0
  89. package/dist/utils/__tests__/target.spec.js.map +1 -0
  90. package/dist/utils/__tests__/typegen.spec.js +9 -4
  91. package/dist/utils/__tests__/typegen.spec.js.map +1 -0
  92. package/dist/utils/__tests__/version.spec.js +1 -0
  93. package/dist/utils/__tests__/version.spec.js.map +1 -0
  94. package/dist/utils/cargo.js +1 -0
  95. package/dist/utils/cargo.js.map +1 -0
  96. package/dist/utils/ci.js +10 -0
  97. package/dist/utils/ci.js.map +1 -0
  98. package/dist/utils/config.d.ts +14 -2
  99. package/dist/utils/config.js +4 -3
  100. package/dist/utils/config.js.map +1 -0
  101. package/dist/utils/index.js +1 -0
  102. package/dist/utils/index.js.map +1 -0
  103. package/dist/utils/log.js +1 -0
  104. package/dist/utils/log.js.map +1 -0
  105. package/dist/utils/metadata.js +1 -0
  106. package/dist/utils/metadata.js.map +1 -0
  107. package/dist/utils/misc.js +7 -1
  108. package/dist/utils/misc.js.map +1 -0
  109. package/dist/utils/target.d.ts +6 -5
  110. package/dist/utils/target.js +14 -2
  111. package/dist/utils/target.js.map +1 -0
  112. package/dist/utils/typegen.d.ts +4 -1
  113. package/dist/utils/typegen.js +27 -6
  114. package/dist/utils/typegen.js.map +1 -0
  115. package/dist/utils/version.js +3 -2
  116. package/dist/utils/version.js.map +1 -0
  117. package/package.json +47 -15
  118. package/src/api/artifacts.ts +7 -4
  119. package/src/api/build.ts +180 -44
  120. package/src/api/load-wasi-template.ts +62 -0
  121. package/src/api/new.ts +1 -4
  122. package/src/api/pre-publish.ts +8 -5
  123. package/src/api/templates/.gitignore.ts +1 -0
  124. package/src/api/templates/ci-template.ts +68 -57
  125. package/src/api/templates/ci.yml.ts +9 -6
  126. package/src/api/templates/js-binding.ts +270 -104
  127. package/src/api/templates/lib.rs.ts +1 -4
  128. package/src/api/templates/package.json.ts +31 -27
  129. package/src/api/wasi-worker-template.ts +52 -0
  130. package/src/commands/new.ts +1 -5
  131. package/src/def/build.ts +28 -0
  132. package/src/index.ts +2 -0
  133. package/src/utils/__tests__/__snapshots__/target.spec.ts.md +7 -0
  134. package/src/utils/__tests__/__snapshots__/target.spec.ts.snap +0 -0
  135. package/src/utils/__tests__/__snapshots__/typegen.spec.ts.md +555 -0
  136. package/src/utils/__tests__/__snapshots__/typegen.spec.ts.snap +0 -0
  137. package/src/utils/__tests__/__snapshots__/version.spec.ts.md +7 -7
  138. package/src/utils/__tests__/__snapshots__/version.spec.ts.snap +0 -0
  139. package/src/utils/__tests__/typegen.spec.ts +19 -4
  140. package/src/utils/ci.ts +9 -0
  141. package/src/utils/config.ts +21 -5
  142. package/src/utils/misc.ts +6 -1
  143. package/src/utils/target.ts +21 -9
  144. package/src/utils/typegen.ts +30 -5
  145. package/src/utils/version.ts +1 -1
  146. package/dist/def/commands/artifacts.d.ts +0 -15
  147. package/dist/def/commands/artifacts.js +0 -29
  148. package/dist/def/commands/build.d.ts +0 -53
  149. package/dist/def/commands/build.js +0 -105
  150. package/dist/def/commands/create-npm-dirs.d.ts +0 -15
  151. package/dist/def/commands/create-npm-dirs.js +0 -29
  152. package/dist/def/commands/new.d.ts +0 -27
  153. package/dist/def/commands/new.js +0 -53
  154. package/dist/def/commands/pre-publish.d.ts +0 -23
  155. package/dist/def/commands/pre-publish.js +0 -45
  156. package/dist/def/commands/rename.d.ts +0 -25
  157. package/dist/def/commands/rename.js +0 -49
  158. package/dist/def/commands/universalize.d.ts +0 -13
  159. package/dist/def/commands/universalize.js +0 -25
  160. package/dist/def/commands/version.d.ts +0 -13
  161. package/dist/def/commands/version.js +0 -25
  162. package/dist/def/options/artifacts.d.ts +0 -35
  163. package/dist/def/options/artifacts.js +0 -11
  164. package/dist/def/options/build.d.ts +0 -97
  165. package/dist/def/options/build.js +0 -3
  166. package/dist/def/options/create-npm-dirs.d.ts +0 -35
  167. package/dist/def/options/create-npm-dirs.js +0 -11
  168. package/dist/def/options/new.d.ts +0 -79
  169. package/dist/def/options/new.js +0 -15
  170. package/dist/def/options/pre-publish.d.ts +0 -65
  171. package/dist/def/options/pre-publish.js +0 -13
  172. package/dist/def/options/rename.d.ts +0 -75
  173. package/dist/def/options/rename.js +0 -11
  174. package/dist/def/options/universalize.d.ts +0 -28
  175. package/dist/def/options/universalize.js +0 -10
  176. package/dist/def/options/version.d.ts +0 -28
  177. package/dist/def/options/version.js +0 -10
package/src/api/build.ts CHANGED
@@ -1,7 +1,8 @@
1
- import { spawn } from 'child_process'
2
- import { createHash } from 'crypto'
3
- import { tmpdir } from 'os'
4
- import { parse, join, resolve } from 'path'
1
+ import { spawn } from 'node:child_process'
2
+ import { createHash } from 'node:crypto'
3
+ import { createRequire } from 'node:module'
4
+ import { tmpdir } from 'node:os'
5
+ import { parse, join, resolve } from 'node:path'
5
6
 
6
7
  import * as colors from 'colorette'
7
8
 
@@ -20,6 +21,7 @@ import {
20
21
  parseMetadata,
21
22
  parseTriple,
22
23
  processTypeDef,
24
+ readFileAsync,
23
25
  readNapiConfig,
24
26
  Target,
25
27
  targetToEnvVar,
@@ -28,11 +30,14 @@ import {
28
30
  writeFileAsync,
29
31
  } from '../utils/index.js'
30
32
 
31
- import { createJsBinding } from './templates/index.js'
33
+ import { createWasiBinding } from './load-wasi-template.js'
34
+ import { createCjsBinding } from './templates/index.js'
35
+ import { WASI_WORKER_TEMPLATE } from './wasi-worker-template.js'
32
36
 
33
37
  const debug = debugFactory('build')
38
+ const require = createRequire(import.meta.url)
34
39
 
35
- type OutputKind = 'js' | 'dts' | 'node' | 'exe'
40
+ type OutputKind = 'js' | 'dts' | 'node' | 'exe' | 'wasm'
36
41
  type Output = {
37
42
  kind: OutputKind
38
43
  path: string
@@ -76,8 +81,8 @@ export async function buildProject(options: BuildOptions) {
76
81
  options.target
77
82
  ? parseTriple(options.target)
78
83
  : process.env.CARGO_BUILD_TARGET
79
- ? parseTriple(process.env.CARGO_BUILD_TARGET)
80
- : getSystemDefaultTarget(),
84
+ ? parseTriple(process.env.CARGO_BUILD_TARGET)
85
+ : getSystemDefaultTarget(),
81
86
  crateDir,
82
87
  resolvePath(options.outputDir ?? crateDir),
83
88
  options.targetDir ??
@@ -149,13 +154,16 @@ class Builder {
149
154
 
150
155
  const controller = new AbortController()
151
156
 
157
+ const watch = this.options.watch
152
158
  const buildTask = new Promise<void>((resolve, reject) => {
153
- const buildProcess = spawn('cargo', this.args, {
159
+ const command =
160
+ process.env.CARGO ?? (this.options.useCross ? 'cross' : 'cargo')
161
+ const buildProcess = spawn(command, this.args, {
154
162
  env: {
155
163
  ...process.env,
156
164
  ...this.envs,
157
165
  },
158
- stdio: 'inherit',
166
+ stdio: watch ? ['inherit', 'inherit', 'pipe'] : 'inherit',
159
167
  cwd: this.cwd,
160
168
  signal: controller.signal,
161
169
  })
@@ -176,6 +184,15 @@ class Builder {
176
184
  }),
177
185
  )
178
186
  })
187
+
188
+ // watch mode only, they are piped through stderr
189
+ buildProcess.stderr?.on('data', (data) => {
190
+ const output = data.toString()
191
+ console.error(output)
192
+ if (/Finished\s(dev|release)/.test(output)) {
193
+ this.postBuild().catch(() => {})
194
+ }
195
+ })
179
196
  })
180
197
 
181
198
  return {
@@ -205,6 +222,7 @@ class Builder {
205
222
  this.crateDir,
206
223
  '--',
207
224
  'cargo',
225
+ 'build',
208
226
  )
209
227
  set = true
210
228
  }
@@ -297,6 +315,10 @@ class Builder {
297
315
  private setEnvs() {
298
316
  // type definition intermediate file
299
317
  this.envs.TYPE_DEF_TMP_PATH = this.getIntermediateTypeFile()
318
+ // WASI register intermediate file
319
+ this.envs.WASI_REGISTER_TMP_PATH = this.getIntermediateWasiRegisterFile()
320
+ // TODO:
321
+ // remove after napi-derive@v3 release
300
322
  this.envs.CARGO_CFG_NAPI_RS_CLI_VERSION = CLI_VERSION
301
323
 
302
324
  // RUSTFLAGS
@@ -320,13 +342,18 @@ class Builder {
320
342
  // END RUSTFLAGS
321
343
 
322
344
  // LINKER
323
- const linker = getTargetLinker(this.target.triple)
324
- if (
325
- linker &&
326
- !process.env.RUSTC_LINKER &&
327
- !process.env[`CARGET_TARGET_${targetToEnvVar(this.target.triple)}_LINKER`]
328
- ) {
329
- this.envs.RUSTC_LINKER = linker
345
+ const linker = this.options.crossCompile
346
+ ? void 0
347
+ : getTargetLinker(this.target.triple)
348
+ // TODO:
349
+ // directly set CARGO_TARGET_<target>_LINKER will cover .cargo/config.toml
350
+ // will detect by cargo config when it becomes stable
351
+ // see: https://github.com/rust-lang/cargo/issues/9301
352
+ const linkerEnv = `CARGO_TARGET_${targetToEnvVar(
353
+ this.target.triple,
354
+ )}_LINKER`
355
+ if (linker && !process.env[linkerEnv]) {
356
+ this.envs[linkerEnv] = linker
330
357
  }
331
358
 
332
359
  if (this.target.platform === 'android') {
@@ -342,18 +369,35 @@ class Builder {
342
369
  const targetArch = this.target.arch === 'arm' ? 'armv7a' : 'aarch64'
343
370
  const targetPlatform =
344
371
  this.target.arch === 'arm' ? 'androideabi24' : 'android24'
372
+ const hostPlatform =
373
+ process.platform === 'darwin'
374
+ ? 'darwin'
375
+ : process.platform === 'win32'
376
+ ? 'windows'
377
+ : 'linux'
345
378
  Object.assign(this.envs, {
346
- CARGO_TARGET_AARCH64_LINUX_ANDROID_LINKER: `${ANDROID_NDK_LATEST_HOME}/toolchains/llvm/prebuilt/linux-x86_64/bin/${targetArch}-linux-android24-clang`,
347
- CARGO_TARGET_ARMV7_LINUX_ANDROIDEABI_LINKER: `${ANDROID_NDK_LATEST_HOME}/toolchains/llvm/prebuilt/linux-x86_64/bin/${targetArch}-linux-androideabi24-clang`,
348
- CC: `${ANDROID_NDK_LATEST_HOME}/toolchains/llvm/prebuilt/linux-x86_64/bin/${targetArch}-linux-${targetPlatform}-clang`,
349
- CXX: `${ANDROID_NDK_LATEST_HOME}/toolchains/llvm/prebuilt/linux-x86_64/bin/${targetArch}-linux-${targetPlatform}-clang++`,
350
- AR: `${ANDROID_NDK_LATEST_HOME}/toolchains/llvm/prebuilt/linux-x86_64/bin/llvm-ar`,
379
+ CARGO_TARGET_AARCH64_LINUX_ANDROID_LINKER: `${ANDROID_NDK_LATEST_HOME}/toolchains/llvm/prebuilt/${hostPlatform}-x86_64/bin/${targetArch}-linux-android24-clang`,
380
+ CARGO_TARGET_ARMV7_LINUX_ANDROIDEABI_LINKER: `${ANDROID_NDK_LATEST_HOME}/toolchains/llvm/prebuilt/${hostPlatform}-x86_64/bin/${targetArch}-linux-androideabi24-clang`,
381
+ CC: `${ANDROID_NDK_LATEST_HOME}/toolchains/llvm/prebuilt/${hostPlatform}-x86_64/bin/${targetArch}-linux-${targetPlatform}-clang`,
382
+ CXX: `${ANDROID_NDK_LATEST_HOME}/toolchains/llvm/prebuilt/${hostPlatform}-x86_64/bin/${targetArch}-linux-${targetPlatform}-clang++`,
383
+ AR: `${ANDROID_NDK_LATEST_HOME}/toolchains/llvm/prebuilt/${hostPlatform}-x86_64/bin/llvm-ar`,
384
+ RANLIB: `${ANDROID_NDK_LATEST_HOME}/toolchains/llvm/prebuilt/${hostPlatform}-x86_64/bin/llvm-ranlib`,
351
385
  ANDROID_NDK: ANDROID_NDK_LATEST_HOME,
352
- PATH: `${ANDROID_NDK_LATEST_HOME}/toolchains/llvm/prebuilt/linux-x86_64/bin:${process.env.PATH}`,
386
+ PATH: `${ANDROID_NDK_LATEST_HOME}/toolchains/llvm/prebuilt/${hostPlatform}-x86_64/bin:${process.env.PATH}`,
353
387
  })
354
388
  }
355
389
  // END LINKER
356
390
 
391
+ if (this.target.platform === 'wasi') {
392
+ const emnapi = join(
393
+ require.resolve('emnapi'),
394
+ '..',
395
+ 'lib',
396
+ 'wasm32-wasi-threads',
397
+ )
398
+ this.envs.EMNAPI_LINK_DIR = emnapi
399
+ }
400
+
357
401
  debug('Set envs: ')
358
402
  Object.entries(this.envs).forEach(([k, v]) => {
359
403
  debug(' %i', `${k}=${v}`)
@@ -392,6 +436,10 @@ class Builder {
392
436
  this.args.push('--target-dir', this.options.targetDir)
393
437
  }
394
438
 
439
+ if (this.options.profile) {
440
+ this.args.push('--profile', this.options.profile)
441
+ }
442
+
395
443
  if (this.options.cargoOptions?.length) {
396
444
  this.args.push(...this.options.cargoOptions)
397
445
  }
@@ -410,6 +458,17 @@ class Builder {
410
458
  )
411
459
  }
412
460
 
461
+ private getIntermediateWasiRegisterFile() {
462
+ return join(
463
+ tmpdir(),
464
+ `${this.crate.name}-${createHash('sha256')
465
+ .update(this.crate.manifest_path)
466
+ .update(CLI_VERSION)
467
+ .digest('hex')
468
+ .substring(0, 8)}.napi_wasi_register.tmp`,
469
+ )
470
+ }
471
+
413
472
  private async postBuild() {
414
473
  try {
415
474
  debug(`Try to create output directory:`)
@@ -422,12 +481,39 @@ class Builder {
422
481
  })
423
482
  }
424
483
 
425
- await this.copyArtifact()
484
+ const dest = await this.copyArtifact()
426
485
 
427
486
  // only for cdylib
428
487
  if (this.cdyLibName) {
429
- await this.generateTypeDef()
430
- await this.writeJsBinding()
488
+ const idents = await this.generateTypeDef()
489
+ const intermediateWasiRegisterFile = this.envs.WASI_REGISTER_TMP_PATH
490
+ const wasiRegisterFunctions =
491
+ this.target.arch === 'wasm32'
492
+ ? JSON.parse(
493
+ await readFileAsync(intermediateWasiRegisterFile, 'utf8').catch(
494
+ (err) => {
495
+ console.warn(
496
+ `Read ${colors.yellowBright(
497
+ intermediateWasiRegisterFile,
498
+ )} failed, reason: ${err.message}`,
499
+ )
500
+ return `[]`
501
+ },
502
+ ),
503
+ )
504
+ : []
505
+ const jsOutput = await this.writeJsBinding(idents)
506
+ const wasmOutput = await this.writeWasiBinding(
507
+ wasiRegisterFunctions,
508
+ dest ?? 'index.wasm',
509
+ idents,
510
+ )
511
+ if (jsOutput) {
512
+ this.outputs.push(jsOutput)
513
+ }
514
+ if (wasmOutput) {
515
+ this.outputs.push(wasmOutput)
516
+ }
431
517
  }
432
518
 
433
519
  return this.outputs
@@ -439,12 +525,10 @@ class Builder {
439
525
  return
440
526
  }
441
527
 
442
- const src = join(
443
- this.targetDir,
444
- this.target.triple,
445
- this.options.release ? 'release' : 'debug',
446
- srcName,
447
- )
528
+ const profile =
529
+ this.options.profile ?? (this.options.release ? 'release' : 'debug')
530
+ const src = join(this.targetDir, this.target.triple, profile, srcName)
531
+ debug(`Copy artifact from: [${src}]`)
448
532
  const dest = join(this.outputDir, destName)
449
533
 
450
534
  try {
@@ -459,6 +543,7 @@ class Builder {
459
543
  kind: dest.endsWith('.node') ? 'node' : 'exe',
460
544
  path: dest,
461
545
  })
546
+ return dest
462
547
  } catch (e) {
463
548
  throw new Error('Failed to copy artifact', {
464
549
  cause: e,
@@ -474,8 +559,10 @@ class Builder {
474
559
  this.target.platform === 'darwin'
475
560
  ? `lib${cdyLib}.dylib`
476
561
  : this.target.platform === 'win32'
477
- ? `${cdyLib}.dll`
478
- : `lib${cdyLib}.so`
562
+ ? `${cdyLib}.dll`
563
+ : this.target.platform === 'wasi' || this.target.platform === 'wasm'
564
+ ? `${cdyLib}.wasm`
565
+ : `lib${cdyLib}.so`
479
566
 
480
567
  let destName = this.config.binaryName
481
568
  // add platform suffix to binary name
@@ -484,7 +571,11 @@ class Builder {
484
571
  if (this.options.platform) {
485
572
  destName += `.${this.target.platformArchABI}`
486
573
  }
487
- destName += '.node'
574
+ if (srcName.endsWith('.wasm')) {
575
+ destName += '.wasi-wasm32.wasm'
576
+ } else {
577
+ destName += '.node'
578
+ }
488
579
 
489
580
  return [srcName, destName]
490
581
  } else if (this.binName) {
@@ -499,13 +590,14 @@ class Builder {
499
590
 
500
591
  private async generateTypeDef() {
501
592
  if (!(await fileExists(this.envs.TYPE_DEF_TMP_PATH))) {
502
- return
593
+ return []
503
594
  }
504
595
 
505
596
  const dest = join(this.outputDir, this.options.dts ?? 'index.d.ts')
506
597
 
507
- const dts = await processTypeDef(
598
+ const { dts, exports } = await processTypeDef(
508
599
  this.envs.TYPE_DEF_TMP_PATH,
600
+ this.options.constEnum ?? true,
509
601
  !this.options.noDtsHeader
510
602
  ? this.options.dtsHeader ?? DEFAULT_TYPE_DEF_HEADER
511
603
  : '',
@@ -523,27 +615,71 @@ class Builder {
523
615
  debug.error('Failed to write type def file')
524
616
  debug.error(e as Error)
525
617
  }
618
+
619
+ return exports
526
620
  }
527
621
 
528
- private async writeJsBinding() {
529
- if (!this.options.platform || this.options.noJsBinding) {
622
+ private async writeJsBinding(idents: string[]) {
623
+ if (
624
+ !this.options.platform ||
625
+ // eslint-disable-next-line @typescript-eslint/prefer-nullish-coalescing
626
+ this.options.noJsBinding ||
627
+ idents.length === 0
628
+ ) {
530
629
  return
531
630
  }
532
631
 
533
- const dest = join(this.outputDir, this.options.jsBinding ?? 'index.js')
632
+ const name = parse(this.options.jsBinding ?? 'index.js').name
534
633
 
535
- const js = createJsBinding(this.config.binaryName, this.config.packageName)
634
+ const cjs = createCjsBinding(
635
+ this.config.binaryName,
636
+ this.config.packageName,
637
+ idents,
638
+ )
536
639
 
537
640
  try {
641
+ const dest = join(this.outputDir, `${name}.js`)
538
642
  debug('Writing js binding to:')
539
643
  debug(' %i', dest)
540
- await writeFileAsync(dest, js, 'utf-8')
541
- this.outputs.push({
644
+ await writeFileAsync(dest, cjs, 'utf-8')
645
+ return {
542
646
  kind: 'js',
543
647
  path: dest,
544
- })
648
+ } satisfies Output
545
649
  } catch (e) {
546
650
  throw new Error('Failed to write js binding file', { cause: e })
547
651
  }
548
652
  }
653
+
654
+ private async writeWasiBinding(
655
+ wasiRegisterFunctions: string[],
656
+ distFileName: string | undefined,
657
+ idents: string[],
658
+ ) {
659
+ if (distFileName && wasiRegisterFunctions.length) {
660
+ const { name, dir } = parse(distFileName)
661
+ const newPath = join(dir, `${this.config.binaryName}.wasi.cjs`)
662
+ const workerPath = join(dir, 'wasi-worker.mjs')
663
+ const declareCodes = `const { ${idents.join(
664
+ ', ',
665
+ )} } = __napiModule.exports\n`
666
+ const exportsCode = idents
667
+ .map((ident) => `module.exports.${ident} = ${ident}`)
668
+ .join(',\n')
669
+ await writeFileAsync(
670
+ newPath,
671
+ createWasiBinding(name, wasiRegisterFunctions) +
672
+ declareCodes +
673
+ exportsCode +
674
+ '\n',
675
+ 'utf8',
676
+ )
677
+ await writeFileAsync(workerPath, WASI_WORKER_TEMPLATE, 'utf8')
678
+ return {
679
+ kind: 'wasm',
680
+ path: newPath,
681
+ } satisfies Output
682
+ }
683
+ return null
684
+ }
549
685
  }
@@ -0,0 +1,62 @@
1
+ export const createWasiBinding = (
2
+ wasmFileName: string,
3
+ wasiRegisterFunctions: string[],
4
+ ) => `/* eslint-disable */
5
+ /* prettier-ignore */
6
+
7
+ /* auto-generated by NAPI-RS */
8
+
9
+ const __nodeFs= require('node:fs')
10
+ const __nodePath = require('node:path')
11
+ const { WASI: __nodeWASI } = require('node:wasi')
12
+ const { Worker } = require('node:worker_threads')
13
+
14
+ const { instantiateNapiModuleSync: __emnapiInstantiateNapiModuleSync } = require('@emnapi/core')
15
+ const { getDefaultContext: __emnapiGetDefaultContext } = require('@emnapi/runtime')
16
+
17
+ const __wasi = new __nodeWASI({
18
+ version: 'preview1',
19
+ env: process.env,
20
+ preopens: {
21
+ '/': __dirname,
22
+ }
23
+ })
24
+
25
+ const __emnapiContext = __emnapiGetDefaultContext()
26
+
27
+ const __sharedMemory = new WebAssembly.Memory({
28
+ initial: 1024,
29
+ maximum: 10240,
30
+ shared: true,
31
+ })
32
+
33
+ const { instance: __napiInstance, module: __wasiModule, napiModule: __napiModule } = __emnapiInstantiateNapiModuleSync(__nodeFs.readFileSync(__nodePath.join(__dirname, '${wasmFileName}.wasm')), {
34
+ context: __emnapiContext,
35
+ asyncWorkPoolSize: 4,
36
+ wasi: __wasi,
37
+ onCreateWorker() {
38
+ return new Worker(__nodePath.join(__dirname, 'wasi-worker.mjs'), {
39
+ env: process.env,
40
+ execArgv: ['--experimental-wasi-unstable-preview1'],
41
+ })
42
+ },
43
+ overwriteImports(importObject) {
44
+ importObject.env = {
45
+ ...importObject.env,
46
+ ...importObject.napi,
47
+ ...importObject.emnapi,
48
+ memory: __sharedMemory,
49
+ }
50
+ return importObject
51
+ },
52
+ beforeInit({ instance }) {
53
+ __napi_rs_initialize_modules(instance)
54
+ }
55
+ })
56
+
57
+ function __napi_rs_initialize_modules(__napiInstance) {
58
+ ${wasiRegisterFunctions
59
+ .map((name) => ` __napiInstance.exports['${name}']()`)
60
+ .join('\n')}
61
+ }
62
+ `
package/src/api/new.ts CHANGED
@@ -157,10 +157,7 @@ function generateGithubWorkflow(options: NewOptions): Output | null {
157
157
 
158
158
  return {
159
159
  target: './.github/workflows/ci.yml',
160
- content: createGithubActionsCIYml(
161
- getBinaryName(options.name),
162
- options.targets,
163
- ),
160
+ content: createGithubActionsCIYml(options.targets),
164
161
  }
165
162
  }
166
163
 
@@ -129,11 +129,14 @@ export async function prePublish(userOptions: PrePublishOptions) {
129
129
  if (!options.dryRun) {
130
130
  await version(userOptions)
131
131
  await updatePackageJson(packageJsonPath, {
132
- optionalDependencies: targets.reduce((deps, target) => {
133
- deps[`${packageName}-${target.platformArchABI}`] = packageJson.version
134
-
135
- return deps
136
- }, {} as Record<string, string>),
132
+ optionalDependencies: targets.reduce(
133
+ (deps, target) => {
134
+ deps[`${packageName}-${target.platformArchABI}`] = packageJson.version
135
+
136
+ return deps
137
+ },
138
+ {} as Record<string, string>,
139
+ ),
137
140
  })
138
141
  }
139
142
 
@@ -195,4 +195,5 @@ Cargo.lock
195
195
  !.yarn/versions
196
196
 
197
197
  *.node
198
+ *.wasm
198
199
  `