MCPcopy Index your code
hub / github.com/nodejs/node / VFSWatchAsyncIterable

Class VFSWatchAsyncIterable

lib/internal/vfs/watcher.js:579–683  ·  view source on GitHub ↗

Source from the content-addressed store, hash-verified

577const kMaxPendingEvents = 1024;
578
579class VFSWatchAsyncIterable {
580 #watcher;
581 #closed = false;
582 #pendingEvents = [];
583 #pendingResolvers = [];
584
585 /**
586 * @param {VirtualProvider} provider The VFS provider
587 * @param {string} path The path to watch (provider-relative)
588 * @param {object} [options] Options
589 */
590 constructor(provider, path, options = kEmptyObject) {
591 // Strip signal from options passed to VFSWatcher - we handle abort
592 // at the iterable level to reject pending next() with AbortError
593 // instead of resolving with done:true via the 'close' event.
594 const signal = options.signal;
595 const watcherOptions = ObjectAssign({ __proto__: null }, options);
596 delete watcherOptions.signal;
597 this.#watcher = new VFSWatcher(provider, path, watcherOptions);
598
599 this.#watcher.on('change', (eventType, filename) => {
600 const event = { eventType, filename };
601 if (this.#pendingResolvers.length > 0) {
602 const { resolve } = this.#pendingResolvers.shift();
603 resolve({ done: false, value: event });
604 } else if (this.#pendingEvents.length < kMaxPendingEvents) {
605 ArrayPrototypePush(this.#pendingEvents, event);
606 }
607 // Drop events when queue is full to prevent unbounded memory growth
608 });
609
610 this.#watcher.on('close', () => {
611 this.#closed = true;
612 // Resolve any pending iterators
613 while (this.#pendingResolvers.length > 0) {
614 const { resolve } = this.#pendingResolvers.shift();
615 resolve({ done: true, value: undefined });
616 }
617 });
618
619 // Handle abort signal - reject pending next() with AbortError
620 if (signal) {
621 const onAbort = () => {
622 this.#closed = true;
623 const err = new AbortError(undefined, { cause: signal.reason });
624 while (this.#pendingResolvers.length > 0) {
625 const { reject } = this.#pendingResolvers.shift();
626 reject(err);
627 }
628 this.#watcher.close();
629 };
630 if (signal.aborted) {
631 onAbort();
632 } else {
633 signal.addEventListener('abort', onAbort, { once: true });
634 }
635 }
636 }

Callers

nothing calls this directly

Calls

no outgoing calls

Tested by

no test coverage detected

Used in the wild real call sites across dependent graphs

searching dependent graphs…