@lunora/codegen 1.0.0-alpha.124 → 1.0.0-alpha.125

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,4 +1,4 @@
1
- import{agentComponent as at}from"@lunora/agent/component";import{LunoraError as te}from"@lunora/errors";import{serializeSchemaSnapshot as yn,hashSchemaSnapshot as bn}from"./SCHEMA_SNAPSHOT_VERSION-CftvRWB8.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:`
1
+ import{agentComponent as st}from"@lunora/agent/component";import{LunoraError as te}from"@lunora/errors";import{serializeSchemaSnapshot as yn,hashSchemaSnapshot as kn}from"./SCHEMA_SNAPSHOT_VERSION-CftvRWB8.mjs";import{s as N}from"./paths-C-9fwEgQ.mjs";const it=[{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,40 +15,40 @@ import{agentComponent as at}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"}],kn=st,wn=new Map(kn.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,xn=new Set(["any","bigint","boolean","date","id","null","number","storage","string","timestamp"]),lt=e=>e.column!==void 0,vn=(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"}],wn=it,xn=new Map(wn.flatMap(e=>e.serverCtxField?[[e.key,e.serverCtxField]]:[])),Hr=it.flatMap(e=>"appMethod"in e?[{appMethod:e.appMethod,key:e.key}]:[]),lt=/^(?:"(?:[^"\\]|\\(?:["\\/bfnrt]|u[0-9A-Fa-f]{4}))*"|'[^'\\]*'|-?\d+(?:\.\d+)?|true|false|null)$/u,vn=new Set(["any","bigint","boolean","date","id","null","number","storage","string","timestamp"]),ct=e=>e.column!==void 0,Rn=(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
- `}},$n=(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(xn.has(e.kind))return e.kind==="any"?{out:t,pre:""}:{out:t,pre:vn(e.kind,t)};switch(e.kind){case"array":return Rn(e,t,n);case"literal":return $n(e,t);case"object":return Tn(e,t,n);default:return}}},Rn=(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
+ `}},$n=(e,t)=>{const n=e.literalValue?.trim();if(!(n===void 0||!lt.test(n)))return{out:t,pre:`if (${t} !== ${n}) return DEFER;
24
+ `}},Ke=(e,t,n)=>{if(!ct(e)&&!(e.hasRefinement||e.sourceText!==void 0)){if(vn.has(e.kind))return e.kind==="any"?{out:t,pre:""}:{out:t,pre:Rn(e.kind,t)};switch(e.kind){case"array":return Sn(e,t,n);case"literal":return $n(e,t);case"object":return An(e,t,n);default:return}}},Sn=(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=Ke(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}},Sn=(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;
30
+ `;return{out:s,pre:d}},Nn=(e,t,n,r)=>{const o=JSON.stringify(e);if(t.kind==="optional"){if(t.hasRefinement||t.sourceText!==void 0||ct(t))return;const{inner:i}=t;if(!i)return;const a=Ke(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}},Nn=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(Nn.has(s)){const p=`__f${String(n.next())}`;r+=`const ${p} = Object.hasOwn(${t}, ${a}) ? ${t}[${a}] : undefined;
37
- `,c=p}const d=Sn(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
- `},Tn=(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}},An=e=>{let t=0;const r=ct(e,"source",{next:()=>(t+=1,t)});if(r)return`(source) => {
36
+ `;return{entry:`...(${d} ? { ${o}: ${p} } : {})`,pre:h}}const s=Ke(t,n,r);if(s)return{entry:`${o}: ${s.out}`,pre:s.pre}},Tn=new Set(Object.getOwnPropertyNames(Object.prototype)),dt=(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(Tn.has(s)){const p=`__f${String(n.next())}`;r+=`const ${p} = Object.hasOwn(${t}, ${a}) ? ${t}[${a}] : undefined;
37
+ `,c=p}const d=Nn(s,i,c,n);if(!d)return;r+=d.pre,o.push(d.entry)}return{entries:o.join(", "),pre:r}},ut=e=>{const t=`Object.getPrototypeOf(${e})`;return`if (${t} !== Object.prototype && ${t} !== null) return DEFER;
38
+ `},An=(e,t,n)=>{const r=e.shape??{},o=dt(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
+ ${ut(t)}${o.pre}const ${i} = { ${o.entries} };
40
+ `;return{out:i,pre:a}},On=e=>{let t=0;const r=dt(e,"source",{next:()=>(t+=1,t)});if(r)return`(source) => {
41
41
  if (typeof source !== "object" || source === null || Array.isArray(source)) return DEFER;
42
- ${dt("source")}${r.pre}return { ${r.entries} };
42
+ ${ut("source")}${r.pre}return { ${r.entries} };
43
43
  }`},S=`// GENERATED by @lunora/codegen — do not edit.
44
44
  // Run \`lunora codegen\` to regenerate.
45
45
 
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,On=/^[\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),In={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"},Cn=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=In[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 Cn(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,Ln=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(`
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"},pt=/^[A-Za-z_$][\w$]*$/u,In=/^[\w./-]+$/u,g=(e,t)=>{if(!pt.test(e))throw new te("INTERNAL",`@lunora/codegen: ${t} is not a valid JS identifier: ${JSON.stringify(e)}`)},Ue=e=>e.charAt(0).toUpperCase()+e.slice(1),E=e=>pt.test(e)?e:JSON.stringify(e),Cn={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"},Ln=e=>{if(e===void 0)return"unknown";if(!lt.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=Cn[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 Ln(e.literalValue);case"object":return e.shape?`{ ${Object.entries(e.shape).map(([r,o])=>mt(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"}},mt=(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])=>mt(n,r)).join("; ")} }`},ht=e=>e.kind==="optional"||!!e.column?.hasDefault,re=e=>e.kind==="optional"&&e.inner?e.inner:e,_n=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 ht(o)?` ${a}?: ${i};`:` ${a}: ${i};`}).join(`
47
47
  `),n=t?`
48
48
  ${t}
49
49
  `:"";return`export interface Insert_${e.name} {
50
50
  _id?: Id<"${e.name}">;
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(`
51
+ _creationTime?: number;${n}}`},Qe="schema",Gr=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(([R,x])=>{const I=E(R);if(x.kind==="optional"){const T=x.inner?A(x.inner):"unknown";return` ${I}?: ${T};`}return` ${I}: ${A(x)};`}).join(`
52
52
  `),f=l?`
53
53
  ${l}
54
54
  `:"",w=u.commitOrdered===!0?`
@@ -61,7 +61,7 @@ ${l}
61
61
  `),i=e.tables.map(u=>{const l=u.searchIndexes.map(f=>JSON.stringify(f.name)).join(" | ");return` ${u.name}: ${l||"never"};`}).join(`
62
62
  `),a=e.tables.map(u=>{const l=u.rankIndexes.map(f=>JSON.stringify(f.name)).join(" | ");return` ${u.name}: ${l||"never"};`}).join(`
63
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(`
64
- `),d=e.vectorIndexes.map(u=>JSON.stringify(u.name)).join(" | ")||"never",p=e.tables.map(u=>Ln(u)).join(`
64
+ `),d=e.vectorIndexes.map(u=>JSON.stringify(u.name)).join(" | ")||"never",p=e.tables.map(u=>_n(u)).join(`
65
65
 
66
66
  `),h=e.tables.map(u=>` ${u.name}: Insert_${u.name};`).join(`
67
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(`
@@ -160,11 +160,11 @@ export interface Relations {
160
160
  ${y}
161
161
  }
162
162
 
163
- `,Ue)},_n=/import\("(?<spec>(?:\.\.?\/)*_generated\/[^"]+)"\)/gu,ht=/^(?:\.\.?\/)*_generated\//u,gt=/\.[A-Za-z]\w*$/u,En=e=>e.replaceAll(_n,(t,n)=>{const r=n.replace(ht,"./");return`import("${gt.test(r)?r:`${r}.js`}")`}),Dn=/import\("(?<spec>\.\.?\/[^"]+)"\)/gu,Fn=/^(?:\.\.?\/)+/u,Pn=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("/")},Mn=(e,t)=>e.replaceAll(Dn,(n,r)=>{if(ht.test(r.replace(Fn,"")))return n;const o=t.includes("/")?t.slice(0,t.lastIndexOf("/")):"",i=`../${Pn(`${o}/${r}`)}`;return`import("${gt.test(i)?i:`${i}.js`}")`}),D=(e,t)=>En(Mn(e,t)),Bn=["client","do","errors","flags","observability","platform","ratelimit","runtime","server","values"],jn=new RegExp(String.raw`import\("@lunora/(?<pkg>${Bn.join("|")})(?<subpath>/[^"]*)?"\)`,"gu"),qn={flags:new Set(["/web"]),platform:new Set},ft=(e,t)=>t?e.replaceAll(jn,(n,r,o)=>{const s=qn[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)),yt=e=>e.output===void 0||e.output.kind==="any"||e.kind==="stream"?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(yt(s),s.filePath);return` ${s.exportName}: FunctionReference<"${s.kind}", ${i}, ${a}>;`}).join(`
163
+ `,Qe)},En=/import\("(?<spec>(?:\.\.?\/)*_generated\/[^"]+)"\)/gu,gt=/^(?:\.\.?\/)*_generated\//u,ft=/\.[A-Za-z]\w*$/u,Dn=e=>e.replaceAll(En,(t,n)=>{const r=n.replace(gt,"./");return`import("${ft.test(r)?r:`${r}.js`}")`}),Fn=/import\("(?<spec>\.\.?\/[^"]+)"\)/gu,Pn=/^(?:\.\.?\/)+/u,Mn=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("/")},Bn=(e,t)=>e.replaceAll(Fn,(n,r)=>{if(gt.test(r.replace(Pn,"")))return n;const o=t.includes("/")?t.slice(0,t.lastIndexOf("/")):"",i=`../${Mn(`${o}/${r}`)}`;return`import("${ft.test(i)?i:`${i}.js`}")`}),D=(e,t)=>Dn(Bn(e,t)),jn=["client","do","errors","flags","observability","platform","ratelimit","runtime","server","values"],qn=new RegExp(String.raw`import\("@lunora/(?<pkg>${jn.join("|")})(?<subpath>/[^"]*)?"\)`,"gu"),Wn={flags:new Set(["/web"]),platform:new Set},bt=(e,t)=>t?e.replaceAll(qn,(n,r,o)=>{const s=Wn[r];return o&&s&&!s.has(o)?n:`import("lunorash/${r}${o??""}")`}):e,Ve=e=>["Doc","Id"].filter(t=>new RegExp(String.raw`\b${t}<`,"u").test(e)),yt=e=>e.output===void 0||e.output.kind==="any"||e.kind==="stream"?e.returnType:A(e.output),He=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))},ot=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(yt(s),s.filePath);return` ${s.exportName}: FunctionReference<"${s.kind}", ${i}, ${a}>;`}).join(`
164
164
  `);return` ${E(N(n))}: {
165
165
  ${o}
166
- };`};return Qe(e).map(n=>t(n)).join(`
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+=`
166
+ };`};return He(e).map(n=>t(n)).join(`
167
+ `)},Un=(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+=`
168
168
  /** A typed reference to a durable workflow, addressable for \`cronJobs()\` targets. Mirrors \`@lunora/scheduler\`'s \`WorkflowReference\` structurally. */
169
169
  export interface WorkflowReference<Params = Record<string, unknown>> {
170
170
  readonly isLunoraWorkflow: true;
@@ -196,7 +196,7 @@ export const agents: AgentsRef = {
196
196
  ${i}
197
197
  };
198
198
  `,n.push(`import type { AgentRunInput } from "@lunora/agent";
199
- `)}return{block:r,importLine:n.join("")}},Un=()=>Object.keys(at().functions).toSorted((e,t)=>e.localeCompare(t)),bt=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=bt(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";
199
+ `)}return{block:r,importLine:n.join("")}},Kn=()=>Object.keys(st().functions).toSorted((e,t)=>e.localeCompare(t)),kt=e=>new Set(e.filter(t=>N(t.filePath)==="agents").map(t=>t.exportName)),Qn=()=>new Set(Object.entries(st().functions).filter(([,e])=>e.visibility==="internal").map(([e])=>e)),Vn=(e,t)=>{const n={importLine:"",lines:"",prelude:""};if(e.length===0)return n;const r=kt(t),o=Qn(),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=Kn().filter(a=>!r.has(a));return i.length===0?n:{importLine:`import { agentComponent } from "@lunora/agent/component";
200
200
  `,lines:i.map(a=>` "agents:${a}": lunoraAgentRuntimeFunctions.${a} as unknown as RegisteredLunoraFunction,`).join(`
201
201
  `),prelude:`
202
202
  /**
@@ -205,8 +205,8 @@ ${i}
205
205
  * subscribe to the public queries (\`agents:agentMessages\` is the live thread view).
206
206
  */
207
207
  const lunoraAgentRuntimeFunctions = agentComponent().functions;
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=bt(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(`
208
+ `}},Hn=(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"}},Gn=(e,t)=>{if(e.length===0)return[];const n=kt(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}))},zn=e=>{const t=e.filter(i=>i.stream);if(t.length===0)return{block:"",body:""};const n=He(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
210
  `);return` ${E(N(i))}: {
211
211
  ${c}
212
212
  };`}).join(`
@@ -223,26 +223,26 @@ ${r}
223
223
  export const httpStreams: HttpStreamsRef = {
224
224
  ${o}
225
225
  };
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}
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"),...Gn(t,n),...Jn(o,n)],d=n.filter(v=>v.visibility==="internal"),p=ot(c),h=ot(d),y=zn(r),u=`${p}
227
227
  ${h}
228
- ${y.body}`,l=Ke(u),f=l.length>0?`
228
+ ${y.body}`,l=Ve(u),f=l.length>0?`
229
229
  import type { ${l.join(", ")} } from "./dataModel.js";
230
230
  `:"",w=p?`
231
231
  ${p}
232
- `:"",$=h?`
232
+ `:"",R=h?`
233
233
  ${h}
234
- `:"",x=Wn(i,t),I=`export interface ApiTypes {${w}}
234
+ `:"",x=Un(i,t),I=`export interface ApiTypes {${w}}
235
235
 
236
236
  export const api = anyApi as unknown as ApiTypes;
237
237
 
238
238
  /** Internal functions — callable only server-side via \`ctx.run*\`, never from a client. */
239
- export interface InternalApiTypes {${$}}
239
+ export interface InternalApiTypes {${R}}
240
240
 
241
241
  export const internal = anyApi as unknown as InternalApiTypes;
242
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}";
243
+ `:"";return bt(`${S}import { anyApi } from "${a.client}";
244
244
  ${_}${x.importLine}${f}
