Skip to content

Commit 283136c

Browse files
feat: cache realpath and realpathSync methods
2 parents 91bd21f + 379ca70 commit 283136c

File tree

4 files changed

+119
-2
lines changed

4 files changed

+119
-2
lines changed

lib/CachedInputFileSystem.js

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -577,6 +577,19 @@ module.exports = class CachedInputFileSystem {
577577
this.readlinkSync = /** @type {SyncFileSystem["readlinkSync"]} */ (
578578
readlinkSync
579579
);
580+
581+
this._realpathBackend = createBackend(
582+
duration,
583+
this.fileSystem.realpath,
584+
this.fileSystem.realpathSync,
585+
this.fileSystem
586+
);
587+
const realpath = this._realpathBackend.provide;
588+
this.realpath = /** @type {FileSystem["realpath"]} */ (realpath);
589+
const realpathSync = this._realpathBackend.provideSync;
590+
this.realpathSync = /** @type {SyncFileSystem["realpathSync"]} */ (
591+
realpathSync
592+
);
580593
}
581594

582595
/**
@@ -589,5 +602,6 @@ module.exports = class CachedInputFileSystem {
589602
this._readFileBackend.purge(what);
590603
this._readlinkBackend.purge(what);
591604
this._readJsonBackend.purge(what);
605+
this._realpathBackend.purge(what);
592606
}
593607
};

lib/Resolver.js

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -17,9 +17,9 @@ const {
1717

1818
/** @typedef {import("./ResolverFactory").ResolveOptions} ResolveOptions */
1919

20-
/** @typedef {Error & {details?: string}} ErrorWithDetail */
20+
/** @typedef {Error & { details?: string }} ErrorWithDetail */
2121

22-
/** @typedef {(err: ErrorWithDetail|null, res?: string|false, req?: ResolveRequest) => void} ResolveCallback */
22+
/** @typedef {(err: ErrorWithDetail | null, res?: string | false, req?: ResolveRequest) => void} ResolveCallback */
2323

2424
/**
2525
* @typedef {Object} FileSystemStats
@@ -65,6 +65,7 @@ const {
6565
* @property {(function(string, FileSystemCallback<Buffer | string>): void) & function(string, object, FileSystemCallback<Buffer | string>): void} readlink
6666
* @property {(function(string, FileSystemCallback<FileSystemStats>): void) & function(string, object, FileSystemCallback<Buffer | string>): void=} lstat
6767
* @property {(function(string, FileSystemCallback<FileSystemStats>): void) & function(string, object, FileSystemCallback<Buffer | string>): void} stat
68+
* @property {(function(string, FileSystemCallback<Buffer | string>): void) & function(string, object, FileSystemCallback<Buffer | string>): void=} realpath
6869
*/
6970

7071
/**
@@ -75,6 +76,7 @@ const {
7576
* @property {function(string, object=): Buffer | string} readlinkSync
7677
* @property {function(string, object=): FileSystemStats=} lstatSync
7778
* @property {function(string, object=): FileSystemStats} statSync
79+
* @property {function(string, object=): string | Buffer=} realpathSync
7880
*/
7981

8082
/**

test/CachedInputFileSystem.test.js

Lines changed: 84 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -165,6 +165,90 @@ describe("CachedInputFileSystem OperationMergerBackend ('lstat' and 'lstatSync')
165165
});
166166
});
167167

168+
describe("CachedInputFileSystem OperationMergerBackend ('realpath' and 'realpathSync')", () => {
169+
let fs;
170+
171+
beforeEach(() => {
172+
fs = new CachedInputFileSystem(
173+
{
174+
realpath: function (path, options, callback) {
175+
if (!callback) {
176+
callback = options;
177+
options = undefined;
178+
}
179+
setTimeout(
180+
() =>
181+
callback(null, {
182+
path,
183+
options
184+
}),
185+
100
186+
);
187+
},
188+
realpathSync: function (path, options) {
189+
return {
190+
path,
191+
options
192+
};
193+
}
194+
},
195+
0
196+
);
197+
});
198+
afterEach(() => {
199+
fs.purge();
200+
});
201+
202+
it("should join accesses", function (done) {
203+
fs.realpath("a", function (err, result) {
204+
expect(result).toBeDefined();
205+
result.a = true;
206+
});
207+
fs.realpath("a", function (err, result) {
208+
expect(result).toBeDefined();
209+
expect(result.a).toBeDefined();
210+
done();
211+
});
212+
});
213+
214+
it("should not join accesses with options", function (done) {
215+
fs.realpath("a", function (err, result) {
216+
expect(result).toBeDefined();
217+
218+
result.a = true;
219+
220+
expect(result).toBeDefined();
221+
expect(result.path).toEqual("a");
222+
expect(result.options).toBeUndefined();
223+
});
224+
fs.realpath("a", { options: true }, function (err, result) {
225+
expect(result).toBeDefined();
226+
expect(result.a).toBeUndefined();
227+
expect(result.path).toEqual("a");
228+
expect(result.options).toMatchObject({ options: true });
229+
done();
230+
});
231+
});
232+
233+
it("should not cache accesses", function (done) {
234+
fs.realpath("a", function (err, result) {
235+
result.a = true;
236+
fs.realpath("a", function (err, result) {
237+
expect(result.a).toBeUndefined();
238+
done();
239+
});
240+
});
241+
});
242+
243+
it("should not cache sync accesses", () => {
244+
const result = fs.realpathSync("a");
245+
result.a = true;
246+
const result2 = fs.realpathSync("a");
247+
248+
expect(result2.a).toBeUndefined();
249+
});
250+
});
251+
168252
describe("CachedInputFileSystem CacheBackend", () => {
169253
let fs;
170254

types.d.ts

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -104,6 +104,15 @@ declare class CachedInputFileSystem {
104104
): void;
105105
};
106106
readlinkSync: (arg0: string, arg1?: object) => string | Buffer;
107+
realpath?: {
108+
(arg0: string, arg1: FileSystemCallback<string | Buffer>): void;
109+
(
110+
arg0: string,
111+
arg1: object,
112+
arg2: FileSystemCallback<string | Buffer>
113+
): void;
114+
};
115+
realpathSync?: (arg0: string, arg1?: object) => string | Buffer;
107116
purge(what?: string | Set<string> | string[]): void;
108117
}
109118
declare class CloneBasenamePlugin {
@@ -206,6 +215,14 @@ declare interface FileSystem {
206215
arg2: FileSystemCallback<string | Buffer>
207216
): void;
208217
};
218+
realpath?: {
219+
(arg0: string, arg1: FileSystemCallback<string | Buffer>): void;
220+
(
221+
arg0: string,
222+
arg1: object,
223+
arg2: FileSystemCallback<string | Buffer>
224+
): void;
225+
};
209226
}
210227
declare interface FileSystemCallback<T> {
211228
(err?: null | (PossibleFileSystemError & Error), result?: T): any;

0 commit comments

Comments
 (0)