@lunora/codegen 1.0.0-alpha.320 → 1.0.0-alpha.322

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.
@@ -0,0 +1 @@
1
+ import{SyntaxKind as c,Node as r}from"ts-morph";import{CAPABILITIES as m}from"./CAPABILITY_PROBES-brcmKenl.mjs";import{bindingKeyName as p,listLunoraSourceFiles as g}from"./isTestPath-B81lOULB.mjs";import{scanImportDeclaration as u,noSandboxUsage as l}from"./discoverSandboxUsage-w6Q3RvxZ.mjs";const d="ctx",E=(e,t,o)=>{for(const n of e.getDescendantsOfKind(c.ElementAccessExpression)){const s=n.getArgumentExpression();t(n.getExpression())&&s!==void 0&&(r.isStringLiteral(s)||r.isNoSubstitutionTemplateLiteral(s))&&o.add(s.getLiteralValue())}},x=e=>{const t=new Set,o=new Set([d]),n=i=>{if(r.isObjectBindingPattern(i))for(const a of i.getElements()){const f=p(a);f&&t.add(f)}};for(const i of e.getDescendantsOfKind(c.BindingElement)){if(p(i)!==d)continue;const a=i.getNameNode();r.isIdentifier(a)?o.add(a.getText()):n(a)}const s=i=>r.isIdentifier(i)&&o.has(i.getText());for(const i of e.getDescendantsOfKind(c.PropertyAccessExpression))s(i.getExpression())&&t.add(i.getName());E(e,s,t);for(const i of e.getDescendantsOfKind(c.VariableDeclaration)){const a=i.getInitializer();a!==void 0&&s(a)&&n(i.getNameNode())}return t},y=e=>{if(e.isTypeOnly())return!0;if(r.isExportDeclaration(e)){const o=e.getNamedExports();return!e.isNamespaceExport()&&o.length>0&&o.every(n=>n.isTypeOnly())}const t=e.getNamedImports();return e.getDefaultImport()===void 0&&e.getNamespaceImport()===void 0&&t.length>0&&t.every(o=>o.isTypeOnly())},N=new Map(m.flatMap(({bindingFreeExports:e,moduleSpecifier:t})=>e===void 0?[]:[[t,new Set(e)]])),I=(e,t)=>{const o=N.get(t);if(o===void 0||r.isImportDeclaration(e)&&(e.getDefaultImport()!==void 0||e.getNamespaceImport()!==void 0))return!1;const n=r.isExportDeclaration(e)?e.getNamedExports():e.getNamedImports();return n.length>0&&n.every(s=>s.isTypeOnly()||o.has(s.getName()))},S=e=>{const t=new Set;for(const o of e.getDescendantsOfKind(c.CallExpression)){const[n]=o.getArguments();o.getExpression().getKind()===c.ImportKeyword&&(r.isStringLiteral(n)||r.isNoSubstitutionTemplateLiteral(n))&&t.add(n.getLiteralValue())}return t},T=e=>{const t=e.getImportDeclarations(),o=l();for(const n of t){const s=u(n);for(const i of Object.keys(o))o[i]||=s[i]}return{contextReads:x(e),dynamicImports:S(e),sandboxTools:o,valueImports:new Set([...t,...e.getExportDeclarations()].flatMap(n=>{const s=n.getModuleSpecifierValue();return s===void 0||y(n)||I(n,s)?[]:[s]}))}},b=e=>{const t=new Set,o=new Set,n=l(),s=new Set;for(const i of e){for(const a of i.contextReads)t.add(a);for(const a of i.dynamicImports)o.add(a);for(const a of i.valueImports)s.add(a);for(const a of Object.keys(n))n[a]||=i.sandboxTools[a]}return{contextReads:t,dynamicImports:o,sandboxTools:n,valueImports:s}},O=e=>new Set(m.filter(({contextProperty:t,moduleSpecifier:o})=>e.valueImports.has(o)||t!==void 0&&e.contextReads.has(t)).map(({key:t})=>t)),v=new RegExp(String.raw`\b${d}\b`,"u"),w=new RegExp(String.raw`\b(?:${m.flatMap(({contextProperty:e})=>e===void 0?[]:[e]).join("|")})\b`,"u"),K=e=>v.test(e)&&w.test(e),L=(e,t)=>{const o=b(g(t).map(s=>T(e.getSourceFile(s)??e.addSourceFileAtPath(s)))),n=O(o);return Object.fromEntries(m.map(({key:s})=>[s,n.has(s)]))};export{O as capabilitiesUsedBy,x as contextPropertiesRead,L as discoverFeatureUsage,b as foldCapabilitySignals,K as mayReadCapabilityContext,T as sourceCapabilitySignals};
@@ -361,8 +361,9 @@ const buildGlobalCdcApplier =
361
361
 
362
362
  return this;
363
363
  }`," /**\n * Route the shard's `ctx.log` lines, `ctx.trace` spans and `ctx.metrics` measurements to a telemetry sink.\n *\n * The DO half of observability: without it every in-handler signal stays in the shard's local ring buffer (the studio Logs panel) and reaches no collector. The worker half — one `onRpc` event per dispatched RPC — is a `createWorker` option; pass the SAME sink to both via `.extend((env) => ({ observability: sink(env) }))` to correlate them.\n */\n public observability(selector: NonNullable<ShardConfig[\"observability\"]>): this {\n this.observabilitySink = selector;\n\n return this;\n }",' /** Resolution policy for a relation-crossing `where` whose child is co-located in this shard: `"auto"` (cost-based, the engine default), `"always"` (inline correlated EXISTS) or `"never"` (universal semijoin). All three return identical rows. */\n public relationExistsPushDown(mode: NonNullable<ShardConfig["relationExistsPushDown"]>): this {\n this.relationExistsPushDownMode = mode;\n\n return this;\n }',` /** Authorize each RPC/subscription read and fence its eventual delivery against durable authority epochs. */
