UNPKG

@theia/filesystem

Version:
192 lines • 7.74 kB
/// <reference types="node" /> import { IMinimatch } from 'minimatch'; import { FileChangeType, FileSystemWatcherService, FileSystemWatcherServiceClient, WatchOptions } from '../../common/filesystem-watcher-protocol'; import { FileChangeCollection } from '../file-change-collection'; import { Deferred } from '@theia/core/lib/common/promise-util'; import { Options, AsyncSubscription, Event } from '@theia/core/shared/@parcel/watcher'; export interface ParcelWatcherOptions { ignored: IMinimatch[]; } export declare const ParcelFileSystemWatcherServerOptions: unique symbol; export interface ParcelFileSystemWatcherServerOptions { verbose: boolean; info: (message: string, ...args: any[]) => void; error: (message: string, ...args: any[]) => void; parcelOptions: Options; } /** * This is a flag value passed around upon disposal. */ export declare const WatcherDisposal: unique symbol; /** * Because URIs can be watched by different clients, we'll track * how many are listening for a given URI. * * This component wraps the whole start/stop process given some * reference count. * * Once there are no more references the handle * will wait for some time before destroying its resources. */ export declare class ParcelWatcher { /** Filesystem path to be watched. */ readonly fsPath: string; /** Watcher-specific options */ readonly watcherOptions: ParcelWatcherOptions; /** Logging and parcel watcher options */ protected readonly parcelFileSystemWatchServerOptions: ParcelFileSystemWatcherServerOptions; /** The client to forward events to. */ protected readonly fileSystemWatcherClient: FileSystemWatcherServiceClient; /** Amount of time in ms to wait once this handle is not referenced anymore. */ protected readonly deferredDisposalTimeout: number; protected static debugIdSequence: number; protected disposed: boolean; /** * Used for debugging to keep track of the watchers. */ protected debugId: number; /** * When this field is set, it means the watcher instance was successfully started. */ protected watcher: AsyncSubscription | undefined; /** * When the ref count hits zero, we schedule this watch handle to be disposed. */ protected deferredDisposalTimer: NodeJS.Timeout | undefined; /** * This deferred only rejects with `WatcherDisposal` and never resolves. */ protected readonly deferredDisposalDeferred: Deferred<never>; /** * We count each reference made to this watcher, per client. * * We do this to know where to send events via the network. * * An entry should be removed when its value hits zero. */ protected readonly refsPerClient: Map<number, { value: number; }>; /** * Ensures that events are processed in the order they are emitted, * despite being processed async. */ protected parcelEventProcessingQueue: Promise<void>; /** * Resolves once this handle disposed itself and its resources. Never throws. */ readonly whenDisposed: Promise<void>; /** * Promise that resolves when the watcher is fully started, or got disposed. * * Will reject if an error occurred while starting. * * @returns `true` if successfully started, `false` if disposed early. */ readonly whenStarted: Promise<boolean>; constructor( /** Initial reference to this handle. */ initialClientId: number, /** Filesystem path to be watched. */ fsPath: string, /** Watcher-specific options */ watcherOptions: ParcelWatcherOptions, /** Logging and parcel watcher options */ parcelFileSystemWatchServerOptions: ParcelFileSystemWatcherServerOptions, /** The client to forward events to. */ fileSystemWatcherClient: FileSystemWatcherServiceClient, /** Amount of time in ms to wait once this handle is not referenced anymore. */ deferredDisposalTimeout?: number); addRef(clientId: number): void; removeRef(clientId: number): void; /** * All clients with at least one active reference. */ getClientIds(): number[]; /** * Add the references for each client together. */ getTotalReferences(): number; /** * Returns true if at least one client listens to this handle. */ isInUse(): boolean; /** * @throws with {@link WatcherDisposal} if this instance is disposed. */ protected assertNotDisposed(): void; /** * When starting a watcher, we'll first check and wait for the path to exists * before running a parcel watcher. */ protected start(): Promise<void>; /** * Given a started parcel watcher instance, gracefully shut it down. */ protected stopWatcher(watcher: AsyncSubscription): Promise<void>; protected createWatcher(): Promise<AsyncSubscription>; protected handleWatcherEvents(events: Event[]): void; protected resolveEventPath(directory: string, file: string): Promise<string>; protected pushFileChange(changes: FileChangeCollection, type: FileChangeType, filePath: string): void; protected fireError(): void; /** * When references hit zero, we'll schedule disposal for a bit later. * * This allows new references to reuse this watcher instead of creating a new one. * * e.g. A frontend disconnects for a few milliseconds before reconnecting again. */ protected onRefsReachZero(): void; /** * If we get new references after hitting zero, let's unschedule our disposal and keep watching. */ protected onRefsRevive(): void; protected isIgnored(filePath: string): boolean; /** * Internal disposal mechanism. */ protected _dispose(): Promise<void>; protected info(prefix: string, ...params: any[]): void; protected debug(prefix: string, ...params: any[]): void; } /** * Each time a client makes a watchRequest, we generate a unique watcherId for it. * * This watcherId will map to this handle type which keeps track of the clientId that made the request. */ export interface PacelWatcherHandle { clientId: number; watcher: ParcelWatcher; } export declare class ParcelFileSystemWatcherService implements FileSystemWatcherService { protected client: FileSystemWatcherServiceClient | undefined; protected watcherId: number; protected readonly watchers: Map<string, ParcelWatcher>; protected readonly watcherHandles: Map<number, PacelWatcherHandle>; protected readonly options: ParcelFileSystemWatcherServerOptions; /** * `this.client` is undefined until someone sets it. */ protected readonly maybeClient: FileSystemWatcherServiceClient; constructor(options?: Partial<ParcelFileSystemWatcherServerOptions>); setClient(client: FileSystemWatcherServiceClient | undefined): void; /** * A specific client requests us to watch a given `uri` according to some `options`. * * We internally re-use all the same `(uri, options)` pairs. */ watchFileChanges(clientId: number, uri: string, options?: WatchOptions): Promise<number>; protected createWatcher(clientId: number, fsPath: string, options: WatchOptions): ParcelWatcher; unwatchFileChanges(watcherId: number): Promise<void>; /** * Given some `URI` and some `WatchOptions`, generate a unique key. */ protected getWatcherKey(uri: string, options: WatchOptions): string; /** * Return fully qualified options. */ protected resolveWatchOptions(options?: WatchOptions): WatchOptions; protected debug(message: string, ...params: any[]): void; dispose(): void; } //# sourceMappingURL=parcel-filesystem-service.d.ts.map