@arcmantle/lit-jsx 1.0.32 → 1.0.34

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 (84) hide show
  1. package/README.md +153 -105
  2. package/dist/compiler/attribute-processor.d.ts +9 -19
  3. package/dist/compiler/attribute-processor.d.ts.map +1 -1
  4. package/dist/compiler/attribute-processor.js +22 -39
  5. package/dist/compiler/attribute-processor.js.map +1 -1
  6. package/dist/compiler/babel-plugin.d.ts +1 -0
  7. package/dist/compiler/babel-plugin.d.ts.map +1 -1
  8. package/dist/compiler/babel-plugin.js +2 -1
  9. package/dist/compiler/babel-plugin.js.map +1 -1
  10. package/dist/compiler/compiler-utils.d.ts +9 -1
  11. package/dist/compiler/compiler-utils.d.ts.map +1 -1
  12. package/dist/compiler/compiler-utils.js +71 -60
  13. package/dist/compiler/compiler-utils.js.map +1 -1
  14. package/dist/compiler/config.d.ts +23 -28
  15. package/dist/compiler/config.d.ts.map +1 -1
  16. package/dist/compiler/config.js +28 -28
  17. package/dist/compiler/config.js.map +1 -1
  18. package/dist/compiler/oxc-walker.d.ts +4 -4
  19. package/dist/compiler/oxc-walker.d.ts.map +1 -1
  20. package/dist/compiler/oxc-walker.js +1 -1
  21. package/dist/compiler/oxc-walker.js.map +1 -1
  22. package/dist/compiler/preprocess.d.ts +1 -0
  23. package/dist/compiler/preprocess.d.ts.map +1 -1
  24. package/dist/compiler/preprocess.js +31 -0
  25. package/dist/compiler/preprocess.js.map +1 -1
  26. package/dist/compiler/transpiler.d.ts.map +1 -1
  27. package/dist/compiler/transpiler.js +31 -13
  28. package/dist/compiler/transpiler.js.map +1 -1
  29. package/dist/compiler/vite-plugin.d.ts +3 -1
  30. package/dist/compiler/vite-plugin.d.ts.map +1 -1
  31. package/dist/compiler/vite-plugin.js +1 -0
  32. package/dist/compiler/vite-plugin.js.map +1 -1
  33. package/dist/runtime/choose-component.d.ts +2 -2
  34. package/dist/runtime/choose-component.d.ts.map +1 -1
  35. package/dist/runtime/for-component.d.ts +3 -3
  36. package/dist/runtime/for-component.d.ts.map +1 -1
  37. package/dist/runtime/for-component.js.map +1 -1
  38. package/dist/runtime/lit-reexports.d.ts +11 -0
  39. package/dist/runtime/lit-reexports.d.ts.map +1 -0
  40. package/dist/runtime/lit-reexports.js +14 -0
  41. package/dist/runtime/lit-reexports.js.map +1 -0
  42. package/dist/runtime/show-component.d.ts +4 -4
  43. package/dist/runtime/show-component.d.ts.map +1 -1
  44. package/dist/runtime/type-helpers.d.ts +1 -1
  45. package/dist/runtime/type-helpers.d.ts.map +1 -1
  46. package/dist/shared/jsx-core.d.ts +83 -0
  47. package/dist/shared/jsx-core.d.ts.map +1 -0
  48. package/dist/shared/jsx-core.js +2 -0
  49. package/dist/shared/jsx-core.js.map +1 -0
  50. package/dist/shared/jsx-dom.d.ts +26 -0
  51. package/dist/shared/jsx-dom.d.ts.map +1 -0
  52. package/dist/shared/jsx-dom.js +2 -0
  53. package/dist/shared/jsx-dom.js.map +1 -0
  54. package/dist/shared/jsx-hooks.d.ts +69 -0
  55. package/dist/shared/jsx-hooks.d.ts.map +1 -0
  56. package/dist/shared/jsx-hooks.js +2 -0
  57. package/dist/shared/jsx-hooks.js.map +1 -0
  58. package/dist/shared/jsx-types.d.ts +3 -2140
  59. package/dist/shared/jsx-types.d.ts.map +1 -1
  60. package/dist/shared/jsx-types.js +3 -1
  61. package/dist/shared/jsx-types.js.map +1 -1
  62. package/dist/utils.d.ts +1 -0
  63. package/dist/utils.d.ts.map +1 -1
  64. package/dist/utils.js +3 -0
  65. package/dist/utils.js.map +1 -1
  66. package/package.json +17 -17
  67. package/src/compiler/attribute-processor.ts +33 -60
  68. package/src/compiler/babel-plugin.ts +3 -1
  69. package/src/compiler/compiler-utils.ts +91 -259
  70. package/src/compiler/config.ts +52 -43
  71. package/src/compiler/oxc-walker.ts +5 -5
  72. package/src/compiler/preprocess.ts +41 -0
  73. package/src/compiler/transpiler.ts +31 -12
  74. package/src/compiler/vite-plugin.ts +4 -1
  75. package/src/runtime/choose-component.ts +2 -2
  76. package/src/runtime/for-component.ts +3 -3
  77. package/src/runtime/lit-reexports.ts +16 -0
  78. package/src/runtime/show-component.ts +4 -4
  79. package/src/runtime/type-helpers.ts +1 -1
  80. package/src/shared/jsx-core.ts +123 -0
  81. package/src/shared/jsx-dom.ts +29 -0
  82. package/src/shared/jsx-hooks.ts +86 -0
  83. package/src/shared/jsx-types.ts +3 -2559
  84. package/src/utils.ts +15 -0
