@travetto/manifest 3.0.0 → 3.0.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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@travetto/manifest",
3
- "version": "3.0.0",
3
+ "version": "3.0.1",
4
4
  "description": "Support for project indexing, manifesting, along with file watching",
5
5
  "keywords": [
6
6
  "path",
@@ -297,23 +297,4 @@ export class ManifestIndex {
297
297
  }
298
298
  return out;
299
299
  }
300
-
301
- /**
302
- * Get local folders that represent the user's controlled input
303
- */
304
- getLocalInputFolderMapping(): [folder: string, moduleSourceRoot: string][] {
305
- return this.getLocalModules().flatMap(x =>
306
- ((!this.manifest.monoRepo || x.sourcePath !== this.manifest.workspacePath) ?
307
- [x.sourcePath] : [...Object.keys(x.files)].filter(y => !y.startsWith('$')).map(y => path.resolve(this.#manifest.workspacePath, x.sourcePath, y))
308
- // eslint-disable-next-line @typescript-eslint/consistent-type-assertions
309
- ).map(f => [f, path.resolve(this.#manifest.workspacePath, x.sourceFolder)] as [string, string])
310
- );
311
- }
312
-
313
- /**
314
- * Get local output folders
315
- */
316
- getLocalOutputFolders(): string[] {
317
- return this.getLocalModules().map(x => x.outputPath);
318
- }
319
300
  }
package/src/watch.ts CHANGED
@@ -1,3 +1,4 @@
1
+ import { watch, Stats } from 'fs';
1
2
  import fs from 'fs/promises';
2
3
  import { path } from './path';
3
4
 
@@ -11,14 +12,14 @@ async function getWatcher(): Promise<typeof import('@parcel/watcher')> {
11
12
  }
12
13
 
13
14
  export type WatchEvent = { action: 'create' | 'update' | 'delete', file: string };
14
- type EventFilter = (ev: WatchEvent) => boolean;
15
+ export type WatchEventFilter = (ev: WatchEvent) => boolean;
15
16
 
16
17
  export type WatchEventListener = (ev: WatchEvent, folder: string) => void;
17
18
  export type WatchConfig = {
18
19
  /**
19
20
  * Predicate for filtering events
20
21
  */
21
- filter?: EventFilter;
22
+ filter?: WatchEventFilter;
22
23
  /**
23
24
  * List of top level folders to ignore
24
25
  */
@@ -33,14 +34,68 @@ export type WatchConfig = {
33
34
  includeHidden?: boolean;
34
35
  };
35
36
 
37
+ /**
38
+ * Watch files for a given folder
39
+ * @param folder
40
+ * @param onEvent
41
+ * @param options
42
+ */
43
+ export async function watchFolderImmediate(
44
+ folder: string,
45
+ onEvent: WatchEventListener,
46
+ options: WatchConfig = {}
47
+ ): Promise<() => Promise<void>> {
48
+ const watchPath = path.resolve(folder);
49
+ const watcher = watch(watchPath, { persistent: true, encoding: 'utf8' });
50
+ const lastStats: Record<string, Stats | undefined> = {};
51
+ const invalidFilter = (el: string): boolean =>
52
+ (el === '.' || el === '..' || (!options.includeHidden && el.startsWith('.')) || !!options.ignore?.includes(el));
53
+
54
+ for (const el of await fs.readdir(watchPath)) {
55
+ if (invalidFilter(el)) {
56
+ continue;
57
+ }
58
+ const file = path.resolve(watchPath, el);
59
+ lastStats[file] = await fs.stat(file);
60
+ }
61
+ watcher.on('change', async (type: string, file: string): Promise<void> => {
62
+ if (invalidFilter(file)) {
63
+ return;
64
+ }
65
+
66
+ file = path.resolve(watchPath, file);
67
+
68
+ const stat = await fs.stat(file).catch(() => undefined);
69
+ const prevStat = lastStats[file];
70
+ lastStats[file] = stat;
71
+
72
+ if (prevStat?.mtimeMs === stat?.mtimeMs) {
73
+ return;
74
+ }
75
+ let ev: WatchEvent;
76
+ if (prevStat && !stat) {
77
+ ev = { action: 'delete', file };
78
+ } else if (!prevStat && stat) {
79
+ ev = { action: 'create', file };
80
+ } else {
81
+ ev = { action: 'update', file };
82
+ }
83
+ if (!options.filter || options.filter(ev)) {
84
+ onEvent(ev, folder);
85
+ }
86
+ });
87
+ process.on('exit', () => watcher.close());
88
+ return async () => watcher.close();
89
+ }
90
+
36
91
  /**
37
92
  * Leverages @parcel/watcher to watch a series of folders
38
93
  * @param folders
39
94
  * @param onEvent
40
- * @private
95
+ * @param options
41
96
  */
42
97
  export async function watchFolders(
43
- folders: string[] | [folder: string, targetFolder: string][],
98
+ folders: string[] | [folder: string, targetFolder: string][] | (readonly [folder: string, targetFolder: string])[],
44
99
  onEvent: WatchEventListener,
45
100
  config: WatchConfig = {}
46
101
  ): Promise<() => Promise<void>> {