180 lines
5.3 KiB
JavaScript

"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.Dir = void 0;
const util_1 = require("./util");
const Dirent_1 = require("./Dirent");
const errors = require("../internal/errors");
/**
* A directory stream, like `fs.Dir`.
*/
class Dir {
constructor(link, options) {
this.link = link;
this.options = options;
this.iteratorInfo = [];
this.closed = false;
this.operationQueue = null;
this.path = link.getPath();
this.iteratorInfo.push(link.children[Symbol.iterator]());
}
closeBase() {
// In a real filesystem implementation, this would close file descriptors
// For memfs, we just need to mark as closed
}
readBase(iteratorInfo) {
let done;
let value;
let name;
let link;
do {
do {
({ done, value } = iteratorInfo[iteratorInfo.length - 1].next());
if (!done) {
[name, link] = value;
}
else {
break;
}
} while (name === '.' || name === '..');
if (done) {
iteratorInfo.pop();
if (iteratorInfo.length === 0) {
break;
}
else {
done = false;
}
}
else {
if (this.options.recursive && link.children.size) {
iteratorInfo.push(link.children[Symbol.iterator]());
}
return Dirent_1.default.build(link, this.options.encoding);
}
} while (!done);
return null;
}
close(callback) {
// Promise-based close
if (callback === undefined) {
if (this.closed) {
return Promise.reject(new errors.Error('ERR_DIR_CLOSED'));
}
return new Promise((resolve, reject) => {
this.close(err => {
if (err)
reject(err);
else
resolve();
});
});
}
// Callback-based close
(0, util_1.validateCallback)(callback);
if (this.closed) {
process.nextTick(callback, new errors.Error('ERR_DIR_CLOSED'));
return;
}
if (this.operationQueue !== null) {
this.operationQueue.push(() => {
this.close(callback);
});
return;
}
this.closed = true;
try {
this.closeBase();
process.nextTick(callback);
}
catch (err) {
process.nextTick(callback, err);
}
}
closeSync() {
if (this.closed) {
throw new errors.Error('ERR_DIR_CLOSED');
}
if (this.operationQueue !== null) {
throw new errors.Error('ERR_DIR_CONCURRENT_OPERATION');
}
this.closed = true;
this.closeBase();
}
read(callback) {
// Promise-based read
if (callback === undefined) {
return new Promise((resolve, reject) => {
this.read((err, result) => {
if (err)
reject(err);
else
resolve(result !== null && result !== void 0 ? result : null);
});
});
}
// Callback-based read
(0, util_1.validateCallback)(callback);
if (this.closed) {
process.nextTick(callback, new errors.Error('ERR_DIR_CLOSED'));
return;
}
if (this.operationQueue !== null) {
this.operationQueue.push(() => {
this.read(callback);
});
return;
}
this.operationQueue = [];
try {
const result = this.readBase(this.iteratorInfo);
process.nextTick(() => {
const queue = this.operationQueue;
this.operationQueue = null;
for (const op of queue)
op();
callback(null, result);
});
}
catch (err) {
process.nextTick(() => {
const queue = this.operationQueue;
this.operationQueue = null;
for (const op of queue)
op();
callback(err);
});
}
}
readSync() {
if (this.closed) {
throw new errors.Error('ERR_DIR_CLOSED');
}
if (this.operationQueue !== null) {
throw new errors.Error('ERR_DIR_CONCURRENT_OPERATION');
}
return this.readBase(this.iteratorInfo);
}
[Symbol.asyncIterator]() {
return {
next: async () => {
try {
const dirEnt = await this.read();
if (dirEnt !== null) {
return { done: false, value: dirEnt };
}
else {
return { done: true, value: undefined };
}
}
catch (err) {
throw err;
}
},
[Symbol.asyncIterator]() {
return this;
},
};
}
}
exports.Dir = Dir;
//# sourceMappingURL=Dir.js.map