@muten/core 0.0.4 → 0.0.5
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.
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import{tokenClass as Z,resolveToken as ge,defaultTheme as _e}from"#engine/style/tokens.js";import{Nt as l,Ek as de,Fmt as y,Fk as q}from"#engine/shared/vocab.js";import{customValue as ye,CONTAINERS as ee,parseClause as be,editableFields as Se}from"#engine/compile/helpers.js";import{emitStore as Ne,emitStatic as Ce,emitStaticHtml as Ee,emitSsr as ve,emitModule as Oe,emitHtml as xe}from"#engine/compile/emit.js";import{Logic as ke}from"#engine/compile/logic.js";function Te(m,x={},k="",w={},J={},$={}){return te(m,x,k,w,J,{...$,format:y.Module})}function Fe(m={},x={},k={}){const{state:w={},gets:J={},actions:$={},effects:d=[],entities:N={}}=m;return te({screen:"store",entities:N,state:w,actions:$,gets:J,effects:d,consts:{},constraints:{},rootId:void 0,nodes:{}},x,"",{},k,{format:y.Store})}function te(m,x={},k="",w={},J={},$={}){const{nodes:d,rootId:N,state:j,entities:A,screen:ne}=m,B=$.theme||_e;let t=[],M=!1;const H=e=>{const s=t;t=[],e();const o=t;return t=s,o},W=new Set,h=(e,s)=>{for(const o of s.style||[])W.add(o);return[e,...(s.style||[]).map(Z),...(s.class||[]).filter(o=>typeof o=="string")].join(" ")},se=new Set(Object.keys(j)),K=new Set(Object.entries(j).filter(([,e])=>typeof e.source=="string"&&e.source.startsWith("query:")).map(([e])=>e)),U=new Set,oe={state:j,entities:A,actions:m.actions,consts:m.consts||{},gets:m.gets||{},effects:m.effects||[],stateKeys:se,queryStates:K,stores:$.stores||{},usedStores:U,params:new Set(m.params||[]),format:$.format},u=new ke(oe),C={locals:new Set},E=(e,s)=>{for(const o of s.class||[])typeof o!="string"&&t.push(`effect(() => el_${e}.classList.toggle(${JSON.stringify(o.name)}, !!(${u.compileExpr(o.cond,C)})));`);for(const[o,n]of Object.entries(s.on||{}))typeof n=="string"&&t.push(`el_${e}.addEventListener(${JSON.stringify(o)}, () => ${u.actionRef(n)}());`)},D=(e,s)=>{for(const o of d[e].children)G(o,s)},z=e=>e.parts.map(s=>typeof s=="string"?JSON.stringify(s):`String(${u.compileExpr(s,C)} ?? '')`).join(" + ");function R(e,s,o,n,f){if(t.push(`const el_${e} = document.createElement('${s}');`),t.push(`el_${e}.className = ${JSON.stringify(o)};`),typeof n=="string")t.push(`el_${e}.textContent = ${JSON.stringify(n)};`);else if(n&&"kind"in n){const c=z(n),i=n.parts.some(p=>typeof p!="string");t.push(i?`effect(() => { el_${e}.textContent = ${c}; });`:`el_${e}.textContent = ${c};`)}t.push(`${f}.appendChild(el_${e});`)}function L(e,s,o){if(typeof o=="string")t.push(`el_${e}.${s} = ${JSON.stringify(o)};`);else if(o&&"kind"in o){const n=z(o),f=o.parts.some(c=>typeof c!="string");t.push(f?`effect(() => { el_${e}.${s} = ${n}; });`:`el_${e}.${s} = ${n};`)}}function G(e,s){const o=d[e],n=o.props||{},f=ee[o.type];if(f){const[c,i]=f;t.push(`const el_${e} = document.createElement('${c}');`),t.push(`el_${e}.className = ${JSON.stringify(h(i,n))};`),o.type===l.Nav&&typeof n.label=="string"&&t.push(`el_${e}.setAttribute('aria-label', ${JSON.stringify(n.label)});`),t.push(`${s}.appendChild(el_${e});`),E(e,n),D(e,`el_${e}`);return}switch(o.type){case l.SearchField:{const c=u.bindSig(n.bind);t.push(`const el_${e} = document.createElement('input');`),t.push(`el_${e}.type = 'search';`),t.push(`el_${e}.className = ${JSON.stringify(h("search",n))};`),typeof n.placeholder=="string"&&t.push(`el_${e}.placeholder = ${JSON.stringify(n.placeholder)};`),t.push(`el_${e}.value = ${c}.get();`),t.push(`el_${e}.addEventListener('input', (e) => ${c}.set(e.target.value));`),t.push(`${s}.appendChild(el_${e});`);break}case l.DataTable:{const c=u.bindSig(n.data),i=K.has(c)?`${c}.get().data`:`${c}.get()`,p=n.columns||[],_=(n.where||[]).map(be),F=_.filter(r=>!r.dynamic).map(r=>`.filter((row) => ${r.expr})`).join(""),b=_.filter(r=>r.dynamic).map(r=>`.filter((row) => ${r.expr})`).join(""),a=o.children.map(r=>d[r]).filter(r=>r.type===l.RowAction);t.push(`const el_${e} = document.createElement('table');`),t.push(`el_${e}.className = ${JSON.stringify(h("datatable",n))};`),t.push(`const head_${e} = el_${e}.createTHead().insertRow();`);for(const r of p)t.push(`{ const th = document.createElement('th'); th.textContent = ${JSON.stringify(r)}; head_${e}.appendChild(th); }`);a.length&&t.push(`head_${e}.appendChild(document.createElement('th'));`),t.push(`const body_${e} = el_${e}.createTBody();`),t.push(`${s}.appendChild(el_${e});`),t.push(`function renderRow_${e}(row) {`),t.push(" const tr = document.createElement('tr');");for(const r of p)t.push(` { const td = document.createElement('td'); td.textContent = row[${JSON.stringify(r)}] ?? ''; tr.appendChild(td); }`);for(const r of a){const g=r.props||{},he=g.arg!==void 0?u.compileExpr(g.arg,{locals:new Set(["row"])}):"";t.push(` { const td = document.createElement('td'); const b = document.createElement('button'); b.className = ${JSON.stringify(h("row-action",g))}; b.textContent = ${JSON.stringify(g.label)}; b.addEventListener('click', () => ${u.actionRef(g.action)}(${he})); td.appendChild(b); tr.appendChild(td); }`)}t.push(" return tr;"),t.push("}"),t.push(`function base_${e}() { return ${i}${F}; }`),t.push("effect(() => {"),t.push(` const rows = base_${e}()${b};`),t.push(` body_${e}.replaceChildren(...rows.map(renderRow_${e}));`),t.push("});");break}case l.Form:{const c=u.bindSig(n.bind),i=j[c].type,p=Se(A[i]),_=(m.constraints||{})[i]||{};t.push(`const el_${e} = document.createElement('form');`),t.push(`el_${e}.className = ${JSON.stringify(h("form",n))};`),t.push(`{ const t = document.createElement('div'); t.className = 'form-title'; t.textContent = ${JSON.stringify("New "+i)}; el_${e}.appendChild(t); }`);const F=[];for(const a of p){const r=`f_${e}_${a.name}`;if(F.push({...a,var:r,c:_[a.name]}),a.kind===q.Enum){t.push(`const ${r} = document.createElement('select');`),t.push(`${r}.className = 'field';`);for(const g of a.options)t.push(`{ const o = document.createElement('option'); o.value = ${JSON.stringify(g)}; o.textContent = ${JSON.stringify(g)}; ${r}.appendChild(o); }`)}else t.push(`const ${r} = document.createElement('input');`),t.push(`${r}.type = ${JSON.stringify(a.kind===q.Email?"email":"text")};`),t.push(`${r}.className = 'field';`),t.push(`${r}.placeholder = ${JSON.stringify(a.name)};`);t.push(`${r}.addEventListener('input', (e) => ${c}.set({ ...${c}.get(), ${JSON.stringify(a.name)}: e.target.value }));`),t.push(`el_${e}.appendChild(${r});`),_[a.name]&&t.push(`const err_${r} = document.createElement('small'); err_${r}.className = 'field-error'; el_${e}.appendChild(err_${r});`)}t.push(`{ const sb = document.createElement('button'); sb.type = 'submit'; sb.className = 'submit'; sb.textContent = ${JSON.stringify(typeof n.submitLabel=="string"?n.submitLabel:"Submit")}; el_${e}.appendChild(sb); }`);const b=[];for(const a of F){if(!a.c)continue;const r=`err_${a.var}`,g=`String(__d[${JSON.stringify(a.name)}] ?? '')`;b.push(`${r}.textContent = '';`),a.c.required&&b.push(`if (!${g}.trim()) { ${r}.textContent = 'Required'; __ok = false; }`),a.c.min!=null&&b.push(`if (${g} && ${g}.length < ${a.c.min}) { ${r}.textContent = 'Min ${a.c.min} characters'; __ok = false; }`),a.c.max!=null&&b.push(`if (${g}.length > ${a.c.max}) { ${r}.textContent = 'Max ${a.c.max} characters'; __ok = false; }`)}b.length?t.push(`el_${e}.addEventListener('submit', (e) => { e.preventDefault(); const __d = ${c}.get(); let __ok = true; ${b.join(" ")} if (__ok) ${u.actionRef(n.submit)}(); });`):t.push(`el_${e}.addEventListener('submit', (e) => { e.preventDefault(); ${u.actionRef(n.submit)}(); });`),t.push("effect(() => {"),t.push(` const d = ${c}.get();`);for(const a of F){const r=a.kind===q.Enum?JSON.stringify(a.options[0]):"''";t.push(` { const v = d[${JSON.stringify(a.name)}] ?? ${r}; if (${a.var}.value !== v) ${a.var}.value = v; }`)}t.push("});"),t.push(`${s}.appendChild(el_${e});`);break}case l.Text:R(e,"p",h("text",n),n.value,s),E(e,n);break;case l.Span:R(e,"span",h("span",n),n.value,s),E(e,n);break;case l.Title:R(e,n.level||"h1",h("title",n),n.value,s),E(e,n);break;case l.Image:{t.push(`const el_${e} = document.createElement('img');`),t.push(`el_${e}.className = ${JSON.stringify(h("image",n))};`),L(e,"src",n.src),L(e,"alt",n.alt??""),t.push(`${s}.appendChild(el_${e});`);break}case l.When:{if(!n.cond)throw new Error("when without a condition");const c=u.compileExpr(n.cond,C),i=H(()=>D(e,"__p"));t.push(`function build_${e}(__p) {`);for(const p of i)t.push(" "+p);t.push("}"),t.push(`const anchor_${e} = document.createComment('when');`),t.push(`${s}.appendChild(anchor_${e});`),t.push(`let shown_${e} = [];`),t.push("effect(() => {"),t.push(` if (${c}) {`),t.push(` if (!shown_${e}.length) { const __f = document.createDocumentFragment(); build_${e}(__f); shown_${e} = [...__f.childNodes]; anchor_${e}.parentNode.insertBefore(__f, anchor_${e}); }`),t.push(` } else if (shown_${e}.length) { for (const __n of shown_${e}) __n.remove(); shown_${e} = []; }`),t.push("});");break}case l.Each:{if(!n.list||!n.as)throw new Error("each without a list or item variable");const c=u.compileExpr(n.list,C),i=H(()=>D(e,"__p"));t.push(`function buildItem_${e}(__p, ${n.as}) {`);for(const p of i)t.push(" "+p);t.push("}"),t.push(`const anchor_${e} = document.createComment('each');`),t.push(`${s}.appendChild(anchor_${e});`),t.push(`let items_${e} = [];`),t.push("effect(() => {"),t.push(` for (const __n of items_${e}) __n.remove();`),t.push(" const __f = document.createDocumentFragment();"),t.push(` for (const ${n.as} of (${c} ?? [])) buildItem_${e}(__f, ${n.as});`),t.push(` items_${e} = [...__f.childNodes];`),t.push(` anchor_${e}.parentNode.insertBefore(__f, anchor_${e});`),t.push("});");break}case l.Custom:{t.push(`const el_${e} = document.createElement('div');`),t.push(`el_${e}.className = ${JSON.stringify(h("custom",n))};`),t.push(`${s}.appendChild(el_${e});`);const c=Object.entries(n.inputs||{}).map(([p,_])=>`${JSON.stringify(p)}: ${ye(_)}`).join(", "),i=Object.entries(n.on||{}).map(([p,_])=>`${JSON.stringify(p)}: (...__a) => ${u.actionRef(typeof _=="string"?_:"")}(...__a)`).join(", ");t.push(`if (typeof __custom_${n.component} === 'function') __custom_${n.component}(el_${e}, { ${c} }, { ${i} });`);break}case l.Button:{if(t.push(`const el_${e} = document.createElement('button');`),t.push(`el_${e}.className = ${JSON.stringify(h("button",n))};`),o.children&&o.children.length?D(e,`el_${e}`):n.label!==void 0&&L(e,"textContent",n.label),n.action){const c=n.arg!==void 0?u.compileExpr(n.arg,C):"";t.push(`el_${e}.addEventListener('click', () => ${u.actionRef(n.action)}(${c}));`)}E(e,n),t.push(`${s}.appendChild(el_${e});`);break}case l.Link:{t.push(`const el_${e} = document.createElement('a');`),t.push(`el_${e}.className = ${JSON.stringify(h("link",n))};`),t.push(`el_${e}.href = ${JSON.stringify(n.to||"/")};`),o.children&&o.children.length?D(e,`el_${e}`):n.label!==void 0&&L(e,"textContent",n.label),E(e,n),t.push(`${s}.appendChild(el_${e});`);break}case l.Slot:{M=!0,t.push("const __outlet = document.createElement('div');"),t.push("__outlet.className = 'muten-outlet';"),t.push(`${s}.appendChild(__outlet);`);break}default:throw new Error("unsupported primitive: "+o.type)}}const v=e=>String(e??"").replace(/&/g,"&").replace(/</g,"<").replace(/>/g,">"),P=e=>v(e).replace(/"/g,"""),S=e=>typeof e=="string"?e:"";function re(){if($.format===y.Store||(m.params||[]).length)return!1;const e=new Set([l.When,l.Each,l.Custom,l.Form,l.SearchField,l.DataTable,l.Slot]),s=["action","bind","submit","on","inputs","data"],o=["value","src","alt","label"];for(const n of Object.keys(d)){const f=d[n],c=f.props||{};if(e.has(f.type)||s.some(i=>c[i]!==void 0)||(c.class||[]).some(i=>typeof i!="string")||o.some(i=>{const p=c[i];return!!p&&typeof p=="object"&&"kind"in p&&p.kind===de.Interp}))return!1}return!0}function Q(e){const s=d[e],o=s.props||{},n=()=>(d[e].children||[]).map(Q).join(""),f=i=>` class="${P(h(i,o))}"`,c=ee[s.type];if(c){const[i,p]=c;return`<${i}${f(p)}>${n()}</${i}>`}switch(s.type){case l.Text:return`<p${f("text")}>${v(S(o.value))}</p>`;case l.Span:return`<span${f("span")}>${v(S(o.value))}</span>`;case l.Title:{const i=o.level||"h1";return`<${i}${f("title")}>${v(S(o.value))}</${i}>`}case l.Image:return`<img${f("image")} src="${P(S(o.src))}" alt="${P(S(o.alt))}">`;case l.Link:return`<a${f("link")} href="${P(o.to||"/")}">${s.children&&s.children.length?n():v(S(o.label))}</a>`;case l.Button:return`<button${f("button")}>${s.children&&s.children.length?n():v(S(o.label))}</button>`;default:return""}}const V=$.format===y.Ssr?!1:re(),ce=(m.params||[]).map(e=>`const ${e} = (__params || {})[${JSON.stringify(e)}] ?? '';`).join(`
|
|
1
|
+
import{tokenClass as Z,resolveToken as ge,defaultTheme as _e}from"#engine/style/tokens.js";import{Nt as l,Ek as de,Fmt as y,Fk as q}from"#engine/shared/vocab.js";import{customValue as ye,CONTAINERS as ee,parseClause as be,editableFields as Se}from"#engine/compile/helpers.js";import{emitStore as Ne,emitStatic as Ce,emitStaticHtml as Ee,emitSsr as ve,emitModule as Oe,emitHtml as xe}from"#engine/compile/emit.js";import{Logic as ke}from"#engine/compile/logic.js";function Te(m,x={},k="",w={},J={},$={}){return te(m,x,k,w,J,{...$,format:y.Module})}function Fe(m={},x={},k={}){const{state:w={},gets:J={},actions:$={},effects:d=[],entities:N={}}=m;return te({screen:"store",entities:N,state:w,actions:$,gets:J,effects:d,consts:{},constraints:{},rootId:void 0,nodes:{}},x,"",{},k,{format:y.Store})}function te(m,x={},k="",w={},J={},$={}){const{nodes:d,rootId:N,state:j,entities:A,screen:ne}=m,B=$.theme||_e;let t=[],M=!1;const H=e=>{const s=t;t=[],e();const o=t;return t=s,o},W=new Set,h=(e,s)=>{for(const o of s.style||[])W.add(o);return[e,...(s.style||[]).map(Z),...(s.class||[]).filter(o=>typeof o=="string")].join(" ")},se=new Set(Object.keys(j)),K=new Set(Object.entries(j).filter(([,e])=>typeof e.source=="string"&&e.source.startsWith("query:")).map(([e])=>e)),U=new Set,oe={state:j,entities:A,actions:m.actions,consts:m.consts||{},gets:m.gets||{},effects:m.effects||[],stateKeys:se,queryStates:K,stores:$.stores||{},usedStores:U,params:new Set(m.params||[]),format:$.format},u=new ke(oe),C={locals:new Set},E=(e,s)=>{for(const o of s.class||[])typeof o!="string"&&t.push(`effect(() => el_${e}.classList.toggle(${JSON.stringify(o.name)}, !!(${u.compileExpr(o.cond,C)})));`);for(const[o,n]of Object.entries(s.on||{}))typeof n=="string"&&t.push(`el_${e}.addEventListener(${JSON.stringify(o)}, () => ${u.actionRef(n)}());`)},D=(e,s)=>{for(const o of d[e].children)G(o,s)},z=e=>e.parts.map(s=>typeof s=="string"?JSON.stringify(s):`String(${u.compileExpr(s,C)} ?? '')`).join(" + ");function R(e,s,o,n,f){if(t.push(`const el_${e} = document.createElement('${s}');`),t.push(`el_${e}.className = ${JSON.stringify(o)};`),typeof n=="string")t.push(`el_${e}.textContent = ${JSON.stringify(n)};`);else if(n&&"kind"in n){const c=z(n),i=n.parts.some(p=>typeof p!="string");t.push(i?`effect(() => { el_${e}.textContent = ${c}; });`:`el_${e}.textContent = ${c};`)}t.push(`${f}.appendChild(el_${e});`)}function I(e,s,o){if(typeof o=="string")t.push(`el_${e}.${s} = ${JSON.stringify(o)};`);else if(o&&"kind"in o){const n=z(o),f=o.parts.some(c=>typeof c!="string");t.push(f?`effect(() => { el_${e}.${s} = ${n}; });`:`el_${e}.${s} = ${n};`)}}function G(e,s){const o=d[e],n=o.props||{},f=ee[o.type];if(f){const[c,i]=f;t.push(`const el_${e} = document.createElement('${c}');`),t.push(`el_${e}.className = ${JSON.stringify(h(i,n))};`),o.type===l.Nav&&typeof n.label=="string"&&t.push(`el_${e}.setAttribute('aria-label', ${JSON.stringify(n.label)});`),t.push(`${s}.appendChild(el_${e});`),E(e,n),D(e,`el_${e}`);return}switch(o.type){case l.SearchField:{const c=u.bindSig(n.bind);t.push(`const el_${e} = document.createElement('input');`),t.push(`el_${e}.type = 'search';`),t.push(`el_${e}.className = ${JSON.stringify(h("search",n))};`),typeof n.placeholder=="string"&&t.push(`el_${e}.placeholder = ${JSON.stringify(n.placeholder)};`),t.push(`el_${e}.value = ${c}.get();`),t.push(`el_${e}.addEventListener('input', (e) => ${c}.set(e.target.value));`),t.push(`${s}.appendChild(el_${e});`);break}case l.DataTable:{const c=u.bindSig(n.data),i=K.has(c)?`${c}.get().data`:`${c}.get()`,p=n.columns||[],_=(n.where||[]).map(be),L=_.filter(r=>!r.dynamic).map(r=>`.filter((row) => ${r.expr})`).join(""),S=_.filter(r=>r.dynamic).map(r=>`.filter((row) => ${r.expr})`).join(""),a=o.children.map(r=>d[r]).filter(r=>r.type===l.RowAction);t.push(`const el_${e} = document.createElement('table');`),t.push(`el_${e}.className = ${JSON.stringify(h("datatable",n))};`),t.push(`const head_${e} = el_${e}.createTHead().insertRow();`);for(const r of p)t.push(`{ const th = document.createElement('th'); th.textContent = ${JSON.stringify(r)}; head_${e}.appendChild(th); }`);a.length&&t.push(`head_${e}.appendChild(document.createElement('th'));`),t.push(`const body_${e} = el_${e}.createTBody();`),t.push(`${s}.appendChild(el_${e});`),t.push(`function renderRow_${e}(row) {`),t.push(" const tr = document.createElement('tr');");for(const r of p)t.push(` { const td = document.createElement('td'); td.textContent = row[${JSON.stringify(r)}] ?? ''; tr.appendChild(td); }`);for(const r of a){const g=r.props||{},he=g.arg!==void 0?u.compileExpr(g.arg,{locals:new Set(["row"])}):"";t.push(` { const td = document.createElement('td'); const b = document.createElement('button'); b.className = ${JSON.stringify(h("row-action",g))}; b.textContent = ${JSON.stringify(g.label)}; b.addEventListener('click', () => ${u.actionRef(g.action)}(${he})); td.appendChild(b); tr.appendChild(td); }`)}t.push(" return tr;"),t.push("}"),t.push(`function base_${e}() { return ${i}${L}; }`),t.push("effect(() => {"),t.push(` const rows = base_${e}()${S};`),t.push(` body_${e}.replaceChildren(...rows.map(renderRow_${e}));`),t.push("});");break}case l.Form:{const c=u.bindSig(n.bind),i=j[c].type,p=Se(A[i]),_=(m.constraints||{})[i]||{};t.push(`const el_${e} = document.createElement('form');`),t.push(`el_${e}.className = ${JSON.stringify(h("form",n))};`),t.push(`{ const t = document.createElement('div'); t.className = 'form-title'; t.textContent = ${JSON.stringify("New "+i)}; el_${e}.appendChild(t); }`);const L=[];for(const a of p){const r=`f_${e}_${a.name}`;if(L.push({...a,var:r,c:_[a.name]}),a.kind===q.Enum){t.push(`const ${r} = document.createElement('select');`),t.push(`${r}.className = 'field';`);for(const g of a.options)t.push(`{ const o = document.createElement('option'); o.value = ${JSON.stringify(g)}; o.textContent = ${JSON.stringify(g)}; ${r}.appendChild(o); }`)}else t.push(`const ${r} = document.createElement('input');`),t.push(`${r}.type = ${JSON.stringify(a.kind===q.Email?"email":"text")};`),t.push(`${r}.className = 'field';`),t.push(`${r}.placeholder = ${JSON.stringify(a.name)};`);t.push(`${r}.addEventListener('input', (e) => ${c}.set({ ...${c}.get(), ${JSON.stringify(a.name)}: e.target.value }));`),t.push(`el_${e}.appendChild(${r});`),_[a.name]&&t.push(`const err_${r} = document.createElement('small'); err_${r}.className = 'field-error'; el_${e}.appendChild(err_${r});`)}t.push(`{ const sb = document.createElement('button'); sb.type = 'submit'; sb.className = 'submit'; sb.textContent = ${JSON.stringify(typeof n.submitLabel=="string"?n.submitLabel:"Submit")}; el_${e}.appendChild(sb); }`);const S=[];for(const a of L){if(!a.c)continue;const r=`err_${a.var}`,g=`String(__d[${JSON.stringify(a.name)}] ?? '')`;S.push(`${r}.textContent = '';`),a.c.required&&S.push(`if (!${g}.trim()) { ${r}.textContent = 'Required'; __ok = false; }`),a.c.min!=null&&S.push(`if (${g} && ${g}.length < ${a.c.min}) { ${r}.textContent = 'Min ${a.c.min} characters'; __ok = false; }`),a.c.max!=null&&S.push(`if (${g}.length > ${a.c.max}) { ${r}.textContent = 'Max ${a.c.max} characters'; __ok = false; }`)}S.length?t.push(`el_${e}.addEventListener('submit', (e) => { e.preventDefault(); const __d = ${c}.get(); let __ok = true; ${S.join(" ")} if (__ok) ${u.actionRef(n.submit)}(); });`):t.push(`el_${e}.addEventListener('submit', (e) => { e.preventDefault(); ${u.actionRef(n.submit)}(); });`),t.push("effect(() => {"),t.push(` const d = ${c}.get();`);for(const a of L){const r=a.kind===q.Enum?JSON.stringify(a.options[0]):"''";t.push(` { const v = d[${JSON.stringify(a.name)}] ?? ${r}; if (${a.var}.value !== v) ${a.var}.value = v; }`)}t.push("});"),t.push(`${s}.appendChild(el_${e});`);break}case l.Text:R(e,"p",h("text",n),n.value,s),E(e,n);break;case l.Span:R(e,"span",h("span",n),n.value,s),E(e,n);break;case l.Title:R(e,n.level||"h1",h("title",n),n.value,s),E(e,n);break;case l.Image:{t.push(`const el_${e} = document.createElement('img');`),t.push(`el_${e}.className = ${JSON.stringify(h("image",n))};`),I(e,"src",n.src),I(e,"alt",n.alt??""),t.push(`${s}.appendChild(el_${e});`);break}case l.When:{if(!n.cond)throw new Error("when without a condition");const c=u.compileExpr(n.cond,C),i=H(()=>D(e,"__p"));t.push(`function build_${e}(__p) {`);for(const p of i)t.push(" "+p);t.push("}"),t.push(`const anchor_${e} = document.createComment('when');`),t.push(`${s}.appendChild(anchor_${e});`),t.push(`let shown_${e} = [];`),t.push("effect(() => {"),t.push(` if (${c}) {`),t.push(` if (!shown_${e}.length) { const __f = document.createDocumentFragment(); build_${e}(__f); shown_${e} = [...__f.childNodes]; anchor_${e}.parentNode.insertBefore(__f, anchor_${e}); }`),t.push(` } else if (shown_${e}.length) { for (const __n of shown_${e}) __n.remove(); shown_${e} = []; }`),t.push("});");break}case l.Each:{if(!n.list||!n.as)throw new Error("each without a list or item variable");const c=u.compileExpr(n.list,C),i=H(()=>D(e,"__p"));t.push(`function buildItem_${e}(__p, ${n.as}) {`);for(const p of i)t.push(" "+p);t.push("}"),t.push(`const anchor_${e} = document.createComment('each');`),t.push(`${s}.appendChild(anchor_${e});`),t.push(`let items_${e} = [];`),t.push("effect(() => {"),t.push(` for (const __n of items_${e}) __n.remove();`),t.push(" const __f = document.createDocumentFragment();"),t.push(` for (const ${n.as} of (${c} ?? [])) buildItem_${e}(__f, ${n.as});`),t.push(` items_${e} = [...__f.childNodes];`),t.push(` anchor_${e}.parentNode.insertBefore(__f, anchor_${e});`),t.push("});");break}case l.Custom:{t.push(`const el_${e} = document.createElement('div');`),t.push(`el_${e}.className = ${JSON.stringify(h("custom",n))};`),t.push(`${s}.appendChild(el_${e});`);const c=Object.entries(n.inputs||{}).map(([p,_])=>`${JSON.stringify(p)}: ${ye(_)}`).join(", "),i=Object.entries(n.on||{}).map(([p,_])=>`${JSON.stringify(p)}: (...__a) => ${u.actionRef(typeof _=="string"?_:"")}(...__a)`).join(", ");t.push(`if (typeof __custom_${n.component} === 'function') __custom_${n.component}(el_${e}, { ${c} }, { ${i} });`);break}case l.Button:{if(t.push(`const el_${e} = document.createElement('button');`),t.push(`el_${e}.className = ${JSON.stringify(h("button",n))};`),o.children&&o.children.length?D(e,`el_${e}`):n.label!==void 0&&I(e,"textContent",n.label),n.action){const c=n.arg!==void 0?u.compileExpr(n.arg,C):"";t.push(`el_${e}.addEventListener('click', () => ${u.actionRef(n.action)}(${c}));`)}E(e,n),t.push(`${s}.appendChild(el_${e});`);break}case l.Link:{t.push(`const el_${e} = document.createElement('a');`),t.push(`el_${e}.className = ${JSON.stringify(h("link",n))};`),I(e,"href",n.to??"/"),o.children&&o.children.length?D(e,`el_${e}`):n.label!==void 0&&I(e,"textContent",n.label),E(e,n),t.push(`${s}.appendChild(el_${e});`);break}case l.Slot:{M=!0,t.push("const __outlet = document.createElement('div');"),t.push("__outlet.className = 'muten-outlet';"),t.push(`${s}.appendChild(__outlet);`);break}default:throw new Error("unsupported primitive: "+o.type)}}const v=e=>String(e??"").replace(/&/g,"&").replace(/</g,"<").replace(/>/g,">"),P=e=>v(e).replace(/"/g,"""),b=e=>typeof e=="string"?e:"";function re(){if($.format===y.Store||(m.params||[]).length)return!1;const e=new Set([l.When,l.Each,l.Custom,l.Form,l.SearchField,l.DataTable,l.Slot]),s=["action","bind","submit","on","inputs","data"],o=["value","src","alt","label","to"];for(const n of Object.keys(d)){const f=d[n],c=f.props||{};if(e.has(f.type)||s.some(i=>c[i]!==void 0)||(c.class||[]).some(i=>typeof i!="string")||o.some(i=>{const p=c[i];return!!p&&typeof p=="object"&&"kind"in p&&p.kind===de.Interp}))return!1}return!0}function Q(e){const s=d[e],o=s.props||{},n=()=>(d[e].children||[]).map(Q).join(""),f=i=>` class="${P(h(i,o))}"`,c=ee[s.type];if(c){const[i,p]=c;return`<${i}${f(p)}>${n()}</${i}>`}switch(s.type){case l.Text:return`<p${f("text")}>${v(b(o.value))}</p>`;case l.Span:return`<span${f("span")}>${v(b(o.value))}</span>`;case l.Title:{const i=o.level||"h1";return`<${i}${f("title")}>${v(b(o.value))}</${i}>`}case l.Image:return`<img${f("image")} src="${P(b(o.src))}" alt="${P(b(o.alt))}">`;case l.Link:return`<a${f("link")} href="${P(b(o.to)||"/")}">${s.children&&s.children.length?n():v(b(o.label))}</a>`;case l.Button:return`<button${f("button")}>${s.children&&s.children.length?n():v(b(o.label))}</button>`;default:return""}}const V=$.format===y.Ssr?!1:re(),ce=(m.params||[]).map(e=>`const ${e} = (__params || {})[${JSON.stringify(e)}] ?? '';`).join(`
|
|
2
2
|
`),ie=u.genState(),ae=u.genActions(),le=Object.entries(m.gets||{}).map(([e,s])=>`export const ${e} = computed(() => ${u.compileExpr(s,C)});`).join(`
|
|
3
3
|
`),pe=u.genEffects();let X=null;V?X=N?Q(N):"":$.format!==y.Store&&N&&G(N,"app");const ue=t.join(`
|
|
4
4
|
`),Y={};for(const e of Object.values(j))if(typeof e.source=="string"&&e.source.startsWith("query:")){const s=e.source.slice(6),o=(e.type.match(/^list<(.+)>$/)||[])[1];Y[s]=o?u.uuidFields(o):[]}const fe=[...W].map(e=>{const s=ge(e,B);if(!s)return"";const o=`.${Z(e)}{${s}}`,n=e.indexOf(":"),f=n>0&&B.breakpoints[e.slice(0,n)];return f?`@media (min-width:${f}){${o}}`:o}).filter(Boolean).join(`
|
|
@@ -8,4 +8,4 @@ ${s}
|
|
|
8
8
|
})();`).join(`
|
|
9
9
|
|
|
10
10
|
`),$e=[...U].map(e=>`import * as __store_${e} from 'virtual:muten/store/${e}';`).join(`
|
|
11
|
-
`),
|
|
11
|
+
`),T=m.meta||{},F={...T};T.title&&!F["og:title"]&&(F["og:title"]=T.title),T.description&&!F["og:description"]&&(F["og:description"]=T.description);const O={screen:ne,tokenCss:fe,projectCss:k,data:x,sources:J,api:$.api||{},meta:F,queryUuids:Y,stateDecls:ie,paramDecls:ce,actionDecls:ae,getDecls:le,effectDecls:pe,componentDecls:me,storeImports:$e,renderBody:ue,staticHtml:X??"",hasSlot:M};return $.format===y.Store?Ne(O):$.format===y.Ssr?ve(O):V?$.format===y.Module?Ce(O):Ee(O):$.format===y.Module?Oe(O):xe(O)}export{te as compile,Te as compileModule,Fe as compileStore};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{Ek as f}from"#engine/shared/vocab.js";function A(t,n){const e=new Set;return{tree:t&&o(t,n,e),used:[...e]}}function o(t,n,e){const u=n[t.type];if(u){e.add(t.type);const c=s(u.tree,t.args||{});return o(c,n,e)}const i={type:t.type};return t.loc&&(i.loc=t.loc),t.args&&(i.args=t.args),t.props&&(i.props=t.props),t.children&&(i.children=t.children.map(c=>o(c,n,e))),i}function s(t,n){const e={type:t.type};return t.props&&(e.props=
|
|
1
|
+
import{Ek as f}from"#engine/shared/vocab.js";function A(t,n){const e=new Set;return{tree:t&&o(t,n,e),used:[...e]}}function o(t,n,e){const u=n[t.type];if(u){e.add(t.type);const c=s(u.tree,t.args||{});return o(c,n,e)}const i={type:t.type};return t.loc&&(i.loc=t.loc),t.args&&(i.args=t.args),t.props&&(i.props=t.props),t.children&&(i.children=t.children.map(c=>o(c,n,e))),i}function s(t,n){const e={type:t.type};return t.props&&(e.props=g(t.props,n)),t.args&&(e.args=a(t.args,n)),t.children&&(e.children=t.children.map(u=>s(u,n))),e}function g(t,n){const e={...t};return t.value!==void 0&&(e.value=d(t.value,n)),t.label!==void 0&&(e.label=d(t.label,n)),t.src!==void 0&&(e.src=d(t.src,n)),t.alt!==void 0&&(e.alt=d(t.alt,n)),t.placeholder!==void 0&&(e.placeholder=d(t.placeholder,n)),t.submitLabel!==void 0&&(e.submitLabel=d(t.submitLabel,n)),t.cond!==void 0&&(e.cond=r(t.cond,n)),t.list!==void 0&&(e.list=r(t.list,n)),t.arg!==void 0&&(e.arg=r(t.arg,n)),t.action!==void 0&&(e.action=l(t.action,n)),t.submit!==void 0&&(e.submit=l(t.submit,n)),t.bind!==void 0&&(e.bind=l(t.bind,n)),t.to!==void 0&&(e.to=typeof t.to=="string"?t.to:b(t.to,n)),t.inputs!==void 0&&(e.inputs=a(t.inputs,n)),t.on!==void 0&&(e.on=a(t.on,n)),e}function d(t,n){if(typeof t=="string")return t;if("$param"in t){const e=n[t.$param];return typeof e=="number"?String(e):e}return b(t,n)}function r(t,n){return t.kind===f.Ref?{kind:f.Ref,name:l(t.name,n)}:t.kind===f.Bin?{...t,left:r(t.left,n),right:r(t.right,n)}:t.kind===f.Un?{...t,operand:r(t.operand,n)}:t.kind===f.Tern?{...t,cond:r(t.cond,n),then:r(t.then,n),else:r(t.else,n)}:t}function b(t,n){return{kind:f.Interp,parts:t.parts.map(e=>typeof e=="string"?e:r(e,n))}}function a(t,n){const e={};for(const[u,i]of Object.entries(t))e[u]=m(i,n);return e}function m(t,n){return typeof t=="string"?t.startsWith("$")?l(t,n):t:typeof t=="number"?t:n[t.$param]}function l(t,n){if(!t.startsWith("$"))return t;const e=t.slice(1).split(".")[0],u=t.slice(1+e.length),i=n[e];return(typeof i=="string"?i:e)+u}export{A as compose};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{resolveToken as x,SUGGESTED as b,defaultTheme as A,isKnownTokenShape as D}from"#engine/style/tokens.js";import{diag as
|
|
1
|
+
import{resolveToken as x,SUGGESTED as b,defaultTheme as A,isKnownTokenShape as D}from"#engine/style/tokens.js";import{diag as p,closest as l}from"#engine/shared/diagnostics.js";import{PRIMITIVE_NAMES as W,ACTION_OPS as _,PRIMITIVES as C}from"#engine/lang/manifest.js";import{Nt as u,Ek as y,StOp as F}from"#engine/shared/vocab.js";const O=new Set(W),K=["bind","data"],E=new Set(_),N=["text","number","bool","uuid","email","string"];function h(s,c=[]){return s.kind===y.Ref?c.push(s.name):s.kind===y.Un?h(s.operand,c):s.kind===y.Bin?(h(s.left,c),h(s.right,c)):s.kind===y.Tern&&(h(s.cond,c),h(s.then,c),h(s.else,c)),c}function q(s,c={}){const r=[],g=new Set(Object.keys(s.state||{})),I=new Set(c.stores||[]),j=new Set(Object.keys(s.consts||{})),T=new Set(s.params||[]),R=new Set(Object.keys(s.actions||{})),P=s.nodes||{},S=Object.keys(s.entities||{});for(const[o,i]of Object.entries(s.state||{})){const t=i.type;if(t==="list")r.push(p("untyped-list",`state "${o}" is an untyped "list" \u2014 declare the element type, e.g. list<uuid> or list<User>`,{loc:i.loc,suggestion:"list<uuid>"}));else if(t.startsWith("list<")){const e=t.slice(5,-1);!N.includes(e)&&!S.includes(e)&&r.push(p("unknown-type",`list element "${e}" is not a known entity or scalar type`,{loc:i.loc,suggestion:l(e,[...S,...N])}))}}const V=(o,i)=>{if(typeof o=="string"&&o.startsWith("@")){const t=o.slice(1).split(".")[0];if(!g.has(t)){const e=l(t,[...g]);r.push(p("unknown-ref",`"@${t}" is not a declared state`,{loc:i.loc,suggestion:e?"@"+e:null}))}}},k=(o,i,t)=>{for(const e of h(o)){const n=e.split(".")[0];if(t.has(n)||g.has(n)||I.has(n)||j.has(n)||T.has(n)||R.has(n))continue;const d=l(n,[...g,...t]);r.push(p("unknown-ref",`"${n}" is not a known state or item variable here`,{loc:i.loc,suggestion:d}))}},w=new Set,$=(o,i)=>{const t=P[o];if(!t){r.push(p("missing-node",`node ${o} does not exist`));return}if(w.has(o)){r.push(p("dup-node",`${o} is referenced twice`,{loc:t.loc}));return}if(w.add(o),!O.has(t.type))t.args?r.push(p("unknown-part",`"${t.type}" is not a known part`,{loc:t.loc,suggestion:l(t.type,c.parts||[])})):r.push(p("unknown-type",`"${t.type}" is not a known primitive`,{loc:t.loc,suggestion:l(t.type,[...O])}));else{const a=C[t.type],m=a?a.props:{};for(const[f,v]of Object.entries(m))!v.endsWith("?")&&!(f in(t.props||{}))&&r.push(p("missing-prop",`${t.type} is missing the required "${f}"`,{loc:t.loc}))}const e=t.props||{};for(const a of K)a in e&&V(e[a],t);if(Array.isArray(e.style)){const a=c.theme||A,m=Object.keys(a.space||{}).length>0;for(const f of e.style)D(f)?m&&x(f,a)===null&&r.push(p("unknown-token",`"${f}": that step isn't in your theme scale`,{loc:t.loc,suggestion:l(f,b)})):r.push(p("unknown-token",`"${f}" is not an accepted style token`,{loc:t.loc,suggestion:l(f,b)}))}t.type===u.When&&e.cond&&k(e.cond,t,i),t.type===u.Each&&e.list&&k(e.list,t,i);const n=[];(t.type===u.Text||t.type===u.Title||t.type===u.Span)&&e.value&&n.push(e.value),t.type===u.Image&&(e.src&&n.push(e.src),e.alt&&n.push(e.alt)),t.type===u.Link&&e.to&&n.push(e.to);for(const a of n)if(typeof a=="object"&&"kind"in a&&a.kind===y.Interp)for(const m of a.parts)typeof m!="string"&&k(m,t,i);const d=t.type===u.Each&&e.as?new Set([...i,e.as]):i;for(const a of t.children||[])$(a,d)};if(s.rootId?$(s.rootId,new Set):c.kind!=="store"&&r.push(p("no-root","the doc is missing a rootId")),c.kind==="store")for(const[o,i]of Object.entries(s.gets||{}))for(const t of h(i)){const e=t.split(".")[0];g.has(e)||r.push(p("unknown-ref",`get "${o}": "${e}" is not a state of this store`,{suggestion:l(e,[...g])}))}for(const[o,i]of Object.entries(s.actions||{})){const t=new Set(i.mutates||[]),e=n=>{if(n.op===F.If){for(const d of n.then||[])e(d);for(const d of n.else||[])e(d);return}E.has(n.op)||r.push(p("unknown-op",`action "${o}" uses unknown op "${n.op}"`,{suggestion:l(n.op,[...E])})),"target"in n&&n.target&&!t.has(n.target)&&r.push(p("undeclared-mutation",`action "${o}" mutates "${n.target}" but only declares mutates(${[...t].join(", ")||"\u2205"})`,{suggestion:l(n.target,[...t])}))};for(const n of i.body||[])e(n)}return{ok:r.length===0,diagnostics:r}}export{q as validate};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{ParseError as f}from"#engine/shared/diagnostics.js";import{PRIMITIVES as g}from"#engine/lang/manifest.js";import{Grammar as R}from"#engine/lang/grammar.js";import{Tk as t,Pn as i,Kw as a,Nt as P,Mod as u,StOp as o}from"#engine/shared/vocab.js";const v={};for(const[c,e]of Object.entries(g))e.string&&(v[c]=e.string);const x=new Set(Object.entries(g).filter(([,c])=>c.interp).map(([c])=>c)),S=c=>c==="text"?"string":c,y=c=>/^h[1-6]$/.test(c);class k extends R{modifiers;statements;constructor(e){super(e),this.modifiers=new Map([[u.Bind,s=>{s.bind=this.at(t.Ref)?this.eat(t.Ref).v:this.parseDotted()}],[u.Submit,s=>{s.submit=this.parseDotted()}],[u.Where,s=>{s.where=this.parseParenList(()=>this.rebuildClause())}],[u.Columns,s=>{s.columns=this.parseParenList(()=>this.eat(t.Ident).v)}],[u.Style,s=>{s.style=this.parseParenList(()=>this.parseStyleToken())}],[u.Class,s=>{s.class=this.parseParenList(()=>{const n=this.at(t.String)?this.next().v:this.eat(t.Ident).v;return this.at(t.Ident,a.When)?(this.next(),{name:n,cond:this.parseExpr()}):n})}],[u.Alt,s=>{s.alt=this.parseInterpolation(this.eat(t.String).v)}],[u.Inputs,s=>{s.inputs=this.parseArgs()}],[u.On,s=>{s.on=this.parseArgs()}]]),this.statements=new Map([[o.Push,s=>({op:o.Push,target:s,arg:this.parseExpr()})],[o.Set,s=>({op:o.Set,target:s,arg:this.parseExpr()})],[o.Reset,s=>({op:o.Reset,target:s})],[o.Remove,s=>{const n=this.eat(t.Ident).v;return this.eat(t.FatArrow),{op:o.Remove,target:s,param:n,pred:this.parseExpr()}}],[o.Create,s=>({op:o.Create,target:s,arg:this.parseExpr()})],[o.Update,s=>({op:o.Update,target:s,arg:this.parseExpr()})],[o.Delete,s=>({op:o.Delete,target:s,arg:this.parseExpr()})],[o.Refetch,s=>{const n={};for(;!this.at(t.Punct,i.ParenR);){const r=this.eat(t.Ident).v;this.eat(t.Punct,i.Colon),n[r]=this.parseExpr(),this.at(t.Punct,i.Comma)&&this.next()}return{op:o.Refetch,target:s,params:n}}]])}parse(){const e={screen:"",entities:{},state:{},actions:{},tree:null},s=new Map([[a.Screen,()=>{this.next(),e.screen=this.eat(t.Ident).v}],[a.Entity,()=>this.parseEntity(e)],[a.State,()=>this.parseState(a.State,e.state)],[a.Store,()=>{e.store=e.store||{},this.parseState(a.Store,e.store)}],[a.Get,()=>this.parseGet(e)],[a.Effect,()=>{this.next(),(e.effects=e.effects||[]).push(this.parseActionBody())}],[a.Action,()=>this.parseAction(e)],[a.Mock,()=>this.parseMock(e)],[a.Sources,()=>this.parseSources(e)],[a.Api,()=>this.parseApi(e)],[a.Meta,()=>this.parseMeta(e)],[a.Routes,()=>this.parseRoutes(e)],[a.Shell,()=>this.parseShell(e)],[a.Part,()=>this.parsePart(e)],[a.Const,()=>this.parseConst(e)],[a.Theme,()=>this.parseTheme(e)],[a.Param,()=>{this.next(),(e.params=e.params||[]).push(this.eat(t.Ident).v)}]]);for(;!this.at(t.Eof);){const n=this.peek(),r=n.t===t.Ident?s.get(n.v):void 0;r?r():e.tree=this.parseNode()}return e}parseEntity(e){this.eat(t.Ident,a.Entity);const s=this.eat(t.Ident).v;this.eat(t.Punct,i.BraceL);const n={id:"uuid"},r={};for(;!this.at(t.Punct,i.BraceR);){const p=this.eat(t.Ident).v,h=[this.eat(t.Ident).v];for(;this.at(t.Punct,i.Pipe);)this.next(),h.push(this.eat(t.Ident).v);n[p]=h.length>1?"enum:"+h.join("|"):S(h[0]);const d=this.parseConstraints();Object.keys(d).length&&(r[p]=d)}this.eat(t.Punct,i.BraceR),e.entities[s]=n,Object.keys(r).length&&((e.constraints=e.constraints||{})[s]=r)}parseConstraints(){const e={};for(;this.at(t.Ident,a.Required)||this.at(t.Ident,a.Min)||this.at(t.Ident,a.Max);){const s=this.next().v;if(s===a.Required){e.required=!0;continue}this.eat(t.Punct,i.Colon);const n=Number(this.eat(t.Number).v);s===a.Min?e.min=n:e.max=n}return e}parseState(e,s){for(this.eat(t.Ident,e),this.eat(t.Punct,i.BraceL);!this.at(t.Punct,i.BraceR);){const n=this.eat(t.Ident);this.eat(t.Punct,i.Assign);let r,p,h=!1;this.at(t.Ident,a.Query)?(this.next(),r="query:"+this.eat(t.Ident).v):this.at(t.Punct,i.BraceL)||this.at(t.Punct,i.BrackL)?(p=this.parseValue(),h=!0):this.at(t.String)?(p=this.next().v,h=!0):this.at(t.Number)?(p=Number(this.next().v),h=!0):this.at(t.Ident,a.True)||this.at(t.Ident,a.False)?(p=this.next().v===a.True,h=!0):(p=this.next().v,h=!0),this.eat(t.Punct,i.Colon);const d=this.parseType(),m=this.locOf(n.pos);s[n.v]=r?{type:d,source:r,loc:m}:{type:d,initial:h?p:null,loc:m}}this.eat(t.Punct,i.BraceR)}parseGet(e){this.eat(t.Ident,a.Get);const s=this.eat(t.Ident).v;this.eat(t.Punct,i.Assign),(e.gets=e.gets||{})[s]=this.parseExpr()}parseAction(e){this.eat(t.Ident,a.Action);const s=this.eat(t.Ident).v,n=[];if(this.at(t.Ident,a.Mutates))for(this.next(),n.push(this.eat(t.Ident).v);this.at(t.Punct,i.Comma);)this.next(),n.push(this.eat(t.Ident).v);let r="";this.at(t.LArrow)&&(this.next(),r=this.eat(t.Ident).v),e.actions[s]={mutates:n,input:r,body:this.parseActionBody()}}parseActionBody(){this.eat(t.Punct,i.BraceL);const e=[];for(;!this.at(t.Punct,i.BraceR);)e.push(this.parseStatement());return this.eat(t.Punct,i.BraceR),e}parseIf(){this.eat(t.Ident,a.If);const e=this.parseExpr(),s=this.parseActionBody(),n=this.at(t.Ident,a.Else)?(this.next(),this.parseActionBody()):null;return{op:o.If,cond:e,then:s,else:n}}parseRequest(){const e=this.eat(t.Ident).v.toUpperCase(),s=this.parseInterpolation(this.eat(t.String).v);let n=null;return this.at(t.Ident,a.Body)&&(this.next(),n=this.parseExpr()),{op:o.Request,method:e,url:s,body:n}}parseStatement(){if(this.at(t.Ident,a.If))return this.parseIf();if(this.at(t.Ident,"post")||this.at(t.Ident,"put")||this.at(t.Ident,"delete"))return this.parseRequest();const e=this.eat(t.Ident).v;this.eat(t.Punct,i.Dot);const s=this.eat(t.Ident).v;this.eat(t.Punct,i.ParenL);const n=this.statements.get(s);if(!n)throw new f(`unknown action method "${s}" on "${e}"`,this.locOf(this.peek().pos));const r=n(e);return this.eat(t.Punct,i.ParenR),r}parseMock(e){this.eat(t.Ident,a.Mock);const s=e.mock||{};this.parseEntries(n=>{s[n]=this.parseValue()}),e.mock=s}parseSources(e){this.eat(t.Ident,a.Sources);const s=e.sources||{};this.parseEntries(n=>{s[n]=this.parseValue()}),e.sources=s}parseApi(e){this.eat(t.Ident,a.Api);const s=e.api||{};this.parseEntries(n=>{s[n]=this.parseValue()}),e.api=s}parseMeta(e){this.eat(t.Ident,a.Meta),this.eat(t.Punct,i.BraceL);const s=e.meta||{};for(;!this.at(t.Punct,i.BraceR);){const n=this.eat(t.Ident).v;s[n]=this.eat(t.String).v}this.eat(t.Punct,i.BraceR),e.meta=s}parseRoutes(e){this.eat(t.Ident,a.Routes),this.eat(t.Punct,i.BraceL);const s=e.routes||[];for(;!this.at(t.Punct,i.BraceR);){const n=this.peek(),r=this.locOf(n.pos).line,p=this.pathOnLine(r);this.eat(t.Arrow);const h={url:p,page:this.eat(t.Ident).v,loc:this.locOf(n.pos)};this.at(t.Ident,a.Guard)&&(this.next(),h.guardNeg=this.at(t.Ident,a.Not)?(this.next(),!0):!1,h.guard=this.parseDotted(),this.eat(t.Ident,a.Else),h.redirect=this.pathOnLine(r)),s.push(h)}this.eat(t.Punct,i.BraceR),e.routes=s}parseShell(e){this.eat(t.Ident,a.Shell),e.shell={type:P.Shell,props:{},children:this.parseChildren()}}parseConst(e){this.eat(t.Ident,a.Const);const s=this.eat(t.Ident).v;if(this.eat(t.Punct,i.Assign),this.at(t.Punct,i.BraceL)||this.at(t.Punct,i.BrackL))throw new f("const holds a single value (string/number/bool) \u2014 use a block like `theme { \u2026 }` for structured data",this.locOf(this.peek().pos));(e.consts=e.consts||{})[s]=this.parseScalar()}parseTheme(e){this.eat(t.Ident,a.Theme),this.eat(t.Punct,i.BraceL);const s={};for(;!this.at(t.Punct,i.BraceR);){const n=this.eat(t.Ident).v;this.eat(t.Punct,i.BraceL);const r={};for(;!this.at(t.Punct,i.BraceR);)r[this.eat(t.Ident).v]=this.eat(t.String).v;this.eat(t.Punct,i.BraceR),s[n]=r}this.eat(t.Punct,i.BraceR),e.theme=s}parsePart(e){this.eat(t.Ident,a.Part);const s=this.eat(t.Ident).v;this.eat(t.Punct,i.ParenL);const n=[];for(;!this.at(t.Punct,i.ParenR);){const p=this.eat(t.Ident).v;this.eat(t.Punct,i.Colon),n.push({name:p,type:this.parseType()}),this.at(t.Punct,i.Comma)&&this.next()}this.eat(t.Punct,i.ParenR);const r=this.parseChildren();e.parts=e.parts||{},e.parts[s]={params:n,tree:r.length===1?r[0]:{type:P.Stack,props:{},children:r}}}parseWhen(){const e=this.eat(t.Ident,a.When),s=this.parseExpr();return{type:P.When,props:{cond:s},children:this.parseChildren(),loc:this.locOf(e.pos)}}parseEach(){const e=this.eat(t.Ident,a.Each),s=this.parseExpr();this.eat(t.Ident,a.As);const n=this.eat(t.Ident).v;return{type:P.Each,props:{list:s,as:n},children:this.parseChildren(),loc:this.locOf(e.pos)}}parseNode(){if(this.at(t.Ident,a.When))return this.parseWhen();if(this.at(t.Ident,a.Each))return this.parseEach();const e=this.eat(t.Ident),s=e.v,n=this.locOf(e.pos);if(this.at(t.Punct,i.ParenL))return{type:s,args:this.parseArgs(),loc:n};const r={},p=[];s===P.Custom&&(r.component=this.eat(t.Ident).v);let h=!0;for(;h;){const m=this.peek();switch(m.t){case t.String:{const l=v[s]||"label";r[l]=x.has(s)?this.parseInterpolation(this.next().v):this.next().v;break}case t.Param:{const l=v[s]||"label";r[l]={$param:this.next().v};break}case t.Ref:r.data=this.next().v;break;case t.Arrow:this.parseArrow(s,r);break;case t.Ident:{const l=m.v;if(s===P.Title&&y(l)){this.next(),r.level=l;break}const I=this.modifiers.get(l);if(!I){h=!1;break}this.next(),I(r);break}case t.Punct:if(m.v===i.BraceL){for(this.next();!this.at(t.Punct,i.BraceR);)p.push(this.parseNode());this.eat(t.Punct,i.BraceR)}h=!1;break;default:h=!1}}const d={type:s,props:r,loc:n};return p.length&&(d.children=p),d}parseArrow(e,s){if(this.next(),e===P.Link){s.to=this.parsePath();return}s.action=this.parseDotted(),this.at(t.Punct,i.ParenL)&&(this.next(),this.at(t.Punct,i.ParenR)||(s.arg=this.parseExpr()),this.eat(t.Punct,i.ParenR))}parseChildren(){this.eat(t.Punct,i.BraceL);const e=[];for(;!this.at(t.Punct,i.BraceR);)e.push(this.parseNode());return this.eat(t.Punct,i.BraceR),e}parseType(){let e=this.eat(t.Ident).v;return this.at(t.Punct,i.Lt)&&(this.next(),e+="<"+this.eat(t.Ident).v+">",this.eat(t.Punct,i.Gt)),e}parseStyleToken(){const e=()=>this.at(t.Number)?this.next().v:this.eat(t.Ident).v;let s=e();for(this.at(t.Punct,i.Colon)&&(this.next(),s+=":"+e());this.at(t.Punct,i.Dot);)this.next(),s+="."+e();return s}parseDotted(){let e=this.at(t.Param)?"$"+this.next().v:this.eat(t.Ident).v;for(;this.at(t.Punct,i.Dot);)this.next(),e+="."+this.eat(t.Ident).v;return e}parseParenList(e){this.eat(t.Punct,i.ParenL);const s=[];for(;!this.at(t.Punct,i.ParenR);)s.push(e()),this.at(t.Punct,i.Comma)&&this.next();return this.eat(t.Punct,i.ParenR),s}rebuildClause(){const e=[];for(;!this.at(t.Punct,i.Comma)&&!this.at(t.Punct,i.ParenR);)e.push(this.next().v);return e.join(" ")}parseEntries(e){for(this.eat(t.Punct,i.BraceL);!this.at(t.Punct,i.BraceR);){const s=this.eat(t.Ident).v;this.eat(t.Punct,i.Colon),e(s),this.at(t.Punct,i.Comma)&&this.next()}this.eat(t.Punct,i.BraceR)}parsePath(){let e="";for(;this.at(t.Punct,i.Slash);){const s=this.next();e+="/",this.at(t.Ident)&&this.peek().pos===s.pos+1&&(e+=this.eat(t.Ident).v)}return e}pathOnLine(e){let s="";for(;this.at(t.Punct,i.Slash)&&this.locOf(this.peek().pos).line===e;)this.next(),s+="/",this.at(t.Punct,i.Colon)?(this.next(),s+=":"+this.eat(t.Ident).v):this.at(t.Ident)&&(s+=this.eat(t.Ident).v);return s}parseArgs(){this.eat(t.Punct,i.ParenL);const e={};for(;!this.at(t.Punct,i.ParenR);){const s=this.eat(t.Ident).v;this.eat(t.Punct,i.Colon),e[s]=this.parseArgValue(),this.at(t.Punct,i.Comma)&&this.next()}return this.eat(t.Punct,i.ParenR),e}parseArgValue(){return this.at(t.String)?this.next().v:this.at(t.Number)?Number(this.next().v):this.at(t.Ref)?this.next().v:this.at(t.Param)?{$param:this.next().v}:this.parseDotted()}}function C(c){return new k(c).parse()}export{k as Parser,C as parse};
|
|
1
|
+
import{ParseError as f}from"#engine/shared/diagnostics.js";import{PRIMITIVES as g}from"#engine/lang/manifest.js";import{Grammar as R}from"#engine/lang/grammar.js";import{Tk as t,Pn as i,Kw as n,Nt as P,Mod as u,StOp as o,Ek as x}from"#engine/shared/vocab.js";const v={};for(const[c,e]of Object.entries(g))e.string&&(v[c]=e.string);const S=new Set(Object.entries(g).filter(([,c])=>c.interp).map(([c])=>c)),y=c=>c==="text"?"string":c,k=c=>/^h[1-6]$/.test(c);class w extends R{modifiers;statements;constructor(e){super(e),this.modifiers=new Map([[u.Bind,s=>{s.bind=this.at(t.Ref)?this.eat(t.Ref).v:this.parseDotted()}],[u.Submit,s=>{s.submit=this.parseDotted()}],[u.Where,s=>{s.where=this.parseParenList(()=>this.rebuildClause())}],[u.Columns,s=>{s.columns=this.parseParenList(()=>this.eat(t.Ident).v)}],[u.Style,s=>{s.style=this.parseParenList(()=>this.parseStyleToken())}],[u.Class,s=>{s.class=this.parseParenList(()=>{const a=this.at(t.String)?this.next().v:this.eat(t.Ident).v;return this.at(t.Ident,n.When)?(this.next(),{name:a,cond:this.parseExpr()}):a})}],[u.Alt,s=>{s.alt=this.parseInterpolation(this.eat(t.String).v)}],[u.Inputs,s=>{s.inputs=this.parseArgs()}],[u.On,s=>{s.on=this.parseArgs()}]]),this.statements=new Map([[o.Push,s=>({op:o.Push,target:s,arg:this.parseExpr()})],[o.Set,s=>({op:o.Set,target:s,arg:this.parseExpr()})],[o.Reset,s=>({op:o.Reset,target:s})],[o.Remove,s=>{const a=this.eat(t.Ident).v;return this.eat(t.FatArrow),{op:o.Remove,target:s,param:a,pred:this.parseExpr()}}],[o.Create,s=>({op:o.Create,target:s,arg:this.parseExpr()})],[o.Update,s=>({op:o.Update,target:s,arg:this.parseExpr()})],[o.Delete,s=>({op:o.Delete,target:s,arg:this.parseExpr()})],[o.Refetch,s=>{const a={};for(;!this.at(t.Punct,i.ParenR);){const r=this.eat(t.Ident).v;this.eat(t.Punct,i.Colon),a[r]=this.parseExpr(),this.at(t.Punct,i.Comma)&&this.next()}return{op:o.Refetch,target:s,params:a}}]])}parse(){const e={screen:"",entities:{},state:{},actions:{},tree:null},s=new Map([[n.Screen,()=>{this.next(),e.screen=this.eat(t.Ident).v}],[n.Entity,()=>this.parseEntity(e)],[n.State,()=>this.parseState(n.State,e.state)],[n.Store,()=>{e.store=e.store||{},this.parseState(n.Store,e.store)}],[n.Get,()=>this.parseGet(e)],[n.Effect,()=>{this.next(),(e.effects=e.effects||[]).push(this.parseActionBody())}],[n.Action,()=>this.parseAction(e)],[n.Mock,()=>this.parseMock(e)],[n.Sources,()=>this.parseSources(e)],[n.Api,()=>this.parseApi(e)],[n.Meta,()=>this.parseMeta(e)],[n.Routes,()=>this.parseRoutes(e)],[n.Shell,()=>this.parseShell(e)],[n.Part,()=>this.parsePart(e)],[n.Const,()=>this.parseConst(e)],[n.Theme,()=>this.parseTheme(e)],[n.Param,()=>{this.next(),(e.params=e.params||[]).push(this.eat(t.Ident).v)}]]);for(;!this.at(t.Eof);){const a=this.peek(),r=a.t===t.Ident?s.get(a.v):void 0;r?r():e.tree=this.parseNode()}return e}parseEntity(e){this.eat(t.Ident,n.Entity);const s=this.eat(t.Ident).v;this.eat(t.Punct,i.BraceL);const a={id:"uuid"},r={};for(;!this.at(t.Punct,i.BraceR);){const p=this.eat(t.Ident).v,h=[this.eat(t.Ident).v];for(;this.at(t.Punct,i.Pipe);)this.next(),h.push(this.eat(t.Ident).v);a[p]=h.length>1?"enum:"+h.join("|"):y(h[0]);const d=this.parseConstraints();Object.keys(d).length&&(r[p]=d)}this.eat(t.Punct,i.BraceR),e.entities[s]=a,Object.keys(r).length&&((e.constraints=e.constraints||{})[s]=r)}parseConstraints(){const e={};for(;this.at(t.Ident,n.Required)||this.at(t.Ident,n.Min)||this.at(t.Ident,n.Max);){const s=this.next().v;if(s===n.Required){e.required=!0;continue}this.eat(t.Punct,i.Colon);const a=Number(this.eat(t.Number).v);s===n.Min?e.min=a:e.max=a}return e}parseState(e,s){for(this.eat(t.Ident,e),this.eat(t.Punct,i.BraceL);!this.at(t.Punct,i.BraceR);){const a=this.eat(t.Ident);this.eat(t.Punct,i.Assign);let r,p,h=!1;this.at(t.Ident,n.Query)?(this.next(),r="query:"+this.eat(t.Ident).v):this.at(t.Punct,i.BraceL)||this.at(t.Punct,i.BrackL)?(p=this.parseValue(),h=!0):this.at(t.String)?(p=this.next().v,h=!0):this.at(t.Number)?(p=Number(this.next().v),h=!0):this.at(t.Ident,n.True)||this.at(t.Ident,n.False)?(p=this.next().v===n.True,h=!0):(p=this.next().v,h=!0),this.eat(t.Punct,i.Colon);const d=this.parseType(),m=this.locOf(a.pos);s[a.v]=r?{type:d,source:r,loc:m}:{type:d,initial:h?p:null,loc:m}}this.eat(t.Punct,i.BraceR)}parseGet(e){this.eat(t.Ident,n.Get);const s=this.eat(t.Ident).v;this.eat(t.Punct,i.Assign),(e.gets=e.gets||{})[s]=this.parseExpr()}parseAction(e){this.eat(t.Ident,n.Action);const s=this.eat(t.Ident).v,a=[];if(this.at(t.Ident,n.Mutates))for(this.next(),a.push(this.eat(t.Ident).v);this.at(t.Punct,i.Comma);)this.next(),a.push(this.eat(t.Ident).v);let r="";this.at(t.LArrow)&&(this.next(),r=this.eat(t.Ident).v),e.actions[s]={mutates:a,input:r,body:this.parseActionBody()}}parseActionBody(){this.eat(t.Punct,i.BraceL);const e=[];for(;!this.at(t.Punct,i.BraceR);)e.push(this.parseStatement());return this.eat(t.Punct,i.BraceR),e}parseIf(){this.eat(t.Ident,n.If);const e=this.parseExpr(),s=this.parseActionBody(),a=this.at(t.Ident,n.Else)?(this.next(),this.parseActionBody()):null;return{op:o.If,cond:e,then:s,else:a}}parseRequest(){const e=this.eat(t.Ident).v.toUpperCase(),s=this.parseInterpolation(this.eat(t.String).v);let a=null;return this.at(t.Ident,n.Body)&&(this.next(),a=this.parseExpr()),{op:o.Request,method:e,url:s,body:a}}parseStatement(){if(this.at(t.Ident,n.If))return this.parseIf();if(this.at(t.Ident,"post")||this.at(t.Ident,"put")||this.at(t.Ident,"delete"))return this.parseRequest();const e=this.eat(t.Ident).v;this.eat(t.Punct,i.Dot);const s=this.eat(t.Ident).v;this.eat(t.Punct,i.ParenL);const a=this.statements.get(s);if(!a)throw new f(`unknown action method "${s}" on "${e}"`,this.locOf(this.peek().pos));const r=a(e);return this.eat(t.Punct,i.ParenR),r}parseMock(e){this.eat(t.Ident,n.Mock);const s=e.mock||{};this.parseEntries(a=>{s[a]=this.parseValue()}),e.mock=s}parseSources(e){this.eat(t.Ident,n.Sources);const s=e.sources||{};this.parseEntries(a=>{s[a]=this.parseValue()}),e.sources=s}parseApi(e){this.eat(t.Ident,n.Api);const s=e.api||{};this.parseEntries(a=>{s[a]=this.parseValue()}),e.api=s}parseMeta(e){this.eat(t.Ident,n.Meta),this.eat(t.Punct,i.BraceL);const s=e.meta||{};for(;!this.at(t.Punct,i.BraceR);){const a=this.eat(t.Ident).v;s[a]=this.eat(t.String).v}this.eat(t.Punct,i.BraceR),e.meta=s}parseRoutes(e){this.eat(t.Ident,n.Routes),this.eat(t.Punct,i.BraceL);const s=e.routes||[];for(;!this.at(t.Punct,i.BraceR);){const a=this.peek(),r=this.locOf(a.pos).line,p=this.pathOnLine(r);this.eat(t.Arrow);const h={url:p,page:this.eat(t.Ident).v,loc:this.locOf(a.pos)};this.at(t.Ident,n.Guard)&&(this.next(),h.guardNeg=this.at(t.Ident,n.Not)?(this.next(),!0):!1,h.guard=this.parseDotted(),this.eat(t.Ident,n.Else),h.redirect=this.pathOnLine(r)),s.push(h)}this.eat(t.Punct,i.BraceR),e.routes=s}parseShell(e){this.eat(t.Ident,n.Shell),e.shell={type:P.Shell,props:{},children:this.parseChildren()}}parseConst(e){this.eat(t.Ident,n.Const);const s=this.eat(t.Ident).v;if(this.eat(t.Punct,i.Assign),this.at(t.Punct,i.BraceL)||this.at(t.Punct,i.BrackL))throw new f("const holds a single value (string/number/bool) \u2014 use a block like `theme { \u2026 }` for structured data",this.locOf(this.peek().pos));(e.consts=e.consts||{})[s]=this.parseScalar()}parseTheme(e){this.eat(t.Ident,n.Theme),this.eat(t.Punct,i.BraceL);const s={};for(;!this.at(t.Punct,i.BraceR);){const a=this.eat(t.Ident).v;this.eat(t.Punct,i.BraceL);const r={};for(;!this.at(t.Punct,i.BraceR);)r[this.eat(t.Ident).v]=this.eat(t.String).v;this.eat(t.Punct,i.BraceR),s[a]=r}this.eat(t.Punct,i.BraceR),e.theme=s}parsePart(e){this.eat(t.Ident,n.Part);const s=this.eat(t.Ident).v;this.eat(t.Punct,i.ParenL);const a=[];for(;!this.at(t.Punct,i.ParenR);){const p=this.eat(t.Ident).v;this.eat(t.Punct,i.Colon),a.push({name:p,type:this.parseType()}),this.at(t.Punct,i.Comma)&&this.next()}this.eat(t.Punct,i.ParenR);const r=this.parseChildren();e.parts=e.parts||{},e.parts[s]={params:a,tree:r.length===1?r[0]:{type:P.Stack,props:{},children:r}}}parseWhen(){const e=this.eat(t.Ident,n.When),s=this.parseExpr();return{type:P.When,props:{cond:s},children:this.parseChildren(),loc:this.locOf(e.pos)}}parseEach(){const e=this.eat(t.Ident,n.Each),s=this.parseExpr();this.eat(t.Ident,n.As);const a=this.eat(t.Ident).v;return{type:P.Each,props:{list:s,as:a},children:this.parseChildren(),loc:this.locOf(e.pos)}}parseNode(){if(this.at(t.Ident,n.When))return this.parseWhen();if(this.at(t.Ident,n.Each))return this.parseEach();const e=this.eat(t.Ident),s=e.v,a=this.locOf(e.pos);if(this.at(t.Punct,i.ParenL))return{type:s,args:this.parseArgs(),loc:a};const r={},p=[];s===P.Custom&&(r.component=this.eat(t.Ident).v);let h=!0;for(;h;){const m=this.peek();switch(m.t){case t.String:{const l=v[s]||"label";r[l]=S.has(s)?this.parseInterpolation(this.next().v):this.next().v;break}case t.Param:{const l=v[s]||"label";r[l]={$param:this.next().v};break}case t.Ref:r.data=this.next().v;break;case t.Arrow:this.parseArrow(s,r);break;case t.Ident:{const l=m.v;if(s===P.Title&&k(l)){this.next(),r.level=l;break}const I=this.modifiers.get(l);if(!I){h=!1;break}this.next(),I(r);break}case t.Punct:if(m.v===i.BraceL){for(this.next();!this.at(t.Punct,i.BraceR);)p.push(this.parseNode());this.eat(t.Punct,i.BraceR)}h=!1;break;default:h=!1}}const d={type:s,props:r,loc:a};return p.length&&(d.children=p),d}parseArrow(e,s){if(this.next(),e===P.Link){s.to=this.parsePath();return}s.action=this.parseDotted(),this.at(t.Punct,i.ParenL)&&(this.next(),this.at(t.Punct,i.ParenR)||(s.arg=this.parseExpr()),this.eat(t.Punct,i.ParenR))}parseChildren(){this.eat(t.Punct,i.BraceL);const e=[];for(;!this.at(t.Punct,i.BraceR);)e.push(this.parseNode());return this.eat(t.Punct,i.BraceR),e}parseType(){let e=this.eat(t.Ident).v;return this.at(t.Punct,i.Lt)&&(this.next(),e+="<"+this.eat(t.Ident).v+">",this.eat(t.Punct,i.Gt)),e}parseStyleToken(){const e=()=>this.at(t.Number)?this.next().v:this.eat(t.Ident).v;let s=e();for(this.at(t.Punct,i.Colon)&&(this.next(),s+=":"+e());this.at(t.Punct,i.Dot);)this.next(),s+="."+e();return s}parseDotted(){let e=this.at(t.Param)?"$"+this.next().v:this.eat(t.Ident).v;for(;this.at(t.Punct,i.Dot);)this.next(),e+="."+this.eat(t.Ident).v;return e}parseParenList(e){this.eat(t.Punct,i.ParenL);const s=[];for(;!this.at(t.Punct,i.ParenR);)s.push(e()),this.at(t.Punct,i.Comma)&&this.next();return this.eat(t.Punct,i.ParenR),s}rebuildClause(){const e=[];for(;!this.at(t.Punct,i.Comma)&&!this.at(t.Punct,i.ParenR);)e.push(this.next().v);return e.join(" ")}parseEntries(e){for(this.eat(t.Punct,i.BraceL);!this.at(t.Punct,i.BraceR);){const s=this.eat(t.Ident).v;this.eat(t.Punct,i.Colon),e(s),this.at(t.Punct,i.Comma)&&this.next()}this.eat(t.Punct,i.BraceR)}parsePath(){const e=[];let s="";for(;this.at(t.Punct,i.Slash);){const a=this.next();s+="/",this.at(t.Punct,i.BraceL)&&this.peek().pos===a.pos+1?(e.push(s),s="",this.next(),e.push(this.parseExpr()),this.eat(t.Punct,i.BraceR)):this.at(t.Ident)&&this.peek().pos===a.pos+1&&(s+=this.eat(t.Ident).v)}return e.length?(s&&e.push(s),{kind:x.Interp,parts:e}):s}pathOnLine(e){let s="";for(;this.at(t.Punct,i.Slash)&&this.locOf(this.peek().pos).line===e;)this.next(),s+="/",this.at(t.Punct,i.Colon)?(this.next(),s+=":"+this.eat(t.Ident).v):this.at(t.Ident)&&(s+=this.eat(t.Ident).v);return s}parseArgs(){this.eat(t.Punct,i.ParenL);const e={};for(;!this.at(t.Punct,i.ParenR);){const s=this.eat(t.Ident).v;this.eat(t.Punct,i.Colon),e[s]=this.parseArgValue(),this.at(t.Punct,i.Comma)&&this.next()}return this.eat(t.Punct,i.ParenR),e}parseArgValue(){return this.at(t.String)?this.next().v:this.at(t.Number)?Number(this.next().v):this.at(t.Ref)?this.next().v:this.at(t.Param)?{$param:this.next().v}:this.parseDotted()}}function A(c){return new w(c).parse()}export{w as Parser,A as parse};
|