Skip to content

Commit 442070d

Browse files
committed
Move things into FileCache from AssetCache
1 parent 8c362da commit 442070d

File tree

6 files changed

+134
-124
lines changed

6 files changed

+134
-124
lines changed

src/AssetCache.js

Lines changed: 21 additions & 74 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,13 @@
11
const fs = require("graceful-fs");
22
const path = require("path");
33
const { createHash } = require("crypto");
4-
const debugUtil = require("debug");
54
const { DateCompare } = require("@11ty/eleventy-utils");
65

76
const FileCache = require("./FileCache.js");
87
const Sources = require("./Sources.js");
98
const DirectoryManager = require("./DirectoryManager.js");
109

10+
const debugUtil = require("debug");
1111
const debug = debugUtil("Eleventy:Fetch");
1212
const debugAssets = debugUtil("Eleventy:Assets");
1313

@@ -175,7 +175,8 @@ class AssetCache {
175175
get cache() {
176176
if (!this.#cache || this.#cacheLocationDirty) {
177177
let cache = new FileCache(this.cacheFilename, {
178-
dir: this.rootDir
178+
dir: this.rootDir,
179+
source: this.source,
179180
});
180181
cache.setDryRun(this.options.dryRun);
181182
cache.setDirectoryManager(this.#directoryManager);
@@ -190,16 +191,6 @@ class AssetCache {
190191
return DateCompare.getDurationMs(duration);
191192
}
192193

193-
getCachedContentsPath(type = "buffer") {
194-
if(type === "xml") {
195-
type = "text";
196-
} else if(type === "parsed-xml") {
197-
type = "json";
198-
}
199-
200-
return `${this.cachePath}.${type}`;
201-
}
202-
203194
setDirectoryManager(manager) {
204195
this.#directoryManager = manager;
205196
}
@@ -222,59 +213,14 @@ class AssetCache {
222213
throw new Error("save(contents) expects contents (was falsy)");
223214
}
224215

225-
this.cache.set(this.hash, {
226-
cachedAt: Date.now(),
227-
type: type,
228-
metadata,
229-
});
230-
231-
let contentPath = this.getCachedContentsPath(type);
232-
233-
if (type === "json" || type === "parsed-xml") {
234-
contents = JSON.stringify(contents);
235-
}
236-
237-
this.#rawContents[type] = contents;
238-
239-
if(this.options.dryRun) {
240-
debug(`Dry run writing ${contentPath}`);
241-
return;
242-
}
243-
244-
this.ensureDir();
216+
this.cache.set(type, contents, metadata);
245217

246-
debugAssets("[11ty/eleventy-fetch] Writing %o from %o", contentPath, this.source);
247-
248-
// the contents must exist before the cache metadata are saved below
249-
fs.writeFileSync(contentPath, contents);
250-
debug(`Writing ${contentPath}`);
251-
}
252-
253-
async #getCachedContents(type) {
254-
let contentPath = this.getCachedContentsPath(type);
255-
256-
debug(`Fetching from cache ${contentPath}`);
257-
258-
if(this.source) {
259-
debugAssets("[11ty/eleventy-fetch] Reading via %o", this.source);
260-
} else {
261-
debugAssets("[11ty/eleventy-fetch] Reading %o", contentPath);
262-
}
263-
264-
if (type === "json" || type === "parsed-xml") {
265-
return require(contentPath);
266-
}
267-
268-
return fs.readFileSync(contentPath, type !== "buffer" ? "utf8" : null);
218+
// Dry-run handled downstream
219+
this.#cache.save();
269220
}
270221

271-
async getCachedContents(type) {
272-
if(!this.#rawContents[type]) {
273-
this.#rawContents[type] = this.#getCachedContents(type);
274-
}
275-
276-
// already saved on this instance in-memory
277-
return this.#rawContents[type];
222+
getCachedContents() {
223+
return this.#cache.getContents();
278224
}
279225

280226
_backwardsCompatibilityGetCachedValue(type) {
@@ -288,23 +234,23 @@ class AssetCache {
288234
return Buffer.from(this.cachedObject.contents);
289235
}
290236

291-
async getCachedValue() {
237+
getCachedValue() {
292238
let type = this.cachedObject.type;
293239

294240
// backwards compat with old caches
241+
// v6+ caches use `data` as internal property for contents
295242
if (this.cachedObject.contents) {
296243
return this._backwardsCompatibilityGetCachedValue(type);
297244
}
298245

299246
if(this.options.returnType === "response") {
300247
return {
301248
...this.cachedObject.metadata?.response,
302-
body: await this.getCachedContents(type),
249+
body: this.getCachedContents(type),
303250
cache: "hit",
304251
}
305252
}
306253

307-
// promise
308254
return this.getCachedContents(type);
309255
}
310256

@@ -313,7 +259,7 @@ class AssetCache {
313259
}
314260

315261
isCacheValid(duration = this.duration) {
316-
if (!this.cachedObject) {
262+
if (!this.cachedObject || !this.cachedObject.cachedAt) {
317263
// not cached
318264
return false;
319265
}
@@ -322,7 +268,7 @@ class AssetCache {
322268
}
323269

324270
get cachedObject() {
325-
return this.cache.get(this.hash);
271+
return this.cache.get();
326272
}
327273

328274
// Deprecated
@@ -345,17 +291,18 @@ class AssetCache {
345291
}
346292

347293
// for testing
348-
hasCacheFiles() {
349-
return fs.existsSync(this.cachePath) || fs.existsSync(this.getCachedContentsPath());
294+
hasAnyCacheFiles() {
295+
for(let p of this.#cache.getFilePaths()) {
296+
if(fs.existsSync(p)) {
297+
return true;
298+
}
299+
}
300+
return false;
350301
}
351302

352303
// for testing
353304
async destroy() {
354-
let paths = [];
355-
paths.push(this.cachePath);
356-
paths.push(this.getCachedContentsPath("json"));
357-
paths.push(this.getCachedContentsPath("text"));
358-
paths.push(this.getCachedContentsPath("buffer"));
305+
let paths = this.#cache.getFilePaths();
359306

360307
await Promise.all(paths.map(path => {
361308
if (fs.existsSync(path)) {

src/DirectoryManager.js

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
const fs = require("node:fs");
2-
const debug = require("debug")("Eleventy:Assets");
2+
const debugAssets = require("debug")("Eleventy:Assets");
33

44
class DirectoryManager {
55
#dirs = new Set();
@@ -14,7 +14,7 @@ class DirectoryManager {
1414
}
1515

1616
this.#dirs.add(dir);
17-
debug("Creating directory %o", dir);
17+
debugAssets("Creating directory %o", dir);
1818
fs.mkdirSync(dir, { recursive: true });
1919
}
2020
}

src/FileCache.js

Lines changed: 104 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -1,26 +1,35 @@
11
const fs = require("node:fs");
22
const path = require("node:path");
3+
const debugUtil = require("debug");
4+
const debug = debugUtil("Eleventy:Fetch");
5+
const debugAssets = debugUtil("Eleventy:Assets");
36

47
const DirectoryManager = require("./DirectoryManager.js");
58
const ExistsCache = require("./ExistsCache.js");
69

710
let existsCache = new ExistsCache();
811

912
class FileCache {
13+
#source;
1014
#directoryManager;
11-
#data = {};
15+
#metadata;
16+
#contents;
1217
#dryRun = false;
1318
#cacheDirectory = ".cache";
19+
#savePending = false;
1420
#counts = {
1521
read: 0,
1622
write: 0,
17-
}
23+
};
1824

19-
constructor(cacheId, options = {}) {
20-
this.cacheId = cacheId;
25+
constructor(cacheFilename, options = {}) {
26+
this.cacheFilename = cacheFilename;
2127
if(options.dir) {
2228
this.#cacheDirectory = options.dir;
2329
}
30+
if(options.source) {
31+
this.#source = options.source;
32+
}
2433
}
2534

2635
setDryRun(val) {
@@ -44,39 +53,118 @@ class FileCache {
4453
this.#directoryManager.create(this.#cacheDirectory);
4554
}
4655

47-
set(id, obj) {
48-
if(this.#data[id] !== obj) {
49-
this.#data[id] = obj;
50-
this.save();
51-
}
56+
isSideLoaded() {
57+
return this.#metadata?.type === "buffer";
58+
}
59+
60+
set(type, contents, extraMetadata = {}) {
61+
this.#savePending = true;
62+
63+
this.#metadata = {
64+
cachedAt: Date.now(),
65+
type,
66+
// source: this.#source,
67+
metadata: extraMetadata,
68+
};
69+
70+
this.#contents = contents;
5271
}
5372

5473
get fsPath() {
55-
return path.join(this.#cacheDirectory, this.cacheId);
74+
return path.join(this.#cacheDirectory, this.cacheFilename);
75+
}
76+
77+
// only when side loaded (buffer content)
78+
get contentsPath() {
79+
return `${this.fsPath}.buffer`;
5680
}
5781

58-
get(id) {
59-
if(this.#data[id]) {
60-
return this.#data[id];
82+
get() {
83+
if(this.#metadata) {
84+
return this.#metadata;
6185
}
6286

6387
if(!existsCache.exists(this.fsPath)) {
6488
return;
6589
}
6690

67-
this.#counts.read++;
91+
debug(`Fetching from cache ${this.contentsPath}`);
92+
if(this.#source) {
93+
debugAssets("[11ty/eleventy-fetch] Reading via %o", this.#source);
94+
} else {
95+
debugAssets("[11ty/eleventy-fetch] Reading %o", this.contentsPath);
96+
}
6897

98+
this.#counts.read++;
6999
let data = fs.readFileSync(this.fsPath, "utf8");
70100
let json = JSON.parse(data);
71-
this.#data[id] = json;
101+
this.#metadata = json;
102+
103+
if(json.data) { // not side-loaded
104+
this.#contents = json.data;
105+
}
106+
72107
return json;
73108
}
74109

110+
getContents() {
111+
if(this.#contents) {
112+
return this.#contents;
113+
}
114+
// Side loaded contents are embedded inside, but we check (for backwards compat)
115+
if(!this.isSideLoaded() && this.get()?.data) {
116+
return this.get()?.data;
117+
}
118+
119+
if(!existsCache.exists(this.contentsPath)) {
120+
return;
121+
}
122+
123+
debug(`Fetching from cache ${this.contentsPath}`);
124+
if(this.#source) {
125+
debugAssets("[11ty/eleventy-fetch] Reading (side loaded) via %o", this.#source);
126+
} else {
127+
debugAssets("[11ty/eleventy-fetch] Reading (side loaded) %o", this.contentsPath);
128+
}
129+
130+
this.#counts.read++;
131+
let data = fs.readFileSync(this.contentsPath, null);
132+
this.#contents = data;
133+
return data;
134+
}
135+
75136
save() {
137+
if(this.#dryRun || !this.#savePending || this.#metadata && Object.keys(this.#metadata) === 0) {
138+
return;
139+
}
140+
76141
this.ensureDir(); // doesn’t add to counts (yet?)
77142

143+
// contents before metadata
144+
if(this.isSideLoaded()) {
145+
debugAssets("[11ty/eleventy-fetch] Writing %o (side loaded) from %o", this.contentsPath, this.#source);
146+
147+
this.#counts.write++;
148+
149+
// the contents must exist before the cache metadata are saved below
150+
fs.writeFileSync(this.contentsPath, contents);
151+
debug(`Writing ${this.contentsPath}`);
152+
}
153+
78154
this.#counts.write++;
79-
fs.writeFileSync(this.fsPath, JSON.stringify(this.#data), "utf8");
155+
debugAssets("[11ty/eleventy-fetch] Writing %o from %o", this.fsPath, this.#source);
156+
fs.writeFileSync(this.fsPath, JSON.stringify(Object.assign({}, this.#metadata, { data: this.#contents })), "utf8");
157+
debug(`Writing ${this.fsPath}`);
158+
}
159+
160+
// for testing
161+
getFilePaths() {
162+
let paths = new Set();
163+
paths.add(this.fsPath);
164+
if(this.isSideLoaded()) {
165+
paths.add(this.contentsPath);
166+
}
167+
return Array.from(paths);
80168
}
81169
}
82170

0 commit comments

Comments
 (0)