@lunora/codegen 1.0.0-alpha.324 → 1.0.0-alpha.325

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.
Files changed (35) hide show
  1. package/dist/index.d.mts +25 -11
  2. package/dist/index.d.ts +25 -11
  3. package/dist/index.mjs +1 -1
  4. package/dist/packem_shared/DEFAULT_TARGET-BbWiB-rs.mjs +1 -0
  5. package/dist/packem_shared/{NOTIFY_FILENAME-bAt7J3cs.mjs → NOTIFY_FILENAME-DiYZjYts.mjs} +1 -1
  6. package/dist/packem_shared/SCHEMA_SNAPSHOT_FILENAME-WbrlAts0.mjs +11 -0
  7. package/dist/packem_shared/chain-DYBhMcDK.mjs +1 -0
  8. package/dist/packem_shared/classify-procedure-call-DUBO9bqm.mjs +1 -0
  9. package/dist/packem_shared/{context-property-calls-Cn3upNgZ.mjs → context-property-calls-eO5eiVZG.mjs} +1 -1
  10. package/dist/packem_shared/{context-root-BdxINX-T.mjs → context-root-D-pTjHtx.mjs} +1 -1
  11. package/dist/packem_shared/{database-calls-BKozZUEW.mjs → database-calls-DJgmh0Kv.mjs} +1 -1
  12. package/dist/packem_shared/discoverFunctions-CIJja4zp.mjs +1 -0
  13. package/dist/packem_shared/discoverHyperdriveCalls-DVIQ0i_e.mjs +1 -0
  14. package/dist/packem_shared/{discoverInserts-BjxXCACZ.mjs → discoverInserts-CednbRCq.mjs} +1 -1
  15. package/dist/packem_shared/discoverMaskProcedures-B4k9BS0s.mjs +1 -0
  16. package/dist/packem_shared/{discoverNondeterministicCalls-DvhyKM-f.mjs → discoverNondeterministicCalls-B6FUSWes.mjs} +1 -1
  17. package/dist/packem_shared/{discoverQueries-C8E7TeRT.mjs → discoverQueries-BezURxvr.mjs} +1 -1
  18. package/dist/packem_shared/discoverR2sqlCalls-B9Q6xfi6.mjs +1 -0
  19. package/dist/packem_shared/{discoverRlsMetadata-QRsWRQbM.mjs → discoverRlsMetadata-DCgP2H39.mjs} +1 -1
  20. package/dist/packem_shared/{discoverRlsProcedures-Du7ITNTQ.mjs → discoverRlsProcedures-Os1lrVX_.mjs} +1 -1
  21. package/dist/packem_shared/{discoverStorageRulesMetadata-ClzKLdCV.mjs → discoverStorageRulesMetadata-BTD9Vs5X.mjs} +1 -1
  22. package/dist/packem_shared/{emitFunctions-CuZzKaU4.mjs → emitFunctions-Cg0JxGpk.mjs} +130 -76
  23. package/dist/packem_shared/{emitShard-BF--3qQv.mjs → emitShard-Ba8hJ_G8.mjs} +1 -1
  24. package/dist/packem_shared/{exported-procedure-chains-BNBUkXui.mjs → exported-procedure-chains-DOFtzPZn.mjs} +1 -1
  25. package/dist/packem_shared/{index-JnqBWRYO.mjs → index-iWQbulvu.mjs} +1 -1
  26. package/dist/packem_shared/{shard-ceGu_Fps.mjs → shard-BtImwCVL.mjs} +95 -92
  27. package/package.json +9 -9
  28. package/dist/packem_shared/DEFAULT_TARGET-DXhxbij-.mjs +0 -1
  29. package/dist/packem_shared/SCHEMA_SNAPSHOT_FILENAME-CXmfa4xx.mjs +0 -11
  30. package/dist/packem_shared/chain-Cm6BMT8g.mjs +0 -1
  31. package/dist/packem_shared/classify-procedure-call-DVxdUhZt.mjs +0 -1
  32. package/dist/packem_shared/discoverFunctions-CZgLhsMn.mjs +0 -1
  33. package/dist/packem_shared/discoverHyperdriveCalls-DV4IglLE.mjs +0 -1
  34. package/dist/packem_shared/discoverMaskProcedures-DE-8CDen.mjs +0 -1
  35. package/dist/packem_shared/discoverR2sqlCalls-DVcfMO6-.mjs +0 -1