245
- ${I}`,s)},Gr=e=>e?`${S}import { createSeedClient as createSeedClientBase } from "@lunora/seed";
245
+ ${I}`,s)},zr=e=>e?`${S}import { createSeedClient as createSeedClientBase } from "@lunora/seed";
246
246
  import type { SeedClient, SeedClientOptions } from "@lunora/seed";
247
247
 
248
248
  import schema from "../schema.js";
@@ -259,8 +259,8 @@ import type { InsertModel } from "./dataModel.js";
259
259
  * const { posts } = await seed.posts((x) => x([10, 20]));
260
260
  */
261
261
  export const createSeedClient = (options?: SeedClientOptions): SeedClient<InsertModel> => createSeedClientBase<InsertModel>(schema, options);
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. */
263
- export interface ${qe(l)} {
262
+ `:"",Yr=(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. */
263
+ export interface ${Ue(l)} {
264
264
  ${y}
265
265
  /**
266
266
  * Share the optimistic-overlay gate with other collections + mutators on this
@@ -285,7 +285,7 @@ ${y}
285
285
  * \`createCollection\`, plus the \`checkpoints\` registry to hand \`bindMutators\` and
286
286
  * \`scope\` to re-point the subscription.
287
287
  */
288
- export const ${c.exportName}CollectionOptions = (options: ${qe(l)}): LunoraCollectionOptions<${d}> =>
288
+ export const ${c.exportName}CollectionOptions = (options: ${Ue(l)}): LunoraCollectionOptions<${d}> =>
289
289
  lunoraCollectionOptions<${d}>({
290
290
  client: options.client,
291
291
  ...(options.checkpoints === undefined ? {} : { checkpoints: options.checkpoints }),
@@ -298,14 +298,14 @@ export const ${c.exportName}CollectionOptions = (options: ${qe(l)}): LunoraColle
298
298
 
299
299
  /** Live collection for the \`${c.exportName}\` shape, with its sync controls. */
300
300
  export const ${c.exportName}Collection = (
301
- options: ${qe(l)},
301
+ options: ${Ue(l)},
302
302
  ): { checkpoints: CheckpointRegistry; collection: Collection<${d}, string>; scope: ${u} } => {
303
303
  const { checkpoints, config, scope } = ${c.exportName}CollectionOptions(options);
304
304
 
305
305
  return { checkpoints, collection: createCollection(config), scope };
306
306
  };`}).join(`
307
307
 
308
- `),i=Ke(s),a=i.length>0?`import type { ${i.join(", ")} } from "./dataModel.js";
308
+ `),i=Ve(s),a=i.length>0?`import type { ${i.join(", ")} } from "./dataModel.js";
309
309
  `:"";return`${S}import type { LunoraClient, SubscriptionError } from "${r.client}";
310
310
  import { lunoraCollectionOptions } from "@lunora/db/collections";
311
311
  import type { CheckpointRegistry, LunoraCollectionOptions, Row } from "@lunora/db";
@@ -313,7 +313,7 @@ import type { Collection } from "@tanstack/db";
313
313
  import { createCollection } from "@tanstack/db";
314
314
  ${a}
315
315
  ${s}
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> => {
316
+ `},Yn=(e,t)=>`lunora_${N(e)}_${String(t)}`,Xn=`const callRegistered = async <R>(context: CallerCtx, functionPath: string, args: Record<string, unknown> | undefined): Promise<R> => {
317
317
  const registered = LUNORA_FUNCTIONS[functionPath];
318
318
 
319
319
  if (!registered) {
@@ -321,13 +321,13 @@ ${s}
321
321
  }
322
322
 
323
323
  return (await registered.handler(context, args ?? {})) as R;
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(!On.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(`
324
+ };`,Zn=(e,t,n=[],r=[])=>{const o=new Map,s=l=>{o.has(l)||o.set(l,Yn(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(!In.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
325
  `),a=e.map(l=>` "${N(l.filePath)}:${l.exportName}": ${o.get(l.filePath)??""}.${l.exportName} as unknown as RegisteredLunoraFunction,`).join(`
326
326
  `),c=t.map(l=>` ${JSON.stringify(l.id)}: ${o.get(l.filePath)??""}.${l.exportName} as unknown as RegisteredDataMigration,`).join(`
327
327
  `),d=n.map(l=>` "${N(l.filePath)}:${l.exportName}": ${o.get(l.filePath)??""}.${l.exportName} as unknown as RegisteredLunoraFunction,`).join(`
328
328
  `),p=r.map(l=>` "${l.exportName}": ${o.get(l.filePath)??""}.${l.exportName} as unknown as RegisteredShape,`).join(`
329
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=An(l.args);return f===void 0?void 0:`installCompiledValidatorMap(${o.get(l.filePath)??""}.${l.exportName}.args, ${f});`}).filter(l=>l!==void 0).join(`
330
+ `),u=e.map(l=>{if(l.lifecycle||Object.keys(l.args).length===0)return;const f=On(l.args);return f===void 0?void 0:`installCompiledValidatorMap(${o.get(l.filePath)??""}.${l.exportName}.args, ${f});`}).filter(l=>l!==void 0).join(`
331
331
  `);return{dispatchBody:y.length>0?`
332
332
  ${y}
333
333
  `:"",importBlock:i.length>0?`${i}
@@ -336,7 +336,7 @@ ${y}
336
336
  ${c}
337
337
  `:"",mutatorPaths:h,shapeBody:p.length>0?`
338
338
  ${p}
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(yt(a),a.filePath);return a.kind==="stream"?` ${a.exportName}: (args${d}: ${c}) => Promise<AsyncIterable<${p}>>;`:` ${a.exportName}: (args${d}: ${c}) => Promise<${p}>;`}).join(`
339
+ `:""}},er=e=>{const t=He(e),n=t.map(([o,s])=>{const i=s.map(a=>{const c=D(ke(a.args),a.filePath),d=c==="{}"?"?":"",p=D(yt(a),a.filePath);return a.kind==="stream"?` ${a.exportName}: (args${d}: ${c}) => Promise<AsyncIterable<${p}>>;`:` ${a.exportName}: (args${d}: ${c}) => Promise<${p}>;`}).join(`
340
340
  `);return` ${E(N(o))}: {
341
341
  ${i}
342
342
  };`}).join(`
@@ -344,7 +344,7 @@ ${i}
344
344
  `);return` ${E(i)}: {
345
345
  ${a}
346
346
  },`}).join(`
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";
347
+ `),types:n}},tr=(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))]},Xr=({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:R=[],schema:x,storageRuleBuckets:I=[],useUmbrella:T=!1,workflows:_=[]}={})=>{const v=ne(T),k=tr(x??{tables:[]},I).map(m=>JSON.stringify(m)).join(" | "),M=o?`import type { LunoraAi } from "@lunora/ai";
348
348
  `:"",oe=o?`
349
349
  readonly ai: LunoraAi;`:"",B=y?`import type { LunoraPayment } from "@lunora/payment";
350
350
  `:"",ae=y?`
@@ -356,10 +356,10 @@ ${a}
356
356
  readonly ${m.exportName}: ContainerAccessor;`).join("")}
357
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
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. */
359
+ readonly ${m.bindingName}?: unknown;`)),...R.map(m=>(g(m.bindingName,`queue binding "${m.bindingName}"`),` /** Queue producer binding for the \`${m.exportName}\` queue. */
360
360
  readonly ${m.bindingName}?: unknown;`)),...e.map(m=>(g(m.bindingName,`agent binding "${m.bindingName}"`),` /** Workflow binding for the \`${m.exportName}\` agent. */
