mono-jsx 0.6.5 → 0.6.6
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 +35 -58
- package/index.mjs +0 -5
- package/jsx-runtime.mjs +36 -53
- package/package.json +1 -1
- package/types/index.d.ts +0 -11
- package/types/jsx-runtime.d.ts +4 -5
- package/types/mono.d.ts +9 -20
- package/types/render.d.ts +3 -3
package/README.md
CHANGED
|
@@ -150,13 +150,11 @@ mono-jsx supports [pseudo classes](https://developer.mozilla.org/en-US/docs/Web/
|
|
|
150
150
|
```tsx
|
|
151
151
|
<a
|
|
152
152
|
style={{
|
|
153
|
-
display: "inline-flex",
|
|
154
|
-
gap: "0.5em",
|
|
155
153
|
color: "black",
|
|
156
154
|
"::after": { content: "↩️" },
|
|
157
155
|
":hover": { textDecoration: "underline" },
|
|
158
156
|
"@media (prefers-color-scheme: dark)": { color: "white" },
|
|
159
|
-
"& .icon": { width: "1em", height: "1em" },
|
|
157
|
+
"& .icon": { width: "1em", height: "1em", marginRight: "0.5em" },
|
|
160
158
|
}}
|
|
161
159
|
>
|
|
162
160
|
<img class="icon" src="link.png" />
|
|
@@ -363,7 +361,7 @@ interface AppSignals {
|
|
|
363
361
|
function Header(this: FC<{}, AppSignals>) {
|
|
364
362
|
return (
|
|
365
363
|
<header>
|
|
366
|
-
<h1 style={{ color: this.app.themeColor }}>Welcome to mono-jsx!</h1>
|
|
364
|
+
<h1 style={this.computed(() => ({ color: this.app.themeColor }))}>Welcome to mono-jsx!</h1>
|
|
367
365
|
</header>
|
|
368
366
|
)
|
|
369
367
|
}
|
|
@@ -371,7 +369,7 @@ function Header(this: FC<{}, AppSignals>) {
|
|
|
371
369
|
function Footer(this: FC<{}, AppSignals>) {
|
|
372
370
|
return (
|
|
373
371
|
<footer>
|
|
374
|
-
<p style={{ color: this.app.themeColor }}>(c) 2025 mono-jsx.</p>
|
|
372
|
+
<p style={this.computed(() => ({ color: this.app.themeColor }))}>(c) 2025 mono-jsx.</p>
|
|
375
373
|
</footer>
|
|
376
374
|
)
|
|
377
375
|
}
|
|
@@ -838,7 +836,7 @@ export default {
|
|
|
838
836
|
}
|
|
839
837
|
```
|
|
840
838
|
|
|
841
|
-
## Using Router(SPA
|
|
839
|
+
## Using Router(SPA)
|
|
842
840
|
|
|
843
841
|
mono-jsx provides a built-in `<router>` element that allows your app to render components based on the current URL. On client side, it listens all `click` events on `<a>` elements and asynchronously fetches the route component without reloading the entire page.
|
|
844
842
|
|
|
@@ -855,11 +853,13 @@ const routes = {
|
|
|
855
853
|
export default {
|
|
856
854
|
fetch: (req) => (
|
|
857
855
|
<html request={req} routes={routes}>
|
|
858
|
-
<
|
|
859
|
-
<
|
|
860
|
-
|
|
861
|
-
|
|
862
|
-
|
|
856
|
+
<header>
|
|
857
|
+
<nav>
|
|
858
|
+
<a href="/">Home</a>
|
|
859
|
+
<a href="/about">About</a>
|
|
860
|
+
<a href="/blog">Blog</a>
|
|
861
|
+
</nav>
|
|
862
|
+
</header>
|
|
863
863
|
<router />
|
|
864
864
|
</html>
|
|
865
865
|
)
|
|
@@ -872,10 +872,12 @@ mono-jsx router requires [URLPattern](https://developer.mozilla.org/en-US/docs/W
|
|
|
872
872
|
- ✅ Cloudflare Workers
|
|
873
873
|
- ✅ Nodejs (>= 24)
|
|
874
874
|
|
|
875
|
-
For Bun users, mono-jsx provides a `
|
|
875
|
+
For Bun users, mono-jsx provides a `monoRoutes` function that uses Bun's built-in routing:
|
|
876
876
|
|
|
877
877
|
```tsx
|
|
878
|
-
|
|
878
|
+
// bun app.tsx
|
|
879
|
+
|
|
880
|
+
import { monoRoutes } from "mono-jsx"
|
|
879
881
|
|
|
880
882
|
const routes = {
|
|
881
883
|
"/": Home,
|
|
@@ -884,18 +886,13 @@ const routes = {
|
|
|
884
886
|
"/post/:id": Post,
|
|
885
887
|
}
|
|
886
888
|
|
|
887
|
-
|
|
888
|
-
routes:
|
|
889
|
-
<html request={
|
|
890
|
-
<nav>
|
|
891
|
-
<a href="/">Home</a>
|
|
892
|
-
<a href="/about">About</a>
|
|
893
|
-
<a href="/blog">Blog</a>
|
|
894
|
-
</nav>
|
|
889
|
+
export default {
|
|
890
|
+
routes: monoRoutes(routes, (request) => (
|
|
891
|
+
<html request={request}>
|
|
895
892
|
<router />
|
|
896
893
|
</html>
|
|
897
894
|
))
|
|
898
|
-
}
|
|
895
|
+
}
|
|
899
896
|
```
|
|
900
897
|
|
|
901
898
|
### Using Route `params`
|
|
@@ -912,22 +909,18 @@ function Post(this: FC) {
|
|
|
912
909
|
}
|
|
913
910
|
```
|
|
914
911
|
|
|
915
|
-
###
|
|
912
|
+
### Using DB/Storage in Route Components
|
|
916
913
|
|
|
917
|
-
|
|
914
|
+
Route components are always rendered on server-side, you can use any database or storage API to fetch data in your route components.
|
|
918
915
|
|
|
919
916
|
```tsx
|
|
920
|
-
function
|
|
921
|
-
|
|
922
|
-
|
|
923
|
-
<
|
|
924
|
-
<
|
|
925
|
-
|
|
926
|
-
|
|
927
|
-
<a href="/blog">Blog</a>
|
|
928
|
-
</nav>
|
|
929
|
-
<router />
|
|
930
|
-
</html>
|
|
917
|
+
async function Post(this: FC) {
|
|
918
|
+
const post = await sql`SELECT * FROM posts WHERE id = ${ this.request.params!.id }`
|
|
919
|
+
return (
|
|
920
|
+
<article>
|
|
921
|
+
<h2>{post.title}<h2>
|
|
922
|
+
<div>html`${post.content}`</div>
|
|
923
|
+
</article>
|
|
931
924
|
)
|
|
932
925
|
}
|
|
933
926
|
```
|
|
@@ -940,35 +933,19 @@ Links under the `<nav>` element will be treated as navigation links by the route
|
|
|
940
933
|
export default {
|
|
941
934
|
fetch: (req) => (
|
|
942
935
|
<html request={req} routes={routes}>
|
|
943
|
-
<
|
|
944
|
-
<a
|
|
945
|
-
|
|
946
|
-
|
|
947
|
-
|
|
936
|
+
<header>
|
|
937
|
+
<nav style={{ "& a.active": { fontWeight: "bold" } }} data-active-class="active">
|
|
938
|
+
<a href="/">Home</a>
|
|
939
|
+
<a href="/about">About</a>
|
|
940
|
+
<a href="/blog">Blog</a>
|
|
941
|
+
</nav>
|
|
942
|
+
</header>
|
|
948
943
|
<router />
|
|
949
944
|
</html>
|
|
950
945
|
)
|
|
951
946
|
}
|
|
952
947
|
```
|
|
953
948
|
|
|
954
|
-
### Using DB/Storage in Route Components
|
|
955
|
-
|
|
956
|
-
Route components are always rendered on server-side, you can use any database or storage API to fetch data in your route components.
|
|
957
|
-
|
|
958
|
-
```tsx
|
|
959
|
-
async function Post(this: FC) {
|
|
960
|
-
const post = await sql`SELECT * FROM posts WHERE id = ${ this.request.params!.id }`
|
|
961
|
-
return (
|
|
962
|
-
<article>
|
|
963
|
-
<h2>{post.title}<h2>
|
|
964
|
-
<section>
|
|
965
|
-
{html(post.content)}
|
|
966
|
-
</section>
|
|
967
|
-
</article>
|
|
968
|
-
)
|
|
969
|
-
}
|
|
970
|
-
```
|
|
971
|
-
|
|
972
949
|
### Fallback(404)
|
|
973
950
|
|
|
974
951
|
You can add fallback(404) content to the `<router>` element as children, which will be displayed when no route matches the current URL.
|
package/index.mjs
CHANGED
|
@@ -1,8 +1,4 @@
|
|
|
1
1
|
// index.ts
|
|
2
|
-
function buildRoutes(handler) {
|
|
3
|
-
const { routes = {} } = handler(Symbol.for("mono.peek"));
|
|
4
|
-
return monoRoutes(routes, handler);
|
|
5
|
-
}
|
|
6
2
|
function monoRoutes(routes, handler) {
|
|
7
3
|
const handlers = {};
|
|
8
4
|
for (const [path, fc] of Object.entries(routes)) {
|
|
@@ -14,6 +10,5 @@ function monoRoutes(routes, handler) {
|
|
|
14
10
|
return handlers;
|
|
15
11
|
}
|
|
16
12
|
export {
|
|
17
|
-
buildRoutes,
|
|
18
13
|
monoRoutes
|
|
19
14
|
};
|
package/jsx-runtime.mjs
CHANGED
|
@@ -1,6 +1,11 @@
|
|
|
1
|
-
//
|
|
2
|
-
|
|
3
|
-
|
|
1
|
+
// runtime/index.ts
|
|
2
|
+
var CX_JS = `{var i=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".split(",")),r=e=>typeof e=="string",o=e=>typeof e=="object"&&e!==null;var n=e=>r(e)?e:o(e)?Array.isArray(e)?e.map(n).filter(Boolean).join(" "):Object.entries(e).filter(([,t])=>!!t).map(([t])=>t).join(" "):"";window.$cx=n;}`;
|
|
3
|
+
var STYLE_JS = `{var a=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".split(",")),l=e=>typeof e=="string",u=e=>typeof e=="object"&&e!==null,p=e=>e.replace(/[a-z][A-Z]/g,n=>n.charAt(0)+"-"+n.charAt(1).toLowerCase());var f=e=>{let n=[],r=[],t=new d;for(let[o,i]of Object.entries(e))switch(o.charCodeAt(0)){case 58:r.push(null,o+"{"+c(i)+"}");break;case 64:r.push(o+"{",null,"{"+c(i)+"}}");break;case 38:r.push(null,o.slice(1)+"{"+c(i)+"}");break;default:n.push([o,i])}return n.length>0&&(t.inline=c(n)),r.length>0&&(t.css=r),t},g=(e,n)=>{let{inline:r,css:t}=f(n);if(t){let o="data-css-",i="["+o+(Date.now()+Math.random()).toString(36).replace(".","")+"]";document.head.appendChild(document.createElement("style")).textContent=(r?i+"{"+r+"}":"")+t.map(s=>s===null?i:s).join(""),e.getAttributeNames().forEach(s=>s.startsWith(o)&&e.removeAttribute(s)),e.setAttribute(i.slice(1,-1),"")}else r&&e.setAttribute("style",r)},c=e=>{if(u(e)){let n="";for(let[r,t]of Array.isArray(e)?e:Object.entries(e))if(l(t)||typeof t=="number"){let o=p(r),i=typeof t=="number"?a.has(o)?""+t:t+"px":""+t;n+=(n?";":"")+o+":"+(o==="content"?JSON.stringify(i):i)}return n}return""},d=(()=>{function e(){}return e.prototype=Object.freeze(Object.create(null)),e})();window.$applyStyle=g;}`;
|
|
4
|
+
var EVENT_JS = `{var w=window;w.$emit=(e,f,s)=>f.call(w.$signals?.(s)??e.target,e.type==="mount"?e.target:e);w.$onsubmit=(e,f,s)=>{e.preventDefault();f.call(w.$signals?.(s)??e.target,new FormData(e.target),e)};}`;
|
|
5
|
+
var SIGNALS_JS = `{let p;const h=window,E=new Map,b=new Map,d=e=>b.get(e)??b.set(e,S(e)).get(e),u=(e,t)=>e.getAttribute(t),y=(e,t,r)=>e.setAttribute(t,r),M=(e,t)=>e.replaceChildren(...t),v=()=>Object.create(null),S=e=>{const t=v(),r=(c,l)=>{t[c]=l},n=new Map,o=(c,l)=>{let i=n.get(c);return i||(i=new Set,n.set(c,i)),i.add(l),()=>{i.delete(l),i.size===0&&n.delete(c)}},s=new Proxy(v(),{get:(c,l)=>document.querySelector("[data-ref='"+e+":"+l+"']")});return new Proxy(t,{get:(c,l,i)=>{switch(l){case"$init":return r;case"$watch":return o;case"app":return d(0);case"refs":return s;default:return p?.(e,l),Reflect.get(c,l,i)}},set:(c,l,i,a)=>{if(i!==Reflect.get(c,l,a)){const f=n.get(l);return f&&queueMicrotask(()=>f.forEach(g=>g())),Reflect.set(c,l,i,a)}return!1}})},k=(e,t,r)=>{if(t==="toggle"){let n;return()=>{if(!n){const o=e.firstElementChild;o&&o.tagName==="TEMPLATE"&&o.hasAttribute("m-slot")?n=[...o.content.childNodes]:n=[...e.childNodes]}M(e,r()?n:[])}}if(t==="switch"){let n,o=u(e,"match"),s,c,l=i=>s.get(i)??s.set(i,[]).get(i);return()=>{if(!s){s=new Map,c=[];for(const i of e.childNodes)if(i.nodeType===1&&i.tagName==="TEMPLATE"&&i.hasAttribute("m-slot")){for(const a of i.content.childNodes)a.nodeType===1&&a.hasAttribute("slot")?l(u(a,"slot")).push(a):c.push(a);i.remove()}else o?l(o).push(i):c.push(i)}n=""+r(),M(e,s.has(n)?s.get(n):c)}}if(t&&t.length>2&&t.startsWith("[")&&t.endsWith("]")){let n=t.slice(1,-1),o=e.parentElement;return o.tagName==="M-GROUP"&&(o=o.previousElementSibling),()=>{const s=r();s===!1||s===null||s===void 0?o.removeAttribute(n):typeof s=="object"&&s!==null&&(n==="class"||n==="style"||n==="props")?n==="class"?y(o,n,$cx(s)):n==="style"?$applyStyle(o,s):y(o,n,JSON.stringify(s)):y(o,n,s===!0?"":s)}}return()=>e.textContent=""+r()},N=e=>{const t=e.indexOf(":");return t>0?[Number(e.slice(0,t)),e.slice(t+1)]:null},w=async e=>{const t=e();return t!==void 0?t:(await new Promise(r=>setTimeout(r,0)),w(e))},T=(e,t)=>customElements.define(e,class extends HTMLElement{disposes=[];connectedCallback(){t(this)}disconnectedCallback(){this.disposes.forEach(r=>r()),this.disposes.length=0}});T("m-signal",e=>{const t=d(Number(u(e,"scope"))),r=u(e,"key");if(r)e.disposes.push(t.$watch(r,k(e,u(e,"mode"),()=>t[r])));else{const n=Number(u(e,"computed"));w(()=>E.get(n)).then(([o,s])=>{const c=k(e,u(e,"mode"),o.bind(t));s.forEach(l=>{const[i,a]=N(l);e.disposes.push(d(i).$watch(a,c))})})}}),T("m-effect",e=>{const{disposes:t}=e,r=Number(u(e,"scope")),n=Number(u(e,"n")),o=new Array(n);t.push(()=>{o.forEach(s=>typeof s=="function"&&s()),o.length=0});for(let s=0;s<n;s++){const c="$ME_"+r+"_"+s;w(()=>h[c]).then(l=>{const i=[],a=d(r),f=()=>{o[s]=l.call(a)};p=(g,m)=>i.push([g,m]),f(),p=void 0;for(const[g,m]of i)t.push(d(g).$watch(m,f))},()=>{})}}),h.$signals=e=>e!==void 0?d(e):void 0,h.$MS=(e,t)=>{const[r,n]=N(e);d(r).$init(n,t)},h.$MC=(e,t,r)=>{E.set(e,[t,r])},h.$patch=(e,...t)=>{for(const[r,...n]of t){const o=n.pop();let s=e;for(const c of n)s=s[c];s[o]=r}return e};}`;
|
|
6
|
+
var SUSPENSE_JS = `{const s=new Map,i=e=>e.getAttribute("chunk-id"),l=(e,t)=>customElements.define(e,class extends HTMLElement{connectedCallback(){t(this)}});l("m-portal",e=>{s.set(i(e),e)}),l("m-chunk",e=>{setTimeout(()=>{const t=e.firstChild?.content.childNodes,o=i(e),n=s.get(o);n&&(e.hasAttribute("next")?n.before(...t):(s.delete(o),e.hasAttribute("done")?n.remove():n.replaceWith(...t)),e.remove())})});}`;
|
|
7
|
+
var LAZY_JS = `{const r=document,o=(t,e)=>t.getAttribute(e),i=(t,e=[])=>t.replaceChildren(...e);customElements.define("m-component",class extends HTMLElement{static observedAttributes=["name","props"];#e;#i;#n;#t;#s;async#r(){const t={"x-component":this.#e,"x-props":this.#i??"{}","x-runtime-flag":""+$runtimeFlag,"x-scope-seq":""+$scopeSeq},e=new AbortController;this.#s?.abort(),this.#s=e,i(this,this.#n);const s=await fetch(location.href,{headers:t,signal:e.signal});if(!s.ok)throw i(this),new Error("Failed to fetch component '"+name+"'");const[l,n]=await s.json();this.innerHTML=l,n&&(r.body.appendChild(r.createElement("script")).textContent=n)}connectedCallback(){setTimeout(()=>{if(!this.#e){const t=o(this,"name"),e=o(this,"props");if(!t)throw new Error("Component name is required");this.#e=t,this.#i=e?.startsWith("base64,")?atob(e.slice(7)):null,this.#n=[...this.childNodes]}this.#r()})}disconnectedCallback(){i(this,this.#n),this.#s?.abort(),this.#t&&clearTimeout(this.#t),this.#s=void 0,this.#t=void 0}attributeChangedCallback(t,e,s){this.#e&&s&&e!==s&&(t==="name"?this.#e=s:t==="props"&&(this.#i=s),this.#t&&clearTimeout(this.#t),this.#t=setTimeout(()=>{this.#t=void 0,this.#r()},20))}});}`;
|
|
8
|
+
var ROUTER_JS = `{const n=document,a=t=>t.split("#",1)[0];customElements.define("m-router",class extends HTMLElement{#t;#e;#s;#i;async#o(t){const i=new AbortController,e={"x-route":"true","x-runtime-flag":""+$runtimeFlag,"x-scope-seq":""+$scopeSeq};this.#i?.abort(),this.#i=i;const s=await fetch(t,{headers:e,signal:i.signal});if(s.status===404){this.replaceChildren(...this.#t);return}if(!s.ok)throw this.replaceChildren(),new Error("Failed to fetch route: "+s.status+" "+s.statusText);const[o,r]=await s.json();this.innerHTML=o,r&&(n.body.appendChild(n.createElement("script")).textContent=r)}#n(){n.querySelectorAll("nav a").forEach(t=>{const{href:i,classList:e}=t,s=t.closest("nav")?.getAttribute("data-active-class")??"active";a(i)===a(location.href)?e.add(s):e.remove(s)})}#a(t){this.#o(t),this.#n()}connectedCallback(){setTimeout(()=>{if(!this.#t)if(this.getAttribute("status")==="404")this.#t=[...this.childNodes];else{this.#t=[];for(const t of this.childNodes)if(t.nodeType===1&&t.tagName==="TEMPLATE"&&t.hasAttribute("m-slot")){this.#t.push(...t.content.childNodes),t.remove();break}}}),this.#e=t=>{if(t.defaultPrevented||t.altKey||t.ctrlKey||t.metaKey||t.shiftKey||!(t.target instanceof HTMLAnchorElement))return;const{download:i,href:e,rel:s,target:o}=t.target;i||s==="external"||o==="_blank"||!e||!e.startsWith(location.origin)||a(e)===a(location.href)||(t.preventDefault(),history.pushState({},"",e),this.#a(e))},this.#s=()=>this.#a(location.href),addEventListener("popstate",this.#s),n.addEventListener("click",this.#e),setTimeout(()=>this.#n())}disconnectedCallback(){removeEventListener("popstate",this.#s),n.removeEventListener("click",this.#e),this.#i?.abort(),this.#s=void 0,this.#e=void 0,this.#i=void 0}});}`;
|
|
4
9
|
|
|
5
10
|
// runtime/utils.ts
|
|
6
11
|
var regexpHtmlSafe = /["'&<>]/;
|
|
@@ -116,12 +121,18 @@ var $vnode = Symbol.for("jsx.vnode");
|
|
|
116
121
|
var $fragment = Symbol.for("jsx.fragment");
|
|
117
122
|
var $html = Symbol.for("jsx.html");
|
|
118
123
|
var $signal = Symbol.for("mono.signal");
|
|
119
|
-
var $peek = Symbol.for("mono.peek");
|
|
120
124
|
|
|
121
125
|
// version.ts
|
|
122
|
-
var VERSION = "0.6.
|
|
126
|
+
var VERSION = "0.6.6";
|
|
123
127
|
|
|
124
128
|
// render.ts
|
|
129
|
+
var RUNTIME_CX = 1;
|
|
130
|
+
var RUNTIME_STYLE = 2;
|
|
131
|
+
var RUNTIME_EVENT = 4;
|
|
132
|
+
var RUNTIME_SIGNALS = 8;
|
|
133
|
+
var RUNTIME_SUSPENSE = 16;
|
|
134
|
+
var RUNTIME_LAZY = 32;
|
|
135
|
+
var RUNTIME_ROUTER = 64;
|
|
125
136
|
var cdn = "https://raw.esm.sh";
|
|
126
137
|
var encoder = new TextEncoder();
|
|
127
138
|
var customElements = /* @__PURE__ */ new Map();
|
|
@@ -285,38 +296,38 @@ async function render(node, options, write, writeJS, componentMode) {
|
|
|
285
296
|
};
|
|
286
297
|
const finalize = async () => {
|
|
287
298
|
let js = "";
|
|
288
|
-
if (rc.flags.runtime &
|
|
289
|
-
runtimeFlag |=
|
|
299
|
+
if (rc.flags.runtime & RUNTIME_CX && !(runtimeFlag & RUNTIME_CX)) {
|
|
300
|
+
runtimeFlag |= RUNTIME_CX;
|
|
290
301
|
js += CX_JS;
|
|
291
302
|
}
|
|
292
|
-
if (rc.flags.runtime &
|
|
293
|
-
runtimeFlag |=
|
|
303
|
+
if (rc.flags.runtime & RUNTIME_STYLE && !(runtimeFlag & RUNTIME_STYLE)) {
|
|
304
|
+
runtimeFlag |= RUNTIME_STYLE;
|
|
294
305
|
js += STYLE_JS;
|
|
295
306
|
}
|
|
296
|
-
if (rc.mfs.size > 0 && !(runtimeFlag &
|
|
297
|
-
runtimeFlag |=
|
|
307
|
+
if (rc.mfs.size > 0 && !(runtimeFlag & RUNTIME_EVENT)) {
|
|
308
|
+
runtimeFlag |= RUNTIME_EVENT;
|
|
298
309
|
js += EVENT_JS;
|
|
299
310
|
}
|
|
300
|
-
if ((signals.store.size > 0 || rc.mcs.size > 0 || signals.effects.length > 0) && !(runtimeFlag &
|
|
301
|
-
runtimeFlag |=
|
|
311
|
+
if ((signals.store.size > 0 || rc.mcs.size > 0 || signals.effects.length > 0) && !(runtimeFlag & RUNTIME_SIGNALS)) {
|
|
312
|
+
runtimeFlag |= RUNTIME_SIGNALS;
|
|
302
313
|
js += SIGNALS_JS;
|
|
303
314
|
}
|
|
304
|
-
if (suspenses.length > 0 && !(runtimeFlag &
|
|
305
|
-
runtimeFlag |=
|
|
315
|
+
if (suspenses.length > 0 && !(runtimeFlag & RUNTIME_SUSPENSE)) {
|
|
316
|
+
runtimeFlag |= RUNTIME_SUSPENSE;
|
|
306
317
|
js += SUSPENSE_JS;
|
|
307
318
|
}
|
|
308
|
-
if (rc.flags.runtime &
|
|
309
|
-
runtimeFlag |=
|
|
319
|
+
if (rc.flags.runtime & RUNTIME_LAZY && !(runtimeFlag & RUNTIME_LAZY)) {
|
|
320
|
+
runtimeFlag |= RUNTIME_LAZY;
|
|
310
321
|
js += LAZY_JS;
|
|
311
322
|
}
|
|
312
|
-
if (rc.flags.runtime &
|
|
313
|
-
runtimeFlag |=
|
|
323
|
+
if (rc.flags.runtime & RUNTIME_ROUTER && !(runtimeFlag & RUNTIME_ROUTER)) {
|
|
324
|
+
runtimeFlag |= RUNTIME_ROUTER;
|
|
314
325
|
js += ROUTER_JS;
|
|
315
326
|
}
|
|
316
327
|
if (js.length > 0) {
|
|
317
328
|
js = "(()=>{" + js + "})();/* --- */window.$runtimeFlag=" + runtimeFlag + ";";
|
|
318
329
|
}
|
|
319
|
-
if (runtimeFlag &
|
|
330
|
+
if (runtimeFlag & RUNTIME_LAZY || runtimeFlag & RUNTIME_ROUTER) {
|
|
320
331
|
js += "window.$scopeSeq=" + rc.flags.scope + ";";
|
|
321
332
|
}
|
|
322
333
|
if (rc.mfs.size > 0) {
|
|
@@ -425,27 +436,8 @@ async function renderNode(rc, node, stripSlotProp) {
|
|
|
425
436
|
}
|
|
426
437
|
// `<toggle>` element
|
|
427
438
|
case "toggle": {
|
|
428
|
-
|
|
439
|
+
const { show, children } = props;
|
|
429
440
|
if (children !== void 0) {
|
|
430
|
-
if (show === void 0 && hidden !== void 0) {
|
|
431
|
-
if (isSignal(hidden)) {
|
|
432
|
-
let { scope, key, value } = hidden[$signal];
|
|
433
|
-
if (typeof key === "string") {
|
|
434
|
-
key = {
|
|
435
|
-
compute: "()=>!this[" + JSON.stringify(key) + "]",
|
|
436
|
-
deps: /* @__PURE__ */ new Set([scope + ":" + key])
|
|
437
|
-
};
|
|
438
|
-
} else {
|
|
439
|
-
key = {
|
|
440
|
-
compute: "()=>!(" + key.compute + ")()",
|
|
441
|
-
deps: key.deps
|
|
442
|
-
};
|
|
443
|
-
}
|
|
444
|
-
show = Signal(scope, key, !value);
|
|
445
|
-
} else {
|
|
446
|
-
show = !hidden;
|
|
447
|
-
}
|
|
448
|
-
}
|
|
449
441
|
if (isSignal(show)) {
|
|
450
442
|
const { scope, key, value } = show[$signal];
|
|
451
443
|
let buf = '<m-signal mode="toggle" scope="' + scope + '" ';
|
|
@@ -555,7 +547,7 @@ async function renderNode(rc, node, stripSlotProp) {
|
|
|
555
547
|
buf += "<m-group>" + attrModifiers + "</m-group>";
|
|
556
548
|
}
|
|
557
549
|
write(buf);
|
|
558
|
-
rc.flags.runtime |=
|
|
550
|
+
rc.flags.runtime |= RUNTIME_LAZY;
|
|
559
551
|
break;
|
|
560
552
|
}
|
|
561
553
|
// `<router>` element
|
|
@@ -582,7 +574,7 @@ async function renderNode(rc, node, stripSlotProp) {
|
|
|
582
574
|
}
|
|
583
575
|
buf += "</m-router>";
|
|
584
576
|
write(buf);
|
|
585
|
-
rc.flags.runtime |=
|
|
577
|
+
rc.flags.runtime |= RUNTIME_ROUTER;
|
|
586
578
|
break;
|
|
587
579
|
}
|
|
588
580
|
default: {
|
|
@@ -655,9 +647,9 @@ function renderAttr(rc, attrName, attrValue, stripSlotProp) {
|
|
|
655
647
|
}
|
|
656
648
|
if (signal) {
|
|
657
649
|
if (attrName === "class") {
|
|
658
|
-
rc.flags.runtime |=
|
|
650
|
+
rc.flags.runtime |= RUNTIME_CX;
|
|
659
651
|
} else if (attrName === "style") {
|
|
660
|
-
rc.flags.runtime |=
|
|
652
|
+
rc.flags.runtime |= RUNTIME_STYLE;
|
|
661
653
|
}
|
|
662
654
|
signalValue = signal;
|
|
663
655
|
attrValue = signal[$signal].value;
|
|
@@ -889,7 +881,6 @@ function createSignals(scopeId, appSignals, context = new NullProtoObj(), reques
|
|
|
889
881
|
case "refs":
|
|
890
882
|
return refs;
|
|
891
883
|
case "computed":
|
|
892
|
-
case "$":
|
|
893
884
|
return computed;
|
|
894
885
|
case "effect":
|
|
895
886
|
return (effect) => {
|
|
@@ -986,9 +977,6 @@ var jsx = (tag, props = new NullProtoObj(), key) => {
|
|
|
986
977
|
props.key = key;
|
|
987
978
|
}
|
|
988
979
|
if (tag === "html") {
|
|
989
|
-
if (props.request === $peek) {
|
|
990
|
-
return props;
|
|
991
|
-
}
|
|
992
980
|
const renderOptions = new NullProtoObj();
|
|
993
981
|
const optionsKeys = /* @__PURE__ */ new Set(["app", "context", "components", "routes", "request", "status", "headers", "htmx"]);
|
|
994
982
|
for (const [key2, value] of Object.entries(props)) {
|
|
@@ -1023,12 +1011,7 @@ Object.assign(globalThis, {
|
|
|
1023
1011
|
});
|
|
1024
1012
|
export {
|
|
1025
1013
|
Fragment,
|
|
1026
|
-
JSX,
|
|
1027
|
-
html as css,
|
|
1028
|
-
html,
|
|
1029
|
-
html as js,
|
|
1030
1014
|
jsx,
|
|
1031
1015
|
jsx as jsxDEV,
|
|
1032
|
-
jsxEscape,
|
|
1033
1016
|
jsx as jsxs
|
|
1034
1017
|
};
|
package/package.json
CHANGED
package/types/index.d.ts
CHANGED
|
@@ -1,16 +1,5 @@
|
|
|
1
1
|
import type { FC } from "./jsx.d.ts";
|
|
2
2
|
|
|
3
|
-
/**
|
|
4
|
-
* `buildRoute` creates a routing map for bun server.
|
|
5
|
-
*/
|
|
6
|
-
export function buildRoute(
|
|
7
|
-
handler: (req: Request) => Response,
|
|
8
|
-
): Record<string, (req: Request) => Response>;
|
|
9
|
-
|
|
10
|
-
/**
|
|
11
|
-
* `monoRoutes` creates a routing map for bun server.
|
|
12
|
-
* @deprecated Use `buildRoute` instead.
|
|
13
|
-
*/
|
|
14
3
|
export function monoRoutes(
|
|
15
4
|
routes: Record<string, FC<any> | Promise<{ default: FC<any> }>>,
|
|
16
5
|
handler: (req: Request) => Response,
|
package/types/jsx-runtime.d.ts
CHANGED
|
@@ -1,8 +1,7 @@
|
|
|
1
1
|
import type { FC, VNode } from "./jsx.d.ts";
|
|
2
2
|
|
|
3
|
-
export
|
|
4
|
-
export const JSX: typeof globalThis.JSX;
|
|
5
|
-
export const Fragment: (props: Record<string, unknown>) => VNode;
|
|
6
|
-
export const jsx: (tag: string | FC, props: Record<string, unknown>, key?: string | number) => VNode;
|
|
3
|
+
export function jsx(tag: string | FC, props: Record<string, unknown>, key?: string | number): VNode;
|
|
7
4
|
|
|
8
|
-
export
|
|
5
|
+
export function Fragment(props: Record<string, unknown>): VNode;
|
|
6
|
+
|
|
7
|
+
export { jsx as jsxDEV, jsx as jsxs };
|
package/types/mono.d.ts
CHANGED
|
@@ -91,27 +91,20 @@ export interface AsyncComponentAttributes {
|
|
|
91
91
|
|
|
92
92
|
export interface Elements {
|
|
93
93
|
/**
|
|
94
|
-
* The `toggle` element is a
|
|
94
|
+
* The `toggle` element is a builtin element that toggles the visibility of its children.
|
|
95
95
|
*/
|
|
96
96
|
toggle: BaseAttributes & {
|
|
97
|
-
show?:
|
|
98
|
-
hidden?: any;
|
|
97
|
+
show?: boolean | 0 | 1;
|
|
99
98
|
};
|
|
100
99
|
/**
|
|
101
|
-
* The `switch` element is a
|
|
100
|
+
* The `switch` element is a builtin element that chooses one of its children based on the `slot` attribute to display.
|
|
102
101
|
* It is similar to a switch statement in programming languages.
|
|
103
102
|
*/
|
|
104
103
|
switch: BaseAttributes & {
|
|
105
104
|
value?: string | number | boolean | null;
|
|
106
105
|
};
|
|
107
106
|
/**
|
|
108
|
-
* The `
|
|
109
|
-
*/
|
|
110
|
-
for: BaseAttributes & {
|
|
111
|
-
items?: unknown[];
|
|
112
|
-
};
|
|
113
|
-
/**
|
|
114
|
-
* The `component` element is a built-in element that is used to load components lazily,
|
|
107
|
+
* The `component` element is a builtin element that is used to load components lazily,
|
|
115
108
|
* which can improve performance by reducing the initial load time of the application.
|
|
116
109
|
*/
|
|
117
110
|
component: BaseAttributes & AsyncComponentAttributes & {
|
|
@@ -119,7 +112,7 @@ export interface Elements {
|
|
|
119
112
|
props?: Record<string, unknown>;
|
|
120
113
|
};
|
|
121
114
|
/**
|
|
122
|
-
* The `router` element is a
|
|
115
|
+
* The `router` element is a builtin element that implements client-side routing.
|
|
123
116
|
*/
|
|
124
117
|
router: BaseAttributes & AsyncComponentAttributes & {};
|
|
125
118
|
}
|
|
@@ -137,17 +130,17 @@ declare global {
|
|
|
137
130
|
*/
|
|
138
131
|
type FC<Signals = {}, AppSignals = {}, Context = {}> = {
|
|
139
132
|
/**
|
|
140
|
-
*
|
|
133
|
+
* Application signals.
|
|
141
134
|
*/
|
|
142
135
|
readonly app: AppSignals;
|
|
143
136
|
/**
|
|
144
|
-
*
|
|
137
|
+
* Rendering context.
|
|
145
138
|
*
|
|
146
139
|
* **⚠ This is a server-side only API.**
|
|
147
140
|
*/
|
|
148
141
|
readonly context: Context;
|
|
149
142
|
/**
|
|
150
|
-
*
|
|
143
|
+
* Current request object.
|
|
151
144
|
*
|
|
152
145
|
* **⚠ This is a server-side only API.**
|
|
153
146
|
*/
|
|
@@ -160,14 +153,10 @@ declare global {
|
|
|
160
153
|
* The `computed` method is used to create a computed signal.
|
|
161
154
|
*/
|
|
162
155
|
readonly computed: <T = unknown>(fn: () => T) => T;
|
|
163
|
-
/**
|
|
164
|
-
* `this.$(fn)` is just a shortcut for `this.computed(fn)`.
|
|
165
|
-
*/
|
|
166
|
-
readonly $: <T = unknown>(fn: () => T) => T;
|
|
167
156
|
/**
|
|
168
157
|
* The `effect` method is used to create a side effect.
|
|
169
158
|
* **The effect function is only called on client side.**
|
|
170
159
|
*/
|
|
171
160
|
readonly effect: (fn: () => void | (() => void)) => void;
|
|
172
|
-
} & Omit<Signals, "app" | "context" | "request" | "
|
|
161
|
+
} & Omit<Signals, "app" | "context" | "request" | "computed" | "effect">;
|
|
173
162
|
}
|
package/types/render.d.ts
CHANGED
|
@@ -11,7 +11,7 @@ type HtmxExts = {
|
|
|
11
11
|
| boolean;
|
|
12
12
|
};
|
|
13
13
|
|
|
14
|
-
export type
|
|
14
|
+
export type FCModule = FC<any> | Promise<{ default: FC<any> }>;
|
|
15
15
|
|
|
16
16
|
/**
|
|
17
17
|
* Render options for the `render` function.
|
|
@@ -28,11 +28,11 @@ export interface RenderOptions extends Partial<HtmxExts> {
|
|
|
28
28
|
/**
|
|
29
29
|
* Components to be rendered by the `<lazy>` element.
|
|
30
30
|
*/
|
|
31
|
-
components?: Record<string,
|
|
31
|
+
components?: Record<string, FCModule>;
|
|
32
32
|
/**
|
|
33
33
|
* Routes to be used by the `<router>` element.
|
|
34
34
|
*/
|
|
35
|
-
routes?: Record<string,
|
|
35
|
+
routes?: Record<string, FCModule>;
|
|
36
36
|
/**
|
|
37
37
|
* Current `Request` object to be passed to components.
|
|
38
38
|
*/
|