@alwatr/node-fs
Version:
Enhanced file system operations in Node.js with asynchronous queue to prevent parallel writes.
8 lines (7 loc) • 14.3 kB
Source Map (JSON)
{
"version": 3,
"sources": ["../src/read-file.ts", "../src/common.ts", "../src/write-file.ts", "../src/json.ts", "../src/read-json.ts", "../src/write-json.ts", "../src/make-file.ts", "../src/main.ts"],
"sourcesContent": ["import {readFileSync as readFileSync_} from 'node:fs';\nimport {readFile as readFile_} from 'node:fs/promises';\n\nimport {flatString} from '@alwatr/flat-string';\n\nimport {asyncQueue, logger} from './common.js';\n\n/**\n * Enhanced read File (Synchronous).\n *\n * @param path - file path\n * @returns file content\n * @example\n * ```typescript\n * const fileContent = readFileSync('./file.txt', sync);\n * ```\n */\nexport function readFileSync(path: string): string {\n logger.logMethodArgs?.('readFileSync', '...' + path.slice(-32));\n // if (!existsSync(path)) throw new Error('file_not_found');\n try {\n return flatString(readFileSync_(path, {encoding: 'utf-8', flag: 'r'}));\n }\n catch (err) {\n logger.error('readFileSync', 'read_file_failed', {path}, err);\n throw new Error('read_file_failed', {cause: (err as Error).cause});\n }\n}\n\n/**\n * Enhanced read File (Asynchronous).\n *\n * - If writing queue is running for target path, it will wait for it to finish.\n *\n * @param path - file path\n * @returns file content\n * @example\n * ```typescript\n * const fileContent = await readFile('./file.txt', sync);\n * ```\n */\nexport function readFile(path: string): Promise<string> {\n logger.logMethodArgs?.('readFile', '...' + path.slice(-32));\n // if (!existsSync(path)) throw new Error('file_not_found');\n return asyncQueue.push(path, async () => {\n try {\n return flatString(await readFile_(path, {encoding: 'utf-8', flag: 'r'}));\n }\n catch (err) {\n logger.error('readFile', 'read_file_failed', {path}, err);\n throw new Error('read_file_failed', {cause: (err as Error).cause});\n }\n });\n}\n", "import {AsyncQueue} from '@alwatr/async-queue';\nimport {createLogger} from '@alwatr/logger';\nimport {packageTracer} from '@alwatr/package-tracer';\n\n__dev_mode__: packageTracer.add(__package_name__, __package_version__);\n\nexport const logger = /* #__PURE__ */ createLogger('@alwatr/node-fs');\n\nexport const asyncQueue = /* #__PURE__ */ new AsyncQueue();\n", "import {writeFileSync as writeFileSync_, existsSync, mkdirSync, renameSync} from 'node:fs';\nimport {mkdir, rename, writeFile as writeFile_} from 'node:fs/promises';\nimport {dirname} from 'node:path';\n\nimport {asyncQueue, logger} from './common.js';\n\n/**\n * Enhanced write file (Synchronous).\n *\n * - If directory not exists, create it recursively.\n * - Write file to `path.tmp` before write success.\n * - If file exists, renamed (keep) to `path.bak`.\n * - If write failed, original file will not be changed.\n *\n * @param path - file path\n * @param content - file content\n * @example\n * ```typescript\n * writeFileSync('./file.txt', 'Hello World!');\n * ```\n */\nexport function writeFileSync(path: string, content: Buffer | string): void {\n logger.logMethodArgs?.('writeFileSync', '...' + path.slice(-32));\n try {\n const pathExists = existsSync(path);\n if (!pathExists) {\n const dir = dirname(path);\n if (!existsSync(dir)) {\n mkdirSync(dir, {recursive: true});\n }\n }\n writeFileSync_(path + '.tmp', content, {encoding: 'utf-8', flag: 'w'});\n if (pathExists) {\n renameSync(path, path + '.bak');\n }\n renameSync(path + '.tmp', path);\n logger.logOther?.('writeFileSync success', '...' + path.slice(-32));\n }\n catch (err) {\n logger.error('writeFileSync', 'write_file_failed', {path}, err);\n throw new Error('write_file_failed', {cause: (err as Error).cause});\n }\n}\n\n/**\n * Enhanced write file (Asynchronous).\n *\n * - If directory not exists, create it recursively.\n * - Write file to `path.tmp` before write success.\n * - If file exists, renamed (keep) to `path.bak`.\n * - If write failed, original file will not be changed.\n *\n * @param path - file path\n * @param content - file content\n * @example\n * ```typescript\n * await writeFile('./file.txt', 'Hello World!');\n * ```\n */\nexport function writeFile(path: string, content: Buffer | string): Promise<void> {\n logger.logMethodArgs?.('writeFile', '...' + path.slice(-32));\n return asyncQueue.push(path, async () => {\n try {\n logger.logOther?.('writeFile start', '...' + path.slice(-32));\n const pathExists = existsSync(path);\n if (!pathExists) {\n const dir = dirname(path);\n if (!existsSync(dir)) {\n await mkdir(dir, {recursive: true});\n }\n }\n await writeFile_(path + '.tmp', content, {encoding: 'utf-8', flag: 'w'});\n if (pathExists) {\n await rename(path, path + '.bak');\n }\n await rename(path + '.tmp', path);\n logger.logOther?.('writeFile success', '...' + path.slice(-32));\n }\n catch (err) {\n logger.error('writeFile', 'write_file_failed', {path}, err);\n throw new Error('write_file_failed', {cause: (err as Error).cause});\n }\n });\n}\n", "import {logger} from './common.js';\n\n/**\n * Parse json string.\n *\n * @param content - json string\n * @returns json object\n * @example\n * ```typescript\n * const json = parseJson('{\"a\":1,\"b\":2}');\n * console.log(json.a); // 1\n * ```\n */\nexport function parseJson<T extends JsonValue>(content: string): T {\n try {\n return JSON.parse(content);\n }\n catch (err) {\n logger.error('parseJson', 'invalid_json', err);\n throw new Error('invalid_json', {cause: (err as Error).cause});\n }\n}\n\n/**\n * Stringify json object.\n *\n * @param data - json object\n * @returns json string\n * @example\n * ```typescript\n * const json = jsonStringify({a:1, b:2});\n * console.log(json); // '{\"a\":1,\"b\":2}'\n * ```\n */\nexport function jsonStringify<T extends JsonValue>(data: T): string {\n try {\n return JSON.stringify(data);\n }\n catch (err) {\n logger.error('jsonStringify', 'stringify_failed', err);\n throw new Error('stringify_failed', {cause: (err as Error).cause});\n }\n}\n", "import {logger} from './common.js';\nimport {parseJson} from './json.js';\nimport {readFile, readFileSync} from './read-file.js';\n\n/**\n * Enhanced read json file (async).\n *\n * @param path - file path\n * @returns json object\n * @example\n * ```typescript\n * const fileContent = await readJson('./file.json');\n * ```\n */\nexport function readJson<T extends JsonValue>(path: string): Promise<T>;\n/**\n * Enhanced read json file (sync).\n *\n * @param path - file path\n * @param sync - sync mode\n * @returns json object\n * @example\n * ```typescript\n * const fileContent = readJson('./file.json', true);\n * ```\n */\nexport function readJson<T extends JsonValue>(path: string, sync: true): T;\n/**\n * Enhanced read json file.\n *\n * @param path - file path\n * @param sync - sync mode\n * @returns json object\n * @example\n * ```typescript\n * const fileContent = await readJson('./file.json', sync);\n * ```\n */\nexport function readJson<T extends JsonValue>(path: string, sync: boolean): MaybePromise<T>;\n/**\n * Enhanced read json file.\n *\n * @param path - file path\n * @param sync - sync mode\n * @returns json object\n * @example\n * ```typescript\n * const fileContent = await readJson('./file.json');\n * ```\n */\nexport function readJson<T extends JsonValue>(path: string, sync = false): MaybePromise<T> {\n logger.logMethodArgs?.('readJson', {path: path.slice(-32), sync});\n if (sync === true) {\n return parseJson<T>(readFileSync(path));\n }\n else {\n return readFile(path).then((content) => parseJson<T>(content));\n }\n}\n", "import {flatString} from '@alwatr/flat-string';\n\nimport {logger} from './common.js';\nimport {jsonStringify} from './json.js';\nimport {writeFile, writeFileSync} from './write-file.js';\n\n/**\n * Enhanced write json file (Asynchronous).\n *\n * @param path - file path\n * @param data - json object\n * @example\n * ```typescript\n * await writeJsonFile('./file.json', { a:1, b:2, c:3 });\n * ```\n */\nexport function writeJson<T extends JsonValue>(path: string, data: T, sync?: false): Promise<void>;\n/**\n * Enhanced write json file (Synchronous).\n *\n * @param path - file path\n * @param data - json object\n * @param sync - sync mode\n * @example\n * ```typescript\n * writeJsonFile('./file.json', { a:1, b:2, c:3 }, true);\n * ```\n */\nexport function writeJson<T extends JsonValue>(path: string, data: T, sync: true): void;\n/**\n * Enhanced write json file.\n *\n * @param path - file path\n * @param data - json object\n * @param sync - sync mode\n * @example\n * ```typescript\n * await writeJsonFile('./file.json', { a:1, b:2, c:3 }, sync);\n * ```\n */\nexport function writeJson<T extends JsonValue>(path: string, data: T, sync: boolean): MaybePromise<void>;\n/**\n * Enhanced write json file.\n *\n * @param path - file path\n * @param data - json object\n * @param sync - sync mode\n * @example\n * ```typescript\n * await writeJsonFile('./file.json', { a:1, b:2, c:3 });\n * ```\n */\nexport function writeJson<T extends JsonValue>(path: string, data: T, sync = false): MaybePromise<void> {\n logger.logMethodArgs?.('writeJson', '...' + path.slice(-32));\n const content = flatString(jsonStringify(data));\n return sync === true ? writeFileSync(path, content) : writeFile(path, content);\n}\n", "import { existsSync } from 'node:fs';\nimport {mkdir, open} from 'node:fs/promises';\nimport { dirname } from 'node:path';\n\nimport {logger} from './common.js';\n\n/**\n * Make empty file.\n *\n * @param path - file path\n *\n * @example\n * ```ts\n * await makeFile('./dir/file.txt');\n * ```\n */\nexport async function makeEmptyFile(path: string): Promise<void> {\n logger.logMethodArgs?.('makeEmptyFile', '...' + path.slice(-32));\n try {\n const pathExists = existsSync(path);\n if (!pathExists) {\n const dir = dirname(path);\n if (!existsSync(dir)) {\n await mkdir(dir, {recursive: true});\n }\n }\n await (await open(path, 'w')).close();\n }\n catch (err) {\n logger.error('makeEmptyFile', 'make_file_failed', {path}, err);\n throw new Error('make_file_failed', {cause: (err as Error).cause});\n }\n}\n", "export * from './read-file.js';\nexport * from './write-file.js';\nexport * from './read-json.js';\nexport * from './write-json.js';\nexport * from './make-file.js';\n\nexport {resolve} from 'node:path';\nexport {existsSync} from 'node:fs';\nexport {unlink} from 'node:fs/promises';\n"],
"mappings": "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",
"names": ["flatString", "flatString", "existsSync", "mkdir", "dirname", "existsSync", "dirname", "mkdir", "existsSync"]
}