361
361
  readonly ${m.bindingName}?: unknown;`))].join(`
362
- `),R=`
362
+ `),$=`
363
363
 
364
364
  /**
365
365
  * This project's Cloudflare bindings, as far as codegen can discover them from
@@ -377,9 +377,9 @@ ${L}`:""}
377
377
  }
378
378
 
379
379
  /** Alias for {@link CloudflareBindings} — the typed shape of \`env\`. */
380
- export type Env = CloudflareBindings;`,j=(m,Me)=>Me?wn.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?`
380
+ export type Env = CloudflareBindings;`,j=(m,Me)=>Me?xn.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
381
  readonly vectors: VectorSearch<VectorIndexName>;`:"",de=P?`
382
- readonly vectors: VectorSearchReader<VectorIndexName>;`:"",J=P?`import type { VectorSearch, VectorSearchReader } from "${v.server}";
382
+ readonly vectors: VectorSearchReader<VectorIndexName>;`:"",G=P?`import type { VectorSearch, VectorSearchReader } from "${v.server}";
383
383
  import type { VectorIndexName } from "./dataModel.js";
384
384
  `:"",U=r?`
385
385
  /** Verified Cloudflare Access identity — a synchronous facade over the resolved claims (email / groups / hasGroup / claims). Anonymous when no Access token is present. */
@@ -405,7 +405,7 @@ export interface LunoraWorkflows {
405
405
  ${_.map(m=>` get(name: ${JSON.stringify(m.exportName)}): WorkflowHandle<WorkflowParamsOf<typeof lunoraWorkflowDefinitions.${m.exportName}>>;`).join(`
406
406
  `)}
407
407
  }`:"",we=q?' | "workflows"':"",xe=q?`
408
- readonly workflows: LunoraWorkflows;`:"",ue=$.length>0,Oe=ue?`import type { QueueProducer } from "@lunora/queue";
408
+ readonly workflows: LunoraWorkflows;`:"",ue=R.length>0,Oe=ue?`import type { QueueProducer } from "@lunora/queue";
409
409
  import type * as lunoraQueueDefinitions from "../queues.js";
410
410
  `:"",Ie=ue?`
411
411
 
@@ -414,7 +414,7 @@ type QueueBodyOf<Definition> = Definition extends { __lunoraBody?: infer Body }
414
414
 
415
415
  /** This project's declared queues, addressable from \`ctx.queues\` by their \`lunora/queues.ts\` export name. */
416
416
  export interface LunoraQueues {
417
- ${$.map(m=>` readonly ${m.exportName}: QueueProducer<QueueBodyOf<typeof lunoraQueueDefinitions.${m.exportName}>>;`).join(`
417
+ ${R.map(m=>` readonly ${m.exportName}: QueueProducer<QueueBodyOf<typeof lunoraQueueDefinitions.${m.exportName}>>;`).join(`
418
418
  `)}
419
419
  }`:"",ve=ue?`
420
420
  readonly queues: LunoraQueues;`:"",pe=e.length>0,Ce=pe?`import type { AgentHandle } from "@lunora/agent";
@@ -424,7 +424,7 @@ ${$.map(m=>` readonly ${m.exportName}: QueueProducer<QueueBodyOf<typeof lunor
424
424
  export interface LunoraAgents {
425
425
  ${e.map(m=>(g(m.exportName,`agent export "${m.exportName}"`),` readonly ${m.exportName}: AgentHandle;`)).join(`
426
426
  `)}
427
- }`:"",$e=pe?`
427
+ }`:"",Re=pe?`
428
428
  readonly agents: LunoraAgents;`:"",_e=w?`import type { InferIdentity } from "${v.server}";
429
429
  import type * as lunoraIdentityContract from "../identity.js";
430
430
  `:"",Ee=w?`
@@ -494,7 +494,7 @@ export type {
494
494
  } from "${v.serverDataModel}";
495
495
 
496
496
  import type { DataModel, Doc, GeoIndexNamesByTable, Id as IdOfTable, IndexNamesByTable, Insert, InsertModel, RankIndexNamesByTable, Relations, SearchIndexNamesByTable, TableName } from "./dataModel.js";
497
- ${J}${M}${B}${se}${C}${ee}${Oe}${Ce}${_e}${Fe}
497
+ ${G}${M}${B}${se}${C}${ee}${Oe}${Ce}${_e}${Fe}
498
498
  export type { AppTableName, DataModel, Doc, Id, TableName } from "./dataModel.js";
499
499
 
500
500
  /**
@@ -554,7 +554,7 @@ export interface OrmWriter extends OrmReader {
554
554
  }
555
555
 
556
556
  /** Storage buckets this schema declares (\`v.storage("name")\`), narrowing \`ctx.storage.bucket(name)\`. */
557
- export type StorageBucketName = ${k};${R}${Ae}${Ie}${Le}${Ee}${Pe}
557
+ export type StorageBucketName = ${k};${$}${Ae}${Ie}${Le}${Ee}${Pe}
558
558
 
559
559
  /**
560
560
  * Project-typed contexts. The base contexts from \`@lunora/server\` are
@@ -626,13 +626,13 @@ export interface QueryCtx extends Omit<QueryCtxBase, "db" | "storage"${H}${me}${
626
626
  export interface MutationCtx extends Omit<MutationCtxBase, "db" | "storage"${H}${we}${me}${ge}> {
627
627
  readonly db: Omit<DatabaseWriter, "asId" | "query" | "get"> & DatabaseWriterFacade & { asId: TypedAsId; query: TypedTableQuery; get: TypedTableGet };
628
628
  readonly orm: OrmWriter;
629
- readonly storage: ReadOnlyStorage<StorageBucketName>;${Z}${U}${ie}${K}${Q}${le}${fe}${xe}${ve}${$e}${he}
629
+ readonly storage: ReadOnlyStorage<StorageBucketName>;${Z}${U}${ie}${K}${Q}${le}${fe}${xe}${ve}${Re}${he}
630
630
  }
631
631
 
632
632
  export interface ActionCtx extends Omit<ActionCtxBase, "db" | "storage"${H}${we}${me}${ge}> {
633
633
  readonly db: Omit<DatabaseWriter, "asId" | "query" | "get"> & DatabaseWriterFacade & { asId: TypedAsId; query: TypedTableQuery; get: TypedTableGet };
634
634
  readonly orm: OrmWriter;
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}
635
+ readonly storage: StorageBase<StorageBucketName>;${Z}${U}${oe}${ae}${W}${X}${ie}${K}${Q}${Se}${Ne}${Te}${le}${ce}${V}${fe}${xe}${ve}${Re}${he}
636
636
  }
637
637
 
638
638
  /**
@@ -707,12 +707,12 @@ export const definePolicy = createPolicyDsl<DataModel, Relations${De}>();
707
707
  export const v = vBase as unknown as Omit<typeof vBase, "id"> & {
708
708
  id: <T extends TableName>(table: T) => ColumnValidator<IdOfTable<T>, IdOfTable<T>>;
709
709
  };
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(`
710
+ `},nr=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},Zr=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}=Zn(n,r,o,s),w=Vn(t,n),R=Hn(a,n),x=[w.lines,R.lines].filter($=>$.length>0).join(`
711
711
  `);let I=p;x.length>0&&(I=p.length>0?`${p.trimEnd()}
712
712
  ${x}
713
713
  `:`
714
714
  ${x}
715
- `);const T=tr(n),_=s.length>0?`import type { RegisteredShape } from "${d.server}";
715
+ `);const T=nr(n),_=s.length>0?`import type { RegisteredShape } from "${d.server}";
716
716
  `:"",v=s.length>0?`
717
717
  /**
718
718
  * Replication-shape registry — one entry per \`defineShape\` in \`lunora/shapes.ts\`.
@@ -727,7 +727,7 @@ export const LUNORA_SHAPES: Record<string, RegisteredShape> = {${f}};
727
727
  * ShardDO's \`isCustomMutator\` override routes through the client-watermark push
728
728
  * protocol (\`x-lunora-client-id\`/\`x-lunora-client-seq\` ordering).
729
729
  */
730
- export const LUNORA_MUTATOR_PATHS: ReadonlySet<string> = new Set([${l.map(R=>JSON.stringify(R)).join(", ")}]);
730
+ export const LUNORA_MUTATOR_PATHS: ReadonlySet<string> = new Set([${l.map($=>JSON.stringify($)).join(", ")}]);
731
731
  `:"",M=y.length>0?`import { DEFER_VALIDATION as DEFER, installCompiledValidatorMap } from "${d.values}";
732
732
  `:"",oe=y.length>0?`
733
733
  /**
@@ -736,14 +736,14 @@ export const LUNORA_MUTATOR_PATHS: ReadonlySet<string> = new Set([${l.map(R=>JSO
736
736
  * parser as a zero-allocation fast path; anything it can't model is deferred.
737
737
  */
738
738
  ${y}
739
- `:"",B=Zn(n),ae=B.types?`
739
+ `:"",B=er(n),ae=B.types?`
740
740
  ${B.types}
741
741
  `:"",se=B.implementation?`
742
742
  ${B.implementation}
743
- `:"",W=Ke(B.types),C=W.length>0?`import type { ${W.join(", ")} } from "./dataModel.js";
744
- `:"",X=c?"context":"_context",L=c?`${Yn}
743
+ `:"",W=Ve(B.types),C=W.length>0?`import type { ${W.join(", ")} } from "./dataModel.js";
744
+ `:"",X=c?"context":"_context",L=c?`${Xn}
745
745
 
746
- `:"";return ft(`${S}${h}${w.importLine}${$.importLine}${M}${_}import { LunoraError } from "${d.server}";
746
+ `:"";return bt(`${S}${h}${w.importLine}${R.importLine}${M}${_}import { LunoraError } from "${d.server}";
747
747
  import type { ActionCtx, MutationCtx, QueryCtx } from "./server.js";
748
748
  ${C}
749
749
  /**
@@ -777,7 +777,7 @@ export interface RegisteredLunoraFunction {
777
777
  /** \`"internal"\` functions are rejected on the external RPC path; absence === public. */
778
778
  visibility?: "internal" | "public";
779
779
  }
780
- ${w.prelude}${$.prelude}
780
+ ${w.prelude}${R.prelude}
781
781
  /**
782
782
  * Static dispatch table. The key matches the \`__lunoraRef\` the client
783
783
  * emits (\`api[namespace][fn].__lunoraRef === "namespace:fn"\`).
@@ -794,10 +794,10 @@ ${oe}${v}${k}
794
794
  * anonymous — all via system dispatch.
795
795
  */
796
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(", ")}],
797
+ connect: [${T.connect.map($=>JSON.stringify($)).join(", ")}],
798
+ disconnect: [${T.disconnect.map($=>JSON.stringify($)).join(", ")}],
799
+ init: [${T.init.map($=>JSON.stringify($)).join(", ")}],
800
+ reactor: [${T.reactor.map($=>JSON.stringify($)).join(", ")}],
801
801
  };
802
802
 
803
803
  /**
@@ -851,7 +851,7 @@ export interface RegisteredDataMigration {
851
851
  * shard DO's admin RPC and the CLI resolve migrations to run through this map.
852
852
  */
