@knighted/jsx 1.7.1 → 1.7.3

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 CHANGED
@@ -4,13 +4,13 @@
4
4
  [![codecov](https://codecov.io/gh/knightedcodemonkey/jsx/graph/badge.svg?token=tjxuFwcwkr)](https://codecov.io/gh/knightedcodemonkey/jsx)
5
5
  [![NPM version](https://img.shields.io/npm/v/@knighted/jsx.svg)](https://www.npmjs.com/package/@knighted/jsx)
6
6
 
7
- A runtime JSX template tag backed by the [`oxc-parser`](https://github.com/oxc-project/oxc) WebAssembly build. Use real JSX syntax directly inside template literals and turn the result into live DOM nodes (or values returned from your own components) without running a bundler. One syntax works everywhere—browser scripts, SSR utilities, and bundler pipelines—no separate transpilation step required.
7
+ A runtime JSX template tag backed by the [`oxc-parser`](https://github.com/oxc-project/oxc) WebAssembly build. Use real JSX syntax directly inside template literals and turn the result into live DOM nodes (or values returned from your own components) without running a bundler. Prefer a build step? The loader can precompile templates so your runtime ships without loading the WASM parser. One syntax works everywhere—browser scripts, SSR utilities, and bundler pipelines—no separate transpilation step required.
8
8
 
9
9
  ## Key features
10
10
 
11
11
  - **Parse true JSX with no build step** – template literals go through `oxc-parser`, so fragments, spreads, and SVG namespaces all work as expected.
12
12
  - **DOM + React runtimes** – choose `jsx` for DOM nodes or `reactJsx` for React elements, and mix them freely (even on the server).
13
- - **Loader + SSR support** – ship tagged templates through Webpack/Rspack, Next.js, or plain Node by using the loader and the `@knighted/jsx/node` entry.
13
+ - **Loader + SSR support** – ship tagged templates through Webpack/Rspack, Next.js, or plain Node by using the loader and the `@knighted/jsx/node` entry (loader builds remove the WASM requirement at runtime).
14
14
 
15
15
  ## Quick links
16
16
 
@@ -96,6 +96,8 @@ createRoot(document.getElementById('root')!).render(reactJsx`<${App} />`)
96
96
 
97
97
  The React runtime shares the same template semantics as `jsx`, except it returns React elements (via `React.createElement`) so you can embed other React components with `<${MyComponent} />` and use hooks/state as usual. The helper lives in a separate subpath so DOM-only consumers never pay the React dependency cost.
98
98
 
99
+ Intrinsic props, events, and refs follow React’s JSX intrinsic element typings (React 18/19), and helper types like `ReactJsxIntrinsicElements`, `ReactJsxRef`, and `ReactJsxDomAttributes` are exported from `@knighted/jsx/react` when you need annotations.
100
+
99
101
  ### DOM-specific props
100
102
 
101
103
  - `style` accepts either a string or an object. Object values handle CSS custom properties (`--token`) automatically.
@@ -143,7 +145,7 @@ document.body.append(view)
143
145
 
144
146
  ## Loader integration
145
147
 
146
- Use the published loader entry (`@knighted/jsx/loader`) when you want your bundler to rewrite tagged template literals at build time. The loader finds every ` jsx`` ` (and, by default, ` reactJsx`` ` ) invocation, rebuilds the template with real JSX semantics, and hands back transformed source that can run in any environment.
148
+ Use the published loader entry (`@knighted/jsx/loader`) when you want your bundler to rewrite tagged template literals at build time. The loader finds every ` jsx`` ` (and, by default, ` reactJsx`` ` ) invocation, rebuilds the template with real JSX semantics, and hands back transformed source that can run in any environment without loading the WASM parser at runtime.
147
149
 
148
150
  ```js
149
151
  // rspack.config.js / webpack.config.js
@@ -1,2 +1,2 @@
1
1
  export { reactJsx } from './react-jsx.cjs';
2
- export type { ReactJsxComponent } from './react-jsx.cjs';
2
+ export type { ReactJsxComponent, ReactJsxDomAttributes, ReactJsxEventHandler, ReactJsxIntrinsicElement, ReactJsxIntrinsicElements, ReactJsxRef, ReactJsxRenderable, } from './react-jsx.cjs';
@@ -1,5 +1,9 @@
1
- import { type ComponentType, type ReactElement, type ReactNode } from 'react';
2
- export type ReactJsxComponent<Props = Record<string, unknown>> = ComponentType<Props & {
3
- children?: ReactNode;
4
- }>;
1
+ import { type ComponentType, type DOMAttributes, type EventHandler, type JSX as ReactJSX, type PropsWithChildren, type ReactElement, type ReactNode, type Ref, type SyntheticEvent } from 'react';
2
+ export type ReactJsxComponent<Props = Record<string, unknown>> = ComponentType<PropsWithChildren<Props>>;
3
+ export type ReactJsxRenderable = ReactNode;
4
+ export type ReactJsxRef<T> = Ref<T>;
5
+ export type ReactJsxEventHandler<E extends SyntheticEvent> = EventHandler<E>;
6
+ export type ReactJsxDomAttributes<T = unknown> = DOMAttributes<T>;
7
+ export type ReactJsxIntrinsicElements = ReactJSX.IntrinsicElements;
8
+ export type ReactJsxIntrinsicElement<Tag extends keyof ReactJsxIntrinsicElements> = ReactJsxIntrinsicElements[Tag];
5
9
  export declare const reactJsx: (templates: TemplateStringsArray, ...values: unknown[]) => ReactElement;
@@ -1,7 +1,7 @@
1
- import {parseSync}from'oxc-parser';import {createElement,Fragment}from'react';var w=e=>{let r=e.replace(/\r/g,"").replace(/\n\s+/g," "),n=e.match(/^\s*/)?.[0]??"",t=e.match(/\s*$/)?.[0]??"",o=/\n/.test(n),s=/\n/.test(t),a=r;return o&&(a=a.replace(/^\s+/,"")),s&&(a=a.replace(/\s+$/,"")),a.length===0||a.trim().length===0?null:a};var O="oxc-parser",j=e=>{let r=e.raw??e,n=r[0]??"",t=[];for(let o=0;o<r.length-1;o++){let s="${expr#"+o+"}",a=n.length;n+=s;let p=n.length;t.push({index:o,templateStart:a,templateEnd:p,label:s}),n+=r[o+1]??"";}return {source:n,spans:t}},L=(e,r)=>{let n=new Map;return r.forEach(t=>{n.set(t.index,t);}),e.expressionRanges.map(t=>{let o=n.get(t.index);if(!o)return null;let s=Math.max(0,t.sourceEnd-t.sourceStart),a=Math.max(0,o.templateEnd-o.templateStart);return {sourceStart:t.sourceStart,sourceEnd:t.sourceEnd,templateStart:o.templateStart,templateEnd:o.templateEnd,delta:a-s}}).filter(t=>!!t).sort((t,o)=>t.sourceStart-o.sourceStart)},D=(e,r,n)=>{if(!Number.isFinite(e)||e<=0)return 0;let t=0;for(let s of r){if(e<s.sourceStart)break;if(e<s.sourceEnd){let a=Math.max(0,e-s.sourceStart),p=Math.max(0,s.templateEnd-s.templateStart);if(p===0)return s.templateStart;let i=Math.min(a,Math.max(0,p-1));return s.templateStart+i}t+=s.delta;}let o=e+t;return o<=0?0:o>=n?n:o},R=(e,r)=>{let n=Math.max(0,Math.min(r,e.length)),t=1,o=1;for(let s=0;s<n;s++){if(e.charCodeAt(s)===10){t++,o=1;continue}o++;}return {line:t,column:o}},B=e=>{let r=[],n=0;return e.forEach((t,o)=>{r.push(n),n+=t.length,o<e.length-1&&(n+=1);}),r},z=(e,r,n,t,o,s,a)=>{let p=n+r.length,i=Math.max(t,n),m=Math.min(o,p);if(m>i){let c=Math.max(0,i-n),l=Math.max(1,m-i);return " ".repeat(c)+"^".repeat(l)}if(r.length===0&&e>=s&&e<=a)return "^";if(e===s){let c=Math.max(0,t-n);return " ".repeat(Math.min(c,r.length))+"^"}return ""},v=(e,r,n,t,o)=>{if(!e.length)return "";let s=e.split(`
2
- `),a=B(s),p=Math.max(1,t-1),i=Math.min(s.length,o+1),m=String(i).length,c=[];for(let l=p;l<=i;l++){let g=s[l-1]??"",u=String(l).padStart(m," ");c.push(`${u} | ${g}`);let d=z(l,g,a[l-1]??0,r,n,t,o);d&&c.push(`${" ".repeat(m)} | ${d}`);}return c.join(`
3
- `)},b=(e,r,n,t,o)=>{let s=O,a=`[${s}] ${t.message}`,p=t.labels?.[0];if(!p)return a;let{source:i,spans:m}=j(r),c=L(n,m),l=h=>D(typeof h=="number"?h:0,c,i.length),g=l(p.start),u=l(p.end);u<=g&&(u=Math.min(i.length,g+1));let d=R(i,g),f=R(i,Math.max(g,u-1)),E=v(i,g,u,d.line,f.line),x=`[${s}] ${t.message}`;return x+=`
1
+ import {parseSync}from'oxc-parser';import {createElement,Fragment}from'react';var R=e=>{let r=e.replace(/\r/g,"").replace(/\n\s+/g," "),n=e.match(/^\s*/)?.[0]??"",t=e.match(/\s*$/)?.[0]??"",o=/\n/.test(n),s=/\n/.test(t),a=r;return o&&(a=a.replace(/^\s+/,"")),s&&(a=a.replace(/\s+$/,"")),a.length===0||a.trim().length===0?null:a};var _="oxc-parser",j=e=>{let r=e.raw??e,n=r[0]??"",t=[];for(let o=0;o<r.length-1;o++){let s="${expr#"+o+"}",a=n.length;n+=s;let p=n.length;t.push({index:o,templateStart:a,templateEnd:p,label:s}),n+=r[o+1]??"";}return {source:n,spans:t}},D=(e,r)=>{let n=new Map;return r.forEach(t=>{n.set(t.index,t);}),e.expressionRanges.map(t=>{let o=n.get(t.index);if(!o)return null;let s=Math.max(0,t.sourceEnd-t.sourceStart),a=Math.max(0,o.templateEnd-o.templateStart);return {sourceStart:t.sourceStart,sourceEnd:t.sourceEnd,templateStart:o.templateStart,templateEnd:o.templateEnd,delta:a-s}}).filter(t=>!!t).sort((t,o)=>t.sourceStart-o.sourceStart)},L=(e,r,n)=>{if(!Number.isFinite(e)||e<=0)return 0;let t=0;for(let s of r){if(e<s.sourceStart)break;if(e<s.sourceEnd){let a=Math.max(0,e-s.sourceStart),p=Math.max(0,s.templateEnd-s.templateStart);if(p===0)return s.templateStart;let i=Math.min(a,Math.max(0,p-1));return s.templateStart+i}t+=s.delta;}let o=e+t;return o<=0?0:o>=n?n:o},w=(e,r)=>{let n=Math.max(0,Math.min(r,e.length)),t=1,o=1;for(let s=0;s<n;s++){if(e.charCodeAt(s)===10){t++,o=1;continue}o++;}return {line:t,column:o}},B=e=>{let r=[],n=0;return e.forEach((t,o)=>{r.push(n),n+=t.length,o<e.length-1&&(n+=1);}),r},v=(e,r,n,t,o,s,a)=>{let p=n+r.length,i=Math.max(t,n),c=Math.min(o,p);if(c>i){let m=Math.max(0,i-n),l=Math.max(1,c-i);return " ".repeat(m)+"^".repeat(l)}if(r.length===0&&e>=s&&e<=a)return "^";if(e===s){let m=Math.max(0,t-n);return " ".repeat(Math.min(m,r.length))+"^"}return ""},z=(e,r,n,t,o)=>{if(!e.length)return "";let s=e.split(`
2
+ `),a=B(s),p=Math.max(1,t-1),i=Math.min(s.length,o+1),c=String(i).length,m=[];for(let l=p;l<=i;l++){let g=s[l-1]??"",u=String(l).padStart(c," ");m.push(`${u} | ${g}`);let d=v(l,g,a[l-1]??0,r,n,t,o);d&&m.push(`${" ".repeat(c)} | ${d}`);}return m.join(`
3
+ `)},J=(e,r,n,t,o)=>{let s=_,a=`[${s}] ${t.message}`,p=t.labels?.[0];if(!p)return a;let{source:i,spans:c}=j(r),m=D(n,c),l=y=>L(typeof y=="number"?y:0,m,i.length),g=l(p.start),u=l(p.end);u<=g&&(u=Math.min(i.length,g+1));let d=w(i,g),f=w(i,Math.max(g,u-1)),h=z(i,g,u,d.line,f.line),x=`[${s}] ${t.message}`;return x+=`
4
4
  --> ${e} template:${d.line}:${d.column}`,p.message&&(x+=`
5
- ${p.message}`),E&&(x+=`
6
- ${E}`),t.helpMessage&&(x+=`
7
- ${t.helpMessage}`),x};var W=/<\s*$/,U=/<\/\s*$/,$="__KX_EXPR__",X=new RegExp(`${$}\\d+_\\d+__`,"g"),V=0;var A={lang:"jsx",sourceType:"module",range:true,preserveParens:true},k=e=>{for(let r of e.body)if(r.type==="ExpressionStatement"){let n=r.expression;if(n.type==="JSXElement"||n.type==="JSXFragment")return n}throw new Error("The jsx template must contain a single JSX element or fragment.")},S=e=>{switch(e.type){case "JSXIdentifier":return e.name;case "JSXNamespacedName":return `${e.namespace.name}:${e.name.name}`;case "JSXMemberExpression":return `${S(e.object)}.${e.property.name}`;default:return ""}},C=(e,r)=>{if(!e||typeof e!="object")return;let n=e;typeof n.type=="string"&&(r(n),Object.values(n).forEach(t=>{if(t){if(Array.isArray(t)){t.forEach(o=>C(o,r));return}typeof t=="object"&&C(t,r);}}));},M=(e,r)=>{let n=w(e);if(!n)return [];let t=[];X.lastIndex=0;let o=0,s;for(;s=X.exec(n);){let p=s.index,i=n.slice(o,p);i&&t.push(i);let m=s[0];r.has(m)?t.push(r.get(m)):t.push(m),o=p+m.length;}let a=n.slice(o);return a&&t.push(a),t},Z=(e,r)=>{let n=new Set;return C(e,t=>{t.type==="Identifier"&&r.placeholders.has(t.name)&&n.add(t.name);}),Array.from(n)},N=(e,r,n)=>{if(e.type==="JSXElement"||e.type==="JSXFragment")return n(e);if(!("range"in e)||!e.range)throw new Error("Unable to evaluate expression: missing source range information.");let[t,o]=e.range,s=r.source.slice(t,o),a=Z(e,r);try{let p=new Function(...a,`"use strict"; return (${s});`),i=a.map(m=>r.placeholders.get(m));return p(...i)}catch(p){throw new Error(`Failed to evaluate expression ${s}: ${p.message}`)}},G=e=>{let r=e.replace(/[^a-zA-Z0-9_$]/g,"");return r?/[A-Za-z_$]/.test(r[0])?r:`Component${r}`:"Component"},H=(e,r,n)=>{let t=n.get(e);if(t)return t;let o=e.displayName||e.name||`Component${r.length}`,s=G(o??""),a=s,p=1;for(;r.some(m=>m.name===a);)a=`${s}${p++}`;let i={name:a,value:e};return r.push(i),n.set(e,i),i},F=(e,r)=>{let n=e.raw??e,t=new Map,o=[],s=new Map,a=n[0]??"",p=V++,i=0,m=[];for(let c=0;c<r.length;c++){let l=n[c]??"",g=n[c+1]??"",u=r[c],d=W.test(l)||U.test(l),f;if(d&&typeof u=="function")f=H(u,o,s).name;else if(d&&typeof u=="string")f=u;else {let h=`${$}${p}_${i++}__`;t.set(h,u),f=h;}let E=a.length;a+=f;let x=a.length;m.push({index:c,sourceStart:E,sourceEnd:x}),a+=g;}return {source:a,placeholders:t,bindings:o,diagnostics:{expressionRanges:m}}};var Q=e=>!e||typeof e=="string"?false:typeof e[Symbol.iterator]=="function",Y=e=>!e||typeof e!="object"&&typeof e!="function"?false:typeof e.then=="function",y=(e,r)=>{if(r!=null&&typeof r!="boolean"){if(Y(r))throw new Error("Async values are not supported inside reactJsx template results.");if(Array.isArray(r)){r.forEach(n=>y(e,n));return}if(Q(r)){for(let n of r)y(e,n);return}e.push(r);}},T=(e,r)=>N(e,r,n=>J(n,r)),ee=(e,r)=>{let n={};return e.forEach(t=>{if(t.type==="JSXSpreadAttribute"){let s=T(t.argument,r);s&&typeof s=="object"&&!Array.isArray(s)&&Object.assign(n,s);return}let o=S(t.name);if(!t.value){n[o]=true;return}if(t.value.type==="Literal"){n[o]=t.value.value;return}if(t.value.type==="JSXExpressionContainer"){if(t.value.expression.type==="JSXEmptyExpression")return;n[o]=T(t.value.expression,r);}}),n},_=(e,r)=>{let n=[];return e.forEach(t=>{switch(t.type){case "JSXText":{M(t.value,r.placeholders).forEach(s=>y(n,s));break}case "JSXExpressionContainer":{if(t.expression.type==="JSXEmptyExpression")break;y(n,T(t.expression,r));break}case "JSXSpreadChild":{let o=T(t.expression,r);o!=null&&y(n,o);break}case "JSXElement":case "JSXFragment":{n.push(J(t,r));break}}}),n},P=(e,r,n)=>createElement(e,r,...n),te=(e,r)=>{let n=e.openingElement,t=S(n.name),o=r.components.get(t),s=ee(n.attributes,r),a=_(e.children,r);if(o)return P(o,s,a);if(/[A-Z]/.test(t[0]??""))throw new Error(`Unknown component "${t}". Did you interpolate it with the template literal?`);return P(t,s,a)},J=(e,r)=>{if(e.type==="JSXFragment"){let n=_(e.children,r);return createElement(Fragment,null,...n)}return te(e,r)},ne=(e,...r)=>{let n=F(e,r),t=parseSync("inline.jsx",n.source,A);if(t.errors.length>0)throw new Error(b("reactJsx",e,n.diagnostics,t.errors[0]));let o=k(t.program),s={source:n.source,placeholders:n.placeholders,components:new Map(n.bindings.map(a=>[a.name,a.value]))};return J(o,s)};export{ne as reactJsx};
5
+ ${p.message}`),h&&(x+=`
6
+ ${h}`),t.helpMessage&&(x+=`
7
+ ${t.helpMessage}`),x};var W=/<\s*$/,H=/<\/\s*$/,A="__KX_EXPR__",X=new RegExp(`${A}\\d+_\\d+__`,"g"),U=0;var k={lang:"jsx",sourceType:"module",range:true,preserveParens:true},$=e=>{for(let r of e.body)if(r.type==="ExpressionStatement"){let n=r.expression;if(n.type==="JSXElement"||n.type==="JSXFragment")return n}throw new Error("The jsx template must contain a single JSX element or fragment.")},S=e=>{switch(e.type){case "JSXIdentifier":return e.name;case "JSXNamespacedName":return `${e.namespace.name}:${e.name.name}`;case "JSXMemberExpression":return `${S(e.object)}.${e.property.name}`;default:return ""}},b=(e,r)=>{if(!e||typeof e!="object")return;let n=e;typeof n.type=="string"&&(r(n),Object.values(n).forEach(t=>{if(t){if(Array.isArray(t)){t.forEach(o=>b(o,r));return}typeof t=="object"&&b(t,r);}}));},M=(e,r)=>{let n=R(e);if(!n)return [];let t=[];X.lastIndex=0;let o=0,s;for(;s=X.exec(n);){let p=s.index,i=n.slice(o,p);i&&t.push(i);let c=s[0];r.has(c)?t.push(r.get(c)):t.push(c),o=p+c.length;}let a=n.slice(o);return a&&t.push(a),t},V=(e,r)=>{let n=new Set;return b(e,t=>{t.type==="Identifier"&&r.placeholders.has(t.name)&&n.add(t.name);}),Array.from(n)},N=(e,r,n)=>{if(e.type==="JSXElement"||e.type==="JSXFragment")return n(e);if(!("range"in e)||!e.range)throw new Error("Unable to evaluate expression: missing source range information.");let[t,o]=e.range,s=r.source.slice(t,o),a=V(e,r);try{let p=new Function(...a,`"use strict"; return (${s});`),i=a.map(c=>r.placeholders.get(c));return p(...i)}catch(p){throw new Error(`Failed to evaluate expression ${s}: ${p.message}`)}},Z=e=>{let r=e.replace(/[^a-zA-Z0-9_$]/g,"");return r?/[A-Za-z_$]/.test(r[0])?r:`Component${r}`:"Component"},G=(e,r,n)=>{let t=n.get(e);if(t)return t;let o=e.displayName||e.name||`Component${r.length}`,s=Z(o??""),a=s,p=1;for(;r.some(c=>c.name===a);)a=`${s}${p++}`;let i={name:a,value:e};return r.push(i),n.set(e,i),i},F=(e,r)=>{let n=e.raw??e,t=new Map,o=[],s=new Map,a=n[0]??"",p=U++,i=0,c=[];for(let m=0;m<r.length;m++){let l=n[m]??"",g=n[m+1]??"",u=r[m],d=W.test(l)||H.test(l),f;if(d&&typeof u=="function")f=G(u,o,s).name;else if(d&&typeof u=="string")f=u;else {let y=`${A}${p}_${i++}__`;t.set(y,u),f=y;}let h=a.length;a+=f;let x=a.length;c.push({index:m,sourceStart:h,sourceEnd:x}),a+=g;}return {source:a,placeholders:t,bindings:o,diagnostics:{expressionRanges:c}}};var Q=e=>!e||typeof e=="string"?false:typeof e[Symbol.iterator]=="function",Y=e=>!e||typeof e!="object"&&typeof e!="function"?false:typeof e.then=="function",E=(e,r)=>{if(r!=null&&typeof r!="boolean"){if(Y(r))throw new Error("Async values are not supported inside reactJsx template results.");if(Array.isArray(r)){r.forEach(n=>E(e,n));return}if(Q(r)){for(let n of r)E(e,n);return}e.push(r);}},T=(e,r)=>N(e,r,n=>C(n,r)),ee=(e,r)=>{let n={};return e.forEach(t=>{if(t.type==="JSXSpreadAttribute"){let s=T(t.argument,r);s&&typeof s=="object"&&!Array.isArray(s)&&Object.assign(n,s);return}let o=S(t.name);if(!t.value){n[o]=true;return}if(t.value.type==="Literal"){n[o]=t.value.value;return}if(t.value.type==="JSXExpressionContainer"){if(t.value.expression.type==="JSXEmptyExpression")return;n[o]=T(t.value.expression,r);}}),n},O=(e,r)=>{let n=[];return e.forEach(t=>{switch(t.type){case "JSXText":{M(t.value,r.placeholders).forEach(s=>E(n,s));break}case "JSXExpressionContainer":{if(t.expression.type==="JSXEmptyExpression")break;E(n,T(t.expression,r));break}case "JSXSpreadChild":{let o=T(t.expression,r);o!=null&&E(n,o);break}case "JSXElement":case "JSXFragment":{n.push(C(t,r));break}}}),n},I=(e,r,n)=>createElement(e,r,...n),te=(e,r)=>{let n=e.openingElement,t=S(n.name),o=r.components.get(t),s=ee(n.attributes,r),a=O(e.children,r);if(o)return I(o,s,a);if(/[A-Z]/.test(t[0]??""))throw new Error(`Unknown component "${t}". Did you interpolate it with the template literal?`);return I(t,s,a)},C=(e,r)=>{if(e.type==="JSXFragment"){let n=O(e.children,r);return createElement(Fragment,null,...n)}return te(e,r)},ne=(e,...r)=>{let n=F(e,r),t=parseSync("inline.jsx",n.source,k);if(t.errors.length>0)throw new Error(J("reactJsx",e,n.diagnostics,t.errors[0]));let o=$(t.program),s={source:n.source,placeholders:n.placeholders,components:new Map(n.bindings.map(a=>[a.name,a.value]))};return C(o,s)};export{ne as reactJsx};
@@ -1,7 +1,7 @@
1
- import {parseSync}from'oxc-parser';import {createElement,Fragment}from'react';var w=e=>{let r=e.replace(/\r/g,"").replace(/\n\s+/g," "),n=e.match(/^\s*/)?.[0]??"",t=e.match(/\s*$/)?.[0]??"",o=/\n/.test(n),s=/\n/.test(t),a=r;return o&&(a=a.replace(/^\s+/,"")),s&&(a=a.replace(/\s+$/,"")),a.length===0||a.trim().length===0?null:a};var O="oxc-parser",j=e=>{let r=e.raw??e,n=r[0]??"",t=[];for(let o=0;o<r.length-1;o++){let s="${expr#"+o+"}",a=n.length;n+=s;let p=n.length;t.push({index:o,templateStart:a,templateEnd:p,label:s}),n+=r[o+1]??"";}return {source:n,spans:t}},L=(e,r)=>{let n=new Map;return r.forEach(t=>{n.set(t.index,t);}),e.expressionRanges.map(t=>{let o=n.get(t.index);if(!o)return null;let s=Math.max(0,t.sourceEnd-t.sourceStart),a=Math.max(0,o.templateEnd-o.templateStart);return {sourceStart:t.sourceStart,sourceEnd:t.sourceEnd,templateStart:o.templateStart,templateEnd:o.templateEnd,delta:a-s}}).filter(t=>!!t).sort((t,o)=>t.sourceStart-o.sourceStart)},D=(e,r,n)=>{if(!Number.isFinite(e)||e<=0)return 0;let t=0;for(let s of r){if(e<s.sourceStart)break;if(e<s.sourceEnd){let a=Math.max(0,e-s.sourceStart),p=Math.max(0,s.templateEnd-s.templateStart);if(p===0)return s.templateStart;let i=Math.min(a,Math.max(0,p-1));return s.templateStart+i}t+=s.delta;}let o=e+t;return o<=0?0:o>=n?n:o},R=(e,r)=>{let n=Math.max(0,Math.min(r,e.length)),t=1,o=1;for(let s=0;s<n;s++){if(e.charCodeAt(s)===10){t++,o=1;continue}o++;}return {line:t,column:o}},B=e=>{let r=[],n=0;return e.forEach((t,o)=>{r.push(n),n+=t.length,o<e.length-1&&(n+=1);}),r},z=(e,r,n,t,o,s,a)=>{let p=n+r.length,i=Math.max(t,n),m=Math.min(o,p);if(m>i){let c=Math.max(0,i-n),l=Math.max(1,m-i);return " ".repeat(c)+"^".repeat(l)}if(r.length===0&&e>=s&&e<=a)return "^";if(e===s){let c=Math.max(0,t-n);return " ".repeat(Math.min(c,r.length))+"^"}return ""},v=(e,r,n,t,o)=>{if(!e.length)return "";let s=e.split(`
2
- `),a=B(s),p=Math.max(1,t-1),i=Math.min(s.length,o+1),m=String(i).length,c=[];for(let l=p;l<=i;l++){let g=s[l-1]??"",u=String(l).padStart(m," ");c.push(`${u} | ${g}`);let d=z(l,g,a[l-1]??0,r,n,t,o);d&&c.push(`${" ".repeat(m)} | ${d}`);}return c.join(`
3
- `)},b=(e,r,n,t,o)=>{let s=O,a=`[${s}] ${t.message}`,p=t.labels?.[0];if(!p)return a;let{source:i,spans:m}=j(r),c=L(n,m),l=h=>D(typeof h=="number"?h:0,c,i.length),g=l(p.start),u=l(p.end);u<=g&&(u=Math.min(i.length,g+1));let d=R(i,g),f=R(i,Math.max(g,u-1)),E=v(i,g,u,d.line,f.line),x=`[${s}] ${t.message}`;return x+=`
1
+ import {parseSync}from'oxc-parser';import {createElement,Fragment}from'react';var R=e=>{let r=e.replace(/\r/g,"").replace(/\n\s+/g," "),n=e.match(/^\s*/)?.[0]??"",t=e.match(/\s*$/)?.[0]??"",o=/\n/.test(n),s=/\n/.test(t),a=r;return o&&(a=a.replace(/^\s+/,"")),s&&(a=a.replace(/\s+$/,"")),a.length===0||a.trim().length===0?null:a};var _="oxc-parser",D=e=>{let r=e.raw??e,n=r[0]??"",t=[];for(let o=0;o<r.length-1;o++){let s="${expr#"+o+"}",a=n.length;n+=s;let p=n.length;t.push({index:o,templateStart:a,templateEnd:p,label:s}),n+=r[o+1]??"";}return {source:n,spans:t}},j=(e,r)=>{let n=new Map;return r.forEach(t=>{n.set(t.index,t);}),e.expressionRanges.map(t=>{let o=n.get(t.index);if(!o)return null;let s=Math.max(0,t.sourceEnd-t.sourceStart),a=Math.max(0,o.templateEnd-o.templateStart);return {sourceStart:t.sourceStart,sourceEnd:t.sourceEnd,templateStart:o.templateStart,templateEnd:o.templateEnd,delta:a-s}}).filter(t=>!!t).sort((t,o)=>t.sourceStart-o.sourceStart)},L=(e,r,n)=>{if(!Number.isFinite(e)||e<=0)return 0;let t=0;for(let s of r){if(e<s.sourceStart)break;if(e<s.sourceEnd){let a=Math.max(0,e-s.sourceStart),p=Math.max(0,s.templateEnd-s.templateStart);if(p===0)return s.templateStart;let i=Math.min(a,Math.max(0,p-1));return s.templateStart+i}t+=s.delta;}let o=e+t;return o<=0?0:o>=n?n:o},w=(e,r)=>{let n=Math.max(0,Math.min(r,e.length)),t=1,o=1;for(let s=0;s<n;s++){if(e.charCodeAt(s)===10){t++,o=1;continue}o++;}return {line:t,column:o}},v=e=>{let r=[],n=0;return e.forEach((t,o)=>{r.push(n),n+=t.length,o<e.length-1&&(n+=1);}),r},B=(e,r,n,t,o,s,a)=>{let p=n+r.length,i=Math.max(t,n),c=Math.min(o,p);if(c>i){let m=Math.max(0,i-n),l=Math.max(1,c-i);return " ".repeat(m)+"^".repeat(l)}if(r.length===0&&e>=s&&e<=a)return "^";if(e===s){let m=Math.max(0,t-n);return " ".repeat(Math.min(m,r.length))+"^"}return ""},z=(e,r,n,t,o)=>{if(!e.length)return "";let s=e.split(`
2
+ `),a=v(s),p=Math.max(1,t-1),i=Math.min(s.length,o+1),c=String(i).length,m=[];for(let l=p;l<=i;l++){let g=s[l-1]??"",u=String(l).padStart(c," ");m.push(`${u} | ${g}`);let d=B(l,g,a[l-1]??0,r,n,t,o);d&&m.push(`${" ".repeat(c)} | ${d}`);}return m.join(`
3
+ `)},J=(e,r,n,t,o)=>{let s=_,a=`[${s}] ${t.message}`,p=t.labels?.[0];if(!p)return a;let{source:i,spans:c}=D(r),m=j(n,c),l=y=>L(typeof y=="number"?y:0,m,i.length),g=l(p.start),u=l(p.end);u<=g&&(u=Math.min(i.length,g+1));let d=w(i,g),f=w(i,Math.max(g,u-1)),h=z(i,g,u,d.line,f.line),x=`[${s}] ${t.message}`;return x+=`
4
4
  --> ${e} template:${d.line}:${d.column}`,p.message&&(x+=`
5
- ${p.message}`),E&&(x+=`
6
- ${E}`),t.helpMessage&&(x+=`
7
- ${t.helpMessage}`),x};var W=/<\s*$/,U=/<\/\s*$/,$="__KX_EXPR__",X=new RegExp(`${$}\\d+_\\d+__`,"g"),V=0;var A={lang:"jsx",sourceType:"module",range:true,preserveParens:true},k=e=>{for(let r of e.body)if(r.type==="ExpressionStatement"){let n=r.expression;if(n.type==="JSXElement"||n.type==="JSXFragment")return n}throw new Error("The jsx template must contain a single JSX element or fragment.")},S=e=>{switch(e.type){case "JSXIdentifier":return e.name;case "JSXNamespacedName":return `${e.namespace.name}:${e.name.name}`;case "JSXMemberExpression":return `${S(e.object)}.${e.property.name}`;default:return ""}},C=(e,r)=>{if(!e||typeof e!="object")return;let n=e;typeof n.type=="string"&&(r(n),Object.values(n).forEach(t=>{if(t){if(Array.isArray(t)){t.forEach(o=>C(o,r));return}typeof t=="object"&&C(t,r);}}));},M=(e,r)=>{let n=w(e);if(!n)return [];let t=[];X.lastIndex=0;let o=0,s;for(;s=X.exec(n);){let p=s.index,i=n.slice(o,p);i&&t.push(i);let m=s[0];r.has(m)?t.push(r.get(m)):t.push(m),o=p+m.length;}let a=n.slice(o);return a&&t.push(a),t},Z=(e,r)=>{let n=new Set;return C(e,t=>{t.type==="Identifier"&&r.placeholders.has(t.name)&&n.add(t.name);}),Array.from(n)},N=(e,r,n)=>{if(e.type==="JSXElement"||e.type==="JSXFragment")return n(e);if(!("range"in e)||!e.range)throw new Error("Unable to evaluate expression: missing source range information.");let[t,o]=e.range,s=r.source.slice(t,o),a=Z(e,r);try{let p=new Function(...a,`"use strict"; return (${s});`),i=a.map(m=>r.placeholders.get(m));return p(...i)}catch(p){throw new Error(`Failed to evaluate expression ${s}: ${p.message}`)}},G=e=>{let r=e.replace(/[^a-zA-Z0-9_$]/g,"");return r?/[A-Za-z_$]/.test(r[0])?r:`Component${r}`:"Component"},H=(e,r,n)=>{let t=n.get(e);if(t)return t;let o=e.displayName||e.name||`Component${r.length}`,s=G(o??""),a=s,p=1;for(;r.some(m=>m.name===a);)a=`${s}${p++}`;let i={name:a,value:e};return r.push(i),n.set(e,i),i},F=(e,r)=>{let n=e.raw??e,t=new Map,o=[],s=new Map,a=n[0]??"",p=V++,i=0,m=[];for(let c=0;c<r.length;c++){let l=n[c]??"",g=n[c+1]??"",u=r[c],d=W.test(l)||U.test(l),f;if(d&&typeof u=="function")f=H(u,o,s).name;else if(d&&typeof u=="string")f=u;else {let h=`${$}${p}_${i++}__`;t.set(h,u),f=h;}let E=a.length;a+=f;let x=a.length;m.push({index:c,sourceStart:E,sourceEnd:x}),a+=g;}return {source:a,placeholders:t,bindings:o,diagnostics:{expressionRanges:m}}};var Q=e=>!e||typeof e=="string"?false:typeof e[Symbol.iterator]=="function",Y=e=>!e||typeof e!="object"&&typeof e!="function"?false:typeof e.then=="function",y=(e,r)=>{if(r!=null&&typeof r!="boolean"){if(Y(r))throw new Error("Async values are not supported inside reactJsx template results.");if(Array.isArray(r)){r.forEach(n=>y(e,n));return}if(Q(r)){for(let n of r)y(e,n);return}e.push(r);}},T=(e,r)=>N(e,r,n=>J(n,r)),ee=(e,r)=>{let n={};return e.forEach(t=>{if(t.type==="JSXSpreadAttribute"){let s=T(t.argument,r);s&&typeof s=="object"&&!Array.isArray(s)&&Object.assign(n,s);return}let o=S(t.name);if(!t.value){n[o]=true;return}if(t.value.type==="Literal"){n[o]=t.value.value;return}if(t.value.type==="JSXExpressionContainer"){if(t.value.expression.type==="JSXEmptyExpression")return;n[o]=T(t.value.expression,r);}}),n},_=(e,r)=>{let n=[];return e.forEach(t=>{switch(t.type){case "JSXText":{M(t.value,r.placeholders).forEach(s=>y(n,s));break}case "JSXExpressionContainer":{if(t.expression.type==="JSXEmptyExpression")break;y(n,T(t.expression,r));break}case "JSXSpreadChild":{let o=T(t.expression,r);o!=null&&y(n,o);break}case "JSXElement":case "JSXFragment":{n.push(J(t,r));break}}}),n},P=(e,r,n)=>createElement(e,r,...n),te=(e,r)=>{let n=e.openingElement,t=S(n.name),o=r.components.get(t),s=ee(n.attributes,r),a=_(e.children,r);if(o)return P(o,s,a);if(/[A-Z]/.test(t[0]??""))throw new Error(`Unknown component "${t}". Did you interpolate it with the template literal?`);return P(t,s,a)},J=(e,r)=>{if(e.type==="JSXFragment"){let n=_(e.children,r);return createElement(Fragment,null,...n)}return te(e,r)},ne=(e,...r)=>{let n=F(e,r),t=parseSync("inline.jsx",n.source,A);if(t.errors.length>0)throw new Error(b("reactJsx",e,n.diagnostics,t.errors[0]));let o=k(t.program),s={source:n.source,placeholders:n.placeholders,components:new Map(n.bindings.map(a=>[a.name,a.value]))};return J(o,s)};export{ne as reactJsx};
5
+ ${p.message}`),h&&(x+=`
6
+ ${h}`),t.helpMessage&&(x+=`
7
+ ${t.helpMessage}`),x};var W=/<\s*$/,H=/<\/\s*$/,A="__KX_EXPR__",X=new RegExp(`${A}\\d+_\\d+__`,"g"),U=0;var k={lang:"jsx",sourceType:"module",range:true,preserveParens:true},$=e=>{for(let r of e.body)if(r.type==="ExpressionStatement"){let n=r.expression;if(n.type==="JSXElement"||n.type==="JSXFragment")return n}throw new Error("The jsx template must contain a single JSX element or fragment.")},S=e=>{switch(e.type){case "JSXIdentifier":return e.name;case "JSXNamespacedName":return `${e.namespace.name}:${e.name.name}`;case "JSXMemberExpression":return `${S(e.object)}.${e.property.name}`;default:return ""}},b=(e,r)=>{if(!e||typeof e!="object")return;let n=e;typeof n.type=="string"&&(r(n),Object.values(n).forEach(t=>{if(t){if(Array.isArray(t)){t.forEach(o=>b(o,r));return}typeof t=="object"&&b(t,r);}}));},M=(e,r)=>{let n=R(e);if(!n)return [];let t=[];X.lastIndex=0;let o=0,s;for(;s=X.exec(n);){let p=s.index,i=n.slice(o,p);i&&t.push(i);let c=s[0];r.has(c)?t.push(r.get(c)):t.push(c),o=p+c.length;}let a=n.slice(o);return a&&t.push(a),t},V=(e,r)=>{let n=new Set;return b(e,t=>{t.type==="Identifier"&&r.placeholders.has(t.name)&&n.add(t.name);}),Array.from(n)},N=(e,r,n)=>{if(e.type==="JSXElement"||e.type==="JSXFragment")return n(e);if(!("range"in e)||!e.range)throw new Error("Unable to evaluate expression: missing source range information.");let[t,o]=e.range,s=r.source.slice(t,o),a=V(e,r);try{let p=new Function(...a,`"use strict"; return (${s});`),i=a.map(c=>r.placeholders.get(c));return p(...i)}catch(p){throw new Error(`Failed to evaluate expression ${s}: ${p.message}`)}},Z=e=>{let r=e.replace(/[^a-zA-Z0-9_$]/g,"");return r?/[A-Za-z_$]/.test(r[0])?r:`Component${r}`:"Component"},G=(e,r,n)=>{let t=n.get(e);if(t)return t;let o=e.displayName||e.name||`Component${r.length}`,s=Z(o??""),a=s,p=1;for(;r.some(c=>c.name===a);)a=`${s}${p++}`;let i={name:a,value:e};return r.push(i),n.set(e,i),i},I=(e,r)=>{let n=e.raw??e,t=new Map,o=[],s=new Map,a=n[0]??"",p=U++,i=0,c=[];for(let m=0;m<r.length;m++){let l=n[m]??"",g=n[m+1]??"",u=r[m],d=W.test(l)||H.test(l),f;if(d&&typeof u=="function")f=G(u,o,s).name;else if(d&&typeof u=="string")f=u;else {let y=`${A}${p}_${i++}__`;t.set(y,u),f=y;}let h=a.length;a+=f;let x=a.length;c.push({index:m,sourceStart:h,sourceEnd:x}),a+=g;}return {source:a,placeholders:t,bindings:o,diagnostics:{expressionRanges:c}}};var Q=e=>!e||typeof e=="string"?false:typeof e[Symbol.iterator]=="function",Y=e=>!e||typeof e!="object"&&typeof e!="function"?false:typeof e.then=="function",E=(e,r)=>{if(r!=null&&typeof r!="boolean"){if(Y(r))throw new Error("Async values are not supported inside reactJsx template results.");if(Array.isArray(r)){r.forEach(n=>E(e,n));return}if(Q(r)){for(let n of r)E(e,n);return}e.push(r);}},T=(e,r)=>N(e,r,n=>C(n,r)),ee=(e,r)=>{let n={};return e.forEach(t=>{if(t.type==="JSXSpreadAttribute"){let s=T(t.argument,r);s&&typeof s=="object"&&!Array.isArray(s)&&Object.assign(n,s);return}let o=S(t.name);if(!t.value){n[o]=true;return}if(t.value.type==="Literal"){n[o]=t.value.value;return}if(t.value.type==="JSXExpressionContainer"){if(t.value.expression.type==="JSXEmptyExpression")return;n[o]=T(t.value.expression,r);}}),n},O=(e,r)=>{let n=[];return e.forEach(t=>{switch(t.type){case "JSXText":{M(t.value,r.placeholders).forEach(s=>E(n,s));break}case "JSXExpressionContainer":{if(t.expression.type==="JSXEmptyExpression")break;E(n,T(t.expression,r));break}case "JSXSpreadChild":{let o=T(t.expression,r);o!=null&&E(n,o);break}case "JSXElement":case "JSXFragment":{n.push(C(t,r));break}}}),n},F=(e,r,n)=>createElement(e,r,...n),te=(e,r)=>{let n=e.openingElement,t=S(n.name),o=r.components.get(t),s=ee(n.attributes,r),a=O(e.children,r);if(o)return F(o,s,a);if(/[A-Z]/.test(t[0]??""))throw new Error(`Unknown component "${t}". Did you interpolate it with the template literal?`);return F(t,s,a)},C=(e,r)=>{if(e.type==="JSXFragment"){let n=O(e.children,r);return createElement(Fragment,null,...n)}return te(e,r)},ne=(e,...r)=>{let n=I(e,r),t=parseSync("inline.jsx",n.source,k);if(t.errors.length>0)throw new Error(J("reactJsx",e,n.diagnostics,t.errors[0]));let o=$(t.program),s={source:n.source,placeholders:n.placeholders,components:new Map(n.bindings.map(a=>[a.name,a.value]))};return C(o,s)};export{ne as reactJsx};
@@ -1,2 +1,2 @@
1
1
  export { reactJsx } from './react-jsx.js';
2
- export type { ReactJsxComponent } from './react-jsx.js';
2
+ export type { ReactJsxComponent, ReactJsxDomAttributes, ReactJsxEventHandler, ReactJsxIntrinsicElement, ReactJsxIntrinsicElements, ReactJsxRef, ReactJsxRenderable, } from './react-jsx.js';
@@ -1,5 +1,9 @@
1
- import { type ComponentType, type ReactElement, type ReactNode } from 'react';
2
- export type ReactJsxComponent<Props = Record<string, unknown>> = ComponentType<Props & {
3
- children?: ReactNode;
4
- }>;
1
+ import { type ComponentType, type DOMAttributes, type EventHandler, type JSX as ReactJSX, type PropsWithChildren, type ReactElement, type ReactNode, type Ref, type SyntheticEvent } from 'react';
2
+ export type ReactJsxComponent<Props = Record<string, unknown>> = ComponentType<PropsWithChildren<Props>>;
3
+ export type ReactJsxRenderable = ReactNode;
4
+ export type ReactJsxRef<T> = Ref<T>;
5
+ export type ReactJsxEventHandler<E extends SyntheticEvent> = EventHandler<E>;
6
+ export type ReactJsxDomAttributes<T = unknown> = DOMAttributes<T>;
7
+ export type ReactJsxIntrinsicElements = ReactJSX.IntrinsicElements;
8
+ export type ReactJsxIntrinsicElement<Tag extends keyof ReactJsxIntrinsicElements> = ReactJsxIntrinsicElements[Tag];
5
9
  export declare const reactJsx: (templates: TemplateStringsArray, ...values: unknown[]) => ReactElement;
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@knighted/jsx",
3
- "version": "1.7.1",
4
- "description": "Runtime JSX tagged template that renders DOM or React trees anywhere without a build step.",
3
+ "version": "1.7.3",
4
+ "description": "Runtime JSX tagged template that renders DOM or React trees anywhere with or without a build step.",
5
5
  "keywords": [
6
6
  "jsx runtime",
7
7
  "tagged template",
@@ -180,7 +180,7 @@
180
180
  "magic-string": "^0.30.21",
181
181
  "oxc-parser": "^0.105.0",
182
182
  "property-information": "^7.1.0",
183
- "tar": "^7.4.3"
183
+ "tar": "^7.5.3"
184
184
  },
185
185
  "peerDependencies": {
186
186
  "jsdom": "*",