@bytecodealliance/jco 1.14.0 → 1.15.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.
@@ -2,7 +2,6 @@
2
2
 
3
3
  import { extname, basename, resolve } from 'node:path';
4
4
 
5
- import c from 'chalk-template';
6
5
  import { minify } from 'terser';
7
6
  import { fileURLToPath } from 'url';
8
7
 
@@ -15,6 +14,7 @@ import {
15
14
  setShowSpinner,
16
15
  getShowSpinner,
17
16
  writeFiles,
17
+ styleText,
18
18
  ASYNC_WASI_IMPORTS,
19
19
  ASYNC_WASI_EXPORTS,
20
20
  DEFAULT_ASYNC_MODE,
@@ -291,7 +291,7 @@ export async function transpileComponent(component, opts = {}) {
291
291
  // Configure the spinner.
292
292
  let completed = 0;
293
293
  const spinnerText = () =>
294
- c`{cyan ${completed} / ${wasmFiles.length}} Running Binaryen wasm2js on Wasm core modules (this takes a while)...\n`;
294
+ `${styleText("cyan", `${completed} / ${wasmFiles.length}`)} Running Binaryen wasm2js on Wasm core modules (this takes a while)...\n`;
295
295
  if (showSpinner) {
296
296
  spinner = ora({
297
297
  color: 'cyan',
@@ -317,16 +317,16 @@ export async function transpileComponent(component, opts = {}) {
317
317
  .map(
318
318
  (asm, nth) => `function asm${nth}(imports) {
319
319
  ${
320
- // strip and replace the asm instantiation wrapper
321
- asm
322
- .replace(/import \* as [^ ]+ from '[^']*';/g, '')
323
- .replace('function asmFunc(imports) {', '')
324
- .replace(/export var ([^ ]+) = ([^. ]+)\.([^ ]+);/g, '')
325
- .replace(/var retasmFunc = [\s\S]*$/, '')
326
- .replace(/var memasmFunc = new ArrayBuffer\(0\);/g, '')
327
- .replace('memory.grow = __wasm_memory_grow;', '')
328
- .trim()
329
- }`
320
+ // strip and replace the asm instantiation wrapper
321
+ asm
322
+ .replace(/import \* as [^ ]+ from '[^']*';/g, '')
323
+ .replace('function asmFunc(imports) {', '')
324
+ .replace(/export var ([^ ]+) = ([^. ]+)\.([^ ]+);/g, '')
325
+ .replace(/var retasmFunc = [\s\S]*$/, '')
326
+ .replace(/var memasmFunc = new ArrayBuffer\(0\);/g, '')
327
+ .replace('memory.grow = __wasm_memory_grow;', '')
328
+ .trim()
329
+ }`
330
330
  )
331
331
  .join(',\n');
332
332
 
@@ -367,14 +367,14 @@ ${
367
367
  // Exporting `$init` must come first to not break the transpiling tests.
368
368
  opts.tlaCompat ? ' $init,\n' : ''
369
369
  }${exports
370
- .map(([name]) => {
371
- if (name === asmMangle(name)) {
372
- return ` ${name},`;
373
- } else {
374
- return ` ${asmMangle(name)} as '${name}',`;
375
- }
376
- })
377
- .join('\n')}
370
+ .map(([name]) => {
371
+ if (name === asmMangle(name)) {
372
+ return ` ${name},`;
373
+ } else {
374
+ return ` ${asmMangle(name)} as '${name}',`;
375
+ }
376
+ })
377
+ .join('\n')}
378
378
  }`;
379
379
  }
380
380
 
@@ -383,35 +383,35 @@ ${
383
383
  .map(([name]) => `_${asmMangle(name)}`)
384
384
  .join(', ')};
385
385
  ${exports
386
- .map(([name, ty]) => {
387
- if (ty === 'function') {
388
- return `\nfunction ${asmMangle(name)} () {
386
+ .map(([name, ty]) => {
387
+ if (ty === 'function') {
388
+ return `\nfunction ${asmMangle(name)} () {
389
389
  return _${asmMangle(name)}.apply(this, arguments);
390
390
  }`;
391
- } else {
392
- return `\nlet ${asmMangle(name)};`;
393
- }
394
- })
395
- .join('\n')}`;
391
+ } else {
392
+ return `\nlet ${asmMangle(name)};`;
393
+ }
394
+ })
395
+ .join('\n')}`;
396
396
 
397
397
  autoInstantiate = `${async_}function $init() {
398
398
  ( {
399
399
  ${exports
400
- .map(([name, ty]) => {
401
- if (ty === 'function') {
402
- return ` '${name}': _${asmMangle(name)},`;
403
- } else if (asmMangle(name) === name) {
404
- return ` ${name},`;
405
- } else {
406
- return ` '${name}': ${asmMangle(name)},`;
407
- }
408
- })
409
- .join('\n')}
400
+ .map(([name, ty]) => {
401
+ if (ty === 'function') {
402
+ return ` '${name}': _${asmMangle(name)},`;
403
+ } else if (asmMangle(name) === name) {
404
+ return ` ${name},`;
405
+ } else {
406
+ return ` '${name}': ${asmMangle(name)},`;
407
+ }
408
+ })
409
+ .join('\n')}
410
410
  } = ${await_}instantiate(
411
411
  {
412
412
  ${imports
413
- .map((import_file, nth) => ` '${import_file}': import${nth},`)
414
- .join('\n')}
413
+ .map((import_file, nth) => ` '${import_file}': import${nth},`)
414
+ .join('\n')}
415
415
  }
416
416
  ) )
417
417
  }
@@ -480,6 +480,41 @@ function asmMangle(name) {
480
480
 
481
481
  // Names must start with a character, $ or _
482
482
  switch (name[0]) {
483
+ case '0':
484
+ case '1':
485
+ case '2':
486
+ case '3':
487
+ case '4':
488
+ case '5':
489
+ case '6':
490
+ case '7':
491
+ case '8':
492
+ case '9': {
493
+ name = '$' + name;
494
+ i = 2;
495
+ // fallthrough
496
+ }
497
+ case '$':
498
+ case '_': {
499
+ mightBeKeyword = false;
500
+ break;
501
+ }
502
+ default: {
503
+ let chNum = name.charCodeAt(0);
504
+ if (
505
+ !(chNum >= 97 && chNum <= 122) &&
506
+ !(chNum >= 65 && chNum <= 90)
507
+ ) {
508
+ name = '$' + name.substr(1);
509
+ mightBeKeyword = false;
510
+ }
511
+ }
512
+ }
513
+
514
+ // Names must contain only characters, digits, $ or _
515
+ let len = name.length;
516
+ for (; i < len; ++i) {
517
+ switch (name[i]) {
483
518
  case '0':
484
519
  case '1':
485
520
  case '2':
@@ -489,194 +524,159 @@ function asmMangle(name) {
489
524
  case '6':
490
525
  case '7':
491
526
  case '8':
492
- case '9': {
493
- name = '$' + name;
494
- i = 2;
495
- // fallthrough
496
- }
527
+ case '9':
497
528
  case '$':
498
529
  case '_': {
499
530
  mightBeKeyword = false;
500
531
  break;
501
532
  }
502
533
  default: {
503
- let chNum = name.charCodeAt(0);
534
+ let chNum = name.charCodeAt(i);
504
535
  if (
505
536
  !(chNum >= 97 && chNum <= 122) &&
506
- !(chNum >= 65 && chNum <= 90)
537
+ !(chNum >= 65 && chNum <= 90)
507
538
  ) {
508
- name = '$' + name.substr(1);
539
+ name = name.substr(0, i) + '_' + name.substr(i + 1);
509
540
  mightBeKeyword = false;
510
541
  }
511
542
  }
512
- }
513
-
514
- // Names must contain only characters, digits, $ or _
515
- let len = name.length;
516
- for (; i < len; ++i) {
517
- switch (name[i]) {
518
- case '0':
519
- case '1':
520
- case '2':
521
- case '3':
522
- case '4':
523
- case '5':
524
- case '6':
525
- case '7':
526
- case '8':
527
- case '9':
528
- case '$':
529
- case '_': {
530
- mightBeKeyword = false;
531
- break;
532
- }
533
- default: {
534
- let chNum = name.charCodeAt(i);
535
- if (
536
- !(chNum >= 97 && chNum <= 122) &&
537
- !(chNum >= 65 && chNum <= 90)
538
- ) {
539
- name = name.substr(0, i) + '_' + name.substr(i + 1);
540
- mightBeKeyword = false;
541
- }
542
- }
543
543
  }
544
544
  }
545
545
 
546
546
  // Names must not collide with keywords
547
547
  if (mightBeKeyword && len >= 2 && len <= 10) {
548
548
  switch (name[0]) {
549
- case 'a': {
550
- if (name == 'arguments') {
551
- return name + '_';
552
- }
553
- break;
549
+ case 'a': {
550
+ if (name == 'arguments') {
551
+ return name + '_';
554
552
  }
555
- case 'b': {
556
- if (name == 'break') {
557
- return name + '_';
558
- }
559
- break;
553
+ break;
554
+ }
555
+ case 'b': {
556
+ if (name == 'break') {
557
+ return name + '_';
560
558
  }
561
- case 'c': {
562
- if (
563
- name == 'case' ||
559
+ break;
560
+ }
561
+ case 'c': {
562
+ if (
563
+ name == 'case' ||
564
564
  name == 'continue' ||
565
565
  name == 'catch' ||
566
566
  name == 'const' ||
567
567
  name == 'class'
568
- ) {
569
- return name + '_';
570
- }
571
- break;
568
+ ) {
569
+ return name + '_';
572
570
  }
573
- case 'd': {
574
- if (name == 'do' || name == 'default' || name == 'debugger') {
575
- return name + '_';
576
- }
577
- break;
571
+ break;
572
+ }
573
+ case 'd': {
574
+ if (name == 'do' || name == 'default' || name == 'debugger') {
575
+ return name + '_';
578
576
  }
579
- case 'e': {
580
- if (
581
- name == 'else' ||
577
+ break;
578
+ }
579
+ case 'e': {
580
+ if (
581
+ name == 'else' ||
582
582
  name == 'enum' ||
583
583
  name == 'eval' || // to be sure
584
584
  name == 'export' ||
585
585
  name == 'extends'
586
- ) {
587
- return name + '_';
588
- }
589
- break;
586
+ ) {
587
+ return name + '_';
590
588
  }
591
- case 'f': {
592
- if (
593
- name == 'for' ||
589
+ break;
590
+ }
591
+ case 'f': {
592
+ if (
593
+ name == 'for' ||
594
594
  name == 'false' ||
595
595
  name == 'finally' ||
596
596
  name == 'function'
597
- ) {
598
- return name + '_';
599
- }
600
- break;
597
+ ) {
598
+ return name + '_';
601
599
  }
602
- case 'i': {
603
- if (
604
- name == 'if' ||
600
+ break;
601
+ }
602
+ case 'i': {
603
+ if (
604
+ name == 'if' ||
605
605
  name == 'in' ||
606
606
  name == 'import' ||
607
607
  name == 'interface' ||
608
608
  name == 'implements' ||
609
609
  name == 'instanceof'
610
- ) {
611
- return name + '_';
612
- }
613
- break;
610
+ ) {
611
+ return name + '_';
614
612
  }
615
- case 'l': {
616
- if (name == 'let') {
617
- return name + '_';
618
- }
619
- break;
613
+ break;
614
+ }
615
+ case 'l': {
616
+ if (name == 'let') {
617
+ return name + '_';
620
618
  }
621
- case 'n': {
622
- if (name == 'new' || name == 'null') {
623
- return name + '_';
624
- }
625
- break;
619
+ break;
620
+ }
621
+ case 'n': {
622
+ if (name == 'new' || name == 'null') {
623
+ return name + '_';
626
624
  }
627
- case 'p': {
628
- if (
629
- name == 'public' ||
625
+ break;
626
+ }
627
+ case 'p': {
628
+ if (
629
+ name == 'public' ||
630
630
  name == 'package' ||
631
631
  name == 'private' ||
632
632
  name == 'protected'
633
- ) {
634
- return name + '_';
635
- }
636
- break;
633
+ ) {
634
+ return name + '_';
637
635
  }
638
- case 'r': {
639
- if (name == 'return') {
640
- return name + '_';
641
- }
642
- break;
636
+ break;
637
+ }
638
+ case 'r': {
639
+ if (name == 'return') {
640
+ return name + '_';
643
641
  }
644
- case 's': {
645
- if (name == 'super' || name == 'static' || name == 'switch') {
646
- return name + '_';
647
- }
648
- break;
642
+ break;
643
+ }
644
+ case 's': {
645
+ if (name == 'super' || name == 'static' || name == 'switch') {
646
+ return name + '_';
649
647
  }
650
- case 't': {
651
- if (
652
- name == 'try' ||
648
+ break;
649
+ }
650
+ case 't': {
651
+ if (
652
+ name == 'try' ||
653
653
  name == 'this' ||
654
654
  name == 'true' ||
655
655
  name == 'throw' ||
656
656
  name == 'typeof'
657
- ) {
658
- return name + '_';
659
- }
660
- break;
657
+ ) {
658
+ return name + '_';
661
659
  }
662
- case 'v': {
663
- if (name == 'var' || name == 'void') {
664
- return name + '_';
665
- }
666
- break;
660
+ break;
661
+ }
662
+ case 'v': {
663
+ if (name == 'var' || name == 'void') {
664
+ return name + '_';
667
665
  }
668
- case 'w': {
669
- if (name == 'with' || name == 'while') {
670
- return name + '_';
671
- }
672
- break;
666
+ break;
667
+ }
668
+ case 'w': {
669
+ if (name == 'with' || name == 'while') {
670
+ return name + '_';
673
671
  }
674
- case 'y': {
675
- if (name == 'yield') {
676
- return name + '_';
677
- }
678
- break;
672
+ break;
673
+ }
674
+ case 'y': {
675
+ if (name == 'yield') {
676
+ return name + '_';
679
677
  }
678
+ break;
679
+ }
680
680
  }
681
681
  }
682
682
  return name;
package/src/cmd/types.js CHANGED
@@ -1,26 +1,56 @@
1
- import { stat } from 'node:fs/promises';
1
+ import { stat, mkdir } from 'node:fs/promises';
2
2
  import { extname, basename, resolve } from 'node:path';
3
3
 
4
- import c from 'chalk-template';
5
-
6
4
  import {
7
5
  $init,
8
6
  generateTypes,
9
7
  } from '../../obj/js-component-bindgen-component.js';
8
+
10
9
  import {
11
10
  isWindows,
12
11
  writeFiles,
12
+ resolveDefaultWITPath,
13
+ styleText,
13
14
  ASYNC_WASI_IMPORTS,
14
15
  ASYNC_WASI_EXPORTS,
15
16
  DEFAULT_ASYNC_MODE,
16
17
  } from '../common.js';
17
18
 
19
+ /** Default relative path for guest type declaration generation */
20
+ const DEFAULT_GUEST_TYPES_OUTPUT_DIR_PATH = './types/generated/wit/guest';
21
+
22
+ /** Default relative path for host type declaration generation */
23
+ const DEFAULT_HOST_TYPES_OUTPUT_DIR_PATH = './types/generated/wit/host';
24
+
18
25
  export async function types(witPath, opts) {
26
+ witPath = await resolveDefaultWITPath(witPath);
27
+
28
+ // Use the default output directory if one was not provided
29
+ if (!opts.outDir) {
30
+ await mkdir(DEFAULT_HOST_TYPES_OUTPUT_DIR_PATH, { recursive: true });
31
+ opts.outDir = resolve(DEFAULT_HOST_TYPES_OUTPUT_DIR_PATH);
32
+ console.error(
33
+ `no output directory specified for host type declarations, using [${DEFAULT_HOST_TYPES_OUTPUT_DIR_PATH}]`
34
+ );
35
+ }
36
+
19
37
  const files = await typesComponent(witPath, opts);
38
+
20
39
  await writeFiles(files, opts.quiet ? false : 'Generated Type Files');
21
40
  }
22
41
 
23
42
  export async function guestTypes(witPath, opts) {
43
+ witPath = await resolveDefaultWITPath(witPath);
44
+
45
+ // Use the default output directory if one was not provided
46
+ if (!opts.outDir) {
47
+ await mkdir(DEFAULT_GUEST_TYPES_OUTPUT_DIR_PATH, { recursive: true });
48
+ opts.outDir = resolve(DEFAULT_GUEST_TYPES_OUTPUT_DIR_PATH);
49
+ console.error(
50
+ `no output directory specified for guest type declarations, using [${DEFAULT_GUEST_TYPES_OUTPUT_DIR_PATH}]`
51
+ );
52
+ }
53
+
24
54
  const files = await typesComponent(witPath, { ...opts, guest: true });
25
55
  await writeFiles(
26
56
  files,
@@ -140,17 +170,18 @@ export async function typesComponent(witPath, opts) {
140
170
  * @param {(string, any) => void} consoleFn
141
171
  */
142
172
  async function printWITLayoutHint(witPath) {
173
+ const warningPrefix = styleText(['yellow', 'bold'], 'warning');
143
174
  const pathMeta = await stat(witPath);
144
175
  let output = '\n';
145
176
  if (!pathMeta.isFile() && !pathMeta.isDirectory()) {
146
- output += c`{yellow.bold warning} The supplited WIT path [${witPath}] is neither a file or directory.\n`;
177
+ output += `${warningPrefix} The supplited WIT path [${witPath}] is neither a file or directory.\n`;
147
178
  return output;
148
179
  }
149
180
  const ftype = pathMeta.isDirectory() ? 'directory' : 'file';
150
- output += c`{yellow.bold warning} Your WIT ${ftype} [${witPath}] may be laid out incorrectly\n`;
151
- output += c`{yellow.bold warning} Keep in mind the following rules:\n`;
152
- output += c`{yellow.bold warning} - Top level WIT files are in the same package (i.e. "ns:pkg" in "wit/*.wit")\n`;
153
- output += c`{yellow.bold warning} - All package dependencies should be in "wit/deps" (i.e. "some:dep" in "wit/deps/some-dep.wit"\n`;
181
+ output += `${warningPrefix} Your WIT ${ftype} [${witPath}] may be laid out incorrectly\n`;
182
+ output += `${warningPrefix} Keep in mind the following rules:\n`;
183
+ output += `${warningPrefix} - Top level WIT files are in the same package (i.e. "ns:pkg" in "wit/*.wit")\n`;
184
+ output += `${warningPrefix} - All package dependencies should be in "wit/deps" (i.e. "some:dep" in "wit/deps/some-dep.wit"\n`;
154
185
  return output;
155
186
  }
156
187
 
@@ -1,5 +1,7 @@
1
+ import { resolve, basename, extname } from 'node:path';
1
2
  import { writeFile } from 'node:fs/promises';
2
- import { readFile, isWindows } from '../common.js';
3
+
4
+ import { readFile, isWindows, styleText } from '../common.js';
3
5
  import { $init, tools } from '../../obj/wasm-tools.js';
4
6
  const {
5
7
  print: printFn,
@@ -10,8 +12,6 @@ const {
10
12
  metadataAdd: metadataAddFn,
11
13
  metadataShow: metadataShowFn,
12
14
  } = tools;
13
- import { resolve, basename, extname } from 'node:path';
14
- import c from 'chalk-template';
15
15
 
16
16
  export async function parse(file, opts) {
17
17
  await $init;
@@ -142,19 +142,19 @@ export async function metadataShow(file, opts) {
142
142
  output += ' '.repeat(stack.length - 1);
143
143
  const indent = ' '.repeat(stack.length);
144
144
  if (metaType.tag === 'component') {
145
- output += c`{bold [component${name ? ' ' + name : ''}]}\n`;
145
+ output += `${styleText('bold', `[component${name ? ' ' + name : ''}]`)}\n`;
146
146
  if (metaType.val > 0) {
147
147
  stack.push(metaType.val);
148
148
  }
149
149
  } else {
150
- output += c`{bold [module${name ? ' ' + name : ''}]}\n`;
150
+ output += `${styleText('bold', `[module${name ? ' ' + name : ''}]`)}\n`;
151
151
  }
152
152
  if (producers.length === 0) {
153
153
  output += `${indent}(no metadata)\n`;
154
154
  }
155
155
  for (const [field, items] of producers) {
156
156
  for (const [name, version] of items) {
157
- output += `${indent}${(field + ':').padEnd(13, ' ')} ${name}${version ? c`{cyan ${version}}` : ''}\n`;
157
+ output += `${indent}${(field + ':').padEnd(13, ' ')} ${name}${version ? `${styleText('cyan', version)}` : ''}\n`;
158
158
  }
159
159
  }
160
160
  output += '\n';