@@ -1 +1 @@
1
- import{Node as o}from"ts-morph";import{listLunoraSourceFiles as c,lunoraRelativePath as f,findObjectProperty as u}from"./isTestPath-B81lOULB.mjs";import{b as p,d}from"./attribution-hVBriwzy.mjs";import{t as m}from"./database-calls-BKozZUEW.mjs";import{c as b}from"./classify-procedure-call-DVxdUhZt.mjs";import{r as h}from"./chain-Cm6BMT8g.mjs";const g=e=>{const t=e.getArguments()[0];if(!t||!o.isArrayLiteralExpression(t))return[];const r=[];for(const s of t.getElements()){if(!o.isObjectLiteralExpression(s))continue;const i=u(s,"table");if(!i||!o.isPropertyAssignment(i))continue;const n=i.getInitializer();n&&o.isStringLiteral(n)&&r.push(n.getLiteralText())}return r},y=e=>{const t=h(e);return{rlsTables:t.flatMap(r=>g(r)),usesRls:t.length>0}},v=new Set(["explain","findFirst","findFirstOrThrow","findMany","get","query"]),x=new Set(["delete","deleteMany","insert","insertMany","patch","patchIf","patchMany","replace"]),P=(e,t)=>{if(!o.isVariableDeclaration(e))return;const r=e.getInitializer();if(!r||!o.isCallExpression(r))return;const s=b(r);if(!s)return;const i=s.receiver?y(s.receiver):{rlsTables:[],usesRls:!1},{tablesRead:n,tablesWritten:a}=m(e,v,x);return{exportName:d(e)??e.getName(),file:t,rlsTables:i.rlsTables,tablesRead:n,tablesWritten:a,usesRls:i.usesRls,visibility:s.visibility}},M=(e,t)=>{const r=[];for(const s of c(t)){const i=e.getSourceFile(s)??e.addSourceFileAtPath(s),n=f(t,s);for(const a of p(i)){const l=P(a,n);l&&r.push(l)}}return r};export{M as default};
1
+ import{Node as o}from"ts-morph";import{listLunoraSourceFiles as c,lunoraRelativePath as f,findObjectProperty as u}from"./isTestPath-B81lOULB.mjs";import{b as p,d}from"./attribution-hVBriwzy.mjs";import{t as m}from"./database-calls-DJgmh0Kv.mjs";import{c as b}from"./classify-procedure-call-DUBO9bqm.mjs";import{r as h}from"./chain-DYBhMcDK.mjs";const g=e=>{const t=e.getArguments()[0];if(!t||!o.isArrayLiteralExpression(t))return[];const r=[];for(const s of t.getElements()){if(!o.isObjectLiteralExpression(s))continue;const i=u(s,"table");if(!i||!o.isPropertyAssignment(i))continue;const n=i.getInitializer();n&&o.isStringLiteral(n)&&r.push(n.getLiteralText())}return r},y=e=>{const t=h(e);return{rlsTables:t.flatMap(r=>g(r)),usesRls:t.length>0}},v=new Set(["explain","findFirst","findFirstOrThrow","findMany","get","query"]),x=new Set(["delete","deleteMany","insert","insertMany","patch","patchIf","patchMany","replace"]),P=(e,t)=>{if(!o.isVariableDeclaration(e))return;const r=e.getInitializer();if(!r||!o.isCallExpression(r))return;const s=b(r);if(!s)return;const i=s.receiver?y(s.receiver):{rlsTables:[],usesRls:!1},{tablesRead:n,tablesWritten:a}=m(e,v,x);return{exportName:d(e)??e.getName(),file:t,rlsTables:i.rlsTables,tablesRead:n,tablesWritten:a,usesRls:i.usesRls,visibility:s.visibility}},M=(e,t)=>{const r=[];for(const s of c(t)){const i=e.getSourceFile(s)??e.addSourceFileAtPath(s),n=f(t,s);for(const a of p(i)){const l=P(a,n);l&&r.push(l)}}return r};export{M as default};
@@ -1 +1 @@
1
- import{Node as u}from"ts-morph";import{listLunoraSourceFiles as f,lunoraRelativePath as p,stringPropertyOf as l}from"./isTestPath-B81lOULB.mjs";import{w as d}from"./classify-procedure-call-DVxdUhZt.mjs";import{e as m}from"./exported-procedure-chains-BNBUkXui.mjs";const h=new Set(["delete","list","read","write"]),g=t=>d(t,"use","storageRules"),x=(t,s,n)=>{const e=t.getArguments()[0];if(!e||!u.isArrayLiteralExpression(e))return[];const i=[];for(const o of e.getElements()){if(!u.isObjectLiteralExpression(o))continue;const r=l(o,"on");if(r===void 0||!h.has(r))continue;const a=l(o,"prefix"),c={bucket:l(o,"bucket")??"",file:s,on:r,procedure:n};a!==void 0&&(c.prefix=a),i.push(c)}return i},A=(t,s)=>{const n=[];for(const e of f(s)){const i=t.getSourceFile(e)??t.addSourceFileAtPath(e),o=p(s,e);for(const{name:r,receiver:a}of m(i))for(const c of g(a))n.push(...x(c,o,r))}return{rules:n}};export{A as default};
1
+ import{Node as u}from"ts-morph";import{listLunoraSourceFiles as f,lunoraRelativePath as p,stringPropertyOf as l}from"./isTestPath-B81lOULB.mjs";import{w as d}from"./classify-procedure-call-DUBO9bqm.mjs";import{e as m}from"./exported-procedure-chains-DOFtzPZn.mjs";const h=new Set(["delete","list","read","write"]),g=t=>d(t,"use","storageRules"),x=(t,s,n)=>{const e=t.getArguments()[0];if(!e||!u.isArrayLiteralExpression(e))return[];const i=[];for(const o of e.getElements()){if(!u.isObjectLiteralExpression(o))continue;const r=l(o,"on");if(r===void 0||!h.has(r))continue;const a=l(o,"prefix"),c={bucket:l(o,"bucket")??"",file:s,on:r,procedure:n};a!==void 0&&(c.prefix=a),i.push(c)}return i},A=(t,s)=>{const n=[];for(const e of f(s)){const i=t.getSourceFile(e)??t.addSourceFileAtPath(e),o=p(s,e);for(const{name:r,receiver:a}of m(i))for(const c of g(a))n.push(...x(c,o,r))}return{rules:n}};export{A as default};
@@ -1,30 +1,30 @@
1
- import{LunoraError as P}from"@lunora/errors";import{L as oe,G as C,d as j,I as F,b as M,r as se,c as ae}from"./shared-DnCokNcE.mjs";import{renderAgentFunctionRegistry as ie,renderSandboxFunctionRegistry as ce}from"./emitApi-CDgIPAG2.mjs";import{b as le,a as de,r as _,c as ue}from"./qualifiers-DEdXn5wP.mjs";import{s as f}from"./dispatch-namespace-DwTjD7BU.mjs";const he=new Set(["any","bigint","boolean","date","id","null","number","storage","string","timestamp"]),D=r=>r.column!==void 0,me=(r,t)=>{switch(r){case"bigint":return`if (typeof ${t} !== "bigint") return DEFER;
1
+ import{LunoraError as x}from"@lunora/errors";import{L as ie,G as D,d as j,I as T,b as F,r as ce,c as le}from"./shared-DnCokNcE.mjs";import{renderAgentFunctionRegistry as ue,renderSandboxFunctionRegistry as de}from"./emitApi-CDgIPAG2.mjs";import{b as he,a as pe,r as I,c as me}from"./qualifiers-DEdXn5wP.mjs";import{s as g}from"./dispatch-namespace-DwTjD7BU.mjs";const ge=new Set(["any","bigint","boolean","date","id","null","number","storage","string","timestamp"]),U=r=>r.column!==void 0,fe=(r,t)=>{switch(r){case"bigint":return`if (typeof ${t} !== "bigint") return DEFER;
2
2
  `;case"boolean":return`if (typeof ${t} !== "boolean") return DEFER;
3
3
  `;case"date":case"number":case"timestamp":return`if (typeof ${t} !== "number" || !Number.isFinite(${t})) return DEFER;
4
4
  `;case"null":return`if (${t} !== null) return DEFER;
5
5
  `;default:return`if (typeof ${t} !== "string") return DEFER;
6
- `}},pe=(r,t)=>r.stringMaxLength===void 0?"":`if (${t}.length > ${String(r.stringMaxLength)}) return DEFER;
7
- `,ge=(r,t)=>{const n=r.literalValue?.trim();if(!(n===void 0||!oe.test(n)))return{out:t,pre:`if (${t} !== ${n}) return DEFER;
8
- `}},T=(r,t,n)=>{if(!D(r)&&!(r.unmodelledRefinement||r.sourceText!==void 0)){if(he.has(r.kind))return r.kind==="any"?{out:t,pre:""}:{out:t,pre:me(r.kind,t)+pe(r,t)};switch(r.kind){case"array":return fe(r,t,n);case"literal":return ge(r,t);case"object":return we(r,t,n);default:return}}},fe=(r,t,n)=>{const{inner:o}=r;if(!o)return;const a=n.next(),i=`__arr${String(a)}`,s=`__i${String(a)}`,d=`__e${String(a)}`,u=T(o,d,n);if(!u)return;const c=`if (!Array.isArray(${t})) return DEFER;
6
+ `}},ye=(r,t)=>r.stringMaxLength===void 0?"":`if (${t}.length > ${String(r.stringMaxLength)}) return DEFER;
7
+ `,$e=(r,t)=>{const n=r.literalValue?.trim();if(!(n===void 0||!ie.test(n)))return{out:t,pre:`if (${t} !== ${n}) return DEFER;
8
+ `}},E=(r,t,n)=>{if(!U(r)&&!(r.unmodelledRefinement||r.sourceText!==void 0)){if(ge.has(r.kind))return r.kind==="any"?{out:t,pre:""}:{out:t,pre:fe(r.kind,t)+ye(r,t)};switch(r.kind){case"array":return we(r,t,n);case"literal":return $e(r,t);case"object":return be(r,t,n);default:return}}},we=(r,t,n)=>{const{inner:o}=r;if(!o)return;const a=n.next(),i=`__arr${String(a)}`,s=`__i${String(a)}`,c=`__e${String(a)}`,d=E(o,c,n);if(!d)return;const l=`if (!Array.isArray(${t})) return DEFER;
9
9
  const ${i} = new Array(${t}.length);
10
10
  for (let ${s} = 0; ${s} < ${t}.length; ${s}++) {
11
- const ${d} = ${t}[${s}];
12
- ${u.pre}${i}[${s}] = ${u.out};
11
+ const ${c} = ${t}[${s}];
12
+ ${d.pre}${i}[${s}] = ${d.out};
13
13
  }
14
- `;return{out:i,pre:c}},ye=(r,t,n,o)=>{const a=JSON.stringify(r);if(t.kind==="optional"){if(t.hasRefinement||t.sourceText!==void 0||D(t))return;const{inner:s}=t;if(!s)return;const d=T(s,n,o);if(!d)return;const u=o.next(),c=`__has${String(u)}`,l=`__val${String(u)}`,g=`let ${c} = false;
15
- let ${l};
14
+ `;return{out:i,pre:l}},Re=(r,t,n,o)=>{const a=JSON.stringify(r);if(t.kind==="optional"){if(t.hasRefinement||t.sourceText!==void 0||U(t))return;const{inner:s}=t;if(!s)return;const c=E(s,n,o);if(!c)return;const d=o.next(),l=`__has${String(d)}`,u=`__val${String(d)}`,f=`let ${l} = false;
15
+ let ${u};
16
16
  if (${n} !== undefined) {
17
- ${d.pre}${l} = ${d.out};
18
- ${c} = true;
17
+ ${c.pre}${u} = ${c.out};
18
+ ${l} = true;
19
19
  }
20
- `;return{entry:`...(${c} ? { ${a}: ${l} } : {})`,pre:g}}const i=T(t,n,o);if(i)return{entry:`${a}: ${i.out}`,pre:i.pre}},$e=new Set(Object.getOwnPropertyNames(Object.prototype)),U=(r,t,n)=>{let o="";const a=[];for(const i of Object.keys(r)){const s=r[i];if(!s)return;const d=JSON.stringify(i);let u=`${t}[${d}]`;if($e.has(i)){const l=`__f${String(n.next())}`;o+=`const ${l} = Object.hasOwn(${t}, ${d}) ? ${t}[${d}] : undefined;
21
- `,u=l}const c=ye(i,s,u,n);if(!c)return;o+=c.pre,a.push(c.entry)}return{entries:a.join(", "),pre:o}},J=r=>{const t=`Object.getPrototypeOf(${r})`;return`if (${t} !== Object.prototype && ${t} !== null) return DEFER;
22
- `},we=(r,t,n)=>{const o=r.shape??{},a=U(o,t,n);if(!a)return;const i=n.next(),s=`__obj${String(i)}`,d=`if (typeof ${t} !== "object" || ${t} === null || Array.isArray(${t})) return DEFER;
23
- ${J(t)}${a.pre}const ${s} = { ${a.entries} };
24
- `;return{out:s,pre:d}},B=r=>{let t=0;const o=U(r,"source",{next:()=>(t+=1,t)});if(o)return`(source) => {
20
+ `;return{entry:`...(${l} ? { ${a}: ${u} } : {})`,pre:f}}const i=E(t,n,o);if(i)return{entry:`${a}: ${i.out}`,pre:i.pre}},ke=new Set(Object.getOwnPropertyNames(Object.prototype)),J=(r,t,n)=>{let o="";const a=[];for(const i of Object.keys(r)){const s=r[i];if(!s)return;const c=JSON.stringify(i);let d=`${t}[${c}]`;if(ke.has(i)){const u=`__f${String(n.next())}`;o+=`const ${u} = Object.hasOwn(${t}, ${c}) ? ${t}[${c}] : undefined;
21
+ `,d=u}const l=Re(i,s,d,n);if(!l)return;o+=l.pre,a.push(l.entry)}return{entries:a.join(", "),pre:o}},B=r=>{const t=`Object.getPrototypeOf(${r})`;return`if (${t} !== Object.prototype && ${t} !== null) return DEFER;
22
+ `},be=(r,t,n)=>{const o=r.shape??{},a=J(o,t,n);if(!a)return;const i=n.next(),s=`__obj${String(i)}`,c=`if (typeof ${t} !== "object" || ${t} === null || Array.isArray(${t})) return DEFER;
23
+ ${B(t)}${a.pre}const ${s} = { ${a.entries} };
24
+ `;return{out:s,pre:c}},q=r=>{let t=0;const o=J(r,"source",{next:()=>(t+=1,t)});if(o)return`(source) => {
25
25
  if (typeof source !== "object" || source === null || Array.isArray(source)) return DEFER;
26
- ${J("source")}${o.pre}return { ${o.entries} };
27
- }`},Re=(r,t)=>`lunora_${f(r)}_${String(t)}`,I=r=>JSON.stringify(Object.entries(r).toSorted(([t],[n])=>t.localeCompare(n)).map(([t,n])=>{const o=n.kind==="optional",a=o?n.inner??{kind:"unknown"}:n,i=a.kind==="array"?a.inner?.kind:void 0,s=a.kind==="id"?a.tableName:void 0;return{kind:a.kind,name:t,optional:o,...s===void 0?{}:{table:s},...i===void 0||i==="unknown"?{}:{element:i}}})),H=(r,t,n,o)=>{const a=new Map,i=s=>{a.has(s)||a.set(s,Re(s,a.size))};for(const s of r)i(s.filePath);for(const s of t)i(s.filePath);for(const s of n)i(s.filePath);for(const s of o)i(s.filePath);return a},q=(r,t,n)=>new Set([...r.map(o=>o.filePath),...t.map(o=>o.filePath),...n.map(o=>o.filePath)]),k=r=>`${r}[functionPath]`,be=`const callRegistered = async <R>(context: CallerCtx, functionPath: string, args: Record<string, unknown> | undefined): Promise<R> => {
26
+ ${B("source")}${o.pre}return { ${o.entries} };
27
+ }`},Ne=(r,t)=>`lunora_${g(r)}_${String(t)}`,C=r=>JSON.stringify(Object.entries(r).toSorted(([t],[n])=>t.localeCompare(n)).map(([t,n])=>{const o=n.kind==="optional",a=o?n.inner??{kind:"unknown"}:n,i=a.kind==="array"?a.inner?.kind:void 0,s=a.kind==="id"?a.tableName:void 0;return{kind:a.kind,name:t,optional:o,...s===void 0?{}:{table:s},...i===void 0||i==="unknown"?{}:{element:i}}})),H=(r,t,n,o)=>{const a=new Map,i=s=>{a.has(s)||a.set(s,Ne(s,a.size))};for(const s of r)i(s.filePath);for(const s of t)i(s.filePath);for(const s of n)i(s.filePath);for(const s of o)i(s.filePath);return a},W=(r,t,n)=>new Set([...r.map(o=>o.filePath),...t.map(o=>o.filePath),...n.map(o=>o.filePath)]),N=r=>`${r}[functionPath]`,ve=`const callRegistered = async <R>(context: CallerCtx, functionPath: string, args: Record<string, unknown> | undefined): Promise<R> => {
28
28
  const registered = await loadFunction(functionPath);
29
29
 
30
30
  if (!registered) {
@@ -57,29 +57,83 @@ ${J("source")}${o.pre}return { ${o.entries} };
57
57
  }
58
58
 
59
59
  return (await registered.handler(context, args ?? {})) as R;
60
- };`,Ne=(r,t,n=[],o=[],a=!1)=>{const i=H(r,t,n,o),s=q(t,n,o),d=[...i.entries()].filter(([e])=>!a||s.has(e)?!0:r.some(m=>m.filePath===e&&m.channel?.kind==="room")).map(([e,m])=>{if(!F.test(e))throw new P("INTERNAL",`@lunora/codegen: refusing to emit import for unsafe file path: ${JSON.stringify(e)}`);return`import ${a&&!s.has(e)?"type ":""}* as ${m} from "../${e}.js";`}).join(`
61
- `),u=r.map(e=>!a||s.has(e.filePath)?` "${f(e.filePath)}:${e.exportName}": ${i.get(e.filePath)??""}.${e.exportName} as unknown as RegisteredLunoraFunction,`:` "${f(e.filePath)}:${e.exportName}": { args: {}, handler: unloadedFunctionHandler, ...${JSON.stringify({argumentDescriptors:JSON.parse(I(e.args)),kind:e.kind,...e.channel?{channel:e.channel}:{},...e.expose?{expose:e.expose}:{},...e.lifecycle?{lifecycle:e.lifecycle}:{},...e.visibility?{visibility:e.visibility}:{},...e.x402?.price===void 0?{}:{x402:{price:e.x402.price}}})} } satisfies RegisteredLunoraFunction & Pick<FunctionManifestEntry, "argumentDescriptors" | "channel" | "expose">,`).join(`
62
- `),c=t.map(e=>` ${JSON.stringify(e.id)}: ${i.get(e.filePath)??""}.${e.exportName} as unknown as RegisteredDataMigration,`).join(`
63
- `),l=n.map(e=>` "${f(e.filePath)}:${e.exportName}": ${i.get(e.filePath)??""}.${e.exportName} as unknown as RegisteredLunoraFunction,`).join(`
64
- `),g=o.map(e=>` "${e.exportName}": ${i.get(e.filePath)??""}.${e.exportName} as unknown as RegisteredShape,`).join(`
65
- `),y=n.map(e=>`${f(e.filePath)}:${e.exportName}`),$=[u,l].filter(e=>e.length>0).join(`
66
- `),v=r.filter(e=>!a||s.has(e.filePath)).map(e=>{if(e.lifecycle||Object.keys(e.args).length===0)return;const m=B(e.args);return m===void 0?void 0:`installCompiledValidatorMap(${i.get(e.filePath)??""}.${e.exportName}.args, ${m});`}).filter(e=>e!==void 0).join(`
60
+ };`,Oe=(r,t,n=[],o=[],a=!1)=>{const i=H(r,t,n,o),s=W(t,n,o),c=[...i.entries()].filter(([e])=>!a||s.has(e)?!0:r.some(p=>p.filePath===e&&p.channel?.kind==="room")).map(([e,p])=>{if(!T.test(e))throw new x("INTERNAL",`@lunora/codegen: refusing to emit import for unsafe file path: ${JSON.stringify(e)}`);return`import ${a&&!s.has(e)?"type ":""}* as ${p} from "../${e}.js";`}).join(`
61
+ `),d=r.map(e=>!a||s.has(e.filePath)?` "${g(e.filePath)}:${e.exportName}": ${i.get(e.filePath)??""}.${e.exportName} as unknown as RegisteredLunoraFunction,`:` "${g(e.filePath)}:${e.exportName}": { args: {}, handler: unloadedFunctionHandler, ...${JSON.stringify({argumentDescriptors:JSON.parse(C(e.args)),kind:e.kind,...e.channel?{channel:e.channel}:{},...e.expose?{expose:e.expose}:{},...e.lifecycle?{lifecycle:e.lifecycle}:{},...e.visibility?{visibility:e.visibility}:{},...e.x402?.price===void 0?{}:{x402:{price:e.x402.price}},...e.socket===void 0?{}:{auth:e.socket.auth,socketPath:e.socket.path}})} } satisfies RegisteredLunoraFunction & Pick<FunctionManifestEntry, "argumentDescriptors" | "channel" | "expose">,`).join(`
62
+ `),l=t.map(e=>` ${JSON.stringify(e.id)}: ${i.get(e.filePath)??""}.${e.exportName} as unknown as RegisteredDataMigration,`).join(`
63
+ `),u=n.map(e=>` "${g(e.filePath)}:${e.exportName}": ${i.get(e.filePath)??""}.${e.exportName} as unknown as RegisteredLunoraFunction,`).join(`
64
+ `),f=o.map(e=>` "${e.exportName}": ${i.get(e.filePath)??""}.${e.exportName} as unknown as RegisteredShape,`).join(`
65
+ `),y=n.map(e=>`${g(e.filePath)}:${e.exportName}`),$=[d,u].filter(e=>e.length>0).join(`
66
+ `),v=r.filter(e=>!a||s.has(e.filePath)).map(e=>{if(e.lifecycle||Object.keys(e.args).length===0)return;const p=q(e.args);return p===void 0?void 0:`installCompiledValidatorMap(${i.get(e.filePath)??""}.${e.exportName}.args, ${p});`}).filter(e=>e!==void 0).join(`
67
67
  `),O=r.filter(e=>e.channel?.kind==="room").map(e=>` ${JSON.stringify(e.channel?.name??"")}: RoomMessageOf<typeof ${i.get(e.filePath)??""}[${JSON.stringify(e.exportName)}]>;`).join(`
68
- `),b=[...r.map(e=>({args:e.args,definition:e,path:`${f(e.filePath)}:${e.exportName}`})),...n.map(e=>({args:e.args,definition:{...e,expose:void 0,kind:"mutation",lifecycle:void 0,visibility:void 0,x402:void 0},path:`${f(e.filePath)}:${e.exportName}`}))],x=a?b.filter(({definition:e})=>!s.has(e.filePath)):[];for(const{definition:e}of b)if(a&&e.x402&&e.x402.price===void 0)throw new P("INTERNAL",`@lunora/codegen: lazy function registry needs a literal \`.x402({ price })\` value in ${e.filePath}:${e.exportName}`);const N=a?x.map(({definition:e,path:m})=>{const R=i.get(e.filePath)??"",S="channel"in e?e.channel:void 0,A={argumentDescriptors:JSON.parse(I(e.args)),exportName:e.exportName,kind:e.kind,moduleId:R,...S?{channel:S}:{},...e.expose?{expose:e.expose}:{},...e.lifecycle?{lifecycle:e.lifecycle}:{},...e.visibility?{visibility:e.visibility}:{},...e.x402?.price===void 0?{}:{x402:{price:e.x402.price}}};return` ${JSON.stringify(m)}: ${JSON.stringify(A)},`}).join(`
69
- `):"",h=[...new Set(x.map(({definition:e})=>e.filePath))],w=a?h.map(e=>{if(!F.test(e))throw new P("INTERNAL",`@lunora/codegen: refusing to emit import for unsafe file path: ${JSON.stringify(e)}`);const m=i.get(e)??"";return` ${JSON.stringify(m)}: () => import(${JSON.stringify(`./fn/${m}.js`)}),`}).join(`
68
+ `),k=[...r.map(e=>({args:e.args,definition:e,path:`${g(e.filePath)}:${e.exportName}`})),...n.map(e=>({args:e.args,definition:{...e,expose:void 0,kind:"mutation",lifecycle:void 0,visibility:void 0,x402:void 0},path:`${g(e.filePath)}:${e.exportName}`}))],S=a?k.filter(({definition:e})=>!s.has(e.filePath)):[];for(const{definition:e}of k)if(a&&e.x402&&e.x402.price===void 0)throw new x("INTERNAL",`@lunora/codegen: lazy function registry needs a literal \`.x402({ price })\` value in ${e.filePath}:${e.exportName}`);const b=a?S.map(({definition:e,path:p})=>{const R=i.get(e.filePath)??"",P="channel"in e?e.channel:void 0,L={argumentDescriptors:JSON.parse(C(e.args)),exportName:e.exportName,kind:e.kind,moduleId:R,...P?{channel:P}:{},...e.expose?{expose:e.expose}:{},...e.lifecycle?{lifecycle:e.lifecycle}:{},...e.visibility?{visibility:e.visibility}:{},...e.x402?.price===void 0?{}:{x402:{price:e.x402.price}}};return` ${JSON.stringify(p)}: ${JSON.stringify(L)},`}).join(`
69
+ `):"",h=[...new Set(S.map(({definition:e})=>e.filePath))],w=a?h.map(e=>{if(!T.test(e))throw new x("INTERNAL",`@lunora/codegen: refusing to emit import for unsafe file path: ${JSON.stringify(e)}`);const p=i.get(e)??"";return` ${JSON.stringify(p)}: () => import(${JSON.stringify(`./fn/${p}.js`)}),`}).join(`
70
70
  `):"";return{dispatchBody:$.length>0?`
71
71
  ${$}
72
- `:"",importBlock:d.length>0?`${d}
72
+ `:"",importBlock:c.length>0?`${c}
73
73
 
74
- `:"",installBlock:v,manifestBody:N.length>0?`
75
- ${N}
76
- `:"",migrationBody:c.length>0?`
77
- ${c}
74
+ `:"",installBlock:v,manifestBody:b.length>0?`
75
+ ${b}
76
+ `:"",migrationBody:l.length>0?`
77
+ ${l}
78
78
  `:"",moduleLoaders:w.length>0?`
79
79
  ${w}
80
- `:"",mutatorPaths:y,roomMessagesBody:O,shapeBody:g.length>0?`
81
- ${g}
82
- `:""}},ke=r=>{const t=M(r,o=>{const a=_(se(o.args),o.filePath),i=a==="{}"?"?":"",s=_(ue(o),o.filePath);return o.kind==="stream"?`${o.exportName}: (args${i}: ${a}) => Promise<AsyncIterable<${s}>>;`:`${o.exportName}: (args${i}: ${a}) => Promise<${s}>;`},"type");return{implementation:M(r,o=>`${ae(o.exportName)}: (args) => callRegistered(context, "${f(o.filePath)}:${o.exportName}", args),`,"value"),types:t}},ve=r=>{const t={connect:[],disconnect:[],init:[],reactor:[],whisper:[]};for(const n of r)n.lifecycle&&t[n.lifecycle].push(`${f(n.filePath)}:${n.exportName}`);return t},Oe=(r,t,n)=>r?{channelField:` /**
80
+ `:"",mutatorPaths:y,roomMessagesBody:O,shapeBody:f.length>0?`
81
+ ${f}
82
+ `:""}},Se=r=>{const t=F(r,o=>{const a=I(ce(o.args),o.filePath),i=a==="{}"?"?":"",s=I(me(o),o.filePath);return o.kind==="stream"?`${o.exportName}: (args${i}: ${a}) => Promise<AsyncIterable<${s}>>;`:`${o.exportName}: (args${i}: ${a}) => Promise<${s}>;`},"type");return{implementation:F(r,o=>`${le(o.exportName)}: (args) => callRegistered(context, "${g(o.filePath)}:${o.exportName}", args),`,"value"),types:t}},xe=r=>{const t={connect:[],disconnect:[],init:[],reactor:[],whisper:[]};for(const n of r)!n.lifecycle||n.lifecycle==="socket"||t[n.lifecycle].push(`${g(n.filePath)}:${n.exportName}`);return t},Pe=r=>{const t=new Map,n=[];for(const o of r){if(o.lifecycle!=="socket"||o.socket===void 0)continue;const{auth:a,origin:i,path:s}=o.socket,c=`${g(o.filePath)}:${o.exportName}`,d=t.get(s);if(!(d?.origin!==void 0&&d.origin===i)){if(d!==void 0)throw new x("DUPLICATE_SOCKET_PATH",`two defineWebSocket routes serve "${s}" (${d.functionPath} and ${c}); socket paths must be unique.`);t.set(s,{functionPath:c,origin:i}),n.push(` ${JSON.stringify(s)}: { auth: ${String(a)}, functionPath: ${JSON.stringify(c)} },`)}}return`
83
+ /**
84
+ * Socket registry: the URL path of each \`defineWebSocket\` route → its function path + auth requirement.
85
+ * Static, so building the worker never evaluates a route's module. The generated ShardDO's \`socketRoute\` override
86
+ * resolves an upgraded socket through this map.
87
+ */
88
+ export const LUNORA_SOCKETS: Readonly<Record<string, { auth: boolean; functionPath: string }>> = {
89
+ ${n.join(`
90
+ `)}
91
+ };
92
+ `},Le=(r,t)=>{const n=r.some(c=>c.lifecycle==="socket"),a=n&&t?Pe(r):n&&!t?`
93
+ /**
94
+ * Socket registry: the URL path of each \`defineWebSocket\` route → its function
95
+ * path + auth requirement. The generated ShardDO's \`socketRoute\` override
96
+ * resolves an upgraded socket through this map so a route's typed
97
+ * \`onOpen\`/\`onMessage\`/\`onClose\` dispatch server-side under the socket's
98
+ * verified identity. Two routes on one path throw at module load rather than letting
99
+ * the map silently keep whichever came last.
100
+ */
101
+ export const LUNORA_SOCKETS: Readonly<Record<string, { auth: boolean; functionPath: string }>> = (() => {
102
+ const registry: Record<string, { auth: boolean; functionPath: string }> = {};
103
+ const owners = new Map<string, unknown>();
104
+
105
+ for (const [path, fn] of Object.entries(LUNORA_FUNCTIONS)) {
106
+ if (fn.lifecycle !== "socket" || typeof fn.socketPath !== "string") {
107
+ continue;
108
+ }
109
+
110
+ const owner = owners.get(fn.socketPath);
111
+
112
+ // The same registration exported under two names (an alias) is one route.
113
+ if (owner !== undefined && owner !== fn) {
114
+ throw new Error(\`two defineWebSocket routes serve "\${fn.socketPath}"; socket paths must be unique\`);
115
+ }
116
+
117
+ if (owner === undefined) {
118
+ owners.set(fn.socketPath, fn);
119
+ registry[fn.socketPath] = { auth: fn.auth === true, functionPath: path };
120
+ }
121
+ }
122
+
123
+ return registry;
124
+ })();
125
+ `:"";return{fields:n?`
126
+ /**
127
+ * Set on a \`defineWebSocket\` registration: the URL path the route serves.
128
+ * The generated \`LUNORA_SOCKETS\` map keys it on this path so the ShardDO
129
+ * resolves an upgraded socket to this registration.
130
+ */
131
+ socketPath?: string;
132
+ /**
133
+ * Set on a \`defineWebSocket\` registration: whether the route refuses an
134
+ * anonymous upgrade. Read into \`LUNORA_SOCKETS\` alongside \`socketPath\`.
135
+ */
136
+ auth?: boolean;`:"",lifecycleMember:n?' | "socket"':"",registry:a}},Ae=(r,t,n)=>r?{channelField:` /**
83
137
  * Set on a \`defineRoom\` registration: the room's name (without the \`room:\`
84
138
  * topic prefix). The generated \`LUNORA_ROOMS\` map keys it on the room's
85
139
  * \`room:<name>\` whisper topic so the ShardDO resolves a room topic to this
@@ -94,7 +148,7 @@ export type LunoraRoomMessages = {
94
148
  ${n}
95
149
  };
96
150
  `,typeImport:`import type { RoomMessageOf } from "${t}";
97
- `}:{channelField:"",messagesBlock:"",typeImport:""},xe=(r,t,n)=>r?t?`
151
+ `}:{channelField:"",messagesBlock:"",typeImport:""},Te=(r,t,n)=>r?t?`
98
152
  /**
99
153
  * Room routes are static metadata so building the worker never evaluates user handlers.
100
154
  */
@@ -103,7 +157,7 @@ export const LUNORA_ROOMS: Readonly<Record<string, string>> = (() => {
103
157
  const owners = new Map<string, string>();
104
158
 
105
159
  for (const { owner, path, topic } of [
106
- ${n.filter(o=>o.channel?.kind==="room").map(o=>` { owner: ${JSON.stringify(o.filePath)}, path: ${JSON.stringify(`${f(o.filePath)}:${o.exportName}`)}, topic: ${JSON.stringify(`room:${o.channel?.name??""}`)} },`).join(`
160
+ ${n.filter(o=>o.channel?.kind==="room").map(o=>` { owner: ${JSON.stringify(o.filePath)}, path: ${JSON.stringify(`${g(o.filePath)}:${o.exportName}`)}, topic: ${JSON.stringify(`room:${o.channel?.name??""}`)} },`).join(`
107
161
  `)}
