diff --git a/packages/gatsby-plugin-sharp/src/gatsby-node.js b/packages/gatsby-plugin-sharp/src/gatsby-node.js index 45c965277912c..63ef17195a242 100644 --- a/packages/gatsby-plugin-sharp/src/gatsby-node.js +++ b/packages/gatsby-plugin-sharp/src/gatsby-node.js @@ -21,6 +21,19 @@ try { coreSupportsOnPluginInit = false } +function removeCachedValue(cache, key) { + if (cache?.del) { + // if cache expose ".del" method directly on public interface + return cache.del(key) + } else if (cache?.cache?.del) { + // legacy - using internal cache instance and calling ".del" on it directly + return cache.cache.del(key) + } + return Promise.reject( + new Error(`Cache instance doesn't expose ".del" function`) + ) +} + exports.onCreateDevServer = async ({ app, cache, reporter }) => { if (!_lazyJobsEnabled()) { return @@ -53,14 +66,14 @@ exports.onCreateDevServer = async ({ app, cache, reporter }) => { } = splitOperationsByRequestedFile(cacheResult, pathOnDisk) await _unstable_createJob(matchingJob, { reporter }) - await cache.cache.del(decodedURI) + await removeCachedValue(cache, decodedURI) if (jobWithRemainingOperations.args.operations.length > 0) { // There are still some operations pending for this job - replace the cached job - await cache.cache.set(jobContentDigest, jobWithRemainingOperations) + await cache.set(jobContentDigest, jobWithRemainingOperations) } else { // No operations left to process - purge the cache - await cache.cache.del(jobContentDigest) + await removeCachedValue(cache, jobContentDigest) } return res.sendFile(pathOnDisk) diff --git a/packages/gatsby/index.d.ts b/packages/gatsby/index.d.ts index 1353e706f4d5b..824e85a162127 100644 --- a/packages/gatsby/index.d.ts +++ b/packages/gatsby/index.d.ts @@ -1279,6 +1279,15 @@ export interface GatsbyCache { * await cache.set(`unique-key`, value) */ set(key: string, value: any): Promise + + /** + * Deletes cached value + * @param {string} key Cache key + * @returns {Promise} Promise resolving once key is deleted from cache + * @example + * await cache.del(`unique-key`) + */ + del(key: string): Promise } export interface Tracing { diff --git a/packages/gatsby/src/utils/api-node-helpers-docs.js b/packages/gatsby/src/utils/api-node-helpers-docs.js index f100aa568c207..abd8eb25e91bb 100644 --- a/packages/gatsby/src/utils/api-node-helpers-docs.js +++ b/packages/gatsby/src/utils/api-node-helpers-docs.js @@ -99,6 +99,15 @@ const GatsbyCache = { * await cache.set(`unique-key`, value) */ set: true, + + /** + * Deletes cached value + * @param {string} key Cache key + * @returns {Promise} Promise resolving once key is deleted from cache + * @example + * await cache.del(`unique-key`) + */ + del: true, }; /***/ diff --git a/packages/gatsby/src/utils/api-runner-node.js b/packages/gatsby/src/utils/api-runner-node.js index cadf43e9827bf..172a4ae538857 100644 --- a/packages/gatsby/src/utils/api-runner-node.js +++ b/packages/gatsby/src/utils/api-runner-node.js @@ -240,6 +240,9 @@ const getUninitializedCache = plugin => { async set() { throw new Error(message) }, + async del() { + throw new Error(message) + }, } } diff --git a/packages/gatsby/src/utils/cache-lmdb.ts b/packages/gatsby/src/utils/cache-lmdb.ts index 4182c3040f300..15170e07ebc5d 100644 --- a/packages/gatsby/src/utils/cache-lmdb.ts +++ b/packages/gatsby/src/utils/cache-lmdb.ts @@ -19,10 +19,15 @@ export default class GatsbyCacheLmdb { public readonly name: string // Needed for plugins that want to write data to the cache directory public readonly directory: string + // TODO: remove `.cache` in v4. This is compat mode - cache-manager cache implementation + // expose internal cache that gives access to `.del` function that wasn't available in public + // cache interface (gatsby-plugin-sharp use it to clear no longer needed data) + public readonly cache: GatsbyCacheLmdb constructor({ name = `db` }: { name: string }) { this.name = name this.directory = path.join(process.cwd(), `.cache/caches/${name}`) + this.cache = this } init(): GatsbyCacheLmdb { @@ -59,4 +64,8 @@ export default class GatsbyCacheLmdb { await this.getDb().put(key, value) return value } + + async del(key: string): Promise { + return (this.getDb().remove(key) as unknown) as Promise + } } diff --git a/packages/gatsby/src/utils/cache.ts b/packages/gatsby/src/utils/cache.ts index 2fc59f13f7e8b..442a414374dad 100644 --- a/packages/gatsby/src/utils/cache.ts +++ b/packages/gatsby/src/utils/cache.ts @@ -20,6 +20,9 @@ export default class GatsbyCache { public name: string public store: Store public directory: string + // TODO: remove `.cache` in v4. This is compat mode - cache-manager cache implementation + // expose internal cache that gives access to `.del` function that wasn't available in public + // cache interface (gatsby-plugin-sharp use it to clear no longer needed data) public cache?: MultiCache // @ts-ignore - set & get types are missing from fsStore? @@ -84,4 +87,14 @@ export default class GatsbyCache { }) }) } + + async del(key: string): Promise { + if (!this.cache) { + throw new Error( + `GatsbyCache wasn't initialised yet, please run the init method first` + ) + } + + return this.cache.del(key) + } }