feat(watchers): add Rust-powered watcher backend with runtime fallback and cross-platform test coverage

This commit is contained in:
2026-03-23 14:15:31 +00:00
parent ca9a66e03e
commit 7def7020c6
26 changed files with 10383 additions and 2870 deletions

View File

@@ -1,6 +1,5 @@
import { tap, expect } from '@git.zone/tstest/tapbundle';
import * as smartwatch from '../ts/index.js';
import * as smartfile from '@push.rocks/smartfile';
import * as smartrx from '@push.rocks/smartrx';
import * as fs from 'fs';
@@ -63,7 +62,7 @@ tap.test('should detect delete+recreate as change event (atomic handling)', asyn
await delay(100);
// Create initial file
await smartfile.memory.toFs('initial content', testFile);
await fs.promises.writeFile(testFile, 'initial content');
await delay(300);
// Get the initial inode
@@ -77,7 +76,7 @@ tap.test('should detect delete+recreate as change event (atomic handling)', asyn
// Delete and recreate (this creates a new inode)
await fs.promises.unlink(testFile);
await smartfile.memory.toFs('recreated content', testFile);
await fs.promises.writeFile(testFile, 'recreated content');
// Check inode changed
const newStats = await fs.promises.stat(testFile);
@@ -103,17 +102,24 @@ tap.test('should detect atomic write pattern (temp file + rename)', async () =>
const tempFile = path.join(TEST_DIR, 'atomic-test.txt.tmp.12345');
// Create initial file
await smartfile.memory.toFs('initial content', testFile);
await fs.promises.writeFile(testFile, 'initial content');
await delay(300);
// Listen for both change and add events — different watcher backends
// may report a rename-over-existing as either a change or an add
const changeObservable = await testSmartwatch.getObservableFor('change');
const eventPromise = waitForFileEvent(changeObservable, 'atomic-test.txt', 3000);
const addObservable = await testSmartwatch.getObservableFor('add');
const eventPromise = Promise.race([
waitForFileEvent(changeObservable, 'atomic-test.txt', 3000),
waitForFileEvent(addObservable, 'atomic-test.txt', 3000),
]);
// Atomic write: create temp file then rename
await smartfile.memory.toFs('atomic content', tempFile);
await fs.promises.writeFile(tempFile, 'atomic content');
await fs.promises.rename(tempFile, testFile);
// Should detect the change to the target file
// Should detect the event on the target file
const [filePath] = await eventPromise;
expect(filePath).toInclude('atomic-test.txt');
expect(filePath).not.toInclude('.tmp.');