853
853
  export const LUNORA_MIGRATIONS: Record<string, RegisteredDataMigration> = {${u}};
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:`
854
+ `,i)},rr=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},or=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},ar=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},sr=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},ir=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},lr=(e,t)=>{const n=re(t),r={name:e,optional:ht(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=ir(n);return o!==void 0&&(r.enumValues=o),n.column?.notNull===!1&&(r.nullable=!0),r},cr=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(lr(o,s));t[n.name]=r}return t},dr=e=>e?{importFragment:"serveRelationFanout, ",override:`
855
855
  protected override async runRelationFanoutRead(functionPath: string, args: Record<string, unknown>): Promise<unknown> {
856
856
  this.ensureMigrated();
857
857
 
@@ -859,7 +859,7 @@ export const LUNORA_MIGRATIONS: Record<string, RegisteredDataMigration> = {${u}}
859
859
 
860
860
  return serveRelationFanout(schema as unknown as SchemaLike, db, functionPath, args);
861
861
  }
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:`
862
+ `}:{importFragment:"",override:""},ur=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:`
863
863
  const aiBinding = config.ai?.(env) ?? (env as Record<string, unknown>).AI;
864
864
  // Correlate AI-Gateway-routed calls with the Lunora trace: thread the
865
865
  // function path + trace id into createAi, which folds them into the
@@ -897,29 +897,38 @@ const aiStub: LunoraAi = {
897
897
  const ${e} = {
898
898
  ${s}
899
899
  }${r};
900
- `},F={build:"",configField:"",contextField:"",importLines:[],stub:""},ur=e=>e?{build:`
900
+ `},F={build:"",configField:"",contextField:"",importLines:[],stub:""},pr=e=>e?{build:`
901
901
  const kvBinding = config.kv?.(env) ?? (env as Record<string, unknown>).KV;
902
- const kv: Kv = kvBinding ? createKv({ namespace: kvBinding as KVNamespaceLike }) : kvStub;
902
+ // KV is not this shard's SQLite, so nothing appends a \`__cdc_log\` entry
903
+ // when a value changes — a subscription that read one can never be proven
904
+ // current on reconnect and must re-snapshot. Reads only; \`put\`/\`delete\`
905
+ // are writes and stay unstamped.
906
+ const kv: Kv = markUnvouchableReads(kvBinding ? createKv({ namespace: kvBinding as KVNamespaceLike }) : kvStub, options.onRead, [
907
+ "get",
908
+ "getRaw",
909
+ "getWithMetadata",
910
+ "list",
911
+ ]);
903
912
  `,configField:`
904
913
  kv?: (env: Record<string, unknown>) => KVNamespaceLike;`,contextField:`
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:`
914
+ 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,mr=(e,t)=>e?{build:`
906
915
  const flags: import("${t}").LunoraFlags = createFlags(flagsConfig, env, {
907
916
  provider: () => config.flags?.(env),
908
917
  targetingKey: () => flagsConfig.identify?.({ identity: identity ?? null, userId: userId ?? null }),
909
918
  });
910
919
  `,configField:`
911
920
  flags?: (env: Record<string, unknown>) => import("${t}").Provider;`,contextField:`
912
- flags,`,importLines:[`import { createFlags } from "${t}";`,'import flagsConfig from "../flags.js";'],stub:""}:F,mr=e=>e?{build:`
921
+ flags,`,importLines:[`import { createFlags } from "${t}";`,'import flagsConfig from "../flags.js";'],stub:""}:F,hr=e=>e?{build:`
913
922
  const { notify, push } = createNotify(notifyConfig, env, { log, metrics });
914
923
  `,configField:"",contextField:`
915
924
  notify,
916
- push,`,importLines:['import { createNotify } from "@lunora/notify";','import notifyConfig from "../notify.js";'],stub:""}:F,hr=e=>e?{build:`
925
+ push,`,importLines:['import { createNotify } from "@lunora/notify";','import notifyConfig from "../notify.js";'],stub:""}:F,gr=e=>e?{build:`
917
926
  const envConfig = lunoraEnvContract.${e.exportName}(env);
918
927
  `,configField:"",contextField:`
919
- env: envConfig,`,importLines:['import * as lunoraEnvContract from "../env.js";'],stub:""}:F,gr=e=>e?{build:`
928
+ env: envConfig,`,importLines:['import * as lunoraEnvContract from "../env.js";'],stub:""}:F,fr=e=>e?{build:`
920
929
  const access = accessFacade(identity, userId);
921
930
  `,configField:"",contextField:`
922
- access,`,importLines:['import { accessFacade } from "@lunora/cloudflare-access/context";'],stub:""}:F,fr=(e,t,n)=>{if(!t)return{constant:"",evaluateOverride:"",subscriptionOverride:""};const r=a=>`
931
+ access,`,importLines:['import { accessFacade } from "@lunora/cloudflare-access/context";'],stub:""}:F,br=(e,t,n)=>{if(!t)return{constant:"",evaluateOverride:"",subscriptionOverride:""};const r=a=>`
923
932
  const env = (this.env ?? {}) as Record<string, unknown>;
924
933
  const flags: import("${n}").LunoraFlags = createFlags(flagsConfig, env, {
925
934
  provider: () => config.flags?.(env),
@@ -986,20 +995,20 @@ const LUNORA_FLAG_KEYS: ReadonlyArray<{ key: string; type: "boolean" | "number"
986
995
  const analytics: AnalyticsClient = analyticsBinding ? createAnalytics(analyticsBinding as AnalyticsEngineDatasetLike) : analyticsStub;
987
996
  `,configField:`
988
997
  analytics?: (env: Record<string, unknown>) => AnalyticsEngineDatasetLike;`,contextField:`
989
- 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:`
998
+ 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,kr=e=>e?{build:`
990
999
  const imagesBinding = config.images?.(env) ?? (env as Record<string, unknown>).IMAGES;
991
1000
  const images: Images = imagesBinding ? createImages({ binding: imagesBinding as ImagesBindingLike }) : imagesStub;
992
1001
  `,configField:`
993
1002
  images?: (env: Record<string, unknown>) => ImagesBindingLike;`,contextField:`
994
- 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:`
1003
+ 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,wr=e=>e?{build:`
995
1004
  const sql: SqlClient = config.sql ? config.sql(env) : sqlStub;
996
1005
  `,configField:`
997
1006
  sql?: (env: Record<string, unknown>) => SqlClient;`,contextField:`
998
- 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:`
1007
+ 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,xr=e=>e?{build:`
999
1008
  const browser: Browser = config.browser ? config.browser(env) : browserStub;
1000
1009
  `,configField:`
1001
1010
  browser?: (env: Record<string, unknown>) => Browser;`,contextField:`
1002
- 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:`
1011
+ 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,vr=e=>e?{build:`
1003
1012
  const r2sqlEnv = env as Record<string, unknown>;
1004
1013
  const r2sqlAccountId = (r2sqlEnv.R2_SQL_ACCOUNT_ID ?? r2sqlEnv.CLOUDFLARE_ACCOUNT_ID) as string | undefined;
1005
1014
  const r2sqlToken = r2sqlEnv.R2_SQL_TOKEN as string | undefined;
@@ -1010,11 +1019,11 @@ const LUNORA_FLAG_KEYS: ReadonlyArray<{ key: string; type: "boolean" | "number"
1010
1019
  ? createR2Sql({ accountId: r2sqlAccountId, apiToken: r2sqlToken, bucket: r2sqlBucket })
1011
1020
  : r2sqlStub;
1012
1021
  `,configField:`
1013
- 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:`
1022
+ 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,Rr=e=>e?{build:`
1014
1023
  const pipelinesBinding = config.pipelines?.(env) ?? (env as Record<string, unknown>).PIPELINES;
1015
1024
  const pipelines: PipelineClient = pipelinesBinding ? createPipelines({ binding: pipelinesBinding as PipelineBindingLike }) : pipelinesStub;
1016
1025
  `,configField:`
1017
- 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}\`). */
1026
+ 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,eo=(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}\`). */
1018
1027
  export class ${s.className} extends LunoraContainer {
1019
1028
  public constructor(ctx: ConstructorParameters<typeof LunoraContainer>[0], env: Record<string, unknown>) {
1020
1029
  super(ctx, env, ${s.exportName}, "${s.exportName}"${n});
@@ -1048,7 +1057,7 @@ ${r}`},$r=(e,t)=>{if(e.length===0)return{build:"",contextField:"",importLines:[]
1048
1057
  const LUNORA_CONTAINERS: ReadonlyArray<ContainerBindingSpec> = [
1049
1058
  ${n}
1050
1059
  ];
1051
- `}},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}\`). */
1060
+ `}},to=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}\`). */
1052
1061
  export class ${r.className} extends LunoraWorkflow<WorkflowParamsOf<typeof ${r.exportName}>, WorkflowOutputOf<typeof ${r.exportName}>> {
1053
1062
  public constructor(ctx: ConstructorParameters<typeof LunoraWorkflow>[0], env: Record<string, unknown>) {
1054
1063
  super(ctx, env, ${r.exportName}, "${r.exportName}");
@@ -1076,7 +1085,7 @@ type WorkflowParamsOf<Definition> = Definition extends { __params?: infer Params
1076
1085
  /** Output type carried by a \`defineWorkflow\` definition (its phantom \`__output\`), so each entrypoint keeps the authored return type. */
1077
1086
  type WorkflowOutputOf<Definition> = Definition extends { __output?: infer Output } ? Output : unknown;
1078
1087
 
1079
- ${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}\`). */
1088
+ ${t}`},no=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}\`). */
1080
1089
  export class ${a.className} extends LunoraWorkflow<AgentRunInput, AgentRunResult> {
1081
1090
  public constructor(ctx: ConstructorParameters<typeof LunoraWorkflow>[0], env: Record<string, unknown>) {
1082
1091
  super(ctx, env, compileAgentWorkflow(${a.exportName}, "${a.exportName}"), "${a.exportName}");
@@ -1104,7 +1113,7 @@ import type { AgentRunInput, AgentRunResult } from "@lunora/agent";
1104
1113
 
1105
1114
  import { ${o} } from "../agents.js";
1106
1115
 
1107
- ${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(`
1116
+ ${r}`},ro=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(`
1108
1117
  `);return`${S}/**
1109
1118
  * Push-consumer registry for the queues declared in \`lunora/queues.ts\`. The
1110
1119
  * composed worker's \`queue(batch, env, ctx)\` entry routes each delivered batch
@@ -1119,7 +1128,7 @@ import { ${n} } from "../queues.js";
1119
1128
  export const LUNORA_QUEUE_REGISTRY: QueueRegistry = {
1120
1129
  ${r}
1121
1130
  };
1122
- `},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(`
1131
+ `},Sr=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(`
1123
1132
  `);return{build:`
1124
1133
  const workflows = createWorkflowContext(env, LUNORA_WORKFLOWS);
1125
1134
  `,contextField:`
@@ -1128,7 +1137,7 @@ ${r}
1128
1137
  const LUNORA_WORKFLOWS: ReadonlyArray<WorkflowBindingSpec> = [
1129
1138
  ${t}
1130
1139
  ];
1131
- `}},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(`
1140
+ `}},Nr=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(`
1132
1141
  `);return{build:`
1133
1142
  const queues = createQueueContext(env, LUNORA_QUEUES);
1134
1143
  `,contextField:`
@@ -1137,7 +1146,7 @@ ${t}
1137
1146
  const LUNORA_QUEUES: ReadonlyArray<QueueBindingSpec> = [
1138
1147
  ${t}
1139
1148
  ];
1140
- `}},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(`
1149
+ `}},Tr=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(`
1141
1150
  `);return{build:`
1142
1151
  const agents = createAgentContext(env, LUNORA_AGENTS);
1143
1152
  `,contextField:`
@@ -1146,28 +1155,28 @@ ${t}
1146
1155
  const LUNORA_AGENTS: ReadonlyArray<AgentBindingSpec> = [
1147
1156
  ${t}
1148
1157
  ];
1149
- `}},kt=(e,t,n,r,o)=>({constant:`
1158
+ `}},wt=(e,t,n,r,o)=>({constant:`
1150
1159
  ${o}
1151
1160
  const ${e}: ${t} = ${JSON.stringify(r,void 0,4)};
1152
1161
  `,override:`
1153
1162
  protected override ${n}(): ${t} {
1154
1163
  return ${e};
1155
1164
  }
1156
- `}),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 kt("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 kt("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:`
1165
+ `}),Ar=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 wt("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. */")},Or=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 wt("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. */")},Ir=e=>e?{imports:['import type { LunoraDatabaseLike as LunoraPaymentDbLike, LunoraPayment, PaymentsFromContextOptions } from "@lunora/payment";','import { paymentsFromContext } from "@lunora/payment";'],build:`
1157
1166
  const payments: LunoraPayment = config.payment
1158
1167
  ? paymentsFromContext({ auth: { userId: userId ?? null }, db: db as unknown as LunoraPaymentDbLike }, config.payment(env))
1159
1168
  : paymentStub;
1160
1169
  `,configField:`
1161
1170
  payment?: (env: Record<string, unknown>) => PaymentsFromContextOptions;`,contextField:`
1162
- 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:`
1171
+ 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:""},Cr=e=>e?{imports:['import type { X402Pay, X402PayConfig } from "@lunora/x402/pay";','import { lazyX402Pay } from "@lunora/x402/pay";'],build:`
1163
1172
  const x402: X402Pay = config.x402
1164
1173
  ? lazyX402Pay(config.x402(env), { getSecret: (name: string) => secrets.get(name) })
1165
1174
  : x402Stub;
1166
1175
  `,configField:`
1167
- 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?"":yn(M),j=M===void 0?"":`
1176
+ 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:""},Lr=(e,t,n,r,o)=>["AdvisorProcedure","AdvisoryFinding","DatabaseWriterLike","DataMigrationLike","ExportRow",...r?["FlagsResult"]:[],"ImportShardResult","KeyRange","MaskPoliciesResult","MigrationRunResult",...n?["QueuesResult"]:[],"RunShardApplyCdcArgs","RunShardExportArgs","RunShardImportArgs","RunShardMigrationArgs","RlsPoliciesResult","RunShardRankBeforeArgs","RunShardRankPageArgs","RunShardWriteArgs","RunShardWriteResult","SchedulerLike",...o?["SearchBackfillProgress"]:[],"TransactionHeadroomTracker","SchemaLike","ShardDOState","ShardRankPageResult","SqlExec","StorageRulesResult","StudioFeaturesResult","SystemReaderStorageLike","TelemetrySink",...t?["WorkflowsResult"]:[],...e?["WriteHook"]:[]],oo=({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:R=!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,$=M===void 0?"":yn(M),j=M===void 0?"":`
1168
1177
  /** 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. */
1169
- const LUNORA_SCHEMA_SNAPSHOT: { hash: string; json: string } = { hash: ${JSON.stringify(bn(M))}, json: ${JSON.stringify(R)} };
1170
- `,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:xt,stub:vt}=Ir(x),$t=e,Rt=t,St=v??{policies:[],roles:[]},Nt=I??{columns:[]},Tt=B??{rules:[]},At=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:Ot,override:It}=Tr(W),{constant:Ct,override:Lt}=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,_t=nr(k),Et=or(k),Dt=lr(k),Ft=rr(k),Ye=ar(k),Xe=Cr(G,W.length>0,_.length>0,p);L&&Xe.push("WhereInput");const Ze=cr(ye),Pt=L?`
1178
+ const LUNORA_SCHEMA_SNAPSHOT: { hash: string; json: string } = { hash: ${JSON.stringify(kn(M))}, json: ${JSON.stringify($)} };
1179
+ `,ie=M===void 0?"":", schemaSnapshot: LUNORA_SCHEMA_SNAPSHOT",{build:le,configField:Se,contextField:Ne,stub:Te}=ur(a),ce=fr(i),V=pr(u),P=mr(p,C.flags),H=br(s,p,C.flags),Z=hr(l),de=gr(o),G=yr(c),U=kr(y),K=wr(h),Q=xr(d),q=vr(R),ee=Rr(w),{build:Ae,contextField:we,importLines:xe,specs:ue}=Nr(_),{build:Oe,contextField:Ie,importLines:ve,specs:pe}=$r(r,k.jurisdiction),{build:Ce,contextField:Le,importLines:Re,specs:_e}=Sr(W),{build:Ee,contextField:me,importLines:he,specs:De}=Tr(n),{build:Fe,configField:Pe,contextField:ge,imports:fe,stub:Je}=Ir(f),{build:m,configField:Me,imports:vt,stub:Rt}=Cr(x),$t=e,St=t,Nt=v??{policies:[],roles:[]},Tt=I??{columns:[]},At=B??{rules:[]},Ot=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:It,override:Ct}=Ar(W),{constant:Lt,override:_t}=Or(_),J=k.vectorIndexes.length>0,ze=new Set(k.tables.filter(b=>typeof b.shardMode=="object"&&b.shardMode.kind==="shardBy").map(b=>b.name)),$e=k.vectorIndexes.some(b=>ze.has(b.table)),be=k.tables.some(b=>b.shardMode==="global"),Be=k.tables.some(b=>b.shardMode==="global"&&b.globalBackend==="hyperdrive"),Ye=k.tables.some(b=>b.shardMode==="global"&&b.globalBackend!=="hyperdrive"),z=k.tables.some(b=>b.externalSource!==void 0),Xe=k.tables.some(b=>b.memory===!0),je=k.tables.some(b=>b.shardMode!=="global"&&b.searchIndexes.length>0);if(Ye&&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 qe=k.tables.length>0,Et=rr(k),Dt=ar(k),Ft=cr(k),Pt=or(k),Ze=sr(k),et=Lr(J,W.length>0,_.length>0,p,je);L&&et.push("WhereInput");const tt=dr(be),Mt=L?`
1171
1180
  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 {
1172
1181
  const shape = LUNORA_SHAPES[name];
1173
1182
 
@@ -1220,30 +1229,37 @@ const LUNORA_SCHEMA_SNAPSHOT: { hash: string; json: string } = { hash: ${JSON.st
1220
1229
 
1221
1230
  return { columns: shape.columns, effectiveWhere, global: isGlobal, table: shape.table };
1222
1231
  }
1223
- `:"",Mt=X?`
1232
+ `:"",Bt=X?`
1224
1233
  protected override isCustomMutator(functionPath: string): boolean {
1225
1234
  return LUNORA_MUTATOR_PATHS.has(functionPath);
1226
1235
  }
1227
- `:"",Bt=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":"",jt=L?"assertShapeShardable, ":"",be=[`import type { ${Xe.join(", ")} } from "${C.do}";`,`import { applyCdcChanges, buildReprojectionMigration, ${ze?"clearMemoryTables, ":""}${jt}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,...xt,"",'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 qt=G?`
1228
- vectors?: (env: Record<string, unknown>) => Record<string, VectorizeIndexLike>;`:"",Wt=Ge?`
1229
- d1?: (env: Record<string, unknown>, request?: { bookmark?: string; identity?: Record<string, unknown>; onBookmark?: (bookmark: string | undefined) => void; userId?: string }) => DatabaseWriterLike | undefined;`:"",Ut=Be?`
1230
- hyperdriveGlobal?: (env: Record<string, unknown>, request?: { identity?: Record<string, unknown>; userId?: string }) => DatabaseWriterLike | undefined;`:"",Kt=z?`
1231
- sourceClient?: (env: Record<string, unknown>, binding: string) => { query: <Row = Record<string, unknown>>(text: string, params?: readonly unknown[]) => Promise<Row[]> } | undefined;`:"",Qt='throw new Error("ctx.db.<globalTable>: no global backend configured. Pass `d1` or `hyperdriveGlobal` to createShardDO().");',Vt='throw new Error("ctx.vectors: no vectors configured. Pass `vectors` to createShardDO().");',Ht='throw new Error("ctx.scheduler: no scheduler configured. Pass `scheduler` to createShardDO().");',Jt='throw new Error("ctx.storage: no storage configured. Pass `storage` to createShardDO().");',Gt=ye?O("globalDbStub: DatabaseWriterLike",Qt,["aggregate","count","delete","findFirst","findFirstOrThrow","findMany","get","groupBy","insert","normalizeId","patch","query","rank","rankPage","replace"],{sync:["normalizeId","query"]}):"",zt=G?O("vectorsStub: VectorSearchLike",Vt,["deleteByIds","getByIds","query","upsert","upsertNow"]):"",Yt=Re?`
1236
+ `:"",jt=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":"",qt=L?"assertShapeShardable, ":"",ye=[`import type { ${et.join(", ")} } from "${C.do}";`,`import { applyCdcChanges, ${je?"backfillSearchIndexes, ":""}buildReprojectionMigration, ${Xe?"clearMemoryTables, ":""}${qt}createReadFootprint, createShardCtxDb, exportShardRows, importShardRows, ${z?"isSourceDue, pullExternalSourceIncrementalTick, pullExternalSourceTick, ":""}markUnvouchableReads, ${$e?"ROOT_SHARD_NAME, ":""}runDataMigration, runShardMigrations, ${tt.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}";`];qe&&ye.push(`import { bindOrm, bindTableFacade } from "${C.server}";`),J&&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,...P.importLines,...Z.importLines,...de.importLines,...G.importLines,...U.importLines,...K.importLines,...Q.importLines,...q.importLines,...ee.importLines,...ve,...Re,...xe,...he,...fe,...vt,"",'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 Wt=J?`
1237
+ vectors?: (env: Record<string, unknown>) => Record<string, VectorizeIndexLike>;`:"",Ut=Ye?`
1238
+ d1?: (env: Record<string, unknown>, request?: { bookmark?: string; cdc?: boolean; cdcRetentionMs?: number; identity?: Record<string, unknown>; onBookmark?: (bookmark: string | undefined) => void; userId?: string }) => DatabaseWriterLike | undefined;`:"",Kt=Be?`
1239
+ hyperdriveGlobal?: (env: Record<string, unknown>, request?: { cdc?: boolean; cdcRetentionMs?: number; identity?: Record<string, unknown>; userId?: string }) => DatabaseWriterLike | undefined;`:"",Qt=z?`
1240
+ sourceClient?: (env: Record<string, unknown>, binding: string) => { query: <Row = Record<string, unknown>>(text: string, params?: readonly unknown[]) => Promise<Row[]> } | undefined;`:"",Vt='throw new Error("ctx.db.<globalTable>: no global backend configured. Pass `d1` or `hyperdriveGlobal` to createShardDO().");',Ht='throw new Error("ctx.vectors: no vectors configured. Pass `vectors` to createShardDO().");',Gt='throw new Error("ctx.scheduler: no scheduler configured. Pass `scheduler` to createShardDO().");',Jt='throw new Error("ctx.storage: no storage configured. Pass `storage` to createShardDO().");',zt=be?O("globalDbStub: DatabaseWriterLike",Vt,["aggregate","count","delete","findFirst","findFirstOrThrow","findMany","get","groupBy","insert","normalizeId","patch","query","rank","rankPage","replace"],{sync:["normalizeId","query"]}):"",Yt=J?O("vectorsStub: VectorSearchLike",Ht,["deleteByIds","getByIds","query","upsert","upsertNow"]):"",Xt=$e?`
1232
1241
  const vectorShardKey = this.currentShardKey();
1233
- `:"",Xt=Re?"namespace: vectorShardKey === ROOT_SHARD_NAME ? undefined : vectorShardKey, ":"",Zt=Re?`, { namespace: vectorShardKey === ROOT_SHARD_NAME ? undefined : vectorShardKey, shardedIndexNames: [${k.vectorIndexes.filter(b=>Je.has(b.table)).map(b=>JSON.stringify(b.name)).join(", ")}] }`:"",en=G?`
1242
+ `:"",Zt=$e?"namespace: vectorShardKey === ROOT_SHARD_NAME ? undefined : vectorShardKey, ":"",en=$e?`, { namespace: vectorShardKey === ROOT_SHARD_NAME ? undefined : vectorShardKey, shardedIndexNames: [${k.vectorIndexes.filter(b=>ze.has(b.table)).map(b=>JSON.stringify(b.name)).join(", ")}] }`:"",tn=J?`
1234
1243
  let vectors: VectorSearchLike;
1235
1244
  let onWrite: WriteHook | undefined;
1236
1245
 
1237
1246
  if (config.vectors) {
1238
1247
  const lunora = createVectors({ indexes: config.vectors(env) });
1239
- ${Yt}
1240
- vectors = createContextVectors(lunora${Zt});
1241
- onWrite = createVectorSyncHook({ ${Xt}schema: schema as unknown as VectorSchemaLike, vectors });
1248
+ ${Xt}
1249
+ vectors = createContextVectors(lunora${en});
1250
+ onWrite = createVectorSyncHook({ ${Zt}schema: schema as unknown as VectorSchemaLike, vectors });
1242
1251
  } else {
1243
1252
  vectors = vectorsStub;
1244
1253
  onWrite = undefined;
1245
1254
  }
1246
- `:"",tn=`{
1255
+
1256
+ // Vectorize lives outside this shard's SQLite, so a query whose result
1257
+ // depends on a similarity search cannot be proven current on reconnect —
1258
+ // an unrelated upsert (or a re-index) moves the matches without touching
1259
+ // \`__cdc_log\`. Wrapped AFTER \`onWrite\` is built so the write-through
1260
+ // vector-sync hook keeps calling the bare facade.
1261
+ vectors = markUnvouchableReads(vectors, options.onRead, ["getByIds", "query"]);
1262
+ `:"",nn=`{
1247
1263
  auth: { identity: identity ?? null, userId: userId ?? null },
1248
1264
  broadcast: (delta) => {
1249
1265
  this.recordChangedTable(delta.table, delta.indexKeys);
@@ -1265,12 +1281,12 @@ ${Yt}
1265
1281
  inTransaction: () => this.isInTransaction(),
1266
1282
  onIndexUse: this.getCtxDbIndexUseHook(),
1267
1283
  onRead: options.onRead ?? this.getCtxDbReadHook(),
1268
- onReadRange: options.onReadRange,${G?`
1284
+ onReadRange: options.onReadRange,${J?`
1269
1285
  onWrite,`:""}
1270
1286
  scheduler,
1271
1287
  schema: schema as unknown as SchemaLike,
1272
1288
  sql: this.sql as SqlExec,
1273
- storage,${ye?`
1289
+ storage,${be?`
1274
1290
  globalDb,`:""}
1275
1291
  }`,Y=` const env = (this.env ?? {}) as Record<string, unknown>;
1276
1292
  const scheduler = (config.scheduler?.(env) ?? schedulerStub) as SchedulerLike;
@@ -1284,18 +1300,18 @@ ${Yt}
1284
1300
  scheduler,
1285
1301
  schema: schema as unknown as SchemaLike,
1286
1302
  sql: this.sql as SqlExec,
1287
- });`,nn=G?`
1288
- vectors,`:"",rn=je?`
1289
- orm: bindOrm(facade),`:"",et=Be?"config.hyperdriveGlobal":"config.d1",on=ye?` const globalRequest = { bookmark: this.getInboundBookmark(), identity, onBookmark: (bookmarkValue: string | undefined) => { this.setOutboundBookmark(bookmarkValue); }, userId };
1290
- const globalDb: DatabaseWriterLike = ${et}?.(env, globalRequest) ?? globalDbStub;
1291
- `:"",an=L&&ye?`
1303
+ });`,rn=J?`
1304
+ vectors,`:"",on=qe?`
1305
+ orm: bindOrm(facade),`:"",We=Be?"config.hyperdriveGlobal":"config.d1",an=be?` const globalRequest = { ...this.globalCdcOptions(config.cdc ?? false), bookmark: this.getInboundBookmark(), identity, onBookmark: (bookmarkValue: string | undefined) => { this.setOutboundBookmark(bookmarkValue); }, userId };
1306
+ const globalDb: DatabaseWriterLike = ${We}?.(env, globalRequest) ?? globalDbStub;
1307
+ `:"",sn=L&&be?`
1292
1308
  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 }>> {
1293
1309
  const env = this.env as Record<string, unknown>;
1294
1310
  // A shape read performs no writes, so the widened request only needs
1295
1311
  // the inbound bookmark (pin the membership drain to the caller's own
1296
1312
  // prior writes) — no \`onBookmark\` here.
1297
- const globalRequest = { ...identity, bookmark: this.getInboundBookmark() };
1298
- const globalDb: DatabaseWriterLike = ${et}?.(env, globalRequest) ?? globalDbStub;
1313
+ const globalRequest = { ...identity, ...this.globalCdcOptions(config.cdc ?? false), bookmark: this.getInboundBookmark() };
1314
+ const globalDb: DatabaseWriterLike = ${We}?.(env, globalRequest) ?? globalDbStub;
1299
1315
  const rows: Array<{ doc: Record<string, unknown>; id: string }> = [];
1300
1316
 
1301
1317
  let cursor: null | string = null;
@@ -1322,17 +1338,28 @@ ${Yt}
1322
1338
 
1323
1339
  return rows;
1324
1340
  }
1325
- `:"",sn=z?`
1341
+
1342
+ protected override async readGlobalChangedTables(sinceSeq: number, cursorOnly?: boolean): Promise<{ cursor: number; floor?: number; tables: string[] } | undefined> {
1343
+ const env = this.env as Record<string, unknown>;
1344
+ // Metadata-only: this asks the global changelog which TABLES moved,
1345
+ // never what changed in them, so it costs one small read per poll tick
1346
+ // for the whole shard — and a tick whose answer omits a shape's table
1347
+ // skips that shape's membership drain entirely.
1348
+ const globalDb: DatabaseWriterLike = ${We}?.(env, { ...this.globalCdcOptions(config.cdc ?? false), bookmark: this.getInboundBookmark() }) ?? globalDbStub;
1349
+
1350
+ return globalDb.cdcChangedTables?.(sinceSeq, { cursorOnly });
1351
+ }
1352
+ `:"",ln=z?`
1326
1353
  const sourceClientCache = new WeakMap<object, Map<string, SourceClientLike>>();
1327
1354
  const sourcePollAtCache = new WeakMap<object, Map<string, number>>();
1328
- `:"",ln=`
1355
+ `:"",cn=`
1329
1356
  protected override async runShardInit(): Promise<void> {
1330
1357
  this.ensureMigrated();
1331
- ${ze?` clearMemoryTables(this.sql as SqlExec, schema as unknown as SchemaLike);
1358
+ ${Xe?` clearMemoryTables(this.sql as SqlExec, schema as unknown as SchemaLike);
1332
1359
  `:""}
1333
1360
  await this.dispatchShardInit();
1334
1361
  }
1335
- `,cn=z?`
1362
+ `,dn=z?`
1336
1363
  protected override async pollExternalSources(trace?: TraceRefLike): Promise<number | undefined> {
1337
1364
  const env = (this.env ?? {}) as Record<string, unknown>;
1338
1365
  const sourced = Object.entries((schema as unknown as SchemaLike).tables)
@@ -1467,7 +1494,7 @@ ${ze?` clearMemoryTables(this.sql as SqlExec, schema as unknown as Sc
1467
1494
 
1468
1495
  return nextDueAt;
1469
1496
  }
1470
- `:"",tt=Ye.length>0,dn=z||tt?`
1497
+ `:"",nt=Ze.length>0,un=z||nt?`
1471
1498
  public constructor(state: ShardDOState, env: unknown) {
1472
1499
  super(state, env);
1473
1500
  ${z?`
@@ -1480,27 +1507,27 @@ ${z?`
1480
1507
  if (autoSourced) {
1481
1508
  void this.scheduleSourcePoll();
1482
1509
  }
1483
- `:""}${tt?`
1510
+ `:""}${nt?`
1484
1511
  if (LUNORA_TTL_SWEEPS.length > 0) {
1485
1512
  void this.scheduleTtlSweep();
1486
1513
  }
1487
1514
  `:""} }
1488
- `:"",un=je?`
1515
+ `:"",pn=qe?`
1489
1516
  const facade = db as unknown as Record<string, ReturnType<typeof bindTableFacade>>;
1490
1517
  ${k.tables.map(b=>` facade[${JSON.stringify(b.name)}] = bindTableFacade(db, ${JSON.stringify(b.name)});`).join(`
1491
1518
  `)}
1492
- `:"",pn=`${ce.build}${V.build}${P.build}${J.build}${de.build}
1519
+ `:"",mn=`${ce.build}${V.build}${P.build}${G.build}${de.build}
1493
1520
  const secrets = createSecrets(env);
1494
- `,mn=`${ce.contextField}${V.contextField}${P.contextField}${Z.contextField}${J.contextField}${de.contextField}
1495
- secrets,`,hn=Z.build,nt=y||h||d||$||w||x,gn=nt?`
1521
+ `,hn=`${ce.contextField}${V.contextField}${P.contextField}${Z.contextField}${G.contextField}${de.contextField}
1522
+ secrets,`,gn=Z.build,rt=y||h||d||R||w||x,fn=rt?`
1496
1523
  // ActionCtx-only helpers (external, non-deterministic I/O): constructed
1497
1524
  // and attached only for an \`action\` so query/mutation ctx never carry them.
1498
1525
  if (isAction) {
1499
- ${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(`
1526
+ ${U.build}${K.build}${Q.build}${q.build}${ee.build}${m}${[...y?[" ctx.images = images;"]:[],...h?[" ctx.sql = sql;"]:[],...d?[" ctx.browser = browser;"]:[],...R?[" ctx.r2sql = r2sql;"]:[],...w?[" ctx.pipelines = pipelines;"]:[],...x?[" ctx.x402 = x402;"]:[]].join(`
1500
1527
  `)}
1501
1528
  }
1502
- `:"",fn=nt?` const isAction = LUNORA_FUNCTIONS[options.functionPath ?? ""]?.kind === "action";
1503
- `:"";return`${S}${be.join(`
1529
+ `:"",bn=rt?` const isAction = LUNORA_FUNCTIONS[options.functionPath ?? ""]?.kind === "action";
1530
+ `:"";return`${S}${ye.join(`
1504
1531
  `)}
1505
1532
 
1506
1533
  type FunctionKind = "action" | "mutation" | "query";
@@ -1510,50 +1537,50 @@ interface FunctionReference {
1510
1537
  }
1511
1538
 
1512
1539
  /** Foreign-key columns per table (\`v.id("target")\` fields) for the data browser. */
1513
- const LUNORA_TABLE_REFS: Record<string, Record<string, string>> = ${JSON.stringify(_t,void 0,4)};
1540
+ const LUNORA_TABLE_REFS: Record<string, Record<string, string>> = ${JSON.stringify(Et,void 0,4)};
1514
1541
 
1515
1542
  /** Declared indexes per table (secondary, search, geo, rank, vector) for the schema viewer. */
1516
- const LUNORA_TABLE_INDEXES: Record<string, Array<{ fields: string[]; name: string; type: "geo" | "index" | "rank" | "search" | "vector"; unique?: boolean }>> = ${JSON.stringify(Et,void 0,4)};
1543
+ const LUNORA_TABLE_INDEXES: Record<string, Array<{ fields: string[]; name: string; type: "geo" | "index" | "rank" | "search" | "vector"; unique?: boolean }>> = ${JSON.stringify(Dt,void 0,4)};
1517
1544
 
1518
1545
  /** Columns per table (typed, with PK/FK markers) for the studio's schema diagram, served via \`__lunora_admin__:describeTable\`. */
1519
1546
  const LUNORA_TABLE_COLUMNS: Record<
1520
1547
  string,
1521
1548
  Array<{ bucket?: string; enumValues?: string[]; isStorage?: boolean; name: string; nullable?: boolean; optional: boolean; pk?: boolean; ref?: string; type: string }>
1522
- > = ${JSON.stringify(Dt,void 0,4)};
1549
+ > = ${JSON.stringify(Ft,void 0,4)};
1523
1550
 
1524
1551
  /** Storage-key columns per table (\`v.storage(...)\` fields) for the file browser's records↔files join. */
1525
- const LUNORA_STORAGE_COLUMNS: Record<string, string[]> = ${JSON.stringify(Ft,void 0,4)};
1552
+ const LUNORA_STORAGE_COLUMNS: Record<string, string[]> = ${JSON.stringify(Pt,void 0,4)};
1526
1553
 
1527
1554
  /** Declarative TTL policies (\`.ttl(field, { after? })\`) the DO alarm sweep auto-expires rows for. */
1528
- const LUNORA_TTL_SWEEPS: Array<{ after?: number; field: string; softDeleteField?: string; table: string }> = ${JSON.stringify(Ye,void 0,4)};
1555
+ const LUNORA_TTL_SWEEPS: Array<{ after?: number; field: string; softDeleteField?: string; table: string }> = ${JSON.stringify(Ze,void 0,4)};
1529
1556
 
1530
1557
  /** Static schema advisories (computed by @lunora/advisor at codegen time) served via \`__lunora_admin__:getAdvisories\`. */
1531
1558
  const LUNORA_ADVISORIES: AdvisoryFinding[] = ${JSON.stringify($t,void 0,4)};
1532
1559
 
1533
1560
  /** Every declared procedure (discovered by @lunora/codegen) served via \`__lunora_admin__:getAdvisorProcedures\` — the health map's denominator. */
1534
- const LUNORA_ADVISOR_PROCEDURES: AdvisorProcedure[] = ${JSON.stringify(Rt,void 0,4)};
1561
+ const LUNORA_ADVISOR_PROCEDURES: AdvisorProcedure[] = ${JSON.stringify(St,void 0,4)};
1535
1562
 
1536
1563
  /** Read-only RLS metadata (policies + roles discovered from \`.use(rls(...))\` chains) served via \`__lunora_admin__:rlsPolicies\` for the studio's RLS inspector. */
1537
- const LUNORA_RLS_METADATA: RlsPoliciesResult = ${JSON.stringify(St,void 0,4)};
1564
+ const LUNORA_RLS_METADATA: RlsPoliciesResult = ${JSON.stringify(Nt,void 0,4)};
1538
1565
 
1539
1566
  /** 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. */
1540
- const LUNORA_MASK_METADATA: MaskPoliciesResult = ${JSON.stringify(Nt,void 0,4)};
1567
+ const LUNORA_MASK_METADATA: MaskPoliciesResult = ${JSON.stringify(Tt,void 0,4)};
1541
1568
 
1542
1569
  /** Read-only storage access-rule metadata (discovered from \`.use(storageRules(...))\` chains) served via \`__lunora_admin__:storageRules\` for the studio's access-rules view. */
1543
- const LUNORA_STORAGE_RULES: StorageRulesResult = ${JSON.stringify(Tt,void 0,4)};
1570
+ const LUNORA_STORAGE_RULES: StorageRulesResult = ${JSON.stringify(At,void 0,4)};
1544
1571
 
1545
1572
  /** 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. */
1546
- const LUNORA_STUDIO_FEATURES: StudioFeaturesResult = ${JSON.stringify(At,void 0,4)};
1547
- ${j}${H.constant}${Bt}${Ot}${Ct}${pe}${_e}${ue}${De}
1573
+ const LUNORA_STUDIO_FEATURES: StudioFeaturesResult = ${JSON.stringify(Ot,void 0,4)};
1574
+ ${j}${H.constant}${jt}${It}${Lt}${pe}${_e}${ue}${De}
1548
1575
  export interface ShardDOConfig {
1549
1576
  /** Opt into change-data-capture: records a post-image to \`__cdc_log\` on every write (backs streaming export + replay-PITR). */
1550
1577
  cdc?: boolean;
1551
1578
  /** 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. */
1552
1579
  observability?: (env: Record<string, unknown>) => TelemetrySink | undefined;
1553
1580
  scheduler?: (env: Record<string, unknown>) => unknown;
1554
- storage?: (env: Record<string, unknown>) => unknown;${qt}${Se}${V.configField}${P.configField}${J.configField}${U.configField}${K.configField}${Q.configField}${q.configField}${ee.configField}${Pe}${Me}${Wt}${Ut}${Kt}
1581
+ storage?: (env: Record<string, unknown>) => unknown;${Wt}${Se}${V.configField}${P.configField}${G.configField}${U.configField}${K.configField}${Q.configField}${q.configField}${ee.configField}${Pe}${Me}${Ut}${Kt}${Qt}
1555
1582
  }
1556
- ${O("schedulerStub",Ht,["cancel","runAfter","runAt"])}${O("storageStub",Jt,["delete","download","getMetadata","getSignedUrl","getUrl","head","list","upload"],{sync:["getUrl"]})}${Gt}${sn}${zt}${Te}${V.stub}${P.stub}${J.stub}${U.stub}${K.stub}${Q.stub}${q.stub}${ee.stub}${He}${vt}
1583
+ ${O("schedulerStub",Gt,["cancel","runAfter","runAt"])}${O("storageStub",Jt,["delete","download","getMetadata","getSignedUrl","getUrl","head","list","upload"],{sync:["getUrl"]})}${zt}${ln}${Yt}${Te}${V.stub}${P.stub}${G.stub}${U.stub}${K.stub}${Q.stub}${q.stub}${ee.stub}${Je}${Rt}
1557
1584
  // Bound in-process \`ctx.run*\` composition depth so a self- or cyclically-
1558
1585
  // referencing call fails loudly with a clear error instead of overflowing the
1559
1586
  // stack. Tracked across the awaited handler chain (one DO invocation is
@@ -1590,7 +1617,7 @@ const dispatchRun = async (expected: FunctionKind, functionPath: string, args: R
1590
1617
  * from the worker entry so wrangler binds it by name.
1591
1618
  */
1592
1619
  export const createShardDO = (config: ShardDOConfig = {}): new (state: ShardDOState, env: unknown) => ShardDOBase =>
1593
- class extends ShardDOBase {${dn}
1620
+ class extends ShardDOBase {${un}
1594
1621
  private migrated = false;
1595
1622
 
1596
1623
  public override async handleRpc(functionPath: string, args: Record<string, unknown>, headroom?: TransactionHeadroomTracker): Promise<unknown> {
@@ -1648,7 +1675,7 @@ export const createShardDO = (config: ShardDOConfig = {}): new (state: ShardDOSt
1648
1675
  protected override isMutationFunction(functionPath: string): boolean {
1649
1676
  return LUNORA_FUNCTIONS[functionPath]?.kind === "mutation";
1650
1677
  }
1651
- ${Ze.override}
1678
+ ${tt.override}
1652
1679
  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> {
1653
1680
  const registered = LUNORA_FUNCTIONS[functionPath];
1654
1681
 
@@ -1684,11 +1711,11 @@ ${Ze.override}
1684
1711
  iterator: (signal) => (registered.handler as (context: unknown, args: Record<string, unknown>, signal: AbortSignal) => AsyncIterable<unknown>)(this.buildCtx({ functionPath }), args, signal),
1685
1712
  };
1686
1713
  }
1687
- ${Mt}${Pt}${an}${cn}
1714
+ ${Bt}${Mt}${sn}${dn}
1688
1715
  protected override lifecycleHookPaths(event: "connect" | "disconnect" | "init" | "reactor"): readonly string[] {
1689
1716
  return LUNORA_LIFECYCLE_HOOKS[event];
1690
1717
  }
1691
- ${ln}
1718
+ ${cn}
1692
1719
  // One \`onQueryChange\` dispatch. Mirrors \`executeSubscription\` — the
1693
1720
  // socket-terminated half of the same reactivity — and differs only in who
1694
1721
  // consumes the result: the base's \`dispatchReactors\` stores the digest as
@@ -1763,7 +1790,7 @@ ${ln}
1763
1790
  protected override studioFeatures(): StudioFeaturesResult {
1764
1791
  return LUNORA_STUDIO_FEATURES;
1765
1792
  }
1766
- ${H.evaluateOverride}${H.subscriptionOverride}${It}${Lt}
1793
+ ${H.evaluateOverride}${H.subscriptionOverride}${Ct}${_t}
1767
1794
  protected override advisories(): AdvisoryFinding[] {
1768
1795
  return LUNORA_ADVISORIES;
1769
1796
  }
@@ -1986,7 +2013,16 @@ ${Y}
1986
2013
  runShardMigrations(this.sql as SqlExec, schema as unknown as SchemaLike, { cdc: config.cdc ?? false${ie} });
1987
2014
  this.migrated = true;
1988
2015
  }
2016
+ ${je?`
2017
+ protected override runShardSearchBackfill(options: { maxPages?: number }): SearchBackfillProgress {
2018
+ // Migrations create the fts5 companions; without them every backfill
2019
+ // statement would raise "no such table" on a shard that has never
2020
+ // served a request.
2021
+ this.ensureMigrated();
1989
2022
 
2023
+ return backfillSearchIndexes(this.sql as SqlExec, schema as unknown as SchemaLike, options);
2024
+ }
2025
+ `:""}
1990
2026
  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 {
1991
2027
  const env = (this.env ?? {}) as Record<string, unknown>;
1992
2028
  // When the caller threads an explicit identity (subscription seed /
@@ -1996,13 +2032,30 @@ ${Y}
1996
2032
  // dispatch path) fall back to the per-request fields as before.
1997
2033
  const userId = options.identity ? options.identity.userId : this.getCurrentUserId();
1998
2034
  const identity = options.identity ? options.identity.identity : this.getCurrentIdentity();
1999
- ${en}${le}${pn}${Oe}${Ce}${Ae}${Ee}
2000
- const scheduler = (config.scheduler?.(env) ?? schedulerStub) as SchedulerLike;
2035
+ ${tn}${le}${mn}${Oe}${Ce}${Ae}${Ee}
2036
+ // \`list\`/\`get\` are the two methods \`ctx.db.system.query("_scheduled_functions")\`
2037
+ // reaches through, and pending jobs live in the SchedulerDO — nothing the
2038
+ // CDC changelog records — so reading them must forfeit a delta resume.
2039
+ // The scheduler's own \`runAfter\`/\`runAt\`/\`cancel\` are writes and stay unstamped.
2040
+ const scheduler = markUnvouchableReads((config.scheduler?.(env) ?? schedulerStub) as SchedulerLike, options.onRead, ["get", "list"]);
2001
2041
  // Build the storage adapter once and share it between \`ctx.storage\`
2002
2042
  // and \`ctx.db.system._storage\` so both read the same R2 binding. The
2003
2043
  // \`storageStub\` fallback satisfies SystemReaderStorageLike structurally
2004
2044
  // (its \`list\`/\`getMetadata\` throw the "no storage configured" error).
2005
- const storage = asBucketStorage(config.storage?.(env) ?? storageStub) as unknown as SystemReaderStorageLike;
2045
+ //
2046
+ // Wrapped BEFORE the split so both consumers share one stamping facade.
2047
+ // Only the methods that actually reach R2 are stamped: \`getUrl\` and
2048
+ // \`getSignedUrl\` build a URL from the configured base (and an HMAC) and
2049
+ // read nothing, and they are what handlers overwhelmingly call — stamping
2050
+ // them would forfeit resumes for a dependency that cannot move the result.
2051
+ // \`bucket\` IS stamped: it hands back a sub-facade this wrapper does not
2052
+ // reach, so the selection is the last point at which the read can be seen.
2053
+ const storage = markUnvouchableReads(asBucketStorage(config.storage?.(env) ?? storageStub) as SystemReaderStorageLike, options.onRead, [
2054
+ "bucket",
2055
+ "download",
2056
+ "getMetadata",
2057
+ "list",
2058
+ ]);
2006
2059
  // \`ctx.log\`: the DO base builds the attributed logger (structured
2007
2060
  // fields + \`.with(...)\` child + trace correlation) and routes each call
2008
2061
  // to the optional \`observability\` sink. It also buffers the line (studio
@@ -2023,13 +2076,13 @@ ${en}${le}${pn}${Oe}${Ce}${Ae}${Ee}
2023
2076
  // so both write to the same trace.
2024
2077
  const span = this.makeDispatchSpan(traceAnchor, observability);
2025
2078
 
2026
- ${on} // \`ctx.db\`, wrapped in automatic instrumentation: by default this
2079
+ ${an} // \`ctx.db\`, wrapped in automatic instrumentation: by default this
2027
2080
  // adds aggregate counters (call count, total time, per-operation
2028
2081
  // breakdown) to the wide event rather than a span per call, so a
2029
2082
  // handler making hundreds of queries stays readable. See
2030
2083
  // \`instrumentDatabase\` for the \`"spans"\` / \`"off"\` levels.
2031
- const db: DatabaseWriterLike = this.instrumentDb(createShardCtxDb(${tn}), logFunctionPath, traceAnchor, observability);
2032
- ${un}${Fe}
2084
+ const db: DatabaseWriterLike = this.instrumentDb(createShardCtxDb(${nn}), logFunctionPath, traceAnchor, observability);
2085
+ ${pn}${Fe}
2033
2086
 
2034
2087
  // \`ctx.trace\` / \`ctx.metrics\`: spans and measurements to the same sink.
2035
2088
  // The trace anchor is threaded explicitly for the same reason \`identity\`
@@ -2037,7 +2090,7 @@ ${un}${Fe}
2037
2090
  // writing mutation's trace from the shared per-request field.
2038
2091
  const trace = this.makeTracer(logFunctionPath, observability, traceAnchor);
2039
2092
  const metrics = this.makeMetrics(logFunctionPath, observability);
2040
- ${hn}
2093
+ ${gn}
2041
2094
  // \`ctx.now\`: the wall-clock instant (epoch ms) this function began,
2042
2095
  // captured ONCE so the whole handler body sees a single stable value.
2043
2096
  // Query/mutation handlers must be deterministic (they may be re-run on
@@ -2060,13 +2113,13 @@ ${hn}
2060
2113
  ip: this.getCurrentIp(),
2061
2114
  log,
2062
2115
  metrics,
2063
- now,${rn}
2116
+ now,${on}
2064
2117
  scheduler,
2065
2118
  span,
2066
2119
  storage,
2067
- trace,${nn}${Ne}${mn}${ge}${Ie}${Le}${we}${me}
2120
+ trace,${rn}${Ne}${hn}${ge}${Ie}${Le}${we}${me}
2068
2121
  };
2069
- ${fn}${gn}
2122
+ ${bn}${fn}
2070
2123
  ctx.runAction = (reference: FunctionReference, fnArgs: Record<string, unknown>) => dispatchRun("action", reference.__lunoraRef, fnArgs, ctx);
2071
2124
  ctx.runMutation = (reference: FunctionReference, fnArgs: Record<string, unknown>) => dispatchRun("mutation", reference.__lunoraRef, fnArgs, ctx);
2072
2125
  // \`ctx.runQuery(ref, args, { untracked: true })\` runs the sub-query on
@@ -2092,21 +2145,21 @@ ${fn}${gn}
2092
2145
  return ctx;
2093
2146
  }
2094
2147
  };
2095
- `},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}}},wt=(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=wt(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(`
2148
+ `},Ge=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?Ge(e.inner):{builder:"text",notNull:!1},notNull:!1};case"storage":case"string":return{builder:"text",notNull:!0};default:return{builder:"text",notNull:!0}}},xt=(e,t)=>{const n=re(e);return n.kind==="id"&&n.tableName!==void 0&&t.has(n.tableName)?n.tableName:void 0},_r=(e,t,n)=>{g(e,"drizzle column name");const r=Ge(t),o=r.mode?`, { mode: "${r.mode}" }`:"";let s=`${r.builder}("${e}"${o})`;r.typeAnnotation&&(s+=`.$type<${r.typeAnnotation}>()`);const i=xt(t,n);return i!==void 0&&(s+=`.references((): AnySQLiteColumn => ${i}._id)`),r.notNull&&(s+=".notNull()"),s},Er=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}),`},Dr=(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}: ${_r(o,s,t)},`)].join(`
2096
2149
  `),r=e.indexes.length>0?`, (t) => ({
2097
- ${e.indexes.map(o=>_r(o)).join(`
2150
+ ${e.indexes.map(o=>Er(o)).join(`
2098
2151
  `)}
