@lunora/vite 1.0.0-alpha.210 → 1.0.0-alpha.212

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,8 +1,8 @@
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, readProjectRemotePreference } from '@lunora/config';
5
- export { type DetectedFramework, type FrameworkClass, type FrameworkDetection, detectFramework } from '@lunora/config';
4
+ import { FrameworkDetection, DetectedFramework, GeneratedClassModule, readProjectRemotePreference } from '@lunora/config';
5
+ export { type DetectedFramework, type FrameworkClass, type FrameworkDetection, GENERATED_CLASS_MODULES, type GeneratedClassModule, detectFramework } from '@lunora/config';
6
6
  import { materializeRemoteWranglerConfig } from '@lunora/config/cloudflare';
7
7
  export { type ReconcileCronsResult as ReconcileResult, reconcileWranglerCrons } from '@lunora/config/cloudflare';
8
8
  import { AddressInfo } from 'node:net';
@@ -98,7 +98,7 @@ interface LunoraPluginOptions {
98
98
  studio?: boolean;
99
99
  /**
100
100
  * Deploy target the emitted `ctx.*` surface is tailored to. Defaults to
101
- * `"target"` in `lunora.json`, then `"cloudflare"` — so an existing project
101
+ * `"target"` in `lunora.config.*`, then `"cloudflare"` — so an existing project
102
102
  * emits byte-identical output.
103
103
  *
104
104
  * Set it here only to override the project config for one build — keeping
@@ -238,16 +238,7 @@ declare const CLASS_A_WIRING: Readonly<Partial<Record<DetectedFramework, ClassAW
238
238
  * (class B/C, `none`) falls back to the existing flow.
239
239
  */
240
240
  declare const isAutoComposable: (context: LunoraPluginContext) => boolean;
241
- /**
242
- * The `_generated/` modules whose exported classes wrangler validates a
243
- * `class_name` against: container Durable Objects, workflow entrypoints, and
244
- * agent (workflow) entrypoints — the same three kinds `reconcile-bindings`
245
- * writes into `wrangler.jsonc`. The composed entry star-re-exports each module
246
- * the project actually has.
247
- */
248
- declare const GENERATED_CLASS_MODULES: readonly ["agents", "containers", "workflows"];
249
- /** One {@link GENERATED_CLASS_MODULES} entry. */
250
- type GeneratedClassModule = (typeof GENERATED_CLASS_MODULES)[number];
241
+ /** Trailing `.ts` on the app-config path — the bundler resolves the extension, so the emitted specifier drops it. */
251
242
  /**
252
243
  * Build the source of the virtual class-A worker entry. Pure (no fs / no Vite),
253
244
  * so the emitted composition is unit-testable in isolation.
@@ -263,7 +254,17 @@ type GeneratedClassModule = (typeof GENERATED_CLASS_MODULES)[number];
263
254
  * virtual module id. Absolute paths are resolved correctly in all environments
264
255
  * (Vite 8 + rolldown 1.x confirmed).
265
256
  */
266
- declare const buildWorkerEntrySource: (framework: DetectedFramework, generatedImportBase: string, classModules?: ReadonlyArray<GeneratedClassModule>, allowUnauthenticatedShardAccess?: boolean, shard?: LunoraShardConfig) => string;
257
+ interface WorkerEntryComposition {
258
+ /** Whether to allow unauthenticated shard access — `.extend(...)` on the builder. */
259
+ allowUnauthenticatedShardAccess?: boolean;
260
+ /** Finished specifier for the project's `lunora.config.*`, when it declares an `app` hook. */
261
+ appConfigModule?: string;
262
+ /** The `_generated/` class modules that exist, each star-re-exported. */
263
+ classModules?: ReadonlyArray<GeneratedClassModule>;
264
+ /** Per-shard knobs, each key named after the builder method that sets it. */
265
+ shard?: LunoraShardConfig;
266
+ }
267
+ declare const buildWorkerEntrySource: (framework: DetectedFramework, generatedImportBase: string, composition?: WorkerEntryComposition) => string;
267
268
  /**
268
269
  * Vite plugin that auto-composes a detected class-A meta-framework's SSR
269
270
  * handler with Lunora into one Cloudflare Worker (PLAN4 §2.4 / §3 class-A row).
@@ -343,9 +344,9 @@ interface ViteRemotePlan {
343
344
  interface PlanViteRemoteOptions {
344
345
  /** Injection seam — defaults to the real materializer. */
345
346
  materialize?: typeof materializeRemoteWranglerConfig;
346
- /** Project root containing `wrangler.jsonc` + the optional `lunora.json`. */
347
+ /** Project root containing `wrangler.jsonc` + the optional `lunora.config.*`. */
347
348
  projectRoot: string;
348
- /** Injection seam — defaults to the real `lunora.json` reader. */
349
+ /** Injection seam — defaults to the real `lunora.config.*` reader. */
349
350
  readPreference?: typeof readProjectRemotePreference;
350
351
  /** The raw `LUNORA_REMOTE` env value; defaults to `process.env.LUNORA_REMOTE`. */
351
352
  remoteEnv?: string;
@@ -356,7 +357,7 @@ interface PlanViteRemoteOptions {
356
357
  * injected materializer; returns a `cleanup` for the dev server's close hook.
357
358
  *
358
359
  * There is no `--remote` flag on the Vite path (Vite has no Lunora CLI flags),
359
- * so the precedence reduces to `LUNORA_REMOTE` env > `lunora.json` `remote`.
360
+ * so the precedence reduces to `LUNORA_REMOTE` env > `lunora.config.*` `remote`.
360
361
  *
361
362
  * Call this from a `config` hook, never at plugin-factory time — see
362
363
  * {@link remoteBindingsPlugin} for the two defects that timing caused.
@@ -558,4 +559,4 @@ declare const resolveOverlayOption: (overlay: LunoraPluginOptions["overlay"]) =>
558
559
  */
559
560
  declare const lunora: (options?: LunoraPluginOptions) => LunoraPlugins;
560
561
  declare const VERSION: string;
561
- export { CLASS_A_WIRING, type ClassAWiring, type CloudflarePluginOptions, GENERATED_CLASS_MODULES, type GeneratedClassModule, LUNORA_API_UPDATED_EVENT, LUNORA_WORKER_VIRTUAL_ID, type LunoraPluginOptions, type LunoraPlugins, type LunoraShardConfig, type OverlayPluginOptions, type PlanViteRemoteOptions, type ResolvedLunoraPluginOptions, STUDIO_PATH, type Solution, type SolutionFinder, VERSION, type ViteRemotePlan, WORKER_STARTUP_HINT, augmentWorkerStartupError, buildStudioUrl, buildWorkerEntrySource, checkLunoraProxy, codegenPlugin, containerLogsPlugin, devStatePlugin, devVariablesPlugin, frameworkComposePlugin, isAutoComposable, isWorkerEntryEvalError, logStreamPlugin, lunora, lunoraSolutionFinder, lunoraSolutionFinders, planViteRemoteBindings, proxyCheckPlugin, remoteBindingsPlugin, resolveOverlayOption, studioPlugin, withRemoteBindings, withWorkerStartupHint, wranglerValidatorPlugin };
562
+ export { CLASS_A_WIRING, type ClassAWiring, type CloudflarePluginOptions, LUNORA_API_UPDATED_EVENT, LUNORA_WORKER_VIRTUAL_ID, type LunoraPluginOptions, type LunoraPlugins, type LunoraShardConfig, type OverlayPluginOptions, type PlanViteRemoteOptions, type ResolvedLunoraPluginOptions, STUDIO_PATH, type Solution, type SolutionFinder, VERSION, type ViteRemotePlan, WORKER_STARTUP_HINT, type WorkerEntryComposition, augmentWorkerStartupError, buildStudioUrl, buildWorkerEntrySource, checkLunoraProxy, codegenPlugin, containerLogsPlugin, devStatePlugin, devVariablesPlugin, frameworkComposePlugin, isAutoComposable, isWorkerEntryEvalError, logStreamPlugin, lunora, lunoraSolutionFinder, lunoraSolutionFinders, planViteRemoteBindings, proxyCheckPlugin, remoteBindingsPlugin, resolveOverlayOption, studioPlugin, withRemoteBindings, withWorkerStartupHint, wranglerValidatorPlugin };
package/dist/index.d.ts CHANGED
@@ -1,8 +1,8 @@
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, readProjectRemotePreference } from '@lunora/config';
5
- export { type DetectedFramework, type FrameworkClass, type FrameworkDetection, detectFramework } from '@lunora/config';
4
+ import { FrameworkDetection, DetectedFramework, GeneratedClassModule, readProjectRemotePreference } from '@lunora/config';
5
+ export { type DetectedFramework, type FrameworkClass, type FrameworkDetection, GENERATED_CLASS_MODULES, type GeneratedClassModule, detectFramework } from '@lunora/config';
6
6
  import { materializeRemoteWranglerConfig } from '@lunora/config/cloudflare';
7
7
  export { type ReconcileCronsResult as ReconcileResult, reconcileWranglerCrons } from '@lunora/config/cloudflare';
8
8
  import { AddressInfo } from 'node:net';
@@ -98,7 +98,7 @@ interface LunoraPluginOptions {
98
98
  studio?: boolean;
99
99
  /**
100
100
  * Deploy target the emitted `ctx.*` surface is tailored to. Defaults to
101
- * `"target"` in `lunora.json`, then `"cloudflare"` — so an existing project
101
+ * `"target"` in `lunora.config.*`, then `"cloudflare"` — so an existing project
102
102
  * emits byte-identical output.
103
103
  *
104
104
  * Set it here only to override the project config for one build — keeping
@@ -238,16 +238,7 @@ declare const CLASS_A_WIRING: Readonly<Partial<Record<DetectedFramework, ClassAW
238
238
  * (class B/C, `none`) falls back to the existing flow.
239
239
  */
240
240
  declare const isAutoComposable: (context: LunoraPluginContext) => boolean;
241
- /**
242
- * The `_generated/` modules whose exported classes wrangler validates a
243
- * `class_name` against: container Durable Objects, workflow entrypoints, and
244
- * agent (workflow) entrypoints — the same three kinds `reconcile-bindings`
245
- * writes into `wrangler.jsonc`. The composed entry star-re-exports each module
246
- * the project actually has.
247
- */
248
- declare const GENERATED_CLASS_MODULES: readonly ["agents", "containers", "workflows"];
249
- /** One {@link GENERATED_CLASS_MODULES} entry. */
250
- type GeneratedClassModule = (typeof GENERATED_CLASS_MODULES)[number];
241
+ /** Trailing `.ts` on the app-config path — the bundler resolves the extension, so the emitted specifier drops it. */
251
242
  /**
252
243
  * Build the source of the virtual class-A worker entry. Pure (no fs / no Vite),
253
244
  * so the emitted composition is unit-testable in isolation.
@@ -263,7 +254,17 @@ type GeneratedClassModule = (typeof GENERATED_CLASS_MODULES)[number];
263
254
  * virtual module id. Absolute paths are resolved correctly in all environments
264
255
  * (Vite 8 + rolldown 1.x confirmed).
265
256
  */
266
- declare const buildWorkerEntrySource: (framework: DetectedFramework, generatedImportBase: string, classModules?: ReadonlyArray<GeneratedClassModule>, allowUnauthenticatedShardAccess?: boolean, shard?: LunoraShardConfig) => string;
257
+ interface WorkerEntryComposition {
258
+ /** Whether to allow unauthenticated shard access — `.extend(...)` on the builder. */
259
+ allowUnauthenticatedShardAccess?: boolean;
260
+ /** Finished specifier for the project's `lunora.config.*`, when it declares an `app` hook. */
261
+ appConfigModule?: string;
262
+ /** The `_generated/` class modules that exist, each star-re-exported. */
263
+ classModules?: ReadonlyArray<GeneratedClassModule>;
264
+ /** Per-shard knobs, each key named after the builder method that sets it. */
265
+ shard?: LunoraShardConfig;
266
+ }
267
+ declare const buildWorkerEntrySource: (framework: DetectedFramework, generatedImportBase: string, composition?: WorkerEntryComposition) => string;
267
268
  /**
268
269
  * Vite plugin that auto-composes a detected class-A meta-framework's SSR
269
270
  * handler with Lunora into one Cloudflare Worker (PLAN4 §2.4 / §3 class-A row).
@@ -343,9 +344,9 @@ interface ViteRemotePlan {
343
344
  interface PlanViteRemoteOptions {
344
345
  /** Injection seam — defaults to the real materializer. */
345
346
  materialize?: typeof materializeRemoteWranglerConfig;
346
- /** Project root containing `wrangler.jsonc` + the optional `lunora.json`. */
347
+ /** Project root containing `wrangler.jsonc` + the optional `lunora.config.*`. */
347
348
  projectRoot: string;
348
- /** Injection seam — defaults to the real `lunora.json` reader. */
349
+ /** Injection seam — defaults to the real `lunora.config.*` reader. */
349
350
  readPreference?: typeof readProjectRemotePreference;
350
351
  /** The raw `LUNORA_REMOTE` env value; defaults to `process.env.LUNORA_REMOTE`. */
351
352
  remoteEnv?: string;
@@ -356,7 +357,7 @@ interface PlanViteRemoteOptions {
356
357
  * injected materializer; returns a `cleanup` for the dev server's close hook.
357
358
  *
358
359
  * There is no `--remote` flag on the Vite path (Vite has no Lunora CLI flags),
359
- * so the precedence reduces to `LUNORA_REMOTE` env > `lunora.json` `remote`.
360
+ * so the precedence reduces to `LUNORA_REMOTE` env > `lunora.config.*` `remote`.
360
361
  *
361
362
  * Call this from a `config` hook, never at plugin-factory time — see
362
363
  * {@link remoteBindingsPlugin} for the two defects that timing caused.
@@ -558,4 +559,4 @@ declare const resolveOverlayOption: (overlay: LunoraPluginOptions["overlay"]) =>
558
559
  */
559
560
  declare const lunora: (options?: LunoraPluginOptions) => LunoraPlugins;
560
561
  declare const VERSION: string;
561
- export { CLASS_A_WIRING, type ClassAWiring, type CloudflarePluginOptions, GENERATED_CLASS_MODULES, type GeneratedClassModule, LUNORA_API_UPDATED_EVENT, LUNORA_WORKER_VIRTUAL_ID, type LunoraPluginOptions, type LunoraPlugins, type LunoraShardConfig, type OverlayPluginOptions, type PlanViteRemoteOptions, type ResolvedLunoraPluginOptions, STUDIO_PATH, type Solution, type SolutionFinder, VERSION, type ViteRemotePlan, WORKER_STARTUP_HINT, augmentWorkerStartupError, buildStudioUrl, buildWorkerEntrySource, checkLunoraProxy, codegenPlugin, containerLogsPlugin, devStatePlugin, devVariablesPlugin, frameworkComposePlugin, isAutoComposable, isWorkerEntryEvalError, logStreamPlugin, lunora, lunoraSolutionFinder, lunoraSolutionFinders, planViteRemoteBindings, proxyCheckPlugin, remoteBindingsPlugin, resolveOverlayOption, studioPlugin, withRemoteBindings, withWorkerStartupHint, wranglerValidatorPlugin };
562
+ export { CLASS_A_WIRING, type ClassAWiring, type CloudflarePluginOptions, LUNORA_API_UPDATED_EVENT, LUNORA_WORKER_VIRTUAL_ID, type LunoraPluginOptions, type LunoraPlugins, type LunoraShardConfig, type OverlayPluginOptions, type PlanViteRemoteOptions, type ResolvedLunoraPluginOptions, STUDIO_PATH, type Solution, type SolutionFinder, VERSION, type ViteRemotePlan, WORKER_STARTUP_HINT, type WorkerEntryComposition, augmentWorkerStartupError, buildStudioUrl, buildWorkerEntrySource, checkLunoraProxy, codegenPlugin, containerLogsPlugin, devStatePlugin, devVariablesPlugin, frameworkComposePlugin, isAutoComposable, isWorkerEntryEvalError, logStreamPlugin, lunora, lunoraSolutionFinder, lunoraSolutionFinders, planViteRemoteBindings, proxyCheckPlugin, remoteBindingsPlugin, resolveOverlayOption, studioPlugin, withRemoteBindings, withWorkerStartupHint, wranglerValidatorPlugin };
package/dist/index.mjs CHANGED
@@ -1,3 +1,3 @@
1
- import{createRequire as i}from"node:module";import{cloudflare as l}from"@cloudflare/vite-plugin";import{detectAgentRules as s,claimAgentRulesHint as u,AGENT_RULES_HINT as c,detectFramework as f,resolveTargetOrThrow as d,isRunnableTarget as m,runnableTargetIds as p}from"@lunora/config";import{detectFramework as ar}from"@lunora/config";import g from"@visulima/vite-overlay";import{l as a}from"./packem_shared/log-DE48L4Oz.mjs";import{r as S,c as v}from"./packem_shared/codegen-plugin-dg384k5b.mjs";import w from"./packem_shared/containerLogsPlugin-CWkqSCL3.mjs";import R from"./packem_shared/devStatePlugin-CcFV-eBl.mjs";import h from"./packem_shared/devVariablesPlugin-DY_bJXsX.mjs";import{frameworkComposePlugin as k}from"./packem_shared/CLASS_A_WIRING-DhnXqptk.mjs";import{CLASS_A_WIRING as lr,GENERATED_CLASS_MODULES as sr,LUNORA_WORKER_VIRTUAL_ID as ur,buildWorkerEntrySource as cr,isAutoComposable as fr}from"./packem_shared/CLASS_A_WIRING-DhnXqptk.mjs";import P from"./packem_shared/logStreamPlugin-DtOu5VX8.mjs";import{proxyCheckPlugin as A}from"./packem_shared/checkLunoraProxy-C9M8c5eS.mjs";import{checkLunoraProxy as mr}from"./packem_shared/checkLunoraProxy-C9M8c5eS.mjs";import{remoteBindingsPlugin as E}from"./packem_shared/planViteRemoteBindings-E3GdC6pY.mjs";import{planViteRemoteBindings as gr,withRemoteBindings as Sr}from"./packem_shared/planViteRemoteBindings-E3GdC6pY.mjs";import{lunoraSolutionFinders as T}from"./packem_shared/lunoraSolutionFinder--J0x2mAM.mjs";import{lunoraSolutionFinder as wr}from"./packem_shared/lunoraSolutionFinder--J0x2mAM.mjs";import{studioPlugin as _}from"./packem_shared/STUDIO_PATH-UztnV2ca.mjs";import{STUDIO_PATH as hr,buildStudioUrl as kr}from"./packem_shared/STUDIO_PATH-UztnV2ca.mjs";import{withWorkerStartupHint as x}from"./packem_shared/WORKER_STARTUP_HINT-COlRTY32.mjs";import{WORKER_STARTUP_HINT as Ar,augmentWorkerStartupError as Er,isWorkerEntryEvalError as Tr}from"./packem_shared/WORKER_STARTUP_HINT-COlRTY32.mjs";import{wranglerValidatorPlugin as O}from"./packem_shared/wranglerValidatorPlugin-BdKLAEoq.mjs";import{default as xr}from"./packem_shared/LUNORA_API_UPDATED_EVENT-CO2Rv2re.mjs";import{reconcileWranglerCrons as br}from"@lunora/config/cloudflare";const b=o=>({apply:"serve",configureServer(r){return()=>{s(o.projectRoot).installed||!u()||r.config.logger.warn(`
1
+ import{createRequire as i}from"node:module";import{cloudflare as l}from"@cloudflare/vite-plugin";import{detectAgentRules as s,claimAgentRulesHint as u,AGENT_RULES_HINT as c,detectFramework as f,resolveTargetOrThrow as d,isRunnableTarget as m,runnableTargetIds as p}from"@lunora/config";import{GENERATED_CLASS_MODULES as ar,detectFramework as ir}from"@lunora/config";import g from"@visulima/vite-overlay";import{l as a}from"./packem_shared/log-DE48L4Oz.mjs";import{r as S,c as v}from"./packem_shared/codegen-plugin-CnF5a3-x.mjs";import w from"./packem_shared/containerLogsPlugin-CWkqSCL3.mjs";import R from"./packem_shared/devStatePlugin-CcFV-eBl.mjs";import h from"./packem_shared/devVariablesPlugin-DY_bJXsX.mjs";import{frameworkComposePlugin as k}from"./packem_shared/CLASS_A_WIRING-B4-x5Aws.mjs";import{CLASS_A_WIRING as sr,LUNORA_WORKER_VIRTUAL_ID as ur,buildWorkerEntrySource as cr,isAutoComposable as fr}from"./packem_shared/CLASS_A_WIRING-B4-x5Aws.mjs";import P from"./packem_shared/logStreamPlugin-DtOu5VX8.mjs";import{proxyCheckPlugin as A}from"./packem_shared/checkLunoraProxy-C9M8c5eS.mjs";import{checkLunoraProxy as mr}from"./packem_shared/checkLunoraProxy-C9M8c5eS.mjs";import{remoteBindingsPlugin as E}from"./packem_shared/planViteRemoteBindings-E3GdC6pY.mjs";import{planViteRemoteBindings as gr,withRemoteBindings as Sr}from"./packem_shared/planViteRemoteBindings-E3GdC6pY.mjs";import{lunoraSolutionFinders as T}from"./packem_shared/lunoraSolutionFinder--J0x2mAM.mjs";import{lunoraSolutionFinder as wr}from"./packem_shared/lunoraSolutionFinder--J0x2mAM.mjs";import{studioPlugin as _}from"./packem_shared/STUDIO_PATH-UztnV2ca.mjs";import{STUDIO_PATH as hr,buildStudioUrl as kr}from"./packem_shared/STUDIO_PATH-UztnV2ca.mjs";import{withWorkerStartupHint as x}from"./packem_shared/WORKER_STARTUP_HINT-COlRTY32.mjs";import{WORKER_STARTUP_HINT as Ar,augmentWorkerStartupError as Er,isWorkerEntryEvalError as Tr}from"./packem_shared/WORKER_STARTUP_HINT-COlRTY32.mjs";import{wranglerValidatorPlugin as O}from"./packem_shared/wranglerValidatorPlugin-BdKLAEoq.mjs";import{default as xr}from"./packem_shared/LUNORA_API_UPDATED_EVENT-CO2Rv2re.mjs";import{reconcileWranglerCrons as br}from"@lunora/config/cloudflare";const b=o=>({apply:"serve",configureServer(r){return()=>{s(o.projectRoot).installed||!u()||r.config.logger.warn(`
2
2
  ${a(c)}
3
- `)}},name:"lunora:agent-rules-hint"}),y=o=>({async config(r,t){t.isPreview!==!0&&await S(o,{info:e=>{console.info(e)},warn:e=>{console.warn(e)}})},enforce:"pre",name:"lunora:bindings-provision"}),L=()=>({}),W={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)"},D=o=>{const r=W[o.framework];return o.framework==="none"?a("no meta-framework detected — running standalone."):o.class==="B"?a(`detected ${r} — composition is handled by the framework adapter.`):a(`detected ${r} — composing the Lunora worker into one Cloudflare Worker.`)},C=(o,r)=>{let t=!1;const e=()=>{r.framework??=f(o.projectRoot)};return{config(){e()},configResolved(){e()},configureServer(){e(),!t&&r.framework!==void 0&&(t=!0,console.info(D(r.framework)))},name:"lunora:framework-detect"}},N=o=>{if(o===!1)return!1;const r=o===!0||o===void 0?{}:o;return{...r,forwardedConsoleMethods:r.forwardedConsoleMethods??["error","warn"],solutionFinders:[...T,...r.solutionFinders??[]]}},U=(o,r)=>{const t=d(o,r);if(!m(t)){const e=p();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: ${e.join(", ")}`)}return t},I=o=>{const r=o??{},t=r.schemaDir??"lunora";let e;r.cloudflare===!1?e=!1:r.cloudflare===!0||r.cloudflare===void 0?e={}:e=r.cloudflare;const n=r.projectRoot??process.cwd();return{allowUnauthenticatedShardAccess:r.allowUnauthenticatedShardAccess??!1,apiSpec:r.apiSpec??"openapi",cloudflare:e,studio:r.studio??!0,generatedDir:`${t}/_generated`,overlay:N(r.overlay),projectRoot:n,schemaDir:t,shard:r.shard??{},target:U(n,r.target),validateWrangler:r.validateWrangler??!0}},er=o=>{const r=I(o),t=L(),e=[C(r,t),k(r,t),h(r),y(r),v(r),P(),R(r),b(r),A()];r.studio&&e.push(_(r)),r.validateWrangler&&e.push(O(r)),r.overlay!==!1&&e.push(g(r.overlay)),e.push(w(r));const n=r.cloudflare===!1?void 0:{...r.cloudflare};return e.push(E(n,{projectRoot:r.projectRoot})),n!==void 0&&e.push(...x(l(n))),e},or=i(import.meta.url)("../package.json").version;export{lr as CLASS_A_WIRING,sr as GENERATED_CLASS_MODULES,xr as LUNORA_API_UPDATED_EVENT,ur as LUNORA_WORKER_VIRTUAL_ID,hr as STUDIO_PATH,or as VERSION,Ar as WORKER_STARTUP_HINT,Er as augmentWorkerStartupError,kr as buildStudioUrl,cr as buildWorkerEntrySource,mr as checkLunoraProxy,v as codegenPlugin,w as containerLogsPlugin,ar as detectFramework,R as devStatePlugin,h as devVariablesPlugin,k as frameworkComposePlugin,fr as isAutoComposable,Tr as isWorkerEntryEvalError,P as logStreamPlugin,er as lunora,wr as lunoraSolutionFinder,T as lunoraSolutionFinders,gr as planViteRemoteBindings,A as proxyCheckPlugin,br as reconcileWranglerCrons,E as remoteBindingsPlugin,N as resolveOverlayOption,_ as studioPlugin,Sr as withRemoteBindings,x as withWorkerStartupHint,O as wranglerValidatorPlugin};
3
+ `)}},name:"lunora:agent-rules-hint"}),y=o=>({async config(r,t){t.isPreview!==!0&&await S(o,{info:e=>{console.info(e)},warn:e=>{console.warn(e)}})},enforce:"pre",name:"lunora:bindings-provision"}),L=()=>({}),W={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)"},D=o=>{const r=W[o.framework];return o.framework==="none"?a("no meta-framework detected — running standalone."):o.class==="B"?a(`detected ${r} — composition is handled by the framework adapter.`):a(`detected ${r} — composing the Lunora worker into one Cloudflare Worker.`)},C=(o,r)=>{let t=!1;const e=()=>{r.framework??=f(o.projectRoot)};return{config(){e()},configResolved(){e()},configureServer(){e(),!t&&r.framework!==void 0&&(t=!0,console.info(D(r.framework)))},name:"lunora:framework-detect"}},N=o=>{if(o===!1)return!1;const r=o===!0||o===void 0?{}:o;return{...r,forwardedConsoleMethods:r.forwardedConsoleMethods??["error","warn"],solutionFinders:[...T,...r.solutionFinders??[]]}},U=(o,r)=>{const t=d(o,r);if(!m(t)){const e=p();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: ${e.join(", ")}`)}return t},I=o=>{const r=o??{},t=r.schemaDir??"lunora";let e;r.cloudflare===!1?e=!1:r.cloudflare===!0||r.cloudflare===void 0?e={}:e=r.cloudflare;const n=r.projectRoot??process.cwd();return{allowUnauthenticatedShardAccess:r.allowUnauthenticatedShardAccess??!1,apiSpec:r.apiSpec??"openapi",cloudflare:e,studio:r.studio??!0,generatedDir:`${t}/_generated`,overlay:N(r.overlay),projectRoot:n,schemaDir:t,shard:r.shard??{},target:U(n,r.target),validateWrangler:r.validateWrangler??!0}},er=o=>{const r=I(o),t=L(),e=[C(r,t),k(r,t),h(r),y(r),v(r),P(),R(r),b(r),A()];r.studio&&e.push(_(r)),r.validateWrangler&&e.push(O(r)),r.overlay!==!1&&e.push(g(r.overlay)),e.push(w(r));const n=r.cloudflare===!1?void 0:{...r.cloudflare};return e.push(E(n,{projectRoot:r.projectRoot})),n!==void 0&&e.push(...x(l(n))),e},or=i(import.meta.url)("../package.json").version;export{sr as CLASS_A_WIRING,ar as GENERATED_CLASS_MODULES,xr as LUNORA_API_UPDATED_EVENT,ur as LUNORA_WORKER_VIRTUAL_ID,hr as STUDIO_PATH,or as VERSION,Ar as WORKER_STARTUP_HINT,Er as augmentWorkerStartupError,kr as buildStudioUrl,cr as buildWorkerEntrySource,mr as checkLunoraProxy,v as codegenPlugin,w as containerLogsPlugin,ir as detectFramework,R as devStatePlugin,h as devVariablesPlugin,k as frameworkComposePlugin,fr as isAutoComposable,Tr as isWorkerEntryEvalError,P as logStreamPlugin,er as lunora,wr as lunoraSolutionFinder,T as lunoraSolutionFinders,gr as planViteRemoteBindings,A as proxyCheckPlugin,br as reconcileWranglerCrons,E as remoteBindingsPlugin,N as resolveOverlayOption,_ as studioPlugin,Sr as withRemoteBindings,x as withWorkerStartupHint,O as wranglerValidatorPlugin};
@@ -0,0 +1,23 @@
1
+ import{existsSync as $}from"node:fs";import{resolve as g,join as k}from"node:path";import{loadProjectConfig as E,findProjectConfigFile as C}from"@lunora/codegen";import{GENERATED_CLASS_MODULES as L}from"@lunora/config";import{LunoraError as M}from"@lunora/errors";const f="virtual:lunora/worker",_="\0",p=`${_}${f}`,I=`// @lunora/vite — the composed worker entry is worker-only and unavailable in the client environment.
2
+ export default {};
3
+ `,O=/\/$/,m={"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";'}},u=r=>{const e=r.framework;return e?.class==="A"&&m[e.framework]!==void 0},D=(r,e,o={})=>{const{allowUnauthenticatedShardAccess:a=!1,appConfigModule:n,classModules:s=[],shard:l={}}=o,i=m[r];if(i===void 0)throw new M("INTERNAL",`[lunora] no class-A worker wiring for framework "${r}"`);const c=e.replaceAll("\\","/"),h=s.map(t=>`
4
+ export * from "${c}/${t}";
5
+ `).join(""),v=s.includes("scheduler")?`
6
+ .scheduler({ namespace: (env) => env.SCHEDULER })`:"",w=n===void 0?"":`
7
+ import lunoraConfig from "${n}";`,[A,R]=n===void 0?["",""]:["lunoraConfig.app(",")"],S=Object.entries(l).filter(([,t])=>t!==void 0).toSorted(([t],[d])=>t.localeCompare(d)).map(([t,d])=>`
8
+ .${t}(${JSON.stringify(d)})`).join("");return`// Generated by @lunora/vite — class-A worker composition (PLAN4 M2).
9
+ // Do not edit: emitted from the detected framework (${r}). Point your
10
+ // wrangler \`main\` here (or re-export it) instead of hand-wiring createWorker.
11
+ ${i.imports}
12
+ import { defineApp } from "${c}/app";${w}
13
+
14
+ const app = ${A}defineApp()
15
+ .shard((env) => env.SHARD)${v}${R}
16
+ .httpRouter(${i.handler})${S}${a?`
17
+ .extend(() => ({ allowUnauthenticatedShardAccess: true }))`:""}
18
+ .build();
19
+
20
+ export const ShardDO = app.ShardDO;
21
+ ${h}
22
+ export default app;
23
+ `},y=async r=>{const{config:e,error:o}=await E(r);return o!==void 0?{error:o}:typeof e?.app!="function"?{}:{specifier:C(r)?.replaceAll("\\","/")}},T=(r,e)=>{const o=g(r.projectRoot,r.generatedDir.replace(O,""));return{async load(a){if(a===p&&u(e)&&e.framework!==void 0){if(this.environment.name==="client")return I;const n=L.filter(i=>$(k(o,`${i}.ts`))),{error:s,specifier:l}=await y(r.projectRoot);return s!==void 0&&this.warn(`[lunora] lunora.config could not be loaded, so its \`app\` hook was not composed: ${s}`),D(e.framework.framework,o,{allowUnauthenticatedShardAccess:r.allowUnauthenticatedShardAccess,appConfigModule:l,classModules:n,shard:r.shard})}},name:"lunora:framework-compose",resolveId(a){if(a===f&&u(e))return p}}};export{m as CLASS_A_WIRING,f as LUNORA_WORKER_VIRTUAL_ID,p as RESOLVED_LUNORA_WORKER_ID,D as buildWorkerEntrySource,T as frameworkComposePlugin,u as isAutoComposable};
@@ -0,0 +1,3 @@
1
+ import{readFileSync as V,existsSync as W}from"node:fs";import{join as J,resolve as w,sep as b,basename as Q}from"node:path";import{findProjectConfigFile as Y,listLunoraSourceFiles as Z,PROJECT_CONFIG_FILENAMES as ee,findTsconfig as ne,runCodegen as re,describeErrorLevelFindings as te,createCodegenProject as oe,refreshCodegenProject as ie,CodegenDiagnosticError as ae}from"@lunora/codegen";import{inferLunoraBindings as ce,isCodegenDisabled as se,CODEGEN_ENV as F,runPostCodegenHook as A}from"@lunora/config";import{findWranglerFile as le,readWranglerJsonc as de,reconcileWranglerBindings as fe,reconcileWranglerCrons as ge,describePreservedCrons as ue,reconcileWranglerCompatibilityDate as he,WRANGLER_FILES as me,collectWranglerSecretVariables as pe}from"@lunora/config/cloudflare";import{isRunnableDevEnvironment as we}from"vite";import{createHash as H}from"node:crypto";import ye from"./LUNORA_API_UPDATED_EVENT-CO2Rv2re.mjs";import{L as d,a as L}from"./log-DE48L4Oz.mjs";import{r as $e,a as ve}from"./server-close-Qoh4i6Ay.mjs";const Se=(e,r)=>{try{const{parsed:t,text:n}=de(e);return t===void 0?`raw:${n}`:JSON.stringify(r?r(t):t)}catch{return"unreadable"}},Ee=e=>{const r={...e},{triggers:t}=r;if(t!==null&&typeof t=="object"){const n={...t};delete n.crons,Object.keys(n).length>0?r.triggers=n:delete r.triggers}return r},N=e=>{const r=le(e),t=r===void 0?"absent":Se(r,Ee),n=Y(e);let o="absent";try{n!==void 0&&(o=H("sha256").update(V(n)).digest("hex"))}catch{}return`${t}\0${o}`},be=async(e,r,t)=>{try{const n=await ce({projectRoot:e.projectRoot,schemaDir:e.schemaDir}),o=fe(e.projectRoot,n);o.changed&&r.info?.(`${d} inferred bindings → ${o.added.join(", ")} (written to ${o.wranglerPath??"wrangler.jsonc"})`);for(const a of o.warnings)r.warn(`${d} ${a}`);o.exportGaps.length>0&&t?.(o.exportGaps)}catch(n){const o=n instanceof Error?n.message:String(n);r.warn(`${d} binding inference skipped: ${o}`)}},G=new Map,Re=(e,r,t)=>{try{const n=ge(e,r);n.changed&&t.info?.(`${d} synced ${r.length.toFixed(0)} cron trigger(s) into ${n.wranglerPath??"wrangler.jsonc"}`);for(const l of n.warnings)t.warn(`${d} ${l}`);const o=n.preserved.join("\0"),a=ue(n.preserved);a!==void 0&&(n.changed||G.get(e)!==o)&&t.info?.(`${d} ${a}`),G.set(e,o)}catch(n){const o=n instanceof Error?n.message:String(n);t.warn(`${d} cron trigger sync skipped: ${o}`)}try{const n=he(e);n.changed&&t.info?.(`${d} bumped compatibility_date to ${n.date??"unknown"} (Workers Cache enabled) → ${n.wranglerPath??"wrangler.jsonc"}`)}catch(n){const o=n instanceof Error?n.message:String(n);t.warn(`${d} compatibility date sync skipped: ${o}`)}},ke=100,z=300,I=2,Ce=e=>{let r,t,n=0;const o=()=>{r&&(clearTimeout(r),r=void 0)},a=(g,u)=>{t&&clearTimeout(t),t=setTimeout(()=>{if(t=void 0,e.fingerprint()!==g){if(n+=1,n>I){e.logger.warn(`${d} \`postcodegen\` keeps rewriting the schema sources — stopping after ${String(I)} reruns. Make the hook idempotent or move it off the schema directory.`);return}e.logger.info(`${d} schema changed while \`postcodegen\` was running — regenerating`),u()}},z)},l=g=>{e.regenerate(g,u=>{a(u,()=>{l(g)})})};return{cancelPending:o,dispose:()=>{o(),t&&(clearTimeout(t),t=void 0)},onSave:g=>{o(),n=0,r=setTimeout(()=>{r=void 0,l(g)},ke)}}},B=e=>{if(!W(e))return"unreadable";const r=Z(e),t=J(e,"schema.ts");W(t)&&r.push(t);const n=H("sha256");for(const o of r.toSorted((a,l)=>a.localeCompare(l)))try{n.update(o).update("\0").update(V(o))}catch{}return n.digest("hex")},U=/[/\\]tsconfig\..+\.json$/u,je=e=>{const r=e.map(n=>` • ${n.kind} "${n.exportName}" — class ${n.className} is not exported by your worker entry.`),t=[...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.`,...r,"","Add to your worker entry:",...t].join(`
2
+ `)},De=e=>{const{advisoryNames:r,platformDiagnosticNames:t}=te(e),n=[...new Set([...r,...t])].toSorted((a,l)=>a.localeCompare(l));if(n.length===0)return;const o=n.length===1?"advisory/platform diagnostic":"advisories/platform diagnostics";return`${d} ${String(n.length)} ERROR-level ${o} (${n.join(", ")}) — see the log above for detail.`},Pe=(e,r,t)=>{if(r.warn(`${d} schema.ts not found at ${e} — codegen skipped`),t!==void 0){const n=`schema.ts not found at ${e} — generated output is now stale`;t.onError(new Error(n),n)}},O=(e,r,t,n)=>{const o=J(e.projectRoot,e.schemaDir,"schema.ts");if(!W(o))return Pe(o,r,t),{};try{const a=re({apiSpec:e.apiSpec,lunoraDirectory:e.schemaDir,project:n,projectRoot:e.projectRoot,target:e.target,wranglerVariables:pe(e.projectRoot)});Re(e.projectRoot,a.cronTriggers,r);for(const l of a.advisories){const g=L(l.level,l.name,l.detail,l.remediation);l.level==="ERROR"?r.error(g):r.warn(g)}for(const l of a.platformDiagnostics){const g=L(l.level==="error"?"ERROR":"WARN",l.name,l.message,l.remediation);l.level==="error"?r.error(g):r.warn(g)}return{blockingMessage:De(a),outputDirectory:w(a.outputDirectory)}}catch(a){const l=a instanceof Error?a.message:String(a);return r.error(`${d} codegen failed: ${l}`),t?.onError(a,l),{failure:`${d} codegen failed: ${l}`}}},_e=(e,r,t)=>{let n;for(const[o,a]of Object.entries(e.environments)){if(o==="client"){n=a;continue}we(a)||a.hot.send({path:"*",triggeredBy:r,type:"full-reload"})}if(n===void 0){e.hot.send({type:"full-reload"});return}if(t){n.hot.send({type:"full-reload"});return}n.hot.send({event:ye,type:"custom"})},k={error:e=>{console.error(e)},info:e=>{console.info(e)},warn:e=>{console.warn(e)}},Ie=e=>{const r=w(e.projectRoot,e.schemaDir),t=se(process.env[F]);let n=w(e.projectRoot,e.generatedDir),o=0,a=!1,l;const g=new Map;let u,C=!1,j=!1,y,D;return{config(c,m){y=m.command},configResolved(){y!=="build"&&t||(D=O(e,k))},async buildStart(){const c=y!=="build"&&t,{blockingMessage:m,failure:$,outputDirectory:R}=D??(c?{}:O(e,k));if(D=void 0,y==="build"&&$!==void 0&&this.error($),R!==void 0){n=R,a=!0;let h;try{h=await A({cwd:e.projectRoot,logger:k})}finally{a=!1}h.ran&&(o=Date.now()),y==="build"&&h.error!==void 0&&this.error(h.error)}y==="build"&&m!==void 0&&this.error(m),await be(e,k,h=>{l?.hot.send({err:{loc:void 0,message:je(h),stack:""},type:"error"})}),l!==void 0&&(u=N(e.projectRoot),C=!0)},configureServer(c){l=c,c.watcher.add(r),u=N(e.projectRoot),C=!1;const m={error:i=>{c.config.logger.error(i)},info:i=>{c.config.logger.info(i)},warn:i=>{c.config.logger.warn(i)}};let $=!1;const R={onError(i,s){$=!0;const f=i instanceof ae?{column:i.column,file:i.file,line:i.line}:void 0,E=f===void 0?`[lunora] codegen failed: ${s}
3
+ (see terminal for full stack trace and file location)`:`[lunora] codegen failed: ${s}`;l?.hot.send({err:{loc:f,message:E,stack:i instanceof Error?i.stack??"":""},type:"error"})}},h=(i,s)=>i===s||i.startsWith(s+b);let P=!1,p;const K=()=>{for(const i of Object.values(c.environments)){const s=i.moduleGraph;for(const f of s.idToModuleMap.values())f.id&&h(f.id,n)&&s.invalidateModule(f)}},X=async(i,s)=>{try{if(P)return;p===void 0?p=oe(r):ie(p,r);const{outputDirectory:f}=O(e,m,R,p);if(f===void 0){p=void 0;return}n=f;const E=B(r);a=!0;let T;try{T=await A({cwd:e.projectRoot,logger:m})}finally{a=!1}if(T.ran&&(o=Date.now(),s(E)),T.error!==void 0)return;K(),_e(c,i,$),$=!1}catch(f){m.error(`${d} codegen watch: ${f instanceof Error?f.message:String(f)}`)}},_=Ce({fingerprint:()=>B(r),logger:m,regenerate:(i,s)=>{X(i,s)}}),v=i=>{const s=w(i);if(U.test(s)){p=void 0;return}if(s.endsWith(`${b}tsconfig.json`)&&s===ne(r)){p=void 0;return}if(h(s,r)&&!h(s,n)&&s.endsWith(".ts")&&!(s.includes(`${b}__tests__${b}`)||s.endsWith(".test.ts")||s.endsWith(".spec.ts"))){if(a||Date.now()-o<z){_.cancelPending();return}_.onSave(s)}},x=i=>{const s=w(i);(s.endsWith(`${b}tsconfig.json`)||U.test(s))&&(p=void 0)};t?c.config.logger.info(`${d} codegen watch disabled (${F}) — _generated/ is written only by an explicit \`lunora codegen\``):(c.watcher.on("add",v),c.watcher.on("change",v),c.watcher.on("unlink",v),c.watcher.on("unlink",x));const M=new Set([...me.map(i=>w(e.projectRoot,i)),...ee.map(i=>w(e.projectRoot,i))]);for(const i of M)c.watcher.add(i);const S=i=>{if(!M.has(w(i))||j)return;const s=N(e.projectRoot);if(!C){u=s;return}if(u===void 0){u=s;return}s!==u&&(u=s,j=!0,c.config.logger.info(`${d} ${Q(w(i))} changed — restarting dev server`),Promise.resolve(c.restart()).finally(()=>{j=!1}).catch(f=>{const E=f instanceof Error?f.message:String(f);c.config.logger.error(`${d} dev server restart failed: ${E} — keeping the running server; re-save your config to retry.`),c.hot.send({err:{loc:void 0,message:`[lunora] dev server restart failed: ${E}`,stack:""},type:"error"})}))};c.watcher.on("add",S),c.watcher.on("change",S),c.watcher.on("unlink",S);const q=()=>{P||(P=!0,p=void 0,_.dispose(),c.watcher.off("add",v),c.watcher.off("change",v),c.watcher.off("unlink",v),c.watcher.off("unlink",x),c.watcher.off("add",S),c.watcher.off("change",S),c.watcher.off("unlink",S))};return()=>{ve(c,g,q)}},buildEnd(){$e(g,this.environment)},name:"lunora:codegen"}};export{Ie as c,be as r};
@@ -1 +1 @@
1
- import{c as i}from"./codegen-plugin-dg384k5b.mjs";import"./LUNORA_API_UPDATED_EVENT-CO2Rv2re.mjs";import"./log-DE48L4Oz.mjs";import"./server-close-Qoh4i6Ay.mjs";export{i as default};
1
+ import{c as i}from"./codegen-plugin-CnF5a3-x.mjs";import"./LUNORA_API_UPDATED_EVENT-CO2Rv2re.mjs";import"./log-DE48L4Oz.mjs";import"./server-close-Qoh4i6Ay.mjs";export{i as default};
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@lunora/vite",
3
- "version": "1.0.0-alpha.210",
3
+ "version": "1.0.0-alpha.212",
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.54.4",
49
- "@lunora/codegen": "1.0.0-alpha.173",
50
- "@lunora/config": "1.0.0-alpha.210",
49
+ "@lunora/codegen": "1.0.0-alpha.175",
50
+ "@lunora/config": "1.0.0-alpha.212",
51
51
  "@lunora/errors": "1.0.0-alpha.35",
