/
watch-proxy.ts
68 lines (61 loc) · 2.02 KB
/
watch-proxy.ts
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
import { EventEmitter } from 'events';
import type { RollupWatcher } from '../rollup/types';
import { ensureArray } from '../utils/ensureArray';
import { errInvalidOption, error } from '../utils/error';
import type { GenericConfigObject } from '../utils/options/options';
import { loadFsEvents } from './fsevents-importer';
class WatchEmitter<T extends { [event: string]: (...args: any) => any }> extends EventEmitter {
private awaitedHandlers: {
[K in keyof T]?: ((...args: Parameters<T[K]>) => Promise<ReturnType<T[K]>>)[];
} = {};
constructor() {
super();
// Allows more than 10 bundles to be watched without
// showing the `MaxListenersExceededWarning` to the user.
this.setMaxListeners(Infinity);
}
// Will be overwritten by Rollup
async close(): Promise<void> {}
emitAndAwait<K extends keyof T>(
event: K,
...args: Parameters<T[K]>
): Promise<ReturnType<T[K]>[]> {
this.emit(event as string, ...(args as any[]));
const handlers = this.awaitedHandlers[event];
if (!handlers) return Promise.resolve([]);
return Promise.all(handlers.map(handler => handler(...args)));
}
onCurrentAwaited<K extends keyof T>(
event: K,
listener: (...args: Parameters<T[K]>) => Promise<ReturnType<T[K]>>
): this {
let handlers = this.awaitedHandlers[event];
if (!handlers) {
handlers = this.awaitedHandlers[event] = [];
}
handlers.push(listener);
return this;
}
removeAwaited(): this {
this.awaitedHandlers = {};
return this;
}
}
export default function watch(configs: GenericConfigObject[] | GenericConfigObject): RollupWatcher {
const emitter = new WatchEmitter() as RollupWatcher;
const configArray = ensureArray(configs);
const watchConfigs = configArray.filter(config => config.watch !== false);
if (watchConfigs.length === 0) {
return error(
errInvalidOption(
'watch',
'watch',
'there must be at least one config where "watch" is not set to "false"'
)
);
}
loadFsEvents()
.then(() => import('./watch'))
.then(({ Watcher }) => new Watcher(watchConfigs, emitter));
return emitter;
}