wasm-bindgen-lite 0.2.0 → 0.3.0

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": "wasm-bindgen-lite",
3
- "version": "0.2.0",
3
+ "version": "0.3.0",
4
4
  "type": "module",
5
5
  "description": "CLI tool to build Rust crates into minimal, SIMD-optimized WASM packages with JS loaders",
6
6
  "repository": {
package/src/cli/config.js CHANGED
@@ -19,6 +19,7 @@ const DEFAULT_CONFIG = {
19
19
  node: true,
20
20
  browser: true,
21
21
  inline: true,
22
+ types: true,
22
23
  },
23
24
  custom: null, // path to custom JS file to include and re-export
24
25
  },
@@ -63,13 +64,14 @@ function readCrateName(crateDir) {
63
64
  }
64
65
 
65
66
  function normalizeEmit(value) {
66
- if (!value) return { node: true, browser: true, inline: true }
67
+ if (!value) return { node: true, browser: true, inline: true, types: true }
67
68
  if (Array.isArray(value)) {
68
69
  const set = new Set(value)
69
70
  return {
70
71
  node: set.has('node'),
71
72
  browser: set.has('browser'),
72
73
  inline: set.has('inline'),
74
+ types: set.has('types') || !set.has('no-types'), // default to true if not specified
73
75
  }
74
76
  }
75
77
  if (typeof value === 'object') {
@@ -77,9 +79,10 @@ function normalizeEmit(value) {
77
79
  node: value.node !== false,
78
80
  browser: value.browser !== false,
79
81
  inline: value.inline !== false,
82
+ types: value.types !== false,
80
83
  }
81
84
  }
82
- return { node: true, browser: true, inline: true }
85
+ return { node: true, browser: true, inline: true, types: true }
83
86
  }
84
87
 
