@allurereport/directory-watcher 3.15.0 → 3.16.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.
package/dist/index.d.ts CHANGED
@@ -5,4 +5,4 @@ declare const watchDirectory: (directory: string, handler: (eventName: EventName
5
5
  }) => () => Promise<void>;
6
6
  export default watchDirectory;
7
7
  export type { Watcher } from "./watcher.js";
8
- export { findMatching, newFilesInDirectoryWatcher, allureResultsDirectoriesWatcher, delayedFileProcessingWatcher, } from "./watcher.js";
8
+ export { findMatching, difference, watch, newFilesInDirectoryWatcher, allureResultsDirectoriesWatcher, delayedFileProcessingWatcher, } from "./watcher.js";
package/dist/index.js CHANGED
@@ -12,4 +12,4 @@ const watchDirectory = (directory, handler, options = {}) => {
12
12
  return () => watcher.close();
13
13
  };
14
14
  export default watchDirectory;
15
- export { findMatching, newFilesInDirectoryWatcher, allureResultsDirectoriesWatcher, delayedFileProcessingWatcher, } from "./watcher.js";
15
+ export { findMatching, difference, watch, newFilesInDirectoryWatcher, allureResultsDirectoriesWatcher, delayedFileProcessingWatcher, } from "./watcher.js";
package/dist/watcher.d.ts CHANGED
@@ -1,7 +1,7 @@
1
1
  import type { Dirent } from "node:fs";
2
2
  export declare const isFileNotFoundError: (e: unknown) => e is Error;
3
3
  export declare const difference: (before: Set<string>, after: Set<string>) => [Set<string>, Set<string>];
