@lunora/codegen 1.0.0-alpha.117 → 1.0.0-alpha.119

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 (28) hide show
  1. package/dist/index.d.mts +15 -22
  2. package/dist/index.d.ts +15 -22
  3. package/dist/index.mjs +1 -1
  4. package/dist/packem_shared/{GENERATED_HEADER-TYN36IWp.mjs → GENERATED_HEADER-Cx5Qh2XJ.mjs} +1 -1
  5. package/dist/packem_shared/{MUTATORS_FILENAME-sGAt-yC1.mjs → MUTATORS_FILENAME-B2-W8Bm3.mjs} +1 -1
  6. package/dist/packem_shared/{NOTIFY_FILENAME-CTZI61e3.mjs → NOTIFY_FILENAME-IJXY4yHt.mjs} +1 -1
  7. package/dist/packem_shared/{OPENRPC_VERSION-BGbPExk0.mjs → OPENRPC_VERSION-14yZ-O3V.mjs} +1 -1
  8. package/dist/packem_shared/{SCHEMA_SNAPSHOT_FILENAME-ks41Eeih.mjs → SCHEMA_SNAPSHOT_FILENAME-CbOqo05-.mjs} +1 -1
  9. package/dist/packem_shared/SCHEMA_SNAPSHOT_VERSION-B0cTpK1D.mjs +2 -0
  10. package/dist/packem_shared/{SDK_LANGUAGES-BHYgTciL.mjs → SDK_LANGUAGES-CFyux-74.mjs} +1 -1
  11. package/dist/packem_shared/{SchemaSnapshotParseError-Dc1aZAph.mjs → SchemaSnapshotParseError-BoHDfCO3.mjs} +1 -1
  12. package/dist/packem_shared/{buildOpenApiDocument-Dk1RRaq3.mjs → buildOpenApiDocument-DI8bgteQ.mjs} +1 -1
  13. package/dist/packem_shared/discoverFunctions-006teuNG.mjs +1 -0
  14. package/dist/packem_shared/{discoverHttpRoutes-DOirwCWw.mjs → discoverHttpRoutes-BxF4FRZL.mjs} +1 -1
  15. package/dist/packem_shared/{discoverMaskProcedures-D-09Qb8S.mjs → discoverMaskProcedures-BCl3fNrQ.mjs} +1 -1
  16. package/dist/packem_shared/{discoverNondeterministicCalls-DhNToI6C.mjs → discoverNondeterministicCalls-BA91Z-vF.mjs} +1 -1
  17. package/dist/packem_shared/{discoverR2sqlCalls-B6e4j4rD.mjs → discoverR2sqlCalls-M2ob41UX.mjs} +1 -1
  18. package/dist/packem_shared/{discoverRlsMetadata-Pw0_c1aS.mjs → discoverRlsMetadata-Dwt2p8IK.mjs} +1 -1
  19. package/dist/packem_shared/{discoverSchema-D_wHstA-.mjs → discoverSchema-gJ93Xjpx.mjs} +1 -1
  20. package/dist/packem_shared/{discoverStorageRulesMetadata-DthHu3mC.mjs → discoverStorageRulesMetadata-69Y8wZb2.mjs} +1 -1
  21. package/dist/packem_shared/{emit-B6siM7LU.mjs → emit-C0azW4mT.mjs} +307 -216
  22. package/dist/packem_shared/{emitApp-C6P6ckvr.mjs → emitApp-Dyr-onNf.mjs} +1 -1
  23. package/dist/packem_shared/{formatAdvisories-BjTV22uR.mjs → formatAdvisories-CkEu1eye.mjs} +1 -1
  24. package/dist/packem_shared/isTypedSchema-B_qlBbE-.mjs +2 -0
  25. package/package.json +6 -6
  26. package/dist/packem_shared/SCHEMA_SNAPSHOT_VERSION-DIqnj_32.mjs +0 -2
  27. package/dist/packem_shared/discoverFunctions-4eSpCR6m.mjs +0 -1
  28. package/dist/packem_shared/isTypedSchema-BBIBMZTg.mjs +0 -2
