@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 +1 -1
- package/src/manifest-index.ts +0 -19
- package/src/watch.ts +59 -4
package/package.json
CHANGED
package/src/manifest-index.ts
CHANGED
|
@@ -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
|
|
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?:
|
|
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
|
-
* @
|
|
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>> {
|