@lvce-editor/file-watcher-process 4.14.0 → 4.14.1

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.
Files changed (2) hide show
  1. package/dist/index.js +63 -41
  2. package/package.json +1 -1
package/dist/index.js CHANGED
@@ -1255,7 +1255,7 @@ const normalizeEvent = (eventName, path) => {
1255
1255
  };
1256
1256
  };
1257
1257
 
1258
- const waitForWatcherToBeReady = async watcher => {
1258
+ const waitForWatcherToBeReady = async (watcher, signal) => {
1259
1259
  const {
1260
1260
  promise,
1261
1261
  reject,
@@ -1264,6 +1264,7 @@ const waitForWatcherToBeReady = async watcher => {
1264
1264
  const cleanup = () => {
1265
1265
  watcher.off('ready', handleReady);
1266
1266
  watcher.off('error', handleError);
1267
+ signal?.removeEventListener('abort', handleAbort);
1267
1268
  };
1268
1269
  const handleReady = () => {
1269
1270
  cleanup();
@@ -1273,6 +1274,13 @@ const waitForWatcherToBeReady = async watcher => {
1273
1274
  cleanup();
1274
1275
  reject(error);
1275
1276
  };
1277
+ const handleAbort = () => {
1278
+ handleError(signal?.reason);
1279
+ };
1280
+ signal?.throwIfAborted();
1281
+ signal?.addEventListener('abort', handleAbort, {
1282
+ once: true
1283
+ });
1276
1284
  watcher.on('ready', handleReady);
1277
1285
  watcher.on('error', handleError);
1278
1286
  await promise;
@@ -1326,7 +1334,7 @@ const callBackInternal = async (eventName, path, stats) => {
1326
1334
  const callback = (eventName, path, stats) => {
1327
1335
  void callBackInternal(eventName, path);
1328
1336
  };
1329
- const errorCallback$1 = error => {
1337
+ const errorCallback = error => {
1330
1338
  console.error(`[file-watcher-process] ${error}`);
1331
1339
  };
1332
1340
  const watchFolder = async uri => {
@@ -1335,7 +1343,7 @@ const watchFolder = async uri => {
1335
1343
  const path = fileURLToPath(uri);
1336
1344
  watcher = new FSWatcher();
1337
1345
  watcher.on('all', callback);
1338
- watcher.on('error', errorCallback$1);
1346
+ watcher.on('error', errorCallback);
1339
1347
  const readyPromise = waitForWatcherToBeReady(watcher);
1340
1348
  watcher.add(path);
1341
1349
  await readyPromise;
@@ -1391,9 +1399,6 @@ const normalizeEvent2 = (id, eventName, path) => {
1391
1399
  };
1392
1400
 
1393
1401
  const createIgnore = ignore;
1394
- const errorCallback = error => {
1395
- console.error(`[file-watcher-process] ${error}`);
1396
- };
1397
1402
  const loadGitIgnore = async (root, enabled) => {
1398
1403
  try {
1399
1404
  const content = await readFile(`${root}/.gitignore`, 'utf8');
@@ -1424,36 +1429,68 @@ const createIgnored = async (root, exclude, useGitIgnore) => {
1424
1429
  return gitIgnore.ignores(candidate);
1425
1430
  };
1426
1431
  };
1432
+ const send = event => {
1433
+ void invoke('FileWatcher.handleChange', event).catch(error => {
1434
+ console.error(`[file-watcher-process] ${error}`);
1435
+ });
1436
+ };
1427
1437
  const watchFolders = async ({
1428
1438
  exclude,
1429
1439
  id,
1430
1440
  roots,
1431
1441
  useGitIgnore = false
1432
1442
  }) => {
1433
- const callBackInternal = async (eventName, path, stats) => {
1434
- const event = normalizeEvent2(id, eventName, path);
1435
-
1436
- // TODO maybe just use send instead of invoke or
1437
- // send the message to a websocket or message channel directly
1438
- // instead of routing events through shared process
1439
- // which might lock up the shared process in case there are many events
1440
- await invoke('FileWatcher.handleChange', event);
1443
+ if (has(id)) {
1444
+ return fromError(new Error(`watcher ${id} is already registered`));
1445
+ }
1446
+ const controller = new AbortController();
1447
+ const watcherEntries = [];
1448
+ let ready = false;
1449
+ let closing;
1450
+ const callback = (eventName, path) => {
1451
+ if (!controller.signal.aborted) {
1452
+ send(normalizeEvent2(id, eventName, path));
1453
+ }
1441
1454
  };
1442
- const callback = (eventName, path, stats) => {
1443
- void callBackInternal(eventName, path);
1455
+ const errorCallback = error => {
1456
+ console.error(`[file-watcher-process] ${error}`);
1457
+ if (controller.signal.aborted) return;
1458
+ if (ready) {
1459
+ send({
1460
+ ...fromError(error),
1461
+ eventName: 'error',
1462
+ id,
1463
+ uri: ''
1464
+ });
1465
+ }
1466
+ controller.abort(error);
1444
1467
  };
1445
- const watcherEntries = [];
1468
+ controller.signal.addEventListener('abort', () => {
1469
+ remove(id);
1470
+ closing = Promise.allSettled(watcherEntries.map(({
1471
+ watcher
1472
+ }) => watcher.close()));
1473
+ }, {
1474
+ once: true
1475
+ });
1476
+ // Register before asynchronous setup so disposal also cancels a pending watch.
1477
+ add(id, controller);
1446
1478
  try {
1447
1479
  for (const root of roots) {
1480
+ controller.signal.throwIfAborted();
1448
1481
  const path = fileURLToPath(root);
1449
1482
  const ignored = useGitIgnore ? await createIgnored(path, exclude, true) : createExcludedNamesFilter(exclude);
1483
+ controller.signal.throwIfAborted();
1450
1484
  const watcher = new FSWatcher({
1451
1485
  ignored,
1452
1486
  ignoreInitial: true,
1453
- ignorePermissionErrors: true
1487
+ ignorePermissionErrors: false
1454
1488
  });
1455
1489
  watcher.on('error', errorCallback);
1456
- const readyPromise = waitForWatcherToBeReady(watcher);
1490
+ watcher.on('all', callback);
1491
+ const readyPromise = waitForWatcherToBeReady(watcher, controller.signal);
1492
+ // Later roots can fail before Promise.all is reached.
1493
+ void readyPromise.catch(() => {});
1457
1494
  watcherEntries.push({
1458
1495
  readyPromise,
1459
1496
  watcher
@@ -1463,31 +1500,16 @@ const watchFolders = async ({
1463
1500
  await Promise.all(watcherEntries.map(({
1464
1501
  readyPromise
1465
1502
  }) => readyPromise));
1503
+ controller.signal.throwIfAborted();
1504
+ ready = true;
1505
+ const inotifyWatchCount = await getInotifyWatchCount();
1506
+ controller.signal.throwIfAborted();
1507
+ return inotifyWatchCount === undefined ? success : successWithInotifyWatchCount(inotifyWatchCount);
1466
1508
  } catch (error) {
1467
- await Promise.allSettled(watcherEntries.map(({
1468
- watcher
1469
- }) => watcher.close()));
1509
+ controller.abort(error);
1510
+ await closing;
1470
1511
  return fromError(error);
1471
1512
  }
1472
- for (const {
1473
- watcher
1474
- } of watcherEntries) {
1475
- watcher.on('all', callback);
1476
- }
1477
- const controller = new AbortController();
1478
- controller.signal.addEventListener('abort', () => {
1479
- void Promise.allSettled(watcherEntries.map(({
1480
- watcher
1481
- }) => watcher.close()));
1482
- }, {
1483
- once: true
1484
- });
1485
- add(id, controller);
1486
- const inotifyWatchCount = await getInotifyWatchCount();
1487
- if (inotifyWatchCount === undefined) {
1488
- return success;
1489
- }
1490
- return successWithInotifyWatchCount(inotifyWatchCount);
1491
1513
  };
1492
1514
 
1493
1515
  const commandMap = {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@lvce-editor/file-watcher-process",
3
- "version": "4.14.0",
3
+ "version": "4.14.1",
4
4
  "description": "File Watcher Process",
5
5
  "keywords": [
6
6
  "Lvce Editor",