mono-jsx 0.1.3 → 0.3.0

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.
package/jsx-runtime.mjs CHANGED
@@ -6,55 +6,59 @@ var $state = Symbol.for("mono.state");
6
6
  var $computed = Symbol.for("mono.computed");
7
7
 
8
8
  // state.ts
9
- function createState(request) {
10
- let collectDeps;
9
+ var collectDeps;
10
+ function createState(fc, appState, context, request) {
11
11
  const computed = (fn) => {
12
12
  const deps = /* @__PURE__ */ Object.create(null);
13
- collectDeps = (key, value2) => deps[key] = value2;
13
+ collectDeps = (fc2, key, value2) => deps[fc2 + ":" + key] = value2;
14
14
  const value = fn();
15
15
  collectDeps = void 0;
16
- if (deps.size === 0) return value;
17
- return [$computed, { value, deps, fn: fn.toString() }, $vnode];
16
+ if (value instanceof Promise || deps.size === 0) return value;
17
+ return [$computed, { value, deps, fn: fn.toString(), fc }, $vnode];
18
18
  };
19
19
  return new Proxy(/* @__PURE__ */ Object.create(null), {
20
20
  get(target, key, receiver) {
21
- const value = Reflect.get(target, key, receiver);
22
- if (key === "request") {
23
- if (!request) {
24
- throw new Error("request is not defined");
21
+ switch (key) {
22
+ case "app":
23
+ return appState;
24
+ case "context":
25
+ return context ?? {};
26
+ case "request":
27
+ if (!request) {
28
+ throw new Error("request is not defined");
29
+ }
30
+ return request;
31
+ case "computed":
32
+ return computed;
33
+ default: {
34
+ const value = Reflect.get(target, key, receiver);
35
+ if (typeof key === "symbol") {
36
+ return value;
37
+ }
38
+ if (collectDeps) {
39
+ collectDeps(fc, key, value);
40
+ return value;
41
+ }
42
+ return [$state, { key, value, fc }, $vnode];
25
43
  }
26
- return request;
27
- }
28
- if (key === "computed") {
29
- return computed;
30
- }
31
- if (typeof key === "symbol") {
32
- return value;
33
- }
34
- if (collectDeps) {
35
- collectDeps(key, value);
36
- return value;
37
44
  }
38
- return [$state, { key, value }, $vnode];
39
45
  },
40
46
  set(target, key, value, receiver) {
41
- const vt = typeof value;
42
- value = vt === "boolean" || vt === "number" || vt === "bigint" ? value : structuredClone(value);
43
47
  return Reflect.set(target, key, value, receiver);
44
48
  }
45
49
  });
46
50
  }
47
51
 
48
52
  // runtime/index.ts
49
- var RUNTIME_STATE_JS = `const p=(e,i)=>e.getAttribute(i),m=(e,i)=>e.hasAttribute(i),M=new Map,T=e=>M.get(e)??M.set(e,L()).get(e);function L(){const e=Object.create(null),i=new Map;function f(n,o){let a=o;Object.defineProperty(e,n,{get:()=>a,set:u=>{if(u!==a){const r=i.get(n);r&&queueMicrotask(()=>r.forEach(s=>s())),a=u}}})}function d(n,o,a,u){let r;if(o==="toggle"){let s;r=()=>{if(!s){const t=n.firstElementChild;t&&t.tagName==="TEMPLATE"&&m(t,"m-slot")?(s=t.content.childNodes,n.innerHTML=""):s=n.childNodes}a()?n.append(...s):n.innerHTML=""}}else if(o==="switch"){let s=p(n,"match"),t,l,E=c=>t.get(c)??t.set(c,[]).get(c),h;r=()=>{if(!t){t=new Map,l=[];for(const c of n.childNodes)if(c.nodeType===1&&c.tagName==="TEMPLATE"&&m(c,"m-slot")){for(const g of c.content.childNodes)g.nodeType===1&&m(g,"slot")?E(p(g,"slot")).push(g):l.push(g);c.remove()}else s?E(s).push(c):l.push(c)}h=a(),n.innerHTML="",n.append(...t.has(h)?t.get(h):l)}}else if(o&&o.length>2&&o.startsWith("[")&&o.endsWith("]")){let s=o.slice(1,-1),t=n.parentElement;t.tagName==="M-GROUP"&&(t=t.previousElementSibling),r=()=>{const l=a();l===!1?t.removeAttribute(s):(s==="class"||s==="style")&&l&&typeof l=="object"?t.setAttribute(s,s==="class"?cx(l):styleToCSS(l)):t.setAttribute(s,l===!0?"":""+l)}}else r=()=>n.textContent=""+a();if(r)for(const s of u){let t=i.get(s);t||(t=[],i.set(s,t)),t.push(r)}}return{store:e,define:f,createEffect:d}}customElements.define("m-state",class extends HTMLElement{connectedCallback(){const e=this,i=p(e,"mode"),f=p(e,"key"),d=T(p(e,"fc"));f?d.createEffect(e,i,()=>d.store[f],[f]):m(e,"computed")&&setTimeout(()=>{const n=e.firstChild;if(n&&n.nodeType===1&&n.type==="computed"){const o=n.textContent;o&&new Function("$",o).call(d.store,(a,u)=>d.createEffect(e,i,a,u))}})}}),Object.assign(globalThis,{$state:e=>T(e).store,$defineState:(e,i)=>{const f=e.indexOf(":");f>0&&T(e.slice(0,f)).define(e.slice(f+1),i)}});`;
50
- var RUNTIME_SUSPENSE_JS = `const n={},o=e=>e.getAttribute("chunk-id");c("m-portal",e=>{n[o(e)]=e}),c("m-chunk",e=>{const t=o(e),s=n[t];s&&setTimeout(()=>{s.replaceWith(...e.firstChild.content.childNodes),delete n[t],e.remove()})});function c(e,t){customElements.define(e,class extends HTMLElement{connectedCallback(){t(this)}})}`;
51
- var RUNTIME_COMPONENTS_JS = {
53
+ var STATE_JS = `const p=new Map,f=e=>p.get(e)??p.set(e,E(e)).get(e),u=(e,t)=>e.getAttribute(t),d=(e,t)=>e.hasAttribute(t),E=e=>{const t=Object.create(null),l=new Map,s=(i,c)=>{let r=c;Object.defineProperty(t,i,{get:()=>r,set:o=>{if(o!==r){const a=l.get(i);a&&queueMicrotask(()=>a.forEach(m=>m())),r=o}}})},n=(i,c)=>{let r=l.get(i);r||(r=[],l.set(i,r)),r.push(c)};return e>0&&Object.defineProperty(t,"app",{get:()=>f(0).store,enumerable:!1,configurable:!1}),{store:t,define:s,watch:n}},g=(e,t,l)=>{if(t==="toggle"){let s;return()=>{if(!s){const n=e.firstElementChild;n&&n.tagName==="TEMPLATE"&&d(n,"m-slot")?(s=n.content.childNodes,e.innerHTML=""):s=e.childNodes}l()?e.append(...s):e.innerHTML=""}}if(t==="switch"){let s=u(e,"match"),n,i,c=o=>n.get(o)??n.set(o,[]).get(o),r;return()=>{if(!n){n=new Map,i=[];for(const o of e.childNodes)if(o.nodeType===1&&o.tagName==="TEMPLATE"&&d(o,"m-slot")){for(const a of o.content.childNodes)a.nodeType===1&&d(a,"slot")?c(u(a,"slot")).push(a):i.push(a);o.remove()}else s?c(s).push(o):i.push(o)}r=l(),e.innerHTML="",e.append(...n.has(r)?n.get(r):i)}}if(t&&t.length>2&&t.startsWith("[")&&t.endsWith("]")){let s=t.slice(1,-1),n=e.parentElement;return n.tagName==="M-GROUP"&&(n=n.previousElementSibling),()=>{const i=l();i===!1?n.removeAttribute(s):(s==="class"||s==="style")&&i&&typeof i=="object"?n.setAttribute(s,s==="class"?cx(i):styleToCSS(i)):n.setAttribute(s,i===!0?"":""+i)}}return()=>e.textContent=""+l()},h=e=>{const t=e.indexOf(":");if(t>0)return[Number(e.slice(0,t)),e.slice(t+1)];throw new Error("Invalid state key")};customElements.define("m-state",class extends HTMLElement{connectedCallback(){const e=this,t=f(Number(u(e,"fc"))),l=u(e,"mode"),s=u(e,"key");s?t.watch(s,g(e,l,()=>t.store[s])):d(e,"computed")&&setTimeout(()=>{const n=e.firstChild;if(n&&n.nodeType===1&&n.type==="computed"){const i=n.textContent;i&&new Function("$",i).call(t.store,(c,r)=>{const o=g(e,l,c);for(const a of r){const[m,T]=h(a);f(m).watch(T,o)}})}})}}),Object.assign(globalThis,{$state:e=>e!==void 0?f(e).store:void 0,$defineState:(e,t)=>{const[l,s]=h(e);f(l).define(s,t)}});`;
54
+ var SUSPENSE_JS = `const n={},o=e=>e.getAttribute("chunk-id");c("m-portal",e=>{n[o(e)]=e}),c("m-chunk",e=>{const t=o(e),s=n[t];s&&setTimeout(()=>{s.replaceWith(...e.firstChild.content.childNodes),delete n[t],e.remove()})});function c(e,t){customElements.define(e,class extends HTMLElement{connectedCallback(){t(this)}})}`;
55
+ var UTILS_JS = {
52
56
  /** cx.js (239 bytes) */
53
- cx: `var cx=(()=>{var n=e=>typeof e=="string",o=e=>typeof e=="object"&&e!==null;function t(e){return n(e)?e:o(e)?Array.isArray(e)?e.map(t).filter(Boolean).join(" "):Object.entries(e).filter(([,r])=>!!r).map(([r])=>r).join(" "):""}return t;})();`,
57
+ cx: `let cx=(()=>{var n=e=>typeof e=="string",o=e=>typeof e=="object"&&e!==null;function t(e){return n(e)?e:o(e)?Array.isArray(e)?e.map(t).filter(Boolean).join(" "):Object.entries(e).filter(([,r])=>!!r).map(([r])=>r).join(" "):""}return t;})();`,
54
58
  /** styleToCSS.js (1203 bytes) */
55
- styleToCSS: `var styleToCSS=(()=>{var c=new Set(["animation-iteration-count","aspect-ratio","border-image-outset","border-image-slice","border-image-width","box-flex-group","box-flex","box-ordinal-group","column-count","columns","fill-opacity","flex-grow","flex-negative","flex-order","flex-positive","flex-shrink","flex","flood-opacity","font-weight","grid-area","grid-column-end","grid-column-span","grid-column-start","grid-column","grid-row-end","grid-row-span","grid-row-start","grid-row","line-clamp","line-height","opacity","order","orphans","stop-opacity","stroke-dasharray","stroke-dashoffset","stroke-miterlimit","stroke-opacity","stroke-width","tab-size","widows","z-index","zoom"]),s=e=>typeof e=="string",u=e=>typeof e=="object"&&e!==null,f=e=>e.replace(/[a-z][A-Z]/g,r=>r.charAt(0)+"-"+r.charAt(1).toLowerCase());function l(e){if(s(e))return e;if(u(e)){let r="";for(let[o,t]of Array.isArray(e)?e:Object.entries(e)){if(t==null||t===!1||Number.isNaN(t)||!s(o))return"";let n=f(o),i=typeof t=="number"?c.has(n)?""+t:t+"px":a(""+t);r+=(r!==""?";":"")+a(n)+":"+(n==="content"?JSON.stringify(i):i)}return r}return""}function a(e){return e.replace(/["<>]/g,r=>r==="<"?"&lt;":r===">"?"&gt;":"'")}return l;})();`,
56
- /** event.js (176 bytes) */
57
- event: `window.$emit=(evt,el,fn,fc)=>fn.call(window.$state?.(fc)??el,evt);window.$onsubmit=(evt,el,fn,fc)=>{evt.preventDefault();fn.call(window.$state?.(fc)??el,new FormData(el),evt)};`
59
+ styleToCSS: `let styleToCSS=(()=>{var c=new Set(["animation-iteration-count","aspect-ratio","border-image-outset","border-image-slice","border-image-width","box-flex-group","box-flex","box-ordinal-group","column-count","columns","fill-opacity","flex-grow","flex-negative","flex-order","flex-positive","flex-shrink","flex","flood-opacity","font-weight","grid-area","grid-column-end","grid-column-span","grid-column-start","grid-column","grid-row-end","grid-row-span","grid-row-start","grid-row","line-clamp","line-height","opacity","order","orphans","stop-opacity","stroke-dasharray","stroke-dashoffset","stroke-miterlimit","stroke-opacity","stroke-width","tab-size","widows","z-index","zoom"]),s=e=>typeof e=="string",u=e=>typeof e=="object"&&e!==null,f=e=>e.replace(/[a-z][A-Z]/g,r=>r.charAt(0)+"-"+r.charAt(1).toLowerCase());function l(e){if(s(e))return e;if(u(e)){let r="";for(let[o,t]of Array.isArray(e)?e:Object.entries(e)){if(t==null||t===!1||Number.isNaN(t)||!s(o))return"";let n=f(o),i=typeof t=="number"?c.has(n)?""+t:t+"px":a(""+t);r+=(r!==""?";":"")+a(n)+":"+(n==="content"?JSON.stringify(i):i)}return r}return""}function a(e){return e.replace(/["<>]/g,r=>r==="<"?"&lt;":r===">"?"&gt;":"'")}return l;})();`,
60
+ /** event.js (169 bytes) */
61
+ event: `let w=window;w.$emit=(evt,el,fn,fc)=>fn.call(w.$state?.(fc)??el,evt);w.$onsubmit=(evt,el,fn,fc)=>{evt.preventDefault();fn.call(w.$state?.(fc)??el,new FormData(el),evt)};`
58
62
  };
59
63
 
60
64
  // runtime/utils.ts
@@ -187,9 +191,9 @@ var regexpHtmlTag = /^[a-z][\w\-$]*$/;
187
191
  var selfClosingTags = new Set("area,base,br,col,embed,hr,img,input,keygen,link,meta,param,source,track,wbr".split(","));
188
192
  var isVNode = (v) => Array.isArray(v) && v.length === 3 && v[2] === $vnode;
189
193
  var hashCode = (s) => [...s].reduce((hash, c) => Math.imul(31, hash) + c.charCodeAt(0) | 0, 0);
190
- var toAttrStringLit = (str) => '"' + escapeHTML(str).replaceAll('"', '\\"') + '"';
191
- async function renderNode(ctx, node, stripSlotProp) {
192
- const { write, stateStore } = ctx;
194
+ var toAttrStringLit = (str) => '"' + escapeHTML(str) + '"';
195
+ async function renderNode(rc, node, stripSlotProp) {
196
+ const { write } = rc;
193
197
  switch (typeof node) {
194
198
  case "string":
195
199
  write(escapeHTML(node));
@@ -200,11 +204,11 @@ async function renderNode(ctx, node, stripSlotProp) {
200
204
  break;
201
205
  case "object":
202
206
  if (isVNode(node)) {
203
- let [tag, props] = node;
204
- let children = props.children;
205
- if (tag === $fragment) {
206
- if (children !== void 0) {
207
- await renderChildren(ctx, children);
207
+ const [tag, props] = node;
208
+ const { stateStore } = rc;
209
+ if (tag === $fragment || tag === "htmx") {
210
+ if (props.children !== void 0) {
211
+ await renderChildren(rc, props.children);
208
212
  }
209
213
  break;
210
214
  }
@@ -214,114 +218,98 @@ async function renderNode(ctx, node, stripSlotProp) {
214
218
  }
215
219
  break;
216
220
  }
217
- if (tag === "slot") {
218
- const ctxSlots = ctx.slots;
219
- let slots;
220
- if (ctxSlots !== void 0) {
221
- if (Array.isArray(ctxSlots)) {
222
- if (isVNode(ctxSlots)) {
223
- slots = [ctxSlots];
224
- } else {
225
- slots = ctxSlots;
226
- }
227
- } else {
228
- slots = [ctxSlots];
229
- }
230
- }
231
- if (props.name) {
232
- children = slots?.filter((v) => isVNode(v) && v[1].slot === props.name);
233
- } else {
234
- children = slots?.filter((v) => !isVNode(v) || !v[1].slot);
235
- }
236
- if (children === void 0 || Array(children) && children.length === 0) {
237
- children = node[1].children;
238
- }
239
- if (children !== void 0) {
240
- await renderChildren(ctx, children, true);
241
- }
242
- break;
243
- }
244
- const fcIndex = ctx.index.fc.toString(36);
245
221
  if (tag === $state) {
246
- const { key, value } = props;
247
- write('<m-state fc="' + fcIndex + '" key=' + toAttrStringLit(key) + ">");
222
+ const { key, value, fc } = props;
223
+ write('<m-state fc="' + fc + '" key=' + toAttrStringLit(key) + ">");
248
224
  if (value !== void 0 && value !== null) {
249
225
  write(escapeHTML("" + value));
250
226
  }
251
227
  write("</m-state>");
252
- stateStore.set(fcIndex + ":" + key, value);
228
+ stateStore.set(fc + ":" + key, value);
253
229
  break;
254
230
  }
255
231
  if (tag === $computed) {
256
- const { deps, value, fn } = props;
232
+ const { deps, value, fn, fc } = props;
257
233
  write(
258
- '<m-state fc="' + fcIndex + '" computed><script type="computed">$(' + fn + ", " + JSON.stringify(Object.keys(deps)) + ")<\/script>"
234
+ '<m-state fc="' + fc + '" computed><script type="computed">$(' + fn + ", " + JSON.stringify(Object.keys(deps)) + ")<\/script>"
259
235
  );
260
236
  if (value !== void 0) {
261
237
  write(escapeHTML("" + value));
262
238
  }
263
239
  write("</m-state>");
264
240
  for (const [key, value2] of Object.entries(deps)) {
265
- const stateKey = fcIndex + ":" + key;
266
- if (!stateStore.has(stateKey)) {
267
- stateStore.set(stateKey, value2);
241
+ if (!stateStore.has(key)) {
242
+ stateStore.set(key, value2);
243
+ }
244
+ }
245
+ break;
246
+ }
247
+ if (tag === "slot") {
248
+ const { fcSlots } = rc;
249
+ if (fcSlots) {
250
+ let slots;
251
+ if (props.name) {
252
+ slots = fcSlots.filter((v) => isVNode(v) && v[1].slot === props.name);
253
+ } else {
254
+ slots = fcSlots.filter((v) => !isVNode(v) || !v[1].slot);
268
255
  }
256
+ if (slots.length === 0) {
257
+ slots = props.children;
258
+ }
259
+ await renderChildren(rc, slots, true);
269
260
  }
270
261
  break;
271
262
  }
272
263
  if (tag === "toggle") {
264
+ const { value: valueProp, children } = props;
273
265
  if (children !== void 0) {
274
- const valueProp = props.value;
275
266
  if (isVNode(valueProp) && valueProp[0] === $state || valueProp[0] === $computed) {
276
- const { key, deps, value, fn } = valueProp[1];
277
- write('<m-state mode="toggle" fc="' + fcIndex + '" ');
267
+ const { key, deps, value, fn, fc } = valueProp[1];
268
+ write('<m-state mode="toggle" fc="' + fc + '" ');
278
269
  if (key) {
279
270
  write("key=" + toAttrStringLit(key) + ">");
280
- stateStore.set(fcIndex + ":" + key, !!value);
271
+ stateStore.set(fc + ":" + key, !!value);
281
272
  } else {
282
273
  write('computed><script type="computed">$(' + fn + ", " + JSON.stringify(Object.keys(deps)) + ")<\/script>");
283
274
  for (const [key2, value2] of Object.entries(deps)) {
284
- const stateKey = fcIndex + ":" + key2;
285
- if (!stateStore.has(stateKey)) {
286
- stateStore.set(stateKey, value2);
275
+ if (!stateStore.has(key2)) {
276
+ stateStore.set(key2, value2);
287
277
  }
288
278
  }
289
279
  }
290
280
  if (!value) {
291
281
  write("<template m-slot>");
292
282
  }
293
- await renderChildren(ctx, children);
283
+ await renderChildren(rc, children);
294
284
  if (!value) {
295
285
  write("</template>");
296
286
  }
297
287
  write("</m-state>");
298
288
  } else if (valueProp) {
299
- await renderChildren(ctx, children);
289
+ await renderChildren(rc, children);
300
290
  }
301
291
  }
302
292
  break;
303
293
  }
304
294
  if (tag === "switch") {
295
+ const { value: valueProp, defaultValue, children } = props;
305
296
  if (children !== void 0) {
306
297
  let slots = Array.isArray(children) ? isVNode(children) ? [children] : children : [children];
307
- let valueProp = props.value;
308
- let defaultValue = props.defaultValue;
309
298
  let stateful;
310
299
  let computed;
311
300
  let valueOrDefault;
312
301
  if (isVNode(valueProp) && (valueProp[0] === $state || valueProp[0] === $computed)) {
313
- const { key, deps, value, fn } = valueProp[1];
302
+ const { key, deps, value, fn, fc } = valueProp[1];
314
303
  valueOrDefault = value ?? defaultValue;
315
- stateful = '<m-state mode="switch" fc="' + fcIndex + '" ';
304
+ stateful = '<m-state mode="switch" fc="' + fc + '" ';
316
305
  if (key) {
317
306
  stateful += "key=" + toAttrStringLit(key) + ">";
318
- stateStore.set(fcIndex + ":" + key, valueOrDefault);
307
+ stateStore.set(fc + ":" + key, valueOrDefault);
319
308
  } else {
320
309
  stateful += 'computed><script type="computed">$(' + fn + ", " + JSON.stringify(Object.keys(deps)) + ")<\/script>";
321
310
  for (const [key2, value2] of Object.entries(deps)) {
322
- const stateKey = fcIndex + ":" + key2;
323
- if (!stateStore.has(stateKey)) {
324
- stateStore.set(stateKey, value2);
311
+ if (!stateStore.has(key2)) {
312
+ stateStore.set(key2, value2);
325
313
  }
326
314
  }
327
315
  }
@@ -350,16 +338,16 @@ async function renderNode(ctx, node, stripSlotProp) {
350
338
  }
351
339
  }
352
340
  if (matchedSlot) {
353
- await renderNode(ctx, matchedSlot[1], true);
341
+ await renderNode(rc, matchedSlot[1], true);
354
342
  } else if (unnamedSlots.length > 0) {
355
- await renderChildren(ctx, unnamedSlots);
343
+ await renderChildren(rc, unnamedSlots);
356
344
  }
357
345
  if (stateful) {
358
346
  if (namedSlots.length > 0 || matchedSlot && unnamedSlots.length > 0) {
359
347
  write("<template m-slot>");
360
- await renderChildren(ctx, namedSlots);
348
+ await renderChildren(rc, namedSlots);
361
349
  if (matchedSlot && unnamedSlots.length > 0) {
362
- await renderChildren(ctx, unnamedSlots);
350
+ await renderChildren(rc, unnamedSlots);
363
351
  }
364
352
  write("</template>");
365
353
  }
@@ -369,48 +357,47 @@ async function renderNode(ctx, node, stripSlotProp) {
369
357
  break;
370
358
  }
371
359
  if (typeof tag === "function") {
360
+ const fcIndex = ++rc.index.fc;
372
361
  const { rendering, placeholder, catch: catchFC, ...fcProps } = props ?? /* @__PURE__ */ Object.create(null);
373
- let eager = ctx.eager;
374
- if ((rendering ?? tag.rendering) === "eager") {
375
- eager = true;
376
- }
377
362
  try {
378
- const v = tag.call(createState(ctx.request), fcProps);
379
- ctx.index.fc++;
363
+ const v = tag.call(createState(fcIndex, rc.appState, rc.context, rc.request), fcProps);
364
+ const { children } = fcProps;
365
+ const fcSlots = children !== void 0 ? Array.isArray(children) ? isVNode(children) ? [children] : children : [children] : void 0;
366
+ const eager = (rendering ?? tag.rendering) === "eager" || rc.eager;
380
367
  if (v instanceof Promise) {
381
368
  if (eager) {
382
- await renderNode({ ...ctx, eager: true, slots: children }, await v);
369
+ await renderNode({ ...rc, fcIndex, eager: true, fcSlots }, await v);
383
370
  } else {
384
- const chunkId = (ctx.suspenses.length + 1).toString(36);
385
- ctx.suspenses.push(v.then(async (c) => {
371
+ const chunkId = (rc.suspenses.length + 1).toString(36);
372
+ rc.suspenses.push(v.then(async (c) => {
386
373
  write('<m-chunk chunk-id="' + chunkId + '"><template>');
387
- await renderNode({ ...ctx, eager, slots: children }, c);
374
+ await renderNode({ ...rc, fcIndex, eager, fcSlots }, c);
388
375
  write("</template></m-chunk>");
389
376
  }));
390
377
  write('<m-portal chunk-id="' + chunkId + '">');
391
378
  if (placeholder) {
392
- await renderNode({ ...ctx, eager: true }, placeholder);
379
+ await renderNode({ ...rc, fcIndex, eager: true }, placeholder);
393
380
  }
394
381
  write("</m-portal>");
395
382
  }
396
383
  } else if (isObject(v) && Symbol.iterator in v && !isVNode(v)) {
397
384
  for (const c of v) {
398
- await renderNode({ ...ctx, eager, slots: children }, c);
385
+ await renderNode({ ...rc, fcIndex, eager, fcSlots }, c);
399
386
  }
400
387
  } else if (isObject(v) && Symbol.asyncIterator in v) {
401
388
  if (eager) {
402
389
  for await (const c of v) {
403
- await renderNode({ ...ctx, eager: true, slots: children }, c);
390
+ await renderNode({ ...rc, fcIndex, eager: true, fcSlots }, c);
404
391
  }
405
392
  } else {
406
393
  }
407
394
  } else {
408
- await renderNode({ ...ctx, eager, slots: children }, v);
395
+ await renderNode({ ...rc, fcIndex, eager, fcSlots }, v);
409
396
  }
410
397
  } catch (err) {
411
398
  if (err instanceof Error) {
412
399
  if (typeof catchFC === "function") {
413
- await renderNode({ ...ctx, eager: true }, catchFC(err));
400
+ await renderNode({ ...rc, fcIndex, eager: true }, catchFC(err));
414
401
  } else {
415
402
  write('<pre style="color:red;font-size:1rem"><code>' + escapeHTML(err.stack ?? err.message) + "</code></pre>");
416
403
  }
@@ -427,22 +414,21 @@ async function renderNode(ctx, node, stripSlotProp) {
427
414
  continue;
428
415
  }
429
416
  if (isVNode(propValue) && (propValue[0] === $state || propValue[0] === $computed)) {
430
- const { key, deps, fn, value } = propValue[1];
417
+ const { key, value, deps, fn, fc } = propValue[1];
431
418
  if (propName === "class") {
432
- ctx.rtComponents.cx = true;
419
+ rc.runtimeUtils.cx = true;
433
420
  } else if (propName === "style") {
434
- ctx.rtComponents.styleToCSS = true;
421
+ rc.runtimeUtils.styleToCSS = true;
435
422
  }
436
- propEffects.push("<m-state mode=" + toAttrStringLit("[" + propName + "]") + ' fc="' + fcIndex + '" ');
423
+ propEffects.push("<m-state mode=" + toAttrStringLit("[" + propName + "]") + ' fc="' + fc + '" ');
437
424
  if (key) {
438
425
  propEffects.push("key=" + toAttrStringLit(key) + ">");
439
- stateStore.set(fcIndex + ":" + key, value);
426
+ stateStore.set(fc + ":" + key, value);
440
427
  } else {
441
428
  propEffects.push('computed><script type="computed">$(' + fn + ", " + JSON.stringify(Object.keys(deps)) + ")<\/script>");
442
429
  for (const [key2, value2] of Object.entries(deps)) {
443
- const stateKey = fcIndex + ":" + key2;
444
- if (!stateStore.has(stateKey)) {
445
- stateStore.set(stateKey, value2);
430
+ if (!stateStore.has(key2)) {
431
+ stateStore.set(key2, value2);
446
432
  }
447
433
  }
448
434
  }
@@ -490,7 +476,7 @@ async function renderNode(ctx, node, stripSlotProp) {
490
476
  raw += css + "|";
491
477
  }
492
478
  raw += [pseudoStyles, atRuleStyles, nestingStyles].flat(1).map(([k, v]) => k + ">" + v).join("|");
493
- styleIds = ctx.styleIds ?? (ctx.styleIds = /* @__PURE__ */ new Set());
479
+ styleIds = rc.styleIds ?? (rc.styleIds = /* @__PURE__ */ new Set());
494
480
  id = hashCode(raw).toString(36);
495
481
  cssSelector = "[data-css-" + id + "]";
496
482
  if (!styleIds.has(id)) {
@@ -522,9 +508,9 @@ async function renderNode(ctx, node, stripSlotProp) {
522
508
  break;
523
509
  case "action":
524
510
  if (typeof propValue === "function" && tag === "form") {
525
- const id = "$MF_" + (ctx.index.mf++).toString(36);
526
- write("<script>function " + id + "(fd){(" + propValue.toString() + ")(fd)}<\/script>");
527
- buffer += ' onsubmit="$onsubmit(event,this,' + id + ",'" + fcIndex + `')"`;
511
+ const fn = "$MF_" + (rc.index.mf++).toString(36);
512
+ write("<script>function " + fn + "(fd){(" + propValue.toString() + ")(fd)}<\/script>");
513
+ buffer += ' onsubmit="$onsubmit(event,this,' + fn + (rc.fcIndex !== void 0 ? "," + rc.fcIndex : "") + ')"';
528
514
  } else if (isString(propValue)) {
529
515
  buffer += " action=" + toAttrStringLit(propValue);
530
516
  }
@@ -538,16 +524,16 @@ async function renderNode(ctx, node, stripSlotProp) {
538
524
  if (regexpHtmlTag.test(propName) && propValue !== void 0) {
539
525
  if (propName.startsWith("on")) {
540
526
  if (typeof propValue === "function") {
541
- const id = "$MF_" + (ctx.index.mf++).toString(36);
542
- write("<script>function " + id + "(e){(" + propValue.toString() + ")(e)}<\/script>");
543
- buffer += " " + propName.toLowerCase() + '="$emit(event,this,' + id + ",'" + fcIndex + `')"`;
527
+ const fn = "$MF_" + (rc.index.mf++).toString(36);
528
+ write("<script>function " + fn + "(e){(" + propValue.toString() + ")(e)}<\/script>");
529
+ buffer += " " + propName.toLowerCase() + '="$emit(event,this,' + fn + (rc.fcIndex !== void 0 ? "," + rc.fcIndex : "") + ')"';
544
530
  }
545
531
  } else if (typeof propValue === "boolean") {
546
532
  if (propValue) {
547
533
  buffer += " " + propName;
548
534
  }
549
535
  } else {
550
- buffer += " " + (propValue === true ? escapeHTML(propName) : escapeHTML(propName) + "=" + toAttrStringLit("" + propValue));
536
+ buffer += " " + escapeHTML(propName) + (propValue === true ? "" : "=" + toAttrStringLit("" + propValue));
551
537
  }
552
538
  }
553
539
  }
@@ -559,97 +545,111 @@ async function renderNode(ctx, node, stripSlotProp) {
559
545
  }
560
546
  if (props.innerHTML) {
561
547
  write(props.innerHTML);
562
- } else if (children !== void 0) {
563
- await renderChildren(ctx, children);
548
+ } else if (props.children !== void 0) {
549
+ await renderChildren(rc, props.children);
564
550
  }
565
551
  write("</" + tag + ">");
566
552
  } else if (propEffects.length > 0) {
567
- write("<m-group>");
568
- write(propEffects.join(""));
569
- write("</m-group>");
553
+ write("<m-group>" + propEffects.join("") + "</m-group>");
570
554
  }
571
555
  if (onMountHandler) {
572
- ctx.index.mf++;
556
+ rc.index.mf++;
573
557
  write(
574
- '<script>{const target=document.currentScript.previousElementSibling;addEventListener("load",()=>$emit({type:"mount",currentTarget:target,target},target,' + onMountHandler.toString() + ',"' + fcIndex + '"))}<\/script>'
558
+ '<script>{const target=document.currentScript.previousElementSibling;addEventListener("load",()=>$emit({type:"mount",currentTarget:target,target},target,' + onMountHandler.toString() + (rc.fcIndex !== void 0 ? "," + rc.fcIndex : "") + "))}<\/script>"
575
559
  );
576
560
  }
577
561
  }
578
- } else if (Array.isArray(node) || node && Symbol.iterator in node) {
579
- for (const child of node) {
580
- await renderNode(ctx, child);
581
- }
582
562
  }
583
563
  break;
584
564
  }
585
565
  }
586
- async function renderChildren(ctx, children, stripSlotProp) {
566
+ async function renderChildren(rc, children, stripSlotProp) {
587
567
  if (Array.isArray(children) && !isVNode(children)) {
588
568
  for (const child of children) {
589
- await renderNode(ctx, child, stripSlotProp);
569
+ await renderNode(rc, child, stripSlotProp);
590
570
  }
591
571
  } else {
592
- await renderNode(ctx, children, stripSlotProp);
572
+ await renderNode(rc, children, stripSlotProp);
593
573
  }
594
574
  }
595
575
  function render(node, renderOptions = {}) {
596
- const { request, status, headers: headersRaw, rendering } = renderOptions;
597
- const headers = /* @__PURE__ */ Object.create(null);
598
- if (headersRaw) {
599
- const { etag, lastModified } = headersRaw;
576
+ const { request, status, headers: headersInit } = renderOptions;
577
+ const headers = new Headers();
578
+ if (headersInit) {
579
+ for (const [key, value] of Object.entries(headersInit)) {
580
+ if (value) {
581
+ headers.set(toHyphenCase(key), value);
582
+ }
583
+ }
584
+ const etag = headers.get("etag");
600
585
  if (etag && request?.headers.get("if-none-match") === etag) {
601
586
  return new Response(null, { status: 304 });
602
587
  }
588
+ const lastModified = headers.get("last-modified");
603
589
  if (lastModified && request?.headers.get("if-modified-since") === lastModified) {
604
590
  return new Response(null, { status: 304 });
605
591
  }
606
- for (const [key, value] of Object.entries(headersRaw)) {
607
- if (value) {
608
- headers[toHyphenCase(key)] = value;
609
- }
610
- }
611
592
  }
612
- headers["transfer-encoding"] = "chunked";
613
- headers["content-type"] = "text/html; charset=utf-8";
593
+ headers.set("transfer-encoding", "chunked");
594
+ headers.set("content-type", "text/html; charset=utf-8");
614
595
  return new Response(
615
596
  new ReadableStream({
616
597
  async start(controller) {
598
+ const { appState: appStateInit, context, rendering, htmx } = renderOptions;
617
599
  const write = (chunk) => controller.enqueue(encoder.encode(chunk));
600
+ const appState = createState(0, null, context, request);
618
601
  const stateStore = /* @__PURE__ */ new Map();
619
602
  const suspenses = [];
620
603
  const rtComponents = { cx: false, styleToCSS: false };
621
- const ctx = {
604
+ const rc = {
622
605
  write,
606
+ context,
623
607
  request,
608
+ appState,
624
609
  stateStore,
625
610
  suspenses,
626
- rtComponents,
611
+ runtimeUtils: rtComponents,
627
612
  index: { fc: 0, mf: 0 },
628
613
  eager: rendering === "eager"
629
614
  };
615
+ if (appStateInit) {
616
+ for (const [key, value] of Object.entries(appStateInit)) {
617
+ if (value !== void 0) {
618
+ appState[key] = value;
619
+ }
620
+ }
621
+ }
630
622
  try {
631
623
  write("<!DOCTYPE html>");
632
- await renderNode(ctx, node);
624
+ await renderNode(rc, node);
633
625
  let js = "";
626
+ if (rc.index.mf > 0) {
627
+ js += UTILS_JS.event;
628
+ }
634
629
  if (stateStore.size > 0) {
635
630
  if (rtComponents.cx) {
636
- js += RUNTIME_COMPONENTS_JS.cx;
631
+ js += UTILS_JS.cx;
637
632
  }
638
633
  if (rtComponents.styleToCSS) {
639
- js += RUNTIME_COMPONENTS_JS.styleToCSS;
634
+ js += UTILS_JS.styleToCSS;
640
635
  }
641
- js += RUNTIME_STATE_JS;
636
+ js += STATE_JS;
642
637
  js += "for(let[k,v]of" + JSON.stringify(Array.from(stateStore.entries()).map((e) => e[1] === void 0 ? [e[0]] : e)) + ")$defineState(k,v);";
643
638
  }
644
- if (ctx.index.mf > 0) {
645
- js += RUNTIME_COMPONENTS_JS.event;
646
- }
647
639
  if (suspenses.length > 0) {
648
- js += RUNTIME_SUSPENSE_JS;
640
+ js += SUSPENSE_JS;
649
641
  }
650
642
  if (js) {
651
643
  write("<script>(()=>{" + js + "})()<\/script>");
652
644
  }
645
+ if (htmx) {
646
+ write(`<script src="https://raw.esm.sh/htmx.org${htmx === true ? "" : "@" + htmx}/dist/htmx.min.js"><\/script>`);
647
+ for (const [name, version] of Object.entries(renderOptions)) {
648
+ if (name.startsWith("html-ext-")) {
649
+ write(`<script src="https://raw.esm.sh/${name}${version === true ? "" : "@" + version}"><\/script>`);
650
+ }
651
+ }
652
+ }
653
653
  if (suspenses.length > 0) {
654
654
  await Promise.all(suspenses);
655
655
  }
@@ -673,9 +673,10 @@ var jsx = (tag, props = /* @__PURE__ */ Object.create(null), key) => {
673
673
  }
674
674
  if (tag === "html") {
675
675
  const renderOptions = /* @__PURE__ */ Object.create(null);
676
- for (const key2 of ["request", "status", "headers", "rendering"]) {
677
- if (Object.hasOwn(props, key2)) {
678
- renderOptions[key2] = props[key2];
676
+ const optionsKeys = /* @__PURE__ */ new Set(["appState", "context", "request", "status", "headers", "rendering", "htmx"]);
677
+ for (const [key2, value] of Object.entries(props)) {
678
+ if (optionsKeys.has(key2) || key2.startsWith("html-ext-")) {
679
+ renderOptions[key2] = value;
679
680
  delete props[key2];
680
681
  }
681
682
  }
@@ -690,8 +691,8 @@ var html = (raw, ...values) => [
690
691
  $vnode
691
692
  ];
692
693
  Object.assign(globalThis, {
693
- css: html,
694
694
  html,
695
+ css: html,
695
696
  js: html
696
697
  });
697
698
  export {