Spaces:
Paused
Paused
Download node_modules/playwright-core/lib/serverRegistry.js from ThomasHeisig/Brain-5D-Space: direct link, hf CLI and curl.
- Browser
- Download file 57 kB
-
https://huggingface.co/spaces/ThomasHeisig/Brain-5D-Space/resolve/main/node_modules/playwright-core/lib/serverRegistry.js
- Command line
-
hf download hf://spaces/ThomasHeisig/Brain-5D-Space/node_modules/playwright-core/lib/serverRegistry.js
-
curl -L -o serverRegistry.js https://huggingface.co/spaces/ThomasHeisig/Brain-5D-Space/resolve/main/node_modules/playwright-core/lib/serverRegistry.js
57 kB
| ; | |
| var __create = Object.create; | |
| var __defProp = Object.defineProperty; | |
| var __getOwnPropDesc = Object.getOwnPropertyDescriptor; | |
| var __getOwnPropNames = Object.getOwnPropertyNames; | |
| var __getProtoOf = Object.getPrototypeOf; | |
| var __hasOwnProp = Object.prototype.hasOwnProperty; | |
| var __export = (target, all) => { | |
| for (var name in all) | |
| __defProp(target, name, { get: all[name], enumerable: true }); | |
| }; | |
| var __copyProps = (to, from, except, desc) => { | |
| if (from && typeof from === "object" || typeof from === "function") { | |
| for (let key of __getOwnPropNames(from)) | |
| if (!__hasOwnProp.call(to, key) && key !== except) | |
| __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable }); | |
| } | |
| return to; | |
| }; | |
| var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps( | |
| // If the importer is in node compatibility mode or this is not an ESM | |
| // file that has been converted to a CommonJS file using a Babel- | |
| // compatible transform (i.e. "__esModule" has not been set), then set | |
| // "default" to the CommonJS "module.exports" for node compatibility. | |
| isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target, | |
| mod | |
| )); | |
| var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod); | |
| // packages/playwright-core/src/serverRegistry.ts | |
| var serverRegistry_exports = {}; | |
| __export(serverRegistry_exports, { | |
| serverRegistry: () => serverRegistry | |
| }); | |
| module.exports = __toCommonJS(serverRegistry_exports); | |
| var import_events2 = require("events"); | |
| var import_fs3 = __toESM(require("fs")); | |
| var import_net = __toESM(require("net")); | |
| var import_path2 = __toESM(require("path")); | |
| var import_os2 = __toESM(require("os")); | |
| // node_modules/chokidar/esm/index.js | |
| var import_fs2 = require("fs"); | |
| var import_promises3 = require("fs/promises"); | |
| var import_events = require("events"); | |
| var sysPath2 = __toESM(require("path"), 1); | |
| // node_modules/readdirp/esm/index.js | |
| var import_promises = require("node:fs/promises"); | |
| var import_node_stream = require("node:stream"); | |
| var import_node_path = require("node:path"); | |
| var EntryTypes = { | |
| FILE_TYPE: "files", | |
| DIR_TYPE: "directories", | |
| FILE_DIR_TYPE: "files_directories", | |
| EVERYTHING_TYPE: "all" | |
| }; | |
| var defaultOptions = { | |
| root: ".", | |
| fileFilter: (_entryInfo) => true, | |
| directoryFilter: (_entryInfo) => true, | |
| type: EntryTypes.FILE_TYPE, | |
| lstat: false, | |
| depth: 2147483648, | |
| alwaysStat: false, | |
| highWaterMark: 4096 | |
| }; | |
| Object.freeze(defaultOptions); | |
| var RECURSIVE_ERROR_CODE = "READDIRP_RECURSIVE_ERROR"; | |
| var NORMAL_FLOW_ERRORS = /* @__PURE__ */ new Set(["ENOENT", "EPERM", "EACCES", "ELOOP", RECURSIVE_ERROR_CODE]); | |
| var ALL_TYPES = [ | |
| EntryTypes.DIR_TYPE, | |
| EntryTypes.EVERYTHING_TYPE, | |
| EntryTypes.FILE_DIR_TYPE, | |
| EntryTypes.FILE_TYPE | |
| ]; | |
| var DIR_TYPES = /* @__PURE__ */ new Set([ | |
| EntryTypes.DIR_TYPE, | |
| EntryTypes.EVERYTHING_TYPE, | |
| EntryTypes.FILE_DIR_TYPE | |
| ]); | |
| var FILE_TYPES = /* @__PURE__ */ new Set([ | |
| EntryTypes.EVERYTHING_TYPE, | |
| EntryTypes.FILE_DIR_TYPE, | |
| EntryTypes.FILE_TYPE | |
| ]); | |
| var isNormalFlowError = (error) => NORMAL_FLOW_ERRORS.has(error.code); | |
| var wantBigintFsStats = process.platform === "win32"; | |
| var emptyFn = (_entryInfo) => true; | |
| var normalizeFilter = (filter) => { | |
| if (filter === void 0) | |
| return emptyFn; | |
| if (typeof filter === "function") | |
| return filter; | |
| if (typeof filter === "string") { | |
| const fl = filter.trim(); | |
| return (entry) => entry.basename === fl; | |
| } | |
| if (Array.isArray(filter)) { | |
| const trItems = filter.map((item) => item.trim()); | |
| return (entry) => trItems.some((f) => entry.basename === f); | |
| } | |
| return emptyFn; | |
| }; | |
| var ReaddirpStream = class extends import_node_stream.Readable { | |
| constructor(options = {}) { | |
| super({ | |
| objectMode: true, | |
| autoDestroy: true, | |
| highWaterMark: options.highWaterMark | |
| }); | |
| const opts = { ...defaultOptions, ...options }; | |
| const { root, type } = opts; | |
| this._fileFilter = normalizeFilter(opts.fileFilter); | |
| this._directoryFilter = normalizeFilter(opts.directoryFilter); | |
| const statMethod = opts.lstat ? import_promises.lstat : import_promises.stat; | |
| if (wantBigintFsStats) { | |
| this._stat = (path3) => statMethod(path3, { bigint: true }); | |
| } else { | |
| this._stat = statMethod; | |
| } | |
| this._maxDepth = opts.depth ?? defaultOptions.depth; | |
| this._wantsDir = type ? DIR_TYPES.has(type) : false; | |
| this._wantsFile = type ? FILE_TYPES.has(type) : false; | |
| this._wantsEverything = type === EntryTypes.EVERYTHING_TYPE; | |
| this._root = (0, import_node_path.resolve)(root); | |
| this._isDirent = !opts.alwaysStat; | |
| this._statsProp = this._isDirent ? "dirent" : "stats"; | |
| this._rdOptions = { encoding: "utf8", withFileTypes: this._isDirent }; | |
| this.parents = [this._exploreDir(root, 1)]; | |
| this.reading = false; | |
| this.parent = void 0; | |
| } | |
| async _read(batch) { | |
| if (this.reading) | |
| return; | |
| this.reading = true; | |
| try { | |
| while (!this.destroyed && batch > 0) { | |
| const par = this.parent; | |
| const fil = par && par.files; | |
| if (fil && fil.length > 0) { | |
| const { path: path3, depth } = par; | |
| const slice = fil.splice(0, batch).map((dirent) => this._formatEntry(dirent, path3)); | |
| const awaited = await Promise.all(slice); | |
| for (const entry of awaited) { | |
| if (!entry) | |
| continue; | |
| if (this.destroyed) | |
| return; | |
| const entryType = await this._getEntryType(entry); | |
| if (entryType === "directory" && this._directoryFilter(entry)) { | |
| if (depth <= this._maxDepth) { | |
| this.parents.push(this._exploreDir(entry.fullPath, depth + 1)); | |
| } | |
| if (this._wantsDir) { | |
| this.push(entry); | |
| batch--; | |
| } | |
| } else if ((entryType === "file" || this._includeAsFile(entry)) && this._fileFilter(entry)) { | |
| if (this._wantsFile) { | |
| this.push(entry); | |
| batch--; | |
| } | |
| } | |
| } | |
| } else { | |
| const parent = this.parents.pop(); | |
| if (!parent) { | |
| this.push(null); | |
| break; | |
| } | |
| this.parent = await parent; | |
| if (this.destroyed) | |
| return; | |
| } | |
| } | |
| } catch (error) { | |
| this.destroy(error); | |
| } finally { | |
| this.reading = false; | |
| } | |
| } | |
| async _exploreDir(path3, depth) { | |
| let files; | |
| try { | |
| files = await (0, import_promises.readdir)(path3, this._rdOptions); | |
| } catch (error) { | |
| this._onError(error); | |
| } | |
| return { files, depth, path: path3 }; | |
| } | |
| async _formatEntry(dirent, path3) { | |
| let entry; | |
| const basename3 = this._isDirent ? dirent.name : dirent; | |
| try { | |
| const fullPath = (0, import_node_path.resolve)((0, import_node_path.join)(path3, basename3)); | |
| entry = { path: (0, import_node_path.relative)(this._root, fullPath), fullPath, basename: basename3 }; | |
| entry[this._statsProp] = this._isDirent ? dirent : await this._stat(fullPath); | |
| } catch (err) { | |
| this._onError(err); | |
| return; | |
| } | |
| return entry; | |
| } | |
| _onError(err) { | |
| if (isNormalFlowError(err) && !this.destroyed) { | |
| this.emit("warn", err); | |
| } else { | |
| this.destroy(err); | |
| } | |
| } | |
| async _getEntryType(entry) { | |
| if (!entry && this._statsProp in entry) { | |
| return ""; | |
| } | |
| const stats = entry[this._statsProp]; | |
| if (stats.isFile()) | |
| return "file"; | |
| if (stats.isDirectory()) | |
| return "directory"; | |
| if (stats && stats.isSymbolicLink()) { | |
| const full = entry.fullPath; | |
| try { | |
| const entryRealPath = await (0, import_promises.realpath)(full); | |
| const entryRealPathStats = await (0, import_promises.lstat)(entryRealPath); | |
| if (entryRealPathStats.isFile()) { | |
| return "file"; | |
| } | |
| if (entryRealPathStats.isDirectory()) { | |
| const len = entryRealPath.length; | |
| if (full.startsWith(entryRealPath) && full.substr(len, 1) === import_node_path.sep) { | |
| const recursiveError = new Error(`Circular symlink detected: "${full}" points to "${entryRealPath}"`); | |
| recursiveError.code = RECURSIVE_ERROR_CODE; | |
| return this._onError(recursiveError); | |
| } | |
| return "directory"; | |
| } | |
| } catch (error) { | |
| this._onError(error); | |
| return ""; | |
| } | |
| } | |
| } | |
| _includeAsFile(entry) { | |
| const stats = entry && entry[this._statsProp]; | |
| return stats && this._wantsEverything && !stats.isDirectory(); | |
| } | |
| }; | |
| function readdirp(root, options = {}) { | |
| let type = options.entryType || options.type; | |
| if (type === "both") | |
| type = EntryTypes.FILE_DIR_TYPE; | |
| if (type) | |
| options.type = type; | |
| if (!root) { | |
| throw new Error("readdirp: root argument is required. Usage: readdirp(root, options)"); | |
| } else if (typeof root !== "string") { | |
| throw new TypeError("readdirp: root argument must be a string. Usage: readdirp(root, options)"); | |
| } else if (type && !ALL_TYPES.includes(type)) { | |
| throw new Error(`readdirp: Invalid type passed. Use one of ${ALL_TYPES.join(", ")}`); | |
| } | |
| options.root = root; | |
| return new ReaddirpStream(options); | |
| } | |
| // node_modules/chokidar/esm/handler.js | |
| var import_fs = require("fs"); | |
| var import_promises2 = require("fs/promises"); | |
| var sysPath = __toESM(require("path"), 1); | |
| var import_os = require("os"); | |
| var STR_DATA = "data"; | |
| var STR_END = "end"; | |
| var STR_CLOSE = "close"; | |
| var EMPTY_FN = () => { | |
| }; | |
| var pl = process.platform; | |
| var isWindows = pl === "win32"; | |
| var isMacos = pl === "darwin"; | |
| var isLinux = pl === "linux"; | |
| var isFreeBSD = pl === "freebsd"; | |
| var isIBMi = (0, import_os.type)() === "OS400"; | |
| var EVENTS = { | |
| ALL: "all", | |
| READY: "ready", | |
| ADD: "add", | |
| CHANGE: "change", | |
| ADD_DIR: "addDir", | |
| UNLINK: "unlink", | |
| UNLINK_DIR: "unlinkDir", | |
| RAW: "raw", | |
| ERROR: "error" | |
| }; | |
| var EV = EVENTS; | |
| var THROTTLE_MODE_WATCH = "watch"; | |
| var statMethods = { lstat: import_promises2.lstat, stat: import_promises2.stat }; | |
| var KEY_LISTENERS = "listeners"; | |
| var KEY_ERR = "errHandlers"; | |
| var KEY_RAW = "rawEmitters"; | |
| var HANDLER_KEYS = [KEY_LISTENERS, KEY_ERR, KEY_RAW]; | |
| var binaryExtensions = /* @__PURE__ */ new Set([ | |
| "3dm", | |
| "3ds", | |
| "3g2", | |
| "3gp", | |
| "7z", | |
| "a", | |
| "aac", | |
| "adp", | |
| "afdesign", | |
| "afphoto", | |
| "afpub", | |
| "ai", | |
| "aif", | |
| "aiff", | |
| "alz", | |
| "ape", | |
| "apk", | |
| "appimage", | |
| "ar", | |
| "arj", | |
| "asf", | |
| "au", | |
| "avi", | |
| "bak", | |
| "baml", | |
| "bh", | |
| "bin", | |
| "bk", | |
| "bmp", | |
| "btif", | |
| "bz2", | |
| "bzip2", | |
| "cab", | |
| "caf", | |
| "cgm", | |
| "class", | |
| "cmx", | |
| "cpio", | |
| "cr2", | |
| "cur", | |
| "dat", | |
| "dcm", | |
| "deb", | |
| "dex", | |
| "djvu", | |
| "dll", | |
| "dmg", | |
| "dng", | |
| "doc", | |
| "docm", | |
| "docx", | |
| "dot", | |
| "dotm", | |
| "dra", | |
| "DS_Store", | |
| "dsk", | |
| "dts", | |
| "dtshd", | |
| "dvb", | |
| "dwg", | |
| "dxf", | |
| "ecelp4800", | |
| "ecelp7470", | |
| "ecelp9600", | |
| "egg", | |
| "eol", | |
| "eot", | |
| "epub", | |
| "exe", | |
| "f4v", | |
| "fbs", | |
| "fh", | |
| "fla", | |
| "flac", | |
| "flatpak", | |
| "fli", | |
| "flv", | |
| "fpx", | |
| "fst", | |
| "fvt", | |
| "g3", | |
| "gh", | |
| "gif", | |
| "graffle", | |
| "gz", | |
| "gzip", | |
| "h261", | |
| "h263", | |
| "h264", | |
| "icns", | |
| "ico", | |
| "ief", | |
| "img", | |
| "ipa", | |
| "iso", | |
| "jar", | |
| "jpeg", | |
| "jpg", | |
| "jpgv", | |
| "jpm", | |
| "jxr", | |
| "key", | |
| "ktx", | |
| "lha", | |
| "lib", | |
| "lvp", | |
| "lz", | |
| "lzh", | |
| "lzma", | |
| "lzo", | |
| "m3u", | |
| "m4a", | |
| "m4v", | |
| "mar", | |
| "mdi", | |
| "mht", | |
| "mid", | |
| "midi", | |
| "mj2", | |
| "mka", | |
| "mkv", | |
| "mmr", | |
| "mng", | |
| "mobi", | |
| "mov", | |
| "movie", | |
| "mp3", | |
| "mp4", | |
| "mp4a", | |
| "mpeg", | |
| "mpg", | |
| "mpga", | |
| "mxu", | |
| "nef", | |
| "npx", | |
| "numbers", | |
| "nupkg", | |
| "o", | |
| "odp", | |
| "ods", | |
| "odt", | |
| "oga", | |
| "ogg", | |
| "ogv", | |
| "otf", | |
| "ott", | |
| "pages", | |
| "pbm", | |
| "pcx", | |
| "pdb", | |
| "pdf", | |
| "pea", | |
| "pgm", | |
| "pic", | |
| "png", | |
| "pnm", | |
| "pot", | |
| "potm", | |
| "potx", | |
| "ppa", | |
| "ppam", | |
| "ppm", | |
| "pps", | |
| "ppsm", | |
| "ppsx", | |
| "ppt", | |
| "pptm", | |
| "pptx", | |
| "psd", | |
| "pya", | |
| "pyc", | |
| "pyo", | |
| "pyv", | |
| "qt", | |
| "rar", | |
| "ras", | |
| "raw", | |
| "resources", | |
| "rgb", | |
| "rip", | |
| "rlc", | |
| "rmf", | |
| "rmvb", | |
| "rpm", | |
| "rtf", | |
| "rz", | |
| "s3m", | |
| "s7z", | |
| "scpt", | |
| "sgi", | |
| "shar", | |
| "snap", | |
| "sil", | |
| "sketch", | |
| "slk", | |
| "smv", | |
| "snk", | |
| "so", | |
| "stl", | |
| "suo", | |
| "sub", | |
| "swf", | |
| "tar", | |
| "tbz", | |
| "tbz2", | |
| "tga", | |
| "tgz", | |
| "thmx", | |
| "tif", | |
| "tiff", | |
| "tlz", | |
| "ttc", | |
| "ttf", | |
| "txz", | |
| "udf", | |
| "uvh", | |
| "uvi", | |
| "uvm", | |
| "uvp", | |
| "uvs", | |
| "uvu", | |
| "viv", | |
| "vob", | |
| "war", | |
| "wav", | |
| "wax", | |
| "wbmp", | |
| "wdp", | |
| "weba", | |
| "webm", | |
| "webp", | |
| "whl", | |
| "wim", | |
| "wm", | |
| "wma", | |
| "wmv", | |
| "wmx", | |
| "woff", | |
| "woff2", | |
| "wrm", | |
| "wvx", | |
| "xbm", | |
| "xif", | |
| "xla", | |
| "xlam", | |
| "xls", | |
| "xlsb", | |
| "xlsm", | |
| "xlsx", | |
| "xlt", | |
| "xltm", | |
| "xltx", | |
| "xm", | |
| "xmind", | |
| "xpi", | |
| "xpm", | |
| "xwd", | |
| "xz", | |
| "z", | |
| "zip", | |
| "zipx" | |
| ]); | |
| var isBinaryPath = (filePath) => binaryExtensions.has(sysPath.extname(filePath).slice(1).toLowerCase()); | |
| var foreach = (val, fn) => { | |
| if (val instanceof Set) { | |
| val.forEach(fn); | |
| } else { | |
| fn(val); | |
| } | |
| }; | |
| var addAndConvert = (main, prop, item) => { | |
| let container = main[prop]; | |
| if (!(container instanceof Set)) { | |
| main[prop] = container = /* @__PURE__ */ new Set([container]); | |
| } | |
| container.add(item); | |
| }; | |
| var clearItem = (cont) => (key) => { | |
| const set = cont[key]; | |
| if (set instanceof Set) { | |
| set.clear(); | |
| } else { | |
| delete cont[key]; | |
| } | |
| }; | |
| var delFromSet = (main, prop, item) => { | |
| const container = main[prop]; | |
| if (container instanceof Set) { | |
| container.delete(item); | |
| } else if (container === item) { | |
| delete main[prop]; | |
| } | |
| }; | |
| var isEmptySet = (val) => val instanceof Set ? val.size === 0 : !val; | |
| var FsWatchInstances = /* @__PURE__ */ new Map(); | |
| function createFsWatchInstance(path3, options, listener, errHandler, emitRaw) { | |
| const handleEvent = (rawEvent, evPath) => { | |
| listener(path3); | |
| emitRaw(rawEvent, evPath, { watchedPath: path3 }); | |
| if (evPath && path3 !== evPath) { | |
| fsWatchBroadcast(sysPath.resolve(path3, evPath), KEY_LISTENERS, sysPath.join(path3, evPath)); | |
| } | |
| }; | |
| try { | |
| return (0, import_fs.watch)(path3, { | |
| persistent: options.persistent | |
| }, handleEvent); | |
| } catch (error) { | |
| errHandler(error); | |
| return void 0; | |
| } | |
| } | |
| var fsWatchBroadcast = (fullPath, listenerType, val1, val2, val3) => { | |
| const cont = FsWatchInstances.get(fullPath); | |
| if (!cont) | |
| return; | |
| foreach(cont[listenerType], (listener) => { | |
| listener(val1, val2, val3); | |
| }); | |
| }; | |
| var setFsWatchListener = (path3, fullPath, options, handlers) => { | |
| const { listener, errHandler, rawEmitter } = handlers; | |
| let cont = FsWatchInstances.get(fullPath); | |
| let watcher; | |
| if (!options.persistent) { | |
| watcher = createFsWatchInstance(path3, options, listener, errHandler, rawEmitter); | |
| if (!watcher) | |
| return; | |
| return watcher.close.bind(watcher); | |
| } | |
| if (cont) { | |
| addAndConvert(cont, KEY_LISTENERS, listener); | |
| addAndConvert(cont, KEY_ERR, errHandler); | |
| addAndConvert(cont, KEY_RAW, rawEmitter); | |
| } else { | |
| watcher = createFsWatchInstance( | |
| path3, | |
| options, | |
| fsWatchBroadcast.bind(null, fullPath, KEY_LISTENERS), | |
| errHandler, | |
| // no need to use broadcast here | |
| fsWatchBroadcast.bind(null, fullPath, KEY_RAW) | |
| ); | |
| if (!watcher) | |
| return; | |
| watcher.on(EV.ERROR, async (error) => { | |
| const broadcastErr = fsWatchBroadcast.bind(null, fullPath, KEY_ERR); | |
| if (cont) | |
| cont.watcherUnusable = true; | |
| if (isWindows && error.code === "EPERM") { | |
| try { | |
| const fd = await (0, import_promises2.open)(path3, "r"); | |
| await fd.close(); | |
| broadcastErr(error); | |
| } catch (err) { | |
| } | |
| } else { | |
| broadcastErr(error); | |
| } | |
| }); | |
| cont = { | |
| listeners: listener, | |
| errHandlers: errHandler, | |
| rawEmitters: rawEmitter, | |
| watcher | |
| }; | |
| FsWatchInstances.set(fullPath, cont); | |
| } | |
| return () => { | |
| delFromSet(cont, KEY_LISTENERS, listener); | |
| delFromSet(cont, KEY_ERR, errHandler); | |
| delFromSet(cont, KEY_RAW, rawEmitter); | |
| if (isEmptySet(cont.listeners)) { | |
| cont.watcher.close(); | |
| FsWatchInstances.delete(fullPath); | |
| HANDLER_KEYS.forEach(clearItem(cont)); | |
| cont.watcher = void 0; | |
| Object.freeze(cont); | |
| } | |
| }; | |
| }; | |
| var FsWatchFileInstances = /* @__PURE__ */ new Map(); | |
| var setFsWatchFileListener = (path3, fullPath, options, handlers) => { | |
| const { listener, rawEmitter } = handlers; | |
| let cont = FsWatchFileInstances.get(fullPath); | |
| const copts = cont && cont.options; | |
| if (copts && (copts.persistent < options.persistent || copts.interval > options.interval)) { | |
| (0, import_fs.unwatchFile)(fullPath); | |
| cont = void 0; | |
| } | |
| if (cont) { | |
| addAndConvert(cont, KEY_LISTENERS, listener); | |
| addAndConvert(cont, KEY_RAW, rawEmitter); | |
| } else { | |
| cont = { | |
| listeners: listener, | |
| rawEmitters: rawEmitter, | |
| options, | |
| watcher: (0, import_fs.watchFile)(fullPath, options, (curr, prev) => { | |
| foreach(cont.rawEmitters, (rawEmitter2) => { | |
| rawEmitter2(EV.CHANGE, fullPath, { curr, prev }); | |
| }); | |
| const currmtime = curr.mtimeMs; | |
| if (curr.size !== prev.size || currmtime > prev.mtimeMs || currmtime === 0) { | |
| foreach(cont.listeners, (listener2) => listener2(path3, curr)); | |
| } | |
| }) | |
| }; | |
| FsWatchFileInstances.set(fullPath, cont); | |
| } | |
| return () => { | |
| delFromSet(cont, KEY_LISTENERS, listener); | |
| delFromSet(cont, KEY_RAW, rawEmitter); | |
| if (isEmptySet(cont.listeners)) { | |
| FsWatchFileInstances.delete(fullPath); | |
| (0, import_fs.unwatchFile)(fullPath); | |
| cont.options = cont.watcher = void 0; | |
| Object.freeze(cont); | |
| } | |
| }; | |
| }; | |
| var NodeFsHandler = class { | |
| constructor(fsW) { | |
| this.fsw = fsW; | |
| this._boundHandleError = (error) => fsW._handleError(error); | |
| } | |
| /** | |
| * Watch file for changes with fs_watchFile or fs_watch. | |
| * @param path to file or dir | |
| * @param listener on fs change | |
| * @returns closer for the watcher instance | |
| */ | |
| _watchWithNodeFs(path3, listener) { | |
| const opts = this.fsw.options; | |
| const directory = sysPath.dirname(path3); | |
| const basename3 = sysPath.basename(path3); | |
| const parent = this.fsw._getWatchedDir(directory); | |
| parent.add(basename3); | |
| const absolutePath = sysPath.resolve(path3); | |
| const options = { | |
| persistent: opts.persistent | |
| }; | |
| if (!listener) | |
| listener = EMPTY_FN; | |
| let closer; | |
| if (opts.usePolling) { | |
| const enableBin = opts.interval !== opts.binaryInterval; | |
| options.interval = enableBin && isBinaryPath(basename3) ? opts.binaryInterval : opts.interval; | |
| closer = setFsWatchFileListener(path3, absolutePath, options, { | |
| listener, | |
| rawEmitter: this.fsw._emitRaw | |
| }); | |
| } else { | |
| closer = setFsWatchListener(path3, absolutePath, options, { | |
| listener, | |
| errHandler: this._boundHandleError, | |
| rawEmitter: this.fsw._emitRaw | |
| }); | |
| } | |
| return closer; | |
| } | |
| /** | |
| * Watch a file and emit add event if warranted. | |
| * @returns closer for the watcher instance | |
| */ | |
| _handleFile(file, stats, initialAdd) { | |
| if (this.fsw.closed) { | |
| return; | |
| } | |
| const dirname3 = sysPath.dirname(file); | |
| const basename3 = sysPath.basename(file); | |
| const parent = this.fsw._getWatchedDir(dirname3); | |
| let prevStats = stats; | |
| if (parent.has(basename3)) | |
| return; | |
| const listener = async (path3, newStats) => { | |
| if (!this.fsw._throttle(THROTTLE_MODE_WATCH, file, 5)) | |
| return; | |
| if (!newStats || newStats.mtimeMs === 0) { | |
| try { | |
| const newStats2 = await (0, import_promises2.stat)(file); | |
| if (this.fsw.closed) | |
| return; | |
| const at = newStats2.atimeMs; | |
| const mt = newStats2.mtimeMs; | |
| if (!at || at <= mt || mt !== prevStats.mtimeMs) { | |
| this.fsw._emit(EV.CHANGE, file, newStats2); | |
| } | |
| if ((isMacos || isLinux || isFreeBSD) && prevStats.ino !== newStats2.ino) { | |
| this.fsw._closeFile(path3); | |
| prevStats = newStats2; | |
| const closer2 = this._watchWithNodeFs(file, listener); | |
| if (closer2) | |
| this.fsw._addPathCloser(path3, closer2); | |
| } else { | |
| prevStats = newStats2; | |
| } | |
| } catch (error) { | |
| this.fsw._remove(dirname3, basename3); | |
| } | |
| } else if (parent.has(basename3)) { | |
| const at = newStats.atimeMs; | |
| const mt = newStats.mtimeMs; | |
| if (!at || at <= mt || mt !== prevStats.mtimeMs) { | |
| this.fsw._emit(EV.CHANGE, file, newStats); | |
| } | |
| prevStats = newStats; | |
| } | |
| }; | |
| const closer = this._watchWithNodeFs(file, listener); | |
| if (!(initialAdd && this.fsw.options.ignoreInitial) && this.fsw._isntIgnored(file)) { | |
| if (!this.fsw._throttle(EV.ADD, file, 0)) | |
| return; | |
| this.fsw._emit(EV.ADD, file, stats); | |
| } | |
| return closer; | |
| } | |
| /** | |
| * Handle symlinks encountered while reading a dir. | |
| * @param entry returned by readdirp | |
| * @param directory path of dir being read | |
| * @param path of this item | |
| * @param item basename of this item | |
| * @returns true if no more processing is needed for this entry. | |
| */ | |
| async _handleSymlink(entry, directory, path3, item) { | |
| if (this.fsw.closed) { | |
| return; | |
| } | |
| const full = entry.fullPath; | |
| const dir = this.fsw._getWatchedDir(directory); | |
| if (!this.fsw.options.followSymlinks) { | |
| this.fsw._incrReadyCount(); | |
| let linkPath; | |
| try { | |
| linkPath = await (0, import_promises2.realpath)(path3); | |
| } catch (e) { | |
| this.fsw._emitReady(); | |
| return true; | |
| } | |
| if (this.fsw.closed) | |
| return; | |
| if (dir.has(item)) { | |
| if (this.fsw._symlinkPaths.get(full) !== linkPath) { | |
| this.fsw._symlinkPaths.set(full, linkPath); | |
| this.fsw._emit(EV.CHANGE, path3, entry.stats); | |
| } | |
| } else { | |
| dir.add(item); | |
| this.fsw._symlinkPaths.set(full, linkPath); | |
| this.fsw._emit(EV.ADD, path3, entry.stats); | |
| } | |
| this.fsw._emitReady(); | |
| return true; | |
| } | |
| if (this.fsw._symlinkPaths.has(full)) { | |
| return true; | |
| } | |
| this.fsw._symlinkPaths.set(full, true); | |
| } | |
| _handleRead(directory, initialAdd, wh, target, dir, depth, throttler) { | |
| directory = sysPath.join(directory, ""); | |
| throttler = this.fsw._throttle("readdir", directory, 1e3); | |
| if (!throttler) | |
| return; | |
| const previous = this.fsw._getWatchedDir(wh.path); | |
| const current = /* @__PURE__ */ new Set(); | |
| let stream = this.fsw._readdirp(directory, { | |
| fileFilter: (entry) => wh.filterPath(entry), | |
| directoryFilter: (entry) => wh.filterDir(entry) | |
| }); | |
| if (!stream) | |
| return; | |
| stream.on(STR_DATA, async (entry) => { | |
| if (this.fsw.closed) { | |
| stream = void 0; | |
| return; | |
| } | |
| const item = entry.path; | |
| let path3 = sysPath.join(directory, item); | |
| current.add(item); | |
| if (entry.stats.isSymbolicLink() && await this._handleSymlink(entry, directory, path3, item)) { | |
| return; | |
| } | |
| if (this.fsw.closed) { | |
| stream = void 0; | |
| return; | |
| } | |
| if (item === target || !target && !previous.has(item)) { | |
| this.fsw._incrReadyCount(); | |
| path3 = sysPath.join(dir, sysPath.relative(dir, path3)); | |
| this._addToNodeFs(path3, initialAdd, wh, depth + 1); | |
| } | |
| }).on(EV.ERROR, this._boundHandleError); | |
| return new Promise((resolve3, reject) => { | |
| if (!stream) | |
| return reject(); | |
| stream.once(STR_END, () => { | |
| if (this.fsw.closed) { | |
| stream = void 0; | |
| return; | |
| } | |
| const wasThrottled = throttler ? throttler.clear() : false; | |
| resolve3(void 0); | |
| previous.getChildren().filter((item) => { | |
| return item !== directory && !current.has(item); | |
| }).forEach((item) => { | |
| this.fsw._remove(directory, item); | |
| }); | |
| stream = void 0; | |
| if (wasThrottled) | |
| this._handleRead(directory, false, wh, target, dir, depth, throttler); | |
| }); | |
| }); | |
| } | |
| /** | |
| * Read directory to add / remove files from `@watched` list and re-read it on change. | |
| * @param dir fs path | |
| * @param stats | |
| * @param initialAdd | |
| * @param depth relative to user-supplied path | |
| * @param target child path targeted for watch | |
| * @param wh Common watch helpers for this path | |
| * @param realpath | |
| * @returns closer for the watcher instance. | |
| */ | |
| async _handleDir(dir, stats, initialAdd, depth, target, wh, realpath2) { | |
| const parentDir = this.fsw._getWatchedDir(sysPath.dirname(dir)); | |
| const tracked = parentDir.has(sysPath.basename(dir)); | |
| if (!(initialAdd && this.fsw.options.ignoreInitial) && !target && !tracked) { | |
| this.fsw._emit(EV.ADD_DIR, dir, stats); | |
| } | |
| parentDir.add(sysPath.basename(dir)); | |
| this.fsw._getWatchedDir(dir); | |
| let throttler; | |
| let closer; | |
| const oDepth = this.fsw.options.depth; | |
| if ((oDepth == null || depth <= oDepth) && !this.fsw._symlinkPaths.has(realpath2)) { | |
| if (!target) { | |
| await this._handleRead(dir, initialAdd, wh, target, dir, depth, throttler); | |
| if (this.fsw.closed) | |
| return; | |
| } | |
| closer = this._watchWithNodeFs(dir, (dirPath, stats2) => { | |
| if (stats2 && stats2.mtimeMs === 0) | |
| return; | |
| this._handleRead(dirPath, false, wh, target, dir, depth, throttler); | |
| }); | |
| } | |
| return closer; | |
| } | |
| /** | |
| * Handle added file, directory, or glob pattern. | |
| * Delegates call to _handleFile / _handleDir after checks. | |
| * @param path to file or ir | |
| * @param initialAdd was the file added at watch instantiation? | |
| * @param priorWh depth relative to user-supplied path | |
| * @param depth Child path actually targeted for watch | |
| * @param target Child path actually targeted for watch | |
| */ | |
| async _addToNodeFs(path3, initialAdd, priorWh, depth, target) { | |
| const ready = this.fsw._emitReady; | |
| if (this.fsw._isIgnored(path3) || this.fsw.closed) { | |
| ready(); | |
| return false; | |
| } | |
| const wh = this.fsw._getWatchHelpers(path3); | |
| if (priorWh) { | |
| wh.filterPath = (entry) => priorWh.filterPath(entry); | |
| wh.filterDir = (entry) => priorWh.filterDir(entry); | |
| } | |
| try { | |
| const stats = await statMethods[wh.statMethod](wh.watchPath); | |
| if (this.fsw.closed) | |
| return; | |
| if (this.fsw._isIgnored(wh.watchPath, stats)) { | |
| ready(); | |
| return false; | |
| } | |
| const follow = this.fsw.options.followSymlinks; | |
| let closer; | |
| if (stats.isDirectory()) { | |
| const absPath = sysPath.resolve(path3); | |
| const targetPath = follow ? await (0, import_promises2.realpath)(path3) : path3; | |
| if (this.fsw.closed) | |
| return; | |
| closer = await this._handleDir(wh.watchPath, stats, initialAdd, depth, target, wh, targetPath); | |
| if (this.fsw.closed) | |
| return; | |
| if (absPath !== targetPath && targetPath !== void 0) { | |
| this.fsw._symlinkPaths.set(absPath, targetPath); | |
| } | |
| } else if (stats.isSymbolicLink()) { | |
| const targetPath = follow ? await (0, import_promises2.realpath)(path3) : path3; | |
| if (this.fsw.closed) | |
| return; | |
| const parent = sysPath.dirname(wh.watchPath); | |
| this.fsw._getWatchedDir(parent).add(wh.watchPath); | |
| this.fsw._emit(EV.ADD, wh.watchPath, stats); | |
| closer = await this._handleDir(parent, stats, initialAdd, depth, path3, wh, targetPath); | |
| if (this.fsw.closed) | |
| return; | |
| if (targetPath !== void 0) { | |
| this.fsw._symlinkPaths.set(sysPath.resolve(path3), targetPath); | |
| } | |
| } else { | |
| closer = this._handleFile(wh.watchPath, stats, initialAdd); | |
| } | |
| ready(); | |
| if (closer) | |
| this.fsw._addPathCloser(path3, closer); | |
| return false; | |
| } catch (error) { | |
| if (this.fsw._handleError(error)) { | |
| ready(); | |
| return path3; | |
| } | |
| } | |
| } | |
| }; | |
| // node_modules/chokidar/esm/index.js | |
| var SLASH = "/"; | |
| var SLASH_SLASH = "//"; | |
| var ONE_DOT = "."; | |
| var TWO_DOTS = ".."; | |
| var STRING_TYPE = "string"; | |
| var BACK_SLASH_RE = /\\/g; | |
| var DOUBLE_SLASH_RE = /\/\//; | |
| var DOT_RE = /\..*\.(sw[px])$|~$|\.subl.*\.tmp/; | |
| var REPLACER_RE = /^\.[/\\]/; | |
| function arrify(item) { | |
| return Array.isArray(item) ? item : [item]; | |
| } | |
| var isMatcherObject = (matcher) => typeof matcher === "object" && matcher !== null && !(matcher instanceof RegExp); | |
| function createPattern(matcher) { | |
| if (typeof matcher === "function") | |
| return matcher; | |
| if (typeof matcher === "string") | |
| return (string) => matcher === string; | |
| if (matcher instanceof RegExp) | |
| return (string) => matcher.test(string); | |
| if (typeof matcher === "object" && matcher !== null) { | |
| return (string) => { | |
| if (matcher.path === string) | |
| return true; | |
| if (matcher.recursive) { | |
| const relative3 = sysPath2.relative(matcher.path, string); | |
| if (!relative3) { | |
| return false; | |
| } | |
| return !relative3.startsWith("..") && !sysPath2.isAbsolute(relative3); | |
| } | |
| return false; | |
| }; | |
| } | |
| return () => false; | |
| } | |
| function normalizePath(path3) { | |
| if (typeof path3 !== "string") | |
| throw new Error("string expected"); | |
| path3 = sysPath2.normalize(path3); | |
| path3 = path3.replace(/\\/g, "/"); | |
| let prepend = false; | |
| if (path3.startsWith("//")) | |
| prepend = true; | |
| const DOUBLE_SLASH_RE2 = /\/\//; | |
| while (path3.match(DOUBLE_SLASH_RE2)) | |
| path3 = path3.replace(DOUBLE_SLASH_RE2, "/"); | |
| if (prepend) | |
| path3 = "/" + path3; | |
| return path3; | |
| } | |
| function matchPatterns(patterns, testString, stats) { | |
| const path3 = normalizePath(testString); | |
| for (let index = 0; index < patterns.length; index++) { | |
| const pattern = patterns[index]; | |
| if (pattern(path3, stats)) { | |
| return true; | |
| } | |
| } | |
| return false; | |
| } | |
| function anymatch(matchers, testString) { | |
| if (matchers == null) { | |
| throw new TypeError("anymatch: specify first argument"); | |
| } | |
| const matchersArray = arrify(matchers); | |
| const patterns = matchersArray.map((matcher) => createPattern(matcher)); | |
| if (testString == null) { | |
| return (testString2, stats) => { | |
| return matchPatterns(patterns, testString2, stats); | |
| }; | |
| } | |
| return matchPatterns(patterns, testString); | |
| } | |
| var unifyPaths = (paths_) => { | |
| const paths = arrify(paths_).flat(); | |
| if (!paths.every((p) => typeof p === STRING_TYPE)) { | |
| throw new TypeError(`Non-string provided as watch path: ${paths}`); | |
| } | |
| return paths.map(normalizePathToUnix); | |
| }; | |
| var toUnix = (string) => { | |
| let str = string.replace(BACK_SLASH_RE, SLASH); | |
| let prepend = false; | |
| if (str.startsWith(SLASH_SLASH)) { | |
| prepend = true; | |
| } | |
| while (str.match(DOUBLE_SLASH_RE)) { | |
| str = str.replace(DOUBLE_SLASH_RE, SLASH); | |
| } | |
| if (prepend) { | |
| str = SLASH + str; | |
| } | |
| return str; | |
| }; | |
| var normalizePathToUnix = (path3) => toUnix(sysPath2.normalize(toUnix(path3))); | |
| var normalizeIgnored = (cwd = "") => (path3) => { | |
| if (typeof path3 === "string") { | |
| return normalizePathToUnix(sysPath2.isAbsolute(path3) ? path3 : sysPath2.join(cwd, path3)); | |
| } else { | |
| return path3; | |
| } | |
| }; | |
| var getAbsolutePath = (path3, cwd) => { | |
| if (sysPath2.isAbsolute(path3)) { | |
| return path3; | |
| } | |
| return sysPath2.join(cwd, path3); | |
| }; | |
| var EMPTY_SET = Object.freeze(/* @__PURE__ */ new Set()); | |
| var DirEntry = class { | |
| constructor(dir, removeWatcher) { | |
| this.path = dir; | |
| this._removeWatcher = removeWatcher; | |
| this.items = /* @__PURE__ */ new Set(); | |
| } | |
| add(item) { | |
| const { items } = this; | |
| if (!items) | |
| return; | |
| if (item !== ONE_DOT && item !== TWO_DOTS) | |
| items.add(item); | |
| } | |
| async remove(item) { | |
| const { items } = this; | |
| if (!items) | |
| return; | |
| items.delete(item); | |
| if (items.size > 0) | |
| return; | |
| const dir = this.path; | |
| try { | |
| await (0, import_promises3.readdir)(dir); | |
| } catch (err) { | |
| if (this._removeWatcher) { | |
| this._removeWatcher(sysPath2.dirname(dir), sysPath2.basename(dir)); | |
| } | |
| } | |
| } | |
| has(item) { | |
| const { items } = this; | |
| if (!items) | |
| return; | |
| return items.has(item); | |
| } | |
| getChildren() { | |
| const { items } = this; | |
| if (!items) | |
| return []; | |
| return [...items.values()]; | |
| } | |
| dispose() { | |
| this.items.clear(); | |
| this.path = ""; | |
| this._removeWatcher = EMPTY_FN; | |
| this.items = EMPTY_SET; | |
| Object.freeze(this); | |
| } | |
| }; | |
| var STAT_METHOD_F = "stat"; | |
| var STAT_METHOD_L = "lstat"; | |
| var WatchHelper = class { | |
| constructor(path3, follow, fsw) { | |
| this.fsw = fsw; | |
| const watchPath = path3; | |
| this.path = path3 = path3.replace(REPLACER_RE, ""); | |
| this.watchPath = watchPath; | |
| this.fullWatchPath = sysPath2.resolve(watchPath); | |
| this.dirParts = []; | |
| this.dirParts.forEach((parts) => { | |
| if (parts.length > 1) | |
| parts.pop(); | |
| }); | |
| this.followSymlinks = follow; | |
| this.statMethod = follow ? STAT_METHOD_F : STAT_METHOD_L; | |
| } | |
| entryPath(entry) { | |
| return sysPath2.join(this.watchPath, sysPath2.relative(this.watchPath, entry.fullPath)); | |
| } | |
| filterPath(entry) { | |
| const { stats } = entry; | |
| if (stats && stats.isSymbolicLink()) | |
| return this.filterDir(entry); | |
| const resolvedPath = this.entryPath(entry); | |
| return this.fsw._isntIgnored(resolvedPath, stats) && this.fsw._hasReadPermissions(stats); | |
| } | |
| filterDir(entry) { | |
| return this.fsw._isntIgnored(this.entryPath(entry), entry.stats); | |
| } | |
| }; | |
| var FSWatcher = class extends import_events.EventEmitter { | |
| // Not indenting methods for history sake; for now. | |
| constructor(_opts = {}) { | |
| super(); | |
| this.closed = false; | |
| this._closers = /* @__PURE__ */ new Map(); | |
| this._ignoredPaths = /* @__PURE__ */ new Set(); | |
| this._throttled = /* @__PURE__ */ new Map(); | |
| this._streams = /* @__PURE__ */ new Set(); | |
| this._symlinkPaths = /* @__PURE__ */ new Map(); | |
| this._watched = /* @__PURE__ */ new Map(); | |
| this._pendingWrites = /* @__PURE__ */ new Map(); | |
| this._pendingUnlinks = /* @__PURE__ */ new Map(); | |
| this._readyCount = 0; | |
| this._readyEmitted = false; | |
| const awf = _opts.awaitWriteFinish; | |
| const DEF_AWF = { stabilityThreshold: 2e3, pollInterval: 100 }; | |
| const opts = { | |
| // Defaults | |
| persistent: true, | |
| ignoreInitial: false, | |
| ignorePermissionErrors: false, | |
| interval: 100, | |
| binaryInterval: 300, | |
| followSymlinks: true, | |
| usePolling: false, | |
| // useAsync: false, | |
| atomic: true, | |
| // NOTE: overwritten later (depends on usePolling) | |
| ..._opts, | |
| // Change format | |
| ignored: _opts.ignored ? arrify(_opts.ignored) : arrify([]), | |
| awaitWriteFinish: awf === true ? DEF_AWF : typeof awf === "object" ? { ...DEF_AWF, ...awf } : false | |
| }; | |
| if (isIBMi) | |
| opts.usePolling = true; | |
| if (opts.atomic === void 0) | |
| opts.atomic = !opts.usePolling; | |
| const envPoll = process.env.CHOKIDAR_USEPOLLING; | |
| if (envPoll !== void 0) { | |
| const envLower = envPoll.toLowerCase(); | |
| if (envLower === "false" || envLower === "0") | |
| opts.usePolling = false; | |
| else if (envLower === "true" || envLower === "1") | |
| opts.usePolling = true; | |
| else | |
| opts.usePolling = !!envLower; | |
| } | |
| const envInterval = process.env.CHOKIDAR_INTERVAL; | |
| if (envInterval) | |
| opts.interval = Number.parseInt(envInterval, 10); | |
| let readyCalls = 0; | |
| this._emitReady = () => { | |
| readyCalls++; | |
| if (readyCalls >= this._readyCount) { | |
| this._emitReady = EMPTY_FN; | |
| this._readyEmitted = true; | |
| process.nextTick(() => this.emit(EVENTS.READY)); | |
| } | |
| }; | |
| this._emitRaw = (...args) => this.emit(EVENTS.RAW, ...args); | |
| this._boundRemove = this._remove.bind(this); | |
| this.options = opts; | |
| this._nodeFsHandler = new NodeFsHandler(this); | |
| Object.freeze(opts); | |
| } | |
| _addIgnoredPath(matcher) { | |
| if (isMatcherObject(matcher)) { | |
| for (const ignored of this._ignoredPaths) { | |
| if (isMatcherObject(ignored) && ignored.path === matcher.path && ignored.recursive === matcher.recursive) { | |
| return; | |
| } | |
| } | |
| } | |
| this._ignoredPaths.add(matcher); | |
| } | |
| _removeIgnoredPath(matcher) { | |
| this._ignoredPaths.delete(matcher); | |
| if (typeof matcher === "string") { | |
| for (const ignored of this._ignoredPaths) { | |
| if (isMatcherObject(ignored) && ignored.path === matcher) { | |
| this._ignoredPaths.delete(ignored); | |
| } | |
| } | |
| } | |
| } | |
| // Public methods | |
| /** | |
| * Adds paths to be watched on an existing FSWatcher instance. | |
| * @param paths_ file or file list. Other arguments are unused | |
| */ | |
| add(paths_, _origAdd, _internal) { | |
| const { cwd } = this.options; | |
| this.closed = false; | |
| this._closePromise = void 0; | |
| let paths = unifyPaths(paths_); | |
| if (cwd) { | |
| paths = paths.map((path3) => { | |
| const absPath = getAbsolutePath(path3, cwd); | |
| return absPath; | |
| }); | |
| } | |
| paths.forEach((path3) => { | |
| this._removeIgnoredPath(path3); | |
| }); | |
| this._userIgnored = void 0; | |
| if (!this._readyCount) | |
| this._readyCount = 0; | |
| this._readyCount += paths.length; | |
| Promise.all(paths.map(async (path3) => { | |
| const res = await this._nodeFsHandler._addToNodeFs(path3, !_internal, void 0, 0, _origAdd); | |
| if (res) | |
| this._emitReady(); | |
| return res; | |
| })).then((results) => { | |
| if (this.closed) | |
| return; | |
| results.forEach((item) => { | |
| if (item) | |
| this.add(sysPath2.dirname(item), sysPath2.basename(_origAdd || item)); | |
| }); | |
| }); | |
| return this; | |
| } | |
| /** | |
| * Close watchers or start ignoring events from specified paths. | |
| */ | |
| unwatch(paths_) { | |
| if (this.closed) | |
| return this; | |
| const paths = unifyPaths(paths_); | |
| const { cwd } = this.options; | |
| paths.forEach((path3) => { | |
| if (!sysPath2.isAbsolute(path3) && !this._closers.has(path3)) { | |
| if (cwd) | |
| path3 = sysPath2.join(cwd, path3); | |
| path3 = sysPath2.resolve(path3); | |
| } | |
| this._closePath(path3); | |
| this._addIgnoredPath(path3); | |
| if (this._watched.has(path3)) { | |
| this._addIgnoredPath({ | |
| path: path3, | |
| recursive: true | |
| }); | |
| } | |
| this._userIgnored = void 0; | |
| }); | |
| return this; | |
| } | |
| /** | |
| * Close watchers and remove all listeners from watched paths. | |
| */ | |
| close() { | |
| if (this._closePromise) { | |
| return this._closePromise; | |
| } | |
| this.closed = true; | |
| this.removeAllListeners(); | |
| const closers = []; | |
| this._closers.forEach((closerList) => closerList.forEach((closer) => { | |
| const promise = closer(); | |
| if (promise instanceof Promise) | |
| closers.push(promise); | |
| })); | |
| this._streams.forEach((stream) => stream.destroy()); | |
| this._userIgnored = void 0; | |
| this._readyCount = 0; | |
| this._readyEmitted = false; | |
| this._watched.forEach((dirent) => dirent.dispose()); | |
| this._closers.clear(); | |
| this._watched.clear(); | |
| this._streams.clear(); | |
| this._symlinkPaths.clear(); | |
| this._throttled.clear(); | |
| this._closePromise = closers.length ? Promise.all(closers).then(() => void 0) : Promise.resolve(); | |
| return this._closePromise; | |
| } | |
| /** | |
| * Expose list of watched paths | |
| * @returns for chaining | |
| */ | |
| getWatched() { | |
| const watchList = {}; | |
| this._watched.forEach((entry, dir) => { | |
| const key = this.options.cwd ? sysPath2.relative(this.options.cwd, dir) : dir; | |
| const index = key || ONE_DOT; | |
| watchList[index] = entry.getChildren().sort(); | |
| }); | |
| return watchList; | |
| } | |
| emitWithAll(event, args) { | |
| this.emit(event, ...args); | |
| if (event !== EVENTS.ERROR) | |
| this.emit(EVENTS.ALL, event, ...args); | |
| } | |
| // Common helpers | |
| // -------------- | |
| /** | |
| * Normalize and emit events. | |
| * Calling _emit DOES NOT MEAN emit() would be called! | |
| * @param event Type of event | |
| * @param path File or directory path | |
| * @param stats arguments to be passed with event | |
| * @returns the error if defined, otherwise the value of the FSWatcher instance's `closed` flag | |
| */ | |
| async _emit(event, path3, stats) { | |
| if (this.closed) | |
| return; | |
| const opts = this.options; | |
| if (isWindows) | |
| path3 = sysPath2.normalize(path3); | |
| if (opts.cwd) | |
| path3 = sysPath2.relative(opts.cwd, path3); | |
| const args = [path3]; | |
| if (stats != null) | |
| args.push(stats); | |
| const awf = opts.awaitWriteFinish; | |
| let pw; | |
| if (awf && (pw = this._pendingWrites.get(path3))) { | |
| pw.lastChange = /* @__PURE__ */ new Date(); | |
| return this; | |
| } | |
| if (opts.atomic) { | |
| if (event === EVENTS.UNLINK) { | |
| this._pendingUnlinks.set(path3, [event, ...args]); | |
| setTimeout(() => { | |
| this._pendingUnlinks.forEach((entry, path4) => { | |
| this.emit(...entry); | |
| this.emit(EVENTS.ALL, ...entry); | |
| this._pendingUnlinks.delete(path4); | |
| }); | |
| }, typeof opts.atomic === "number" ? opts.atomic : 100); | |
| return this; | |
| } | |
| if (event === EVENTS.ADD && this._pendingUnlinks.has(path3)) { | |
| event = EVENTS.CHANGE; | |
| this._pendingUnlinks.delete(path3); | |
| } | |
| } | |
| if (awf && (event === EVENTS.ADD || event === EVENTS.CHANGE) && this._readyEmitted) { | |
| const awfEmit = (err, stats2) => { | |
| if (err) { | |
| event = EVENTS.ERROR; | |
| args[0] = err; | |
| this.emitWithAll(event, args); | |
| } else if (stats2) { | |
| if (args.length > 1) { | |
| args[1] = stats2; | |
| } else { | |
| args.push(stats2); | |
| } | |
| this.emitWithAll(event, args); | |
| } | |
| }; | |
| this._awaitWriteFinish(path3, awf.stabilityThreshold, event, awfEmit); | |
| return this; | |
| } | |
| if (event === EVENTS.CHANGE) { | |
| const isThrottled = !this._throttle(EVENTS.CHANGE, path3, 50); | |
| if (isThrottled) | |
| return this; | |
| } | |
| if (opts.alwaysStat && stats === void 0 && (event === EVENTS.ADD || event === EVENTS.ADD_DIR || event === EVENTS.CHANGE)) { | |
| const fullPath = opts.cwd ? sysPath2.join(opts.cwd, path3) : path3; | |
| let stats2; | |
| try { | |
| stats2 = await (0, import_promises3.stat)(fullPath); | |
| } catch (err) { | |
| } | |
| if (!stats2 || this.closed) | |
| return; | |
| args.push(stats2); | |
| } | |
| this.emitWithAll(event, args); | |
| return this; | |
| } | |
| /** | |
| * Common handler for errors | |
| * @returns The error if defined, otherwise the value of the FSWatcher instance's `closed` flag | |
| */ | |
| _handleError(error) { | |
| const code = error && error.code; | |
| if (error && code !== "ENOENT" && code !== "ENOTDIR" && (!this.options.ignorePermissionErrors || code !== "EPERM" && code !== "EACCES")) { | |
| this.emit(EVENTS.ERROR, error); | |
| } | |
| return error || this.closed; | |
| } | |
| /** | |
| * Helper utility for throttling | |
| * @param actionType type being throttled | |
| * @param path being acted upon | |
| * @param timeout duration of time to suppress duplicate actions | |
| * @returns tracking object or false if action should be suppressed | |
| */ | |
| _throttle(actionType, path3, timeout) { | |
| if (!this._throttled.has(actionType)) { | |
| this._throttled.set(actionType, /* @__PURE__ */ new Map()); | |
| } | |
| const action = this._throttled.get(actionType); | |
| if (!action) | |
| throw new Error("invalid throttle"); | |
| const actionPath = action.get(path3); | |
| if (actionPath) { | |
| actionPath.count++; | |
| return false; | |
| } | |
| let timeoutObject; | |
| const clear = () => { | |
| const item = action.get(path3); | |
| const count = item ? item.count : 0; | |
| action.delete(path3); | |
| clearTimeout(timeoutObject); | |
| if (item) | |
| clearTimeout(item.timeoutObject); | |
| return count; | |
| }; | |
| timeoutObject = setTimeout(clear, timeout); | |
| const thr = { timeoutObject, clear, count: 0 }; | |
| action.set(path3, thr); | |
| return thr; | |
| } | |
| _incrReadyCount() { | |
| return this._readyCount++; | |
| } | |
| /** | |
| * Awaits write operation to finish. | |
| * Polls a newly created file for size variations. When files size does not change for 'threshold' milliseconds calls callback. | |
| * @param path being acted upon | |
| * @param threshold Time in milliseconds a file size must be fixed before acknowledging write OP is finished | |
| * @param event | |
| * @param awfEmit Callback to be called when ready for event to be emitted. | |
| */ | |
| _awaitWriteFinish(path3, threshold, event, awfEmit) { | |
| const awf = this.options.awaitWriteFinish; | |
| if (typeof awf !== "object") | |
| return; | |
| const pollInterval = awf.pollInterval; | |
| let timeoutHandler; | |
| let fullPath = path3; | |
| if (this.options.cwd && !sysPath2.isAbsolute(path3)) { | |
| fullPath = sysPath2.join(this.options.cwd, path3); | |
| } | |
| const now = /* @__PURE__ */ new Date(); | |
| const writes = this._pendingWrites; | |
| function awaitWriteFinishFn(prevStat) { | |
| (0, import_fs2.stat)(fullPath, (err, curStat) => { | |
| if (err || !writes.has(path3)) { | |
| if (err && err.code !== "ENOENT") | |
| awfEmit(err); | |
| return; | |
| } | |
| const now2 = Number(/* @__PURE__ */ new Date()); | |
| if (prevStat && curStat.size !== prevStat.size) { | |
| writes.get(path3).lastChange = now2; | |
| } | |
| const pw = writes.get(path3); | |
| const df = now2 - pw.lastChange; | |
| if (df >= threshold) { | |
| writes.delete(path3); | |
| awfEmit(void 0, curStat); | |
| } else { | |
| timeoutHandler = setTimeout(awaitWriteFinishFn, pollInterval, curStat); | |
| } | |
| }); | |
| } | |
| if (!writes.has(path3)) { | |
| writes.set(path3, { | |
| lastChange: now, | |
| cancelWait: () => { | |
| writes.delete(path3); | |
| clearTimeout(timeoutHandler); | |
| return event; | |
| } | |
| }); | |
| timeoutHandler = setTimeout(awaitWriteFinishFn, pollInterval); | |
| } | |
| } | |
| /** | |
| * Determines whether user has asked to ignore this path. | |
| */ | |
| _isIgnored(path3, stats) { | |
| if (this.options.atomic && DOT_RE.test(path3)) | |
| return true; | |
| if (!this._userIgnored) { | |
| const { cwd } = this.options; | |
| const ign = this.options.ignored; | |
| const ignored = (ign || []).map(normalizeIgnored(cwd)); | |
| const ignoredPaths = [...this._ignoredPaths]; | |
| const list = [...ignoredPaths.map(normalizeIgnored(cwd)), ...ignored]; | |
| this._userIgnored = anymatch(list, void 0); | |
| } | |
| return this._userIgnored(path3, stats); | |
| } | |
| _isntIgnored(path3, stat4) { | |
| return !this._isIgnored(path3, stat4); | |
| } | |
| /** | |
| * Provides a set of common helpers and properties relating to symlink handling. | |
| * @param path file or directory pattern being watched | |
| */ | |
| _getWatchHelpers(path3) { | |
| return new WatchHelper(path3, this.options.followSymlinks, this); | |
| } | |
| // Directory helpers | |
| // ----------------- | |
| /** | |
| * Provides directory tracking objects | |
| * @param directory path of the directory | |
| */ | |
| _getWatchedDir(directory) { | |
| const dir = sysPath2.resolve(directory); | |
| if (!this._watched.has(dir)) | |
| this._watched.set(dir, new DirEntry(dir, this._boundRemove)); | |
| return this._watched.get(dir); | |
| } | |
| // File helpers | |
| // ------------ | |
| /** | |
| * Check for read permissions: https://stackoverflow.com/a/11781404/1358405 | |
| */ | |
| _hasReadPermissions(stats) { | |
| if (this.options.ignorePermissionErrors) | |
| return true; | |
| return Boolean(Number(stats.mode) & 256); | |
| } | |
| /** | |
| * Handles emitting unlink events for | |
| * files and directories, and via recursion, for | |
| * files and directories within directories that are unlinked | |
| * @param directory within which the following item is located | |
| * @param item base path of item/directory | |
| */ | |
| _remove(directory, item, isDirectory) { | |
| const path3 = sysPath2.join(directory, item); | |
| const fullPath = sysPath2.resolve(path3); | |
| isDirectory = isDirectory != null ? isDirectory : this._watched.has(path3) || this._watched.has(fullPath); | |
| if (!this._throttle("remove", path3, 100)) | |
| return; | |
| if (!isDirectory && this._watched.size === 1) { | |
| this.add(directory, item, true); | |
| } | |
| const wp = this._getWatchedDir(path3); | |
| const nestedDirectoryChildren = wp.getChildren(); | |
| nestedDirectoryChildren.forEach((nested) => this._remove(path3, nested)); | |
| const parent = this._getWatchedDir(directory); | |
| const wasTracked = parent.has(item); | |
| parent.remove(item); | |
| if (this._symlinkPaths.has(fullPath)) { | |
| this._symlinkPaths.delete(fullPath); | |
| } | |
| let relPath = path3; | |
| if (this.options.cwd) | |
| relPath = sysPath2.relative(this.options.cwd, path3); | |
| if (this.options.awaitWriteFinish && this._pendingWrites.has(relPath)) { | |
| const event = this._pendingWrites.get(relPath).cancelWait(); | |
| if (event === EVENTS.ADD) | |
| return; | |
| } | |
| this._watched.delete(path3); | |
| this._watched.delete(fullPath); | |
| const eventName = isDirectory ? EVENTS.UNLINK_DIR : EVENTS.UNLINK; | |
| if (wasTracked && !this._isIgnored(path3)) | |
| this._emit(eventName, path3); | |
| this._closePath(path3); | |
| } | |
| /** | |
| * Closes all watchers for a path | |
| */ | |
| _closePath(path3) { | |
| this._closeFile(path3); | |
| const dir = sysPath2.dirname(path3); | |
| this._getWatchedDir(dir).remove(sysPath2.basename(path3)); | |
| } | |
| /** | |
| * Closes only file-specific watchers | |
| */ | |
| _closeFile(path3) { | |
| const closers = this._closers.get(path3); | |
| if (!closers) | |
| return; | |
| closers.forEach((closer) => closer()); | |
| this._closers.delete(path3); | |
| } | |
| _addPathCloser(path3, closer) { | |
| if (!closer) | |
| return; | |
| let list = this._closers.get(path3); | |
| if (!list) { | |
| list = []; | |
| this._closers.set(path3, list); | |
| } | |
| list.push(closer); | |
| } | |
| _readdirp(root, opts) { | |
| if (this.closed) | |
| return; | |
| const options = { type: EVENTS.ALL, alwaysStat: true, lstat: true, ...opts, depth: 0 }; | |
| let stream = readdirp(root, options); | |
| this._streams.add(stream); | |
| stream.once(STR_CLOSE, () => { | |
| stream = void 0; | |
| }); | |
| stream.once(STR_END, () => { | |
| if (stream) { | |
| this._streams.delete(stream); | |
| stream = void 0; | |
| } | |
| }); | |
| return stream; | |
| } | |
| }; | |
| function watch(paths, options = {}) { | |
| const watcher = new FSWatcher(options); | |
| watcher.add(paths); | |
| return watcher; | |
| } | |
| var esm_default = { watch, FSWatcher }; | |
| // packages/playwright-core/src/package.ts | |
| var import_path = __toESM(require("path")); | |
| var packageRoot = import_path.default.join(__dirname, ".."); | |
| var packageJSON = require(import_path.default.join(packageRoot, "package.json")); | |
| var binPath = import_path.default.join(packageRoot, "bin"); | |
| // packages/playwright-core/src/serverRegistry.ts | |
| var packageVersion = packageJSON.version; | |
| var ServerRegistry = class extends import_events2.EventEmitter { | |
| constructor() { | |
| super(...arguments); | |
| this._descriptors = /* @__PURE__ */ new Map(); | |
| this._watcherRefs = 0; | |
| } | |
| on(event, listener) { | |
| return super.on(event, listener); | |
| } | |
| off(event, listener) { | |
| return super.off(event, listener); | |
| } | |
| watch() { | |
| this._watcherRefs++; | |
| if (!this._watcher) | |
| this._startWatcher(); | |
| let disposed = false; | |
| return () => { | |
| if (disposed) | |
| return; | |
| disposed = true; | |
| this._watcherRefs--; | |
| if (this._watcherRefs === 0) | |
| this._stopWatcher(); | |
| }; | |
| } | |
| ready() { | |
| return this._ready ?? Promise.resolve(); | |
| } | |
| async list() { | |
| const ownWatcher = !this._watcher; | |
| let dispose; | |
| if (ownWatcher) | |
| dispose = this.watch(); | |
| try { | |
| await this._ready; | |
| const statuses = await Promise.all( | |
| [...this._descriptors.values()].map(async (descriptor) => { | |
| const canConnect = await canConnectTo(descriptor); | |
| return { descriptor, canConnect }; | |
| }) | |
| ); | |
| const result = /* @__PURE__ */ new Map(); | |
| for (const { descriptor, canConnect } of statuses) { | |
| if (!canConnect) { | |
| await import_fs3.default.promises.unlink(import_path2.default.join(this._browsersDir(), descriptor.browser.guid)).catch(() => { | |
| }); | |
| continue; | |
| } | |
| const key = descriptor.workspaceDir ?? ""; | |
| let list = result.get(key); | |
| if (!list) { | |
| list = []; | |
| result.set(key, list); | |
| } | |
| list.push(descriptor); | |
| } | |
| return result; | |
| } finally { | |
| dispose?.(); | |
| } | |
| } | |
| async create(browser, endpoint) { | |
| const file = import_path2.default.join(this._browsersDir(), browser.guid); | |
| await import_fs3.default.promises.mkdir(this._browsersDir(), { recursive: true }); | |
| const descriptor = { | |
| playwrightVersion: packageVersion, | |
| playwrightLib: packageRoot, | |
| title: endpoint.title, | |
| browser, | |
| endpoint: endpoint.endpoint, | |
| workspaceDir: endpoint.workspaceDir | |
| }; | |
| await import_fs3.default.promises.writeFile(file, JSON.stringify(descriptor, null, 2), "utf-8"); | |
| } | |
| async delete(guid) { | |
| const file = import_path2.default.join(this._browsersDir(), guid); | |
| await import_fs3.default.promises.unlink(file).catch(() => { | |
| }); | |
| } | |
| async deleteUserData(guid) { | |
| const filePath = import_path2.default.join(this._browsersDir(), guid); | |
| const content = await import_fs3.default.promises.readFile(filePath, "utf-8"); | |
| const descriptor = JSON.parse(content); | |
| if (descriptor.browser.userDataDir) | |
| await import_fs3.default.promises.rm(descriptor.browser.userDataDir, { recursive: true, force: true }); | |
| await import_fs3.default.promises.unlink(filePath); | |
| } | |
| readDescriptor(guid) { | |
| const cached = this._descriptors.get(guid); | |
| if (cached) | |
| return cached; | |
| const filePath = import_path2.default.join(this._browsersDir(), guid); | |
| const content = import_fs3.default.readFileSync(filePath, "utf-8"); | |
| return JSON.parse(content); | |
| } | |
| async find(name) { | |
| const entries = await this.list(); | |
| for (const [, browsers] of entries) { | |
| for (const browser of browsers) { | |
| if (browser.title === name) | |
| return browser; | |
| } | |
| } | |
| return null; | |
| } | |
| _browsersDir() { | |
| return process.env.PWTEST_SERVER_REGISTRY || registryDirectory(); | |
| } | |
| _startWatcher() { | |
| const dir = this._browsersDir(); | |
| try { | |
| import_fs3.default.mkdirSync(dir, { recursive: true }); | |
| } catch { | |
| } | |
| const watcher = esm_default.watch(dir, { | |
| ignoreInitial: false, | |
| depth: 0, | |
| awaitWriteFinish: { stabilityThreshold: 50, pollInterval: 20 } | |
| }); | |
| this._watcher = watcher; | |
| this._ready = new Promise((resolve3, reject) => { | |
| watcher.once("ready", () => resolve3()); | |
| watcher.once("error", reject); | |
| }); | |
| watcher.on("add", (file) => this._onAddOrChange(file, "added")); | |
| watcher.on("change", (file) => this._onAddOrChange(file, "changed")); | |
| watcher.on("unlink", (file) => { | |
| const guid = import_path2.default.basename(file); | |
| if (this._descriptors.delete(guid)) | |
| this.emit("removed", guid); | |
| }); | |
| } | |
| _onAddOrChange(file, event) { | |
| const guid = import_path2.default.basename(file); | |
| let descriptor; | |
| try { | |
| descriptor = JSON.parse(import_fs3.default.readFileSync(file, "utf-8")); | |
| } catch { | |
| return; | |
| } | |
| this._descriptors.set(guid, descriptor); | |
| this.emit(event, descriptor); | |
| } | |
| _stopWatcher() { | |
| const watcher = this._watcher; | |
| this._watcher = void 0; | |
| this._ready = void 0; | |
| this._descriptors.clear(); | |
| void watcher?.close(); | |
| } | |
| }; | |
| async function canConnectTo(descriptor) { | |
| if (!descriptor.endpoint) | |
| return false; | |
| if (descriptor.endpoint.startsWith("ws://") || descriptor.endpoint.startsWith("wss://")) { | |
| return await new Promise((resolve3) => { | |
| const url = new URL(descriptor.endpoint); | |
| const socket = import_net.default.createConnection(Number(url.port), url.hostname, () => { | |
| socket.destroy(); | |
| resolve3(true); | |
| }); | |
| socket.on("error", () => resolve3(false)); | |
| }); | |
| } | |
| return await new Promise((resolve3) => { | |
| const socket = import_net.default.createConnection(descriptor.endpoint ?? descriptor.pipeName, () => { | |
| socket.destroy(); | |
| resolve3(true); | |
| }); | |
| socket.on("error", () => resolve3(false)); | |
| }); | |
| } | |
| function computeDefaultCacheDirectory() { | |
| if (process.platform === "linux") | |
| return process.env.XDG_CACHE_HOME || import_path2.default.join(import_os2.default.homedir(), ".cache"); | |
| if (process.platform === "darwin") | |
| return import_path2.default.join(import_os2.default.homedir(), "Library", "Caches"); | |
| if (process.platform === "win32") | |
| return process.env.LOCALAPPDATA || import_path2.default.join(import_os2.default.homedir(), "AppData", "Local"); | |
| throw new Error("Unsupported platform: " + process.platform); | |
| } | |
| var _defaultCacheDirectory; | |
| function defaultCacheDirectory() { | |
| return _defaultCacheDirectory ??= computeDefaultCacheDirectory(); | |
| } | |
| function registryDirectory() { | |
| return import_path2.default.join(defaultCacheDirectory(), "ms-playwright", "b"); | |
| } | |
| var serverRegistry = new ServerRegistry(); | |
| // Annotate the CommonJS export names for ESM import in node: | |
| 0 && (module.exports = { | |
| serverRegistry | |
| }); | |
| /*! Bundled license information: | |
| chokidar/esm/index.js: | |
| (*! chokidar - MIT License (c) 2012 Paul Miller (paulmillr.com) *) | |
| */ | |