@mandujs/core 0.9.13 → 0.9.15
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/package.json +1 -1
- package/src/generator/generate.ts +15 -0
- package/src/watcher/watcher.ts +31 -0
package/package.json
CHANGED
|
@@ -2,8 +2,10 @@ import type { RoutesManifest, RouteSpec } from "../spec/schema";
|
|
|
2
2
|
import { generateApiHandler, generatePageComponent, generateSlotLogic } from "./templates";
|
|
3
3
|
import { generateContractTypeGlue, generateContractTemplate, generateContractTypesIndex } from "./contract-glue";
|
|
4
4
|
import { computeHash } from "../spec/lock";
|
|
5
|
+
import { getWatcher } from "../watcher/watcher";
|
|
5
6
|
import path from "path";
|
|
6
7
|
import fs from "fs/promises";
|
|
8
|
+
import fsSync from "fs";
|
|
7
9
|
|
|
8
10
|
async function fileExists(filePath: string): Promise<boolean> {
|
|
9
11
|
try {
|
|
@@ -135,6 +137,10 @@ export async function generateRoutes(
|
|
|
135
137
|
warnings: [],
|
|
136
138
|
};
|
|
137
139
|
|
|
140
|
+
// Suppress watcher during generation to avoid false positives
|
|
141
|
+
const watcher = getWatcher();
|
|
142
|
+
watcher?.suppress();
|
|
143
|
+
|
|
138
144
|
const serverRoutesDir = path.join(rootDir, "apps/server/generated/routes");
|
|
139
145
|
const webRoutesDir = path.join(rootDir, "apps/web/generated/routes");
|
|
140
146
|
const typesDir = path.join(rootDir, "apps/server/generated/types");
|
|
@@ -338,5 +344,14 @@ export async function generateRoutes(
|
|
|
338
344
|
const mapPath = path.join(mapDir, "generated.map.json");
|
|
339
345
|
await Bun.write(mapPath, JSON.stringify(generatedMap, null, 2));
|
|
340
346
|
|
|
347
|
+
// Resume watcher after generation
|
|
348
|
+
watcher?.resume();
|
|
349
|
+
// Cross-process timestamp: watcher skips warnings if generate finished recently
|
|
350
|
+
const stampDir = path.join(rootDir, ".mandu");
|
|
351
|
+
if (!fsSync.existsSync(stampDir)) {
|
|
352
|
+
fsSync.mkdirSync(stampDir, { recursive: true });
|
|
353
|
+
}
|
|
354
|
+
fsSync.writeFileSync(path.join(stampDir, "generate.stamp"), Date.now().toString());
|
|
355
|
+
|
|
341
356
|
return result;
|
|
342
357
|
}
|
package/src/watcher/watcher.ts
CHANGED
|
@@ -67,6 +67,7 @@ export class FileWatcher {
|
|
|
67
67
|
private logFile: string | null = null;
|
|
68
68
|
private logStream: fs.WriteStream | null = null;
|
|
69
69
|
private tailProcess: ChildProcess | null = null;
|
|
70
|
+
private _suppressed: boolean = false;
|
|
70
71
|
|
|
71
72
|
constructor(config: WatcherConfig) {
|
|
72
73
|
this.config = {
|
|
@@ -229,6 +230,20 @@ export class FileWatcher {
|
|
|
229
230
|
this.recentWarnings = [];
|
|
230
231
|
}
|
|
231
232
|
|
|
233
|
+
/**
|
|
234
|
+
* Suppress warnings (e.g. during generate)
|
|
235
|
+
*/
|
|
236
|
+
suppress(): void {
|
|
237
|
+
this._suppressed = true;
|
|
238
|
+
}
|
|
239
|
+
|
|
240
|
+
/**
|
|
241
|
+
* Resume warnings after suppression
|
|
242
|
+
*/
|
|
243
|
+
resume(): void {
|
|
244
|
+
this._suppressed = false;
|
|
245
|
+
}
|
|
246
|
+
|
|
232
247
|
/**
|
|
233
248
|
* Open a new terminal window tailing the log file
|
|
234
249
|
*/
|
|
@@ -266,8 +281,24 @@ export class FileWatcher {
|
|
|
266
281
|
event: "create" | "modify" | "delete",
|
|
267
282
|
filePath: string
|
|
268
283
|
): Promise<void> {
|
|
284
|
+
if (this._suppressed) return;
|
|
285
|
+
|
|
269
286
|
const { rootDir } = this.config;
|
|
270
287
|
|
|
288
|
+
// Cross-process: skip if generate finished within last 2 seconds
|
|
289
|
+
// Walk up from the changed file to find nearest .mandu/generate.stamp
|
|
290
|
+
let stampDir = path.dirname(filePath);
|
|
291
|
+
while (stampDir !== path.dirname(stampDir)) {
|
|
292
|
+
const stampFile = path.join(stampDir, ".mandu", "generate.stamp");
|
|
293
|
+
try {
|
|
294
|
+
const stamp = parseInt(fs.readFileSync(stampFile, "utf-8"), 10);
|
|
295
|
+
if (Date.now() - stamp < 2000) return;
|
|
296
|
+
break;
|
|
297
|
+
} catch {}
|
|
298
|
+
stampDir = path.dirname(stampDir);
|
|
299
|
+
}
|
|
300
|
+
|
|
301
|
+
|
|
271
302
|
// Validate file against rules
|
|
272
303
|
try {
|
|
273
304
|
const warnings = await validateFile(filePath, event, rootDir);
|