@lithia-js/cli 1.0.0-canary.29 → 1.0.0-canary.30

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.mjs CHANGED
@@ -284,7 +284,7 @@ async function processDevBatch(lithia, batch, state) {
284
284
 
285
285
  // package.json
286
286
  var package_default = {
287
- version: "1.0.0-canary.29"};
287
+ version: "1.0.0-canary.30"};
288
288
 
289
289
  // src/meta.ts
290
290
  var version = package_default.version;
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/cmd/build.ts","../src/cmd/dev-scheduler.ts","../src/cmd/dev.ts","../package.json","../src/meta.ts","../src/index.ts"],"names":["defineCommand","HostSupervisor","logger","join"],"mappings":"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","file":"index.mjs","sourcesContent":["import { chmod, readFile, writeFile } from \"node:fs/promises\";\nimport { join, resolve } from \"node:path\";\nimport { HostSupervisor } from \"@lithia-js/core/_\";\nimport { logger } from \"@lithia-js/utils\";\nimport { defineCommand } from \"citty\";\n\n/**\n * CLI command that builds a Lithia application for production execution.\n *\n * The command initializes a host supervisor in build mode, compiles the app,\n * generates the production `server.js` entrypoint from the template file, loads\n * the generated manifests so the route/event/task trees can be printed, and\n * marks the entrypoint as executable.\n */\nconst build = defineCommand({\n\tmeta: {\n\t\tname: \"build\",\n\t\tdescription: \"Compile the project for production deployment\",\n\t},\n\n\t/**\n\t * Runs the production build lifecycle for the current project.\n\t *\n\t * The command exits the process with status `1` when the core build step\n\t * fails. Errors that happen later during entrypoint finalization are logged\n\t * but do not currently rethrow.\n\t *\n\t * @returns {Promise<void>} Resolves after the build flow and tree printing\n\t * finish.\n\t */\n\tasync run() {\n\t\tconst lithia = new HostSupervisor({ environment: \"build\" });\n\n\t\t// Initialize the host environment\n\t\tawait lithia.setup();\n\n\t\tlogger.info(\"Initializing production build sequence...\");\n\n\t\t// Trigger the core build process\n\t\ttry {\n\t\t\tawait lithia.build();\n\t\t} catch {\n\t\t\tprocess.exit(1);\n\t\t}\n\n\t\tconst { config } = lithia;\n\t\tconst workingDirectory = process.cwd();\n\n\t\t// Path resolution for entry point generation\n\t\tconst entryPath = join(workingDirectory, config.outDir, \"server.js\");\n\t\tconst templatePath = resolve(import.meta.dirname, \"_entrypoint.mjs\");\n\n\t\t// Generate production entry point by injecting runtime configuration\n\t\ttry {\n\t\t\tconst rawTemplate = await readFile(templatePath, \"utf-8\");\n\t\t\tconst processedContent = rawTemplate.replace(\n\t\t\t\t\"__CONFIG__\",\n\t\t\t\tJSON.stringify(config),\n\t\t\t);\n\n\t\t\tawait writeFile(entryPath, processedContent, \"utf-8\");\n\n\t\t\t// Post-write operations: Loading metadata and setting permissions\n\t\t\tawait lithia.loadRoutes();\n\t\t\tawait lithia.loadEvents();\n\t\t\tawait lithia.loadTasks();\n\n\t\t\t// Ensure the entry point is executable (0o755: rwxr-xr-x)\n\t\t\tawait chmod(entryPath, 0o755);\n\n\t\t\tlogger.success(\"Production build completed successfully.\");\n\t\t} catch (error) {\n\t\t\tlogger.error(\"Failed to finalize the build entry point.\");\n\t\t\tlogger.debug(error);\n\t\t\t// Silent catch maintained as per original implementation,\n\t\t\t// but logged for visibility.\n\t\t}\n\n\t\t// Output visual representation of the application structure\n\t\tlithia.printRouteTree();\n\t\tlithia.printEventTree();\n\t\tlithia.printTaskTree();\n\t},\n});\n\nexport default build;\n","/**\n * Change category tracked by the development lifecycle scheduler.\n */\nexport type DevChangeKind = \"source\" | \"config\" | \"env\";\n\n/**\n * Coalesced batch of pending development changes.\n *\n * Each flag indicates whether at least one change of that category occurred\n * since the previous flushed batch.\n */\nexport interface DevChangeBatch {\n\tsource: boolean;\n\tconfig: boolean;\n\tenv: boolean;\n}\n\n/**\n * Debounces and serializes development lifecycle work.\n *\n * The scheduler accumulates file-change categories into a single pending batch,\n * ensures only one batch is processed at a time, and automatically schedules a\n * follow-up flush when more changes arrive while a batch is running.\n */\nexport class DevLifecycleScheduler {\n\tprivate readonly pending: DevChangeBatch = {\n\t\tsource: false,\n\t\tconfig: false,\n\t\tenv: false,\n\t};\n\n\tprivate timer: NodeJS.Timeout | null = null;\n\tprivate running = false;\n\n\t/**\n\t * Creates a scheduler for coalesced dev lifecycle processing.\n\t *\n\t * @param {(batch: DevChangeBatch) => Promise<void>} onBatch - Async callback\n\t * invoked with each consumed batch of pending changes.\n\t * @param {number} [debounceMs=180] - Debounce window used before a pending\n\t * batch is flushed.\n\t * @param {(error: unknown) => void} [onError=() => {}] - Error callback\n\t * invoked when batch processing fails.\n\t */\n\tconstructor(\n\t\tprivate readonly onBatch: (batch: DevChangeBatch) => Promise<void>,\n\t\tprivate readonly debounceMs: number = 180,\n\t\tprivate readonly onError: (error: unknown) => void = () => {},\n\t) {}\n\n\t/**\n\t * Marks a change category as pending and schedules a future flush.\n\t *\n\t * @param {DevChangeKind} kind - Change category that was observed by a\n\t * filesystem watcher.\n\t */\n\tpublic enqueue(kind: DevChangeKind): void {\n\t\tthis.pending[kind] = true;\n\t\tif (this.running) return;\n\n\t\tif (this.timer) clearTimeout(this.timer);\n\t\tthis.timer = setTimeout(() => {\n\t\t\tthis.timer = null;\n\t\t\tvoid this.flush();\n\t\t}, this.debounceMs);\n\t}\n\n\t/**\n\t * Flushes pending changes in serialized batches.\n\t *\n\t * @returns {Promise<void>} Resolves after all currently pending changes have\n\t * been consumed or the error callback has been invoked.\n\t */\n\tprivate async flush(): Promise<void> {\n\t\tif (this.running) return;\n\t\tthis.running = true;\n\n\t\ttry {\n\t\t\twhile (this.hasPendingChanges()) {\n\t\t\t\tawait this.onBatch(this.consumePending());\n\t\t\t}\n\t\t} catch (error) {\n\t\t\tthis.onError(error);\n\t\t} finally {\n\t\t\tthis.running = false;\n\t\t\tif (this.hasPendingChanges() && !this.timer) {\n\t\t\t\tthis.timer = setTimeout(() => {\n\t\t\t\t\tthis.timer = null;\n\t\t\t\t\tvoid this.flush();\n\t\t\t\t}, this.debounceMs);\n\t\t\t}\n\t\t}\n\t}\n\n\t/**\n\t * Returns whether any change category is currently pending.\n\t *\n\t * @returns {boolean} `true` when a flush still has work to process.\n\t */\n\tprivate hasPendingChanges(): boolean {\n\t\treturn this.pending.source || this.pending.config || this.pending.env;\n\t}\n\n\t/**\n\t * Returns the current pending batch and clears the internal flags.\n\t *\n\t * @returns {DevChangeBatch} Snapshot of the pending change flags that should\n\t * be processed next.\n\t */\n\tprivate consumePending(): DevChangeBatch {\n\t\tconst batch = { ...this.pending };\n\t\tthis.pending.source = false;\n\t\tthis.pending.config = false;\n\t\tthis.pending.env = false;\n\t\treturn batch;\n\t}\n}\n","import { join } from \"node:path\";\nimport { HostSupervisor } from \"@lithia-js/core/_\";\nimport { logger } from \"@lithia-js/utils\";\nimport chokidar from \"chokidar\";\nimport { defineCommand } from \"citty\";\nimport { type DevChangeBatch, DevLifecycleScheduler } from \"./dev-scheduler\";\n\n/**\n * CLI command that runs the Lithia development server with incremental rebuild\n * and reload behavior.\n *\n * The command boots a development host supervisor, starts filesystem watchers\n * for source, config, and environment files, and serializes reload work\n * through `DevLifecycleScheduler` so overlapping file changes do not race.\n */\nconst dev = defineCommand({\n\tmeta: {\n\t\tname: \"dev\",\n\t\tdescription: \"Start the development server with hot-reload capabilities\",\n\t},\n\n\t/**\n\t * Runs the development server lifecycle for the current project.\n\t *\n\t * @returns {Promise<void>} Resolves after watchers and shutdown handlers have\n\t * been registered.\n\t */\n\tasync run() {\n\t\tconst cwd = process.cwd();\n\t\tconst lithia = new HostSupervisor({ environment: \"development\" });\n\n\t\t// 1. Initial Host Setup\n\t\tawait lithia.setup();\n\t\tconst initialBuildSucceeded = await lithia.build();\n\t\tconst lifecycleState = {\n\t\t\thasReloadableArtifacts: initialBuildSucceeded,\n\t\t};\n\n\t\tif (initialBuildSucceeded) {\n\t\t\ttry {\n\t\t\t\tawait lithia.start();\n\t\t\t} catch {\n\t\t\t\tlogger.error(\"Failed to start the development server.\");\n\t\t\t}\n\t\t} else {\n\t\t\tlogger.warn(\n\t\t\t\t\"Initial build failed. Waiting for file changes while continuing to serve nothing.\",\n\t\t\t);\n\t\t}\n\n\t\t// 2. Define the serialized dev lifecycle\n\t\tconst scheduler = new DevLifecycleScheduler(\n\t\t\tasync (batch) => {\n\t\t\t\tawait processDevBatch(lithia, batch, lifecycleState);\n\t\t\t},\n\t\t\t180,\n\t\t\t(error) => {\n\t\t\t\tlogger.error(\"Dev lifecycle failed:\", error);\n\t\t\t},\n\t\t);\n\n\t\t// 3. Source Code Watcher\n\t\tconst srcWatcher = chokidar.watch(join(cwd, \"src\"), {\n\t\t\tignored: [/(^|[/\\\\])\\../, \"**/node_modules/**\"],\n\t\t\tpersistent: true,\n\t\t\tignoreInitial: true,\n\t\t});\n\n\t\tsrcWatcher.on(\"all\", (event) => {\n\t\t\tif ([\"add\", \"change\", \"unlink\"].includes(event)) {\n\t\t\t\tscheduler.enqueue(\"source\");\n\t\t\t}\n\t\t});\n\n\t\t// 4. Configuration and Environment Watcher\n\t\tconst extensions = [\".js\", \".mjs\", \".ts\", \".mts\", \".json\"];\n\t\tconst configFiles = [\n\t\t\t...lithia.config.envFiles,\n\t\t\t...extensions.map((ext) => join(cwd, `lithia.config${ext}`)),\n\t\t];\n\n\t\tconst configWatcher = chokidar.watch(configFiles, {\n\t\t\tcwd,\n\t\t\tignoreInitial: true,\n\t\t});\n\n\t\tconfigWatcher.on(\"all\", (event, filePath) => {\n\t\t\tif ([\"change\", \"add\"].includes(event)) {\n\t\t\t\tif (filePath.includes(\"lithia.config\")) {\n\t\t\t\t\tscheduler.enqueue(\"config\");\n\t\t\t\t} else {\n\t\t\t\t\tscheduler.enqueue(\"env\");\n\t\t\t\t}\n\t\t\t}\n\t\t});\n\n\t\t// 5. Graceful Shutdown Orchestration\n\t\tconst shutdown = async () => {\n\t\t\tlogger.info(\"Shutting down development server...\");\n\t\t\tawait Promise.allSettled([\n\t\t\t\tsrcWatcher.close(),\n\t\t\t\tconfigWatcher.close(),\n\t\t\t\tlithia.stop(),\n\t\t\t]);\n\t\t\tprocess.exit(0);\n\t\t};\n\n\t\t// Correctly bind signal handlers to the shutdown sequence\n\t\tprocess.once(\"SIGINT\", shutdown);\n\t\tprocess.once(\"SIGTERM\", shutdown);\n\t},\n});\n\nexport default dev;\n\n/**\n * Processes a coalesced development change batch against the host supervisor.\n *\n * Config changes reload config and env first, rebuild the project, and roll\n * back to the previous config/env snapshot when the rebuild fails. Source-only\n * changes rebuild the project before reloading, while env-only changes reload\n * the host only when usable build artifacts are already available.\n *\n * @param {HostSupervisor} lithia - Development host supervisor that owns build\n * and reload behavior.\n * @param {DevChangeBatch} batch - Coalesced set of pending source/config/env\n * changes.\n * @param {{ hasReloadableArtifacts: boolean }} state - Mutable lifecycle state\n * used to remember whether reloadable build artifacts currently exist.\n * @returns {Promise<void>} Resolves after the requested dev lifecycle work\n * completes.\n */\nexport async function processDevBatch(\n\tlithia: HostSupervisor,\n\tbatch: DevChangeBatch,\n\tstate: { hasReloadableArtifacts: boolean },\n): Promise<void> {\n\tif (batch.config) {\n\t\tconst previousConfig = structuredClone(lithia.config);\n\t\tconst previousEnv = lithia.getEnvSnapshot();\n\n\t\ttry {\n\t\t\tawait lithia.loadConfig();\n\t\t\tawait lithia.loadEnv();\n\n\t\t\tconst buildSucceeded = await lithia.build();\n\t\t\tif (!buildSucceeded) {\n\t\t\t\tstate.hasReloadableArtifacts =\n\t\t\t\t\tstate.hasReloadableArtifacts || lithia.isAppReady;\n\t\t\t\tlithia.replaceConfig(previousConfig);\n\t\t\t\tlithia.replaceEnv(previousEnv);\n\t\t\t\tlogger.warn(\n\t\t\t\t\t\"Reload skipped due to build failure. Rolled back config/env and kept serving the previous app.\",\n\t\t\t\t);\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tawait lithia.reload();\n\t\t\tstate.hasReloadableArtifacts = true;\n\t\t\treturn;\n\t\t} catch (error) {\n\t\t\tlithia.replaceConfig(previousConfig);\n\t\t\tlithia.replaceEnv(previousEnv);\n\t\t\tthrow error;\n\t\t}\n\t}\n\n\tif (batch.source) {\n\t\tconst buildSucceeded = await lithia.build();\n\n\t\tif (!buildSucceeded) {\n\t\t\tstate.hasReloadableArtifacts =\n\t\t\t\tstate.hasReloadableArtifacts || lithia.isAppReady;\n\t\t\tlogger.warn(\n\t\t\t\t\"Reload skipped due to build failure. Continuing to serve previous app.\",\n\t\t\t);\n\t\t\treturn;\n\t\t}\n\n\t\tstate.hasReloadableArtifacts = true;\n\t}\n\n\tif (batch.env) {\n\t\tif (!state.hasReloadableArtifacts) {\n\t\t\tlogger.warn(\n\t\t\t\t\"Reload skipped because the latest build artifacts are unavailable. Fix the build and save again.\",\n\t\t\t);\n\t\t\treturn;\n\t\t}\n\t\tawait lithia.loadEnv();\n\t}\n\n\tif (batch.source || batch.env) {\n\t\tawait lithia.reload();\n\t\tstate.hasReloadableArtifacts = true;\n\n\t\tif (batch.env && !batch.source) {\n\t\t\tlogger.success(\"Applied environment changes.\");\n\t\t}\n\t}\n}\n","{\n\t\"name\": \"@lithia-js/cli\",\n\t\"version\": \"1.0.0-canary.29\",\n\t\"description\": \"Command-line interface for developing and building Lithia.js applications.\",\n\t\"keywords\": [\n\t\t\"lithia\",\n\t\t\"lithia-js\",\n\t\t\"cli\",\n\t\t\"framework\",\n\t\t\"backend\",\n\t\t\"create-app\",\n\t\t\"build-tool\",\n\t\t\"dev-server\"\n\t],\n\t\"author\": \"Lucas Arch <luketsx@icloud.com>\",\n\t\"license\": \"MIT\",\n\t\"homepage\": \"https://lithiajs.org\",\n\t\"repository\": {\n\t\t\"type\": \"git\",\n\t\t\"url\": \"git+https://github.com/lithia-framework/lithia.git\",\n\t\t\"directory\": \"packages/cli\"\n\t},\n\t\"bugs\": {\n\t\t\"url\": \"https://github.com/lithia-framework/lithia/issues\"\n\t},\n\t\"type\": \"module\",\n\t\"bin\": {\n\t\t\"lithia\": \"./dist/index.mjs\"\n\t},\n\t\"main\": \"./dist/index.mjs\",\n\t\"files\": [\n\t\t\"dist\",\n\t\t\"templates\"\n\t],\n\t\"engines\": {\n\t\t\"node\": \">=20\"\n\t},\n\t\"scripts\": {\n\t\t\"build\": \"tsup --config tsup.config.ts\",\n\t\t\"test\": \"vitest --run\"\n\t},\n\t\"dependencies\": {\n\t\t\"@lithia-js/core\": \"workspace:1.0.0-canary.29\",\n\t\t\"@lithia-js/utils\": \"workspace:1.0.0-canary.29\",\n\t\t\"citty\": \"^0.2.0\",\n\t\t\"chokidar\": \"^5.0.0\"\n\t},\n\t\"publishConfig\": {\n\t\t\"registry\": \"https://registry.npmjs.org/\",\n\t\t\"access\": \"public\",\n\t\t\"provenance\": true\n\t}\n}\n","import pJson from \"../package.json\" with { type: \"json\" };\nexport const version = pJson.version;\n","#! /usr/bin/env node\n\nimport { defineCommand, runMain } from \"citty\";\nimport build from \"./cmd/build\";\nimport dev from \"./cmd/dev\";\nimport { version } from \"./meta\";\n\nconst main = defineCommand({\n\tmeta: {\n\t\tname: \"lithia\",\n\t\tdescription: \"Lithia CLI\",\n\t\tversion,\n\t},\n\tsubCommands: {\n\t\tdev,\n\t\tbuild,\n\t},\n});\n\nrunMain(main).then();\n"]}
1
+ {"version":3,"sources":["../src/cmd/build.ts","../src/cmd/dev-scheduler.ts","../src/cmd/dev.ts","../package.json","../src/meta.ts","../src/index.ts"],"names":["defineCommand","HostSupervisor","logger","join"],"mappings":"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","file":"index.mjs","sourcesContent":["import { chmod, readFile, writeFile } from \"node:fs/promises\";\nimport { join, resolve } from \"node:path\";\nimport { HostSupervisor } from \"@lithia-js/core/_\";\nimport { logger } from \"@lithia-js/utils\";\nimport { defineCommand } from \"citty\";\n\n/**\n * CLI command that builds a Lithia application for production execution.\n *\n * The command initializes a host supervisor in build mode, compiles the app,\n * generates the production `server.js` entrypoint from the template file, loads\n * the generated manifests so the route/event/task trees can be printed, and\n * marks the entrypoint as executable.\n */\nconst build = defineCommand({\n\tmeta: {\n\t\tname: \"build\",\n\t\tdescription: \"Compile the project for production deployment\",\n\t},\n\n\t/**\n\t * Runs the production build lifecycle for the current project.\n\t *\n\t * The command exits the process with status `1` when the core build step\n\t * fails. Errors that happen later during entrypoint finalization are logged\n\t * but do not currently rethrow.\n\t *\n\t * @returns {Promise<void>} Resolves after the build flow and tree printing\n\t * finish.\n\t */\n\tasync run() {\n\t\tconst lithia = new HostSupervisor({ environment: \"build\" });\n\n\t\t// Initialize the host environment\n\t\tawait lithia.setup();\n\n\t\tlogger.info(\"Initializing production build sequence...\");\n\n\t\t// Trigger the core build process\n\t\ttry {\n\t\t\tawait lithia.build();\n\t\t} catch {\n\t\t\tprocess.exit(1);\n\t\t}\n\n\t\tconst { config } = lithia;\n\t\tconst workingDirectory = process.cwd();\n\n\t\t// Path resolution for entry point generation\n\t\tconst entryPath = join(workingDirectory, config.outDir, \"server.js\");\n\t\tconst templatePath = resolve(import.meta.dirname, \"_entrypoint.mjs\");\n\n\t\t// Generate production entry point by injecting runtime configuration\n\t\ttry {\n\t\t\tconst rawTemplate = await readFile(templatePath, \"utf-8\");\n\t\t\tconst processedContent = rawTemplate.replace(\n\t\t\t\t\"__CONFIG__\",\n\t\t\t\tJSON.stringify(config),\n\t\t\t);\n\n\t\t\tawait writeFile(entryPath, processedContent, \"utf-8\");\n\n\t\t\t// Post-write operations: Loading metadata and setting permissions\n\t\t\tawait lithia.loadRoutes();\n\t\t\tawait lithia.loadEvents();\n\t\t\tawait lithia.loadTasks();\n\n\t\t\t// Ensure the entry point is executable (0o755: rwxr-xr-x)\n\t\t\tawait chmod(entryPath, 0o755);\n\n\t\t\tlogger.success(\"Production build completed successfully.\");\n\t\t} catch (error) {\n\t\t\tlogger.error(\"Failed to finalize the build entry point.\");\n\t\t\tlogger.debug(error);\n\t\t\t// Silent catch maintained as per original implementation,\n\t\t\t// but logged for visibility.\n\t\t}\n\n\t\t// Output visual representation of the application structure\n\t\tlithia.printRouteTree();\n\t\tlithia.printEventTree();\n\t\tlithia.printTaskTree();\n\t},\n});\n\nexport default build;\n","/**\n * Change category tracked by the development lifecycle scheduler.\n */\nexport type DevChangeKind = \"source\" | \"config\" | \"env\";\n\n/**\n * Coalesced batch of pending development changes.\n *\n * Each flag indicates whether at least one change of that category occurred\n * since the previous flushed batch.\n */\nexport interface DevChangeBatch {\n\tsource: boolean;\n\tconfig: boolean;\n\tenv: boolean;\n}\n\n/**\n * Debounces and serializes development lifecycle work.\n *\n * The scheduler accumulates file-change categories into a single pending batch,\n * ensures only one batch is processed at a time, and automatically schedules a\n * follow-up flush when more changes arrive while a batch is running.\n */\nexport class DevLifecycleScheduler {\n\tprivate readonly pending: DevChangeBatch = {\n\t\tsource: false,\n\t\tconfig: false,\n\t\tenv: false,\n\t};\n\n\tprivate timer: NodeJS.Timeout | null = null;\n\tprivate running = false;\n\n\t/**\n\t * Creates a scheduler for coalesced dev lifecycle processing.\n\t *\n\t * @param {(batch: DevChangeBatch) => Promise<void>} onBatch - Async callback\n\t * invoked with each consumed batch of pending changes.\n\t * @param {number} [debounceMs=180] - Debounce window used before a pending\n\t * batch is flushed.\n\t * @param {(error: unknown) => void} [onError=() => {}] - Error callback\n\t * invoked when batch processing fails.\n\t */\n\tconstructor(\n\t\tprivate readonly onBatch: (batch: DevChangeBatch) => Promise<void>,\n\t\tprivate readonly debounceMs: number = 180,\n\t\tprivate readonly onError: (error: unknown) => void = () => {},\n\t) {}\n\n\t/**\n\t * Marks a change category as pending and schedules a future flush.\n\t *\n\t * @param {DevChangeKind} kind - Change category that was observed by a\n\t * filesystem watcher.\n\t */\n\tpublic enqueue(kind: DevChangeKind): void {\n\t\tthis.pending[kind] = true;\n\t\tif (this.running) return;\n\n\t\tif (this.timer) clearTimeout(this.timer);\n\t\tthis.timer = setTimeout(() => {\n\t\t\tthis.timer = null;\n\t\t\tvoid this.flush();\n\t\t}, this.debounceMs);\n\t}\n\n\t/**\n\t * Flushes pending changes in serialized batches.\n\t *\n\t * @returns {Promise<void>} Resolves after all currently pending changes have\n\t * been consumed or the error callback has been invoked.\n\t */\n\tprivate async flush(): Promise<void> {\n\t\tif (this.running) return;\n\t\tthis.running = true;\n\n\t\ttry {\n\t\t\twhile (this.hasPendingChanges()) {\n\t\t\t\tawait this.onBatch(this.consumePending());\n\t\t\t}\n\t\t} catch (error) {\n\t\t\tthis.onError(error);\n\t\t} finally {\n\t\t\tthis.running = false;\n\t\t\tif (this.hasPendingChanges() && !this.timer) {\n\t\t\t\tthis.timer = setTimeout(() => {\n\t\t\t\t\tthis.timer = null;\n\t\t\t\t\tvoid this.flush();\n\t\t\t\t}, this.debounceMs);\n\t\t\t}\n\t\t}\n\t}\n\n\t/**\n\t * Returns whether any change category is currently pending.\n\t *\n\t * @returns {boolean} `true` when a flush still has work to process.\n\t */\n\tprivate hasPendingChanges(): boolean {\n\t\treturn this.pending.source || this.pending.config || this.pending.env;\n\t}\n\n\t/**\n\t * Returns the current pending batch and clears the internal flags.\n\t *\n\t * @returns {DevChangeBatch} Snapshot of the pending change flags that should\n\t * be processed next.\n\t */\n\tprivate consumePending(): DevChangeBatch {\n\t\tconst batch = { ...this.pending };\n\t\tthis.pending.source = false;\n\t\tthis.pending.config = false;\n\t\tthis.pending.env = false;\n\t\treturn batch;\n\t}\n}\n","import { join } from \"node:path\";\nimport { HostSupervisor } from \"@lithia-js/core/_\";\nimport { logger } from \"@lithia-js/utils\";\nimport chokidar from \"chokidar\";\nimport { defineCommand } from \"citty\";\nimport { type DevChangeBatch, DevLifecycleScheduler } from \"./dev-scheduler\";\n\n/**\n * CLI command that runs the Lithia development server with incremental rebuild\n * and reload behavior.\n *\n * The command boots a development host supervisor, starts filesystem watchers\n * for source, config, and environment files, and serializes reload work\n * through `DevLifecycleScheduler` so overlapping file changes do not race.\n */\nconst dev = defineCommand({\n\tmeta: {\n\t\tname: \"dev\",\n\t\tdescription: \"Start the development server with hot-reload capabilities\",\n\t},\n\n\t/**\n\t * Runs the development server lifecycle for the current project.\n\t *\n\t * @returns {Promise<void>} Resolves after watchers and shutdown handlers have\n\t * been registered.\n\t */\n\tasync run() {\n\t\tconst cwd = process.cwd();\n\t\tconst lithia = new HostSupervisor({ environment: \"development\" });\n\n\t\t// 1. Initial Host Setup\n\t\tawait lithia.setup();\n\t\tconst initialBuildSucceeded = await lithia.build();\n\t\tconst lifecycleState = {\n\t\t\thasReloadableArtifacts: initialBuildSucceeded,\n\t\t};\n\n\t\tif (initialBuildSucceeded) {\n\t\t\ttry {\n\t\t\t\tawait lithia.start();\n\t\t\t} catch {\n\t\t\t\tlogger.error(\"Failed to start the development server.\");\n\t\t\t}\n\t\t} else {\n\t\t\tlogger.warn(\n\t\t\t\t\"Initial build failed. Waiting for file changes while continuing to serve nothing.\",\n\t\t\t);\n\t\t}\n\n\t\t// 2. Define the serialized dev lifecycle\n\t\tconst scheduler = new DevLifecycleScheduler(\n\t\t\tasync (batch) => {\n\t\t\t\tawait processDevBatch(lithia, batch, lifecycleState);\n\t\t\t},\n\t\t\t180,\n\t\t\t(error) => {\n\t\t\t\tlogger.error(\"Dev lifecycle failed:\", error);\n\t\t\t},\n\t\t);\n\n\t\t// 3. Source Code Watcher\n\t\tconst srcWatcher = chokidar.watch(join(cwd, \"src\"), {\n\t\t\tignored: [/(^|[/\\\\])\\../, \"**/node_modules/**\"],\n\t\t\tpersistent: true,\n\t\t\tignoreInitial: true,\n\t\t});\n\n\t\tsrcWatcher.on(\"all\", (event) => {\n\t\t\tif ([\"add\", \"change\", \"unlink\"].includes(event)) {\n\t\t\t\tscheduler.enqueue(\"source\");\n\t\t\t}\n\t\t});\n\n\t\t// 4. Configuration and Environment Watcher\n\t\tconst extensions = [\".js\", \".mjs\", \".ts\", \".mts\", \".json\"];\n\t\tconst configFiles = [\n\t\t\t...lithia.config.envFiles,\n\t\t\t...extensions.map((ext) => join(cwd, `lithia.config${ext}`)),\n\t\t];\n\n\t\tconst configWatcher = chokidar.watch(configFiles, {\n\t\t\tcwd,\n\t\t\tignoreInitial: true,\n\t\t});\n\n\t\tconfigWatcher.on(\"all\", (event, filePath) => {\n\t\t\tif ([\"change\", \"add\"].includes(event)) {\n\t\t\t\tif (filePath.includes(\"lithia.config\")) {\n\t\t\t\t\tscheduler.enqueue(\"config\");\n\t\t\t\t} else {\n\t\t\t\t\tscheduler.enqueue(\"env\");\n\t\t\t\t}\n\t\t\t}\n\t\t});\n\n\t\t// 5. Graceful Shutdown Orchestration\n\t\tconst shutdown = async () => {\n\t\t\tlogger.info(\"Shutting down development server...\");\n\t\t\tawait Promise.allSettled([\n\t\t\t\tsrcWatcher.close(),\n\t\t\t\tconfigWatcher.close(),\n\t\t\t\tlithia.stop(),\n\t\t\t]);\n\t\t\tprocess.exit(0);\n\t\t};\n\n\t\t// Correctly bind signal handlers to the shutdown sequence\n\t\tprocess.once(\"SIGINT\", shutdown);\n\t\tprocess.once(\"SIGTERM\", shutdown);\n\t},\n});\n\nexport default dev;\n\n/**\n * Processes a coalesced development change batch against the host supervisor.\n *\n * Config changes reload config and env first, rebuild the project, and roll\n * back to the previous config/env snapshot when the rebuild fails. Source-only\n * changes rebuild the project before reloading, while env-only changes reload\n * the host only when usable build artifacts are already available.\n *\n * @param {HostSupervisor} lithia - Development host supervisor that owns build\n * and reload behavior.\n * @param {DevChangeBatch} batch - Coalesced set of pending source/config/env\n * changes.\n * @param {{ hasReloadableArtifacts: boolean }} state - Mutable lifecycle state\n * used to remember whether reloadable build artifacts currently exist.\n * @returns {Promise<void>} Resolves after the requested dev lifecycle work\n * completes.\n */\nexport async function processDevBatch(\n\tlithia: HostSupervisor,\n\tbatch: DevChangeBatch,\n\tstate: { hasReloadableArtifacts: boolean },\n): Promise<void> {\n\tif (batch.config) {\n\t\tconst previousConfig = structuredClone(lithia.config);\n\t\tconst previousEnv = lithia.getEnvSnapshot();\n\n\t\ttry {\n\t\t\tawait lithia.loadConfig();\n\t\t\tawait lithia.loadEnv();\n\n\t\t\tconst buildSucceeded = await lithia.build();\n\t\t\tif (!buildSucceeded) {\n\t\t\t\tstate.hasReloadableArtifacts =\n\t\t\t\t\tstate.hasReloadableArtifacts || lithia.isAppReady;\n\t\t\t\tlithia.replaceConfig(previousConfig);\n\t\t\t\tlithia.replaceEnv(previousEnv);\n\t\t\t\tlogger.warn(\n\t\t\t\t\t\"Reload skipped due to build failure. Rolled back config/env and kept serving the previous app.\",\n\t\t\t\t);\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tawait lithia.reload();\n\t\t\tstate.hasReloadableArtifacts = true;\n\t\t\treturn;\n\t\t} catch (error) {\n\t\t\tlithia.replaceConfig(previousConfig);\n\t\t\tlithia.replaceEnv(previousEnv);\n\t\t\tthrow error;\n\t\t}\n\t}\n\n\tif (batch.source) {\n\t\tconst buildSucceeded = await lithia.build();\n\n\t\tif (!buildSucceeded) {\n\t\t\tstate.hasReloadableArtifacts =\n\t\t\t\tstate.hasReloadableArtifacts || lithia.isAppReady;\n\t\t\tlogger.warn(\n\t\t\t\t\"Reload skipped due to build failure. Continuing to serve previous app.\",\n\t\t\t);\n\t\t\treturn;\n\t\t}\n\n\t\tstate.hasReloadableArtifacts = true;\n\t}\n\n\tif (batch.env) {\n\t\tif (!state.hasReloadableArtifacts) {\n\t\t\tlogger.warn(\n\t\t\t\t\"Reload skipped because the latest build artifacts are unavailable. Fix the build and save again.\",\n\t\t\t);\n\t\t\treturn;\n\t\t}\n\t\tawait lithia.loadEnv();\n\t}\n\n\tif (batch.source || batch.env) {\n\t\tawait lithia.reload();\n\t\tstate.hasReloadableArtifacts = true;\n\n\t\tif (batch.env && !batch.source) {\n\t\t\tlogger.success(\"Applied environment changes.\");\n\t\t}\n\t}\n}\n","{\n\t\"name\": \"@lithia-js/cli\",\n\t\"version\": \"1.0.0-canary.30\",\n\t\"description\": \"Command-line interface for developing and building Lithia.js applications.\",\n\t\"keywords\": [\n\t\t\"lithia\",\n\t\t\"lithia-js\",\n\t\t\"cli\",\n\t\t\"framework\",\n\t\t\"backend\",\n\t\t\"create-app\",\n\t\t\"build-tool\",\n\t\t\"dev-server\"\n\t],\n\t\"author\": \"Lucas Arch <luketsx@icloud.com>\",\n\t\"license\": \"MIT\",\n\t\"homepage\": \"https://lithiajs.org\",\n\t\"repository\": {\n\t\t\"type\": \"git\",\n\t\t\"url\": \"git+https://github.com/lithia-framework/lithia.git\",\n\t\t\"directory\": \"packages/cli\"\n\t},\n\t\"bugs\": {\n\t\t\"url\": \"https://github.com/lithia-framework/lithia/issues\"\n\t},\n\t\"type\": \"module\",\n\t\"bin\": {\n\t\t\"lithia\": \"./dist/index.mjs\"\n\t},\n\t\"main\": \"./dist/index.mjs\",\n\t\"files\": [\n\t\t\"dist\",\n\t\t\"templates\"\n\t],\n\t\"engines\": {\n\t\t\"node\": \">=20\"\n\t},\n\t\"scripts\": {\n\t\t\"build\": \"tsup --config tsup.config.ts\",\n\t\t\"test\": \"vitest --run\"\n\t},\n\t\"dependencies\": {\n\t\t\"@lithia-js/core\": \"workspace:1.0.0-canary.30\",\n\t\t\"@lithia-js/utils\": \"workspace:1.0.0-canary.30\",\n\t\t\"citty\": \"^0.2.0\",\n\t\t\"chokidar\": \"^5.0.0\"\n\t},\n\t\"publishConfig\": {\n\t\t\"registry\": \"https://registry.npmjs.org/\",\n\t\t\"access\": \"public\",\n\t\t\"provenance\": true\n\t}\n}\n","import pJson from \"../package.json\" with { type: \"json\" };\nexport const version = pJson.version;\n","#! /usr/bin/env node\n\nimport { defineCommand, runMain } from \"citty\";\nimport build from \"./cmd/build\";\nimport dev from \"./cmd/dev\";\nimport { version } from \"./meta\";\n\nconst main = defineCommand({\n\tmeta: {\n\t\tname: \"lithia\",\n\t\tdescription: \"Lithia CLI\",\n\t\tversion,\n\t},\n\tsubCommands: {\n\t\tdev,\n\t\tbuild,\n\t},\n});\n\nrunMain(main).then();\n"]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@lithia-js/cli",
3
- "version": "1.0.0-canary.29",
3
+ "version": "1.0.0-canary.30",
4
4
  "description": "Command-line interface for developing and building Lithia.js applications.",
5
5
  "keywords": [
6
6
  "lithia",
@@ -36,8 +36,8 @@
36
36
  "node": ">=20"
37
37
  },
38
38
  "dependencies": {
39
- "@lithia-js/core": "1.0.0-canary.29",
40
- "@lithia-js/utils": "1.0.0-canary.29",
39
+ "@lithia-js/core": "1.0.0-canary.30",
40
+ "@lithia-js/utils": "1.0.0-canary.30",
41
41
  "citty": "^0.2.0",
42
42
  "chokidar": "^5.0.0"
43
43
  },