-
Notifications
You must be signed in to change notification settings - Fork 10.3k
/
cache-lmdb.ts
104 lines (88 loc) · 2.87 KB
/
cache-lmdb.ts
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
import { open, RootDatabase, Database, DatabaseOptions } from "lmdb"
import * as fs from "fs-extra"
import * as path from "path"
// Since the regular GatsbyCache saves to "caches" this should be "caches-lmdb"
const cacheDbFile =
process.env.NODE_ENV === `test`
? `caches-lmdb-${
// FORCE_TEST_DATABASE_ID will be set if this gets executed in worker context
// when running jest tests. JEST_WORKER_ID will be set when this gets executed directly
// in test context (jest will use jest-worker internally).
process.env.FORCE_TEST_DATABASE_ID ?? process.env.JEST_WORKER_ID
}`
: `caches-lmdb`
const dbPath = path.join(process.cwd(), `.cache/${cacheDbFile}`)
function getAlreadyOpenedStore(): RootDatabase | undefined {
if (!globalThis.__GATSBY_OPEN_ROOT_LMDBS) {
globalThis.__GATSBY_OPEN_ROOT_LMDBS = new Map()
}
return globalThis.__GATSBY_OPEN_ROOT_LMDBS.get(dbPath)
}
export default class GatsbyCacheLmdb {
private db: Database | undefined
private encoding: DatabaseOptions["encoding"]
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`,
encoding = `json`,
}: {
name: string
encoding?: DatabaseOptions["encoding"]
}) {
this.name = name
this.encoding = encoding
this.directory = path.join(process.cwd(), `.cache/caches/${name}`)
this.cache = this
}
init(): GatsbyCacheLmdb {
fs.ensureDirSync(this.directory)
return this
}
private static getStore(): RootDatabase {
let rootDb = getAlreadyOpenedStore()
if (rootDb) {
return rootDb
}
rootDb = open({
name: `root`,
path: dbPath,
compression: true,
maxDbs: 200,
})
globalThis.__GATSBY_OPEN_ROOT_LMDBS.set(dbPath, rootDb)
return rootDb
}
private getDb(): Database {
if (!this.db) {
this.db = GatsbyCacheLmdb.getStore().openDB({
name: this.name,
encoding: this.encoding,
})
}
return this.db
}
async get<T = unknown>(key): Promise<T | undefined> {
return this.getDb().get(key)
}
async set<T>(key: string, value: T): Promise<T | undefined> {
await this.getDb().put(key, value)
return value
}
async del(key: string): Promise<void> {
return this.getDb().remove(key) as unknown as Promise<void>
}
}
export async function resetCache(): Promise<void> {
const store = getAlreadyOpenedStore()
if (store) {
await store.close()
globalThis.__GATSBY_OPEN_ROOT_LMDBS.delete(dbPath)
}
await fs.emptyDir(dbPath)
}