@cosmicdrift/kumiko-dev-server 0.402.0 → 0.403.0

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.
@@ -19,4 +19,5 @@ export type DevFileWatcherDeps = {
19
19
  readonly reloadHub: DevReloadHub;
20
20
  readonly stop: () => Promise<void>;
21
21
  };
22
+ export declare function isUnchangedSinceWatchStart(absolutePath: string, watchStartedAtMs: number): boolean;
22
23
  export declare function startDevFileWatchers(deps: DevFileWatcherDeps): void;
@@ -112,14 +112,27 @@ function expandWatchPatterns(patterns) {
112
112
  }
113
113
  return out;
114
114
  }
115
+ // A deleted or renamed file is a real change, so a failing stat counts as changed.
116
+ export function isUnchangedSinceWatchStart(absolutePath, watchStartedAtMs) {
117
+ try {
118
+ return statSync(absolutePath).mtimeMs < watchStartedAtMs;
119
+ }
120
+ catch {
121
+ return false;
122
+ }
123
+ }
115
124
  // Because Bun caches module imports, a server-side change needs a process
116
125
  // restart: exit code 75 (EX_TEMPFAIL) lets the `kumiko-dev` wrapper respawn.
117
- async function handleWatchedChange(deps, dir, filename, entrySourceFiles) {
126
+ async function handleWatchedChange(deps, dir, filename, entrySourceFiles, watchStartedAtMs) {
118
127
  const action = classifyWatchedChange(dir, filename, entrySourceFiles);
119
128
  // skip: file change classified as ignore (test/css/json), nothing to rebuild
120
129
  if (action === "ignore")
121
130
  return;
122
131
  if (action === "restart") {
132
+ // skip: macOS FSEvents also reports metadata and late events without a content change;
133
+ // restarting would kill a directly started server (no kumiko-dev wrapper) for nothing.
134
+ if (isUnchangedSinceWatchStart(resolve(dir, filename), watchStartedAtMs))
135
+ return;
123
136
  logInfo(`[kumiko-server] schema change in ${filename} — restarting (Bun caches imports, hot-reload reicht hier nicht). ` +
124
137
  "The kumiko-dev wrapper (package.json's `dev` script) respawns automatically " +
125
138
  "and re-syncs new r.entity() columns on the new boot; running this entry " +
@@ -148,8 +161,9 @@ export function startDevFileWatchers(deps) {
148
161
  for (const e of deps.entries)
149
162
  entryDirs.add(resolve(e.sourceFile, ".."));
150
163
  const entrySourceFiles = new Set(deps.entries.map((e) => resolve(e.sourceFile)));
164
+ const watchStartedAtMs = Date.now();
151
165
  const dirs = [...entryDirs, ...expandWatchPatterns(deps.watchDirs ?? [])];
152
166
  for (const dir of dirs) {
153
- void watchDir(dir, (filename) => handleWatchedChange(deps, dir, filename, entrySourceFiles), deps.signal, deps.watchDirectory ?? watch);
167
+ void watchDir(dir, (filename) => handleWatchedChange(deps, dir, filename, entrySourceFiles, watchStartedAtMs), deps.signal, deps.watchDirectory ?? watch);
154
168
  }
155
169
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@cosmicdrift/kumiko-dev-server",
3
- "version": "0.402.0",
3
+ "version": "0.403.0",
4
4
  "description": "Dev-tooling for Kumiko apps: local dev-server bootstrap (runDevApp), scaffolding. Its compose-stacks/env-schema subpaths are consumed at prod boot too — see @cosmicdrift/kumiko-server-runtime for the prod runner itself.",
5
5
  "license": "MIT",
6
6
  "author": "Marc Frost <marc@cosmicdriftgamestudio.com>",
@@ -77,15 +77,15 @@
77
77
  "kumiko-upgrade": "./bin/kumiko-upgrade.ts"
78
78
  },
79
79
  "dependencies": {
80
- "@cosmicdrift/kumiko-bundled-features": "0.402.0",
81
- "@cosmicdrift/kumiko-feature-ast": "0.402.0",
82
- "@cosmicdrift/kumiko-framework": "0.402.0",
83
- "@cosmicdrift/kumiko-renderer": "0.402.0",
84
- "@cosmicdrift/kumiko-renderer-mail-html": "0.402.0",
85
- "@cosmicdrift/kumiko-guards": "0.402.0",
86
- "@cosmicdrift/kumiko-server-runtime": "0.402.0",
87
- "@cosmicdrift/kumiko-testing": "0.402.0",
88
- "@cosmicdrift/kumiko-types": "0.402.0",
80
+ "@cosmicdrift/kumiko-bundled-features": "0.403.0",
81
+ "@cosmicdrift/kumiko-feature-ast": "0.403.0",
82
+ "@cosmicdrift/kumiko-framework": "0.403.0",
83
+ "@cosmicdrift/kumiko-renderer": "0.403.0",
84
+ "@cosmicdrift/kumiko-renderer-mail-html": "0.403.0",
85
+ "@cosmicdrift/kumiko-guards": "0.403.0",
86
+ "@cosmicdrift/kumiko-server-runtime": "0.403.0",
87
+ "@cosmicdrift/kumiko-testing": "0.403.0",
88
+ "@cosmicdrift/kumiko-types": "0.403.0",
89
89
  "ts-morph": "^28.0.0",
90
90
  "zod": "^4.6.7"
91
91
  },
package/src/changes.json CHANGED
@@ -1,4 +1,10 @@
1
1
  [
2
+ {
3
+ "version": "0.403.0",
4
+ "type": "fix",
5
+ "title": "Dev watcher ignores restart events on unchanged files",
6
+ "detail": "startDevFileWatchers records the watcher start time and skips a restart when the changed file's mtime is older than that start. A failing stat (deleted or renamed file) still restarts. Known limit: a file copied in with a preserved older mtime (cp -p, rsync -a) no longer triggers a restart."
7
+ },
2
8
  {
3
9
  "version": "0.401.0",
4
10
  "type": "improvement",