@lunora/codegen 1.0.0-alpha.85 → 1.0.0-alpha.86

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (36) hide show
  1. package/dist/index.d.mts +1 -1
  2. package/dist/index.d.ts +1 -1
  3. package/dist/index.mjs +1 -1
  4. package/dist/packem_shared/{FLAGS_FILENAME-BiJh08O0.mjs → FLAGS_FILENAME-CHaH6obH.mjs} +1 -1
  5. package/dist/packem_shared/GENERATED_HEADER-CUBdTCVk.mjs +1 -0
  6. package/dist/packem_shared/{MUTATORS_FILENAME-9652koWz.mjs → MUTATORS_FILENAME-DY3rgWGl.mjs} +1 -1
  7. package/dist/packem_shared/{NOTIFY_FILENAME-DeIlwPBu.mjs → NOTIFY_FILENAME-CDvoTY3Y.mjs} +1 -1
  8. package/dist/packem_shared/{OPENRPC_VERSION-K3RTK2CP.mjs → OPENRPC_VERSION-aq5eyIkd.mjs} +1 -1
  9. package/dist/packem_shared/SCHEMA_SNAPSHOT_FILENAME-ChA6rpGP.mjs +9 -0
  10. package/dist/packem_shared/{SHAPES_FILENAME-Cwn4I4UB.mjs → SHAPES_FILENAME-BdLj5-mD.mjs} +1 -1
  11. package/dist/packem_shared/{buildOpenApiDocument-Blf3mpIz.mjs → buildOpenApiDocument-Bw3MChvT.mjs} +1 -1
  12. package/dist/packem_shared/{discover-queries-B4Lw0cEr.mjs → discover-queries-BmZeJ--u.mjs} +1 -1
  13. package/dist/packem_shared/{discoverAuthApiCalls-CVTXSguP.mjs → discoverAuthApiCalls-BgL6nj03.mjs} +1 -1
  14. package/dist/packem_shared/{discoverCrons-CZ0_RXUc.mjs → discoverCrons-WJscxQFl.mjs} +1 -1
  15. package/dist/packem_shared/discoverFunctions-BgGmxEqW.mjs +1 -0
  16. package/dist/packem_shared/{discoverHttpRoutes-VyBQ9CbN.mjs → discoverHttpRoutes-eW8RbVOr.mjs} +1 -1
  17. package/dist/packem_shared/{discoverInserts-BGlOx2Cg.mjs → discoverInserts-BCz6zpI0.mjs} +1 -1
  18. package/dist/packem_shared/{discoverMaskProcedures-DpAT4zsu.mjs → discoverMaskProcedures-DLfQRsQc.mjs} +1 -1
  19. package/dist/packem_shared/{discoverMigrations-CcOvlTA7.mjs → discoverMigrations-Cbc4W765.mjs} +1 -1
  20. package/dist/packem_shared/{discoverNondeterministicCalls-CVY5_-x1.mjs → discoverNondeterministicCalls-x9IhWxPP.mjs} +1 -1
  21. package/dist/packem_shared/discoverQueries-Cf0LGoQG.mjs +1 -0
  22. package/dist/packem_shared/{discoverR2sqlCalls-BKn9ogOI.mjs → discoverR2sqlCalls--MSfSeDm.mjs} +1 -1
  23. package/dist/packem_shared/{discoverRlsMetadata-B2iTIbm0.mjs → discoverRlsMetadata-DTRS0ROc.mjs} +1 -1
  24. package/dist/packem_shared/{discoverSandboxUsage-rkLj3ZC0.mjs → discoverSandboxUsage-BDyeyuYo.mjs} +1 -1
  25. package/dist/packem_shared/discoverSchema-DSJSX4Ss.mjs +1 -0
  26. package/dist/packem_shared/{discoverStorageRulesMetadata-AD_GPKdF.mjs → discoverStorageRulesMetadata-Cic97L-2.mjs} +1 -1
  27. package/dist/packem_shared/{emit-B7IUlWwi.mjs → emit-DMvG162j.mjs} +335 -324
  28. package/dist/packem_shared/{emitApp-jRD2D9kI.mjs → emitApp--dJ6EnFn.mjs} +1 -1
  29. package/dist/packem_shared/parse-validator-CkLxY-Mr.mjs +1 -0
  30. package/package.json +5 -5
  31. package/dist/packem_shared/GENERATED_HEADER-oy7DTIDi.mjs +0 -1
  32. package/dist/packem_shared/SCHEMA_SNAPSHOT_FILENAME-DHVrsPNK.mjs +0 -9
  33. package/dist/packem_shared/discoverFunctions-9GMvSwz7.mjs +0 -1
  34. package/dist/packem_shared/discoverQueries-BFFoJLOQ.mjs +0 -1
  35. package/dist/packem_shared/discoverSchema-1zm6abY5.mjs +0 -1
  36. package/dist/packem_shared/parse-validator-DCrBLhq7.mjs +0 -1
@@ -15,89 +15,57 @@ import{agentComponent as tt}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"}],ln=nt,dn=new Map(ln.flatMap(e=>e.serverCtxField?[[e.key,e.serverCtxField]]:[])),Or=nt.flatMap(e=>"appMethod"in e?[{appMethod:e.appMethod,key:e.key}]:[]),rt=/^(?:"(?:[^"\\]|\\(?:["\\/bfnrt]|u[0-9A-Fa-f]{4}))*"|'[^'\\]*'|-?\d+(?:\.\d+)?|true|false|null)$/u,cn=new Set(["any","bigint","boolean","date","id","null","number","storage","string","timestamp"]),at=e=>e.column!==void 0,un=(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"}],ln=nt,dn=new Map(ln.flatMap(e=>e.serverCtxField?[[e.key,e.serverCtxField]]:[])),Ar=nt.flatMap(e=>"appMethod"in e?[{appMethod:e.appMethod,key:e.key}]:[]),rt=/^(?:"(?:[^"\\]|\\(?:["\\/bfnrt]|u[0-9A-Fa-f]{4}))*"|'[^'\\]*'|-?\d+(?:\.\d+)?|true|false|null)$/u,cn=new Set(["any","bigint","boolean","date","id","null","number","storage","string","timestamp"]),at=e=>e.column!==void 0,un=(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
23
  `}},pn=(e,t)=>{const n=e.literalValue?.trim();if(!(n===void 0||!rt.test(n)))return{out:t,pre:`if (${t} !== ${n}) return DEFER;
24
- `}},Me=(e,t,n)=>{if(!at(e)&&!(e.hasRefinement||e.sourceText!==void 0)){if(cn.has(e.kind))return e.kind==="any"?{out:t,pre:""}:{out:t,pre:un(e.kind,t)};switch(e.kind){case"array":return hn(e,t,n);case"literal":return pn(e,t);case"object":return mn(e,t,n);default:return}}},hn=(e,t,n)=>{const{inner:r}=e;if(!r)return;const a=n.next(),o=`__arr${String(a)}`,i=`__i${String(a)}`,s=`__e${String(a)}`,l=Me(r,s,n);if(!l)return;const u=`if (!Array.isArray(${t})) return DEFER;
24
+ `}},qe=(e,t,n)=>{if(!at(e)&&!(e.hasRefinement||e.sourceText!==void 0)){if(cn.has(e.kind))return e.kind==="any"?{out:t,pre:""}:{out:t,pre:un(e.kind,t)};switch(e.kind){case"array":return hn(e,t,n);case"literal":return pn(e,t);case"object":return mn(e,t,n);default:return}}},hn=(e,t,n)=>{const{inner:r}=e;if(!r)return;const a=n.next(),o=`__arr${String(a)}`,i=`__i${String(a)}`,s=`__e${String(a)}`,d=qe(r,s,n);if(!d)return;const u=`if (!Array.isArray(${t})) return DEFER;
25
25
  const ${o} = new Array(${t}.length);
26
26
  for (let ${i} = 0; ${i} < ${t}.length; ${i}++) {
27
27
  const ${s} = ${t}[${i}];
28
- ${l.pre}${o}[${i}] = ${l.out};
28
+ ${d.pre}${o}[${i}] = ${d.out};
29
29
  }
30
- `;return{out:o,pre:u}},gn=(e,t,n,r)=>{const a=JSON.stringify(e);if(t.kind==="optional"){if(t.hasRefinement||t.sourceText!==void 0||at(t))return;const{inner:i}=t;if(!i)return;const s=Me(i,n,r);if(!s)return;const l=r.next(),u=`__has${String(l)}`,p=`__val${String(l)}`,f=`let ${u} = false;
30
+ `;return{out:o,pre:u}},gn=(e,t,n,r)=>{const a=JSON.stringify(e);if(t.kind==="optional"){if(t.hasRefinement||t.sourceText!==void 0||at(t))return;const{inner:i}=t;if(!i)return;const s=qe(i,n,r);if(!s)return;const d=r.next(),u=`__has${String(d)}`,p=`__val${String(d)}`,g=`let ${u} = false;
31
31
  let ${p};
32
32
  if (${n} !== undefined) {
33
33
  ${s.pre}${p} = ${s.out};
34
34
  ${u} = true;
35
35
  }
36
- `;return{entry:`...(${u} ? { ${a}: ${p} } : {})`,pre:f}}const o=Me(t,n,r);if(o)return{entry:`${a}: ${o.out}`,pre:o.pre}},ot=(e,t,n)=>{let r="";const a=[];for(const o of Object.keys(e)){const i=e[o];if(!i)return;const s=gn(o,i,t(o),n);if(!s)return;r+=s.pre,a.push(s.entry)}return{entries:a.join(", "),pre:r}},mn=(e,t,n)=>{const r=e.shape??{},a=ot(r,l=>`${t}[${JSON.stringify(l)}]`,n);if(!a)return;const o=n.next(),i=`__obj${String(o)}`,s=`if (typeof ${t} !== "object" || ${t} === null || Array.isArray(${t})) return DEFER;
36
+ `;return{entry:`...(${u} ? { ${a}: ${p} } : {})`,pre:g}}const o=qe(t,n,r);if(o)return{entry:`${a}: ${o.out}`,pre:o.pre}},ot=(e,t,n)=>{let r="";const a=[];for(const o of Object.keys(e)){const i=e[o];if(!i)return;const s=gn(o,i,t(o),n);if(!s)return;r+=s.pre,a.push(s.entry)}return{entries:a.join(", "),pre:r}},mn=(e,t,n)=>{const r=e.shape??{},a=ot(r,d=>`${t}[${JSON.stringify(d)}]`,n);if(!a)return;const o=n.next(),i=`__obj${String(o)}`,s=`if (typeof ${t} !== "object" || ${t} === null || Array.isArray(${t})) return DEFER;
37
37
  ${a.pre}const ${i} = { ${a.entries} };
38
38
  `;return{out:i,pre:s}},fn=e=>{let t=0;const n=ot(e,r=>`source[${JSON.stringify(r)}]`,{next:()=>(t+=1,t)});if(n)return`(source) => {
39
39
  if (typeof source !== "object" || source === null || Array.isArray(source)) return DEFER;
40
40
  ${n.pre}return { ${n.entries} };
41
- }`},v=`// GENERATED by @lunora/codegen — do not edit.
41
+ }`},S=`// GENERATED by @lunora/codegen — do not edit.
42
42
  // Run \`lunora codegen\` to regenerate.
43
43
 
44
- `,G=(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"},st=/^[A-Za-z_$][\w$]*$/u,bn=/^[\w./-]+$/u,m=(e,t)=>{if(!st.test(e))throw new Z("INTERNAL",`@lunora/codegen: ${t} is not a valid JS identifier: ${JSON.stringify(e)}`)},Fe=e=>e.charAt(0).toUpperCase()+e.slice(1),D=e=>st.test(e)?e:JSON.stringify(e),yn={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"},wn=e=>{if(e===void 0)return"unknown";if(!rt.test(e))throw new Z("INTERNAL",`@lunora/codegen: v.literal() argument is not a parseable string/number/boolean/null literal: ${JSON.stringify(e)}`);return e},C=e=>{const t=yn[e.kind];if(t!==void 0)return t;switch(e.kind){case"array":return`Array<${e.inner?C(e.inner):"unknown"}>`;case"from":return e.tsType??"unknown";case"id":{const n=e.tableName??"_unknown_";return m(n,"v.id() table name"),`Id<"${n}">`}case"literal":return wn(e.literalValue);case"object":return e.shape?`{ ${Object.entries(e.shape).map(([n,r])=>it(n,r)).join("; ")} }`:"Record<string, unknown>";case"optional":return`${e.inner?C(e.inner):"unknown"} | undefined`;case"record":{const n=e.keyType?C(e.keyType):"string",r=e.valueType?C(e.valueType):"unknown";return`Record<${n}, ${r}>`}case"union":return e.members&&e.members.length>0?e.members.map(n=>C(n)).join(" | "):"never";default:return"unknown"}},it=(e,t)=>{const n=D(e);if(t.kind==="optional"){const r=t.inner?C(t.inner):"unknown";return`${n}?: ${r}`}return`${n}: ${C(t)}`},me=e=>{const t=Object.entries(e);return t.length===0?"{}":`{ ${t.map(([n,r])=>it(n,r)).join("; ")} }`},xn=e=>e.kind==="optional"||!!e.column?.hasDefault,kn=e=>{m(e.name,"table name");const t=Object.entries(e.shape).map(([r,a])=>{const o=a.kind==="optional"&&a.inner?a.inner:a,i=C(o),s=D(r);return xn(a)?` ${s}?: ${i};`:` ${s}: ${i};`}).join(`
44
+ `,ee=(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"},st=/^[A-Za-z_$][\w$]*$/u,bn=/^[\w./-]+$/u,m=(e,t)=>{if(!st.test(e))throw new Z("INTERNAL",`@lunora/codegen: ${t} is not a valid JS identifier: ${JSON.stringify(e)}`)},Fe=e=>e.charAt(0).toUpperCase()+e.slice(1),I=e=>st.test(e)?e:JSON.stringify(e),yn={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"},wn=e=>{if(e===void 0)return"unknown";if(!rt.test(e))throw new Z("INTERNAL",`@lunora/codegen: v.literal() argument is not a parseable string/number/boolean/null literal: ${JSON.stringify(e)}`);return e},N=e=>{const t=yn[e.kind];if(t!==void 0)return t;switch(e.kind){case"array":return`Array<${e.inner?N(e.inner):"unknown"}>`;case"from":return e.tsType??"unknown";case"id":{const n=e.tableName??"_unknown_";return m(n,"v.id() table name"),`Id<"${n}">`}case"literal":return wn(e.literalValue);case"object":return e.shape?`{ ${Object.entries(e.shape).map(([n,r])=>it(n,r)).join("; ")} }`:"Record<string, unknown>";case"optional":return`${e.inner?N(e.inner):"unknown"} | undefined`;case"record":{const n=e.keyType?N(e.keyType):"string",r=e.valueType?N(e.valueType):"unknown";return`Record<${n}, ${r}>`}case"union":return e.members&&e.members.length>0?e.members.map(n=>N(n)).join(" | "):"never";default:return"unknown"}},it=(e,t)=>{const n=I(e);if(t.kind==="optional"){const r=t.inner?N(t.inner):"unknown";return`${n}?: ${r}`}return`${n}: ${N(t)}`},fe=e=>{const t=Object.entries(e);return t.length===0?"{}":`{ ${t.map(([n,r])=>it(n,r)).join("; ")} }`},xn=e=>e.kind==="optional"||!!e.column?.hasDefault,kn=e=>{m(e.name,"table name");const t=Object.entries(e.shape).map(([r,a])=>{const o=a.kind==="optional"&&a.inner?a.inner:a,i=N(o),s=I(r);return xn(a)?` ${s}?: ${i};`:` ${s}: ${i};`}).join(`
45
45
  `),n=t?`
46
46
  ${t}
47
47
  `:"";return`export interface Insert_${e.name} {
48
48
  _id?: Id<"${e.name}">;
49
- _creationTime?: number;${n}}`},Tr=(e,t=!1)=>{const n=G(t);for(const c of e.tables)m(c.name,"table name");const r=e.tables.map(c=>`"${c.name}"`).join(" | ")||"never",a=e.tables.filter(c=>c.extensionKey===void 0).map(c=>`"${c.name}"`).join(" | ")||"never",o=e.tables.map(c=>{const g=Object.entries(c.shape).map(([k,$])=>{const T=D(k);if($.kind==="optional"){const O=$.inner?C($.inner):"unknown";return` ${T}?: ${O};`}return` ${T}: ${C($)};`}).join(`
50
- `),b=g?`
51
- ${g}
49
+ _creationTime?: number;${n}}`},Be="schema",Lr=e=>{for(const c of e.tables)m(c.name,"table name");const t=e.tables.map(c=>`"${c.name}"`).join(" | ")||"never",n=e.tables.filter(c=>c.extensionKey===void 0).map(c=>`"${c.name}"`).join(" | ")||"never",r=e.tables.map(c=>{const l=Object.entries(c.shape).map(([x,k])=>{const v=I(x);if(k.kind==="optional"){const A=k.inner?N(k.inner):"unknown";return` ${v}?: ${A};`}return` ${v}: ${N(k)};`}).join(`
50
+ `),f=l?`
51
+ ${l}
52
52
  `:"";return`export interface Doc_${c.name} {
53
53
  _id: Id<"${c.name}">;
54
- _creationTime: number;${b}}`}).join(`
55
-
56
- `),i=e.tables.map(c=>` ${c.name}: Doc_${c.name};`).join(`
57
- `),s=e.tables.map(c=>{const g=c.indexes.map(b=>JSON.stringify(b.name)).join(" | ");return` ${c.name}: ${g||"never"};`}).join(`
58
- `),l=e.tables.map(c=>{const g=c.searchIndexes.map(b=>JSON.stringify(b.name)).join(" | ");return` ${c.name}: ${g||"never"};`}).join(`
59
- `),u=e.tables.map(c=>{const g=c.rankIndexes.map(b=>JSON.stringify(b.name)).join(" | ");return` ${c.name}: ${g||"never"};`}).join(`
60
- `),p=e.tables.map(c=>{const g=c.shardMode==="global"?"":(c.geoIndexes??[]).map(b=>JSON.stringify(b.name)).join(" | ");return` ${c.name}: ${g||"never"};`}).join(`
61
- `),f=e.vectorIndexes.map(c=>JSON.stringify(c.name)).join(" | ")||"never",y=e.tables.map(c=>kn(c)).join(`
62
-
63
- `),N=e.tables.map(c=>` ${c.name}: Insert_${c.name};`).join(`
64
- `),d=e.tables.map(c=>{const g=c.relations.map(b=>(m(b.table,"relation target table"),` ${D(b.name)}: ${b.kind==="one"?"OneRelation":"ManyRelation"}<"${b.table}">;`)).join(`
65
- `);return g?` ${c.name}: {
66
- ${g}
54
+ _creationTime: number;${f}}`}).join(`
55
+
56
+ `),a=e.tables.map(c=>` ${c.name}: Doc_${c.name};`).join(`
57
+ `),o=e.tables.map(c=>{const l=c.indexes.map(f=>JSON.stringify(f.name)).join(" | ");return` ${c.name}: ${l||"never"};`}).join(`
58
+ `),i=e.tables.map(c=>{const l=c.searchIndexes.map(f=>JSON.stringify(f.name)).join(" | ");return` ${c.name}: ${l||"never"};`}).join(`
59
+ `),s=e.tables.map(c=>{const l=c.rankIndexes.map(f=>JSON.stringify(f.name)).join(" | ");return` ${c.name}: ${l||"never"};`}).join(`
60
+ `),d=e.tables.map(c=>{const l=c.shardMode==="global"?"":(c.geoIndexes??[]).map(f=>JSON.stringify(f.name)).join(" | ");return` ${c.name}: ${l||"never"};`}).join(`
61
+ `),u=e.vectorIndexes.map(c=>JSON.stringify(c.name)).join(" | ")||"never",p=e.tables.map(c=>kn(c)).join(`
62
+
63
+ `),g=e.tables.map(c=>` ${c.name}: Insert_${c.name};`).join(`
64
+ `),b=e.tables.map(c=>{const l=c.relations.map(f=>(m(f.table,"relation target table"),` ${I(f.name)}: ${f.kind==="one"?"OneRelation":"ManyRelation"}<"${f.table}">;`)).join(`
65
+ `);return l?` ${c.name}: {
66
+ ${l}
67
67
  };`:` ${c.name}: {};`}).join(`
68
- `);return`${v}import type {
69
- DatabaseReaderFacade as DatabaseReaderFacadeOf,
70
- DatabaseWriterFacade as DatabaseWriterFacadeOf,
71
- LoadWith as LoadWithOf,
72
- TableReaderFacade as TableReaderFacadeOf,
73
- TableWriterFacade as TableWriterFacadeOf,
74
- WithArg as WithArgOf,
75
- } from "${n.serverDataModel}";
76
-
77
- export type {
78
- AggregateOp,
79
- GroupByEntry,
80
- OrderBy,
81
- QueryArgs,
82
- QueryPage,
83
- RankPage,
84
- RankResult,
85
- RestrictableQueryOptions,
86
- RestrictableQueryOptionsOf,
87
- SearchFilterBuilder,
88
- SearchReader,
89
- TableAggregateOptions,
90
- TableAggregateOptionsOf,
91
- TableGroupByOptions,
92
- TableGroupByOptionsOf,
93
- TableRankOptions,
94
- TableRankPageOptions,
95
- Where,
96
- WhereOf,
97
- WhereOperators,
98
- } from "${n.serverDataModel}";
99
-
100
- export type TableName = ${r};
68
+ `);return D(`${S}export type TableName = ${t};
101
69
 
