@xaendar/compiler 0.5.7 → 0.5.8

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.
@@ -2221,16 +2221,45 @@ function processElement(node, nodeName, parentNode, context) {
2221
2221
  const childrenContext = new Context([], context);
2222
2222
  return [
2223
2223
  `const ${nodeName} = document.createElement("${node.tagName}");`,
2224
- ...node.attributes?.map((attr) => {
2225
- const value = attr.value;
2226
- return typeof value === "string" ? `${nodeName}.setAttribute('${attr.name}', ${value});` : `unwatchFns.push(effect(() => ${nodeName}.setAttribute('${attr.name}', ${resolveExpression(value.expression, context)})));`;
2227
- }) || [],
2228
- ...node.events?.map((event) => `${nodeName}.addEventListener("${event.name}", ($event) => this.${event.handler});`) || [],
2224
+ ...mapAttributes(node.attributes, nodeName, context),
2225
+ ...mapEvents(node.events, nodeName),
2229
2226
  `${parentNode}.appendChild(${nodeName});`,
2230
2227
  `unwatchFns.push(() => ${parentNode}.removeChild(${nodeName}));`,
2231
2228
  ...node.children.map((child, i) => processNode(child, i.toString(), nodeName, childrenContext)).flat()
2232
2229
  ];
2233
2230
  }
2231
+ /**
2232
+ * Generates code that assigns attributes to a DOM element.
2233
+ *
2234
+ * Static (string) attribute values are set once via a direct `setAttribute` call,
2235
+ * while dynamic attribute values are wrapped in an `effect` so the attribute is
2236
+ * re-evaluated and updated whenever its underlying signal dependencies change.
2237
+ * The disposer returned by the `effect` is registered in `unwatchFns` for cleanup.
2238
+ *
2239
+ * @param attributes The attribute nodes to map onto the element.
2240
+ * @param nodeName Variable name of the DOM element receiving the attributes.
2241
+ * @param context Current render scope context, used to resolve dynamic expressions.
2242
+ * @returns Array of generated code lines, one per attribute.
2243
+ */
2244
+ function mapAttributes(attributes, nodeName, context) {
2245
+ return attributes?.map((attr) => {
2246
+ const value = attr.value;
2247
+ return typeof value === "string" ? `${nodeName}.setAttribute('${attr.name}', ${value});` : `unwatchFns.push(effect(() => ${nodeName}.setAttribute('${attr.name}', ${resolveExpression(value.expression, context)})));`;
2248
+ }) ?? [];
2249
+ }
2250
+ /**
2251
+ * Generates code that attaches event listeners to a DOM element.
2252
+ *
2253
+ * For each event node an `addEventListener` call is emitted, binding the event
2254
+ * to the component instance handler and exposing the native event as `$event`.
2255
+ *
2256
+ * @param events The event nodes to bind to the element.
2257
+ * @param nodeName Variable name of the DOM element receiving the listeners.
2258
+ * @returns Array of generated code lines, one per event listener.
2259
+ */
2260
+ function mapEvents(events, nodeName) {
2261
+ return events?.map((event) => `${nodeName}.addEventListener("${event.name}", ($event) => this.${event.handler});`) ?? [];
2262
+ }
2234
2263
  //#endregion
2235
2264
  //#region ../packages/compiler/src/render-generator/states/process-for.state.ts
2236
2265
  /**
@@ -2432,12 +2461,12 @@ function generateRenderFunction(ast, cssVariableName) {
2432
2461
  nodeToProcess.clear();
2433
2462
  const context = new Context();
2434
2463
  const renderFunctions = ["_render() {"];
2435
- if (cssVariableName) renderFunctions.push(` this._root.adoptedStyleSheets = [${cssVariableName}];`);
2436
- renderFunctions.push(" let unwatchFns = [];", ...indent(...ast.map((node, i) => [...processNode(node, i.toString(), ROOT_NODE, context)]).flat()), " return unwatchFns;", "}");
2464
+ if (cssVariableName) renderFunctions.push(...indent(`this._root.adoptedStyleSheets = [${cssVariableName}];`));
2465
+ renderFunctions.push(...indent("let unwatchFns = [];", ...indent(...ast.map((node, i) => [...processNode(node, i.toString(), ROOT_NODE, context)]).flat()), "return unwatchFns;"), "}");
2437
2466
  while (nodeToProcess.size > 0) {
2438
2467
  const [key, fnData] = nodeToProcess.entries().next().value;
2439
- if ("args" in fnData) renderFunctions.push(`${key}(${fnData.args.join(", ")}) {`, " let unwatchFns = [];", ...indent(...fnData.fn(...fnData.args)), " return unwatchFns;", "}");
2440
- else renderFunctions.push(`${key}() {`, " let unwatchFns = [];", ...indent(...fnData.fn()), " return unwatchFns;", "}");
2468
+ if ("args" in fnData) renderFunctions.push(`${key}(${fnData.args.join(", ")}) {`, ...indent("let unwatchFns = [];", ...indent(...fnData.fn(...fnData.args)), "return unwatchFns;"), "}");
2469
+ else renderFunctions.push(`${key}() {`, ...indent("let unwatchFns = [];", ...indent(...fnData.fn()), "return unwatchFns;", "}"));
2441
2470
  nodeToProcess.delete(key);
2442
2471
  }
2443
2472
  return renderFunctions.join("\n");
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@xaendar/compiler",
3
- "version": "0.5.7",
3
+ "version": "0.5.8",
4
4
  "description": "A library for transpiling Xaendar Templates into JavaScript code",
5
5
  "sideEffects": false,
6
6
  "type": "module",
@@ -16,8 +16,8 @@
16
16
  }
17
17
  },
18
18
  "dependencies": {
19
- "@xaendar/common": "0.5.7",
20
- "@xaendar/types": "0.5.7",
19
+ "@xaendar/common": "0.5.8",
20
+ "@xaendar/types": "0.5.8",
21
21
  "typescript": "^6.0.3"
22
22
  }
23
23
  }