UNPKG

convex

Version:

Client for the Convex Cloud

469 lines (468 loc) 13.5 kB
"use strict"; 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( isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target, mod )); var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod); var fs_exports = {}; __export(fs_exports, { Observations: () => Observations, RecordingFs: () => RecordingFs, mkdtemp: () => mkdtemp, nodeFs: () => nodeFs, stMatches: () => stMatches }); module.exports = __toCommonJS(fs_exports); var import_chalk = __toESM(require("chalk")); var import_fs = __toESM(require("fs")); var import_os = __toESM(require("os")); var import_path = __toESM(require("path")); const tmpDirOverrideVar = "CONVEX_TMPDIR"; function tmpDirPath() { const envTmpDir = process.env[tmpDirOverrideVar]; return envTmpDir ?? import_os.default.tmpdir(); } const tmpDirRoot = tmpDirPath(); let warned = false; function warnCrossFilesystem(dstPath) { const dstDir = import_path.default.dirname(dstPath); if (!warned) { console.warn( import_chalk.default.yellow( `Temporary directory '${tmpDirRoot}' and project directory '${dstDir}' are on different filesystems.` ) ); console.warn( import_chalk.default.gray( ` If you're running into errors with other tools watching the project directory, override the temporary directory location with the ${import_chalk.default.bold( tmpDirOverrideVar )} environment variable.` ) ); console.warn( import_chalk.default.gray( ` Be sure to pick a temporary directory that's on the same filesystem as your project.` ) ); warned = true; } } async function mkdtemp(prefix, callback) { const tmpPath = import_fs.default.mkdtempSync(import_path.default.join(tmpDirRoot, prefix)); try { await callback({ tmpPath }); } finally { import_fs.default.rmSync(tmpPath, { force: true, recursive: true }); } } class NodeFs { listDir(dirPath) { return import_fs.default.readdirSync(dirPath, { withFileTypes: true }); } exists(path2) { try { import_fs.default.statSync(path2); return true; } catch (e) { if (e.code === "ENOENT") { return false; } throw e; } } stat(path2) { return import_fs.default.statSync(path2); } readUtf8File(path2) { return import_fs.default.readFileSync(path2, { encoding: "utf-8" }); } createReadStream(path2) { return import_fs.default.createReadStream(path2); } access(path2) { return import_fs.default.accessSync(path2); } writeUtf8File(path2, contents, mode) { const fd = import_fs.default.openSync(path2, "w", mode); try { import_fs.default.writeFileSync(fd, contents, { encoding: "utf-8" }); import_fs.default.fsyncSync(fd); } finally { import_fs.default.closeSync(fd); } } mkdir(dirPath, options) { try { import_fs.default.mkdirSync(dirPath); } catch (e) { if (options?.allowExisting && e.code === "EEXIST") { return; } throw e; } } rm(path2, options) { import_fs.default.rmSync(path2, options); } rmdir(path2) { import_fs.default.rmdirSync(path2); } unlink(path2) { return import_fs.default.unlinkSync(path2); } renameFile(fromPath, toPath) { try { return import_fs.default.renameSync(fromPath, toPath); } catch (e) { if (e.code === "EXDEV") { warnCrossFilesystem(toPath); import_fs.default.copyFileSync(fromPath, toPath); return; } throw e; } } registerPath(_path, _st) { } invalidate() { } } const nodeFs = new NodeFs(); class RecordingFs { constructor(traceEvents) { this.observedDirectories = /* @__PURE__ */ new Map(); this.observedFiles = /* @__PURE__ */ new Map(); this.invalidated = false; this.traceEvents = traceEvents; } listDir(dirPath) { const absDirPath = import_path.default.resolve(dirPath); const dirSt = nodeFs.stat(absDirPath); this.registerNormalized(absDirPath, dirSt); const entries = nodeFs.listDir(dirPath); for (const entry of entries) { const childPath = import_path.default.join(absDirPath, entry.name); const childSt = nodeFs.stat(childPath); this.registerPath(childPath, childSt); } const observedNames = new Set(entries.map((e) => e.name)); const existingNames = this.observedDirectories.get(absDirPath); if (existingNames) { if (!setsEqual(observedNames, existingNames)) { if (this.traceEvents) { console.log( "Invalidating due to directory children mismatch", observedNames, existingNames ); } this.invalidated = true; } } this.observedDirectories.set(absDirPath, observedNames); return entries; } exists(path2) { try { const st = nodeFs.stat(path2); this.registerPath(path2, st); return true; } catch (err) { if (err.code === "ENOENT") { this.registerPath(path2, null); return false; } throw err; } } stat(path2) { try { const st = nodeFs.stat(path2); this.registerPath(path2, st); return st; } catch (err) { if (err.code === "ENOENT") { this.registerPath(path2, null); } throw err; } } readUtf8File(path2) { try { const st = nodeFs.stat(path2); this.registerPath(path2, st); return nodeFs.readUtf8File(path2); } catch (err) { if (err.code === "ENOENT") { this.registerPath(path2, null); } throw err; } } createReadStream(path2) { try { const st = nodeFs.stat(path2); this.registerPath(path2, st); return nodeFs.createReadStream(path2); } catch (err) { if (err.code === "ENOENT") { this.registerPath(path2, null); } throw err; } } access(path2) { try { const st = nodeFs.stat(path2); this.registerPath(path2, st); return nodeFs.access(path2); } catch (err) { if (err.code === "ENOENT") { this.registerPath(path2, null); } throw err; } } writeUtf8File(filePath, contents, mode) { const absPath = import_path.default.resolve(filePath); nodeFs.writeUtf8File(filePath, contents, mode); this.updateOnWrite(absPath); } mkdir(dirPath, options) { const absPath = import_path.default.resolve(dirPath); try { import_fs.default.mkdirSync(absPath); } catch (e) { if (options?.allowExisting && e.code === "EEXIST") { const st = nodeFs.stat(absPath); this.registerNormalized(absPath, st); return; } throw e; } this.updateOnWrite(absPath); } rm(entityPath, options) { const absPath = import_path.default.resolve(entityPath); const isDir = this.exists(absPath) && this.stat(absPath).isDirectory(); if (options?.recursive && isDir) { const entries = this.listDir(entityPath); for (const entry of entries) { this.rm(import_path.default.join(absPath, entry.name), options); } } try { if (isDir) { import_fs.default.rmdirSync(absPath); } else { import_fs.default.rmSync(absPath); } } catch (e) { const allowed = options?.force && e.code === "ENOENT"; if (!allowed) { throw e; } } this.updateOnDelete(absPath); } rmdir(dirPath) { const absPath = import_path.default.resolve(dirPath); import_fs.default.rmdirSync(absPath); this.updateOnDelete(absPath); } unlink(filePath) { const absPath = import_path.default.resolve(filePath); import_fs.default.unlinkSync(absPath); this.updateOnDelete(absPath); } renameFile(fromPath, toPath) { const absFromPath = import_path.default.resolve(fromPath); const absToPath = import_path.default.resolve(toPath); nodeFs.renameFile(absFromPath, absToPath); this.updateOnDelete(absFromPath); this.updateOnWrite(absToPath); } updateOnWrite(absPath) { const newSt = nodeFs.stat(absPath); this.observedFiles.set(absPath, newSt); const parentPath = import_path.default.resolve(import_path.default.dirname(absPath)); const observedParent = this.observedDirectories.get(parentPath); if (observedParent !== void 0) { observedParent.add(import_path.default.basename(absPath)); } } updateOnDelete(absPath) { this.observedFiles.set(absPath, null); const parentPath = import_path.default.resolve(import_path.default.dirname(absPath)); const observedParent = this.observedDirectories.get(parentPath); if (observedParent !== void 0) { observedParent.delete(import_path.default.basename(absPath)); } } registerPath(p, st) { const absPath = import_path.default.resolve(p); this.registerNormalized(absPath, st); } invalidate() { this.invalidated = true; } registerNormalized(absPath, observed) { const existing = this.observedFiles.get(absPath); if (existing !== void 0) { const stMatch = stMatches(observed, existing); if (!stMatch.matches) { if (this.traceEvents) { console.log( "Invalidating due to st mismatch", absPath, observed, existing, stMatch.reason ); } this.invalidated = true; } } this.observedFiles.set(absPath, observed); } finalize() { if (this.invalidated) { return "invalidated"; } return new Observations(this.observedDirectories, this.observedFiles); } } class Observations { constructor(directories, files) { this.directories = directories; this.files = files; } paths() { const out = []; for (const path2 of this.directories.keys()) { out.push(path2); } for (const path2 of this.files.keys()) { out.push(path2); } return out; } overlaps({ absPath }) { let currentSt; try { currentSt = nodeFs.stat(absPath); } catch (e) { if (e.code === "ENOENT") { currentSt = null; } else { throw e; } } const observedSt = this.files.get(absPath); if (observedSt !== void 0) { const stMatch = stMatches(observedSt, currentSt); if (!stMatch.matches) { const reason = `modified (${stMatch.reason})`; return { overlaps: true, reason }; } } const parentPath = import_path.default.resolve(import_path.default.dirname(absPath)); const observedParent = this.directories.get(parentPath); if (observedParent !== void 0) { const filename = import_path.default.basename(absPath); if (currentSt === null && observedParent.has(filename)) { return { overlaps: true, reason: "deleted" }; } if (currentSt !== null && !observedParent.has(filename)) { return { overlaps: true, reason: "added" }; } } return { overlaps: false }; } } function setsEqual(a, b) { if (a.size !== b.size) { return false; } for (const elem of a.keys()) { if (!b.has(elem)) { return false; } } return true; } function stMatches(a, b) { if (a === null && b === null) { return { matches: true }; } if (a !== null && b !== null) { if (a.dev !== b.dev) { return { matches: false, reason: "device boundary" }; } if (a.isFile() || b.isFile()) { if (!a.isFile() || !b.isFile()) { return { matches: false, reason: "file type" }; } if (a.ino !== b.ino) { return { matches: false, reason: `file inode (${a.ino} vs. ${b.ino})` }; } if (a.size !== b.size) { return { matches: false, reason: `file size (${a.size} vs. ${b.size})` }; } if (a.mtimeMs !== b.mtimeMs) { return { matches: false, reason: `file mtime (${a.mtimeMs} vs. ${b.mtimeMs})` }; } return { matches: true }; } if (a.isDirectory() || b.isDirectory()) { if (!b.isDirectory() || !b.isDirectory()) { return { matches: false, reason: "dir file type" }; } if (a.ino !== b.ino) { return { matches: false, reason: `dir inode (${a.ino} vs. ${b.ino})` }; } return { matches: true }; } if (a.ino !== b.ino) { return { matches: false, reason: `special inode (${a.ino} vs. ${b.ino})` }; } return { matches: true }; } return { matches: false, reason: "deleted mismatch" }; } //# sourceMappingURL=fs.js.map