@sprlab/wccompiler 0.16.6 → 0.16.7

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 (2) hide show
  1. package/lib/codegen.js +36 -22
  2. package/package.json +1 -1
package/lib/codegen.js CHANGED
@@ -317,9 +317,10 @@ export function transformMethodBody(body, signalNames, computedNames, propsObjec
317
317
  * @param {Set<string>} propsSet
318
318
  * @param {Set<string>} rootVarNames - Set of signal names
319
319
  * @param {Set<string>} computedNames
320
+ * @param {string[]} methodNames
320
321
  * @returns {string}
321
322
  */
322
- export function transformForExpr(expr, itemVar, indexVar, propsSet, rootVarNames, computedNames) {
323
+ export function transformForExpr(expr, itemVar, indexVar, propsSet, rootVarNames, computedNames, methodNames = []) {
323
324
  let r = expr;
324
325
  const excludeSet = new Set([itemVar]);
325
326
  if (indexVar) excludeSet.add(indexVar);
@@ -345,6 +346,17 @@ export function transformForExpr(expr, itemVar, indexVar, propsSet, rootVarNames
345
346
  // Then: transform bare name references
346
347
  r = r.replace(new RegExp(`\\b${n}\\b(?!\\()`, 'g'), `this._c_${n}()`);
347
348
  }
349
+ // Transform method calls: methodName(args) → this._methodName(args)
350
+ for (const m of methodNames) {
351
+ if (excludeSet.has(m)) continue;
352
+ // Transform method calls with arguments
353
+ r = r.replace(new RegExp(`\\b${m}\\(`, 'g'), `this._${m}(`);
354
+ }
355
+ // Transform bare method references (not followed by parentheses)
356
+ for (const m of methodNames) {
357
+ if (excludeSet.has(m)) continue;
358
+ r = r.replace(new RegExp(`\\b${m}\\b(?!\\()`, 'g'), `this._${m}`);
359
+ }
348
360
  return r;
349
361
  }
350
362
 
@@ -440,22 +452,23 @@ export function generateEventHandler(handler, signalNames, computedNames, propsO
440
452
  * @param {Set<string>} propNames
441
453
  * @param {Set<string>} signalNamesSet
442
454
  * @param {Set<string>} computedNamesSet
455
+ * @param {string[]} methodNames
443
456
  * @returns {string}
444
457
  */
445
- export function generateForEventHandler(handler, itemVar, indexVar, propNames, signalNamesSet, computedNamesSet) {
458
+ export function generateForEventHandler(handler, itemVar, indexVar, propNames, signalNamesSet, computedNamesSet, methodNames) {
446
459
  if (handler.includes('=>')) {
447
460
  // Arrow function expression
448
461
  const arrowIdx = handler.indexOf('=>');
449
462
  const params = handler.slice(0, arrowIdx).trim();
450
463
  let body = handler.slice(arrowIdx + 2).trim();
451
- body = transformForExpr(body, itemVar, indexVar, propNames, signalNamesSet, computedNamesSet);
464
+ body = transformForExpr(body, itemVar, indexVar, propNames, signalNamesSet, computedNamesSet, methodNames);
452
465
  return `${params} => { ${body}; }`;
453
466
  } else if (handler.includes('(')) {
454
467
  // Function call expression: removeItem(item)
455
468
  const parenIdx = handler.indexOf('(');
456
469
  const fnName = handler.slice(0, parenIdx).trim();
457
470
  const args = handler.slice(parenIdx + 1, handler.lastIndexOf(')')).trim();
458
- const transformedArgs = args ? transformForExpr(args, itemVar, indexVar, propNames, signalNamesSet, computedNamesSet) : '';
471
+ const transformedArgs = args ? transformForExpr(args, itemVar, indexVar, propNames, signalNamesSet, computedNamesSet, methodNames) : '';
459
472
  return `(e) => { this._${fnName}(${transformedArgs}); }`;
460
473
  } else {
461
474
  // Simple method name
@@ -474,8 +487,9 @@ export function generateForEventHandler(handler, itemVar, indexVar, propNames, s
474
487
  * @param {Set<string>} propNames
475
488
  * @param {Set<string>} signalNamesSet
476
489
  * @param {Set<string>} computedNamesSet
490
+ * @param {string[]} methodNames
477
491
  */
478
- function generateItemSetup(lines, forBlock, itemVar, indexVar, propNames, signalNamesSet, computedNamesSet) {
492
+ function generateItemSetup(lines, forBlock, itemVar, indexVar, propNames, signalNamesSet, computedNamesSet, methodNames) {
479
493
  const indent = ' ';
480
494
 
481
495
  // Bindings
@@ -484,7 +498,7 @@ function generateItemSetup(lines, forBlock, itemVar, indexVar, propNames, signal
484
498
  if (isStaticForBinding(b.name, itemVar, indexVar)) {
485
499
  lines.push(`${indent} ${nodeRef}.textContent = ${b.name} ?? '';`);
486
500
  } else {
487
- const expr = transformForExpr(b.name, itemVar, indexVar, propNames, signalNamesSet, computedNamesSet);
501
+ const expr = transformForExpr(b.name, itemVar, indexVar, propNames, signalNamesSet, computedNamesSet, methodNames);
488
502
  lines.push(`${indent} __effect(() => { ${nodeRef}.textContent = ${wrapTernaryExpr(expr)} ?? ''; });`);
489
503
  }
490
504
  }
@@ -492,7 +506,7 @@ function generateItemSetup(lines, forBlock, itemVar, indexVar, propNames, signal
492
506
  // Events
493
507
  for (const e of forBlock.events) {
494
508
  const nodeRef = pathExpr(e.path, 'node');
495
- const handlerExpr = generateForEventHandler(e.handler, itemVar, indexVar, propNames, signalNamesSet, computedNamesSet);
509
+ const handlerExpr = generateForEventHandler(e.handler, itemVar, indexVar, propNames, signalNamesSet, computedNamesSet, methodNames);
496
510
  lines.push(`${indent} ${nodeRef}.addEventListener('${e.event}', ${handlerExpr});`);
497
511
  }
498
512
 
@@ -502,7 +516,7 @@ function generateItemSetup(lines, forBlock, itemVar, indexVar, propNames, signal
502
516
  if (isStaticForExpr(sb.expression, itemVar, indexVar, propNames, signalNamesSet, computedNamesSet)) {
503
517
  lines.push(`${indent} ${nodeRef}.style.display = (${sb.expression}) ? '' : 'none';`);
504
518
  } else {
505
- const expr = transformForExpr(sb.expression, itemVar, indexVar, propNames, signalNamesSet, computedNamesSet);
519
+ const expr = transformForExpr(sb.expression, itemVar, indexVar, propNames, signalNamesSet, computedNamesSet, methodNames);
506
520
  lines.push(`${indent} __effect(() => { ${nodeRef}.style.display = (${expr}) ? '' : 'none'; });`);
507
521
  }
508
522
  }
@@ -514,7 +528,7 @@ function generateItemSetup(lines, forBlock, itemVar, indexVar, propNames, signal
514
528
  lines.push(`${indent} const __val_${ab.varName} = ${ab.expression};`);
515
529
  lines.push(`${indent} if (__val_${ab.varName} != null && __val_${ab.varName} !== false) { ${nodeRef}.setAttribute('${ab.attr}', __val_${ab.varName}); }`);
516
530
  } else {
517
- const expr = transformForExpr(ab.expression, itemVar, indexVar, propNames, signalNamesSet, computedNamesSet);
531
+ const expr = transformForExpr(ab.expression, itemVar, indexVar, propNames, signalNamesSet, computedNamesSet, methodNames);
518
532
  lines.push(`${indent} __effect(() => {`);
519
533
  lines.push(`${indent} const __val = ${expr};`);
520
534
  lines.push(`${indent} if (__val == null || __val === false) { ${nodeRef}.removeAttribute('${ab.attr}'); }`);
@@ -583,7 +597,7 @@ function generateItemSetup(lines, forBlock, itemVar, indexVar, propNames, signal
583
597
  lines.push(`${indent} const ${innerVn}_anchor = ${pathExpr(innerFor.anchorPath, 'node')};`);
584
598
 
585
599
  // Transform the inner source expression (may reference outer item var)
586
- const innerSourceExpr = transformForExpr(innerSource, itemVar, indexVar, propNames, signalNamesSet, computedNamesSet);
600
+ const innerSourceExpr = transformForExpr(innerSource, itemVar, indexVar, propNames, signalNamesSet, computedNamesSet, methodNames);
587
601
 
588
602
  // Determine if inner source is static (only references outer loop vars)
589
603
  const innerSourceIsStatic = isStaticForExpr(innerSource, itemVar, indexVar, propNames, signalNamesSet, computedNamesSet);
@@ -601,7 +615,7 @@ function generateItemSetup(lines, forBlock, itemVar, indexVar, propNames, signal
601
615
  lines.push(`${indent} const innerNode = clone.firstChild;`);
602
616
 
603
617
  // Generate inner item bindings with combined excludeSet
604
- generateNestedItemSetup(lines, innerFor, itemVar, indexVar, innerItemVar, innerIndexVar, propNames, signalNamesSet, computedNamesSet, indent + ' ');
618
+ generateNestedItemSetup(lines, innerFor, itemVar, indexVar, innerItemVar, innerIndexVar, propNames, signalNamesSet, computedNamesSet, methodNames, indent + ' ');
605
619
 
606
620
  lines.push(`${indent} ${innerVn}_newNodes.push(innerNode);`);
607
621
  lines.push(`${indent} });`);
@@ -617,7 +631,7 @@ function generateItemSetup(lines, forBlock, itemVar, indexVar, propNames, signal
617
631
  lines.push(`${indent} const innerNode = clone.firstChild;`);
618
632
 
619
633
  // Generate inner item bindings with combined excludeSet
620
- generateNestedItemSetup(lines, innerFor, itemVar, indexVar, innerItemVar, innerIndexVar, propNames, signalNamesSet, computedNamesSet, indent + ' ');
634
+ generateNestedItemSetup(lines, innerFor, itemVar, indexVar, innerItemVar, innerIndexVar, propNames, signalNamesSet, computedNamesSet, methodNames, indent + ' ');
621
635
 
622
636
  lines.push(`${indent} ${innerVn}_anchor.parentNode.insertBefore(innerNode, ${innerVn}_anchor);`);
623
637
  lines.push(`${indent} });`);
@@ -690,7 +704,7 @@ function generateItemSetup(lines, forBlock, itemVar, indexVar, propNames, signal
690
704
  if (isStaticForBinding(b.name, itemVar, indexVar)) {
691
705
  lines.push(`${indent} ${nodeRef}.textContent = ${b.name} ?? '';`);
692
706
  } else {
693
- const expr = transformForExpr(b.name, itemVar, indexVar, propNames, signalNamesSet, computedNamesSet);
707
+ const expr = transformForExpr(b.name, itemVar, indexVar, propNames, signalNamesSet, computedNamesSet, methodNames);
694
708
  lines.push(`${indent} __effect(() => { ${nodeRef}.textContent = ${wrapTernaryExpr(expr)} ?? ''; });`);
695
709
  }
696
710
  }
@@ -698,7 +712,7 @@ function generateItemSetup(lines, forBlock, itemVar, indexVar, propNames, signal
698
712
  // Events
699
713
  for (const e of branch.events) {
700
714
  const nodeRef = pathExpr(e.path, `${vn}_node`);
701
- const handlerExpr = generateForEventHandler(e.handler, itemVar, indexVar, propNames, signalNamesSet, computedNamesSet);
715
+ const handlerExpr = generateForEventHandler(e.handler, itemVar, indexVar, propNames, signalNamesSet, computedNamesSet, methodNames);
702
716
  lines.push(`${indent} ${nodeRef}.addEventListener('${e.event}', ${handlerExpr});`);
703
717
  }
704
718
 
@@ -708,7 +722,7 @@ function generateItemSetup(lines, forBlock, itemVar, indexVar, propNames, signal
708
722
  if (isStaticForExpr(sb.expression, itemVar, indexVar, propNames, signalNamesSet, computedNamesSet)) {
709
723
  lines.push(`${indent} ${nodeRef}.style.display = (${sb.expression}) ? '' : 'none';`);
710
724
  } else {
711
- const expr = transformForExpr(sb.expression, itemVar, indexVar, propNames, signalNamesSet, computedNamesSet);
725
+ const expr = transformForExpr(sb.expression, itemVar, indexVar, propNames, signalNamesSet, computedNamesSet, methodNames);
712
726
  lines.push(`${indent} __effect(() => { ${nodeRef}.style.display = (${expr}) ? '' : 'none'; });`);
713
727
  }
714
728
  }
@@ -720,7 +734,7 @@ function generateItemSetup(lines, forBlock, itemVar, indexVar, propNames, signal
720
734
  lines.push(`${indent} const __val_${ab.varName} = ${ab.expression};`);
721
735
  lines.push(`${indent} if (__val_${ab.varName} != null && __val_${ab.varName} !== false) { ${nodeRef}.setAttribute('${ab.attr}', __val_${ab.varName}); }`);
722
736
  } else {
723
- const expr = transformForExpr(ab.expression, itemVar, indexVar, propNames, signalNamesSet, computedNamesSet);
737
+ const expr = transformForExpr(ab.expression, itemVar, indexVar, propNames, signalNamesSet, computedNamesSet, methodNames);
724
738
  lines.push(`${indent} __effect(() => {`);
725
739
  lines.push(`${indent} const __val = ${expr};`);
726
740
  lines.push(`${indent} if (__val == null || __val === false) { ${nodeRef}.removeAttribute('${ab.attr}'); }`);
@@ -772,7 +786,7 @@ function generateItemSetup(lines, forBlock, itemVar, indexVar, propNames, signal
772
786
  * @param {Set<string>} computedNamesSet - Computed names set
773
787
  * @param {string} indent - Current indentation
774
788
  */
775
- function generateNestedItemSetup(lines, innerFor, outerItemVar, outerIndexVar, innerItemVar, innerIndexVar, propNames, signalNamesSet, computedNamesSet, indent) {
789
+ function generateNestedItemSetup(lines, innerFor, outerItemVar, outerIndexVar, innerItemVar, innerIndexVar, propNames, signalNamesSet, computedNamesSet, methodNames, indent) {
776
790
  // Build combined exclude set with both outer and inner loop variables
777
791
  const combinedExcludeItemVar = innerItemVar;
778
792
  const combinedExcludeIndexVar = innerIndexVar;
@@ -810,7 +824,7 @@ function generateNestedItemSetup(lines, innerFor, outerItemVar, outerIndexVar, i
810
824
 
811
825
  // Helper: transform expression excluding both outer and inner loop vars
812
826
  function transformNested(expr) {
813
- return transformForExpr(expr, innerItemVar, innerIndexVar, filteredPropNames, filteredSignalNames, filteredComputedNames);
827
+ return transformForExpr(expr, innerItemVar, innerIndexVar, filteredPropNames, filteredSignalNames, filteredComputedNames, methodNames);
814
828
  }
815
829
 
816
830
  // Bindings
@@ -827,7 +841,7 @@ function generateNestedItemSetup(lines, innerFor, outerItemVar, outerIndexVar, i
827
841
  // Events
828
842
  for (const e of innerFor.events) {
829
843
  const nodeRef = pathExpr(e.path, 'innerNode');
830
- const handlerExpr = generateForEventHandler(e.handler, innerItemVar, innerIndexVar, filteredPropNames, filteredSignalNames, filteredComputedNames);
844
+ const handlerExpr = generateForEventHandler(e.handler, innerItemVar, innerIndexVar, filteredPropNames, filteredSignalNames, filteredComputedNames, methodNames);
831
845
  lines.push(`${indent}${nodeRef}.addEventListener('${e.event}', ${handlerExpr});`);
832
846
  }
833
847
 
@@ -1674,7 +1688,7 @@ export function generateComponent(parseResult, options = {}) {
1674
1688
  const computedNamesSet = new Set(computedNames);
1675
1689
 
1676
1690
  // Transform the source expression
1677
- const sourceExpr = transformForExpr(source, itemVar, indexVar, propNames, signalNamesSet, computedNamesSet);
1691
+ const sourceExpr = transformForExpr(source, itemVar, indexVar, propNames, signalNamesSet, computedNamesSet, methodNames);
1678
1692
 
1679
1693
  lines.push(' this.__disposers.push(__effect(() => {');
1680
1694
  lines.push(` const __source = ${sourceExpr};`);
@@ -1703,7 +1717,7 @@ export function generateComponent(parseResult, options = {}) {
1703
1717
 
1704
1718
  // Setup bindings/events/show/attr/model/slots for NEW nodes only
1705
1719
  // (reused nodes keep their existing bindings)
1706
- generateItemSetup(lines, forBlock, itemVar, indexVar, propNames, signalNamesSet, computedNamesSet);
1720
+ generateItemSetup(lines, forBlock, itemVar, indexVar, propNames, signalNamesSet, computedNamesSet, methodNames);
1707
1721
 
1708
1722
  lines.push(' __newMap.set(__key, node);');
1709
1723
  lines.push(' __newNodes.push(node);');
@@ -1728,7 +1742,7 @@ export function generateComponent(parseResult, options = {}) {
1728
1742
  lines.push(` const clone = this.${vn}_tpl.content.cloneNode(true);`);
1729
1743
  lines.push(' const node = clone.firstChild;');
1730
1744
 
1731
- generateItemSetup(lines, forBlock, itemVar, indexVar, propNames, signalNamesSet, computedNamesSet);
1745
+ generateItemSetup(lines, forBlock, itemVar, indexVar, propNames, signalNamesSet, computedNamesSet, methodNames);
1732
1746
 
1733
1747
  lines.push(` this.${vn}_anchor.parentNode.insertBefore(node, this.${vn}_anchor);`);
1734
1748
  lines.push(' customElements.upgrade(node);');
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@sprlab/wccompiler",
3
- "version": "0.16.6",
3
+ "version": "0.16.7",
4
4
  "description": "Zero-runtime compiler that transforms .wcc single-file components into native web components with signals-based reactivity",
5
5
  "type": "module",
6
6
  "exports": {