4
- export declare const findMatching: (watchDirectory: string, existingResults: Set<string>, match: (dirent: Dirent) => boolean, maximumDepth?: number) => Promise<void>;
4
+ export declare const findMatching: (watchDirectory: string, existingResults: Set<string>, match: (dirent: Dirent) => boolean, maximumDepth?: number, signal?: AbortSignal) => Promise<boolean>;
5
5
  interface WatchOptions {
6
6
  indexDelay?: number;
7
7
  abortController?: AbortController;
@@ -11,6 +11,7 @@ export interface Watcher {
11
11
  initialScan: () => Promise<void>;
12
12
  watchEnd: () => Promise<void>;
13
13
  }
14
+ export declare const watch: (initialCallback: () => Promise<void>, iterationCallback: () => Promise<void>, doneCallback: () => Promise<void>, options?: WatchOptions) => Watcher;
14
15
  interface WatchNewFilesOptions extends WatchOptions {
15
16
  recursive?: boolean;
16
17
  maximumDepth?: number;
package/dist/watcher.js CHANGED
@@ -18,39 +18,58 @@ export const difference = (before, after) => {
18
18
  }
19
19
  return [added, deleted];
20
20
  };
21
- export const findMatching = async (watchDirectory, existingResults, match, maximumDepth = 5) => {
22
- try {
23
- const dir = await opendir(watchDirectory);
24
- for await (const dirent of dir) {
25
- const path = join(dirent.parentPath ?? dirent.path, dirent.name);
26
- if (dirent.name.at(0) === "." || dirent.name === "node_modules") {
27
- continue;
28
- }
29
- if (existingResults.has(path)) {
30
- continue;
31
- }
32
- if (match(dirent)) {
33
- existingResults.add(path);
34
- continue;
35
- }
36
- if (dirent.isDirectory() && maximumDepth > 0) {
37
- await findMatching(path, existingResults, match, maximumDepth - 1);
21
+ export const findMatching = async (watchDirectory, existingResults, match, maximumDepth = 5, signal) => {
22
+ const scan = async (directory, remainingDepth, isRoot) => {
23
+ if (signal?.aborted) {
24
+ return false;
25
+ }
26
+ try {
27
+ const dir = await opendir(directory);
28
+ for await (const dirent of dir) {
29
+ if (signal?.aborted) {
30
+ return false;
31
+ }
32
+ const path = join(dirent.parentPath ?? dirent.path, dirent.name);
33
+ if (dirent.name.at(0) === "." || dirent.name === "node_modules") {
34
+ continue;
35
+ }
36
+ if (existingResults.has(path)) {
37
+ continue;
38
+ }
39
+ if (match(dirent)) {
40
+ existingResults.add(path);
41
+ continue;
42
+ }
43
+ if (dirent.isDirectory() && remainingDepth > 0) {
44
+ const completed = await scan(path, remainingDepth - 1, false);
45
+ if (!completed) {
46
+ return false;
47
+ }
48
+ }
38
49
  }
50
+ return !signal?.aborted;
39
51
  }
40
- }
41
- catch (e) {
42
- if (isFileNotFoundError(e)) {
43
- existingResults.clear();
44
- return;
52
+ catch (e) {
53
+ if (isFileNotFoundError(e)) {
54
+ if (isRoot) {
55
+ existingResults.clear();
56
+ }
57
+ return true;
58
+ }
59
+ console.error("can't read directory", e);
60
+ return false;
45
61
  }
46
- console.error("can't read directory", e);
47
- }
62
+ };
63
+ return scan(watchDirectory, maximumDepth, true);
48
64
  };
49
- const findFiles = async (watchDirectory, existingResults, onNewFile, recursive, maximumDepth = 10) => {
65
+ const findFiles = async (watchDirectory, existingResults, onNewFile, recursive, maximumDepth = 10, signal) => {
50
66
  const scanDirectory = async (directory, isRoot, remainingDepth) => {
51
67
  try {
52
68
  const dir = await opendir(directory);
53
69
  for await (const dirent of dir) {
70
+ if (signal?.aborted) {
71
+ return;
72
+ }
54
73
  const path = join(dirent.parentPath ?? dirent.path, dirent.name);
55
74
  if (dirent.isDirectory()) {
56
75
  if (recursive && remainingDepth > 0) {
@@ -100,7 +119,7 @@ const repeatedIteration = async (indexInterval, callback, ...ac) => {
100
119
  .then(() => repeatedIteration(indexInterval, callback, ...ac));
101
120
  };
102
121
  const noop = async () => { };
103
- const watch = (initialCallback, iterationCallback, doneCallback, options = {}) => {
122
+ export const watch = (initialCallback, iterationCallback, doneCallback, options = {}) => {
104
123
  const { indexDelay = 300, abortController: haltAc = new AbortController() } = options;
105
124
  const gracefulShutdownAc = new AbortController();
106
125
  const init = singleIteration(initialCallback, haltAc);
@@ -132,26 +151,30 @@ const watch = (initialCallback, iterationCallback, doneCallback, options = {}) =
132
151
  };
133
152
  };
134
153
  export const newFilesInDirectoryWatcher = (directory, onNewFile, options = {}) => {
135
- const { recursive = true, maximumDepth = 10, ignoreInitial = false, ...rest } = options;
154
+ const { recursive = true, maximumDepth = 10, ignoreInitial = false, abortController = new AbortController(), ...rest } = options;
136
155
  const indexedFiles = new Set();
137
156
  const initialCallback = async () => {
138
- await findFiles(directory, indexedFiles, ignoreInitial ? noop : onNewFile, recursive, maximumDepth);
157
+ await findFiles(directory, indexedFiles, ignoreInitial ? noop : onNewFile, recursive, maximumDepth, abortController.signal);
139
158
  };
140
159
  const iterationCallback = async () => {
141
- await findFiles(directory, indexedFiles, onNewFile, recursive, maximumDepth);
160
+ await findFiles(directory, indexedFiles, onNewFile, recursive, maximumDepth, abortController.signal);
142
161
  };
143
- return watch(initialCallback, iterationCallback, iterationCallback, rest);
162
+ return watch(initialCallback, iterationCallback, iterationCallback, { ...rest, abortController });
144
163
  };
145
164
  export const allureResultsDirectoriesWatcher = (directory, update, options = {}) => {
165
+ const { abortController = new AbortController(), ...rest } = options;
146
166
  let previousAllureResults = new Set();
147
167
  const callback = async () => {
148
168
  const currentAllureResults = new Set();
149
- await findMatching(directory, currentAllureResults, (dirent) => dirent.isDirectory() && dirent.name === "allure-results");
169
+ const completed = await findMatching(directory, currentAllureResults, (dirent) => dirent.isDirectory() && dirent.name === "allure-results", undefined, abortController.signal);
170
+ if (!completed) {
171
+ return;
172
+ }
150
173
  const [added, deleted] = difference(previousAllureResults, currentAllureResults);
151
174
  await update(added, deleted);
152
175
  previousAllureResults = currentAllureResults;
153
176
  };
154
- return watch(callback, callback, callback, options);
177
+ return watch(callback, callback, callback, { ...rest, abortController });
155
178
  };
156
179
  const calculateInfo = async (file) => {
157
180
  try {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@allurereport/directory-watcher",
3
- "version": "3.15.0",
3
+ "version": "3.16.1",
4
4
  "description": "File system watcher for directories",
5
5
  "keywords": [
6
6
  "allure",