108
162
  ]) {
109
163
  const prior = owners.get(topic);
@@ -154,54 +208,54 @@ export const LUNORA_ROOMS: Readonly<Record<string, string>> = (() => {
154
208
 
155
209
  return registry;
156
210
  })();
157
- `:"",Se=(r,t)=>{const n=ke(r),o=n.types?`
211
+ `:"",Ee=(r,t)=>{const n=Se(r),o=n.types?`
158
212
  ${n.types}
159
213
  `:"",a=n.implementation?`
160
214
  ${n.implementation}
161
- `:"",i=de(n.types),s=i.length>0?`import type { ${i.join(", ")} } from "./dataModel.js";
162
- `:"",d=r.length>0?"context":"_context";let u="";if(r.length>0){let c=be;t||(c=c.replace("await loadFunction(functionPath)",k("LUNORA_FUNCTIONS"))),u=`${c}
215
+ `:"",i=pe(n.types),s=i.length>0?`import type { ${i.join(", ")} } from "./dataModel.js";
216
+ `:"",c=r.length>0?"context":"_context";let d="";if(r.length>0){let l=ve;t||(l=l.replace("await loadFunction(functionPath)",N("LUNORA_FUNCTIONS"))),d=`${l}
163
217
 
164
- `}return{callRegisteredHelper:u,dataModelImport:s,implementation:a,parameter:d,types:o}},Ee=r=>{const{agents:t=[],functions:n,lazyFunctions:o=!1,migrations:a=[],mutators:i=[],shapes:s=[],useUmbrella:d=!1,usesSandbox:u=!1}=r,c=j(d),{dispatchBody:l,importBlock:g,installBlock:y,manifestBody:$,migrationBody:v,moduleLoaders:O,mutatorPaths:b,roomMessagesBody:x,shapeBody:N}=Ne(n,a,i,s,o),h=ie(t,n),w=ce(u,n),e=[h.lines,w.lines].filter(p=>p.length>0).join(`
165
- `);let m=l;e.length>0&&(m=l.length>0?`${l.trimEnd()}
218
+ `}return{callRegisteredHelper:d,dataModelImport:s,implementation:a,parameter:c,types:o}},De=r=>{const{agents:t=[],functions:n,lazyFunctions:o=!1,migrations:a=[],mutators:i=[],shapes:s=[],useUmbrella:c=!1,usesSandbox:d=!1}=r,l=j(c),{dispatchBody:u,importBlock:f,installBlock:y,manifestBody:$,migrationBody:v,moduleLoaders:O,mutatorPaths:k,roomMessagesBody:S,shapeBody:b}=Oe(n,a,i,s,o),h=ue(t,n),w=de(d,n),e=[h.lines,w.lines].filter(m=>m.length>0).join(`
219
+ `);let p=u;e.length>0&&(p=u.length>0?`${u.trimEnd()}
166
220
  ${e}
167
221
  `:`
168
222
  ${e}
169
- `);const R=ve(n),S=o?"await loadFunction(functionPath)":k("LUNORA_FUNCTIONS"),A=o?` if (${k("LUNORA_FUNCTION_MANIFEST")}?.visibility === "internal") {
223
+ `);const R=xe(n),P=o?"await loadFunction(functionPath)":N("LUNORA_FUNCTIONS"),L=o?` if (${N("LUNORA_FUNCTION_MANIFEST")}?.visibility === "internal") {
170
224
  throw new LunoraError("FUNCTION_NOT_FOUND", \`function not registered: \${functionPath}\`);
171
225
  }
172
226
 
173
- `:"",z=s.length>0?`import type { RegisteredShape } from "${c.server}";
174
- `:"",E=n.some(p=>p.channel?.kind==="room"),L=Oe(E,c.server,x),Q=s.length>0?`
227
+ `:"",z=s.length>0?`import type { RegisteredShape } from "${l.server}";
228
+ `:"",M=n.some(m=>m.channel?.kind==="room"),A=Ae(M,l.server,S),Q=s.length>0?`
175
229
  /**
176
230
  * Replication-shape registry — one entry per \`defineShape\` in \`lunora/shapes.ts\`.
177
231
  * The generated ShardDO's \`resolveShape\` override looks a shape up by name and
178
232
  * evaluates its trusted \`compileWhere(ctx, args)\` to authorize + scope a
179
233
  * \`shape_subscribe\` (reads-as-permissions).
180
234
  */
181
- export const LUNORA_SHAPES: Record<string, RegisteredShape> = {${N}};
182
- `:"",G=b.length>0?`
235
+ export const LUNORA_SHAPES: Record<string, RegisteredShape> = {${b}};
236
+ `:"",G=k.length>0?`
183
237
  /**
184
238
  * Custom-mutator function paths — the \`LUNORA_FUNCTIONS\` keys the generated
185
239
  * ShardDO's \`isCustomMutator\` override routes through the client-watermark push
186
240
  * protocol (\`x-lunora-client-id\`/\`x-lunora-client-seq\` ordering).
187
241
  */
188
- export const LUNORA_MUTATOR_PATHS: ReadonlySet<string> = new Set([${b.map(p=>JSON.stringify(p)).join(", ")}]);
189
- `:"",V=xe(E,o,n),W=y.length>0?`import { DEFER_VALIDATION as DEFER, installCompiledValidatorMap } from "${c.values}";
190
- `:"",Y=y.length>0?`
242
+ export const LUNORA_MUTATOR_PATHS: ReadonlySet<string> = new Set([${k.map(m=>JSON.stringify(m)).join(", ")}]);
243
+ `:"",V=Te(M,o,n),{fields:K,lifecycleMember:_,registry:Y}=Le(n,o),Z=y.length>0?`import { DEFER_VALIDATION as DEFER, installCompiledValidatorMap } from "${l.values}";
244
+ `:"",X=y.length>0?`
191
245
  /**
192
246
  * AOT-compiled argument validators (Worker-safe, no \`eval\`). Each is installed
193
247
  * onto its function's live \`.args\` object and consulted by the interpreted
194
248
  * parser as a zero-allocation fast path; anything it can't model is deferred.
195
249
  */
196
250
  ${y}
197
- `:"",K=Se(n,o),{callRegisteredHelper:Z,dataModelImport:X,implementation:ee,parameter:te,types:re}=K,ne=o?`
251
+ `:"",ee=Ee(n,o),{callRegisteredHelper:te,dataModelImport:re,implementation:ne,parameter:oe,types:se}=ee,ae=o?`
198
252
  export interface FunctionManifestEntry {
199
253
  argumentDescriptors: ReadonlyArray<{ element?: string; kind: string; name: string; optional: boolean; table?: string }>;
200
254
  channel?: { kind: "room"; name: string };
201
255
  exportName: string;
202
256
  expose?: { cache?: { credentialHeaders?: ReadonlyArray<string>; maxAge?: number; scope?: "private" | "public"; staleWhileRevalidate?: number; tag?: string; vary?: string }; rest?: boolean };
203
257
  kind: "action" | "mutation" | "query" | "stream";
204
- lifecycle?: "connect" | "disconnect" | "init" | "reactor" | "whisper";
258
+ lifecycle?: "connect" | "disconnect" | "init" | "reactor" | "whisper"${_};
205
259
  moduleId: string;
206
260
  visibility?: "internal" | "public";
207
261
  x402?: { readonly price: number | string };
@@ -220,8 +274,8 @@ const unloadedFunctionHandler = (): never => {
220
274
 
221
275
  /** Reuse an evaluated module synchronously, so dispatch does not yield after restoring request scope. */
222
276
  export const getLoadedFunction = (functionPath: string): RegisteredLunoraFunction | undefined => {
223
- const registered = ${k("LUNORA_FUNCTIONS")};
224
- const manifest = ${k("LUNORA_FUNCTION_MANIFEST")};
277
+ const registered = ${N("LUNORA_FUNCTIONS")};
278
+ const manifest = ${N("LUNORA_FUNCTION_MANIFEST")};
225
279
 
226
280
  if (!registered || !manifest) {
227
281
  return registered;
@@ -252,7 +306,7 @@ export const getLoadedFunction = (functionPath: string): RegisteredLunoraFunctio
252
306
  /** Load one function's owning module once per isolate, then merge its live builder result into the registry entry. */
253
307
  export const loadFunction = async (functionPath: string): Promise<RegisteredLunoraFunction | undefined> => {
254
308
  const registered = getLoadedFunction(functionPath);
255
- const manifest = ${k("LUNORA_FUNCTION_MANIFEST")};
309
+ const manifest = ${N("LUNORA_FUNCTION_MANIFEST")};
256
310
 
257
311
  if (registered || !manifest) {
258
312
  return registered;
@@ -278,9 +332,9 @@ export const loadFunction = async (functionPath: string): Promise<RegisteredLuno
278
332
 
279
333
  return getLoadedFunction(functionPath);
280
334
  };
281
- `:"";return le(`${C}${g}${h.importLine}${w.importLine}${W}${z}${L.typeImport}import { LunoraError } from "${c.server}";
335
+ `:"";return he(`${D}${f}${h.importLine}${w.importLine}${Z}${z}${A.typeImport}import { LunoraError } from "${l.server}";
282
336
  import type { ActionCtx, MutationCtx, QueryCtx } from "./server.js";
283
- ${X}
337
+ ${re}
284
338
  /**
285
339
  * Single registered function, narrowed to the shape \`handleRpc\` needs.
286
340
  * The real argument validators / return types are checked elsewhere — at
@@ -309,8 +363,8 @@ export interface RegisteredLunoraFunction {
309
363
  * \`init\` and \`reactor\` have no caller identity, so RLS has no user to scope
310
364
  * to. \`whisper\` does have one — it runs under the asking socket's identity.
311
365
  */
312
- lifecycle?: "connect" | "disconnect" | "init" | "reactor" | "whisper";
313
- ${L.channelField} /**
366
+ lifecycle?: "connect" | "disconnect" | "init" | "reactor" | "whisper"${_};${K}
367
+ ${A.channelField} /**
314
368
  * Hoisted by the builder when the \`.use()\` chain carries a step with a
315
369
  * per-dispatch effect — \`rateLimit(...)\` consuming budget, a single-use
316
370
  * captcha token being burned. Read by \`isCacheableQuery\`: the chain runs
@@ -326,13 +380,13 @@ ${L.channelField} /**
326
380
  */
327
381
  x402?: { readonly price: number | string };
328
382
  }
329
- ${h.prelude}${w.prelude}${ne}
383
+ ${h.prelude}${w.prelude}${ae}
330
384
  /**
331
385
  * Static dispatch table. The key matches the \`__lunoraRef\` the client
332
386
  * emits (\`api[namespace][fn].__lunoraRef === "namespace:fn"\`).
333
387
  */
334
- export const LUNORA_FUNCTIONS: Record<string, RegisteredLunoraFunction> = {${m}};
335
- ${Y}${Q}${G}${V}${L.messagesBlock}
388
+ export const LUNORA_FUNCTIONS: Record<string, RegisteredLunoraFunction> = {${p}};
389
+ ${X}${Q}${G}${V}${A.messagesBlock}${Y}
336
390
  /**
337
391
  * Lifecycle manifest: the function paths the generated ShardDO dispatches when a
338
392
  * client's WebSocket connects (\`connect\`) or disconnects (\`disconnect\`), once
@@ -350,11 +404,11 @@ export const LUNORA_LIFECYCLE_HOOKS: {
350
404
  reactor: readonly string[];
351
405
  whisper: readonly string[];
352
406
  } = {
353
- connect: [${R.connect.map(p=>JSON.stringify(p)).join(", ")}],
354
- disconnect: [${R.disconnect.map(p=>JSON.stringify(p)).join(", ")}],
355
- init: [${R.init.map(p=>JSON.stringify(p)).join(", ")}],
356
- reactor: [${R.reactor.map(p=>JSON.stringify(p)).join(", ")}],
357
- whisper: [${R.whisper.map(p=>JSON.stringify(p)).join(", ")}],
407
+ connect: [${R.connect.map(m=>JSON.stringify(m)).join(", ")}],
408
+ disconnect: [${R.disconnect.map(m=>JSON.stringify(m)).join(", ")}],
409
+ init: [${R.init.map(m=>JSON.stringify(m)).join(", ")}],
410
+ reactor: [${R.reactor.map(m=>JSON.stringify(m)).join(", ")}],
411
+ whisper: [${R.whisper.map(m=>JSON.stringify(m)).join(", ")}],
358
412
  };
359
413
 
360
414
  /**
@@ -364,7 +418,7 @@ export const LUNORA_LIFECYCLE_HOOKS: {
364
418
  * functions are treated as not-found so their existence never leaks to clients.
365
419
  */
366
420
  export const dispatchLunoraFunction = async (functionPath: string, context: unknown, args: Record<string, unknown>): Promise<unknown> => {
367
- ${A} const registered = ${S};
421
+ ${L} const registered = ${P};
368
422
 
369
423
  if (!registered || registered.visibility === "internal") {
370
424
  throw new LunoraError("FUNCTION_NOT_FOUND", \`function not registered: \${functionPath}\`);
@@ -385,10 +439,10 @@ export type CallerCtx = ActionCtx | MutationCtx | QueryCtx;
385
439
  * with the supplied \`context\`, exactly like \`ctx.runQuery\`/\`runMutation\`/
386
440
  * \`runAction\` but without re-stating the function path.
387
441
  */
388
- export interface Caller {${re}}
442
+ export interface Caller {${se}}
389
443
 
390
- ${Z}/** Build a {@link Caller} bound to \`context\` (typically a handler's \`ctx\`). */
391
- export const createCaller = (${te}: CallerCtx): Caller => ({${ee}});
444
+ ${te}/** Build a {@link Caller} bound to \`context\` (typically a handler's \`ctx\`). */
445
+ export const createCaller = (${oe}: CallerCtx): Caller => ({${ne}});
392
446
 
393
447
  /**
394
448
  * Single registered data migration, narrowed to the shape the per-shard runner
@@ -408,12 +462,12 @@ export interface RegisteredDataMigration {
408
462
  * shard DO's admin RPC and the CLI resolve migrations to run through this map.
409
463
  */
410
464
  export const LUNORA_MIGRATIONS: Record<string, RegisteredDataMigration> = {${v}};
411
- `,d)},Me="fn",_e=r=>{if(r.lazyFunctions!==!0)return{};const{functions:t}=r,n=r.migrations??[],o=r.mutators??[],a=r.shapes??[],i=H(t,n,o,a),s=q(n,o,a),d=[...new Set(t.filter(l=>!s.has(l.filePath)).map(l=>l.filePath))],u=j(r.useUmbrella??!1),c={};for(const l of d){if(!F.test(l))throw new P("INTERNAL",`@lunora/codegen: refusing to emit import for unsafe file path: ${JSON.stringify(l)}`);const g=i.get(l)??"",y=`../../${l}.js`,$=t.filter(h=>h.filePath===l&&!h.lifecycle&&Object.keys(h.args).length>0).flatMap(h=>{const w=B(h.args);return w===void 0?[]:[`installCompiledValidatorMap(${g}.${h.exportName}.args, ${w});`]}),v=$.length>0?`import { DEFER_VALIDATION as DEFER, installCompiledValidatorMap } from "${u.values}";
412
- `:"",O=$.length>0?`import * as ${g} from "${y}";
413
- `:"",b=$.length>0?`
465
+ `,c)},je="fn",Ue=r=>{if(r.lazyFunctions!==!0)return{};const{functions:t}=r,n=r.migrations??[],o=r.mutators??[],a=r.shapes??[],i=H(t,n,o,a),s=W(n,o,a),c=[...new Set(t.filter(u=>!s.has(u.filePath)).map(u=>u.filePath))],d=j(r.useUmbrella??!1),l={};for(const u of c){if(!T.test(u))throw new x("INTERNAL",`@lunora/codegen: refusing to emit import for unsafe file path: ${JSON.stringify(u)}`);const f=i.get(u)??"",y=`../../${u}.js`,$=t.filter(h=>h.filePath===u&&!h.lifecycle&&Object.keys(h.args).length>0).flatMap(h=>{const w=q(h.args);return w===void 0?[]:[`installCompiledValidatorMap(${f}.${h.exportName}.args, ${w});`]}),v=$.length>0?`import { DEFER_VALIDATION as DEFER, installCompiledValidatorMap } from "${d.values}";
466
+ `:"",O=$.length>0?`import * as ${f} from "${y}";
467
+ `:"",k=$.length>0?`
414
468
  /** Install the precompiled argument parsers before the module is dispatched. */
415
469
  ${$.join(`
416
470
  `)}
417
- `:"",N=t.some(h=>h.filePath===l&&h.exportName==="default")||n.some(h=>h.filePath===l&&h.exportName==="default")?`export { default } from "${y}";
418
- `:"";c[`${g}.ts`]=`${C}${v}${O}${b}export * from "${y}";
419
- ${N}`}return c};export{Me as LAZY_FUNCTION_DIRECTORY,Ee as emitFunctions,_e as emitLazyFunctionModules};
471
+ `:"",b=t.some(h=>h.filePath===u&&h.exportName==="default")||n.some(h=>h.filePath===u&&h.exportName==="default")?`export { default } from "${y}";
472
+ `:"";l[`${f}.ts`]=`${D}${v}${O}${k}export * from "${y}";
473
+ ${b}`}return l};export{je as LAZY_FUNCTION_DIRECTORY,De as emitFunctions,Ue as emitLazyFunctionModules};
@@ -1 +1 @@
1
- import"./SCHEMA_SNAPSHOT_VERSION-C0oHwiJZ.mjs";import"./isD1GlobalTable-udvHAAzD.mjs";import"./json-data-Chfs2Cz5.mjs";import{e as d}from"./shard-ceGu_Fps.mjs";import"./shard-runtime-BpoCV-aM.mjs";import"./shared-DnCokNcE.mjs";import"./platform-8oj7iXQy.mjs";import"./schema-BgM8A3XV.mjs";export{d as default};
1
+ import"./SCHEMA_SNAPSHOT_VERSION-C0oHwiJZ.mjs";import"./isD1GlobalTable-udvHAAzD.mjs";import"./json-data-Chfs2Cz5.mjs";import{e as d}from"./shard-BtImwCVL.mjs";import"./shard-runtime-BpoCV-aM.mjs";import"./shared-DnCokNcE.mjs";import"./platform-8oj7iXQy.mjs";import"./schema-BgM8A3XV.mjs";export{d as default};
@@ -1 +1 @@
1
- import{Node as s}from"ts-morph";import{b as t,d as c}from"./attribution-hVBriwzy.mjs";import{c as n}from"./classify-procedure-call-DVxdUhZt.mjs";const m=a=>{const i=[];for(const e of t(a)){const r=e.getInitializer(),o=r&&s.isCallExpression(r)?n(r):void 0;o?.receiver&&i.push({name:c(e)??e.getName(),receiver:o.receiver})}return i};export{m as e};
1
+ import{Node as s}from"ts-morph";import{b as t,d as c}from"./attribution-hVBriwzy.mjs";import{c as n}from"./classify-procedure-call-DUBO9bqm.mjs";const m=a=>{const i=[];for(const e of t(a)){const r=e.getInitializer(),o=r&&s.isCallExpression(r)?n(r):void 0;o?.receiver&&i.push({name:c(e)??e.getName(),receiver:o.receiver})}return i};export{m as e};
@@ -1 +1 @@
1
- import{Node as r}from"ts-morph";import{listLunoraSourceFiles as u,lunoraRelativePath as f}from"./isTestPath-B81lOULB.mjs";import{b as m,d as p}from"./attribution-hVBriwzy.mjs";import{t as d}from"./database-calls-BKozZUEW.mjs";import{w as g,c as h}from"./classify-procedure-call-DVxdUhZt.mjs";import{a as k}from"./project-config-file-BV7RR-l6.mjs";const l=e=>{if(!(!r.isPropertyAssignment(e)&&!r.isShorthandPropertyAssignment(e)&&!r.isMethodDeclaration(e)&&!r.isGetAccessorDeclaration(e)))return k(e)},v=e=>g(e,"use","mask"),D=e=>{if(r.isPropertyAssignment(e)){const s=e.getInitializer();if(s&&r.isStringLiteral(s)){const t=s.getLiteralText();if(t==="redact"||t==="hash")return t}}return"custom"},P=e=>{const s=e.getArguments()[0];if(!s||!r.isObjectLiteralExpression(s))return[];const t=[];for(const i of s.getProperties()){const o=l(i);if(o===void 0||!r.isPropertyAssignment(i))continue;const n=i.getInitializer();if(!(!n||!r.isObjectLiteralExpression(n)))for(const a of n.getProperties()){const c=l(a);c!==void 0&&t.push({column:c,table:o})}}return t},y=e=>{const s=v(e);return{maskColumns:s.flatMap(t=>P(t)),usesMask:s.length>0}},C=new Set(["explain","findFirst","findFirstOrThrow","findMany","get","query"]),M=new Set(["delete","insert","patch","replace"]),x=(e,s)=>{if(!r.isVariableDeclaration(e))return;const t=e.getInitializer();if(!t||!r.isCallExpression(t))return;const i=h(t);if(!i)return;const o=i.receiver?y(i.receiver):{maskColumns:[],usesMask:!1},{tablesRead:n,tablesWritten:a}=d(e,C,M);return{exportName:p(e)??e.getName(),file:s,maskColumns:o.maskColumns,tablesRead:n,tablesWritten:a,usesMask:o.usesMask,visibility:i.visibility}},E=(e,s)=>{const t=[];for(const i of u(s)){const o=e.getSourceFile(i)??e.addSourceFileAtPath(i),n=f(s,i);for(const a of m(o)){const c=x(a,n);c&&t.push(c)}}return t};export{l as a,E as d,v as m,D as s};
1
+ import{Node as r}from"ts-morph";import{listLunoraSourceFiles as u,lunoraRelativePath as f}from"./isTestPath-B81lOULB.mjs";import{b as m,d as p}from"./attribution-hVBriwzy.mjs";import{t as d}from"./database-calls-DJgmh0Kv.mjs";import{w as g,c as h}from"./classify-procedure-call-DUBO9bqm.mjs";import{a as k}from"./project-config-file-BV7RR-l6.mjs";const l=e=>{if(!(!r.isPropertyAssignment(e)&&!r.isShorthandPropertyAssignment(e)&&!r.isMethodDeclaration(e)&&!r.isGetAccessorDeclaration(e)))return k(e)},v=e=>g(e,"use","mask"),D=e=>{if(r.isPropertyAssignment(e)){const s=e.getInitializer();if(s&&r.isStringLiteral(s)){const t=s.getLiteralText();if(t==="redact"||t==="hash")return t}}return"custom"},P=e=>{const s=e.getArguments()[0];if(!s||!r.isObjectLiteralExpression(s))return[];const t=[];for(const i of s.getProperties()){const o=l(i);if(o===void 0||!r.isPropertyAssignment(i))continue;const n=i.getInitializer();if(!(!n||!r.isObjectLiteralExpression(n)))for(const a of n.getProperties()){const c=l(a);c!==void 0&&t.push({column:c,table:o})}}return t},y=e=>{const s=v(e);return{maskColumns:s.flatMap(t=>P(t)),usesMask:s.length>0}},C=new Set(["explain","findFirst","findFirstOrThrow","findMany","get","query"]),M=new Set(["delete","insert","patch","replace"]),x=(e,s)=>{if(!r.isVariableDeclaration(e))return;const t=e.getInitializer();if(!t||!r.isCallExpression(t))return;const i=h(t);if(!i)return;const o=i.receiver?y(i.receiver):{maskColumns:[],usesMask:!1},{tablesRead:n,tablesWritten:a}=d(e,C,M);return{exportName:p(e)??e.getName(),file:s,maskColumns:o.maskColumns,tablesRead:n,tablesWritten:a,usesMask:o.usesMask,visibility:i.visibility}},E=(e,s)=>{const t=[];for(const i of u(s)){const o=e.getSourceFile(i)??e.addSourceFileAtPath(i),n=f(s,i);for(const a of m(o)){const c=x(a,n);c&&t.push(c)}}return t};export{l as a,E as d,v as m,D as s};