2099
2152
  })`:"";return`export const ${e.name} = sqliteTable("${e.name}", {
2100
2153
  ${n}
2101
- }${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||wt(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 {};
2102
- `;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(`
2154
+ }${r});`},Fr=e=>e.typeAnnotation?.includes('Id<"')??!1,Pr=(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=Ge(a);n.add(c.builder),s=s||Fr(c),o=o||xt(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}},at=(e,t=!1)=>{if(e.length===0)return`${S}export {};
2155
+ `;const n=ne(t),r=new Set(e.map(h=>h.name)),{columns:o,indexes:s,needsAnyColumn:i,needsId:a}=Pr(e,r),c=[...s,...o].toSorted((h,y)=>h.localeCompare(y)),d=e.map(h=>Dr(h,r)).join(`
2103
2156
 
2104
2157
  `),p=[i?`import type { AnySQLiteColumn } from "${n.serverDrizzle}";
2105
2158
  `:"",a?`import type { Id } from "./dataModel.js";
2106
2159
  `:""].join("");return`${S}import { ${c.join(", ")} } from "${n.serverDrizzle}";
2107
2160
  ${p}
2108
2161
  ${d}
2109
- `},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(`
2162
+ `},ao=(e,t=!1)=>{const n=e.tables.filter(o=>o.shardMode==="global"),r=e.tables.filter(o=>o.shardMode!=="global");return{global:D(at(n,t),Qe),shard:D(at(r,t),Qe)}},so=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(`
2110
2163
  `),r=n.length>0?`
2111
2164
  ${n}
2112
2165
  `:"",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(`
@@ -2140,7 +2193,7 @@ export const LUNORA_CRON_TRIGGERS: ReadonlyArray<string> = [${r}];
2140
2193
  * looks up \`event.cron\` here and dispatches every job in the list.
2141
2194
  */
2142
2195
  export const LUNORA_CRONS: Record<string, ReadonlyArray<LunoraCronJob>> = {${s}};
2143
- `},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(`
2196
+ `},io=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(`
2144
2197
  `),n=t.length>0?`
2145
2198
  ${t}
2146
2199
  `:"";return`${S}/**
@@ -2164,4 +2217,4 @@ export interface LunoraVectorIndex {
2164
2217
  * \`createWorker({ vectorIntrospector })\` to back the studio's vector browser.
2165
2218
  */
2166
2219
  export const LUNORA_VECTOR_INDEXES: ReadonlyArray<LunoraVectorIndex> = [${n}];
2167
- `},io=e=>[...new Set(e.map(t=>t.cron))];export{Vr as A,kn as C,S as G,Bn 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};
2220
+ `},lo=e=>[...new Set(e.map(t=>t.cron))];export{Hr as A,wn as C,S as G,jn as U,Jr as a,Yr as b,eo as c,so as d,no as e,Gr as f,ao as g,Zr as h,Xr as i,oo as j,io as k,to as l,lo as m,or as n,ro as o,zr as p};