@zenithbuild/cli 0.6.5 → 0.6.6

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.
@@ -17,6 +17,7 @@ import { readFile, stat } from 'node:fs/promises';
17
17
  import { basename, dirname, extname, isAbsolute, join, relative, resolve } from 'node:path';
18
18
  import { build } from './build.js';
19
19
  import { createSilentLogger } from './ui/logger.js';
20
+ import { readChangeFingerprint } from './dev-watch.js';
20
21
  import {
21
22
  executeServerRoute,
22
23
  injectSsrPayload,
@@ -570,6 +571,7 @@ export async function createDevServer(options) {
570
571
 
571
572
  let _buildDebounce = null;
572
573
  let _queuedFiles = new Set();
574
+ const _lastQueuedFingerprints = new Map();
573
575
  let _buildInFlight = false;
574
576
 
575
577
  function _isWithin(parent, child) {
@@ -726,8 +728,15 @@ export async function createDevServer(options) {
726
728
  if (_shouldIgnoreChange(changedPath)) {
727
729
  return;
728
730
  }
729
- _queuedFiles.add(changedPath);
730
- triggerBuildDrain();
731
+ void (async () => {
732
+ const fingerprint = await readChangeFingerprint(changedPath);
733
+ if (_lastQueuedFingerprints.get(changedPath) === fingerprint) {
734
+ return;
735
+ }
736
+ _lastQueuedFingerprints.set(changedPath, fingerprint);
737
+ _queuedFiles.add(changedPath);
738
+ triggerBuildDrain();
739
+ })();
731
740
  });
732
741
  _watchers.push(watcher);
733
742
  } catch {
@@ -0,0 +1,19 @@
1
+ import { stat } from 'node:fs/promises';
2
+
3
+ export async function readChangeFingerprint(absPath) {
4
+ try {
5
+ const info = await stat(absPath);
6
+ const kind = info.isDirectory()
7
+ ? 'dir'
8
+ : info.isFile()
9
+ ? 'file'
10
+ : 'other';
11
+ return `${kind}:${info.mtimeMs}:${info.size}`;
12
+ } catch (error) {
13
+ const code = error && typeof error === 'object' ? error.code : '';
14
+ if (code === 'ENOENT' || code === 'ENOTDIR') {
15
+ return 'missing';
16
+ }
17
+ return `error:${String(code || 'unknown')}`;
18
+ }
19
+ }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@zenithbuild/cli",
3
- "version": "0.6.5",
3
+ "version": "0.6.6",
4
4
  "description": "Deterministic project orchestrator for Zenith framework",
5
5
  "license": "MIT",
6
6
  "type": "module",
@@ -15,6 +15,15 @@
15
15
  "dist/**",
16
16
  "package.json"
17
17
  ],
18
+ "repository": {
19
+ "type": "git",
20
+ "url": "https://github.com/zenithbuild/framework",
21
+ "directory": "packages/cli"
22
+ },
23
+ "bugs": {
24
+ "url": "https://github.com/zenithbuild/framework/issues"
25
+ },
26
+ "homepage": "https://github.com/zenithbuild/framework#readme",
18
27
  "publishConfig": {
19
28
  "access": "public"
20
29
  },
@@ -24,13 +33,14 @@
24
33
  "prepublishOnly": "npm run build"
25
34
  },
26
35
  "dependencies": {
27
- "@zenithbuild/compiler": "^0.6.5",
36
+ "@zenithbuild/compiler": "0.6.6",
28
37
  "picocolors": "^1.1.1"
29
38
  },
30
39
  "devDependencies": {
31
40
  "@jest/globals": "^30.2.0",
32
41
  "jest": "^30.2.0",
33
- "jest-environment-jsdom": "^30.2.0"
42
+ "jest-environment-jsdom": "^30.2.0",
43
+ "typescript": "^5.7.3"
34
44
  },
35
45
  "private": false
36
46
  }