mono-jsx 0.2.0 → 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/README.md +58 -16
- package/bin/mono-jsx +1 -42
- package/jsx-runtime.mjs +135 -136
- package/package.json +3 -2
- package/setup.mjs +58 -0
- package/types/css.d.ts +1 -1
- package/types/html.d.ts +3 -2
- package/types/htmx.d.ts +791 -0
- package/types/mono.d.ts +6 -5
- package/types/render.d.ts +42 -1
package/jsx-runtime.mjs
CHANGED
|
@@ -6,19 +6,21 @@ var $state = Symbol.for("mono.state");
|
|
|
6
6
|
var $computed = Symbol.for("mono.computed");
|
|
7
7
|
|
|
8
8
|
// state.ts
|
|
9
|
-
|
|
10
|
-
|
|
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
21
|
switch (key) {
|
|
22
|
+
case "app":
|
|
23
|
+
return appState;
|
|
22
24
|
case "context":
|
|
23
25
|
return context ?? {};
|
|
24
26
|
case "request":
|
|
@@ -34,31 +36,29 @@ function createState(context, request) {
|
|
|
34
36
|
return value;
|
|
35
37
|
}
|
|
36
38
|
if (collectDeps) {
|
|
37
|
-
collectDeps(key, value);
|
|
39
|
+
collectDeps(fc, key, value);
|
|
38
40
|
return value;
|
|
39
41
|
}
|
|
40
|
-
return [$state, { key, value }, $vnode];
|
|
42
|
+
return [$state, { key, value, fc }, $vnode];
|
|
41
43
|
}
|
|
42
44
|
}
|
|
43
45
|
},
|
|
44
46
|
set(target, key, value, receiver) {
|
|
45
|
-
const vt = typeof value;
|
|
46
|
-
value = vt === "boolean" || vt === "number" || vt === "bigint" ? value : structuredClone(value);
|
|
47
47
|
return Reflect.set(target, key, value, receiver);
|
|
48
48
|
}
|
|
49
49
|
});
|
|
50
50
|
}
|
|
51
51
|
|
|
52
52
|
// runtime/index.ts
|
|
53
|
-
var
|
|
54
|
-
var
|
|
55
|
-
var
|
|
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 = {
|
|
56
56
|
/** cx.js (239 bytes) */
|
|
57
|
-
cx: `
|
|
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;})();`,
|
|
58
58
|
/** styleToCSS.js (1203 bytes) */
|
|
59
|
-
styleToCSS: `
|
|
60
|
-
/** event.js (
|
|
61
|
-
event: `window.$emit=(evt,el,fn,fc)=>fn.call(
|
|
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==="<"?"<":r===">"?">":"'")}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)};`
|
|
62
62
|
};
|
|
63
63
|
|
|
64
64
|
// runtime/utils.ts
|
|
@@ -191,9 +191,9 @@ var regexpHtmlTag = /^[a-z][\w\-$]*$/;
|
|
|
191
191
|
var selfClosingTags = new Set("area,base,br,col,embed,hr,img,input,keygen,link,meta,param,source,track,wbr".split(","));
|
|
192
192
|
var isVNode = (v) => Array.isArray(v) && v.length === 3 && v[2] === $vnode;
|
|
193
193
|
var hashCode = (s) => [...s].reduce((hash, c) => Math.imul(31, hash) + c.charCodeAt(0) | 0, 0);
|
|
194
|
-
var toAttrStringLit = (str) => '"' + escapeHTML(str)
|
|
195
|
-
async function renderNode(
|
|
196
|
-
const { write
|
|
194
|
+
var toAttrStringLit = (str) => '"' + escapeHTML(str) + '"';
|
|
195
|
+
async function renderNode(rc, node, stripSlotProp) {
|
|
196
|
+
const { write } = rc;
|
|
197
197
|
switch (typeof node) {
|
|
198
198
|
case "string":
|
|
199
199
|
write(escapeHTML(node));
|
|
@@ -204,11 +204,11 @@ async function renderNode(ctx, node, stripSlotProp) {
|
|
|
204
204
|
break;
|
|
205
205
|
case "object":
|
|
206
206
|
if (isVNode(node)) {
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
if (tag === $fragment) {
|
|
210
|
-
if (children !== void 0) {
|
|
211
|
-
await renderChildren(
|
|
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);
|
|
212
212
|
}
|
|
213
213
|
break;
|
|
214
214
|
}
|
|
@@ -218,114 +218,98 @@ async function renderNode(ctx, node, stripSlotProp) {
|
|
|
218
218
|
}
|
|
219
219
|
break;
|
|
220
220
|
}
|
|
221
|
-
if (tag === "slot") {
|
|
222
|
-
const ctxSlots = ctx.slots;
|
|
223
|
-
let slots;
|
|
224
|
-
if (ctxSlots !== void 0) {
|
|
225
|
-
if (Array.isArray(ctxSlots)) {
|
|
226
|
-
if (isVNode(ctxSlots)) {
|
|
227
|
-
slots = [ctxSlots];
|
|
228
|
-
} else {
|
|
229
|
-
slots = ctxSlots;
|
|
230
|
-
}
|
|
231
|
-
} else {
|
|
232
|
-
slots = [ctxSlots];
|
|
233
|
-
}
|
|
234
|
-
}
|
|
235
|
-
if (props.name) {
|
|
236
|
-
children = slots?.filter((v) => isVNode(v) && v[1].slot === props.name);
|
|
237
|
-
} else {
|
|
238
|
-
children = slots?.filter((v) => !isVNode(v) || !v[1].slot);
|
|
239
|
-
}
|
|
240
|
-
if (children === void 0 || Array(children) && children.length === 0) {
|
|
241
|
-
children = node[1].children;
|
|
242
|
-
}
|
|
243
|
-
if (children !== void 0) {
|
|
244
|
-
await renderChildren(ctx, children, true);
|
|
245
|
-
}
|
|
246
|
-
break;
|
|
247
|
-
}
|
|
248
|
-
const fcIndex = ctx.index.fc.toString(36);
|
|
249
221
|
if (tag === $state) {
|
|
250
|
-
const { key, value } = props;
|
|
251
|
-
write('<m-state fc="' +
|
|
222
|
+
const { key, value, fc } = props;
|
|
223
|
+
write('<m-state fc="' + fc + '" key=' + toAttrStringLit(key) + ">");
|
|
252
224
|
if (value !== void 0 && value !== null) {
|
|
253
225
|
write(escapeHTML("" + value));
|
|
254
226
|
}
|
|
255
227
|
write("</m-state>");
|
|
256
|
-
stateStore.set(
|
|
228
|
+
stateStore.set(fc + ":" + key, value);
|
|
257
229
|
break;
|
|
258
230
|
}
|
|
259
231
|
if (tag === $computed) {
|
|
260
|
-
const { deps, value, fn } = props;
|
|
232
|
+
const { deps, value, fn, fc } = props;
|
|
261
233
|
write(
|
|
262
|
-
'<m-state fc="' +
|
|
234
|
+
'<m-state fc="' + fc + '" computed><script type="computed">$(' + fn + ", " + JSON.stringify(Object.keys(deps)) + ")<\/script>"
|
|
263
235
|
);
|
|
264
236
|
if (value !== void 0) {
|
|
265
237
|
write(escapeHTML("" + value));
|
|
266
238
|
}
|
|
267
239
|
write("</m-state>");
|
|
268
240
|
for (const [key, value2] of Object.entries(deps)) {
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
stateStore.set(stateKey, value2);
|
|
241
|
+
if (!stateStore.has(key)) {
|
|
242
|
+
stateStore.set(key, value2);
|
|
272
243
|
}
|
|
273
244
|
}
|
|
274
245
|
break;
|
|
275
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);
|
|
255
|
+
}
|
|
256
|
+
if (slots.length === 0) {
|
|
257
|
+
slots = props.children;
|
|
258
|
+
}
|
|
259
|
+
await renderChildren(rc, slots, true);
|
|
260
|
+
}
|
|
261
|
+
break;
|
|
262
|
+
}
|
|
276
263
|
if (tag === "toggle") {
|
|
264
|
+
const { value: valueProp, children } = props;
|
|
277
265
|
if (children !== void 0) {
|
|
278
|
-
const valueProp = props.value;
|
|
279
266
|
if (isVNode(valueProp) && valueProp[0] === $state || valueProp[0] === $computed) {
|
|
280
|
-
const { key, deps, value, fn } = valueProp[1];
|
|
281
|
-
write('<m-state mode="toggle" fc="' +
|
|
267
|
+
const { key, deps, value, fn, fc } = valueProp[1];
|
|
268
|
+
write('<m-state mode="toggle" fc="' + fc + '" ');
|
|
282
269
|
if (key) {
|
|
283
270
|
write("key=" + toAttrStringLit(key) + ">");
|
|
284
|
-
stateStore.set(
|
|
271
|
+
stateStore.set(fc + ":" + key, !!value);
|
|
285
272
|
} else {
|
|
286
273
|
write('computed><script type="computed">$(' + fn + ", " + JSON.stringify(Object.keys(deps)) + ")<\/script>");
|
|
287
274
|
for (const [key2, value2] of Object.entries(deps)) {
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
stateStore.set(stateKey, value2);
|
|
275
|
+
if (!stateStore.has(key2)) {
|
|
276
|
+
stateStore.set(key2, value2);
|
|
291
277
|
}
|
|
292
278
|
}
|
|
293
279
|
}
|
|
294
280
|
if (!value) {
|
|
295
281
|
write("<template m-slot>");
|
|
296
282
|
}
|
|
297
|
-
await renderChildren(
|
|
283
|
+
await renderChildren(rc, children);
|
|
298
284
|
if (!value) {
|
|
299
285
|
write("</template>");
|
|
300
286
|
}
|
|
301
287
|
write("</m-state>");
|
|
302
288
|
} else if (valueProp) {
|
|
303
|
-
await renderChildren(
|
|
289
|
+
await renderChildren(rc, children);
|
|
304
290
|
}
|
|
305
291
|
}
|
|
306
292
|
break;
|
|
307
293
|
}
|
|
308
294
|
if (tag === "switch") {
|
|
295
|
+
const { value: valueProp, defaultValue, children } = props;
|
|
309
296
|
if (children !== void 0) {
|
|
310
297
|
let slots = Array.isArray(children) ? isVNode(children) ? [children] : children : [children];
|
|
311
|
-
let valueProp = props.value;
|
|
312
|
-
let defaultValue = props.defaultValue;
|
|
313
298
|
let stateful;
|
|
314
299
|
let computed;
|
|
315
300
|
let valueOrDefault;
|
|
316
301
|
if (isVNode(valueProp) && (valueProp[0] === $state || valueProp[0] === $computed)) {
|
|
317
|
-
const { key, deps, value, fn } = valueProp[1];
|
|
302
|
+
const { key, deps, value, fn, fc } = valueProp[1];
|
|
318
303
|
valueOrDefault = value ?? defaultValue;
|
|
319
|
-
stateful = '<m-state mode="switch" fc="' +
|
|
304
|
+
stateful = '<m-state mode="switch" fc="' + fc + '" ';
|
|
320
305
|
if (key) {
|
|
321
306
|
stateful += "key=" + toAttrStringLit(key) + ">";
|
|
322
|
-
stateStore.set(
|
|
307
|
+
stateStore.set(fc + ":" + key, valueOrDefault);
|
|
323
308
|
} else {
|
|
324
309
|
stateful += 'computed><script type="computed">$(' + fn + ", " + JSON.stringify(Object.keys(deps)) + ")<\/script>";
|
|
325
310
|
for (const [key2, value2] of Object.entries(deps)) {
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
stateStore.set(stateKey, value2);
|
|
311
|
+
if (!stateStore.has(key2)) {
|
|
312
|
+
stateStore.set(key2, value2);
|
|
329
313
|
}
|
|
330
314
|
}
|
|
331
315
|
}
|
|
@@ -354,16 +338,16 @@ async function renderNode(ctx, node, stripSlotProp) {
|
|
|
354
338
|
}
|
|
355
339
|
}
|
|
356
340
|
if (matchedSlot) {
|
|
357
|
-
await renderNode(
|
|
341
|
+
await renderNode(rc, matchedSlot[1], true);
|
|
358
342
|
} else if (unnamedSlots.length > 0) {
|
|
359
|
-
await renderChildren(
|
|
343
|
+
await renderChildren(rc, unnamedSlots);
|
|
360
344
|
}
|
|
361
345
|
if (stateful) {
|
|
362
346
|
if (namedSlots.length > 0 || matchedSlot && unnamedSlots.length > 0) {
|
|
363
347
|
write("<template m-slot>");
|
|
364
|
-
await renderChildren(
|
|
348
|
+
await renderChildren(rc, namedSlots);
|
|
365
349
|
if (matchedSlot && unnamedSlots.length > 0) {
|
|
366
|
-
await renderChildren(
|
|
350
|
+
await renderChildren(rc, unnamedSlots);
|
|
367
351
|
}
|
|
368
352
|
write("</template>");
|
|
369
353
|
}
|
|
@@ -373,48 +357,47 @@ async function renderNode(ctx, node, stripSlotProp) {
|
|
|
373
357
|
break;
|
|
374
358
|
}
|
|
375
359
|
if (typeof tag === "function") {
|
|
360
|
+
const fcIndex = ++rc.index.fc;
|
|
376
361
|
const { rendering, placeholder, catch: catchFC, ...fcProps } = props ?? /* @__PURE__ */ Object.create(null);
|
|
377
|
-
let eager = ctx.eager;
|
|
378
|
-
if ((rendering ?? tag.rendering) === "eager") {
|
|
379
|
-
eager = true;
|
|
380
|
-
}
|
|
381
362
|
try {
|
|
382
|
-
const v = tag.call(createState(
|
|
383
|
-
|
|
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;
|
|
384
367
|
if (v instanceof Promise) {
|
|
385
368
|
if (eager) {
|
|
386
|
-
await renderNode({ ...
|
|
369
|
+
await renderNode({ ...rc, fcIndex, eager: true, fcSlots }, await v);
|
|
387
370
|
} else {
|
|
388
|
-
const chunkId = (
|
|
389
|
-
|
|
371
|
+
const chunkId = (rc.suspenses.length + 1).toString(36);
|
|
372
|
+
rc.suspenses.push(v.then(async (c) => {
|
|
390
373
|
write('<m-chunk chunk-id="' + chunkId + '"><template>');
|
|
391
|
-
await renderNode({ ...
|
|
374
|
+
await renderNode({ ...rc, fcIndex, eager, fcSlots }, c);
|
|
392
375
|
write("</template></m-chunk>");
|
|
393
376
|
}));
|
|
394
377
|
write('<m-portal chunk-id="' + chunkId + '">');
|
|
395
378
|
if (placeholder) {
|
|
396
|
-
await renderNode({ ...
|
|
379
|
+
await renderNode({ ...rc, fcIndex, eager: true }, placeholder);
|
|
397
380
|
}
|
|
398
381
|
write("</m-portal>");
|
|
399
382
|
}
|
|
400
383
|
} else if (isObject(v) && Symbol.iterator in v && !isVNode(v)) {
|
|
401
384
|
for (const c of v) {
|
|
402
|
-
await renderNode({ ...
|
|
385
|
+
await renderNode({ ...rc, fcIndex, eager, fcSlots }, c);
|
|
403
386
|
}
|
|
404
387
|
} else if (isObject(v) && Symbol.asyncIterator in v) {
|
|
405
388
|
if (eager) {
|
|
406
389
|
for await (const c of v) {
|
|
407
|
-
await renderNode({ ...
|
|
390
|
+
await renderNode({ ...rc, fcIndex, eager: true, fcSlots }, c);
|
|
408
391
|
}
|
|
409
392
|
} else {
|
|
410
393
|
}
|
|
411
394
|
} else {
|
|
412
|
-
await renderNode({ ...
|
|
395
|
+
await renderNode({ ...rc, fcIndex, eager, fcSlots }, v);
|
|
413
396
|
}
|
|
414
397
|
} catch (err) {
|
|
415
398
|
if (err instanceof Error) {
|
|
416
399
|
if (typeof catchFC === "function") {
|
|
417
|
-
await renderNode({ ...
|
|
400
|
+
await renderNode({ ...rc, fcIndex, eager: true }, catchFC(err));
|
|
418
401
|
} else {
|
|
419
402
|
write('<pre style="color:red;font-size:1rem"><code>' + escapeHTML(err.stack ?? err.message) + "</code></pre>");
|
|
420
403
|
}
|
|
@@ -431,22 +414,21 @@ async function renderNode(ctx, node, stripSlotProp) {
|
|
|
431
414
|
continue;
|
|
432
415
|
}
|
|
433
416
|
if (isVNode(propValue) && (propValue[0] === $state || propValue[0] === $computed)) {
|
|
434
|
-
const { key, deps, fn,
|
|
417
|
+
const { key, value, deps, fn, fc } = propValue[1];
|
|
435
418
|
if (propName === "class") {
|
|
436
|
-
|
|
419
|
+
rc.runtimeUtils.cx = true;
|
|
437
420
|
} else if (propName === "style") {
|
|
438
|
-
|
|
421
|
+
rc.runtimeUtils.styleToCSS = true;
|
|
439
422
|
}
|
|
440
|
-
propEffects.push("<m-state mode=" + toAttrStringLit("[" + propName + "]") + ' fc="' +
|
|
423
|
+
propEffects.push("<m-state mode=" + toAttrStringLit("[" + propName + "]") + ' fc="' + fc + '" ');
|
|
441
424
|
if (key) {
|
|
442
425
|
propEffects.push("key=" + toAttrStringLit(key) + ">");
|
|
443
|
-
stateStore.set(
|
|
426
|
+
stateStore.set(fc + ":" + key, value);
|
|
444
427
|
} else {
|
|
445
428
|
propEffects.push('computed><script type="computed">$(' + fn + ", " + JSON.stringify(Object.keys(deps)) + ")<\/script>");
|
|
446
429
|
for (const [key2, value2] of Object.entries(deps)) {
|
|
447
|
-
|
|
448
|
-
|
|
449
|
-
stateStore.set(stateKey, value2);
|
|
430
|
+
if (!stateStore.has(key2)) {
|
|
431
|
+
stateStore.set(key2, value2);
|
|
450
432
|
}
|
|
451
433
|
}
|
|
452
434
|
}
|
|
@@ -494,7 +476,7 @@ async function renderNode(ctx, node, stripSlotProp) {
|
|
|
494
476
|
raw += css + "|";
|
|
495
477
|
}
|
|
496
478
|
raw += [pseudoStyles, atRuleStyles, nestingStyles].flat(1).map(([k, v]) => k + ">" + v).join("|");
|
|
497
|
-
styleIds =
|
|
479
|
+
styleIds = rc.styleIds ?? (rc.styleIds = /* @__PURE__ */ new Set());
|
|
498
480
|
id = hashCode(raw).toString(36);
|
|
499
481
|
cssSelector = "[data-css-" + id + "]";
|
|
500
482
|
if (!styleIds.has(id)) {
|
|
@@ -526,9 +508,9 @@ async function renderNode(ctx, node, stripSlotProp) {
|
|
|
526
508
|
break;
|
|
527
509
|
case "action":
|
|
528
510
|
if (typeof propValue === "function" && tag === "form") {
|
|
529
|
-
const
|
|
530
|
-
write("<script>function " +
|
|
531
|
-
buffer += ' onsubmit="$onsubmit(event,this,' +
|
|
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 : "") + ')"';
|
|
532
514
|
} else if (isString(propValue)) {
|
|
533
515
|
buffer += " action=" + toAttrStringLit(propValue);
|
|
534
516
|
}
|
|
@@ -542,16 +524,16 @@ async function renderNode(ctx, node, stripSlotProp) {
|
|
|
542
524
|
if (regexpHtmlTag.test(propName) && propValue !== void 0) {
|
|
543
525
|
if (propName.startsWith("on")) {
|
|
544
526
|
if (typeof propValue === "function") {
|
|
545
|
-
const
|
|
546
|
-
write("<script>function " +
|
|
547
|
-
buffer += " " + propName.toLowerCase() + '="$emit(event,this,' +
|
|
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 : "") + ')"';
|
|
548
530
|
}
|
|
549
531
|
} else if (typeof propValue === "boolean") {
|
|
550
532
|
if (propValue) {
|
|
551
533
|
buffer += " " + propName;
|
|
552
534
|
}
|
|
553
535
|
} else {
|
|
554
|
-
buffer += " " + (propValue === true ?
|
|
536
|
+
buffer += " " + escapeHTML(propName) + (propValue === true ? "" : "=" + toAttrStringLit("" + propValue));
|
|
555
537
|
}
|
|
556
538
|
}
|
|
557
539
|
}
|
|
@@ -563,19 +545,17 @@ async function renderNode(ctx, node, stripSlotProp) {
|
|
|
563
545
|
}
|
|
564
546
|
if (props.innerHTML) {
|
|
565
547
|
write(props.innerHTML);
|
|
566
|
-
} else if (children !== void 0) {
|
|
567
|
-
await renderChildren(
|
|
548
|
+
} else if (props.children !== void 0) {
|
|
549
|
+
await renderChildren(rc, props.children);
|
|
568
550
|
}
|
|
569
551
|
write("</" + tag + ">");
|
|
570
552
|
} else if (propEffects.length > 0) {
|
|
571
|
-
write("<m-group>");
|
|
572
|
-
write(propEffects.join(""));
|
|
573
|
-
write("</m-group>");
|
|
553
|
+
write("<m-group>" + propEffects.join("") + "</m-group>");
|
|
574
554
|
}
|
|
575
555
|
if (onMountHandler) {
|
|
576
|
-
|
|
556
|
+
rc.index.mf++;
|
|
577
557
|
write(
|
|
578
|
-
'<script>{const target=document.currentScript.previousElementSibling;addEventListener("load",()=>$emit({type:"mount",currentTarget:target,target},target,' + onMountHandler.toString() +
|
|
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>"
|
|
579
559
|
);
|
|
580
560
|
}
|
|
581
561
|
}
|
|
@@ -583,17 +563,17 @@ async function renderNode(ctx, node, stripSlotProp) {
|
|
|
583
563
|
break;
|
|
584
564
|
}
|
|
585
565
|
}
|
|
586
|
-
async function renderChildren(
|
|
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(
|
|
569
|
+
await renderNode(rc, child, stripSlotProp);
|
|
590
570
|
}
|
|
591
571
|
} else {
|
|
592
|
-
await renderNode(
|
|
572
|
+
await renderNode(rc, children, stripSlotProp);
|
|
593
573
|
}
|
|
594
574
|
}
|
|
595
575
|
function render(node, renderOptions = {}) {
|
|
596
|
-
const {
|
|
576
|
+
const { request, status, headers: headersInit } = renderOptions;
|
|
597
577
|
const headers = new Headers();
|
|
598
578
|
if (headersInit) {
|
|
599
579
|
for (const [key, value] of Object.entries(headersInit)) {
|
|
@@ -615,43 +595,61 @@ function render(node, renderOptions = {}) {
|
|
|
615
595
|
return new Response(
|
|
616
596
|
new ReadableStream({
|
|
617
597
|
async start(controller) {
|
|
598
|
+
const { appState: appStateInit, context, rendering, htmx } = renderOptions;
|
|
618
599
|
const write = (chunk) => controller.enqueue(encoder.encode(chunk));
|
|
600
|
+
const appState = createState(0, null, context, request);
|
|
619
601
|
const stateStore = /* @__PURE__ */ new Map();
|
|
620
602
|
const suspenses = [];
|
|
621
603
|
const rtComponents = { cx: false, styleToCSS: false };
|
|
622
|
-
const
|
|
604
|
+
const rc = {
|
|
623
605
|
write,
|
|
624
606
|
context,
|
|
625
607
|
request,
|
|
608
|
+
appState,
|
|
626
609
|
stateStore,
|
|
627
610
|
suspenses,
|
|
628
|
-
rtComponents,
|
|
611
|
+
runtimeUtils: rtComponents,
|
|
629
612
|
index: { fc: 0, mf: 0 },
|
|
630
613
|
eager: rendering === "eager"
|
|
631
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
|
+
}
|
|
632
622
|
try {
|
|
633
623
|
write("<!DOCTYPE html>");
|
|
634
|
-
await renderNode(
|
|
624
|
+
await renderNode(rc, node);
|
|
635
625
|
let js = "";
|
|
626
|
+
if (rc.index.mf > 0) {
|
|
627
|
+
js += UTILS_JS.event;
|
|
628
|
+
}
|
|
636
629
|
if (stateStore.size > 0) {
|
|
637
630
|
if (rtComponents.cx) {
|
|
638
|
-
js +=
|
|
631
|
+
js += UTILS_JS.cx;
|
|
639
632
|
}
|
|
640
633
|
if (rtComponents.styleToCSS) {
|
|
641
|
-
js +=
|
|
634
|
+
js += UTILS_JS.styleToCSS;
|
|
642
635
|
}
|
|
643
|
-
js +=
|
|
636
|
+
js += STATE_JS;
|
|
644
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);";
|
|
645
638
|
}
|
|
646
|
-
if (ctx.index.mf > 0) {
|
|
647
|
-
js += RUNTIME_COMPONENTS_JS.event;
|
|
648
|
-
}
|
|
649
639
|
if (suspenses.length > 0) {
|
|
650
|
-
js +=
|
|
640
|
+
js += SUSPENSE_JS;
|
|
651
641
|
}
|
|
652
642
|
if (js) {
|
|
653
643
|
write("<script>(()=>{" + js + "})()<\/script>");
|
|
654
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
|
+
}
|
|
655
653
|
if (suspenses.length > 0) {
|
|
656
654
|
await Promise.all(suspenses);
|
|
657
655
|
}
|
|
@@ -675,9 +673,10 @@ var jsx = (tag, props = /* @__PURE__ */ Object.create(null), key) => {
|
|
|
675
673
|
}
|
|
676
674
|
if (tag === "html") {
|
|
677
675
|
const renderOptions = /* @__PURE__ */ Object.create(null);
|
|
678
|
-
|
|
679
|
-
|
|
680
|
-
|
|
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;
|
|
681
680
|
delete props[key2];
|
|
682
681
|
}
|
|
683
682
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "mono-jsx",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.3.0",
|
|
4
4
|
"description": "`<html>` as a `Response`.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"module": "./index.mjs",
|
|
@@ -26,7 +26,8 @@
|
|
|
26
26
|
}
|
|
27
27
|
},
|
|
28
28
|
"scripts": {
|
|
29
|
-
"prepublishOnly": "deno task build"
|
|
29
|
+
"prepublishOnly": "deno task build",
|
|
30
|
+
"postinstall": "node setup.mjs"
|
|
30
31
|
},
|
|
31
32
|
"files": [
|
|
32
33
|
"*.mjs",
|
package/setup.mjs
ADDED
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
// setup.ts
|
|
2
|
+
import { existsSync } from "node:fs";
|
|
3
|
+
import { readFile, writeFile } from "node:fs/promises";
|
|
4
|
+
import { fileURLToPath } from "node:url";
|
|
5
|
+
import { argv } from "node:process";
|
|
6
|
+
async function setup() {
|
|
7
|
+
if (globalThis.Deno && existsSync("deno.jsonc")) {
|
|
8
|
+
console.log("Please add the following options to your deno.jsonc file:");
|
|
9
|
+
console.log(
|
|
10
|
+
[
|
|
11
|
+
`{`,
|
|
12
|
+
` "compilerOptions": {`,
|
|
13
|
+
` %c"jsx": "react-jsx",`,
|
|
14
|
+
` "jsxImportSource": "mono-jsx",%c`,
|
|
15
|
+
` }`,
|
|
16
|
+
`}`
|
|
17
|
+
].join("\n"),
|
|
18
|
+
"color:green",
|
|
19
|
+
""
|
|
20
|
+
);
|
|
21
|
+
return;
|
|
22
|
+
}
|
|
23
|
+
let tsConfigFilename = globalThis.Deno ? "deno.json" : "tsconfig.json";
|
|
24
|
+
let tsConfig = /* @__PURE__ */ Object.create(null);
|
|
25
|
+
try {
|
|
26
|
+
const data = await readFile(tsConfigFilename, "utf8");
|
|
27
|
+
tsConfig = JSON.parse(data);
|
|
28
|
+
} catch {
|
|
29
|
+
}
|
|
30
|
+
const compilerOptions = tsConfig.compilerOptions ?? (tsConfig.compilerOptions = {});
|
|
31
|
+
if (compilerOptions.jsx === "react-jsx" && compilerOptions.jsxImportSource === "mono-jsx") {
|
|
32
|
+
console.log("%cmono-jsx already setup.", "color:grey");
|
|
33
|
+
return;
|
|
34
|
+
}
|
|
35
|
+
if (!globalThis.Deno) {
|
|
36
|
+
compilerOptions.module ??= "es2022";
|
|
37
|
+
compilerOptions.moduleResolution ??= "bundler";
|
|
38
|
+
}
|
|
39
|
+
compilerOptions.jsx = "react-jsx";
|
|
40
|
+
compilerOptions.jsxImportSource = "mono-jsx";
|
|
41
|
+
await writeFile(tsConfigFilename, JSON.stringify(tsConfig, null, 2));
|
|
42
|
+
console.log("\u2705 mono-jsx setup complete.");
|
|
43
|
+
}
|
|
44
|
+
function isMain() {
|
|
45
|
+
if (import.meta.main) {
|
|
46
|
+
return true;
|
|
47
|
+
}
|
|
48
|
+
if (import.meta.url.startsWith("file:")) {
|
|
49
|
+
return argv[1] === fileURLToPath(import.meta.url);
|
|
50
|
+
}
|
|
51
|
+
return false;
|
|
52
|
+
}
|
|
53
|
+
if (isMain()) {
|
|
54
|
+
setup();
|
|
55
|
+
}
|
|
56
|
+
export {
|
|
57
|
+
setup
|
|
58
|
+
};
|
package/types/css.d.ts
CHANGED
|
@@ -6671,7 +6671,7 @@ export interface VendorLonghandProperties<TLength = (string & {}) | 0, TTime = s
|
|
|
6671
6671
|
*/
|
|
6672
6672
|
msHyphens?: Property.Hyphens | undefined;
|
|
6673
6673
|
/**
|
|
6674
|
-
* The **`-ms-ime-align`** CSS property is a Microsoft extension aligning the Input Method Editor (IME) candidate window box relative to the element on which the IME composition is active. The extension is implemented in Microsoft Edge and Internet Explorer
|
|
6674
|
+
* The **`-ms-ime-align`** CSS property is a Microsoft extension aligning the Input Method Editor (IME) candidate window box relative to the element on which the IME composition is active. The extension is implemented in Microsoft Edge and Internet Explorer 11.
|
|
6675
6675
|
*
|
|
6676
6676
|
* **Syntax**: `auto | after`
|
|
6677
6677
|
*
|