52
52
  "@visulima/vite-overlay": "2.0.20"
53
53
  },
@@ -1,21 +0,0 @@
1
- import{existsSync as h}from"node:fs";import{resolve as v,join as R}from"node:path";import{LunoraError as w}from"@lunora/errors";const m="virtual:lunora/worker",A="\0",d=`${A}${m}`,k=`// @lunora/vite — the composed worker entry is worker-only and unavailable in the client environment.
2
- export default {};
3
- `,S=/\/$/,u={"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";'}},c=r=>{const e=r.framework;return e?.class==="A"&&u[e.framework]!==void 0},E=["agents","containers","workflows"],$=(r,e,a=[],o=!1,n={})=>{const s=u[r];if(s===void 0)throw new w("INTERNAL",`[lunora] no class-A worker wiring for framework "${r}"`);const l=e.replaceAll("\\","/"),p=a.map(t=>`
4
- export * from "${l}/${t}";
5
- `).join(""),f=Object.entries(n).filter(([,t])=>t!==void 0).toSorted(([t],[i])=>t.localeCompare(i)).map(([t,i])=>`
6
- .${t}(${JSON.stringify(i)})`).join("");return`// Generated by @lunora/vite — class-A worker composition (PLAN4 M2).
7
- // Do not edit: emitted from the detected framework (${r}). Point your
8
- // wrangler \`main\` here (or re-export it) instead of hand-wiring createWorker.
9
- ${s.imports}
10
- import { defineApp } from "${l}/app";
11
-
12
- const app = defineApp()
13
- .shard((env) => env.SHARD)
14
- .httpRouter(${s.handler})${f}${o?`
15
- .extend(() => ({ allowUnauthenticatedShardAccess: true }))`:""}
16
- .build();
17
-
18
- export const ShardDO = app.ShardDO;
19
- ${p}
20
- export default app;
21
- `},O=(r,e)=>{const a=v(r.projectRoot,r.generatedDir.replace(S,""));return{load(o){if(o===d&&c(e)&&e.framework!==void 0){if(this.environment.name==="client")return k;const n=E.filter(s=>h(R(a,`${s}.ts`)));return $(e.framework.framework,a,n,r.allowUnauthenticatedShardAccess,r.shard)}},name:"lunora:framework-compose",resolveId(o){if(o===m&&c(e))return d}}};export{u as CLASS_A_WIRING,E as GENERATED_CLASS_MODULES,m as LUNORA_WORKER_VIRTUAL_ID,d as RESOLVED_LUNORA_WORKER_ID,$ as buildWorkerEntrySource,O as frameworkComposePlugin,c as isAutoComposable};
@@ -1,3 +0,0 @@
1
- import{existsSync as j,readFileSync as X}from"node:fs";import{join as N,resolve as p,sep as k,basename as q}from"node:path";import{listLunoraSourceFiles as Q,findTsconfig as Y,runCodegen as Z,describeErrorLevelFindings as ee,createCodegenProject as ne,refreshCodegenProject as re,CodegenDiagnosticError as te}from"@lunora/codegen";import{LUNORA_CONFIG_FILE as V,inferLunoraBindings as oe,isCodegenDisabled as ie,CODEGEN_ENV as x,runPostCodegenHook as M}from"@lunora/config";import{findWranglerFile as ae,readWranglerJsonc as ce,reconcileWranglerBindings as se,reconcileWranglerCrons as le,describePreservedCrons as de,reconcileWranglerCompatibilityDate as fe,WRANGLER_FILES as ge,collectWranglerSecretVariables as ue}from"@lunora/config/cloudflare";import{isRunnableDevEnvironment as he}from"vite";import me from"./LUNORA_API_UPDATED_EVENT-CO2Rv2re.mjs";import{L as d,a as A}from"./log-DE48L4Oz.mjs";import{createHash as pe}from"node:crypto";import{r as we,a as ye}from"./server-close-Qoh4i6Ay.mjs";const F=(n,r)=>{try{const{parsed:t,text:e}=ce(n);return t===void 0?`raw:${e}`:JSON.stringify(r?r(t):t)}catch{return"unreadable"}},$e=n=>{const r={...n},{triggers:t}=r;if(t!==null&&typeof t=="object"){const e={...t};delete e.crons,Object.keys(e).length>0?r.triggers=e:delete r.triggers}return r},T=n=>{const r=ae(n),t=r===void 0?"absent":F(r,$e),e=N(n,V),o=j(e)?F(e):"absent";return`${t}\0${o}`},ve=async(n,r,t)=>{try{const e=await oe({projectRoot:n.projectRoot,schemaDir:n.schemaDir}),o=se(n.projectRoot,e);o.changed&&r.info?.(`${d} inferred bindings → ${o.added.join(", ")} (written to ${o.wranglerPath??"wrangler.jsonc"})`);for(const c of o.warnings)r.warn(`${d} ${c}`);o.exportGaps.length>0&&t?.(o.exportGaps)}catch(e){const o=e instanceof Error?e.message:String(e);r.warn(`${d} binding inference skipped: ${o}`)}},L=new Map,Se=(n,r,t)=>{try{const e=le(n,r);e.changed&&t.info?.(`${d} synced ${r.length.toFixed(0)} cron trigger(s) into ${e.wranglerPath??"wrangler.jsonc"}`);for(const l of e.warnings)t.warn(`${d} ${l}`);const o=e.preserved.join("\0"),c=de(e.preserved);c!==void 0&&(e.changed||L.get(n)!==o)&&t.info?.(`${d} ${c}`),L.set(n,o)}catch(e){const o=e instanceof Error?e.message:String(e);t.warn(`${d} cron trigger sync skipped: ${o}`)}try{const e=fe(n);e.changed&&t.info?.(`${d} bumped compatibility_date to ${e.date??"unknown"} (Workers Cache enabled) → ${e.wranglerPath??"wrangler.jsonc"}`)}catch(e){const o=e instanceof Error?e.message:String(e);t.warn(`${d} compatibility date sync skipped: ${o}`)}},be=100,H=300,G=2,Ee=n=>{let r,t,e=0;const o=()=>{r&&(clearTimeout(r),r=void 0)},c=(u,h)=>{t&&clearTimeout(t),t=setTimeout(()=>{if(t=void 0,n.fingerprint()!==u){if(e+=1,e>G){n.logger.warn(`${d} \`postcodegen\` keeps rewriting the schema sources — stopping after ${String(G)} reruns. Make the hook idempotent or move it off the schema directory.`);return}n.logger.info(`${d} schema changed while \`postcodegen\` was running — regenerating`),h()}},H)},l=u=>{n.regenerate(u,h=>{c(h,()=>{l(u)})})};return{cancelPending:o,dispose:()=>{o(),t&&(clearTimeout(t),t=void 0)},onSave:u=>{o(),e=0,r=setTimeout(()=>{r=void 0,l(u)},be)}}},I=n=>{if(!j(n))return"unreadable";const r=Q(n),t=N(n,"schema.ts");j(t)&&r.push(t);const e=pe("sha256");for(const o of r.toSorted((c,l)=>c.localeCompare(l)))try{e.update(o).update("\0").update(X(o))}catch{}return e.digest("hex")},B=/[/\\]tsconfig\..+\.json$/u,ke=n=>{const r=n.map(e=>` • ${e.kind} "${e.exportName}" — class ${e.className} is not exported by your worker entry.`),t=[...new Set(n.map(e=>e.module))].map(e=>` export * from "./lunora/_generated/${e}";`);return[`[lunora] ${String(n.length)} declared ${n.length===1?"binding is":"bindings are"} not exported by your worker entry — \`wrangler deploy\` will fail.`,...r,"","Add to your worker entry:",...t].join(`
2
- `)},Re=n=>{const{advisoryNames:r,platformDiagnosticNames:t}=ee(n),e=[...new Set([...r,...t])].toSorted((c,l)=>c.localeCompare(l));if(e.length===0)return;const o=e.length===1?"advisory/platform diagnostic":"advisories/platform diagnostics";return`${d} ${String(e.length)} ERROR-level ${o} (${e.join(", ")}) — see the log above for detail.`},je=(n,r,t)=>{if(r.warn(`${d} schema.ts not found at ${n} — codegen skipped`),t!==void 0){const e=`schema.ts not found at ${n} — generated output is now stale`;t.onError(new Error(e),e)}},U=(n,r,t,e)=>{const o=N(n.projectRoot,n.schemaDir,"schema.ts");if(!j(o))return je(o,r,t),{};try{const c=Z({apiSpec:n.apiSpec,lunoraDirectory:n.schemaDir,project:e,projectRoot:n.projectRoot,target:n.target,wranglerVariables:ue(n.projectRoot)});Se(n.projectRoot,c.cronTriggers,r);for(const l of c.advisories){const u=A(l.level,l.name,l.detail,l.remediation);l.level==="ERROR"?r.error(u):r.warn(u)}for(const l of c.platformDiagnostics){const u=A(l.level==="error"?"ERROR":"WARN",l.name,l.message,l.remediation);l.level==="error"?r.error(u):r.warn(u)}return{blockingMessage:Re(c),outputDirectory:p(c.outputDirectory)}}catch(c){const l=c instanceof Error?c.message:String(c);return r.error(`${d} codegen failed: ${l}`),t?.onError(c,l),{failure:`${d} codegen failed: ${l}`}}},Ce=(n,r,t)=>{let e;for(const[o,c]of Object.entries(n.environments)){if(o==="client"){e=c;continue}he(c)||c.hot.send({path:"*",triggeredBy:r,type:"full-reload"})}if(e===void 0){n.hot.send({type:"full-reload"});return}if(t){e.hot.send({type:"full-reload"});return}e.hot.send({event:me,type:"custom"})},Fe=n=>{const r=p(n.projectRoot,n.schemaDir),t=ie(process.env[x]);let e=p(n.projectRoot,n.generatedDir),o=0,c=!1,l;const u=new Map;let h,C=!1,D=!1,E;return{config(i,w){E=w.command},async buildStart(){const i={error:g=>{console.error(g)},info:g=>{console.info(g)},warn:g=>{console.warn(g)}},w=E!=="build"&&t,{blockingMessage:y,failure:R,outputDirectory:$}=w?{}:U(n,i);if(E==="build"&&R!==void 0&&this.error(R),$!==void 0){e=$,c=!0;let g;try{g=await M({cwd:n.projectRoot,logger:i})}finally{c=!1}g.ran&&(o=Date.now()),E==="build"&&g.error!==void 0&&this.error(g.error)}E==="build"&&y!==void 0&&this.error(y),await ve(n,i,g=>{l?.hot.send({err:{loc:void 0,message:ke(g),stack:""},type:"error"})}),l!==void 0&&(h=T(n.projectRoot),C=!0)},configureServer(i){l=i,i.watcher.add(r),h=T(n.projectRoot),C=!1;const w={error:a=>{i.config.logger.error(a)},info:a=>{i.config.logger.info(a)},warn:a=>{i.config.logger.warn(a)}};let y=!1;const R={onError(a,s){y=!0;const f=a instanceof te?{column:a.column,file:a.file,line:a.line}:void 0,b=f===void 0?`[lunora] codegen failed: ${s}
3
- (see terminal for full stack trace and file location)`:`[lunora] codegen failed: ${s}`;l?.hot.send({err:{loc:f,message:b,stack:a instanceof Error?a.stack??"":""},type:"error"})}},$=(a,s)=>a===s||a.startsWith(s+k);let g=!1,m;const J=()=>{for(const a of Object.values(i.environments)){const s=a.moduleGraph;for(const f of s.idToModuleMap.values())f.id&&$(f.id,e)&&s.invalidateModule(f)}},z=async(a,s)=>{try{if(g)return;m===void 0?m=ne(r):re(m,r);const{outputDirectory:f}=U(n,w,R,m);if(f===void 0){m=void 0;return}e=f;const b=I(r);c=!0;let P;try{P=await M({cwd:n.projectRoot,logger:w})}finally{c=!1}if(P.ran&&(o=Date.now(),s(b)),P.error!==void 0)return;J(),Ce(i,a,y),y=!1}catch(f){w.error(`${d} codegen watch: ${f instanceof Error?f.message:String(f)}`)}},_=Ee({fingerprint:()=>I(r),logger:w,regenerate:(a,s)=>{z(a,s)}}),v=a=>{const s=p(a);if(B.test(s)){m=void 0;return}if(s.endsWith(`${k}tsconfig.json`)&&s===Y(r)){m=void 0;return}if($(s,r)&&!$(s,e)&&s.endsWith(".ts")&&!(s.includes(`${k}__tests__${k}`)||s.endsWith(".test.ts")||s.endsWith(".spec.ts"))){if(c||Date.now()-o<H){_.cancelPending();return}_.onSave(s)}},O=a=>{const s=p(a);(s.endsWith(`${k}tsconfig.json`)||B.test(s))&&(m=void 0)};t?i.config.logger.info(`${d} codegen watch disabled (${x}) — _generated/ is written only by an explicit \`lunora codegen\``):(i.watcher.on("add",v),i.watcher.on("change",v),i.watcher.on("unlink",v),i.watcher.on("unlink",O));const W=new Set([...ge.map(a=>p(n.projectRoot,a)),p(n.projectRoot,V)]);for(const a of W)i.watcher.add(a);const S=a=>{if(!W.has(p(a))||D)return;const s=T(n.projectRoot);if(!C){h=s;return}if(h===void 0){h=s;return}s!==h&&(h=s,D=!0,i.config.logger.info(`${d} ${q(p(a))} changed — restarting dev server`),Promise.resolve(i.restart()).finally(()=>{D=!1}).catch(f=>{const b=f instanceof Error?f.message:String(f);i.config.logger.error(`${d} dev server restart failed: ${b} — keeping the running server; re-save your config to retry.`),i.hot.send({err:{loc:void 0,message:`[lunora] dev server restart failed: ${b}`,stack:""},type:"error"})}))};i.watcher.on("add",S),i.watcher.on("change",S),i.watcher.on("unlink",S);const K=()=>{g||(g=!0,m=void 0,_.dispose(),i.watcher.off("add",v),i.watcher.off("change",v),i.watcher.off("unlink",v),i.watcher.off("unlink",O),i.watcher.off("add",S),i.watcher.off("change",S),i.watcher.off("unlink",S))};return()=>{ye(i,u,K)}},buildEnd(){we(u,this.environment)},name:"lunora:codegen"}};export{Fe as c,ve as r};