@napi-rs/cli 3.0.0-alpha.4 → 3.0.0-alpha.41

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/cli.mjs +0 -0
  2. package/dist/api/artifacts.js +32 -8
  3. package/dist/api/artifacts.js.map +1 -0
  4. package/dist/api/build.d.ts +1 -1
  5. package/dist/api/build.js +231 -30
  6. package/dist/api/build.js.map +1 -0
  7. package/dist/api/create-npm-dirs.js +46 -8
  8. package/dist/api/create-npm-dirs.js.map +1 -0
  9. package/dist/api/new.js +47 -20
  10. package/dist/api/new.js.map +1 -0
  11. package/dist/api/pre-publish.js +10 -7
  12. package/dist/api/pre-publish.js.map +1 -0
  13. package/dist/api/rename.js +10 -1
  14. package/dist/api/rename.js.map +1 -0
  15. package/dist/api/templates/.gitignore.d.ts +1 -1
  16. package/dist/api/templates/.gitignore.js +2 -0
  17. package/dist/api/templates/.gitignore.js.map +1 -0
  18. package/dist/api/templates/.npmignore.js +1 -0
  19. package/dist/api/templates/.npmignore.js.map +1 -0
  20. package/dist/api/templates/build.rs.js +1 -0
  21. package/dist/api/templates/build.rs.js.map +1 -0
  22. package/dist/api/templates/cargo.toml.js +1 -0
  23. package/dist/api/templates/cargo.toml.js.map +1 -0
  24. package/dist/api/templates/ci-template.d.ts +2 -1
  25. package/dist/api/templates/ci-template.js +150 -152
  26. package/dist/api/templates/ci-template.js.map +1 -0
  27. package/dist/api/templates/ci.yml.d.ts +2 -1
  28. package/dist/api/templates/ci.yml.js +19 -4
  29. package/dist/api/templates/ci.yml.js.map +1 -0
  30. package/dist/api/templates/index.js +1 -0
  31. package/dist/api/templates/index.js.map +1 -0
  32. package/dist/api/templates/js-binding.d.ts +1 -1
  33. package/dist/api/templates/js-binding.js +143 -30
  34. package/dist/api/templates/js-binding.js.map +1 -0
  35. package/dist/api/templates/lib.rs.js +2 -4
  36. package/dist/api/templates/lib.rs.js.map +1 -0
  37. package/dist/api/templates/load-wasi-template.d.ts +2 -0
  38. package/dist/api/templates/load-wasi-template.js +143 -0
  39. package/dist/api/templates/load-wasi-template.js.map +1 -0
  40. package/dist/api/templates/package.json.d.ts +9 -2
  41. package/dist/api/templates/package.json.js +53 -28
  42. package/dist/api/templates/package.json.js.map +1 -0
  43. package/dist/api/templates/wasi-worker-template.d.ts +2 -0
  44. package/dist/api/templates/wasi-worker-template.js +93 -0
  45. package/dist/api/templates/wasi-worker-template.js.map +1 -0
  46. package/dist/api/universalize.js +6 -5
  47. package/dist/api/universalize.js.map +1 -0
  48. package/dist/api/version.js +3 -2
  49. package/dist/api/version.js.map +1 -0
  50. package/dist/cli.js +1 -0
  51. package/dist/cli.js.map +1 -0
  52. package/dist/commands/artifacts.js +4 -4
  53. package/dist/commands/artifacts.js.map +1 -0
  54. package/dist/commands/build.js +2 -1
  55. package/dist/commands/build.js.map +1 -0
  56. package/dist/commands/create-npm-dirs.js +1 -0
  57. package/dist/commands/create-npm-dirs.js.map +1 -0
  58. package/dist/commands/help.js +2 -2
  59. package/dist/commands/help.js.map +1 -0
  60. package/dist/commands/new.js +15 -7
  61. package/dist/commands/new.js.map +1 -0
  62. package/dist/commands/pre-publish.js +1 -0
  63. package/dist/commands/pre-publish.js.map +1 -0
  64. package/dist/commands/rename.js +1 -0
  65. package/dist/commands/rename.js.map +1 -0
  66. package/dist/commands/universalize.js +1 -0
  67. package/dist/commands/universalize.js.map +1 -0
  68. package/dist/commands/version.js +1 -0
  69. package/dist/commands/version.js.map +1 -0
  70. package/dist/def/artifacts.d.ts +21 -1
  71. package/dist/def/artifacts.js +12 -4
  72. package/dist/def/artifacts.js.map +1 -0
  73. package/dist/def/build.d.ts +20 -2
  74. package/dist/def/build.js +16 -4
  75. package/dist/def/build.js.map +1 -0
  76. package/dist/def/create-npm-dirs.d.ts +10 -0
  77. package/dist/def/create-npm-dirs.js +6 -2
  78. package/dist/def/create-npm-dirs.js.map +1 -0
  79. package/dist/def/new.d.ts +24 -6
  80. package/dist/def/new.js +13 -3
  81. package/dist/def/new.js.map +1 -0
  82. package/dist/def/pre-publish.d.ts +10 -0
  83. package/dist/def/pre-publish.js +9 -5
  84. package/dist/def/pre-publish.js.map +1 -0
  85. package/dist/def/rename.d.ts +11 -1
  86. package/dist/def/rename.js +7 -3
  87. package/dist/def/rename.js.map +1 -0
  88. package/dist/def/universalize.d.ts +10 -0
  89. package/dist/def/universalize.js +6 -2
  90. package/dist/def/universalize.js.map +1 -0
  91. package/dist/def/version.d.ts +10 -0
  92. package/dist/def/version.js +6 -2
  93. package/dist/def/version.js.map +1 -0
  94. package/dist/index.cjs +6022 -8033
  95. package/dist/index.d.ts +1 -0
  96. package/dist/index.js +2 -0
  97. package/dist/index.js.map +1 -0
  98. package/dist/utils/__tests__/config.spec.d.ts +1 -0
  99. package/dist/utils/__tests__/config.spec.js +63 -0
  100. package/dist/utils/__tests__/config.spec.js.map +1 -0
  101. package/dist/utils/__tests__/target.spec.js +1 -0
  102. package/dist/utils/__tests__/target.spec.js.map +1 -0
  103. package/dist/utils/__tests__/typegen.spec.js +9 -4
  104. package/dist/utils/__tests__/typegen.spec.js.map +1 -0
  105. package/dist/utils/__tests__/version.spec.js +1 -0
  106. package/dist/utils/__tests__/version.spec.js.map +1 -0
  107. package/dist/utils/cargo.js +2 -1
  108. package/dist/utils/cargo.js.map +1 -0
  109. package/dist/utils/ci.js +1 -0
  110. package/dist/utils/ci.js.map +1 -0
  111. package/dist/utils/config.d.ts +25 -5
  112. package/dist/utils/config.js +39 -6
  113. package/dist/utils/config.js.map +1 -0
  114. package/dist/utils/index.js +1 -0
  115. package/dist/utils/index.js.map +1 -0
  116. package/dist/utils/log.js +1 -0
  117. package/dist/utils/log.js.map +1 -0
  118. package/dist/utils/metadata.js +3 -2
  119. package/dist/utils/metadata.js.map +1 -0
  120. package/dist/utils/misc.d.ts +1 -1
  121. package/dist/utils/misc.js +4 -3
  122. package/dist/utils/misc.js.map +1 -0
  123. package/dist/utils/target.d.ts +9 -5
  124. package/dist/utils/target.js +16 -1
  125. package/dist/utils/target.js.map +1 -0
  126. package/dist/utils/typegen.d.ts +4 -1
  127. package/dist/utils/typegen.js +27 -6
  128. package/dist/utils/typegen.js.map +1 -0
  129. package/dist/utils/version.d.ts +2 -1
  130. package/dist/utils/version.js +13 -10
  131. package/dist/utils/version.js.map +1 -0
  132. package/package.json +50 -16
  133. package/src/api/artifacts.ts +85 -10
  134. package/src/api/build.ts +381 -32
  135. package/src/api/create-npm-dirs.ts +56 -8
  136. package/src/api/new.ts +69 -33
  137. package/src/api/pre-publish.ts +21 -12
  138. package/src/api/rename.ts +10 -1
  139. package/src/api/templates/.gitignore.ts +1 -0
  140. package/src/api/templates/ci-template.ts +151 -152
  141. package/src/api/templates/ci.yml.ts +19 -4
  142. package/src/api/templates/js-binding.ts +146 -30
  143. package/src/api/templates/lib.rs.ts +1 -4
  144. package/src/api/templates/load-wasi-template.ts +150 -0
  145. package/src/api/templates/package.json.ts +74 -27
  146. package/src/api/templates/wasi-worker-template.ts +93 -0
  147. package/src/api/universalize.ts +8 -5
  148. package/src/api/version.ts +5 -2
  149. package/src/commands/artifacts.ts +2 -2
  150. package/src/commands/build.ts +1 -1
  151. package/src/commands/new.ts +14 -8
  152. package/src/def/artifacts.ts +22 -3
  153. package/src/def/build.ts +32 -4
  154. package/src/def/create-npm-dirs.ts +9 -0
  155. package/src/def/new.ts +28 -3
  156. package/src/def/pre-publish.ts +12 -3
  157. package/src/def/rename.ts +11 -2
  158. package/src/def/universalize.ts +9 -0
  159. package/src/def/version.ts +9 -0
  160. package/src/index.ts +2 -0
  161. package/src/utils/__tests__/__snapshots__/config.spec.ts.md +97 -0
  162. package/src/utils/__tests__/__snapshots__/config.spec.ts.snap +0 -0
  163. package/src/utils/__tests__/__snapshots__/target.spec.ts.md +7 -0
  164. package/src/utils/__tests__/__snapshots__/target.spec.ts.snap +0 -0
  165. package/src/utils/__tests__/__snapshots__/typegen.spec.ts.md +555 -0
  166. package/src/utils/__tests__/__snapshots__/typegen.spec.ts.snap +0 -0
  167. package/src/utils/__tests__/__snapshots__/version.spec.ts.md +9 -8
  168. package/src/utils/__tests__/__snapshots__/version.spec.ts.snap +0 -0
  169. package/src/utils/__tests__/config.spec.ts +81 -0
  170. package/src/utils/__tests__/typegen.spec.ts +19 -4
  171. package/src/utils/cargo.ts +1 -1
  172. package/src/utils/config.ts +85 -9
  173. package/src/utils/metadata.ts +2 -2
  174. package/src/utils/misc.ts +11 -3
  175. package/src/utils/target.ts +23 -7
  176. package/src/utils/typegen.ts +30 -5
  177. package/src/utils/version.ts +11 -9