85
88
  function normalizeWasmOpt(input) {
package/src/cli/emit.js CHANGED
@@ -1,4 +1,4 @@
1
- import { readFileSync, writeFileSync, mkdirSync } from 'node:fs'
1
+ import { readFileSync, writeFileSync, mkdirSync, existsSync } from 'node:fs'
2
2
  import { join } from 'node:path'
3
3
  import { fileURLToPath } from 'node:url'
4
4
 
@@ -363,6 +363,62 @@ export function createCore({ exportsList, autoInit, stream }) {
363
363
  return b.toString()
364
364
  }
365
365
 
366
+ export function createCoreTypes({ exportsList, autoInit, stream }) {
367
+ const needsEnsure = autoInit === 'lazy'
368
+ const wrappersIR = buildWrapperIR(exportsList)
369
+ const b = code()
370
+
371
+ b.line('export type WasmInput = Uint8Array | ArrayBufferView | ArrayBuffer;')
372
+ b.blank()
373
+
374
+ b.line('export function setInstance(instance: WebAssembly.Instance): void;')
375
+ b.line('export function wasmExports(): WebAssembly.Exports;')
376
+ b.line('export function memoryU8(): Uint8Array;')
377
+ b.line('export function alloc(len: number): number;')
378
+ b.line('export function free(ptr: number, len: number): void;')
379
+ b.blank()
380
+
381
+ wrappersIR.forEach((w) => {
382
+ let tsRetType
383
+ switch (w.returnType) {
384
+ case 'f32':
385
+ case 'f64':
386
+ case 'i32':
387
+ case 'u32':
388
+ case 'i16':
389
+ case 'u16':
390
+ case 'i8':
391
+ case 'u8':
392
+ tsRetType = 'number'
393
+ break
394
+ case 'u32_array':
395
+ tsRetType = 'Uint32Array'
396
+ break
397
+ case 'i32_array':
398
+ tsRetType = 'Int32Array'
399
+ break
400
+ case 'f32_array':
401
+ tsRetType = 'Float32Array'
402
+ break
403
+ case 'bytes':
404
+ default:
405
+ tsRetType = 'Uint8Array'
406
+ }
407
+
408
+ const ret = needsEnsure ? `Promise<${tsRetType}>` : tsRetType
409
+ b.line(`export function ${w.fnName}(input: WasmInput): ${ret};`)
410
+ })
411
+
412
+ if (stream?.enable) {
413
+ b.blank()
414
+ b.line(
415
+ 'export function createTransformStream(fnName?: string): TransformStream<WasmInput, Uint8Array>;'
416
+ )
417
+ }
418
+
419
+ return b.toString()
420
+ }
421
+
366
422
  export function code() {
367
423
  const lines = []
368
424
  let indent = 0
@@ -388,6 +444,12 @@ export function code() {
388
444
  return api
389
445
  }
390
446
 
447
+ export function createLoaderTypes({ exportFrom }) {
448
+ return `export function init(imports?: WebAssembly.Imports): Promise<void>;
449
+ export * from "${exportFrom}";
450
+ `
451
+ }
452
+
391
453
  export function createLoader({ exportFrom, autoInit, getBytesSrc }) {
392
454
  const eager =
393
455
  autoInit === 'eager'
@@ -502,6 +564,7 @@ export function emitRuntime({
502
564
  emitNode,
503
565
  emitBrowser,
504
566
  emitInline,
567
+ emitTypes,
505
568
  wasmPaths,
506
569
  exportsList,
507
570
  autoInit,
@@ -514,14 +577,36 @@ export function emitRuntime({
514
577
  if (customJs) {
515
578
  const customJsContent = readFileSync(join(process.cwd(), customJs), 'utf8')
516
579
  writeFileSync(join(outDir, 'custom.js'), customJsContent)
580
+
581
+ if (emitTypes) {
582
+ const customTsPath = customJs.replace(/\.js$/, '.d.ts')
583
+ if (existsSync(join(process.cwd(), customTsPath))) {
584
+ writeFileSync(
585
+ join(outDir, 'custom.d.ts'),
586
+ readFileSync(join(process.cwd(), customTsPath), 'utf8')
587
+ )
588
+ }
589
+ }
517
590
  }
518
591
 
519
592
  writeFileSync(
520
593
  join(outDir, 'core.js'),
521
594
  createCore({ exportsList, autoInit, stream })
522
595
  )
596
+ if (emitTypes) {
597
+ writeFileSync(
598
+ join(outDir, 'core.d.ts'),
599
+ createCoreTypes({ exportsList, autoInit, stream })
600
+ )
601
+ }
523
602
  writeFileSync(join(outDir, 'util.js'), readFileSync(UTIL_PATH, 'utf8'))
524
603
 
604
+ const loaderTypes = emitTypes
605
+ ? createLoaderTypes({
606
+ exportFrom: customJs ? './custom.js' : './core.js',
607
+ })
608
+ : null
609
+
525
610
  if (emitBrowser) {
526
611
  writeFileSync(
527
612
  join(outDir, 'browser.js'),
@@ -532,6 +617,7 @@ export function emitRuntime({
532
617
  wasmDelivery,
533
618
  })
534
619
  )
620
+ if (emitTypes) writeFileSync(join(outDir, 'browser.d.ts'), loaderTypes)
535
621
  }
536
622
 
537
623
  if (emitNode) {
@@ -539,6 +625,7 @@ export function emitRuntime({
539
625
  join(outDir, 'node.js'),
540
626
  createNodeLoader({ name: artifactBaseName, autoInit, customJs })
541
627
  )
628
+ if (emitTypes) writeFileSync(join(outDir, 'node.d.ts'), loaderTypes)
542
629
  }
543
630
 
544
631
  if (emitInline && wasmPaths.baselinePath) {
@@ -546,10 +633,13 @@ export function emitRuntime({
546
633
  join(outDir, 'browser-inline.js'),
547
634
  createInlineLoader({ name: artifactBaseName, autoInit, customJs })
548
635
  )
636
+ if (emitTypes)
637
+ writeFileSync(join(outDir, 'browser-inline.d.ts'), loaderTypes)
549
638
  writeFileSync(
550
639
  join(outDir, 'node-inline.js'),
551
640
  createInlineLoader({ name: artifactBaseName, autoInit, customJs })
552
641
  )
642
+ if (emitTypes) writeFileSync(join(outDir, 'node-inline.d.ts'), loaderTypes)
553
643
  writeInlineModules({
554
644
  outDir,
555
645
  artifactBaseName,
package/src/cli/index.js CHANGED
@@ -24,6 +24,7 @@ export async function runBuild(cliOpts) {
24
24
  emitNode: cfg.js.emit.node,
25
25
  emitBrowser: cfg.js.emit.browser,
26
26
  emitInline: cfg.inline && cfg.js.emit.inline,
27
+ emitTypes: cfg.js.emit.types,
27
28
  wasmPaths,
28
29
  exportsList: cfg.exports,
29
30
  autoInit: cfg.autoInit,
package/src/cli/pkg.js CHANGED
@@ -11,6 +11,9 @@ export function updatePackageJson({ crateDir, outDir, js, inline }) {
11
11
  if (!pkg.exports) pkg.exports = {}
12
12
 
13
13
  const mainExports = {}
14
+ if (js.emit.types) {
15
+ mainExports.types = `${relOutDir}/node.d.ts`
16
+ }
14
17
  if (js.emit.browser) {
15
18
  mainExports.browser = `${relOutDir}/browser.js`
16
19
  }
@@ -25,6 +28,9 @@ export function updatePackageJson({ crateDir, outDir, js, inline }) {
25
28
 
26
29
  if (inline && js.emit.inline) {
27
30
  const inlineExports = {}
31
+ if (js.emit.types) {
32
+ inlineExports.types = `${relOutDir}/node-inline.d.ts`
33
+ }
28
34
  if (js.emit.browser) {
29
35
  inlineExports.browser = `${relOutDir}/browser-inline.js`
30
36
  }
@@ -38,9 +44,16 @@ export function updatePackageJson({ crateDir, outDir, js, inline }) {
38
44
  }
39
45
  }
40
46
 
41
- // Also update main/module/types if they are missing?
42
- // For now let's just focus on exports as it's the modern way.
47
+ if (js.emit.types) {
48
+ pkg.types = `${relOutDir}/node.d.ts`
49
+ }
50
+ if (js.emit.node) {
51
+ pkg.main = `${relOutDir}/node.js`
52
+ }
53
+ if (js.emit.browser) {
54
+ pkg.module = `${relOutDir}/browser.js`
55
+ }
43
56
 
44
57
  writeFileSync(pkgPath, JSON.stringify(pkg, null, 2) + '\n')
45
- console.log('Updated package.json exports')
58
+ console.log('Updated package.json exports and fields')
46
59
  }