what-compiler 0.1.1 → 0.1.2

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/package.json +1 -1
  2. package/src/runtime.js +56 -2
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "what-compiler",
3
- "version": "0.1.1",
3
+ "version": "0.1.2",
4
4
  "description": "JSX compiler for What Framework - transforms JSX to optimized DOM operations",
5
5
  "main": "src/index.js",
6
6
  "type": "module",
package/src/runtime.js CHANGED
@@ -204,15 +204,69 @@ function appendChild(parent, child) {
204
204
  for (const c of child) {
205
205
  appendChild(parent, c);
206
206
  }
207
+ } else if (child && typeof child === 'object' && child.tag != null) {
208
+ // VNode from h() — interop with what-core's VNode system
209
+ parent.appendChild(renderVNode(child));
207
210
  }
208
211
  }
209
212
 
213
+ // Convert a what-core VNode to a real DOM node (interop bridge)
214
+ function renderVNode(vnode) {
215
+ if (vnode == null || vnode === false || vnode === true) return document.createComment('');
216
+ if (typeof vnode === 'string' || typeof vnode === 'number') return document.createTextNode(String(vnode));
217
+ if (vnode instanceof Node) return vnode;
218
+ if (Array.isArray(vnode)) {
219
+ const frag = document.createDocumentFragment();
220
+ for (const v of vnode) frag.appendChild(renderVNode(v));
221
+ return frag;
222
+ }
223
+
224
+ const { tag, props, children } = vnode;
225
+
226
+ // Component VNode
227
+ if (typeof tag === 'function') {
228
+ const result = tag({ ...props, children });
229
+ return renderVNode(result);
230
+ }
231
+
232
+ // Element VNode
233
+ const el = document.createElement(tag);
234
+ if (props) {
235
+ for (const [key, val] of Object.entries(props)) {
236
+ if (key === 'key' || key === 'ref' || key === 'children') continue;
237
+ if (key.startsWith('on') && typeof val === 'function') {
238
+ el.addEventListener(key.slice(2).toLowerCase(), val);
239
+ } else if (key === 'className' || key === 'class') {
240
+ el.className = val || '';
241
+ } else if (key === 'style' && typeof val === 'object') {
242
+ Object.assign(el.style, val);
243
+ } else if (val !== false && val != null) {
244
+ el.setAttribute(key, val === true ? '' : String(val));
245
+ }
246
+ }
247
+ }
248
+ if (children) {
249
+ for (const child of children) {
250
+ el.appendChild(renderVNode(child));
251
+ }
252
+ }
253
+ return el;
254
+ }
255
+
210
256
  /**
211
257
  * Create a component instance
212
258
  */
213
259
  export function _createComponent(Component, props) {
214
- // Components are just functions that return DOM nodes
215
- return untrack(() => Component(props));
260
+ // Call the component function.
261
+ // Don't untrack framework components like Router need signal tracking.
262
+ const result = Component(props);
263
+
264
+ // If the component returned a VNode (from h()), convert to DOM
265
+ if (result && typeof result === 'object' && !(result instanceof Node) && !Array.isArray(result) && result.tag != null) {
266
+ return renderVNode(result);
267
+ }
268
+
269
+ return result;
216
270
  }
217
271
 
218
272
  /**