@sprlab/wccompiler 0.16.11 → 0.16.13

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 +28 -19
  2. package/package.json +1 -1
package/lib/codegen.js CHANGED
@@ -120,6 +120,27 @@ function wrapTernaryExpr(expr) {
120
120
  export function transformExpr(expr, signalNames, computedNames, propsObjectName = null, propNames = new Set(), emitsObjectName = null, constantNames = [], methodNames = [], modelVarMap = new Map()) {
121
121
  let result = expr;
122
122
 
123
+ // BUG-0009 FIX: Protect object literal keys from transformation
124
+ // Store original keys and replace with placeholders to prevent them from being transformed
125
+ const keyPlaceholders = new Map();
126
+ let placeholderIndex = 0;
127
+
128
+ // Match ALL object literal keys (identifier or string before colon)
129
+ // We need to loop because replace with /g only replaces non-overlapping matches
130
+ let prevResult;
131
+ do {
132
+ prevResult = result;
133
+ result = result.replace(/(\{|,|;)\s*(?:([a-zA-Z_$][\w$]*)|(['"])([^'"\\]*(?:\\.[^'"\\]*)*?)\3)\s*:/g, (match, prefix, identifierKey, quote, stringKey) => {
134
+ const key = identifierKey || stringKey;
135
+ if (key && !key.startsWith('__KEY_PLACEHOLDER_')) {
136
+ const placeholder = `__KEY_PLACEHOLDER_${placeholderIndex++}__`;
137
+ keyPlaceholders.set(placeholder, identifierKey ? key : `${quote}${key}${quote}`);
138
+ return `${prefix} ${placeholder}:`;
139
+ }
140
+ return match;
141
+ });
142
+ } while (result !== prevResult);
143
+
123
144
  // Transform emit calls: emitsObjectName( → this._emit(
124
145
  if (emitsObjectName) {
125
146
  const emitsRe = new RegExp(`\\b${escapeRegex(emitsObjectName)}\\(`, 'g');
@@ -198,7 +219,12 @@ export function transformExpr(expr, signalNames, computedNames, propsObjectName
198
219
  const bareRe = new RegExp(`\\b(${name})\\b(?!\\.set\\()(?!\\()`, 'g');
199
220
  result = result.replace(bareRe, `this._const_${name}`);
200
221
  }
201
-
222
+
223
+ // BUG-0009 FIX: Restore original object literal keys from placeholders
224
+ for (const [placeholder, originalKey] of keyPlaceholders) {
225
+ result = result.replace(placeholder, originalKey);
226
+ }
227
+
202
228
  return result;
203
229
  }
204
230
 
@@ -1165,16 +1191,6 @@ export function generateComponent(parseResult, options = {}) {
1165
1191
  lines.push(" child.removeAttribute('slot-props');");
1166
1192
  lines.push(" __slotMap[slotName] = { content: propsExpr ? child.innerHTML : child.outerHTML, propsExpr };");
1167
1193
  lines.push(" } else if (child.nodeType === 1) {");
1168
- // NEW: check for slot-template-<name> attributes (React/Angular string attribute pattern)
1169
- lines.push(" for (const attr of Array.from(child.attributes)) {");
1170
- lines.push(" if (attr.name.startsWith('slot-template-')) {");
1171
- lines.push(" const slotName = attr.name.slice('slot-template-'.length);");
1172
- lines.push(" if (!__slotMap[slotName]) {");
1173
- lines.push(" __slotMap[slotName] = { content: attr.value, propsExpr: '' };");
1174
- lines.push(" }");
1175
- lines.push(" child.removeAttribute(attr.name);");
1176
- lines.push(" }");
1177
- lines.push(" }");
1178
1194
  lines.push(" __defaultSlotNodes.push(child);");
1179
1195
  lines.push(" } else if (child.nodeType === 3 && child.textContent.trim()) {");
1180
1196
  lines.push(' __defaultSlotNodes.push(child);');
@@ -1327,15 +1343,8 @@ export function generateComponent(parseResult, options = {}) {
1327
1343
  lines.push(" __sm[sn] = { content: pe ? child.innerHTML : child.outerHTML, propsExpr: pe };");
1328
1344
  lines.push(" child.remove();");
1329
1345
  lines.push(" } else if (child.nodeType === 1) {");
1330
- lines.push(" for (const attr of Array.from(child.attributes)) {");
1331
- lines.push(" if (attr.name.startsWith('slot-template-')) {");
1332
- lines.push(" const sn = attr.name.slice('slot-template-'.length);");
1333
- lines.push(" if (!__sm[sn]) { __sm[sn] = { content: attr.value, propsExpr: '' }; }");
1334
- lines.push(" child.removeAttribute(attr.name);");
1335
- lines.push(" }");
1336
- lines.push(" }");
1337
1346
  lines.push(" __dn.push(child);");
1338
- lines.push(" } else if (child.nodeType === 3 && child.textContent.trim()) {");
1347
+ lines.push(" } else if (child.nodeType === 3 && child.textContent.trim()) {",);
1339
1348
  lines.push(" __dn.push(child);");
1340
1349
  lines.push(' }');
1341
1350
  lines.push(' }');
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@sprlab/wccompiler",
3
- "version": "0.16.11",
3
+ "version": "0.16.13",
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": {