364
- public deliveryAuthorization(selector: NonNullable<ShardConfig["deliveryAuthorization"]>): this {
365
- this.deliveryAuthorizationSelector = selector;
364
+ public deliveryAuthorization(selector: (env: Env) => ReturnType<NonNullable<ShardConfig["deliveryAuthorization"]>>): this {
365
+ this.deliveryAuthorizationSelector = selector as NonNullable<ShardConfig["deliveryAuthorization"]>;
366
+
366
367
  return this;
367
368
  }`,...e.hasAuth?[' /** Wire better-auth — the builder lazily builds the instance, runs `ensureMigrated`, and dispatches `/api/auth/*` inside the worker (instrumented for the auth-failure SLO). Pass `d1` for the D1-backed default, or `namespace` + `internalSecret` to host the auth tables in a Durable Object (what `@better-auth/scim` needs). */\n public auth(declaration: AuthDeclaration<Env>): this {\n // Reject the ambiguous and the empty shapes here rather than at the first\n // request: with neither storage set, auth would silently never answer, and\n // with both it is unclear which one owns the tables.\n if (declaration.d1 && declaration.namespace) {\n throw new Error(".auth(): pass either `d1` or `namespace`, not both — they are two different homes for the same tables.");\n }\n\n if (!declaration.d1 && !declaration.namespace) {\n throw new Error(".auth(): needs `d1` (D1-backed) or `namespace` (Durable-Object-backed) to know where the auth tables live.");\n }\n\n if (declaration.namespace && !declaration.internalSecret) {\n throw new Error(\n ".auth(): `namespace` requires `internalSecret` — the auth DO binding is reachable from any worker bound to it, so identity resolution is gated on a shared secret and would otherwise fail closed on every request.",\n );\n }\n\n this.authDeclaration = declaration;\n\n return this;\n }']:[]," /** Escape hatch — merge raw `WorkerOptions` (anything not yet sugared) over the derived options at build time. The second `derived` argument is a snapshot of the options assembled so far (after `.auth(...)` etc.), so you can compose rather than clobber — e.g. wrap `derived.resolveIdentity` instead of replacing it. */\n public extend(fn: (env: Env, derived: Readonly<WorkerOptions>) => Partial<WorkerOptions>): this {\n this.extendFns.push(fn);\n\n return this;\n }",...e.hasGlobal?[` /** Back \`.global()\` (cross-tenant) tables with D1 — wires \`ctx.db\` routing, the studio global browser, and reverse cross-shard relations. */
368
369
  public global(declaration: GlobalDeclaration<Env>): this {
@@ -404,7 +405,7 @@ const buildGlobalCdcApplier =
404
405
  this.storageDeclaration = declaration;
405
406
 
406
407
  return this;
407
- }`]:[],...T(e)],I=e=>{const r=a=>e.hasScheduler?`
408
+ }`]:[],...T(e)],q=e=>{const r=a=>e.hasScheduler?`
408
409
  ...(this.schedulerDeclaration ? { scheduler: this.resolveScheduler(env) as unknown as ${a}["scheduler"] } : {}),`:"",t=[" cdc: this.cdcEnabled,"," reactiveCache: this.reactiveCacheConfig,"," ...(this.maxRelationKeysLimit === undefined ? {} : { maxRelationKeys: this.maxRelationKeysLimit }),"," ...(this.observabilitySink === undefined ? {} : { observability: this.observabilitySink }),"," ...(this.deliveryAuthorizationSelector === undefined ? {} : { deliveryAuthorization: this.deliveryAuthorizationSelector }),"," ...(this.relationExistsPushDownMode === undefined ? {} : { relationExistsPushDown: this.relationExistsPushDownMode }),",...e.hasGlobal?[` ...(this.globalDeclaration
409
410
  ? {
410
411
  d1: (rawEnv: Record<string, unknown>, request?: { bookmark?: string; cdc?: boolean; cdcRetentionMs?: number; identity?: Record<string, unknown>; onBookmark?: (bookmark: string | undefined) => void; userId?: string | null }) => {
@@ -487,7 +488,7 @@ const buildGlobalCdcApplier =
487
488
  : {}),`]:[],...d(e)?[" ...(this.shardRegistrySelector ? { shardRegistry: (rawEnv: Record<string, unknown>) => this.shardRegistrySelector?.(rawEnv as Env) } : {}),"]:[],...e.hasSourcedTables?[" ...(this.sourceClientFactory === undefined ? {} : { sourceClient: this.sourceClientFactory }),"]:[],...e.hasStorage?[" ...(this.storageDeclaration ? { storage: (rawEnv: Record<string, unknown>, origin?: string) => this.resolveStorage(rawEnv as Env, origin) } : {}),"]:[],...g(e)?[" ...this.shardExtras,"]:[]];return t.length>0?`
488
489
  ${t.join(`
489
490
  `)}
490
- `:""},q=e=>e?['import * as lunoraIdentityContract from "../identity.js";']:[],L=(e,r)=>e?['import type { CreateAccessResolverOptions } from "@lunora/cloudflare-access";',`import { createAccessResolver${r?", composeResolvers":""} } from "@lunora/cloudflare-access";`]:[],j=e=>e?['import { createKvIntrospectorFromEnv } from "@lunora/bindings/kv";']:[],B=e=>e?['import { createVectorAdminIntrospector } from "@lunora/bindings/vectors";']:[],P=e=>e?['import type { D1CtxDbOptions, D1DatabaseLike, D1Exec } from "@lunora/d1";','import { applyCdcChanges, createD1CtxDb, emitD1QueryCost, exportGlobalRows, facetGlobalColumn, importGlobalRows, listGlobalTables, readD1CdcChanges, readGlobalTablePage, retryingExec } from "@lunora/d1";']:[],G=e=>e?['import notifyConfig from "../notify.js";']:[],_=e=>v(e)?['import { dispatchAgentEmail } from "@lunora/agent/inbound";']:[],W=e=>v(e)?['import * as lunoraAgentDefinitions from "../agents.js";']:[],M=e=>{const{hasFramework:r,hasGlobal:t,hasHyperdriveGlobal:a,hasQueue:n,useUmbrella:o}=e,i=o?"lunorash/runtime":"@lunora/runtime",c=["ExecutionContextLike","HttpRouterLike","LunoraWorker","Route","ScheduledControllerLike","ShardNamespaceLike","WorkerOptions",...n?["TriggerTrace"]:[],...t?["GlobalIntrospector"]:[],...e.tables.length>0?["ShardingInfo"]:[],...r?["FrameworkHostHandler"]:[]],l=[...t||a?["createCrossShardRelationCapabilities"]:[],...d(e)?["createDynamicShardRegistry","createQueryCoordinator"]:[],"createWorker",...e.jurisdiction?["declareAppJurisdiction"]:[],"resolveLogArchiveFromEnv",...e.hasAuth?["memoizeIdentity"]:[],...r?["withFrameworkWorker"]:[]].join(", ");return[`import type { ${[...c].toSorted((s,h)=>s.localeCompare(h)).join(", ")} } from "${i}";`,`import { ${l} } from "${i}";`]},H=e=>{const{hasAccess:r,hasAuth:t,hasGlobal:a,hasHyperdriveGlobal:n,hasKvIntrospector:o,hasQueue:i,hasScheduler:c,hasStorage:l,hasWorkflow:s,wantsOpenApi:h,wantsOpenRpc:u}=e;return[...t?['import type { AuthNamespaceLike, LunoraAuth, LunoraAuthOptions } from "@lunora/auth";','import { authDiscoveryPathsFor, createAuth, createAuthAdmin, createAuthAuditReader, createDoAuthWiring, d1Executor, handleAuthDiscoveryRequest, handleAuthRequest, lunoraD1Adapter } from "@lunora/auth";']:[],...L(r,t),...P(a),...n?['import type { HyperdriveEngine } from "@lunora/hyperdrive/global";','import { createHyperdriveGlobalCtxDb } from "@lunora/hyperdrive/global";','import type { SqlCtxDbOptions, SqlExec } from "@lunora/sql-store";']:[],...j(o),...B(e.hasVectors),...c?['import type { DurableObjectNamespaceLike } from "@lunora/scheduler";','import { createScheduler } from "@lunora/scheduler";']:[],...l?['import type { R2BucketLike, R2S3Credentials, Storage } from "@lunora/storage";','import { createBucketStorage, createStorage } from "@lunora/storage";']:[],...s?['import { createWorkflowsRestClient } from "@lunora/workflow";']:[],..._(e),...M(e),"",...q(e.identity),...W(e),...a||n?['import schema from "../schema.js";']:[],...G(e.hasNotify),'import { LUNORA_CRONS } from "./crons.js";','import { LUNORA_FUNCTIONS } from "./functions.js";',...i?['import { createQueueCaptureSink, dispatchQueueBatch, shouldCaptureQueue } from "@lunora/queue";','import { LUNORA_QUEUE_REGISTRY } from "./queues.js";']:[],...e.wantsArchitecture?['import { architecture } from "./architecture.js";']:[],...h?['import { openApiSpec } from "./openapi.js";']:[],...u?['import { openRpcSpec } from "./openrpc.js";']:[],'import { createShardDO } from "./shard.js";',...e.hasVectors?['import { LUNORA_VECTOR_INDEXES } from "./vectors.js";']:[]]},$=e=>e.jurisdiction&&e.jurisdictionPinsAuth===!0?`
491
+ `:""},I=e=>e?['import * as lunoraIdentityContract from "../identity.js";']:[],L=(e,r)=>e?['import type { CreateAccessResolverOptions } from "@lunora/cloudflare-access";',`import { createAccessResolver${r?", composeResolvers":""} } from "@lunora/cloudflare-access";`]:[],j=e=>e?['import { createKvIntrospectorFromEnv } from "@lunora/bindings/kv";']:[],B=e=>e?['import { createVectorAdminIntrospector } from "@lunora/bindings/vectors";']:[],P=e=>e?['import type { D1CtxDbOptions, D1DatabaseLike, D1Exec } from "@lunora/d1";','import { applyCdcChanges, createD1CtxDb, emitD1QueryCost, exportGlobalRows, facetGlobalColumn, importGlobalRows, listGlobalTables, readD1CdcChanges, readGlobalTablePage, retryingExec } from "@lunora/d1";']:[],G=e=>e?['import notifyConfig from "../notify.js";']:[],_=e=>v(e)?['import { dispatchAgentEmail } from "@lunora/agent/inbound";']:[],W=e=>v(e)?['import * as lunoraAgentDefinitions from "../agents.js";']:[],M=e=>{const{hasFramework:r,hasGlobal:t,hasHyperdriveGlobal:a,hasQueue:s,useUmbrella:o}=e,i=o?"lunorash/runtime":"@lunora/runtime",c=["ExecutionContextLike","HttpRouterLike","LunoraWorker","Route","ScheduledControllerLike","ShardNamespaceLike","WorkerOptions",...s?["TriggerTrace"]:[],...t?["GlobalIntrospector"]:[],...e.tables.length>0?["ShardingInfo"]:[],...r?["FrameworkHostHandler"]:[]],l=[...t||a?["createCrossShardRelationCapabilities"]:[],...d(e)?["createDynamicShardRegistry","createQueryCoordinator"]:[],"createWorker",...e.jurisdiction?["declareAppJurisdiction"]:[],"resolveLogArchiveFromEnv",...e.hasAuth?["memoizeIdentity"]:[],...r?["withFrameworkWorker"]:[]].join(", ");return[`import type { ${[...c].toSorted((n,h)=>n.localeCompare(h)).join(", ")} } from "${i}";`,`import { ${l} } from "${i}";`]},H=e=>{const{hasAccess:r,hasAuth:t,hasGlobal:a,hasHyperdriveGlobal:s,hasKvIntrospector:o,hasQueue:i,hasScheduler:c,hasStorage:l,hasWorkflow:n,wantsOpenApi:h,wantsOpenRpc:u}=e;return[...t?['import type { AuthNamespaceLike, LunoraAuth, LunoraAuthOptions } from "@lunora/auth";','import { authDiscoveryPathsFor, createAuth, createAuthAdmin, createAuthAuditReader, createDoAuthWiring, d1Executor, handleAuthDiscoveryRequest, handleAuthRequest, lunoraD1Adapter } from "@lunora/auth";']:[],...L(r,t),...P(a),...s?['import type { HyperdriveEngine } from "@lunora/hyperdrive/global";','import { createHyperdriveGlobalCtxDb } from "@lunora/hyperdrive/global";','import type { SqlCtxDbOptions, SqlExec } from "@lunora/sql-store";']:[],...j(o),...B(e.hasVectors),...c?['import type { DurableObjectNamespaceLike } from "@lunora/scheduler";','import { createScheduler } from "@lunora/scheduler";']:[],...l?['import type { R2BucketLike, R2S3Credentials, Storage } from "@lunora/storage";','import { createBucketStorage, createStorage } from "@lunora/storage";']:[],...n?['import { createWorkflowsRestClient } from "@lunora/workflow";']:[],..._(e),...M(e),"",...I(e.identity),...W(e),...a||s?['import schema from "../schema.js";']:[],...G(e.hasNotify),'import { LUNORA_CRONS } from "./crons.js";','import { LUNORA_FUNCTIONS } from "./functions.js";',...i?['import { createQueueCaptureSink, dispatchQueueBatch, shouldCaptureQueue } from "@lunora/queue";','import { LUNORA_QUEUE_REGISTRY } from "./queues.js";']:[],...e.wantsArchitecture?['import { architecture } from "./architecture.js";']:[],...h?['import { openApiSpec } from "./openapi.js";']:[],...u?['import { openRpcSpec } from "./openrpc.js";']:[],'import { createShardDO } from "./shard.js";',...e.hasVectors?['import { LUNORA_VECTOR_INDEXES } from "./vectors.js";']:[]]},$=e=>e.jurisdiction&&e.jurisdictionPinsAuth===!0?`
491
492
  // The schema's jurisdiction pins the auth object like every other DO.
492
493
  jurisdiction: ${JSON.stringify(e.jurisdiction)},`:"",U=e=>typeof e=="string"?`{ mode: { kind: ${JSON.stringify(e)} } }`:`{ mode: { field: ${JSON.stringify(e.field)}, kind: "shardBy" } }`,F=e=>[...e.tables.length>0?[` const tableSharding = new Map<string, ShardingInfo>([
493
494
  ${e.tables.map(r=>` [${JSON.stringify(r.name)}, ${U(r.shardMode)}],`).join(`
@@ -747,10 +748,10 @@ ${e.tables.map(r=>` [${JSON.stringify(r.name)}, ${U(r.shardMode)}],`)
747
748
  }`]:[],...e.voiceAgents&&e.voiceAgents.length>0?[` options.voiceAgents = {
748
749
  ${e.voiceAgents.map(r=>` ${JSON.stringify(r.exportName)}: (env as Record<string, unknown>)[${JSON.stringify(r.bindingName)}] as ShardNamespaceLike,`).join(`
749
750
  `)}
750
- };`]:[]],z=e=>[" cronJobs: LUNORA_CRONS,"," functions: LUNORA_FUNCTIONS,",...e.identity?[` identity: lunoraIdentityContract.${e.identity.exportName},`]:[],...e.jurisdiction?[` jurisdiction: ${JSON.stringify(e.jurisdiction)},`]:[],...e.wantsArchitecture?[" architecture,"]:[],...e.wantsOpenApi?[" openApiSpec,"]:[],...e.wantsOpenRpc?[" openRpcSpec,"]:[],...e.hasQueue?[" queue: (batch: unknown, queueEnv: unknown, _context: ExecutionContextLike, trigger: TriggerTrace): Promise<void> =>"," dispatchQueueBatch(batch as Parameters<typeof dispatchQueueBatch>[0], LUNORA_QUEUE_REGISTRY, {"," capture: shouldCaptureQueue(queueEnv as Record<string, unknown>)",` ? createQueueCaptureSink(queueEnv as Record<string, unknown>${e.jurisdiction?`, { jurisdiction: ${JSON.stringify(e.jurisdiction)} }`:""})`," : undefined,"," env: queueEnv as Record<string, unknown>,"," traceparent: trigger.traceparent,"," }),"]:[]," ...(this.httpRouterApp ? { httpRouter: this.httpRouterApp } : {}),"," routes: this.routeMap,"," shardDO: this.shardSelector?.(env) ?? (undefined as unknown as ShardNamespaceLike),"],J=e=>e?`
751
+ };`]:[]],z=e=>[" cronJobs: LUNORA_CRONS,"," functions: LUNORA_FUNCTIONS,",...e.identity?[` identity: lunoraIdentityContract.${e.identity.exportName},`]:[],...e.jurisdiction?[` jurisdiction: ${JSON.stringify(e.jurisdiction)},`]:[],...e.wantsArchitecture?[" architecture,"]:[],...e.wantsOpenApi?[" openApiSpec,"]:[],...e.wantsOpenRpc?[" openRpcSpec,"]:[],...e.hasQueue?[` queue: (batch: unknown, queueEnv: unknown, _context: ExecutionContextLike, trigger: TriggerTrace, ${e.liveStreams?"queueLive":"_live"}: Parameters<typeof dispatchQueueBatch>[2]["live"], queueFetch: Parameters<typeof dispatchQueueBatch>[2]["fetchImpl"]): Promise<void> =>`," dispatchQueueBatch(batch as Parameters<typeof dispatchQueueBatch>[0], LUNORA_QUEUE_REGISTRY, {"," capture: shouldCaptureQueue(queueEnv as Record<string, unknown>)",` ? createQueueCaptureSink(queueEnv as Record<string, unknown>${e.jurisdiction?`, { jurisdiction: ${JSON.stringify(e.jurisdiction)} }`:""})`," : undefined,"," env: queueEnv as Record<string, unknown>,"," traceparent: trigger.traceparent,"," fetchImpl: queueFetch,",...e.liveStreams?[" live: queueLive,"]:[]," }),"]:[]," ...(this.httpRouterApp ? { httpRouter: this.httpRouterApp } : {}),"," routes: this.routeMap,",...e.liveStreamsWithheld?[" liveStreams: false,"]:[]," shardDO: this.shardSelector?.(env) ?? (undefined as unknown as ShardNamespaceLike),"],J=e=>e?`
751
752
  /** The identity memo per \`env\` object, owned by one assembled worker. */
752
753
  type IdentityMemoStore = WeakMap<object, ReturnType<typeof memoizeIdentity>>;
753
- `:"",K=e=>[...e.hasAuth?["AuthDeclaration"]:[],"ComposedApp",...e.hasGlobal?["GlobalDeclaration"]:[],"LunoraConfig",...e.hasScheduler?["SchedulerDeclaration"]:[],"Selector",...e.hasStorage?["StorageDeclaration"]:[]].toSorted((r,t)=>r.localeCompare(t)).join(", "),Z=e=>{const r=(e.hasVectors??!0)&&(e.vectorIndexCount??0)>0,t={...e,hasVectors:r},{hasAuth:a}=t,n=C(t),o=Q(t),i=a?` let auth: LunoraAuth | null = null;
754
+ `:"",K=e=>[...e.hasAuth?["AuthDeclaration"]:[],"ComposedApp",...e.hasGlobal?["GlobalDeclaration"]:[],"LunoraConfig",...e.hasScheduler?["SchedulerDeclaration"]:[],"Selector",...e.hasStorage?["StorageDeclaration"]:[]].toSorted((r,t)=>r.localeCompare(t)).join(", "),Z=e=>{const r=(e.hasVectors??!0)&&(e.vectorIndexCount??0)>0,t={...e,hasVectors:r},{hasAuth:a}=t,s=C(t),o=Q(t),i=a?` let auth: LunoraAuth | null = null;
754
755
  let authInit: Promise<void> | null = null;
755
756
  // One memo per env for THIS assembled worker: a framework-hosted worker rebuilds its options per
756
757
  // request and must reuse it, but a second \`assemble()\` has its own auth closure and must not share.
@@ -808,8 +809,8 @@ type IdentityMemoStore = WeakMap<object, ReturnType<typeof memoizeIdentity>>;
808
809
  throw error;
809
810
  }));
810
811
  `:"",l=a?`
811
- await ensureAuth(env);`:"",s=a?"() => auth, identityMemos":"() => null",h=a?"getAuth: () => LunoraAuth | null, identityMemos: IdentityMemoStore":"_getAuth: () => null",u=t.hasFramework?` const buildWorker = (env: Env): LunoraWorker =>
812
- host ? withFrameworkWorker(host, (hostEnv) => this.buildWorkerOptions(hostEnv as Env, ${s})) : createWorker(this.buildWorkerOptions(env, ${s}));`:` const buildWorker = (env: Env): LunoraWorker => createWorker(this.buildWorkerOptions(env, ${s}));`,y=t.hasFramework?"host?: FrameworkHostHandler":"",p=t.emailAgents??[],f=p.length>0?` composed.email = dispatchAgentEmail([
812
+ await ensureAuth(env);`:"",n=a?"() => auth, identityMemos":"() => null",h=a?"getAuth: () => LunoraAuth | null, identityMemos: IdentityMemoStore":"_getAuth: () => null",u=t.hasFramework?` const buildWorker = (env: Env): LunoraWorker =>
813
+ host ? withFrameworkWorker(host, (hostEnv) => this.buildWorkerOptions(hostEnv as Env, ${n})) : createWorker(this.buildWorkerOptions(env, ${n}));`:` const buildWorker = (env: Env): LunoraWorker => createWorker(this.buildWorkerOptions(env, ${n}));`,y=t.hasFramework?"host?: FrameworkHostHandler":"",p=t.emailAgents??[],f=p.length>0?` composed.email = dispatchAgentEmail([
813
814
  ${p.map(b=>` { agent: lunoraAgentDefinitions.${b.exportName}, className: ${JSON.stringify(b.className)} },`).join(`
814
815
  `)}
815
816
  ]);
@@ -831,9 +832,9 @@ ${J(a)}${t.jurisdiction?`
831
832
  // \`@lunora/mail\` reads it to pin its shard RPC like every other DO path.
832
833
  declareAppJurisdiction(${JSON.stringify(t.jurisdiction)});
833
834
  `:""}
834
- ${n.join(`
835
+ ${s.join(`
835
836
 
836
- `)}${n.length>0?`
837
+ `)}${s.length>0?`
837
838
 
838
839
  `:""}/** The composed app: a Cloudflare module worker (\`fetch\` / \`scheduled\` / optional \`email\`) plus the \`ShardDO\` class binding. */
839
840
  interface ComposedApp extends LunoraWorker {
@@ -863,7 +864,7 @@ ${w}
863
864
 
864
865
  /** Build the shard DO + compose the worker (standalone or framework-hosted), wrapping the lazy per-isolate singletons + auth init. */
865
866
  private assemble(${y}): ComposedApp {
866
- const ShardDO = createShardDO({${I(t)}});
867
+ const ShardDO = createShardDO({${q(t)}});
867
868
 
868
869
  // Per-isolate singletons: the worker (and auth instance) are expensive to
869
870
  // build, so the first request constructs them and every later request on
@@ -1,4 +1,4 @@
1
- import{LunoraError as P}from"@lunora/errors";import{L as oe,G as C,d as j,I as M,b as F,r as se,c as ae}from"./shared-DnCokNcE.mjs";import{renderAgentFunctionRegistry as ie,renderSandboxFunctionRegistry as ce}from"./emitApi-CDgIPAG2.mjs";import{b as le,a as de,r as _,c as ue}from"./qualifiers-DEdXn5wP.mjs";import{s as f}from"./dispatch-namespace-DwTjD7BU.mjs";const he=new Set(["any","bigint","boolean","date","id","null","number","storage","string","timestamp"]),D=r=>r.column!==void 0,me=(r,t)=>{switch(r){case"bigint":return`if (typeof ${t} !== "bigint") return DEFER;
1
+ import{LunoraError as P}from"@lunora/errors";import{L as oe,G as C,d as j,I as F,b as M,r as se,c as ae}from"./shared-DnCokNcE.mjs";import{renderAgentFunctionRegistry as ie,renderSandboxFunctionRegistry as ce}from"./emitApi-CDgIPAG2.mjs";import{b as le,a as de,r as _,c as ue}from"./qualifiers-DEdXn5wP.mjs";import{s as f}from"./dispatch-namespace-DwTjD7BU.mjs";const he=new Set(["any","bigint","boolean","date","id","null","number","storage","string","timestamp"]),D=r=>r.column!==void 0,me=(r,t)=>{switch(r){case"bigint":return`if (typeof ${t} !== "bigint") return DEFER;
2
2
  `;case"boolean":return`if (typeof ${t} !== "boolean") return DEFER;
3
3
  `;case"date":case"number":case"timestamp":return`if (typeof ${t} !== "number" || !Number.isFinite(${t})) return DEFER;
4
4
  `;case"null":return`if (${t} !== null) return DEFER;
@@ -24,7 +24,7 @@ ${J(t)}${a.pre}const ${s} = { ${a.entries} };
24
24
  `;return{out:s,pre:d}},B=r=>{let t=0;const o=U(r,"source",{next:()=>(t+=1,t)});if(o)return`(source) => {
25
25
  if (typeof source !== "object" || source === null || Array.isArray(source)) return DEFER;
26
26
  ${J("source")}${o.pre}return { ${o.entries} };
27
- }`},Re=(r,t)=>`lunora_${f(r)}_${String(t)}`,I=r=>JSON.stringify(Object.entries(r).toSorted(([t],[n])=>t.localeCompare(n)).map(([t,n])=>{const o=n.kind==="optional",a=o?n.inner??{kind:"unknown"}:n,i=a.kind==="array"?a.inner?.kind:void 0,s=a.kind==="id"?a.tableName:void 0;return{kind:a.kind,name:t,optional:o,...s===void 0?{}:{table:s},...i===void 0||i==="unknown"?{}:{element:i}}})),H=(r,t,n,o)=>{const a=new Map,i=s=>{a.has(s)||a.set(s,Re(s,a.size))};for(const s of r)i(s.filePath);for(const s of t)i(s.filePath);for(const s of n)i(s.filePath);for(const s of o)i(s.filePath);return a},q=(r,t,n)=>new Set([...r.map(o=>o.filePath),...t.map(o=>o.filePath),...n.map(o=>o.filePath)]),k=r=>`${r}[functionPath]`,Ne=`const callRegistered = async <R>(context: CallerCtx, functionPath: string, args: Record<string, unknown> | undefined): Promise<R> => {
27
+ }`},Re=(r,t)=>`lunora_${f(r)}_${String(t)}`,I=r=>JSON.stringify(Object.entries(r).toSorted(([t],[n])=>t.localeCompare(n)).map(([t,n])=>{const o=n.kind==="optional",a=o?n.inner??{kind:"unknown"}:n,i=a.kind==="array"?a.inner?.kind:void 0,s=a.kind==="id"?a.tableName:void 0;return{kind:a.kind,name:t,optional:o,...s===void 0?{}:{table:s},...i===void 0||i==="unknown"?{}:{element:i}}})),H=(r,t,n,o)=>{const a=new Map,i=s=>{a.has(s)||a.set(s,Re(s,a.size))};for(const s of r)i(s.filePath);for(const s of t)i(s.filePath);for(const s of n)i(s.filePath);for(const s of o)i(s.filePath);return a},q=(r,t,n)=>new Set([...r.map(o=>o.filePath),...t.map(o=>o.filePath),...n.map(o=>o.filePath)]),k=r=>`${r}[functionPath]`,be=`const callRegistered = async <R>(context: CallerCtx, functionPath: string, args: Record<string, unknown> | undefined): Promise<R> => {
28
28
  const registered = await loadFunction(functionPath);
29
29
 
30
30
  if (!registered) {
@@ -57,7 +57,7 @@ ${J("source")}${o.pre}return { ${o.entries} };
57
57
  }
58
58
 
59
59
  return (await registered.handler(context, args ?? {})) as R;
60
- };`,be=(r,t,n=[],o=[],a=!1)=>{const i=H(r,t,n,o),s=q(t,n,o),d=[...i.entries()].filter(([e])=>!a||s.has(e)?!0:r.some(m=>m.filePath===e&&m.channel?.kind==="room")).map(([e,m])=>{if(!M.test(e))throw new P("INTERNAL",`@lunora/codegen: refusing to emit import for unsafe file path: ${JSON.stringify(e)}`);return`import ${a&&!s.has(e)?"type ":""}* as ${m} from "../${e}.js";`}).join(`
60
+ };`,Ne=(r,t,n=[],o=[],a=!1)=>{const i=H(r,t,n,o),s=q(t,n,o),d=[...i.entries()].filter(([e])=>!a||s.has(e)?!0:r.some(m=>m.filePath===e&&m.channel?.kind==="room")).map(([e,m])=>{if(!F.test(e))throw new P("INTERNAL",`@lunora/codegen: refusing to emit import for unsafe file path: ${JSON.stringify(e)}`);return`import ${a&&!s.has(e)?"type ":""}* as ${m} from "../${e}.js";`}).join(`
61
61
  `),u=r.map(e=>!a||s.has(e.filePath)?` "${f(e.filePath)}:${e.exportName}": ${i.get(e.filePath)??""}.${e.exportName} as unknown as RegisteredLunoraFunction,`:` "${f(e.filePath)}:${e.exportName}": { args: {}, handler: unloadedFunctionHandler, ...${JSON.stringify({argumentDescriptors:JSON.parse(I(e.args)),kind:e.kind,...e.channel?{channel:e.channel}:{},...e.expose?{expose:e.expose}:{},...e.lifecycle?{lifecycle:e.lifecycle}:{},...e.visibility?{visibility:e.visibility}:{},...e.x402?.price===void 0?{}:{x402:{price:e.x402.price}}})} } satisfies RegisteredLunoraFunction & Pick<FunctionManifestEntry, "argumentDescriptors" | "channel" | "expose">,`).join(`
62
62
  `),c=t.map(e=>` ${JSON.stringify(e.id)}: ${i.get(e.filePath)??""}.${e.exportName} as unknown as RegisteredDataMigration,`).join(`
63
63
  `),l=n.map(e=>` "${f(e.filePath)}:${e.exportName}": ${i.get(e.filePath)??""}.${e.exportName} as unknown as RegisteredLunoraFunction,`).join(`
@@ -65,21 +65,21 @@ ${J("source")}${o.pre}return { ${o.entries} };
65
65
  `),y=n.map(e=>`${f(e.filePath)}:${e.exportName}`),$=[u,l].filter(e=>e.length>0).join(`
66
66
  `),v=r.filter(e=>!a||s.has(e.filePath)).map(e=>{if(e.lifecycle||Object.keys(e.args).length===0)return;const m=B(e.args);return m===void 0?void 0:`installCompiledValidatorMap(${i.get(e.filePath)??""}.${e.exportName}.args, ${m});`}).filter(e=>e!==void 0).join(`
67
67
  `),O=r.filter(e=>e.channel?.kind==="room").map(e=>` ${JSON.stringify(e.channel?.name??"")}: RoomMessageOf<typeof ${i.get(e.filePath)??""}[${JSON.stringify(e.exportName)}]>;`).join(`
68
- `),N=[...r.map(e=>({args:e.args,definition:e,path:`${f(e.filePath)}:${e.exportName}`})),...n.map(e=>({args:e.args,definition:{...e,expose:void 0,kind:"mutation",lifecycle:void 0,visibility:void 0,x402:void 0},path:`${f(e.filePath)}:${e.exportName}`}))],x=a?N.filter(({definition:e})=>!s.has(e.filePath)):[];for(const{definition:e}of N)if(a&&e.x402&&e.x402.price===void 0)throw new P("INTERNAL",`@lunora/codegen: lazy function registry needs a literal \`.x402({ price })\` value in ${e.filePath}:${e.exportName}`);const b=a?x.map(({definition:e,path:m})=>{const R=i.get(e.filePath)??"",S="channel"in e?e.channel:void 0,A={argumentDescriptors:JSON.parse(I(e.args)),exportName:e.exportName,kind:e.kind,moduleId:R,...S?{channel:S}:{},...e.expose?{expose:e.expose}:{},...e.lifecycle?{lifecycle:e.lifecycle}:{},...e.visibility?{visibility:e.visibility}:{},...e.x402?.price===void 0?{}:{x402:{price:e.x402.price}}};return` ${JSON.stringify(m)}: ${JSON.stringify(A)},`}).join(`
69
- `):"",h=[...new Set(x.map(({definition:e})=>e.filePath))],w=a?h.map(e=>{if(!M.test(e))throw new P("INTERNAL",`@lunora/codegen: refusing to emit import for unsafe file path: ${JSON.stringify(e)}`);const m=i.get(e)??"";return` ${JSON.stringify(m)}: () => import(${JSON.stringify(`./fn/${m}.js`)}),`}).join(`
68
+ `),b=[...r.map(e=>({args:e.args,definition:e,path:`${f(e.filePath)}:${e.exportName}`})),...n.map(e=>({args:e.args,definition:{...e,expose:void 0,kind:"mutation",lifecycle:void 0,visibility:void 0,x402:void 0},path:`${f(e.filePath)}:${e.exportName}`}))],x=a?b.filter(({definition:e})=>!s.has(e.filePath)):[];for(const{definition:e}of b)if(a&&e.x402&&e.x402.price===void 0)throw new P("INTERNAL",`@lunora/codegen: lazy function registry needs a literal \`.x402({ price })\` value in ${e.filePath}:${e.exportName}`);const N=a?x.map(({definition:e,path:m})=>{const R=i.get(e.filePath)??"",S="channel"in e?e.channel:void 0,A={argumentDescriptors:JSON.parse(I(e.args)),exportName:e.exportName,kind:e.kind,moduleId:R,...S?{channel:S}:{},...e.expose?{expose:e.expose}:{},...e.lifecycle?{lifecycle:e.lifecycle}:{},...e.visibility?{visibility:e.visibility}:{},...e.x402?.price===void 0?{}:{x402:{price:e.x402.price}}};return` ${JSON.stringify(m)}: ${JSON.stringify(A)},`}).join(`
69
+ `):"",h=[...new Set(x.map(({definition:e})=>e.filePath))],w=a?h.map(e=>{if(!F.test(e))throw new P("INTERNAL",`@lunora/codegen: refusing to emit import for unsafe file path: ${JSON.stringify(e)}`);const m=i.get(e)??"";return` ${JSON.stringify(m)}: () => import(${JSON.stringify(`./fn/${m}.js`)}),`}).join(`
70
70
  `):"";return{dispatchBody:$.length>0?`
71
71
  ${$}
72
72
  `:"",importBlock:d.length>0?`${d}
73
73
 
74
- `:"",installBlock:v,manifestBody:b.length>0?`
75
- ${b}
74
+ `:"",installBlock:v,manifestBody:N.length>0?`
75
+ ${N}
76
76
  `:"",migrationBody:c.length>0?`
77
77
  ${c}
78
78
  `:"",moduleLoaders:w.length>0?`
79
79
  ${w}
80
80
  `:"",mutatorPaths:y,roomMessagesBody:O,shapeBody:g.length>0?`
81
81
  ${g}
82
- `:""}},ke=r=>{const t=F(r,o=>{const a=_(se(o.args),o.filePath),i=a==="{}"?"?":"",s=_(ue(o),o.filePath);return o.kind==="stream"?`${o.exportName}: (args${i}: ${a}) => Promise<AsyncIterable<${s}>>;`:`${o.exportName}: (args${i}: ${a}) => Promise<${s}>;`},"type");return{implementation:F(r,o=>`${ae(o.exportName)}: (args) => callRegistered(context, "${f(o.filePath)}:${o.exportName}", args),`,"value"),types:t}},ve=r=>{const t={connect:[],disconnect:[],init:[],reactor:[],whisper:[]};for(const n of r)n.lifecycle&&t[n.lifecycle].push(`${f(n.filePath)}:${n.exportName}`);return t},Oe=(r,t,n)=>r?{channelField:` /**
82
+ `:""}},ke=r=>{const t=M(r,o=>{const a=_(se(o.args),o.filePath),i=a==="{}"?"?":"",s=_(ue(o),o.filePath);return o.kind==="stream"?`${o.exportName}: (args${i}: ${a}) => Promise<AsyncIterable<${s}>>;`:`${o.exportName}: (args${i}: ${a}) => Promise<${s}>;`},"type");return{implementation:M(r,o=>`${ae(o.exportName)}: (args) => callRegistered(context, "${f(o.filePath)}:${o.exportName}", args),`,"value"),types:t}},ve=r=>{const t={connect:[],disconnect:[],init:[],reactor:[],whisper:[]};for(const n of r)n.lifecycle&&t[n.lifecycle].push(`${f(n.filePath)}:${n.exportName}`);return t},Oe=(r,t,n)=>r?{channelField:` /**
83
83
  * Set on a \`defineRoom\` registration: the room's name (without the \`room:\`
84
84
  * topic prefix). The generated \`LUNORA_ROOMS\` map keys it on the room's
85
85
  * \`room:<name>\` whisper topic so the ShardDO resolves a room topic to this
@@ -159,9 +159,9 @@ ${n.types}
159
159
  `:"",a=n.implementation?`
160
160
  ${n.implementation}
161
161
  `:"",i=de(n.types),s=i.length>0?`import type { ${i.join(", ")} } from "./dataModel.js";
162
- `:"",d=r.length>0?"context":"_context";let u="";if(r.length>0){let c=Ne;t||(c=c.replace("await loadFunction(functionPath)",k("LUNORA_FUNCTIONS"))),u=`${c}
162
+ `:"",d=r.length>0?"context":"_context";let u="";if(r.length>0){let c=be;t||(c=c.replace("await loadFunction(functionPath)",k("LUNORA_FUNCTIONS"))),u=`${c}
163
163
 
164
- `}return{callRegisteredHelper:u,dataModelImport:s,implementation:a,parameter:d,types:o}},Ee=r=>{const{agents:t=[],functions:n,lazyFunctions:o=!1,migrations:a=[],mutators:i=[],shapes:s=[],useUmbrella:d=!1,usesSandbox:u=!1}=r,c=j(d),{dispatchBody:l,importBlock:g,installBlock:y,manifestBody:$,migrationBody:v,moduleLoaders:O,mutatorPaths:N,roomMessagesBody:x,shapeBody:b}=be(n,a,i,s,o),h=ie(t,n),w=ce(u,n),e=[h.lines,w.lines].filter(p=>p.length>0).join(`
164
+ `}return{callRegisteredHelper:u,dataModelImport:s,implementation:a,parameter:d,types:o}},Ee=r=>{const{agents:t=[],functions:n,lazyFunctions:o=!1,migrations:a=[],mutators:i=[],shapes:s=[],useUmbrella:d=!1,usesSandbox:u=!1}=r,c=j(d),{dispatchBody:l,importBlock:g,installBlock:y,manifestBody:$,migrationBody:v,moduleLoaders:O,mutatorPaths:b,roomMessagesBody:x,shapeBody:N}=Ne(n,a,i,s,o),h=ie(t,n),w=ce(u,n),e=[h.lines,w.lines].filter(p=>p.length>0).join(`
165
165
  `);let m=l;e.length>0&&(m=l.length>0?`${l.trimEnd()}
166
166
  ${e}
167
167
  `:`
@@ -170,31 +170,31 @@ ${e}
170
170
  throw new LunoraError("FUNCTION_NOT_FOUND", \`function not registered: \${functionPath}\`);
171
171
  }
172
172
 
173
- `:"",Q=s.length>0?`import type { RegisteredShape } from "${c.server}";
174
- `:"",E=n.some(p=>p.channel?.kind==="room"),L=Oe(E,c.server,x),G=s.length>0?`
173
+ `:"",z=s.length>0?`import type { RegisteredShape } from "${c.server}";
174
+ `:"",E=n.some(p=>p.channel?.kind==="room"),L=Oe(E,c.server,x),Q=s.length>0?`
175
175
  /**
176
176
  * Replication-shape registry — one entry per \`defineShape\` in \`lunora/shapes.ts\`.
177
177
  * The generated ShardDO's \`resolveShape\` override looks a shape up by name and
178
178
  * evaluates its trusted \`compileWhere(ctx, args)\` to authorize + scope a
179
179
  * \`shape_subscribe\` (reads-as-permissions).
180
180
  */
181
- export const LUNORA_SHAPES: Record<string, RegisteredShape> = {${b}};
182
- `:"",V=N.length>0?`
181
+ export const LUNORA_SHAPES: Record<string, RegisteredShape> = {${N}};
182
+ `:"",G=b.length>0?`
183
183
  /**
184
184
  * Custom-mutator function paths — the \`LUNORA_FUNCTIONS\` keys the generated
185
185
  * ShardDO's \`isCustomMutator\` override routes through the client-watermark push
186
186
  * protocol (\`x-lunora-client-id\`/\`x-lunora-client-seq\` ordering).
187
187
  */
188
- export const LUNORA_MUTATOR_PATHS: ReadonlySet<string> = new Set([${N.map(p=>JSON.stringify(p)).join(", ")}]);
189
- `:"",z=xe(E,o,n),W=y.length>0?`import { DEFER_VALIDATION as DEFER, installCompiledValidatorMap } from "${c.values}";
190
- `:"",K=y.length>0?`
188
+ export const LUNORA_MUTATOR_PATHS: ReadonlySet<string> = new Set([${b.map(p=>JSON.stringify(p)).join(", ")}]);
189
+ `:"",V=xe(E,o,n),W=y.length>0?`import { DEFER_VALIDATION as DEFER, installCompiledValidatorMap } from "${c.values}";
190
+ `:"",Y=y.length>0?`
191
191
  /**
192
192
  * AOT-compiled argument validators (Worker-safe, no \`eval\`). Each is installed
193
193
  * onto its function's live \`.args\` object and consulted by the interpreted
194
194
  * parser as a zero-allocation fast path; anything it can't model is deferred.
195
195
  */
196
196
  ${y}
197
- `:"",Y=Se(n,o),{callRegisteredHelper:X,dataModelImport:Z,implementation:ee,parameter:te,types:re}=Y,ne=o?`
197
+ `:"",K=Se(n,o),{callRegisteredHelper:Z,dataModelImport:X,implementation:ee,parameter:te,types:re}=K,ne=o?`
198
198
  export interface FunctionManifestEntry {
199
199
  argumentDescriptors: ReadonlyArray<{ element?: string; kind: string; name: string; optional: boolean; table?: string }>;
200
200
  channel?: { kind: "room"; name: string };
@@ -213,6 +213,7 @@ export const LUNORA_FUNCTION_MANIFEST: Readonly<Record<string, FunctionManifestE
213
213
  const MODULE_LOADERS: Record<string, () => Promise<Record<string, unknown>>> = {${O}};
214
214
  const loadedModules = new Map<string, Promise<Record<string, unknown>>>();
215
215
  const resolvedModules = new Map<string, Record<string, unknown>>();
216
+ const boundFunctions = new Set<string>();
216
217
  const unloadedFunctionHandler = (): never => {
217
218
  throw new Error("a lazy function was invoked before it was prepared");
218
219
  };
@@ -226,6 +227,10 @@ export const getLoadedFunction = (functionPath: string): RegisteredLunoraFunctio
226
227
  return registered;
227
228
  }
228
229
 
230
+ if (boundFunctions.has(functionPath)) {
231
+ return registered;
232
+ }
233
+
229
234
  const module = resolvedModules.get(manifest.moduleId);
230
235
 
231
236
  if (module === undefined) {
@@ -239,6 +244,7 @@ export const getLoadedFunction = (functionPath: string): RegisteredLunoraFunctio
239
244
  }
240
245
 
241
246
  Object.assign(registered, loaded);
247
+ boundFunctions.add(functionPath);
242
248
 
243
249
  return registered;
244
250
  };
@@ -265,25 +271,16 @@ export const loadFunction = async (functionPath: string): Promise<RegisteredLuno
265
271
  loadedModules.set(manifest.moduleId, pending);
266
272
  }
267
273
 
268
- let module: Record<string, unknown>;
269
-
270
- try {
271
- module = await pending;
272
- } catch (error: unknown) {
273
- if (loadedModules.get(manifest.moduleId) === pending) {
274
- loadedModules.delete(manifest.moduleId);
275
- }
276
-
277
- throw error;
278
- }
279
-
280
- resolvedModules.set(manifest.moduleId, module);
274
+ // A module that failed to evaluate stays failed for the isolate: the runtime has already cached
275
+ // the failed evaluation, and a bundler's lazy initializer can hand a retry a half-initialized
276
+ // namespace, so every later call rethrows the original error instead.
277
+ resolvedModules.set(manifest.moduleId, await pending);
281
278
 
282
279
  return getLoadedFunction(functionPath);
283
280
  };
284
- `:"";return le(`${C}${g}${h.importLine}${w.importLine}${W}${Q}${L.typeImport}import { LunoraError } from "${c.server}";
281
+ `:"";return le(`${C}${g}${h.importLine}${w.importLine}${W}${z}${L.typeImport}import { LunoraError } from "${c.server}";
285
282
  import type { ActionCtx, MutationCtx, QueryCtx } from "./server.js";
286
- ${Z}
283
+ ${X}
287
284
  /**
288
285
  * Single registered function, narrowed to the shape \`handleRpc\` needs.
289
286
  * The real argument validators / return types are checked elsewhere — at
@@ -335,7 +332,7 @@ ${h.prelude}${w.prelude}${ne}
335
332
  * emits (\`api[namespace][fn].__lunoraRef === "namespace:fn"\`).
336
333
  */
337
334
  export const LUNORA_FUNCTIONS: Record<string, RegisteredLunoraFunction> = {${m}};
338
- ${K}${G}${V}${z}${L.messagesBlock}
335
+ ${Y}${Q}${G}${V}${L.messagesBlock}
339
336
  /**
340
337
  * Lifecycle manifest: the function paths the generated ShardDO dispatches when a
341
338
  * client's WebSocket connects (\`connect\`) or disconnects (\`disconnect\`), once
@@ -390,7 +387,7 @@ export type CallerCtx = ActionCtx | MutationCtx | QueryCtx;
390
387
  */
391
388
  export interface Caller {${re}}
392
389
 
393
- ${X}/** Build a {@link Caller} bound to \`context\` (typically a handler's \`ctx\`). */
390
+ ${Z}/** Build a {@link Caller} bound to \`context\` (typically a handler's \`ctx\`). */
394
391
  export const createCaller = (${te}: CallerCtx): Caller => ({${ee}});
395
392
 
396
393
  /**
@@ -411,12 +408,12 @@ export interface RegisteredDataMigration {
411
408
  * shard DO's admin RPC and the CLI resolve migrations to run through this map.
412
409
  */
413
410
  export const LUNORA_MIGRATIONS: Record<string, RegisteredDataMigration> = {${v}};
414
- `,d)},Fe=r=>{if(r.lazyFunctions!==!0)return{};const{functions:t}=r,n=r.migrations??[],o=r.mutators??[],a=r.shapes??[],i=H(t,n,o,a),s=q(n,o,a),d=[...new Set(t.filter(l=>!s.has(l.filePath)).map(l=>l.filePath))],u=j(r.useUmbrella??!1),c={};for(const l of d){if(!M.test(l))throw new P("INTERNAL",`@lunora/codegen: refusing to emit import for unsafe file path: ${JSON.stringify(l)}`);const g=i.get(l)??"",y=`../../${l}.js`,$=t.filter(h=>h.filePath===l&&!h.lifecycle&&Object.keys(h.args).length>0).flatMap(h=>{const w=B(h.args);return w===void 0?[]:[`installCompiledValidatorMap(${g}.${h.exportName}.args, ${w});`]}),v=$.length>0?`import { DEFER_VALIDATION as DEFER, installCompiledValidatorMap } from "${u.values}";
411
+ `,d)},Me="fn",_e=r=>{if(r.lazyFunctions!==!0)return{};const{functions:t}=r,n=r.migrations??[],o=r.mutators??[],a=r.shapes??[],i=H(t,n,o,a),s=q(n,o,a),d=[...new Set(t.filter(l=>!s.has(l.filePath)).map(l=>l.filePath))],u=j(r.useUmbrella??!1),c={};for(const l of d){if(!F.test(l))throw new P("INTERNAL",`@lunora/codegen: refusing to emit import for unsafe file path: ${JSON.stringify(l)}`);const g=i.get(l)??"",y=`../../${l}.js`,$=t.filter(h=>h.filePath===l&&!h.lifecycle&&Object.keys(h.args).length>0).flatMap(h=>{const w=B(h.args);return w===void 0?[]:[`installCompiledValidatorMap(${g}.${h.exportName}.args, ${w});`]}),v=$.length>0?`import { DEFER_VALIDATION as DEFER, installCompiledValidatorMap } from "${u.values}";
415
412
  `:"",O=$.length>0?`import * as ${g} from "${y}";
416
- `:"",N=$.length>0?`
413
+ `:"",b=$.length>0?`
417
414
  /** Install the precompiled argument parsers before the module is dispatched. */
418
415
  ${$.join(`
419
416
  `)}
420
- `:"",b=t.some(h=>h.filePath===l&&h.exportName==="default")||n.some(h=>h.filePath===l&&h.exportName==="default")?`export { default } from "${y}";
421
- `:"";c[`fn/${g}.ts`]=`${C}${v}${O}${N}export * from "${y}";
422
- ${b}`}return c};export{Ee as emitFunctions,Fe as emitLazyFunctionModules};
417
+ `:"",N=t.some(h=>h.filePath===l&&h.exportName==="default")||n.some(h=>h.filePath===l&&h.exportName==="default")?`export { default } from "${y}";
418
+ `:"";c[`${g}.ts`]=`${C}${v}${O}${b}export * from "${y}";
419
+ ${N}`}return c};export{Me as LAZY_FUNCTION_DIRECTORY,Ee as emitFunctions,_e as emitLazyFunctionModules};
@@ -1 +1 @@
1
- import"./SCHEMA_SNAPSHOT_VERSION-C0oHwiJZ.mjs";import"./isD1GlobalTable-udvHAAzD.mjs";import"./json-data-Chfs2Cz5.mjs";import{e as d}from"./shard-CsOnD3Na.mjs";import"./shard-runtime-BpoCV-aM.mjs";import"./shared-DnCokNcE.mjs";import"./platform-8oj7iXQy.mjs";import"./schema-BgM8A3XV.mjs";export{d as default};
1
+ import"./SCHEMA_SNAPSHOT_VERSION-C0oHwiJZ.mjs";import"./isD1GlobalTable-udvHAAzD.mjs";import"./json-data-Chfs2Cz5.mjs";import{e as d}from"./shard-ceGu_Fps.mjs";import"./shard-runtime-BpoCV-aM.mjs";import"./shared-DnCokNcE.mjs";import"./platform-8oj7iXQy.mjs";import"./schema-BgM8A3XV.mjs";export{d as default};