@lunora/vite 1.0.0-alpha.17 → 1.0.0-alpha.19

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
@@ -63,6 +63,23 @@ type LunoraPlugins = Plugin[];
63
63
  * inside the lunora schema directory.
64
64
  */
65
65
  declare const codegenPlugin: (options: ResolvedLunoraPluginOptions) => Plugin;
66
+ /**
67
+ * Dev-only plugin that tails the local dev containers' own stdout/stderr in the
68
+ * Vite terminal.
69
+ *
70
+ * `@cloudflare/vite-plugin` builds and runs each declared container locally via
71
+ * Docker (image `cloudflare-dev/<class>:<id>`) but only forwards the *worker's*
72
+ * console — the container process's own output is otherwise invisible. This
73
+ * plugin attaches to those Docker log streams (via `@lunora/config`'s
74
+ * `streamContainerLogs`, which lazy-loads `dockerode`) and prints each line
75
+ * through Vite's logger, branded and tagged `container:<name>`.
76
+ *
77
+ * A no-op when the project declares no containers (the common case): discovery
78
+ * returns an empty list, so `dockerode` is never imported and no Docker work
79
+ * starts. Set `LUNORA_CONTAINER_LOGS=0` to opt out. A missing/stopped Docker
80
+ * engine degrades to a single warning rather than breaking dev.
81
+ */
82
+ declare const containerLogsPlugin: (options: ResolvedLunoraPluginOptions) => Plugin;
66
83
  interface ReconcileResult {
67
84
  /** `true` when `wrangler.jsonc` was rewritten. */
68
85
  changed: boolean;
@@ -378,4 +395,4 @@ declare const wranglerValidatorPlugin: (options: ResolvedLunoraPluginOptions) =>
378
395
  */
379
396
  declare const lunora: (options?: LunoraPluginOptions) => LunoraPlugins;
380
397
  declare const VERSION = "0.0.0";
381
- export { CLASS_A_WIRING, type ClassAWiring, type CloudflarePluginOptions, DEV_WORKER_ENV_VALUE, DEV_WORKER_ENV_VAR, LUNORA_WORKER_VIRTUAL_ID, type LunoraPluginOptions, type LunoraPlugins, type OverlayPluginOptions, type PlanViteRemoteOptions, type ReconcileResult, type ResolvedLunoraPluginOptions, STUDIO_PATH, VERSION, type ViteRemotePlan, WORKER_STARTUP_HINT, augmentWorkerStartupError, buildStudioUrl, buildWorkerEntrySource, codegenPlugin, createCommandProbe, devVariablesPlugin, frameworkComposePlugin, isAutoComposable, isWorkerEntryEvalError, logStreamPlugin, lunora, planViteRemoteBindings, reconcileWranglerCrons, remoteBindingsCleanupPlugin, studioPlugin, withDevWorkerEnv, withRemoteBindings, withWorkerStartupHint, wranglerValidatorPlugin };
398
+ export { CLASS_A_WIRING, type ClassAWiring, type CloudflarePluginOptions, DEV_WORKER_ENV_VALUE, DEV_WORKER_ENV_VAR, LUNORA_WORKER_VIRTUAL_ID, type LunoraPluginOptions, type LunoraPlugins, type OverlayPluginOptions, type PlanViteRemoteOptions, type ReconcileResult, type ResolvedLunoraPluginOptions, STUDIO_PATH, VERSION, type ViteRemotePlan, WORKER_STARTUP_HINT, augmentWorkerStartupError, buildStudioUrl, buildWorkerEntrySource, codegenPlugin, containerLogsPlugin, createCommandProbe, devVariablesPlugin, frameworkComposePlugin, isAutoComposable, isWorkerEntryEvalError, logStreamPlugin, lunora, planViteRemoteBindings, reconcileWranglerCrons, remoteBindingsCleanupPlugin, studioPlugin, withDevWorkerEnv, withRemoteBindings, withWorkerStartupHint, wranglerValidatorPlugin };
package/dist/index.d.ts CHANGED
@@ -63,6 +63,23 @@ type LunoraPlugins = Plugin[];
63
63
  * inside the lunora schema directory.
64
64
  */
65
65
  declare const codegenPlugin: (options: ResolvedLunoraPluginOptions) => Plugin;
66
+ /**
67
+ * Dev-only plugin that tails the local dev containers' own stdout/stderr in the
68
+ * Vite terminal.
69
+ *
70
+ * `@cloudflare/vite-plugin` builds and runs each declared container locally via
71
+ * Docker (image `cloudflare-dev/<class>:<id>`) but only forwards the *worker's*
72
+ * console — the container process's own output is otherwise invisible. This
73
+ * plugin attaches to those Docker log streams (via `@lunora/config`'s
74
+ * `streamContainerLogs`, which lazy-loads `dockerode`) and prints each line
75
+ * through Vite's logger, branded and tagged `container:<name>`.
76
+ *
77
+ * A no-op when the project declares no containers (the common case): discovery
78
+ * returns an empty list, so `dockerode` is never imported and no Docker work
79
+ * starts. Set `LUNORA_CONTAINER_LOGS=0` to opt out. A missing/stopped Docker
80
+ * engine degrades to a single warning rather than breaking dev.
81
+ */
82
+ declare const containerLogsPlugin: (options: ResolvedLunoraPluginOptions) => Plugin;
66
83
  interface ReconcileResult {
67
84
  /** `true` when `wrangler.jsonc` was rewritten. */
68
85
  changed: boolean;
@@ -378,4 +395,4 @@ declare const wranglerValidatorPlugin: (options: ResolvedLunoraPluginOptions) =>
378
395
  */
379
396
  declare const lunora: (options?: LunoraPluginOptions) => LunoraPlugins;
380
397
  declare const VERSION = "0.0.0";
381
- export { CLASS_A_WIRING, type ClassAWiring, type CloudflarePluginOptions, DEV_WORKER_ENV_VALUE, DEV_WORKER_ENV_VAR, LUNORA_WORKER_VIRTUAL_ID, type LunoraPluginOptions, type LunoraPlugins, type OverlayPluginOptions, type PlanViteRemoteOptions, type ReconcileResult, type ResolvedLunoraPluginOptions, STUDIO_PATH, VERSION, type ViteRemotePlan, WORKER_STARTUP_HINT, augmentWorkerStartupError, buildStudioUrl, buildWorkerEntrySource, codegenPlugin, createCommandProbe, devVariablesPlugin, frameworkComposePlugin, isAutoComposable, isWorkerEntryEvalError, logStreamPlugin, lunora, planViteRemoteBindings, reconcileWranglerCrons, remoteBindingsCleanupPlugin, studioPlugin, withDevWorkerEnv, withRemoteBindings, withWorkerStartupHint, wranglerValidatorPlugin };
398
+ export { CLASS_A_WIRING, type ClassAWiring, type CloudflarePluginOptions, DEV_WORKER_ENV_VALUE, DEV_WORKER_ENV_VAR, LUNORA_WORKER_VIRTUAL_ID, type LunoraPluginOptions, type LunoraPlugins, type OverlayPluginOptions, type PlanViteRemoteOptions, type ReconcileResult, type ResolvedLunoraPluginOptions, STUDIO_PATH, VERSION, type ViteRemotePlan, WORKER_STARTUP_HINT, augmentWorkerStartupError, buildStudioUrl, buildWorkerEntrySource, codegenPlugin, containerLogsPlugin, createCommandProbe, devVariablesPlugin, frameworkComposePlugin, isAutoComposable, isWorkerEntryEvalError, logStreamPlugin, lunora, planViteRemoteBindings, reconcileWranglerCrons, remoteBindingsCleanupPlugin, studioPlugin, withDevWorkerEnv, withRemoteBindings, withWorkerStartupHint, wranglerValidatorPlugin };
package/dist/index.mjs CHANGED
@@ -3,12 +3,13 @@ import errorOverlayPlugin from '@visulima/vite-overlay';
3
3
  import { detectAgentRules, claimAgentRulesHint, AGENT_RULES_HINT, detectFramework } from '@lunora/config';
4
4
  export { detectFramework } from '@lunora/config';
5
5
  import { l as lunoraLine } from './packem_shared/log-BjO9EWah.mjs';
6
- import codegenPlugin from './packem_shared/codegenPlugin-MuvbqAP8.mjs';
6
+ import codegenPlugin from './packem_shared/codegenPlugin-B_ayaObq.mjs';
7
+ import containerLogsPlugin from './packem_shared/containerLogsPlugin-DMssU3wb.mjs';
7
8
  import devVariablesPlugin from './packem_shared/devVariablesPlugin-CDNSnvOP.mjs';
8
9
  import { createCommandProbe, withDevWorkerEnv } from './packem_shared/DEV_WORKER_ENV_VALUE-Coo6bgVz.mjs';
9
10
  export { DEV_WORKER_ENV_VALUE, DEV_WORKER_ENV_VAR } from './packem_shared/DEV_WORKER_ENV_VALUE-Coo6bgVz.mjs';
10
- import { frameworkComposePlugin } from './packem_shared/CLASS_A_WIRING-CZVcjgKo.mjs';
11
- export { CLASS_A_WIRING, LUNORA_WORKER_VIRTUAL_ID, buildWorkerEntrySource, isAutoComposable } from './packem_shared/CLASS_A_WIRING-CZVcjgKo.mjs';
11
+ import { frameworkComposePlugin } from './packem_shared/CLASS_A_WIRING-DpX_WcOK.mjs';
12
+ export { CLASS_A_WIRING, LUNORA_WORKER_VIRTUAL_ID, buildWorkerEntrySource, isAutoComposable } from './packem_shared/CLASS_A_WIRING-DpX_WcOK.mjs';
12
13
  import logStreamPlugin from './packem_shared/logStreamPlugin-CqvZ17kd.mjs';
13
14
  import { planViteRemoteBindings, remoteBindingsCleanupPlugin, withRemoteBindings } from './packem_shared/planViteRemoteBindings-QN5ncUS1.mjs';
14
15
  import { studioPlugin } from './packem_shared/STUDIO_PATH-5ppCdBHa.mjs';
@@ -141,6 +142,7 @@ const lunora = (options) => {
141
142
  plugins.push(errorOverlayPlugin(resolved.overlay));
142
143
  }
143
144
  if (resolved.cloudflare !== false) {
145
+ plugins.push(containerLogsPlugin(resolved));
144
146
  const remotePlan = planViteRemoteBindings({ projectRoot: resolved.projectRoot });
145
147
  if (remotePlan.enabled && remotePlan.configPath !== void 0) {
146
148
  plugins.push(remoteBindingsCleanupPlugin(remotePlan.cleanup));
@@ -152,4 +154,4 @@ const lunora = (options) => {
152
154
  };
153
155
  const VERSION = "0.0.0";
154
156
 
155
- export { VERSION, codegenPlugin, createCommandProbe, devVariablesPlugin, frameworkComposePlugin, logStreamPlugin, lunora, planViteRemoteBindings, remoteBindingsCleanupPlugin, studioPlugin, withDevWorkerEnv, withRemoteBindings, withWorkerStartupHint, wranglerValidatorPlugin };
157
+ export { VERSION, codegenPlugin, containerLogsPlugin, createCommandProbe, devVariablesPlugin, frameworkComposePlugin, logStreamPlugin, lunora, planViteRemoteBindings, remoteBindingsCleanupPlugin, studioPlugin, withDevWorkerEnv, withRemoteBindings, withWorkerStartupHint, wranglerValidatorPlugin };
@@ -4,6 +4,9 @@ import { resolve, join } from 'node:path';
4
4
  const LUNORA_WORKER_VIRTUAL_ID = "virtual:lunora/worker";
5
5
  const RESOLVED_VIRTUAL_PREFIX = "\0";
6
6
  const RESOLVED_LUNORA_WORKER_ID = `${RESOLVED_VIRTUAL_PREFIX}${LUNORA_WORKER_VIRTUAL_ID}`;
7
+ const CLIENT_WORKER_STUB = `// @lunora/vite — the composed worker entry is worker-only and unavailable in the client environment.
8
+ export default {};
9
+ `;
7
10
  const TRAILING_SLASH = /\/$/;
8
11
  const CLASS_A_WIRING = {
9
12
  "react-router": {
@@ -88,6 +91,9 @@ const frameworkComposePlugin = (options, context) => {
88
91
  return {
89
92
  load(id) {
90
93
  if (id === RESOLVED_LUNORA_WORKER_ID && isWorkerVirtualActive(context) && context.framework !== void 0) {
94
+ if (this.environment.name === "client") {
95
+ return CLIENT_WORKER_STUB;
96
+ }
91
97
  const hasContainers = existsSync(join(generatedImportBase, "containers.ts"));
92
98
  return buildWorkerEntrySource(context.framework.framework, generatedImportBase, hasContainers, useUmbrella);
93
99
  }
@@ -133,19 +133,8 @@ const codegenPlugin = (options) => {
133
133
  let closed = false;
134
134
  let cachedProject;
135
135
  const invalidateGenerated = () => {
136
- const environments = server.environments;
137
- const graphs = [];
138
- if (environments !== void 0) {
139
- for (const environment of Object.values(environments)) {
140
- if (environment.moduleGraph !== void 0) {
141
- graphs.push(environment.moduleGraph);
142
- }
143
- }
144
- }
145
- if (graphs.length === 0) {
146
- graphs.push(server.moduleGraph);
147
- }
148
- for (const graph of graphs) {
136
+ for (const environment of Object.values(server.environments)) {
137
+ const graph = environment.moduleGraph;
149
138
  for (const moduleEntry of graph.idToModuleMap.values()) {
150
139
  if (moduleEntry.id && isInside(moduleEntry.id, absoluteGeneratedDirectory)) {
151
140
  graph.invalidateModule(moduleEntry);
@@ -0,0 +1,50 @@
1
+ import { discoverContainerInfo, streamContainerLogs } from '@lunora/config';
2
+ import { l as lunoraLine } from './log-BjO9EWah.mjs';
3
+
4
+ const containerLogsPlugin = (options) => {
5
+ let handle;
6
+ const closeHandle = () => {
7
+ handle?.close();
8
+ handle = void 0;
9
+ };
10
+ return {
11
+ apply: "serve",
12
+ // Fires on `server.close()` for both the normal and middleware-mode dev
13
+ // servers, so the Docker poll loop is torn down even when there is no
14
+ // `httpServer` to listen on (middleware mode).
15
+ buildEnd() {
16
+ closeHandle();
17
+ },
18
+ configureServer(server) {
19
+ if (handle || process.env.LUNORA_CONTAINER_LOGS === "0") {
20
+ return;
21
+ }
22
+ const discovery = discoverContainerInfo(options.projectRoot, options.schemaDir);
23
+ const containers = discovery.containers.map((container) => {
24
+ return { className: container.className, exportName: container.exportName };
25
+ });
26
+ if (containers.length === 0) {
27
+ return;
28
+ }
29
+ const { logger } = server.config;
30
+ handle = streamContainerLogs({
31
+ containers,
32
+ onLine: (line) => {
33
+ const text = lunoraLine(`container:${line.name} ${line.text}`);
34
+ if (line.level === "error") {
35
+ logger.warn(text);
36
+ } else {
37
+ logger.info(text);
38
+ }
39
+ },
40
+ onUnavailable: (message) => {
41
+ logger.warn(lunoraLine(`container: Docker engine unreachable — container logs unavailable (${message})`));
42
+ }
43
+ });
44
+ server.httpServer?.once("close", closeHandle);
45
+ },
46
+ name: "lunora:container-logs"
47
+ };
48
+ };
49
+
50
+ export { containerLogsPlugin as default };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@lunora/vite",
3
- "version": "1.0.0-alpha.17",
3
+ "version": "1.0.0-alpha.19",
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.42.0",
49
- "@lunora/codegen": "1.0.0-alpha.11",
50
- "@lunora/config": "1.0.0-alpha.17",
49
+ "@lunora/codegen": "1.0.0-alpha.12",
50
+ "@lunora/config": "1.0.0-alpha.19",
51
51
  "@visulima/vite-overlay": "2.0.0-alpha.35",
52
52
  "jsonc-parser": "^3.3.1",
53
53
  "ts-morph": "^28.0.0"