@lunora/vite 1.0.0-alpha.385 → 1.0.0-alpha.387

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.
package/dist/index.d.mts CHANGED
@@ -1,7 +1,7 @@
1
1
  import { CodegenOptions } from '@lunora/codegen';
2
2
  import errorOverlayPlugin from '@visulima/vite-overlay';
3
3
  import { Plugin } from 'vite';
4
- import { FrameworkDetection, DetectedFramework, GeneratedClassModule, readProjectRemotePreference } from '@lunora/config';
4
+ import { DiscoveryCache, FrameworkDetection, DetectedFramework, GeneratedClassModule, readProjectRemotePreference } from '@lunora/config';
5
5
  export { type DetectedFramework, type FrameworkClass, type FrameworkDetection, GENERATED_CLASS_MODULES, type GeneratedClassModule, detectFramework } from '@lunora/config';
6
6
  import { materializeDevWranglerConfig, WithheldBinding } from '@lunora/config/cloudflare';
7
7
  export { type ReconcileCronsResult as ReconcileResult, reconcileWranglerCrons } from '@lunora/config/cloudflare';
@@ -146,8 +146,12 @@ type LunoraPlugins = Plugin[];
146
146
  /**
147
147
  * Vite plugin that runs `@lunora/codegen` on startup and on file changes
148
148
  * inside the lunora schema directory.
149
+ *
150
+ * `discovery` is the startup's shared source-scan memo (see
151
+ * `bindingsProvisionPlugin`); `buildStart`'s binding reconcile reads it and then
152
+ * ends it, so nothing after startup sees a scan from before an edit.
149
153
  */
150
- declare const codegenPlugin: (options: ResolvedLunoraPluginOptions) => Plugin;
154
+ declare const codegenPlugin: (options: ResolvedLunoraPluginOptions, discovery?: DiscoveryCache) => Plugin;
151
155
  /**
152
156
  * Dev-only plugin that tails the local dev containers' own stdout/stderr in the
153
157
  * Vite terminal.
@@ -163,8 +167,11 @@ declare const codegenPlugin: (options: ResolvedLunoraPluginOptions) => Plugin;
163
167
  * returns an empty list, so `dockerode` is never imported and no Docker work
164
168
  * starts. Set `LUNORA_CONTAINER_LOGS=0` to opt out. A missing/stopped Docker
165
169
  * engine degrades to a single warning rather than breaking dev.
170
+ *
171
+ * `discovery` is the startup's shared source-scan memo, so the container
172
+ * discovery binding inference already ran is not parsed again here.
166
173
  */
167
- declare const containerLogsPlugin: (options: ResolvedLunoraPluginOptions) => Plugin;
174
+ declare const containerLogsPlugin: (options: ResolvedLunoraPluginOptions, discovery?: DiscoveryCache) => Plugin;
168
175
  /** Vite plugin (serve-only) that writes the dev-server state record on listen and clears it on close. */
169
176
  declare const devStatePlugin: (options: ResolvedLunoraPluginOptions) => Plugin;
170
177
  /**
@@ -539,7 +546,7 @@ declare const withWorkerStartupHint: (plugins: ReadonlyArray<Plugin>) => Plugin[
539
546
  * Skipped under `vite preview`, which resolves with `command: "serve"` and so
540
547
  * runs `apply: "serve"` plugins: previewing a built app must not probe Docker.
541
548
  */
542
- declare const wranglerValidatorPlugin: (options: ResolvedLunoraPluginOptions) => Plugin;
549
+ declare const wranglerValidatorPlugin: (options: ResolvedLunoraPluginOptions, discovery?: DiscoveryCache) => Plugin;
543
550
  /**
544
551
  * Resolve the `overlay` toggle into the overlay plugin's options — or `false` to
545
552
  * skip it. Lunora's solution finders are **prepended** so they run before the
package/dist/index.d.ts CHANGED
@@ -1,7 +1,7 @@
1
1
  import { CodegenOptions } from '@lunora/codegen';
2
2
  import errorOverlayPlugin from '@visulima/vite-overlay';
3
3
  import { Plugin } from 'vite';
4
- import { FrameworkDetection, DetectedFramework, GeneratedClassModule, readProjectRemotePreference } from '@lunora/config';
4
+ import { DiscoveryCache, FrameworkDetection, DetectedFramework, GeneratedClassModule, readProjectRemotePreference } from '@lunora/config';
5
5
  export { type DetectedFramework, type FrameworkClass, type FrameworkDetection, GENERATED_CLASS_MODULES, type GeneratedClassModule, detectFramework } from '@lunora/config';
6
6
  import { materializeDevWranglerConfig, WithheldBinding } from '@lunora/config/cloudflare';
7
7
  export { type ReconcileCronsResult as ReconcileResult, reconcileWranglerCrons } from '@lunora/config/cloudflare';
@@ -146,8 +146,12 @@ type LunoraPlugins = Plugin[];
146
146
  /**
147
147
  * Vite plugin that runs `@lunora/codegen` on startup and on file changes
148
148
  * inside the lunora schema directory.
149
+ *
150
+ * `discovery` is the startup's shared source-scan memo (see
151
+ * `bindingsProvisionPlugin`); `buildStart`'s binding reconcile reads it and then
152
+ * ends it, so nothing after startup sees a scan from before an edit.
149
153
  */
150
- declare const codegenPlugin: (options: ResolvedLunoraPluginOptions) => Plugin;
154
+ declare const codegenPlugin: (options: ResolvedLunoraPluginOptions, discovery?: DiscoveryCache) => Plugin;
151
155
  /**
152
156
  * Dev-only plugin that tails the local dev containers' own stdout/stderr in the
153
157
  * Vite terminal.
@@ -163,8 +167,11 @@ declare const codegenPlugin: (options: ResolvedLunoraPluginOptions) => Plugin;
163
167
  * returns an empty list, so `dockerode` is never imported and no Docker work
164
168
  * starts. Set `LUNORA_CONTAINER_LOGS=0` to opt out. A missing/stopped Docker
165
169
  * engine degrades to a single warning rather than breaking dev.
170
+ *
171
+ * `discovery` is the startup's shared source-scan memo, so the container
172
+ * discovery binding inference already ran is not parsed again here.
166
173
  */
167
- declare const containerLogsPlugin: (options: ResolvedLunoraPluginOptions) => Plugin;
174
+ declare const containerLogsPlugin: (options: ResolvedLunoraPluginOptions, discovery?: DiscoveryCache) => Plugin;
168
175
  /** Vite plugin (serve-only) that writes the dev-server state record on listen and clears it on close. */
169
176
  declare const devStatePlugin: (options: ResolvedLunoraPluginOptions) => Plugin;
170
177
  /**
@@ -539,7 +546,7 @@ declare const withWorkerStartupHint: (plugins: ReadonlyArray<Plugin>) => Plugin[
539
546
  * Skipped under `vite preview`, which resolves with `command: "serve"` and so
540
547
  * runs `apply: "serve"` plugins: previewing a built app must not probe Docker.
541
548
  */
