@lunora/codegen 1.0.0-alpha.178 → 1.0.0-alpha.179

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 ht}from"@lunora/agent/component";import{LunoraError as X}from"@lunora/errors";import{serializeSchemaSnapshot as $n,hashSchemaSnapshot as Tn}from"./SCHEMA_SNAPSHOT_VERSION-CWESEYLi.mjs";import{isHyperdriveGlobalTable as Nn,isD1GlobalTable as An}from"./isD1GlobalTable-udvHAAzD.mjs";import{s as N}from"./paths-C-9fwEgQ.mjs";import{acceptsAbsentIr as On}from"./LUNORA_ERROR_CODES-C2s0xWQD.mjs";const mt=[{contextProperty:"access",key:"access",moduleSpecifier:"@lunora/cloudflare-access",requiredPackage:"@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",requiredPackage:"@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",requiredPackage:"@lunora/bindings",serverCtxField:{field:`
1
+ import{agentComponent as pt}from"@lunora/agent/component";import{LunoraError as X}from"@lunora/errors";import{serializeSchemaSnapshot as $n,hashSchemaSnapshot as Tn}from"./SCHEMA_SNAPSHOT_VERSION-CWESEYLi.mjs";import{isHyperdriveGlobalTable as Nn,isD1GlobalTable as An}from"./isD1GlobalTable-udvHAAzD.mjs";import{s as N}from"./paths-C-9fwEgQ.mjs";import{acceptsAbsentIr as On}from"./LUNORA_ERROR_CODES-C2s0xWQD.mjs";const mt=[{contextProperty:"access",key:"access",moduleSpecifier:"@lunora/cloudflare-access",requiredPackage:"@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",requiredPackage:"@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",requiredPackage:"@lunora/bindings",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",requiredPackage:"@lunora/browser",serverCtxField:{field:`
4
4
  /** Browser Rendering (screenshots/PDF/scrape). Non-deterministic — available only in actions. */
@@ -28,14 +28,14 @@ for (let ${i} = 0; ${i} < ${t}.length; ${i}++) {
28
28
  const ${a} = ${t}[${i}];
29
29
  ${c.pre}${s}[${i}] = ${c.out};
30
30
  }
31
- `;return{out:s,pre:d}},Mn=(e,t,n,r)=>{const o=JSON.stringify(e);if(t.kind==="optional"){if(t.hasRefinement||t.sourceText!==void 0||ft(t))return;const{inner:i}=t;if(!i)return;const a=Ge(i,n,r);if(!a)return;const c=r.next(),d=`__has${String(c)}`,p=`__val${String(c)}`,g=`let ${d} = false;
32
- let ${p};
31
+ `;return{out:s,pre:d}},Mn=(e,t,n,r)=>{const o=JSON.stringify(e);if(t.kind==="optional"){if(t.hasRefinement||t.sourceText!==void 0||ft(t))return;const{inner:i}=t;if(!i)return;const a=Ge(i,n,r);if(!a)return;const c=r.next(),d=`__has${String(c)}`,h=`__val${String(c)}`,g=`let ${d} = false;
32
+ let ${h};
33
33
  if (${n} !== undefined) {
34
- ${a.pre}${p} = ${a.out};
34
+ ${a.pre}${h} = ${a.out};
35
35
  ${d} = true;
36
36
  }
37
- `;return{entry:`...(${d} ? { ${o}: ${p} } : {})`,pre:g}}const s=Ge(t,n,r);if(s)return{entry:`${o}: ${s.out}`,pre:s.pre}},Fn=new Set(Object.getOwnPropertyNames(Object.prototype)),bt=(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(Fn.has(s)){const p=`__f${String(n.next())}`;r+=`const ${p} = Object.hasOwn(${t}, ${a}) ? ${t}[${a}] : undefined;
38
- `,c=p}const d=Mn(s,i,c,n);if(!d)return;r+=d.pre,o.push(d.entry)}return{entries:o.join(", "),pre:r}},yt=e=>{const t=`Object.getPrototypeOf(${e})`;return`if (${t} !== Object.prototype && ${t} !== null) return DEFER;
37
+ `;return{entry:`...(${d} ? { ${o}: ${h} } : {})`,pre:g}}const s=Ge(t,n,r);if(s)return{entry:`${o}: ${s.out}`,pre:s.pre}},Fn=new Set(Object.getOwnPropertyNames(Object.prototype)),bt=(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(Fn.has(s)){const h=`__f${String(n.next())}`;r+=`const ${h} = Object.hasOwn(${t}, ${a}) ? ${t}[${a}] : undefined;
38
+ `,c=h}const d=Mn(s,i,c,n);if(!d)return;r+=d.pre,o.push(d.entry)}return{entries:o.join(", "),pre:r}},yt=e=>{const t=`Object.getPrototypeOf(${e})`;return`if (${t} !== Object.prototype && ${t} !== null) return DEFER;
39
39
  `},Bn=(e,t,n)=>{const r=e.shape??{},o=bt(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;
40
40
  ${yt(t)}${o.pre}const ${i} = { ${o.entries} };
41
41
  `;return{out:i,pre:a}},qn=e=>{let t=0;const r=bt(e,"source",{next:()=>(t+=1,t)});if(r)return`(source) => {
@@ -62,7 +62,7 @@ ${l}
62
62
  `),i=e.tables.map(u=>{const l=u.searchIndexes.map(b=>JSON.stringify(b.name)).join(" | ");return` ${u.name}: ${l||"never"};`}).join(`
63
63
  `),a=e.tables.map(u=>{const l=u.rankIndexes.map(b=>JSON.stringify(b.name)).join(" | ");return` ${u.name}: ${l||"never"};`}).join(`
64
64
  `),c=e.tables.map(u=>{const l=u.shardMode==="global"?"":(u.geoIndexes??[]).map(b=>JSON.stringify(b.name)).join(" | ");return` ${u.name}: ${l||"never"};`}).join(`
65
- `),d=e.vectorIndexes.map(u=>JSON.stringify(u.name)).join(" | ")||"never",p=e.tables.map(u=>Kn(u)).join(`
65
+ `),d=e.vectorIndexes.map(u=>JSON.stringify(u.name)).join(" | ")||"never",h=e.tables.map(u=>Kn(u)).join(`
66
66
 
67
67
  `),g=e.tables.map(u=>` ${u.name}: Insert_${u.name};`).join(`
68
68
  `),y=e.tables.map(u=>{const l=u.relations.map(b=>(f(b.table,"relation target table"),` ${q(b.name)}: ${b.kind==="one"?"OneRelation":"ManyRelation"}<"${b.table}">;`)).join(`
@@ -132,7 +132,7 @@ export type GeoIndexName<T extends keyof DataModel> = GeoIndexNamesByTable[T];
132
132
  /** Union of declared vector index names. \`never\` when none are declared. */
133
133
  export type VectorIndexName = ${d};
134
134
 
135
- ${p}
135
+ ${h}
136
136
 
137
137
  /** Per-table insert shape, accepted by \`ctx.db.<table>.insert(...)\`. */
138
138
  export interface InsertModel {
@@ -197,7 +197,7 @@ export const agents: AgentsRef = {
197
197
  ${i}
198
198
  };
199
199
  `,n.push(`import type { AgentRunInput } from "@lunora/agent";
200
- `)}return{block:r,importLine:n.join("")}},or=()=>Object.keys(ht().functions).toSorted((e,t)=>e.localeCompare(t)),Tt=e=>new Set(e.filter(t=>N(t.filePath)==="agents").map(t=>t.exportName)),ar=()=>new Set(Object.entries(ht().functions).filter(([,e])=>e.visibility==="internal").map(([e])=>e)),sr=(e,t)=>{const n={importLine:"",lines:"",prelude:""};if(e.length===0)return n;const r=Tt(t),o=ar(),s=t.find(a=>N(a.filePath)==="agents"&&o.has(a.exportName));if(s)throw new X("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=or().filter(a=>!r.has(a));return i.length===0?n:{importLine:`import { agentComponent } from "@lunora/agent/component";
200
+ `)}return{block:r,importLine:n.join("")}},or=()=>Object.keys(pt().functions).toSorted((e,t)=>e.localeCompare(t)),Tt=e=>new Set(e.filter(t=>N(t.filePath)==="agents").map(t=>t.exportName)),ar=()=>new Set(Object.entries(pt().functions).filter(([,e])=>e.visibility==="internal").map(([e])=>e)),sr=(e,t)=>{const n={importLine:"",lines:"",prelude:""};if(e.length===0)return n;const r=Tt(t),o=ar(),s=t.find(a=>N(a.filePath)==="agents"&&o.has(a.exportName));if(s)throw new X("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=or().filter(a=>!r.has(a));return i.length===0?n:{importLine:`import { agentComponent } from "@lunora/agent/component";
201
201
  `,lines:i.map(a=>` "agents:${a}": lunoraAgentRuntimeFunctions.${a} as unknown as RegisteredLunoraFunction,`).join(`
202
202
  `),prelude:`
203
203
  /**
@@ -207,7 +207,7 @@ ${i}
207
207
  */
208
208
  const lunoraAgentRuntimeFunctions = agentComponent().functions;
209
209
  `}},ir=(e,t)=>{if(!e)return{importLine:"",lines:"",prelude:""};const n=t.find(r=>N(r.filePath)==="sandbox"&&r.exportName==="invoke");if(n)throw new X("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";
210
- `,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"}},lr=(e,t)=>{if(e.length===0)return[];const n=Tt(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))},cr=(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}))},dr=e=>{const t=e.filter(i=>i.stream);if(t.length===0)return{block:"",body:""};const n=Ye(t),r=n.map(([i,a])=>{const c=a.map(d=>{const p=D(d.chunkType??"unknown",d.filePath),g=D(xe(d.searchParams),d.filePath),y=D(xe(d.params),d.filePath);return` ${q(d.exportName)}: HttpStreamRef<${p}, ${g}, ${y}>;`}).join(`
210
+ `,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"}},lr=(e,t)=>{if(e.length===0)return[];const n=Tt(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))},cr=(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}))},dr=e=>{const t=e.filter(i=>i.stream);if(t.length===0)return{block:"",body:""};const n=Ye(t),r=n.map(([i,a])=>{const c=a.map(d=>{const h=D(d.chunkType??"unknown",d.filePath),g=D(xe(d.searchParams),d.filePath),y=D(xe(d.params),d.filePath);return` ${q(d.exportName)}: HttpStreamRef<${h}, ${g}, ${y}>;`}).join(`
211
211
  `);return` ${q(N(i))}: {
212
212
  ${c}
213
213
  };`}).join(`
@@ -224,12 +224,12 @@ ${r}
224
224
  export const httpStreams: HttpStreamsRef = {
225
225
  ${o}
226
226
  };
227
- `,body:r}},po=e=>{const{agents:t=[],functions:n,httpRoutes:r=[],mutators:o=[],useUmbrella:s=!1,workflows:i=[]}=e,a=ae(s),c=[...n.filter(O=>O.visibility!=="internal"),...lr(t,n),...cr(o,n)],d=n.filter(O=>O.visibility==="internal"),p=ut(c),g=ut(d),y=dr(r),u=`${p}
227
+ `,body:r}},ho=e=>{const{agents:t=[],functions:n,httpRoutes:r=[],mutators:o=[],useUmbrella:s=!1,workflows:i=[]}=e,a=ae(s),c=[...n.filter(O=>O.visibility!=="internal"),...lr(t,n),...cr(o,n)],d=n.filter(O=>O.visibility==="internal"),h=ut(c),g=ut(d),y=dr(r),u=`${h}
228
228
  ${g}
229
229
  ${y.body}`,l=ze(u),b=l.length>0?`
230
230
  import type { ${l.join(", ")} } from "./dataModel.js";
231
- `:"",S=p?`
232
- ${p}
231
+ `:"",S=h?`
232
+ ${h}
233
233
  `:"",x=g?`
234
234
  ${g}
235
235
  `:"",v=rr(i,t),$=`export interface ApiTypes {${S}}
@@ -240,10 +240,10 @@ export const api = anyApi as unknown as ApiTypes;
240
240
  export interface InternalApiTypes {${x}}
241
241
 
242
242
  export const internal = anyApi as unknown as InternalApiTypes;
243
- ${v.block}${y.block}`,A=[...$.includes("FunctionReference<")?["FunctionReference"]:[],...y.block===""?[]:["HttpStreamRef"]],Q=A.length>0?`import type { ${A.join(", ")} } from "${a.client}";
243
+ ${v.block}${y.block}`,A=[...$.includes("FunctionReference<")?["FunctionReference"]:[],...y.block===""?[]:["HttpStreamRef"]],V=A.length>0?`import type { ${A.join(", ")} } from "${a.client}";
244
244
  `:"";return St(`${R}import { anyApi } from "${a.client}";
245
- ${Q}${v.importLine}${b}
246
- ${$}`,s)},ho=e=>e?`${R}import { createSeedClient as createSeedClientBase } from "@lunora/seed";
245
+ ${V}${v.importLine}${b}
246
+ ${$}`,s)},po=e=>e?`${R}import { createSeedClient as createSeedClientBase } from "@lunora/seed";
247
247
  import type { SeedClient, SeedClientOptions } from "@lunora/seed";
248
248
 
249
249
  import schema from "../schema.js";
@@ -260,7 +260,7 @@ import type { InsertModel } from "./dataModel.js";
260
260
  * const { posts } = await seed.posts((x) => x([10, 20]));
261
261
  */
262
262
  export const createSeedClient = (options?: SeedClientOptions): SeedClient<InsertModel> => createSeedClientBase<InsertModel>(schema, options);
263
- `:"",mo=(e,t,n=!1)=>{if(e.length===0||!t)return"";const r=ae(n),o=c=>c.table===void 0?"Row":`Doc<${JSON.stringify(c.table)}> & Row`,s=e.map(c=>{f(c.exportName,"shape export name");const d=o(c),p=D(xe(c.args),c.filePath),g=Object.keys(c.args).length>0,y=g?` args: ${p};`:` args?: ${p};`,u=g?`(args: ${p}) => void`:`(args?: ${p}) => void`,l=`${c.exportName}CollectionOptions`;return`/** Options for the \`${c.exportName}\` shape binding. */
263
+ `:"",mo=(e,t,n=!1)=>{if(e.length===0||!t)return"";const r=ae(n),o=c=>c.table===void 0?"Row":`Doc<${JSON.stringify(c.table)}> & Row`,s=e.map(c=>{f(c.exportName,"shape export name");const d=o(c),h=D(xe(c.args),c.filePath),g=Object.keys(c.args).length>0,y=g?` args: ${h};`:` args?: ${h};`,u=g?`(args: ${h}) => void`:`(args?: ${h}) => void`,l=`${c.exportName}CollectionOptions`;return`/** Options for the \`${c.exportName}\` shape binding. */
264
264
  export interface ${He(l)} {
265
265
  ${y}
266
266
  /**
@@ -314,7 +314,7 @@ import type { Collection } from "@tanstack/db";
314
314
  import { createCollection } from "@tanstack/db";
315
315
  ${a}
316
316
  ${s}
317
- `},ur=(e,t)=>`lunora_${N(e)}_${String(t)}`,pr=`const callRegistered = async <R>(context: CallerCtx, functionPath: string, args: Record<string, unknown> | undefined): Promise<R> => {
317
+ `},ur=(e,t)=>`lunora_${N(e)}_${String(t)}`,hr=`const callRegistered = async <R>(context: CallerCtx, functionPath: string, args: Record<string, unknown> | undefined): Promise<R> => {
318
318
  const registered = LUNORA_FUNCTIONS[functionPath];
319
319
 
320
320
  if (!registered) {
@@ -343,11 +343,11 @@ ${s}
343
343
  }
344
344
 
345
345
  return (await registered.handler(context, args ?? {})) as R;
346
- };`,hr=(e,t,n=[],r=[])=>{const o=new Map,s=l=>{o.has(l)||o.set(l,ur(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,b])=>{if(!jn.test(l))throw new X("INTERNAL",`@lunora/codegen: refusing to emit import for unsafe file path: ${JSON.stringify(l)}`);return`import * as ${b} from "../${l}.js";`}).join(`
346
+ };`,pr=(e,t,n=[],r=[])=>{const o=new Map,s=l=>{o.has(l)||o.set(l,ur(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,b])=>{if(!jn.test(l))throw new X("INTERNAL",`@lunora/codegen: refusing to emit import for unsafe file path: ${JSON.stringify(l)}`);return`import * as ${b} from "../${l}.js";`}).join(`
347
347
  `),a=e.map(l=>` "${N(l.filePath)}:${l.exportName}": ${o.get(l.filePath)??""}.${l.exportName} as unknown as RegisteredLunoraFunction,`).join(`
348
348
  `),c=t.map(l=>` ${JSON.stringify(l.id)}: ${o.get(l.filePath)??""}.${l.exportName} as unknown as RegisteredDataMigration,`).join(`
349
349
  `),d=n.map(l=>` "${N(l.filePath)}:${l.exportName}": ${o.get(l.filePath)??""}.${l.exportName} as unknown as RegisteredLunoraFunction,`).join(`
350
- `),p=r.map(l=>` "${l.exportName}": ${o.get(l.filePath)??""}.${l.exportName} as unknown as RegisteredShape,`).join(`
350
+ `),h=r.map(l=>` "${l.exportName}": ${o.get(l.filePath)??""}.${l.exportName} as unknown as RegisteredShape,`).join(`
351
351
  `),g=n.map(l=>`${N(l.filePath)}:${l.exportName}`),y=[a,d].filter(l=>l.length>0).join(`
352
352
  `),u=e.map(l=>{if(l.lifecycle||Object.keys(l.args).length===0)return;const b=qn(l.args);return b===void 0?void 0:`installCompiledValidatorMap(${o.get(l.filePath)??""}.${l.exportName}.args, ${b});`}).filter(l=>l!==void 0).join(`
353
353
  `);return{dispatchBody:y.length>0?`
@@ -356,9 +356,9 @@ ${y}
356
356
 
357
357
  `:"",installBlock:u,migrationBody:c.length>0?`
358
358
  ${c}
359
- `:"",mutatorPaths:g,shapeBody:p.length>0?`
360
- ${p}
361
- `:""}},mr=e=>{const t=Ye(e),n=t.map(([o,s])=>{const i=s.map(a=>{const c=D(xe(a.args),a.filePath),d=c==="{}"?"?":"",p=D($t(a),a.filePath);return a.kind==="stream"?` ${a.exportName}: (args${d}: ${c}) => Promise<AsyncIterable<${p}>>;`:` ${a.exportName}: (args${d}: ${c}) => Promise<${p}>;`}).join(`
359
+ `:"",mutatorPaths:g,shapeBody:h.length>0?`
360
+ ${h}
361
+ `:""}},mr=e=>{const t=Ye(e),n=t.map(([o,s])=>{const i=s.map(a=>{const c=D(xe(a.args),a.filePath),d=c==="{}"?"?":"",h=D($t(a),a.filePath);return a.kind==="stream"?` ${a.exportName}: (args${d}: ${c}) => Promise<AsyncIterable<${h}>>;`:` ${a.exportName}: (args${d}: ${c}) => Promise<${h}>;`}).join(`
362
362
  `);return` ${q(N(o))}: {
363
363
  ${i}
364
364
  };`}).join(`
@@ -366,21 +366,21 @@ ${i}
366
366
  `);return` ${Y(i)}: {
367
367
  ${a}
368
368
  },`}).join(`
369
- `),types:n}},gr=(e,t=[])=>{const n=new Set;for(const r of e.tables)for(const o of Object.values(r.shape)){const s=se(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))]},go=({agents:e=[],containers:t=[],env:n,hasAccessFacade:r=!1,hasAi:o=!1,hasAnalytics:s=!1,hasBrowser:i=!1,hasVectors:a=!0,hasFlags:c=!1,hasHyperdrive:d=!1,hasImages:p=!1,hasKv:g=!1,hasNotify:y=!1,hasPayments:u=!1,hasPipelines:l=!1,hasR2sql:b=!1,hasX402:S=!1,identity:x,queues:v=[],schema:$,storageRuleBuckets:A=[],useUmbrella:Q=!1,workflows:O=[]}={})=>{const C=ae(Q),w=gr($??{tables:[]},A).map(h=>JSON.stringify(h)).join(" | "),P=o?`import type { LunoraAi } from "@lunora/ai";
369
+ `),types:n}},gr=(e,t=[])=>{const n=new Set;for(const r of e.tables)for(const o of Object.values(r.shape)){const s=se(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))]},go=({agents:e=[],containers:t=[],env:n,hasAccessFacade:r=!1,hasAi:o=!1,hasAnalytics:s=!1,hasBrowser:i=!1,hasVectors:a=!0,hasFlags:c=!1,hasHyperdrive:d=!1,hasImages:h=!1,hasKv:g=!1,hasNotify:y=!1,hasPayments:u=!1,hasPipelines:l=!1,hasR2sql:b=!1,hasX402:S=!1,identity:x,queues:v=[],schema:$,storageRuleBuckets:A=[],useUmbrella:V=!1,workflows:O=[]}={})=>{const C=ae(V),w=gr($??{tables:[]},A).map(p=>JSON.stringify(p)).join(" | "),P=o?`import type { LunoraAi } from "@lunora/ai";
370
370
  `:"",M=o?`
371
371
  readonly ai: LunoraAi;`:"",ie=u?`import type { LunoraPayment } from "@lunora/payment";
372
372
  `:"",le=u?`
373
373
  readonly payments: LunoraPayment;`:"",Z=S?`import type { X402Pay } from "@lunora/x402/pay";
374
- `:"",V=S?`
374
+ `:"",H=S?`
375
375
  readonly x402: X402Pay;`:"",L=t.length>0?`import type { ContainerAccessor } from "@lunora/container";
376
376
  `:"",ee=t.length>0?`
377
- readonly containers: {${t.map(h=>`
378
- readonly ${h.exportName}: ContainerAccessor;`).join("")}
379
- };`:"",k=[...o?[" /** Workers AI binding (the conventional `env.AI`), narrowing `ctx.ai`. */\n readonly AI?: unknown;"]:[],...t.map(h=>(f(h.bindingName,`container binding "${h.bindingName}"`),` /** Durable Object namespace for the \`${h.exportName}\` container. */
380
- readonly ${h.bindingName}?: unknown;`)),...O.map(h=>(f(h.bindingName,`workflow binding "${h.bindingName}"`),` /** Workflow binding for the \`${h.exportName}\` workflow. */
381
- readonly ${h.bindingName}?: unknown;`)),...v.map(h=>(f(h.bindingName,`queue binding "${h.bindingName}"`),` /** Queue producer binding for the \`${h.exportName}\` queue. */
382
- readonly ${h.bindingName}?: unknown;`)),...e.map(h=>(f(h.bindingName,`agent binding "${h.bindingName}"`),` /** Workflow binding for the \`${h.exportName}\` agent. */
383
- readonly ${h.bindingName}?: unknown;`))].join(`
377
+ readonly containers: {${t.map(p=>`
378
+ readonly ${p.exportName}: ContainerAccessor;`).join("")}
379
+ };`:"",k=[...o?[" /** Workers AI binding (the conventional `env.AI`), narrowing `ctx.ai`. */\n readonly AI?: unknown;"]:[],...t.map(p=>(f(p.bindingName,`container binding "${p.bindingName}"`),` /** Durable Object namespace for the \`${p.exportName}\` container. */
380
+ readonly ${p.bindingName}?: unknown;`)),...O.map(p=>(f(p.bindingName,`workflow binding "${p.bindingName}"`),` /** Workflow binding for the \`${p.exportName}\` workflow. */
381
+ readonly ${p.bindingName}?: unknown;`)),...v.map(p=>(f(p.bindingName,`queue binding "${p.bindingName}"`),` /** Queue producer binding for the \`${p.exportName}\` queue. */
382
+ readonly ${p.bindingName}?: unknown;`)),...e.map(p=>(f(p.bindingName,`agent binding "${p.bindingName}"`),` /** Workflow binding for the \`${p.exportName}\` agent. */
383
+ readonly ${p.bindingName}?: unknown;`))].join(`
384
384
  `),Ae=`
385
385
 
386
386
  /**
@@ -399,9 +399,9 @@ ${k}`:""}
399
399
  }
400
400
 
401
401
  /** Alias for {@link CloudflareBindings} — the typed shape of \`env\`. */
402
- export type Env = CloudflareBindings;`,F=(h,We,Te)=>{const re=Cn.get(h);if(re!==void 0&&re.tier!==Te)throw new X("INTERNAL",`@lunora/codegen: capability "${h}" declares tier "${re.tier}" in SERVER_CTX_FIELDS but is emitted onto the "${Te}" context — update whichever is wrong.`);return We?re?.field??"":""},ce=F("kv",g,"every"),de=F("analytics",s,"every"),Oe=F("hyperdrive",d,"action"),Ie=F("browser",i,"action"),Ce=F("images",p,"action"),ue=F("pipelines",l,"action"),H=F("r2sql",b,"action"),_=a&&($?.vectorIndexes.length??0)>0,G=_?' | "vectors"':"",te=_?`
403
- readonly vectors: VectorSearch<VectorIndexName>;`:"",pe=_?`
404
- readonly vectors: VectorSearchReader<VectorIndexName>;`:"",J=_?`import type { VectorSearch, VectorSearchReader } from "${C.server}";
402
+ export type Env = CloudflareBindings;`,F=(p,We,Te)=>{const re=Cn.get(p);if(re!==void 0&&re.tier!==Te)throw new X("INTERNAL",`@lunora/codegen: capability "${p}" declares tier "${re.tier}" in SERVER_CTX_FIELDS but is emitted onto the "${Te}" context — update whichever is wrong.`);return We?re?.field??"":""},ce=F("kv",g,"every"),de=F("analytics",s,"every"),Oe=F("hyperdrive",d,"action"),Ie=F("browser",i,"action"),Ce=F("images",h,"action"),ue=F("pipelines",l,"action"),G=F("r2sql",b,"action"),_=a&&($?.vectorIndexes.length??0)>0,J=_?' | "vectors"':"",te=_?`
403
+ readonly vectors: VectorSearch<VectorIndexName>;`:"",he=_?`
404
+ readonly vectors: VectorSearchReader<VectorIndexName>;`:"",z=_?`import type { VectorSearch, VectorSearchReader } from "${C.server}";
405
405
  import type { VectorIndexName } from "./dataModel.js";
406
406
  `:"",j=r?`
407
407
  /** Verified Cloudflare Access identity — a synchronous facade over the resolved claims (email / groups / hasGroup / claims). Anonymous when no Access token is present. */
@@ -424,27 +424,27 @@ type WorkflowParamsOf<Definition> = Definition extends { __params?: infer Params
424
424
 
425
425
  /** This project's declared workflows, addressable from \`ctx.workflows\` by their \`lunora/workflows.ts\` export name. */
426
426
  export interface LunoraWorkflows {
427
- ${O.map(h=>` get(name: ${JSON.stringify(h.exportName)}): WorkflowHandle<WorkflowParamsOf<typeof lunoraWorkflowDefinitions.${h.exportName}>>;`).join(`
427
+ ${O.map(p=>` get(name: ${JSON.stringify(p.exportName)}): WorkflowHandle<WorkflowParamsOf<typeof lunoraWorkflowDefinitions.${p.exportName}>>;`).join(`
428
428
  `)}
429
429
  }`:"",ve=B?' | "workflows"':"",Re=B?`
430
- readonly workflows: LunoraWorkflows;`:"",he=v.length>0,De=he?`import type { QueueProducer } from "@lunora/queue";
430
+ readonly workflows: LunoraWorkflows;`:"",pe=v.length>0,De=pe?`import type { QueueProducer } from "@lunora/queue";
431
431
  import type * as lunoraQueueDefinitions from "../queues.js";
432
- `:"",Ee=he?`
432
+ `:"",Ee=pe?`
433
433
 
434
434
  /** Message body type carried by a \`defineQueue\` definition (its phantom \`__lunoraBody\`). */
435
435
  type QueueBodyOf<Definition> = Definition extends { __lunoraBody?: infer Body } ? (unknown extends Body ? unknown : NonNullable<Body>) : unknown;
436
436
 
437
437
  /** This project's declared queues, addressable from \`ctx.queues\` by their \`lunora/queues.ts\` export name. */
438
438
  export interface LunoraQueues {
439
- ${v.map(h=>` readonly ${h.exportName}: QueueProducer<QueueBodyOf<typeof lunoraQueueDefinitions.${h.exportName}>>;`).join(`
439
+ ${v.map(p=>` readonly ${p.exportName}: QueueProducer<QueueBodyOf<typeof lunoraQueueDefinitions.${p.exportName}>>;`).join(`
440
440
  `)}
441
- }`:"",Se=he?`
441
+ }`:"",Se=pe?`
442
442
  readonly queues: LunoraQueues;`:"",me=e.length>0,_e=me?`import type { AgentHandle } from "@lunora/agent";
443
443
  `:"",Pe=me?`
444
444
 
445
445
  /** This project's declared agents, addressable from \`ctx.agents\` by their \`lunora/agents.ts\` export name. */
446
446
  export interface LunoraAgents {
447
- ${e.map(h=>(f(h.exportName,`agent export "${h.exportName}"`),` readonly ${h.exportName}: AgentHandle;`)).join(`
447
+ ${e.map(p=>(f(p.exportName,`agent export "${p.exportName}"`),` readonly ${p.exportName}: AgentHandle;`)).join(`
448
448
  `)}
449
449
  }`:"",$e=me?`
450
450
  readonly agents: LunoraAgents;`:"",Me=x?`import type { InferIdentity } from "${C.server}";
@@ -517,7 +517,7 @@ export type {
517
517
  } from "${C.serverDataModel}";
518
518
 
519
519
  import type { DataModel, Doc, GeoIndexNamesByTable, Id as IdOfTable, IndexNamesByTable, Insert, InsertModel, RankIndexNamesByTable, Relations, SearchIndexNamesByTable, TableName } from "./dataModel.js";
520
- ${J}${P}${ie}${Z}${L}${ne}${De}${_e}${Me}${qe}
520
+ ${z}${P}${ie}${Z}${L}${ne}${De}${_e}${Me}${qe}
521
521
  export type { AppTableName, DataModel, Doc, Id, TableName } from "./dataModel.js";
522
522
 
523
523
  /**
@@ -640,22 +640,22 @@ type AsIdTable<T extends string> = T extends TableName ? T : string extends T ?
640
640
  */
641
641
  type TypedAsId = <T extends string>(tableName: AsIdTable<T>, id: string) => IdOfTable<T & TableName>;
642
642
 
643
- export interface QueryCtx extends Omit<QueryCtxBase, "db" | "storage"${G}${ge}${be}> {
643
+ export interface QueryCtx extends Omit<QueryCtxBase, "db" | "storage"${J}${ge}${be}> {
644
644
  readonly db: Omit<DatabaseReader, "asId" | "query" | "get"> & DatabaseReaderFacade & { asId: TypedAsId; query: TypedTableQuery; get: TypedTableGet };
645
645
  readonly orm: OrmReader;
646
- readonly storage: ReadOnlyStorage<StorageBucketName>;${pe}${j}${ce}${W}${U}${de}${ye}${fe}
646
+ readonly storage: ReadOnlyStorage<StorageBucketName>;${he}${j}${ce}${W}${U}${de}${ye}${fe}
647
647
  }
648
648
 
649
- export interface MutationCtx extends Omit<MutationCtxBase, "db" | "storage"${G}${ve}${ge}${be}> {
649
+ export interface MutationCtx extends Omit<MutationCtxBase, "db" | "storage"${J}${ve}${ge}${be}> {
650
650
  readonly db: Omit<DatabaseWriter, "asId" | "query" | "get"> & DatabaseWriterFacade & { asId: TypedAsId; query: TypedTableQuery; get: TypedTableGet };
651
651
  readonly orm: OrmWriter;
652
652
  readonly storage: MutationStorage<StorageBucketName>;${te}${j}${ce}${W}${U}${de}${ye}${Re}${Se}${$e}${fe}
653
653
  }
654
654
 
655
- export interface ActionCtx extends Omit<ActionCtxBase, "db" | "storage"${G}${ve}${ge}${be}> {
655
+ export interface ActionCtx extends Omit<ActionCtxBase, "db" | "storage"${J}${ve}${ge}${be}> {
656
656
  readonly db: Omit<DatabaseWriter, "asId" | "query" | "get"> & DatabaseWriterFacade & { asId: TypedAsId; query: TypedTableQuery; get: TypedTableGet };
657
657
  readonly orm: OrmWriter;
658
- readonly storage: StorageBase<StorageBucketName>;${te}${j}${M}${le}${V}${ee}${ce}${W}${U}${Oe}${Ie}${Ce}${de}${ue}${H}${ye}${Re}${Se}${$e}${fe}
658
+ readonly storage: StorageBase<StorageBucketName>;${te}${j}${M}${le}${H}${ee}${ce}${W}${U}${Oe}${Ie}${Ce}${de}${ue}${G}${ye}${Re}${Se}${$e}${fe}
659
659
  }
660
660
 
661
661
  /**
@@ -730,12 +730,12 @@ export const definePolicy = createPolicyDsl<DataModel, Relations${Be}>();
730
730
  export const v = vBase as unknown as Omit<typeof vBase, "id"> & {
731
731
  id: <T extends TableName>(table: T) => ColumnValidator<IdOfTable<T>, IdOfTable<T>>;
732
732
  };
733
- `},fr=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},fo=e=>{const{agents:t=[],functions:n,migrations:r=[],mutators:o=[],shapes:s=[],useUmbrella:i=!1,usesSandbox:a=!1}=e,c=n.length>0,d=ae(i),{dispatchBody:p,importBlock:g,installBlock:y,migrationBody:u,mutatorPaths:l,shapeBody:b}=hr(n,r,o,s),S=sr(t,n),x=ir(a,n),v=[S.lines,x.lines].filter(k=>k.length>0).join(`
734
- `);let $=p;v.length>0&&($=p.length>0?`${p.trimEnd()}
733
+ `},fr=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},fo=e=>{const{agents:t=[],functions:n,migrations:r=[],mutators:o=[],shapes:s=[],useUmbrella:i=!1,usesSandbox:a=!1}=e,c=n.length>0,d=ae(i),{dispatchBody:h,importBlock:g,installBlock:y,migrationBody:u,mutatorPaths:l,shapeBody:b}=pr(n,r,o,s),S=sr(t,n),x=ir(a,n),v=[S.lines,x.lines].filter(k=>k.length>0).join(`
734
+ `);let $=h;v.length>0&&($=h.length>0?`${h.trimEnd()}
735
735
  ${v}
736
736
  `:`
737
737
  ${v}
738
- `);const A=fr(n),Q=s.length>0?`import type { RegisteredShape } from "${d.server}";
738
+ `);const A=fr(n),V=s.length>0?`import type { RegisteredShape } from "${d.server}";
739
739
  `:"",O=s.length>0?`
740
740
  /**
741
741
  * Replication-shape registry — one entry per \`defineShape\` in \`lunora/shapes.ts\`.
@@ -763,12 +763,12 @@ ${y}
763
763
  ${M.types}
764
764
  `:"",le=M.implementation?`
765
765
  ${M.implementation}
766
- `:"",Z=ze(M.types),V=Z.length>0?`import type { ${Z.join(", ")} } from "./dataModel.js";
767
- `:"",L=c?"context":"_context",ee=c?`${pr}
766
+ `:"",Z=ze(M.types),H=Z.length>0?`import type { ${Z.join(", ")} } from "./dataModel.js";
767
+ `:"",L=c?"context":"_context",ee=c?`${hr}
768
768
 
769
- `:"";return St(`${R}${g}${S.importLine}${x.importLine}${w}${Q}import { LunoraError } from "${d.server}";
769
+ `:"";return St(`${R}${g}${S.importLine}${x.importLine}${w}${V}import { LunoraError } from "${d.server}";
770
770
  import type { ActionCtx, MutationCtx, QueryCtx } from "./server.js";
771
- ${V}
771
+ ${H}
772
772
  /**
773
773
  * Single registered function, narrowed to the shape \`handleRpc\` needs.
774
774
  * The real argument validators / return types are checked elsewhere — at
@@ -1119,8 +1119,8 @@ export class ${a.className} extends LunoraWorkflow<AgentRunInput, AgentRunResult
1119
1119
  super(ctx, env, compileAgentWorkflow(${a.exportName}, "${a.exportName}"), "${a.exportName}");
1120
1120
  }
1121
1121
  }
1122
- `;if(!a.voice)return c;const d=a.voiceClassName??"",p=a.voiceBindingName??"";f(d,`agent voice class "${d}"`);const g=`
1123
- /** Voice-session Durable Object for the \`${a.exportName}\` agent (binding \`${p}\`). */
1122
+ `;if(!a.voice)return c;const d=a.voiceClassName??"",h=a.voiceBindingName??"";f(d,`agent voice class "${d}"`);const g=`
1123
+ /** Voice-session Durable Object for the \`${a.exportName}\` agent (binding \`${h}\`). */
1124
1124
  export class ${d} extends VoiceSessionDO {
1125
1125
  public constructor(ctx: ConstructorParameters<typeof VoiceSessionDO>[0], env: Record<string, unknown>) {
1126
1126
  super(ctx, env, ${a.exportName}, "${a.exportName}");
@@ -1201,10 +1201,10 @@ const ${e}: ${t} = ${JSON.stringify(r,void 0,4)};
1201
1201
  ? lazyX402Pay(config.x402(env), { getSecret: (name: string) => secrets.get(name) })
1202
1202
  : x402Stub;
1203
1203
  `,configField:`
1204
- x402?: (env: Record<string, unknown>) => X402PayConfig;`,stub:I("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:""},Vr=(e,t,n,r,o)=>["AdvisorProcedure","AdvisoryFinding","DatabaseWriterLike","DataMigrationLike","DispatchBookmark","ExportRow",...r?["FlagsResult"]:[],"ImportShardResult","KeyRange","MaskPoliciesResult","MigrationRunResult","QueryReadScope",...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"]:[]],xo=({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:g=!1,hasImages:y=!1,hasKv:u=!1,hasNotify:l=!1,hasPayments:b=!1,hasPipelines:S=!1,hasR2sql:x=!1,hasVectors:v=!0,hasX402:$=!1,maskMetadata:A,mutators:Q=[],queues:O=[],rlsMetadata:C,schema:w,schemaSnapshot:P,shapes:M=[],storageRules:ie,studioFeatures:le,useUmbrella:Z=!1,workflows:V=[]})=>{const L=ae(Z),ee=Q.length>0,k=M.length>0,Ae=P===void 0?"":$n(P),F=P===void 0?"":`
1204
+ x402?: (env: Record<string, unknown>) => X402PayConfig;`,stub:I("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:""},Vr=(e,t,n,r,o)=>["AdvisorProcedure","AdvisoryFinding","DatabaseWriterLike","DataMigrationLike","DispatchBookmark","ExportRow",...r?["FlagsResult"]:[],"ImportShardResult","KeyRange","MaskPoliciesResult","MigrationRunResult","QueryReadScope",...n?["QueuesResult"]:[],"RelatedPage","RunShardApplyCdcArgs","RunShardExportArgs","RunShardFindRelatedArgs","RunShardImportArgs","RunShardMigrationArgs","RlsPoliciesResult","RunShardRankBeforeArgs","RunShardRankPageArgs","RunShardWriteArgs","RunShardWriteResult","SchedulerLike",...o?["SearchBackfillProgress"]:[],"TransactionHeadroomTracker","SchemaLike","ShardDOState","ShardRankPageResult","SqlExec","StorageRulesResult","StudioFeaturesResult","SystemReaderStorageLike","TelemetrySink",...t?["WorkflowsResult"]:[],...e?["WriteHook"]:[]],xo=({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:h=!1,hasHyperdrive:g=!1,hasImages:y=!1,hasKv:u=!1,hasNotify:l=!1,hasPayments:b=!1,hasPipelines:S=!1,hasR2sql:x=!1,hasVectors:v=!0,hasX402:$=!1,maskMetadata:A,mutators:V=[],queues:O=[],rlsMetadata:C,schema:w,schemaSnapshot:P,shapes:M=[],storageRules:ie,studioFeatures:le,useUmbrella:Z=!1,workflows:H=[]})=>{const L=ae(Z),ee=V.length>0,k=M.length>0,Ae=P===void 0?"":$n(P),F=P===void 0?"":`
1205
1205
  /** 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. */
1206
1206
  const LUNORA_SCHEMA_SNAPSHOT: { hash: string; json: string } = { hash: ${JSON.stringify(Tn(P))}, json: ${JSON.stringify(Ae)} };
1207
- `,ce=P===void 0?"":", schemaSnapshot: LUNORA_SCHEMA_SNAPSHOT",{build:de,configField:Oe,contextField:Ie,stub:Ce}=$r(a),ue=Ir(i),H=Tr(u),_=Nr(p,L.flags),G=Cr(s,p,L.flags),te=Ar(l),pe=Or(o),J=Lr(c),j=Dr(y),W=Er(g),U=_r(d),B=Pr(x),ne=Mr(S),{build:Le,contextField:ve,importLines:Re,specs:he}=qr(O),{build:De,contextField:Ee,importLines:Se,specs:me}=Fr(r,w.jurisdiction),{build:_e,contextField:Pe,importLines:$e,specs:Me}=Br(V),{build:Fe,contextField:ge,importLines:fe,specs:Be}=jr(n),{build:qe,configField:je,contextField:be,imports:ye,stub:Ze}=Kr(b),{build:h,configField:We,imports:Te,stub:re}=Qr($),Ot=e,It=t,et=C??{policies:[],roles:[]},Ct=A??{columns:[]},Lt=ie??{rules:[]},Dt=le??{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:Et,override:_t}=Wr(V),{constant:Pt,override:Mt}=Ur(O),K=v&&w.vectorIndexes.length>0,tt=new Set(w.tables.filter(m=>typeof m.shardMode=="object"&&m.shardMode.kind==="shardBy").map(m=>m.name)),Ne=K&&w.vectorIndexes.some(m=>tt.has(m.table)),we=w.tables.some(m=>m.shardMode==="global"),Ue=w.tables.some(m=>Nn(m)),nt=w.tables.some(m=>An(m)),oe=w.tables.some(m=>m.externalSource!==void 0),rt=w.tables.some(m=>m.memory===!0),Ke=w.tables.some(m=>m.shardMode!=="global"&&m.searchIndexes.length>0);if(nt&&Ue)throw new X("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=w.tables.length>0,Ft=br(w),Bt=wr(w),qt=Rr(w),jt=yr(w),ot=kr(w),at=Vr(K,V.length>0,O.length>0,p,Ke);k&&at.push("WhereInput");const st=Sr(we),Wt=k?`
1207
+ `,ce=P===void 0?"":", schemaSnapshot: LUNORA_SCHEMA_SNAPSHOT",{build:de,configField:Oe,contextField:Ie,stub:Ce}=$r(a),ue=Ir(i),G=Tr(u),_=Nr(h,L.flags),J=Cr(s,h,L.flags),te=Ar(l),he=Or(o),z=Lr(c),j=Dr(y),W=Er(g),U=_r(d),B=Pr(x),ne=Mr(S),{build:Le,contextField:ve,importLines:Re,specs:pe}=qr(O),{build:De,contextField:Ee,importLines:Se,specs:me}=Fr(r,w.jurisdiction),{build:_e,contextField:Pe,importLines:$e,specs:Me}=Br(H),{build:Fe,contextField:ge,importLines:fe,specs:Be}=jr(n),{build:qe,configField:je,contextField:be,imports:ye,stub:Ze}=Kr(b),{build:p,configField:We,imports:Te,stub:re}=Qr($),Ot=e,It=t,et=C??{policies:[],roles:[]},Ct=A??{columns:[]},Lt=ie??{rules:[]},Dt=le??{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:Et,override:_t}=Wr(H),{constant:Pt,override:Mt}=Ur(O),K=v&&w.vectorIndexes.length>0,tt=new Set(w.tables.filter(m=>typeof m.shardMode=="object"&&m.shardMode.kind==="shardBy").map(m=>m.name)),Ne=K&&w.vectorIndexes.some(m=>tt.has(m.table)),we=w.tables.some(m=>m.shardMode==="global"),Ue=w.tables.some(m=>Nn(m)),nt=w.tables.some(m=>An(m)),oe=w.tables.some(m=>m.externalSource!==void 0),rt=w.tables.some(m=>m.memory===!0),Ke=w.tables.some(m=>m.shardMode!=="global"&&m.searchIndexes.length>0);if(nt&&Ue)throw new X("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=w.tables.length>0,Ft=br(w),Bt=wr(w),qt=Rr(w),jt=yr(w),ot=kr(w),at=Vr(K,H.length>0,O.length>0,h,Ke);k&&at.push("WhereInput");const st=Sr(we),Wt=k?`
1208
1208
  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 {
1209
1209
  const shape = LUNORA_SHAPES[name];
1210
1210
 
@@ -1275,7 +1275,7 @@ assertShapesDeclareReadPolicies(LUNORA_SHAPES, ${JSON.stringify(it)}, (schema as
1275
1275
  protected override isCustomMutator(functionPath: string): boolean {
1276
1276
  return LUNORA_MUTATOR_PATHS.has(functionPath);
1277
1277
  }
1278
- `:"",Kt=k?"assertShapeShardable, ":"",Qt=lt===""?"":"assertShapesDeclareReadPolicies, ",ke=[`import type { ${at.join(", ")} } from "${L.do}";`,`import { applyCdcChanges, ${Ke?"backfillSearchIndexes, ":""}buildReprojectionMigration, ${rt?"clearMemoryTables, ":""}${Kt}createReadFootprint, createShardCtxDb, exportShardRows, importShardRows, ${oe?"isSourceDue, pullExternalSourceIncrementalTick, pullExternalSourceTick, ":""}markUnvouchableReads, ${Ne?"ROOT_SHARD_NAME, ":""}runDataMigration, runShardMigrations, ${st.importFragment}ShardDO as ShardDOBase } from "${L.do}";`,...oe?[`import type { ExternalSourceLike, SourceClientLike, TraceRefLike } from "${L.do}";`]:[],k?`import { asBucketStorage, ${Qt}beginDeferredSchedules, composeShapeReadWhere, createSecrets, flushDeferredDeletes, LunoraError, withDeferredDeletes, withDeferredSchedules } from "${L.server}";`:`import { asBucketStorage, beginDeferredSchedules, createSecrets, flushDeferredDeletes, LunoraError, withDeferredDeletes, withDeferredSchedules } from "${L.server}";`];Qe&&ke.push(`import { bindOrm, bindTableFacade } from "${L.server}";`),K&&ke.push('import type { SchemaLike as VectorSchemaLike, VectorizeIndexLike, VectorSearchLike } from "@lunora/bindings/vectors";','import { createContextVectors, createVectors, createVectorSyncHook } from "@lunora/bindings/vectors";'),a&&ke.push('import type { AiBindingLike, LunoraAi } from "@lunora/ai";','import { createAi } from "@lunora/ai";'),ke.push(...ue.importLines,...H.importLines,..._.importLines,...te.importLines,...pe.importLines,...J.importLines,...j.importLines,...W.importLines,...U.importLines,...B.importLines,...ne.importLines,...Se,...$e,...Re,...fe,...ye,...Te,"",'import schema from "../schema.js";',`import { ${["LUNORA_FUNCTIONS","LUNORA_LIFECYCLE_HOOKS","LUNORA_MIGRATIONS",...ee?["LUNORA_MUTATOR_PATHS"]:[],...k?["LUNORA_SHAPES"]:[]].join(", ")} } from "./functions.js";`);const Vt=K?`
1278
+ `:"",Kt=k?"assertShapeShardable, ":"",Qt=lt===""?"":"assertShapesDeclareReadPolicies, ",ke=[`import type { ${at.join(", ")} } from "${L.do}";`,`import { applyCdcChanges, ${Ke?"backfillSearchIndexes, ":""}buildReprojectionMigration, ${rt?"clearMemoryTables, ":""}${Kt}createReadFootprint, createShardCtxDb, exportShardRows, importShardRows, ${oe?"isSourceDue, pullExternalSourceIncrementalTick, pullExternalSourceTick, ":""}markUnvouchableReads, ${Ne?"ROOT_SHARD_NAME, ":""}runDataMigration, runShardMigrations, ${st.importFragment}ShardDO as ShardDOBase } from "${L.do}";`,...oe?[`import type { ExternalSourceLike, SourceClientLike, TraceRefLike } from "${L.do}";`]:[],k?`import { asBucketStorage, ${Qt}beginDeferredDeletes, beginDeferredSchedules, composeShapeReadWhere, createSecrets, flushDeferredDeletes, LunoraError, withDeferredDeletes, withDeferredSchedules } from "${L.server}";`:`import { asBucketStorage, beginDeferredDeletes, beginDeferredSchedules, createSecrets, flushDeferredDeletes, LunoraError, withDeferredDeletes, withDeferredSchedules } from "${L.server}";`];Qe&&ke.push(`import { bindOrm, bindTableFacade } from "${L.server}";`),K&&ke.push('import type { SchemaLike as VectorSchemaLike, VectorizeIndexLike, VectorSearchLike } from "@lunora/bindings/vectors";','import { createContextVectors, createVectors, createVectorSyncHook } from "@lunora/bindings/vectors";'),a&&ke.push('import type { AiBindingLike, LunoraAi } from "@lunora/ai";','import { createAi } from "@lunora/ai";'),ke.push(...ue.importLines,...G.importLines,..._.importLines,...te.importLines,...he.importLines,...z.importLines,...j.importLines,...W.importLines,...U.importLines,...B.importLines,...ne.importLines,...Se,...$e,...Re,...fe,...ye,...Te,"",'import schema from "../schema.js";',`import { ${["LUNORA_FUNCTIONS","LUNORA_LIFECYCLE_HOOKS","LUNORA_MIGRATIONS",...ee?["LUNORA_MUTATOR_PATHS"]:[],...k?["LUNORA_SHAPES"]:[]].join(", ")} } from "./functions.js";`);const Vt=K?`
1279
1279
  vectors?: (env: Record<string, unknown>) => Record<string, VectorizeIndexLike>;`:"",Ht=nt?`
1280
1280
  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;`:"",Gt=Ue?`
1281
1281
  hyperdriveGlobal?: (env: Record<string, unknown>, request?: { cdc?: boolean; cdcRetentionMs?: number; identity?: Record<string, unknown>; userId?: string }) => DatabaseWriterLike | undefined;`:"",Jt=oe?`
@@ -1371,11 +1371,11 @@ ${nn}
1371
1371
  schema: schema as unknown as SchemaLike,
1372
1372
  sql: this.sql as SqlExec,
1373
1373
  });
1374
- }`,z=(m="")=>` const writer = this.adminWriter(${m});`,cn=K?`
1374
+ }`,Q=(m="")=>` const writer = this.adminWriter(${m});`,cn=K?`
1375
1375
  vectors,`:"",dn=Qe?`
1376
1376
  orm: bindOrm(facade),`:"",Ve=Ue?"config.hyperdriveGlobal":"config.d1",un=we?` const globalRequest = { ...this.globalCdcOptions(config.cdc ?? false), bookmark: this.getInboundBookmark(), identity, onBookmark: (bookmarkValue: string | undefined) => { if (options.bookmarks !== undefined) { options.bookmarks.value = bookmarkValue; } }, userId };
1377
1377
  const globalDb: DatabaseWriterLike = ${Ve}?.(env, globalRequest) ?? globalDbStub;
1378
- `:"",pn=k&&we?`
1378
+ `:"",hn=k&&we?`
1379
1379
  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 }>> {
1380
1380
  const env = this.env as Record<string, unknown>;
1381
1381
  // A shape read performs no writes, so the widened request only needs
@@ -1420,7 +1420,7 @@ ${nn}
1420
1420
 
1421
1421
  return globalDb.cdcChangedTables?.(sinceSeq, { cursorOnly });
1422
1422
  }
1423
- `:"",hn=oe?`
1423
+ `:"",pn=oe?`
1424
1424
  const sourceClientCache = new WeakMap<object, Map<string, SourceClientLike>>();
1425
1425
  const sourcePollAtCache = new WeakMap<object, Map<string, number>>();
1426
1426
  `:"",mn=`
@@ -1610,14 +1610,14 @@ ${oe?`
1610
1610
  const facade = db as unknown as Record<string, ReturnType<typeof bindTableFacade>>;
1611
1611
  ${w.tables.map(m=>` facade[${JSON.stringify(m.name)}] = bindTableFacade(db, ${JSON.stringify(m.name)});`).join(`
1612
1612
  `)}
1613
- `:"",wn=`${ue.build}${H.build}${_.build}${J.build}${pe.build}
1613
+ `:"",wn=`${ue.build}${G.build}${_.build}${z.build}${he.build}
1614
1614
  const secrets = createSecrets(env);
1615
- `,kn=`${ue.contextField}${H.contextField}${_.contextField}${te.contextField}${J.contextField}${pe.contextField}
1615
+ `,kn=`${ue.contextField}${G.contextField}${_.contextField}${te.contextField}${z.contextField}${he.contextField}
1616
1616
  secrets,`,xn=te.build,ct=y||g||d||x||S||$,vn=ct?`
1617
1617
  // ActionCtx-only helpers (external, non-deterministic I/O): constructed
1618
1618
  // and attached only for an \`action\` so query/mutation ctx never carry them.
1619
1619
  if (isAction) {
1620
- ${j.build}${W.build}${U.build}${B.build}${ne.build}${h}${[...y?[" ctx.images = images;"]:[],...g?[" ctx.sql = sql;"]:[],...d?[" ctx.browser = browser;"]:[],...x?[" ctx.r2sql = r2sql;"]:[],...S?[" ctx.pipelines = pipelines;"]:[],...$?[" ctx.x402 = x402;"]:[]].join(`
1620
+ ${j.build}${W.build}${U.build}${B.build}${ne.build}${p}${[...y?[" ctx.images = images;"]:[],...g?[" ctx.sql = sql;"]:[],...d?[" ctx.browser = browser;"]:[],...x?[" ctx.r2sql = r2sql;"]:[],...S?[" ctx.pipelines = pipelines;"]:[],...$?[" ctx.x402 = x402;"]:[]].join(`
1621
1621
  `)}
1622
1622
  }
1623
1623
  `:"",Rn=ct?` const isAction = LUNORA_FUNCTIONS[options.functionPath ?? ""]?.kind === "action";
@@ -1665,7 +1665,7 @@ const LUNORA_STORAGE_RULES: StorageRulesResult = ${JSON.stringify(Lt,void 0,4)};
1665
1665
 
1666
1666
  /** 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. */
1667
1667
  const LUNORA_STUDIO_FEATURES: StudioFeaturesResult = ${JSON.stringify(Dt,void 0,4)};
1668
- ${F}${G.constant}${Et}${Pt}${me}${Me}${he}${Be}
1668
+ ${F}${J.constant}${Et}${Pt}${me}${Me}${pe}${Be}
1669
1669
  export interface ShardDOConfig {
1670
1670
  /** Opt into change-data-capture: records a post-image to \`__cdc_log\` on every write (backs streaming export + replay-PITR). */
1671
1671
  cdc?: boolean;
@@ -1679,9 +1679,9 @@ export interface ShardDOConfig {
1679
1679
  observability?: (env: Record<string, unknown>) => TelemetrySink | undefined;
1680
1680
  /** \`unknown\` because \`@lunora/scheduler\`'s \`Scheduler\` is not assignable to \`SchedulerLike\`; the shard casts it. */
1681
1681
  scheduler?: (env: Record<string, unknown>) => unknown;
1682
- storage?: (env: Record<string, unknown>) => unknown;${Vt}${Oe}${H.configField}${_.configField}${J.configField}${j.configField}${W.configField}${U.configField}${B.configField}${ne.configField}${je}${We}${Ht}${Gt}${Jt}
1682
+ storage?: (env: Record<string, unknown>) => unknown;${Vt}${Oe}${G.configField}${_.configField}${z.configField}${j.configField}${W.configField}${U.configField}${B.configField}${ne.configField}${je}${We}${Ht}${Gt}${Jt}
1683
1683
  }
1684
- ${I("schedulerStub",Xt,["cancel","runAfter","runAt"])}${I("storageStub",Zt,["delete","download","getMetadata","getSignedUrl","getUrl","head","list","upload"],{sync:["getUrl"]})}${en}${hn}${tn}${Ce}${H.stub}${_.stub}${J.stub}${j.stub}${W.stub}${U.stub}${B.stub}${ne.stub}${Ze}${re}
1684
+ ${I("schedulerStub",Xt,["cancel","runAfter","runAt"])}${I("storageStub",Zt,["delete","download","getMetadata","getSignedUrl","getUrl","head","list","upload"],{sync:["getUrl"]})}${en}${pn}${tn}${Ce}${G.stub}${_.stub}${z.stub}${j.stub}${W.stub}${U.stub}${B.stub}${ne.stub}${Ze}${re}
1685
1685
  // Bound in-process \`ctx.run*\` composition depth so a self- or cyclically-
1686
1686
  // referencing call fails loudly with a clear error instead of overflowing the
1687
1687
  // stack. Tracked across the awaited handler chain (one DO invocation is
@@ -1839,18 +1839,30 @@ export const createShardDO = (config: ShardDOConfig = {}): new (state: ShardDOSt
1839
1839
  * has no savepoints and \`runInTransaction\` rejects a second open, so it
1840
1840
  * rides the enclosing span, which also owns its commit and therefore its
1841
1841
  * scheduler flush.
1842
+ *
1843
+ * Both deferral windows are opened here and settled against the SAME
1844
+ * outcome. The delete window is what keeps a composed mutation's queued
1845
+ * object deletes off the caller's flush when it rolls back: \`ctx\` is
1846
+ * shared, so without a window the keys are indistinguishable from the
1847
+ * action's own and the action's flush destroys objects whose rows the
1848
+ * rollback put back.
1842
1849
  */
1843
1850
  private async runMutationTransaction<T>(ctx: unknown, work: () => Promise<T>): Promise<T> {
1844
1851
  const settleSchedules = beginDeferredSchedules(ctx as { scheduler?: unknown });
1852
+ // Synchronous and non-throwing (it only moves queue entries), so it can
1853
+ // settle first on every path and cannot mask the outcome.
1854
+ const settleDeletes = beginDeferredDeletes(ctx);
1845
1855
 
1846
1856
  if (this.isInTransaction()) {
1847
1857
  try {
1848
1858
  const nested = await work();
1849
1859
 
1860
+ settleDeletes(true);
1850
1861
  await settleSchedules(true);
1851
1862
 
1852
1863
  return nested;
1853
1864
  } catch (error) {
1865
+ settleDeletes(false);
1854
1866
  await settleSchedules(false);
1855
1867
 
1856
1868
  throw error;
@@ -1866,11 +1878,20 @@ export const createShardDO = (config: ShardDOConfig = {}): new (state: ShardDOSt
1866
1878
  // to run "after I commit" must go with them. Dropping them is the
1867
1879
  // whole point of buffering: a persisted job for a write that never
1868
1880
  // landed fires against state that does not exist.
1881
+ //
1882
+ // The queued object deletes go the same way, and for a sharper
1883
+ // reason: the rows they were to clean up after are still there, and
1884
+ // an R2 delete cannot be undone.
1885
+ settleDeletes(false);
1869
1886
  await settleSchedules(false);
1870
1887
 
1871
1888
  throw error;
1872
1889
  }
1873
1890
 
1891
+ // Committed, so this span's queued keys join whatever the flush below
1892
+ // (or an enclosing span's) will drain.
1893
+ settleDeletes(true);
1894
+
1874
1895
  // Committed. Schedules first and AWAITED: \`runAfter(0, ...)\` is
1875
1896
  // documented as the deterministic equivalent of an \`afterCommit\` hook,
1876
1897
  // so the job must be enqueued after the commit, and a failure to enqueue
@@ -1947,7 +1968,7 @@ ${st.override}
1947
1968
  iterator: (signal) => (registered.handler as (context: unknown, args: Record<string, unknown>, signal: AbortSignal) => AsyncIterable<unknown>)(this.buildCtx({ functionPath, identity }), args, signal),
1948
1969
  };
1949
1970
  }
1950
- ${Ut}${Wt}${pn}${gn}
1971
+ ${Ut}${Wt}${hn}${gn}
1951
1972
  protected override lifecycleHookPaths(event: "connect" | "disconnect" | "init" | "reactor"): readonly string[] {
1952
1973
  return LUNORA_LIFECYCLE_HOOKS[event];
1953
1974
  }
@@ -2030,7 +2051,7 @@ ${mn}
2030
2051
  protected override studioFeatures(): StudioFeaturesResult {
2031
2052
  return LUNORA_STUDIO_FEATURES;
2032
2053
  }
2033
- ${G.evaluateOverride}${G.subscriptionOverride}${_t}${Mt}
2054
+ ${J.evaluateOverride}${J.subscriptionOverride}${_t}${Mt}
2034
2055
  protected override advisories(): AdvisoryFinding[] {
2035
2056
  return LUNORA_ADVISORIES;
2036
2057
  }
@@ -2056,7 +2077,7 @@ ${ln}
2056
2077
  throw new LunoraError("MIGRATION_NOT_FOUND", \`data migration "\${args.id}" is not registered\`, { status: 404 });
2057
2078
  }
2058
2079
 
2059
- ${z()}
2080
+ ${Q()}
2060
2081
 
2061
2082
  return runDataMigration({
2062
2083
  batchSize: args.batchSize,
@@ -2089,7 +2110,7 @@ ${z()}
2089
2110
 
2090
2111
  this.ensureMigrated();
2091
2112
 
2092
- ${z("headroom ?? this.transactionHeadroom()")}
2113
+ ${Q("headroom ?? this.transactionHeadroom()")}
2093
2114
 
2094
2115
  if (args.op === "insert") {
2095
2116
  const id = await writer.insert(args.table, args.doc ?? {});
@@ -2140,7 +2161,7 @@ ${z("headroom ?? this.transactionHeadroom()")}
2140
2161
  protected override async runShardExport(args: RunShardExportArgs): Promise<ExportRow[]> {
2141
2162
  this.ensureMigrated();
2142
2163
 
2143
- ${z()}
2164
+ ${Q()}
2144
2165
 
2145
2166
  const rows: ExportRow[] = [];
2146
2167
 
@@ -2157,7 +2178,7 @@ ${z()}
2157
2178
  protected override async runShardImport(args: RunShardImportArgs): Promise<ImportShardResult> {
2158
2179
  this.ensureMigrated();
2159
2180
 
2160
- ${z()}
2181
+ ${Q()}
2161
2182
 
2162
2183
  // \`importShardRows\` inserts with \`allowExplicitId\`, so a source
2163
2184
  // database's \`_id\`s carry across verbatim and every foreign key
@@ -2168,7 +2189,7 @@ ${z()}
2168
2189
  protected override async runShardRankBefore(args: RunShardRankBeforeArgs): Promise<{ before: number; total: number }> {
2169
2190
  this.ensureMigrated();
2170
2191
 
2171
- ${z()}
2192
+ ${Q()}
2172
2193
 
2173
2194
  // \`rankBefore\` is optional on \`DatabaseWriterLike\` (the D1 twin omits it),
2174
2195
  // but the shard writer from \`createShardCtxDb\` always defines it.
@@ -2183,10 +2204,28 @@ ${z()}
2183
2204
  });
2184
2205
  }
2185
2206
 
2207
+ protected override async runShardFindRelated(args: RunShardFindRelatedArgs): Promise<RelatedPage> {
2208
+ this.ensureMigrated();
2209
+
2210
+ ${Q()}
2211
+
2212
+ // \`related\` is optional on \`DatabaseWriterLike\` (the D1 twin omits it),
2213
+ // but the shard writer from \`createShardCtxDb\` always defines it — it
2214
+ // derives the edge set from this app's schema.
2215
+ if (!writer.related) {
2216
+ throw new LunoraError("NOT_IMPLEMENTED", "findRelated is unavailable on the shard writer", { status: 500 });
2217
+ }
2218
+
2219
+ return writer.related(
2220
+ { id: args.id, table: args.table },
2221
+ { cursor: args.cursor, depth: args.depth, direction: args.direction, edges: args.edges, limit: args.limit },
2222
+ );
2223
+ }
2224
+
2186
2225
  protected override async runShardRankPage(args: RunShardRankPageArgs): Promise<ShardRankPageResult> {
2187
2226
  this.ensureMigrated();
2188
2227
 
2189
- ${z()}
2228
+ ${Q()}
2190
2229
 
2191
2230
  // \`rankPageRows\` is optional on \`DatabaseWriterLike\` (the D1 twin omits it),
2192
2231
  // but the shard writer from \`createShardCtxDb\` always defines it. The sort
@@ -2207,7 +2246,7 @@ ${z()}
2207
2246
  protected override async runShardApplyCdc(args: RunShardApplyCdcArgs): Promise<{ applied: number }> {
2208
2247
  this.ensureMigrated();
2209
2248
 
2210
- ${z()}
2249
+ ${Q()}
2211
2250
 
2212
2251
  await applyCdcChanges(writer, args.changes);
2213
2252
 
@@ -2410,15 +2449,15 @@ ${e.indexes.map(o=>Gr(o)).join(`
2410
2449
  `)}
2411
2450
  })`:"";return`export const ${e.name} = sqliteTable("${e.name}", {
2412
2451
  ${n}
2413
- }${r});`},zr=e=>e.typeAnnotation?.includes('Id<"')??!1,Yr=(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=Xe(a);n.add(c.builder),s=s||zr(c),o=o||At(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}},pt=(e,t=!1)=>{if(e.length===0)return`${R}export {};
2452
+ }${r});`},zr=e=>e.typeAnnotation?.includes('Id<"')??!1,Yr=(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=Xe(a);n.add(c.builder),s=s||zr(c),o=o||At(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}},ht=(e,t=!1)=>{if(e.length===0)return`${R}export {};
2414
2453
  `;const n=ae(t),r=new Set(e.map(g=>g.name)),{columns:o,indexes:s,needsAnyColumn:i,needsId:a}=Yr(e,r),c=[...s,...o].toSorted((g,y)=>g.localeCompare(y)),d=e.map(g=>Jr(g,r)).join(`
2415
2454
 
2416
- `),p=[i?`import type { AnySQLiteColumn } from "${n.serverDrizzle}";
2455
+ `),h=[i?`import type { AnySQLiteColumn } from "${n.serverDrizzle}";
2417
2456
  `:"",a?`import type { Id } from "./dataModel.js";
2418
2457
  `:""].join("");return`${R}import { ${c.join(", ")} } from "${n.serverDrizzle}";
2419
- ${p}
2458
+ ${h}
2420
2459
  ${d}
2421
- `},vo=(e,t=!1)=>{const n=e.tables.filter(o=>o.shardMode==="global"),r=e.tables.filter(o=>o.shardMode!=="global");return{global:D(pt(n,t),Je),shard:D(pt(r,t),Je)}},Ro=e=>e?`${R}/**
2460
+ `},vo=(e,t=!1)=>{const n=e.tables.filter(o=>o.shardMode==="global"),r=e.tables.filter(o=>o.shardMode!=="global");return{global:D(ht(n,t),Je),shard:D(ht(r,t),Je)}},Ro=e=>e?`${R}/**
2422
2461
  * The \`SchedulerDO\` Durable Object class, re-exported so a worker entry can
2423
2462
  * forward it — wrangler binds only what the entry exports:
2424
2463
  *
@@ -2431,7 +2470,7 @@ export { SchedulerDO } from "@lunora/scheduler";
2431
2470
  `:"",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(`
2432
2471
  `),r=n.length>0?`
2433
2472
  ${n}
2434
- `:"",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(`
2473
+ `:"",o=[...t.entries()].map(([i,a])=>{const c=a.map(d=>{const h=d.workflow?`workflow: ${JSON.stringify(d.workflow.binding)}`:`functionPath: ${JSON.stringify(d.functionPath)}`;return` { name: ${JSON.stringify(d.name)}, ${h}, args: ${JSON.stringify(d.args)} },`}).join(`
2435
2474
  `);return` ${JSON.stringify(i)}: [
2436
2475
  ${c}
2437
2476
  ],`}).join(`
@@ -2486,4 +2525,4 @@ export interface LunoraVectorIndex {
2486
2525
  * \`createWorker({ vectorIntrospector })\` to back the studio's vector browser.
2487
2526
  */
2488
2527
  export const LUNORA_VECTOR_INDEXES: ReadonlyArray<LunoraVectorIndex> = [${n}];
2489
- `},To=e=>[...new Set(e.map(t=>t.cron))];export{co as A,In as C,R as G,er as U,po as a,mo as b,bo as c,So as d,wo as e,uo as f,vo as g,fo as h,Ro as i,go as j,xo as k,$o as l,yo as m,To as n,yr as o,ko as p,ho as q};
2528
+ `},To=e=>[...new Set(e.map(t=>t.cron))];export{co as A,In as C,R as G,er as U,ho as a,mo as b,bo as c,So as d,wo as e,uo as f,vo as g,fo as h,Ro as i,go as j,xo as k,$o as l,yo as m,To as n,yr as o,ko as p,po as q};