102
70
  /**
103
71
  * The tables **this app declared** — every {@link TableName} except those an add-on
@@ -114,14 +82,14 @@ export type TableName = ${r};
114
82
  * const EXPORTED: readonly AppTableName[] = ["nodes", "tagColors"];
115
83
  * \`\`\`
116
84
  */
117
- export type AppTableName = ${a};
85
+ export type AppTableName = ${n};
118
86
 
119
87
  export type Id<TName extends string> = string & { readonly __table: TName };
120
88
 
121
- ${o}
89
+ ${r}
122
90
 
123
91
  export interface DataModel {
124
- ${i}
92
+ ${a}
125
93
  }
126
94
 
127
95
  export type Doc<T extends keyof DataModel> = DataModel[T];
@@ -131,40 +99,40 @@ export type Doc<T extends keyof DataModel> = DataModel[T];
131
99
  * Used by \`TableReader.withIndex()\` to constrain callers to declared names.
132
100
  */
133
101
  export interface IndexNamesByTable {
134
- ${s}
102
+ ${o}
135
103
  }
136
104
 
137
105
  export type IndexName<T extends keyof DataModel> = IndexNamesByTable[T];
138
106
 
139
107
  /** Per-table search-index name union. \`never\` for tables without searchIndex. */
140
108
  export interface SearchIndexNamesByTable {
141
- ${l}
109
+ ${i}
142
110
  }
143
111
 
144
112
  export type SearchIndexName<T extends keyof DataModel> = SearchIndexNamesByTable[T];
145
113
 
146
114
  /** Per-table rank-index name union. \`never\` for tables without a rankIndex. */
147
115
  export interface RankIndexNamesByTable {
148
- ${u}
116
+ ${s}
149
117
  }
150
118
 
151
119
  export type RankIndexName<T extends keyof DataModel> = RankIndexNamesByTable[T];
152
120
 
153
121
  /** Per-table geo-index name union. \`never\` for tables without a geoIndex. */
154
122
  export interface GeoIndexNamesByTable {
155
- ${p}
123
+ ${d}
156
124
  }
157
125
 
158
126
  export type GeoIndexName<T extends keyof DataModel> = GeoIndexNamesByTable[T];
159
127
 
160
128
  /** Union of declared vector index names. \`never\` when none are declared. */
161
- export type VectorIndexName = ${f};
129
+ export type VectorIndexName = ${u};
162
130
 
163
- ${y}
131
+ ${p}
164
132
 
165
133
  /** Per-table insert shape, accepted by \`ctx.db.<table>.insert(...)\`. */
166
134
  export interface InsertModel {
167
- ${N}
135
+ ${g}
168
136
  }
169
137
 
170
138
  export type Insert<T extends keyof DataModel> = InsertModel[T];
@@ -186,59 +154,14 @@ export interface ManyRelation<Target extends keyof DataModel> {
186
154
 
187
155
  /** Per-table relation map keyed by accessor name. \`{}\` for tables with none. */
188
156
  export interface Relations {
189
- ${d}
190
- }
191
-
192
- /** The \`with\` argument for table \`T\` — see \`@lunora/server/data-model\`. */
193
- export type WithArg<T extends keyof DataModel> = WithArgOf<DataModel, Relations, T>;
194
-
195
- /** \`Doc<T>\` narrowed to exactly the relations requested in the with-arg \`W\`. */
196
- export type LoadWith<T extends keyof DataModel, W> = LoadWithOf<DataModel, Relations, T, W>;
197
-
198
- /** Read-only typed table accessor exposed on \`QueryCtx.db.<table>\`. */
199
- export type TableReaderFacade<T extends keyof DataModel> = TableReaderFacadeOf<DataModel, Relations, RankIndexNamesByTable, SearchIndexNamesByTable, T, GeoIndexNamesByTable>;
200
-
201
- /** Read-write typed table accessor exposed on \`MutationCtx.db.<table>\` / \`ActionCtx.db.<table>\`. */
202
- export type TableWriterFacade<T extends keyof DataModel> = TableWriterFacadeOf<DataModel, InsertModel, Relations, RankIndexNamesByTable, SearchIndexNamesByTable, T, GeoIndexNamesByTable>;
203
-
204
- /** Per-table read facade — \`ctx.db.<table>\` on a \`QueryCtx\`. */
205
- export type DatabaseReaderFacade = DatabaseReaderFacadeOf<DataModel, Relations, RankIndexNamesByTable, SearchIndexNamesByTable, GeoIndexNamesByTable>;
206
-
207
- /** Per-table read-write facade — \`ctx.db.<table>\` on a \`MutationCtx\` / \`ActionCtx\`. */
208
- export type DatabaseWriterFacade = DatabaseWriterFacadeOf<DataModel, InsertModel, Relations, RankIndexNamesByTable, SearchIndexNamesByTable, GeoIndexNamesByTable>;
209
-
210
- /** Insert builder returned by \`ctx.orm.insert(table)\`. */
211
- export interface OrmInsertBuilder<T extends keyof DataModel> {
212
- values: (values: Insert<T>) => Promise<Id<T>>;
213
- }
214
-
215
- /** Replace builder returned by \`ctx.orm.replace(table, id)\` — swaps the whole document. */
216
- export interface OrmReplaceBuilder<T extends keyof DataModel> {
217
- with: (values: Insert<T>) => Promise<void>;
218
- }
219
-
220
- /** Update builder returned by \`ctx.orm.update(table, id)\` — patches the named fields. */
221
- export interface OrmUpdateBuilder<T extends keyof DataModel> {
222
- set: (values: Partial<Insert<T>>) => Promise<void>;
157
+ ${b}
223
158
  }
224
159
 
225
- /** Read-only ORM surface \`ctx.orm\` on a \`QueryCtx\`. Mirrors \`ctx.db\` reads under a kitcn-style \`query\` namespace. */
226
- export interface OrmReader {
227
- query: DatabaseReaderFacade;
228
- }
229
-
230
- /** Read-write ORM surface — \`ctx.orm\` on a \`MutationCtx\` / \`ActionCtx\`. Writes are addressed by id, like \`ctx.db\`. */
231
- export interface OrmWriter extends OrmReader {
232
- delete: <T extends keyof DataModel>(table: T, id: Id<T>) => Promise<void>;
233
- insert: <T extends keyof DataModel>(table: T) => OrmInsertBuilder<T>;
234
- replace: <T extends keyof DataModel>(table: T, id: Id<T>) => OrmReplaceBuilder<T>;
235
- update: <T extends keyof DataModel>(table: T, id: Id<T>) => OrmUpdateBuilder<T>;
236
- }
237
- `},vn=/import\("(?<spec>(?:\.\.?\/)*_generated\/[^"]+)"\)/gu,lt=/^(?:\.\.?\/)*_generated\//u,dt=/\.[A-Za-z]\w*$/u,qe=e=>e.replaceAll(vn,(t,n)=>{const r=n.replace(lt,"./");return`import("${dt.test(r)?r:`${r}.js`}")`}),$n=/import\("(?<spec>\.\.?\/[^"]+)"\)/gu,Sn=/^(?:\.\.?\/)+/u,Rn=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("/")},Be=(e,t)=>e.replaceAll($n,(n,r)=>{if(lt.test(r.replace(Sn,"")))return n;const a=t.includes("/")?t.slice(0,t.lastIndexOf("/")):"",o=`../${Rn(`${a}/${r}`)}`;return`import("${dt.test(o)?o:`${o}.js`}")`}),Nn=["client","do","errors","flags","observability","platform","ratelimit","runtime","server","values"],On=new RegExp(String.raw`import\("@lunora/(?<pkg>${Nn.join("|")})(?<subpath>/[^"]*)?"\)`,"gu"),Tn={flags:new Set(["/web"]),platform:new Set},ct=(e,t)=>t?e.replaceAll(On,(n,r,a)=>{const o=Tn[r];return a&&o&&!o.has(a)?n:`import("lunorash/${r}${a??""}")`}):e,je=e=>["Doc","Id"].filter(t=>new RegExp(String.raw`\b${t}<`,"u").test(e)),An=e=>e.output===void 0||e.output.kind==="any"?e.returnType:C(e.output),Ze=e=>{const t=new Map;for(const r of e){const a=t.get(r.filePath)??[];a.push(r),t.set(r.filePath,a)}const n=([r,a])=>{const o=a.toSorted((i,s)=>i.exportName.localeCompare(s.exportName)).map(i=>{const s=me(i.args),l=qe(Be(An(i),i.filePath));return` ${i.exportName}: FunctionReference<"${i.kind}", ${s}, ${l}>;`}).join(`
238
- `);return` ${D(R(r))}: {
160
+ `,Be)},vn=/import\("(?<spec>(?:\.\.?\/)*_generated\/[^"]+)"\)/gu,lt=/^(?:\.\.?\/)*_generated\//u,dt=/\.[A-Za-z]\w*$/u,$n=e=>e.replaceAll(vn,(t,n)=>{const r=n.replace(lt,"./");return`import("${dt.test(r)?r:`${r}.js`}")`}),Sn=/import\("(?<spec>\.\.?\/[^"]+)"\)/gu,Rn=/^(?:\.\.?\/)+/u,Nn=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("/")},Tn=(e,t)=>e.replaceAll(Sn,(n,r)=>{if(lt.test(r.replace(Rn,"")))return n;const a=t.includes("/")?t.slice(0,t.lastIndexOf("/")):"",o=`../${Nn(`${a}/${r}`)}`;return`import("${dt.test(o)?o:`${o}.js`}")`}),D=(e,t)=>$n(Tn(e,t)),On=["client","do","errors","flags","observability","platform","ratelimit","runtime","server","values"],An=new RegExp(String.raw`import\("@lunora/(?<pkg>${On.join("|")})(?<subpath>/[^"]*)?"\)`,"gu"),Ln={flags:new Set(["/web"]),platform:new Set},ct=(e,t)=>t?e.replaceAll(An,(n,r,a)=>{const o=Ln[r];return a&&o&&!o.has(a)?n:`import("lunorash/${r}${a??""}")`}):e,je=e=>["Doc","Id"].filter(t=>new RegExp(String.raw`\b${t}<`,"u").test(e)),Cn=e=>e.output===void 0||e.output.kind==="any"?e.returnType:N(e.output),Ze=e=>{const t=new Map;for(const r of e){const a=t.get(r.filePath)??[];a.push(r),t.set(r.filePath,a)}const n=([r,a])=>{const o=a.toSorted((i,s)=>i.exportName.localeCompare(s.exportName)).map(i=>{const s=D(fe(i.args),i.filePath),d=D(Cn(i),i.filePath);return` ${i.exportName}: FunctionReference<"${i.kind}", ${s}, ${d}>;`}).join(`
161
+ `);return` ${I(R(r))}: {
239
162
  ${o}
240
163
  };`};return[...t.entries()].toSorted(([r],[a])=>r.localeCompare(a)).map(r=>n(r)).join(`
241
- `)},Ln=(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+=`
164
+ `)},In=(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+=`
242
165
  /** A typed reference to a durable workflow, addressable for \`cronJobs()\` targets. Mirrors \`@lunora/scheduler\`'s \`WorkflowReference\` structurally. */
243
166
  export interface WorkflowReference<Params = Record<string, unknown>> {
244
167
  readonly isLunoraWorkflow: true;
@@ -246,7 +169,7 @@ export interface WorkflowReference<Params = Record<string, unknown>> {
246
169
  readonly binding: string;
247
170
  readonly name: string;
248
171
  }
249
- `,e.length>0){const a=[...e].toSorted((s,l)=>s.exportName.localeCompare(l.exportName)),o=a.map(s=>` ${s.exportName}: WorkflowReference<WorkflowParamsOf<typeof lunoraWorkflowDefinitions.${s.exportName}>>;`).join(`
172
+ `,e.length>0){const a=[...e].toSorted((s,d)=>s.exportName.localeCompare(d.exportName)),o=a.map(s=>` ${s.exportName}: WorkflowReference<WorkflowParamsOf<typeof lunoraWorkflowDefinitions.${s.exportName}>>;`).join(`
250
173
  `),i=a.map(s=>` ${s.exportName}: { isLunoraWorkflow: true, binding: ${JSON.stringify(s.bindingName)}, name: ${JSON.stringify(s.exportName)} },`).join(`
251
174
  `);r+=`
252
175
  /** This project's durable workflows, addressable as typed references (e.g. \`crons.daily("digest", …, workflows.digestPipeline, params)\`). */
@@ -258,7 +181,7 @@ export const workflows: WorkflowsRef = {
258
181
  ${i}
259
182
  };
260
183
  `,n.push(`import type * as lunoraWorkflowDefinitions from "../workflows.js";
261
- `)}if(t.length>0){const a=[...t].toSorted((s,l)=>s.exportName.localeCompare(l.exportName)),o=a.map(s=>` ${s.exportName}: WorkflowReference<AgentRunInput>;`).join(`
184
+ `)}if(t.length>0){const a=[...t].toSorted((s,d)=>s.exportName.localeCompare(d.exportName)),o=a.map(s=>` ${s.exportName}: WorkflowReference<AgentRunInput>;`).join(`
262
185
  `),i=a.map(s=>` ${s.exportName}: { isLunoraWorkflow: true, binding: ${JSON.stringify(s.bindingName)}, name: ${JSON.stringify(s.name)} },`).join(`
263
186
  `);r+=`
264
187
  /** This project's durable agents, addressable as typed references for \`cronJobs()\` — each fire starts a fresh agent run (e.g. \`crons.daily("sweep", …, agents.support, { input, threadKey })\`). */
@@ -270,7 +193,7 @@ export const agents: AgentsRef = {
270
193
  ${i}
271
194
  };
272
195
  `,n.push(`import type { AgentRunInput } from "@lunora/agent";
273
- `)}return{block:r,importLine:n.join("")}},Cn=()=>Object.keys(tt().functions).toSorted((e,t)=>e.localeCompare(t)),ut=e=>new Set(e.filter(t=>R(t.filePath)==="agents").map(t=>t.exportName)),In=()=>new Set(Object.entries(tt().functions).filter(([,e])=>e.visibility==="internal").map(([e])=>e)),Dn=(e,t)=>{const n={importLine:"",lines:"",prelude:""};if(e.length===0)return n;const r=ut(t),a=In(),o=t.find(s=>R(s.filePath)==="agents"&&a.has(s.exportName));if(o)throw new Z("INTERNAL",`@lunora/codegen: "agents:${o.exportName}" is reserved for the durable agent loop's internal dispatch — rename the "${o.exportName}" export in ${o.filePath}`);const i=Cn().filter(s=>!r.has(s));return i.length===0?n:{importLine:`import { agentComponent } from "@lunora/agent/component";
196
+ `)}return{block:r,importLine:n.join("")}},Dn=()=>Object.keys(tt().functions).toSorted((e,t)=>e.localeCompare(t)),ut=e=>new Set(e.filter(t=>R(t.filePath)==="agents").map(t=>t.exportName)),_n=()=>new Set(Object.entries(tt().functions).filter(([,e])=>e.visibility==="internal").map(([e])=>e)),En=(e,t)=>{const n={importLine:"",lines:"",prelude:""};if(e.length===0)return n;const r=ut(t),a=_n(),o=t.find(s=>R(s.filePath)==="agents"&&a.has(s.exportName));if(o)throw new Z("INTERNAL",`@lunora/codegen: "agents:${o.exportName}" is reserved for the durable agent loop's internal dispatch — rename the "${o.exportName}" export in ${o.filePath}`);const i=Dn().filter(s=>!r.has(s));return i.length===0?n:{importLine:`import { agentComponent } from "@lunora/agent/component";
274
197
  `,lines:i.map(s=>` "agents:${s}": lunoraAgentRuntimeFunctions.${s} as unknown as RegisteredLunoraFunction,`).join(`
275
198
  `),prelude:`
276
199
  /**
@@ -279,14 +202,14 @@ ${i}
279
202
  * subscribe to the public queries (\`agents:agentMessages\` is the live thread view).
280
203
  */
281
204
  const lunoraAgentRuntimeFunctions = agentComponent().functions;
282
- `}},_n=(e,t)=>{if(!e)return{importLine:"",lines:"",prelude:""};const n=t.find(r=>R(r.filePath)==="sandbox"&&r.exportName==="invoke");if(n)throw new Z("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";
283
- `,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"}},En=(e,t)=>{if(e.length===0)return[];const n=ut(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 a of e)a.voice&&r.push({args:{threadKey:{kind:"string"}},exportName:`${a.exportName}Voice`,filePath:"agents",kind:"stream",returnType:"Record<string, unknown>"});return r.filter(a=>!n.has(a.exportName))},Pn=(e,t)=>{if(e.length===0)return[];const n=new Set(t.filter(r=>R(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}))},Fn=e=>{const t=e.filter(i=>i.stream);if(t.length===0)return{block:"",body:""};const n=new Map;for(const i of t){const s=n.get(i.filePath)??[];s.push(i),n.set(i.filePath,s)}const r=[...n.entries()].toSorted(([i],[s])=>i.localeCompare(s)),a=r.map(([i,s])=>{const l=s.map(u=>{const p=qe(Be(u.chunkType??"unknown",u.filePath));return` ${D(u.exportName)}: HttpStreamRef<${p}, ${me(u.searchParams)}, ${me(u.params)}>;`}).join(`
284
- `);return` ${D(R(i))}: {
285
- ${l}
205
+ `}},Pn=(e,t)=>{if(!e)return{importLine:"",lines:"",prelude:""};const n=t.find(r=>R(r.filePath)==="sandbox"&&r.exportName==="invoke");if(n)throw new Z("INTERNAL",`@lunora/codegen: "sandbox:invoke" is reserved for the batteries-included sandbox tool dispatcher (browserTool/containerTool) — rename the "invoke" export in ${n.filePath}`);return{importLine:`import { sandboxComponent } from "@lunora/agent/component";
206
+ `,lines:' "sandbox:invoke": lunoraSandbox.invoke as unknown as RegisteredLunoraFunction,',prelude:"\n/**\n * The `@lunora/agent` sandbox dispatcher — auto-registered because `lunora/`\n * imports a sandbox tool (`browserTool`/`containerTool`). The batteries-included\n * tools dispatch to this internal action, which runs on an action ctx carrying\n * `ctx.browser` + `ctx.containers` (the durable tool step itself has neither).\n */\nconst lunoraSandbox = sandboxComponent();\n"}},Mn=(e,t)=>{if(e.length===0)return[];const n=ut(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 a of e)a.voice&&r.push({args:{threadKey:{kind:"string"}},exportName:`${a.exportName}Voice`,filePath:"agents",kind:"stream",returnType:"Record<string, unknown>"});return r.filter(a=>!n.has(a.exportName))},Fn=(e,t)=>{if(e.length===0)return[];const n=new Set(t.filter(r=>R(r.filePath)==="mutators").map(r=>r.exportName));return e.filter(r=>!n.has(r.exportName)).map(r=>({args:r.args,exportName:r.exportName,filePath:r.filePath,kind:"mutation",returnType:r.returnType}))},qn=e=>{const t=e.filter(i=>i.stream);if(t.length===0)return{block:"",body:""};const n=new Map;for(const i of t){const s=n.get(i.filePath)??[];s.push(i),n.set(i.filePath,s)}const r=[...n.entries()].toSorted(([i],[s])=>i.localeCompare(s)),a=r.map(([i,s])=>{const d=s.map(u=>{const p=D(u.chunkType??"unknown",u.filePath),g=D(fe(u.searchParams),u.filePath),b=D(fe(u.params),u.filePath);return` ${I(u.exportName)}: HttpStreamRef<${p}, ${g}, ${b}>;`}).join(`
207
+ `);return` ${I(R(i))}: {
208
+ ${d}
286
209
  };`}).join(`
287
- `),o=r.map(([i,s])=>{const l=s.map(u=>` ${D(u.exportName)}: { method: ${JSON.stringify(u.method)}, path: ${JSON.stringify(u.path)} },`).join(`
288
- `);return` ${D(R(i))}: {
289
- ${l}
210
+ `),o=r.map(([i,s])=>{const d=s.map(u=>` ${I(u.exportName)}: { method: ${JSON.stringify(u.method)}, path: ${JSON.stringify(u.path)} },`).join(`
211
+ `);return` ${I(R(i))}: {
212
+ ${d}
290
213
  },`}).join(`
291
214
  `);return{block:`
292
215
  /** This project's HTTP-SSE stream routes (\`httpRoute.<verb>(path).stream()\`), addressable as typed references for \`client.httpStream\` / \`useHttpStream\`. */
@@ -297,26 +220,26 @@ ${a}
297
220
  export const httpStreams: HttpStreamsRef = {
298
221
  ${o}
299
222
  };
300
- `,body:a}},Ar=e=>{const{agents:t=[],functions:n,httpRoutes:r=[],mutators:a=[],useUmbrella:o=!1,workflows:i=[]}=e,s=G(o),l=[...n.filter(S=>S.visibility!=="internal"),...En(t,n),...Pn(a,n)],u=n.filter(S=>S.visibility==="internal"),p=Ze(l),f=Ze(u),y=Fn(r),N=`${p}
301
- ${f}
302
- ${y.body}`,d=je(N),c=d.length>0?`
303
- import type { ${d.join(", ")} } from "./dataModel.js";
304
- `:"",g=p?`
223
+ `,body:a}},Cr=e=>{const{agents:t=[],functions:n,httpRoutes:r=[],mutators:a=[],useUmbrella:o=!1,workflows:i=[]}=e,s=ee(o),d=[...n.filter($=>$.visibility!=="internal"),...Mn(t,n),...Fn(a,n)],u=n.filter($=>$.visibility==="internal"),p=Ze(d),g=Ze(u),b=qn(r),c=`${p}
224
+ ${g}
225
+ ${b.body}`,l=je(c),f=l.length>0?`
226
+ import type { ${l.join(", ")} } from "./dataModel.js";
227
+ `:"",x=p?`
305
228
  ${p}
306
- `:"",b=f?`
307
- ${f}
308
- `:"",k=Ln(i,t),$=`export interface ApiTypes {${g}}
229
+ `:"",k=g?`
230
+ ${g}
231
+ `:"",v=In(i,t),A=`export interface ApiTypes {${x}}
309
232
 
310
233
  export const api = anyApi as unknown as ApiTypes;
311
234
 
312
235
  /** Internal functions — callable only server-side via \`ctx.run*\`, never from a client. */
313
- export interface InternalApiTypes {${b}}
236
+ export interface InternalApiTypes {${k}}
314
237
 
315
238
  export const internal = anyApi as unknown as InternalApiTypes;
316
- ${k.block}${y.block}`,T=[...$.includes("FunctionReference<")?["FunctionReference"]:[],...y.block===""?[]:["HttpStreamRef"]],O=T.length>0?`import type { ${T.join(", ")} } from "${s.client}";
317
- `:"";return ct(`${v}import { anyApi } from "${s.client}";
318
- ${O}${k.importLine}${c}
319
- ${$}`,o)},Lr=e=>e?`${v}import { createSeedClient as createSeedClientBase } from "@lunora/seed";
239
+ ${v.block}${b.block}`,P=[...A.includes("FunctionReference<")?["FunctionReference"]:[],...b.block===""?[]:["HttpStreamRef"]],L=P.length>0?`import type { ${P.join(", ")} } from "${s.client}";
240
+ `:"";return ct(`${S}import { anyApi } from "${s.client}";
241
+ ${L}${v.importLine}${f}
242
+ ${A}`,o)},Ir=e=>e?`${S}import { createSeedClient as createSeedClientBase } from "@lunora/seed";
320
243
  import type { SeedClient, SeedClientOptions } from "@lunora/seed";
321
244
 
322
245
  import schema from "../schema.js";
@@ -333,9 +256,9 @@ import type { InsertModel } from "./dataModel.js";
333
256
  * const { posts } = await seed.posts((x) => x([10, 20]));
334
257
  */
335
258
  export const createSeedClient = (options?: SeedClientOptions): SeedClient<InsertModel> => createSeedClientBase<InsertModel>(schema, options);
336
- `:"",Cr=(e,t,n=!1)=>{if(e.length===0||!t)return"";const r=G(n),a=l=>l.table===void 0?"Row":`Doc<${JSON.stringify(l.table)}> & Row`,o=e.map(l=>{m(l.exportName,"shape export name");const u=a(l),p=me(l.args),f=Object.keys(l.args).length>0,y=f?` args: ${p};`:` args?: ${p};`,N=f?`(args: ${p}) => void`:`(args?: ${p}) => void`,d=`${l.exportName}CollectionOptions`;return`/** Options for the \`${l.exportName}\` shape binding. */
337
- export interface ${Fe(d)} {
338
- ${y}
259
+ `:"",Dr=(e,t,n=!1)=>{if(e.length===0||!t)return"";const r=ee(n),a=d=>d.table===void 0?"Row":`Doc<${JSON.stringify(d.table)}> & Row`,o=e.map(d=>{m(d.exportName,"shape export name");const u=a(d),p=D(fe(d.args),d.filePath),g=Object.keys(d.args).length>0,b=g?` args: ${p};`:` args?: ${p};`,c=g?`(args: ${p}) => void`:`(args?: ${p}) => void`,l=`${d.exportName}CollectionOptions`;return`/** Options for the \`${d.exportName}\` shape binding. */
260
+ export interface ${Fe(l)} {
261
+ ${b}
339
262
  /**
340
263
  * Share the optimistic-overlay gate with other collections + mutators on this
341
264
  * shard. Defaults to the shared per-shard registry, which is almost always what
@@ -355,11 +278,11 @@ ${y}
355
278
  }
356
279
 
357
280
  /**
358
- * Collection options for the \`${l.exportName}\` replication shape: \`config\` for
281
+ * Collection options for the \`${d.exportName}\` replication shape: \`config\` for
359
282
  * \`createCollection\`, plus the \`checkpoints\` registry to hand \`bindMutators\` and
360
283
  * \`scope\` to re-point the subscription.
361
284
  */
362
- export const ${l.exportName}CollectionOptions = (options: ${Fe(d)}): LunoraCollectionOptions<${u}> =>
285
+ export const ${d.exportName}CollectionOptions = (options: ${Fe(l)}): LunoraCollectionOptions<${u}> =>
363
286
  lunoraCollectionOptions<${u}>({
364
287
  client: options.client,
365
288
  ...(options.checkpoints === undefined ? {} : { checkpoints: options.checkpoints }),
@@ -367,27 +290,27 @@ export const ${l.exportName}CollectionOptions = (options: ${Fe(d)}): LunoraColle
367
290
  ...(options.load === undefined ? {} : { load: options.load }),
368
291
  ...(options.onError === undefined ? {} : { onError: options.onError }),
369
292
  ...(options.shardKey === undefined ? {} : { shardKey: options.shardKey }),
370
- shape: { args: options.args, name: ${JSON.stringify(l.exportName)}, ...(options.shardKey === undefined ? {} : { shardKey: options.shardKey }) },
293
+ shape: { args: options.args, name: ${JSON.stringify(d.exportName)}, ...(options.shardKey === undefined ? {} : { shardKey: options.shardKey }) },
371
294
  });
372
295
 
373
- /** Live collection for the \`${l.exportName}\` shape, with its sync controls. */
374
- export const ${l.exportName}Collection = (
375
- options: ${Fe(d)},
376
- ): { checkpoints: CheckpointRegistry; collection: Collection<${u}, string>; scope: ${N} } => {
377
- const { checkpoints, config, scope } = ${l.exportName}CollectionOptions(options);
296
+ /** Live collection for the \`${d.exportName}\` shape, with its sync controls. */
297
+ export const ${d.exportName}Collection = (
298
+ options: ${Fe(l)},
299
+ ): { checkpoints: CheckpointRegistry; collection: Collection<${u}, string>; scope: ${c} } => {
300
+ const { checkpoints, config, scope } = ${d.exportName}CollectionOptions(options);
378
301
 
379
302
  return { checkpoints, collection: createCollection(config), scope };
380
303
  };`}).join(`
381
304
 
382
305
  `),i=je(o),s=i.length>0?`import type { ${i.join(", ")} } from "./dataModel.js";
383
- `:"";return`${v}import type { LunoraClient, SubscriptionError } from "${r.client}";
306
+ `:"";return`${S}import type { LunoraClient, SubscriptionError } from "${r.client}";
384
307
  import { lunoraCollectionOptions } from "@lunora/db/collections";
385
308
  import type { CheckpointRegistry, LunoraCollectionOptions, Row } from "@lunora/db";
386
309
  import type { Collection } from "@tanstack/db";
387
310
  import { createCollection } from "@tanstack/db";
388
311
  ${s}
389
312
  ${o}
390
- `},Mn=(e,t)=>`lunora_${R(e)}_${String(t)}`,qn=`const callRegistered = async <R>(context: CallerCtx, functionPath: string, args: Record<string, unknown> | undefined): Promise<R> => {
313
+ `},Bn=(e,t)=>`lunora_${R(e)}_${String(t)}`,jn=`const callRegistered = async <R>(context: CallerCtx, functionPath: string, args: Record<string, unknown> | undefined): Promise<R> => {
391
314
  const registered = LUNORA_FUNCTIONS[functionPath];
392
315
 
393
316
  if (!registered) {
@@ -395,45 +318,45 @@ ${o}
395
318
  }
396
319
 
397
320
  return (await registered.handler(context, args ?? {})) as R;
398
- };`,Bn=(e,t,n=[],r=[])=>{const a=new Map,o=d=>{a.has(d)||a.set(d,Mn(d,a.size))};for(const d of e)o(d.filePath);for(const d of t)o(d.filePath);for(const d of n)o(d.filePath);for(const d of r)o(d.filePath);const i=[...a.entries()].map(([d,c])=>{if(!bn.test(d))throw new Z("INTERNAL",`@lunora/codegen: refusing to emit import for unsafe file path: ${JSON.stringify(d)}`);return`import * as ${c} from "../${d}.js";`}).join(`
399
- `),s=e.map(d=>` "${R(d.filePath)}:${d.exportName}": ${a.get(d.filePath)??""}.${d.exportName} as unknown as RegisteredLunoraFunction,`).join(`
400
- `),l=t.map(d=>` ${JSON.stringify(d.id)}: ${a.get(d.filePath)??""}.${d.exportName} as unknown as RegisteredDataMigration,`).join(`
401
- `),u=n.map(d=>` "${R(d.filePath)}:${d.exportName}": ${a.get(d.filePath)??""}.${d.exportName} as unknown as RegisteredLunoraFunction,`).join(`
402
- `),p=r.map(d=>` "${d.exportName}": ${a.get(d.filePath)??""}.${d.exportName} as unknown as RegisteredShape,`).join(`
403
- `),f=n.map(d=>`${R(d.filePath)}:${d.exportName}`),y=[s,u].filter(d=>d.length>0).join(`
404
- `),N=e.map(d=>{if(d.lifecycle||Object.keys(d.args).length===0)return;const c=fn(d.args);return c===void 0?void 0:`installCompiledValidatorMap(${a.get(d.filePath)??""}.${d.exportName}.args, ${c});`}).filter(d=>d!==void 0).join(`
405
- `);return{dispatchBody:y.length>0?`
406
- ${y}
321
+ };`,Wn=(e,t,n=[],r=[])=>{const a=new Map,o=l=>{a.has(l)||a.set(l,Bn(l,a.size))};for(const l of e)o(l.filePath);for(const l of t)o(l.filePath);for(const l of n)o(l.filePath);for(const l of r)o(l.filePath);const i=[...a.entries()].map(([l,f])=>{if(!bn.test(l))throw new Z("INTERNAL",`@lunora/codegen: refusing to emit import for unsafe file path: ${JSON.stringify(l)}`);return`import * as ${f} from "../${l}.js";`}).join(`
322
+ `),s=e.map(l=>` "${R(l.filePath)}:${l.exportName}": ${a.get(l.filePath)??""}.${l.exportName} as unknown as RegisteredLunoraFunction,`).join(`
323
+ `),d=t.map(l=>` ${JSON.stringify(l.id)}: ${a.get(l.filePath)??""}.${l.exportName} as unknown as RegisteredDataMigration,`).join(`
324
+ `),u=n.map(l=>` "${R(l.filePath)}:${l.exportName}": ${a.get(l.filePath)??""}.${l.exportName} as unknown as RegisteredLunoraFunction,`).join(`
325
+ `),p=r.map(l=>` "${l.exportName}": ${a.get(l.filePath)??""}.${l.exportName} as unknown as RegisteredShape,`).join(`
326
+ `),g=n.map(l=>`${R(l.filePath)}:${l.exportName}`),b=[s,u].filter(l=>l.length>0).join(`
327
+ `),c=e.map(l=>{if(l.lifecycle||Object.keys(l.args).length===0)return;const f=fn(l.args);return f===void 0?void 0:`installCompiledValidatorMap(${a.get(l.filePath)??""}.${l.exportName}.args, ${f});`}).filter(l=>l!==void 0).join(`
328
+ `);return{dispatchBody:b.length>0?`
329
+ ${b}
407
330
  `:"",importBlock:i.length>0?`${i}
408
331
 
409
- `:"",installBlock:N,migrationBody:l.length>0?`
410
- ${l}
411
- `:"",mutatorPaths:f,shapeBody:p.length>0?`
332
+ `:"",installBlock:c,migrationBody:d.length>0?`
333
+ ${d}
334
+ `:"",mutatorPaths:g,shapeBody:p.length>0?`
412
335
  ${p}
413
- `:""}},jn=e=>{const t=new Map;for(const a of e){const o=t.get(a.filePath)??[];o.push(a),t.set(a.filePath,o)}const n=[...t.entries()].toSorted(([a],[o])=>a.localeCompare(o)),r=n.map(([a,o])=>{const i=o.map(s=>{const l=me(s.args),u=l==="{}"?"?":"",p=qe(Be(s.returnType,s.filePath));return s.kind==="stream"?` ${s.exportName}: (args${u}: ${l}) => Promise<AsyncIterable<${p}>>;`:` ${s.exportName}: (args${u}: ${l}) => Promise<${p}>;`}).join(`
414
- `);return` ${D(R(a))}: {
336
+ `:""}},Un=e=>{const t=new Map;for(const a of e){const o=t.get(a.filePath)??[];o.push(a),t.set(a.filePath,o)}const n=[...t.entries()].toSorted(([a],[o])=>a.localeCompare(o)),r=n.map(([a,o])=>{const i=o.map(s=>{const d=D(fe(s.args),s.filePath),u=d==="{}"?"?":"",p=D(s.returnType,s.filePath);return s.kind==="stream"?` ${s.exportName}: (args${u}: ${d}) => Promise<AsyncIterable<${p}>>;`:` ${s.exportName}: (args${u}: ${d}) => Promise<${p}>;`}).join(`
337
+ `);return` ${I(R(a))}: {
415
338
  ${i}
416
339
  };`}).join(`
417
- `);return{implementation:n.map(([a,o])=>{const i=R(a),s=o.map(l=>` ${l.exportName}: (args) => callRegistered(context, "${i}:${l.exportName}", args),`).join(`
418
- `);return` ${D(i)}: {
340
+ `);return{implementation:n.map(([a,o])=>{const i=R(a),s=o.map(d=>` ${d.exportName}: (args) => callRegistered(context, "${i}:${d.exportName}", args),`).join(`
341
+ `);return` ${I(i)}: {
419
342
  ${s}
420
343
  },`}).join(`
421
- `),types:r}},Wn=(e,t=[])=>{const n=new Set;for(const r of e.tables)for(const a of Object.values(r.shape)){const o=a.kind==="optional"&&a.inner?a.inner:a;o.kind==="storage"&&typeof o.bucket=="string"&&o.bucket!==""&&n.add(o.bucket)}for(const r of t)r!==""&&r!=="default"&&n.add(r);return["default",...[...n].toSorted((r,a)=>r.localeCompare(a))]},Ir=({agents:e=[],containers:t=[],env:n,hasAccessFacade:r=!1,hasAi:a=!1,hasAnalytics:o=!1,hasBrowser:i=!1,hasFlags:s=!1,hasHyperdrive:l=!1,hasImages:u=!1,hasKv:p=!1,hasNotify:f=!1,hasPayments:y=!1,hasPipelines:N=!1,hasR2sql:d=!1,hasX402:c=!1,identity:g,queues:b=[],schema:k,storageRuleBuckets:$=[],useUmbrella:T=!1,workflows:O=[]}={})=>{const S=G(T),x=Wn(k??{tables:[]},$).map(h=>JSON.stringify(h)).join(" | "),P=a?`import type { LunoraAi } from "@lunora/ai";
422
- `:"",ee=a?`
423
- readonly ai: LunoraAi;`:"",F=y?`import type { LunoraPayment } from "@lunora/payment";
424
- `:"",te=y?`
425
- readonly payments: LunoraPayment;`:"",ne=c?`import type { X402Pay } from "@lunora/x402/pay";
426
- `:"",B=c?`
427
- readonly x402: X402Pay;`:"",A=t.length>0?`import type { ContainerAccessor } from "@lunora/container";
344
+ `),types:r}},Kn=(e,t=[])=>{const n=new Set;for(const r of e.tables)for(const a of Object.values(r.shape)){const o=a.kind==="optional"&&a.inner?a.inner:a;o.kind==="storage"&&typeof o.bucket=="string"&&o.bucket!==""&&n.add(o.bucket)}for(const r of t)r!==""&&r!=="default"&&n.add(r);return["default",...[...n].toSorted((r,a)=>r.localeCompare(a))]},_r=({agents:e=[],containers:t=[],env:n,hasAccessFacade:r=!1,hasAi:a=!1,hasAnalytics:o=!1,hasBrowser:i=!1,hasFlags:s=!1,hasHyperdrive:d=!1,hasImages:u=!1,hasKv:p=!1,hasNotify:g=!1,hasPayments:b=!1,hasPipelines:c=!1,hasR2sql:l=!1,hasX402:f=!1,identity:x,queues:k=[],schema:v,storageRuleBuckets:A=[],useUmbrella:P=!1,workflows:L=[]}={})=>{const $=ee(P),w=Kn(v??{tables:[]},A).map(h=>JSON.stringify(h)).join(" | "),M=a?`import type { LunoraAi } from "@lunora/ai";
345
+ `:"",te=a?`
346
+ readonly ai: LunoraAi;`:"",F=b?`import type { LunoraPayment } from "@lunora/payment";
347
+ `:"",ne=b?`
348
+ readonly payments: LunoraPayment;`:"",re=f?`import type { X402Pay } from "@lunora/x402/pay";
349
+ `:"",j=f?`
350
+ readonly x402: X402Pay;`:"",T=t.length>0?`import type { ContainerAccessor } from "@lunora/container";
428
351
  `:"",z=t.length>0?`
429
352
  readonly containers: {${t.map(h=>`
430
353
  readonly ${h.exportName}: ContainerAccessor;`).join("")}
431
- };`:"",L=[...a?[" /** Workers AI binding (the conventional `env.AI`), narrowing `ctx.ai`. */\n readonly AI?: unknown;"]:[],...t.map(h=>(m(h.bindingName,`container binding "${h.bindingName}"`),` /** Durable Object namespace for the \`${h.exportName}\` container. */
432
- readonly ${h.bindingName}?: unknown;`)),...O.map(h=>(m(h.bindingName,`workflow binding "${h.bindingName}"`),` /** Workflow binding for the \`${h.exportName}\` workflow. */
433
- readonly ${h.bindingName}?: unknown;`)),...b.map(h=>(m(h.bindingName,`queue binding "${h.bindingName}"`),` /** Queue producer binding for the \`${h.exportName}\` queue. */
354
+ };`:"",O=[...a?[" /** Workers AI binding (the conventional `env.AI`), narrowing `ctx.ai`. */\n readonly AI?: unknown;"]:[],...t.map(h=>(m(h.bindingName,`container binding "${h.bindingName}"`),` /** Durable Object namespace for the \`${h.exportName}\` container. */
355
+ readonly ${h.bindingName}?: unknown;`)),...L.map(h=>(m(h.bindingName,`workflow binding "${h.bindingName}"`),` /** Workflow binding for the \`${h.exportName}\` workflow. */
356
+ readonly ${h.bindingName}?: unknown;`)),...k.map(h=>(m(h.bindingName,`queue binding "${h.bindingName}"`),` /** Queue producer binding for the \`${h.exportName}\` queue. */
434
357
  readonly ${h.bindingName}?: unknown;`)),...e.map(h=>(m(h.bindingName,`agent binding "${h.bindingName}"`),` /** Workflow binding for the \`${h.exportName}\` agent. */
435
358
  readonly ${h.bindingName}?: unknown;`))].join(`
436
- `),I=`
359
+ `),C=`
437
360
 
438
361
  /**
439
362
  * This project's Cloudflare bindings, as far as codegen can discover them from
@@ -446,26 +369,26 @@ ${s}
446
369
  * surface, so treat them as \`Fetcher\`/\`Service<unknown>\` and cast.
447
370
  */
448
371
  export interface CloudflareBindings {
449
- readonly [binding: string]: unknown;${L?`
450
- ${L}`:""}
372
+ readonly [binding: string]: unknown;${O?`
373
+ ${O}`:""}
451
374
  }
452
375
 
453
376
  /** Alias for {@link CloudflareBindings} — the typed shape of \`env\`. */
454
- export type Env = CloudflareBindings;`,M=(h,_e)=>_e?dn.get(h)?.field??"":"",re=M("kv",p),ae=M("analytics",o),ke=M("hyperdrive",l),ve=M("browser",i),$e=M("images",u),oe=M("pipelines",N),K=M("r2sql",d),E=(k?.vectorIndexes.length??0)>0,Q=E?' | "vectors"':"",X=E?`
455
- readonly vectors: VectorSearch<VectorIndexName>;`:"",se=E?`
456
- readonly vectors: VectorSearchReader<VectorIndexName>;`:"",H=E?`import type { VectorSearch, VectorSearchReader } from "${S.server}";
377
+ export type Env = CloudflareBindings;`,q=(h,Ee)=>Ee?dn.get(h)?.field??"":"",ae=q("kv",p),oe=q("analytics",o),ve=q("hyperdrive",d),$e=q("browser",i),Se=q("images",u),se=q("pipelines",c),Q=q("r2sql",l),E=(v?.vectorIndexes.length??0)>0,H=E?' | "vectors"':"",X=E?`
378
+ readonly vectors: VectorSearch<VectorIndexName>;`:"",ie=E?`
379
+ readonly vectors: VectorSearchReader<VectorIndexName>;`:"",V=E?`import type { VectorSearch, VectorSearchReader } from "${$.server}";
457
380
  import type { VectorIndexName } from "./dataModel.js";
458
- `:"",j=r?`
381
+ `:"",W=r?`
459
382
  /** Verified Cloudflare Access identity — a synchronous facade over the resolved claims (email / groups / hasGroup / claims). Anonymous when no Access token is present. */
460
- readonly access: import("@lunora/cloudflare-access/context").AccessFacade;`:"",W=s?`
383
+ readonly access: import("@lunora/cloudflare-access/context").AccessFacade;`:"",U=s?`
461
384
  /** Feature-flag evaluation (OpenFeature). Reads are memoized per request; evaluations never throw — a provider error resolves to the supplied default. */
462
- readonly flags: import("${S.flags}").LunoraFlags;`:"",U=f?`
385
+ readonly flags: import("${$.flags}").LunoraFlags;`:"",K=g?`
463
386
  /** Multi-channel notifications (@lunora/notify): send / chat / inApp / webhook plus the push device sub-facade. Sends are external I/O — confine them to action handlers. */
464
387
  readonly notify: import("@lunora/notify").LunoraNotify;
465
388
  /** Device push sub-facade — the same object as ctx.notify.push (register / send / broadcast). Sends belong in action handlers. */
466
- readonly push: import("@lunora/notify").LunoraPush;`:"",q=O.length>0,Y=q?`import type { WorkflowHandle } from "@lunora/workflow";
389
+ readonly push: import("@lunora/notify").LunoraPush;`:"",B=L.length>0,Y=B?`import type { WorkflowHandle } from "@lunora/workflow";
467
390
  import type * as lunoraWorkflowDefinitions from "../workflows.js";
468
- `:"",Se=q?`
391
+ `:"",Re=B?`
469
392
 
470
393
  /** Params type carried by a \`defineWorkflow\` definition (its phantom \`__params\`). */
471
394
  type WorkflowParamsOf<Definition> = Definition extends { __params?: infer Params }
@@ -476,43 +399,43 @@ type WorkflowParamsOf<Definition> = Definition extends { __params?: infer Params
476
399
 
477
400
  /** This project's declared workflows, addressable from \`ctx.workflows\` by their \`lunora/workflows.ts\` export name. */
478
401
  export interface LunoraWorkflows {
479
- ${O.map(h=>` get(name: ${JSON.stringify(h.exportName)}): WorkflowHandle<WorkflowParamsOf<typeof lunoraWorkflowDefinitions.${h.exportName}>>;`).join(`
402
+ ${L.map(h=>` get(name: ${JSON.stringify(h.exportName)}): WorkflowHandle<WorkflowParamsOf<typeof lunoraWorkflowDefinitions.${h.exportName}>>;`).join(`
480
403
  `)}
481
- }`:"",fe=q?' | "workflows"':"",be=q?`
482
- readonly workflows: LunoraWorkflows;`:"",ie=b.length>0,Re=ie?`import type { QueueProducer } from "@lunora/queue";
404
+ }`:"",be=B?' | "workflows"':"",ye=B?`
405
+ readonly workflows: LunoraWorkflows;`:"",le=k.length>0,Ne=le?`import type { QueueProducer } from "@lunora/queue";
483
406
  import type * as lunoraQueueDefinitions from "../queues.js";
484
- `:"",Ne=ie?`
407
+ `:"",Te=le?`
485
408
 
486
409
  /** Message body type carried by a \`defineQueue\` definition (its phantom \`__lunoraBody\`). */
487
410
  type QueueBodyOf<Definition> = Definition extends { __lunoraBody?: infer Body } ? (unknown extends Body ? unknown : NonNullable<Body>) : unknown;
488
411
 
489
412
  /** This project's declared queues, addressable from \`ctx.queues\` by their \`lunora/queues.ts\` export name. */
490
413
  export interface LunoraQueues {
491
- ${b.map(h=>` readonly ${h.exportName}: QueueProducer<QueueBodyOf<typeof lunoraQueueDefinitions.${h.exportName}>>;`).join(`
414
+ ${k.map(h=>` readonly ${h.exportName}: QueueProducer<QueueBodyOf<typeof lunoraQueueDefinitions.${h.exportName}>>;`).join(`
492
415
  `)}
493
- }`:"",ye=ie?`
494
- readonly queues: LunoraQueues;`:"",le=e.length>0,Oe=le?`import type { AgentHandle } from "@lunora/agent";
495
- `:"",Te=le?`
416
+ }`:"",we=le?`
417
+ readonly queues: LunoraQueues;`:"",de=e.length>0,Oe=de?`import type { AgentHandle } from "@lunora/agent";
418
+ `:"",Ae=de?`
496
419
 
497
420
  /** This project's declared agents, addressable from \`ctx.agents\` by their \`lunora/agents.ts\` export name. */
498
421
  export interface LunoraAgents {
499
422
  ${e.map(h=>(m(h.exportName,`agent export "${h.exportName}"`),` readonly ${h.exportName}: AgentHandle;`)).join(`
500
423
  `)}
501
- }`:"",we=le?`
502
- readonly agents: LunoraAgents;`:"",Ae=g?`import type { InferIdentity } from "${S.server}";
424
+ }`:"",xe=de?`
425
+ readonly agents: LunoraAgents;`:"",Le=x?`import type { InferIdentity } from "${$.server}";
503
426
  import type * as lunoraIdentityContract from "../identity.js";
504
- `:"",Le=g?`
427
+ `:"",Ce=x?`
505
428
 
506
429
  /** This app's declared identity claim contract (\`defineIdentity\` in \`lunora/identity.ts\`) — the typed shape of \`ctx.auth.getIdentity()\`, the RLS policy \`ctx.auth.identity\`, and the \`authorizeShard\`/\`authorizeFanOut\` identity argument. */
507
- export type Identity = InferIdentity<typeof lunoraIdentityContract.${g.exportName}>;
430
+ export type Identity = InferIdentity<typeof lunoraIdentityContract.${x.exportName}>;
508
431
 
509
432
  /** \`ctx.auth\` narrowed so \`getIdentity()\` resolves the declared {@link Identity} contract instead of the untyped claim bag. */
510
- type NarrowedAuth = Omit<QueryCtxBase["auth"], "getIdentity"> & { getIdentity: () => Promise<Identity | null> };`:"",de=g?' | "auth"':"",ce=g?`
511
- readonly auth: NarrowedAuth;`:"",Ce=g?", Identity":"",Ie=n?`import type * as lunoraEnvContract from "../env.js";
512
- `:"",De=n?`
433
+ type NarrowedAuth = Omit<QueryCtxBase["auth"], "getIdentity"> & { getIdentity: () => Promise<Identity | null> };`:"",ce=x?' | "auth"':"",ue=x?`
434
+ readonly auth: NarrowedAuth;`:"",Ie=x?", Identity":"",De=n?`import type * as lunoraEnvContract from "../env.js";
435
+ `:"",_e=n?`
513
436
 
514
437
  /** This app's declared env contract (\`defineEnv\` in \`lunora/env.ts\`) — the validated, coercion-aware shape of \`ctx.env\`. */
515
- export type LunoraEnv = ReturnType<typeof lunoraEnvContract.${n.exportName}>;`:"",ue=n?' | "env"':"",pe=n?"\n /** Validated, typed environment declared by `defineEnv` in `lunora/env.ts` — parsed & coercion-aware config values (`ctx.env.STRIPE_KEY`); a missing or invalid value throws at read time. */\n readonly env: LunoraEnv;":"";return`${v}import { createPolicyDsl, defineMutator as defineMutatorBase, initLunora, v as vBase } from "${S.server}";
438
+ export type LunoraEnv = ReturnType<typeof lunoraEnvContract.${n.exportName}>;`:"",pe=n?' | "env"':"",he=n?"\n /** Validated, typed environment declared by `defineEnv` in `lunora/env.ts` — parsed & coercion-aware config values (`ctx.env.STRIPE_KEY`); a missing or invalid value throws at read time. */\n readonly env: LunoraEnv;":"";return`${S}import { createPolicyDsl, defineMutator as defineMutatorBase, initLunora, v as vBase } from "${$.server}";
516
439
  import type {
517
440
  ActionBuilder,
518
441
  ActionCtx as ActionCtxBase,
@@ -533,14 +456,102 @@ import type {
533
456
  Storage as StorageBase,
534
457
  TableReader,
535
458
  Validator,
536
- } from "${S.server}";
459
+ } from "${$.server}";
460
+
461
+ import type {
462
+ DatabaseReaderFacade as DatabaseReaderFacadeOf,
463
+ DatabaseWriterFacade as DatabaseWriterFacadeOf,
464
+ LoadWith as LoadWithOf,
465
+ TableReaderFacade as TableReaderFacadeOf,
466
+ TableWriterFacade as TableWriterFacadeOf,
467
+ WithArg as WithArgOf,
468
+ } from "${$.serverDataModel}";
469
+
470
+ export type {
471
+ AggregateOp,
472
+ GroupByEntry,
473
+ OrderBy,
474
+ QueryArgs,
475
+ QueryPage,
476
+ RankPage,
477
+ RankResult,
478
+ RestrictableQueryOptions,
479
+ RestrictableQueryOptionsOf,
480
+ SearchFilterBuilder,
481
+ SearchReader,
482
+ TableAggregateOptions,
483
+ TableAggregateOptionsOf,
484
+ TableGroupByOptions,
485
+ TableGroupByOptionsOf,
486
+ TableRankOptions,
487
+ TableRankPageOptions,
488
+ Where,
489
+ WhereOf,
490
+ WhereOperators,
491
+ } from "${$.serverDataModel}";
537
492
 
538
- import type { DataModel, DatabaseReaderFacade, DatabaseWriterFacade, Doc, GeoIndexNamesByTable, Id as IdOfTable, IndexNamesByTable, OrmReader, OrmWriter, Relations, SearchIndexNamesByTable, TableName } from "./dataModel.js";
539
- ${H}${P}${F}${ne}${A}${Y}${Re}${Oe}${Ae}${Ie}
493
+ import type { DataModel, Doc, GeoIndexNamesByTable, Id as IdOfTable, IndexNamesByTable, Insert, InsertModel, RankIndexNamesByTable, Relations, SearchIndexNamesByTable, TableName } from "./dataModel.js";
494
+ ${V}${M}${F}${re}${T}${Y}${Ne}${Oe}${Le}${De}
540
495
  export type { AppTableName, DataModel, Doc, Id, TableName } from "./dataModel.js";
541
496
 
497
+ /**
498
+ * The query-DSL bindings: \`@lunora/server/data-model\`'s generics parameterized
499
+ * over this project's \`DataModel\` / \`InsertModel\` / \`Relations\` / index maps.
500
+ *
501
+ * They live here rather than in \`dataModel.ts\` because they are the half that
502
+ * needs the SERVER package. Keeping \`dataModel.ts\` free of it lets a sibling
503
+ * package — a web app, another Worker — compile \`api.ts\` for its \`Doc\`/\`Id\`
504
+ * types without installing a server dependency to do it.
505
+ */
506
+
507
+ /** The \`with\` argument for table \`T\` — see \`@lunora/server/data-model\`. */
508
+ export type WithArg<T extends keyof DataModel> = WithArgOf<DataModel, Relations, T>;
509
+
510
+ /** \`Doc<T>\` narrowed to exactly the relations requested in the with-arg \`W\`. */
511
+ export type LoadWith<T extends keyof DataModel, W> = LoadWithOf<DataModel, Relations, T, W>;
512
+
513
+ /** Read-only typed table accessor exposed on \`QueryCtx.db.<table>\`. */
514
+ export type TableReaderFacade<T extends keyof DataModel> = TableReaderFacadeOf<DataModel, Relations, RankIndexNamesByTable, SearchIndexNamesByTable, T, GeoIndexNamesByTable>;
515
+
516
+ /** Read-write typed table accessor exposed on \`MutationCtx.db.<table>\` / \`ActionCtx.db.<table>\`. */
517
+ export type TableWriterFacade<T extends keyof DataModel> = TableWriterFacadeOf<DataModel, InsertModel, Relations, RankIndexNamesByTable, SearchIndexNamesByTable, T, GeoIndexNamesByTable>;
518
+
519
+ /** Per-table read facade — \`ctx.db.<table>\` on a \`QueryCtx\`. */
520
+ export type DatabaseReaderFacade = DatabaseReaderFacadeOf<DataModel, Relations, RankIndexNamesByTable, SearchIndexNamesByTable, GeoIndexNamesByTable>;
521
+
522
+ /** Per-table read-write facade — \`ctx.db.<table>\` on a \`MutationCtx\` / \`ActionCtx\`. */
523
+ export type DatabaseWriterFacade = DatabaseWriterFacadeOf<DataModel, InsertModel, Relations, RankIndexNamesByTable, SearchIndexNamesByTable, GeoIndexNamesByTable>;
524
+
525
+ /** Insert builder returned by \`ctx.orm.insert(table)\`. */
526
+ export interface OrmInsertBuilder<T extends keyof DataModel> {
527
+ values: (values: Insert<T>) => Promise<IdOfTable<T>>;
528
+ }
529
+
530
+ /** Replace builder returned by \`ctx.orm.replace(table, id)\` — swaps the whole document. */
531
+ export interface OrmReplaceBuilder<T extends keyof DataModel> {
532
+ with: (values: Insert<T>) => Promise<void>;
533
+ }
534
+
535
+ /** Update builder returned by \`ctx.orm.update(table, id)\` — patches the named fields. */
536
+ export interface OrmUpdateBuilder<T extends keyof DataModel> {
537
+ set: (values: Partial<Insert<T>>) => Promise<void>;
538
+ }
539
+
540
+ /** Read-only ORM surface — \`ctx.orm\` on a \`QueryCtx\`. Mirrors \`ctx.db\` reads under a kitcn-style \`query\` namespace. */
541
+ export interface OrmReader {
542
+ query: DatabaseReaderFacade;
543
+ }
544
+
545
+ /** Read-write ORM surface — \`ctx.orm\` on a \`MutationCtx\` / \`ActionCtx\`. Writes are addressed by id, like \`ctx.db\`. */
546
+ export interface OrmWriter extends OrmReader {
547
+ delete: <T extends keyof DataModel>(table: T, id: IdOfTable<T>) => Promise<void>;
548
+ insert: <T extends keyof DataModel>(table: T) => OrmInsertBuilder<T>;
549
+ replace: <T extends keyof DataModel>(table: T, id: IdOfTable<T>) => OrmReplaceBuilder<T>;
550
+ update: <T extends keyof DataModel>(table: T, id: IdOfTable<T>) => OrmUpdateBuilder<T>;
551
+ }
552
+
542
553
  /** Storage buckets this schema declares (\`v.storage("name")\`), narrowing \`ctx.storage.bucket(name)\`. */
543
- export type StorageBucketName = ${x};${I}${Se}${Ne}${Te}${Le}${De}
554
+ export type StorageBucketName = ${w};${C}${Re}${Te}${Ae}${Ce}${_e}
544
555
 
545
556
  /**
546
557
  * Project-typed contexts. The base contexts from \`@lunora/server\` are
@@ -603,22 +614,22 @@ type AsIdTable<T extends string> = T extends TableName ? T : string extends T ?
603
614
  */
604
615
  type TypedAsId = <T extends string>(tableName: AsIdTable<T>, id: string) => IdOfTable<T & TableName>;
605
616
 
606
- export interface QueryCtx extends Omit<QueryCtxBase, "db" | "storage"${Q}${de}${ue}> {
617
+ export interface QueryCtx extends Omit<QueryCtxBase, "db" | "storage"${H}${ce}${pe}> {
607
618
  readonly db: Omit<DatabaseReader, "asId" | "query" | "get"> & DatabaseReaderFacade & { asId: TypedAsId; query: TypedTableQuery; get: TypedTableGet };
608
619
  readonly orm: OrmReader;
609
- readonly storage: ReadOnlyStorage<StorageBucketName>;${se}${j}${re}${W}${U}${ae}${pe}${ce}
620
+ readonly storage: ReadOnlyStorage<StorageBucketName>;${ie}${W}${ae}${U}${K}${oe}${he}${ue}
610
621
  }
611
622
 
612
- export interface MutationCtx extends Omit<MutationCtxBase, "db" | "storage"${Q}${fe}${de}${ue}> {
623
+ export interface MutationCtx extends Omit<MutationCtxBase, "db" | "storage"${H}${be}${ce}${pe}> {
613
624
  readonly db: Omit<DatabaseWriter, "asId" | "query" | "get"> & DatabaseWriterFacade & { asId: TypedAsId; query: TypedTableQuery; get: TypedTableGet };
614
625
  readonly orm: OrmWriter;
615
- readonly storage: ReadOnlyStorage<StorageBucketName>;${X}${j}${re}${W}${U}${ae}${pe}${be}${ye}${we}${ce}
626
+ readonly storage: ReadOnlyStorage<StorageBucketName>;${X}${W}${ae}${U}${K}${oe}${he}${ye}${we}${xe}${ue}
616
627
  }
617
628
 
618
- export interface ActionCtx extends Omit<ActionCtxBase, "db" | "storage"${Q}${fe}${de}${ue}> {
629
+ export interface ActionCtx extends Omit<ActionCtxBase, "db" | "storage"${H}${be}${ce}${pe}> {
619
630
  readonly db: Omit<DatabaseWriter, "asId" | "query" | "get"> & DatabaseWriterFacade & { asId: TypedAsId; query: TypedTableQuery; get: TypedTableGet };
620
631
  readonly orm: OrmWriter;
621
- readonly storage: StorageBase<StorageBucketName>;${X}${j}${ee}${te}${B}${z}${re}${W}${U}${ke}${ve}${$e}${ae}${oe}${K}${pe}${be}${ye}${we}${ce}
632
+ readonly storage: StorageBase<StorageBucketName>;${X}${W}${te}${ne}${j}${z}${ae}${U}${K}${ve}${$e}${Se}${oe}${se}${Q}${he}${ye}${we}${xe}${ue}
622
633
  }
623
634
 
624
635
  /**
@@ -651,7 +662,7 @@ export const internalAction = lunoraBuilders.internalAction as unknown as Intern
651
662
  /**
652
663
  * \`defineMutator\` bound to this project's typed {@link MutationCtx} — declare
653
664
  * custom mutators (\`lunora/mutators.ts\`) with it instead of importing from
654
- * \`${S.server}\`, and the authoritative \`server\` impl's \`ctx\` carries the
665
+ * \`${$.server}\`, and the authoritative \`server\` impl's \`ctx\` carries the
655
666
  * schema-typed \`ctx.db\` (\`ctx.db.query("nodes")\` resolves \`Doc<"nodes">\`,
656
667
  * \`ctx.db.patch(id, …)\` takes an \`Id<"nodes">\`) with no hand-written ctx type and
657
668
  * no \`as unknown as\` cast. Runtime-identical to the package export; only the
@@ -676,7 +687,7 @@ export const defineMutator = defineMutatorBase as unknown as <Args extends Recor
676
687
  * Runtime-identical to \`@lunora/server\`'s \`definePolicy\`; only the types narrow,
677
688
  * so the \`rls()\` chain discovers a policy authored either way the same.
678
689
  */
679
- export const definePolicy = createPolicyDsl<DataModel, Relations${Ce}>();
690
+ export const definePolicy = createPolicyDsl<DataModel, Relations${Ie}>();
680
691
 
681
692
  /**
682
693
  * The validator builder \`v\`, with \`v.id(...)\` constrained to THIS schema's
@@ -693,45 +704,45 @@ export const definePolicy = createPolicyDsl<DataModel, Relations${Ce}>();
693
704
  export const v = vBase as unknown as Omit<typeof vBase, "id"> & {
694
705
  id: <T extends TableName>(table: T) => ColumnValidator<IdOfTable<T>, IdOfTable<T>>;
695
706
  };
696
- `},Un=e=>{const t={connect:[],disconnect:[]};for(const n of e)n.lifecycle&&t[n.lifecycle].push(`${R(n.filePath)}:${n.exportName}`);return t},Dr=e=>{const{agents:t=[],functions:n,migrations:r=[],mutators:a=[],shapes:o=[],useUmbrella:i=!1,usesSandbox:s=!1}=e,l=n.length>0,u=G(i),{dispatchBody:p,importBlock:f,installBlock:y,migrationBody:N,mutatorPaths:d,shapeBody:c}=Bn(n,r,a,o),g=Dn(t,n),b=_n(s,n),k=[g.lines,b.lines].filter(I=>I.length>0).join(`
697
- `);let $=p;k.length>0&&($=p.length>0?`${p.trimEnd()}
698
- ${k}
707
+ `},Qn=e=>{const t={connect:[],disconnect:[]};for(const n of e)n.lifecycle&&t[n.lifecycle].push(`${R(n.filePath)}:${n.exportName}`);return t},Er=e=>{const{agents:t=[],functions:n,migrations:r=[],mutators:a=[],shapes:o=[],useUmbrella:i=!1,usesSandbox:s=!1}=e,d=n.length>0,u=ee(i),{dispatchBody:p,importBlock:g,installBlock:b,migrationBody:c,mutatorPaths:l,shapeBody:f}=Wn(n,r,a,o),x=En(t,n),k=Pn(s,n),v=[x.lines,k.lines].filter(C=>C.length>0).join(`
708
+ `);let A=p;v.length>0&&(A=p.length>0?`${p.trimEnd()}
709
+ ${v}
699
710
  `:`
700
- ${k}
701
- `);const T=Un(n),O=o.length>0?`import type { RegisteredShape } from "${u.server}";
702
- `:"",S=o.length>0?`
711
+ ${v}
712
+ `);const P=Qn(n),L=o.length>0?`import type { RegisteredShape } from "${u.server}";
713
+ `:"",$=o.length>0?`
703
714
  /**
704
715
  * Replication-shape registry — one entry per \`defineShape\` in \`lunora/shapes.ts\`.
705
716
  * The generated ShardDO's \`resolveShape\` override looks a shape up by name and
706
717
  * evaluates its trusted \`compileWhere(ctx, args)\` to authorize + scope a
707
718
  * \`shape_subscribe\` (reads-as-permissions).
708
719
  */
709
- export const LUNORA_SHAPES: Record<string, RegisteredShape> = {${c}};
710
- `:"",x=d.length>0?`
720
+ export const LUNORA_SHAPES: Record<string, RegisteredShape> = {${f}};
721
+ `:"",w=l.length>0?`
711
722
  /**
712
723
  * Custom-mutator function paths — the \`LUNORA_FUNCTIONS\` keys the generated
713
724
  * ShardDO's \`isCustomMutator\` override routes through the client-watermark push
714
725
  * protocol (\`x-lunora-client-id\`/\`x-lunora-client-seq\` ordering).
715
726
  */
716
- export const LUNORA_MUTATOR_PATHS: ReadonlySet<string> = new Set([${d.map(I=>JSON.stringify(I)).join(", ")}]);
717
- `:"",P=y.length>0?`import { DEFER_VALIDATION as DEFER, installCompiledValidatorMap } from "${u.values}";
718
- `:"",ee=y.length>0?`
727
+ export const LUNORA_MUTATOR_PATHS: ReadonlySet<string> = new Set([${l.map(C=>JSON.stringify(C)).join(", ")}]);
728
+ `:"",M=b.length>0?`import { DEFER_VALIDATION as DEFER, installCompiledValidatorMap } from "${u.values}";
729
+ `:"",te=b.length>0?`
719
730
  /**
720
731
  * AOT-compiled argument validators (Worker-safe, no \`eval\`). Each is installed
721
732
  * onto its function's live \`.args\` object and consulted by the interpreted
722
733
  * parser as a zero-allocation fast path; anything it can't model is deferred.
723
734
  */
724
- ${y}
725
- `:"",F=jn(n),te=F.types?`
735
+ ${b}
736
+ `:"",F=Un(n),ne=F.types?`
726
737
  ${F.types}
727
- `:"",ne=F.implementation?`
738
+ `:"",re=F.implementation?`
728
739
  ${F.implementation}
729
- `:"",B=je(F.types),A=B.length>0?`import type { ${B.join(", ")} } from "./dataModel.js";
730
- `:"",z=l?"context":"_context",L=l?`${qn}
740
+ `:"",j=je(F.types),T=j.length>0?`import type { ${j.join(", ")} } from "./dataModel.js";
741
+ `:"",z=d?"context":"_context",O=d?`${jn}
731
742
 
732
- `:"";return ct(`${v}${f}${g.importLine}${b.importLine}${P}${O}import { LunoraError } from "${u.server}";
743
+ `:"";return ct(`${S}${g}${x.importLine}${k.importLine}${M}${L}import { LunoraError } from "${u.server}";
733
744
  import type { ActionCtx, MutationCtx, QueryCtx } from "./server.js";
734
- ${A}
745
+ ${T}
735
746
  /**
736
747
  * Single registered function, narrowed to the shape \`handleRpc\` needs.
737
748
  * The real argument validators / return types are checked elsewhere — at
@@ -750,13 +761,13 @@ export interface RegisteredLunoraFunction {
750
761
  /** \`"internal"\` functions are rejected on the external RPC path; absence === public. */
751
762
  visibility?: "internal" | "public";
752
763
  }
753
- ${g.prelude}${b.prelude}
764
+ ${x.prelude}${k.prelude}
754
765
  /**
755
766
  * Static dispatch table. The key matches the \`__lunoraRef\` the client
756
767
  * emits (\`api[namespace][fn].__lunoraRef === "namespace:fn"\`).
757
768
  */
758
- export const LUNORA_FUNCTIONS: Record<string, RegisteredLunoraFunction> = {${$}};
759
- ${ee}${S}${x}
769
+ export const LUNORA_FUNCTIONS: Record<string, RegisteredLunoraFunction> = {${A}};
770
+ ${te}${$}${w}
760
771
  /**
761
772
  * Connection-lifecycle manifest: the function paths the generated ShardDO
762
773
  * dispatches when a client's WebSocket connects (\`connect\`) or disconnects
@@ -764,8 +775,8 @@ ${ee}${S}${x}
764
775
  * DO runs every hook under the socket's verified identity via system dispatch.
765
776
  */
766
777
  export const LUNORA_LIFECYCLE_HOOKS: { connect: readonly string[]; disconnect: readonly string[] } = {
767
- connect: [${T.connect.map(I=>JSON.stringify(I)).join(", ")}],
768
- disconnect: [${T.disconnect.map(I=>JSON.stringify(I)).join(", ")}],
778
+ connect: [${P.connect.map(C=>JSON.stringify(C)).join(", ")}],
779
+ disconnect: [${P.disconnect.map(C=>JSON.stringify(C)).join(", ")}],
769
780
  };
770
781
 
771
782
  /**
@@ -796,10 +807,10 @@ export type CallerCtx = ActionCtx | MutationCtx | QueryCtx;
796
807
  * with the supplied \`context\`, exactly like \`ctx.runQuery\`/\`runMutation\`/
797
808
  * \`runAction\` but without re-stating the function path.
798
809
  */
799
- export interface Caller {${te}}
810
+ export interface Caller {${ne}}
800
811
 
801
- ${L}/** Build a {@link Caller} bound to \`context\` (typically a handler's \`ctx\`). */
802
- export const createCaller = (${z}: CallerCtx): Caller => ({${ne}});
812
+ ${O}/** Build a {@link Caller} bound to \`context\` (typically a handler's \`ctx\`). */
813
+ export const createCaller = (${z}: CallerCtx): Caller => ({${re}});
803
814
 
804
815
  /**
805
816
  * Single registered data migration, narrowed to the shape the per-shard runner
@@ -818,8 +829,8 @@ export interface RegisteredDataMigration {
818
829
  * Registry of online data migrations keyed by \`defineMigration\`'s \`id\`. The
819
830
  * shard DO's admin RPC and the CLI resolve migrations to run through this map.
820
831
  */
821
- export const LUNORA_MIGRATIONS: Record<string, RegisteredDataMigration> = {${N}};
822
- `,i)},Kn=e=>{const t={};for(const n of e.tables){const r={};for(const[a,o]of Object.entries(n.shape)){const i=o.kind==="optional"&&o.inner?o.inner:o;i.kind==="id"&&i.tableName!==void 0&&(r[a]=i.tableName)}Object.keys(r).length>0&&(t[n.name]=r)}return t},Qn=e=>{const t={};for(const n of e.tables){const r=[];for(const[a,o]of Object.entries(n.shape))(o.kind==="optional"&&o.inner?o.inner:o).kind==="storage"&&r.push(a);r.length>0&&(t[n.name]=r)}return t},Hn=e=>{const t={};for(const n of e.tables){const r=[...n.indexes.map(a=>({fields:[...a.fields],name:a.name,type:"index",...a.unique===!0?{unique:!0}:{}})),...n.searchIndexes.map(a=>({fields:[a.field,...a.filterFields??[]],name:a.name,type:"search"})),...(n.geoIndexes??[]).map(a=>({fields:[a.field],name:a.name,type:"geo"})),...n.rankIndexes.map(a=>({fields:a.sortBy.map(o=>o.field),name:a.name,type:"rank"})),...n.vectorIndexes.map(a=>({fields:a.field===void 0?[]:[a.field],name:a.name,type:"vector"}))];r.length>0&&(t[n.name]=r)}return t},Jn=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},Vn=e=>{const t={};for(const n of e.tables){const r=[{name:"_id",optional:!1,pk:!0,type:"id"},{name:"_creationTime",optional:!1,type:"number"}];for(const[a,o]of Object.entries(n.shape)){const i=o.kind==="optional"||!!o.column?.hasDefault,s=o.kind==="optional"&&o.inner?o.inner:o,l={name:a,optional:i,type:s.kind};s.kind==="id"&&s.tableName!==void 0&&(l.ref=s.tableName),s.kind==="storage"&&(l.isStorage=!0),r.push(l)}t[n.name]=r}return t},Gn=e=>e?{importFragment:"serveRelationFanout, ",override:`
832
+ export const LUNORA_MIGRATIONS: Record<string, RegisteredDataMigration> = {${c}};
833
+ `,i)},Hn=e=>{const t={};for(const n of e.tables){const r={};for(const[a,o]of Object.entries(n.shape)){const i=o.kind==="optional"&&o.inner?o.inner:o;i.kind==="id"&&i.tableName!==void 0&&(r[a]=i.tableName)}Object.keys(r).length>0&&(t[n.name]=r)}return t},Vn=e=>{const t={};for(const n of e.tables){const r=[];for(const[a,o]of Object.entries(n.shape))(o.kind==="optional"&&o.inner?o.inner:o).kind==="storage"&&r.push(a);r.length>0&&(t[n.name]=r)}return t},Jn=e=>{const t={};for(const n of e.tables){const r=[...n.indexes.map(a=>({fields:[...a.fields],name:a.name,type:"index",...a.unique===!0?{unique:!0}:{}})),...n.searchIndexes.map(a=>({fields:[a.field,...a.filterFields??[]],name:a.name,type:"search"})),...(n.geoIndexes??[]).map(a=>({fields:[a.field],name:a.name,type:"geo"})),...n.rankIndexes.map(a=>({fields:a.sortBy.map(o=>o.field),name:a.name,type:"rank"})),...n.vectorIndexes.map(a=>({fields:a.field===void 0?[]:[a.field],name:a.name,type:"vector"}))];r.length>0&&(t[n.name]=r)}return t},Gn=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},zn=e=>{const t={};for(const n of e.tables){const r=[{name:"_id",optional:!1,pk:!0,type:"id"},{name:"_creationTime",optional:!1,type:"number"}];for(const[a,o]of Object.entries(n.shape)){const i=o.kind==="optional"||!!o.column?.hasDefault,s=o.kind==="optional"&&o.inner?o.inner:o,d={name:a,optional:i,type:s.kind};s.kind==="id"&&s.tableName!==void 0&&(d.ref=s.tableName),s.kind==="storage"&&(d.isStorage=!0),r.push(d)}t[n.name]=r}return t},Xn=e=>e?{importFragment:"serveRelationFanout, ",override:`
823
834
  protected override async runRelationFanoutRead(functionPath: string, args: Record<string, unknown>): Promise<unknown> {
824
835
  this.ensureMigrated();
825
836
 
@@ -827,7 +838,7 @@ export const LUNORA_MIGRATIONS: Record<string, RegisteredDataMigration> = {${N}}
827
838
 
828
839
  return serveRelationFanout(schema as unknown as SchemaLike, db, functionPath, args);
829
840
  }
830
- `}:{importFragment:"",override:""},zn=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:`
841
+ `}:{importFragment:"",override:""},Yn=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:`
831
842
  const aiBinding = config.ai?.(env) ?? (env as Record<string, unknown>).AI;
832
843
  // Correlate AI-Gateway-routed calls with the Lunora trace: thread the
833
844
  // function path + trace id into createAi, which folds them into the
@@ -858,7 +869,7 @@ const aiStub: LunoraAi = {
858
869
  ${t}
859
870
  }) as unknown as LunoraAi["workersai"],
860
871
  };
861
- `}},_={build:"",configField:"",contextField:"",importLines:[],stub:""},Xn=e=>{if(!e)return _;const t='throw new Error("ctx.kv: no KV binding found. Add a \\`kv_namespaces\\` binding (env.KV) to wrangler.jsonc, or pass \\`kv\\` to createShardDO().");';return{build:`
872
+ `}},_={build:"",configField:"",contextField:"",importLines:[],stub:""},Zn=e=>{if(!e)return _;const t='throw new Error("ctx.kv: no KV binding found. Add a \\`kv_namespaces\\` binding (env.KV) to wrangler.jsonc, or pass \\`kv\\` to createShardDO().");';return{build:`
862
873
  const kvBinding = config.kv?.(env) ?? (env as Record<string, unknown>).KV;
863
874
  const kv: Kv = kvBinding ? createKv({ namespace: kvBinding as KVNamespaceLike }) : kvStub;
864
875
  `,configField:`
@@ -884,7 +895,7 @@ const kvStub: Kv = {
884
895
  ${t}
885
896
  },
886
897
  };
887
- `}},Yn=(e,t)=>e?{build:`
898
+ `}},er=(e,t)=>e?{build:`
888
899
  const flags: import("${t}").LunoraFlags = createFlags({
889
900
  hooks: flagsConfig.hooks,
890
901
  logger: flagsConfig.logger,
@@ -893,17 +904,17 @@ const kvStub: Kv = {
893
904
  });
894
905
  `,configField:`
895
906
  flags?: (env: Record<string, unknown>) => import("${t}").Provider;`,contextField:`
896
- flags,`,importLines:[`import { createFlags } from "${t}";`,'import flagsConfig from "../flags.js";'],stub:""}:_,Zn=e=>e?{build:`
907
+ flags,`,importLines:[`import { createFlags } from "${t}";`,'import flagsConfig from "../flags.js";'],stub:""}:_,tr=e=>e?{build:`
897
908
  const { notify, push } = createNotify(notifyConfig, env, { log, metrics });
898
909
  `,configField:"",contextField:`
899
910
  notify,
900
- push,`,importLines:['import { createNotify } from "@lunora/notify";','import notifyConfig from "../notify.js";'],stub:""}:_,er=e=>e?{build:`
911
+ push,`,importLines:['import { createNotify } from "@lunora/notify";','import notifyConfig from "../notify.js";'],stub:""}:_,nr=e=>e?{build:`
901
912
  const envConfig = lunoraEnvContract.${e.exportName}(env);
902
913
  `,configField:"",contextField:`
903
- env: envConfig,`,importLines:['import * as lunoraEnvContract from "../env.js";'],stub:""}:_,tr=e=>e?{build:`
914
+ env: envConfig,`,importLines:['import * as lunoraEnvContract from "../env.js";'],stub:""}:_,rr=e=>e?{build:`
904
915
  const access = accessFacade(identity, userId);
905
916
  `,configField:"",contextField:`
906
- access,`,importLines:['import { accessFacade } from "@lunora/cloudflare-access/context";'],stub:""}:_,nr=(e,t,n)=>{if(!t)return{constant:"",evaluateOverride:"",subscriptionOverride:""};const r=s=>`
917
+ access,`,importLines:['import { accessFacade } from "@lunora/cloudflare-access/context";'],stub:""}:_,ar=(e,t,n)=>{if(!t)return{constant:"",evaluateOverride:"",subscriptionOverride:""};const r=s=>`
907
918
  const env = (this.env ?? {}) as Record<string, unknown>;
908
919
  const flags: import("${n}").LunoraFlags = createFlags({
909
920
  hooks: flagsConfig.hooks,
@@ -967,7 +978,7 @@ const LUNORA_FLAG_KEYS: ReadonlyArray<{ key: string; type: "boolean" | "number"
967
978
 
968
979
  return flags.boolean(key, typeof args.default === "boolean" ? args.default : false, context);
969
980
  }
970
- `;return{constant:a,evaluateOverride:o,subscriptionOverride:i}},rr=e=>{if(!e)return _;const t='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().");';return{build:`
981
+ `;return{constant:a,evaluateOverride:o,subscriptionOverride:i}},or=e=>{if(!e)return _;const t='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().");';return{build:`
971
982
  const analyticsBinding = config.analytics?.(env) ?? (env as Record<string, unknown>).ANALYTICS;
972
983
  const analytics: AnalyticsClient = analyticsBinding ? createAnalytics(analyticsBinding as AnalyticsEngineDatasetLike) : analyticsStub;
973
984
  `,configField:`
@@ -981,7 +992,7 @@ const analyticsStub: AnalyticsClient = {
981
992
  ${t}
982
993
  },
983
994
  };
984
- `}},ar=e=>{if(!e)return _;const t='throw new Error("ctx.images: no Images binding found. Add an \\`images\\` binding (env.IMAGES) to wrangler.jsonc, or pass \\`images\\` to createShardDO().");';return{build:`
995
+ `}},sr=e=>{if(!e)return _;const t='throw new Error("ctx.images: no Images binding found. Add an \\`images\\` binding (env.IMAGES) to wrangler.jsonc, or pass \\`images\\` to createShardDO().");';return{build:`
985
996
  const imagesBinding = config.images?.(env) ?? (env as Record<string, unknown>).IMAGES;
986
997
  const images: Images = imagesBinding ? createImages({ binding: imagesBinding as ImagesBindingLike }) : imagesStub;
987
998
  `,configField:`
@@ -995,7 +1006,7 @@ const imagesStub: Images = {
995
1006
  ${t}
996
1007
  },
997
1008
  };
998
- `}},or=e=>e?{build:`
1009
+ `}},ir=e=>e?{build:`
999
1010
  const sql: SqlClient = config.sql ? config.sql(env) : sqlStub;
1000
1011
  `,configField:`
1001
1012
  sql?: (env: Record<string, unknown>) => SqlClient;`,contextField:`
@@ -1005,7 +1016,7 @@ const sqlStub: SqlClient = {
1005
1016
  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))\\\`.");
1006
1017
  },
1007
1018
  };
1008
- `}:_,sr=e=>{if(!e)return _;const t="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.\");";return{build:`
1019
+ `}:_,lr=e=>{if(!e)return _;const t="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.\");";return{build:`
1009
1020
  const browser: Browser = config.browser ? config.browser(env) : browserStub;
1010
1021
  `,configField:`
1011
1022
  browser?: (env: Record<string, unknown>) => Browser;`,contextField:`
@@ -1033,7 +1044,7 @@ const browserStub: Browser = {
1033
1044
  ${t}
1034
1045
  },
1035
1046
  };
1036
- `}},ir=e=>{if(!e)return _;const t='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().");';return{build:`
1047
+ `}},dr=e=>{if(!e)return _;const t='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().");';return{build:`
1037
1048
  const r2sqlEnv = env as Record<string, unknown>;
1038
1049
  const r2sqlAccountId = (r2sqlEnv.R2_SQL_ACCOUNT_ID ?? r2sqlEnv.CLOUDFLARE_ACCOUNT_ID) as string | undefined;
1039
1050
  const r2sqlToken = r2sqlEnv.R2_SQL_TOKEN as string | undefined;
@@ -1065,7 +1076,7 @@ const r2sqlStub: R2SqlClient = {
1065
1076
  ${t}
1066
1077
  },
1067
1078
  };
1068
- `}},lr=e=>e?{build:`
1079
+ `}},cr=e=>e?{build:`
1069
1080
  const pipelinesBinding = config.pipelines?.(env) ?? (env as Record<string, unknown>).PIPELINES;
1070
1081
  const pipelines: PipelineClient = pipelinesBinding ? createPipelines({ binding: pipelinesBinding as PipelineBindingLike }) : pipelinesStub;
1071
1082
  `,configField:`
@@ -1075,14 +1086,14 @@ const pipelinesStub: PipelineClient = {
1075
1086
  throw new Error("ctx.pipelines: no Pipelines binding found. Add a \\\`pipelines\\\` binding (env.PIPELINES) to wrangler.jsonc, or pass \\\`pipelines\\\` to createShardDO().");
1076
1087
  },
1077
1088
  };
1078
- `}:_,_r=(e,t)=>{if(e.length===0)return"";const n=t?`, ${JSON.stringify(t)}`:"",r=e.map(o=>(m(o.exportName,`container export "${o.exportName}"`),m(o.className,`container class "${o.className}"`),`/** Container DO for the \`${o.exportName}\` definition (binding \`${o.bindingName}\`). */
1089
+ `}:_,Pr=(e,t)=>{if(e.length===0)return"";const n=t?`, ${JSON.stringify(t)}`:"",r=e.map(o=>(m(o.exportName,`container export "${o.exportName}"`),m(o.className,`container class "${o.className}"`),`/** Container DO for the \`${o.exportName}\` definition (binding \`${o.bindingName}\`). */
1079
1090
  export class ${o.className} extends LunoraContainer {
1080
1091
  public constructor(ctx: ConstructorParameters<typeof LunoraContainer>[0], env: Record<string, unknown>) {
1081
1092
  super(ctx, env, ${o.exportName}, "${o.exportName}"${n});
1082
1093
  }
1083
1094
  }
1084
1095
  `)).join(`
1085
- `),a=e.map(o=>o.exportName).join(", ");return`${v}/**
1096
+ `),a=e.map(o=>o.exportName).join(", ");return`${S}/**
1086
1097
  * Container-enabled Durable Object classes for the containers declared in
1087
1098
  * \`lunora/containers.ts\`. Re-export them from your worker entry — wrangler
1088
1099
  * requires each \`containers[].class_name\` to be exported by the worker:
@@ -1100,7 +1111,7 @@ import { ${a} } from "../containers.js";
1100
1111
 
1101
1112
  export { ContainerProxy } from "@lunora/container/do";
1102
1113
 
1103
- ${r}`},dr=(e,t)=>{if(e.length===0)return{build:"",contextField:"",importLines:[],specs:""};for(const r of e)m(r.exportName,`container export "${r.exportName}"`),m(r.bindingName,`container binding "${r.bindingName}"`);const n=e.map(r=>{const a=r.maxInstances===void 0?"":`, maxInstances: ${String(r.maxInstances)}`;return` { binding: "${r.bindingName}", exportName: "${r.exportName}"${a} },`}).join(`
1114
+ ${r}`},ur=(e,t)=>{if(e.length===0)return{build:"",contextField:"",importLines:[],specs:""};for(const r of e)m(r.exportName,`container export "${r.exportName}"`),m(r.bindingName,`container binding "${r.bindingName}"`);const n=e.map(r=>{const a=r.maxInstances===void 0?"":`, maxInstances: ${String(r.maxInstances)}`;return` { binding: "${r.bindingName}", exportName: "${r.exportName}"${a} },`}).join(`
1104
1115
  `);return{build:`
1105
1116
  const containers = createContainerContext(env, LUNORA_CONTAINERS, ${t?JSON.stringify(t):"undefined"}, this.getCurrentTraceparent());
1106
1117
  `,contextField:`
@@ -1109,14 +1120,14 @@ ${r}`},dr=(e,t)=>{if(e.length===0)return{build:"",contextField:"",importLines:[]
1109
1120
  const LUNORA_CONTAINERS: ReadonlyArray<ContainerBindingSpec> = [
1110
1121
  ${n}
1111
1122
  ];
1112
- `}},Er=e=>{if(e.length===0)return"";const t=e.map(r=>(m(r.exportName,`workflow export "${r.exportName}"`),m(r.className,`workflow class "${r.className}"`),`/** WorkflowEntrypoint for the \`${r.exportName}\` definition (binding \`${r.bindingName}\`). */
1123
+ `}},Mr=e=>{if(e.length===0)return"";const t=e.map(r=>(m(r.exportName,`workflow export "${r.exportName}"`),m(r.className,`workflow class "${r.className}"`),`/** WorkflowEntrypoint for the \`${r.exportName}\` definition (binding \`${r.bindingName}\`). */
1113
1124
  export class ${r.className} extends LunoraWorkflow<WorkflowParamsOf<typeof ${r.exportName}>, WorkflowOutputOf<typeof ${r.exportName}>> {
1114
1125
  public constructor(ctx: ConstructorParameters<typeof LunoraWorkflow>[0], env: Record<string, unknown>) {
1115
1126
  super(ctx, env, ${r.exportName}, "${r.exportName}");
1116
1127
  }
1117
1128
  }
1118
1129
  `)).join(`
1119
- `),n=e.map(r=>r.exportName).join(", ");return`${v}/**
1130
+ `),n=e.map(r=>r.exportName).join(", ");return`${S}/**
1120
1131
  * WorkflowEntrypoint classes for the workflows declared in
1121
1132
  * \`lunora/workflows.ts\`. Re-export them from your worker entry — wrangler
1122
1133
  * requires each \`workflows[].class_name\` to be exported by the worker:
@@ -1137,21 +1148,21 @@ type WorkflowParamsOf<Definition> = Definition extends { __params?: infer Params
1137
1148
  /** Output type carried by a \`defineWorkflow\` definition (its phantom \`__output\`), so each entrypoint keeps the authored return type. */
1138
1149
  type WorkflowOutputOf<Definition> = Definition extends { __output?: infer Output } ? Output : unknown;
1139
1150
 
1140
- ${t}`},Pr=e=>{if(e.length===0)return"";const t=e.filter(a=>a.voice).length>0,n=e.map(a=>{m(a.exportName,`agent export "${a.exportName}"`),m(a.className,`agent class "${a.className}"`);const o=`/** WorkflowEntrypoint for the \`${a.exportName}\` agent (binding \`${a.bindingName}\`). */
1151
+ ${t}`},Fr=e=>{if(e.length===0)return"";const t=e.filter(a=>a.voice).length>0,n=e.map(a=>{m(a.exportName,`agent export "${a.exportName}"`),m(a.className,`agent class "${a.className}"`);const o=`/** WorkflowEntrypoint for the \`${a.exportName}\` agent (binding \`${a.bindingName}\`). */
1141
1152
  export class ${a.className} extends LunoraWorkflow<AgentRunInput, AgentRunResult> {
1142
1153
  public constructor(ctx: ConstructorParameters<typeof LunoraWorkflow>[0], env: Record<string, unknown>) {
1143
1154
  super(ctx, env, compileAgentWorkflow(${a.exportName}, "${a.exportName}"), "${a.exportName}");
1144
1155
  }
1145
1156
  }
1146
- `;if(!a.voice)return o;const i=a.voiceClassName??"",s=a.voiceBindingName??"";m(i,`agent voice class "${i}"`);const l=`
1157
+ `;if(!a.voice)return o;const i=a.voiceClassName??"",s=a.voiceBindingName??"";m(i,`agent voice class "${i}"`);const d=`
1147
1158
  /** Voice-session Durable Object for the \`${a.exportName}\` agent (binding \`${s}\`). */
1148
1159
  export class ${i} extends VoiceSessionDO {
1149
1160
  public constructor(ctx: ConstructorParameters<typeof VoiceSessionDO>[0], env: Record<string, unknown>) {
1150
1161
  super(ctx, env, ${a.exportName}, "${a.exportName}");
1151
1162
  }
1152
1163
  }
1153
- `;return`${o}${l}`}).join(`
1154
- `),r=e.map(a=>a.exportName).join(", ");return`${v}/**
1164
+ `;return`${o}${d}`}).join(`
1165
+ `),r=e.map(a=>a.exportName).join(", ");return`${S}/**
1155
1166
  * WorkflowEntrypoint classes for the agents declared in \`lunora/agents.ts\`.
1156
1167
  * Each \`defineAgent\` compiles a replay-safe tool-loop onto a Cloudflare
1157
1168
  * Workflow. Re-export them from your worker entry — wrangler requires each
@@ -1165,8 +1176,8 @@ import type { AgentRunInput, AgentRunResult } from "@lunora/agent";
1165
1176
 
1166
1177
  import { ${r} } from "../agents.js";
1167
1178
 
1168
- ${n}`},Fr=e=>{const t=e.filter(a=>a.mode==="push");if(t.length===0)return"";for(const a of t)m(a.exportName,`queue export "${a.exportName}"`);const n=t.map(a=>a.exportName).join(", "),r=t.map(a=>` ${JSON.stringify(a.name)}: { definition: ${a.exportName}, exportName: ${JSON.stringify(a.exportName)} },`).join(`
1169
- `);return`${v}/**
1179
+ ${n}`},qr=e=>{const t=e.filter(a=>a.mode==="push");if(t.length===0)return"";for(const a of t)m(a.exportName,`queue export "${a.exportName}"`);const n=t.map(a=>a.exportName).join(", "),r=t.map(a=>` ${JSON.stringify(a.name)}: { definition: ${a.exportName}, exportName: ${JSON.stringify(a.exportName)} },`).join(`
1180
+ `);return`${S}/**
1170
1181
  * Push-consumer registry for the queues declared in \`lunora/queues.ts\`. The
1171
1182
  * composed worker's \`queue(batch, env, ctx)\` entry routes each delivered batch
1172
1183
  * by \`batch.queue\` to the matching \`defineQueue\` handler. Wired automatically
@@ -1180,7 +1191,7 @@ import { ${n} } from "../queues.js";
1180
1191
  export const LUNORA_QUEUE_REGISTRY: QueueRegistry = {
1181
1192
  ${r}
1182
1193
  };
1183
- `},cr=e=>{if(e.length===0)return{build:"",contextField:"",importLines:[],specs:""};for(const n of e)m(n.exportName,`workflow export "${n.exportName}"`),m(n.bindingName,`workflow binding "${n.bindingName}"`);const t=e.map(n=>` { binding: "${n.bindingName}", exportName: "${n.exportName}" },`).join(`
1194
+ `},pr=e=>{if(e.length===0)return{build:"",contextField:"",importLines:[],specs:""};for(const n of e)m(n.exportName,`workflow export "${n.exportName}"`),m(n.bindingName,`workflow binding "${n.bindingName}"`);const t=e.map(n=>` { binding: "${n.bindingName}", exportName: "${n.exportName}" },`).join(`
1184
1195
  `);return{build:`
1185
1196
  const workflows = createWorkflowContext(env, LUNORA_WORKFLOWS);
1186
1197
  `,contextField:`
@@ -1189,7 +1200,7 @@ ${r}
1189
1200
  const LUNORA_WORKFLOWS: ReadonlyArray<WorkflowBindingSpec> = [
1190
1201
  ${t}
1191
1202
  ];
1192
- `}},ur=e=>{if(e.length===0)return{build:"",contextField:"",importLines:[],specs:""};for(const n of e)m(n.exportName,`queue export "${n.exportName}"`),m(n.bindingName,`queue binding "${n.bindingName}"`);const t=e.map(n=>` { binding: "${n.bindingName}", exportName: "${n.exportName}", name: ${JSON.stringify(n.name)} },`).join(`
1203
+ `}},hr=e=>{if(e.length===0)return{build:"",contextField:"",importLines:[],specs:""};for(const n of e)m(n.exportName,`queue export "${n.exportName}"`),m(n.bindingName,`queue binding "${n.bindingName}"`);const t=e.map(n=>` { binding: "${n.bindingName}", exportName: "${n.exportName}", name: ${JSON.stringify(n.name)} },`).join(`
1193
1204
  `);return{build:`
1194
1205
  const queues = createQueueContext(env, LUNORA_QUEUES);
1195
1206
  `,contextField:`
@@ -1198,7 +1209,7 @@ ${t}
1198
1209
  const LUNORA_QUEUES: ReadonlyArray<QueueBindingSpec> = [
1199
1210
  ${t}
1200
1211
  ];
1201
- `}},pr=e=>{if(e.length===0)return{build:"",contextField:"",importLines:[],specs:""};for(const n of e)m(n.exportName,`agent export "${n.exportName}"`),m(n.bindingName,`agent binding "${n.bindingName}"`);const t=e.map(n=>` { binding: "${n.bindingName}", exportName: "${n.exportName}"${n.publicRun===!0?", publicRun: true":""} },`).join(`
1212
+ `}},gr=e=>{if(e.length===0)return{build:"",contextField:"",importLines:[],specs:""};for(const n of e)m(n.exportName,`agent export "${n.exportName}"`),m(n.bindingName,`agent binding "${n.bindingName}"`);const t=e.map(n=>` { binding: "${n.bindingName}", exportName: "${n.exportName}"${n.publicRun===!0?", publicRun: true":""} },`).join(`
1202
1213
  `);return{build:`
1203
1214
  const agents = createAgentContext(env, LUNORA_AGENTS);
1204
1215
  `,contextField:`
@@ -1207,21 +1218,21 @@ ${t}
1207
1218
  const LUNORA_AGENTS: ReadonlyArray<AgentBindingSpec> = [
1208
1219
  ${t}
1209
1220
  ];
1210
- `}},hr=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{constant:`
1221
+ `}},mr=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{constant:`
1211
1222
  /** Read-only declared-workflow metadata (discovered from \`lunora/workflows.ts\`) served via \`__lunora_admin__:listWorkflows\` for the studio's workflows view. */
1212
1223
  const LUNORA_WORKFLOWS_INFO: WorkflowsResult = ${JSON.stringify(t,void 0,4)};
1213
1224
  `,override:`
1214
1225
  protected override workflowsMetadata(): WorkflowsResult {
1215
1226
  return LUNORA_WORKFLOWS_INFO;
1216
1227
  }
1217
- `}},gr=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{constant:`
1228
+ `}},fr=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{constant:`
1218
1229
  /** Read-only declared-queue metadata (discovered from \`lunora/queues.ts\`) served via \`__lunora_admin__:listQueues\` for the studio's queues view. */
1219
1230
  const LUNORA_QUEUES_INFO: QueuesResult = ${JSON.stringify(t,void 0,4)};
1220
1231
  `,override:`
1221
1232
  protected override queuesMetadata(): QueuesResult {
1222
1233
  return LUNORA_QUEUES_INFO;
1223
1234
  }
1224
- `}},mr=e=>{if(!e)return{build:"",configField:"",contextField:"",imports:[],stub:""};const t='throw new Error("ctx.payments: no payment configured. Pass \\`payment\\` to createShardDO().");';return{imports:['import type { LunoraDatabaseLike as LunoraPaymentDbLike, LunoraPayment, PaymentsFromContextOptions } from "@lunora/payment";','import { paymentsFromContext } from "@lunora/payment";'],build:`
1235
+ `}},br=e=>{if(!e)return{build:"",configField:"",contextField:"",imports:[],stub:""};const t='throw new Error("ctx.payments: no payment configured. Pass \\`payment\\` to createShardDO().");';return{imports:['import type { LunoraDatabaseLike as LunoraPaymentDbLike, LunoraPayment, PaymentsFromContextOptions } from "@lunora/payment";','import { paymentsFromContext } from "@lunora/payment";'],build:`
1225
1236
  const payments: LunoraPayment = config.payment
1226
1237
  ? paymentsFromContext({ auth: { userId: userId ?? null }, db: db as unknown as LunoraPaymentDbLike }, config.payment(env))
1227
1238
  : paymentStub;
@@ -1257,7 +1268,7 @@ const paymentStub: LunoraPayment = {
1257
1268
  ${t}
1258
1269
  },
1259
1270
  } as unknown as LunoraPayment;
1260
- `}},fr=e=>e?{imports:['import type { X402Pay, X402PayConfig } from "@lunora/x402/pay";','import { lazyX402Pay } from "@lunora/x402/pay";'],build:`
1271
+ `}},yr=e=>e?{imports:['import type { X402Pay, X402PayConfig } from "@lunora/x402/pay";','import { lazyX402Pay } from "@lunora/x402/pay";'],build:`
1261
1272
  const x402: X402Pay = config.x402
1262
1273
  ? lazyX402Pay(config.x402(env), { getSecret: (name: string) => secrets.get(name) })
1263
1274
  : x402Stub;
@@ -1269,10 +1280,10 @@ const x402Stub: X402Pay = {
1269
1280
  throw new Error("ctx.x402: no pay rail configured. Pass \\\`x402\\\` to createShardDO().");
1270
1281
  },
1271
1282
  } as unknown as X402Pay;
1272
- `}:{build:"",configField:"",contextField:"",imports:[],stub:""},br=(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"]:[]],Mr=({advisories:e=[],advisorProcedures:t=[],agents:n=[],containers:r=[],env:a,flagKeys:o=[],hasAccessFacade:i=!1,hasAi:s=!1,hasAnalytics:l=!1,hasBrowser:u=!1,hasFlags:p=!1,hasHyperdrive:f=!1,hasImages:y=!1,hasKv:N=!1,hasNotify:d=!1,hasPayments:c=!1,hasPipelines:g=!1,hasR2sql:b=!1,hasX402:k=!1,maskMetadata:$,mutators:T=[],queues:O=[],rlsMetadata:S,schema:x,schemaSnapshot:P,shapes:ee=[],storageRules:F,studioFeatures:te,useUmbrella:ne=!1,workflows:B=[]})=>{const A=G(ne),z=T.length>0,L=ee.length>0,I=P===void 0?"":on(P),M=P===void 0?"":`
1283
+ `}:{build:"",configField:"",contextField:"",imports:[],stub:""},wr=(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"]:[]],Br=({advisories:e=[],advisorProcedures:t=[],agents:n=[],containers:r=[],env:a,flagKeys:o=[],hasAccessFacade:i=!1,hasAi:s=!1,hasAnalytics:d=!1,hasBrowser:u=!1,hasFlags:p=!1,hasHyperdrive:g=!1,hasImages:b=!1,hasKv:c=!1,hasNotify:l=!1,hasPayments:f=!1,hasPipelines:x=!1,hasR2sql:k=!1,hasX402:v=!1,maskMetadata:A,mutators:P=[],queues:L=[],rlsMetadata:$,schema:w,schemaSnapshot:M,shapes:te=[],storageRules:F,studioFeatures:ne,useUmbrella:re=!1,workflows:j=[]})=>{const T=ee(re),z=P.length>0,O=te.length>0,C=M===void 0?"":on(M),q=M===void 0?"":`
1273
1284
  /** 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. */
1274
- const LUNORA_SCHEMA_SNAPSHOT: { hash: string; json: string } = { hash: ${JSON.stringify(sn(P))}, json: ${JSON.stringify(I)} };
1275
- `,re=P===void 0?"":", schemaSnapshot: LUNORA_SCHEMA_SNAPSHOT",{build:ae,configField:ke,contextField:ve,stub:$e}=zn(s),oe=tr(i),K=Xn(N),E=Yn(p,A.flags),Q=nr(o,p,A.flags),X=Zn(d),se=er(a),H=rr(l),j=ar(y),W=or(f),U=sr(u),q=ir(b),Y=lr(g),{build:Se,contextField:fe,importLines:be,specs:ie}=ur(O),{build:Re,contextField:Ne,importLines:ye,specs:le}=dr(r,x.jurisdiction),{build:Oe,contextField:Te,importLines:we,specs:Ae}=cr(B),{build:Le,contextField:de,importLines:ce,specs:Ce}=pr(n),{build:Ie,configField:De,contextField:ue,imports:pe,stub:h}=mr(c),{build:_e,configField:ht,imports:gt,stub:mt}=fr(k),ft=e,bt=t,yt=S??{policies:[],roles:[]},wt=$??{columns:[]},xt=F??{rules:[]},kt=te??{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:vt,override:$t}=hr(B),{constant:St,override:Rt}=gr(O),J=x.vectorIndexes.length>0,Ue=new Set(x.tables.filter(w=>typeof w.shardMode=="object"&&w.shardMode.kind==="shardBy").map(w=>w.name)),xe=x.vectorIndexes.some(w=>Ue.has(w.table)),he=x.tables.some(w=>w.shardMode==="global"),Ee=x.tables.some(w=>w.shardMode==="global"&&w.globalBackend==="hyperdrive"),Ke=x.tables.some(w=>w.shardMode==="global"&&w.globalBackend!=="hyperdrive"),V=x.tables.some(w=>w.externalSource!==void 0);if(Ke&&Ee)throw new Z("INTERNAL",'lunora codegen: mixing `.global()` (D1) and `.global({ backend: "hyperdrive" })` tables in one app is not supported yet — use a single global backend.');const Pe=x.tables.length>0,Nt=Kn(x),Ot=Hn(x),Tt=Vn(x),At=Qn(x),Qe=Jn(x),He=br(J,B.length>0,O.length>0,p);L&&He.push("WhereInput");const Je=Gn(he),Lt=L?`
1285
+ const LUNORA_SCHEMA_SNAPSHOT: { hash: string; json: string } = { hash: ${JSON.stringify(sn(M))}, json: ${JSON.stringify(C)} };
1286
+ `,ae=M===void 0?"":", schemaSnapshot: LUNORA_SCHEMA_SNAPSHOT",{build:oe,configField:ve,contextField:$e,stub:Se}=Yn(s),se=rr(i),Q=Zn(c),E=er(p,T.flags),H=ar(o,p,T.flags),X=tr(l),ie=nr(a),V=or(d),W=sr(b),U=ir(g),K=lr(u),B=dr(k),Y=cr(x),{build:Re,contextField:be,importLines:ye,specs:le}=hr(L),{build:Ne,contextField:Te,importLines:we,specs:de}=ur(r,w.jurisdiction),{build:Oe,contextField:Ae,importLines:xe,specs:Le}=pr(j),{build:Ce,contextField:ce,importLines:ue,specs:Ie}=gr(n),{build:De,configField:_e,contextField:pe,imports:he,stub:h}=br(f),{build:Ee,configField:ht,imports:gt,stub:mt}=yr(v),ft=e,bt=t,yt=$??{policies:[],roles:[]},wt=A??{columns:[]},xt=F??{rules:[]},kt=ne??{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:vt,override:$t}=mr(j),{constant:St,override:Rt}=fr(L),J=w.vectorIndexes.length>0,Ue=new Set(w.tables.filter(y=>typeof y.shardMode=="object"&&y.shardMode.kind==="shardBy").map(y=>y.name)),ke=w.vectorIndexes.some(y=>Ue.has(y.table)),ge=w.tables.some(y=>y.shardMode==="global"),Pe=w.tables.some(y=>y.shardMode==="global"&&y.globalBackend==="hyperdrive"),Ke=w.tables.some(y=>y.shardMode==="global"&&y.globalBackend!=="hyperdrive"),G=w.tables.some(y=>y.externalSource!==void 0);if(Ke&&Pe)throw new Z("INTERNAL",'lunora codegen: mixing `.global()` (D1) and `.global({ backend: "hyperdrive" })` tables in one app is not supported yet — use a single global backend.');const Me=w.tables.length>0,Nt=Hn(w),Tt=Jn(w),Ot=zn(w),At=Vn(w),Qe=Gn(w),He=wr(J,j.length>0,L.length>0,p);O&&He.push("WhereInput");const Ve=Xn(ge),Lt=O?`
1276
1287
  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 {
1277
1288
  const shape = LUNORA_SHAPES[name];
1278
1289
 
@@ -1329,11 +1340,11 @@ const LUNORA_SCHEMA_SNAPSHOT: { hash: string; json: string } = { hash: ${JSON.st
1329
1340
  protected override isCustomMutator(functionPath: string): boolean {
1330
1341
  return LUNORA_MUTATOR_PATHS.has(functionPath);
1331
1342
  }
1332
- `:"",It=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":"",Dt=L?"assertShapeShardable, ":"",ge=[`import type { ${He.join(", ")} } from "${A.do}";`,`import { applyCdcChanges, ${Dt}createReadFootprint, createShardCtxDb, exportShardRows, importShardRows, ${V?"isSourceDue, pullExternalSourceIncrementalTick, pullExternalSourceTick, ":""}${xe?"ROOT_SHARD_NAME, ":""}runDataMigration, runShardMigrations, ${Je.importFragment}ShardDO as ShardDOBase } from "${A.do}";`,...V?[`import type { ExternalSourceLike, SourceClientLike } from "${A.do}";`]:[],L?`import { asBucketStorage, buildRlsReadRegistry, composeShapeReadWhere, createSecrets, LunoraError } from "${A.server}";`:`import { asBucketStorage, createSecrets, LunoraError } from "${A.server}";`];Pe&&ge.push(`import { bindOrm, bindTableFacade } from "${A.server}";`),J&&ge.push('import type { SchemaLike as VectorSchemaLike, VectorizeIndexLike, VectorSearchLike } from "@lunora/bindings/vectors";','import { createContextVectors, createVectors, createVectorSyncHook } from "@lunora/bindings/vectors";'),s&&ge.push('import type { AiBindingLike, LunoraAi } from "@lunora/ai";','import { createAi } from "@lunora/ai";'),ge.push(...oe.importLines,...K.importLines,...E.importLines,...X.importLines,...se.importLines,...H.importLines,...j.importLines,...W.importLines,...U.importLines,...q.importLines,...Y.importLines,...ye,...we,...be,...ce,...pe,...gt,"",'import schema from "../schema.js";',`import { ${["LUNORA_FUNCTIONS","LUNORA_LIFECYCLE_HOOKS","LUNORA_MIGRATIONS",...z?["LUNORA_MUTATOR_PATHS"]:[],...L?["LUNORA_SHAPES"]:[]].join(", ")} } from "./functions.js";`);const _t=J?`
1343
+ `:"",It=O?"\n/** Per-table RLS read policies (hoisted from `.use(rls(...))` chains) the shape resolver AND-merges into each `defineShape` predicate so partial replication honours read policies. */\nconst LUNORA_RLS_READ_REGISTRY = buildRlsReadRegistry(Object.values(LUNORA_FUNCTIONS));\n":"",Dt=O?"assertShapeShardable, ":"",me=[`import type { ${He.join(", ")} } from "${T.do}";`,`import { applyCdcChanges, ${Dt}createReadFootprint, createShardCtxDb, exportShardRows, importShardRows, ${G?"isSourceDue, pullExternalSourceIncrementalTick, pullExternalSourceTick, ":""}${ke?"ROOT_SHARD_NAME, ":""}runDataMigration, runShardMigrations, ${Ve.importFragment}ShardDO as ShardDOBase } from "${T.do}";`,...G?[`import type { ExternalSourceLike, SourceClientLike } from "${T.do}";`]:[],O?`import { asBucketStorage, buildRlsReadRegistry, composeShapeReadWhere, createSecrets, LunoraError } from "${T.server}";`:`import { asBucketStorage, createSecrets, LunoraError } from "${T.server}";`];Me&&me.push(`import { bindOrm, bindTableFacade } from "${T.server}";`),J&&me.push('import type { SchemaLike as VectorSchemaLike, VectorizeIndexLike, VectorSearchLike } from "@lunora/bindings/vectors";','import { createContextVectors, createVectors, createVectorSyncHook } from "@lunora/bindings/vectors";'),s&&me.push('import type { AiBindingLike, LunoraAi } from "@lunora/ai";','import { createAi } from "@lunora/ai";'),me.push(...se.importLines,...Q.importLines,...E.importLines,...X.importLines,...ie.importLines,...V.importLines,...W.importLines,...U.importLines,...K.importLines,...B.importLines,...Y.importLines,...we,...xe,...ye,...ue,...he,...gt,"",'import schema from "../schema.js";',`import { ${["LUNORA_FUNCTIONS","LUNORA_LIFECYCLE_HOOKS","LUNORA_MIGRATIONS",...z?["LUNORA_MUTATOR_PATHS"]:[],...O?["LUNORA_SHAPES"]:[]].join(", ")} } from "./functions.js";`);const _t=J?`
1333
1344
  vectors?: (env: Record<string, unknown>) => Record<string, VectorizeIndexLike>;`:"",Et=Ke?`
1334
- d1?: (env: Record<string, unknown>, request?: { identity?: Record<string, unknown>; userId?: string }) => DatabaseWriterLike | undefined;`:"",Pt=Ee?`
1335
- hyperdriveGlobal?: (env: Record<string, unknown>, request?: { identity?: Record<string, unknown>; userId?: string }) => DatabaseWriterLike | undefined;`:"",Ft=V?`
1336
- sourceClient?: (env: Record<string, unknown>, binding: string) => { query: <Row = Record<string, unknown>>(text: string, params?: readonly unknown[]) => Promise<Row[]> } | undefined;`:"",Mt=he?'\nconst globalDbStub: DatabaseWriterLike = {\n aggregate: async () => {\n throw new Error("ctx.db.<globalTable>: no global backend configured. Pass `d1` or `hyperdriveGlobal` to createShardDO().");\n },\n count: async () => {\n throw new Error("ctx.db.<globalTable>: no global backend configured. Pass `d1` or `hyperdriveGlobal` to createShardDO().");\n },\n delete: async () => {\n throw new Error("ctx.db.<globalTable>: no global backend configured. Pass `d1` or `hyperdriveGlobal` to createShardDO().");\n },\n findFirst: async () => {\n throw new Error("ctx.db.<globalTable>: no global backend configured. Pass `d1` or `hyperdriveGlobal` to createShardDO().");\n },\n findFirstOrThrow: async () => {\n throw new Error("ctx.db.<globalTable>: no global backend configured. Pass `d1` or `hyperdriveGlobal` to createShardDO().");\n },\n findMany: async () => {\n throw new Error("ctx.db.<globalTable>: no global backend configured. Pass `d1` or `hyperdriveGlobal` to createShardDO().");\n },\n get: async () => {\n throw new Error("ctx.db.<globalTable>: no global backend configured. Pass `d1` or `hyperdriveGlobal` to createShardDO().");\n },\n groupBy: async () => {\n throw new Error("ctx.db.<globalTable>: no global backend configured. Pass `d1` or `hyperdriveGlobal` to createShardDO().");\n },\n insert: async () => {\n throw new Error("ctx.db.<globalTable>: no global backend configured. Pass `d1` or `hyperdriveGlobal` to createShardDO().");\n },\n normalizeId: () => {\n throw new Error("ctx.db.<globalTable>: no global backend configured. Pass `d1` or `hyperdriveGlobal` to createShardDO().");\n },\n patch: async () => {\n throw new Error("ctx.db.<globalTable>: no global backend configured. Pass `d1` or `hyperdriveGlobal` to createShardDO().");\n },\n query: () => {\n throw new Error("ctx.db.<globalTable>: no global backend configured. Pass `d1` or `hyperdriveGlobal` to createShardDO().");\n },\n rank: async () => {\n throw new Error("ctx.db.<globalTable>: no global backend configured. Pass `d1` or `hyperdriveGlobal` to createShardDO().");\n },\n rankPage: async () => {\n throw new Error("ctx.db.<globalTable>: no global backend configured. Pass `d1` or `hyperdriveGlobal` to createShardDO().");\n },\n replace: async () => {\n throw new Error("ctx.db.<globalTable>: no global backend configured. Pass `d1` or `hyperdriveGlobal` to createShardDO().");\n },\n};\n':"",qt=J?`
1345
+ d1?: (env: Record<string, unknown>, request?: { identity?: Record<string, unknown>; userId?: string }) => DatabaseWriterLike | undefined;`:"",Pt=Pe?`
1346
+ hyperdriveGlobal?: (env: Record<string, unknown>, request?: { identity?: Record<string, unknown>; userId?: string }) => DatabaseWriterLike | undefined;`:"",Mt=G?`
1347
+ sourceClient?: (env: Record<string, unknown>, binding: string) => { query: <Row = Record<string, unknown>>(text: string, params?: readonly unknown[]) => Promise<Row[]> } | undefined;`:"",Ft=ge?'\nconst globalDbStub: DatabaseWriterLike = {\n aggregate: async () => {\n throw new Error("ctx.db.<globalTable>: no global backend configured. Pass `d1` or `hyperdriveGlobal` to createShardDO().");\n },\n count: async () => {\n throw new Error("ctx.db.<globalTable>: no global backend configured. Pass `d1` or `hyperdriveGlobal` to createShardDO().");\n },\n delete: async () => {\n throw new Error("ctx.db.<globalTable>: no global backend configured. Pass `d1` or `hyperdriveGlobal` to createShardDO().");\n },\n findFirst: async () => {\n throw new Error("ctx.db.<globalTable>: no global backend configured. Pass `d1` or `hyperdriveGlobal` to createShardDO().");\n },\n findFirstOrThrow: async () => {\n throw new Error("ctx.db.<globalTable>: no global backend configured. Pass `d1` or `hyperdriveGlobal` to createShardDO().");\n },\n findMany: async () => {\n throw new Error("ctx.db.<globalTable>: no global backend configured. Pass `d1` or `hyperdriveGlobal` to createShardDO().");\n },\n get: async () => {\n throw new Error("ctx.db.<globalTable>: no global backend configured. Pass `d1` or `hyperdriveGlobal` to createShardDO().");\n },\n groupBy: async () => {\n throw new Error("ctx.db.<globalTable>: no global backend configured. Pass `d1` or `hyperdriveGlobal` to createShardDO().");\n },\n insert: async () => {\n throw new Error("ctx.db.<globalTable>: no global backend configured. Pass `d1` or `hyperdriveGlobal` to createShardDO().");\n },\n normalizeId: () => {\n throw new Error("ctx.db.<globalTable>: no global backend configured. Pass `d1` or `hyperdriveGlobal` to createShardDO().");\n },\n patch: async () => {\n throw new Error("ctx.db.<globalTable>: no global backend configured. Pass `d1` or `hyperdriveGlobal` to createShardDO().");\n },\n query: () => {\n throw new Error("ctx.db.<globalTable>: no global backend configured. Pass `d1` or `hyperdriveGlobal` to createShardDO().");\n },\n rank: async () => {\n throw new Error("ctx.db.<globalTable>: no global backend configured. Pass `d1` or `hyperdriveGlobal` to createShardDO().");\n },\n rankPage: async () => {\n throw new Error("ctx.db.<globalTable>: no global backend configured. Pass `d1` or `hyperdriveGlobal` to createShardDO().");\n },\n replace: async () => {\n throw new Error("ctx.db.<globalTable>: no global backend configured. Pass `d1` or `hyperdriveGlobal` to createShardDO().");\n },\n};\n':"",qt=J?`
1337
1348
  const vectorsStub: VectorSearchLike = {
1338
1349
  deleteByIds: async () => {
1339
1350
  throw new Error("ctx.vectors: no vectors configured. Pass \`vectors\` to createShardDO().");
@@ -1351,9 +1362,9 @@ const vectorsStub: VectorSearchLike = {
1351
1362
  throw new Error("ctx.vectors: no vectors configured. Pass \`vectors\` to createShardDO().");
1352
1363
  },
1353
1364
  };
1354
- `:"",Bt=xe?`
1365
+ `:"",Bt=ke?`
1355
1366
  const vectorShardKey = this.currentShardKey();
1356
- `:"",jt=xe?"namespace: vectorShardKey === ROOT_SHARD_NAME ? undefined : vectorShardKey, ":"",Wt=xe?`, { namespace: vectorShardKey === ROOT_SHARD_NAME ? undefined : vectorShardKey, shardedIndexNames: [${x.vectorIndexes.filter(w=>Ue.has(w.table)).map(w=>JSON.stringify(w.name)).join(", ")}] }`:"",Ut=J?`
1367
+ `:"",jt=ke?"namespace: vectorShardKey === ROOT_SHARD_NAME ? undefined : vectorShardKey, ":"",Wt=ke?`, { namespace: vectorShardKey === ROOT_SHARD_NAME ? undefined : vectorShardKey, shardedIndexNames: [${w.vectorIndexes.filter(y=>Ue.has(y.table)).map(y=>JSON.stringify(y.name)).join(", ")}] }`:"",Ut=J?`
1357
1368
  let vectors: VectorSearchLike;
1358
1369
  let onWrite: WriteHook | undefined;
1359
1370
 
@@ -1366,7 +1377,7 @@ ${Bt}
1366
1377
  vectors = vectorsStub;
1367
1378
  onWrite = undefined;
1368
1379
  }
1369
- `:"",Ve=he?`
1380
+ `:"",Je=ge?`
1370
1381
  globalDb,`:"",Ge=`
1371
1382
  auth: { identity: identity ?? null, userId: userId ?? null },`,Kt=J?`{${Ge}
1372
1383
  broadcast: (delta) => {
@@ -1382,7 +1393,7 @@ ${Bt}
1382
1393
  scheduler,
1383
1394
  schema: schema as unknown as SchemaLike,
1384
1395
  sql: this.sql as SqlExec,
1385
- storage,${Ve}
1396
+ storage,${Je}
1386
1397
  }`:`{${Ge}
1387
1398
  broadcast: (delta) => {
1388
1399
  this.recordChangedTable(delta.table, delta.indexKeys);
@@ -1396,11 +1407,11 @@ ${Bt}
1396
1407
  scheduler,
1397
1408
  schema: schema as unknown as SchemaLike,
1398
1409
  sql: this.sql as SqlExec,
1399
- storage,${Ve}
1410
+ storage,${Je}
1400
1411
  }`,Qt=J?`
1401
- vectors,`:"",Ht=Pe?`
1402
- orm: bindOrm(facade),`:"",Jt="",ze=Ee?"config.hyperdriveGlobal":"config.d1",Vt=he?` const globalDb: DatabaseWriterLike = ${ze}?.(env, { identity, userId }) ?? globalDbStub;
1403
- `:"",Gt=L&&he?`
1412
+ vectors,`:"",Ht=Me?`
1413
+ orm: bindOrm(facade),`:"",Vt="",ze=Pe?"config.hyperdriveGlobal":"config.d1",Jt=ge?` const globalDb: DatabaseWriterLike = ${ze}?.(env, { identity, userId }) ?? globalDbStub;
1414
+ `:"",Gt=O&&ge?`
1404
1415
  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 }>> {
1405
1416
  const env = this.env as Record<string, unknown>;
1406
1417
  const globalDb: DatabaseWriterLike = ${ze}?.(env, identity) ?? globalDbStub;
@@ -1430,10 +1441,10 @@ ${Bt}
1430
1441
 
1431
1442
  return rows;
1432
1443
  }
1433
- `:"",zt=V?`
1444
+ `:"",zt=G?`
1434
1445
  const sourceClientCache = new WeakMap<object, Map<string, SourceClientLike>>();
1435
1446
  const sourcePollAtCache = new WeakMap<object, Map<string, number>>();
1436
- `:"",Xt=V?`
1447
+ `:"",Xt=G?`
1437
1448
  protected override async pollExternalSources(): Promise<number | undefined> {
1438
1449
  const env = (this.env ?? {}) as Record<string, unknown>;
1439
1450
  const sourced = Object.entries((schema as unknown as SchemaLike).tables)
@@ -1569,10 +1580,10 @@ const sourcePollAtCache = new WeakMap<object, Map<string, number>>();
1569
1580
 
1570
1581
  return nextDueAt;
1571
1582
  }
1572
- `:"",Xe=Qe.length>0,Yt=V||Xe?`
1583
+ `:"",Xe=Qe.length>0,Yt=G||Xe?`
1573
1584
  public constructor(state: ShardDOState, env: unknown) {
1574
1585
  super(state, env);
1575
- ${V?`
1586
+ ${G?`
1576
1587
  const autoSourced = Object.values((schema as unknown as SchemaLike).tables).some((definition) => {
1577
1588
  const source = (definition as { externalSource?: ExternalSourceLike }).externalSource;
1578
1589
 
@@ -1587,22 +1598,22 @@ ${V?`
1587
1598
  void this.scheduleTtlSweep();
1588
1599
  }
1589
1600
  `:""} }
1590
- `:"",Zt=Pe?`
1601
+ `:"",Zt=Me?`
1591
1602
  const facade = db as unknown as Record<string, ReturnType<typeof bindTableFacade>>;
1592
- ${x.tables.map(w=>` facade[${JSON.stringify(w.name)}] = bindTableFacade(db, ${JSON.stringify(w.name)});`).join(`
1603
+ ${w.tables.map(y=>` facade[${JSON.stringify(y.name)}] = bindTableFacade(db, ${JSON.stringify(y.name)});`).join(`
1593
1604
  `)}
1594
- `:"",en=`${oe.build}${K.build}${E.build}${H.build}${se.build}
1605
+ `:"",en=`${se.build}${Q.build}${E.build}${V.build}${ie.build}
1595
1606
  const secrets = createSecrets(env);
1596
- `,tn=`${oe.contextField}${K.contextField}${E.contextField}${X.contextField}${H.contextField}${se.contextField}
1597
- secrets,`,nn=X.build,Ye=y||f||u||b||g||k,rn=Ye?`
1607
+ `,tn=`${se.contextField}${Q.contextField}${E.contextField}${X.contextField}${V.contextField}${ie.contextField}
1608
+ secrets,`,nn=X.build,Ye=b||g||u||k||x||v,rn=Ye?`
1598
1609
  // ActionCtx-only helpers (external, non-deterministic I/O): constructed
1599
1610
  // and attached only for an \`action\` so query/mutation ctx never carry them.
1600
1611
  if (isAction) {
1601
- ${j.build}${W.build}${U.build}${q.build}${Y.build}${_e}${[...y?[" ctx.images = images;"]:[],...f?[" ctx.sql = sql;"]:[],...u?[" ctx.browser = browser;"]:[],...b?[" ctx.r2sql = r2sql;"]:[],...g?[" ctx.pipelines = pipelines;"]:[],...k?[" ctx.x402 = x402;"]:[]].join(`
1612
+ ${W.build}${U.build}${K.build}${B.build}${Y.build}${Ee}${[...b?[" ctx.images = images;"]:[],...g?[" ctx.sql = sql;"]:[],...u?[" ctx.browser = browser;"]:[],...k?[" ctx.r2sql = r2sql;"]:[],...x?[" ctx.pipelines = pipelines;"]:[],...v?[" ctx.x402 = x402;"]:[]].join(`
1602
1613
  `)}
1603
1614
  }
1604
1615
  `:"",an=Ye?` const isAction = LUNORA_FUNCTIONS[options.functionPath ?? ""]?.kind === "action";
1605
- `:"";return`${v}${ge.join(`
1616
+ `:"";return`${S}${me.join(`
1606
1617
  `)}
1607
1618
 
1608
1619
  type FunctionKind = "action" | "mutation" | "query";
@@ -1615,10 +1626,10 @@ interface FunctionReference {
1615
1626
  const LUNORA_TABLE_REFS: Record<string, Record<string, string>> = ${JSON.stringify(Nt,void 0,4)};
1616
1627
 
1617
1628
  /** Declared indexes per table (secondary, search, geo, rank, vector) for the schema viewer. */
1618
- const LUNORA_TABLE_INDEXES: Record<string, Array<{ fields: string[]; name: string; type: "geo" | "index" | "rank" | "search" | "vector"; unique?: boolean }>> = ${JSON.stringify(Ot,void 0,4)};
1629
+ const LUNORA_TABLE_INDEXES: Record<string, Array<{ fields: string[]; name: string; type: "geo" | "index" | "rank" | "search" | "vector"; unique?: boolean }>> = ${JSON.stringify(Tt,void 0,4)};
1619
1630
 
1620
1631
  /** Columns per table (typed, with PK/FK markers) for the studio's schema diagram, served via \`__lunora_admin__:describeTable\`. */
1621
- const LUNORA_TABLE_COLUMNS: Record<string, Array<{ isStorage?: boolean; name: string; optional: boolean; pk?: boolean; ref?: string; type: string }>> = ${JSON.stringify(Tt,void 0,4)};
1632
+ const LUNORA_TABLE_COLUMNS: Record<string, Array<{ isStorage?: boolean; name: string; optional: boolean; pk?: boolean; ref?: string; type: string }>> = ${JSON.stringify(Ot,void 0,4)};
1622
1633
 
1623
1634
  /** Storage-key columns per table (\`v.storage(...)\` fields) for the file browser's records↔files join. */
1624
1635
  const LUNORA_STORAGE_COLUMNS: Record<string, string[]> = ${JSON.stringify(At,void 0,4)};
@@ -1643,14 +1654,14 @@ const LUNORA_STORAGE_RULES: StorageRulesResult = ${JSON.stringify(xt,void 0,4)};
1643
1654
 
1644
1655
  /** 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. */
1645
1656
  const LUNORA_STUDIO_FEATURES: StudioFeaturesResult = ${JSON.stringify(kt,void 0,4)};
1646
- ${M}${Q.constant}${It}${vt}${St}${le}${Ae}${ie}${Ce}
1657
+ ${q}${H.constant}${It}${vt}${St}${de}${Le}${le}${Ie}
1647
1658
  export interface ShardDOConfig {
1648
1659
  /** Opt into change-data-capture: records a post-image to \`__cdc_log\` on every write (backs streaming export + replay-PITR). */
1649
1660
  cdc?: boolean;
1650
1661
  /** 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. */
1651
1662
  observability?: (env: Record<string, unknown>) => TelemetrySink | undefined;
1652
1663
  scheduler?: (env: Record<string, unknown>) => unknown;
1653
- storage?: (env: Record<string, unknown>) => unknown;${_t}${ke}${K.configField}${E.configField}${H.configField}${j.configField}${W.configField}${U.configField}${q.configField}${Y.configField}${De}${ht}${Et}${Pt}${Ft}
1664
+ storage?: (env: Record<string, unknown>) => unknown;${_t}${ve}${Q.configField}${E.configField}${V.configField}${W.configField}${U.configField}${K.configField}${B.configField}${Y.configField}${_e}${ht}${Et}${Pt}${Mt}
1654
1665
  }
1655
1666
 
1656
1667
  const schedulerStub = {
@@ -1688,7 +1699,7 @@ const storageStub = {
1688
1699
  throw new Error("ctx.storage: no storage configured. Pass \`storage\` to createShardDO().");
1689
1700
  },
1690
1701
  };
1691
- ${Mt}${zt}${qt}${$e}${K.stub}${E.stub}${H.stub}${j.stub}${W.stub}${U.stub}${q.stub}${Y.stub}${h}${mt}${Jt}
1702
+ ${Ft}${zt}${qt}${Se}${Q.stub}${E.stub}${V.stub}${W.stub}${U.stub}${K.stub}${B.stub}${Y.stub}${h}${mt}${Vt}
1692
1703
  // Bound in-process \`ctx.run*\` composition depth so a self- or cyclically-
1693
1704
  // referencing call fails loudly with a clear error instead of overflowing the
1694
1705
  // stack. Tracked across the awaited handler chain (one DO invocation is
@@ -1774,7 +1785,7 @@ export const createShardDO = (config: ShardDOConfig = {}): new (state: ShardDOSt
1774
1785
 
1775
1786
  return registered.handler(ctx, args);
1776
1787
  }
1777
- ${Je.override}
1788
+ ${Ve.override}
1778
1789
  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> {
1779
1790
  const registered = LUNORA_FUNCTIONS[functionPath];
1780
1791
 
@@ -1849,7 +1860,7 @@ ${Ct}${Lt}${Gt}${Xt}
1849
1860
  protected override studioFeatures(): StudioFeaturesResult {
1850
1861
  return LUNORA_STUDIO_FEATURES;
1851
1862
  }
1852
- ${Q.evaluateOverride}${Q.subscriptionOverride}${$t}${Rt}
1863
+ ${H.evaluateOverride}${H.subscriptionOverride}${$t}${Rt}
1853
1864
  protected override advisories(): AdvisoryFinding[] {
1854
1865
  return LUNORA_ADVISORIES;
1855
1866
  }
@@ -2133,7 +2144,7 @@ ${Q.evaluateOverride}${Q.subscriptionOverride}${$t}${Rt}
2133
2144
  return;
2134
2145
  }
2135
2146
 
2136
- runShardMigrations(this.sql as SqlExec, schema as unknown as SchemaLike, { cdc: config.cdc ?? false${re} });
2147
+ runShardMigrations(this.sql as SqlExec, schema as unknown as SchemaLike, { cdc: config.cdc ?? false${ae} });
2137
2148
  this.migrated = true;
2138
2149
  }
2139
2150
 
@@ -2146,7 +2157,7 @@ ${Q.evaluateOverride}${Q.subscriptionOverride}${$t}${Rt}
2146
2157
  // dispatch path) fall back to the per-request fields as before.
2147
2158
  const userId = options.identity ? options.identity.userId : this.getCurrentUserId();
2148
2159
  const identity = options.identity ? options.identity.identity : this.getCurrentIdentity();
2149
- ${Ut}${ae}${en}${Re}${Oe}${Se}${Le}
2160
+ ${Ut}${oe}${en}${Ne}${Oe}${Re}${Ce}
2150
2161
  const scheduler = (config.scheduler?.(env) ?? schedulerStub) as SchedulerLike;
2151
2162
  // Build the storage adapter once and share it between \`ctx.storage\`
2152
2163
  // and \`ctx.db.system._storage\` so both read the same R2 binding. The
@@ -2173,13 +2184,13 @@ ${Ut}${ae}${en}${Re}${Oe}${Se}${Le}
2173
2184
  // so both write to the same trace.
2174
2185
  const span = this.makeDispatchSpan(traceAnchor, observability);
2175
2186
 
2176
- ${Vt} // \`ctx.db\`, wrapped in automatic instrumentation: by default this
2187
+ ${Jt} // \`ctx.db\`, wrapped in automatic instrumentation: by default this
2177
2188
  // adds aggregate counters (call count, total time, per-operation
2178
2189
  // breakdown) to the wide event rather than a span per call, so a
2179
2190
  // handler making hundreds of queries stays readable. See
2180
2191
  // \`instrumentDatabase\` for the \`"spans"\` / \`"off"\` levels.
2181
2192
  const db: DatabaseWriterLike = this.instrumentDb(createShardCtxDb(${Kt}), logFunctionPath, traceAnchor, observability);
2182
- ${Zt}${Ie}
2193
+ ${Zt}${De}
2183
2194
 
2184
2195
  // \`ctx.trace\` / \`ctx.metrics\`: spans and measurements to the same sink.
2185
2196
  // The trace anchor is threaded explicitly for the same reason \`identity\`
@@ -2214,7 +2225,7 @@ ${nn}
2214
2225
  scheduler,
2215
2226
  span,
2216
2227
  storage,
2217
- trace,${Qt}${ve}${tn}${ue}${Ne}${Te}${fe}${de}
2228
+ trace,${Qt}${$e}${tn}${pe}${Te}${Ae}${be}${ce}
2218
2229
  };
2219
2230
  ${an}${rn}
2220
2231
  ctx.runAction = (reference: FunctionReference, fnArgs: Record<string, unknown>) => dispatchRun("action", reference.__lunoraRef, fnArgs, ctx);
@@ -2224,30 +2235,30 @@ ${an}${rn}
2224
2235
  return ctx;
2225
2236
  }
2226
2237
  };
2227
- `},We=e=>{switch(e.kind){case"array":case"object":case"record":case"union":return{builder:"text",mode:"json",notNull:!0,typeAnnotation:C(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"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?We(e.inner):{builder:"text",notNull:!1},notNull:!1};case"storage":case"string":return{builder:"text",notNull:!0};default:return{builder:"text",notNull:!0}}},pt=(e,t)=>{const n=e.kind==="optional"&&e.inner?e.inner:e;return n.kind==="id"&&n.tableName!==void 0&&t.has(n.tableName)?n.tableName:void 0},yr=(e,t,n)=>{m(e,"drizzle column name");const r=We(t),a=r.mode?`, { mode: "${r.mode}" }`:"";let o=`${r.builder}("${e}"${a})`;r.typeAnnotation&&(o+=`.$type<${r.typeAnnotation}>()`);const i=pt(t,n);return i!==void 0&&(o+=`.references((): AnySQLiteColumn => ${i}._id)`),r.notNull&&(o+=".notNull()"),o},wr=e=>{m(e.name,"drizzle index name");const t=e.unique?"uniqueIndex":"index",n=e.fields.map(r=>(m(r,"drizzle index field"),`t.${r}`)).join(", ");return` ${e.name}: ${t}("${e.name}").on(${n}),`},xr=(e,t)=>{m(e.name,"table name");const n=[' _id: text("_id").primaryKey(),',' _creationTime: integer("_creationTime").notNull(),',...Object.entries(e.shape).map(([a,o])=>` ${a}: ${yr(a,o,t)},`)].join(`
2238
+ `},We=e=>{switch(e.kind){case"array":case"object":case"record":case"union":return{builder:"text",mode:"json",notNull:!0,typeAnnotation:N(e)};case"bigint":return{builder:"blob",mode:"bigint",notNull:!0};case"boolean":return{builder:"integer",mode:"boolean",notNull:!0};case"bytes":return{builder:"blob",mode:"buffer",notNull:!0};case"date":case"timestamp":return{builder:"integer",notNull:!0};case"from":return{builder:"text",notNull:!0,typeAnnotation:N(e)};case"id":return{builder:"text",notNull:!0};case"literal":{const t=e.literalValue??"";return t.startsWith('"')||t.startsWith("'")?{builder:"text",notNull:!0}:t==="true"||t==="false"?{builder:"integer",mode:"boolean",notNull:!0}:t==="null"?{builder:"text",notNull:!0}:{builder:"real",notNull:!0}}case"null":return{builder:"text",notNull:!0};case"number":return{builder:"real",notNull:!0};case"optional":return{...e.inner?We(e.inner):{builder:"text",notNull:!1},notNull:!1};case"storage":case"string":return{builder:"text",notNull:!0};default:return{builder:"text",notNull:!0}}},pt=(e,t)=>{const n=e.kind==="optional"&&e.inner?e.inner:e;return n.kind==="id"&&n.tableName!==void 0&&t.has(n.tableName)?n.tableName:void 0},xr=(e,t,n)=>{m(e,"drizzle column name");const r=We(t),a=r.mode?`, { mode: "${r.mode}" }`:"";let o=`${r.builder}("${e}"${a})`;r.typeAnnotation&&(o+=`.$type<${r.typeAnnotation}>()`);const i=pt(t,n);return i!==void 0&&(o+=`.references((): AnySQLiteColumn => ${i}._id)`),r.notNull&&(o+=".notNull()"),o},kr=e=>{m(e.name,"drizzle index name");const t=e.unique?"uniqueIndex":"index",n=e.fields.map(r=>(m(r,"drizzle index field"),`t.${r}`)).join(", ");return` ${e.name}: ${t}("${e.name}").on(${n}),`},vr=(e,t)=>{m(e.name,"table name");const n=[' _id: text("_id").primaryKey(),',' _creationTime: integer("_creationTime").notNull(),',...Object.entries(e.shape).map(([a,o])=>` ${a}: ${xr(a,o,t)},`)].join(`
2228
2239
  `),r=e.indexes.length>0?`, (t) => ({
2229
- ${e.indexes.map(a=>wr(a)).join(`
2240
+ ${e.indexes.map(a=>kr(a)).join(`
2230
2241
  `)}
2231
2242
  })`:"";return`export const ${e.name} = sqliteTable("${e.name}", {
2232
2243
  ${n}
2233
- }${r});`},kr=e=>e.typeAnnotation?.includes('Id<"')??!1,vr=(e,t)=>{const n=new Set(["integer","sqliteTable","text"]),r=new Set;let a=!1,o=!1;for(const i of e){for(const s of Object.values(i.shape)){const l=We(s);n.add(l.builder),o=o||kr(l),a=a||pt(s,t)!==void 0}for(const s of i.indexes)r.add(s.unique?"uniqueIndex":"index")}return{columns:[...n].toSorted((i,s)=>i.localeCompare(s)),indexes:[...r].toSorted((i,s)=>i.localeCompare(s)),needsAnyColumn:a,needsId:o}},et=(e,t=!1)=>{if(e.length===0)return`${v}export {};
2234
- `;const n=G(t),r=new Set(e.map(f=>f.name)),{columns:a,indexes:o,needsAnyColumn:i,needsId:s}=vr(e,r),l=[...o,...a].toSorted((f,y)=>f.localeCompare(y)),u=e.map(f=>xr(f,r)).join(`
2244
+ }${r});`},$r=e=>e.typeAnnotation?.includes('Id<"')??!1,Sr=(e,t)=>{const n=new Set(["integer","sqliteTable","text"]),r=new Set;let a=!1,o=!1;for(const i of e){for(const s of Object.values(i.shape)){const d=We(s);n.add(d.builder),o=o||$r(d),a=a||pt(s,t)!==void 0}for(const s of i.indexes)r.add(s.unique?"uniqueIndex":"index")}return{columns:[...n].toSorted((i,s)=>i.localeCompare(s)),indexes:[...r].toSorted((i,s)=>i.localeCompare(s)),needsAnyColumn:a,needsId:o}},et=(e,t=!1)=>{if(e.length===0)return`${S}export {};
2245
+ `;const n=ee(t),r=new Set(e.map(g=>g.name)),{columns:a,indexes:o,needsAnyColumn:i,needsId:s}=Sr(e,r),d=[...o,...a].toSorted((g,b)=>g.localeCompare(b)),u=e.map(g=>vr(g,r)).join(`
2235
2246
 
2236
2247
  `),p=[i?`import type { AnySQLiteColumn } from "${n.serverDrizzle}";
2237
2248
  `:"",s?`import type { Id } from "./dataModel.js";
2238
- `:""].join("");return`${v}import { ${l.join(", ")} } from "${n.serverDrizzle}";
2249
+ `:""].join("");return`${S}import { ${d.join(", ")} } from "${n.serverDrizzle}";
2239
2250
  ${p}
2240
2251
  ${u}
2241
- `},qr=(e,t=!1)=>{const n=e.tables.filter(a=>a.shardMode==="global"),r=e.tables.filter(a=>a.shardMode!=="global");return{global:et(n,t),shard:et(r,t)}},Br=e=>{const t=[],n=new Map;for(const s of e){const l=n.get(s.cron);l?l.push(s):(n.set(s.cron,[s]),t.push(s.cron))}const r=t.map(s=>` ${JSON.stringify(s)},`).join(`
2252
+ `},jr=(e,t=!1)=>{const n=e.tables.filter(a=>a.shardMode==="global"),r=e.tables.filter(a=>a.shardMode!=="global");return{global:D(et(n,t),Be),shard:D(et(r,t),Be)}},Wr=e=>{const t=[],n=new Map;for(const s of e){const d=n.get(s.cron);d?d.push(s):(n.set(s.cron,[s]),t.push(s.cron))}const r=t.map(s=>` ${JSON.stringify(s)},`).join(`
2242
2253
  `),a=r.length>0?`
2243
2254
  ${r}
2244
- `:"",o=[...n.entries()].map(([s,l])=>{const u=l.map(p=>{const f=p.workflow?`workflow: ${JSON.stringify(p.workflow.binding)}`:`functionPath: ${JSON.stringify(p.functionPath)}`;return` { name: ${JSON.stringify(p.name)}, ${f}, args: ${JSON.stringify(p.args)} },`}).join(`
2255
+ `:"",o=[...n.entries()].map(([s,d])=>{const u=d.map(p=>{const g=p.workflow?`workflow: ${JSON.stringify(p.workflow.binding)}`:`functionPath: ${JSON.stringify(p.functionPath)}`;return` { name: ${JSON.stringify(p.name)}, ${g}, args: ${JSON.stringify(p.args)} },`}).join(`
2245
2256
  `);return` ${JSON.stringify(s)}: [
2246
2257
  ${u}
2247
2258
  ],`}).join(`
2248
2259
  `),i=o.length>0?`
2249
2260
  ${o}
2250
- `:"";return`${v}/**
2261
+ `:"";return`${S}/**
2251
2262
  * One scheduled cron invocation. Exactly one target is set: \`functionPath\` is
2252
2263
  * the \`namespace:fn\` dispatch ref (matches \`__lunoraRef\`), invoked on the
2253
2264
  * shard; \`workflow\` is a \`WORKFLOW_*\` binding name whose durable workflow is
@@ -2272,10 +2283,10 @@ export const LUNORA_CRON_TRIGGERS: ReadonlyArray<string> = [${a}];
2272
2283
  * looks up \`event.cron\` here and dispatches every job in the list.
2273
2284
  */
2274
2285
  export const LUNORA_CRONS: Record<string, ReadonlyArray<LunoraCronJob>> = {${i}};
2275
- `},jr=e=>{const t=[...e].toSorted((r,a)=>r.name.localeCompare(a.name)).map(r=>{const a=[`name: ${JSON.stringify(r.name)}`,`table: ${JSON.stringify(r.table)}`];return r.field!==void 0&&a.push(`field: ${JSON.stringify(r.field)}`),r.dimensions!==void 0&&a.push(`dimensions: ${JSON.stringify(r.dimensions)}`),r.metric!==void 0&&a.push(`metric: ${JSON.stringify(r.metric)}`),r.metadata!==void 0&&a.push(`metadata: ${JSON.stringify(r.metadata)}`),` { ${a.join(", ")} },`}).join(`
2286
+ `},Ur=e=>{const t=[...e].toSorted((r,a)=>r.name.localeCompare(a.name)).map(r=>{const a=[`name: ${JSON.stringify(r.name)}`,`table: ${JSON.stringify(r.table)}`];return r.field!==void 0&&a.push(`field: ${JSON.stringify(r.field)}`),r.dimensions!==void 0&&a.push(`dimensions: ${JSON.stringify(r.dimensions)}`),r.metric!==void 0&&a.push(`metric: ${JSON.stringify(r.metric)}`),r.metadata!==void 0&&a.push(`metadata: ${JSON.stringify(r.metadata)}`),` { ${a.join(", ")} },`}).join(`
2276
2287
  `),n=t.length>0?`
2277
2288
  ${t}
2278
- `:"";return`${v}/**
2289
+ `:"";return`${S}/**
2279
2290
  * One vector index declared in \`schema.ts\` — an inline \`.vectorize()\` column
2280
2291
  * or a standalone \`defineVectorIndex()\`. \`field\` is the source column (absent
2281
2292
  * for a \`select\`-derived Shape B index); \`metadata\` lists the row fields
@@ -2296,4 +2307,4 @@ export interface LunoraVectorIndex {
2296
2307
  * \`createWorker({ vectorIntrospector })\` to back the studio's vector browser.
2297
2308
  */
2298
2309
  export const LUNORA_VECTOR_INDEXES: ReadonlyArray<LunoraVectorIndex> = [${n}];
2299
- `},Wr=e=>{const t=new Set,n=[];for(const r of e)t.has(r.cron)||(t.add(r.cron),n.push(r.cron));return n};export{jr as $,Wr as A,Dr as B,Cr as C,Ar as I,Lr as O,Ir as P,v as R,Br as S,Nn as a,Mr as b,Qn as c,Tr as g,Pr as i,Fr as l,Or as n,_r as o,ln as r,Er as s,qr as v};
2310
+ `},Kr=e=>{const t=new Set,n=[];for(const r of e)t.has(r.cron)||(t.add(r.cron),n.push(r.cron));return n};export{jr as $,Wr as A,_r as B,Cr as C,Dr as E,Ir as L,Ur as N,S,Kr as T,Vn as a,On as b,Fr as c,qr as d,Lr as g,Mr as l,Ar as n,Er as q,ln as r,Pr as s,Br as x};