@@ -1,4 +1,4 @@
1
- import{agentComponent as ot}from"@lunora/agent/component";import{LunoraError as te}from"@lunora/errors";import{serializeSchemaSnapshot as mn,hashSchemaSnapshot as hn}from"./SCHEMA_SNAPSHOT_VERSION-DIqnj_32.mjs";import{s as S}from"./paths-C-9fwEgQ.mjs";const at=[{contextProperty:"access",key:"access",moduleSpecifier:"@lunora/cloudflare-access"},{appMethod:{configKey:"ai",doc:"Override the Workers AI binding backing `ctx.ai` (defaults to `env.AI`).",method:"ai"},contextProperty:"ai",key:"ai",moduleSpecifier:"@lunora/ai"},{appMethod:{configKey:"analytics",doc:"Override the Analytics Engine dataset backing `ctx.analytics` (defaults to `env.ANALYTICS`).",method:"analytics"},contextProperty:"analytics",key:"analytics",moduleSpecifier:"@lunora/bindings/analytics",serverCtxField:{field:`
1
+ import{agentComponent as at}from"@lunora/agent/component";import{LunoraError as te}from"@lunora/errors";import{serializeSchemaSnapshot as fn,hashSchemaSnapshot as yn}from"./SCHEMA_SNAPSHOT_VERSION-B0cTpK1D.mjs";import{s as N}from"./paths-C-9fwEgQ.mjs";const st=[{contextProperty:"access",key:"access",moduleSpecifier:"@lunora/cloudflare-access"},{appMethod:{configKey:"ai",doc:"Override the Workers AI binding backing `ctx.ai` (defaults to `env.AI`).",method:"ai"},contextProperty:"ai",key:"ai",moduleSpecifier:"@lunora/ai"},{appMethod:{configKey:"analytics",doc:"Override the Analytics Engine dataset backing `ctx.analytics` (defaults to `env.ANALYTICS`).",method:"analytics"},contextProperty:"analytics",key:"analytics",moduleSpecifier:"@lunora/bindings/analytics",serverCtxField:{field:`
2
2
  /** Analytics Engine telemetry sink. Fire-and-forget and sampled; do not read it back in-handler. */
3
3
  readonly analytics: import("@lunora/bindings/analytics").AnalyticsClient;`,tier:"every"}},{appMethod:{configKey:"browser",doc:"Override the Browser Rendering binding backing `ctx.browser` (defaults to `env.BROWSER`).",method:"browser"},contextProperty:"browser",key:"browser",moduleSpecifier:"@lunora/browser",serverCtxField:{field:`
4
4
  /** Browser Rendering (screenshots/PDF/scrape). Non-deterministic — available only in actions. */
@@ -15,57 +15,60 @@ import{agentComponent as ot}from"@lunora/agent/component";import{LunoraError as
15
15
  /**
16
16
  * R2 SQL over Apache Iceberg tables (window functions, DISTINCT, set operations). Non-deterministic — available only in actions. Reads here are NOT tracked by Lunora live queries.
17
17
  */
18
- readonly r2sql: import("@lunora/bindings/r2sql").R2SqlClient;`,tier:"action"}},{contextProperty:"scheduler",key:"scheduler",moduleSpecifier:"@lunora/scheduler"},{contextProperty:"storage",key:"storage",moduleSpecifier:"@lunora/storage"},{appMethod:{configKey:"vectors",doc:"Wire the Vectorize index map backing `ctx.vectors`.",method:"vectors"},contextProperty:"vectors",key:"vectors",moduleSpecifier:"@lunora/bindings/vectors"},{contextProperty:"workflows",key:"workflows",moduleSpecifier:"@lunora/workflow"}],gn=at,fn=new Map(gn.flatMap(e=>e.serverCtxField?[[e.key,e.serverCtxField]]:[])),Wr=at.flatMap(e=>"appMethod"in e?[{appMethod:e.appMethod,key:e.key}]:[]),st=/^(?:"(?:[^"\\]|\\(?:["\\/bfnrt]|u[0-9A-Fa-f]{4}))*"|'[^'\\]*'|-?\d+(?:\.\d+)?|true|false|null)$/u,bn=new Set(["any","bigint","boolean","date","id","null","number","storage","string","timestamp"]),it=e=>e.column!==void 0,yn=(e,t)=>{switch(e){case"bigint":return`if (typeof ${t} !== "bigint") return DEFER;
18
+ readonly r2sql: import("@lunora/bindings/r2sql").R2SqlClient;`,tier:"action"}},{contextProperty:"scheduler",key:"scheduler",moduleSpecifier:"@lunora/scheduler"},{contextProperty:"storage",key:"storage",moduleSpecifier:"@lunora/storage"},{appMethod:{configKey:"vectors",doc:"Wire the Vectorize index map backing `ctx.vectors`.",method:"vectors"},contextProperty:"vectors",key:"vectors",moduleSpecifier:"@lunora/bindings/vectors"},{contextProperty:"workflows",key:"workflows",moduleSpecifier:"@lunora/workflow"}],bn=st,kn=new Map(bn.flatMap(e=>e.serverCtxField?[[e.key,e.serverCtxField]]:[])),Vr=st.flatMap(e=>"appMethod"in e?[{appMethod:e.appMethod,key:e.key}]:[]),it=/^(?:"(?:[^"\\]|\\(?:["\\/bfnrt]|u[0-9A-Fa-f]{4}))*"|'[^'\\]*'|-?\d+(?:\.\d+)?|true|false|null)$/u,wn=new Set(["any","bigint","boolean","date","id","null","number","storage","string","timestamp"]),lt=e=>e.column!==void 0,xn=(e,t)=>{switch(e){case"bigint":return`if (typeof ${t} !== "bigint") return DEFER;
19
19
  `;case"boolean":return`if (typeof ${t} !== "boolean") return DEFER;
20
20
  `;case"date":case"number":case"timestamp":return`if (typeof ${t} !== "number" || !Number.isFinite(${t})) return DEFER;
21
21
  `;case"null":return`if (${t} !== null) return DEFER;
22
22
  `;default:return`if (typeof ${t} !== "string") return DEFER;
23
- `}},kn=(e,t)=>{const n=e.literalValue?.trim();if(!(n===void 0||!st.test(n)))return{out:t,pre:`if (${t} !== ${n}) return DEFER;
24
- `}},We=(e,t,n)=>{if(!it(e)&&!(e.hasRefinement||e.sourceText!==void 0)){if(bn.has(e.kind))return e.kind==="any"?{out:t,pre:""}:{out:t,pre:yn(e.kind,t)};switch(e.kind){case"array":return xn(e,t,n);case"literal":return kn(e,t);case"object":return vn(e,t,n);default:return}}},xn=(e,t,n)=>{const{inner:r}=e;if(!r)return;const o=n.next(),s=`__arr${String(o)}`,i=`__i${String(o)}`,a=`__e${String(o)}`,c=We(r,a,n);if(!c)return;const d=`if (!Array.isArray(${t})) return DEFER;
23
+ `}},vn=(e,t)=>{const n=e.literalValue?.trim();if(!(n===void 0||!it.test(n)))return{out:t,pre:`if (${t} !== ${n}) return DEFER;
24
+ `}},We=(e,t,n)=>{if(!lt(e)&&!(e.hasRefinement||e.sourceText!==void 0)){if(wn.has(e.kind))return e.kind==="any"?{out:t,pre:""}:{out:t,pre:xn(e.kind,t)};switch(e.kind){case"array":return $n(e,t,n);case"literal":return vn(e,t);case"object":return Nn(e,t,n);default:return}}},$n=(e,t,n)=>{const{inner:r}=e;if(!r)return;const o=n.next(),s=`__arr${String(o)}`,i=`__i${String(o)}`,a=`__e${String(o)}`,c=We(r,a,n);if(!c)return;const d=`if (!Array.isArray(${t})) return DEFER;
25
25
  const ${s} = new Array(${t}.length);
26
26
  for (let ${i} = 0; ${i} < ${t}.length; ${i}++) {
27
27
  const ${a} = ${t}[${i}];
28
28
  ${c.pre}${s}[${i}] = ${c.out};
29
29
  }
30
- `;return{out:s,pre:d}},wn=(e,t,n,r)=>{const o=JSON.stringify(e);if(t.kind==="optional"){if(t.hasRefinement||t.sourceText!==void 0||it(t))return;const{inner:i}=t;if(!i)return;const a=We(i,n,r);if(!a)return;const c=r.next(),d=`__has${String(c)}`,p=`__val${String(c)}`,h=`let ${d} = false;
30
+ `;return{out:s,pre:d}},Rn=(e,t,n,r)=>{const o=JSON.stringify(e);if(t.kind==="optional"){if(t.hasRefinement||t.sourceText!==void 0||lt(t))return;const{inner:i}=t;if(!i)return;const a=We(i,n,r);if(!a)return;const c=r.next(),d=`__has${String(c)}`,p=`__val${String(c)}`,h=`let ${d} = false;
31
31
  let ${p};
32
32
  if (${n} !== undefined) {
33
33
  ${a.pre}${p} = ${a.out};
34
34
  ${d} = true;
35
35
  }
36
- `;return{entry:`...(${d} ? { ${o}: ${p} } : {})`,pre:h}}const s=We(t,n,r);if(s)return{entry:`${o}: ${s.out}`,pre:s.pre}},lt=(e,t,n)=>{let r="";const o=[];for(const s of Object.keys(e)){const i=e[s];if(!i)return;const a=wn(s,i,t(s),n);if(!a)return;r+=a.pre,o.push(a.entry)}return{entries:o.join(", "),pre:r}},vn=(e,t,n)=>{const r=e.shape??{},o=lt(r,c=>`${t}[${JSON.stringify(c)}]`,n);if(!o)return;const s=n.next(),i=`__obj${String(s)}`,a=`if (typeof ${t} !== "object" || ${t} === null || Array.isArray(${t})) return DEFER;
37
- ${o.pre}const ${i} = { ${o.entries} };
38
- `;return{out:i,pre:a}},$n=e=>{let t=0;const r=lt(e,o=>`source[${JSON.stringify(o)}]`,{next:()=>(t+=1,t)});if(r)return`(source) => {
36
+ `;return{entry:`...(${d} ? { ${o}: ${p} } : {})`,pre:h}}const s=We(t,n,r);if(s)return{entry:`${o}: ${s.out}`,pre:s.pre}},Sn=new Set(Object.getOwnPropertyNames(Object.prototype)),ct=(e,t,n)=>{let r="";const o=[];for(const s of Object.keys(e)){const i=e[s];if(!i)return;const a=JSON.stringify(s);let c=`${t}[${a}]`;if(Sn.has(s)){const p=`__f${String(n.next())}`;r+=`const ${p} = Object.hasOwn(${t}, ${a}) ? ${t}[${a}] : undefined;
37
+ `,c=p}const d=Rn(s,i,c,n);if(!d)return;r+=d.pre,o.push(d.entry)}return{entries:o.join(", "),pre:r}},dt=e=>{const t=`Object.getPrototypeOf(${e})`;return`if (${t} !== Object.prototype && ${t} !== null) return DEFER;
38
+ `},Nn=(e,t,n)=>{const r=e.shape??{},o=ct(r,t,n);if(!o)return;const s=n.next(),i=`__obj${String(s)}`,a=`if (typeof ${t} !== "object" || ${t} === null || Array.isArray(${t})) return DEFER;
39
+ ${dt(t)}${o.pre}const ${i} = { ${o.entries} };
40
+ `;return{out:i,pre:a}},Tn=e=>{let t=0;const r=ct(e,"source",{next:()=>(t+=1,t)});if(r)return`(source) => {
39
41
  if (typeof source !== "object" || source === null || Array.isArray(source)) return DEFER;
40
- ${r.pre}return { ${r.entries} };
41
- }`},R=`// GENERATED by @lunora/codegen — do not edit.
42
+ ${dt("source")}${r.pre}return { ${r.entries} };
43
+ }`},S=`// GENERATED by @lunora/codegen — do not edit.
42
44
  // Run \`lunora codegen\` to regenerate.
43
45
 
44
- `,ne=(e=!1)=>e?{client:"lunorash/client",do:"lunorash/do",flags:"lunorash/flags",server:"lunorash/server",serverDataModel:"lunorash/server/data-model",serverDrizzle:"lunorash/server/drizzle",serverTypes:"lunorash/server/types",values:"lunorash/values"}:{client:"@lunora/client",do:"@lunora/do",flags:"@lunora/flags",server:"@lunora/server",serverDataModel:"@lunora/server/data-model",serverDrizzle:"@lunora/server/drizzle",serverTypes:"@lunora/server/types",values:"@lunora/values"},ct=/^[A-Za-z_$][\w$]*$/u,Rn=/^[\w./-]+$/u,g=(e,t)=>{if(!ct.test(e))throw new te("INTERNAL",`@lunora/codegen: ${t} is not a valid JS identifier: ${JSON.stringify(e)}`)},qe=e=>e.charAt(0).toUpperCase()+e.slice(1),_=e=>ct.test(e)?e:JSON.stringify(e),Sn={any:"unknown",bigint:"bigint",boolean:"boolean",bytes:"ArrayBuffer",date:"number",geoPoint:"{ lat: number; lng: number }",null:"null",number:"number",storage:"string",string:"string",timestamp:"number"},Nn=e=>{if(e===void 0)return"unknown";if(!st.test(e))throw new te("INTERNAL",`@lunora/codegen: v.literal() argument is not a parseable string/number/boolean/null literal: ${JSON.stringify(e)}`);return e},N=e=>{const t=Sn[e.kind];if(t!==void 0)return t;switch(e.kind){case"array":return`Array<${e.inner?N(e.inner):"unknown"}>`;case"from":return e.tsType??"unknown";case"id":{const n=e.tableName??"_unknown_";return g(n,"v.id() table name"),`Id<"${n}">`}case"literal":return Nn(e.literalValue);case"object":return e.shape?`{ ${Object.entries(e.shape).map(([r,o])=>dt(r,o)).join("; ")} }`:"Record<string, unknown>";case"optional":return`${e.inner?N(e.inner):"unknown"} | undefined`;case"record":{const n=e.keyType?N(e.keyType):"string",r=e.valueType?N(e.valueType):"unknown";return`Record<${n}, ${r}>`}case"union":return e.members&&e.members.length>0?e.members.map(n=>N(n)).join(" | "):"never";default:return"unknown"}},dt=(e,t)=>{const n=_(e);if(t.kind==="optional"){const r=t.inner?N(t.inner):"unknown";return`${n}?: ${r}`}return`${n}: ${N(t)}`},ke=e=>{const t=Object.entries(e);return t.length===0?"{}":`{ ${t.map(([n,r])=>dt(n,r)).join("; ")} }`},ut=e=>e.kind==="optional"||!!e.column?.hasDefault,re=e=>e.kind==="optional"&&e.inner?e.inner:e,Tn=e=>{g(e.name,"table name");const t=Object.entries(e.shape).map(([r,o])=>{const s=re(o),i=N(s),a=_(r);return ut(o)?` ${a}?: ${i};`:` ${a}: ${i};`}).join(`
46
+ `,ne=(e=!1)=>e?{client:"lunorash/client",do:"lunorash/do",flags:"lunorash/flags",server:"lunorash/server",serverDataModel:"lunorash/server/data-model",serverDrizzle:"lunorash/server/drizzle",serverTypes:"lunorash/server/types",values:"lunorash/values"}:{client:"@lunora/client",do:"@lunora/do",flags:"@lunora/flags",server:"@lunora/server",serverDataModel:"@lunora/server/data-model",serverDrizzle:"@lunora/server/drizzle",serverTypes:"@lunora/server/types",values:"@lunora/values"},ut=/^[A-Za-z_$][\w$]*$/u,An=/^[\w./-]+$/u,g=(e,t)=>{if(!ut.test(e))throw new te("INTERNAL",`@lunora/codegen: ${t} is not a valid JS identifier: ${JSON.stringify(e)}`)},qe=e=>e.charAt(0).toUpperCase()+e.slice(1),E=e=>ut.test(e)?e:JSON.stringify(e),On={any:"unknown",bigint:"bigint",boolean:"boolean",bytes:"ArrayBuffer",date:"number",geoPoint:"{ lat: number; lng: number }",null:"null",number:"number",storage:"string",string:"string",timestamp:"number"},In=e=>{if(e===void 0)return"unknown";if(!it.test(e))throw new te("INTERNAL",`@lunora/codegen: v.literal() argument is not a parseable string/number/boolean/null literal: ${JSON.stringify(e)}`);return e},A=e=>{const t=On[e.kind];if(t!==void 0)return t;switch(e.kind){case"array":return`Array<${e.inner?A(e.inner):"unknown"}>`;case"from":return e.tsType??"unknown";case"id":{const n=e.tableName??"_unknown_";return g(n,"v.id() table name"),`Id<"${n}">`}case"literal":return In(e.literalValue);case"object":return e.shape?`{ ${Object.entries(e.shape).map(([r,o])=>pt(r,o)).join("; ")} }`:"Record<string, unknown>";case"optional":return`${e.inner?A(e.inner):"unknown"} | undefined`;case"record":{const n=e.keyType?A(e.keyType):"string",r=e.valueType?A(e.valueType):"unknown";return`Record<${n}, ${r}>`}case"union":return e.members&&e.members.length>0?e.members.map(n=>A(n)).join(" | "):"never";default:return"unknown"}},pt=(e,t)=>{const n=E(e);if(t.kind==="optional"){const r=t.inner?A(t.inner):"unknown";return`${n}?: ${r}`}return`${n}: ${A(t)}`},ke=e=>{const t=Object.entries(e);return t.length===0?"{}":`{ ${t.map(([n,r])=>pt(n,r)).join("; ")} }`},mt=e=>e.kind==="optional"||!!e.column?.hasDefault,re=e=>e.kind==="optional"&&e.inner?e.inner:e,Cn=e=>{g(e.name,"table name");const t=Object.entries(e.shape).map(([r,o])=>{const s=re(o),i=A(s),a=E(r);return mt(o)?` ${a}?: ${i};`:` ${a}: ${i};`}).join(`
45
47
  `),n=t?`
46
48
  ${t}
47
49
  `:"";return`export interface Insert_${e.name} {
48
50
  _id?: Id<"${e.name}">;
49
- _creationTime?: number;${n}}`},Ue="schema",Ur=e=>{for(const u of e.tables)g(u.name,"table name");const t=e.tables.map(u=>`"${u.name}"`).join(" | ")||"never",n=e.tables.filter(u=>u.extensionKey===void 0).map(u=>`"${u.name}"`).join(" | ")||"never",r=e.tables.map(u=>{const l=Object.entries(u.shape).map(([x,w])=>{const v=_(x);if(w.kind==="optional"){const I=w.inner?N(w.inner):"unknown";return` ${v}?: ${I};`}return` ${v}: ${N(w)};`}).join(`
51
+ _creationTime?: number;${n}}`},Ue="schema",Hr=e=>{for(const u of e.tables)g(u.name,"table name");const t=e.tables.map(u=>`"${u.name}"`).join(" | ")||"never",n=e.tables.filter(u=>u.extensionKey===void 0).map(u=>`"${u.name}"`).join(" | ")||"never",r=e.tables.map(u=>{const l=Object.entries(u.shape).map(([$,x])=>{const I=E($);if(x.kind==="optional"){const T=x.inner?A(x.inner):"unknown";return` ${I}?: ${T};`}return` ${I}: ${A(x)};`}).join(`
50
52
  `),f=l?`
51
53
  ${l}
52
- `:"";return`export interface Doc_${u.name} {
54
+ `:"",w=u.commitOrdered===!0?`
55
+ _commitSeq: number;`:"";return`export interface Doc_${u.name} {
53
56
  _id: Id<"${u.name}">;
54
- _creationTime: number;${f}}`}).join(`
57
+ _creationTime: number;${w}${f}}`}).join(`
55
58
 
56
59
  `),o=e.tables.map(u=>` ${u.name}: Doc_${u.name};`).join(`
57
60
  `),s=e.tables.map(u=>{const l=u.indexes.map(f=>JSON.stringify(f.name)).join(" | ");return` ${u.name}: ${l||"never"};`}).join(`
58
61
  `),i=e.tables.map(u=>{const l=u.searchIndexes.map(f=>JSON.stringify(f.name)).join(" | ");return` ${u.name}: ${l||"never"};`}).join(`
59
62
  `),a=e.tables.map(u=>{const l=u.rankIndexes.map(f=>JSON.stringify(f.name)).join(" | ");return` ${u.name}: ${l||"never"};`}).join(`
60
63
  `),c=e.tables.map(u=>{const l=u.shardMode==="global"?"":(u.geoIndexes??[]).map(f=>JSON.stringify(f.name)).join(" | ");return` ${u.name}: ${l||"never"};`}).join(`
61
- `),d=e.vectorIndexes.map(u=>JSON.stringify(u.name)).join(" | ")||"never",p=e.tables.map(u=>Tn(u)).join(`
64
+ `),d=e.vectorIndexes.map(u=>JSON.stringify(u.name)).join(" | ")||"never",p=e.tables.map(u=>Cn(u)).join(`
62
65
 
63
66
  `),h=e.tables.map(u=>` ${u.name}: Insert_${u.name};`).join(`
64
- `),b=e.tables.map(u=>{const l=u.relations.map(f=>(g(f.table,"relation target table"),` ${_(f.name)}: ${f.kind==="one"?"OneRelation":"ManyRelation"}<"${f.table}">;`)).join(`
67
+ `),y=e.tables.map(u=>{const l=u.relations.map(f=>(g(f.table,"relation target table"),` ${E(f.name)}: ${f.kind==="one"?"OneRelation":"ManyRelation"}<"${f.table}">;`)).join(`
65
68
  `);return l?` ${u.name}: {
66
69
  ${l}
67
70
  };`:` ${u.name}: {};`}).join(`
68
- `);return E(`${R}export type TableName = ${t};
71
+ `);return D(`${S}export type TableName = ${t};
69
72
 
70
73
  /**
71
74
  * The tables **this app declared** — every {@link TableName} except those an add-on
@@ -154,14 +157,14 @@ export interface ManyRelation<Target extends keyof DataModel> {
154
157
 
155
158
  /** Per-table relation map keyed by accessor name. \`{}\` for tables with none. */
156
159
  export interface Relations {
157
- ${b}
160
+ ${y}
158
161
  }
159
162
 
160
- `,Ue)},An=/import\("(?<spec>(?:\.\.?\/)*_generated\/[^"]+)"\)/gu,pt=/^(?:\.\.?\/)*_generated\//u,mt=/\.[A-Za-z]\w*$/u,On=e=>e.replaceAll(An,(t,n)=>{const r=n.replace(pt,"./");return`import("${mt.test(r)?r:`${r}.js`}")`}),In=/import\("(?<spec>\.\.?\/[^"]+)"\)/gu,Cn=/^(?:\.\.?\/)+/u,Ln=e=>{const t=[];for(const n of e.split("/"))if(!(n===""||n===".")){if(n===".."&&t.length>0&&t.at(-1)!==".."){t.pop();continue}t.push(n)}return t.join("/")},_n=(e,t)=>e.replaceAll(In,(n,r)=>{if(pt.test(r.replace(Cn,"")))return n;const o=t.includes("/")?t.slice(0,t.lastIndexOf("/")):"",i=`../${Ln(`${o}/${r}`)}`;return`import("${mt.test(i)?i:`${i}.js`}")`}),E=(e,t)=>On(_n(e,t)),En=["client","do","errors","flags","observability","platform","ratelimit","runtime","server","values"],Dn=new RegExp(String.raw`import\("@lunora/(?<pkg>${En.join("|")})(?<subpath>/[^"]*)?"\)`,"gu"),Fn={flags:new Set(["/web"]),platform:new Set},ht=(e,t)=>t?e.replaceAll(Dn,(n,r,o)=>{const s=Fn[r];return o&&s&&!s.has(o)?n:`import("lunorash/${r}${o??""}")`}):e,Ke=e=>["Doc","Id"].filter(t=>new RegExp(String.raw`\b${t}<`,"u").test(e)),Pn=e=>e.output===void 0||e.output.kind==="any"?e.returnType:N(e.output),Qe=e=>{const t=new Map;for(const n of e){const r=t.get(n.filePath)??[];r.push(n),t.set(n.filePath,r)}return[...t.entries()].toSorted(([n],[r])=>n.localeCompare(r))},nt=e=>{const t=([n,r])=>{const o=r.toSorted((s,i)=>s.exportName.localeCompare(i.exportName)).map(s=>{const i=E(ke(s.args),s.filePath),a=E(Pn(s),s.filePath);return` ${s.exportName}: FunctionReference<"${s.kind}", ${i}, ${a}>;`}).join(`
161
- `);return` ${_(S(n))}: {
163
+ `,Ue)},Ln=/import\("(?<spec>(?:\.\.?\/)*_generated\/[^"]+)"\)/gu,ht=/^(?:\.\.?\/)*_generated\//u,gt=/\.[A-Za-z]\w*$/u,_n=e=>e.replaceAll(Ln,(t,n)=>{const r=n.replace(ht,"./");return`import("${gt.test(r)?r:`${r}.js`}")`}),En=/import\("(?<spec>\.\.?\/[^"]+)"\)/gu,Dn=/^(?:\.\.?\/)+/u,Fn=e=>{const t=[];for(const n of e.split("/"))if(!(n===""||n===".")){if(n===".."&&t.length>0&&t.at(-1)!==".."){t.pop();continue}t.push(n)}return t.join("/")},Pn=(e,t)=>e.replaceAll(En,(n,r)=>{if(ht.test(r.replace(Dn,"")))return n;const o=t.includes("/")?t.slice(0,t.lastIndexOf("/")):"",i=`../${Fn(`${o}/${r}`)}`;return`import("${gt.test(i)?i:`${i}.js`}")`}),D=(e,t)=>_n(Pn(e,t)),Mn=["client","do","errors","flags","observability","platform","ratelimit","runtime","server","values"],Bn=new RegExp(String.raw`import\("@lunora/(?<pkg>${Mn.join("|")})(?<subpath>/[^"]*)?"\)`,"gu"),jn={flags:new Set(["/web"]),platform:new Set},ft=(e,t)=>t?e.replaceAll(Bn,(n,r,o)=>{const s=jn[r];return o&&s&&!s.has(o)?n:`import("lunorash/${r}${o??""}")`}):e,Ke=e=>["Doc","Id"].filter(t=>new RegExp(String.raw`\b${t}<`,"u").test(e)),qn=e=>e.output===void 0||e.output.kind==="any"?e.returnType:A(e.output),Qe=e=>{const t=new Map;for(const n of e){const r=t.get(n.filePath)??[];r.push(n),t.set(n.filePath,r)}return[...t.entries()].toSorted(([n],[r])=>n.localeCompare(r))},rt=e=>{const t=([n,r])=>{const o=r.toSorted((s,i)=>s.exportName.localeCompare(i.exportName)).map(s=>{const i=D(ke(s.args),s.filePath),a=D(qn(s),s.filePath);return` ${s.exportName}: FunctionReference<"${s.kind}", ${i}, ${a}>;`}).join(`
164
+ `);return` ${E(N(n))}: {
162
165
  ${o}
163
166
  };`};return Qe(e).map(n=>t(n)).join(`
164
- `)},Mn=(e,t)=>{if(e.length===0&&t.length===0)return{block:"",importLine:""};const n=[];let r="";if(e.length>0&&(r+="\n/** Params type carried by a `defineWorkflow` definition (its phantom `__params`). */\ntype WorkflowParamsOf<Definition> = Definition extends { __params?: infer Params } ? (unknown extends Params ? Record<string, unknown> : Params) : Record<string, unknown>;\n"),r+=`
167
+ `)},Wn=(e,t)=>{if(e.length===0&&t.length===0)return{block:"",importLine:""};const n=[];let r="";if(e.length>0&&(r+="\n/** Params type carried by a `defineWorkflow` definition (its phantom `__params`). */\ntype WorkflowParamsOf<Definition> = Definition extends { __params?: infer Params } ? (unknown extends Params ? Record<string, unknown> : Params) : Record<string, unknown>;\n"),r+=`
165
168
  /** A typed reference to a durable workflow, addressable for \`cronJobs()\` targets. Mirrors \`@lunora/scheduler\`'s \`WorkflowReference\` structurally. */
166
169
  export interface WorkflowReference<Params = Record<string, unknown>> {
167
170
  readonly isLunoraWorkflow: true;
@@ -193,7 +196,7 @@ export const agents: AgentsRef = {
193
196
  ${i}
194
197
  };
195
198
  `,n.push(`import type { AgentRunInput } from "@lunora/agent";
196
- `)}return{block:r,importLine:n.join("")}},Bn=()=>Object.keys(ot().functions).toSorted((e,t)=>e.localeCompare(t)),gt=e=>new Set(e.filter(t=>S(t.filePath)==="agents").map(t=>t.exportName)),jn=()=>new Set(Object.entries(ot().functions).filter(([,e])=>e.visibility==="internal").map(([e])=>e)),qn=(e,t)=>{const n={importLine:"",lines:"",prelude:""};if(e.length===0)return n;const r=gt(t),o=jn(),s=t.find(a=>S(a.filePath)==="agents"&&o.has(a.exportName));if(s)throw new te("INTERNAL",`@lunora/codegen: "agents:${s.exportName}" is reserved for the durable agent loop's internal dispatch — rename the "${s.exportName}" export in ${s.filePath}`);const i=Bn().filter(a=>!r.has(a));return i.length===0?n:{importLine:`import { agentComponent } from "@lunora/agent/component";
199
+ `)}return{block:r,importLine:n.join("")}},Un=()=>Object.keys(at().functions).toSorted((e,t)=>e.localeCompare(t)),yt=e=>new Set(e.filter(t=>N(t.filePath)==="agents").map(t=>t.exportName)),Kn=()=>new Set(Object.entries(at().functions).filter(([,e])=>e.visibility==="internal").map(([e])=>e)),Qn=(e,t)=>{const n={importLine:"",lines:"",prelude:""};if(e.length===0)return n;const r=yt(t),o=Kn(),s=t.find(a=>N(a.filePath)==="agents"&&o.has(a.exportName));if(s)throw new te("INTERNAL",`@lunora/codegen: "agents:${s.exportName}" is reserved for the durable agent loop's internal dispatch — rename the "${s.exportName}" export in ${s.filePath}`);const i=Un().filter(a=>!r.has(a));return i.length===0?n:{importLine:`import { agentComponent } from "@lunora/agent/component";
197
200
  `,lines:i.map(a=>` "agents:${a}": lunoraAgentRuntimeFunctions.${a} as unknown as RegisteredLunoraFunction,`).join(`
198
201
  `),prelude:`
199
202
  /**
@@ -202,13 +205,13 @@ ${i}
202
205
  * subscribe to the public queries (\`agents:agentMessages\` is the live thread view).
203
206
  */
204
207
  const lunoraAgentRuntimeFunctions = agentComponent().functions;
205
- `}},Wn=(e,t)=>{if(!e)return{importLine:"",lines:"",prelude:""};const n=t.find(r=>S(r.filePath)==="sandbox"&&r.exportName==="invoke");if(n)throw new te("INTERNAL",`@lunora/codegen: "sandbox:invoke" is reserved for the batteries-included sandbox tool dispatcher (browserTool/containerTool) — rename the "invoke" export in ${n.filePath}`);return{importLine:`import { sandboxComponent } from "@lunora/agent/component";
206
- `,lines:' "sandbox:invoke": lunoraSandbox.invoke as unknown as RegisteredLunoraFunction,',prelude:"\n/**\n * The `@lunora/agent` sandbox dispatcher — auto-registered because `lunora/`\n * imports a sandbox tool (`browserTool`/`containerTool`). The batteries-included\n * tools dispatch to this internal action, which runs on an action ctx carrying\n * `ctx.browser` + `ctx.containers` (the durable tool step itself has neither).\n */\nconst lunoraSandbox = sandboxComponent();\n"}},Un=(e,t)=>{if(e.length===0)return[];const n=gt(t),r=[{args:{key:{kind:"string"},limit:{inner:{kind:"number"},kind:"optional"}},exportName:"agentMessages",filePath:"agents",kind:"query",returnType:"Record<string, unknown>[]"},{args:{decision:{kind:"union",members:[{kind:"literal",literalValue:'"approve"'},{kind:"literal",literalValue:'"reject"'}]},instanceId:{kind:"string"},note:{inner:{kind:"string"},kind:"optional"},threadKey:{kind:"string"},toolCallId:{kind:"string"}},exportName:"agentResolveApproval",filePath:"agents",kind:"mutation",returnType:"{ resolved: boolean }"},{args:{agent:{kind:"string"},input:{kind:"string"},threadKey:{kind:"string"},title:{inner:{kind:"string"},kind:"optional"}},exportName:"agentRun",filePath:"agents",kind:"mutation",returnType:"{ id: string; threadKey: string }"},{args:{key:{kind:"string"}},exportName:"agentState",filePath:"agents",kind:"query",returnType:"Record<string, unknown> | undefined"},{args:{key:{kind:"string"}},exportName:"agentThread",filePath:"agents",kind:"query",returnType:"Record<string, unknown> | undefined"}];for(const o of e)o.voice&&r.push({args:{threadKey:{kind:"string"}},exportName:`${o.exportName}Voice`,filePath:"agents",kind:"stream",returnType:"Record<string, unknown>"});return r.filter(o=>!n.has(o.exportName))},Kn=(e,t)=>{if(e.length===0)return[];const n=new Set(t.filter(r=>S(r.filePath)==="mutators").map(r=>r.exportName));return e.filter(r=>!n.has(r.exportName)).map(r=>({args:r.args,exportName:r.exportName,filePath:r.filePath,kind:"mutation",returnType:r.returnType}))},Qn=e=>{const t=e.filter(i=>i.stream);if(t.length===0)return{block:"",body:""};const n=Qe(t),r=n.map(([i,a])=>{const c=a.map(d=>{const p=E(d.chunkType??"unknown",d.filePath),h=E(ke(d.searchParams),d.filePath),b=E(ke(d.params),d.filePath);return` ${_(d.exportName)}: HttpStreamRef<${p}, ${h}, ${b}>;`}).join(`
207
- `);return` ${_(S(i))}: {
208
+ `}},Vn=(e,t)=>{if(!e)return{importLine:"",lines:"",prelude:""};const n=t.find(r=>N(r.filePath)==="sandbox"&&r.exportName==="invoke");if(n)throw new te("INTERNAL",`@lunora/codegen: "sandbox:invoke" is reserved for the batteries-included sandbox tool dispatcher (browserTool/containerTool) — rename the "invoke" export in ${n.filePath}`);return{importLine:`import { sandboxComponent } from "@lunora/agent/component";
209
+ `,lines:' "sandbox:invoke": lunoraSandbox.invoke as unknown as RegisteredLunoraFunction,',prelude:"\n/**\n * The `@lunora/agent` sandbox dispatcher — auto-registered because `lunora/`\n * imports a sandbox tool (`browserTool`/`containerTool`). The batteries-included\n * tools dispatch to this internal action, which runs on an action ctx carrying\n * `ctx.browser` + `ctx.containers` (the durable tool step itself has neither).\n */\nconst lunoraSandbox = sandboxComponent();\n"}},Hn=(e,t)=>{if(e.length===0)return[];const n=yt(t),r=[{args:{key:{kind:"string"},limit:{inner:{kind:"number"},kind:"optional"}},exportName:"agentMessages",filePath:"agents",kind:"query",returnType:"Record<string, unknown>[]"},{args:{decision:{kind:"union",members:[{kind:"literal",literalValue:'"approve"'},{kind:"literal",literalValue:'"reject"'}]},instanceId:{kind:"string"},note:{inner:{kind:"string"},kind:"optional"},threadKey:{kind:"string"},toolCallId:{kind:"string"}},exportName:"agentResolveApproval",filePath:"agents",kind:"mutation",returnType:"{ resolved: boolean }"},{args:{agent:{kind:"string"},input:{kind:"string"},threadKey:{kind:"string"},title:{inner:{kind:"string"},kind:"optional"}},exportName:"agentRun",filePath:"agents",kind:"mutation",returnType:"{ id: string; threadKey: string }"},{args:{key:{kind:"string"}},exportName:"agentState",filePath:"agents",kind:"query",returnType:"Record<string, unknown> | undefined"},{args:{key:{kind:"string"}},exportName:"agentThread",filePath:"agents",kind:"query",returnType:"Record<string, unknown> | undefined"}];for(const o of e)o.voice&&r.push({args:{threadKey:{kind:"string"}},exportName:`${o.exportName}Voice`,filePath:"agents",kind:"stream",returnType:"Record<string, unknown>"});return r.filter(o=>!n.has(o.exportName))},Jn=(e,t)=>{if(e.length===0)return[];const n=new Set(t.filter(r=>N(r.filePath)==="mutators").map(r=>r.exportName));return e.filter(r=>!n.has(r.exportName)).map(r=>({args:r.args,exportName:r.exportName,filePath:r.filePath,kind:"mutation",returnType:r.returnType}))},Gn=e=>{const t=e.filter(i=>i.stream);if(t.length===0)return{block:"",body:""};const n=Qe(t),r=n.map(([i,a])=>{const c=a.map(d=>{const p=D(d.chunkType??"unknown",d.filePath),h=D(ke(d.searchParams),d.filePath),y=D(ke(d.params),d.filePath);return` ${E(d.exportName)}: HttpStreamRef<${p}, ${h}, ${y}>;`}).join(`
210
+ `);return` ${E(N(i))}: {
208
211
  ${c}
209
212
  };`}).join(`
210
- `),o=n.map(([i,a])=>{const c=a.map(d=>` ${_(d.exportName)}: { method: ${JSON.stringify(d.method)}, path: ${JSON.stringify(d.path)} },`).join(`
211
- `);return` ${_(S(i))}: {
213
+ `),o=n.map(([i,a])=>{const c=a.map(d=>` ${E(d.exportName)}: { method: ${JSON.stringify(d.method)}, path: ${JSON.stringify(d.path)} },`).join(`
214
+ `);return` ${E(N(i))}: {
212
215
  ${c}
213
216
  },`}).join(`
214
217
  `);return{block:`
@@ -220,26 +223,26 @@ ${r}
220
223
  export const httpStreams: HttpStreamsRef = {
221
224
  ${o}
222
225
  };
223
- `,body:r}},Kr=e=>{const{agents:t=[],functions:n,httpRoutes:r=[],mutators:o=[],useUmbrella:s=!1,workflows:i=[]}=e,a=ne(s),c=[...n.filter($=>$.visibility!=="internal"),...Un(t,n),...Kn(o,n)],d=n.filter($=>$.visibility==="internal"),p=nt(c),h=nt(d),b=Qn(r),u=`${p}
226
+ `,body:r}},Jr=e=>{const{agents:t=[],functions:n,httpRoutes:r=[],mutators:o=[],useUmbrella:s=!1,workflows:i=[]}=e,a=ne(s),c=[...n.filter(v=>v.visibility!=="internal"),...Hn(t,n),...Jn(o,n)],d=n.filter(v=>v.visibility==="internal"),p=rt(c),h=rt(d),y=Gn(r),u=`${p}
224
227
  ${h}
225
- ${b.body}`,l=Ke(u),f=l.length>0?`
228
+ ${y.body}`,l=Ke(u),f=l.length>0?`
226
229
  import type { ${l.join(", ")} } from "./dataModel.js";
227
- `:"",x=p?`
230
+ `:"",w=p?`
228
231
  ${p}
229
- `:"",w=h?`
232
+ `:"",$=h?`
230
233
  ${h}
231
- `:"",v=Mn(i,t),I=`export interface ApiTypes {${x}}
234
+ `:"",x=Wn(i,t),I=`export interface ApiTypes {${w}}
232
235
 
233
236
  export const api = anyApi as unknown as ApiTypes;
234
237
 
235
238
  /** Internal functions — callable only server-side via \`ctx.run*\`, never from a client. */
236
- export interface InternalApiTypes {${w}}
239
+ export interface InternalApiTypes {${$}}
237
240
 
238
241
  export const internal = anyApi as unknown as InternalApiTypes;
239
- ${v.block}${b.block}`,P=[...I.includes("FunctionReference<")?["FunctionReference"]:[],...b.block===""?[]:["HttpStreamRef"]],C=P.length>0?`import type { ${P.join(", ")} } from "${a.client}";
240
- `:"";return ht(`${R}import { anyApi } from "${a.client}";
241
- ${C}${v.importLine}${f}
242
- ${I}`,s)},Qr=e=>e?`${R}import { createSeedClient as createSeedClientBase } from "@lunora/seed";
242
+ ${x.block}${y.block}`,T=[...I.includes("FunctionReference<")?["FunctionReference"]:[],...y.block===""?[]:["HttpStreamRef"]],_=T.length>0?`import type { ${T.join(", ")} } from "${a.client}";
243
+ `:"";return ft(`${S}import { anyApi } from "${a.client}";
244
+ ${_}${x.importLine}${f}
245
+ ${I}`,s)},Gr=e=>e?`${S}import { createSeedClient as createSeedClientBase } from "@lunora/seed";
243
246
  import type { SeedClient, SeedClientOptions } from "@lunora/seed";
244
247
 
245
248
  import schema from "../schema.js";
@@ -256,9 +259,9 @@ import type { InsertModel } from "./dataModel.js";
256
259
  * const { posts } = await seed.posts((x) => x([10, 20]));
257
260
  */
258
261
  export const createSeedClient = (options?: SeedClientOptions): SeedClient<InsertModel> => createSeedClientBase<InsertModel>(schema, options);
259
- `:"",Vr=(e,t,n=!1)=>{if(e.length===0||!t)return"";const r=ne(n),o=c=>c.table===void 0?"Row":`Doc<${JSON.stringify(c.table)}> & Row`,s=e.map(c=>{g(c.exportName,"shape export name");const d=o(c),p=E(ke(c.args),c.filePath),h=Object.keys(c.args).length>0,b=h?` args: ${p};`:` args?: ${p};`,u=h?`(args: ${p}) => void`:`(args?: ${p}) => void`,l=`${c.exportName}CollectionOptions`;return`/** Options for the \`${c.exportName}\` shape binding. */
262
+ `:"",zr=(e,t,n=!1)=>{if(e.length===0||!t)return"";const r=ne(n),o=c=>c.table===void 0?"Row":`Doc<${JSON.stringify(c.table)}> & Row`,s=e.map(c=>{g(c.exportName,"shape export name");const d=o(c),p=D(ke(c.args),c.filePath),h=Object.keys(c.args).length>0,y=h?` args: ${p};`:` args?: ${p};`,u=h?`(args: ${p}) => void`:`(args?: ${p}) => void`,l=`${c.exportName}CollectionOptions`;return`/** Options for the \`${c.exportName}\` shape binding. */
260
263
  export interface ${qe(l)} {
261
- ${b}
264
+ ${y}
262
265
  /**
263
266
  * Share the optimistic-overlay gate with other collections + mutators on this
264
267
  * shard. Defaults to the shared per-shard registry, which is almost always what
@@ -303,14 +306,14 @@ export const ${c.exportName}Collection = (
303
306
  };`}).join(`
304
307
 
305
308
  `),i=Ke(s),a=i.length>0?`import type { ${i.join(", ")} } from "./dataModel.js";
306
- `:"";return`${R}import type { LunoraClient, SubscriptionError } from "${r.client}";
309
+ `:"";return`${S}import type { LunoraClient, SubscriptionError } from "${r.client}";
307
310
  import { lunoraCollectionOptions } from "@lunora/db/collections";
308
311
  import type { CheckpointRegistry, LunoraCollectionOptions, Row } from "@lunora/db";
309
312
  import type { Collection } from "@tanstack/db";
310
313
  import { createCollection } from "@tanstack/db";
311
314
  ${a}
312
315
  ${s}
313
- `},Vn=(e,t)=>`lunora_${S(e)}_${String(t)}`,Hn=`const callRegistered = async <R>(context: CallerCtx, functionPath: string, args: Record<string, unknown> | undefined): Promise<R> => {
316
+ `},zn=(e,t)=>`lunora_${N(e)}_${String(t)}`,Yn=`const callRegistered = async <R>(context: CallerCtx, functionPath: string, args: Record<string, unknown> | undefined): Promise<R> => {
314
317
  const registered = LUNORA_FUNCTIONS[functionPath];
315
318
 
316
319
  if (!registered) {
@@ -318,45 +321,45 @@ ${s}
318
321
  }
319
322
 
320
323
  return (await registered.handler(context, args ?? {})) as R;
321
- };`,Jn=(e,t,n=[],r=[])=>{const o=new Map,s=l=>{o.has(l)||o.set(l,Vn(l,o.size))};for(const l of e)s(l.filePath);for(const l of t)s(l.filePath);for(const l of n)s(l.filePath);for(const l of r)s(l.filePath);const i=[...o.entries()].map(([l,f])=>{if(!Rn.test(l))throw new te("INTERNAL",`@lunora/codegen: refusing to emit import for unsafe file path: ${JSON.stringify(l)}`);return`import * as ${f} from "../${l}.js";`}).join(`
322
- `),a=e.map(l=>` "${S(l.filePath)}:${l.exportName}": ${o.get(l.filePath)??""}.${l.exportName} as unknown as RegisteredLunoraFunction,`).join(`
324
+ };`,Xn=(e,t,n=[],r=[])=>{const o=new Map,s=l=>{o.has(l)||o.set(l,zn(l,o.size))};for(const l of e)s(l.filePath);for(const l of t)s(l.filePath);for(const l of n)s(l.filePath);for(const l of r)s(l.filePath);const i=[...o.entries()].map(([l,f])=>{if(!An.test(l))throw new te("INTERNAL",`@lunora/codegen: refusing to emit import for unsafe file path: ${JSON.stringify(l)}`);return`import * as ${f} from "../${l}.js";`}).join(`
325
+ `),a=e.map(l=>` "${N(l.filePath)}:${l.exportName}": ${o.get(l.filePath)??""}.${l.exportName} as unknown as RegisteredLunoraFunction,`).join(`
323
326
  `),c=t.map(l=>` ${JSON.stringify(l.id)}: ${o.get(l.filePath)??""}.${l.exportName} as unknown as RegisteredDataMigration,`).join(`
324
- `),d=n.map(l=>` "${S(l.filePath)}:${l.exportName}": ${o.get(l.filePath)??""}.${l.exportName} as unknown as RegisteredLunoraFunction,`).join(`
327
+ `),d=n.map(l=>` "${N(l.filePath)}:${l.exportName}": ${o.get(l.filePath)??""}.${l.exportName} as unknown as RegisteredLunoraFunction,`).join(`
325
328
  `),p=r.map(l=>` "${l.exportName}": ${o.get(l.filePath)??""}.${l.exportName} as unknown as RegisteredShape,`).join(`
326
- `),h=n.map(l=>`${S(l.filePath)}:${l.exportName}`),b=[a,d].filter(l=>l.length>0).join(`
327
- `),u=e.map(l=>{if(l.lifecycle||Object.keys(l.args).length===0)return;const f=$n(l.args);return f===void 0?void 0:`installCompiledValidatorMap(${o.get(l.filePath)??""}.${l.exportName}.args, ${f});`}).filter(l=>l!==void 0).join(`
328
- `);return{dispatchBody:b.length>0?`
329
- ${b}
329
+ `),h=n.map(l=>`${N(l.filePath)}:${l.exportName}`),y=[a,d].filter(l=>l.length>0).join(`
330
+ `),u=e.map(l=>{if(l.lifecycle||Object.keys(l.args).length===0)return;const f=Tn(l.args);return f===void 0?void 0:`installCompiledValidatorMap(${o.get(l.filePath)??""}.${l.exportName}.args, ${f});`}).filter(l=>l!==void 0).join(`
331
+ `);return{dispatchBody:y.length>0?`
332
+ ${y}
330
333
  `:"",importBlock:i.length>0?`${i}
331
334
 
332
335
  `:"",installBlock:u,migrationBody:c.length>0?`
333
336
  ${c}
334
337
  `:"",mutatorPaths:h,shapeBody:p.length>0?`
335
338
  ${p}
336
- `:""}},Gn=e=>{const t=Qe(e),n=t.map(([o,s])=>{const i=s.map(a=>{const c=E(ke(a.args),a.filePath),d=c==="{}"?"?":"",p=E(a.returnType,a.filePath);return a.kind==="stream"?` ${a.exportName}: (args${d}: ${c}) => Promise<AsyncIterable<${p}>>;`:` ${a.exportName}: (args${d}: ${c}) => Promise<${p}>;`}).join(`
337
- `);return` ${_(S(o))}: {
339
+ `:""}},Zn=e=>{const t=Qe(e),n=t.map(([o,s])=>{const i=s.map(a=>{const c=D(ke(a.args),a.filePath),d=c==="{}"?"?":"",p=D(a.returnType,a.filePath);return a.kind==="stream"?` ${a.exportName}: (args${d}: ${c}) => Promise<AsyncIterable<${p}>>;`:` ${a.exportName}: (args${d}: ${c}) => Promise<${p}>;`}).join(`
340
+ `);return` ${E(N(o))}: {
338
341
  ${i}
339
342
  };`}).join(`
340
- `);return{implementation:t.map(([o,s])=>{const i=S(o),a=s.map(c=>` ${c.exportName}: (args) => callRegistered(context, "${i}:${c.exportName}", args),`).join(`
341
- `);return` ${_(i)}: {
343
+ `);return{implementation:t.map(([o,s])=>{const i=N(o),a=s.map(c=>` ${c.exportName}: (args) => callRegistered(context, "${i}:${c.exportName}", args),`).join(`
344
+ `);return` ${E(i)}: {
342
345
  ${a}
343
346
  },`}).join(`
344
- `),types:n}},zn=(e,t=[])=>{const n=new Set;for(const r of e.tables)for(const o of Object.values(r.shape)){const s=re(o);s.kind==="storage"&&typeof s.bucket=="string"&&s.bucket!==""&&n.add(s.bucket)}for(const r of t)r!==""&&r!=="default"&&n.add(r);return["default",...[...n].toSorted((r,o)=>r.localeCompare(o))]},Hr=({agents:e=[],containers:t=[],env:n,hasAccessFacade:r=!1,hasAi:o=!1,hasAnalytics:s=!1,hasBrowser:i=!1,hasFlags:a=!1,hasHyperdrive:c=!1,hasImages:d=!1,hasKv:p=!1,hasNotify:h=!1,hasPayments:b=!1,hasPipelines:u=!1,hasR2sql:l=!1,hasX402:f=!1,identity:x,queues:w=[],schema:v,storageRuleBuckets:I=[],useUmbrella:P=!1,workflows:C=[]}={})=>{const $=ne(P),k=zn(v??{tables:[]},I).map(m=>JSON.stringify(m)).join(" | "),M=o?`import type { LunoraAi } from "@lunora/ai";
347
+ `),types:n}},er=(e,t=[])=>{const n=new Set;for(const r of e.tables)for(const o of Object.values(r.shape)){const s=re(o);s.kind==="storage"&&typeof s.bucket=="string"&&s.bucket!==""&&n.add(s.bucket)}for(const r of t)r!==""&&r!=="default"&&n.add(r);return["default",...[...n].toSorted((r,o)=>r.localeCompare(o))]},Yr=({agents:e=[],containers:t=[],env:n,hasAccessFacade:r=!1,hasAi:o=!1,hasAnalytics:s=!1,hasBrowser:i=!1,hasFlags:a=!1,hasHyperdrive:c=!1,hasImages:d=!1,hasKv:p=!1,hasNotify:h=!1,hasPayments:y=!1,hasPipelines:u=!1,hasR2sql:l=!1,hasX402:f=!1,identity:w,queues:$=[],schema:x,storageRuleBuckets:I=[],useUmbrella:T=!1,workflows:_=[]}={})=>{const v=ne(T),k=er(x??{tables:[]},I).map(m=>JSON.stringify(m)).join(" | "),M=o?`import type { LunoraAi } from "@lunora/ai";
345
348
  `:"",oe=o?`
346
- readonly ai: LunoraAi;`:"",B=b?`import type { LunoraPayment } from "@lunora/payment";
347
- `:"",ae=b?`
349
+ readonly ai: LunoraAi;`:"",B=y?`import type { LunoraPayment } from "@lunora/payment";
350
+ `:"",ae=y?`
348
351
  readonly payments: LunoraPayment;`:"",se=f?`import type { X402Pay } from "@lunora/x402/pay";
349
352
  `:"",W=f?`
350
- readonly x402: X402Pay;`:"",A=t.length>0?`import type { ContainerAccessor } from "@lunora/container";
353
+ readonly x402: X402Pay;`:"",C=t.length>0?`import type { ContainerAccessor } from "@lunora/container";
351
354
  `:"",X=t.length>0?`
352
355
  readonly containers: {${t.map(m=>`
353
356
  readonly ${m.exportName}: ContainerAccessor;`).join("")}
354
- };`:"",O=[...o?[" /** Workers AI binding (the conventional `env.AI`), narrowing `ctx.ai`. */\n readonly AI?: unknown;"]:[],...t.map(m=>(g(m.bindingName,`container binding "${m.bindingName}"`),` /** Durable Object namespace for the \`${m.exportName}\` container. */
355
- readonly ${m.bindingName}?: unknown;`)),...C.map(m=>(g(m.bindingName,`workflow binding "${m.bindingName}"`),` /** Workflow binding for the \`${m.exportName}\` workflow. */
356
- readonly ${m.bindingName}?: unknown;`)),...w.map(m=>(g(m.bindingName,`queue binding "${m.bindingName}"`),` /** Queue producer binding for the \`${m.exportName}\` queue. */
357
+ };`:"",L=[...o?[" /** Workers AI binding (the conventional `env.AI`), narrowing `ctx.ai`. */\n readonly AI?: unknown;"]:[],...t.map(m=>(g(m.bindingName,`container binding "${m.bindingName}"`),` /** Durable Object namespace for the \`${m.exportName}\` container. */
358
+ readonly ${m.bindingName}?: unknown;`)),..._.map(m=>(g(m.bindingName,`workflow binding "${m.bindingName}"`),` /** Workflow binding for the \`${m.exportName}\` workflow. */
359
+ readonly ${m.bindingName}?: unknown;`)),...$.map(m=>(g(m.bindingName,`queue binding "${m.bindingName}"`),` /** Queue producer binding for the \`${m.exportName}\` queue. */
357
360
  readonly ${m.bindingName}?: unknown;`)),...e.map(m=>(g(m.bindingName,`agent binding "${m.bindingName}"`),` /** Workflow binding for the \`${m.exportName}\` agent. */
358
361
  readonly ${m.bindingName}?: unknown;`))].join(`
359
- `),L=`
362
+ `),R=`
360
363
 
361
364
  /**
362
365
  * This project's Cloudflare bindings, as far as codegen can discover them from
@@ -369,24 +372,24 @@ ${a}
369
372
  * surface, so treat them as \`Fetcher\`/\`Service<unknown>\` and cast.
370
373
  */
371
374
  export interface CloudflareBindings {
372
- readonly [binding: string]: unknown;${O?`
373
- ${O}`:""}
375
+ readonly [binding: string]: unknown;${L?`
376
+ ${L}`:""}
374
377
  }
375
378
 
376
379
  /** Alias for {@link CloudflareBindings} — the typed shape of \`env\`. */
377
- export type Env = CloudflareBindings;`,j=(m,Me)=>Me?fn.get(m)?.field??"":"",ie=j("kv",p),le=j("analytics",s),Se=j("hyperdrive",c),Ne=j("browser",i),Te=j("images",d),ce=j("pipelines",u),V=j("r2sql",l),F=(v?.vectorIndexes.length??0)>0,H=F?' | "vectors"':"",Z=F?`
378
- readonly vectors: VectorSearch<VectorIndexName>;`:"",de=F?`
379
- readonly vectors: VectorSearchReader<VectorIndexName>;`:"",J=F?`import type { VectorSearch, VectorSearchReader } from "${$.server}";
380
+ export type Env = CloudflareBindings;`,j=(m,Me)=>Me?kn.get(m)?.field??"":"",ie=j("kv",p),le=j("analytics",s),Se=j("hyperdrive",c),Ne=j("browser",i),Te=j("images",d),ce=j("pipelines",u),V=j("r2sql",l),P=(x?.vectorIndexes.length??0)>0,H=P?' | "vectors"':"",Z=P?`
381
+ readonly vectors: VectorSearch<VectorIndexName>;`:"",de=P?`
382
+ readonly vectors: VectorSearchReader<VectorIndexName>;`:"",J=P?`import type { VectorSearch, VectorSearchReader } from "${v.server}";
380
383
  import type { VectorIndexName } from "./dataModel.js";
381
384
  `:"",U=r?`
382
385
  /** Verified Cloudflare Access identity — a synchronous facade over the resolved claims (email / groups / hasGroup / claims). Anonymous when no Access token is present. */
383
386
  readonly access: import("@lunora/cloudflare-access/context").AccessFacade;`:"",K=a?`
384
387
  /** Feature-flag evaluation (OpenFeature). Reads are memoized per request; evaluations never throw — a provider error resolves to the supplied default. */
385
- readonly flags: import("${$.flags}").LunoraFlags;`:"",Q=h?`
388
+ readonly flags: import("${v.flags}").LunoraFlags;`:"",Q=h?`
386
389
  /** Multi-channel notifications (@lunora/notify): send / chat / inApp / webhook plus the push device sub-facade. Sends are external I/O — confine them to action handlers. */
387
390
  readonly notify: import("@lunora/notify").LunoraNotify;
388
391
  /** Device push sub-facade — the same object as ctx.notify.push (register / send / broadcast). Sends belong in action handlers. */
389
- readonly push: import("@lunora/notify").LunoraPush;`:"",q=C.length>0,ee=q?`import type { WorkflowHandle } from "@lunora/workflow";
392
+ readonly push: import("@lunora/notify").LunoraPush;`:"",q=_.length>0,ee=q?`import type { WorkflowHandle } from "@lunora/workflow";
390
393
  import type * as lunoraWorkflowDefinitions from "../workflows.js";
391
394
  `:"",Ae=q?`
392
395
 
@@ -399,10 +402,10 @@ type WorkflowParamsOf<Definition> = Definition extends { __params?: infer Params
399
402
 
400
403
  /** This project's declared workflows, addressable from \`ctx.workflows\` by their \`lunora/workflows.ts\` export name. */
401
404
  export interface LunoraWorkflows {
402
- ${C.map(m=>` get(name: ${JSON.stringify(m.exportName)}): WorkflowHandle<WorkflowParamsOf<typeof lunoraWorkflowDefinitions.${m.exportName}>>;`).join(`
405
+ ${_.map(m=>` get(name: ${JSON.stringify(m.exportName)}): WorkflowHandle<WorkflowParamsOf<typeof lunoraWorkflowDefinitions.${m.exportName}>>;`).join(`
403
406
  `)}
404
- }`:"",xe=q?' | "workflows"':"",we=q?`
405
- readonly workflows: LunoraWorkflows;`:"",ue=w.length>0,Oe=ue?`import type { QueueProducer } from "@lunora/queue";
407
+ }`:"",we=q?' | "workflows"':"",xe=q?`
408
+ readonly workflows: LunoraWorkflows;`:"",ue=$.length>0,Oe=ue?`import type { QueueProducer } from "@lunora/queue";
406
409
  import type * as lunoraQueueDefinitions from "../queues.js";
407
410
  `:"",Ie=ue?`
408
411
 
@@ -411,7 +414,7 @@ type QueueBodyOf<Definition> = Definition extends { __lunoraBody?: infer Body }
411
414
 
412
415
  /** This project's declared queues, addressable from \`ctx.queues\` by their \`lunora/queues.ts\` export name. */
413
416
  export interface LunoraQueues {
414
- ${w.map(m=>` readonly ${m.exportName}: QueueProducer<QueueBodyOf<typeof lunoraQueueDefinitions.${m.exportName}>>;`).join(`
417
+ ${$.map(m=>` readonly ${m.exportName}: QueueProducer<QueueBodyOf<typeof lunoraQueueDefinitions.${m.exportName}>>;`).join(`
415
418
  `)}
416
419
  }`:"",ve=ue?`
417
420
  readonly queues: LunoraQueues;`:"",pe=e.length>0,Ce=pe?`import type { AgentHandle } from "@lunora/agent";
@@ -422,20 +425,20 @@ export interface LunoraAgents {
422
425
  ${e.map(m=>(g(m.exportName,`agent export "${m.exportName}"`),` readonly ${m.exportName}: AgentHandle;`)).join(`
423
426
  `)}
424
427
  }`:"",$e=pe?`
425
- readonly agents: LunoraAgents;`:"",_e=x?`import type { InferIdentity } from "${$.server}";
428
+ readonly agents: LunoraAgents;`:"",_e=w?`import type { InferIdentity } from "${v.server}";
426
429
  import type * as lunoraIdentityContract from "../identity.js";
427
- `:"",Ee=x?`
430
+ `:"",Ee=w?`
428
431
 
429
432
  /** This app's declared identity claim contract (\`defineIdentity\` in \`lunora/identity.ts\`) — the typed shape of \`ctx.auth.getIdentity()\`, the RLS policy \`ctx.auth.identity\`, and the \`authorizeShard\`/\`authorizeFanOut\` identity argument. */
430
- export type Identity = InferIdentity<typeof lunoraIdentityContract.${x.exportName}>;
433
+ export type Identity = InferIdentity<typeof lunoraIdentityContract.${w.exportName}>;
431
434
 
432
435
  /** \`ctx.auth\` narrowed so \`getIdentity()\` resolves the declared {@link Identity} contract instead of the untyped claim bag. */
433
- type NarrowedAuth = Omit<QueryCtxBase["auth"], "getIdentity"> & { getIdentity: () => Promise<Identity | null> };`:"",me=x?' | "auth"':"",he=x?`
434
- readonly auth: NarrowedAuth;`:"",De=x?", Identity":"",Fe=n?`import type * as lunoraEnvContract from "../env.js";
436
+ type NarrowedAuth = Omit<QueryCtxBase["auth"], "getIdentity"> & { getIdentity: () => Promise<Identity | null> };`:"",me=w?' | "auth"':"",he=w?`
437
+ readonly auth: NarrowedAuth;`:"",De=w?", Identity":"",Fe=n?`import type * as lunoraEnvContract from "../env.js";
435
438
  `:"",Pe=n?`
436
439
 
437
440
  /** This app's declared env contract (\`defineEnv\` in \`lunora/env.ts\`) — the validated, coercion-aware shape of \`ctx.env\`. */
438
- export type LunoraEnv = ReturnType<typeof lunoraEnvContract.${n.exportName}>;`:"",ge=n?' | "env"':"",fe=n?"\n /** Validated, typed environment declared by `defineEnv` in `lunora/env.ts` — parsed & coercion-aware config values (`ctx.env.STRIPE_KEY`); a missing or invalid value throws at read time. */\n readonly env: LunoraEnv;":"";return`${R}import { createPolicyDsl, defineMutator as defineMutatorBase, initLunora, v as vBase } from "${$.server}";
441
+ export type LunoraEnv = ReturnType<typeof lunoraEnvContract.${n.exportName}>;`:"",ge=n?' | "env"':"",fe=n?"\n /** Validated, typed environment declared by `defineEnv` in `lunora/env.ts` — parsed & coercion-aware config values (`ctx.env.STRIPE_KEY`); a missing or invalid value throws at read time. */\n readonly env: LunoraEnv;":"";return`${S}import { createPolicyDsl, defineMutator as defineMutatorBase, initLunora, v as vBase } from "${v.server}";
439
442
  import type {
440
443
  ActionBuilder,
441
444
  ActionCtx as ActionCtxBase,
@@ -456,7 +459,7 @@ import type {
456
459
  Storage as StorageBase,
457
460
  TableReader,
458
461
  Validator,
459
- } from "${$.server}";
462
+ } from "${v.server}";
460
463
 
461
464
  import type {
462
465
  DatabaseReaderFacade as DatabaseReaderFacadeOf,
@@ -465,7 +468,7 @@ import type {
465
468
  TableReaderFacade as TableReaderFacadeOf,
466
469
  TableWriterFacade as TableWriterFacadeOf,
467
470
  WithArg as WithArgOf,
468
- } from "${$.serverDataModel}";
471
+ } from "${v.serverDataModel}";
469
472
 
470
473
  export type {
471
474
  AggregateOp,
@@ -488,10 +491,10 @@ export type {
488
491
  Where,
489
492
  WhereOf,
490
493
  WhereOperators,
491
- } from "${$.serverDataModel}";
494
+ } from "${v.serverDataModel}";
492
495
 
493
496
  import type { DataModel, Doc, GeoIndexNamesByTable, Id as IdOfTable, IndexNamesByTable, Insert, InsertModel, RankIndexNamesByTable, Relations, SearchIndexNamesByTable, TableName } from "./dataModel.js";
494
- ${J}${M}${B}${se}${A}${ee}${Oe}${Ce}${_e}${Fe}
497
+ ${J}${M}${B}${se}${C}${ee}${Oe}${Ce}${_e}${Fe}
495
498
  export type { AppTableName, DataModel, Doc, Id, TableName } from "./dataModel.js";
496
499
 
497
500
  /**
@@ -551,7 +554,7 @@ export interface OrmWriter extends OrmReader {
551
554
  }
552
555
 
553
556
  /** Storage buckets this schema declares (\`v.storage("name")\`), narrowing \`ctx.storage.bucket(name)\`. */
554
- export type StorageBucketName = ${k};${L}${Ae}${Ie}${Le}${Ee}${Pe}
557
+ export type StorageBucketName = ${k};${R}${Ae}${Ie}${Le}${Ee}${Pe}
555
558
 
556
559
  /**
557
560
  * Project-typed contexts. The base contexts from \`@lunora/server\` are
@@ -620,16 +623,16 @@ export interface QueryCtx extends Omit<QueryCtxBase, "db" | "storage"${H}${me}${
620
623
  readonly storage: ReadOnlyStorage<StorageBucketName>;${de}${U}${ie}${K}${Q}${le}${fe}${he}
621
624
  }
622
625
 
623
- export interface MutationCtx extends Omit<MutationCtxBase, "db" | "storage"${H}${xe}${me}${ge}> {
626
+ export interface MutationCtx extends Omit<MutationCtxBase, "db" | "storage"${H}${we}${me}${ge}> {
624
627
  readonly db: Omit<DatabaseWriter, "asId" | "query" | "get"> & DatabaseWriterFacade & { asId: TypedAsId; query: TypedTableQuery; get: TypedTableGet };
625
628
  readonly orm: OrmWriter;
626
- readonly storage: ReadOnlyStorage<StorageBucketName>;${Z}${U}${ie}${K}${Q}${le}${fe}${we}${ve}${$e}${he}
629
+ readonly storage: ReadOnlyStorage<StorageBucketName>;${Z}${U}${ie}${K}${Q}${le}${fe}${xe}${ve}${$e}${he}
627
630
  }
628
631
 
629
- export interface ActionCtx extends Omit<ActionCtxBase, "db" | "storage"${H}${xe}${me}${ge}> {
632
+ export interface ActionCtx extends Omit<ActionCtxBase, "db" | "storage"${H}${we}${me}${ge}> {
630
633
  readonly db: Omit<DatabaseWriter, "asId" | "query" | "get"> & DatabaseWriterFacade & { asId: TypedAsId; query: TypedTableQuery; get: TypedTableGet };
631
634
  readonly orm: OrmWriter;
632
- readonly storage: StorageBase<StorageBucketName>;${Z}${U}${oe}${ae}${W}${X}${ie}${K}${Q}${Se}${Ne}${Te}${le}${ce}${V}${fe}${we}${ve}${$e}${he}
635
+ readonly storage: StorageBase<StorageBucketName>;${Z}${U}${oe}${ae}${W}${X}${ie}${K}${Q}${Se}${Ne}${Te}${le}${ce}${V}${fe}${xe}${ve}${$e}${he}
633
636
  }
634
637
 
635
638
  /**
@@ -662,7 +665,7 @@ export const internalAction = lunoraBuilders.internalAction as unknown as Intern
662
665
  /**
663
666
  * \`defineMutator\` bound to this project's typed {@link MutationCtx} — declare
664
667
  * custom mutators (\`lunora/mutators.ts\`) with it instead of importing from
665
- * \`${$.server}\`, and the authoritative \`server\` impl's \`ctx\` carries the
668
+ * \`${v.server}\`, and the authoritative \`server\` impl's \`ctx\` carries the
666
669
  * schema-typed \`ctx.db\` (\`ctx.db.query("nodes")\` resolves \`Doc<"nodes">\`,
667
670
  * \`ctx.db.patch(id, …)\` takes an \`Id<"nodes">\`) with no hand-written ctx type and
668
671
  * no \`as unknown as\` cast. Runtime-identical to the package export; only the
@@ -704,13 +707,13 @@ export const definePolicy = createPolicyDsl<DataModel, Relations${De}>();
704
707
  export const v = vBase as unknown as Omit<typeof vBase, "id"> & {
705
708
  id: <T extends TableName>(table: T) => ColumnValidator<IdOfTable<T>, IdOfTable<T>>;
706
709
  };
707
- `},Yn=e=>{const t={connect:[],disconnect:[]};for(const n of e)n.lifecycle&&t[n.lifecycle].push(`${S(n.filePath)}:${n.exportName}`);return t},Jr=e=>{const{agents:t=[],functions:n,migrations:r=[],mutators:o=[],shapes:s=[],useUmbrella:i=!1,usesSandbox:a=!1}=e,c=n.length>0,d=ne(i),{dispatchBody:p,importBlock:h,installBlock:b,migrationBody:u,mutatorPaths:l,shapeBody:f}=Jn(n,r,o,s),x=qn(t,n),w=Wn(a,n),v=[x.lines,w.lines].filter(L=>L.length>0).join(`
708
- `);let I=p;v.length>0&&(I=p.length>0?`${p.trimEnd()}
709
- ${v}
710
+ `},tr=e=>{const t={connect:[],disconnect:[],init:[],reactor:[]};for(const n of e)n.lifecycle&&t[n.lifecycle].push(`${N(n.filePath)}:${n.exportName}`);return t},Xr=e=>{const{agents:t=[],functions:n,migrations:r=[],mutators:o=[],shapes:s=[],useUmbrella:i=!1,usesSandbox:a=!1}=e,c=n.length>0,d=ne(i),{dispatchBody:p,importBlock:h,installBlock:y,migrationBody:u,mutatorPaths:l,shapeBody:f}=Xn(n,r,o,s),w=Qn(t,n),$=Vn(a,n),x=[w.lines,$.lines].filter(R=>R.length>0).join(`
711
+ `);let I=p;x.length>0&&(I=p.length>0?`${p.trimEnd()}
712
+ ${x}
710
713
  `:`
711
- ${v}
712
- `);const P=Yn(n),C=s.length>0?`import type { RegisteredShape } from "${d.server}";
713
- `:"",$=s.length>0?`
714
+ ${x}
715
+ `);const T=tr(n),_=s.length>0?`import type { RegisteredShape } from "${d.server}";
716
+ `:"",v=s.length>0?`
714
717
  /**
715
718
  * Replication-shape registry — one entry per \`defineShape\` in \`lunora/shapes.ts\`.
716
719
  * The generated ShardDO's \`resolveShape\` override looks a shape up by name and
@@ -724,25 +727,25 @@ export const LUNORA_SHAPES: Record<string, RegisteredShape> = {${f}};
724
727
  * ShardDO's \`isCustomMutator\` override routes through the client-watermark push
725
728
  * protocol (\`x-lunora-client-id\`/\`x-lunora-client-seq\` ordering).
726
729
  */
727
- export const LUNORA_MUTATOR_PATHS: ReadonlySet<string> = new Set([${l.map(L=>JSON.stringify(L)).join(", ")}]);
728
- `:"",M=b.length>0?`import { DEFER_VALIDATION as DEFER, installCompiledValidatorMap } from "${d.values}";
729
- `:"",oe=b.length>0?`
730
+ export const LUNORA_MUTATOR_PATHS: ReadonlySet<string> = new Set([${l.map(R=>JSON.stringify(R)).join(", ")}]);
731
+ `:"",M=y.length>0?`import { DEFER_VALIDATION as DEFER, installCompiledValidatorMap } from "${d.values}";
732
+ `:"",oe=y.length>0?`
730
733
  /**
731
734
  * AOT-compiled argument validators (Worker-safe, no \`eval\`). Each is installed
732
735
  * onto its function's live \`.args\` object and consulted by the interpreted
733
736
  * parser as a zero-allocation fast path; anything it can't model is deferred.
734
737
  */
735
- ${b}
736
- `:"",B=Gn(n),ae=B.types?`
738
+ ${y}
739
+ `:"",B=Zn(n),ae=B.types?`
737
740
  ${B.types}
738
741
  `:"",se=B.implementation?`
739
742
  ${B.implementation}
740
- `:"",W=Ke(B.types),A=W.length>0?`import type { ${W.join(", ")} } from "./dataModel.js";
741
- `:"",X=c?"context":"_context",O=c?`${Hn}
743
+ `:"",W=Ke(B.types),C=W.length>0?`import type { ${W.join(", ")} } from "./dataModel.js";
744
+ `:"",X=c?"context":"_context",L=c?`${Yn}
742
745
 
743
- `:"";return ht(`${R}${h}${x.importLine}${w.importLine}${M}${C}import { LunoraError } from "${d.server}";
746
+ `:"";return ft(`${S}${h}${w.importLine}${$.importLine}${M}${_}import { LunoraError } from "${d.server}";
744
747
  import type { ActionCtx, MutationCtx, QueryCtx } from "./server.js";
745
- ${A}
748
+ ${C}
746
749
  /**
747
750
  * Single registered function, narrowed to the shape \`handleRpc\` needs.
748
751
  * The real argument validators / return types are checked elsewhere — at
@@ -764,25 +767,37 @@ export interface RegisteredLunoraFunction {
764
767
  * \`AbortSignal\` as a third argument — the runtime drives it frame-by-frame.
765
768
  */
766
769
  handler: ((context: unknown, args: Record<string, unknown>) => Promise<unknown> | unknown) | ((context: unknown, args: Record<string, unknown>, signal?: AbortSignal) => AsyncIterable<unknown>);
770
+ /**
771
+ * The lifecycle moment a hook fires on, when this registration came from
772
+ * \`onConnect\`/\`onDisconnect\`/\`onShardInit\`/\`onQueryChange\`. Read at
773
+ * dispatch to decide whether the function runs system-trusted: \`init\` and
774
+ * \`reactor\` have no caller identity, so RLS has no user to scope to.
775
+ */
776
+ lifecycle?: "connect" | "disconnect" | "init" | "reactor";
767
777
  /** \`"internal"\` functions are rejected on the external RPC path; absence === public. */
768
778
  visibility?: "internal" | "public";
769
779
  }
770
- ${x.prelude}${w.prelude}
780
+ ${w.prelude}${$.prelude}
771
781
  /**
772
782
  * Static dispatch table. The key matches the \`__lunoraRef\` the client
773
783
  * emits (\`api[namespace][fn].__lunoraRef === "namespace:fn"\`).
774
784
  */
775
785
  export const LUNORA_FUNCTIONS: Record<string, RegisteredLunoraFunction> = {${I}};
776
- ${oe}${$}${k}
786
+ ${oe}${v}${k}
777
787
  /**
778
- * Connection-lifecycle manifest: the function paths the generated ShardDO
779
- * dispatches when a client's WebSocket connects (\`connect\`) or disconnects
780
- * (\`disconnect\`). Each path also resolves through {@link LUNORA_FUNCTIONS}; the
781
- * DO runs every hook under the socket's verified identity via system dispatch.
788
+ * Lifecycle manifest: the function paths the generated ShardDO dispatches when a
789
+ * client's WebSocket connects (\`connect\`) or disconnects (\`disconnect\`), once
790
+ * per Durable Object instance before any handler runs (\`init\`), and after a
791
+ * write flush when a watched read's result changed (\`reactor\`). Each path also
792
+ * resolves through {@link LUNORA_FUNCTIONS}. The socket sides run under the
793
+ * socket's verified identity; \`init\` and \`reactor\` have no caller, so they run
794
+ * anonymous — all via system dispatch.
782
795
  */
783
- export const LUNORA_LIFECYCLE_HOOKS: { connect: readonly string[]; disconnect: readonly string[] } = {
784
- connect: [${P.connect.map(L=>JSON.stringify(L)).join(", ")}],
785
- disconnect: [${P.disconnect.map(L=>JSON.stringify(L)).join(", ")}],
796
+ export const LUNORA_LIFECYCLE_HOOKS: { connect: readonly string[]; disconnect: readonly string[]; init: readonly string[]; reactor: readonly string[] } = {
797
+ connect: [${T.connect.map(R=>JSON.stringify(R)).join(", ")}],
798
+ disconnect: [${T.disconnect.map(R=>JSON.stringify(R)).join(", ")}],
799
+ init: [${T.init.map(R=>JSON.stringify(R)).join(", ")}],
800
+ reactor: [${T.reactor.map(R=>JSON.stringify(R)).join(", ")}],
786
801
  };
787
802
 
788
803
  /**
@@ -815,7 +830,7 @@ export type CallerCtx = ActionCtx | MutationCtx | QueryCtx;
815
830
  */
816
831
  export interface Caller {${ae}}
817
832
 
818
- ${O}/** Build a {@link Caller} bound to \`context\` (typically a handler's \`ctx\`). */
833
+ ${L}/** Build a {@link Caller} bound to \`context\` (typically a handler's \`ctx\`). */
819
834
  export const createCaller = (${X}: CallerCtx): Caller => ({${se}});
820
835
 
821
836
  /**
@@ -836,7 +851,7 @@ export interface RegisteredDataMigration {
836
851
  * shard DO's admin RPC and the CLI resolve migrations to run through this map.
837
852
  */
838
853
  export const LUNORA_MIGRATIONS: Record<string, RegisteredDataMigration> = {${u}};
839
- `,i)},Xn=e=>{const t={};for(const n of e.tables){const r={};for(const[o,s]of Object.entries(n.shape)){const i=re(s);i.kind==="id"&&i.tableName!==void 0&&(r[o]=i.tableName)}Object.keys(r).length>0&&(t[n.name]=r)}return t},Zn=e=>{const t={};for(const n of e.tables){const r=[];for(const[o,s]of Object.entries(n.shape))re(s).kind==="storage"&&r.push(o);r.length>0&&(t[n.name]=r)}return t},er=e=>{const t={};for(const n of e.tables){const r=[...n.indexes.map(o=>({fields:[...o.fields],name:o.name,type:"index",...o.unique===!0?{unique:!0}:{}})),...n.searchIndexes.map(o=>({fields:[o.field,...o.filterFields??[]],name:o.name,type:"search"})),...(n.geoIndexes??[]).map(o=>({fields:[o.field],name:o.name,type:"geo"})),...n.rankIndexes.map(o=>({fields:o.sortBy.map(s=>s.field),name:o.name,type:"rank"})),...n.vectorIndexes.map(o=>({fields:o.field===void 0?[]:[o.field],name:o.name,type:"vector"}))];r.length>0&&(t[n.name]=r)}return t},tr=e=>{const t=[];for(const n of e.tables)!n.ttl||n.shardMode==="global"||t.push({...n.ttl.after===void 0?{}:{after:n.ttl.after},field:n.ttl.field,...n.softDelete?{softDeleteField:n.softDelete.field}:{},table:n.name});return t},nr=e=>{if(e.kind!=="union"||e.members===void 0||e.members.length===0)return;const t=[];for(const n of e.members){if(n.kind!=="literal"||n.literalValue===void 0)return;try{const r=JSON.parse(n.literalValue);if(typeof r!="string")return;t.push(r)}catch{return}}return t},rr=(e,t)=>{const n=re(t),r={name:e,optional:ut(t),type:n.kind};n.kind==="id"&&n.tableName!==void 0&&(r.ref=n.tableName),n.kind==="storage"&&(r.isStorage=!0,n.bucket!==void 0&&(r.bucket=n.bucket));const o=nr(n);return o!==void 0&&(r.enumValues=o),n.column?.notNull===!1&&(r.nullable=!0),r},or=e=>{const t={};for(const n of e.tables){const r=[{name:"_id",optional:!1,pk:!0,type:"id"},{name:"_creationTime",optional:!1,type:"number"}];for(const[o,s]of Object.entries(n.shape))r.push(rr(o,s));t[n.name]=r}return t},ar=e=>e?{importFragment:"serveRelationFanout, ",override:`
854
+ `,i)},nr=e=>{const t={};for(const n of e.tables){const r={};for(const[o,s]of Object.entries(n.shape)){const i=re(s);i.kind==="id"&&i.tableName!==void 0&&(r[o]=i.tableName)}Object.keys(r).length>0&&(t[n.name]=r)}return t},rr=e=>{const t={};for(const n of e.tables){const r=[];for(const[o,s]of Object.entries(n.shape))re(s).kind==="storage"&&r.push(o);r.length>0&&(t[n.name]=r)}return t},or=e=>{const t={};for(const n of e.tables){const r=[...n.indexes.map(o=>({fields:[...o.fields],name:o.name,type:"index",...o.unique===!0?{unique:!0}:{}})),...n.searchIndexes.map(o=>({fields:[o.field,...o.filterFields??[]],name:o.name,type:"search"})),...(n.geoIndexes??[]).map(o=>({fields:[o.field],name:o.name,type:"geo"})),...n.rankIndexes.map(o=>({fields:o.sortBy.map(s=>s.field),name:o.name,type:"rank"})),...n.vectorIndexes.map(o=>({fields:o.field===void 0?[]:[o.field],name:o.name,type:"vector"}))];r.length>0&&(t[n.name]=r)}return t},ar=e=>{const t=[];for(const n of e.tables)!n.ttl||n.shardMode==="global"||t.push({...n.ttl.after===void 0?{}:{after:n.ttl.after},field:n.ttl.field,...n.softDelete?{softDeleteField:n.softDelete.field}:{},table:n.name});return t},sr=e=>{if(e.kind!=="union"||e.members===void 0||e.members.length===0)return;const t=[];for(const n of e.members){if(n.kind!=="literal"||n.literalValue===void 0)return;try{const r=JSON.parse(n.literalValue);if(typeof r!="string")return;t.push(r)}catch{return}}return t},ir=(e,t)=>{const n=re(t),r={name:e,optional:mt(t),type:n.kind};n.kind==="id"&&n.tableName!==void 0&&(r.ref=n.tableName),n.kind==="storage"&&(r.isStorage=!0,n.bucket!==void 0&&(r.bucket=n.bucket));const o=sr(n);return o!==void 0&&(r.enumValues=o),n.column?.notNull===!1&&(r.nullable=!0),r},lr=e=>{const t={};for(const n of e.tables){const r=[{name:"_id",optional:!1,pk:!0,type:"id"},{name:"_creationTime",optional:!1,type:"number"},...n.commitOrdered===!0?[{name:"_commitSeq",optional:!1,type:"number"}]:[]];for(const[o,s]of Object.entries(n.shape))r.push(ir(o,s));t[n.name]=r}return t},cr=e=>e?{importFragment:"serveRelationFanout, ",override:`
840
855
  protected override async runRelationFanoutRead(functionPath: string, args: Record<string, unknown>): Promise<unknown> {
841
856
  this.ensureMigrated();
842
857
 
@@ -844,7 +859,7 @@ export const LUNORA_MIGRATIONS: Record<string, RegisteredDataMigration> = {${u}}
844
859
 
845
860
  return serveRelationFanout(schema as unknown as SchemaLike, db, functionPath, args);
846
861
  }
847
- `}:{importFragment:"",override:""},sr=e=>{if(!e)return{build:"",configField:"",contextField:"",stub:""};const t='throw new Error("ctx.ai: no AI binding found. Add an \\`ai\\` binding (env.AI) to wrangler.jsonc, or pass \\`ai\\` to createShardDO().");';return{build:`
862
+ `}:{importFragment:"",override:""},dr=e=>{if(!e)return{build:"",configField:"",contextField:"",stub:""};const t='throw new Error("ctx.ai: no AI binding found. Add an \\`ai\\` binding (env.AI) to wrangler.jsonc, or pass \\`ai\\` to createShardDO().");';return{build:`
848
863
  const aiBinding = config.ai?.(env) ?? (env as Record<string, unknown>).AI;
849
864
  // Correlate AI-Gateway-routed calls with the Lunora trace: thread the
850
865
  // function path + trace id into createAi, which folds them into the
@@ -875,19 +890,19 @@ const aiStub: LunoraAi = {
875
890
  ${t}
876
891
  }) as unknown as LunoraAi["workersai"],
877
892
  };
878
- `}},T=(e,t,n,{cast:r="",sync:o=[]}={})=>{const s=n.map(i=>` ${i}: ${o.includes(i)?"":"async "}() => {
893
+ `}},O=(e,t,n,{cast:r="",sync:o=[]}={})=>{const s=n.map(i=>` ${i}: ${o.includes(i)?"":"async "}() => {
879
894
  ${t}
880
895
  },`).join(`
881
896
  `);return`
882
897
  const ${e} = {
883
898
  ${s}
884
899
  }${r};
885
- `},D={build:"",configField:"",contextField:"",importLines:[],stub:""},ir=e=>e?{build:`
900
+ `},F={build:"",configField:"",contextField:"",importLines:[],stub:""},ur=e=>e?{build:`
886
901
  const kvBinding = config.kv?.(env) ?? (env as Record<string, unknown>).KV;
887
902
  const kv: Kv = kvBinding ? createKv({ namespace: kvBinding as KVNamespaceLike }) : kvStub;
888
903
  `,configField:`
889
904
  kv?: (env: Record<string, unknown>) => KVNamespaceLike;`,contextField:`
890
- kv,`,importLines:['import type { Kv, KVNamespaceLike } from "@lunora/bindings/kv";','import { createKv } from "@lunora/bindings/kv";'],stub:T("kvStub: Kv",'throw new Error("ctx.kv: no KV binding found. Add a \\`kv_namespaces\\` binding (env.KV) to wrangler.jsonc, or pass \\`kv\\` to createShardDO().");',["delete","get","getRaw","getWithMetadata","list","put"])}:D,lr=(e,t)=>e?{build:`
905
+ kv,`,importLines:['import type { Kv, KVNamespaceLike } from "@lunora/bindings/kv";','import { createKv } from "@lunora/bindings/kv";'],stub:O("kvStub: Kv",'throw new Error("ctx.kv: no KV binding found. Add a \\`kv_namespaces\\` binding (env.KV) to wrangler.jsonc, or pass \\`kv\\` to createShardDO().");',["delete","get","getRaw","getWithMetadata","list","put"])}:F,pr=(e,t)=>e?{build:`
891
906
  const flags: import("${t}").LunoraFlags = createFlags({
892
907
  hooks: flagsConfig.hooks,
893
908
  logger: flagsConfig.logger,
@@ -896,17 +911,17 @@ ${s}
896
911
  });
897
912
  `,configField:`
898
913
  flags?: (env: Record<string, unknown>) => import("${t}").Provider;`,contextField:`
899
- flags,`,importLines:[`import { createFlags } from "${t}";`,'import flagsConfig from "../flags.js";'],stub:""}:D,cr=e=>e?{build:`
914
+ flags,`,importLines:[`import { createFlags } from "${t}";`,'import flagsConfig from "../flags.js";'],stub:""}:F,mr=e=>e?{build:`
900
915
  const { notify, push } = createNotify(notifyConfig, env, { log, metrics });
901
916
  `,configField:"",contextField:`
902
917
  notify,
903
- push,`,importLines:['import { createNotify } from "@lunora/notify";','import notifyConfig from "../notify.js";'],stub:""}:D,dr=e=>e?{build:`
918
+ push,`,importLines:['import { createNotify } from "@lunora/notify";','import notifyConfig from "../notify.js";'],stub:""}:F,hr=e=>e?{build:`
904
919
  const envConfig = lunoraEnvContract.${e.exportName}(env);
905
920
  `,configField:"",contextField:`
906
- env: envConfig,`,importLines:['import * as lunoraEnvContract from "../env.js";'],stub:""}:D,ur=e=>e?{build:`
921
+ env: envConfig,`,importLines:['import * as lunoraEnvContract from "../env.js";'],stub:""}:F,gr=e=>e?{build:`
907
922
  const access = accessFacade(identity, userId);
908
923
  `,configField:"",contextField:`
909
- access,`,importLines:['import { accessFacade } from "@lunora/cloudflare-access/context";'],stub:""}:D,pr=(e,t,n)=>{if(!t)return{constant:"",evaluateOverride:"",subscriptionOverride:""};const r=a=>`
924
+ access,`,importLines:['import { accessFacade } from "@lunora/cloudflare-access/context";'],stub:""}:F,fr=(e,t,n)=>{if(!t)return{constant:"",evaluateOverride:"",subscriptionOverride:""};const r=a=>`
910
925
  const env = (this.env ?? {}) as Record<string, unknown>;
911
926
  const flags: import("${n}").LunoraFlags = createFlags({
912
927
  hooks: flagsConfig.hooks,
@@ -970,25 +985,25 @@ const LUNORA_FLAG_KEYS: ReadonlyArray<{ key: string; type: "boolean" | "number"
970
985
 
971
986
  return flags.boolean(key, typeof args.default === "boolean" ? args.default : false, context);
972
987
  }
973
- `;return{constant:o,evaluateOverride:s,subscriptionOverride:i}},mr=e=>e?{build:`
988
+ `;return{constant:o,evaluateOverride:s,subscriptionOverride:i}},yr=e=>e?{build:`
974
989
  const analyticsBinding = config.analytics?.(env) ?? (env as Record<string, unknown>).ANALYTICS;
975
990
  const analytics: AnalyticsClient = analyticsBinding ? createAnalytics(analyticsBinding as AnalyticsEngineDatasetLike) : analyticsStub;
976
991
  `,configField:`
977
992
  analytics?: (env: Record<string, unknown>) => AnalyticsEngineDatasetLike;`,contextField:`
978
- analytics,`,importLines:['import type { AnalyticsClient, AnalyticsEngineDatasetLike } from "@lunora/bindings/analytics";','import { createAnalytics } from "@lunora/bindings/analytics";'],stub:T("analyticsStub: AnalyticsClient",'throw new Error("ctx.analytics: no Analytics Engine binding found. Add an \\`analytics_engine_datasets\\` binding (env.ANALYTICS) to wrangler.jsonc, or pass \\`analytics\\` to createShardDO().");',["track","writeDataPoint"],{sync:["track","writeDataPoint"]})}:D,hr=e=>e?{build:`
993
+ analytics,`,importLines:['import type { AnalyticsClient, AnalyticsEngineDatasetLike } from "@lunora/bindings/analytics";','import { createAnalytics } from "@lunora/bindings/analytics";'],stub:O("analyticsStub: AnalyticsClient",'throw new Error("ctx.analytics: no Analytics Engine binding found. Add an \\`analytics_engine_datasets\\` binding (env.ANALYTICS) to wrangler.jsonc, or pass \\`analytics\\` to createShardDO().");',["track","writeDataPoint"],{sync:["track","writeDataPoint"]})}:F,br=e=>e?{build:`
979
994
  const imagesBinding = config.images?.(env) ?? (env as Record<string, unknown>).IMAGES;
980
995
  const images: Images = imagesBinding ? createImages({ binding: imagesBinding as ImagesBindingLike }) : imagesStub;
981
996
  `,configField:`
982
997
  images?: (env: Record<string, unknown>) => ImagesBindingLike;`,contextField:`
983
- images,`,importLines:['import type { Images, ImagesBindingLike } from "@lunora/bindings/images";','import { createImages } from "@lunora/bindings/images";'],stub:T("imagesStub: Images",'throw new Error("ctx.images: no Images binding found. Add an \\`images\\` binding (env.IMAGES) to wrangler.jsonc, or pass \\`images\\` to createShardDO().");',["info","transform"])}:D,gr=e=>e?{build:`
998
+ images,`,importLines:['import type { Images, ImagesBindingLike } from "@lunora/bindings/images";','import { createImages } from "@lunora/bindings/images";'],stub:O("imagesStub: Images",'throw new Error("ctx.images: no Images binding found. Add an \\`images\\` binding (env.IMAGES) to wrangler.jsonc, or pass \\`images\\` to createShardDO().");',["info","transform"])}:F,kr=e=>e?{build:`
984
999
  const sql: SqlClient = config.sql ? config.sql(env) : sqlStub;
985
1000
  `,configField:`
986
1001
  sql?: (env: Record<string, unknown>) => SqlClient;`,contextField:`
987
- sql,`,importLines:['import type { SqlClient } from "@lunora/hyperdrive";'],stub:T("sqlStub: SqlClient",'throw new Error("ctx.sql: provide a \\`sql\\` config thunk that builds a SqlClient from your driver, e.g. \\`sql: (env) => fromPostgresJs(postgres(env.HYPERDRIVE.connectionString))\\`.");',["query"])}:D,fr=e=>e?{build:`
1002
+ sql,`,importLines:['import type { SqlClient } from "@lunora/hyperdrive";'],stub:O("sqlStub: SqlClient",'throw new Error("ctx.sql: provide a \\`sql\\` config thunk that builds a SqlClient from your driver, e.g. \\`sql: (env) => fromPostgresJs(postgres(env.HYPERDRIVE.connectionString))\\`.");',["query"])}:F,wr=e=>e?{build:`
988
1003
  const browser: Browser = config.browser ? config.browser(env) : browserStub;
989
1004
  `,configField:`
990
1005
  browser?: (env: Record<string, unknown>) => Browser;`,contextField:`
991
- browser,`,importLines:['import type { Browser } from "@lunora/browser";'],stub:T("browserStub: Browser","throw new Error(\"ctx.browser: provide a \\`browser\\` config thunk, e.g. \\`browser: (env) => createBrowser({ binding: env.BROWSER, launch })\\` with \\`import { launch } from '@cloudflare/playwright'\\`. Session reuse (connect/sessions) additionally needs those two exports passed the same way.\");",["connect","content","launch","pdf","scrape","screenshot","sessions"])}:D,br=e=>e?{build:`
1006
+ browser,`,importLines:['import type { Browser } from "@lunora/browser";'],stub:O("browserStub: Browser","throw new Error(\"ctx.browser: provide a \\`browser\\` config thunk, e.g. \\`browser: (env) => createBrowser({ binding: env.BROWSER, launch })\\` with \\`import { launch } from '@cloudflare/playwright'\\`. Session reuse (connect/sessions) additionally needs those two exports passed the same way.\");",["connect","content","launch","pdf","scrape","screenshot","sessions"])}:F,xr=e=>e?{build:`
992
1007
  const r2sqlEnv = env as Record<string, unknown>;
993
1008
  const r2sqlAccountId = (r2sqlEnv.R2_SQL_ACCOUNT_ID ?? r2sqlEnv.CLOUDFLARE_ACCOUNT_ID) as string | undefined;
994
1009
  const r2sqlToken = r2sqlEnv.R2_SQL_TOKEN as string | undefined;
@@ -999,18 +1014,18 @@ const LUNORA_FLAG_KEYS: ReadonlyArray<{ key: string; type: "boolean" | "number"
999
1014
  ? createR2Sql({ accountId: r2sqlAccountId, apiToken: r2sqlToken, bucket: r2sqlBucket })
1000
1015
  : r2sqlStub;
1001
1016
  `,configField:`
1002
- r2sql?: (env: Record<string, unknown>) => R2SqlClient;`,contextField:"",importLines:['import type { R2SqlClient } from "@lunora/bindings/r2sql";','import { createR2Sql } from "@lunora/bindings/r2sql";'],stub:T("r2sqlStub: R2SqlClient",'throw new Error("ctx.r2sql: no R2 SQL credentials found. Set \\`R2_SQL_TOKEN\\`, \\`R2_SQL_ACCOUNT_ID\\` (or \\`CLOUDFLARE_ACCOUNT_ID\\`), and \\`R2_SQL_BUCKET\\` in your env/.dev.vars, or pass an \\`r2sql\\` config thunk to createShardDO().");',["describe","explain","from","query","showDatabases","showTables"],{sync:["from"]})}:D,yr=e=>e?{build:`
1017
+ r2sql?: (env: Record<string, unknown>) => R2SqlClient;`,contextField:"",importLines:['import type { R2SqlClient } from "@lunora/bindings/r2sql";','import { createR2Sql } from "@lunora/bindings/r2sql";'],stub:O("r2sqlStub: R2SqlClient",'throw new Error("ctx.r2sql: no R2 SQL credentials found. Set \\`R2_SQL_TOKEN\\`, \\`R2_SQL_ACCOUNT_ID\\` (or \\`CLOUDFLARE_ACCOUNT_ID\\`), and \\`R2_SQL_BUCKET\\` in your env/.dev.vars, or pass an \\`r2sql\\` config thunk to createShardDO().");',["describe","explain","from","query","showDatabases","showTables"],{sync:["from"]})}:F,vr=e=>e?{build:`
1003
1018
  const pipelinesBinding = config.pipelines?.(env) ?? (env as Record<string, unknown>).PIPELINES;
1004
1019
  const pipelines: PipelineClient = pipelinesBinding ? createPipelines({ binding: pipelinesBinding as PipelineBindingLike }) : pipelinesStub;
1005
1020
  `,configField:`
1006
- pipelines?: (env: Record<string, unknown>) => PipelineBindingLike;`,contextField:"",importLines:['import type { PipelineBindingLike, PipelineClient } from "@lunora/bindings/pipelines";','import { createPipelines } from "@lunora/bindings/pipelines";'],stub:T("pipelinesStub: PipelineClient",'throw new Error("ctx.pipelines: no Pipelines binding found. Add a \\`pipelines\\` binding (env.PIPELINES) to wrangler.jsonc, or pass \\`pipelines\\` to createShardDO().");',["send"])}:D,Gr=(e,t)=>{if(e.length===0)return"";const n=t?`, ${JSON.stringify(t)}`:"",r=e.map(s=>(g(s.exportName,`container export "${s.exportName}"`),g(s.className,`container class "${s.className}"`),`/** Container DO for the \`${s.exportName}\` definition (binding \`${s.bindingName}\`). */
1021
+ pipelines?: (env: Record<string, unknown>) => PipelineBindingLike;`,contextField:"",importLines:['import type { PipelineBindingLike, PipelineClient } from "@lunora/bindings/pipelines";','import { createPipelines } from "@lunora/bindings/pipelines";'],stub:O("pipelinesStub: PipelineClient",'throw new Error("ctx.pipelines: no Pipelines binding found. Add a \\`pipelines\\` binding (env.PIPELINES) to wrangler.jsonc, or pass \\`pipelines\\` to createShardDO().");',["send"])}:F,Zr=(e,t)=>{if(e.length===0)return"";const n=t?`, ${JSON.stringify(t)}`:"",r=e.map(s=>(g(s.exportName,`container export "${s.exportName}"`),g(s.className,`container class "${s.className}"`),`/** Container DO for the \`${s.exportName}\` definition (binding \`${s.bindingName}\`). */
1007
1022
  export class ${s.className} extends LunoraContainer {
1008
1023
  public constructor(ctx: ConstructorParameters<typeof LunoraContainer>[0], env: Record<string, unknown>) {
1009
1024
  super(ctx, env, ${s.exportName}, "${s.exportName}"${n});
1010
1025
  }
1011
1026
  }
1012
1027
  `)).join(`
1013
- `),o=e.map(s=>s.exportName).join(", ");return`${R}/**
1028
+ `),o=e.map(s=>s.exportName).join(", ");return`${S}/**
1014
1029
  * Container-enabled Durable Object classes for the containers declared in
1015
1030
  * \`lunora/containers.ts\`. Re-export them from your worker entry — wrangler
1016
1031
  * requires each \`containers[].class_name\` to be exported by the worker:
@@ -1028,7 +1043,7 @@ import { ${o} } from "../containers.js";
1028
1043
 
1029
1044
  export { ContainerProxy } from "@lunora/container/do";
1030
1045
 
1031
- ${r}`},kr=(e,t)=>{if(e.length===0)return{build:"",contextField:"",importLines:[],specs:""};for(const r of e)g(r.exportName,`container export "${r.exportName}"`),g(r.bindingName,`container binding "${r.bindingName}"`);const n=e.map(r=>{const o=r.maxInstances===void 0?"":`, maxInstances: ${String(r.maxInstances)}`;return` { binding: "${r.bindingName}", exportName: "${r.exportName}"${o} },`}).join(`
1046
+ ${r}`},$r=(e,t)=>{if(e.length===0)return{build:"",contextField:"",importLines:[],specs:""};for(const r of e)g(r.exportName,`container export "${r.exportName}"`),g(r.bindingName,`container binding "${r.bindingName}"`);const n=e.map(r=>{const o=r.maxInstances===void 0?"":`, maxInstances: ${String(r.maxInstances)}`;return` { binding: "${r.bindingName}", exportName: "${r.exportName}"${o} },`}).join(`
1032
1047
  `);return{build:`
1033
1048
  const containers = createContainerContext(env, LUNORA_CONTAINERS, ${t?JSON.stringify(t):"undefined"}, this.getCurrentTraceparent());
1034
1049
  `,contextField:`
@@ -1037,14 +1052,14 @@ ${r}`},kr=(e,t)=>{if(e.length===0)return{build:"",contextField:"",importLines:[]
1037
1052
  const LUNORA_CONTAINERS: ReadonlyArray<ContainerBindingSpec> = [
1038
1053
  ${n}
1039
1054
  ];
1040
- `}},zr=e=>{if(e.length===0)return"";const t=e.map(r=>(g(r.exportName,`workflow export "${r.exportName}"`),g(r.className,`workflow class "${r.className}"`),`/** WorkflowEntrypoint for the \`${r.exportName}\` definition (binding \`${r.bindingName}\`). */
1055
+ `}},eo=e=>{if(e.length===0)return"";const t=e.map(r=>(g(r.exportName,`workflow export "${r.exportName}"`),g(r.className,`workflow class "${r.className}"`),`/** WorkflowEntrypoint for the \`${r.exportName}\` definition (binding \`${r.bindingName}\`). */
1041
1056
  export class ${r.className} extends LunoraWorkflow<WorkflowParamsOf<typeof ${r.exportName}>, WorkflowOutputOf<typeof ${r.exportName}>> {
1042
1057
  public constructor(ctx: ConstructorParameters<typeof LunoraWorkflow>[0], env: Record<string, unknown>) {
1043
1058
  super(ctx, env, ${r.exportName}, "${r.exportName}");
1044
1059
  }
1045
1060
  }
1046
1061
  `)).join(`
1047
- `),n=e.map(r=>r.exportName).join(", ");return`${R}/**
1062
+ `),n=e.map(r=>r.exportName).join(", ");return`${S}/**
1048
1063
  * WorkflowEntrypoint classes for the workflows declared in
1049
1064
  * \`lunora/workflows.ts\`. Re-export them from your worker entry — wrangler
1050
1065
  * requires each \`workflows[].class_name\` to be exported by the worker:
@@ -1065,7 +1080,7 @@ type WorkflowParamsOf<Definition> = Definition extends { __params?: infer Params
1065
1080
  /** Output type carried by a \`defineWorkflow\` definition (its phantom \`__output\`), so each entrypoint keeps the authored return type. */
1066
1081
  type WorkflowOutputOf<Definition> = Definition extends { __output?: infer Output } ? Output : unknown;
1067
1082
 
1068
- ${t}`},Yr=e=>{if(e.length===0)return"";const n=e.filter(a=>a.voice).length>0,r=e.map(a=>{g(a.exportName,`agent export "${a.exportName}"`),g(a.className,`agent class "${a.className}"`);const c=`/** WorkflowEntrypoint for the \`${a.exportName}\` agent (binding \`${a.bindingName}\`). */
1083
+ ${t}`},to=e=>{if(e.length===0)return"";const n=e.filter(a=>a.voice).length>0,r=e.map(a=>{g(a.exportName,`agent export "${a.exportName}"`),g(a.className,`agent class "${a.className}"`);const c=`/** WorkflowEntrypoint for the \`${a.exportName}\` agent (binding \`${a.bindingName}\`). */
1069
1084
  export class ${a.className} extends LunoraWorkflow<AgentRunInput, AgentRunResult> {
1070
1085
  public constructor(ctx: ConstructorParameters<typeof LunoraWorkflow>[0], env: Record<string, unknown>) {
1071
1086
  super(ctx, env, compileAgentWorkflow(${a.exportName}, "${a.exportName}"), "${a.exportName}");
@@ -1079,7 +1094,7 @@ export class ${d} extends VoiceSessionDO {
1079
1094
  }
1080
1095
  }
1081
1096
  `;return`${c}${h}`}).join(`
1082
- `),o=e.map(a=>a.exportName).join(", ");return`${R}/**
1097
+ `),o=e.map(a=>a.exportName).join(", ");return`${S}/**
1083
1098
  * WorkflowEntrypoint classes for the agents declared in \`lunora/agents.ts\`.
1084
1099
  * Each \`defineAgent\` compiles a replay-safe tool-loop onto a Cloudflare
1085
1100
  * Workflow. Re-export them from your worker entry — wrangler requires each
@@ -1093,8 +1108,8 @@ import type { AgentRunInput, AgentRunResult } from "@lunora/agent";
1093
1108
 
1094
1109
  import { ${o} } from "../agents.js";
1095
1110
 
1096
- ${r}`},Xr=e=>{const t=e.filter(o=>o.mode==="push");if(t.length===0)return"";for(const o of t)g(o.exportName,`queue export "${o.exportName}"`);const n=t.map(o=>o.exportName).join(", "),r=t.map(o=>` ${JSON.stringify(o.name)}: { definition: ${o.exportName}, exportName: ${JSON.stringify(o.exportName)} },`).join(`
1097
- `);return`${R}/**
1111
+ ${r}`},no=e=>{const t=e.filter(o=>o.mode==="push");if(t.length===0)return"";for(const o of t)g(o.exportName,`queue export "${o.exportName}"`);const n=t.map(o=>o.exportName).join(", "),r=t.map(o=>` ${JSON.stringify(o.name)}: { definition: ${o.exportName}, exportName: ${JSON.stringify(o.exportName)} },`).join(`
1112
+ `);return`${S}/**
1098
1113
  * Push-consumer registry for the queues declared in \`lunora/queues.ts\`. The
1099
1114
  * composed worker's \`queue(batch, env, ctx)\` entry routes each delivered batch
1100
1115
  * by \`batch.queue\` to the matching \`defineQueue\` handler. Wired automatically
@@ -1108,7 +1123,7 @@ import { ${n} } from "../queues.js";
1108
1123
  export const LUNORA_QUEUE_REGISTRY: QueueRegistry = {
1109
1124
  ${r}
1110
1125
  };
1111
- `},xr=e=>{if(e.length===0)return{build:"",contextField:"",importLines:[],specs:""};for(const n of e)g(n.exportName,`workflow export "${n.exportName}"`),g(n.bindingName,`workflow binding "${n.bindingName}"`);const t=e.map(n=>` { binding: "${n.bindingName}", exportName: "${n.exportName}" },`).join(`
1126
+ `},Rr=e=>{if(e.length===0)return{build:"",contextField:"",importLines:[],specs:""};for(const n of e)g(n.exportName,`workflow export "${n.exportName}"`),g(n.bindingName,`workflow binding "${n.bindingName}"`);const t=e.map(n=>` { binding: "${n.bindingName}", exportName: "${n.exportName}" },`).join(`
1112
1127
  `);return{build:`
1113
1128
  const workflows = createWorkflowContext(env, LUNORA_WORKFLOWS);
1114
1129
  `,contextField:`
@@ -1117,7 +1132,7 @@ ${r}
1117
1132
  const LUNORA_WORKFLOWS: ReadonlyArray<WorkflowBindingSpec> = [
1118
1133
  ${t}
1119
1134
  ];
1120
- `}},wr=e=>{if(e.length===0)return{build:"",contextField:"",importLines:[],specs:""};for(const n of e)g(n.exportName,`queue export "${n.exportName}"`),g(n.bindingName,`queue binding "${n.bindingName}"`);const t=e.map(n=>` { binding: "${n.bindingName}", exportName: "${n.exportName}", name: ${JSON.stringify(n.name)} },`).join(`
1135
+ `}},Sr=e=>{if(e.length===0)return{build:"",contextField:"",importLines:[],specs:""};for(const n of e)g(n.exportName,`queue export "${n.exportName}"`),g(n.bindingName,`queue binding "${n.bindingName}"`);const t=e.map(n=>` { binding: "${n.bindingName}", exportName: "${n.exportName}", name: ${JSON.stringify(n.name)} },`).join(`
1121
1136
  `);return{build:`
1122
1137
  const queues = createQueueContext(env, LUNORA_QUEUES);
1123
1138
  `,contextField:`
@@ -1126,7 +1141,7 @@ ${t}
1126
1141
  const LUNORA_QUEUES: ReadonlyArray<QueueBindingSpec> = [
1127
1142
  ${t}
1128
1143
  ];
1129
- `}},vr=e=>{if(e.length===0)return{build:"",contextField:"",importLines:[],specs:""};for(const n of e)g(n.exportName,`agent export "${n.exportName}"`),g(n.bindingName,`agent binding "${n.bindingName}"`);const t=e.map(n=>` { binding: "${n.bindingName}", exportName: "${n.exportName}"${n.publicRun===!0?", publicRun: true":""} },`).join(`
1144
+ `}},Nr=e=>{if(e.length===0)return{build:"",contextField:"",importLines:[],specs:""};for(const n of e)g(n.exportName,`agent export "${n.exportName}"`),g(n.bindingName,`agent binding "${n.bindingName}"`);const t=e.map(n=>` { binding: "${n.bindingName}", exportName: "${n.exportName}"${n.publicRun===!0?", publicRun: true":""} },`).join(`
1130
1145
  `);return{build:`
1131
1146
  const agents = createAgentContext(env, LUNORA_AGENTS);
1132
1147
  `,contextField:`
@@ -1135,28 +1150,28 @@ ${t}
1135
1150
  const LUNORA_AGENTS: ReadonlyArray<AgentBindingSpec> = [
1136
1151
  ${t}
1137
1152
  ];
1138
- `}},ft=(e,t,n,r,o)=>({constant:`
1153
+ `}},bt=(e,t,n,r,o)=>({constant:`
1139
1154
  ${o}
1140
1155
  const ${e}: ${t} = ${JSON.stringify(r,void 0,4)};
1141
1156
  `,override:`
1142
1157
  protected override ${n}(): ${t} {
1143
1158
  return ${e};
1144
1159
  }
1145
- `}),$r=e=>{if(e.length===0)return{constant:"",override:""};const t={workflows:e.map(n=>({binding:n.bindingName,className:n.className,exportName:n.exportName,name:n.name}))};return ft("LUNORA_WORKFLOWS_INFO","WorkflowsResult","workflowsMetadata",t,"/** Read-only declared-workflow metadata (discovered from `lunora/workflows.ts`) served via `__lunora_admin__:listWorkflows` for the studio's workflows view. */")},Rr=e=>{if(e.length===0)return{constant:"",override:""};const t={queues:e.map(n=>({binding:n.bindingName,...n.tuning.deadLetterQueue===void 0?{}:{deadLetterQueue:n.tuning.deadLetterQueue},exportName:n.exportName,mode:n.mode,name:n.name}))};return ft("LUNORA_QUEUES_INFO","QueuesResult","queuesMetadata",t,"/** Read-only declared-queue metadata (discovered from `lunora/queues.ts`) served via `__lunora_admin__:listQueues` for the studio's queues view. */")},Sr=e=>e?{imports:['import type { LunoraDatabaseLike as LunoraPaymentDbLike, LunoraPayment, PaymentsFromContextOptions } from "@lunora/payment";','import { paymentsFromContext } from "@lunora/payment";'],build:`
1160
+ `}),Tr=e=>{if(e.length===0)return{constant:"",override:""};const t={workflows:e.map(n=>({binding:n.bindingName,className:n.className,exportName:n.exportName,name:n.name}))};return bt("LUNORA_WORKFLOWS_INFO","WorkflowsResult","workflowsMetadata",t,"/** Read-only declared-workflow metadata (discovered from `lunora/workflows.ts`) served via `__lunora_admin__:listWorkflows` for the studio's workflows view. */")},Ar=e=>{if(e.length===0)return{constant:"",override:""};const t={queues:e.map(n=>({binding:n.bindingName,...n.tuning.deadLetterQueue===void 0?{}:{deadLetterQueue:n.tuning.deadLetterQueue},exportName:n.exportName,mode:n.mode,name:n.name}))};return bt("LUNORA_QUEUES_INFO","QueuesResult","queuesMetadata",t,"/** Read-only declared-queue metadata (discovered from `lunora/queues.ts`) served via `__lunora_admin__:listQueues` for the studio's queues view. */")},Or=e=>e?{imports:['import type { LunoraDatabaseLike as LunoraPaymentDbLike, LunoraPayment, PaymentsFromContextOptions } from "@lunora/payment";','import { paymentsFromContext } from "@lunora/payment";'],build:`
1146
1161
  const payments: LunoraPayment = config.payment
1147
1162
  ? paymentsFromContext({ auth: { userId: userId ?? null }, db: db as unknown as LunoraPaymentDbLike }, config.payment(env))
1148
1163
  : paymentStub;
1149
1164
  `,configField:`
1150
1165
  payment?: (env: Record<string, unknown>) => PaymentsFromContextOptions;`,contextField:`
1151
- payments,`,stub:T("paymentStub: LunoraPayment",'throw new Error("ctx.payments: no payment configured. Pass \\`payment\\` to createShardDO().");',["attach","cancelSubscription","check","createCheckout","createPortalSession","handleWebhook","listBalances","listSubscriptions","track"],{cast:" as unknown as LunoraPayment",sync:["attach","cancelSubscription","check","createCheckout","createPortalSession","handleWebhook","listBalances","listSubscriptions","track"]})}:{build:"",configField:"",contextField:"",imports:[],stub:""},Nr=e=>e?{imports:['import type { X402Pay, X402PayConfig } from "@lunora/x402/pay";','import { lazyX402Pay } from "@lunora/x402/pay";'],build:`
1166
+ payments,`,stub:O("paymentStub: LunoraPayment",'throw new Error("ctx.payments: no payment configured. Pass \\`payment\\` to createShardDO().");',["attach","cancelSubscription","check","createCheckout","createPortalSession","handleWebhook","listBalances","listSubscriptions","track"],{cast:" as unknown as LunoraPayment",sync:["attach","cancelSubscription","check","createCheckout","createPortalSession","handleWebhook","listBalances","listSubscriptions","track"]})}:{build:"",configField:"",contextField:"",imports:[],stub:""},Ir=e=>e?{imports:['import type { X402Pay, X402PayConfig } from "@lunora/x402/pay";','import { lazyX402Pay } from "@lunora/x402/pay";'],build:`
1152
1167
  const x402: X402Pay = config.x402
1153
1168
  ? lazyX402Pay(config.x402(env), { getSecret: (name: string) => secrets.get(name) })
1154
1169
  : x402Stub;
1155
1170
  `,configField:`
1156
- x402?: (env: Record<string, unknown>) => X402PayConfig;`,stub:T("x402Stub: X402Pay",'throw new Error("ctx.x402: no pay rail configured. Pass \\`x402\\` to createShardDO().");',["fetch"],{cast:" as unknown as X402Pay",sync:["fetch"]})}:{build:"",configField:"",imports:[],stub:""},Tr=(e,t,n,r)=>["AdvisorProcedure","AdvisoryFinding","DatabaseWriterLike","DataMigrationLike","ExportRow",...r?["FlagsResult"]:[],"ImportShardResult","KeyRange","MaskPoliciesResult","MigrationRunResult",...n?["QueuesResult"]:[],"RunShardApplyCdcArgs","RunShardExportArgs","RunShardImportArgs","RunShardMigrationArgs","RlsPoliciesResult","RunShardRankBeforeArgs","RunShardRankPageArgs","RunShardWriteArgs","RunShardWriteResult","SchedulerLike","TransactionHeadroomTracker","SchemaLike","ShardDOState","ShardRankPageResult","SqlExec","StorageRulesResult","StudioFeaturesResult","SystemReaderStorageLike","TelemetrySink",...t?["WorkflowsResult"]:[],...e?["WriteHook"]:[]],Zr=({advisories:e=[],advisorProcedures:t=[],agents:n=[],containers:r=[],env:o,flagKeys:s=[],hasAccessFacade:i=!1,hasAi:a=!1,hasAnalytics:c=!1,hasBrowser:d=!1,hasFlags:p=!1,hasHyperdrive:h=!1,hasImages:b=!1,hasKv:u=!1,hasNotify:l=!1,hasPayments:f=!1,hasPipelines:x=!1,hasR2sql:w=!1,hasX402:v=!1,maskMetadata:I,mutators:P=[],queues:C=[],rlsMetadata:$,schema:k,schemaSnapshot:M,shapes:oe=[],storageRules:B,studioFeatures:ae,useUmbrella:se=!1,workflows:W=[]})=>{const A=ne(se),X=P.length>0,O=oe.length>0,L=M===void 0?"":mn(M),j=M===void 0?"":`
1171
+ x402?: (env: Record<string, unknown>) => X402PayConfig;`,stub:O("x402Stub: X402Pay",'throw new Error("ctx.x402: no pay rail configured. Pass \\`x402\\` to createShardDO().");',["fetch"],{cast:" as unknown as X402Pay",sync:["fetch"]})}:{build:"",configField:"",imports:[],stub:""},Cr=(e,t,n,r)=>["AdvisorProcedure","AdvisoryFinding","DatabaseWriterLike","DataMigrationLike","ExportRow",...r?["FlagsResult"]:[],"ImportShardResult","KeyRange","MaskPoliciesResult","MigrationRunResult",...n?["QueuesResult"]:[],"RunShardApplyCdcArgs","RunShardExportArgs","RunShardImportArgs","RunShardMigrationArgs","RlsPoliciesResult","RunShardRankBeforeArgs","RunShardRankPageArgs","RunShardWriteArgs","RunShardWriteResult","SchedulerLike","TransactionHeadroomTracker","SchemaLike","ShardDOState","ShardRankPageResult","SqlExec","StorageRulesResult","StudioFeaturesResult","SystemReaderStorageLike","TelemetrySink",...t?["WorkflowsResult"]:[],...e?["WriteHook"]:[]],ro=({advisories:e=[],advisorProcedures:t=[],agents:n=[],containers:r=[],env:o,flagKeys:s=[],hasAccessFacade:i=!1,hasAi:a=!1,hasAnalytics:c=!1,hasBrowser:d=!1,hasFlags:p=!1,hasHyperdrive:h=!1,hasImages:y=!1,hasKv:u=!1,hasNotify:l=!1,hasPayments:f=!1,hasPipelines:w=!1,hasR2sql:$=!1,hasX402:x=!1,maskMetadata:I,mutators:T=[],queues:_=[],rlsMetadata:v,schema:k,schemaSnapshot:M,shapes:oe=[],storageRules:B,studioFeatures:ae,useUmbrella:se=!1,workflows:W=[]})=>{const C=ne(se),X=T.length>0,L=oe.length>0,R=M===void 0?"":fn(M),j=M===void 0?"":`
1157
1172
  /** Structural schema snapshot + its content hash, recorded in the shard's \`__lunora_schema_history\` ledger on cold start so the studio can show a schema-version timeline and diff any two versions. */
1158
- const LUNORA_SCHEMA_SNAPSHOT: { hash: string; json: string } = { hash: ${JSON.stringify(hn(M))}, json: ${JSON.stringify(L)} };
1159
- `,ie=M===void 0?"":", schemaSnapshot: LUNORA_SCHEMA_SNAPSHOT",{build:le,configField:Se,contextField:Ne,stub:Te}=sr(a),ce=ur(i),V=ir(u),F=lr(p,A.flags),H=pr(s,p,A.flags),Z=cr(l),de=dr(o),J=mr(c),U=hr(b),K=gr(h),Q=fr(d),q=br(w),ee=yr(x),{build:Ae,contextField:xe,importLines:we,specs:ue}=wr(C),{build:Oe,contextField:Ie,importLines:ve,specs:pe}=kr(r,k.jurisdiction),{build:Ce,contextField:Le,importLines:$e,specs:_e}=xr(W),{build:Ee,contextField:me,importLines:he,specs:De}=vr(n),{build:Fe,configField:Pe,contextField:ge,imports:fe,stub:He}=Sr(f),{build:m,configField:Me,imports:yt,stub:kt}=Nr(v),xt=e,wt=t,vt=$??{policies:[],roles:[]},$t=I??{columns:[]},Rt=B??{rules:[]},St=ae??{analytics:!1,auth:!1,containers:!1,flags:!1,kv:!1,mail:!1,notifications:!1,payments:!1,queues:!1,scheduler:!1,storage:!1,vectors:!1,workflows:!1},{constant:Nt,override:Tt}=$r(W),{constant:At,override:Ot}=Rr(C),G=k.vectorIndexes.length>0,Je=new Set(k.tables.filter(y=>typeof y.shardMode=="object"&&y.shardMode.kind==="shardBy").map(y=>y.name)),Re=k.vectorIndexes.some(y=>Je.has(y.table)),be=k.tables.some(y=>y.shardMode==="global"),Be=k.tables.some(y=>y.shardMode==="global"&&y.globalBackend==="hyperdrive"),Ge=k.tables.some(y=>y.shardMode==="global"&&y.globalBackend!=="hyperdrive"),z=k.tables.some(y=>y.externalSource!==void 0);if(Ge&&Be)throw new te("INTERNAL",'lunora codegen: mixing `.global()` (D1) and `.global({ backend: "hyperdrive" })` tables in one app is not supported yet — use a single global backend.');const je=k.tables.length>0,It=Xn(k),Ct=er(k),Lt=or(k),_t=Zn(k),ze=tr(k),Ye=Tr(G,W.length>0,C.length>0,p);O&&Ye.push("WhereInput");const Xe=ar(be),Et=O?`
1173
+ const LUNORA_SCHEMA_SNAPSHOT: { hash: string; json: string } = { hash: ${JSON.stringify(yn(M))}, json: ${JSON.stringify(R)} };
1174
+ `,ie=M===void 0?"":", schemaSnapshot: LUNORA_SCHEMA_SNAPSHOT",{build:le,configField:Se,contextField:Ne,stub:Te}=dr(a),ce=gr(i),V=ur(u),P=pr(p,C.flags),H=fr(s,p,C.flags),Z=mr(l),de=hr(o),J=yr(c),U=br(y),K=kr(h),Q=wr(d),q=xr($),ee=vr(w),{build:Ae,contextField:we,importLines:xe,specs:ue}=Sr(_),{build:Oe,contextField:Ie,importLines:ve,specs:pe}=$r(r,k.jurisdiction),{build:Ce,contextField:Le,importLines:$e,specs:_e}=Rr(W),{build:Ee,contextField:me,importLines:he,specs:De}=Nr(n),{build:Fe,configField:Pe,contextField:ge,imports:fe,stub:He}=Or(f),{build:m,configField:Me,imports:wt,stub:xt}=Ir(x),vt=e,$t=t,Rt=v??{policies:[],roles:[]},St=I??{columns:[]},Nt=B??{rules:[]},Tt=ae??{analytics:!1,auth:!1,containers:!1,flags:!1,kv:!1,mail:!1,notifications:!1,payments:!1,queues:!1,scheduler:!1,storage:!1,vectors:!1,workflows:!1},{constant:At,override:Ot}=Tr(W),{constant:It,override:Ct}=Ar(_),G=k.vectorIndexes.length>0,Je=new Set(k.tables.filter(b=>typeof b.shardMode=="object"&&b.shardMode.kind==="shardBy").map(b=>b.name)),Re=k.vectorIndexes.some(b=>Je.has(b.table)),ye=k.tables.some(b=>b.shardMode==="global"),Be=k.tables.some(b=>b.shardMode==="global"&&b.globalBackend==="hyperdrive"),Ge=k.tables.some(b=>b.shardMode==="global"&&b.globalBackend!=="hyperdrive"),z=k.tables.some(b=>b.externalSource!==void 0),ze=k.tables.some(b=>b.memory===!0);if(Ge&&Be)throw new te("INTERNAL",'lunora codegen: mixing `.global()` (D1) and `.global({ backend: "hyperdrive" })` tables in one app is not supported yet — use a single global backend.');const je=k.tables.length>0,Lt=nr(k),_t=or(k),Et=lr(k),Dt=rr(k),Ye=ar(k),Xe=Cr(G,W.length>0,_.length>0,p);L&&Xe.push("WhereInput");const Ze=cr(ye),Ft=L?`
1160
1175
  protected override resolveShape(name: string, args: Record<string, unknown>, identity?: { identity?: Record<string, unknown>; userId?: string }): { columns?: readonly string[]; effectiveWhere?: WhereInput; global?: boolean; table: string } | undefined {
1161
1176
  const shape = LUNORA_SHAPES[name];
1162
1177
 
@@ -1209,37 +1224,49 @@ const LUNORA_SCHEMA_SNAPSHOT: { hash: string; json: string } = { hash: ${JSON.st
1209
1224
 
1210
1225
  return { columns: shape.columns, effectiveWhere, global: isGlobal, table: shape.table };
1211
1226
  }
1212
- `:"",Dt=X?`
1227
+ `:"",Pt=X?`
1213
1228
  protected override isCustomMutator(functionPath: string): boolean {
1214
1229
  return LUNORA_MUTATOR_PATHS.has(functionPath);
1215
1230
  }
1216
- `:"",Ft=O?"\n/** Per-table RLS read policies (hoisted from `.use(rls(...))` chains) the shape resolver AND-merges into each `defineShape` predicate so partial replication honours read policies. */\nconst LUNORA_RLS_READ_REGISTRY = buildRlsReadRegistry(Object.values(LUNORA_FUNCTIONS));\n":"",Pt=O?"assertShapeShardable, ":"",ye=[`import type { ${Ye.join(", ")} } from "${A.do}";`,`import { applyCdcChanges, buildReprojectionMigration, ${Pt}createReadFootprint, createShardCtxDb, exportShardRows, importShardRows, ${z?"isSourceDue, pullExternalSourceIncrementalTick, pullExternalSourceTick, ":""}${Re?"ROOT_SHARD_NAME, ":""}runDataMigration, runShardMigrations, ${Xe.importFragment}ShardDO as ShardDOBase } from "${A.do}";`,...z?[`import type { ExternalSourceLike, SourceClientLike, TraceRefLike } from "${A.do}";`]:[],O?`import { asBucketStorage, buildRlsReadRegistry, composeShapeReadWhere, createSecrets, LunoraError } from "${A.server}";`:`import { asBucketStorage, createSecrets, LunoraError } from "${A.server}";`];je&&ye.push(`import { bindOrm, bindTableFacade } from "${A.server}";`),G&&ye.push('import type { SchemaLike as VectorSchemaLike, VectorizeIndexLike, VectorSearchLike } from "@lunora/bindings/vectors";','import { createContextVectors, createVectors, createVectorSyncHook } from "@lunora/bindings/vectors";'),a&&ye.push('import type { AiBindingLike, LunoraAi } from "@lunora/ai";','import { createAi } from "@lunora/ai";'),ye.push(...ce.importLines,...V.importLines,...F.importLines,...Z.importLines,...de.importLines,...J.importLines,...U.importLines,...K.importLines,...Q.importLines,...q.importLines,...ee.importLines,...ve,...$e,...we,...he,...fe,...yt,"",'import schema from "../schema.js";',`import { ${["LUNORA_FUNCTIONS","LUNORA_LIFECYCLE_HOOKS","LUNORA_MIGRATIONS",...X?["LUNORA_MUTATOR_PATHS"]:[],...O?["LUNORA_SHAPES"]:[]].join(", ")} } from "./functions.js";`);const Mt=G?`
1217
- vectors?: (env: Record<string, unknown>) => Record<string, VectorizeIndexLike>;`:"",Bt=Ge?`
1218
- d1?: (env: Record<string, unknown>, request?: { bookmark?: string; identity?: Record<string, unknown>; onBookmark?: (bookmark: string | undefined) => void; userId?: string }) => DatabaseWriterLike | undefined;`:"",jt=Be?`
1219
- hyperdriveGlobal?: (env: Record<string, unknown>, request?: { identity?: Record<string, unknown>; userId?: string }) => DatabaseWriterLike | undefined;`:"",qt=z?`
1220
- sourceClient?: (env: Record<string, unknown>, binding: string) => { query: <Row = Record<string, unknown>>(text: string, params?: readonly unknown[]) => Promise<Row[]> } | undefined;`:"",Wt='throw new Error("ctx.db.<globalTable>: no global backend configured. Pass `d1` or `hyperdriveGlobal` to createShardDO().");',Ut='throw new Error("ctx.vectors: no vectors configured. Pass `vectors` to createShardDO().");',Kt='throw new Error("ctx.scheduler: no scheduler configured. Pass `scheduler` to createShardDO().");',Qt='throw new Error("ctx.storage: no storage configured. Pass `storage` to createShardDO().");',Vt=be?T("globalDbStub: DatabaseWriterLike",Wt,["aggregate","count","delete","findFirst","findFirstOrThrow","findMany","get","groupBy","insert","normalizeId","patch","query","rank","rankPage","replace"],{sync:["normalizeId","query"]}):"",Ht=G?T("vectorsStub: VectorSearchLike",Ut,["deleteByIds","getByIds","query","upsert","upsertNow"]):"",Jt=Re?`
1231
+ `:"",Mt=L?"\n/** Per-table RLS read policies (hoisted from `.use(rls(...))` chains) the shape resolver AND-merges into each `defineShape` predicate so partial replication honours read policies. */\nconst LUNORA_RLS_READ_REGISTRY = buildRlsReadRegistry(Object.values(LUNORA_FUNCTIONS));\n":"",Bt=L?"assertShapeShardable, ":"",be=[`import type { ${Xe.join(", ")} } from "${C.do}";`,`import { applyCdcChanges, buildReprojectionMigration, ${ze?"clearMemoryTables, ":""}${Bt}createReadFootprint, createShardCtxDb, exportShardRows, importShardRows, ${z?"isSourceDue, pullExternalSourceIncrementalTick, pullExternalSourceTick, ":""}${Re?"ROOT_SHARD_NAME, ":""}runDataMigration, runShardMigrations, ${Ze.importFragment}ShardDO as ShardDOBase } from "${C.do}";`,...z?[`import type { ExternalSourceLike, SourceClientLike, TraceRefLike } from "${C.do}";`]:[],L?`import { asBucketStorage, buildRlsReadRegistry, composeShapeReadWhere, createSecrets, LunoraError } from "${C.server}";`:`import { asBucketStorage, createSecrets, LunoraError } from "${C.server}";`];je&&be.push(`import { bindOrm, bindTableFacade } from "${C.server}";`),G&&be.push('import type { SchemaLike as VectorSchemaLike, VectorizeIndexLike, VectorSearchLike } from "@lunora/bindings/vectors";','import { createContextVectors, createVectors, createVectorSyncHook } from "@lunora/bindings/vectors";'),a&&be.push('import type { AiBindingLike, LunoraAi } from "@lunora/ai";','import { createAi } from "@lunora/ai";'),be.push(...ce.importLines,...V.importLines,...P.importLines,...Z.importLines,...de.importLines,...J.importLines,...U.importLines,...K.importLines,...Q.importLines,...q.importLines,...ee.importLines,...ve,...$e,...xe,...he,...fe,...wt,"",'import schema from "../schema.js";',`import { ${["LUNORA_FUNCTIONS","LUNORA_LIFECYCLE_HOOKS","LUNORA_MIGRATIONS",...X?["LUNORA_MUTATOR_PATHS"]:[],...L?["LUNORA_SHAPES"]:[]].join(", ")} } from "./functions.js";`);const jt=G?`
1232
+ vectors?: (env: Record<string, unknown>) => Record<string, VectorizeIndexLike>;`:"",qt=Ge?`
1233
+ d1?: (env: Record<string, unknown>, request?: { bookmark?: string; identity?: Record<string, unknown>; onBookmark?: (bookmark: string | undefined) => void; userId?: string }) => DatabaseWriterLike | undefined;`:"",Wt=Be?`
1234
+ hyperdriveGlobal?: (env: Record<string, unknown>, request?: { identity?: Record<string, unknown>; userId?: string }) => DatabaseWriterLike | undefined;`:"",Ut=z?`
1235
+ sourceClient?: (env: Record<string, unknown>, binding: string) => { query: <Row = Record<string, unknown>>(text: string, params?: readonly unknown[]) => Promise<Row[]> } | undefined;`:"",Kt='throw new Error("ctx.db.<globalTable>: no global backend configured. Pass `d1` or `hyperdriveGlobal` to createShardDO().");',Qt='throw new Error("ctx.vectors: no vectors configured. Pass `vectors` to createShardDO().");',Vt='throw new Error("ctx.scheduler: no scheduler configured. Pass `scheduler` to createShardDO().");',Ht='throw new Error("ctx.storage: no storage configured. Pass `storage` to createShardDO().");',Jt=ye?O("globalDbStub: DatabaseWriterLike",Kt,["aggregate","count","delete","findFirst","findFirstOrThrow","findMany","get","groupBy","insert","normalizeId","patch","query","rank","rankPage","replace"],{sync:["normalizeId","query"]}):"",Gt=G?O("vectorsStub: VectorSearchLike",Qt,["deleteByIds","getByIds","query","upsert","upsertNow"]):"",zt=Re?`
1221
1236
  const vectorShardKey = this.currentShardKey();
1222
- `:"",Gt=Re?"namespace: vectorShardKey === ROOT_SHARD_NAME ? undefined : vectorShardKey, ":"",zt=Re?`, { namespace: vectorShardKey === ROOT_SHARD_NAME ? undefined : vectorShardKey, shardedIndexNames: [${k.vectorIndexes.filter(y=>Je.has(y.table)).map(y=>JSON.stringify(y.name)).join(", ")}] }`:"",Yt=G?`
1237
+ `:"",Yt=Re?"namespace: vectorShardKey === ROOT_SHARD_NAME ? undefined : vectorShardKey, ":"",Xt=Re?`, { namespace: vectorShardKey === ROOT_SHARD_NAME ? undefined : vectorShardKey, shardedIndexNames: [${k.vectorIndexes.filter(b=>Je.has(b.table)).map(b=>JSON.stringify(b.name)).join(", ")}] }`:"",Zt=G?`
1223
1238
  let vectors: VectorSearchLike;
1224
1239
  let onWrite: WriteHook | undefined;
1225
1240
 
1226
1241
  if (config.vectors) {
1227
1242
  const lunora = createVectors({ indexes: config.vectors(env) });
1228
- ${Jt}
1229
- vectors = createContextVectors(lunora${zt});
1230
- onWrite = createVectorSyncHook({ ${Gt}schema: schema as unknown as VectorSchemaLike, vectors });
1243
+ ${zt}
1244
+ vectors = createContextVectors(lunora${Xt});
1245
+ onWrite = createVectorSyncHook({ ${Yt}schema: schema as unknown as VectorSchemaLike, vectors });
1231
1246
  } else {
1232
1247
  vectors = vectorsStub;
1233
1248
  onWrite = undefined;
1234
1249
  }
1235
- `:"",Xt=`{
1250
+ `:"",en=`{
1236
1251
  auth: { identity: identity ?? null, userId: userId ?? null },
1237
1252
  broadcast: (delta) => {
1238
1253
  this.recordChangedTable(delta.table, delta.indexKeys);
1239
1254
  },
1240
1255
  cdc: config.cdc ?? false,
1241
- enforceRls: true,
1256
+ // A dispatch with NO caller identity runs system-trusted: RLS scopes
1257
+ // rows to a user, and these have no user to scope to. This is the tier
1258
+ // migrations, imports and the external-source poll loop already run in
1259
+ // (see \`adminWriterPrelude\`). Only \`onShardInit\` and \`onQueryChange\`
1260
+ // reach it; \`onConnect\`/\`onDisconnect\` carry a verified identity and
1261
+ // stay guarded like any request.
1262
+ enforceRls: options.trusted !== true,
1242
1263
  headroom: options.headroom ?? this.transactionHeadroom(),
1264
+ // A live predicate, not a flag: the transaction opens AFTER this ctx
1265
+ // is built (a mutation dispatch wraps the handler), so only a call-time
1266
+ // read reports the truth. \`_commitSeq\` reuses one sequence across
1267
+ // writes only while they commit together — an action is not wrapped, so
1268
+ // each of its writes allocates its own.
1269
+ inTransaction: () => this.isInTransaction(),
1243
1270
  onIndexUse: this.getCtxDbIndexUseHook(),
1244
1271
  onRead: options.onRead ?? this.getCtxDbReadHook(),
1245
1272
  onReadRange: options.onReadRange,${G?`
@@ -1247,7 +1274,7 @@ ${Jt}
1247
1274
  scheduler,
1248
1275
  schema: schema as unknown as SchemaLike,
1249
1276
  sql: this.sql as SqlExec,
1250
- storage,${be?`
1277
+ storage,${ye?`
1251
1278
  globalDb,`:""}
1252
1279
  }`,Y=` const env = (this.env ?? {}) as Record<string, unknown>;
1253
1280
  const scheduler = (config.scheduler?.(env) ?? schedulerStub) as SchedulerLike;
@@ -1256,21 +1283,23 @@ ${Jt}
1256
1283
  this.recordChangedTable(delta.table, delta.indexKeys);
1257
1284
  },
1258
1285
  cdc: config.cdc ?? false,
1286
+ // Live predicate, same as the user-facing ctx — see \`databaseOptions\`.
1287
+ inTransaction: () => this.isInTransaction(),
1259
1288
  scheduler,
1260
1289
  schema: schema as unknown as SchemaLike,
1261
1290
  sql: this.sql as SqlExec,
1262
- });`,Zt=G?`
1263
- vectors,`:"",en=je?`
1264
- orm: bindOrm(facade),`:"",Ze=Be?"config.hyperdriveGlobal":"config.d1",tn=be?` const globalRequest = { bookmark: this.getInboundBookmark(), identity, onBookmark: (bookmarkValue: string | undefined) => { this.setOutboundBookmark(bookmarkValue); }, userId };
1265
- const globalDb: DatabaseWriterLike = ${Ze}?.(env, globalRequest) ?? globalDbStub;
1266
- `:"",nn=O&&be?`
1291
+ });`,tn=G?`
1292
+ vectors,`:"",nn=je?`
1293
+ orm: bindOrm(facade),`:"",et=Be?"config.hyperdriveGlobal":"config.d1",rn=ye?` const globalRequest = { bookmark: this.getInboundBookmark(), identity, onBookmark: (bookmarkValue: string | undefined) => { this.setOutboundBookmark(bookmarkValue); }, userId };
1294
+ const globalDb: DatabaseWriterLike = ${et}?.(env, globalRequest) ?? globalDbStub;
1295
+ `:"",on=L&&ye?`
1267
1296
  protected override async readGlobalShapeRows(resolved: { columns?: readonly string[]; effectiveWhere?: WhereInput; global?: boolean; table: string }, identity?: { identity?: Record<string, unknown>; userId?: string }): Promise<Array<{ doc: Record<string, unknown>; id: string }>> {
1268
1297
  const env = this.env as Record<string, unknown>;
1269
1298
  // A shape read performs no writes, so the widened request only needs
1270
1299
  // the inbound bookmark (pin the membership drain to the caller's own
1271
1300
  // prior writes) — no \`onBookmark\` here.
1272
1301
  const globalRequest = { ...identity, bookmark: this.getInboundBookmark() };
1273
- const globalDb: DatabaseWriterLike = ${Ze}?.(env, globalRequest) ?? globalDbStub;
1302
+ const globalDb: DatabaseWriterLike = ${et}?.(env, globalRequest) ?? globalDbStub;
1274
1303
  const rows: Array<{ doc: Record<string, unknown>; id: string }> = [];
1275
1304
 
1276
1305
  let cursor: null | string = null;
@@ -1297,10 +1326,17 @@ ${Jt}
1297
1326
 
1298
1327
  return rows;
1299
1328
  }
1300
- `:"",rn=z?`
1329
+ `:"",an=z?`
1301
1330
  const sourceClientCache = new WeakMap<object, Map<string, SourceClientLike>>();
1302
1331
  const sourcePollAtCache = new WeakMap<object, Map<string, number>>();
1303
- `:"",on=z?`
1332
+ `:"",sn=`
1333
+ protected override async runShardInit(): Promise<void> {
1334
+ this.ensureMigrated();
1335
+ ${ze?` clearMemoryTables(this.sql as SqlExec, schema as unknown as SchemaLike);
1336
+ `:""}
1337
+ await this.dispatchShardInit();
1338
+ }
1339
+ `,ln=z?`
1304
1340
  protected override async pollExternalSources(trace?: TraceRefLike): Promise<number | undefined> {
1305
1341
  const env = (this.env ?? {}) as Record<string, unknown>;
1306
1342
  const sourced = Object.entries((schema as unknown as SchemaLike).tables)
@@ -1435,7 +1471,7 @@ const sourcePollAtCache = new WeakMap<object, Map<string, number>>();
1435
1471
 
1436
1472
  return nextDueAt;
1437
1473
  }
1438
- `:"",et=ze.length>0,an=z||et?`
1474
+ `:"",tt=Ye.length>0,cn=z||tt?`
1439
1475
  public constructor(state: ShardDOState, env: unknown) {
1440
1476
  super(state, env);
1441
1477
  ${z?`
@@ -1448,27 +1484,27 @@ ${z?`
1448
1484
  if (autoSourced) {
1449
1485
  void this.scheduleSourcePoll();
1450
1486
  }
1451
- `:""}${et?`
1487
+ `:""}${tt?`
1452
1488
  if (LUNORA_TTL_SWEEPS.length > 0) {
1453
1489
  void this.scheduleTtlSweep();
1454
1490
  }
1455
1491
  `:""} }
1456
- `:"",sn=je?`
1492
+ `:"",dn=je?`
1457
1493
  const facade = db as unknown as Record<string, ReturnType<typeof bindTableFacade>>;
1458
- ${k.tables.map(y=>` facade[${JSON.stringify(y.name)}] = bindTableFacade(db, ${JSON.stringify(y.name)});`).join(`
1494
+ ${k.tables.map(b=>` facade[${JSON.stringify(b.name)}] = bindTableFacade(db, ${JSON.stringify(b.name)});`).join(`
1459
1495
  `)}
1460
- `:"",ln=`${ce.build}${V.build}${F.build}${J.build}${de.build}
1496
+ `:"",un=`${ce.build}${V.build}${P.build}${J.build}${de.build}
1461
1497
  const secrets = createSecrets(env);
1462
- `,cn=`${ce.contextField}${V.contextField}${F.contextField}${Z.contextField}${J.contextField}${de.contextField}
1463
- secrets,`,dn=Z.build,tt=b||h||d||w||x||v,un=tt?`
1498
+ `,pn=`${ce.contextField}${V.contextField}${P.contextField}${Z.contextField}${J.contextField}${de.contextField}
1499
+ secrets,`,mn=Z.build,nt=y||h||d||$||w||x,hn=nt?`
1464
1500
  // ActionCtx-only helpers (external, non-deterministic I/O): constructed
1465
1501
  // and attached only for an \`action\` so query/mutation ctx never carry them.
1466
1502
  if (isAction) {
1467
- ${U.build}${K.build}${Q.build}${q.build}${ee.build}${m}${[...b?[" ctx.images = images;"]:[],...h?[" ctx.sql = sql;"]:[],...d?[" ctx.browser = browser;"]:[],...w?[" ctx.r2sql = r2sql;"]:[],...x?[" ctx.pipelines = pipelines;"]:[],...v?[" ctx.x402 = x402;"]:[]].join(`
1503
+ ${U.build}${K.build}${Q.build}${q.build}${ee.build}${m}${[...y?[" ctx.images = images;"]:[],...h?[" ctx.sql = sql;"]:[],...d?[" ctx.browser = browser;"]:[],...$?[" ctx.r2sql = r2sql;"]:[],...w?[" ctx.pipelines = pipelines;"]:[],...x?[" ctx.x402 = x402;"]:[]].join(`
1468
1504
  `)}
1469
1505
  }
1470
- `:"",pn=tt?` const isAction = LUNORA_FUNCTIONS[options.functionPath ?? ""]?.kind === "action";
1471
- `:"";return`${R}${ye.join(`
1506
+ `:"",gn=nt?` const isAction = LUNORA_FUNCTIONS[options.functionPath ?? ""]?.kind === "action";
1507
+ `:"";return`${S}${be.join(`
1472
1508
  `)}
1473
1509
 
1474
1510
  type FunctionKind = "action" | "mutation" | "query";
@@ -1478,50 +1514,50 @@ interface FunctionReference {
1478
1514
  }
1479
1515
 
1480
1516
  /** Foreign-key columns per table (\`v.id("target")\` fields) for the data browser. */
1481
- const LUNORA_TABLE_REFS: Record<string, Record<string, string>> = ${JSON.stringify(It,void 0,4)};
1517
+ const LUNORA_TABLE_REFS: Record<string, Record<string, string>> = ${JSON.stringify(Lt,void 0,4)};
1482
1518
 
1483
1519
  /** Declared indexes per table (secondary, search, geo, rank, vector) for the schema viewer. */
1484
- const LUNORA_TABLE_INDEXES: Record<string, Array<{ fields: string[]; name: string; type: "geo" | "index" | "rank" | "search" | "vector"; unique?: boolean }>> = ${JSON.stringify(Ct,void 0,4)};
1520
+ const LUNORA_TABLE_INDEXES: Record<string, Array<{ fields: string[]; name: string; type: "geo" | "index" | "rank" | "search" | "vector"; unique?: boolean }>> = ${JSON.stringify(_t,void 0,4)};
1485
1521
 
1486
1522
  /** Columns per table (typed, with PK/FK markers) for the studio's schema diagram, served via \`__lunora_admin__:describeTable\`. */
1487
1523
  const LUNORA_TABLE_COLUMNS: Record<
1488
1524
  string,
1489
1525
  Array<{ bucket?: string; enumValues?: string[]; isStorage?: boolean; name: string; nullable?: boolean; optional: boolean; pk?: boolean; ref?: string; type: string }>
1490
- > = ${JSON.stringify(Lt,void 0,4)};
1526
+ > = ${JSON.stringify(Et,void 0,4)};
1491
1527
 
1492
1528
  /** Storage-key columns per table (\`v.storage(...)\` fields) for the file browser's records↔files join. */
1493
- const LUNORA_STORAGE_COLUMNS: Record<string, string[]> = ${JSON.stringify(_t,void 0,4)};
1529
+ const LUNORA_STORAGE_COLUMNS: Record<string, string[]> = ${JSON.stringify(Dt,void 0,4)};
1494
1530
 
1495
1531
  /** Declarative TTL policies (\`.ttl(field, { after? })\`) the DO alarm sweep auto-expires rows for. */
1496
- const LUNORA_TTL_SWEEPS: Array<{ after?: number; field: string; softDeleteField?: string; table: string }> = ${JSON.stringify(ze,void 0,4)};
1532
+ const LUNORA_TTL_SWEEPS: Array<{ after?: number; field: string; softDeleteField?: string; table: string }> = ${JSON.stringify(Ye,void 0,4)};
1497
1533
 
1498
1534
  /** Static schema advisories (computed by @lunora/advisor at codegen time) served via \`__lunora_admin__:getAdvisories\`. */
1499
- const LUNORA_ADVISORIES: AdvisoryFinding[] = ${JSON.stringify(xt,void 0,4)};
1535
+ const LUNORA_ADVISORIES: AdvisoryFinding[] = ${JSON.stringify(vt,void 0,4)};
1500
1536
 
1501
1537
  /** Every declared procedure (discovered by @lunora/codegen) served via \`__lunora_admin__:getAdvisorProcedures\` — the health map's denominator. */
1502
- const LUNORA_ADVISOR_PROCEDURES: AdvisorProcedure[] = ${JSON.stringify(wt,void 0,4)};
1538
+ const LUNORA_ADVISOR_PROCEDURES: AdvisorProcedure[] = ${JSON.stringify($t,void 0,4)};
1503
1539
 
1504
1540
  /** Read-only RLS metadata (policies + roles discovered from \`.use(rls(...))\` chains) served via \`__lunora_admin__:rlsPolicies\` for the studio's RLS inspector. */
1505
- const LUNORA_RLS_METADATA: RlsPoliciesResult = ${JSON.stringify(vt,void 0,4)};
1541
+ const LUNORA_RLS_METADATA: RlsPoliciesResult = ${JSON.stringify(Rt,void 0,4)};
1506
1542
 
1507
1543
  /** Read-only masking metadata (table + column + strategy discovered from \`.use(mask(...))\` chains) served via \`__lunora_admin__:maskPolicies\` for the studio's data-browser mask preview. */
1508
- const LUNORA_MASK_METADATA: MaskPoliciesResult = ${JSON.stringify($t,void 0,4)};
1544
+ const LUNORA_MASK_METADATA: MaskPoliciesResult = ${JSON.stringify(St,void 0,4)};
1509
1545
 
1510
1546
  /** Read-only storage access-rule metadata (discovered from \`.use(storageRules(...))\` chains) served via \`__lunora_admin__:storageRules\` for the studio's access-rules view. */
1511
- const LUNORA_STORAGE_RULES: StorageRulesResult = ${JSON.stringify(Rt,void 0,4)};
1547
+ const LUNORA_STORAGE_RULES: StorageRulesResult = ${JSON.stringify(Nt,void 0,4)};
1512
1548
 
1513
1549
  /** Which optional package-backed features this app wires up (discovered from imports / \`ctx.*\` reads / schema signals) served via \`__lunora_admin__:studioFeatures\` so the studio hides nav pages whose package isn't enabled. */
1514
- const LUNORA_STUDIO_FEATURES: StudioFeaturesResult = ${JSON.stringify(St,void 0,4)};
1515
- ${j}${H.constant}${Ft}${Nt}${At}${pe}${_e}${ue}${De}
1550
+ const LUNORA_STUDIO_FEATURES: StudioFeaturesResult = ${JSON.stringify(Tt,void 0,4)};
1551
+ ${j}${H.constant}${Mt}${At}${It}${pe}${_e}${ue}${De}
1516
1552
  export interface ShardDOConfig {
1517
1553
  /** Opt into change-data-capture: records a post-image to \`__cdc_log\` on every write (backs streaming export + replay-PITR). */
1518
1554
  cdc?: boolean;
1519
1555
  /** Optional telemetry sink. When supplied, each \`ctx.log.*\` call is forwarded to \`sink.onLog\`. Pass the SAME sink you give \`createWorker({ observability })\` (which drives \`onRpc\`) to route both RPC and log events. */
1520
1556
  observability?: (env: Record<string, unknown>) => TelemetrySink | undefined;
1521
1557
  scheduler?: (env: Record<string, unknown>) => unknown;
1522
- storage?: (env: Record<string, unknown>) => unknown;${Mt}${Se}${V.configField}${F.configField}${J.configField}${U.configField}${K.configField}${Q.configField}${q.configField}${ee.configField}${Pe}${Me}${Bt}${jt}${qt}
1558
+ storage?: (env: Record<string, unknown>) => unknown;${jt}${Se}${V.configField}${P.configField}${J.configField}${U.configField}${K.configField}${Q.configField}${q.configField}${ee.configField}${Pe}${Me}${qt}${Wt}${Ut}
1523
1559
  }
1524
- ${T("schedulerStub",Kt,["cancel","runAfter","runAt"])}${T("storageStub",Qt,["delete","download","getMetadata","getSignedUrl","getUrl","list","upload"],{sync:["getUrl"]})}${Vt}${rn}${Ht}${Te}${V.stub}${F.stub}${J.stub}${U.stub}${K.stub}${Q.stub}${q.stub}${ee.stub}${He}${kt}
1560
+ ${O("schedulerStub",Vt,["cancel","runAfter","runAt"])}${O("storageStub",Ht,["delete","download","getMetadata","getSignedUrl","getUrl","list","upload"],{sync:["getUrl"]})}${Jt}${an}${Gt}${Te}${V.stub}${P.stub}${J.stub}${U.stub}${K.stub}${Q.stub}${q.stub}${ee.stub}${He}${xt}
1525
1561
  // Bound in-process \`ctx.run*\` composition depth so a self- or cyclically-
1526
1562
  // referencing call fails loudly with a clear error instead of overflowing the
1527
1563
  // stack. Tracked across the awaited handler chain (one DO invocation is
@@ -1558,7 +1594,7 @@ const dispatchRun = async (expected: FunctionKind, functionPath: string, args: R
1558
1594
  * from the worker entry so wrangler binds it by name.
1559
1595
  */
1560
1596
  export const createShardDO = (config: ShardDOConfig = {}): new (state: ShardDOState, env: unknown) => ShardDOBase =>
1561
- class extends ShardDOBase {${an}
1597
+ class extends ShardDOBase {${cn}
1562
1598
  private migrated = false;
1563
1599
 
1564
1600
  public override async handleRpc(functionPath: string, args: Record<string, unknown>, headroom?: TransactionHeadroomTracker): Promise<unknown> {
@@ -1580,7 +1616,7 @@ export const createShardDO = (config: ShardDOConfig = {}): new (state: ShardDOSt
1580
1616
  // The main \`/rpc\` path always supplies one; \`dispatchLifecycle\` /
1581
1617
  // \`handleRunAs\` don't mint their own and omit it, so they keep the
1582
1618
  // prior fallback behavior unchanged.
1583
- const ctx = this.buildCtx({ functionPath, headroom });
1619
+ const ctx = this.buildCtx({ functionPath, headroom, trusted: registered.lifecycle === "init" });
1584
1620
 
1585
1621
  // A mutation's writes must commit all-or-nothing: wrap its dispatch in
1586
1622
  // the DO's BEGIN/COMMIT span so any throw (a validator, an RLS denial,
@@ -1616,7 +1652,7 @@ export const createShardDO = (config: ShardDOConfig = {}): new (state: ShardDOSt
1616
1652
  protected override isMutationFunction(functionPath: string): boolean {
1617
1653
  return LUNORA_FUNCTIONS[functionPath]?.kind === "mutation";
1618
1654
  }
1619
- ${Xe.override}
1655
+ ${Ze.override}
1620
1656
  protected override async executeSubscription(functionPath: string, args: Record<string, unknown>, identity?: { identity?: Record<string, unknown>; userId?: string }): Promise<{ ranges?: Map<string, KeyRange[]>; result: unknown; tables: Set<string> } | null> {
1621
1657
  const registered = LUNORA_FUNCTIONS[functionPath];
1622
1658
 
@@ -1652,10 +1688,47 @@ ${Xe.override}
1652
1688
  iterator: (signal) => (registered.handler as (context: unknown, args: Record<string, unknown>, signal: AbortSignal) => AsyncIterable<unknown>)(this.buildCtx({ functionPath }), args, signal),
1653
1689
  };
1654
1690
  }
1655
- ${Dt}${Et}${nn}${on}
1656
- protected override lifecycleHookPaths(event: "connect" | "disconnect"): readonly string[] {
1691
+ ${Pt}${Ft}${on}${ln}
1692
+ protected override lifecycleHookPaths(event: "connect" | "disconnect" | "init" | "reactor"): readonly string[] {
1657
1693
  return LUNORA_LIFECYCLE_HOOKS[event];
1658
1694
  }
1695
+ ${sn}
1696
+ // One \`onQueryChange\` dispatch. Mirrors \`executeSubscription\` — the
1697
+ // socket-terminated half of the same reactivity — and differs only in who
1698
+ // consumes the result: the base's \`dispatchReactors\` stores the digest as
1699
+ // the new baseline and the footprint as the "should I even re-run this"
1700
+ // gate, instead of pushing a frame down a socket.
1701
+ //
1702
+ // Wrapped in \`runInTransaction\` because a reactor handler is a mutation
1703
+ // and its writes must commit all-or-nothing. Safe to open here: the refresh
1704
+ // drain runs OUTSIDE any dispatch transaction (it is post-flush background
1705
+ // work), so this never nests.
1706
+ //
1707
+ // NO identity is threaded, and the ctx is built \`trusted\`. A reactor fires
1708
+ // because data moved, not because anyone asked, so there is no user for RLS
1709
+ // to scope to — it runs in the same system tier as migrations and the
1710
+ // external-source poll loop. Inheriting the shared per-request identity
1711
+ // would instead run an app's reactor as whichever user happened to write
1712
+ // last, which is worse than running it as nobody.
1713
+ protected override async runReactor(functionPath: string, previousDigest?: string): Promise<{ digest: string; ran: boolean; tables: readonly string[] } | undefined> {
1714
+ const registered = LUNORA_FUNCTIONS[functionPath];
1715
+
1716
+ if (!registered || registered.kind !== "mutation") {
1717
+ return undefined;
1718
+ }
1719
+
1720
+ this.ensureMigrated();
1721
+
1722
+ const footprint = createReadFootprint();
1723
+ const ctx = this.buildCtx({ functionPath, headroom: this.subscriptionHeadroom(), onRead: footprint.onRead, onReadRange: footprint.onReadRange, trusted: true });
1724
+ const outcome = (await this.runInTransaction(async () => registered.handler(ctx, { previousDigest } as unknown as Record<string, unknown>))) as {
1725
+ digest: string;
1726
+ ran: boolean;
1727
+ };
1728
+
1729
+ return { digest: outcome.digest, ran: outcome.ran, tables: [...footprint.tables] };
1730
+ }
1731
+
1659
1732
 
1660
1733
  protected override tableRefs(table: string): Record<string, string> | undefined {
1661
1734
  return LUNORA_TABLE_REFS[table];
@@ -1694,7 +1767,7 @@ ${Dt}${Et}${nn}${on}
1694
1767
  protected override studioFeatures(): StudioFeaturesResult {
1695
1768
  return LUNORA_STUDIO_FEATURES;
1696
1769
  }
1697
- ${H.evaluateOverride}${H.subscriptionOverride}${Tt}${Ot}
1770
+ ${H.evaluateOverride}${H.subscriptionOverride}${Ot}${Ct}
1698
1771
  protected override advisories(): AdvisoryFinding[] {
1699
1772
  return LUNORA_ADVISORIES;
1700
1773
  }
@@ -1918,7 +1991,7 @@ ${Y}
1918
1991
  this.migrated = true;
1919
1992
  }
1920
1993
 
1921
- private buildCtx(options: { functionPath?: string; headroom?: TransactionHeadroomTracker; identity?: { identity?: Record<string, unknown>; userId?: string }; onRead?: (table: string, idOrScan?: string) => void; onReadRange?: (range: KeyRange) => void } = {}): unknown {
1994
+ private buildCtx(options: { functionPath?: string; headroom?: TransactionHeadroomTracker; identity?: { identity?: Record<string, unknown>; userId?: string }; onRead?: (table: string, idOrScan?: string) => void; onReadRange?: (range: KeyRange) => void; trusted?: boolean } = {}): unknown {
1922
1995
  const env = (this.env ?? {}) as Record<string, unknown>;
1923
1996
  // When the caller threads an explicit identity (subscription seed /
1924
1997
  // refresh — both run in deferred/interleaved contexts), use it by
@@ -1927,7 +2000,7 @@ ${Y}
1927
2000
  // dispatch path) fall back to the per-request fields as before.
1928
2001
  const userId = options.identity ? options.identity.userId : this.getCurrentUserId();
1929
2002
  const identity = options.identity ? options.identity.identity : this.getCurrentIdentity();
1930
- ${Yt}${le}${ln}${Oe}${Ce}${Ae}${Ee}
2003
+ ${Zt}${le}${un}${Oe}${Ce}${Ae}${Ee}
1931
2004
  const scheduler = (config.scheduler?.(env) ?? schedulerStub) as SchedulerLike;
1932
2005
  // Build the storage adapter once and share it between \`ctx.storage\`
1933
2006
  // and \`ctx.db.system._storage\` so both read the same R2 binding. The
@@ -1954,13 +2027,13 @@ ${Yt}${le}${ln}${Oe}${Ce}${Ae}${Ee}
1954
2027
  // so both write to the same trace.
1955
2028
  const span = this.makeDispatchSpan(traceAnchor, observability);
1956
2029
 
1957
- ${tn} // \`ctx.db\`, wrapped in automatic instrumentation: by default this
2030
+ ${rn} // \`ctx.db\`, wrapped in automatic instrumentation: by default this
1958
2031
  // adds aggregate counters (call count, total time, per-operation
1959
2032
  // breakdown) to the wide event rather than a span per call, so a
1960
2033
  // handler making hundreds of queries stays readable. See
1961
2034
  // \`instrumentDatabase\` for the \`"spans"\` / \`"off"\` levels.
1962
- const db: DatabaseWriterLike = this.instrumentDb(createShardCtxDb(${Xt}), logFunctionPath, traceAnchor, observability);
1963
- ${sn}${Fe}
2035
+ const db: DatabaseWriterLike = this.instrumentDb(createShardCtxDb(${en}), logFunctionPath, traceAnchor, observability);
2036
+ ${dn}${Fe}
1964
2037
 
1965
2038
  // \`ctx.trace\` / \`ctx.metrics\`: spans and measurements to the same sink.
1966
2039
  // The trace anchor is threaded explicitly for the same reason \`identity\`
@@ -1968,7 +2041,7 @@ ${sn}${Fe}
1968
2041
  // writing mutation's trace from the shared per-request field.
1969
2042
  const trace = this.makeTracer(logFunctionPath, observability, traceAnchor);
1970
2043
  const metrics = this.makeMetrics(logFunctionPath, observability);
1971
- ${dn}
2044
+ ${mn}
1972
2045
  // \`ctx.now\`: the wall-clock instant (epoch ms) this function began,
1973
2046
  // captured ONCE so the whole handler body sees a single stable value.
1974
2047
  // Query/mutation handlers must be deterministic (they may be re-run on
@@ -1991,35 +2064,53 @@ ${dn}
1991
2064
  ip: this.getCurrentIp(),
1992
2065
  log,
1993
2066
  metrics,
1994
- now,${en}
2067
+ now,${nn}
1995
2068
  scheduler,
1996
2069
  span,
1997
2070
  storage,
1998
- trace,${Zt}${Ne}${cn}${ge}${Ie}${Le}${xe}${me}
2071
+ trace,${tn}${Ne}${pn}${ge}${Ie}${Le}${we}${me}
1999
2072
  };
2000
- ${pn}${un}
2073
+ ${gn}${hn}
2001
2074
  ctx.runAction = (reference: FunctionReference, fnArgs: Record<string, unknown>) => dispatchRun("action", reference.__lunoraRef, fnArgs, ctx);
2002
2075
  ctx.runMutation = (reference: FunctionReference, fnArgs: Record<string, unknown>) => dispatchRun("mutation", reference.__lunoraRef, fnArgs, ctx);
2003
- ctx.runQuery = (reference: FunctionReference, fnArgs: Record<string, unknown>) => dispatchRun("query", reference.__lunoraRef, fnArgs, ctx);
2076
+ // \`ctx.runQuery(ref, args, { untracked: true })\` runs the sub-query on
2077
+ // its OWN context, built without the read-footprint hooks — so its
2078
+ // reads never enter this subscription's footprint and a write to the
2079
+ // tables it touched does not re-run us. Everything else is inherited:
2080
+ // \`functionPath\` (log/metric attribution), \`headroom\` (the sub-query
2081
+ // must not escape this dispatch's resource ceiling), and — load-bearing
2082
+ // — the identity BY VALUE. Omitting identity would let \`buildCtx\` fall
2083
+ // back to the shared per-request fields, which a concurrent RPC may
2084
+ // have re-set, and an RLS-scoped sub-query would then read as the wrong
2085
+ // user. A tracked call keeps sharing \`ctx\` exactly as before.
2086
+ ctx.runQuery = (reference: FunctionReference, fnArgs: Record<string, unknown>, runOptions?: { untracked?: boolean }) =>
2087
+ dispatchRun(
2088
+ "query",
2089
+ reference.__lunoraRef,
2090
+ fnArgs,
2091
+ runOptions?.untracked === true
2092
+ ? this.buildCtx({ functionPath: options.functionPath, headroom: options.headroom, identity: { identity, userId } })
2093
+ : ctx,
2094
+ );
2004
2095
 
2005
2096
  return ctx;
2006
2097
  }
2007
2098
  };
2008
- `},Ve=e=>{switch(e.kind){case"array":case"object":case"record":case"union":return{builder:"text",mode:"json",notNull:!0,typeAnnotation:N(e)};case"bigint":return{builder:"blob",mode:"bigint",notNull:!0};case"boolean":return{builder:"integer",mode:"boolean",notNull:!0};case"bytes":return{builder:"blob",mode:"buffer",notNull:!0};case"date":case"timestamp":return{builder:"integer",notNull:!0};case"from":return{builder:"text",notNull:!0,typeAnnotation:N(e)};case"id":return{builder:"text",notNull:!0};case"literal":{const t=e.literalValue??"";return t.startsWith('"')||t.startsWith("'")?{builder:"text",notNull:!0}:t==="true"||t==="false"?{builder:"integer",mode:"boolean",notNull:!0}:t==="null"?{builder:"text",notNull:!0}:{builder:"real",notNull:!0}}case"null":return{builder:"text",notNull:!0};case"number":return{builder:"real",notNull:!0};case"optional":return{...e.inner?Ve(e.inner):{builder:"text",notNull:!1},notNull:!1};case"storage":case"string":return{builder:"text",notNull:!0};default:return{builder:"text",notNull:!0}}},bt=(e,t)=>{const n=re(e);return n.kind==="id"&&n.tableName!==void 0&&t.has(n.tableName)?n.tableName:void 0},Ar=(e,t,n)=>{g(e,"drizzle column name");const r=Ve(t),o=r.mode?`, { mode: "${r.mode}" }`:"";let s=`${r.builder}("${e}"${o})`;r.typeAnnotation&&(s+=`.$type<${r.typeAnnotation}>()`);const i=bt(t,n);return i!==void 0&&(s+=`.references((): AnySQLiteColumn => ${i}._id)`),r.notNull&&(s+=".notNull()"),s},Or=e=>{g(e.name,"drizzle index name");const t=e.unique?"uniqueIndex":"index",n=e.fields.map(r=>(g(r,"drizzle index field"),`t.${r}`)).join(", ");return` ${e.name}: ${t}("${e.name}").on(${n}),`},Ir=(e,t)=>{g(e.name,"table name");const n=[' _id: text("_id").primaryKey(),',' _creationTime: integer("_creationTime").notNull(),',...Object.entries(e.shape).map(([o,s])=>` ${o}: ${Ar(o,s,t)},`)].join(`
2099
+ `},Ve=e=>{switch(e.kind){case"array":case"object":case"record":case"union":return{builder:"text",mode:"json",notNull:!0,typeAnnotation:A(e)};case"bigint":return{builder:"blob",mode:"bigint",notNull:!0};case"boolean":return{builder:"integer",mode:"boolean",notNull:!0};case"bytes":return{builder:"blob",mode:"buffer",notNull:!0};case"date":case"timestamp":return{builder:"integer",notNull:!0};case"from":return{builder:"text",notNull:!0,typeAnnotation:A(e)};case"id":return{builder:"text",notNull:!0};case"literal":{const t=e.literalValue??"";return t.startsWith('"')||t.startsWith("'")?{builder:"text",notNull:!0}:t==="true"||t==="false"?{builder:"integer",mode:"boolean",notNull:!0}:t==="null"?{builder:"text",notNull:!0}:{builder:"real",notNull:!0}}case"null":return{builder:"text",notNull:!0};case"number":return{builder:"real",notNull:!0};case"optional":return{...e.inner?Ve(e.inner):{builder:"text",notNull:!1},notNull:!1};case"storage":case"string":return{builder:"text",notNull:!0};default:return{builder:"text",notNull:!0}}},kt=(e,t)=>{const n=re(e);return n.kind==="id"&&n.tableName!==void 0&&t.has(n.tableName)?n.tableName:void 0},Lr=(e,t,n)=>{g(e,"drizzle column name");const r=Ve(t),o=r.mode?`, { mode: "${r.mode}" }`:"";let s=`${r.builder}("${e}"${o})`;r.typeAnnotation&&(s+=`.$type<${r.typeAnnotation}>()`);const i=kt(t,n);return i!==void 0&&(s+=`.references((): AnySQLiteColumn => ${i}._id)`),r.notNull&&(s+=".notNull()"),s},_r=e=>{g(e.name,"drizzle index name");const t=e.unique?"uniqueIndex":"index",n=e.fields.map(r=>(g(r,"drizzle index field"),`t.${r}`)).join(", ");return` ${e.name}: ${t}("${e.name}").on(${n}),`},Er=(e,t)=>{g(e.name,"table name");const n=[' _id: text("_id").primaryKey(),',' _creationTime: integer("_creationTime").notNull(),',...Object.entries(e.shape).map(([o,s])=>` ${o}: ${Lr(o,s,t)},`)].join(`
2009
2100
  `),r=e.indexes.length>0?`, (t) => ({
2010
- ${e.indexes.map(o=>Or(o)).join(`
2101
+ ${e.indexes.map(o=>_r(o)).join(`
2011
2102
  `)}
2012
2103
  })`:"";return`export const ${e.name} = sqliteTable("${e.name}", {
2013
2104
  ${n}
2014
- }${r});`},Cr=e=>e.typeAnnotation?.includes('Id<"')??!1,Lr=(e,t)=>{const n=new Set(["integer","sqliteTable","text"]),r=new Set;let o=!1,s=!1;for(const i of e){for(const a of Object.values(i.shape)){const c=Ve(a);n.add(c.builder),s=s||Cr(c),o=o||bt(a,t)!==void 0}for(const a of i.indexes)r.add(a.unique?"uniqueIndex":"index")}return{columns:[...n].toSorted((i,a)=>i.localeCompare(a)),indexes:[...r].toSorted((i,a)=>i.localeCompare(a)),needsAnyColumn:o,needsId:s}},rt=(e,t=!1)=>{if(e.length===0)return`${R}export {};
2015
- `;const n=ne(t),r=new Set(e.map(h=>h.name)),{columns:o,indexes:s,needsAnyColumn:i,needsId:a}=Lr(e,r),c=[...s,...o].toSorted((h,b)=>h.localeCompare(b)),d=e.map(h=>Ir(h,r)).join(`
2105
+ }${r});`},Dr=e=>e.typeAnnotation?.includes('Id<"')??!1,Fr=(e,t)=>{const n=new Set(["integer","sqliteTable","text"]),r=new Set;let o=!1,s=!1;for(const i of e){for(const a of Object.values(i.shape)){const c=Ve(a);n.add(c.builder),s=s||Dr(c),o=o||kt(a,t)!==void 0}for(const a of i.indexes)r.add(a.unique?"uniqueIndex":"index")}return{columns:[...n].toSorted((i,a)=>i.localeCompare(a)),indexes:[...r].toSorted((i,a)=>i.localeCompare(a)),needsAnyColumn:o,needsId:s}},ot=(e,t=!1)=>{if(e.length===0)return`${S}export {};
2106
+ `;const n=ne(t),r=new Set(e.map(h=>h.name)),{columns:o,indexes:s,needsAnyColumn:i,needsId:a}=Fr(e,r),c=[...s,...o].toSorted((h,y)=>h.localeCompare(y)),d=e.map(h=>Er(h,r)).join(`
2016
2107
 
2017
2108
  `),p=[i?`import type { AnySQLiteColumn } from "${n.serverDrizzle}";
2018
2109
  `:"",a?`import type { Id } from "./dataModel.js";
2019
- `:""].join("");return`${R}import { ${c.join(", ")} } from "${n.serverDrizzle}";
2110
+ `:""].join("");return`${S}import { ${c.join(", ")} } from "${n.serverDrizzle}";
2020
2111
  ${p}
2021
2112
  ${d}
2022
- `},eo=(e,t=!1)=>{const n=e.tables.filter(o=>o.shardMode==="global"),r=e.tables.filter(o=>o.shardMode!=="global");return{global:E(rt(n,t),Ue),shard:E(rt(r,t),Ue)}},to=e=>{const t=new Map;for(const i of e){const a=t.get(i.cron);a?a.push(i):t.set(i.cron,[i])}const n=[...t.keys()].map(i=>` ${JSON.stringify(i)},`).join(`
2113
+ `},oo=(e,t=!1)=>{const n=e.tables.filter(o=>o.shardMode==="global"),r=e.tables.filter(o=>o.shardMode!=="global");return{global:D(ot(n,t),Ue),shard:D(ot(r,t),Ue)}},ao=e=>{const t=new Map;for(const i of e){const a=t.get(i.cron);a?a.push(i):t.set(i.cron,[i])}const n=[...t.keys()].map(i=>` ${JSON.stringify(i)},`).join(`
2023
2114
  `),r=n.length>0?`
2024
2115
  ${n}
2025
2116
  `:"",o=[...t.entries()].map(([i,a])=>{const c=a.map(d=>{const p=d.workflow?`workflow: ${JSON.stringify(d.workflow.binding)}`:`functionPath: ${JSON.stringify(d.functionPath)}`;return` { name: ${JSON.stringify(d.name)}, ${p}, args: ${JSON.stringify(d.args)} },`}).join(`
@@ -2028,7 +2119,7 @@ ${c}
2028
2119
  ],`}).join(`
2029
2120
  `),s=o.length>0?`
2030
2121
  ${o}
2031
- `:"";return`${R}/**
2122
+ `:"";return`${S}/**
2032
2123
  * One scheduled cron invocation. Exactly one target is set: \`functionPath\` is
2033
2124
  * the \`namespace:fn\` dispatch ref (matches \`__lunoraRef\`), invoked on the
2034
2125
  * shard; \`workflow\` is a \`WORKFLOW_*\` binding name whose durable workflow is
@@ -2053,10 +2144,10 @@ export const LUNORA_CRON_TRIGGERS: ReadonlyArray<string> = [${r}];
2053
2144
  * looks up \`event.cron\` here and dispatches every job in the list.
2054
2145
  */
2055
2146
  export const LUNORA_CRONS: Record<string, ReadonlyArray<LunoraCronJob>> = {${s}};
2056
- `},no=e=>{const t=[...e].toSorted((r,o)=>r.name.localeCompare(o.name)).map(r=>{const o=[`name: ${JSON.stringify(r.name)}`,`table: ${JSON.stringify(r.table)}`];return r.field!==void 0&&o.push(`field: ${JSON.stringify(r.field)}`),r.dimensions!==void 0&&o.push(`dimensions: ${JSON.stringify(r.dimensions)}`),r.metric!==void 0&&o.push(`metric: ${JSON.stringify(r.metric)}`),r.metadata!==void 0&&o.push(`metadata: ${JSON.stringify(r.metadata)}`),` { ${o.join(", ")} },`}).join(`
2147
+ `},so=e=>{const t=[...e].toSorted((r,o)=>r.name.localeCompare(o.name)).map(r=>{const o=[`name: ${JSON.stringify(r.name)}`,`table: ${JSON.stringify(r.table)}`];return r.field!==void 0&&o.push(`field: ${JSON.stringify(r.field)}`),r.dimensions!==void 0&&o.push(`dimensions: ${JSON.stringify(r.dimensions)}`),r.metric!==void 0&&o.push(`metric: ${JSON.stringify(r.metric)}`),r.metadata!==void 0&&o.push(`metadata: ${JSON.stringify(r.metadata)}`),` { ${o.join(", ")} },`}).join(`
2057
2148
  `),n=t.length>0?`
2058
2149
  ${t}
2059
- `:"";return`${R}/**
2150
+ `:"";return`${S}/**
2060
2151
  * One vector index declared in \`schema.ts\` — an inline \`.vectorize()\` column
2061
2152
  * or a standalone \`defineVectorIndex()\`. \`field\` is the source column (absent
2062
2153
  * for a \`select\`-derived Shape B index); \`metadata\` lists the row fields
@@ -2077,4 +2168,4 @@ export interface LunoraVectorIndex {
2077
2168
  * \`createWorker({ vectorIntrospector })\` to back the studio's vector browser.
2078
2169
  */
2079
2170
  export const LUNORA_VECTOR_INDEXES: ReadonlyArray<LunoraVectorIndex> = [${n}];
2080
- `},ro=e=>[...new Set(e.map(t=>t.cron))];export{Wr as A,gn as C,R as G,En as U,Kr as a,Vr as b,Gr as c,to as d,Yr as e,Ur as f,eo as g,Jr as h,Hr as i,Zr as j,no as k,zr as l,ro as m,Zn as n,Xr as o,Qr as p};
2171
+ `},io=e=>[...new Set(e.map(t=>t.cron))];export{Vr as A,bn as C,S as G,Mn as U,Jr as a,zr as b,Zr as c,ao as d,to as e,Hr as f,oo as g,Xr as h,Yr as i,ro as j,so as k,eo as l,io as m,rr as n,no as o,Gr as p};