542
- declare const wranglerValidatorPlugin: (options: ResolvedLunoraPluginOptions) => Plugin;
549
+ declare const wranglerValidatorPlugin: (options: ResolvedLunoraPluginOptions, discovery?: DiscoveryCache) => Plugin;
543
550
  /**
544
551
  * Resolve the `overlay` toggle into the overlay plugin's options — or `false` to
545
552
  * skip it. Lunora's solution finders are **prepended** so they run before the
package/dist/index.mjs CHANGED
@@ -1,4 +1,4 @@
1
- import{createRequire as $}from"node:module";import{sep as O,resolve as h,dirname as B,isAbsolute as I,relative as M}from"node:path";import{cloudflare as N}from"@cloudflare/vite-plugin";import{BUNDLE_META_PATH_ENV as U,canonicalPath as k,DEFAULT_BUNDLE_META_PATH as F,resolveDeployDriver as H,startCelldDevSession as j,formatLunoraEvent as V,lunoraLine as G,detectFramework as z,targetRunsOwnDevServer as K,resolveLazyFunctions as q,resolveTargetOrThrow as J,isRunnableTarget as Q,runnableTargetIds as Y,assertBuildTargetMatches as X}from"@lunora/config";import{GENERATED_CLASS_MODULES as Er,detectFramework as Tr}from"@lunora/config";import Z from"@visulima/vite-overlay";import{detectAgentRules as ee,claimAgentRulesHint as re,lunoraLine as m,AGENT_RULES_HINT as te}from"@lunora/config/cli";import{reconcileBindingsSafely as oe,findWranglerFile as ne,readWranglerJsonc as ie,warnCloudflareCliConfigOnce as se,hasCloudflareCredentials as ae,withheldBindings as le,describeWithheld as ce,startLocalHyperdrive as ue}from"@lunora/config/cloudflare";import{reconcileWranglerCrons as Cr}from"@lunora/config/cloudflare";import{mkdirSync as de,writeFileSync as fe,statSync as pe,rmSync as me}from"node:fs";import{r as L,a as D}from"./packem_shared/server-close-DWiO4Vxb.mjs";import ge from"./packem_shared/codegenPlugin-C1aM7GMx.mjs";import ve from"./packem_shared/containerLogsPlugin-BCqWF6EU.mjs";import he from"./packem_shared/devStatePlugin-CF4GDvBn.mjs";import we from"./packem_shared/devVariablesPlugin-DbD6cSF0.mjs";import{frameworkComposePlugin as ye}from"./packem_shared/CLASS_A_WIRING-qeJbUuf3.mjs";import{CLASS_A_WIRING as Or,LUNORA_WORKER_VIRTUAL_ID as Lr,buildWorkerEntrySource as Dr,isAutoComposable as Wr}from"./packem_shared/CLASS_A_WIRING-qeJbUuf3.mjs";import Se from"./packem_shared/logStreamPlugin-EMXiy6pI.mjs";import{proxyCheckPlugin as Pe}from"./packem_shared/checkLunoraProxy-BNPgNWtV.mjs";import{checkLunoraProxy as Br}from"./packem_shared/checkLunoraProxy-BNPgNWtV.mjs";import{remoteBindingsPlugin as be}from"./packem_shared/planViteRemoteBindings-DYUUW67d.mjs";import{planViteRemoteBindings as Mr,withRemoteBindings as Nr}from"./packem_shared/planViteRemoteBindings-DYUUW67d.mjs";import{readServiceBindings as ke}from"@lunora/codegen";import{lunoraSolutionFinders as Ae}from"./packem_shared/lunoraSolutionFinder--J0x2mAM.mjs";import{lunoraSolutionFinder as Fr}from"./packem_shared/lunoraSolutionFinder--J0x2mAM.mjs";import{studioPlugin as Re}from"./packem_shared/buildStudioUrl-B9K0wAjC.mjs";import{buildStudioUrl as jr}from"./packem_shared/buildStudioUrl-B9K0wAjC.mjs";import{withWorkerStartupHint as Ee}from"./packem_shared/WORKER_STARTUP_HINT-COlRTY32.mjs";import{WORKER_STARTUP_HINT as Gr,augmentWorkerStartupError as zr,isWorkerEntryEvalError as Kr}from"./packem_shared/WORKER_STARTUP_HINT-COlRTY32.mjs";import{wranglerValidatorPlugin as Te}from"./packem_shared/wranglerValidatorPlugin-BlGHjTXZ.mjs";import{default as Jr}from"./packem_shared/LUNORA_API_UPDATED_EVENT-CO2Rv2re.mjs";import{STUDIO_PATH as Yr}from"@lunora/config/studio-host";const _e=r=>({apply:"serve",configureServer(e){return()=>{ee(r.projectRoot).installed||!re()||e.config.logger.warn(`
2
- ${m(te)}
3
- `)}},name:"lunora:agent-rules-hint"}),Ce=r=>({async config(e,t){t.isPreview!==!0&&await oe(r,{info:o=>{console.info(o)},warn:o=>{console.warn(o)}})},enforce:"pre",name:"lunora:bindings-provision"}),xe=(r,e=O)=>r.split(e).join("/"),b=(r,e)=>I(e)?xe(M(r,e)):e,w=(r,e,t)=>e.map(o=>({kind:t,path:b(r,o)})),Oe=/[?#]/,A=r=>{try{return pe(r).size}catch{return}},Le=(r,e)=>A(r)??A(r.split(Oe)[0]??r)??Buffer.byteLength(e??""),De=r=>{let e;return{apply:"build",applyToEnvironment:t=>t.config.consumer==="server",name:"lunora:bundle-meta",sharedDuringBuild:!0,generateBundle(t,o){const n={},i={};for(const[u,d]of Object.entries(o)){if(d.type!=="chunk")continue;const f={bytes:Buffer.byteLength(d.code),imports:[...w(r,d.imports,"import-statement"),...w(r,d.dynamicImports,"dynamic-import")],inputs:{}};d.facadeModuleId&&(f.entryPoint=b(r,d.facadeModuleId));for(const[g,y]of Object.entries(d.modules)){const p=b(r,g);if(f.inputs[p]={bytesInOutput:Buffer.byteLength(y.code??"")},!n[p]){const S=this.getModuleInfo(g);n[p]={bytes:Le(g,S?.code),imports:[...w(r,S?.importedIds??[],"import-statement"),...w(r,S?.dynamicallyImportedIds??[],"dynamic-import")]}}}i[u]=f}const a=process.env[U],s=a===void 0||a===""?void 0:h(r,a),l=`${k(h(r,".lunora"))}${O}`,c=s!==void 0&&k(s).startsWith(l)?s:h(r,F);if(e!==void 0&&e!==this.environment.name){me(c,{force:!0}),this.warn(`bundle-meta: environment "${this.environment.name}" built a server bundle after "${e}" wrote one; no bundle-meta.json is written, because the app's own graph cannot be told apart from a service's`);return}e=this.environment.name,de(B(c),{recursive:!0}),fe(c,`${JSON.stringify({inputs:n,outputs:i},void 0,2)}
4
- `,"utf8")}}},R="/_lunora",We=8787,v=new Map,W=r=>r.command==="serve"&&r.isPreview!==!0,$e=(r,e)=>{let t;return()=>{if(t===void 0)try{H(e).projectConfig?.(r,"dev"),t={runs:!0}}catch(o){t={reason:o instanceof Error?o.message:String(o),runs:!1}}return t}},Be=r=>{const e=ne(r),t=e===void 0?void 0:ie(e).parsed?.dev?.port;return typeof t=="number"?t:We},Ie=(r,e)=>r.map(t=>{const o=t.apply;return{...t,apply:(n,i)=>W(i)&&e()?!1:typeof o=="function"?o(n,i):o===void 0||o===i.command}}),Me=(r,e,{stream:t,tag:o})=>{const n=V(e);n!==void 0?r[n.level](`[lunora] ${n.text}`):t==="stderr"?r.warn(`[${o}] ${e}`):r.info(`[${o}] ${e}`)},Ne=(r,e)=>{const t=Be(r),o=new Map;return{apply:(n,i)=>W(i)&&e(),buildEnd(){D(o,this.environment)},config:n=>{if(n.server?.proxy?.[R]===void 0)return{server:{proxy:{[R]:{changeOrigin:!0,target:`http://127.0.0.1:${String(t)}`,ws:!0}}}}},async configureServer(n){const{logger:i}=n.config;await v.get(r)?.stop(),v.delete(r),i.info(`[lunora] starting the worker on celld at http://127.0.0.1:${String(t)} …`);const a=await j({log:(l,c)=>{Me(i,l,c)},port:t,projectRoot:r});v.set(r,a);const s=l=>{i.error(`[lunora] the worker on celld exited (code ${String(l)}) — restart vite dev to bring it back`)};a.exited.then(s).catch(()=>{}),L(n,o,()=>{v.get(r)===a&&v.delete(r),a.stop().catch(l=>{i.error(`[lunora] stopping celld failed: ${l instanceof Error?l.message:String(l)}`)})})},name:"lunora:celld-dev"}},Ue=r=>({configResolved(e){se(r.projectRoot,t=>{e.logger.warn(G(t))})},name:"lunora:cf-config-warning"}),Fe=()=>({}),He={astro:"Astro",none:"standalone (SPA / SSR-less)",nuxt:"Nuxt","react-router":"React Router","solid-start":"SolidStart",sveltekit:"SvelteKit","tanstack-start":"TanStack Start","tanstack-start-solid":"TanStack Start (Solid)",vinext:"Next.js on Vite (vinext)"},je=r=>{const e=He[r.framework];return r.framework==="none"?m("no meta-framework detected — running standalone."):r.class==="B"?m(`detected ${e} — composition is handled by the framework adapter.`):m(`detected ${e} — composing the Lunora worker into one Cloudflare Worker.`)},Ve=(r,e)=>{let t=!1;const o=()=>{e.framework??=z(r.projectRoot)};return{config(){o()},configResolved(){o()},configureServer(){o(),!t&&e.framework!==void 0&&(t=!0,console.info(je(e.framework)))},name:"lunora:framework-detect"}},E=r=>Array.isArray(r)?r:[],P=new WeakSet,Ge=(r,e={})=>{let t=!1;const o=r.experimental?.newConfig,n=o!==void 0&&o!==!1,i=e.hasCredentials??(()=>ae({projectRoot:e.projectRoot})),a=s=>{const l=(c,...u)=>{const d=typeof s=="function"?s(c,...u):s,f=d===void 0?void 0:{...d},g=t?[...E(c.artifacts),...E(f?.artifacts)]:[],y=t?le({ai:c.ai??f?.ai,artifacts:g},i):[];for(const p of y)Reflect.deleteProperty(c,p.kind),Reflect.deleteProperty(f??{},p.kind),console.warn(m(ce(p)));return f};return P.add(l),l};return{config(s,l){if(t=l.command==="serve"&&l.isPreview!==!0,n)return;const c=r;P.has(c.config)||(c.config=a(c.config)),Array.isArray(c.auxiliaryWorkers)&&(c.auxiliaryWorkers=c.auxiliaryWorkers.map(u=>P.has(u.config)?u:{...u,config:a(u.config)}))},enforce:"pre",name:"lunora:local-ai-binding"}},ze=5e3,Ke=3e4,T=new Map,_=r=>{const e=T.get(r);if(e!==void 0)return e;const t={databases:[],pending:Promise.resolve(),servers:0,stopping:Promise.resolve()};return T.set(r,t),t},qe=async r=>{const e=r.databases.splice(0);await Promise.allSettled(e.map(async t=>t.stop()))},C=(r,e)=>{const t=setTimeout(()=>{r.pending.then(async()=>{r.servers===0&&(r.stopping=qe(r),await r.stopping)}).catch(()=>{})},e);return t.unref(),t},x=({projectRoot:r,start:e=ue,wranglerConfigPath:t})=>{const o=new Map,n=i=>{const a=_(r);let s=!1;a.servers+=1,clearTimeout(a.stopTimer),i(()=>{s||(s=!0,a.servers-=1,a.servers===0&&(a.stopTimer=C(a,ze)))})};return{async config(i,a){if(a.command!=="serve")return;const s=_(r);clearTimeout(s.stopTimer);const l=s.pending,c=(async()=>{await l,await s.stopping;const u=await e({onWarning:d=>{console.warn(m(d))},projectRoot:r,wranglerConfigPath:t});u!==void 0&&s.databases.push(u),u!==void 0&&u.bindings.length>0&&console.info(m(`Hyperdrive ${u.bindings.join(", ")}: embedded Postgres (PGlite), data in .wrangler/state/lunora-pglite.`))})();s.pending=c.catch(()=>{});try{await c}finally{s.servers===0&&(clearTimeout(s.stopTimer),s.stopTimer=C(s,Ke))}},buildEnd(){D(o,this.environment)},configureServer(i){n(a=>{L(i,o,a)})},configurePreviewServer(i){n(a=>{i.httpServer.once("close",a)})},enforce:"pre",name:"lunora:local-hyperdrive"}},Je=(r,e)=>({config(t,o){if(o.command!=="serve")return;const{services:n}=ke(e),i=Array.isArray(r.auxiliaryWorkers)?r.auxiliaryWorkers:[],a=new Set(i.map(l=>l.configPath===void 0?"":h(e,l.configPath))),s=[...new Set(n.map(l=>l.wranglerPath))].filter(l=>!a.has(l)).map(l=>({configPath:l}));s.length>0&&(r.auxiliaryWorkers=[...i,...s])},enforce:"pre",name:"lunora:service-workers"}),Qe=r=>{if(r===!1)return!1;const e=r===!0||r===void 0?{}:r;return{...e,forwardedConsoleMethods:e.forwardedConsoleMethods??["error","warn"],solutionFinders:[...Ae,...e.solutionFinders??[]]}},Ye=(r,e)=>{const t=J(r,e);if(!Q(t)){const o=Y();throw new Error(`target "${t}" has no command-line toolchain, so the Lunora Vite plugin cannot build or serve it — it can only generate for it (\`lunora codegen --target ${t}\`). Buildable targets: ${o.join(", ")}`)}return X(t,r),t},Xe=r=>{const e=r??{},t=e.schemaDir??"lunora";let o;e.cloudflare===!1?o=!1:e.cloudflare===!0||e.cloudflare===void 0?o={}:o=e.cloudflare;const n=e.projectRoot??process.cwd(),i=Ye(n,e.target);return{allowUnauthenticatedShardAccess:e.allowUnauthenticatedShardAccess??!1,apiSpec:e.apiSpec??"openapi",lazyFunctions:q(e.lazyFunctions),cloudflare:o,studio:e.studio??!0,generatedDir:`${t}/_generated`,overlay:Qe(e.overlay),projectRoot:n,schemaDir:t,shard:e.shard??{},target:i,validateWrangler:e.validateWrangler??!0}},Ze=(r,e)=>{const{configPath:t}=r;return typeof t=="string"&&t!==""?h(e,t):void 0},br=r=>{const e=Xe(r),t=Fe(),o=[Ve(e,t),ye(e,t),we(e),Ce(e),ge(e),De(e.projectRoot),Se(),he(e),_e(e),Ue(e),Pe()];e.studio&&o.push(Re(e)),e.validateWrangler&&o.push(Te(e)),e.overlay!==!1&&o.push(Z(e.overlay)),o.push(ve(e));const n=e.cloudflare===!1?void 0:{...e.cloudflare};if(o.push(be(n,{projectRoot:e.projectRoot})),n===void 0&&o.push(x({projectRoot:e.projectRoot})),n!==void 0){o.push(Je(n,e.projectRoot));const i=K(e.target),a=$e(e.projectRoot,e.target),s=()=>i&&a().runs;o.push(...Ie([x({projectRoot:e.projectRoot,wranglerConfigPath:Ze(n,e.projectRoot)}),Ge(n,{projectRoot:e.projectRoot}),...Ee(N(n))],s)),i&&o.push(Ne(e.projectRoot,s),{apply:(l,c)=>c.command==="serve"&&c.isPreview!==!0&&!s(),configureServer(l){l.config.logger.warn(`[lunora] target "${e.target}": vite dev serves the worker in workerd, not on ${e.target} — ${a().reason??"it cannot run this project"}. \`vite build\` then \`lunora deploy\` ships it to ${e.target}.`)},name:"lunora:target-runtime-notice"})}return o},kr=$(import.meta.url)("../package.json").version;export{Or as CLASS_A_WIRING,Er as GENERATED_CLASS_MODULES,Jr as LUNORA_API_UPDATED_EVENT,Lr as LUNORA_WORKER_VIRTUAL_ID,Yr as STUDIO_PATH,kr as VERSION,Gr as WORKER_STARTUP_HINT,zr as augmentWorkerStartupError,jr as buildStudioUrl,Dr as buildWorkerEntrySource,Br as checkLunoraProxy,ge as codegenPlugin,ve as containerLogsPlugin,Tr as detectFramework,he as devStatePlugin,we as devVariablesPlugin,ye as frameworkComposePlugin,Wr as isAutoComposable,Kr as isWorkerEntryEvalError,Se as logStreamPlugin,br as lunora,Fr as lunoraSolutionFinder,Ae as lunoraSolutionFinders,Mr as planViteRemoteBindings,Pe as proxyCheckPlugin,Cr as reconcileWranglerCrons,be as remoteBindingsPlugin,Qe as resolveOverlayOption,Re as studioPlugin,Nr as withRemoteBindings,Ee as withWorkerStartupHint,Te as wranglerValidatorPlugin};
1
+ import{createRequire as $}from"node:module";import{sep as O,resolve as h,dirname as B,isAbsolute as I,relative as M}from"node:path";import{cloudflare as N}from"@cloudflare/vite-plugin";import{BUNDLE_META_PATH_ENV as U,canonicalPath as k,DEFAULT_BUNDLE_META_PATH as F,resolveDeployDriver as H,startCelldDevSession as j,formatLunoraEvent as V,lunoraLine as G,detectFramework as z,createDiscoveryCache as K,targetRunsOwnDevServer as q,resolveLazyFunctions as J,resolveTargetOrThrow as Q,isRunnableTarget as Y,runnableTargetIds as X,assertBuildTargetMatches as Z}from"@lunora/config";import{GENERATED_CLASS_MODULES as Cr,detectFramework as xr}from"@lunora/config";import ee from"@visulima/vite-overlay";import{detectAgentRules as re,claimAgentRulesHint as te,lunoraLine as m,AGENT_RULES_HINT as oe}from"@lunora/config/cli";import{reconcileBindingsSafely as ne,findWranglerFile as ie,readWranglerJsonc as se,warnCloudflareCliConfigOnce as ae,hasCloudflareCredentials as ce,withheldBindings as le,describeWithheld as ue,startLocalHyperdrive as de}from"@lunora/config/cloudflare";import{reconcileWranglerCrons as Dr}from"@lunora/config/cloudflare";import{o as fe}from"./packem_shared/build-session-D75JzvIT.mjs";import{mkdirSync as pe,writeFileSync as me,statSync as ge,rmSync as ve}from"node:fs";import{r as D,a as L}from"./packem_shared/server-close-DWiO4Vxb.mjs";import he from"./packem_shared/codegenPlugin-D-Exl6Lf.mjs";import we from"./packem_shared/containerLogsPlugin-CWF3LHN3.mjs";import ye from"./packem_shared/devStatePlugin-CF4GDvBn.mjs";import Se from"./packem_shared/devVariablesPlugin-DbD6cSF0.mjs";import{frameworkComposePlugin as Pe}from"./packem_shared/CLASS_A_WIRING-j8JLPFDs.mjs";import{CLASS_A_WIRING as Wr,LUNORA_WORKER_VIRTUAL_ID as $r,buildWorkerEntrySource as Br,isAutoComposable as Ir}from"./packem_shared/CLASS_A_WIRING-j8JLPFDs.mjs";import be from"./packem_shared/logStreamPlugin-EMXiy6pI.mjs";import{proxyCheckPlugin as ke}from"./packem_shared/checkLunoraProxy-BNPgNWtV.mjs";import{checkLunoraProxy as Nr}from"./packem_shared/checkLunoraProxy-BNPgNWtV.mjs";import{remoteBindingsPlugin as Ae}from"./packem_shared/planViteRemoteBindings-DYUUW67d.mjs";import{planViteRemoteBindings as Fr,withRemoteBindings as Hr}from"./packem_shared/planViteRemoteBindings-DYUUW67d.mjs";import{readServiceBindings as Re}from"@lunora/codegen";import{lunoraSolutionFinders as Ee}from"./packem_shared/lunoraSolutionFinder--J0x2mAM.mjs";import{lunoraSolutionFinder as Vr}from"./packem_shared/lunoraSolutionFinder--J0x2mAM.mjs";import{studioPlugin as Te}from"./packem_shared/buildStudioUrl-B9K0wAjC.mjs";import{buildStudioUrl as zr}from"./packem_shared/buildStudioUrl-B9K0wAjC.mjs";import{withWorkerStartupHint as _e}from"./packem_shared/WORKER_STARTUP_HINT-COlRTY32.mjs";import{WORKER_STARTUP_HINT as qr,augmentWorkerStartupError as Jr,isWorkerEntryEvalError as Qr}from"./packem_shared/WORKER_STARTUP_HINT-COlRTY32.mjs";import{wranglerValidatorPlugin as Ce}from"./packem_shared/wranglerValidatorPlugin-CPPKubFC.mjs";import{default as Xr}from"./packem_shared/LUNORA_API_UPDATED_EVENT-CO2Rv2re.mjs";import{STUDIO_PATH as et}from"@lunora/config/studio-host";const xe=r=>({apply:"serve",configureServer(e){return()=>{re(r.projectRoot).installed||!te()||e.config.logger.warn(`
2
+ ${m(oe)}
3
+ `)}},name:"lunora:agent-rules-hint"}),Oe=(r,e)=>({async config(t,o){if(e?.clear(),o.isPreview===!0)return;const n=async()=>ne({...r,cache:e},{info:i=>{console.info(i)},warn:i=>{console.warn(i)}});await(o.command==="build"?fe(r,"provision",n):n())},enforce:"pre",name:"lunora:bindings-provision"}),De=(r,e=O)=>r.split(e).join("/"),b=(r,e)=>I(e)?De(M(r,e)):e,w=(r,e,t)=>e.map(o=>({kind:t,path:b(r,o)})),Le=/[?#]/,A=r=>{try{return ge(r).size}catch{return}},We=(r,e)=>A(r)??A(r.split(Le)[0]??r)??Buffer.byteLength(e??""),$e=r=>{let e;return{apply:"build",applyToEnvironment:t=>t.config.consumer==="server",name:"lunora:bundle-meta",sharedDuringBuild:!0,generateBundle(t,o){const n={},i={};for(const[u,d]of Object.entries(o)){if(d.type!=="chunk")continue;const f={bytes:Buffer.byteLength(d.code),imports:[...w(r,d.imports,"import-statement"),...w(r,d.dynamicImports,"dynamic-import")],inputs:{}};d.facadeModuleId&&(f.entryPoint=b(r,d.facadeModuleId));for(const[g,y]of Object.entries(d.modules)){const p=b(r,g);if(f.inputs[p]={bytesInOutput:Buffer.byteLength(y.code??"")},!n[p]){const S=this.getModuleInfo(g);n[p]={bytes:We(g,S?.code),imports:[...w(r,S?.importedIds??[],"import-statement"),...w(r,S?.dynamicallyImportedIds??[],"dynamic-import")]}}}i[u]=f}const a=process.env[U],c=a===void 0||a===""?void 0:h(r,a),s=`${k(h(r,".lunora"))}${O}`,l=c!==void 0&&k(c).startsWith(s)?c:h(r,F);if(e!==void 0&&e!==this.environment.name){ve(l,{force:!0}),this.warn(`bundle-meta: environment "${this.environment.name}" built a server bundle after "${e}" wrote one; no bundle-meta.json is written, because the app's own graph cannot be told apart from a service's`);return}e=this.environment.name,pe(B(l),{recursive:!0}),me(l,`${JSON.stringify({inputs:n,outputs:i},void 0,2)}
4
+ `,"utf8")}}},R="/_lunora",Be=8787,v=new Map,W=r=>r.command==="serve"&&r.isPreview!==!0,Ie=(r,e)=>{let t;return()=>{if(t===void 0)try{H(e).projectConfig?.(r,"dev"),t={runs:!0}}catch(o){t={reason:o instanceof Error?o.message:String(o),runs:!1}}return t}},Me=r=>{const e=ie(r),t=e===void 0?void 0:se(e).parsed?.dev?.port;return typeof t=="number"?t:Be},Ne=(r,e)=>r.map(t=>{const o=t.apply;return{...t,apply:(n,i)=>W(i)&&e()?!1:typeof o=="function"?o(n,i):o===void 0||o===i.command}}),Ue=(r,e,{stream:t,tag:o})=>{const n=V(e);n!==void 0?r[n.level](`[lunora] ${n.text}`):t==="stderr"?r.warn(`[${o}] ${e}`):r.info(`[${o}] ${e}`)},Fe=(r,e)=>{const t=Me(r),o=new Map;return{apply:(n,i)=>W(i)&&e(),buildEnd(){L(o,this.environment)},config:n=>{if(n.server?.proxy?.[R]===void 0)return{server:{proxy:{[R]:{changeOrigin:!0,target:`http://127.0.0.1:${String(t)}`,ws:!0}}}}},async configureServer(n){const{logger:i}=n.config;await v.get(r)?.stop(),v.delete(r),i.info(`[lunora] starting the worker on celld at http://127.0.0.1:${String(t)} …`);const a=await j({log:(s,l)=>{Ue(i,s,l)},port:t,projectRoot:r});v.set(r,a);const c=s=>{i.error(`[lunora] the worker on celld exited (code ${String(s)}) — restart vite dev to bring it back`)};a.exited.then(c).catch(()=>{}),D(n,o,()=>{v.get(r)===a&&v.delete(r),a.stop().catch(s=>{i.error(`[lunora] stopping celld failed: ${s instanceof Error?s.message:String(s)}`)})})},name:"lunora:celld-dev"}},He=r=>({configResolved(e){ae(r.projectRoot,t=>{e.logger.warn(G(t))})},name:"lunora:cf-config-warning"}),je=()=>({}),Ve={astro:"Astro",none:"standalone (SPA / SSR-less)",nuxt:"Nuxt","react-router":"React Router","solid-start":"SolidStart",sveltekit:"SvelteKit","tanstack-start":"TanStack Start","tanstack-start-solid":"TanStack Start (Solid)",vinext:"Next.js on Vite (vinext)"},Ge=r=>{const e=Ve[r.framework];return r.framework==="none"?m("no meta-framework detected — running standalone."):r.class==="B"?m(`detected ${e} — composition is handled by the framework adapter.`):m(`detected ${e} — composing the Lunora worker into one Cloudflare Worker.`)},ze=(r,e)=>{let t=!1;const o=()=>{e.framework??=z(r.projectRoot)};return{config(){o()},configResolved(){o()},configureServer(){o(),!t&&e.framework!==void 0&&(t=!0,console.info(Ge(e.framework)))},name:"lunora:framework-detect"}},E=r=>Array.isArray(r)?r:[],P=new WeakSet,Ke=(r,e={})=>{let t=!1;const o=r.experimental?.newConfig,n=o!==void 0&&o!==!1,i=e.hasCredentials??(()=>ce({projectRoot:e.projectRoot})),a=c=>{const s=(l,...u)=>{const d=typeof c=="function"?c(l,...u):c,f=d===void 0?void 0:{...d},g=t?[...E(l.artifacts),...E(f?.artifacts)]:[],y=t?le({ai:l.ai??f?.ai,artifacts:g},i):[];for(const p of y)Reflect.deleteProperty(l,p.kind),Reflect.deleteProperty(f??{},p.kind),console.warn(m(ue(p)));return f};return P.add(s),s};return{config(c,s){if(t=s.command==="serve"&&s.isPreview!==!0,n)return;const l=r;P.has(l.config)||(l.config=a(l.config)),Array.isArray(l.auxiliaryWorkers)&&(l.auxiliaryWorkers=l.auxiliaryWorkers.map(u=>P.has(u.config)?u:{...u,config:a(u.config)}))},enforce:"pre",name:"lunora:local-ai-binding"}},qe=5e3,Je=3e4,T=new Map,_=r=>{const e=T.get(r);if(e!==void 0)return e;const t={databases:[],pending:Promise.resolve(),servers:0,stopping:Promise.resolve()};return T.set(r,t),t},Qe=async r=>{const e=r.databases.splice(0);await Promise.allSettled(e.map(async t=>t.stop()))},C=(r,e)=>{const t=setTimeout(()=>{r.pending.then(async()=>{r.servers===0&&(r.stopping=Qe(r),await r.stopping)}).catch(()=>{})},e);return t.unref(),t},x=({projectRoot:r,start:e=de,wranglerConfigPath:t})=>{const o=new Map,n=i=>{const a=_(r);let c=!1;a.servers+=1,clearTimeout(a.stopTimer),i(()=>{c||(c=!0,a.servers-=1,a.servers===0&&(a.stopTimer=C(a,qe)))})};return{async config(i,a){if(a.command!=="serve")return;const c=_(r);clearTimeout(c.stopTimer);const s=c.pending,l=(async()=>{await s,await c.stopping;const u=await e({onWarning:d=>{console.warn(m(d))},projectRoot:r,wranglerConfigPath:t});u!==void 0&&c.databases.push(u),u!==void 0&&u.bindings.length>0&&console.info(m(`Hyperdrive ${u.bindings.join(", ")}: embedded Postgres (PGlite), data in .wrangler/state/lunora-pglite.`))})();c.pending=l.catch(()=>{});try{await l}finally{c.servers===0&&(clearTimeout(c.stopTimer),c.stopTimer=C(c,Je))}},buildEnd(){L(o,this.environment)},configureServer(i){n(a=>{D(i,o,a)})},configurePreviewServer(i){n(a=>{i.httpServer.once("close",a)})},enforce:"pre",name:"lunora:local-hyperdrive"}},Ye=(r,e)=>({config(t,o){if(o.command!=="serve")return;const{services:n}=Re(e),i=Array.isArray(r.auxiliaryWorkers)?r.auxiliaryWorkers:[],a=new Set(i.map(s=>s.configPath===void 0?"":h(e,s.configPath))),c=[...new Set(n.map(s=>s.wranglerPath))].filter(s=>!a.has(s)).map(s=>({configPath:s}));c.length>0&&(r.auxiliaryWorkers=[...i,...c])},enforce:"pre",name:"lunora:service-workers"}),Xe=r=>{if(r===!1)return!1;const e=r===!0||r===void 0?{}:r;return{...e,forwardedConsoleMethods:e.forwardedConsoleMethods??["error","warn"],solutionFinders:[...Ee,...e.solutionFinders??[]]}},Ze=(r,e)=>{const t=Q(r,e);if(!Y(t)){const o=X();throw new Error(`target "${t}" has no command-line toolchain, so the Lunora Vite plugin cannot build or serve it — it can only generate for it (\`lunora codegen --target ${t}\`). Buildable targets: ${o.join(", ")}`)}return Z(t,r),t},er=r=>{const e=r??{},t=e.schemaDir??"lunora";let o;e.cloudflare===!1?o=!1:e.cloudflare===!0||e.cloudflare===void 0?o={}:o=e.cloudflare;const n=e.projectRoot??process.cwd(),i=Ze(n,e.target);return{allowUnauthenticatedShardAccess:e.allowUnauthenticatedShardAccess??!1,apiSpec:e.apiSpec??"openapi",lazyFunctions:J(e.lazyFunctions),cloudflare:o,studio:e.studio??!0,generatedDir:`${t}/_generated`,overlay:Xe(e.overlay),projectRoot:n,schemaDir:t,shard:e.shard??{},target:i,validateWrangler:e.validateWrangler??!0}},rr=(r,e)=>{const{configPath:t}=r;return typeof t=="string"&&t!==""?h(e,t):void 0},Rr=r=>{const e=er(r),t=je(),o=K(),n=[ze(e,t),Pe(e,t),Se(e),Oe(e,o),he(e,o),$e(e.projectRoot),be(),ye(e),xe(e),He(e),ke()];e.studio&&n.push(Te(e)),e.validateWrangler&&n.push(Ce(e,o)),e.overlay!==!1&&n.push(ee(e.overlay)),n.push(we(e,o));const i=e.cloudflare===!1?void 0:{...e.cloudflare};if(n.push(Ae(i,{projectRoot:e.projectRoot})),i===void 0&&n.push(x({projectRoot:e.projectRoot})),i!==void 0){n.push(Ye(i,e.projectRoot));const a=q(e.target),c=Ie(e.projectRoot,e.target),s=()=>a&&c().runs;n.push(...Ne([x({projectRoot:e.projectRoot,wranglerConfigPath:rr(i,e.projectRoot)}),Ke(i,{projectRoot:e.projectRoot}),..._e(N(i))],s)),a&&n.push(Fe(e.projectRoot,s),{apply:(l,u)=>u.command==="serve"&&u.isPreview!==!0&&!s(),configureServer(l){l.config.logger.warn(`[lunora] target "${e.target}": vite dev serves the worker in workerd, not on ${e.target} — ${c().reason??"it cannot run this project"}. \`vite build\` then \`lunora deploy\` ships it to ${e.target}.`)},name:"lunora:target-runtime-notice"})}return n},Er=$(import.meta.url)("../package.json").version;export{Wr as CLASS_A_WIRING,Cr as GENERATED_CLASS_MODULES,Xr as LUNORA_API_UPDATED_EVENT,$r as LUNORA_WORKER_VIRTUAL_ID,et as STUDIO_PATH,Er as VERSION,qr as WORKER_STARTUP_HINT,Jr as augmentWorkerStartupError,zr as buildStudioUrl,Br as buildWorkerEntrySource,Nr as checkLunoraProxy,he as codegenPlugin,we as containerLogsPlugin,xr as detectFramework,ye as devStatePlugin,Se as devVariablesPlugin,Pe as frameworkComposePlugin,Ir as isAutoComposable,Qr as isWorkerEntryEvalError,be as logStreamPlugin,Rr as lunora,Vr as lunoraSolutionFinder,Ee as lunoraSolutionFinders,Fr as planViteRemoteBindings,ke as proxyCheckPlugin,Dr as reconcileWranglerCrons,Ae as remoteBindingsPlugin,Xe as resolveOverlayOption,Te as studioPlugin,Hr as withRemoteBindings,_e as withWorkerStartupHint,Ce as wranglerValidatorPlugin};
@@ -0,0 +1,28 @@
1
+ import{existsSync as w}from"node:fs";import{resolve as L,join as y}from"node:path";import{loadProjectConfig as M,findProjectConfigFile as k}from"@lunora/codegen";import{GENERATED_CLASS_MODULES as C,isMergedProject as b,DURABLE_OBJECT_BINDINGS as m,GENERATED_MODULE_DURABLE_OBJECTS as I,isMergedRoleModule as N,MERGED_DURABLE_OBJECTS_MODULE as U}from"@lunora/config";import{LunoraError as j}from"@lunora/errors";const R="virtual:lunora/worker",x="\0",f=`${x}${R}`,T=/^virtual:lunora\/worker$/u,B=/^\0virtual:lunora\/worker$/u,W=`// @lunora/vite — the composed worker entry is worker-only and unavailable in the client environment.
2
+ export default {};
3
+ `,G=/\/$/,E={"react-router":{handler:'{ fetch: (request) => createRequestHandler(() => import("virtual:react-router/server-build"), import.meta.env.MODE)(request) }',imports:'import { createRequestHandler } from "react-router";'},"solid-start":{handler:"ssrModule.default",imports:'import * as ssrModule from "@solidjs/start/server-handler";'},"tanstack-start":{handler:"ssrModule.default",imports:'import * as ssrModule from "@tanstack/react-start/server-entry";'},"tanstack-start-solid":{handler:"ssrModule.default",imports:'import * as ssrModule from "@tanstack/solid-start/server-entry";'},vinext:{handler:"ssrModule.default",imports:'import * as ssrModule from "vinext/server/fetch-handler";'}},h=e=>{const o=e.framework;return o?.class==="A"&&E[o.framework]!==void 0},P=(e,o,s)=>{if(!s)return{classExport:"export const ShardDO = app.ShardDO;",imports:"",namespace:r=>`env.${r==="scheduler"?m.SchedulerDO:m.ShardRegistryDO}`,reexported:()=>!0};const a=o.flatMap(r=>{const t=I[r];return t===void 0?[]:[{className:t,module:r}]});return{classExport:`export const LunoraDO = mergeDurableObjects({ shard: app.ShardDO${a.map(({className:r,module:t})=>`, ${t}: ${r}`).join("")} });`,imports:[`
4
+ import { mergeDurableObjects, roleNamespace } from "${e}/${U}";`,...a.map(({className:r,module:t})=>`
5
+ import { ${r} } from "${e}/${t}";`)].join(""),namespace:r=>`roleNamespace(env.SHARD, "${r}")`,reexported:r=>!N(r)}},V=(e,o,s={})=>{const{allowUnauthenticatedShardAccess:a=!1,appConfigModule:r,classModules:t=[],mergeDurableObjects:i=!1,shard:p={}}=s,l=E[e];if(l===void 0)throw new j("INTERNAL",`[lunora] no class-A worker wiring for framework "${e}"`);const d=o.replaceAll("\\","/"),c=P(d,t,i),$=i&&t.includes("shardRegistry")?`
6
+ export { ShardRegistryEntrypoint } from "${d}/shardRegistry";
7
+ `:"",g=t.filter(n=>c.reexported(n)).map(n=>`
8
+ export * from "${d}/${n}";
9
+ `).join("")+$,v=t.includes("scheduler")?`
10
+ .scheduler({ namespace: (env) => ${c.namespace("scheduler")} })`:"",O=t.includes("shardRegistry")?`
11
+ .shardRegistry((env) => ${c.namespace("shardRegistry")})`:"",A=r===void 0?"":`
12
+ import lunoraConfig from "${r}";`,[D,S]=r===void 0?["",""]:["lunoraConfig.app(",")"],_=Object.entries(p).filter(([,n])=>n!==void 0).toSorted(([n],[u])=>n.localeCompare(u)).map(([n,u])=>`
13
+ .${n}(${JSON.stringify(u)})`).join("");return`// Generated by @lunora/vite — class-A worker composition (PLAN4 M2).
14
+ // Do not edit: emitted from the detected framework (${e}). Point your
15
+ // wrangler \`main\` here (or re-export it) instead of hand-wiring createWorker.
16
+ ${l.imports}
17
+ import { defineApp } from "${d}/app";${c.imports}${A}
18
+
19
+ const app = ${D}defineApp()
20
+ .shard((env) => env.SHARD)${v}${O}${S}
21
+ .httpRouter(${l.handler})${_}${a?`
22
+ .extend(() => ({ allowUnauthenticatedShardAccess: true }))`:""}
23
+ .build();
24
+
25
+ ${c.classExport}
26
+ ${g}
27
+ export default app;
28
+ `},H=async e=>{const{config:o,error:s}=await M(e);return s!==void 0?{error:s}:typeof o?.app!="function"?{}:{specifier:k(e)?.replaceAll("\\","/")}},z=(e,o)=>{const s=L(e.projectRoot,e.generatedDir.replace(G,""));return{load:{filter:{id:B},async handler(a){if(a===f&&h(o)&&o.framework!==void 0){if(this.environment.name==="client")return W;const r=C.filter(l=>w(y(s,`${l}.ts`))),t=b(s),{error:i,specifier:p}=await H(e.projectRoot);return i!==void 0&&this.warn(`[lunora] lunora.config could not be loaded, so its \`app\` hook was not composed: ${i}`),V(o.framework.framework,s,{allowUnauthenticatedShardAccess:e.allowUnauthenticatedShardAccess,appConfigModule:p,classModules:r,mergeDurableObjects:t,shard:e.shard})}}},name:"lunora:framework-compose",resolveId:{filter:{id:T},handler(a){if(a===R&&h(o))return f}}}};export{E as CLASS_A_WIRING,R as LUNORA_WORKER_VIRTUAL_ID,f as RESOLVED_LUNORA_WORKER_ID,V as buildWorkerEntrySource,z as frameworkComposePlugin,h as isAutoComposable};
@@ -0,0 +1 @@
1
+ import{join as a}from"node:path";import{findProjectConfigFile as f,fingerprintSchemaSources as u}from"@lunora/codegen";import{createHash as l}from"node:crypto";import{readFileSync as m}from"node:fs";import{findWranglerFile as h,readWranglerJsonc as y}from"@lunora/config/cloudflare";const p=(n,e)=>{try{const{parsed:r,text:t}=y(n);return r===void 0?`raw:${t}`:JSON.stringify(e?e(r):r)}catch{return"unreadable"}},w=n=>{const e={...n},{triggers:r}=e;if(r!==null&&typeof r=="object"){const t={...r};delete t.crons,Object.keys(t).length>0?e.triggers=t:delete e.triggers}return e},c=n=>{const e=h(n),r=e===void 0?"absent":p(e,w),t=f(n);let o="absent";try{t!==void 0&&(o=l("sha256").update(m(t)).digest("hex"))}catch{}return`${r}\0${o}`},i=new Map,g=n=>JSON.stringify([a(n.projectRoot,n.schemaDir),n.apiSpec,n.lazyFunctions,n.target]),S=n=>u(a(n.projectRoot,n.schemaDir)),d=n=>{const e=g(n),r=S(n),t=c(n.projectRoot);let o=i.get(e);return(o===void 0||o.started||o.sources!==r||o.config!==t&&o.running===0)&&(o={config:t,done:new Map,running:0,sources:r,started:!1},i.set(e,o)),o},C=async(n,e,r)=>{const t=d(n);let o=t.done.get(e);return o===void 0&&(t.running+=1,o=(async()=>r())().then(s=>(t.running-=1,t.config=c(n.projectRoot),s),s=>{throw t.running-=1,t.done.delete(e),s}),t.done.set(e,o)),o},k=(n,e,r)=>{const t=d(n);t.done.has(e)||(r(),t.done.set(e,Promise.resolve()),t.config=c(n.projectRoot))},J=n=>{const e=i.get(g(n));e!==void 0&&(e.started=!0)};export{k as a,c,J as m,C as o};
@@ -0,0 +1,3 @@
1
+ import{existsSync as ce}from"node:fs";import{resolve as E,dirname as ae,sep as D,basename as x,join as G,relative as se}from"node:path";import{readServiceBindings as de,PROJECT_CONFIG_FILENAMES as L,projectConfigCandidatePaths as B,createCodegenProject as Q,runCodegen as le,findTsconfig as fe,isTestPath as ue,fingerprintSchemaSources as U,refreshCodegenProject as ge,CodegenDiagnosticError as me}from"@lunora/codegen";import{LUNORA_TAG as w,isCodegenDisabled as he,CODEGEN_ENV as V,writeApiSpecMarker as pe,reportCodegenFindings as we,blockingFindingsMessage as Se,STRICT_ADVISORIES_ENV as ye,runPostCodegenHook as H}from"@lunora/config";import{WRANGLER_FILES as ve,wranglerCodegenInputs as Ee,reconcileWranglerExtras as Re,reconcileBindingsSafely as ke}from"@lunora/config/cloudflare";import{consumeStudioWrite as Ce}from"@lunora/config/studio-host";import{isRunnableDevEnvironment as je}from"vite";import{c as N,m as $e,o as be}from"./build-session-D75JzvIT.mjs";import De from"./LUNORA_API_UPDATED_EVENT-CO2Rv2re.mjs";import{a as Te,r as Pe}from"./server-close-DWiO4Vxb.mjs";const _e=100,Y=300,J=2,Me=e=>{let i,c=!1,n,f=0;const a=()=>{i&&(clearTimeout(i),i=void 0)},d=(s,y)=>{n&&clearTimeout(n),n=setTimeout(()=>{if(n=void 0,e.fingerprint()!==s){if(f+=1,f>J){e.logger.warn(`${w} \`postcodegen\` keeps rewriting the schema sources — stopping after ${String(J)} reruns. Make the hook idempotent or move it off the schema directory.`);return}e.logger.info(`${w} schema changed while \`postcodegen\` was running — regenerating`),y()}},Y)},h=(s,y)=>{e.regenerate(s,R=>{d(R,()=>{h(s,!0)})},y)},S=(s,y)=>{const R=y||i!==void 0&&c;a(),f=0,c=R,i=setTimeout(()=>{i=void 0,h(s,R)},_e)};return{cancelPending:a,dispose:()=>{a(),n&&(clearTimeout(n),n=void 0)},onSave:s=>{S(s,!0)},onStudioWrite:s=>{S(s,!1)}}},K=/[/\\]tsconfig\..+\.json$/u,Ae=/(?:\.[cm]?[jt]sx?|(?:^|[/\\])tsconfig(?:\..+)?\.json)$/u,Fe=e=>{const i=e.map(n=>` • ${n.kind} "${n.exportName}" — class ${n.className} is not exported by your worker entry.`),c=[...new Set(e.map(n=>n.module))].map(n=>` export * from "./lunora/_generated/${n}";`);return[`[lunora] ${String(e.length)} declared ${e.length===1?"binding is":"bindings are"} not exported by your worker entry — \`wrangler deploy\` will fail.`,...i,"","Add to your worker entry:",...c].join(`
2
+ `)},Ie=(e,i,c)=>{if(i.warn(`${w} schema.ts not found at ${e} — codegen skipped`),c!==void 0){const n=`schema.ts not found at ${e} — generated output is now stale`;c.onError(new Error(n),n)}},A=(e,i,c,n)=>{const f=G(e.projectRoot,e.schemaDir,"schema.ts");if(!ce(f))return Ie(f,i,c),{};try{const a=n??Q(G(e.projectRoot,e.schemaDir)),d=le({apiSpec:e.apiSpec,lazyFunctions:e.lazyFunctions,lunoraDirectory:e.schemaDir,project:a,projectRoot:e.projectRoot,target:e.target,...Ee(e.projectRoot)});Re(e.projectRoot,d.cronTriggers,i);let h;try{pe(e.projectRoot,e.apiSpec)}catch(S){h=`${w} could not write the API spec marker: ${S instanceof Error?S.message:String(S)}`,i.error(h)}return we(d,i),{blockingMessage:Se(d,{strictAdvisories:process.env[ye]!=="0"}),markerFailure:h,outputDirectory:E(d.outputDirectory),project:a}}catch(a){const d=a instanceof Error?a.message:String(a);return i.error(`${w} codegen failed: ${d}`),c?.onError(a,d),{failure:`${w} codegen failed: ${d}`}}},Ne=(e,i,c)=>{let n;for(const[f,a]of Object.entries(e.environments)){if(f==="client"){n=a;continue}je(a)||a.hot.send({path:"*",triggeredBy:i,type:"full-reload"})}if(n===void 0){e.hot.send({type:"full-reload"});return}if(c){n.hot.send({type:"full-reload"});return}n.hot.send({event:De,type:"custom"})},P={error:e=>{console.error(e)},info:e=>{console.info(e)},warn:e=>{console.warn(e)}},X=new WeakMap,q=async(e,i,c)=>{const n=X.get(e)??new Map;return X.set(e,n),n.has(i)||n.set(i,c()),n.get(i)},Ke=(e,i)=>{const c=E(e.projectRoot,e.schemaDir),n=he(process.env[V]);let f=E(e.projectRoot,e.generatedDir),a=0,d=!1,h;const S=new Map;let s,y=!1,R=!1,p,T;const F=new Set,Z=t=>{const u=F.has(t)?void 0:T;return F.add(t),p!=="build"&&(T=void 0),u},z=async()=>{d=!0;let t;try{t=await H({cwd:e.projectRoot,logger:P})}finally{d=!1}return t.ran&&(a=Date.now(),i?.clear()),t.error},ee=async()=>{T=await be(e,"codegen",()=>{const{blockingMessage:t,failure:u,markerFailure:v,outputDirectory:k}=A(e,P);return{blockingMessage:t,failure:u,markerFailure:v,outputDirectory:k}})};return{config(t,u){p=u.command},configResolved(){if(F.clear(),p==="build")return ee();n||(T=A(e,P))},async buildStart(){const t=p!=="build"&&n,u=Z(p==="build"?this.environment.name:"")??(t?{}:A(e,P)),{blockingMessage:v,failure:k,markerFailure:_,outputDirectory:C}=u;p==="build"&&$e(e),p==="build"&&k!==void 0&&this.error(k),p==="build"&&_!==void 0&&this.error(_),f=C??f;const j=C===void 0?void 0:await q(u,"postcodegen",z);p==="build"&&j!==void 0&&this.error(j),p==="build"&&v!==void 0&&this.error(v),await q(u,"reconcile",async()=>ke({...e,cache:i},P,g=>{h?.hot.send({err:{loc:void 0,message:Fe(g),stack:""},type:"error"})})),i?.clear(),h!==void 0&&(s=N(e.projectRoot),y=!0)},configureServer(t){h=t,t.watcher.add(c);const u=de(e.projectRoot).services.filter(r=>r.rpcEntrypoint!==void 0).map(r=>ae(r.wranglerPath));t.watcher.add(u),s=N(e.projectRoot),y=!1;const v={error:r=>{t.config.logger.error(r)},info:r=>{t.config.logger.info(r)},warn:r=>{t.config.logger.warn(r)}};let k=!1;const _={onError(r,o){k=!0;const l=r instanceof me?{column:r.column,file:r.file,line:r.line}:void 0,m=l===void 0?`[lunora] codegen failed: ${o}
3
+ (see terminal for full stack trace and file location)`:`[lunora] codegen failed: ${o}`;h?.hot.send({err:{loc:l,message:m,stack:r instanceof Error?r.stack??"":""},type:"error"})}},C=(r,o)=>r===o||r.startsWith(o+D);let j=!1,g=T?.project;const re=()=>{for(const r of Object.values(t.environments)){const o=r.moduleGraph;for(const l of o.idToModuleMap.values())l.id&&C(l.id,f)&&o.invalidateModule(l)}},te=()=>{g===void 0?g=Q(c):ge(g,c);const{outputDirectory:r}=A(e,v,_,g);return r===void 0?(g=void 0,!1):(f=r,!0)},ne=async(r,o,l)=>{try{if(j||l&&!te())return;const m=U(c);d=!0;let I;try{I=await H({cwd:e.projectRoot,logger:v})}finally{d=!1}if(I.ran&&(a=Date.now(),o(m)),I.error!==void 0)return;re(),Ne(t,r,k),k=!1}catch(m){v.error(`${w} codegen watch: ${m instanceof Error?m.message:String(m)}`)}},M=Me({fingerprint:()=>U(c),logger:v,regenerate:(r,o,l)=>{ne(r,o,l)}}),oe=r=>K.test(r)||L.includes(x(r))&&B(c).includes(r)||r.endsWith(`${D}tsconfig.json`)&&r===fe(c)?(g=void 0,!1):!(!C(r,c)||C(r,f)||!r.endsWith(".ts")||ue(se(c,r).split(D).join("/"))),$=r=>{const o=E(r);if(!(!(Ae.test(o)&&!o.includes(`${D}node_modules${D}`)&&u.some(m=>C(o,m)))&&!oe(o))){if(d||Date.now()-a<Y){M.cancelPending();return}if(Ce(o)){M.onStudioWrite(o);return}M.onSave(o)}},O=r=>{const o=E(r);(o.endsWith(`${D}tsconfig.json`)||K.test(o))&&(g=void 0)};n?t.config.logger.info(`${w} codegen watch disabled (${V}) — _generated/ is written only by an explicit \`lunora codegen\``):(t.watcher.on("add",$),t.watcher.on("change",$),t.watcher.on("unlink",$),t.watcher.on("unlink",O));const W=new Set([...ve.map(r=>E(e.projectRoot,r)),...L.map(r=>E(e.projectRoot,r)),...B(c)]);for(const r of W)t.watcher.add(r);const b=r=>{if(!W.has(E(r))||R)return;const o=N(e.projectRoot);if(!y){s=o;return}if(s===void 0){s=o;return}o!==s&&(s=o,R=!0,t.config.logger.info(`${w} ${x(E(r))} changed — restarting dev server`),Promise.resolve(t.restart()).finally(()=>{R=!1}).catch(l=>{const m=l instanceof Error?l.message:String(l);t.config.logger.error(`${w} dev server restart failed: ${m} — keeping the running server; re-save your config to retry.`),t.hot.send({err:{loc:void 0,message:`[lunora] dev server restart failed: ${m}`,stack:""},type:"error"})}))};t.watcher.on("add",b),t.watcher.on("change",b),t.watcher.on("unlink",b);const ie=()=>{j||(j=!0,g=void 0,M.dispose(),t.watcher.off("add",$),t.watcher.off("change",$),t.watcher.off("unlink",$),t.watcher.off("unlink",O),t.watcher.off("add",b),t.watcher.off("change",b),t.watcher.off("unlink",b))};return()=>{Pe(t,S,ie)}},buildEnd(){Te(S,this.environment)},name:"lunora:codegen"}};export{Ke as default};
@@ -0,0 +1 @@
1
+ import{discoverContainerInfo as m,streamContainerLogs as u}from"@lunora/config";import{lunoraLine as s}from"@lunora/config/cli";const p=(r,i)=>{let n;const a=()=>{n?.close(),n=void 0};return{apply:"serve",buildEnd(){a()},configureServer(t){if(n||process.env.LUNORA_CONTAINER_LOGS==="0")return;const c=m(r.projectRoot,r.schemaDir,i).containers.map(e=>({className:e.className,exportName:e.exportName}));if(c.length===0)return;const{logger:o}=t.config;n=u({containers:c,onLine:e=>{const l=s(`container:${e.name} ${e.text}`);e.level==="error"?o.warn(l):o.info(l)},onUnavailable:e=>{o.warn(s(`container: Docker engine unreachable — container logs unavailable (${e})`))}}),t.httpServer?.once("close",a)},name:"lunora:container-logs"}};export{p as default};
@@ -0,0 +1 @@
1
+ import{spawnSync as s}from"node:child_process";import{lunoraLine as c}from"@lunora/config";import{readWranglerJsonc as l,assertWranglerSatisfiesSchema as f,findWranglerFile as d}from"@lunora/config/cloudflare";import{a as u}from"./build-session-D75JzvIT.mjs";const g=r=>r.startsWith("./")||r.startsWith("../")||r.startsWith("/")||r.includes("Dockerfile"),m=()=>{try{return s("docker",["info"],{stdio:"ignore"}).status===0}catch{return!1}},w=(r,t=m)=>{const{parsed:n}=l(r);!(n?.containers??[]).some(e=>typeof e?.image=="string"&&g(e.image))||t()||console.warn(c("wrangler.jsonc declares containers built from a local Dockerfile, but no Docker-compatible engine is running. Start Docker (or Colima) before `vite dev`, or the container instances will fail to start."))},D=(r,t)=>{let n=!1,a=!1;const e=()=>{f({...r,cache:t},o=>{console.warn(o)},"Update your wrangler.jsonc and restart the dev server.");const i=d(r.projectRoot);i!==void 0&&w(i)};return{config(i,o){n=o.isPreview===!0,a=o.command==="build"},configResolved(){if(!n){if(a){u(r,"validate-wrangler",e);return}e()}},enforce:"pre",name:"lunora:wrangler-validator"}};export{w as warnWhenDockerMissing,D as wranglerValidatorPlugin};
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@lunora/vite",
3
- "version": "1.0.0-alpha.385",
3
+ "version": "1.0.0-alpha.387",
4
4
  "description": "The Lunora Vite plugin: codegen, type sync, wrangler validation, and an error overlay over @cloudflare/vite-plugin",
5
5
  "keywords": [
6
6
  "cloudflare",
@@ -46,8 +46,8 @@
46
46
  },
47
47
  "dependencies": {
48
48
  "@cloudflare/vite-plugin": "1.63.1",
49
- "@lunora/codegen": "1.0.0-alpha.357",
50
- "@lunora/config": "1.0.0-alpha.411",
49
+ "@lunora/codegen": "1.0.0-alpha.359",
50
+ "@lunora/config": "1.0.0-alpha.413",
51
51
  "@lunora/errors": ">=1.0.0-alpha.51 <2.0.0-0",
52
52
  "@visulima/vite-overlay": "2.0.41"
53
53
  },
@@ -1,28 +0,0 @@
1
- import{existsSync as y}from"node:fs";import{resolve as _,join as M}from"node:path";import{loadProjectConfig as C,findProjectConfigFile as L}from"@lunora/codegen";import{GENERATED_CLASS_MODULES as b,isMergedProject as k,DURABLE_OBJECT_BINDINGS as m,GENERATED_MODULE_DURABLE_OBJECTS as j,isMergedRoleModule as x,MERGED_DURABLE_OBJECTS_MODULE as I}from"@lunora/config";import{LunoraError as N}from"@lunora/errors";const R="virtual:lunora/worker",U="\0",f=`${U}${R}`,T=`// @lunora/vite — the composed worker entry is worker-only and unavailable in the client environment.
2
- export default {};
3
- `,B=/\/$/,$={"react-router":{handler:'{ fetch: (request) => createRequestHandler(() => import("virtual:react-router/server-build"), import.meta.env.MODE)(request) }',imports:'import { createRequestHandler } from "react-router";'},"solid-start":{handler:"ssrModule.default",imports:'import * as ssrModule from "@solidjs/start/server-handler";'},"tanstack-start":{handler:"ssrModule.default",imports:'import * as ssrModule from "@tanstack/react-start/server-entry";'},"tanstack-start-solid":{handler:"ssrModule.default",imports:'import * as ssrModule from "@tanstack/solid-start/server-entry";'},vinext:{handler:"ssrModule.default",imports:'import * as ssrModule from "vinext/server/fetch-handler";'}},h=r=>{const o=r.framework;return o?.class==="A"&&$[o.framework]!==void 0},G=(r,o,s)=>{if(!s)return{classExport:"export const ShardDO = app.ShardDO;",imports:"",namespace:e=>`env.${e==="scheduler"?m.SchedulerDO:m.ShardRegistryDO}`,reexported:()=>!0};const a=o.flatMap(e=>{const t=j[e];return t===void 0?[]:[{className:t,module:e}]});return{classExport:`export const LunoraDO = mergeDurableObjects({ shard: app.ShardDO${a.map(({className:e,module:t})=>`, ${t}: ${e}`).join("")} });`,imports:[`
4
- import { mergeDurableObjects, roleNamespace } from "${r}/${I}";`,...a.map(({className:e,module:t})=>`
5
- import { ${e} } from "${r}/${t}";`)].join(""),namespace:e=>`roleNamespace(env.SHARD, "${e}")`,reexported:e=>!x(e)}},P=(r,o,s={})=>{const{allowUnauthenticatedShardAccess:a=!1,appConfigModule:e,classModules:t=[],mergeDurableObjects:i=!1,shard:p={}}=s,l=$[r];if(l===void 0)throw new N("INTERNAL",`[lunora] no class-A worker wiring for framework "${r}"`);const d=o.replaceAll("\\","/"),c=G(d,t,i),g=i&&t.includes("shardRegistry")?`
6
- export { ShardRegistryEntrypoint } from "${d}/shardRegistry";
7
- `:"",E=t.filter(n=>c.reexported(n)).map(n=>`
8
- export * from "${d}/${n}";
9
- `).join("")+g,v=t.includes("scheduler")?`
10
- .scheduler({ namespace: (env) => ${c.namespace("scheduler")} })`:"",A=t.includes("shardRegistry")?`
11
- .shardRegistry((env) => ${c.namespace("shardRegistry")})`:"",S=e===void 0?"":`
12
- import lunoraConfig from "${e}";`,[D,O]=e===void 0?["",""]:["lunoraConfig.app(",")"],w=Object.entries(p).filter(([,n])=>n!==void 0).toSorted(([n],[u])=>n.localeCompare(u)).map(([n,u])=>`
13
- .${n}(${JSON.stringify(u)})`).join("");return`// Generated by @lunora/vite — class-A worker composition (PLAN4 M2).
14
- // Do not edit: emitted from the detected framework (${r}). Point your
15
- // wrangler \`main\` here (or re-export it) instead of hand-wiring createWorker.
16
- ${l.imports}
17
- import { defineApp } from "${d}/app";${c.imports}${S}
18
-
19
- const app = ${D}defineApp()
20
- .shard((env) => env.SHARD)${v}${A}${O}
21
- .httpRouter(${l.handler})${w}${a?`
22
- .extend(() => ({ allowUnauthenticatedShardAccess: true }))`:""}
23
- .build();
24
-
25
- ${c.classExport}
26
- ${E}
27
- export default app;
28
- `},W=async r=>{const{config:o,error:s}=await C(r);return s!==void 0?{error:s}:typeof o?.app!="function"?{}:{specifier:L(r)?.replaceAll("\\","/")}},F=(r,o)=>{const s=_(r.projectRoot,r.generatedDir.replace(B,""));return{async load(a){if(a===f&&h(o)&&o.framework!==void 0){if(this.environment.name==="client")return T;const e=b.filter(l=>y(M(s,`${l}.ts`))),t=k(s),{error:i,specifier:p}=await W(r.projectRoot);return i!==void 0&&this.warn(`[lunora] lunora.config could not be loaded, so its \`app\` hook was not composed: ${i}`),P(o.framework.framework,s,{allowUnauthenticatedShardAccess:r.allowUnauthenticatedShardAccess,appConfigModule:p,classModules:e,mergeDurableObjects:t,shard:r.shard})}},name:"lunora:framework-compose",resolveId(a){if(a===R&&h(o))return f}}};export{$ as CLASS_A_WIRING,R as LUNORA_WORKER_VIRTUAL_ID,f as RESOLVED_LUNORA_WORKER_ID,P as buildWorkerEntrySource,F as frameworkComposePlugin,h as isAutoComposable};
@@ -1,3 +0,0 @@
1
- import{readFileSync as Y,existsSync as Z}from"node:fs";import{resolve as v,dirname as z,sep as b,basename as I,join as ee,relative as re}from"node:path";import{findProjectConfigFile as te,readServiceBindings as ne,PROJECT_CONFIG_FILENAMES as x,projectConfigCandidatePaths as W,runCodegen as oe,findTsconfig as ie,isTestPath as ce,fingerprintSchemaSources as G,createCodegenProject as ae,refreshCodegenProject as se,CodegenDiagnosticError as le}from"@lunora/codegen";import{LUNORA_TAG as w,isCodegenDisabled as de,CODEGEN_ENV as L,runPostCodegenHook as U,writeApiSpecMarker as fe,reportCodegenFindings as ge,blockingFindingsMessage as ue,STRICT_ADVISORIES_ENV as he}from"@lunora/config";import{findWranglerFile as me,readWranglerJsonc as pe,WRANGLER_FILES as we,reconcileBindingsSafely as ye,wranglerCodegenInputs as Se,reconcileWranglerExtras as ve}from"@lunora/config/cloudflare";import{consumeStudioWrite as Ee}from"@lunora/config/studio-host";import{isRunnableDevEnvironment as Re}from"vite";import{createHash as Ce}from"node:crypto";import $e from"./LUNORA_API_UPDATED_EVENT-CO2Rv2re.mjs";import{a as ke,r as be}from"./server-close-DWiO4Vxb.mjs";const je=(e,t)=>{try{const{parsed:c,text:n}=pe(e);return c===void 0?`raw:${n}`:JSON.stringify(t?t(c):c)}catch{return"unreadable"}},De=e=>{const t={...e},{triggers:c}=t;if(c!==null&&typeof c=="object"){const n={...c};delete n.crons,Object.keys(n).length>0?t.triggers=n:delete t.triggers}return t},O=e=>{const t=me(e),c=t===void 0?"absent":je(t,De),n=te(e);let s="absent";try{n!==void 0&&(s=Ce("sha256").update(Y(n)).digest("hex"))}catch{}return`${c}\0${s}`},Te=100,J=300,V=2,_e=e=>{let t,c=!1,n,s=0;const a=()=>{t&&(clearTimeout(t),t=void 0)},d=(f,S)=>{n&&clearTimeout(n),n=setTimeout(()=>{if(n=void 0,e.fingerprint()!==f){if(s+=1,s>V){e.logger.warn(`${w} \`postcodegen\` keeps rewriting the schema sources — stopping after ${String(V)} reruns. Make the hook idempotent or move it off the schema directory.`);return}e.logger.info(`${w} schema changed while \`postcodegen\` was running — regenerating`),S()}},J)},y=(f,S)=>{e.regenerate(f,g=>{d(g,()=>{y(f,!0)})},S)},m=(f,S)=>{const g=S||t!==void 0&&c;a(),s=0,c=g,t=setTimeout(()=>{t=void 0,y(f,g)},Te)};return{cancelPending:a,dispose:()=>{a(),n&&(clearTimeout(n),n=void 0)},onSave:f=>{m(f,!0)},onStudioWrite:f=>{m(f,!1)}}},B=/[/\\]tsconfig\..+\.json$/u,Pe=/(?:\.[cm]?[jt]sx?|(?:^|[/\\])tsconfig(?:\..+)?\.json)$/u,Fe=e=>{const t=e.map(n=>` • ${n.kind} "${n.exportName}" — class ${n.className} is not exported by your worker entry.`),c=[...new Set(e.map(n=>n.module))].map(n=>` export * from "./lunora/_generated/${n}";`);return[`[lunora] ${String(e.length)} declared ${e.length===1?"binding is":"bindings are"} not exported by your worker entry — \`wrangler deploy\` will fail.`,...t,"","Add to your worker entry:",...c].join(`
2
- `)},Oe=(e,t,c)=>{if(t.warn(`${w} schema.ts not found at ${e} — codegen skipped`),c!==void 0){const n=`schema.ts not found at ${e} — generated output is now stale`;c.onError(new Error(n),n)}},A=(e,t,c,n)=>{const s=ee(e.projectRoot,e.schemaDir,"schema.ts");if(!Z(s))return Oe(s,t,c),{};try{const a=oe({apiSpec:e.apiSpec,lazyFunctions:e.lazyFunctions,lunoraDirectory:e.schemaDir,project:n,projectRoot:e.projectRoot,target:e.target,...Se(e.projectRoot)});ve(e.projectRoot,a.cronTriggers,t);let d;try{fe(e.projectRoot,e.apiSpec)}catch(y){d=`${w} could not write the API spec marker: ${y instanceof Error?y.message:String(y)}`,t.error(d)}return ge(a,t),{blockingMessage:ue(a,{strictAdvisories:process.env[he]!=="0"}),markerFailure:d,outputDirectory:v(a.outputDirectory)}}catch(a){const d=a instanceof Error?a.message:String(a);return t.error(`${w} codegen failed: ${d}`),c?.onError(a,d),{failure:`${w} codegen failed: ${d}`}}},Ae=(e,t,c)=>{let n;for(const[s,a]of Object.entries(e.environments)){if(s==="client"){n=a;continue}Re(a)||a.hot.send({path:"*",triggeredBy:t,type:"full-reload"})}if(n===void 0){e.hot.send({type:"full-reload"});return}if(c){n.hot.send({type:"full-reload"});return}n.hot.send({event:$e,type:"custom"})},T={error:e=>{console.error(e)},info:e=>{console.info(e)},warn:e=>{console.warn(e)}},Je=e=>{const t=v(e.projectRoot,e.schemaDir),c=de(process.env[L]);let n=v(e.projectRoot,e.generatedDir),s=0,a=!1,d;const y=new Map;let m,f=!1,S=!1,g,_;return{config(o,E){g=E.command},configResolved(){g!=="build"&&c||(_=A(e,T))},async buildStart(){const o=g!=="build"&&c,{blockingMessage:E,failure:R,markerFailure:C,outputDirectory:j}=_??(o?{}:A(e,T));if(_=void 0,g==="build"&&R!==void 0&&this.error(R),g==="build"&&C!==void 0&&this.error(C),j!==void 0){n=j,a=!0;let h;try{h=await U({cwd:e.projectRoot,logger:T})}finally{a=!1}h.ran&&(s=Date.now()),g==="build"&&h.error!==void 0&&this.error(h.error)}g==="build"&&E!==void 0&&this.error(E),await ye(e,T,h=>{d?.hot.send({err:{loc:void 0,message:Fe(h),stack:""},type:"error"})}),d!==void 0&&(m=O(e.projectRoot),f=!0)},configureServer(o){d=o,o.watcher.add(t);const E=ne(e.projectRoot).services.filter(r=>r.rpcEntrypoint!==void 0).map(r=>z(r.wranglerPath));o.watcher.add(E),m=O(e.projectRoot),f=!1;const R={error:r=>{o.config.logger.error(r)},info:r=>{o.config.logger.info(r)},warn:r=>{o.config.logger.warn(r)}};let C=!1;const j={onError(r,i){C=!0;const l=r instanceof le?{column:r.column,file:r.file,line:r.line}:void 0,u=l===void 0?`[lunora] codegen failed: ${i}
3
- (see terminal for full stack trace and file location)`:`[lunora] codegen failed: ${i}`;d?.hot.send({err:{loc:l,message:u,stack:r instanceof Error?r.stack??"":""},type:"error"})}},h=(r,i)=>r===i||r.startsWith(i+b);let P=!1,p;const H=()=>{for(const r of Object.values(o.environments)){const i=r.moduleGraph;for(const l of i.idToModuleMap.values())l.id&&h(l.id,n)&&i.invalidateModule(l)}},K=()=>{p===void 0?p=ae(t):se(p,t);const{outputDirectory:r}=A(e,R,j,p);return r===void 0?(p=void 0,!1):(n=r,!0)},X=async(r,i,l)=>{try{if(P||l&&!K())return;const u=G(t);a=!0;let F;try{F=await U({cwd:e.projectRoot,logger:R})}finally{a=!1}if(F.ran&&(s=Date.now(),i(u)),F.error!==void 0)return;H(),Ae(o,r,C),C=!1}catch(u){R.error(`${w} codegen watch: ${u instanceof Error?u.message:String(u)}`)}},D=_e({fingerprint:()=>G(t),logger:R,regenerate:(r,i,l)=>{X(r,i,l)}}),q=r=>B.test(r)||x.includes(I(r))&&W(t).includes(r)||r.endsWith(`${b}tsconfig.json`)&&r===ie(t)?(p=void 0,!1):!(!h(r,t)||h(r,n)||!r.endsWith(".ts")||ce(re(t,r).split(b).join("/"))),$=r=>{const i=v(r);if(!(!(Pe.test(i)&&!i.includes(`${b}node_modules${b}`)&&E.some(u=>h(i,u)))&&!q(i))){if(a||Date.now()-s<J){D.cancelPending();return}if(Ee(i)){D.onStudioWrite(i);return}D.onSave(i)}},N=r=>{const i=v(r);(i.endsWith(`${b}tsconfig.json`)||B.test(i))&&(p=void 0)};c?o.config.logger.info(`${w} codegen watch disabled (${L}) — _generated/ is written only by an explicit \`lunora codegen\``):(o.watcher.on("add",$),o.watcher.on("change",$),o.watcher.on("unlink",$),o.watcher.on("unlink",N));const M=new Set([...we.map(r=>v(e.projectRoot,r)),...x.map(r=>v(e.projectRoot,r)),...W(t)]);for(const r of M)o.watcher.add(r);const k=r=>{if(!M.has(v(r))||S)return;const i=O(e.projectRoot);if(!f){m=i;return}if(m===void 0){m=i;return}i!==m&&(m=i,S=!0,o.config.logger.info(`${w} ${I(v(r))} changed — restarting dev server`),Promise.resolve(o.restart()).finally(()=>{S=!1}).catch(l=>{const u=l instanceof Error?l.message:String(l);o.config.logger.error(`${w} dev server restart failed: ${u} — keeping the running server; re-save your config to retry.`),o.hot.send({err:{loc:void 0,message:`[lunora] dev server restart failed: ${u}`,stack:""},type:"error"})}))};o.watcher.on("add",k),o.watcher.on("change",k),o.watcher.on("unlink",k);const Q=()=>{P||(P=!0,p=void 0,D.dispose(),o.watcher.off("add",$),o.watcher.off("change",$),o.watcher.off("unlink",$),o.watcher.off("unlink",N),o.watcher.off("add",k),o.watcher.off("change",k),o.watcher.off("unlink",k))};return()=>{be(o,y,Q)}},buildEnd(){ke(y,this.environment)},name:"lunora:codegen"}};export{Je as default};
@@ -1 +0,0 @@
1
- import{discoverContainerInfo as l,streamContainerLogs as m}from"@lunora/config";import{lunoraLine as i}from"@lunora/config/cli";const p=r=>{let n;const a=()=>{n?.close(),n=void 0};return{apply:"serve",buildEnd(){a()},configureServer(t){if(n||process.env.LUNORA_CONTAINER_LOGS==="0")return;const c=l(r.projectRoot,r.schemaDir).containers.map(e=>({className:e.className,exportName:e.exportName}));if(c.length===0)return;const{logger:o}=t.config;n=m({containers:c,onLine:e=>{const s=i(`container:${e.name} ${e.text}`);e.level==="error"?o.warn(s):o.info(s)},onUnavailable:e=>{o.warn(i(`container: Docker engine unreachable — container logs unavailable (${e})`))}}),t.httpServer?.once("close",a)},name:"lunora:container-logs"}};export{p as default};
@@ -1 +0,0 @@
1
- import{spawnSync as a}from"node:child_process";import{lunoraLine as s}from"@lunora/config";import{assertWranglerSatisfiesSchema as i,findWranglerFile as c,readWranglerJsonc as l}from"@lunora/config/cloudflare";const f=r=>r.startsWith("./")||r.startsWith("../")||r.startsWith("/")||r.includes("Dockerfile"),d=()=>{try{return a("docker",["info"],{stdio:"ignore"}).status===0}catch{return!1}},g=(r,n=d)=>{const{parsed:e}=l(r);!(e?.containers??[]).some(t=>typeof t?.image=="string"&&f(t.image))||n()||console.warn(s("wrangler.jsonc declares containers built from a local Dockerfile, but no Docker-compatible engine is running. Start Docker (or Colima) before `vite dev`, or the container instances will fail to start."))},p=r=>{let n=!1;return{config(e,o){n=o.isPreview===!0},configResolved(){if(n)return;i(r,o=>{console.warn(o)},"Update your wrangler.jsonc and restart the dev server.");const e=c(r.projectRoot);e!==void 0&&g(e)},enforce:"pre",name:"lunora:wrangler-validator"}};export{g as warnWhenDockerMissing,p as wranglerValidatorPlugin};