123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190 |
- "use strict";
- Object.defineProperty(exports, "__esModule", { value: true });
- exports.FileHandle = void 0;
- const util_1 = require("./util");
- const events_1 = require("events");
- class FileHandle extends events_1.EventEmitter {
- constructor(fs, fd) {
- super();
- this.refs = 1;
- this.closePromise = null;
- this.position = 0;
- this.readableWebStreamLocked = false;
- this.fs = fs;
- this.fd = fd;
- }
- getAsyncId() {
- // Return a unique async ID for this file handle
- // In a real implementation, this would be provided by the underlying system
- return this.fd;
- }
- appendFile(data, options) {
- return (0, util_1.promisify)(this.fs, 'appendFile')(this.fd, data, options);
- }
- chmod(mode) {
- return (0, util_1.promisify)(this.fs, 'fchmod')(this.fd, mode);
- }
- chown(uid, gid) {
- return (0, util_1.promisify)(this.fs, 'fchown')(this.fd, uid, gid);
- }
- close() {
- if (this.fd === -1) {
- return Promise.resolve();
- }
- if (this.closePromise) {
- return this.closePromise;
- }
- this.refs--;
- if (this.refs === 0) {
- const currentFd = this.fd;
- this.fd = -1;
- this.closePromise = (0, util_1.promisify)(this.fs, 'close')(currentFd).finally(() => {
- this.closePromise = null;
- });
- }
- else {
- this.closePromise = new Promise((resolve, reject) => {
- this.closeResolve = resolve;
- this.closeReject = reject;
- }).finally(() => {
- this.closePromise = null;
- this.closeReject = undefined;
- this.closeResolve = undefined;
- });
- }
- this.emit('close');
- return this.closePromise;
- }
- datasync() {
- return (0, util_1.promisify)(this.fs, 'fdatasync')(this.fd);
- }
- createReadStream(options) {
- return this.fs.createReadStream('', Object.assign(Object.assign({}, options), { fd: this }));
- }
- createWriteStream(options) {
- return this.fs.createWriteStream('', Object.assign(Object.assign({}, options), { fd: this }));
- }
- readableWebStream(options = {}) {
- const { type = 'bytes', autoClose = false } = options;
- let position = 0;
- if (this.fd === -1) {
- throw new Error('The FileHandle is closed');
- }
- if (this.closePromise) {
- throw new Error('The FileHandle is closing');
- }
- if (this.readableWebStreamLocked) {
- throw new Error('An error will be thrown if this method is called more than once or is called after the FileHandle is closed or closing.');
- }
- this.readableWebStreamLocked = true;
- this.ref();
- const unlockAndCleanup = () => {
- this.readableWebStreamLocked = false;
- this.unref();
- if (autoClose) {
- this.close().catch(() => {
- // Ignore close errors in cleanup
- });
- }
- };
- return new ReadableStream({
- type: type === 'bytes' ? 'bytes' : undefined,
- autoAllocateChunkSize: 16384,
- pull: async (controller) => {
- var _a;
- try {
- const view = (_a = controller.byobRequest) === null || _a === void 0 ? void 0 : _a.view;
- if (!view) {
- // Fallback for when BYOB is not available
- const buffer = new Uint8Array(16384);
- const result = await this.read(buffer, 0, buffer.length, position);
- if (result.bytesRead === 0) {
- controller.close();
- unlockAndCleanup();
- return;
- }
- position += result.bytesRead;
- controller.enqueue(buffer.slice(0, result.bytesRead));
- return;
- }
- const result = await this.read(view, view.byteOffset, view.byteLength, position);
- if (result.bytesRead === 0) {
- controller.close();
- unlockAndCleanup();
- return;
- }
- position += result.bytesRead;
- controller.byobRequest.respond(result.bytesRead);
- }
- catch (error) {
- controller.error(error);
- unlockAndCleanup();
- }
- },
- cancel: async () => {
- unlockAndCleanup();
- },
- });
- }
- async read(buffer, offset, length, position) {
- const readPosition = position !== null && position !== undefined ? position : this.position;
- const result = await (0, util_1.promisify)(this.fs, 'read', bytesRead => ({ bytesRead, buffer }))(this.fd, buffer, offset, length, readPosition);
- // Update internal position only if position was null/undefined
- if (position === null || position === undefined) {
- this.position += result.bytesRead;
- }
- return result;
- }
- readv(buffers, position) {
- return (0, util_1.promisify)(this.fs, 'readv', bytesRead => ({ bytesRead, buffers }))(this.fd, buffers, position);
- }
- readFile(options) {
- return (0, util_1.promisify)(this.fs, 'readFile')(this.fd, options);
- }
- stat(options) {
- return (0, util_1.promisify)(this.fs, 'fstat')(this.fd, options);
- }
- sync() {
- return (0, util_1.promisify)(this.fs, 'fsync')(this.fd);
- }
- truncate(len) {
- return (0, util_1.promisify)(this.fs, 'ftruncate')(this.fd, len);
- }
- utimes(atime, mtime) {
- return (0, util_1.promisify)(this.fs, 'futimes')(this.fd, atime, mtime);
- }
- async write(buffer, offset, length, position) {
- const useInternalPosition = typeof position !== 'number';
- const writePosition = useInternalPosition ? this.position : position;
- const result = await (0, util_1.promisify)(this.fs, 'write', bytesWritten => ({ bytesWritten, buffer }))(this.fd, buffer, offset, length, writePosition);
- // Update internal position only if position was null/undefined
- if (useInternalPosition) {
- this.position += result.bytesWritten;
- }
- return result;
- }
- writev(buffers, position) {
- return (0, util_1.promisify)(this.fs, 'writev', bytesWritten => ({ bytesWritten, buffers }))(this.fd, buffers, position);
- }
- writeFile(data, options) {
- return (0, util_1.promisify)(this.fs, 'writeFile')(this.fd, data, options);
- }
- // Implement Symbol.asyncDispose if available (ES2023+)
- async [Symbol.asyncDispose]() {
- await this.close();
- }
- ref() {
- this.refs++;
- }
- unref() {
- this.refs--;
- if (this.refs === 0) {
- this.fd = -1;
- if (this.closeResolve) {
- (0, util_1.promisify)(this.fs, 'close')(this.fd).then(this.closeResolve, this.closeReject);
- }
- }
- }
- }
- exports.FileHandle = FileHandle;
- //# sourceMappingURL=FileHandle.js.map
|