1 | "use strict";
|
2 |
|
3 | var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault");
|
4 |
|
5 | var _asyncToGenerator2 = _interopRequireDefault(require("@babel/runtime/helpers/asyncToGenerator"));
|
6 |
|
7 | const fs = require('@parcel/fs');
|
8 |
|
9 | const path = require('path');
|
10 |
|
11 | const md5 = require('./utils/md5');
|
12 |
|
13 | const objectHash = require('./utils/objectHash');
|
14 |
|
15 | const pkg = require('../package.json');
|
16 |
|
17 | const logger = require('@parcel/logger');
|
18 |
|
19 | const _require = require('./utils/glob'),
|
20 | isGlob = _require.isGlob,
|
21 | glob = _require.glob;
|
22 |
|
23 |
|
24 | const OPTION_KEYS = ['publicURL', 'minify', 'hmr', 'target', 'scopeHoist', 'sourceMaps'];
|
25 |
|
26 | class FSCache {
|
27 | constructor(options) {
|
28 | this.dir = path.resolve(options.cacheDir || '.cache');
|
29 | this.dirExists = false;
|
30 | this.invalidated = new Set();
|
31 | this.optionsHash = objectHash(OPTION_KEYS.reduce((p, k) => (p[k] = options[k], p), {
|
32 | version: pkg.version
|
33 | }));
|
34 | }
|
35 |
|
36 | ensureDirExists() {
|
37 | var _this = this;
|
38 |
|
39 | return (0, _asyncToGenerator2.default)(function* () {
|
40 | if (_this.dirExists) {
|
41 | return;
|
42 | }
|
43 |
|
44 | yield fs.mkdirp(_this.dir);
|
45 |
|
46 |
|
47 | for (let i = 0; i < 256; i++) {
|
48 | yield fs.mkdirp(path.join(_this.dir, ('00' + i.toString(16)).slice(-2)));
|
49 | }
|
50 |
|
51 | _this.dirExists = true;
|
52 | })();
|
53 | }
|
54 |
|
55 | getCacheFile(filename) {
|
56 | let hash = md5(this.optionsHash + filename);
|
57 | return path.join(this.dir, hash.slice(0, 2), hash.slice(2) + '.json');
|
58 | }
|
59 |
|
60 | getLastModified(filename) {
|
61 | return (0, _asyncToGenerator2.default)(function* () {
|
62 | if (isGlob(filename)) {
|
63 | let files = yield glob(filename, {
|
64 | onlyFiles: true
|
65 | });
|
66 | return (yield Promise.all(files.map(file => fs.stat(file).then(({
|
67 | mtime
|
68 | }) => mtime.getTime())))).reduce((a, b) => Math.max(a, b), 0);
|
69 | }
|
70 |
|
71 | return (yield fs.stat(filename)).mtime.getTime();
|
72 | })();
|
73 | }
|
74 |
|
75 | writeDepMtimes(data) {
|
76 | var _this2 = this;
|
77 |
|
78 | return (0, _asyncToGenerator2.default)(function* () {
|
79 |
|
80 | var _iteratorNormalCompletion = true;
|
81 | var _didIteratorError = false;
|
82 | var _iteratorError = undefined;
|
83 |
|
84 | try {
|
85 | for (var _iterator = data.dependencies[Symbol.iterator](), _step; !(_iteratorNormalCompletion = (_step = _iterator.next()).done); _iteratorNormalCompletion = true) {
|
86 | let dep = _step.value;
|
87 |
|
88 | if (dep.includedInParent) {
|
89 | dep.mtime = yield _this2.getLastModified(dep.name);
|
90 | }
|
91 | }
|
92 | } catch (err) {
|
93 | _didIteratorError = true;
|
94 | _iteratorError = err;
|
95 | } finally {
|
96 | try {
|
97 | if (!_iteratorNormalCompletion && _iterator.return != null) {
|
98 | _iterator.return();
|
99 | }
|
100 | } finally {
|
101 | if (_didIteratorError) {
|
102 | throw _iteratorError;
|
103 | }
|
104 | }
|
105 | }
|
106 | })();
|
107 | }
|
108 |
|
109 | write(filename, data) {
|
110 | var _this3 = this;
|
111 |
|
112 | return (0, _asyncToGenerator2.default)(function* () {
|
113 | try {
|
114 | yield _this3.ensureDirExists();
|
115 | yield _this3.writeDepMtimes(data);
|
116 | yield fs.writeFile(_this3.getCacheFile(filename), JSON.stringify(data));
|
117 |
|
118 | _this3.invalidated.delete(filename);
|
119 | } catch (err) {
|
120 | logger.error(`Error writing to cache: ${err.message}`);
|
121 | }
|
122 | })();
|
123 | }
|
124 |
|
125 | checkDepMtimes(data) {
|
126 | var _this4 = this;
|
127 |
|
128 | return (0, _asyncToGenerator2.default)(function* () {
|
129 |
|
130 |
|
131 | var _iteratorNormalCompletion2 = true;
|
132 | var _didIteratorError2 = false;
|
133 | var _iteratorError2 = undefined;
|
134 |
|
135 | try {
|
136 | for (var _iterator2 = data.dependencies[Symbol.iterator](), _step2; !(_iteratorNormalCompletion2 = (_step2 = _iterator2.next()).done); _iteratorNormalCompletion2 = true) {
|
137 | let dep = _step2.value;
|
138 |
|
139 | if (dep.includedInParent) {
|
140 | if ((yield _this4.getLastModified(dep.name)) > dep.mtime) {
|
141 | return false;
|
142 | }
|
143 | }
|
144 | }
|
145 | } catch (err) {
|
146 | _didIteratorError2 = true;
|
147 | _iteratorError2 = err;
|
148 | } finally {
|
149 | try {
|
150 | if (!_iteratorNormalCompletion2 && _iterator2.return != null) {
|
151 | _iterator2.return();
|
152 | }
|
153 | } finally {
|
154 | if (_didIteratorError2) {
|
155 | throw _iteratorError2;
|
156 | }
|
157 | }
|
158 | }
|
159 |
|
160 | return true;
|
161 | })();
|
162 | }
|
163 |
|
164 | read(filename) {
|
165 | var _this5 = this;
|
166 |
|
167 | return (0, _asyncToGenerator2.default)(function* () {
|
168 | if (_this5.invalidated.has(filename)) {
|
169 | return null;
|
170 | }
|
171 |
|
172 | let cacheFile = _this5.getCacheFile(filename);
|
173 |
|
174 | try {
|
175 | let stats = yield fs.stat(filename);
|
176 | let cacheStats = yield fs.stat(cacheFile);
|
177 |
|
178 | if (stats.mtime > cacheStats.mtime) {
|
179 | return null;
|
180 | }
|
181 |
|
182 | let json = yield fs.readFile(cacheFile);
|
183 | let data = JSON.parse(json);
|
184 |
|
185 | if (!(yield _this5.checkDepMtimes(data))) {
|
186 | return null;
|
187 | }
|
188 |
|
189 | return data;
|
190 | } catch (err) {
|
191 | return null;
|
192 | }
|
193 | })();
|
194 | }
|
195 |
|
196 | invalidate(filename) {
|
197 | this.invalidated.add(filename);
|
198 | }
|
199 |
|
200 | delete(filename) {
|
201 | var _this6 = this;
|
202 |
|
203 | return (0, _asyncToGenerator2.default)(function* () {
|
204 | try {
|
205 | yield fs.unlink(_this6.getCacheFile(filename));
|
206 |
|
207 | _this6.invalidated.delete(filename);
|
208 | } catch (err) {
|
209 | }
|
210 | })();
|
211 | }
|
212 |
|
213 | }
|
214 |
|
215 | module.exports = FSCache; |
\ | No newline at end of file |