chore: import upstream snapshot with attribution
This commit is contained in:
@@ -0,0 +1,61 @@
|
||||
import type watcher from '@parcel/watcher'
|
||||
import { debounceAsync } from './concurrency-utils'
|
||||
import { EventEmitter } from './event-emitter'
|
||||
|
||||
export type FileChangeHandler = (events: watcher.Event[]) => Promise<void>
|
||||
|
||||
type EmptyObject = Record<never, never>
|
||||
type FileWatcherEvent = {
|
||||
error: unknown
|
||||
close: EmptyObject
|
||||
}
|
||||
|
||||
type FileWatcherOptions = watcher.Options & {
|
||||
debounceMs?: number
|
||||
}
|
||||
|
||||
/**
|
||||
* Wraps the Parcel file watcher to ensure errors can be catched in an async/await fashion
|
||||
*/
|
||||
export class FileWatcher {
|
||||
public static async watch(dir: string, fn: FileChangeHandler, opt?: FileWatcherOptions) {
|
||||
const eventEmitter = new EventEmitter<FileWatcherEvent>()
|
||||
|
||||
let subscriptionHandler = async (err: Error | null, events: watcher.Event[]) => {
|
||||
if (err) {
|
||||
eventEmitter.emit('error', err)
|
||||
return
|
||||
}
|
||||
|
||||
try {
|
||||
await fn(events)
|
||||
} catch (thrown) {
|
||||
eventEmitter.emit('error', thrown)
|
||||
}
|
||||
}
|
||||
|
||||
if (opt?.debounceMs) {
|
||||
subscriptionHandler = debounceAsync(subscriptionHandler, opt.debounceMs)
|
||||
}
|
||||
const watcher = await import('@parcel/watcher')
|
||||
|
||||
const subscription = await watcher.subscribe(dir, subscriptionHandler, opt)
|
||||
return new FileWatcher(subscription, eventEmitter)
|
||||
}
|
||||
|
||||
private constructor(
|
||||
private _subscription: watcher.AsyncSubscription,
|
||||
private _errorEmitter: EventEmitter<FileWatcherEvent>
|
||||
) {}
|
||||
|
||||
public async close() {
|
||||
await this._subscription.unsubscribe()
|
||||
this._errorEmitter.emit('close', {})
|
||||
}
|
||||
|
||||
public wait = () =>
|
||||
new Promise((resolve, reject) => {
|
||||
this._errorEmitter.once('error', reject)
|
||||
this._errorEmitter.once('close', resolve)
|
||||
})
|
||||
}
|
||||
Reference in New Issue
Block a user