Skip to content

Commit

Permalink
Extract emitter and improve coverage
Browse files Browse the repository at this point in the history
  • Loading branch information
lukastaegert committed Mar 6, 2022
1 parent 5415fba commit 548332f
Show file tree
Hide file tree
Showing 3 changed files with 49 additions and 55 deletions.
11 changes: 0 additions & 11 deletions src/utils/PluginDriver.ts
Expand Up @@ -270,17 +270,6 @@ export class PluginDriver {
return promise;
}

// chains synchronously, ignores returns
hookSeqSync<H extends SyncPluginHooks & SequentialPluginHooks>(
hookName: H,
args: Parameters<PluginHooks[H]>,
replaceContext?: ReplaceContext
): void {
for (const plugin of this.plugins) {
this.runHookSync(hookName, args, plugin, replaceContext);
}
}

/**
* Run an async plugin hook and return the result.
* @param hookName Name of the plugin hook. Must be either in `PluginHooks` or `OutputPluginValueHooks`.
Expand Down
48 changes: 48 additions & 0 deletions src/watch/WatchEmitter.ts
@@ -0,0 +1,48 @@
import { EventEmitter } from 'events';

type PromiseReturn<T extends (...args: any) => any> = (
...args: Parameters<T>
) => Promise<ReturnType<T>>;

export class WatchEmitter<
T extends { [event: string]: (...args: any) => any }
> extends EventEmitter {
private awaitedHandlers: {
[K in keyof T]?: PromiseReturn<T[K]>[];
} = Object.create(null);

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[]));
return Promise.all(this.getHandlers(event).map(handler => handler(...args)));
}

onCurrentAwaited<K extends keyof T>(
event: K,
listener: (...args: Parameters<T[K]>) => Promise<ReturnType<T[K]>>
): this {
this.getHandlers(event).push(listener);
return this;
}

removeAwaited(): this {
this.awaitedHandlers = {};
return this;
}

private getHandlers<K extends keyof T>(event: K): PromiseReturn<T[K]>[] {
return this.awaitedHandlers[event] || (this.awaitedHandlers[event] = []);
}
}
45 changes: 1 addition & 44 deletions src/watch/watch-proxy.ts
@@ -1,53 +1,10 @@
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 { WatchEmitter } from './WatchEmitter';
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);
Expand Down

0 comments on commit 548332f

Please sign in to comment.