@@ -2,6 +2,7 @@ import { load, dump } from 'js-yaml'
2
2
 
3
3
  import {
4
4
  NodeArchToCpu,
5
+ type SupportedPackageManager,
5
6
  UniArchsByPlatform,
6
7
  parseTriple,
7
8
  } from '../../utils/index.js'
@@ -15,11 +16,12 @@ const TEST_LINUX_X64_MUSL = 'test-linux-x64-musl-binding'
15
16
  const TEST_LINUX_AARCH64_GNU = 'test-linux-aarch64-gnu-binding'
16
17
  const TEST_LINUX_AARCH64_MUSL = 'test-linux-aarch64-musl-binding'
17
18
  const TEST_LINUX_ARM_GNUEABIHF = 'test-linux-arm-gnueabihf-binding'
19
+ const TEST_WASI = 'test-wasi-nodejs'
18
20
  const UNIVERSAL_MACOS = 'universal-macOS'
19
21
 
20
22
  export const createGithubActionsCIYml = (
21
- binaryName: string,
22
23
  targets: string[],
24
+ packageManager: SupportedPackageManager,
23
25
  ) => {
24
26
  const allTargets = new Set(
25
27
  targets.flatMap((t) => {
@@ -34,7 +36,7 @@ export const createGithubActionsCIYml = (
34
36
  }),
35
37
  )
36
38
 
37
- const fullTemplate = load(YAML()) as any
39
+ const fullTemplate = load(YAML(packageManager)) as any
38
40
 
39
41
  const requiredSteps = []
40
42
  const enableWindowsX86 = allTargets.has('x86_64-pc-windows-msvc')
@@ -46,6 +48,7 @@ export const createGithubActionsCIYml = (
46
48
  const enableLinuxArm7 = allTargets.has('armv7-unknown-linux-gnueabihf')
47
49
  const enableFreeBSD = allTargets.has('x86_64-unknown-freebsd')
48
50
  const enableMacOSUni = allTargets.has('universal-apple-darwin')
51
+ const enableWasi = allTargets.has('wasm32-wasi-preview1-threads')
49
52
  fullTemplate.jobs.build.strategy.matrix.settings =
50
53
  fullTemplate.jobs.build.strategy.matrix.settings.filter(
51
54
  ({ target }: { target: string }) => allTargets.has(target),
@@ -63,10 +66,16 @@ export const createGithubActionsCIYml = (
63
66
  if (!enableWindowsX86 && !enableMacOSX86) {
64
67
  delete fullTemplate.jobs[TEST_MACOS_WINDOWS]
65
68
  } else {
66
- const filterTarget = enableWindowsX86 ? 'macos-latest' : 'windows-latest'
69
+ const filterTargets = new Set<string>()
70
+ if (enableWindowsX86) {
71
+ filterTargets.add('windows-latest')
72
+ }
73
+ if (enableMacOSUni || enableMacOSX86) {
74
+ filterTargets.add('macos-latest')
75
+ }
67
76
  fullTemplate.jobs[TEST_MACOS_WINDOWS].strategy.matrix.settings =
68
77
  fullTemplate.jobs[TEST_MACOS_WINDOWS].strategy.matrix.settings.filter(
69
- ({ host }: { host: string; target: string }) => host !== filterTarget,
78
+ ({ host }: { host: string; target: string }) => filterTargets.has(host),
70
79
  )
71
80
 
72
81
  requiredSteps.push(TEST_MACOS_WINDOWS)
@@ -108,6 +117,12 @@ export const createGithubActionsCIYml = (
108
117
  requiredSteps.push(UNIVERSAL_MACOS)
109
118
  }
110
119
 
120
+ if (!enableWasi) {
121
+ delete fullTemplate.jobs[TEST_WASI]
122
+ } else {
123
+ requiredSteps.push(TEST_WASI)
124
+ }
125
+
111
126
  fullTemplate.jobs.publish.needs = requiredSteps
112
127
 
113
128
  return dump(fullTemplate, {
@@ -1,8 +1,10 @@
1
- export function createJsBinding(localName: string, pkgName: string): string {
1
+ export function createCjsBinding(
2
+ localName: string,
3
+ pkgName: string,
4
+ idents: string[],
5
+ ): string {
2
6
  return `// prettier-ignore
3
- /* tslint:disable */
4
7
  /* eslint-disable */
5
-
6
8
  /* auto-generated by NAPI-RS */
7
9
 
8
10
  const { existsSync, readFileSync } = require('fs')
@@ -14,18 +16,52 @@ let nativeBinding = null
14
16
  let localFileExisted = false
15
17
  let loadError = null
16
18
 
17
- function isMusl() {
18
- // For Node 10
19
- if (!process.report || typeof process.report.getReport !== 'function') {
20
- try {
21
- const lddPath = require('child_process').execSync('which ldd').toString().trim()
22
- return readFileSync(lddPath, 'utf8').includes('musl')
23
- } catch (e) {
19
+ const isMusl = () => {
20
+ let musl = false
21
+ if (process.platform === 'linux') {
22
+ musl = isMuslFromFilesystem()
23
+ if (musl === null) {
24
+ musl = isMuslFromReport()
25
+ }
26
+ if (musl === null) {
27
+ musl = isMuslFromChildProcess()
28
+ }
29
+ }
30
+ return musl
31
+ }
32
+
33
+ const isFileMusl = (f) => f.includes('libc.musl-') || f.includes('ld-musl-')
34
+
35
+ const isMuslFromFilesystem = () => {
36
+ try {
37
+ return readFileSync('/usr/bin/ldd', 'utf-8').includes('musl')
38
+ } catch {
39
+ return null
40
+ }
41
+ }
42
+
43
+ const isMuslFromReport = () => {
44
+ const report = typeof process.report.getReport === 'function' ? process.report.getReport() : null
45
+ if (!report) {
46
+ return null
47
+ }
48
+ if (report.header && report.header.glibcVersionRuntime) {
49
+ return false
50
+ }
51
+ if (Array.isArray(report.sharedObjects)) {
52
+ if (report.sharedObjects.some(isFileMusl)) {
24
53
  return true
25
54
  }
26
- } else {
27
- const { glibcVersionRuntime } = process.report.getReport().header
28
- return !glibcVersionRuntime
55
+ }
56
+ return false
57
+ }
58
+
59
+ const isMuslFromChildProcess = () => {
60
+ try {
61
+ return require('child_process').execSync('ldd --version', { encoding: 'utf8' }).includes('musl')
62
+ } catch (e) {
63
+ // If we reach this case, we don't know if the system is musl or not, so is better to just fallback to false
64
+ return false
29
65
  }
30
66
  }
31
67
 
@@ -57,7 +93,7 @@ switch (platform) {
57
93
  }
58
94
  break
59
95
  default:
60
- throw new Error(\`Unsupported architecture on Android \${arch}\`)
96
+ loadError = new Error(\`Unsupported architecture on Android \${arch}\`)
61
97
  }
62
98
  break
63
99
  case 'win32':
@@ -105,7 +141,7 @@ switch (platform) {
105
141
  }
106
142
  break
107
143
  default:
108
- throw new Error(\`Unsupported architecture on Windows: \${arch}\`)
144
+ loadError = new Error(\`Unsupported architecture on Windows: \${arch}\`)
109
145
  }
110
146
  break
111
147
  case 'darwin':
@@ -146,22 +182,37 @@ switch (platform) {
146
182
  }
147
183
  break
148
184
  default:
149
- throw new Error(\`Unsupported architecture on macOS: \${arch}\`)
185
+ loadError = new Error(\`Unsupported architecture on macOS: \${arch}\`)
150
186
  }
151
187
  break
152
188
  case 'freebsd':
153
- if (arch !== 'x64') {
154
- throw new Error(\`Unsupported architecture on FreeBSD: \${arch}\`)
155
- }
156
- localFileExisted = existsSync(join(__dirname, '${localName}.freebsd-x64.node'))
157
- try {
158
- if (localFileExisted) {
159
- nativeBinding = require('./${localName}.freebsd-x64.node')
160
- } else {
161
- nativeBinding = require('${pkgName}-freebsd-x64')
162
- }
163
- } catch (e) {
164
- loadError = e
189
+ switch (arch) {
190
+ case 'x64':
191
+ localFileExisted = existsSync(join(__dirname, '${localName}.freebsd-x64.node'))
192
+ try {
193
+ if (localFileExisted) {
194
+ nativeBinding = require('./${localName}.freebsd-x64.node')
195
+ } else {
196
+ nativeBinding = require('${pkgName}-freebsd-x64')
197
+ }
198
+ } catch (e) {
199
+ loadError = e
200
+ }
201
+ break
202
+ case 'arm64':
203
+ localFileExisted = existsSync(join(__dirname, '${localName}.freebsd-arm64.node'))
204
+ try {
205
+ if (localFileExisted) {
206
+ nativeBinding = require('./${localName}.freebsd-arm64.node')
207
+ } else {
208
+ nativeBinding = require('${pkgName}-freebsd-arm64')
209
+ }
210
+ } catch (e) {
211
+ loadError = e
212
+ }
213
+ break
214
+ default:
215
+ loadError = new Error(\`Unsupported architecture on FreeBSD: \${arch}\`)
165
216
  }
166
217
  break
167
218
  case 'linux':
@@ -238,12 +289,74 @@ switch (platform) {
238
289
  loadError = e
239
290
  }
240
291
  break
292
+ case 'riscv64':
293
+ if (isMusl()) {
294
+ localFileExisted = existsSync(
295
+ join(__dirname, '${localName}.linux-riscv64-musl.node')
296
+ )
297
+ try {
298
+ if (localFileExisted) {
299
+ nativeBinding = require('./${localName}.linux-riscv64-musl.node')
300
+ } else {
301
+ nativeBinding = require('${pkgName}-linux-riscv64-musl')
302
+ }
303
+ } catch (e) {
304
+ loadError = e
305
+ }
306
+ } else {
307
+ localFileExisted = existsSync(
308
+ join(__dirname, '${localName}.linux-riscv64-gnu.node')
309
+ )
310
+ try {
311
+ if (localFileExisted) {
312
+ nativeBinding = require('./${localName}.linux-riscv64-gnu.node')
313
+ } else {
314
+ nativeBinding = require('${pkgName}-linux-riscv64-gnu')
315
+ }
316
+ } catch (e) {
317
+ loadError = e
318
+ }
319
+ }
320
+ break
321
+ case 's390x':
322
+ localFileExisted = existsSync(
323
+ join(__dirname, '${localName}.linux-s390x-gnu.node')
324
+ )
325
+ try {
326
+ if (localFileExisted) {
327
+ nativeBinding = require('./${localName}.linux-s390x-gnu.node')
328
+ } else {
329
+ nativeBinding = require('${pkgName}-linux-s390x-gnu')
330
+ }
331
+ } catch (e) {
332
+ loadError = e
333
+ }
334
+ break
241
335
  default:
242
- throw new Error(\`Unsupported architecture on Linux: \${arch}\`)
336
+ loadError = new Error(\`Unsupported architecture on Linux: \${arch}\`)
243
337
  }
244
338
  break
245
339
  default:
246
- throw new Error(\`Unsupported OS: \${platform}, architecture: \${arch}\`)
340
+ loadError = new Error(\`Unsupported OS: \${platform}, architecture: \${arch}\`)
341
+ }
342
+
343
+ if (!nativeBinding || process.env.NAPI_RS_FORCE_WASI) {
344
+ try {
345
+ nativeBinding = require('./${localName}.wasi.cjs')
346
+ } catch (err) {
347
+ if (process.env.NAPI_RS_FORCE_WASI) {
348
+ console.error(err)
349
+ }
350
+ }
351
+ if (!nativeBinding) {
352
+ try {
353
+ nativeBinding = require('${pkgName}-wasm32-wasi')
354
+ } catch (err) {
355
+ if (process.env.NAPI_RS_FORCE_WASI) {
356
+ console.error(err)
357
+ }
358
+ }
359
+ }
247
360
  }
248
361
 
249
362
  if (!nativeBinding) {
@@ -253,5 +366,8 @@ if (!nativeBinding) {
253
366
  throw new Error(\`Failed to load native binding\`)
254
367
  }
255
368
 
369
+ ${idents
370
+ .map((ident) => `module.exports.${ident} = nativeBinding.${ident}`)
371
+ .join('\n')}
256
372
  `
257
373
  }
@@ -1,7 +1,4 @@
1
- export const createLibRs = () => `#![deny(clippy::all)]
2
-
3
- #[macro_use]
4
- extern crate napi_derive;
1
+ export const createLibRs = () => `use napi_derive::napi;
5
2
 
6
3
  #[napi]
7
4
  pub fn sum(a: i32, b: i32) -> i32 {
@@ -0,0 +1,150 @@
1
+ export const createWasiBrowserBinding = (
2
+ wasiFilename: string,
3
+ wasiRegisterFunctions: string[],
4
+ ) => `import {
5
+ instantiateNapiModuleSync as __emnapiInstantiateNapiModuleSync,
6
+ getDefaultContext as __emnapiGetDefaultContext,
7
+ WASI as __WASI,
8
+ } from '@napi-rs/wasm-runtime'
9
+ import { Volume as __Volume, createFsFromVolume as __createFsFromVolume } from '@napi-rs/wasm-runtime/fs'
10
+
11
+ import __wasmUrl from './${wasiFilename}.wasm?url'
12
+
13
+ const __fs = __createFsFromVolume(
14
+ __Volume.fromJSON({
15
+ '/': null,
16
+ }),
17
+ )
18
+
19
+ const __wasi = new __WASI({
20
+ version: 'preview1',
21
+ fs: __fs,
22
+ })
23
+
24
+ const __emnapiContext = __emnapiGetDefaultContext()
25
+
26
+ const __sharedMemory = new WebAssembly.Memory({
27
+ initial: 1024,
28
+ maximum: 10240,
29
+ shared: true,
30
+ })
31
+
32
+ const __wasmFile = await fetch(__wasmUrl).then((res) => res.arrayBuffer())
33
+
34
+ const {
35
+ instance: __napiInstance,
36
+ module: __wasiModule,
37
+ napiModule: __napiModule,
38
+ } = __emnapiInstantiateNapiModuleSync(__wasmFile, {
39
+ context: __emnapiContext,
40
+ asyncWorkPoolSize: 4,
41
+ wasi: __wasi,
42
+ onCreateWorker() {
43
+ return new Worker(new URL('./wasi-worker-browser.mjs', import.meta.url), {
44
+ type: 'module',
45
+ })
46
+ },
47
+ overwriteImports(importObject) {
48
+ importObject.env = {
49
+ ...importObject.env,
50
+ ...importObject.napi,
51
+ ...importObject.emnapi,
52
+ memory: __sharedMemory,
53
+ }
54
+ return importObject
55
+ },
56
+ beforeInit({ instance }) {
57
+ __napi_rs_initialize_modules(instance)
58
+ },
59
+ })
60
+
61
+ function __napi_rs_initialize_modules(__napiInstance) {
62
+ ${wasiRegisterFunctions
63
+ .map((name) => ` __napiInstance.exports['${name}']?.()`)
64
+ .join('\n')}
65
+ }
66
+ `
67
+
68
+ export const createWasiBinding = (
69
+ wasmFileName: string,
70
+ packageName: string,
71
+ wasiRegisterFunctions: string[],
72
+ ) => `/* eslint-disable */
73
+ /* prettier-ignore */
74
+
75
+ /* auto-generated by NAPI-RS */
76
+
77
+ const __nodeFs= require('node:fs')
78
+ const __nodePath = require('node:path')
79
+ const { WASI: __nodeWASI } = require('node:wasi')
80
+ const { Worker } = require('node:worker_threads')
81
+
82
+ const {
83
+ instantiateNapiModuleSync: __emnapiInstantiateNapiModuleSync,
84
+ getDefaultContext: __emnapiGetDefaultContext,
85
+ } = require('@napi-rs/wasm-runtime')
86
+
87
+ const __wasi = new __nodeWASI({
88
+ version: 'preview1',
89
+ env: process.env,
90
+ preopens: {
91
+ '/': '/'
92
+ }
93
+ })
94
+
95
+ const __emnapiContext = __emnapiGetDefaultContext()
96
+
97
+ const __sharedMemory = new WebAssembly.Memory({
98
+ initial: 1024,
99
+ maximum: 10240,
100
+ shared: true,
101
+ })
102
+
103
+ let __wasmFilePath = __nodePath.join(__dirname, '${wasmFileName}.wasm')
104
+
105
+ if (!__nodeFs.existsSync(__wasmFilePath)) {
106
+ try {
107
+ __wasmFilePath = __nodePath.resolve('${packageName}-wasm32-wasi')
108
+ } catch {
109
+ throw new Error('Cannot find ${wasmFileName}.wasm file, and ${packageName}-wasm32-wasi package is not installed.')
110
+ }
111
+ }
112
+
113
+ const { instance: __napiInstance, module: __wasiModule, napiModule: __napiModule } = __emnapiInstantiateNapiModuleSync(__nodeFs.readFileSync(__wasmFilePath), {
114
+ context: __emnapiContext,
115
+ asyncWorkPoolSize: (function() {
116
+ const threadsSizeFromEnv = Number(process.env.NAPI_RS_ASYNC_WORK_POOL_SIZE ?? process.env.UV_THREADPOOL_SIZE)
117
+ // NaN > 0 is false
118
+ if (threadsSizeFromEnv > 0) {
119
+ return threadsSizeFromEnv
120
+ } else {
121
+ return 4
122
+ }
123
+ })(),
124
+ wasi: __wasi,
125
+ onCreateWorker() {
126
+ return new Worker(__nodePath.join(__dirname, 'wasi-worker.mjs'), {
127
+ env: process.env,
128
+ execArgv: ['--experimental-wasi-unstable-preview1'],
129
+ })
130
+ },
131
+ overwriteImports(importObject) {
132
+ importObject.env = {
133
+ ...importObject.env,
134
+ ...importObject.napi,
135
+ ...importObject.emnapi,
136
+ memory: __sharedMemory,
137
+ }
138
+ return importObject
139
+ },
140
+ beforeInit({ instance }) {
141
+ __napi_rs_initialize_modules(instance)
142
+ }
143
+ })
144
+
145
+ function __napi_rs_initialize_modules(__napiInstance) {
146
+ ${wasiRegisterFunctions
147
+ .map((name) => ` __napiInstance.exports['${name}']?.()`)
148
+ .join('\n')}
149
+ }
150
+ `
@@ -1,10 +1,21 @@
1
- export const createPackageJson = ({
1
+ import type {
2
+ CommonPackageJsonFields,
3
+ SupportedTestFramework,
4
+ } from '../../utils/config.js'
5
+ import { UNIVERSAL_TARGETS } from '../../utils/target.js'
6
+
7
+ export interface PackageMeta {
8
+ 'dist-tags': { [index: string]: string }
9
+ }
10
+
11
+ export const createPackageJson = async ({
2
12
  name,
3
13
  binaryName,
4
14
  targets,
5
15
  license,
6
16
  engineRequirement,
7
17
  cliVersion,
18
+ testFramework,
8
19
  }: {
9
20
  name: string
10
21
  binaryName: string
@@ -12,32 +23,68 @@ export const createPackageJson = ({
12
23
  license: string
13
24
  engineRequirement: string
14
25
  cliVersion: string
26
+ testFramework: SupportedTestFramework
15
27
  }) => {
16
- return `{
17
- "name": "${name}",
18
- "version": "1.0.0",
19
- "main": "index.js",
20
- "types": "index.d.ts",
21
- "license": "${license}",
22
- "engines": {
23
- "node": "${engineRequirement}"
24
- },
25
- "napi": {
26
- "binaryName": "${binaryName}",
27
- "targets": [
28
- ${targets.map((t) => `"${t}"`).join(',\n ')}
29
- ]
30
- },
31
- "scripts": {
32
- "test": "node -e \\"assert(require('.').sum(1, 2) === 3)\\"",
33
- "build": "napi build --release --platform --strip",
34
- "build:debug": "napi build",
35
- "prepublishOnly": "napi prepublish -t npm",
36
- "artifacts": "napi artifacts",
37
- "version": "napi version"
38
- },
39
- "devDependencies": {
40
- "@napi-rs/cli": "^${cliVersion}"
28
+ const hasWasmTarget = targets.some((t) => t.includes('wasm'))
29
+ const universalTargets = targets.filter(
30
+ (t) => t in UNIVERSAL_TARGETS,
31
+ ) as (keyof typeof UNIVERSAL_TARGETS)[]
32
+ const unifiedtargets = universalTargets.length
33
+ ? targets.filter(
34
+ (target) =>
35
+ !universalTargets.some((t) => {
36
+ // @ts-expect-error
37
+ return UNIVERSAL_TARGETS[t].includes(target)
38
+ }),
39
+ )
40
+ : targets
41
+ const content: CommonPackageJsonFields = {
42
+ name,
43
+ version: '0.0.0',
44
+ license,
45
+ engines: {
46
+ node: engineRequirement,
47
+ },
48
+ type: 'commonjs',
49
+ main: 'index.js',
50
+ types: 'index.d.ts',
51
+ browser: 'browser.js',
52
+ module: undefined,
53
+ exports: undefined,
54
+ napi: {
55
+ binaryName,
56
+ targets: unifiedtargets,
57
+ },
58
+ scripts: {
59
+ test: testFramework,
60
+ build: 'napi build --release --platform --strip',
61
+ 'build:debug': 'napi build',
62
+ prepublishOnly: 'napi prepublish -t npm',
63
+ artifacts: 'napi artifacts',
64
+ version: 'napi version',
65
+ },
66
+ devDependencies: {
67
+ '@napi-rs/cli': `^${cliVersion}`,
68
+ },
69
+ }
70
+
71
+ if (testFramework === 'ava') {
72
+ const avaMeta = await fetch(`https://registry.npmjs.org/ava`).then(
73
+ (res) => res.json() as Promise<PackageMeta>,
74
+ )
75
+ content.devDependencies!['ava'] = `^${avaMeta['dist-tags'].latest}`
76
+ content.ava = {
77
+ timeout: '1m',
78
+ }
79
+ }
80
+
81
+ if (hasWasmTarget) {
82
+ const wasmRuntime = await fetch(
83
+ `https://registry.npmjs.org/@napi-rs/wasm-runtime`,
84
+ ).then((res) => res.json() as Promise<PackageMeta>)
85
+ const latest = wasmRuntime['dist-tags'].latest
86
+ content.devDependencies!['@napi-rs/wasm-runtime'] = `^${latest}`
41
87
  }
42
- }`
88
+
89
+ return JSON.stringify(content, null, 2)
43
90
  }
@@ -0,0 +1,93 @@
1
+ export const WASI_WORKER_TEMPLATE = `import fs from "node:fs";
2
+ import { createRequire } from "node:module";
3
+ import { parentPort, Worker } from "node:worker_threads";
4
+
5
+ import { instantiateNapiModuleSync, MessageHandler, WASI } from "@napi-rs/wasm-runtime";
6
+
7
+ const require = createRequire(import.meta.url);
8
+
9
+ if (parentPort) {
10
+ parentPort.on("message", (data) => {
11
+ globalThis.onmessage({ data });
12
+ });
13
+ }
14
+
15
+ Object.assign(globalThis, {
16
+ self: globalThis,
17
+ require,
18
+ Worker,
19
+ importScripts: function (f) {
20
+ ;(0, eval)(fs.readFileSync(f, "utf8") + "//# sourceURL=" + f);
21
+ },
22
+ postMessage: function (msg) {
23
+ if (parentPort) {
24
+ parentPort.postMessage(msg);
25
+ }
26
+ },
27
+ });
28
+
29
+ const handler = new MessageHandler({
30
+ onLoad({ wasmModule, wasmMemory }) {
31
+ const wasi = new WASI({ fs });
32
+
33
+ return instantiateNapiModuleSync(wasmModule, {
34
+ childThread: true,
35
+ wasi,
36
+ overwriteImports(importObject) {
37
+ importObject.env = {
38
+ ...importObject.env,
39
+ ...importObject.napi,
40
+ ...importObject.emnapi,
41
+ memory: wasmMemory
42
+ };
43
+ },
44
+ });
45
+ },
46
+ });
47
+
48
+ globalThis.onmessage = function (e) {
49
+ handler.handle(e);
50
+ };
51
+ `
52
+
53
+ export const WASI_WORKER_BROWSER_TEMPLATE = `import { instantiateNapiModuleSync, MessageHandler, WASI } from '@napi-rs/wasm-runtime'
54
+ import { Volume, createFsFromVolume } from '@napi-rs/wasm-runtime/fs'
55
+
56
+ const fs = createFsFromVolume(
57
+ Volume.fromJSON({
58
+ '/': null,
59
+ }),
60
+ )
61
+
62
+ const handler = new MessageHandler({
63
+ onLoad({ wasmModule, wasmMemory }) {
64
+ const wasi = new WASI({
65
+ fs,
66
+ print: function () {
67
+ // eslint-disable-next-line no-console
68
+ console.log.apply(console, arguments)
69
+ },
70
+ printErr: function() {
71
+ // eslint-disable-next-line no-console
72
+ console.error.apply(console, arguments)
73
+ },
74
+ })
75
+ return instantiateNapiModuleSync(wasmModule, {
76
+ childThread: true,
77
+ wasi,
78
+ overwriteImports(importObject) {
79
+ importObject.env = {
80
+ ...importObject.env,
81
+ ...importObject.napi,
82
+ ...importObject.emnapi,
83
+ memory: wasmMemory,
84
+ }
85
+ },
86
+ })
87
+ },
88
+ })
89
+
90
+ globalThis.onmessage = function (e) {
91
+ handler.handle(e)
92
+ }
93
+ `