@@ -6,9 +6,9 @@ import * as t from '@babel/types';
6
6
 
7
7
  import { isMathmlTag } from '../shared/mathml-tags.js';
8
8
  import { isSvgTag } from '../shared/svg-tags.js';
9
- import type { ProcessorContext } from './attribute-processor.js';
9
+ import { hasCustomElementIdentifier, type ProcessorContext } from './attribute-processor.js';
10
10
  import { traverse } from './babel-traverse.js';
11
- import { babelPlugins, ERROR_MESSAGES, SOURCES, VARIABLES } from './config.js';
11
+ import { babelPlugins, ERROR_MESSAGES, options, SOURCES, VARIABLES } from './config.js';
12
12
  import { isDynamicOrCustomElement } from './import-discovery.js';
13
13
 
14
14
 
@@ -420,327 +420,132 @@ export class Ensure {
420
420
  }
421
421
 
422
422
 
423
+ interface ImportConfig {
424
+ source: string;
425
+ name: string;
426
+ local: string;
427
+ }
428
+
429
+ const IMPORT_CONFIGS = {
430
+ html: { source: SOURCES.HTML, name: VARIABLES.HTML, local: VARIABLES.HTML_LOCAL },
431
+ htmlStatic: { source: SOURCES.HTML_STATIC, name: VARIABLES.HTML_STATIC, local: VARIABLES.HTML_STATIC_LOCAL },
432
+ svg: { source: SOURCES.SVG, name: VARIABLES.SVG, local: VARIABLES.SVG_LOCAL },
433
+ svgStatic: { source: SOURCES.SVG_STATIC, name: VARIABLES.SVG_STATIC, local: VARIABLES.SVG_STATIC_LOCAL },
434
+ mathml: { source: SOURCES.MATHML, name: VARIABLES.MATHML, local: VARIABLES.MATHML_LOCAL },
435
+ mathmlStatic: { source: SOURCES.MATHML_STATIC, name: VARIABLES.MATHML_STATIC, local: VARIABLES.MATHML_STATIC_LOCAL },
436
+ unsafeStatic: { source: SOURCES.UNSAFE_STATIC, name: VARIABLES.UNSAFE_STATIC, local: VARIABLES.UNSAFE_STATIC_LOCAL },
437
+ createRef: { source: SOURCES.REF, name: VARIABLES.REF, local: VARIABLES.REF_LOCAL },
438
+ styleMap: { source: SOURCES.STYLE_MAP, name: VARIABLES.STYLE_MAP, local: VARIABLES.STYLE_MAP_LOCAL },
439
+ classMap: { source: SOURCES.CLASS_MAP, name: VARIABLES.CLASS_MAP, local: VARIABLES.CLASS_MAP_LOCAL },
440
+ rest: { source: SOURCES.REST, name: VARIABLES.REST, local: VARIABLES.REST },
441
+ literalMap: { source: SOURCES.LITERAL_MAP, name: VARIABLES.LITERAL_MAP, local: VARIABLES.LITERAL_MAP },
442
+ booleanPart: { source: SOURCES.JSX_LIT, name: VARIABLES.BOOLEAN_PART, local: VARIABLES.BOOLEAN_PART },
443
+ attributePart: { source: SOURCES.JSX_LIT, name: VARIABLES.ATTRIBUTE_PART, local: VARIABLES.ATTRIBUTE_PART },
444
+ propertyPart: { source: SOURCES.JSX_LIT, name: VARIABLES.PROPERTY_PART, local: VARIABLES.PROPERTY_PART },
445
+ elementPart: { source: SOURCES.JSX_LIT, name: VARIABLES.ELEMENT_PART, local: VARIABLES.ELEMENT_PART },
446
+ eventPart: { source: SOURCES.JSX_LIT, name: VARIABLES.EVENT_PART, local: VARIABLES.EVENT_PART },
447
+ childPart: { source: SOURCES.JSX_LIT, name: VARIABLES.CHILD_PART, local: VARIABLES.CHILD_PART },
448
+ tTemplateUtil: { source: SOURCES.JSX_LIT, name: VARIABLES.T_TEMPLATE_UTIL, local: VARIABLES.T_TEMPLATE_UTIL },
449
+ } as const;
450
+
423
451
  export class EnsureImport {
424
452
 
425
- static html(program: t.Program, path: NodePath): void {
453
+ protected static ensureImport(
454
+ config: ImportConfig,
455
+ program: t.Program,
456
+ path: NodePath,
457
+ ): void {
426
458
  Ensure.import(
427
- (source) => source === SOURCES.HTML || source === SOURCES.HTML_ALT,
428
- (name) => name === VARIABLES.HTML,
459
+ (source) => source === config.source,
460
+ (name) => name === config.name,
429
461
  () => t.importDeclaration(
430
462
  [
431
463
  t.importSpecifier(
432
- t.identifier(VARIABLES.HTML_LOCAL),
433
- t.identifier(VARIABLES.HTML),
464
+ t.identifier(config.local),
465
+ t.identifier(config.name),
434
466
  ),
435
467
  ],
436
- t.stringLiteral(SOURCES.HTML),
468
+ t.stringLiteral(config.source),
437
469
  ),
438
470
  program,
439
471
  path,
440
472
  );
441
473
  }
442
474
 
475
+ static html(program: t.Program, path: NodePath): void {
476
+ this.ensureImport(IMPORT_CONFIGS.html, program, path);
477
+ }
478
+
443
479
  static htmlStatic(program: t.Program, path: NodePath): void {
444
- Ensure.import(
445
- (source) => source === SOURCES.HTML_STATIC || source === SOURCES.HTML_STATIC_ALT,
446
- (name) => name === VARIABLES.HTML,
447
- () => t.importDeclaration(
448
- [
449
- t.importSpecifier(
450
- t.identifier(VARIABLES.HTML_STATIC_LOCAL),
451
- t.identifier(VARIABLES.HTML_STATIC),
452
- ),
453
- ],
454
- t.stringLiteral(SOURCES.HTML_STATIC),
455
- ),
456
- program,
457
- path,
458
- );
480
+ this.ensureImport(IMPORT_CONFIGS.htmlStatic, program, path);
459
481
  }
460
482
 
461
483
  static svg(program: t.Program, path: NodePath): void {
462
- Ensure.import(
463
- (source) => source === SOURCES.SVG || source === SOURCES.SVG_ALT,
464
- (name) => name === VARIABLES.SVG,
465
- () => t.importDeclaration(
466
- [
467
- t.importSpecifier(
468
- t.identifier(VARIABLES.SVG_LOCAL),
469
- t.identifier(VARIABLES.SVG),
470
- ),
471
- ],
472
- t.stringLiteral(SOURCES.SVG),
473
- ),
474
- program,
475
- path,
476
- );
484
+ this.ensureImport(IMPORT_CONFIGS.svg, program, path);
477
485
  }
478
486
 
479
487
  static svgStatic(program: t.Program, path: NodePath): void {
480
- Ensure.import(
481
- (source) => source === SOURCES.SVG_STATIC || source === SOURCES.SVG_STATIC_ALT,
482
- (name) => name === VARIABLES.SVG,
483
- () => t.importDeclaration(
484
- [
485
- t.importSpecifier(
486
- t.identifier(VARIABLES.SVG_STATIC_LOCAL),
487
- t.identifier(VARIABLES.SVG_STATIC),
488
- ),
489
- ],
490
- t.stringLiteral(SOURCES.SVG_STATIC),
491
- ),
492
- program,
493
- path,
494
- );
488
+ this.ensureImport(IMPORT_CONFIGS.svgStatic, program, path);
495
489
  }
496
490
 
497
491
  static mathml(program: t.Program, path: NodePath): void {
498
- Ensure.import(
499
- (source) => source === SOURCES.MATHML || source === SOURCES.MATHML_ALT,
500
- (name) => name === VARIABLES.MATHML,
501
- () => t.importDeclaration(
502
- [
503
- t.importSpecifier(
504
- t.identifier(VARIABLES.MATHML_LOCAL),
505
- t.identifier(VARIABLES.MATHML),
506
- ),
507
- ],
508
- t.stringLiteral(SOURCES.MATHML),
509
- ),
510
- program,
511
- path,
512
- );
492
+ this.ensureImport(IMPORT_CONFIGS.mathml, program, path);
513
493
  }
514
494
 
515
495
  static mathmlStatic(program: t.Program, path: NodePath): void {
516
- Ensure.import(
517
- (source) => source === SOURCES.MATHML_STATIC || source === SOURCES.MATHML_STATIC_ALT,
518
- (name) => name === VARIABLES.MATHML,
519
- () => t.importDeclaration(
520
- [
521
- t.importSpecifier(
522
- t.identifier(VARIABLES.MATHML_STATIC_LOCAL),
523
- t.identifier(VARIABLES.MATHML_STATIC),
524
- ),
525
- ],
526
- t.stringLiteral(SOURCES.MATHML_STATIC),
527
- ),
528
- program,
529
- path,
530
- );
496
+ this.ensureImport(IMPORT_CONFIGS.mathmlStatic, program, path);
531
497
  }
532
498
 
533
499
  static unsafeStatic(program: t.Program, path: NodePath): void {
534
- Ensure.import(
535
- (source) => source === SOURCES.UNSAFE_STATIC || source === SOURCES.UNSAFE_STATIC_ALT,
536
- (name) => name === VARIABLES.UNSAFE_STATIC,
537
- () => t.importDeclaration(
538
- [
539
- t.importSpecifier(
540
- t.identifier(VARIABLES.UNSAFE_STATIC_LOCAL),
541
- t.identifier(VARIABLES.UNSAFE_STATIC),
542
- ),
543
- ],
544
- t.stringLiteral(SOURCES.UNSAFE_STATIC),
545
- ),
546
- program,
547
- path,
548
- );
500
+ this.ensureImport(IMPORT_CONFIGS.unsafeStatic, program, path);
549
501
  }
550
502
 
551
503
  static createRef(program: t.Program, path: NodePath): void {
552
- Ensure.import(
553
- (source) => source === SOURCES.REF_ALT || source === SOURCES.REF,
554
- (name) => name === VARIABLES.REF,
555
- () => t.importDeclaration(
556
- [
557
- t.importSpecifier(
558
- t.identifier(VARIABLES.REF_LOCAL),
559
- t.identifier(VARIABLES.REF),
560
- ),
561
- ],
562
- t.stringLiteral(SOURCES.REF),
563
- ),
564
- program,
565
- path,
566
- );
504
+ this.ensureImport(IMPORT_CONFIGS.createRef, program, path);
567
505
  }
568
506
 
569
507
  static styleMap(program: t.Program, path: NodePath): void {
570
- Ensure.import(
571
- (source) => source === SOURCES.STYLE_MAP_ALT || source === SOURCES.STYLE_MAP,
572
- (name) => name === VARIABLES.STYLE_MAP,
573
- () => t.importDeclaration(
574
- [
575
- t.importSpecifier(
576
- t.identifier(VARIABLES.STYLE_MAP_LOCAL),
577
- t.identifier(VARIABLES.STYLE_MAP),
578
- ),
579
- ],
580
- t.stringLiteral(SOURCES.STYLE_MAP),
581
- ),
582
- program,
583
- path,
584
- );
508
+ this.ensureImport(IMPORT_CONFIGS.styleMap, program, path);
585
509
  }
586
510
 
587
511
  static classMap(program: t.Program, path: NodePath): void {
588
- Ensure.import(
589
- (source) => source === SOURCES.CLASS_MAP_ALT || source === SOURCES.CLASS_MAP,
590
- (name) => name === VARIABLES.CLASS_MAP,
591
- () => t.importDeclaration(
592
- [
593
- t.importSpecifier(
594
- t.identifier(VARIABLES.CLASS_MAP_LOCAL),
595
- t.identifier(VARIABLES.CLASS_MAP),
596
- ),
597
- ],
598
- t.stringLiteral(SOURCES.CLASS_MAP),
599
- ),
600
- program,
601
- path,
602
- );
512
+ this.ensureImport(IMPORT_CONFIGS.classMap, program, path);
603
513
  }
604
514
 
605
515
  static rest(program: t.Program, path: NodePath): void {
606
- Ensure.import(
607
- (source) => source === SOURCES.REST,
608
- (name) => name === VARIABLES.REST,
609
- () => t.importDeclaration(
610
- [
611
- t.importSpecifier(
612
- t.identifier(VARIABLES.REST),
613
- t.identifier(VARIABLES.REST),
614
- ),
615
- ],
616
- t.stringLiteral(SOURCES.REST),
617
- ),
618
- program,
619
- path,
620
- );
516
+ this.ensureImport(IMPORT_CONFIGS.rest, program, path);
621
517
  }
622
518
 
623
519
  static literalMap(program: t.Program, path: NodePath): void {
624
- Ensure.import(
625
- (source) => source === SOURCES.LITERAL_MAP,
626
- (name) => name === VARIABLES.LITERAL_MAP,
627
- () => t.importDeclaration(
628
- [
629
- t.importSpecifier(
630
- t.identifier(VARIABLES.LITERAL_MAP),
631
- t.identifier(VARIABLES.LITERAL_MAP),
632
- ),
633
- ],
634
- t.stringLiteral(SOURCES.LITERAL_MAP),
635
- ),
636
- program,
637
- path,
638
- );
520
+ this.ensureImport(IMPORT_CONFIGS.literalMap, program, path);
639
521
  }
640
522
 
641
523
  static taggedTemplateUtil(program: t.Program, path: NodePath): void {
642
- Ensure.import(
643
- (source) => source === SOURCES.JSX_LIT,
644
- (name) => name === VARIABLES.TAGGED_TEMPLATE_UTIL,
645
- () => t.importDeclaration([
646
- t.importSpecifier(
647
- t.identifier(VARIABLES.TAGGED_TEMPLATE_UTIL),
648
- t.identifier(VARIABLES.TAGGED_TEMPLATE_UTIL),
649
- ),
650
- ], t.stringLiteral(SOURCES.JSX_LIT)),
651
- program,
652
- path,
653
- );
524
+ this.ensureImport(IMPORT_CONFIGS.tTemplateUtil, program, path);
654
525
  }
655
526
 
656
527
  static booleanPart(program: t.Program, path: NodePath): void {
657
- Ensure.import(
658
- (source) => source === SOURCES.JSX_LIT,
659
- (name) => name === VARIABLES.BOOLEAN_PART,
660
- () => t.importDeclaration([
661
- t.importSpecifier(
662
- t.identifier(VARIABLES.BOOLEAN_PART),
663
- t.identifier(VARIABLES.BOOLEAN_PART),
664
- ),
665
- ], t.stringLiteral(SOURCES.JSX_LIT)),
666
- program,
667
- path,
668
- );
528
+ this.ensureImport(IMPORT_CONFIGS.booleanPart, program, path);
669
529
  }
670
530
 
671
531
  static attributePart(program: t.Program, path: NodePath): void {
672
- Ensure.import(
673
- (source) => source === SOURCES.JSX_LIT,
674
- (name) => name === VARIABLES.ATTRIBUTE_PART,
675
- () => t.importDeclaration([
676
- t.importSpecifier(
677
- t.identifier(VARIABLES.ATTRIBUTE_PART),
678
- t.identifier(VARIABLES.ATTRIBUTE_PART),
679
- ),
680
- ], t.stringLiteral(SOURCES.JSX_LIT)),
681
- program,
682
- path,
683
- );
532
+ this.ensureImport(IMPORT_CONFIGS.attributePart, program, path);
684
533
  }
685
534
 
686
535
  static propertyPart(program: t.Program, path: NodePath): void {
687
- Ensure.import(
688
- (source) => source === SOURCES.JSX_LIT,
689
- (name) => name === VARIABLES.PROPERTY_PART,
690
- () => t.importDeclaration([
691
- t.importSpecifier(
692
- t.identifier(VARIABLES.PROPERTY_PART),
693
- t.identifier(VARIABLES.PROPERTY_PART),
694
- ),
695
- ], t.stringLiteral(SOURCES.JSX_LIT)),
696
- program,
697
- path,
698
- );
536
+ this.ensureImport(IMPORT_CONFIGS.propertyPart, program, path);
699
537
  }
700
538
 
701
539
  static elementPart(program: t.Program, path: NodePath): void {
702
- Ensure.import(
703
- (source) => source === SOURCES.JSX_LIT,
704
- (name) => name === VARIABLES.ELEMENT_PART,
705
- () => t.importDeclaration([
706
- t.importSpecifier(
707
- t.identifier(VARIABLES.ELEMENT_PART),
708
- t.identifier(VARIABLES.ELEMENT_PART),
709
- ),
710
- ], t.stringLiteral(SOURCES.JSX_LIT)),
711
- program,
712
- path,
713
- );
540
+ this.ensureImport(IMPORT_CONFIGS.elementPart, program, path);
714
541
  }
715
542
 
716
543
  static eventPart(program: t.Program, path: NodePath): void {
717
- Ensure.import(
718
- (source) => source === SOURCES.JSX_LIT,
719
- (name) => name === VARIABLES.EVENT_PART,
720
- () => t.importDeclaration([
721
- t.importSpecifier(
722
- t.identifier(VARIABLES.EVENT_PART),
723
- t.identifier(VARIABLES.EVENT_PART),
724
- ),
725
- ], t.stringLiteral(SOURCES.JSX_LIT)),
726
- program,
727
- path,
728
- );
544
+ this.ensureImport(IMPORT_CONFIGS.eventPart, program, path);
729
545
  }
730
546
 
731
547
  static childPart(program: t.Program, path: NodePath): void {
732
- Ensure.import(
733
- (source) => source === SOURCES.JSX_LIT,
734
- (name) => name === VARIABLES.CHILD_PART,
735
- () => t.importDeclaration([
736
- t.importSpecifier(
737
- t.identifier(VARIABLES.CHILD_PART),
738
- t.identifier(VARIABLES.CHILD_PART),
739
- ),
740
- ], t.stringLiteral(SOURCES.JSX_LIT)),
741
- program,
742
- path,
743
- );
548
+ this.ensureImport(IMPORT_CONFIGS.childPart, program, path);
744
549
  }
745
550
 
746
551
  }
@@ -795,9 +600,14 @@ export const isJSXCustomElementComponent = (
795
600
  if (!isComponent(tagName))
796
601
  return false;
797
602
 
798
- if (isDynamicOrCustomElement(path.get('openingElement')))
603
+ if (hasCustomElementIdentifier(node.openingElement.attributes))
799
604
  return true;
800
605
 
606
+ if (options.useImportDiscovery) {
607
+ if (isDynamicOrCustomElement(path.get('openingElement')))
608
+ return true;
609
+ }
610
+
801
611
  return false;
802
612
  };
803
613
 
@@ -815,9 +625,14 @@ export const isJSXFunctionElementComponent = (
815
625
  if (!isComponent(tagName))
816
626
  return false;
817
627
 
818
- if (isDynamicOrCustomElement(path.get('openingElement')))
628
+ if (hasCustomElementIdentifier(node.openingElement.attributes))
819
629
  return false;
820
630
 
631
+ if (options.useImportDiscovery) {
632
+ if (isDynamicOrCustomElement(path.get('openingElement')))
633
+ return false;
634
+ }
635
+
821
636
  return true;
822
637
  };
823
638
 
@@ -839,6 +654,16 @@ export const isJSXElementStatic = (path: NodePath<t.JSXElement | t.JSXFragment>)
839
654
  return true;
840
655
 
841
656
  for (const childPath of path.get('children')) {
657
+ // If it has an expression container as a child, with an unknown value inside.
658
+ // treat it as a static element, as we cannot safely compile it.
659
+ if (t.isJSXExpressionContainer(childPath.node)) {
660
+ // Check if the expression value is a JSXElement or JSXFragment
661
+ if (!t.isJSXElement(childPath.node.expression)
662
+ && !t.isJSXFragment(childPath.node.expression))
663
+ return true;
664
+ }
665
+
666
+ // If it's not a jsx element and not a jsx fragment, continue skip this.
842
667
  if (!isJSXElementPath(childPath) && !isJSXFragmentPath(childPath))
843
668
  continue;
844
669
 
@@ -892,3 +717,10 @@ export const getTemplateTag = (
892
717
 
893
718
  return VARIABLES.HTML;
894
719
  };
720
+
721
+
722
+ export const normalizeText = (text: string): string => {
723
+ return text
724
+ .replace(/[\r\n\t]/g, '')
725
+ .replace(/ {2,}/g, ' ');
726
+ };
@@ -1,12 +1,18 @@
1
1
  import type { BabelFile, PluginPass } from '@babel/core';
2
2
 
3
+
3
4
  export type BabelPlugins = NonNullable<NonNullable<babel.TransformOptions['parserOpts']>['plugins']>;
4
5
 
5
6
 
6
- export const babelPlugins: Set<BabelPlugins[number]> = new Set([ 'jsx', 'typescript', 'decorators', 'decoratorAutoAccessors' ]);
7
+ export const babelPlugins: Set<BabelPlugins[number]> = new Set([
8
+ 'jsx',
9
+ 'typescript',
10
+ 'decorators',
11
+ 'decoratorAutoAccessors',
12
+ ]);
7
13
  export const debugMode = { value: false };
8
14
 
9
-
15
+ export const CE_ATTR_IDENTIFIER = 'static';
10
16
  export const COMPONENT_LITERAL_PREFIX = '__$';
11
17
  export const WHITESPACE_TAGS: string[] = [ 'pre', 'textarea' ];
12
18
  export const SPECIAL_TAGS: string[] = [];
@@ -15,7 +21,7 @@ export const ATTR_NAMES = {
15
21
  CLASS_LIST: 'classList',
16
22
  STYLE_LIST: 'styleList',
17
23
  DIRECTIVE: 'directive',
18
- EVENT_PREFIX: 'on-',
24
+ EVENT_PREFIX: 'on',
19
25
  } as const;
20
26
  export const ATTR_BIND_OBJ_NAME = 'as';
21
27
  export const ATTR_VALUES = {
@@ -25,15 +31,15 @@ export const ATTR_VALUES = {
25
31
  export const VARIABLES = {
26
32
  HTML: 'html',
27
33
  HTML_LOCAL: '__$html',
28
- HTML_STATIC: 'html',
34
+ HTML_STATIC: 'htmlStatic',
29
35
  HTML_STATIC_LOCAL: '__$htmlStatic',
30
36
  SVG: 'svg',
31
37
  SVG_LOCAL: '__$svg',
32
- SVG_STATIC: 'svg',
38
+ SVG_STATIC: 'svgStatic',
33
39
  SVG_STATIC_LOCAL: '__$svgStatic',
34
40
  MATHML: 'mathml',
35
41
  MATHML_LOCAL: '__$mathml',
36
- MATHML_STATIC: 'mathml',
42
+ MATHML_STATIC: 'mathmlStatic',
37
43
  MATHML_STATIC_LOCAL: '__$mathmlStatic',
38
44
  UNSAFE_STATIC: 'unsafeStatic',
39
45
  UNSAFE_STATIC_LOCAL: '__$unsafeStatic',
@@ -43,41 +49,30 @@ export const VARIABLES = {
43
49
  STYLE_MAP_LOCAL: '__$styleMap',
44
50
  REF: 'ref',
45
51
  REF_LOCAL: '__$ref',
46
-
47
- REST: '__$rest',
48
- LITERAL_MAP: '__$literalMap',
49
- TAGGED_TEMPLATE_UTIL: '__$t',
50
- BOOLEAN_PART: 'BooleanPart',
51
- ATTRIBUTE_PART: 'AttributePart',
52
- PROPERTY_PART: 'PropertyPart',
53
- ELEMENT_PART: 'ElementPart',
54
- EVENT_PART: 'EventPart',
55
- CHILD_PART: 'ChildPart',
52
+ REST: '__$rest',
53
+ LITERAL_MAP: '__$literalMap',
54
+ T_TEMPLATE_UTIL: '__$t',
55
+ BOOLEAN_PART: 'BooleanPart',
56
+ ATTRIBUTE_PART: 'AttributePart',
57
+ PROPERTY_PART: 'PropertyPart',
58
+ ELEMENT_PART: 'ElementPart',
59
+ EVENT_PART: 'EventPart',
60
+ CHILD_PART: 'ChildPart',
56
61
  } as const;
57
62
  export const SOURCES = {
58
- HTML: 'lit-html',
59
- HTML_ALT: 'lit',
60
- HTML_STATIC: 'lit-html/static.js',
61
- HTML_STATIC_ALT: 'lit/static-html.js',
62
- SVG: 'lit-html/directives/svg.js',
63
- SVG_ALT: 'lit/directives/svg.js',
64
- MATHML: 'lit-html/directives/mathml.js',
65
- MATHML_ALT: 'lit/directives/mathml.js',
66
- SVG_STATIC: 'lit-html/static.js',
67
- SVG_STATIC_ALT: 'lit/static-html.js',
68
- MATHML_STATIC: 'lit-html/static.js',
69
- MATHML_STATIC_ALT: 'lit/static-html.js',
70
- UNSAFE_STATIC: 'lit-html/static.js',
71
- UNSAFE_STATIC_ALT: 'lit/static-html.js',
72
- REF: 'lit-html/directives/ref.js',
73
- REF_ALT: 'lit/directives/ref.js',
74
- CLASS_MAP: 'lit-html/directives/class-map.js',
75
- CLASS_MAP_ALT: 'lit/directives/class-map.js',
76
- STYLE_MAP: 'lit-html/directives/style-map.js',
77
- STYLE_MAP_ALT: 'lit/directives/style-map.js',
78
- REST: '@arcmantle/lit-jsx',
79
- LITERAL_MAP: '@arcmantle/lit-jsx',
80
- JSX_LIT: '@arcmantle/lit-jsx',
63
+ HTML: '@arcmantle/lit-jsx',
64
+ HTML_STATIC: '@arcmantle/lit-jsx',
65
+ SVG: '@arcmantle/lit-jsx',
66
+ SVG_STATIC: '@arcmantle/lit-jsx',
67
+ MATHML: '@arcmantle/lit-jsx',
68
+ MATHML_STATIC: '@arcmantle/lit-jsx',
69
+ UNSAFE_STATIC: '@arcmantle/lit-jsx',
70
+ REF: '@arcmantle/lit-jsx',
71
+ CLASS_MAP: '@arcmantle/lit-jsx',
72
+ STYLE_MAP: '@arcmantle/lit-jsx',
73
+ REST: '@arcmantle/lit-jsx',
74
+ LITERAL_MAP: '@arcmantle/lit-jsx',
75
+ JSX_LIT: '@arcmantle/lit-jsx',
81
76
  } as const;
82
77
  export const ERROR_MESSAGES = {
83
78
  INVALID_INITIAL_ELEMENT: 'Invalid initial element found. The first element must be a JSX element.',
@@ -97,26 +92,40 @@ export const ERROR_MESSAGES = {
97
92
  } as const;
98
93
 
99
94
 
95
+ interface PluginOptions {
96
+ useCompiledTemplates?: boolean;
97
+ useImportDiscovery?: boolean;
98
+ }
99
+
100
+
100
101
  export const initializePluginOptions = (file: BabelFile): { useCompiledTemplates?: boolean; } => {
101
102
  if (optionsInitialized)
102
103
  return options;
103
104
 
104
105
  optionsInitialized = true;
105
106
 
106
- const plugin = file.opts?.plugins
107
- ?.find(plugin => (plugin as PluginPass).key === 'lit-jsx-transform') as { options?: { useCompiledTemplates?: boolean; }; };
107
+ const plugin = file.opts?.plugins?.find(plugin =>
108
+ (plugin as PluginPass).key === 'lit-jsx-transform') as { options?: PluginOptions; };
108
109
 
109
110
  const pluginOptions = plugin?.options || {};
111
+ pluginOptions.useCompiledTemplates ??= true;
110
112
 
111
113
  for (const [ key, value ] of Object.entries(pluginOptions))
112
114
  options[key as keyof typeof options] = value as any;
113
115
 
114
116
  console.log(`Lit JSX plugin options initialized:`, options);
115
117
 
116
-
117
118
  return pluginOptions;
118
119
  };
119
120
 
120
121
 
122
+ export const getPluginOptions = (file: BabelFile): PluginOptions => {
123
+ const plugin = file.opts?.plugins?.find(plugin =>
124
+ (plugin as PluginPass).key === 'lit-jsx-transform') as { options?: PluginOptions; };
125
+
126
+ return plugin.options ?? {};
127
+ };
128
+
129
+
121
130
  let optionsInitialized = false;
122
- export const options: { useCompiledTemplates?: boolean; } = {};
131
+ export const options: PluginOptions = {};
@@ -1,19 +1,19 @@
1
- import oxc from 'oxc-parser';
1
+ import { type Node, type Program } from 'oxc-parser';
2
2
  import { ScopeTracker, walk } from 'oxc-walker';
3
3
 
4
4
 
5
5
  type WalkerContext = ThisParameterType<NonNullable<Parameters<typeof walk>[1]['enter']>>;
6
6
  type WalkerCallbackContext = Parameters<NonNullable<Parameters<typeof walk>[1]['enter']>>[2];
7
- type NodeWalker<T extends oxc.Node['type']> = (
8
- node: Extract<oxc.Node, { type: T; }>,
9
- parent: oxc.Node | null,
7
+ type NodeWalker<T extends Node['type']> = (
8
+ node: Extract<Node, { type: T; }>,
9
+ parent: Node | null,
10
10
  ctx: WalkerContext,
11
11
  scope: ScopeTracker,
12
12
  cbCtx: WalkerCallbackContext
13
13
  ) => void;
14
14
 
15
15
 
16
- export const oxcWalker = (input: oxc.Program | oxc.Node, options: Partial<{
16
+ export const oxcWalker = (input: Program | Node, options: Partial<{
17
17
  callExpression: NodeWalker<'CallExpression'>;
18
18
  }>): void => {
19
19
  const scopeTracker = new ScopeTracker();
@@ -76,3 +76,44 @@ export const preprocess: VisitNodeFunction<PluginPass, t.Program> = (path): void
76
76
  path.traverse(ensureValidJSXNesting);
77
77
  path.traverse(ensureValidFunctionsReturningJSX);
78
78
  };
79
+
80
+
81
+ /**
82
+ * Strips all compiler-only helper calls like `as.prop(x)`, `as.bool(x)`, and `as.tag(x)`.
83
+ *
84
+ * These helpers are declared as type-only globals and must never survive into emitted JS.
85
+ * This runs AFTER JSX transformation, so the JSX transformer has already used as.prop() and
86
+ * as.bool() to determine the correct part types (BooleanPart, PropertyPart, etc).
87
+ */
88
+ const stripCompilerOnlyAsHelpers: TraverseOptions = {
89
+ CallExpression(path) {
90
+ const { node } = path;
91
+
92
+ if (!t.isMemberExpression(node.callee))
93
+ return;
94
+
95
+ if (!t.isIdentifier(node.callee.object) || node.callee.object.name !== 'as')
96
+ return;
97
+
98
+ if (!t.isIdentifier(node.callee.property))
99
+ return;
100
+
101
+ const name = node.callee.property.name;
102
+ if (name !== 'prop' && name !== 'bool' && name !== 'tag')
103
+ return;
104
+
105
+ if (node.arguments.length !== 1)
106
+ return;
107
+
108
+ const arg = node.arguments[0];
109
+ if (!t.isExpression(arg))
110
+ return;
111
+
112
+ // Strip all as.* helper calls after JSX transformation
113
+ path.replaceWith(arg);
114
+ },
115
+ };
116
+
117
+ export const postprocess: VisitNodeFunction<PluginPass, t.Program> = (path): void => {
118
+ path.traverse(stripCompilerOnlyAsHelpers);
119
+ };