|
1 | 1 | "use strict"; |
2 | 2 |
|
3 | | -let { abort, repr } = require("../"); |
4 | 3 | let { writeFile } = require("fs/promises"); |
5 | 4 | let { mkdirSync } = require("fs"); |
6 | 5 | let path = require("path"); |
7 | 6 |
|
8 | | -let KNOWN = {}; // avoids redundant `mkdirp` invocations |
9 | | -let LOCKS = {}; |
| 7 | +let KNOWN = new Set(); // avoids redundant `mkdir` invocations |
| 8 | +let LOCKS = new Map(); |
10 | 9 |
|
11 | 10 | // avoids concurrent write operations and creates target directory if necessary |
12 | 11 | module.exports = function createFile(filepath, contents) { |
13 | | - let lock = LOCKS[filepath]; |
| 12 | + let lock = LOCKS.get(filepath); |
14 | 13 | if(lock) { // defer |
15 | 14 | return lock.then(_ => createFile(filepath, contents)); |
16 | 15 | } |
17 | 16 |
|
18 | 17 | // create directory if necessary |
19 | | - if(!KNOWN[filepath]) { |
20 | | - KNOWN[filepath] = true; |
21 | | - // NB: `sync` avoids race condition for subsequent operations |
22 | | - mkdirpSync(path.dirname(filepath)); |
| 18 | + if(!KNOWN.has(filepath)) { |
| 19 | + KNOWN.add(filepath); |
| 20 | + mkdirSync(path.dirname(filepath), { recursive: true }); |
23 | 21 | } |
24 | 22 |
|
25 | 23 | let prom = writeFile(filepath, contents); |
26 | | - LOCKS[filepath] = prom; |
| 24 | + LOCKS.set(filepath, prom); |
27 | 25 | return prom.then(_ => { |
28 | | - delete LOCKS[filepath]; |
| 26 | + LOCKS.delete(filepath); |
29 | 27 | }); |
30 | 28 | }; |
31 | | - |
32 | | -function mkdirpSync(directory) { |
33 | | - try { |
34 | | - // NB: `recursive` option was introduced in Node v10.12.0 |
35 | | - mkdirSync(directory, { recursive: true }); |
36 | | - } catch(err) { |
37 | | - abort(`ERROR: auto-creating ${repr(directory)} requires ` + |
38 | | - "Node v10.12.0 or above"); |
39 | | - } |
40 | | -} |
0 commit comments