@fluixi/compiler 1.0.0-alpha.73 → 1.0.0-alpha.75
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 +41 -16
- package/dist/analyze/expr-shape.cjs +1 -0
- package/dist/analyze/expr-shape.d.ts +15 -0
- package/dist/analyze/expr-shape.d.ts.map +1 -0
- package/dist/analyze/expr-shape.js +37 -0
- package/dist/analyze/expr-shape.mjs +1 -0
- package/dist/analyze/reactive-expr.cjs +1 -0
- package/dist/analyze/reactive-expr.d.ts +39 -0
- package/dist/analyze/reactive-expr.d.ts.map +1 -0
- package/dist/analyze/reactive-expr.js +31 -0
- package/dist/analyze/reactive-expr.mjs +1 -0
- package/dist/babel-GXO3KAVI.mjs +1 -0
- package/dist/chunk-3SAEGOMQ.mjs +1 -0
- package/dist/chunk-E2PW2OZU.mjs +1 -0
- package/dist/chunk-IBRM4W7I.mjs +10 -0
- package/dist/chunk-OHHZCYIQ.mjs +1 -0
- package/dist/chunk-TIE4XNAM.mjs +1 -0
- package/dist/frontend/babel/build-ir-lit.cjs +1 -1
- package/dist/frontend/babel/build-ir-lit.d.ts +1 -0
- package/dist/frontend/babel/build-ir-lit.d.ts.map +1 -1
- package/dist/frontend/babel/build-ir-lit.mjs +1 -1
- package/dist/frontend/babel/build-ir.cjs +1 -1
- package/dist/frontend/babel/build-ir.d.ts +13 -11
- package/dist/frontend/babel/build-ir.d.ts.map +1 -1
- package/dist/frontend/babel/build-ir.js +27 -217
- package/dist/frontend/babel/build-ir.mjs +1 -1
- package/dist/frontend/babel/index.cjs +1 -2
- package/dist/frontend/babel/index.mjs +1 -2
- package/dist/frontend/babel/lower-template.cjs +1 -1
- package/dist/frontend/babel/lower-template.d.ts +12 -9
- package/dist/frontend/babel/lower-template.d.ts.map +1 -1
- package/dist/frontend/babel/lower-template.js +33 -445
- package/dist/frontend/babel/lower-template.mjs +1 -1
- package/dist/frontend/babel/plugin.cjs +1 -2
- package/dist/frontend/babel/plugin.d.ts +24 -85
- package/dist/frontend/babel/plugin.d.ts.map +1 -1
- package/dist/frontend/babel/plugin.js +52 -1285
- package/dist/frontend/babel/plugin.mjs +1 -2
- package/dist/frontend/babel/server-functions.cjs +1 -1
- package/dist/frontend/babel/server-functions.d.ts.map +1 -1
- package/dist/frontend/babel/server-functions.js +2 -9
- package/dist/frontend/babel/server-functions.mjs +1 -1
- package/dist/index.cjs +8 -8
- package/dist/index.d.ts +4 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +8 -0
- package/dist/index.mjs +9 -9
- package/dist/integrations.cjs +15 -19
- package/dist/integrations.d.ts +39 -151
- package/dist/integrations.d.ts.map +1 -1
- package/dist/integrations.js +79 -491
- package/dist/integrations.mjs +11 -17
- package/dist/lower/compile-template.cjs +1 -0
- package/dist/lower/compile-template.d.ts +57 -0
- package/dist/lower/compile-template.d.ts.map +1 -0
- package/dist/lower/compile-template.js +72 -0
- package/dist/lower/compile-template.mjs +1 -0
- package/dist/lower/jsx.cjs +1 -0
- package/dist/lower/jsx.d.ts +24 -0
- package/dist/lower/jsx.d.ts.map +1 -0
- package/dist/lower/jsx.js +193 -0
- package/dist/lower/jsx.mjs +1 -0
- package/dist/lower/template.cjs +1 -0
- package/dist/lower/template.d.ts +41 -0
- package/dist/lower/template.d.ts.map +1 -0
- package/dist/lower/template.js +445 -0
- package/dist/lower/template.mjs +1 -0
- package/dist/lower/text.cjs +1 -0
- package/dist/lower/text.d.ts +11 -0
- package/dist/lower/text.d.ts.map +1 -0
- package/dist/lower/text.js +31 -0
- package/dist/lower/text.mjs +1 -0
- package/dist/options.cjs +1 -1
- package/dist/options.d.ts +0 -2
- package/dist/options.d.ts.map +1 -1
- package/dist/options.js +0 -1
- package/dist/options.mjs +1 -1
- package/dist/server-fns-6QM243HC.mjs +2 -0
- package/dist/server-functions-E3LKCZ4R.mjs +1 -0
- package/dist/transform/bindings.cjs +1 -0
- package/dist/transform/bindings.d.ts +17 -0
- package/dist/transform/bindings.d.ts.map +1 -0
- package/dist/transform/bindings.js +69 -0
- package/dist/transform/bindings.mjs +1 -0
- package/dist/transform/index.cjs +3 -0
- package/dist/transform/index.d.ts +12 -0
- package/dist/transform/index.d.ts.map +1 -0
- package/dist/transform/index.js +10 -0
- package/dist/transform/index.mjs +12 -0
- package/dist/transform/server-fn-id.cjs +1 -0
- package/dist/transform/server-fn-id.d.ts +10 -0
- package/dist/transform/server-fn-id.d.ts.map +1 -0
- package/dist/transform/server-fn-id.js +18 -0
- package/dist/transform/server-fn-id.mjs +1 -0
- package/dist/transform/server-fns.cjs +2 -0
- package/dist/transform/server-fns.d.ts +13 -0
- package/dist/transform/server-fns.d.ts.map +1 -0
- package/dist/transform/server-fns.js +94 -0
- package/dist/transform/server-fns.mjs +11 -0
- package/dist/transform/templates.cjs +3 -0
- package/dist/transform/templates.d.ts +26 -0
- package/dist/transform/templates.d.ts.map +1 -0
- package/dist/transform/templates.js +347 -0
- package/dist/transform/templates.mjs +12 -0
- package/dist/transform-PJX2GNSV.mjs +3 -0
- package/dist/tsconfig.lib.tsbuildinfo +1 -1
- package/package.json +30 -8
- package/dist/babel-E7EQLX36.mjs +0 -2
- package/dist/chunk-EF6V4GTD.mjs +0 -1
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import{parse as B}from"@babel/parser";var N=44,I=59,y="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/",E=new Uint8Array(64),O=new Uint8Array(128);for(let o=0;o<y.length;o++){let t=y.charCodeAt(o);E[o]=t,O[t]=o}function d(o,t,e){let n=t-e;n=n<0?-n<<1|1:n<<1;do{let i=n&31;n>>>=5,n>0&&(i|=32),o.write(E[i])}while(n>0);return t}var v=1024*16,x=typeof TextDecoder<"u"?new TextDecoder:typeof Buffer<"u"?{decode(o){return Buffer.from(o.buffer,o.byteOffset,o.byteLength).toString()}}:{decode(o){let t="";for(let e=0;e<o.length;e++)t+=String.fromCharCode(o[e]);return t}},_=class{constructor(){this.pos=0,this.out="",this.buffer=new Uint8Array(v)}write(o){let{buffer:t}=this;t[this.pos++]=o,this.pos===v&&(this.out+=x.decode(t),this.pos=0)}flush(){let{buffer:o,out:t,pos:e}=this;return e>0?t+x.decode(o.subarray(0,e)):t}};function L(o){let t=new _,e=0,n=0,i=0,r=0;for(let s=0;s<o.length;s++){let l=o[s];if(s>0&&t.write(I),l.length===0)continue;let h=0;for(let u=0;u<l.length;u++){let a=l[u];u>0&&t.write(N),h=d(t,a[0],h),a.length!==1&&(e=d(t,a[1],e),n=d(t,a[2],n),i=d(t,a[3],i),a.length!==4&&(r=d(t,a[4],r)))}}return t.flush()}var p=class o{constructor(t){this.bits=t instanceof o?t.bits.slice():[]}add(t){this.bits[t>>5]|=1<<(t&31)}has(t){return!!(this.bits[t>>5]&1<<(t&31))}},m=class o{constructor(t,e,n){this.start=t,this.end=e,this.original=n,this.intro="",this.outro="",this.content=n,this.storeName=!1,this.edited=!1,this.previous=null,this.next=null}appendLeft(t){this.outro+=t}appendRight(t){this.intro=this.intro+t}clone(){let t=new o(this.start,this.end,this.original);return t.intro=this.intro,t.outro=this.outro,t.content=this.content,t.storeName=this.storeName,t.edited=this.edited,t}contains(t){return this.start<t&&t<this.end}eachNext(t){let e=this;for(;e;)t(e),e=e.next}eachPrevious(t){let e=this;for(;e;)t(e),e=e.previous}edit(t,e,n){return this.content=t,n||(this.intro="",this.outro=""),this.storeName=e,this.edited=!0,this}prependLeft(t){this.outro=t+this.outro}prependRight(t){this.intro=t+this.intro}reset(){this.intro="",this.outro="",this.edited&&(this.content=this.original,this.storeName=!1,this.edited=!1)}split(t){let e=t-this.start,n=this.original.slice(0,e),i=this.original.slice(e);this.original=n;let r=new o(t,this.end,i);return r.outro=this.outro,this.outro="",this.end=t,this.edited?(r.edit("",!1),this.content=""):this.content=n,r.next=this.next,r.next&&(r.next.previous=r),r.previous=this,this.next=r,r}toString(){return this.intro+this.content+this.outro}trimEnd(t){if(this.outro=this.outro.replace(t,""),this.outro.length)return!0;let e=this.content.replace(t,"");if(e.length)return e!==this.content&&(this.split(this.start+e.length).edit("",void 0,!0),this.edited&&this.edit(e,this.storeName,!0)),!0;if(this.edit("",void 0,!0),this.intro=this.intro.replace(t,""),this.intro.length)return!0}trimStart(t){if(this.intro=this.intro.replace(t,""),this.intro.length)return!0;let e=this.content.replace(t,"");if(e.length){if(e!==this.content){let n=this.split(this.end-e.length);this.edited&&n.edit(e,this.storeName,!0),this.edit("",void 0,!0)}return!0}else if(this.edit("",void 0,!0),this.outro=this.outro.replace(t,""),this.outro.length)return!0}};function $(){return typeof globalThis<"u"&&typeof globalThis.btoa=="function"?o=>globalThis.btoa(unescape(encodeURIComponent(o))):typeof Buffer=="function"?o=>Buffer.from(o,"utf-8").toString("base64"):()=>{throw new Error("Unsupported environment: `window.btoa` or `Buffer` should be supported.")}}var A=$(),b=class{constructor(t){this.version=3,this.file=t.file,this.sources=t.sources,this.sourcesContent=t.sourcesContent,this.names=t.names,this.mappings=L(t.mappings),typeof t.x_google_ignoreList<"u"&&(this.x_google_ignoreList=t.x_google_ignoreList),typeof t.debugId<"u"&&(this.debugId=t.debugId)}toString(){return JSON.stringify(this)}toUrl(){return"data:application/json;charset=utf-8;base64,"+A(this.toString())}};function j(o){let t=o.split(`
|
|
2
|
+
`),e=t.filter(r=>/^\t+/.test(r)),n=t.filter(r=>/^ {2,}/.test(r));if(e.length===0&&n.length===0)return null;if(e.length>=n.length)return" ";let i=n.reduce((r,s)=>{let l=/^ +/.exec(s)[0].length;return Math.min(l,r)},1/0);return new Array(i+1).join(" ")}function F(o,t){let e=o.split(/[/\\]/),n=t.split(/[/\\]/);for(e.pop();e[0]===n[0];)e.shift(),n.shift();if(e.length){let i=e.length;for(;i--;)e[i]=".."}return e.concat(n).join("/")}var T=Object.prototype.toString;function M(o){return T.call(o)==="[object Object]"}function k(o){let t=o.split(`
|
|
3
|
+
`),e=[];for(let n=0,i=0;n<t.length;n++)e.push(i),i+=t[n].length+1;return function(i){let r=0,s=e.length;for(;r<s;){let u=r+s>>1;i<e[u]?s=u:r=u+1}let l=r-1,h=i-e[l];return{line:l,column:h}}}var U=/\w/,C=class{constructor(t){this.hires=t,this.generatedCodeLine=0,this.generatedCodeColumn=0,this.raw=[],this.rawSegments=this.raw[this.generatedCodeLine]=[],this.pending=null}addEdit(t,e,n,i){if(e.length){let r=e.length-1,s=e.indexOf(`
|
|
4
|
+
`,0),l=-1;for(;s>=0&&r>s;){let u=[this.generatedCodeColumn,t,n.line,n.column];i>=0&&u.push(i),this.rawSegments.push(u),this.generatedCodeLine+=1,this.raw[this.generatedCodeLine]=this.rawSegments=[],this.generatedCodeColumn=0,l=s,s=e.indexOf(`
|
|
5
|
+
`,s+1)}let h=[this.generatedCodeColumn,t,n.line,n.column];i>=0&&h.push(i),this.rawSegments.push(h),this.advance(e.slice(l+1))}else this.pending&&(this.rawSegments.push(this.pending),this.advance(e));this.pending=null}addUneditedChunk(t,e,n,i,r){let s=e.start,l=!0,h=!1;for(;s<e.end;){if(n[s]===`
|
|
6
|
+
`)i.line+=1,i.column=0,this.generatedCodeLine+=1,this.raw[this.generatedCodeLine]=this.rawSegments=[],this.generatedCodeColumn=0,l=!0,h=!1;else{if(this.hires||l||r.has(s)){let u=[this.generatedCodeColumn,t,i.line,i.column];this.hires==="boundary"?U.test(n[s])?h||(this.rawSegments.push(u),h=!0):(this.rawSegments.push(u),h=!1):this.rawSegments.push(u)}i.column+=1,this.generatedCodeColumn+=1,l=!1}s+=1}this.pending=null}advance(t){if(!t)return;let e=t.split(`
|
|
7
|
+
`);if(e.length>1){for(let n=0;n<e.length-1;n++)this.generatedCodeLine++,this.raw[this.generatedCodeLine]=this.rawSegments=[];this.generatedCodeColumn=0}this.generatedCodeColumn+=e[e.length-1].length}},g=`
|
|
8
|
+
`,c={insertLeft:!1,insertRight:!1,storeName:!1},w=class o{constructor(t,e={}){let n=new m(0,t.length,t);Object.defineProperties(this,{original:{writable:!0,value:t},outro:{writable:!0,value:""},intro:{writable:!0,value:""},firstChunk:{writable:!0,value:n},lastChunk:{writable:!0,value:n},lastSearchedChunk:{writable:!0,value:n},byStart:{writable:!0,value:{}},byEnd:{writable:!0,value:{}},filename:{writable:!0,value:e.filename},indentExclusionRanges:{writable:!0,value:e.indentExclusionRanges},sourcemapLocations:{writable:!0,value:new p},storedNames:{writable:!0,value:{}},indentStr:{writable:!0,value:void 0},ignoreList:{writable:!0,value:e.ignoreList},offset:{writable:!0,value:e.offset||0}}),this.byStart[0]=n,this.byEnd[t.length]=n}addSourcemapLocation(t){this.sourcemapLocations.add(t)}append(t){if(typeof t!="string")throw new TypeError("outro content must be a string");return this.outro+=t,this}appendLeft(t,e){if(t=t+this.offset,typeof e!="string")throw new TypeError("inserted content must be a string");this._split(t);let n=this.byEnd[t];return n?n.appendLeft(e):this.intro+=e,this}appendRight(t,e){if(t=t+this.offset,typeof e!="string")throw new TypeError("inserted content must be a string");this._split(t);let n=this.byStart[t];return n?n.appendRight(e):this.outro+=e,this}clone(){let t=new o(this.original,{filename:this.filename,offset:this.offset}),e=this.firstChunk,n=t.firstChunk=t.lastSearchedChunk=e.clone();for(;e;){t.byStart[n.start]=n,t.byEnd[n.end]=n;let i=e.next,r=i&&i.clone();r&&(n.next=r,r.previous=n,n=r),e=i}return t.lastChunk=n,this.indentExclusionRanges&&(t.indentExclusionRanges=this.indentExclusionRanges.slice()),t.sourcemapLocations=new p(this.sourcemapLocations),t.intro=this.intro,t.outro=this.outro,t}generateDecodedMap(t){t=t||{};let e=0,n=Object.keys(this.storedNames),i=new C(t.hires),r=k(this.original);return this.intro&&i.advance(this.intro),this.firstChunk.eachNext(s=>{let l=r(s.start);s.intro.length&&i.advance(s.intro),s.edited?i.addEdit(e,s.content,l,s.storeName?n.indexOf(s.original):-1):i.addUneditedChunk(e,s,this.original,l,this.sourcemapLocations),s.outro.length&&i.advance(s.outro)}),this.outro&&i.advance(this.outro),{file:t.file?t.file.split(/[/\\]/).pop():void 0,sources:[t.source?F(t.file||"",t.source):t.file||""],sourcesContent:t.includeContent?[this.original]:void 0,names:n,mappings:i.raw,x_google_ignoreList:this.ignoreList?[e]:void 0}}generateMap(t){return new b(this.generateDecodedMap(t))}_ensureindentStr(){this.indentStr===void 0&&(this.indentStr=j(this.original))}_getRawIndentString(){return this._ensureindentStr(),this.indentStr}getIndentString(){return this._ensureindentStr(),this.indentStr===null?" ":this.indentStr}indent(t,e){let n=/^[^\r\n]/gm;if(M(t)&&(e=t,t=void 0),t===void 0&&(this._ensureindentStr(),t=this.indentStr||" "),t==="")return this;e=e||{};let i={};e.exclude&&(typeof e.exclude[0]=="number"?[e.exclude]:e.exclude).forEach(a=>{for(let f=a[0];f<a[1];f+=1)i[f]=!0});let r=e.indentStart!==!1,s=u=>r?`${t}${u}`:(r=!0,u);this.intro=this.intro.replace(n,s);let l=0,h=this.firstChunk;for(;h;){let u=h.end;if(h.edited)i[l]||(h.content=h.content.replace(n,s),h.content.length&&(r=h.content[h.content.length-1]===`
|
|
9
|
+
`));else for(l=h.start;l<u;){if(!i[l]){let a=this.original[l];a===`
|
|
10
|
+
`?r=!0:a!=="\r"&&r&&(r=!1,l===h.start||(this._splitChunk(h,l),h=h.next),h.prependRight(t))}l+=1}l=h.end,h=h.next}return this.outro=this.outro.replace(n,s),this}insert(){throw new Error("magicString.insert(...) is deprecated. Use prependRight(...) or appendLeft(...)")}insertLeft(t,e){return c.insertLeft||(console.warn("magicString.insertLeft(...) is deprecated. Use magicString.appendLeft(...) instead"),c.insertLeft=!0),this.appendLeft(t,e)}insertRight(t,e){return c.insertRight||(console.warn("magicString.insertRight(...) is deprecated. Use magicString.prependRight(...) instead"),c.insertRight=!0),this.prependRight(t,e)}move(t,e,n){if(t=t+this.offset,e=e+this.offset,n=n+this.offset,n>=t&&n<=e)throw new Error("Cannot move a selection inside itself");this._split(t),this._split(e),this._split(n);let i=this.byStart[t],r=this.byEnd[e],s=i.previous,l=r.next,h=this.byStart[n];if(!h&&r===this.lastChunk)return this;let u=h?h.previous:this.lastChunk;return s&&(s.next=l),l&&(l.previous=s),u&&(u.next=i),h&&(h.previous=r),i.previous||(this.firstChunk=r.next),r.next||(this.lastChunk=i.previous,this.lastChunk.next=null),i.previous=u,r.next=h||null,u||(this.firstChunk=i),h||(this.lastChunk=r),this}overwrite(t,e,n,i){return i=i||{},this.update(t,e,n,{...i,overwrite:!i.contentOnly})}update(t,e,n,i){if(t=t+this.offset,e=e+this.offset,typeof n!="string")throw new TypeError("replacement content must be a string");if(this.original.length!==0){for(;t<0;)t+=this.original.length;for(;e<0;)e+=this.original.length}if(e>this.original.length)throw new Error("end is out of bounds");if(t===e)throw new Error("Cannot overwrite a zero-length range – use appendLeft or prependRight instead");this._split(t),this._split(e),i===!0&&(c.storeName||(console.warn("The final argument to magicString.overwrite(...) should be an options object. See https://github.com/rich-harris/magic-string"),c.storeName=!0),i={storeName:!0});let r=i!==void 0?i.storeName:!1,s=i!==void 0?i.overwrite:!1;if(r){let u=this.original.slice(t,e);Object.defineProperty(this.storedNames,u,{writable:!0,value:!0,enumerable:!0})}let l=this.byStart[t],h=this.byEnd[e];if(l){let u=l;for(;u!==h;){if(u.next!==this.byStart[u.end])throw new Error("Cannot overwrite across a split point");u=u.next,u.edit("",!1)}l.edit(n,r,!s)}else{let u=new m(t,e,"").edit(n,r);h.next=u,u.previous=h}return this}prepend(t){if(typeof t!="string")throw new TypeError("outro content must be a string");return this.intro=t+this.intro,this}prependLeft(t,e){if(t=t+this.offset,typeof e!="string")throw new TypeError("inserted content must be a string");this._split(t);let n=this.byEnd[t];return n?n.prependLeft(e):this.intro=e+this.intro,this}prependRight(t,e){if(t=t+this.offset,typeof e!="string")throw new TypeError("inserted content must be a string");this._split(t);let n=this.byStart[t];return n?n.prependRight(e):this.outro=e+this.outro,this}remove(t,e){if(t=t+this.offset,e=e+this.offset,this.original.length!==0){for(;t<0;)t+=this.original.length;for(;e<0;)e+=this.original.length}if(t===e)return this;if(t<0||e>this.original.length)throw new Error("Character is out of bounds");if(t>e)throw new Error("end must be greater than start");this._split(t),this._split(e);let n=this.byStart[t];for(;n;)n.intro="",n.outro="",n.edit(""),n=e>n.end?this.byStart[n.end]:null;return this}reset(t,e){if(t=t+this.offset,e=e+this.offset,this.original.length!==0){for(;t<0;)t+=this.original.length;for(;e<0;)e+=this.original.length}if(t===e)return this;if(t<0||e>this.original.length)throw new Error("Character is out of bounds");if(t>e)throw new Error("end must be greater than start");this._split(t),this._split(e);let n=this.byStart[t];for(;n;)n.reset(),n=e>n.end?this.byStart[n.end]:null;return this}lastChar(){if(this.outro.length)return this.outro[this.outro.length-1];let t=this.lastChunk;do{if(t.outro.length)return t.outro[t.outro.length-1];if(t.content.length)return t.content[t.content.length-1];if(t.intro.length)return t.intro[t.intro.length-1]}while(t=t.previous);return this.intro.length?this.intro[this.intro.length-1]:""}lastLine(){let t=this.outro.lastIndexOf(g);if(t!==-1)return this.outro.substr(t+1);let e=this.outro,n=this.lastChunk;do{if(n.outro.length>0){if(t=n.outro.lastIndexOf(g),t!==-1)return n.outro.substr(t+1)+e;e=n.outro+e}if(n.content.length>0){if(t=n.content.lastIndexOf(g),t!==-1)return n.content.substr(t+1)+e;e=n.content+e}if(n.intro.length>0){if(t=n.intro.lastIndexOf(g),t!==-1)return n.intro.substr(t+1)+e;e=n.intro+e}}while(n=n.previous);return t=this.intro.lastIndexOf(g),t!==-1?this.intro.substr(t+1)+e:this.intro+e}slice(t=0,e=this.original.length-this.offset){if(t=t+this.offset,e=e+this.offset,this.original.length!==0){for(;t<0;)t+=this.original.length;for(;e<0;)e+=this.original.length}let n="",i=this.firstChunk;for(;i&&(i.start>t||i.end<=t);){if(i.start<e&&i.end>=e)return n;i=i.next}if(i&&i.edited&&i.start!==t)throw new Error(`Cannot use replaced character ${t} as slice start anchor.`);let r=i;for(;i;){i.intro&&(r!==i||i.start===t)&&(n+=i.intro);let s=i.start<e&&i.end>=e;if(s&&i.edited&&i.end!==e)throw new Error(`Cannot use replaced character ${e} as slice end anchor.`);let l=r===i?t-i.start:0,h=s?i.content.length+e-i.end:i.content.length;if(n+=i.content.slice(l,h),i.outro&&(!s||i.end===e)&&(n+=i.outro),s)break;i=i.next}return n}snip(t,e){let n=this.clone();return n.remove(0,t),n.remove(e,n.original.length),n}_split(t){if(this.byStart[t]||this.byEnd[t])return;let e=this.lastSearchedChunk,n=e,i=t>e.end;for(;e;){if(e.contains(t))return this._splitChunk(e,t);if(e=i?this.byStart[e.end]:this.byEnd[e.start],e===n)return;n=e}}_splitChunk(t,e){if(t.edited&&t.content.length){let i=k(this.original)(e);throw new Error(`Cannot split a chunk that has already been edited (${i.line}:${i.column} – "${t.original}")`)}let n=t.split(e);return this.byEnd[e]=t,this.byStart[e]=n,this.byEnd[n.end]=n,t===this.lastChunk&&(this.lastChunk=n),this.lastSearchedChunk=t,!0}toString(){let t=this.intro,e=this.firstChunk;for(;e;)t+=e.toString(),e=e.next;return t+this.outro}isEmpty(){let t=this.firstChunk;do if(t.intro.length&&t.intro.trim()||t.content.length&&t.content.trim()||t.outro.length&&t.outro.trim())return!1;while(t=t.next);return!0}length(){let t=this.firstChunk,e=0;do e+=t.intro.length+t.content.length+t.outro.length;while(t=t.next);return e}trimLines(){return this.trim("[\\r\\n]")}trim(t){return this.trimStart(t).trimEnd(t)}trimEndAborted(t){let e=new RegExp((t||"\\s")+"+$");if(this.outro=this.outro.replace(e,""),this.outro.length)return!0;let n=this.lastChunk;do{let i=n.end,r=n.trimEnd(e);if(n.end!==i&&(this.lastChunk===n&&(this.lastChunk=n.next),this.byEnd[n.end]=n,this.byStart[n.next.start]=n.next,this.byEnd[n.next.end]=n.next),r)return!0;n=n.previous}while(n);return!1}trimEnd(t){return this.trimEndAborted(t),this}trimStartAborted(t){let e=new RegExp("^"+(t||"\\s")+"+");if(this.intro=this.intro.replace(e,""),this.intro.length)return!0;let n=this.firstChunk;do{let i=n.end,r=n.trimStart(e);if(n.end!==i&&(n===this.lastChunk&&(this.lastChunk=n.next),this.byEnd[n.end]=n,this.byStart[n.next.start]=n.next,this.byEnd[n.next.end]=n.next),r)return!0;n=n.next}while(n);return!1}trimStart(t){return this.trimStartAborted(t),this}hasChanged(){return this.original!==this.toString()}_replaceRegexp(t,e){function n(r,s){return typeof e=="string"?e.replace(/\$(\$|&|\d+)/g,(l,h)=>h==="$"?"$":h==="&"?r[0]:+h<r.length?r[+h]:`$${h}`):e(...r,r.index,s,r.groups)}function i(r,s){let l,h=[];for(;l=r.exec(s);)h.push(l);return h}if(t.global)i(t,this.original).forEach(s=>{if(s.index!=null){let l=n(s,this.original);l!==s[0]&&this.overwrite(s.index,s.index+s[0].length,l)}});else{let r=this.original.match(t);if(r&&r.index!=null){let s=n(r,this.original);s!==r[0]&&this.overwrite(r.index,r.index+r[0].length,s)}}return this}_replaceString(t,e){let{original:n}=this,i=n.indexOf(t);return i!==-1&&(typeof e=="function"&&(e=e(t,i,n)),t!==e&&this.overwrite(i,i+t.length,e)),this}replace(t,e){return typeof t=="string"?this._replaceString(t,e):this._replaceRegexp(t,e)}_replaceAllString(t,e){let{original:n}=this,i=t.length;for(let r=n.indexOf(t);r!==-1;r=n.indexOf(t,r+i)){let s=n.slice(r,r+i),l=e;typeof e=="function"&&(l=e(s,r,n)),s!==l&&this.overwrite(r,r+i,l)}return this}replaceAll(t,e){if(typeof t=="string")return this._replaceAllString(t,e);if(!t.global)throw new TypeError("MagicString.prototype.replaceAll called with a non-global RegExp argument");return this._replaceRegexp(t,e)}};function q(o){let t=5381;for(let e=0;e<o.length;e++)t=t*33^o.charCodeAt(e);return(t>>>0).toString(16)}function R(o,t,e){let n=(o||"unknown").replace(t?t+"/":"","");return`${q(n)}:${e}`}var P="@fluixi/start/server-fn",D=new Set(["FunctionDeclaration","FunctionExpression","ArrowFunctionExpression"]);function J(o){if(!D.has(o.type))return null;let t=o.body;if(!t||t.type!=="BlockStatement")return null;for(let e of t.directives??[])if(e.value?.value==="use server")return e;return null}function S(o,t){if(!(!o||typeof o!="object")){if(Array.isArray(o)){for(let e of o)S(e,t);return}if(typeof o.type=="string"){let e=J(o);if(e){t.push({fn:o,directive:e});return}}for(let e of Object.keys(o))e==="loc"||e==="leadingComments"||e==="trailingComments"||S(o[e],t)}}function Z(o,t){if(!o.includes("use server"))return null;let e=B(o,{sourceType:"module",plugins:["jsx","typescript"],errorRecovery:!0}),n=[];if(S(e.program,n),n.length===0)return null;let i=t.ssr?"$$registerServerFn":"$$createServerReference",r=new w(o);return n.forEach(({fn:s,directive:l},h)=>{let u=R(t.filename,t.root,h),a=s.type==="FunctionDeclaration";if(!t.ssr){let f=`${i}(${JSON.stringify(u)})`;r.overwrite(s.start,s.end,a?`const ${s.id.name} = ${f};`:f);return}r.remove(l.start,l.end),r.appendLeft(s.start,a?`const ${s.id.name} = ${i}(${JSON.stringify(u)}, `:`${i}(${JSON.stringify(u)}, `),r.appendRight(s.end,a?");":")")}),r.prepend(`import { ${i} } from ${JSON.stringify(t.runtimeModule??P)};
|
|
11
|
+
`),{code:r.toString(),map:r.generateMap({source:t.filename,includeContent:!0,hires:!0})}}export{Z as transformServerFns};
|
|
@@ -0,0 +1,3 @@
|
|
|
1
|
+
"use strict";var je=Object.create;var L=Object.defineProperty;var De=Object.getOwnPropertyDescriptor;var _e=Object.getOwnPropertyNames;var Be=Object.getPrototypeOf,Fe=Object.prototype.hasOwnProperty;var He=(e,t)=>{for(var n in t)L(e,n,{get:t[n],enumerable:!0})},se=(e,t,n,o)=>{if(t&&typeof t=="object"||typeof t=="function")for(let r of _e(t))!Fe.call(e,r)&&r!==n&&L(e,r,{get:()=>t[r],enumerable:!(o=De(t,r))||o.enumerable});return e};var Xe=(e,t,n)=>(n=e!=null?je(Be(e)):{},se(t||!e||!e.__esModule?L(n,"default",{value:e,enumerable:!0}):n,e)),ze=e=>se(L({},"__esModule",{value:!0}),e);var jt={};He(jt,{transformTemplates:()=>At});module.exports=ze(jt);var Pe=require("@babel/parser"),Ae=Xe(require("magic-string"),1);function qe(e){switch(e.kind){case"event":return"event";case"ref":return"ref";case"spread":return"spread";case"class":case"style":return"class-or-style-directive";case"attr":case"prop":return e.reactive?"reactive-prop":e.expr!==void 0?"expression-prop":void 0;default:return"expression-prop"}}function x(e){let t=[],n=new Map,o=r=>{switch(r.kind){case"text":return!0;case"expr":return!1;case"component":case"control":for(let s of r.children)o(s);return!1;case"fragment":for(let s of r.children)o(s);return!1;case"element":{let s=!0;for(let a of r.children)o(a)||(s=!1);let i;for(let a of r.props)if(i=qe(a),i)break;return!i&&!s&&(i=Ve(r)),r.static=!i,i?n.set(r,i):t.push(r),r.static}default:return!1}};for(let r of Array.isArray(e)?e:[e])o(r);return{staticElements:t,reasons:n}}function Ve(e){for(let t of e.children){if(t.kind==="expr")return"expression-child";if(t.kind==="component")return"component-child";if(t.kind==="control")return"control-child";if(t.kind==="element"&&!t.static||t.kind==="fragment")return"expression-child"}return"expression-child"}var J={kind:"eager"},We=["pointerdown","focusin","keydown"],ae=new Set(["eager","idle","visible","interaction","media","never"]),v=class extends Error{};function U(e){return e.startsWith("load:")}function j(e,t){let n=e.slice(5);if(!ae.has(n))throw new v(`Unknown load strategy 'load:${n}'. Expected one of ${[...ae].join(", ")}.`);switch(n){case"eager":return J;case"idle":return{kind:"idle"};case"never":return{kind:"never"};case"visible":return t?{kind:"visible",rootMargin:t}:{kind:"visible"};case"interaction":return{kind:"interaction",events:t?Ue(t):[...We]};case"media":if(!t)throw new v(`'load:media' needs a query, e.g. load:media="(min-width: 1024px)".`);return{kind:"media",query:t};default:throw new v(`Unhandled load strategy '${n}'.`)}}function Ue(e){let t=e.split(/[\s,]+/).map(n=>n.trim()).filter(Boolean);if(t.length===0)throw new v("'load:interaction' was given no event names.");return t}function D(e){return e.kind!=="eager"&&e.kind!=="never"}var b=["Show","For","Index","Switch","Match","Portal","Dynamic","ErrorBoundary"],C=["Suspense","SuspenseList","Await"],N=["Router","Outlet","Redirect","Link"],Ft=[...b,...C,...N],G=new Set([...b,...C]);function le(e={}){let{controlFlowModule:t="@fluixi/dom",coreModule:n="@fluixi/core",routerModule:o="@fluixi/core/router-next"}=e,r={};for(let s of b)r[s]=t;for(let s of C)r[s]=n;for(let s of N)r[s]=o;return r}function _(e,t={}){let{resolver:n,isBound:o,modules:r,strategyFor:s}=t,i=le(r),a=new Map,l=new Set,c=d=>{let{name:p}=d;if(!p||p.includes(".")||o?.(p))return;let f=u(p);if(!f){l.add(p);return}let g=f.origin==="builtin"&&G.has(p)?J:s?.(d)??J;d.source={...f,loading:g},a.set(p,d.source)},u=d=>{if(G.has(d))return{module:i[d],export:d,origin:"builtin"};let p=n?.resolve(d);if(p)return{module:p.module,export:p.export,origin:"rule"};if(N.includes(d))return{module:i[d],export:d,origin:"builtin"}};return B(e,d=>{d.kind==="component"&&c(d)}),{resolved:a,unresolved:[...l]}}function B(e,t){let n=Array.isArray(e)?e:[e];for(let o of n){t(o);let r=o.children;r&&B(r,t)}}function F(e){let t=[];B(e,s=>{s.kind==="component"&&s.source&&t.push(s)});let n=new Set,o=new Set;for(let s of t){let{module:i,loading:a}=s.source;a.kind==="eager"&&n.add(i),a.kind==="never"&&o.add(i)}let r=new Map;for(let s of t){let i=s.source;D(i.loading)&&n.has(i.module)&&(i.loading={kind:"eager"},r.set(i.module,(r.get(i.module)??0)+1))}return{collapsed:r,conflicted:[...o].filter(s=>n.has(s))}}var Ge=new Set(["area","base","br","col","embed","hr","img","input","link","meta","param","source","track","wbr"]),ce={className:"class",htmlFor:"for"},Ke=new Set(["innerHTML","outerHTML","innerText","textContent","value","checked","selected","muted","defaultValue","defaultChecked","children","ref"]),Ye=new Set(["script","style","textarea","title"]);function K(e){return Ye.has(e)}function pe(e){return ce[e]??e}function I(e){return e.kind!=="attr"||e.expr!==void 0||e.name.includes(":")?!1:!Ke.has(e.name)}function Y(e){if(!e.static||K(e.tag))return!1;for(let t of e.props)if(!I(t))return!1;for(let t of e.children)if(t.kind!=="text"&&!(t.kind==="element"&&Y(t)))return!1;return!0}function w(e){let t=e.props.map(Qe).filter(Boolean).join(""),n=`<${e.tag}${t}>`;return Ge.has(e.tag)?n:`${n}${e.children.map(Ze).join("")}</${e.tag}>`}function Ze(e){if(e.kind==="text")return tt(e.value);if(e.kind!=="element")throw new Error(`serializeStatic: unexpected ${e.kind}`);return w(e)}function Qe(e){let t=ce[e.name]??e.name,n=e.literal;return n===!0||n===void 0?` ${t}`:n===!1||n===null?"":` ${t}="${et(String(n))}"`}function et(e){return e.replace(/&/g,"&").replace(/"/g,""").replace(/</g,"<").replace(/>/g,">")}function tt(e){return e.replace(/&/g,"&").replace(/</g,"<").replace(/>/g,">")}var nt="<!--fx-->",rt="<!--fx/-->";function X(e){return e.kind==="expr"||e.kind==="component"||e.kind==="control"}function ot(e){return e.kind==="text"||e.kind==="element"&&ue(e)}function ue(e){return e.svg||K(e.tag)||!e.props.every(t=>I(t))?!1:e.children.every(t=>ot(t)||X(t))}function H(e){if(X(e))return!0;let t=e.children;return t?t.some(H):!1}function de(e){for(let t=0;t<e.children.length;t++){let n=e.children[t];if(n.kind==="text"&&(n.value===""||e.children[t+1]?.kind==="text"))return!1}return e.children.every(t=>t.kind!=="element"||de(t))}function me(e){if(!ue(e)||!de(e)||!e.children.some(H))return null;let t=[],n=[],o=0,r=i=>{let a=`_n$${o++}`;return t.push({ref:a,expr:i}),a};return s(e,"_el$"),{html:it(e),tag:e.tag,steps:t,holes:n};function s(i,a){let l=-1;i.children.forEach((u,d)=>{H(u)&&(l=d)});let c=null;for(let u=0;u<=l;u++){let d=i.children[u],p=c?`${c}.nextSibling`:`${a}.firstChild`;if(X(d)){let g=r(p),P=r(`holeEnd(${g})`);n.push({parentRef:a,startRef:g,endRef:P,node:d}),c=P;continue}let f=r(p);d.kind==="element"&&H(d)&&s(d,f),c=f}}}function it(e){return w(fe(e)).split(ge).join(nt+rt)}function fe(e){return{...e,children:e.children.map(t=>X(t)?{kind:"text",value:ge}:t.kind==="element"?fe(t):t)}}var ge="\0fx-hole\0";var Z={version:1,module:"@fluixi/dom",symbols:["createNativeElement","insert","spread","setAttribute","delegateEvents","createComponent","createMemo","untrack","Show","For","Index","Switch","Match","Dynamic","ErrorBoundary"]},Zt={version:2,module:"@fluixi/dom",symbols:[...Z.symbols,"template","cloneTemplate","walk"]};var st={show:"Show",for:"For",index:"Index",switch:"Switch",match:"Match",dynamic:"Dynamic",errorBoundary:"ErrorBoundary",suspense:"Suspense"};function at(e){return/^[A-Za-z_$][A-Za-z0-9_$]*$/.test(e)}function ve(e){return at(e)?e:JSON.stringify(e)}function lt(e){return e.expr!==void 0?e.reactive?`() => (${e.expr})`:`(${e.expr})`:JSON.stringify(e.literal??!0)}function ct(e){return e.expr!==void 0?`(${e.expr})`:JSON.stringify(e.literal??!0)}function pt(e,t,n){let o=e.filter(a=>a.kind==="spread"),s=e.filter(a=>a.kind!=="spread").map(a=>`${ve(a.name)}: ${lt(a)}`);t!=null&&s.push(`children: ${t}`);let i=`{ ${s.join(", ")} }`;return o.length>0?(n.add("mergeProps"),`mergeProps(${o.map(a=>a.expr).join(", ")}, ${i})`):i}function Re(e,t,n){return e.length===1?T(e[0],t,n):`[${e.map(o=>T(o,t,n)).join(", ")}]`}function he(e,t,n,o,r){o.add("createMemo"),o.add("createComponent");let s=t.filter(c=>c.kind==="spread"),a=t.filter(c=>c.kind!=="spread").map(c=>`get ${ve(c.name)}() { return ${ct(c)}; }`);n.length>0&&a.push(`get children() { return ${Re(n,o,r)}; }`);let l=`{ ${a.join(", ")} }`;return s.length>0&&(o.add("mergeProps"),l=`mergeProps(${s.map(c=>c.expr).join(", ")}, ${l})`),`createMemo(() => createComponent(${e}, ${l}))`}function ut(e,t){let n=pe(t.name),o=t.literal;return o===!0||o===void 0?`${e}.setAttribute(${JSON.stringify(n)}, "");`:o===!1||o===null?"":`${e}.setAttribute(${JSON.stringify(n)}, ${JSON.stringify(String(o))});`}var ye=!1;function T(e,t,n){switch(e.kind){case"text":return JSON.stringify(e.value);case"expr":return e.reactive?`() => (${e.code})`:`(${e.code})`;case"fragment":return e.children.length===0?"null":Re(e.children,t,n);case"component":return he(e.name,e.props,e.children,t,n);case"control":{let o=st[e.control]??e.control;return t.add(o),he(o,e.props,e.children,t,n)}case"element":{if(n&&e.static&&!e.svg&&Y(e)){t.add("templateNode");let a=`_tmpl$${n.length}`;return n.push({id:a,html:w(e),tag:e.tag,svg:!1}),`templateNode(${a}, ${JSON.stringify(e.tag)})`}if(n&&ye){let a=me(e);if(a){t.add("templateNode"),t.add("insert"),t.add("holeEnd"),t.add("holeContent"),t.add("holeScope");let l=`_tmpl$${n.length}`;n.push({id:l,html:a.html,tag:a.tag,svg:!1});let c=[`const _el$ = templateNode(${l}, ${JSON.stringify(a.tag)}, true);`];for(let u of a.steps)c.push(`const ${u.ref} = ${u.expr};`);for(let u of a.holes)c.push(`insert(${u.parentRef}, holeScope(${u.startRef}, () => (${T(u.node,t,n)})), ${u.endRef}, holeContent(${u.startRef}, ${u.endRef}));`);return c.push("return _el$;"),`(() => { ${c.join(" ")} })()`}}t.add("createNativeElement");let o=JSON.stringify(e.tag),r="_el$",s=[],i=e.svg?`${o}, true`:o;if(s.push(`const ${r} = createNativeElement(${i});`),e.props.length>0)if(!e.svg&&e.props.every(I))for(let a of e.props)s.push(ut(r,a));else{t.add("spread");let a=e.svg?", isSVG: true":"";s.push(`spread({ element: ${r}, props: ${pt(e.props,null,t)}${a} });`)}for(let a of e.children){t.add("insert");let l=T(a,t,n),c=a.kind==="expr"&&a.reactive||a.kind==="component"||a.kind==="control";s.push(c?`insert(${r}, ${l}, null);`:`insert(${r}, ${l});`)}return s.push(`return ${r};`),`(() => { ${s.join(" ")} })()`}}}function z(e,t){if(!t||t.length===0)return e;let n=new Map(t.map(o=>[o.id,JSON.stringify(o.html)]));return e.replace(/_tmpl\$\d+/g,o=>n.get(o)??o)}var k={name:"imperative",contract:Z,emit(e,t){let n=new Set,o=t?.templateClone!==!1?[]:void 0;return ye=t?.partialTemplates===!0,{code:T(e,n,o),imports:Array.from(n),templates:o}}};var dt=e=>"components"in e;function xe(e,t){return e.replace(/\$(\d+)/g,(n,o)=>t[Number(o)]??n)}function mt(e,t){return typeof t=="string"?{module:t,export:e}:t}function q(e=[]){let t=new Map,n=[],o=[];for(let i of e){if(!dt(i)){o.push(i);continue}for(let[a,l]of Object.entries(i.components)){let c=mt(a,l),u=t.get(a);if(u&&u.module!==c.module){let d=n.find(p=>p.name===a);d?d.modules.push(c.module):n.push({name:a,modules:[u.module,c.module]});continue}t.set(a,c)}}let r=new Map;return{resolve:i=>{if(r.has(i))return r.get(i);let a=t.get(i);if(!a)for(let l of o){let c=i.match(new RegExp(l.match.source,l.match.flags.replace("g","")));if(c){a={module:xe(l.module,c),export:l.export?xe(l.export,c):i};break}}return r.set(i,a),a},names:()=>[...t.keys()],conflicts:()=>n}}var Ee=require("@fluixi/template-parser");function $(e){let t=e.split(/\r\n|\n|\r/),n=0;for(let r=0;r<t.length;r++)/[^ \t]/.test(t[r])&&(n=r);let o="";for(let r=0;r<t.length;r++){let s=t[r].replace(/\t/g," ");r!==0&&(s=s.replace(/^ +/,"")),r!==t.length-1&&(s=s.replace(/ +$/,"")),s&&(r!==n&&(s+=" "),o+=s)}return o}var Ne=new Set(["click","dblclick","input","change","submit","focus","blur","keydown","keyup","keypress","mousedown","mouseup"]);function ft(e){return e.replace(/\\/g,"\\\\").replace(/`/g,"\\`").replace(/\$\{/g,"\\${")}function ke(e){return e.charAt(0).toUpperCase()+e.slice(1)}var Q=class{constructor(t,n){this.holes=t;this.used=n}hole(t){return this.holes[t]??{code:"undefined",reactive:!1}}emit(t){let{code:n,imports:o,templates:r}=k.emit(t,{});for(let s of o)this.used.add(s);return z(n,r)}lowerRoot(t){let n=this.lowerChildren(t);return n.length===1?n[0]:{kind:"fragment",children:n}}lowerChildren(t){let n=[];for(let o=0;o<t.length;o++){let r=t[o];if(r.kind==="Element"||r.kind==="Component"){let i=r.attributes.find(a=>a.kind==="IfDirective");if(i&&i.kind==="IfDirective"){let a=o+1;a<t.length&&this.isBlankText(t[a])&&a++;let l=t[a],c=l&&(l.kind==="Element"||l.kind==="Component")&&l.attributes.some(u=>u.kind==="ElseDirective");n.push(this.lowerIf(r,i.hole,c?l:null)),c&&(o=a);continue}if(r.attributes.some(a=>a.kind==="EachDirective")){n.push(this.lowerEach(r));continue}}let s=this.lowerNode(r);s&&n.push(s)}return n}isBlankText(t){return t.kind==="Text"&&!t.raw&&$(t.value)===""}lowerNode(t){switch(t.kind){case"Text":{if(t.raw)return{kind:"text",value:t.value};let n=$(t.value);return n?{kind:"text",value:n}:null}case"Comment":return null;case"Expression":{let n=this.hole(t.hole);return{kind:"expr",code:n.code,reactive:n.reactive}}case"Fragment":return{kind:"fragment",children:this.lowerChildren(t.children)};case"Element":return this.lowerElement(t);case"Component":return this.lowerComponent(t);default:return null}}lowerElement(t){let n=t.attributes.find(o=>o.kind==="Attribute"&&o.name==="is");if(t.tag==="component"&&n&&n.value&&n.value.kind==="hole"){let o=t.attributes.filter(s=>s!==n),r=this.lowerComponent({...t,kind:"Component",tag:"Dynamic",tagHole:null,attributes:o});return r.props.unshift({name:"component",kind:"attr",expr:`() => (${this.hole(n.value.hole).code})`}),r}return{kind:"element",tag:t.tag,svg:t.namespace==="svg",props:this.lowerAttributes(t.attributes),children:this.lowerChildren(t.children),static:!1}}lowerComponent(t){let n=t.tagHole!=null?this.hole(t.tagHole).code:t.tag,o=this.lowerAttributes(t.attributes),{slots:r,rest:s}=this.partitionSlots(t.children);for(let[l,c]of r){let u=c.length===1?c[0]:{kind:"fragment",children:c},d={name:l,kind:"attr",expr:this.emit(u),jsxElement:!0},p=o.findIndex(f=>f.name===l);p>=0?o[p]=d:o.push(d)}let i=t.attributes.find(l=>l.kind==="LoadDirective"),a=i?j(`load:${i.strategy}`,i.modifier):void 0;return{kind:"component",name:n,props:o,children:this.lowerChildren(s),...a?{load:a}:{}}}partitionSlots(t){let n=new Map,o=[];for(let r of t){if(r.kind==="Element"||r.kind==="Component"){let s=r.attributes.find(i=>i.kind==="Attribute"&&i.name==="slot");if(s&&s.value&&s.value.kind==="static"){let i={...r,attributes:r.attributes.filter(c=>c!==s)},a=i.kind==="Element"?this.lowerElement(i):this.lowerComponent(i),l=n.get(s.value.value)??[];l.push(a),n.set(s.value.value,l);continue}}o.push(r)}return{slots:n,rest:o}}lowerIf(t,n,o){let r=this.hole(n),s=[{name:"when",kind:"attr",expr:r.code,reactive:r.reactive}];if(o){let a=this.stripAndLower(o,l=>l.kind==="ElseDirective");s.push({name:"fallback",kind:"attr",expr:this.emit(a),jsxElement:!0})}let i=this.stripAndLower(t,a=>a.kind==="IfDirective");return{kind:"component",name:"Show",props:s,children:[i]}}lowerEach(t){let n=t.attributes.find(l=>l.kind==="EachDirective");if(!n||n.kind!=="EachDirective")return this.lowerNode(t);let o=this.hole(n.hole),r=[{name:"each",kind:"attr",expr:o.code,reactive:o.reactive}];if(n.key){let l="static"in n.key?`(item) => item[${JSON.stringify(n.key.static)}]`:this.hole(n.key.hole).code;r.push({name:"by",kind:"attr",expr:l})}let s=this.itemArrow(t),i;if(s){let l={kind:"expr",code:s.body,reactive:s.bodyReactive},c=this.rebuildWithChildren(t,[l]);i=`(${s.params.join(", ")}) => (${this.emit(c)})`}else{let l=this.stripAndLower(t,c=>c.kind==="EachDirective");i=`() => (${this.emit(l)})`}return{kind:"component",name:"For",props:r,children:[{kind:"expr",code:i,reactive:!1}]}}itemArrow(t){let n=t.children.filter(o=>!this.isBlankText(o));return n.length!==1||n[0].kind!=="Expression"?null:this.hole(n[0].hole).arrow??null}stripAndLower(t,n){let o={...t,attributes:t.attributes.filter(r=>!n(r))};return o.kind==="Element"?this.lowerElement(o):this.lowerComponent(o)}rebuildWithChildren(t,n){let o=this.lowerAttributes(t.attributes.filter(r=>r.kind!=="EachDirective"));return t.kind==="Element"?{kind:"element",tag:t.tag,svg:t.namespace==="svg",props:o,children:n,static:!1}:{kind:"component",name:t.tag,props:o,children:n}}lowerAttributes(t){let n=[],o=[],r=!1,s=[],i=!1,a=[];for(let l of t)switch(l.kind){case"IfDirective":case"EachDirective":case"ElseDirective":break;case"Attribute":n.push(this.plainAttr(l));break;case"PropertyBinding":n.push({name:l.name,kind:"prop",expr:this.hole(l.hole).code,reactive:this.hole(l.hole).reactive});break;case"EventBinding":n.push(this.eventProp(l));break;case"RefBinding":n.push({name:"ref",kind:"ref",expr:this.hole(l.hole).code,reactive:this.hole(l.hole).reactive});break;case"Spread":n.push({name:"",kind:"spread",expr:this.hole(l.hole).code});break;case"ClassDirective":{let c=this.hole(l.hole);o.push(`${JSON.stringify(l.name)}: ${c.code}`),r=r||c.reactive;break}case"StyleDirective":{let c=this.hole(l.hole);s.push(`${JSON.stringify(l.name)}: ${c.code}`),i=i||c.reactive;break}case"BindDirective":n.push(...this.bindProps(l.name,this.hole(l.hole).code));break;case"UseDirective":{let c=l.name??(l.hole!=null?this.hole(l.hole).code:null);if(!c)break;a.push(l.name!=null&&l.hole!=null?`[${c}, () => (${this.hole(l.hole).code})]`:`[${c}]`);break}}return o.length>0&&n.push({name:"classList",kind:"attr",expr:`{ ${o.join(", ")} }`,reactive:r}),s.length>0&&n.push({name:"style",kind:"attr",expr:`{ ${s.join(", ")} }`,reactive:i}),a.length>0&&n.push({name:"use",kind:"attr",expr:`[${a.join(", ")}]`}),n}eventProp(t){let n=t.name.toLowerCase(),o=this.hole(t.hole).code;if(!(t.syntax==="colon"||t.modifiers.length>0))return{name:"on"+ke(t.name),kind:"event",event:{name:n,delegated:Ne.has(n)},expr:o};let s=this.wrapHandler(o,t.modifiers),i=this.eventOptions(t.modifiers),a=i?`[${s}, ${i}]`:s;return{name:"on:"+n,kind:"attr",expr:a}}wrapHandler(t,n){let o=n.includes("self")?"if (e.target !== e.currentTarget) return; ":"",r=[];return n.includes("prevent")&&r.push("e.preventDefault();"),n.includes("stop")&&r.push("e.stopPropagation();"),!o&&r.length===0?t:`(e) => { ${o}${r.join(" ")} return (${t})(e); }`}eventOptions(t){let n=[];return t.includes("capture")&&n.push("capture: true"),t.includes("once")&&n.push("once: true"),t.includes("passive")&&n.push("passive: true"),n.length?`{ ${n.join(", ")} }`:null}bindProps(t,n){let o=t==="checked",r=o?"change":"input",s=o?"checked":"value",i=`(${n})`;return[{name:t,kind:"attr",expr:`${i}[0]()`,reactive:!0},{name:"on"+ke(r),kind:"event",event:{name:r,delegated:Ne.has(r)},expr:`(e) => ${i}[1](e.target.${s})`}]}plainAttr(t){let n=t.value,o=t.name;t.name==="class"?o=n&&n.kind==="hole"&&this.hole(n.hole).object?"classList":"className":t.name==="html"&&(o="innerHTML");let s={name:o,kind:"attr"};if(n==null)return s.literal=!0,s;if(n.kind==="static")return s.literal=n.value,s;if(n.kind==="hole"){let l=this.hole(n.hole);return s.expr=l.code,s.reactive=l.reactive,s}let i=!1,a=n.parts.map(l=>{if("text"in l)return ft(l.text);let c=this.hole(l.hole);return i=i||c.reactive,"${"+c.code+"}"}).join("");return s.expr="`"+a+"`",s.reactive=i,s}};function Se(e,t,n,o={}){let{root:r}=(0,Ee.parseTemplate)(e,{svg:o.svg});return new Q(t,n).lowerRoot(r.children)}function be(e,t,n={}){let o=new Set,r=Se(e,[...t],o,{svg:n.svg});x(r),_(r,{resolver:q(n.resolve??[]),modules:{controlFlowModule:n.controlFlowModule??"@fluixi/dom",coreModule:n.coreModule??"@fluixi/core",routerModule:n.routerModule??"@fluixi/core/router-next"},strategyFor:l=>l.load}),F(r);let{code:s,imports:i,templates:a}=k.emit(r,{templateClone:n.templateClone,partialTemplates:n.partialTemplates});for(let l of i)o.add(l);return n.hoistTemplates?{code:s,imports:[...o],ir:r,templates:a}:{code:z(s,a),imports:[...o],ir:r}}var gt="children";function E(e){switch(e.kind){case"call":return!0;case"member":return e.property!==gt;case"compound":return e.parts.some(E);case"opaque":return!1}}var ht=new Set(["CallExpression","OptionalCallExpression"]),vt=new Set(["MemberExpression","OptionalMemberExpression"]);function S(e){if(!e)return{kind:"opaque"};if(ht.has(e.type))return{kind:"call"};if(vt.has(e.type)){let t=e.property;return{kind:"member",property:!(e.computed===!0)&&t?.type==="Identifier"?t.name:null}}return e.type==="ConditionalExpression"?{kind:"compound",parts:[e.test,e.consequent,e.alternate].map(M)}:e.type==="LogicalExpression"||e.type==="BinaryExpression"?{kind:"compound",parts:[e.left,e.right].map(M)}:e.type==="TemplateLiteral"?{kind:"compound",parts:e.expressions.map(M)}:e.type==="ObjectExpression"?{kind:"compound",parts:e.properties.filter(n=>(n.type==="ObjectProperty"||n.type==="Property")&&n.computed!==!0).map(n=>M(n.value))}:e.type==="ArrayExpression"?{kind:"compound",parts:e.elements.filter(n=>n!=null&&n.type!=="SpreadElement").map(M)}:{kind:"opaque"}}var M=e=>S(e);var Rt=new Set(["svg","path","circle","rect","line","polygon","polyline","ellipse","g","defs","clipPath","text"]),yt=/^on[A-Z]/,xt=new Set(["click","dblclick","input","change","submit","focus","blur","keydown","keyup","keypress","mousedown","mouseup"]),we=e=>E(S(e));function O(e){if(e.type==="StringLiteral"||e.type==="NumericLiteral"||e.type==="BooleanLiteral"||e.type==="Literal"&&(typeof e.value=="string"||typeof e.value=="number"||typeof e.value=="boolean"))return e.value}var ee=e=>!!e&&typeof O(e)=="string";function Nt(e,t){return e.type==="JSXIdentifier"?{tag:e.name,component:e.name[0]!==e.name[0].toLowerCase()}:e.type==="JSXMemberExpression"?{tag:t.code(e),component:!0}:e.type==="JSXNamespacedName"?{tag:`${e.namespace.name}:${e.name.name}`,component:!1}:{tag:"div",component:!1}}function te(e){return e.type==="JSXIdentifier"?e.name==="class"?"className":e.name:e.type==="JSXNamespacedName"?`${e.namespace.name}:${e.name.name}`:"unknown"}function kt(e,t){let n=te(e.name),o=yt.test(n),r=o||n.startsWith("on:")||n==="ref",i={name:n,kind:o?"event":"attr"};if(o){let l=n.slice(2).toLowerCase();i.event={name:l,delegated:xt.has(l)}}let a=e.value;if(a==null)return i.literal=!0,i;if(ee(a))return i.literal=O(a),i;if(a.type==="JSXExpressionContainer"&&a.expression?.type!=="JSXEmptyExpression"){let l=a.expression,c=O(l);return c!==void 0?(i.literal=c,i):(i.expr=t.code(l),i.reactive=r?!1:we(l),(l.type==="JSXElement"||l.type==="JSXFragment")&&(i.jsxElement=!0),i)}return i.literal=!0,i}function Ce(e,t){let n=e.value;return n==null?null:ee(n)?JSON.stringify(O(n)):n.type==="JSXExpressionContainer"&&n.expression?.type!=="JSXEmptyExpression"?t.code(n.expression):null}function Et(e,t){let n=[],o=[];for(let r of e){if(r.type==="JSXSpreadAttribute"){n.push({name:"",kind:"spread",expr:t.code(r.argument)});continue}if(r.type!=="JSXAttribute"||U(te(r.name)))continue;let s=r.name.type==="JSXNamespacedName"?r.name.namespace.name:null;if(s==="use"){let i=r.name.name.name;t.used.add(i);let a=Ce(r,t);o.push(a!=null?`[${i}, () => (${a})]`:`[${i}]`);continue}if(s==="oncapture"){let i=r.name.name.name.toLowerCase(),a=Ce(r,t)??"undefined";n.push({name:"on:"+i,kind:"attr",expr:`[${a}, { capture: true }]`});continue}n.push(kt(r,t))}return o.length>0&&n.push({name:"use",kind:"attr",expr:`[${o.join(", ")}]`}),n}function Ie(e,t){let n=[];for(let o of e)if(o.type==="JSXText"){let r=$(o.value);r&&n.push({kind:"text",value:r})}else if(o.type==="JSXExpressionContainer"){if(o.expression?.type!=="JSXEmptyExpression"){let r=o.expression;n.push({kind:"expr",code:t.code(r),reactive:we(r)})}}else o.type==="JSXElement"||o.type==="JSXFragment"?n.push(Te(o,t)):o.type==="JSXSpreadChild"&&n.push({kind:"expr",code:t.code(o.expression),reactive:!1});return n}function St(e){for(let t of e){if(t.type!=="JSXAttribute")continue;let n=te(t.name);if(U(n)){if(t.value&&!ee(t.value))throw new v(`'${n}' needs a literal value, not an expression — the strategy is compile-time.`);return j(n,t.value?O(t.value):null)}}}function Te(e,t){if(e.type==="JSXFragment")return{kind:"fragment",children:Ie(e.children,t)};let{tag:n,component:o}=Nt(e.openingElement.name,t),r=Et(e.openingElement.attributes,t),s=Ie(e.children,t);if(o){let i=St(e.openingElement.attributes);return{kind:"component",name:n,props:r,children:s,...i?{load:i}:{}}}return{kind:"element",tag:n,svg:Rt.has(n),props:r,children:s,static:!1}}function $e(e,t){let n=Te(e,t);return x(n),n}function R(e,t){if(e)switch(e.type){case"Identifier":t.add(e.name);return;case"ObjectPattern":for(let n of e.properties)n.type==="RestElement"?R(n.argument,t):R(n.value,t);return;case"ArrayPattern":for(let n of e.elements)R(n,t);return;case"AssignmentPattern":R(e.left,t);return;case"RestElement":R(e.argument,t);return}}function Me(e,t){switch(e.type){case"ImportDeclaration":for(let n of e.specifiers)R(n.local,t);return;case"VariableDeclaration":for(let n of e.declarations)R(n.id,t);return;case"FunctionDeclaration":case"ClassDeclaration":R(e.id,t);return;case"ExportNamedDeclaration":case"ExportDefaultDeclaration":e.declaration&&Me(e.declaration,t);return}}function Oe(e){let t=new Set;for(let n of e.body)Me(n,t);return t}var bt=new Set(b),Ct=new Set(C),It=new Set(N),wt=new Set(["createMemo","createEffect","createRenderEffect","createRoot","createSignal","onCleanup","batch","untrack"]);function ne(e,t,n=null,o=""){if(!(!e||typeof e!="object")){if(Array.isArray(e)){for(let r of e)ne(r,t,n,o);return}typeof e.type=="string"&&t(e,n,o);for(let r of Object.keys(e))r==="loc"||r==="leadingComments"||r==="trailingComments"||ne(e[r],t,typeof e.type=="string"?e:n,r)}}var re=e=>e.type==="JSXElement"||e.type==="JSXFragment";function Tt(e,t,n){return re(e)?!(t&&re(t)&&n==="children"):!1}function $t(e,t){return e.type==="TaggedTemplateExpression"&&e.tag?.type==="Identifier"&&(e.tag.name===t||e.tag.name==="svg")}function Le(e){return e.filter(t=>!e.some(n=>n!==t&&n.start<=t.start&&n.end>=t.end&&n.end-n.start>t.end-t.start))}function V(e,t,n,o){let r=Le(o.filter(i=>i.start>=t&&i.end<=n)).sort((i,a)=>a.start-i.start),s=e.slice(t,n);for(let i of r)s=s.slice(0,i.start-t)+i.code+s.slice(i.end-t);return s}function Mt(e,t,n){let o={code:V(e,t.start,t.end,n),reactive:E(S(t))};return t.type==="ArrowFunctionExpression"&&t.body?.type!=="BlockStatement"&&(o.arrow={params:t.params.map(r=>V(e,r.start,r.end,n)),body:V(e,t.body.start,t.body.end,n),bodyReactive:E(S(t.body))}),t.type==="ObjectExpression"&&(o.object=!0),o}function Je(e,t,n){if(!t||t.length===0)return e;let o=new Map;for(let r of t){let s=`${r.svg?"svg:":""}${r.html}`,i=n.get(s);i||(i=`_fxTmpl$${n.size}`,n.set(s,i)),o.set(r.id,i)}return e.replace(/_tmpl\$\d+/g,r=>o.get(r)??r)}function oe(e,t){if(e.kind==="component"&&e.source){let n=e.source;n.origin==="builtin"?t.builtins.add(e.name):D(n.loading)&&!t.resolved.has(e.name)?t.deferred.set(e.name,n):(t.deferred.delete(e.name),t.resolved.set(e.name,n))}if("props"in e&&e.props)for(let n of e.props)n.kind==="event"&&n.event?.delegated&&t.delegatedEvents.add(n.event.name);if("children"in e&&e.children)for(let n of e.children)oe(n,t)}function Ot(e){let t=[`kind: ${JSON.stringify(e.kind)}`];return e.kind==="visible"&&e.rootMargin&&t.push(`rootMargin: ${JSON.stringify(e.rootMargin)}`),e.kind==="interaction"&&t.push(`events: ${JSON.stringify(e.events)}`),e.kind==="media"&&t.push(`query: ${JSON.stringify(e.query)}`),`{ ${t.join(", ")} }`}function Pt(e){let t=[];return e.quasi.quasis.forEach((n,o)=>{if(t.push({kind:"static",text:n.value.cooked??n.value.raw,start:n.start}),o<e.quasi.expressions.length){let r=e.quasi.expressions[o];t.push({kind:"hole",index:o,start:r.start,end:r.end})}}),t}function At(e,t,n={}){let o=n.litTag??"html",r=n.format??"both",s=r!=="jsx",i=r!=="lit";if(!(s&&(e.includes(`${o}\``)||e.includes("svg`")))&&!(i&&e.includes("<")))return null;let l=(0,Pe.parse)(e,{sourceType:"module",plugins:["jsx","typescript"],errorRecovery:!0}),c=[];if(ne(l.program,(m,y,W)=>{(s&&$t(m,o)||i&&Tt(m,y,W))&&c.push(m)}),c.length===0)return null;c.sort((m,y)=>y.start-m.start||m.end-y.end);let u=new Set,d={builtins:new Set,resolved:new Map,deferred:new Map,delegatedEvents:new Set},p=new Map,f=[];for(let m of c){let y=c.some(h=>h!==m&&h.start<=m.start&&h.end>=m.end&&h.end-h.start>m.end-m.start);if(re(m)){f.push({start:m.start,end:m.end,code:Lt(e,m,f,y,u,d,p,n)});continue}let W=m.quasi.expressions.map(h=>Mt(e,h,f)),A=be(Pt(m),W,{...n,hoistTemplates:!0,templateClone:n.templateClone??!0,partialTemplates:y?!1:n.partialTemplates??!0,svg:m.tag.name==="svg"});for(let h of A.imports)u.add(h);oe(A.ir,d),f.push({start:m.start,end:m.end,code:Je(A.code,A.templates,p)})}let g=new Ae.default(e);for(let m of Le(f))g.overwrite(m.start,m.end,m.code);let P=Oe(l.program),ie=Jt(u,d,p,P,n);ie&&g.prepend(ie);for(let m of l.program.body)m.type==="ImportDeclaration"&&m.source?.value==="@fluixi/core/rx"&&g.overwrite(m.source.start,m.source.end,JSON.stringify("@fluixi/reactive"));return{code:g.toString(),map:g.generateMap({source:t,includeContent:!0,hires:!0})}}function Lt(e,t,n,o,r,s,i,a){let l=$e(t,{code:u=>V(e,u.start,u.end,n),used:r});x(l),_(l,{resolver:q(a.resolve??[]),modules:{controlFlowModule:a.controlFlowModule??a.runtimeModule??"@fluixi/dom",coreModule:a.coreModule??"@fluixi/core",routerModule:a.routerModule??"@fluixi/core/router-next"},strategyFor:u=>u.load}),F(l);let c=k.emit(l,{templateClone:a.templateClone??!0,partialTemplates:o?!1:a.partialTemplates??!0});for(let u of c.imports)r.add(u);return oe(l,s),Je(c.code,c.templates,i)}function Jt(e,t,n,o,r){let s=r.runtimeModule??"@fluixi/dom",i=r.coreModule??"@fluixi/core",a=new Map,l=(p,f)=>a.set(p,[...a.get(p)??[],f]),c=new Set(e);for(let p of t.builtins)c.add(p);t.delegatedEvents.size>0&&c.add("delegateEvents");for(let p of[...c].sort())o.has(p)||(wt.has(p)?l(r.reactiveModule??"@fluixi/reactive/signal",p):It.has(p)?l(r.routerModule??"@fluixi/core/router-next",p):Ct.has(p)?l(i,p):bt.has(p)?l(r.controlFlowModule??s,p):l(s,p));for(let[p,f]of t.resolved)o.has(p)||l(f.module,f.export==="default"?`default as ${p}`:p===f.export?p:`${f.export} as ${p}`);let u=[];for(let[p,f]of a)u.push(`import { ${f.join(", ")} } from ${JSON.stringify(p)};`);let d=[...t.deferred].filter(([p])=>!o.has(p));if(d.length>0){o.has("deferred")||u.push(`import { deferred } from ${JSON.stringify(i)};`);for(let[p,f]of d)u.push(`const ${p} = deferred(() => import(${JSON.stringify(f.module)}), { strategy: ${Ot(f.loading)}, export: ${JSON.stringify(f.export)} });`)}for(let[p,f]of n)u.push(`const ${f} = ${JSON.stringify(p.startsWith("svg:")?p.slice(4):p)};`);return t.delegatedEvents.size>0&&u.push(`delegateEvents(${JSON.stringify([...t.delegatedEvents])});`),u.length>0?u.join(`
|
|
2
|
+
`)+`
|
|
3
|
+
`:null}
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import MagicString from 'magic-string';
|
|
2
|
+
import { type CompileTemplateOptions } from '../lower/compile-template.js';
|
|
3
|
+
export interface TransformOptions extends CompileTemplateOptions {
|
|
4
|
+
/**
|
|
5
|
+
* Which authoring syntaxes to compile. Both lower to the same IR, so this is
|
|
6
|
+
* about which source forms are touched, not about output.
|
|
7
|
+
* @default 'both'
|
|
8
|
+
*/
|
|
9
|
+
format?: 'jsx' | 'lit' | 'both';
|
|
10
|
+
/** Tag marking a template for compilation. @default 'html' */
|
|
11
|
+
litTag?: string;
|
|
12
|
+
/** Module the emitted runtime symbols are imported from. @default '@fluixi/dom' */
|
|
13
|
+
runtimeModule?: string;
|
|
14
|
+
/** Where reactive primitives come from. @default '@fluixi/reactive/signal' */
|
|
15
|
+
reactiveModule?: string;
|
|
16
|
+
}
|
|
17
|
+
export interface TransformResult {
|
|
18
|
+
code: string;
|
|
19
|
+
map: ReturnType<MagicString['generateMap']>;
|
|
20
|
+
}
|
|
21
|
+
/**
|
|
22
|
+
* Compile every template in `code`. Returns null when the module has none, so a
|
|
23
|
+
* bundler can skip the file untouched.
|
|
24
|
+
*/
|
|
25
|
+
export declare function transformTemplates(code: string, id: string, options?: TransformOptions): TransformResult | null;
|
|
26
|
+
//# sourceMappingURL=templates.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"templates.d.ts","sourceRoot":"","sources":["../../src/transform/templates.ts"],"names":[],"mappings":"AASA,OAAO,WAAW,MAAM,cAAc,CAAC;AAEvC,OAAO,EAAiB,KAAK,sBAAsB,EAAE,MAAM,8BAA8B,CAAC;AA8B1F,MAAM,WAAW,gBAAiB,SAAQ,sBAAsB;IAC9D;;;;OAIG;IACH,MAAM,CAAC,EAAE,KAAK,GAAG,KAAK,GAAG,MAAM,CAAC;IAChC,8DAA8D;IAC9D,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,mFAAmF;IACnF,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,8EAA8E;IAC9E,cAAc,CAAC,EAAE,MAAM,CAAC;CACzB;AAED,MAAM,WAAW,eAAe;IAC9B,IAAI,EAAE,MAAM,CAAC;IACb,GAAG,EAAE,UAAU,CAAC,WAAW,CAAC,aAAa,CAAC,CAAC,CAAC;CAC7C;AAkLD;;;GAGG;AACH,wBAAgB,kBAAkB,CAChC,IAAI,EAAE,MAAM,EACZ,EAAE,EAAE,MAAM,EACV,OAAO,GAAE,gBAAqB,GAC7B,eAAe,GAAG,IAAI,CA0ExB"}
|
|
@@ -0,0 +1,347 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Compile `` html`...` `` / `` svg`...` `` templates in a module.
|
|
3
|
+
*
|
|
4
|
+
* We own the transform here rather than running as a plugin inside someone
|
|
5
|
+
* else's: parse once, find the templates, splice the emitted code over their
|
|
6
|
+
* spans with magic-string. Holes are source slices, so nothing is reprinted and
|
|
7
|
+
* the output keeps the author's formatting; the map comes out of the splice.
|
|
8
|
+
*/
|
|
9
|
+
import { parse } from '@babel/parser';
|
|
10
|
+
import MagicString from 'magic-string';
|
|
11
|
+
import { compilePieces } from '../lower/compile-template.js';
|
|
12
|
+
import { isDeferred } from '../resolve/load-directive.js';
|
|
13
|
+
import { isReactiveShape } from '../analyze/reactive-expr.js';
|
|
14
|
+
import { shapeOf } from '../analyze/expr-shape.js';
|
|
15
|
+
import { buildJsxIR } from '../lower/jsx.js';
|
|
16
|
+
import { analyzeStatic } from '../optimize/analyze-static.js';
|
|
17
|
+
import { collapseStrategies } from '../optimize/collapse-strategies.js';
|
|
18
|
+
import { resolveComponentSources } from '../resolve/resolve-ir.js';
|
|
19
|
+
import { createComponentResolver } from '../resolve/component-resolver.js';
|
|
20
|
+
import { imperativeBackend } from '../codegen/backends/imperative.js';
|
|
21
|
+
import { moduleBindings } from './bindings.js';
|
|
22
|
+
import { DOM_CONTROL_FLOW, CORE_CONTROL_FLOW, ROUTER_COMPONENTS } from '../resolve/builtins.js';
|
|
23
|
+
// Which builtin comes from which module is published by resolve/builtins.ts —
|
|
24
|
+
// the same lists the resolve pass and the TS plugin read. Restating them here is
|
|
25
|
+
// how `Await` ended up imported from the dom runtime, which does not export it.
|
|
26
|
+
const CONTROL_FLOW = new Set(DOM_CONTROL_FLOW);
|
|
27
|
+
const CORE_ONLY = new Set(CORE_CONTROL_FLOW);
|
|
28
|
+
const ROUTER = new Set(ROUTER_COMPONENTS);
|
|
29
|
+
const REACTIVE = new Set([
|
|
30
|
+
'createMemo', 'createEffect', 'createRenderEffect', 'createRoot',
|
|
31
|
+
'createSignal', 'onCleanup', 'batch', 'untrack',
|
|
32
|
+
]);
|
|
33
|
+
/** Depth-first walk, carrying the parent and the field the node came from. */
|
|
34
|
+
function walk(node, visit, parent = null, key = '') {
|
|
35
|
+
if (!node || typeof node !== 'object')
|
|
36
|
+
return;
|
|
37
|
+
if (Array.isArray(node)) {
|
|
38
|
+
for (const child of node)
|
|
39
|
+
walk(child, visit, parent, key);
|
|
40
|
+
return;
|
|
41
|
+
}
|
|
42
|
+
if (typeof node.type === 'string')
|
|
43
|
+
visit(node, parent, key);
|
|
44
|
+
for (const k of Object.keys(node)) {
|
|
45
|
+
if (k === 'loc' || k === 'leadingComments' || k === 'trailingComments')
|
|
46
|
+
continue;
|
|
47
|
+
walk(node[k], visit, typeof node.type === 'string' ? node : parent, k);
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
const isJsx = (node) => node.type === 'JSXElement' || node.type === 'JSXFragment';
|
|
51
|
+
/**
|
|
52
|
+
* A JSX node the transform compiles on its own.
|
|
53
|
+
*
|
|
54
|
+
* A direct child — `<li>` in `<ul><li/></ul>` — is not one: the builder recurses
|
|
55
|
+
* into it, and compiling it separately would splice its output into the middle of
|
|
56
|
+
* its parent's. JSX reached through an expression or an attribute value *is* one,
|
|
57
|
+
* because the builder asks for that expression as source text and needs it
|
|
58
|
+
* already compiled.
|
|
59
|
+
*/
|
|
60
|
+
function isJsxRoot(node, parent, key) {
|
|
61
|
+
if (!isJsx(node))
|
|
62
|
+
return false;
|
|
63
|
+
return !(parent && isJsx(parent) && key === 'children');
|
|
64
|
+
}
|
|
65
|
+
function isTemplateTag(node, litTag) {
|
|
66
|
+
return (node.type === 'TaggedTemplateExpression' &&
|
|
67
|
+
node.tag?.type === 'Identifier' &&
|
|
68
|
+
(node.tag.name === litTag || node.tag.name === 'svg'));
|
|
69
|
+
}
|
|
70
|
+
/** The edits in `list` that no other edit in `list` contains. */
|
|
71
|
+
function outermost(list) {
|
|
72
|
+
return list.filter((e) => !list.some((o) => o !== e && o.start <= e.start && o.end >= e.end && o.end - o.start > e.end - e.start));
|
|
73
|
+
}
|
|
74
|
+
/**
|
|
75
|
+
* Apply edits to a slice of the source.
|
|
76
|
+
*
|
|
77
|
+
* Only the outermost ones: a contained edit was already folded into its
|
|
78
|
+
* container's emitted code, and applying both would splice it twice — the second
|
|
79
|
+
* write landing at an offset the first has already moved.
|
|
80
|
+
*/
|
|
81
|
+
function slice(code, start, end, edits) {
|
|
82
|
+
const inside = outermost(edits.filter((e) => e.start >= start && e.end <= end))
|
|
83
|
+
.sort((a, b) => b.start - a.start);
|
|
84
|
+
let out = code.slice(start, end);
|
|
85
|
+
for (const e of inside)
|
|
86
|
+
out = out.slice(0, e.start - start) + e.code + out.slice(e.end - start);
|
|
87
|
+
return out;
|
|
88
|
+
}
|
|
89
|
+
/** Describe one `${…}` for the lowering, substituting any template already compiled inside it. */
|
|
90
|
+
function bindHole(code, expr, edits) {
|
|
91
|
+
const hole = {
|
|
92
|
+
code: slice(code, expr.start, expr.end, edits),
|
|
93
|
+
reactive: isReactiveShape(shapeOf(expr)),
|
|
94
|
+
};
|
|
95
|
+
if (expr.type === 'ArrowFunctionExpression' && expr.body?.type !== 'BlockStatement') {
|
|
96
|
+
hole.arrow = {
|
|
97
|
+
params: expr.params.map((p) => slice(code, p.start, p.end, edits)),
|
|
98
|
+
body: slice(code, expr.body.start, expr.body.end, edits),
|
|
99
|
+
bodyReactive: isReactiveShape(shapeOf(expr.body)),
|
|
100
|
+
};
|
|
101
|
+
}
|
|
102
|
+
if (expr.type === 'ObjectExpression')
|
|
103
|
+
hole.object = true;
|
|
104
|
+
return hole;
|
|
105
|
+
}
|
|
106
|
+
/**
|
|
107
|
+
* What the emitted code needs beyond the runtime symbols the backend reports:
|
|
108
|
+
* component references the resolve pass annotated, and the events it wants
|
|
109
|
+
* delegated. Both live on the IR rather than in the emit result.
|
|
110
|
+
*/
|
|
111
|
+
/**
|
|
112
|
+
* Static templates hoisted to module scope, keyed by their HTML so two components
|
|
113
|
+
* with the same markup share one string.
|
|
114
|
+
*
|
|
115
|
+
* Hoisted names deliberately do not use the backend's `_tmpl$N` namespace. Roots
|
|
116
|
+
* are emitted innermost first and spliced into their parent, so by the time the
|
|
117
|
+
* outer one is renamed its code already contains hoisted names — and with a
|
|
118
|
+
* shared prefix the rename rewrites those too, pointing two templates at one
|
|
119
|
+
* string. A separate prefix makes the two impossible to confuse.
|
|
120
|
+
*/
|
|
121
|
+
function adoptTemplates(code, templates, hoisted) {
|
|
122
|
+
if (!templates || templates.length === 0)
|
|
123
|
+
return code;
|
|
124
|
+
const rename = new Map();
|
|
125
|
+
for (const tpl of templates) {
|
|
126
|
+
const key = `${tpl.svg ? 'svg:' : ''}${tpl.html}`;
|
|
127
|
+
let name = hoisted.get(key);
|
|
128
|
+
if (!name) {
|
|
129
|
+
name = `_fxTmpl$${hoisted.size}`;
|
|
130
|
+
hoisted.set(key, name);
|
|
131
|
+
}
|
|
132
|
+
rename.set(tpl.id, name);
|
|
133
|
+
}
|
|
134
|
+
return code.replace(/_tmpl\$\d+/g, (id) => rename.get(id) ?? id);
|
|
135
|
+
}
|
|
136
|
+
function collectNeeds(node, out) {
|
|
137
|
+
if (node.kind === 'component' && node.source) {
|
|
138
|
+
const src = node.source;
|
|
139
|
+
if (src.origin === 'builtin')
|
|
140
|
+
out.builtins.add(node.name);
|
|
141
|
+
else if (isDeferred(src.loading) && !out.resolved.has(node.name))
|
|
142
|
+
out.deferred.set(node.name, src);
|
|
143
|
+
else {
|
|
144
|
+
out.deferred.delete(node.name);
|
|
145
|
+
out.resolved.set(node.name, src);
|
|
146
|
+
}
|
|
147
|
+
}
|
|
148
|
+
if ('props' in node && node.props) {
|
|
149
|
+
for (const p of node.props) {
|
|
150
|
+
if (p.kind === 'event' && p.event?.delegated)
|
|
151
|
+
out.delegatedEvents.add(p.event.name);
|
|
152
|
+
}
|
|
153
|
+
}
|
|
154
|
+
if ('children' in node && node.children)
|
|
155
|
+
for (const c of node.children)
|
|
156
|
+
collectNeeds(c, out);
|
|
157
|
+
}
|
|
158
|
+
/** The strategy object a `deferred()` binding is given. */
|
|
159
|
+
function strategyLiteral(s) {
|
|
160
|
+
const parts = [`kind: ${JSON.stringify(s.kind)}`];
|
|
161
|
+
if (s.kind === 'visible' && s.rootMargin)
|
|
162
|
+
parts.push(`rootMargin: ${JSON.stringify(s.rootMargin)}`);
|
|
163
|
+
if (s.kind === 'interaction')
|
|
164
|
+
parts.push(`events: ${JSON.stringify(s.events)}`);
|
|
165
|
+
if (s.kind === 'media')
|
|
166
|
+
parts.push(`query: ${JSON.stringify(s.query)}`);
|
|
167
|
+
return `{ ${parts.join(', ')} }`;
|
|
168
|
+
}
|
|
169
|
+
/** Quasis and holes as position-carrying parser pieces. */
|
|
170
|
+
function toPieces(node) {
|
|
171
|
+
const pieces = [];
|
|
172
|
+
node.quasi.quasis.forEach((q, i) => {
|
|
173
|
+
pieces.push({ kind: 'static', text: q.value.cooked ?? q.value.raw, start: q.start });
|
|
174
|
+
if (i < node.quasi.expressions.length) {
|
|
175
|
+
const e = node.quasi.expressions[i];
|
|
176
|
+
pieces.push({ kind: 'hole', index: i, start: e.start, end: e.end });
|
|
177
|
+
}
|
|
178
|
+
});
|
|
179
|
+
return pieces;
|
|
180
|
+
}
|
|
181
|
+
/**
|
|
182
|
+
* Compile every template in `code`. Returns null when the module has none, so a
|
|
183
|
+
* bundler can skip the file untouched.
|
|
184
|
+
*/
|
|
185
|
+
export function transformTemplates(code, id, options = {}) {
|
|
186
|
+
const litTag = options.litTag ?? 'html';
|
|
187
|
+
const format = options.format ?? 'both';
|
|
188
|
+
const wantsLit = format !== 'jsx';
|
|
189
|
+
const wantsJsx = format !== 'lit';
|
|
190
|
+
const mayHaveTemplate = wantsLit && (code.includes(`${litTag}\``) || code.includes('svg`'));
|
|
191
|
+
if (!mayHaveTemplate && !(wantsJsx && code.includes('<')))
|
|
192
|
+
return null;
|
|
193
|
+
const ast = parse(code, {
|
|
194
|
+
sourceType: 'module',
|
|
195
|
+
plugins: ['jsx', 'typescript'],
|
|
196
|
+
errorRecovery: true,
|
|
197
|
+
});
|
|
198
|
+
const found = [];
|
|
199
|
+
walk(ast.program, (n, parent, key) => {
|
|
200
|
+
if (wantsLit && isTemplateTag(n, litTag))
|
|
201
|
+
found.push(n);
|
|
202
|
+
else if (wantsJsx && isJsxRoot(n, parent, key))
|
|
203
|
+
found.push(n);
|
|
204
|
+
});
|
|
205
|
+
if (found.length === 0)
|
|
206
|
+
return null;
|
|
207
|
+
// Innermost first, so a nested template is already compiled by the time the
|
|
208
|
+
// hole containing it is sliced.
|
|
209
|
+
found.sort((a, b) => b.start - a.start || a.end - b.end);
|
|
210
|
+
const used = new Set();
|
|
211
|
+
const needs = {
|
|
212
|
+
builtins: new Set(), resolved: new Map(), deferred: new Map(), delegatedEvents: new Set(),
|
|
213
|
+
};
|
|
214
|
+
const hoisted = new Map();
|
|
215
|
+
const edits = [];
|
|
216
|
+
for (const node of found) {
|
|
217
|
+
// A root inside another root's hole is emitted without partial templates,
|
|
218
|
+
// matching what the plugin does for nested emits. Marker layout has to agree
|
|
219
|
+
// between server and client, so this is not the place to change it.
|
|
220
|
+
const nested = found.some((o) => o !== node && o.start <= node.start && o.end >= node.end && o.end - o.start > node.end - node.start);
|
|
221
|
+
if (isJsx(node)) {
|
|
222
|
+
edits.push({ start: node.start, end: node.end, code: compileJsx(code, node, edits, nested, used, needs, hoisted, options) });
|
|
223
|
+
continue;
|
|
224
|
+
}
|
|
225
|
+
const holes = node.quasi.expressions.map((e) => bindHole(code, e, edits));
|
|
226
|
+
const result = compilePieces(toPieces(node), holes, {
|
|
227
|
+
...options,
|
|
228
|
+
hoistTemplates: true,
|
|
229
|
+
// Same defaults as the plugin, so moving a build over is not a rendering change.
|
|
230
|
+
templateClone: options.templateClone ?? true,
|
|
231
|
+
partialTemplates: nested ? false : options.partialTemplates ?? true,
|
|
232
|
+
svg: node.tag.name === 'svg',
|
|
233
|
+
});
|
|
234
|
+
for (const symbol of result.imports)
|
|
235
|
+
used.add(symbol);
|
|
236
|
+
collectNeeds(result.ir, needs);
|
|
237
|
+
edits.push({ start: node.start, end: node.end, code: adoptTemplates(result.code, result.templates, hoisted) });
|
|
238
|
+
}
|
|
239
|
+
const out = new MagicString(code);
|
|
240
|
+
// Same reason as in `slice`: a nested edit is already inside its parent's code.
|
|
241
|
+
for (const e of outermost(edits))
|
|
242
|
+
out.overwrite(e.start, e.end, e.code);
|
|
243
|
+
const bound = moduleBindings(ast.program);
|
|
244
|
+
const prologue = buildPrologue(used, needs, hoisted, bound, options);
|
|
245
|
+
if (prologue)
|
|
246
|
+
out.prepend(prologue);
|
|
247
|
+
// `@fluixi/core/rx` is the client alias for the reactive primitives.
|
|
248
|
+
for (const node of ast.program.body) {
|
|
249
|
+
if (node.type === 'ImportDeclaration' && node.source?.value === '@fluixi/core/rx') {
|
|
250
|
+
out.overwrite(node.source.start, node.source.end, JSON.stringify('@fluixi/reactive'));
|
|
251
|
+
}
|
|
252
|
+
}
|
|
253
|
+
return {
|
|
254
|
+
code: out.toString(),
|
|
255
|
+
map: out.generateMap({ source: id, includeContent: true, hires: true }),
|
|
256
|
+
};
|
|
257
|
+
}
|
|
258
|
+
/**
|
|
259
|
+
* A JSX root, emitted the same way a template is. Expressions are source slices
|
|
260
|
+
* with anything already compiled inside them folded in, so nested JSX and nested
|
|
261
|
+
* `` html`` `` both come along for free.
|
|
262
|
+
*/
|
|
263
|
+
function compileJsx(code, node, edits, nested, used, needs, hoisted, options) {
|
|
264
|
+
const ir = buildJsxIR(node, {
|
|
265
|
+
code: (n) => slice(code, n.start, n.end, edits),
|
|
266
|
+
used,
|
|
267
|
+
});
|
|
268
|
+
analyzeStatic(ir);
|
|
269
|
+
resolveComponentSources(ir, {
|
|
270
|
+
resolver: createComponentResolver(options.resolve ?? []),
|
|
271
|
+
modules: {
|
|
272
|
+
controlFlowModule: options.controlFlowModule ?? options.runtimeModule ?? '@fluixi/dom',
|
|
273
|
+
coreModule: options.coreModule ?? '@fluixi/core',
|
|
274
|
+
routerModule: options.routerModule ?? '@fluixi/core/router-next',
|
|
275
|
+
},
|
|
276
|
+
strategyFor: (n) => n.load,
|
|
277
|
+
});
|
|
278
|
+
collapseStrategies(ir);
|
|
279
|
+
const emitted = imperativeBackend.emit(ir, {
|
|
280
|
+
templateClone: options.templateClone ?? true,
|
|
281
|
+
partialTemplates: nested ? false : options.partialTemplates ?? true,
|
|
282
|
+
});
|
|
283
|
+
for (const symbol of emitted.imports)
|
|
284
|
+
used.add(symbol);
|
|
285
|
+
collectNeeds(ir, needs);
|
|
286
|
+
return adoptTemplates(emitted.code, emitted.templates, hoisted);
|
|
287
|
+
}
|
|
288
|
+
/**
|
|
289
|
+
* Everything the emitted code needs at the top of the module: runtime imports,
|
|
290
|
+
* imports for components a resolve rule supplied, `deferred()` bindings for the
|
|
291
|
+
* lazy ones, and the delegateEvents call. A name already bound in the file wins,
|
|
292
|
+
* so enabling resolution can never change what an existing module means.
|
|
293
|
+
*/
|
|
294
|
+
function buildPrologue(used, needs, hoisted, bound, options) {
|
|
295
|
+
const runtime = options.runtimeModule ?? '@fluixi/dom';
|
|
296
|
+
const core = options.coreModule ?? '@fluixi/core';
|
|
297
|
+
const groups = new Map();
|
|
298
|
+
const add = (mod, name) => groups.set(mod, [...(groups.get(mod) ?? []), name]);
|
|
299
|
+
const wanted = new Set(used);
|
|
300
|
+
for (const name of needs.builtins)
|
|
301
|
+
wanted.add(name);
|
|
302
|
+
if (needs.delegatedEvents.size > 0)
|
|
303
|
+
wanted.add('delegateEvents');
|
|
304
|
+
for (const name of [...wanted].sort()) {
|
|
305
|
+
if (bound.has(name))
|
|
306
|
+
continue;
|
|
307
|
+
if (REACTIVE.has(name))
|
|
308
|
+
add(options.reactiveModule ?? '@fluixi/reactive/signal', name);
|
|
309
|
+
else if (ROUTER.has(name))
|
|
310
|
+
add(options.routerModule ?? '@fluixi/core/router-next', name);
|
|
311
|
+
else if (CORE_ONLY.has(name))
|
|
312
|
+
add(core, name);
|
|
313
|
+
else if (CONTROL_FLOW.has(name))
|
|
314
|
+
add(options.controlFlowModule ?? runtime, name);
|
|
315
|
+
else
|
|
316
|
+
add(runtime, name);
|
|
317
|
+
}
|
|
318
|
+
for (const [name, src] of needs.resolved) {
|
|
319
|
+
if (!bound.has(name))
|
|
320
|
+
add(src.module, src.export === 'default' ? `default as ${name}` : name === src.export ? name : `${src.export} as ${name}`);
|
|
321
|
+
}
|
|
322
|
+
const lines = [];
|
|
323
|
+
for (const [mod, names] of groups) {
|
|
324
|
+
lines.push(`import { ${names.join(', ')} } from ${JSON.stringify(mod)};`);
|
|
325
|
+
}
|
|
326
|
+
// A literal import() is what lets the bundler split and hash the chunk, so the
|
|
327
|
+
// deferred component is an ordinary binding rather than an integration.
|
|
328
|
+
const lazy = [...needs.deferred].filter(([name]) => !bound.has(name));
|
|
329
|
+
if (lazy.length > 0) {
|
|
330
|
+
if (!bound.has('deferred'))
|
|
331
|
+
lines.push(`import { deferred } from ${JSON.stringify(core)};`);
|
|
332
|
+
for (const [name, src] of lazy) {
|
|
333
|
+
lines.push(`const ${name} = deferred(() => import(${JSON.stringify(src.module)}), ` +
|
|
334
|
+
`{ strategy: ${strategyLiteral(src.loading)}, export: ${JSON.stringify(src.export)} });`);
|
|
335
|
+
}
|
|
336
|
+
}
|
|
337
|
+
// Just the HTML: parsing is deferred to `templateNode`, which knows whether this
|
|
338
|
+
// is a server render, a hydration or a fresh client render. A module-scope
|
|
339
|
+
// `createTemplate` would touch `document` at import time and break SSR.
|
|
340
|
+
for (const [key, name] of hoisted) {
|
|
341
|
+
lines.push(`const ${name} = ${JSON.stringify(key.startsWith('svg:') ? key.slice(4) : key)};`);
|
|
342
|
+
}
|
|
343
|
+
if (needs.delegatedEvents.size > 0) {
|
|
344
|
+
lines.push(`delegateEvents(${JSON.stringify([...needs.delegatedEvents])});`);
|
|
345
|
+
}
|
|
346
|
+
return lines.length > 0 ? lines.join('\n') + '\n' : null;
|
|
347
|
+
}
|