@lage-run/cache 1.4.4 → 1.4.6
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +16 -13
- package/lib/providers/BackfillCacheProvider.d.ts +1 -1
- package/lib/providers/BackfillCacheProvider.js.map +1 -1
- package/lib/providers/RemoteFallbackCacheProvider.js.map +1 -1
- package/package.json +12 -10
- package/CHANGELOG.json +0 -1381
- package/CHANGELOG.md +0 -609
- package/jest.config.js +0 -1
- package/tsconfig.json +0 -7
package/README.md
CHANGED
|
@@ -2,16 +2,18 @@
|
|
|
2
2
|
|
|
3
3
|
This package provides:
|
|
4
4
|
|
|
5
|
-
1. `
|
|
6
|
-
2. a default cache provider that uses `backfill`
|
|
5
|
+
1. `CacheProvider` interface
|
|
6
|
+
2. a default cache provider that uses [`backfill`](https://www.npmjs.com/package/backfill)
|
|
7
7
|
|
|
8
8
|
## Usage
|
|
9
9
|
|
|
10
|
+
The following example shows standalone cache usage. If you're using the `lage` CLI, provider creation is handled internally (though you can customize `cacheOptions` in `lage.config.js`).
|
|
11
|
+
|
|
10
12
|
```ts
|
|
11
|
-
import { BackfillCacheProvider, RemoteFallbackCacheProvider, TargetHasher } from "@lage-run/cache";
|
|
13
|
+
import { BackfillCacheProvider, RemoteFallbackCacheProvider, TargetHasher, type CacheOptions } from "@lage-run/cache";
|
|
12
14
|
import { getWorkspaceManagerRoot } from "workspace-tools";
|
|
13
15
|
|
|
14
|
-
const cacheOptions = {
|
|
16
|
+
const cacheOptions: CacheOptions = {
|
|
15
17
|
internalCacheFolder: ".cache",
|
|
16
18
|
outputGlob: ["dist/**", "lib/**"]
|
|
17
19
|
}
|
|
@@ -33,10 +35,13 @@ const remoteFallbackCacheProviderOptions = {
|
|
|
33
35
|
cacheStorageOptions: {
|
|
34
36
|
provider: "azure-blob",
|
|
35
37
|
options: {
|
|
36
|
-
|
|
38
|
+
// This connection string can optionally contain credentials.
|
|
39
|
+
// If no credentials are present, see credentialName below.
|
|
40
|
+
connectionString: "asdfasdfasdfafds";
|
|
37
41
|
container: "container";
|
|
38
42
|
maxSize?: 150;
|
|
39
|
-
|
|
43
|
+
// If connectionString doesn't have credentials, specify a supported credential type
|
|
44
|
+
credentialName?: "environment"
|
|
40
45
|
}
|
|
41
46
|
},
|
|
42
47
|
...cacheOptions
|
|
@@ -71,16 +76,14 @@ if (target.cache && !skipCaching) {
|
|
|
71
76
|
await cacheProvider.put(hash, target);
|
|
72
77
|
```
|
|
73
78
|
|
|
74
|
-
## Differentiating
|
|
75
|
-
|
|
76
|
-
To specifically differentiate the hash generated for the cache, between different steps the parameter `cacheKey` can be used. The parameter will be a part of the hash generation for the cache, and generated hash can be altered by modifying the parameter.
|
|
79
|
+
## Differentiating cache
|
|
77
80
|
|
|
78
|
-
|
|
81
|
+
`CacheOptions.cacheKey` is included in the hash and can be used to differentiate the hash generated for the cache between different steps, or to invalidate the cache.
|
|
79
82
|
|
|
80
|
-
|
|
83
|
+
Example of usage in `lage.config.js`:
|
|
81
84
|
|
|
82
|
-
```
|
|
83
|
-
{
|
|
85
|
+
```js
|
|
86
|
+
module.exports = {
|
|
84
87
|
cacheOptions: {
|
|
85
88
|
cacheKey: "some cache key";
|
|
86
89
|
}
|
|
@@ -19,5 +19,5 @@ export declare class BackfillCacheProvider implements CacheProvider {
|
|
|
19
19
|
put(hash: string, target: Target): Promise<void>;
|
|
20
20
|
clear(concurrency?: number): Promise<void>;
|
|
21
21
|
purge(prunePeriod?: number, concurrency?: number): Promise<void>;
|
|
22
|
-
getCachePath
|
|
22
|
+
private getCachePath;
|
|
23
23
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/providers/BackfillCacheProvider.ts"],"sourcesContent":["import { createBackfillCacheConfig, createBackfillLogger } from \"../backfillWrapper.js\";\nimport { getCacheStorageProvider } from \"backfill-cache\";\nimport { promisify } from \"util\";\nimport * as fs from \"fs\";\nimport * as path from \"path\";\nimport type { CacheProvider } from \"../types/CacheProvider.js\";\nimport type { CacheOptions } from \"@lage-run/config\";\nimport type { Logger as BackfillLogger } from \"backfill-logger\";\nimport type { Target } from \"@lage-run/target-graph\";\nimport type { Logger } from \"@lage-run/logger\";\nimport { getCacheDirectory, getCacheDirectoryRoot } from \"../getCacheDirectory.js\";\nimport { chunkPromise } from \"../chunkPromise.js\";\n\nconst rm = promisify(fs.rm);\nconst readdir = promisify(fs.readdir);\nconst stat = promisify(fs.stat);\n\nconst MS_IN_A_DAY = 1000 * 60 * 60 * 24;\n\nexport interface BackfillCacheProviderOptions {\n root: string;\n logger: Logger;\n cacheOptions: Partial<CacheOptions>;\n}\n\nexport class BackfillCacheProvider implements CacheProvider {\n /**\n * logger for backfill\n */\n private backfillLogger: BackfillLogger;\n\n private getTargetCacheStorageProvider(cwd: string, hash: string) {\n const { cacheOptions } = this.options;\n const { cacheStorageConfig, incrementalCaching } = createBackfillCacheConfig(cwd, cacheOptions, this.backfillLogger);\n\n const cachePath = this.getCachePath(cwd, hash);\n\n return getCacheStorageProvider(cacheStorageConfig ?? { provider: \"local\" }, cachePath, this.backfillLogger, cwd, incrementalCaching);\n }\n\n constructor(private options: BackfillCacheProviderOptions) {\n this.backfillLogger = createBackfillLogger();\n }\n\n async fetch(hash: string, target: Target): Promise<boolean> {\n const { logger } = this.options;\n\n if (!hash) {\n return false;\n }\n\n const cacheStorage = this.getTargetCacheStorageProvider(target.cwd, hash);\n\n try {\n return await cacheStorage.fetch(hash);\n } catch (error) {\n let message;\n\n if (error instanceof Error) {\n message = error.message;\n } else message = String(error);\n\n logger.silly(`Cache fetch failed: ${message}`, { target });\n\n // backfill fetch can error, but we should simply ignore and continue\n return false;\n }\n }\n\n async put(hash: string, target: Target): Promise<void> {\n const { logger } = this.options;\n\n if (!hash) {\n return;\n }\n\n const cacheStorage = this.getTargetCacheStorageProvider(target.cwd, hash);\n\n try {\n await cacheStorage.put(hash, target.outputs ?? this.options.cacheOptions.outputGlob ?? [\"**/*\"]);\n } catch (error) {\n let message;\n\n if (error instanceof Error) {\n message = error.message;\n } else message = String(error);\n\n logger.silly(`Cache fetch failed: ${message}`, { target });\n\n // backfill throws an error if outputGlob doesn't match any files, we will skip this error\n }\n }\n\n async clear(concurrency = 10): Promise<void> {\n return this.purge(0, concurrency);\n }\n\n async purge(prunePeriod = 30, concurrency = 10): Promise<void> {\n const now = new Date();\n\n const cacheTypes = [\"cache\", \"logs\"];\n const entries: string[] = [];\n\n for (const cacheType of cacheTypes) {\n const cacheTypeDirectory = path.join(getCacheDirectoryRoot(this.options.root), cacheType);\n if (fs.existsSync(cacheTypeDirectory)) {\n const hashPrefixes = await readdir(cacheTypeDirectory);\n for (const prefix of hashPrefixes) {\n const cachePath = path.join(cacheTypeDirectory, prefix);\n entries.push(cachePath);\n }\n }\n }\n\n await chunkPromise(\n entries.map((entry) => {\n return async () => {\n const entryPath = entry;\n const entryStat = await stat(entryPath);\n\n if (now.getTime() - entryStat.mtime.getTime() > prunePeriod * MS_IN_A_DAY) {\n await removeCache(entryPath, entryStat);\n }\n };\n }),\n concurrency\n );\n }\n\n getCachePath(packagePath: string, hash: string): string {\n return path.relative(packagePath, getCacheDirectory(this.options.root, hash));\n }\n}\n\nasync function removeCache(cachePath: string, entryStat: fs.Stats) {\n if (entryStat.isDirectory()) {\n return rm(cachePath, { recursive: true });\n } else {\n return rm(cachePath);\n }\n}\n"],"names":["BackfillCacheProvider","rm","promisify","fs","readdir","stat","MS_IN_A_DAY","getTargetCacheStorageProvider","cwd","hash","cacheOptions","options","cacheStorageConfig","incrementalCaching","createBackfillCacheConfig","backfillLogger","cachePath","getCachePath","getCacheStorageProvider","provider","fetch","target","logger","cacheStorage","error","message","Error","String","silly","put","outputs","outputGlob","clear","concurrency","purge","prunePeriod","now","Date","cacheTypes","entries","cacheType","cacheTypeDirectory","path","join","getCacheDirectoryRoot","root","existsSync","hashPrefixes","prefix","push","chunkPromise","map","entry","entryPath","entryStat","getTime","mtime","removeCache","packagePath","relative","getCacheDirectory","createBackfillLogger","isDirectory","recursive"],"mappings":";;;;+BAyBaA;;;eAAAA;;;iCAzBmD;+BACxB;sBACd;4DACN;8DACE;mCAMmC;8BAC5B;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAE7B,MAAMC,KAAKC,IAAAA,eAAS,EAACC,IAAGF,EAAE;AAC1B,MAAMG,UAAUF,IAAAA,eAAS,EAACC,IAAGC,OAAO;AACpC,MAAMC,OAAOH,IAAAA,eAAS,EAACC,IAAGE,IAAI;AAE9B,MAAMC,cAAc,OAAO,KAAK,KAAK;AAQ9B,MAAMN;IAMHO,8BAA8BC,GAAW,EAAEC,IAAY,EAAE;QAC/D,MAAM,EAAEC,YAAY,EAAE,GAAG,IAAI,CAACC,OAAO;QACrC,MAAM,EAAEC,kBAAkB,EAAEC,kBAAkB,EAAE,GAAGC,IAAAA,0CAAyB,EAACN,KAAKE,cAAc,IAAI,CAACK,cAAc;QAEnH,MAAMC,YAAY,IAAI,CAACC,YAAY,CAACT,KAAKC;QAEzC,OAAOS,IAAAA,sCAAuB,EAACN,sBAAsB;YAAEO,UAAU;QAAQ,GAAGH,WAAW,IAAI,CAACD,cAAc,EAAEP,KAAKK;IACnH;IAMA,
|
|
1
|
+
{"version":3,"sources":["../../src/providers/BackfillCacheProvider.ts"],"sourcesContent":["import { createBackfillCacheConfig, createBackfillLogger } from \"../backfillWrapper.js\";\nimport { getCacheStorageProvider } from \"backfill-cache\";\nimport { promisify } from \"util\";\nimport * as fs from \"fs\";\nimport * as path from \"path\";\nimport type { CacheProvider } from \"../types/CacheProvider.js\";\nimport type { CacheOptions } from \"@lage-run/config\";\nimport type { Logger as BackfillLogger } from \"backfill-logger\";\nimport type { Target } from \"@lage-run/target-graph\";\nimport type { Logger } from \"@lage-run/logger\";\nimport { getCacheDirectory, getCacheDirectoryRoot } from \"../getCacheDirectory.js\";\nimport { chunkPromise } from \"../chunkPromise.js\";\n\nconst rm = promisify(fs.rm);\nconst readdir = promisify(fs.readdir);\nconst stat = promisify(fs.stat);\n\nconst MS_IN_A_DAY = 1000 * 60 * 60 * 24;\n\nexport interface BackfillCacheProviderOptions {\n root: string;\n logger: Logger;\n cacheOptions: Partial<CacheOptions>;\n}\n\nexport class BackfillCacheProvider implements CacheProvider {\n /**\n * logger for backfill\n */\n private backfillLogger: BackfillLogger;\n\n private getTargetCacheStorageProvider(cwd: string, hash: string) {\n const { cacheOptions } = this.options;\n const { cacheStorageConfig, incrementalCaching } = createBackfillCacheConfig(cwd, cacheOptions, this.backfillLogger);\n\n const cachePath = this.getCachePath(cwd, hash);\n\n return getCacheStorageProvider(cacheStorageConfig ?? { provider: \"local\" }, cachePath, this.backfillLogger, cwd, incrementalCaching);\n }\n\n constructor(private options: BackfillCacheProviderOptions) {\n this.backfillLogger = createBackfillLogger();\n }\n\n public async fetch(hash: string, target: Target): Promise<boolean> {\n const { logger } = this.options;\n\n if (!hash) {\n return false;\n }\n\n const cacheStorage = this.getTargetCacheStorageProvider(target.cwd, hash);\n\n try {\n return await cacheStorage.fetch(hash);\n } catch (error) {\n let message;\n\n if (error instanceof Error) {\n message = error.message;\n } else message = String(error);\n\n logger.silly(`Cache fetch failed: ${message}`, { target });\n\n // backfill fetch can error, but we should simply ignore and continue\n return false;\n }\n }\n\n public async put(hash: string, target: Target): Promise<void> {\n const { logger } = this.options;\n\n if (!hash) {\n return;\n }\n\n const cacheStorage = this.getTargetCacheStorageProvider(target.cwd, hash);\n\n try {\n await cacheStorage.put(hash, target.outputs ?? this.options.cacheOptions.outputGlob ?? [\"**/*\"]);\n } catch (error) {\n let message;\n\n if (error instanceof Error) {\n message = error.message;\n } else message = String(error);\n\n logger.silly(`Cache fetch failed: ${message}`, { target });\n\n // backfill throws an error if outputGlob doesn't match any files, we will skip this error\n }\n }\n\n public async clear(concurrency = 10): Promise<void> {\n return this.purge(0, concurrency);\n }\n\n public async purge(prunePeriod = 30, concurrency = 10): Promise<void> {\n const now = new Date();\n\n const cacheTypes = [\"cache\", \"logs\"];\n const entries: string[] = [];\n\n for (const cacheType of cacheTypes) {\n const cacheTypeDirectory = path.join(getCacheDirectoryRoot(this.options.root), cacheType);\n if (fs.existsSync(cacheTypeDirectory)) {\n const hashPrefixes = await readdir(cacheTypeDirectory);\n for (const prefix of hashPrefixes) {\n const cachePath = path.join(cacheTypeDirectory, prefix);\n entries.push(cachePath);\n }\n }\n }\n\n await chunkPromise(\n entries.map((entry) => {\n return async () => {\n const entryPath = entry;\n const entryStat = await stat(entryPath);\n\n if (now.getTime() - entryStat.mtime.getTime() > prunePeriod * MS_IN_A_DAY) {\n await removeCache(entryPath, entryStat);\n }\n };\n }),\n concurrency\n );\n }\n\n private getCachePath(packagePath: string, hash: string): string {\n return path.relative(packagePath, getCacheDirectory(this.options.root, hash));\n }\n}\n\nasync function removeCache(cachePath: string, entryStat: fs.Stats) {\n if (entryStat.isDirectory()) {\n return rm(cachePath, { recursive: true });\n } else {\n return rm(cachePath);\n }\n}\n"],"names":["BackfillCacheProvider","rm","promisify","fs","readdir","stat","MS_IN_A_DAY","getTargetCacheStorageProvider","cwd","hash","cacheOptions","options","cacheStorageConfig","incrementalCaching","createBackfillCacheConfig","backfillLogger","cachePath","getCachePath","getCacheStorageProvider","provider","fetch","target","logger","cacheStorage","error","message","Error","String","silly","put","outputs","outputGlob","clear","concurrency","purge","prunePeriod","now","Date","cacheTypes","entries","cacheType","cacheTypeDirectory","path","join","getCacheDirectoryRoot","root","existsSync","hashPrefixes","prefix","push","chunkPromise","map","entry","entryPath","entryStat","getTime","mtime","removeCache","packagePath","relative","getCacheDirectory","createBackfillLogger","isDirectory","recursive"],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/providers/RemoteFallbackCacheProvider.ts"],"sourcesContent":["import type { CacheProvider } from \"../types/CacheProvider.js\";\nimport type { Logger } from \"@lage-run/logger\";\nimport type { Target } from \"@lage-run/target-graph\";\n\nexport interface RemoteFallbackCacheProviderOptions {\n root: string;\n logger: Logger;\n\n localCacheProvider?: CacheProvider;\n remoteCacheProvider?: CacheProvider;\n\n writeRemoteCache?: boolean;\n}\n\n/**\n * Remote Fallback Cache Provider\n *\n * This backfill cache provider will fallback to a remote cache provider if the local cache does not contain the item.\n * It will also automatically populate the local cache with the remote cache.\n */\nexport class RemoteFallbackCacheProvider implements CacheProvider {\n private static localHits: { [hash: string]: boolean } = {};\n private static remoteHits: { [hash: string]: boolean } = {};\n\n constructor(private options: RemoteFallbackCacheProviderOptions) {}\n\n async fetch(hash: string, target: Target): Promise<boolean> {\n const { logger, remoteCacheProvider, localCacheProvider } = this.options;\n\n if (localCacheProvider) {\n RemoteFallbackCacheProvider.localHits[hash] = await localCacheProvider.fetch(hash, target);\n logger.silly(`local cache fetch: ${hash} ${RemoteFallbackCacheProvider.localHits[hash]}`);\n }\n\n if (!RemoteFallbackCacheProvider.localHits[hash] && remoteCacheProvider) {\n RemoteFallbackCacheProvider.remoteHits[hash] = await remoteCacheProvider.fetch(hash, target);\n logger.silly(`remote fallback fetch: ${hash} ${RemoteFallbackCacheProvider.remoteHits[hash]}`);\n\n // now save this into the localCacheProvider, if available\n if (localCacheProvider && RemoteFallbackCacheProvider.remoteHits[hash]) {\n logger.silly(`local cache put, fetched cache from remote: ${hash}`);\n await localCacheProvider.put(hash, target);\n }\n\n return RemoteFallbackCacheProvider.remoteHits[hash];\n }\n\n return RemoteFallbackCacheProvider.localHits[hash];\n }\n\n async put(hash: string, target: Target): Promise<void> {\n const { logger, remoteCacheProvider, localCacheProvider, writeRemoteCache } = this.options;\n const putPromises: Promise<void>[] = [];\n\n // Write local cache if it doesn't already exist, or if the the hash isn't in the localHits\n const shouldWriteLocalCache = !this.isLocalHit(hash) && !!localCacheProvider;\n\n if (shouldWriteLocalCache) {\n logger.silly(`local cache put: ${hash}`);\n putPromises.push(localCacheProvider.put(hash, target));\n }\n\n // Write to remote if there is a no hit in the remote cache, and remote cache storage provider, and that the \"writeRemoteCache\" config flag is set to true\n const shouldWriteRemoteCache = !this.isRemoteHit(hash) && !!remoteCacheProvider && writeRemoteCache;\n\n if (shouldWriteRemoteCache) {\n logger.silly(`remote fallback put: ${hash}`);\n const remotePut = remoteCacheProvider.put(hash, target);\n putPromises.push(remotePut);\n }\n\n await Promise.all(putPromises);\n }\n\n private isRemoteHit(hash: string) {\n return hash in RemoteFallbackCacheProvider.remoteHits && RemoteFallbackCacheProvider.remoteHits[hash];\n }\n\n private isLocalHit(hash: string) {\n return hash in RemoteFallbackCacheProvider.localHits && RemoteFallbackCacheProvider.localHits[hash];\n }\n\n async clear(): Promise<void> {\n const { localCacheProvider } = this.options;\n if (localCacheProvider) {\n return localCacheProvider.clear();\n }\n }\n\n async purge(sinceDays: number): Promise<void> {\n const { localCacheProvider } = this.options;\n if (localCacheProvider) {\n return localCacheProvider.purge(sinceDays);\n }\n }\n}\n"],"names":["RemoteFallbackCacheProvider","fetch","hash","target","logger","remoteCacheProvider","localCacheProvider","options","localHits","silly","remoteHits","put","writeRemoteCache","putPromises","shouldWriteLocalCache","isLocalHit","push","shouldWriteRemoteCache","isRemoteHit","remotePut","Promise","all","clear","purge","sinceDays"],"mappings":";;;;+BAoBaA;;;eAAAA;;;;;;;;;;;;;;;;AAAN,MAAMA;IAMX,
|
|
1
|
+
{"version":3,"sources":["../../src/providers/RemoteFallbackCacheProvider.ts"],"sourcesContent":["import type { CacheProvider } from \"../types/CacheProvider.js\";\nimport type { Logger } from \"@lage-run/logger\";\nimport type { Target } from \"@lage-run/target-graph\";\n\nexport interface RemoteFallbackCacheProviderOptions {\n root: string;\n logger: Logger;\n\n localCacheProvider?: CacheProvider;\n remoteCacheProvider?: CacheProvider;\n\n writeRemoteCache?: boolean;\n}\n\n/**\n * Remote Fallback Cache Provider\n *\n * This backfill cache provider will fallback to a remote cache provider if the local cache does not contain the item.\n * It will also automatically populate the local cache with the remote cache.\n */\nexport class RemoteFallbackCacheProvider implements CacheProvider {\n private static localHits: { [hash: string]: boolean } = {};\n private static remoteHits: { [hash: string]: boolean } = {};\n\n constructor(private options: RemoteFallbackCacheProviderOptions) {}\n\n public async fetch(hash: string, target: Target): Promise<boolean> {\n const { logger, remoteCacheProvider, localCacheProvider } = this.options;\n\n if (localCacheProvider) {\n RemoteFallbackCacheProvider.localHits[hash] = await localCacheProvider.fetch(hash, target);\n logger.silly(`local cache fetch: ${hash} ${RemoteFallbackCacheProvider.localHits[hash]}`);\n }\n\n if (!RemoteFallbackCacheProvider.localHits[hash] && remoteCacheProvider) {\n RemoteFallbackCacheProvider.remoteHits[hash] = await remoteCacheProvider.fetch(hash, target);\n logger.silly(`remote fallback fetch: ${hash} ${RemoteFallbackCacheProvider.remoteHits[hash]}`);\n\n // now save this into the localCacheProvider, if available\n if (localCacheProvider && RemoteFallbackCacheProvider.remoteHits[hash]) {\n logger.silly(`local cache put, fetched cache from remote: ${hash}`);\n await localCacheProvider.put(hash, target);\n }\n\n return RemoteFallbackCacheProvider.remoteHits[hash];\n }\n\n return RemoteFallbackCacheProvider.localHits[hash];\n }\n\n public async put(hash: string, target: Target): Promise<void> {\n const { logger, remoteCacheProvider, localCacheProvider, writeRemoteCache } = this.options;\n const putPromises: Promise<void>[] = [];\n\n // Write local cache if it doesn't already exist, or if the the hash isn't in the localHits\n const shouldWriteLocalCache = !this.isLocalHit(hash) && !!localCacheProvider;\n\n if (shouldWriteLocalCache) {\n logger.silly(`local cache put: ${hash}`);\n putPromises.push(localCacheProvider.put(hash, target));\n }\n\n // Write to remote if there is a no hit in the remote cache, and remote cache storage provider, and that the \"writeRemoteCache\" config flag is set to true\n const shouldWriteRemoteCache = !this.isRemoteHit(hash) && !!remoteCacheProvider && writeRemoteCache;\n\n if (shouldWriteRemoteCache) {\n logger.silly(`remote fallback put: ${hash}`);\n const remotePut = remoteCacheProvider.put(hash, target);\n putPromises.push(remotePut);\n }\n\n await Promise.all(putPromises);\n }\n\n private isRemoteHit(hash: string) {\n return hash in RemoteFallbackCacheProvider.remoteHits && RemoteFallbackCacheProvider.remoteHits[hash];\n }\n\n private isLocalHit(hash: string) {\n return hash in RemoteFallbackCacheProvider.localHits && RemoteFallbackCacheProvider.localHits[hash];\n }\n\n public async clear(): Promise<void> {\n const { localCacheProvider } = this.options;\n if (localCacheProvider) {\n return localCacheProvider.clear();\n }\n }\n\n public async purge(sinceDays: number): Promise<void> {\n const { localCacheProvider } = this.options;\n if (localCacheProvider) {\n return localCacheProvider.purge(sinceDays);\n }\n }\n}\n"],"names":["RemoteFallbackCacheProvider","fetch","hash","target","logger","remoteCacheProvider","localCacheProvider","options","localHits","silly","remoteHits","put","writeRemoteCache","putPromises","shouldWriteLocalCache","isLocalHit","push","shouldWriteRemoteCache","isRemoteHit","remotePut","Promise","all","clear","purge","sinceDays"],"mappings":";;;;+BAoBaA;;;eAAAA;;;;;;;;;;;;;;;;AAAN,MAAMA;IAMX,MAAaC,MAAMC,IAAY,EAAEC,MAAc,EAAoB;QACjE,MAAM,EAAEC,MAAM,EAAEC,mBAAmB,EAAEC,kBAAkB,EAAE,GAAG,IAAI,CAACC,OAAO;QAExE,IAAID,oBAAoB;YACtBN,4BAA4BQ,SAAS,CAACN,KAAK,GAAG,MAAMI,mBAAmBL,KAAK,CAACC,MAAMC;YACnFC,OAAOK,KAAK,CAAC,CAAC,mBAAmB,EAAEP,KAAK,CAAC,EAAEF,4BAA4BQ,SAAS,CAACN,KAAK,EAAE;QAC1F;QAEA,IAAI,CAACF,4BAA4BQ,SAAS,CAACN,KAAK,IAAIG,qBAAqB;YACvEL,4BAA4BU,UAAU,CAACR,KAAK,GAAG,MAAMG,oBAAoBJ,KAAK,CAACC,MAAMC;YACrFC,OAAOK,KAAK,CAAC,CAAC,uBAAuB,EAAEP,KAAK,CAAC,EAAEF,4BAA4BU,UAAU,CAACR,KAAK,EAAE;YAE7F,0DAA0D;YAC1D,IAAII,sBAAsBN,4BAA4BU,UAAU,CAACR,KAAK,EAAE;gBACtEE,OAAOK,KAAK,CAAC,CAAC,4CAA4C,EAAEP,MAAM;gBAClE,MAAMI,mBAAmBK,GAAG,CAACT,MAAMC;YACrC;YAEA,OAAOH,4BAA4BU,UAAU,CAACR,KAAK;QACrD;QAEA,OAAOF,4BAA4BQ,SAAS,CAACN,KAAK;IACpD;IAEA,MAAaS,IAAIT,IAAY,EAAEC,MAAc,EAAiB;QAC5D,MAAM,EAAEC,MAAM,EAAEC,mBAAmB,EAAEC,kBAAkB,EAAEM,gBAAgB,EAAE,GAAG,IAAI,CAACL,OAAO;QAC1F,MAAMM,cAA+B,EAAE;QAEvC,2FAA2F;QAC3F,MAAMC,wBAAwB,CAAC,IAAI,CAACC,UAAU,CAACb,SAAS,CAAC,CAACI;QAE1D,IAAIQ,uBAAuB;YACzBV,OAAOK,KAAK,CAAC,CAAC,iBAAiB,EAAEP,MAAM;YACvCW,YAAYG,IAAI,CAACV,mBAAmBK,GAAG,CAACT,MAAMC;QAChD;QAEA,0JAA0J;QAC1J,MAAMc,yBAAyB,CAAC,IAAI,CAACC,WAAW,CAAChB,SAAS,CAAC,CAACG,uBAAuBO;QAEnF,IAAIK,wBAAwB;YAC1Bb,OAAOK,KAAK,CAAC,CAAC,qBAAqB,EAAEP,MAAM;YAC3C,MAAMiB,YAAYd,oBAAoBM,GAAG,CAACT,MAAMC;YAChDU,YAAYG,IAAI,CAACG;QACnB;QAEA,MAAMC,QAAQC,GAAG,CAACR;IACpB;IAEQK,YAAYhB,IAAY,EAAE;QAChC,OAAOA,QAAQF,4BAA4BU,UAAU,IAAIV,4BAA4BU,UAAU,CAACR,KAAK;IACvG;IAEQa,WAAWb,IAAY,EAAE;QAC/B,OAAOA,QAAQF,4BAA4BQ,SAAS,IAAIR,4BAA4BQ,SAAS,CAACN,KAAK;IACrG;IAEA,MAAaoB,QAAuB;QAClC,MAAM,EAAEhB,kBAAkB,EAAE,GAAG,IAAI,CAACC,OAAO;QAC3C,IAAID,oBAAoB;YACtB,OAAOA,mBAAmBgB,KAAK;QACjC;IACF;IAEA,MAAaC,MAAMC,SAAiB,EAAiB;QACnD,MAAM,EAAElB,kBAAkB,EAAE,GAAG,IAAI,CAACC,OAAO;QAC3C,IAAID,oBAAoB;YACtB,OAAOA,mBAAmBiB,KAAK,CAACC;QAClC;IACF;IAtEA,YAAY,AAAQjB,OAA2C,CAAE;;aAA7CA,UAAAA;IAA8C;AAuEpE;AA1EE,iBADWP,6BACIQ,aAAyC,CAAC;AACzD,iBAFWR,6BAEIU,cAA0C,CAAC"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@lage-run/cache",
|
|
3
|
-
"version": "1.4.
|
|
3
|
+
"version": "1.4.6",
|
|
4
4
|
"description": "Cache for Lage",
|
|
5
5
|
"repository": {
|
|
6
6
|
"type": "git",
|
|
@@ -11,17 +11,18 @@
|
|
|
11
11
|
"main": "lib/index.js",
|
|
12
12
|
"types": "lib/index.d.ts",
|
|
13
13
|
"scripts": {
|
|
14
|
-
"build": "
|
|
15
|
-
"
|
|
16
|
-
"
|
|
14
|
+
"build": "yarn types && yarn transpile",
|
|
15
|
+
"transpile": "monorepo-scripts transpile",
|
|
16
|
+
"types": "yarn run -T tsc",
|
|
17
|
+
"test": "yarn run -T jest",
|
|
17
18
|
"lint": "monorepo-scripts lint"
|
|
18
19
|
},
|
|
19
20
|
"dependencies": {
|
|
20
21
|
"@azure/core-auth": "^1.10.1",
|
|
21
22
|
"@azure/identity": "^4.13.0",
|
|
22
|
-
"@lage-run/config": "^0.
|
|
23
|
-
"@lage-run/logger": "^1.3.
|
|
24
|
-
"@lage-run/target-graph": "^0.12.
|
|
23
|
+
"@lage-run/config": "^0.8.0",
|
|
24
|
+
"@lage-run/logger": "^1.3.3",
|
|
25
|
+
"@lage-run/target-graph": "^0.12.3",
|
|
25
26
|
"backfill-cache": "^5.11.2",
|
|
26
27
|
"backfill-config": "^6.7.1",
|
|
27
28
|
"backfill-logger": "^5.4.0",
|
|
@@ -31,7 +32,8 @@
|
|
|
31
32
|
"@lage-run/monorepo-fixture": "^0.1.0",
|
|
32
33
|
"@lage-run/monorepo-scripts": "^1.0.0"
|
|
33
34
|
},
|
|
34
|
-
"
|
|
35
|
-
"
|
|
36
|
-
|
|
35
|
+
"files": [
|
|
36
|
+
"lib/!(__*)",
|
|
37
|
+
"lib/!(__*)/**"
|
|
38
|
+
]
|
|
37
39
|
}
|