@holoscript/std 6.0.3 → 7.0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +8 -0
- package/dist/chunk-DGUM43GV.js +11 -0
- package/dist/chunk-DGUM43GV.js.map +1 -0
- package/dist/{chunk-PFX2JM4X.js → chunk-FAMOLKH3.js} +2 -1
- package/dist/{chunk-PFX2JM4X.js.map → chunk-FAMOLKH3.js.map} +1 -1
- package/dist/{chunk-7HVUYGPS.js → chunk-SOKH6FJ7.js} +37 -5
- package/dist/chunk-SOKH6FJ7.js.map +1 -0
- package/dist/{chunk-W2Q3LUCM.js → chunk-XJIFG7G3.js} +3 -3
- package/dist/chunk-XJIFG7G3.js.map +1 -0
- package/dist/collections.cjs +1 -0
- package/dist/collections.cjs.map +1 -1
- package/dist/collections.js +2 -1
- package/dist/fs/fs.d.ts +288 -0
- package/dist/fs/fs.d.ts.map +1 -0
- package/dist/fs/index.cjs +1049 -0
- package/dist/fs/index.cjs.map +1 -0
- package/dist/fs/index.d.ts +51 -0
- package/dist/fs/index.d.ts.map +1 -0
- package/dist/fs/index.js +918 -0
- package/dist/fs/index.js.map +1 -0
- package/dist/fs/path.d.ts +135 -0
- package/dist/fs/path.d.ts.map +1 -0
- package/dist/fs/sandbox.d.ts +49 -0
- package/dist/fs/sandbox.d.ts.map +1 -0
- package/dist/fs/watch.d.ts +133 -0
- package/dist/fs/watch.d.ts.map +1 -0
- package/dist/index.cjs +54 -7
- package/dist/index.cjs.map +1 -1
- package/dist/index.js +19 -4
- package/dist/index.js.map +1 -1
- package/dist/math.cjs +21 -2
- package/dist/math.cjs.map +1 -1
- package/dist/math.js +2 -1
- package/dist/string.cjs +2 -2
- package/dist/string.cjs.map +1 -1
- package/dist/string.js +2 -1
- package/dist/time.js +1 -0
- package/dist/traits/EconomicPrimitives.js +1 -0
- package/dist/traits/EconomicTraits.js +1 -0
- package/dist/traits/VRRTraits.d.ts +2 -2
- package/dist/types.d.ts.map +1 -1
- package/package.json +24 -9
- package/CHANGELOG.md +0 -7
- package/dist/__tests__/EconomicPrimitives.test.d.ts +0 -2
- package/dist/__tests__/EconomicPrimitives.test.d.ts.map +0 -1
- package/dist/__tests__/EconomicTraits.test.d.ts +0 -2
- package/dist/__tests__/EconomicTraits.test.d.ts.map +0 -1
- package/dist/__tests__/SimulationLabPrimitives.test.d.ts +0 -2
- package/dist/__tests__/SimulationLabPrimitives.test.d.ts.map +0 -1
- package/dist/__tests__/collections.test.d.ts +0 -2
- package/dist/__tests__/collections.test.d.ts.map +0 -1
- package/dist/__tests__/events.test.d.ts +0 -2
- package/dist/__tests__/events.test.d.ts.map +0 -1
- package/dist/__tests__/index.test.d.ts +0 -2
- package/dist/__tests__/index.test.d.ts.map +0 -1
- package/dist/__tests__/materials.test.d.ts +0 -2
- package/dist/__tests__/materials.test.d.ts.map +0 -1
- package/dist/__tests__/math.test.d.ts +0 -2
- package/dist/__tests__/math.test.d.ts.map +0 -1
- package/dist/__tests__/physics.test.d.ts +0 -2
- package/dist/__tests__/physics.test.d.ts.map +0 -1
- package/dist/__tests__/spatial.test.d.ts +0 -2
- package/dist/__tests__/spatial.test.d.ts.map +0 -1
- package/dist/__tests__/standard-library-fundamentals.test.d.ts +0 -2
- package/dist/__tests__/standard-library-fundamentals.test.d.ts.map +0 -1
- package/dist/__tests__/string-and-time-utilities.test.d.ts +0 -2
- package/dist/__tests__/string-and-time-utilities.test.d.ts.map +0 -1
- package/dist/__tests__/string-decoupled.test.d.ts +0 -2
- package/dist/__tests__/string-decoupled.test.d.ts.map +0 -1
- package/dist/__tests__/string.test.d.ts +0 -2
- package/dist/__tests__/string.test.d.ts.map +0 -1
- package/dist/__tests__/time.test.d.ts +0 -2
- package/dist/__tests__/time.test.d.ts.map +0 -1
- package/dist/chunk-7HVUYGPS.js.map +0 -1
- package/dist/chunk-W2Q3LUCM.js.map +0 -1
- package/dist/string.basic.test.d.ts +0 -5
- package/dist/string.basic.test.d.ts.map +0 -1
- package/dist/string.test.d.ts +0 -5
- package/dist/string.test.d.ts.map +0 -1
- package/dist/traits/__tests__/ARTraits.test.d.ts +0 -2
- package/dist/traits/__tests__/ARTraits.test.d.ts.map +0 -1
- package/dist/traits/__tests__/EconomicPrimitives.test.d.ts +0 -2
- package/dist/traits/__tests__/EconomicPrimitives.test.d.ts.map +0 -1
- package/dist/traits/__tests__/EconomicTraits.test.d.ts +0 -2
- package/dist/traits/__tests__/EconomicTraits.test.d.ts.map +0 -1
- package/error-utf8.log +0 -6
- package/error.log +0 -0
- package/src/__tests__/EconomicPrimitives.test.ts +0 -690
- package/src/__tests__/EconomicTraits.test.ts +0 -425
- package/src/__tests__/SimulationLabPrimitives.test.ts +0 -415
- package/src/__tests__/collections.test.ts +0 -182
- package/src/__tests__/events.test.ts +0 -135
- package/src/__tests__/index.test.ts +0 -14
- package/src/__tests__/materials.test.ts +0 -84
- package/src/__tests__/math.test.ts +0 -246
- package/src/__tests__/physics.test.ts +0 -83
- package/src/__tests__/spatial.test.ts +0 -333
- package/src/__tests__/standard-library-fundamentals.test.ts +0 -1301
- package/src/__tests__/string-and-time-utilities.test.ts +0 -1070
- package/src/__tests__/string-decoupled.test.ts +0 -14
- package/src/__tests__/string.test.ts +0 -164
- package/src/__tests__/time.test.ts +0 -110
- package/src/collections.ts +0 -850
- package/src/events.ts +0 -88
- package/src/index.ts +0 -474
- package/src/materials.ts +0 -109
- package/src/math.ts +0 -674
- package/src/physics.ts +0 -141
- package/src/spatial.ts +0 -320
- package/src/string.basic.test.ts +0 -14
- package/src/string.test.ts +0 -335
- package/src/string.ts +0 -531
- package/src/time.ts +0 -621
- package/src/traits/ARTraits.ts +0 -103
- package/src/traits/EconomicPrimitives.ts +0 -755
- package/src/traits/EconomicTraits.ts +0 -552
- package/src/traits/IoTTraits.ts +0 -102
- package/src/traits/SimulationLabPrimitives.ts +0 -650
- package/src/traits/SimulationLabTraits.ts +0 -191
- package/src/traits/VRRTraits.ts +0 -326
- package/src/traits/__tests__/ARTraits.test.ts +0 -14
- package/src/traits/__tests__/EconomicPrimitives.test.ts +0 -14
- package/src/traits/__tests__/EconomicTraits.test.ts +0 -14
- package/src/types.ts +0 -411
- package/std_error.log +0 -5
- package/tsconfig.json +0 -18
- package/tsup.config.ts +0 -17
- package/vitest.config.ts +0 -10
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../src/fs/fs.ts","../../src/fs/sandbox.ts","../../src/fs/path.ts","../../src/fs/watch.ts","../../src/fs/index.ts"],"sourcesContent":["/**\n * @holoscript/fs - File System Module\n *\n * File and directory operations for HoloScript Plus programs.\n */\n\nimport * as fs from 'fs';\nimport * as fsPromises from 'fs/promises';\nimport * as nodePath from 'path';\nimport { glob as globAsync } from 'glob';\nimport { enforcePathBoundary } from './sandbox.js';\n\nexport type Encoding = BufferEncoding;\n\n/**\n * File stats information\n */\nexport interface FileStats {\n size: number;\n isFile: boolean;\n isDirectory: boolean;\n isSymlink: boolean;\n createdAt: Date;\n modifiedAt: Date;\n accessedAt: Date;\n mode: number;\n}\n\n/**\n * Directory entry\n */\nexport interface DirEntry {\n name: string;\n path: string;\n isFile: boolean;\n isDirectory: boolean;\n isSymlink: boolean;\n}\n\n/**\n * Read options\n */\nexport interface ReadOptions {\n encoding?: Encoding;\n}\n\n/**\n * Write options\n */\nexport interface WriteOptions {\n encoding?: Encoding;\n mode?: number;\n flag?: string;\n append?: boolean;\n}\n\n/**\n * Copy options\n */\nexport interface CopyOptions {\n overwrite?: boolean;\n recursive?: boolean;\n filter?: (src: string) => boolean;\n}\n\n// ============================================================================\n// File Reading\n// ============================================================================\n\n/**\n * Read a file as text\n */\nexport async function readText(path: string, encoding: Encoding = 'utf-8'): Promise<string> {\n path = enforcePathBoundary(path);\n return fsPromises.readFile(path, { encoding });\n}\n\n/**\n * Read a file as text (sync)\n */\nexport function readTextSync(path: string, encoding: Encoding = 'utf-8'): string {\n path = enforcePathBoundary(path);\n return fs.readFileSync(path, { encoding });\n}\n\n/**\n * Read a file as bytes\n */\nexport async function readBytes(path: string): Promise<Buffer> {\n path = enforcePathBoundary(path);\n return fsPromises.readFile(path);\n}\n\n/**\n * Read a file as bytes (sync)\n */\nexport function readBytesSync(path: string): Buffer {\n path = enforcePathBoundary(path);\n return fs.readFileSync(path);\n}\n\n/**\n * Read a JSON file\n */\nexport async function readJson<T = unknown>(path: string): Promise<T> {\n const text = await readText(path);\n return JSON.parse(text);\n}\n\n/**\n * Read a JSON file (sync)\n */\nexport function readJsonSync<T = unknown>(path: string): T {\n const text = readTextSync(path);\n return JSON.parse(text);\n}\n\n/**\n * Read file lines as an array\n */\nexport async function readLines(path: string, encoding: Encoding = 'utf-8'): Promise<string[]> {\n const text = await readText(path, encoding);\n return text.split(/\\r?\\n/);\n}\n\n/**\n * Read file lines as an array (sync)\n */\nexport function readLinesSync(path: string, encoding: Encoding = 'utf-8'): string[] {\n const text = readTextSync(path, encoding);\n return text.split(/\\r?\\n/);\n}\n\n// ============================================================================\n// File Writing\n// ============================================================================\n\n/**\n * Write text to a file\n */\nexport async function writeText(\n path: string,\n content: string,\n options: WriteOptions = {}\n): Promise<void> {\n path = enforcePathBoundary(path);\n const { encoding = 'utf-8', mode, flag = options.append ? 'a' : 'w' } = options;\n await ensureDir(nodePath.dirname(path));\n await fsPromises.writeFile(path, content, { encoding, mode, flag });\n}\n\n/**\n * Write text to a file (sync)\n */\nexport function writeTextSync(path: string, content: string, options: WriteOptions = {}): void {\n path = enforcePathBoundary(path);\n const { encoding = 'utf-8', mode, flag = options.append ? 'a' : 'w' } = options;\n ensureDirSync(nodePath.dirname(path));\n fs.writeFileSync(path, content, { encoding, mode, flag });\n}\n\n/**\n * Write bytes to a file\n */\nexport async function writeBytes(\n path: string,\n content: Buffer,\n options: WriteOptions = {}\n): Promise<void> {\n path = enforcePathBoundary(path);\n const { mode, flag = options.append ? 'a' : 'w' } = options;\n await ensureDir(nodePath.dirname(path));\n await fsPromises.writeFile(path, content, { mode, flag });\n}\n\n/**\n * Write bytes to a file (sync)\n */\nexport function writeBytesSync(path: string, content: Buffer, options: WriteOptions = {}): void {\n path = enforcePathBoundary(path);\n const { mode, flag = options.append ? 'a' : 'w' } = options;\n ensureDirSync(nodePath.dirname(path));\n fs.writeFileSync(path, content, { mode, flag });\n}\n\n/**\n * Write JSON to a file\n */\nexport async function writeJson(\n path: string,\n data: unknown,\n options: WriteOptions & { pretty?: boolean } = {}\n): Promise<void> {\n const { pretty = true, ...writeOpts } = options;\n const text = pretty ? JSON.stringify(data, null, 2) : JSON.stringify(data);\n await writeText(path, text, writeOpts);\n}\n\n/**\n * Write JSON to a file (sync)\n */\nexport function writeJsonSync(\n path: string,\n data: unknown,\n options: WriteOptions & { pretty?: boolean } = {}\n): void {\n const { pretty = true, ...writeOpts } = options;\n const text = pretty ? JSON.stringify(data, null, 2) : JSON.stringify(data);\n writeTextSync(path, text, writeOpts);\n}\n\n/**\n * Append text to a file\n */\nexport async function appendText(\n path: string,\n content: string,\n encoding: Encoding = 'utf-8'\n): Promise<void> {\n await writeText(path, content, { encoding, append: true });\n}\n\n/**\n * Append text to a file (sync)\n */\nexport function appendTextSync(path: string, content: string, encoding: Encoding = 'utf-8'): void {\n writeTextSync(path, content, { encoding, append: true });\n}\n\n/**\n * Append a line to a file\n */\nexport async function appendLine(\n path: string,\n line: string,\n encoding: Encoding = 'utf-8'\n): Promise<void> {\n await appendText(path, line + '\\n', encoding);\n}\n\n/**\n * Append a line to a file (sync)\n */\nexport function appendLineSync(path: string, line: string, encoding: Encoding = 'utf-8'): void {\n appendTextSync(path, line + '\\n', encoding);\n}\n\n// ============================================================================\n// File/Directory Operations\n// ============================================================================\n\n/**\n * Check if a path exists\n */\nexport async function exists(path: string): Promise<boolean> {\n path = enforcePathBoundary(path);\n try {\n await fsPromises.access(path);\n return true;\n } catch {\n return false;\n }\n}\n\n/**\n * Check if a path exists (sync)\n */\nexport function existsSync(path: string): boolean {\n path = enforcePathBoundary(path);\n return fs.existsSync(path);\n}\n\n/**\n * Check if path is a file\n */\nexport async function isFile(path: string): Promise<boolean> {\n path = enforcePathBoundary(path);\n try {\n const stats = await fsPromises.stat(path);\n return stats.isFile();\n } catch {\n return false;\n }\n}\n\n/**\n * Check if path is a file (sync)\n */\nexport function isFileSync(path: string): boolean {\n path = enforcePathBoundary(path);\n try {\n return fs.statSync(path).isFile();\n } catch {\n return false;\n }\n}\n\n/**\n * Check if path is a directory\n */\nexport async function isDirectory(path: string): Promise<boolean> {\n path = enforcePathBoundary(path);\n try {\n const stats = await fsPromises.stat(path);\n return stats.isDirectory();\n } catch {\n return false;\n }\n}\n\n/**\n * Check if path is a directory (sync)\n */\nexport function isDirectorySync(path: string): boolean {\n path = enforcePathBoundary(path);\n try {\n return fs.statSync(path).isDirectory();\n } catch {\n return false;\n }\n}\n\n/**\n * Get file/directory stats\n */\nexport async function stat(path: string): Promise<FileStats> {\n path = enforcePathBoundary(path);\n const stats = await fsPromises.stat(path);\n return {\n size: stats.size,\n isFile: stats.isFile(),\n isDirectory: stats.isDirectory(),\n isSymlink: stats.isSymbolicLink(),\n createdAt: stats.birthtime,\n modifiedAt: stats.mtime,\n accessedAt: stats.atime,\n mode: stats.mode,\n };\n}\n\n/**\n * Get file/directory stats (sync)\n */\nexport function statSync(path: string): FileStats {\n path = enforcePathBoundary(path);\n const stats = fs.statSync(path);\n return {\n size: stats.size,\n isFile: stats.isFile(),\n isDirectory: stats.isDirectory(),\n isSymlink: stats.isSymbolicLink(),\n createdAt: stats.birthtime,\n modifiedAt: stats.mtime,\n accessedAt: stats.atime,\n mode: stats.mode,\n };\n}\n\n/**\n * Create a directory (and parents if needed)\n */\nexport async function mkdir(path: string, recursive = true): Promise<void> {\n path = enforcePathBoundary(path);\n await fsPromises.mkdir(path, { recursive });\n}\n\n/**\n * Create a directory (sync)\n */\nexport function mkdirSync(path: string, recursive = true): void {\n path = enforcePathBoundary(path);\n fs.mkdirSync(path, { recursive });\n}\n\n/**\n * Ensure a directory exists\n */\nexport async function ensureDir(path: string): Promise<void> {\n if (!(await exists(path))) {\n await mkdir(path, true);\n }\n}\n\n/**\n * Ensure a directory exists (sync)\n */\nexport function ensureDirSync(path: string): void {\n if (!existsSync(path)) {\n mkdirSync(path, true);\n }\n}\n\n/**\n * Ensure a file exists (create empty if not)\n */\nexport async function ensureFile(path: string): Promise<void> {\n path = enforcePathBoundary(path);\n if (!(await exists(path))) {\n await ensureDir(nodePath.dirname(path));\n await writeText(path, '');\n }\n}\n\n/**\n * Ensure a file exists (sync)\n */\nexport function ensureFileSync(path: string): void {\n path = enforcePathBoundary(path);\n if (!existsSync(path)) {\n ensureDirSync(nodePath.dirname(path));\n writeTextSync(path, '');\n }\n}\n\n/**\n * Remove a file or directory\n */\nexport async function remove(path: string, recursive = true): Promise<void> {\n path = enforcePathBoundary(path);\n await fsPromises.rm(path, { recursive, force: true });\n}\n\n/**\n * Remove a file or directory (sync)\n */\nexport function removeSync(path: string, recursive = true): void {\n path = enforcePathBoundary(path);\n fs.rmSync(path, { recursive, force: true });\n}\n\n/**\n * Copy a file or directory\n */\nexport async function copy(src: string, dest: string, options: CopyOptions = {}): Promise<void> {\n src = enforcePathBoundary(src);\n dest = enforcePathBoundary(dest);\n const { overwrite = true, recursive = true, filter } = options;\n\n if (filter && !filter(src)) return;\n\n const srcStat = await stat(src);\n\n if (srcStat.isDirectory) {\n await ensureDir(dest);\n\n if (recursive) {\n const entries = await readDir(src);\n for (const entry of entries) {\n await copy(entry.path, nodePath.join(dest, entry.name), options);\n }\n }\n } else {\n if (!overwrite && (await exists(dest))) {\n return;\n }\n await ensureDir(nodePath.dirname(dest));\n await fsPromises.copyFile(src, dest);\n }\n}\n\n/**\n * Copy a file or directory (sync)\n */\nexport function copySync(src: string, dest: string, options: CopyOptions = {}): void {\n src = enforcePathBoundary(src);\n dest = enforcePathBoundary(dest);\n const { overwrite = true, recursive = true, filter } = options;\n\n if (filter && !filter(src)) return;\n\n const srcStat = statSync(src);\n\n if (srcStat.isDirectory) {\n ensureDirSync(dest);\n\n if (recursive) {\n const entries = readDirSync(src);\n for (const entry of entries) {\n copySync(entry.path, nodePath.join(dest, entry.name), options);\n }\n }\n } else {\n if (!overwrite && existsSync(dest)) {\n return;\n }\n ensureDirSync(nodePath.dirname(dest));\n fs.copyFileSync(src, dest);\n }\n}\n\n/**\n * Move/rename a file or directory\n */\nexport async function move(src: string, dest: string, overwrite = true): Promise<void> {\n src = enforcePathBoundary(src);\n dest = enforcePathBoundary(dest);\n if (!overwrite && (await exists(dest))) {\n throw new Error(`Destination already exists: ${dest}`);\n }\n await ensureDir(nodePath.dirname(dest));\n await fsPromises.rename(src, dest);\n}\n\n/**\n * Move/rename a file or directory (sync)\n */\nexport function moveSync(src: string, dest: string, overwrite = true): void {\n src = enforcePathBoundary(src);\n dest = enforcePathBoundary(dest);\n if (!overwrite && existsSync(dest)) {\n throw new Error(`Destination already exists: ${dest}`);\n }\n ensureDirSync(nodePath.dirname(dest));\n fs.renameSync(src, dest);\n}\n\n// ============================================================================\n// Directory Reading\n// ============================================================================\n\n/**\n * Read directory entries\n */\nexport async function readDir(path: string): Promise<DirEntry[]> {\n path = enforcePathBoundary(path);\n const entries = await fsPromises.readdir(path, { withFileTypes: true });\n return entries.map((entry) => ({\n name: entry.name,\n path: nodePath.join(path, entry.name),\n isFile: entry.isFile(),\n isDirectory: entry.isDirectory(),\n isSymlink: entry.isSymbolicLink(),\n }));\n}\n\n/**\n * Read directory entries (sync)\n */\nexport function readDirSync(path: string): DirEntry[] {\n path = enforcePathBoundary(path);\n const entries = fs.readdirSync(path, { withFileTypes: true });\n return entries.map((entry) => ({\n name: entry.name,\n path: nodePath.join(path, entry.name),\n isFile: entry.isFile(),\n isDirectory: entry.isDirectory(),\n isSymlink: entry.isSymbolicLink(),\n }));\n}\n\n/**\n * List files in a directory (names only)\n */\nexport async function listFiles(path: string): Promise<string[]> {\n const entries = await readDir(path);\n return entries.filter((e) => e.isFile).map((e) => e.name);\n}\n\n/**\n * List files in a directory (sync)\n */\nexport function listFilesSync(path: string): string[] {\n const entries = readDirSync(path);\n return entries.filter((e) => e.isFile).map((e) => e.name);\n}\n\n/**\n * List directories in a directory (names only)\n */\nexport async function listDirs(path: string): Promise<string[]> {\n const entries = await readDir(path);\n return entries.filter((e) => e.isDirectory).map((e) => e.name);\n}\n\n/**\n * List directories in a directory (sync)\n */\nexport function listDirsSync(path: string): string[] {\n const entries = readDirSync(path);\n return entries.filter((e) => e.isDirectory).map((e) => e.name);\n}\n\n/**\n * Walk directory recursively\n */\nexport async function* walk(\n path: string,\n options: { depth?: number; followSymlinks?: boolean } = {}\n): AsyncGenerator<DirEntry> {\n const { depth = Infinity, followSymlinks = false } = options;\n\n async function* walkDir(dir: string, currentDepth: number): AsyncGenerator<DirEntry> {\n if (currentDepth > depth) return;\n\n const entries = await readDir(dir);\n for (const entry of entries) {\n yield entry;\n\n if (entry.isDirectory || (followSymlinks && entry.isSymlink)) {\n yield* walkDir(entry.path, currentDepth + 1);\n }\n }\n }\n\n yield* walkDir(path, 0);\n}\n\n/**\n * Find files matching a glob pattern\n */\nexport async function glob(\n pattern: string,\n options: { cwd?: string; ignore?: string[] } = {}\n): Promise<string[]> {\n const { cwd = process.cwd(), ignore = [] } = options;\n return globAsync(pattern, { cwd, ignore, absolute: true });\n}\n\n/**\n * Find files matching a glob pattern (sync)\n */\nexport function globSync(\n pattern: string,\n options: { cwd?: string; ignore?: string[] } = {}\n): string[] {\n const { cwd = process.cwd(), ignore = [] } = options;\n return globAsync.sync(pattern, { cwd, ignore, absolute: true });\n}\n\n// ============================================================================\n// Temp Files\n// ============================================================================\n\n/**\n * Get the system temp directory\n */\nexport function tempDir(): string {\n return require('os').tmpdir();\n}\n\n/**\n * Create a temporary file\n */\nexport async function createTempFile(\n prefix = 'tmp-',\n suffix = '',\n dir?: string\n): Promise<{ path: string; cleanup: () => Promise<void> }> {\n const tempDirectory = dir || tempDir();\n const filename = `${prefix}${Date.now()}-${Math.random().toString(36).slice(2)}${suffix}`;\n const filePath = nodePath.join(tempDirectory, filename);\n\n await writeText(filePath, '');\n\n return {\n path: filePath,\n cleanup: async () => {\n await remove(filePath);\n },\n };\n}\n\n/**\n * Create a temporary directory\n */\nexport async function createTempDir(\n prefix = 'tmp-'\n): Promise<{ path: string; cleanup: () => Promise<void> }> {\n const tempDirectory = tempDir();\n const dirname = `${prefix}${Date.now()}-${Math.random().toString(36).slice(2)}`;\n const dirPath = nodePath.join(tempDirectory, dirname);\n\n await mkdir(dirPath);\n\n return {\n path: dirPath,\n cleanup: async () => {\n await remove(dirPath, true);\n },\n };\n}\n\n// ============================================================================\n// File Size Utilities\n// ============================================================================\n\n/**\n * Get file size in bytes\n */\nexport async function fileSize(path: string): Promise<number> {\n const stats = await stat(path);\n return stats.size;\n}\n\n/**\n * Get file size in bytes (sync)\n */\nexport function fileSizeSync(path: string): number {\n const stats = statSync(path);\n return stats.size;\n}\n\n/**\n * Get directory size (recursive)\n */\nexport async function dirSize(path: string): Promise<number> {\n let total = 0;\n for await (const entry of walk(path)) {\n if (entry.isFile) {\n total += await fileSize(entry.path);\n }\n }\n return total;\n}\n\n/**\n * Format bytes as human-readable string\n */\nexport function formatSize(bytes: number, decimals = 2): string {\n if (bytes === 0) return '0 B';\n const k = 1024;\n const sizes = ['B', 'KB', 'MB', 'GB', 'TB', 'PB'];\n const i = Math.floor(Math.log(bytes) / Math.log(k));\n return parseFloat((bytes / Math.pow(k, i)).toFixed(decimals)) + ' ' + sizes[i];\n}\n","/**\n * @holoscript/std/fs sandbox boundary enforcement.\n *\n * Closes A-003 R-02 P1 finding (PackagePermissionManifest noted \"NO path\n * boundary enforcement currently\"). Without a boundary, a `.hsplus`\n * scene can call `readText('../../etc/passwd')` and read host files —\n * the vm2 sandbox confines the JS runtime but trusts std/fs as a\n * privileged bridge.\n *\n * Behavior is **opt-in** via env var so this module ships as a no-op\n * for existing call sites and existing tests. The HoloScript runtime\n * loader sets `HOLOSCRIPT_FS_SANDBOX_ROOT` to the project root when\n * loading a `.hsplus`; flipping that switch enables enforcement\n * fleet-wide without further code changes.\n *\n * Two modes:\n * - disabled (env var unset): pass-through, behavior identical to\n * pre-R-02 code. Existing tests remain valid.\n * - enabled (env var set): every path is resolved against the\n * sandbox root; paths that resolve outside it throw `PathBoundaryError`.\n */\n\nimport { resolve, isAbsolute, relative } from 'path';\n\nconst SANDBOX_ROOT_ENV = 'HOLOSCRIPT_FS_SANDBOX_ROOT';\n\nexport class PathBoundaryError extends Error {\n readonly code = 'ERR_PATH_BOUNDARY';\n readonly attemptedPath: string;\n readonly sandboxRoot: string;\n constructor(attemptedPath: string, sandboxRoot: string) {\n super(\n `[@holoscript/std/fs] path \"${attemptedPath}\" resolves outside sandbox root \"${sandboxRoot}\"`\n );\n this.name = 'PathBoundaryError';\n this.attemptedPath = attemptedPath;\n this.sandboxRoot = sandboxRoot;\n }\n}\n\n/**\n * Returns the configured sandbox root, or null if enforcement is disabled.\n * Reads from process.env at every call so the runtime can flip enforcement\n * on/off without rebuilding the std package.\n */\nexport function getSandboxRoot(): string | null {\n const raw = process.env[SANDBOX_ROOT_ENV];\n if (!raw || raw.trim() === '') return null;\n return resolve(raw.trim());\n}\n\n/**\n * Validates a user-supplied path against the sandbox root and returns the\n * resolved absolute path. When enforcement is disabled, returns the path\n * unchanged so call sites compose cleanly with both modes.\n *\n * Throws `PathBoundaryError` when the path resolves outside the sandbox.\n * Symlinks are NOT followed here — that's a layer above this check; we\n * enforce the lexical boundary only. (vm2 + filesystem permissions handle\n * symlink-targeted escapes.)\n */\nexport function enforcePathBoundary(path: string): string {\n const root = getSandboxRoot();\n if (root === null) return path;\n if (typeof path !== 'string') {\n throw new TypeError(`[@holoscript/std/fs] path must be a string, got ${typeof path}`);\n }\n\n // Resolve relative paths against sandbox root, not the current working\n // directory. This is the critical difference: a `.hsplus` scene shouldn't\n // be able to control which directory relative paths are interpreted from.\n const absolute = isAbsolute(path) ? resolve(path) : resolve(root, path);\n\n // Lexical containment check via `relative()`. If the relative path starts\n // with `..` the target is outside the root.\n const rel = relative(root, absolute);\n if (rel === '' || (!rel.startsWith('..') && !isAbsolute(rel))) {\n return absolute;\n }\n throw new PathBoundaryError(path, root);\n}\n\n/**\n * Convenience for two-path APIs (copy, move, rename).\n */\nexport function enforcePathBoundaryPair(src: string, dest: string): [string, string] {\n return [enforcePathBoundary(src), enforcePathBoundary(dest)];\n}\n","/**\n * @holoscript/fs - Path Module\n *\n * Cross-platform path manipulation utilities for HoloScript Plus.\n */\n\nimport * as nodePath from 'path';\n\n/**\n * Path separator for the current platform\n */\nexport const sep = nodePath.sep;\n\n/**\n * Path delimiter for environment variables\n */\nexport const delimiter = nodePath.delimiter;\n\n/**\n * Join path segments\n */\nexport function join(...paths: string[]): string {\n return nodePath.join(...paths);\n}\n\n/**\n * Resolve path segments to an absolute path\n */\nexport function resolve(...paths: string[]): string {\n return nodePath.resolve(...paths);\n}\n\n/**\n * Get the relative path from one path to another\n */\nexport function relative(from: string, to: string): string {\n return nodePath.relative(from, to);\n}\n\n/**\n * Normalize a path (resolve . and .. segments)\n */\nexport function normalize(p: string): string {\n return nodePath.normalize(p);\n}\n\n/**\n * Check if a path is absolute\n */\nexport function isAbsolute(p: string): boolean {\n return nodePath.isAbsolute(p);\n}\n\n/**\n * Get the directory name of a path\n */\nexport function dirname(p: string): string {\n return nodePath.dirname(p);\n}\n\n/**\n * Get the base name of a path\n */\nexport function basename(p: string, ext?: string): string {\n return nodePath.basename(p, ext);\n}\n\n/**\n * Get the extension of a path\n */\nexport function extname(p: string): string {\n return nodePath.extname(p);\n}\n\n/**\n * Parse a path into components\n */\nexport interface ParsedPath {\n root: string;\n dir: string;\n base: string;\n ext: string;\n name: string;\n}\n\nexport function parse(p: string): ParsedPath {\n return nodePath.parse(p);\n}\n\n/**\n * Format a parsed path back into a string\n */\nexport function format(pathObject: Partial<ParsedPath>): string {\n return nodePath.format(pathObject);\n}\n\n/**\n * Convert path to POSIX format (forward slashes)\n */\nexport function toPosix(p: string): string {\n return p.replace(/\\\\/g, '/');\n}\n\n/**\n * Convert path to Windows format (backslashes)\n */\nexport function toWindows(p: string): string {\n return p.replace(/\\//g, '\\\\');\n}\n\n/**\n * Get the parent directory\n */\nexport function parent(p: string): string {\n return dirname(p);\n}\n\n/**\n * Get path segments as an array\n */\nexport function segments(p: string): string[] {\n const normalized = normalize(p);\n return normalized.split(sep).filter((s) => s.length > 0);\n}\n\n/**\n * Check if a path has a specific extension\n */\nexport function hasExtension(p: string, ext: string): boolean {\n const pathExt = extname(p).toLowerCase();\n const checkExt = ext.startsWith('.') ? ext.toLowerCase() : `.${ext.toLowerCase()}`;\n return pathExt === checkExt;\n}\n\n/**\n * Change the extension of a path\n */\nexport function changeExtension(p: string, newExt: string): string {\n const parsed = parse(p);\n const ext = newExt.startsWith('.') ? newExt : `.${newExt}`;\n return join(parsed.dir, `${parsed.name}${ext}`);\n}\n\n/**\n * Remove the extension from a path\n */\nexport function removeExtension(p: string): string {\n const parsed = parse(p);\n return join(parsed.dir, parsed.name);\n}\n\n/**\n * Add a suffix before the extension\n */\nexport function addSuffix(p: string, suffix: string): string {\n const parsed = parse(p);\n return join(parsed.dir, `${parsed.name}${suffix}${parsed.ext}`);\n}\n\n/**\n * Check if a path is a child of another path\n */\nexport function isChildOf(child: string, parent: string): boolean {\n const childResolved = resolve(child);\n const parentResolved = resolve(parent);\n const rel = relative(parentResolved, childResolved);\n return !rel.startsWith('..') && !isAbsolute(rel);\n}\n\n/**\n * Get the common base path of multiple paths\n */\nexport function commonBase(...paths: string[]): string {\n if (paths.length === 0) return '';\n if (paths.length === 1) return dirname(paths[0]);\n\n const resolvedPaths = paths.map((p) => resolve(p));\n const segmentsList = resolvedPaths.map((p) => segments(p));\n const minLength = Math.min(...segmentsList.map((s) => s.length));\n\n const common: string[] = [];\n for (let i = 0; i < minLength; i++) {\n const segment = segmentsList[0][i];\n if (segmentsList.every((s) => s[i] === segment)) {\n common.push(segment);\n } else {\n break;\n }\n }\n\n if (common.length === 0) return '';\n\n // Handle root on Unix vs Windows\n if (resolvedPaths[0].startsWith('/')) {\n return '/' + common.join('/');\n }\n\n return common.join(sep);\n}\n\n/**\n * Expand tilde (~) to home directory\n */\nexport function expandHome(p: string): string {\n if (p.startsWith('~')) {\n const home = process.env.HOME || process.env.USERPROFILE || '';\n return join(home, p.slice(1));\n }\n return p;\n}\n\n/**\n * Make a path safe for use as a filename\n */\nexport function sanitize(filename: string): string {\n return filename\n .replace(/[<>:\"/\\\\|?*\\x00-\\x1F]/g, '_')\n .replace(/^\\.+/, '_')\n .replace(/\\.+$/, '_')\n .slice(0, 255);\n}\n\n/**\n * Check if a filename matches a glob pattern\n */\nexport function matchesPattern(filename: string, pattern: string): boolean {\n const regexPattern = pattern\n .replace(/[.+^${}()|[\\]\\\\]/g, '\\\\$&')\n .replace(/\\*/g, '.*')\n .replace(/\\?/g, '.');\n return new RegExp(`^${regexPattern}$`).test(filename);\n}\n\n/**\n * Path builder for fluent API\n */\nexport class PathBuilder {\n private path: string;\n\n constructor(base: string = process.cwd()) {\n this.path = resolve(base);\n }\n\n static from(base: string): PathBuilder {\n return new PathBuilder(base);\n }\n\n static cwd(): PathBuilder {\n return new PathBuilder(process.cwd());\n }\n\n join(...segments: string[]): PathBuilder {\n this.path = join(this.path, ...segments);\n return this;\n }\n\n parent(): PathBuilder {\n this.path = dirname(this.path);\n return this;\n }\n\n sibling(name: string): PathBuilder {\n this.path = join(dirname(this.path), name);\n return this;\n }\n\n withExtension(ext: string): PathBuilder {\n this.path = changeExtension(this.path, ext);\n return this;\n }\n\n withSuffix(suffix: string): PathBuilder {\n this.path = addSuffix(this.path, suffix);\n return this;\n }\n\n normalize(): PathBuilder {\n this.path = normalize(this.path);\n return this;\n }\n\n toString(): string {\n return this.path;\n }\n\n get value(): string {\n return this.path;\n }\n\n get dirname(): string {\n return dirname(this.path);\n }\n\n get basename(): string {\n return basename(this.path);\n }\n\n get extname(): string {\n return extname(this.path);\n }\n\n get name(): string {\n return parse(this.path).name;\n }\n}\n\n// Convenience function\nexport function path(base?: string): PathBuilder {\n return new PathBuilder(base);\n}\n","/**\n * @holoscript/fs - File Watch Module\n *\n * File and directory watching utilities for HoloScript Plus programs.\n */\n\nimport chokidar, { type FSWatcher, type WatchOptions as ChokidarOptions } from 'chokidar';\nimport { EventEmitter } from 'events';\n\n/**\n * Watch event types\n */\nexport type WatchEventType =\n | 'add'\n | 'change'\n | 'unlink'\n | 'addDir'\n | 'unlinkDir'\n | 'error'\n | 'ready';\n\n/**\n * Watch event\n */\nexport interface WatchEvent {\n type: WatchEventType;\n path: string;\n stats?: {\n size: number;\n mtime: Date;\n };\n}\n\n/**\n * Watch options\n */\nexport interface WatchOptions {\n /** Glob patterns to ignore */\n ignored?: string | string[];\n /** Use polling instead of native events */\n usePolling?: boolean;\n /** Polling interval in ms */\n interval?: number;\n /** Emit events for initial files */\n emitInitial?: boolean;\n /** Follow symlinks */\n followSymlinks?: boolean;\n /** Watch depth */\n depth?: number;\n /** Persistent watch */\n persistent?: boolean;\n /** Debounce delay in ms */\n debounce?: number;\n}\n\n/**\n * Watch callback\n */\nexport type WatchCallback = (event: WatchEvent) => void | Promise<void>;\n\n/**\n * File watcher class\n */\nexport class FileWatcher extends EventEmitter {\n private watcher: FSWatcher | null = null;\n private paths: string[];\n private options: WatchOptions;\n private debounceTimers: Map<string, NodeJS.Timeout> = new Map();\n\n constructor(paths: string | string[], options: WatchOptions = {}) {\n super();\n this.paths = Array.isArray(paths) ? paths : [paths];\n this.options = {\n ignored: options.ignored || ['**/node_modules/**', '**/.git/**'],\n usePolling: options.usePolling || false,\n interval: options.interval || 100,\n emitInitial: options.emitInitial ?? true,\n followSymlinks: options.followSymlinks ?? true,\n depth: options.depth,\n persistent: options.persistent ?? true,\n debounce: options.debounce || 0,\n };\n }\n\n /**\n * Start watching\n */\n start(): this {\n if (this.watcher) {\n return this;\n }\n\n const chokidarOpts: ChokidarOptions = {\n ignored: this.options.ignored,\n persistent: this.options.persistent,\n followSymlinks: this.options.followSymlinks,\n depth: this.options.depth,\n usePolling: this.options.usePolling,\n interval: this.options.interval,\n ignoreInitial: !this.options.emitInitial,\n };\n\n this.watcher = chokidar.watch(this.paths, chokidarOpts);\n\n this.watcher.on('add', (path, stats) => this.handleEvent('add', path, stats));\n this.watcher.on('change', (path, stats) => this.handleEvent('change', path, stats));\n this.watcher.on('unlink', (path) => this.handleEvent('unlink', path));\n this.watcher.on('addDir', (path, stats) => this.handleEvent('addDir', path, stats));\n this.watcher.on('unlinkDir', (path) => this.handleEvent('unlinkDir', path));\n this.watcher.on('error', (error) => this.emit('error', error));\n this.watcher.on('ready', () => this.emit('ready'));\n\n return this;\n }\n\n /**\n * Stop watching\n */\n async stop(): Promise<void> {\n if (this.watcher) {\n await this.watcher.close();\n this.watcher = null;\n }\n\n for (const timer of this.debounceTimers.values()) {\n clearTimeout(timer);\n }\n this.debounceTimers.clear();\n }\n\n /**\n * Add paths to watch\n */\n add(paths: string | string[]): this {\n const pathsArray = Array.isArray(paths) ? paths : [paths];\n this.paths.push(...pathsArray);\n this.watcher?.add(pathsArray);\n return this;\n }\n\n /**\n * Remove paths from watch\n */\n unwatch(paths: string | string[]): this {\n const pathsArray = Array.isArray(paths) ? paths : [paths];\n this.paths = this.paths.filter((p) => !pathsArray.includes(p));\n this.watcher?.unwatch(pathsArray);\n return this;\n }\n\n /**\n * Get watched paths\n */\n getWatched(): Record<string, string[]> {\n return this.watcher?.getWatched() || {};\n }\n\n /**\n * Check if watcher is ready\n */\n get isReady(): boolean {\n return this.watcher !== null;\n }\n\n /**\n * Register event handler\n */\n on(\n event: 'add' | 'change' | 'unlink' | 'addDir' | 'unlinkDir' | 'all',\n listener: (event: WatchEvent) => void\n ): this;\n on(event: 'error', listener: (error: Error) => void): this;\n on(event: 'ready', listener: () => void): this;\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n on(event: string, listener: (...args: any[]) => void): this {\n return super.on(event, listener);\n }\n\n private handleEvent(\n type: WatchEventType,\n path: string,\n stats?: { size: number; mtime: Date }\n ): void {\n const event: WatchEvent = {\n type,\n path,\n stats: stats\n ? {\n size: stats.size,\n mtime: stats.mtime,\n }\n : undefined,\n };\n\n if (this.options.debounce && this.options.debounce > 0) {\n // Debounce the event\n if (this.debounceTimers.has(path)) {\n clearTimeout(this.debounceTimers.get(path));\n }\n\n this.debounceTimers.set(\n path,\n setTimeout(() => {\n this.debounceTimers.delete(path);\n this.emitEvent(event);\n }, this.options.debounce)\n );\n } else {\n this.emitEvent(event);\n }\n }\n\n private emitEvent(event: WatchEvent): void {\n this.emit(event.type, event);\n this.emit('all', event);\n }\n}\n\n/**\n * Watch files/directories\n */\nexport function watch(paths: string | string[], options?: WatchOptions): FileWatcher {\n return new FileWatcher(paths, options).start();\n}\n\n/**\n * Watch and run callback on changes\n */\nexport function watchCallback(\n paths: string | string[],\n callback: WatchCallback,\n options?: WatchOptions\n): FileWatcher {\n const watcher = watch(paths, options);\n\n watcher.on('all', async (event) => {\n try {\n await callback(event);\n } catch (error) {\n watcher.emit('error', error);\n }\n });\n\n return watcher;\n}\n\n/**\n * Watch for specific file types\n */\nexport function watchFileTypes(\n dir: string,\n extensions: string[],\n callback: WatchCallback,\n options?: WatchOptions\n): FileWatcher {\n const patterns = extensions.map((ext) => {\n const e = ext.startsWith('.') ? ext : `.${ext}`;\n return `${dir}/**/*${e}`;\n });\n\n return watchCallback(patterns, callback, options);\n}\n\n/**\n * Watch a single file\n */\nexport function watchFile(\n path: string,\n callback: WatchCallback,\n options?: WatchOptions\n): FileWatcher {\n return watchCallback(path, callback, { ...options, depth: 0 });\n}\n\n/**\n * Watch and debounce - only emit after changes have stopped for a duration\n */\nexport function watchDebounced(\n paths: string | string[],\n callback: WatchCallback,\n debounceMs = 300,\n options?: WatchOptions\n): FileWatcher {\n return watchCallback(paths, callback, { ...options, debounce: debounceMs });\n}\n\n/**\n * One-shot watch - stop after first event\n */\nexport async function watchOnce(\n paths: string | string[],\n options?: WatchOptions\n): Promise<WatchEvent> {\n return new Promise((resolve, reject) => {\n const watcher = watch(paths, { ...options, emitInitial: false });\n\n const cleanup = async () => {\n await watcher.stop();\n };\n\n watcher.on('all', async (event) => {\n await cleanup();\n resolve(event);\n });\n\n watcher.on('error', async (error) => {\n await cleanup();\n reject(error);\n });\n });\n}\n\n/**\n * Watch with batching - collect events and emit in batches\n */\nexport function watchBatched(\n paths: string | string[],\n callback: (events: WatchEvent[]) => void | Promise<void>,\n batchMs = 100,\n options?: WatchOptions\n): FileWatcher {\n const watcher = watch(paths, options);\n let batch: WatchEvent[] = [];\n let timer: NodeJS.Timeout | null = null;\n\n const flush = async () => {\n if (batch.length > 0) {\n const events = [...batch];\n batch = [];\n try {\n await callback(events);\n } catch (error) {\n watcher.emit('error', error);\n }\n }\n };\n\n watcher.on('all', (event) => {\n batch.push(event);\n\n if (timer) {\n clearTimeout(timer);\n }\n\n timer = setTimeout(flush, batchMs);\n });\n\n // Extend stop to flush remaining\n const originalStop = watcher.stop.bind(watcher);\n watcher.stop = async () => {\n if (timer) {\n clearTimeout(timer);\n }\n await flush();\n await originalStop();\n };\n\n return watcher;\n}\n\n/**\n * Watch with filtering\n */\nexport function watchFiltered(\n paths: string | string[],\n filter: (event: WatchEvent) => boolean,\n callback: WatchCallback,\n options?: WatchOptions\n): FileWatcher {\n return watchCallback(\n paths,\n async (event) => {\n if (filter(event)) {\n await callback(event);\n }\n },\n options\n );\n}\n\n/**\n * Watch only for specific event types\n */\nexport function watchEvents(\n paths: string | string[],\n eventTypes: WatchEventType[],\n callback: WatchCallback,\n options?: WatchOptions\n): FileWatcher {\n return watchFiltered(paths, (event) => eventTypes.includes(event.type), callback, options);\n}\n\n/**\n * Watch only for file changes (add, change, unlink)\n */\nexport function watchFiles(\n paths: string | string[],\n callback: WatchCallback,\n options?: WatchOptions\n): FileWatcher {\n return watchEvents(paths, ['add', 'change', 'unlink'], callback, options);\n}\n\n/**\n * Watch only for directory changes\n */\nexport function watchDirs(\n paths: string | string[],\n callback: WatchCallback,\n options?: WatchOptions\n): FileWatcher {\n return watchEvents(paths, ['addDir', 'unlinkDir'], callback, options);\n}\n","/**\n * @holoscript/fs - File System Library for HoloScript Plus\n *\n * Provides file I/O, directory operations, path manipulation,\n * and file watching for HoloScript Plus programs.\n *\n * @example\n * ```hsplus\n * import { readText, writeText, watch } from \"@holoscript/fs\";\n * import { join } from \"@holoscript/fs/path\";\n *\n * async fn main() {\n * // Read a config file\n * let config = await readJson(\"config.json\");\n *\n * // Watch for changes\n * let watcher = watch(\"./src\", { debounce: 100 });\n * watcher.on(\"change\", fn(event) {\n * print(\"File changed:\", event.path);\n * });\n * }\n * ```\n */\n\n// File operations\nexport {\n // Types\n type Encoding,\n type FileStats,\n type DirEntry,\n type ReadOptions,\n type WriteOptions,\n type CopyOptions,\n\n // Reading\n readText,\n readTextSync,\n readBytes,\n readBytesSync,\n readJson,\n readJsonSync,\n readLines,\n readLinesSync,\n\n // Writing\n writeText,\n writeTextSync,\n writeBytes,\n writeBytesSync,\n writeJson,\n writeJsonSync,\n appendText,\n appendTextSync,\n appendLine,\n appendLineSync,\n\n // File/Directory operations\n exists,\n existsSync,\n isFile,\n isFileSync,\n isDirectory,\n isDirectorySync,\n stat,\n statSync,\n mkdir,\n mkdirSync,\n ensureDir,\n ensureDirSync,\n ensureFile,\n ensureFileSync,\n remove,\n removeSync,\n copy,\n copySync,\n move,\n moveSync,\n\n // Directory reading\n readDir,\n readDirSync,\n listFiles,\n listFilesSync,\n listDirs,\n listDirsSync,\n walk,\n glob,\n globSync,\n\n // Temp files\n tempDir,\n createTempFile,\n createTempDir,\n\n // Size utilities\n fileSize,\n fileSizeSync,\n dirSize,\n formatSize,\n} from './fs.js';\n\n// Path utilities\nexport {\n sep,\n delimiter,\n join,\n resolve,\n relative,\n normalize,\n isAbsolute,\n dirname,\n basename,\n extname,\n type ParsedPath,\n parse,\n format,\n toPosix,\n toWindows,\n parent,\n segments,\n hasExtension,\n changeExtension,\n removeExtension,\n addSuffix,\n isChildOf,\n commonBase,\n expandHome,\n sanitize,\n matchesPattern,\n PathBuilder,\n path,\n} from './path.js';\n\n// Watch utilities\nexport {\n type WatchEventType,\n type WatchEvent,\n type WatchOptions,\n type WatchCallback,\n FileWatcher,\n watch,\n watchCallback,\n watchFileTypes,\n watchFile,\n watchDebounced,\n watchOnce,\n watchBatched,\n watchFiltered,\n watchEvents,\n watchFiles,\n watchDirs,\n} from './watch.js';\n\n/**\n * Convenience: Get current working directory\n */\nexport function cwd(): string {\n return process.cwd();\n}\n\n/**\n * Convenience: Change current working directory\n */\nexport function chdir(path: string): void {\n process.chdir(path);\n}\n\n/**\n * Convenience: Get home directory\n */\nexport function homeDir(): string {\n return require('os').homedir();\n}\n\n/**\n * Convenience: Check if running on Windows\n */\nexport function isWindows(): boolean {\n return process.platform === 'win32';\n}\n\n/**\n * Convenience: Check if running on macOS\n */\nexport function isMacOS(): boolean {\n return process.platform === 'darwin';\n}\n\n/**\n * Convenience: Check if running on Linux\n */\nexport function isLinux(): boolean {\n return process.platform === 'linux';\n}\n"],"mappings":"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","names":["path","path","existsSync","stat","statSync","mkdir","mkdirSync","cwd","dirname","nodePath","sep","delimiter","join","resolve","relative","normalize","isAbsolute","dirname","basename","extname","parse","format","parent","segments","path","resolve","path"]}
|
|
@@ -0,0 +1,135 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @holoscript/fs - Path Module
|
|
3
|
+
*
|
|
4
|
+
* Cross-platform path manipulation utilities for HoloScript Plus.
|
|
5
|
+
*/
|
|
6
|
+
/**
|
|
7
|
+
* Path separator for the current platform
|
|
8
|
+
*/
|
|
9
|
+
export declare const sep: "/" | "\\";
|
|
10
|
+
/**
|
|
11
|
+
* Path delimiter for environment variables
|
|
12
|
+
*/
|
|
13
|
+
export declare const delimiter: ";" | ":";
|
|
14
|
+
/**
|
|
15
|
+
* Join path segments
|
|
16
|
+
*/
|
|
17
|
+
export declare function join(...paths: string[]): string;
|
|
18
|
+
/**
|
|
19
|
+
* Resolve path segments to an absolute path
|
|
20
|
+
*/
|
|
21
|
+
export declare function resolve(...paths: string[]): string;
|
|
22
|
+
/**
|
|
23
|
+
* Get the relative path from one path to another
|
|
24
|
+
*/
|
|
25
|
+
export declare function relative(from: string, to: string): string;
|
|
26
|
+
/**
|
|
27
|
+
* Normalize a path (resolve . and .. segments)
|
|
28
|
+
*/
|
|
29
|
+
export declare function normalize(p: string): string;
|
|
30
|
+
/**
|
|
31
|
+
* Check if a path is absolute
|
|
32
|
+
*/
|
|
33
|
+
export declare function isAbsolute(p: string): boolean;
|
|
34
|
+
/**
|
|
35
|
+
* Get the directory name of a path
|
|
36
|
+
*/
|
|
37
|
+
export declare function dirname(p: string): string;
|
|
38
|
+
/**
|
|
39
|
+
* Get the base name of a path
|
|
40
|
+
*/
|
|
41
|
+
export declare function basename(p: string, ext?: string): string;
|
|
42
|
+
/**
|
|
43
|
+
* Get the extension of a path
|
|
44
|
+
*/
|
|
45
|
+
export declare function extname(p: string): string;
|
|
46
|
+
/**
|
|
47
|
+
* Parse a path into components
|
|
48
|
+
*/
|
|
49
|
+
export interface ParsedPath {
|
|
50
|
+
root: string;
|
|
51
|
+
dir: string;
|
|
52
|
+
base: string;
|
|
53
|
+
ext: string;
|
|
54
|
+
name: string;
|
|
55
|
+
}
|
|
56
|
+
export declare function parse(p: string): ParsedPath;
|
|
57
|
+
/**
|
|
58
|
+
* Format a parsed path back into a string
|
|
59
|
+
*/
|
|
60
|
+
export declare function format(pathObject: Partial<ParsedPath>): string;
|
|
61
|
+
/**
|
|
62
|
+
* Convert path to POSIX format (forward slashes)
|
|
63
|
+
*/
|
|
64
|
+
export declare function toPosix(p: string): string;
|
|
65
|
+
/**
|
|
66
|
+
* Convert path to Windows format (backslashes)
|
|
67
|
+
*/
|
|
68
|
+
export declare function toWindows(p: string): string;
|
|
69
|
+
/**
|
|
70
|
+
* Get the parent directory
|
|
71
|
+
*/
|
|
72
|
+
export declare function parent(p: string): string;
|
|
73
|
+
/**
|
|
74
|
+
* Get path segments as an array
|
|
75
|
+
*/
|
|
76
|
+
export declare function segments(p: string): string[];
|
|
77
|
+
/**
|
|
78
|
+
* Check if a path has a specific extension
|
|
79
|
+
*/
|
|
80
|
+
export declare function hasExtension(p: string, ext: string): boolean;
|
|
81
|
+
/**
|
|
82
|
+
* Change the extension of a path
|
|
83
|
+
*/
|
|
84
|
+
export declare function changeExtension(p: string, newExt: string): string;
|
|
85
|
+
/**
|
|
86
|
+
* Remove the extension from a path
|
|
87
|
+
*/
|
|
88
|
+
export declare function removeExtension(p: string): string;
|
|
89
|
+
/**
|
|
90
|
+
* Add a suffix before the extension
|
|
91
|
+
*/
|
|
92
|
+
export declare function addSuffix(p: string, suffix: string): string;
|
|
93
|
+
/**
|
|
94
|
+
* Check if a path is a child of another path
|
|
95
|
+
*/
|
|
96
|
+
export declare function isChildOf(child: string, parent: string): boolean;
|
|
97
|
+
/**
|
|
98
|
+
* Get the common base path of multiple paths
|
|
99
|
+
*/
|
|
100
|
+
export declare function commonBase(...paths: string[]): string;
|
|
101
|
+
/**
|
|
102
|
+
* Expand tilde (~) to home directory
|
|
103
|
+
*/
|
|
104
|
+
export declare function expandHome(p: string): string;
|
|
105
|
+
/**
|
|
106
|
+
* Make a path safe for use as a filename
|
|
107
|
+
*/
|
|
108
|
+
export declare function sanitize(filename: string): string;
|
|
109
|
+
/**
|
|
110
|
+
* Check if a filename matches a glob pattern
|
|
111
|
+
*/
|
|
112
|
+
export declare function matchesPattern(filename: string, pattern: string): boolean;
|
|
113
|
+
/**
|
|
114
|
+
* Path builder for fluent API
|
|
115
|
+
*/
|
|
116
|
+
export declare class PathBuilder {
|
|
117
|
+
private path;
|
|
118
|
+
constructor(base?: string);
|
|
119
|
+
static from(base: string): PathBuilder;
|
|
120
|
+
static cwd(): PathBuilder;
|
|
121
|
+
join(...segments: string[]): PathBuilder;
|
|
122
|
+
parent(): PathBuilder;
|
|
123
|
+
sibling(name: string): PathBuilder;
|
|
124
|
+
withExtension(ext: string): PathBuilder;
|
|
125
|
+
withSuffix(suffix: string): PathBuilder;
|
|
126
|
+
normalize(): PathBuilder;
|
|
127
|
+
toString(): string;
|
|
128
|
+
get value(): string;
|
|
129
|
+
get dirname(): string;
|
|
130
|
+
get basename(): string;
|
|
131
|
+
get extname(): string;
|
|
132
|
+
get name(): string;
|
|
133
|
+
}
|
|
134
|
+
export declare function path(base?: string): PathBuilder;
|
|
135
|
+
//# sourceMappingURL=path.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"path.d.ts","sourceRoot":"","sources":["../../src/fs/path.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @holoscript/std/fs sandbox boundary enforcement.
|
|
3
|
+
*
|
|
4
|
+
* Closes A-003 R-02 P1 finding (PackagePermissionManifest noted "NO path
|
|
5
|
+
* boundary enforcement currently"). Without a boundary, a `.hsplus`
|
|
6
|
+
* scene can call `readText('../../etc/passwd')` and read host files —
|
|
7
|
+
* the vm2 sandbox confines the JS runtime but trusts std/fs as a
|
|
8
|
+
* privileged bridge.
|
|
9
|
+
*
|
|
10
|
+
* Behavior is **opt-in** via env var so this module ships as a no-op
|
|
11
|
+
* for existing call sites and existing tests. The HoloScript runtime
|
|
12
|
+
* loader sets `HOLOSCRIPT_FS_SANDBOX_ROOT` to the project root when
|
|
13
|
+
* loading a `.hsplus`; flipping that switch enables enforcement
|
|
14
|
+
* fleet-wide without further code changes.
|
|
15
|
+
*
|
|
16
|
+
* Two modes:
|
|
17
|
+
* - disabled (env var unset): pass-through, behavior identical to
|
|
18
|
+
* pre-R-02 code. Existing tests remain valid.
|
|
19
|
+
* - enabled (env var set): every path is resolved against the
|
|
20
|
+
* sandbox root; paths that resolve outside it throw `PathBoundaryError`.
|
|
21
|
+
*/
|
|
22
|
+
export declare class PathBoundaryError extends Error {
|
|
23
|
+
readonly code = "ERR_PATH_BOUNDARY";
|
|
24
|
+
readonly attemptedPath: string;
|
|
25
|
+
readonly sandboxRoot: string;
|
|
26
|
+
constructor(attemptedPath: string, sandboxRoot: string);
|
|
27
|
+
}
|
|
28
|
+
/**
|
|
29
|
+
* Returns the configured sandbox root, or null if enforcement is disabled.
|
|
30
|
+
* Reads from process.env at every call so the runtime can flip enforcement
|
|
31
|
+
* on/off without rebuilding the std package.
|
|
32
|
+
*/
|
|
33
|
+
export declare function getSandboxRoot(): string | null;
|
|
34
|
+
/**
|
|
35
|
+
* Validates a user-supplied path against the sandbox root and returns the
|
|
36
|
+
* resolved absolute path. When enforcement is disabled, returns the path
|
|
37
|
+
* unchanged so call sites compose cleanly with both modes.
|
|
38
|
+
*
|
|
39
|
+
* Throws `PathBoundaryError` when the path resolves outside the sandbox.
|
|
40
|
+
* Symlinks are NOT followed here — that's a layer above this check; we
|
|
41
|
+
* enforce the lexical boundary only. (vm2 + filesystem permissions handle
|
|
42
|
+
* symlink-targeted escapes.)
|
|
43
|
+
*/
|
|
44
|
+
export declare function enforcePathBoundary(path: string): string;
|
|
45
|
+
/**
|
|
46
|
+
* Convenience for two-path APIs (copy, move, rename).
|
|
47
|
+
*/
|
|
48
|
+
export declare function enforcePathBoundaryPair(src: string, dest: string): [string, string];
|
|
49
|
+
//# sourceMappingURL=sandbox.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"sandbox.d.ts","sourceRoot":"","sources":["../../src/fs/sandbox.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;GAoBG;AAMH,qBAAa,iBAAkB,SAAQ,KAAK;IAC1C,QAAQ,CAAC,IAAI,uBAAuB;IACpC,QAAQ,CAAC,aAAa,EAAE,MAAM,CAAC;IAC/B,QAAQ,CAAC,WAAW,EAAE,MAAM,CAAC;gBACjB,aAAa,EAAE,MAAM,EAAE,WAAW,EAAE,MAAM;CAQvD;AAED;;;;GAIG;AACH,wBAAgB,cAAc,IAAI,MAAM,GAAG,IAAI,CAI9C;AAED;;;;;;;;;GASG;AACH,wBAAgB,mBAAmB,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAmBxD;AAED;;GAEG;AACH,wBAAgB,uBAAuB,CAAC,GAAG,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,CAAC,MAAM,EAAE,MAAM,CAAC,CAEnF"}
|
|
@@ -0,0 +1,133 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @holoscript/fs - File Watch Module
|
|
3
|
+
*
|
|
4
|
+
* File and directory watching utilities for HoloScript Plus programs.
|
|
5
|
+
*/
|
|
6
|
+
import { EventEmitter } from 'events';
|
|
7
|
+
/**
|
|
8
|
+
* Watch event types
|
|
9
|
+
*/
|
|
10
|
+
export type WatchEventType = 'add' | 'change' | 'unlink' | 'addDir' | 'unlinkDir' | 'error' | 'ready';
|
|
11
|
+
/**
|
|
12
|
+
* Watch event
|
|
13
|
+
*/
|
|
14
|
+
export interface WatchEvent {
|
|
15
|
+
type: WatchEventType;
|
|
16
|
+
path: string;
|
|
17
|
+
stats?: {
|
|
18
|
+
size: number;
|
|
19
|
+
mtime: Date;
|
|
20
|
+
};
|
|
21
|
+
}
|
|
22
|
+
/**
|
|
23
|
+
* Watch options
|
|
24
|
+
*/
|
|
25
|
+
export interface WatchOptions {
|
|
26
|
+
/** Glob patterns to ignore */
|
|
27
|
+
ignored?: string | string[];
|
|
28
|
+
/** Use polling instead of native events */
|
|
29
|
+
usePolling?: boolean;
|
|
30
|
+
/** Polling interval in ms */
|
|
31
|
+
interval?: number;
|
|
32
|
+
/** Emit events for initial files */
|
|
33
|
+
emitInitial?: boolean;
|
|
34
|
+
/** Follow symlinks */
|
|
35
|
+
followSymlinks?: boolean;
|
|
36
|
+
/** Watch depth */
|
|
37
|
+
depth?: number;
|
|
38
|
+
/** Persistent watch */
|
|
39
|
+
persistent?: boolean;
|
|
40
|
+
/** Debounce delay in ms */
|
|
41
|
+
debounce?: number;
|
|
42
|
+
}
|
|
43
|
+
/**
|
|
44
|
+
* Watch callback
|
|
45
|
+
*/
|
|
46
|
+
export type WatchCallback = (event: WatchEvent) => void | Promise<void>;
|
|
47
|
+
/**
|
|
48
|
+
* File watcher class
|
|
49
|
+
*/
|
|
50
|
+
export declare class FileWatcher extends EventEmitter {
|
|
51
|
+
private watcher;
|
|
52
|
+
private paths;
|
|
53
|
+
private options;
|
|
54
|
+
private debounceTimers;
|
|
55
|
+
constructor(paths: string | string[], options?: WatchOptions);
|
|
56
|
+
/**
|
|
57
|
+
* Start watching
|
|
58
|
+
*/
|
|
59
|
+
start(): this;
|
|
60
|
+
/**
|
|
61
|
+
* Stop watching
|
|
62
|
+
*/
|
|
63
|
+
stop(): Promise<void>;
|
|
64
|
+
/**
|
|
65
|
+
* Add paths to watch
|
|
66
|
+
*/
|
|
67
|
+
add(paths: string | string[]): this;
|
|
68
|
+
/**
|
|
69
|
+
* Remove paths from watch
|
|
70
|
+
*/
|
|
71
|
+
unwatch(paths: string | string[]): this;
|
|
72
|
+
/**
|
|
73
|
+
* Get watched paths
|
|
74
|
+
*/
|
|
75
|
+
getWatched(): Record<string, string[]>;
|
|
76
|
+
/**
|
|
77
|
+
* Check if watcher is ready
|
|
78
|
+
*/
|
|
79
|
+
get isReady(): boolean;
|
|
80
|
+
/**
|
|
81
|
+
* Register event handler
|
|
82
|
+
*/
|
|
83
|
+
on(event: 'add' | 'change' | 'unlink' | 'addDir' | 'unlinkDir' | 'all', listener: (event: WatchEvent) => void): this;
|
|
84
|
+
on(event: 'error', listener: (error: Error) => void): this;
|
|
85
|
+
on(event: 'ready', listener: () => void): this;
|
|
86
|
+
private handleEvent;
|
|
87
|
+
private emitEvent;
|
|
88
|
+
}
|
|
89
|
+
/**
|
|
90
|
+
* Watch files/directories
|
|
91
|
+
*/
|
|
92
|
+
export declare function watch(paths: string | string[], options?: WatchOptions): FileWatcher;
|
|
93
|
+
/**
|
|
94
|
+
* Watch and run callback on changes
|
|
95
|
+
*/
|
|
96
|
+
export declare function watchCallback(paths: string | string[], callback: WatchCallback, options?: WatchOptions): FileWatcher;
|
|
97
|
+
/**
|
|
98
|
+
* Watch for specific file types
|
|
99
|
+
*/
|
|
100
|
+
export declare function watchFileTypes(dir: string, extensions: string[], callback: WatchCallback, options?: WatchOptions): FileWatcher;
|
|
101
|
+
/**
|
|
102
|
+
* Watch a single file
|
|
103
|
+
*/
|
|
104
|
+
export declare function watchFile(path: string, callback: WatchCallback, options?: WatchOptions): FileWatcher;
|
|
105
|
+
/**
|
|
106
|
+
* Watch and debounce - only emit after changes have stopped for a duration
|
|
107
|
+
*/
|
|
108
|
+
export declare function watchDebounced(paths: string | string[], callback: WatchCallback, debounceMs?: number, options?: WatchOptions): FileWatcher;
|
|
109
|
+
/**
|
|
110
|
+
* One-shot watch - stop after first event
|
|
111
|
+
*/
|
|
112
|
+
export declare function watchOnce(paths: string | string[], options?: WatchOptions): Promise<WatchEvent>;
|
|
113
|
+
/**
|
|
114
|
+
* Watch with batching - collect events and emit in batches
|
|
115
|
+
*/
|
|
116
|
+
export declare function watchBatched(paths: string | string[], callback: (events: WatchEvent[]) => void | Promise<void>, batchMs?: number, options?: WatchOptions): FileWatcher;
|
|
117
|
+
/**
|
|
118
|
+
* Watch with filtering
|
|
119
|
+
*/
|
|
120
|
+
export declare function watchFiltered(paths: string | string[], filter: (event: WatchEvent) => boolean, callback: WatchCallback, options?: WatchOptions): FileWatcher;
|
|
121
|
+
/**
|
|
122
|
+
* Watch only for specific event types
|
|
123
|
+
*/
|
|
124
|
+
export declare function watchEvents(paths: string | string[], eventTypes: WatchEventType[], callback: WatchCallback, options?: WatchOptions): FileWatcher;
|
|
125
|
+
/**
|
|
126
|
+
* Watch only for file changes (add, change, unlink)
|
|
127
|
+
*/
|
|
128
|
+
export declare function watchFiles(paths: string | string[], callback: WatchCallback, options?: WatchOptions): FileWatcher;
|
|
129
|
+
/**
|
|
130
|
+
* Watch only for directory changes
|
|
131
|
+
*/
|
|
132
|
+
export declare function watchDirs(paths: string | string[], callback: WatchCallback, options?: WatchOptions): FileWatcher;
|
|
133
|
+
//# sourceMappingURL=watch.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"watch.d.ts","sourceRoot":"","sources":["../../src/fs/watch.ts"],"names":[],"mappings":"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"}
|
package/dist/index.cjs
CHANGED
|
@@ -223,10 +223,42 @@ module.exports = __toCommonJS(index_exports);
|
|
|
223
223
|
|
|
224
224
|
// src/types.ts
|
|
225
225
|
function vec2(x = 0, y = 0) {
|
|
226
|
-
|
|
226
|
+
const v = [x, y];
|
|
227
|
+
Object.defineProperty(v, "x", {
|
|
228
|
+
value: x,
|
|
229
|
+
writable: true,
|
|
230
|
+
enumerable: false,
|
|
231
|
+
configurable: true
|
|
232
|
+
});
|
|
233
|
+
Object.defineProperty(v, "y", {
|
|
234
|
+
value: y,
|
|
235
|
+
writable: true,
|
|
236
|
+
enumerable: false,
|
|
237
|
+
configurable: true
|
|
238
|
+
});
|
|
239
|
+
return v;
|
|
227
240
|
}
|
|
228
241
|
function vec3(x = 0, y = 0, z = 0) {
|
|
229
|
-
|
|
242
|
+
const v = [x, y, z];
|
|
243
|
+
Object.defineProperty(v, "x", {
|
|
244
|
+
value: x,
|
|
245
|
+
writable: true,
|
|
246
|
+
enumerable: false,
|
|
247
|
+
configurable: true
|
|
248
|
+
});
|
|
249
|
+
Object.defineProperty(v, "y", {
|
|
250
|
+
value: y,
|
|
251
|
+
writable: true,
|
|
252
|
+
enumerable: false,
|
|
253
|
+
configurable: true
|
|
254
|
+
});
|
|
255
|
+
Object.defineProperty(v, "z", {
|
|
256
|
+
value: z,
|
|
257
|
+
writable: true,
|
|
258
|
+
enumerable: false,
|
|
259
|
+
configurable: true
|
|
260
|
+
});
|
|
261
|
+
return v;
|
|
230
262
|
}
|
|
231
263
|
function vec4(x = 0, y = 0, z = 0, w = 0) {
|
|
232
264
|
return { x, y, z, w };
|
|
@@ -256,7 +288,7 @@ function vec3ToArray(v) {
|
|
|
256
288
|
return [v.x, v.y, v.z];
|
|
257
289
|
}
|
|
258
290
|
function arrayToVec3(arr) {
|
|
259
|
-
return
|
|
291
|
+
return vec3(arr[0] || 0, arr[1] || 0, arr[2] || 0);
|
|
260
292
|
}
|
|
261
293
|
function quatToArray(q) {
|
|
262
294
|
return [q.x, q.y, q.z, q.w];
|
|
@@ -357,6 +389,9 @@ var Vec3 = class _Vec3 {
|
|
|
357
389
|
this.y = y;
|
|
358
390
|
this.z = z;
|
|
359
391
|
}
|
|
392
|
+
x;
|
|
393
|
+
y;
|
|
394
|
+
z;
|
|
360
395
|
static zero() {
|
|
361
396
|
return new _Vec3(0, 0, 0);
|
|
362
397
|
}
|
|
@@ -433,6 +468,10 @@ var Quaternion = class _Quaternion {
|
|
|
433
468
|
this.z = z;
|
|
434
469
|
this.w = w;
|
|
435
470
|
}
|
|
471
|
+
x;
|
|
472
|
+
y;
|
|
473
|
+
z;
|
|
474
|
+
w;
|
|
436
475
|
static identity() {
|
|
437
476
|
return new _Quaternion(0, 0, 0, 1);
|
|
438
477
|
}
|
|
@@ -514,6 +553,9 @@ var Transform = class _Transform {
|
|
|
514
553
|
this.rotation = rotation;
|
|
515
554
|
this.scale = scale;
|
|
516
555
|
}
|
|
556
|
+
position;
|
|
557
|
+
rotation;
|
|
558
|
+
scale;
|
|
517
559
|
static identity() {
|
|
518
560
|
return new _Transform();
|
|
519
561
|
}
|
|
@@ -530,6 +572,8 @@ var Ray = class {
|
|
|
530
572
|
this.origin = origin;
|
|
531
573
|
this.direction = direction;
|
|
532
574
|
}
|
|
575
|
+
origin;
|
|
576
|
+
direction;
|
|
533
577
|
pointAt(t) {
|
|
534
578
|
return this.origin.add(this.direction.mul(t));
|
|
535
579
|
}
|
|
@@ -539,6 +583,8 @@ var AABB = class {
|
|
|
539
583
|
this.min = min;
|
|
540
584
|
this.max = max;
|
|
541
585
|
}
|
|
586
|
+
min;
|
|
587
|
+
max;
|
|
542
588
|
contains(point) {
|
|
543
589
|
return point.x >= this.min.x && point.x <= this.max.x && point.y >= this.min.y && point.y <= this.max.y && point.z >= this.min.z && point.z <= this.max.z;
|
|
544
590
|
}
|
|
@@ -797,7 +843,7 @@ var vec3Math = {
|
|
|
797
843
|
back: () => vec3(0, 0, 1),
|
|
798
844
|
left: () => vec3(-1, 0, 0),
|
|
799
845
|
right: () => vec3(1, 0, 0),
|
|
800
|
-
add: (a, b) => (
|
|
846
|
+
add: (a, b) => vec3(a.x + b.x, a.y + b.y, a.z + b.z),
|
|
801
847
|
sub: (a, b) => ({ x: a.x - b.x, y: a.y - b.y, z: a.z - b.z }),
|
|
802
848
|
mul: (a, s) => ({ x: a.x * s, y: a.y * s, z: a.z * s }),
|
|
803
849
|
div: (a, s) => ({ x: a.x / s, y: a.y / s, z: a.z / s }),
|
|
@@ -1836,6 +1882,7 @@ var PriorityQueue = class _PriorityQueue {
|
|
|
1836
1882
|
constructor(compareFn = (a, b) => a - b) {
|
|
1837
1883
|
this.compareFn = compareFn;
|
|
1838
1884
|
}
|
|
1885
|
+
compareFn;
|
|
1839
1886
|
heap = [];
|
|
1840
1887
|
static minHeap() {
|
|
1841
1888
|
return new _PriorityQueue((a, b) => a - b);
|
|
@@ -2040,8 +2087,8 @@ function formatDuration(ms) {
|
|
|
2040
2087
|
if (ms < 36e5) {
|
|
2041
2088
|
return `${(ms / 6e4).toFixed(1)}m`;
|
|
2042
2089
|
}
|
|
2043
|
-
const
|
|
2044
|
-
const
|
|
2090
|
+
const _hours = Math.floor(ms / 36e5);
|
|
2091
|
+
const _mins = Math.floor(ms % 36e5 / 6e4);
|
|
2045
2092
|
return `${(ms / 36e5).toFixed(1)}h`;
|
|
2046
2093
|
}
|
|
2047
2094
|
function escapeHtml(s) {
|
|
@@ -3824,7 +3871,7 @@ function unreachable(message) {
|
|
|
3824
3871
|
throw new Error(message ?? "Unreachable code reached");
|
|
3825
3872
|
}
|
|
3826
3873
|
function todo(message) {
|
|
3827
|
-
throw new Error(`
|
|
3874
|
+
throw new Error(`Not implemented: ${message ?? "No details"}`);
|
|
3828
3875
|
}
|
|
3829
3876
|
function clone(value) {
|
|
3830
3877
|
if (value === null || typeof value !== "object") {
|