sitevision-cli 1.0.0-beta.29 → 1.0.0-beta.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/CHANGELOG.md CHANGED
@@ -1,5 +1,13 @@
1
1
  # Changelog
2
2
 
3
+ ## 1.0.0-beta.30
4
+
5
+ - Dev and watch no longer rebuild on file events that change nothing, such as
6
+ editor metadata, swap files or `.DS_Store`. Ignored events are logged as
7
+ warnings so a stray trigger can be traced.
8
+ - The log names the event and path of the file that started a rebuild, for
9
+ example `change src/index.tsx`.
10
+
3
11
  ## 1.0.0-beta.29
4
12
 
5
13
  - After an update, the shell opens What's new with the changes since the
@@ -342,10 +342,42 @@ export function startDev(project, options) {
342
342
  building = false;
343
343
  }
344
344
  };
345
- const onChange = (name, file) => {
346
- log('fs', `changed ${file ?? name}`);
345
+ // Size + mtime of every watched file. An event that leaves this unchanged
346
+ // (editor metadata, xattrs, identical re-save) is noise and must not
347
+ // rebuild, or a stray event during sign/deploy loops forever.
348
+ const snapshot = () => {
349
+ const entries = [];
350
+ for (const name of WATCH_TARGETS) {
351
+ const target = path.join(root, name);
352
+ const stat = fs.statSync(target, { throwIfNoEntry: false });
353
+ if (!stat)
354
+ continue;
355
+ const files = (stat.isDirectory()
356
+ ? fs
357
+ .readdirSync(target, { recursive: true, withFileTypes: true })
358
+ .filter(entry => entry.isFile())
359
+ .map(entry => path.join(entry.parentPath, entry.name))
360
+ : [target]).filter(file => !path.basename(file).startsWith('.'));
361
+ for (const file of files) {
362
+ const info = fs.statSync(file, { throwIfNoEntry: false });
363
+ if (info)
364
+ entries.push(`${file}:${info.size}:${info.mtimeMs}`);
365
+ }
366
+ }
367
+ return entries.toSorted().join('\n');
368
+ };
369
+ let fingerprint = '';
370
+ const onChange = (name, event, file) => {
371
+ const where = file ? path.join(name, file) : name;
347
372
  clearTimeout(debounce);
348
373
  debounce = setTimeout(() => {
374
+ const next = snapshot();
375
+ if (next === fingerprint) {
376
+ log('fs', `${event} ${where} · no file changed, ignored`, 'warn');
377
+ return;
378
+ }
379
+ fingerprint = next;
380
+ log('fs', `${event} ${where}`);
349
381
  void rebuild();
350
382
  }, 300);
351
383
  };
@@ -355,10 +387,11 @@ export function startDev(project, options) {
355
387
  if (!fs.existsSync(target))
356
388
  continue;
357
389
  const isDir = fs.statSync(target).isDirectory();
358
- watchers.push(fs.watch(target, { recursive: isDir }, (_event, file) => {
359
- onChange(name, file);
390
+ watchers.push(fs.watch(target, { recursive: isDir }, (event, file) => {
391
+ onChange(name, event, file);
360
392
  }));
361
393
  }
394
+ fingerprint = snapshot();
362
395
  log('svc', `watching ${WATCH_TARGETS.join(', ')}`);
363
396
  };
364
397
  void (async () => {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "sitevision-cli",
3
- "version": "1.0.0-beta.29",
3
+ "version": "1.0.0-beta.30",
4
4
  "license": "MIT",
5
5
  "bin": {
6
6
  "svc": "dist/cli.js"