FsPromises.js 6.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161
  1. "use strict";
  2. Object.defineProperty(exports, "__esModule", { value: true });
  3. exports.FsPromises = void 0;
  4. const util_1 = require("./util");
  5. const constants_1 = require("../constants");
  6. // AsyncIterator implementation for promises.watch
  7. class FSWatchAsyncIterator {
  8. constructor(fs, path, options = {}) {
  9. this.fs = fs;
  10. this.path = path;
  11. this.options = options;
  12. this.eventQueue = [];
  13. this.resolveQueue = [];
  14. this.finished = false;
  15. this.maxQueue = options.maxQueue || 2048;
  16. this.overflow = options.overflow || 'ignore';
  17. this.startWatching();
  18. // Handle AbortSignal
  19. if (options.signal) {
  20. if (options.signal.aborted) {
  21. this.finish();
  22. return;
  23. }
  24. options.signal.addEventListener('abort', () => {
  25. this.finish();
  26. });
  27. }
  28. }
  29. startWatching() {
  30. try {
  31. this.watcher = this.fs.watch(this.path, this.options, (eventType, filename) => {
  32. this.enqueueEvent({ eventType, filename });
  33. });
  34. }
  35. catch (error) {
  36. // If we can't start watching, finish immediately
  37. this.finish();
  38. throw error;
  39. }
  40. }
  41. enqueueEvent(event) {
  42. if (this.finished)
  43. return;
  44. // Handle queue overflow
  45. if (this.eventQueue.length >= this.maxQueue) {
  46. if (this.overflow === 'throw') {
  47. const error = new Error(`Watch queue overflow: more than ${this.maxQueue} events queued`);
  48. this.finish(error);
  49. return;
  50. }
  51. else {
  52. // 'ignore' - drop the oldest event
  53. this.eventQueue.shift();
  54. console.warn(`Watch queue overflow: dropping event due to exceeding maxQueue of ${this.maxQueue}`);
  55. }
  56. }
  57. this.eventQueue.push(event);
  58. // If there's a waiting promise, resolve it
  59. if (this.resolveQueue.length > 0) {
  60. const { resolve } = this.resolveQueue.shift();
  61. const nextEvent = this.eventQueue.shift();
  62. resolve({ value: nextEvent, done: false });
  63. }
  64. }
  65. finish(error) {
  66. if (this.finished)
  67. return;
  68. this.finished = true;
  69. if (this.watcher) {
  70. this.watcher.close();
  71. this.watcher = null;
  72. }
  73. // Resolve or reject all pending promises
  74. while (this.resolveQueue.length > 0) {
  75. const { resolve, reject } = this.resolveQueue.shift();
  76. if (error) {
  77. reject(error);
  78. }
  79. else {
  80. resolve({ value: undefined, done: true });
  81. }
  82. }
  83. }
  84. async next() {
  85. if (this.finished) {
  86. return { value: undefined, done: true };
  87. }
  88. // If we have queued events, return one
  89. if (this.eventQueue.length > 0) {
  90. const event = this.eventQueue.shift();
  91. return { value: event, done: false };
  92. }
  93. // Otherwise, wait for the next event
  94. return new Promise((resolve, reject) => {
  95. this.resolveQueue.push({ resolve, reject });
  96. });
  97. }
  98. async return() {
  99. this.finish();
  100. return { value: undefined, done: true };
  101. }
  102. async throw(error) {
  103. this.finish(error);
  104. throw error;
  105. }
  106. [Symbol.asyncIterator]() {
  107. return this;
  108. }
  109. }
  110. class FsPromises {
  111. constructor(fs, FileHandle) {
  112. this.fs = fs;
  113. this.FileHandle = FileHandle;
  114. this.constants = constants_1.constants;
  115. this.cp = (0, util_1.promisify)(this.fs, 'cp');
  116. this.opendir = (0, util_1.promisify)(this.fs, 'opendir');
  117. this.statfs = (0, util_1.promisify)(this.fs, 'statfs');
  118. this.lutimes = (0, util_1.promisify)(this.fs, 'lutimes');
  119. this.glob = (0, util_1.promisify)(this.fs, 'glob');
  120. this.access = (0, util_1.promisify)(this.fs, 'access');
  121. this.chmod = (0, util_1.promisify)(this.fs, 'chmod');
  122. this.chown = (0, util_1.promisify)(this.fs, 'chown');
  123. this.copyFile = (0, util_1.promisify)(this.fs, 'copyFile');
  124. this.lchmod = (0, util_1.promisify)(this.fs, 'lchmod');
  125. this.lchown = (0, util_1.promisify)(this.fs, 'lchown');
  126. this.link = (0, util_1.promisify)(this.fs, 'link');
  127. this.lstat = (0, util_1.promisify)(this.fs, 'lstat');
  128. this.mkdir = (0, util_1.promisify)(this.fs, 'mkdir');
  129. this.mkdtemp = (0, util_1.promisify)(this.fs, 'mkdtemp');
  130. this.readdir = (0, util_1.promisify)(this.fs, 'readdir');
  131. this.readlink = (0, util_1.promisify)(this.fs, 'readlink');
  132. this.realpath = (0, util_1.promisify)(this.fs, 'realpath');
  133. this.rename = (0, util_1.promisify)(this.fs, 'rename');
  134. this.rmdir = (0, util_1.promisify)(this.fs, 'rmdir');
  135. this.rm = (0, util_1.promisify)(this.fs, 'rm');
  136. this.stat = (0, util_1.promisify)(this.fs, 'stat');
  137. this.symlink = (0, util_1.promisify)(this.fs, 'symlink');
  138. this.truncate = (0, util_1.promisify)(this.fs, 'truncate');
  139. this.unlink = (0, util_1.promisify)(this.fs, 'unlink');
  140. this.utimes = (0, util_1.promisify)(this.fs, 'utimes');
  141. this.readFile = (id, options) => {
  142. return (0, util_1.promisify)(this.fs, 'readFile')(id instanceof this.FileHandle ? id.fd : id, options);
  143. };
  144. this.appendFile = (path, data, options) => {
  145. return (0, util_1.promisify)(this.fs, 'appendFile')(path instanceof this.FileHandle ? path.fd : path, data, options);
  146. };
  147. this.open = (path, flags = 'r', mode) => {
  148. return (0, util_1.promisify)(this.fs, 'open', fd => new this.FileHandle(this.fs, fd))(path, flags, mode);
  149. };
  150. this.writeFile = (id, data, options) => {
  151. const dataPromise = (0, util_1.isReadableStream)(data) ? (0, util_1.streamToBuffer)(data) : Promise.resolve(data);
  152. return dataPromise.then(data => (0, util_1.promisify)(this.fs, 'writeFile')(id instanceof this.FileHandle ? id.fd : id, data, options));
  153. };
  154. this.watch = (filename, options) => {
  155. const watchOptions = typeof options === 'string' ? { encoding: options } : options || {};
  156. return new FSWatchAsyncIterator(this.fs, filename, watchOptions);
  157. };
  158. }
  159. }
  160. exports.FsPromises = FsPromises;
  161. //# sourceMappingURL=FsPromises.js.map