@atlaspack/cache 3.1.1-canary.48 → 3.1.1-canary.481
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/CHANGELOG.md +602 -0
- package/dist/FSCache.js +162 -0
- package/dist/IDBCache.browser.js +124 -0
- package/dist/IDBCache.js +10 -0
- package/dist/LMDBLiteCache.js +198 -0
- package/dist/constants.js +5 -0
- package/dist/index.js +19 -0
- package/dist/types.js +2 -0
- package/lib/FSCache.js +15 -25
- package/lib/IDBCache.browser.js +10 -7
- package/lib/IDBCache.js +1 -1
- package/lib/LMDBLiteCache.js +20 -63
- package/lib/types/FSCache.d.ts +27 -0
- package/lib/types/IDBCache.browser.d.ts +22 -0
- package/lib/types/IDBCache.d.ts +4 -0
- package/lib/types/LMDBLiteCache.d.ts +78 -0
- package/lib/types/constants.d.ts +1 -0
- package/lib/types/index.d.ts +4 -0
- package/lib/types/types.d.ts +2 -0
- package/package.json +14 -15
- package/src/{FSCache.js → FSCache.ts} +21 -24
- package/src/{IDBCache.browser.js → IDBCache.browser.ts} +9 -10
- package/src/{IDBCache.js → IDBCache.ts} +1 -2
- package/src/{LMDBLiteCache.js → LMDBLiteCache.ts} +26 -60
- package/src/{constants.js → constants.ts} +0 -2
- package/src/{index.js → index.ts} +0 -2
- package/src/{types.js → types.ts} +0 -1
- package/test/{LMDBLiteCache.test.js → LMDBLiteCache.test.ts} +9 -11
- package/tsconfig.json +27 -0
- package/tsconfig.tsbuildinfo +1 -0
- package/index.d.ts +0 -12
- package/lib/types.d.ts +0 -2
package/lib/LMDBLiteCache.js
CHANGED
|
@@ -12,13 +12,6 @@ function _buildCache() {
|
|
|
12
12
|
};
|
|
13
13
|
return data;
|
|
14
14
|
}
|
|
15
|
-
function _featureFlags() {
|
|
16
|
-
const data = require("@atlaspack/feature-flags");
|
|
17
|
-
_featureFlags = function () {
|
|
18
|
-
return data;
|
|
19
|
-
};
|
|
20
|
-
return data;
|
|
21
|
-
}
|
|
22
15
|
function _rust() {
|
|
23
16
|
const data = require("@atlaspack/rust");
|
|
24
17
|
_rust = function () {
|
|
@@ -26,13 +19,6 @@ function _rust() {
|
|
|
26
19
|
};
|
|
27
20
|
return data;
|
|
28
21
|
}
|
|
29
|
-
function _fs() {
|
|
30
|
-
const data = _interopRequireDefault(require("fs"));
|
|
31
|
-
_fs = function () {
|
|
32
|
-
return data;
|
|
33
|
-
};
|
|
34
|
-
return data;
|
|
35
|
-
}
|
|
36
22
|
function _ncp() {
|
|
37
23
|
const data = _interopRequireDefault(require("ncp"));
|
|
38
24
|
_ncp = function () {
|
|
@@ -61,9 +47,9 @@ function _path() {
|
|
|
61
47
|
};
|
|
62
48
|
return data;
|
|
63
49
|
}
|
|
64
|
-
function
|
|
50
|
+
function _fs() {
|
|
65
51
|
const data = require("@atlaspack/fs");
|
|
66
|
-
|
|
52
|
+
_fs = function () {
|
|
67
53
|
return data;
|
|
68
54
|
};
|
|
69
55
|
return data;
|
|
@@ -77,8 +63,9 @@ function _logger() {
|
|
|
77
63
|
};
|
|
78
64
|
return data;
|
|
79
65
|
}
|
|
80
|
-
function _interopRequireDefault(
|
|
81
|
-
//
|
|
66
|
+
function _interopRequireDefault(e) { return e && e.__esModule ? e : { default: e }; }
|
|
67
|
+
// @ts-expect-error TS7016
|
|
68
|
+
|
|
82
69
|
const ncpAsync = (0, _util().promisify)(_ncp().default);
|
|
83
70
|
class LmdbWrapper {
|
|
84
71
|
constructor(lmdb) {
|
|
@@ -112,13 +99,13 @@ class LmdbWrapper {
|
|
|
112
99
|
}
|
|
113
100
|
}
|
|
114
101
|
exports.LmdbWrapper = LmdbWrapper;
|
|
115
|
-
function open(directory
|
|
102
|
+
function open(directory,
|
|
116
103
|
// eslint-disable-next-line no-unused-vars
|
|
117
|
-
) {
|
|
104
|
+
openOptions) {
|
|
118
105
|
return new LmdbWrapper(new (_rust().Lmdb)({
|
|
119
106
|
path: directory,
|
|
120
107
|
asyncWrites: true,
|
|
121
|
-
mapSize: 1024 * 1024 * 1024 * 15
|
|
108
|
+
mapSize: process.env.ATLASPACK_BUILD_ENV === 'test' ? 256 * 1024 * 1024 : 1024 * 1024 * 1024 * 15
|
|
122
109
|
}));
|
|
123
110
|
}
|
|
124
111
|
const pipeline = (0, _util().promisify)(_stream().default.pipeline);
|
|
@@ -128,7 +115,7 @@ class LMDBLiteCache {
|
|
|
128
115
|
*/
|
|
129
116
|
|
|
130
117
|
constructor(cacheDir) {
|
|
131
|
-
this.fs = new (
|
|
118
|
+
this.fs = new (_fs().NodeFS)();
|
|
132
119
|
this.dir = cacheDir;
|
|
133
120
|
this.cacheFilesDirectory = _path().default.join(cacheDir, 'files');
|
|
134
121
|
this.fsCache = new _FSCache.FSCache(this.fs, cacheDir);
|
|
@@ -146,9 +133,7 @@ class LMDBLiteCache {
|
|
|
146
133
|
return this.store.lmdb;
|
|
147
134
|
}
|
|
148
135
|
async ensure() {
|
|
149
|
-
|
|
150
|
-
await this.fsCache.ensure();
|
|
151
|
-
}
|
|
136
|
+
await this.fsCache.ensure();
|
|
152
137
|
await this.fs.mkdirp(this.cacheFilesDirectory);
|
|
153
138
|
return Promise.resolve();
|
|
154
139
|
}
|
|
@@ -174,20 +159,10 @@ class LMDBLiteCache {
|
|
|
174
159
|
await this.setBlob(key, (0, _buildCache().serialize)(value));
|
|
175
160
|
}
|
|
176
161
|
getStream(key) {
|
|
177
|
-
|
|
178
|
-
return this.fs.createReadStream(_path().default.join(this.dir, key));
|
|
179
|
-
}
|
|
180
|
-
return _fs().default.createReadStream(this.getFileKey(key));
|
|
162
|
+
return this.fs.createReadStream(_path().default.join(this.dir, key));
|
|
181
163
|
}
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
return pipeline(stream, this.fs.createWriteStream(_path().default.join(this.dir, key)));
|
|
185
|
-
}
|
|
186
|
-
const filePath = this.getFileKey(key);
|
|
187
|
-
await _fs().default.promises.mkdir(_path().default.dirname(filePath), {
|
|
188
|
-
recursive: true
|
|
189
|
-
});
|
|
190
|
-
return pipeline(stream, _fs().default.createWriteStream(filePath));
|
|
164
|
+
setStream(key, stream) {
|
|
165
|
+
return pipeline(stream, this.fs.createWriteStream(_path().default.join(this.dir, key)));
|
|
191
166
|
}
|
|
192
167
|
|
|
193
168
|
// eslint-disable-next-line require-await
|
|
@@ -208,45 +183,27 @@ class LMDBLiteCache {
|
|
|
208
183
|
return Promise.resolve(this.store.get(key));
|
|
209
184
|
}
|
|
210
185
|
hasLargeBlob(key) {
|
|
211
|
-
|
|
212
|
-
return this.fsCache.hasLargeBlob(key);
|
|
213
|
-
}
|
|
214
|
-
return _fs().default.promises.access(this.getFileKey(key), _fs().default.constants.F_OK).then(() => true).catch(() => false);
|
|
186
|
+
return this.fsCache.hasLargeBlob(key);
|
|
215
187
|
}
|
|
216
188
|
getLargeBlob(key) {
|
|
217
|
-
|
|
218
|
-
return this.fsCache.getLargeBlob(key);
|
|
219
|
-
}
|
|
220
|
-
return _fs().default.promises.readFile(this.getFileKey(key));
|
|
189
|
+
return this.fsCache.getLargeBlob(key);
|
|
221
190
|
}
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
return this.fsCache.setLargeBlob(key, contents, options);
|
|
225
|
-
}
|
|
226
|
-
const targetPath = this.getFileKey(key);
|
|
227
|
-
await _fs().default.promises.mkdir(_path().default.dirname(targetPath), {
|
|
228
|
-
recursive: true
|
|
229
|
-
});
|
|
230
|
-
return _fs().default.promises.writeFile(targetPath, contents);
|
|
191
|
+
setLargeBlob(key, contents, options) {
|
|
192
|
+
return this.fsCache.setLargeBlob(key, contents, options);
|
|
231
193
|
}
|
|
232
194
|
|
|
233
195
|
/**
|
|
234
196
|
* @deprecated Use store.delete instead.
|
|
235
197
|
*/
|
|
236
198
|
deleteLargeBlob(key) {
|
|
237
|
-
|
|
238
|
-
return this.fsCache.deleteLargeBlob(key);
|
|
239
|
-
}
|
|
240
|
-
return this.store.delete(key);
|
|
199
|
+
return this.fsCache.deleteLargeBlob(key);
|
|
241
200
|
}
|
|
242
201
|
keys() {
|
|
243
202
|
return this.store.keys();
|
|
244
203
|
}
|
|
245
204
|
async compact(targetPath) {
|
|
246
|
-
await
|
|
247
|
-
|
|
248
|
-
});
|
|
249
|
-
const files = await _fs().default.promises.readdir(this.dir);
|
|
205
|
+
await this.fs.mkdirp(targetPath);
|
|
206
|
+
const files = await this.fs.readdir(this.dir);
|
|
250
207
|
// copy all files except data.mdb and lock.mdb to the target path (recursive)
|
|
251
208
|
for (const file of files) {
|
|
252
209
|
const filePath = _path().default.join(this.dir, file);
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
import type { Readable } from 'stream';
|
|
2
|
+
import type { FilePath } from '@atlaspack/types';
|
|
3
|
+
import type { FileSystem } from '@atlaspack/fs';
|
|
4
|
+
import type { Cache } from './types';
|
|
5
|
+
export declare class FSCache implements Cache {
|
|
6
|
+
#private;
|
|
7
|
+
fs: FileSystem;
|
|
8
|
+
dir: FilePath;
|
|
9
|
+
constructor(fs: FileSystem, cacheDir: FilePath);
|
|
10
|
+
ensure(): Promise<void>;
|
|
11
|
+
_getCachePath(cacheId: string): FilePath;
|
|
12
|
+
getStream(key: string): Readable;
|
|
13
|
+
setStream(key: string, stream: Readable): Promise<void>;
|
|
14
|
+
has(key: string): Promise<boolean>;
|
|
15
|
+
getBlob(key: string): Promise<Buffer>;
|
|
16
|
+
setBlob(key: string, contents: Buffer | string): Promise<void>;
|
|
17
|
+
getBuffer(key: string): Promise<Buffer | null | undefined>;
|
|
18
|
+
hasLargeBlob(key: string): Promise<boolean>;
|
|
19
|
+
getLargeBlob(key: string): Promise<Buffer>;
|
|
20
|
+
setLargeBlob(key: string, contents: Buffer | string, options?: {
|
|
21
|
+
signal?: AbortSignal;
|
|
22
|
+
}): Promise<void>;
|
|
23
|
+
deleteLargeBlob(key: string): Promise<void>;
|
|
24
|
+
get<T>(key: string): Promise<T | null | undefined>;
|
|
25
|
+
set(key: string, value: unknown): Promise<void>;
|
|
26
|
+
refresh(): void;
|
|
27
|
+
}
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import type { Cache } from './types';
|
|
2
|
+
import { Readable } from 'stream';
|
|
3
|
+
export declare class IDBCache implements Cache {
|
|
4
|
+
store: any;
|
|
5
|
+
constructor();
|
|
6
|
+
ensure(): Promise<void>;
|
|
7
|
+
serialize(): Record<any, any>;
|
|
8
|
+
static deserialize(): IDBCache;
|
|
9
|
+
has(key: string): Promise<boolean>;
|
|
10
|
+
get<T>(key: string): Promise<T | null | undefined>;
|
|
11
|
+
set(key: string, value: unknown): Promise<void>;
|
|
12
|
+
getStream(key: string): Readable;
|
|
13
|
+
setStream(key: string, stream: Readable): Promise<void>;
|
|
14
|
+
getBlob(key: string): Promise<Buffer>;
|
|
15
|
+
setBlob(key: string, contents: Buffer | string): Promise<void>;
|
|
16
|
+
getBuffer(key: string): Promise<Buffer | null | undefined>;
|
|
17
|
+
hasLargeBlob(key: string): Promise<boolean>;
|
|
18
|
+
getLargeBlob(key: string): Promise<Buffer>;
|
|
19
|
+
setLargeBlob(key: string, contents: Buffer | string): Promise<void>;
|
|
20
|
+
deleteLargeBlob(key: string): Promise<void>;
|
|
21
|
+
refresh(): void;
|
|
22
|
+
}
|
|
@@ -0,0 +1,78 @@
|
|
|
1
|
+
import { Lmdb } from '@atlaspack/rust';
|
|
2
|
+
import type { FilePath } from '@atlaspack/types';
|
|
3
|
+
import type { Cache } from './types';
|
|
4
|
+
import type { Readable } from 'stream';
|
|
5
|
+
import { NodeFS } from '@atlaspack/fs';
|
|
6
|
+
import { FSCache } from './FSCache';
|
|
7
|
+
interface DBOpenOptions {
|
|
8
|
+
name: string;
|
|
9
|
+
encoding: string;
|
|
10
|
+
compression: boolean;
|
|
11
|
+
}
|
|
12
|
+
export declare class LmdbWrapper {
|
|
13
|
+
lmdb: Lmdb;
|
|
14
|
+
constructor(lmdb: Lmdb);
|
|
15
|
+
has(key: string): boolean;
|
|
16
|
+
delete(key: string): Promise<void>;
|
|
17
|
+
get(key: string): Buffer | null;
|
|
18
|
+
put(key: string, value: Buffer | string): Promise<void>;
|
|
19
|
+
keys(): Iterable<string>;
|
|
20
|
+
compact(targetPath: string): void;
|
|
21
|
+
}
|
|
22
|
+
export declare function open(directory: string, openOptions: DBOpenOptions): LmdbWrapper;
|
|
23
|
+
export type SerLMDBLiteCache = {
|
|
24
|
+
dir: FilePath;
|
|
25
|
+
};
|
|
26
|
+
export declare class LMDBLiteCache implements Cache {
|
|
27
|
+
fs: NodeFS;
|
|
28
|
+
dir: FilePath;
|
|
29
|
+
store: LmdbWrapper;
|
|
30
|
+
fsCache: FSCache;
|
|
31
|
+
/**
|
|
32
|
+
* Directory where we store raw files.
|
|
33
|
+
*/
|
|
34
|
+
cacheFilesDirectory: FilePath;
|
|
35
|
+
constructor(cacheDir: FilePath);
|
|
36
|
+
/**
|
|
37
|
+
* Use this to pass the native LMDB instance back to Rust.
|
|
38
|
+
*/
|
|
39
|
+
getNativeRef(): Lmdb;
|
|
40
|
+
ensure(): Promise<void>;
|
|
41
|
+
serialize(): SerLMDBLiteCache;
|
|
42
|
+
static deserialize(cache: SerLMDBLiteCache): LMDBLiteCache;
|
|
43
|
+
has(key: string): Promise<boolean>;
|
|
44
|
+
get<T>(key: string): Promise<T | null | undefined>;
|
|
45
|
+
set(key: string, value: unknown): Promise<void>;
|
|
46
|
+
getStream(key: string): Readable;
|
|
47
|
+
setStream(key: string, stream: Readable): Promise<void>;
|
|
48
|
+
getBlob(key: string): Promise<Buffer>;
|
|
49
|
+
getBlobSync(key: string): Buffer;
|
|
50
|
+
setBlob(key: string, contents: Buffer | string): Promise<void>;
|
|
51
|
+
getBuffer(key: string): Promise<Buffer | null | undefined>;
|
|
52
|
+
hasLargeBlob(key: string): Promise<boolean>;
|
|
53
|
+
getLargeBlob(key: string): Promise<Buffer>;
|
|
54
|
+
setLargeBlob(key: string, contents: Buffer | string, options?: {
|
|
55
|
+
signal?: AbortSignal;
|
|
56
|
+
}): Promise<void>;
|
|
57
|
+
/**
|
|
58
|
+
* @deprecated Use store.delete instead.
|
|
59
|
+
*/
|
|
60
|
+
deleteLargeBlob(key: string): Promise<void>;
|
|
61
|
+
keys(): Iterable<string>;
|
|
62
|
+
compact(targetPath: string): Promise<void>;
|
|
63
|
+
refresh(): void;
|
|
64
|
+
/**
|
|
65
|
+
* Streams, packages are stored in files instead of LMDB.
|
|
66
|
+
*
|
|
67
|
+
* On this case, if a cache key happens to have a parent traversal, ../..
|
|
68
|
+
* it is treated specially
|
|
69
|
+
*
|
|
70
|
+
* That is, something/../something and something are meant to be different
|
|
71
|
+
* keys.
|
|
72
|
+
*
|
|
73
|
+
* Plus we do not want to store values outside of the cache directory.
|
|
74
|
+
*/
|
|
75
|
+
getFileKey(key: string): string;
|
|
76
|
+
clear(): Promise<void>;
|
|
77
|
+
}
|
|
78
|
+
export {};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export declare const WRITE_LIMIT_CHUNK: number;
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@atlaspack/cache",
|
|
3
3
|
"description": "Interface for defining caches and file-system, IDB and LMDB implementations.",
|
|
4
|
-
"version": "3.1.1-canary.
|
|
4
|
+
"version": "3.1.1-canary.481+a1d772935",
|
|
5
5
|
"license": "(MIT OR Apache-2.0)",
|
|
6
6
|
"type": "commonjs",
|
|
7
7
|
"publishConfig": {
|
|
@@ -11,31 +11,30 @@
|
|
|
11
11
|
"type": "git",
|
|
12
12
|
"url": "https://github.com/atlassian-labs/atlaspack.git"
|
|
13
13
|
},
|
|
14
|
-
"main": "lib/index.js",
|
|
15
|
-
"source": "src/index.
|
|
16
|
-
"types": "index.d.ts",
|
|
14
|
+
"main": "./lib/index.js",
|
|
15
|
+
"source": "./src/index.ts",
|
|
16
|
+
"types": "./lib/types/index.d.ts",
|
|
17
17
|
"engines": {
|
|
18
18
|
"node": ">= 16.0.0"
|
|
19
19
|
},
|
|
20
20
|
"scripts": {
|
|
21
21
|
"test": "mocha",
|
|
22
|
-
"build
|
|
23
|
-
"check-ts": "tsc --noEmit index.d.ts"
|
|
22
|
+
"build:lib": "gulp build --gulpfile ../../../gulpfile.js --cwd ."
|
|
24
23
|
},
|
|
25
24
|
"dependencies": {
|
|
26
|
-
"@atlaspack/build-cache": "2.13.3-canary.
|
|
27
|
-
"@atlaspack/feature-flags": "2.14.1-canary.
|
|
28
|
-
"@atlaspack/fs": "2.14.5-canary.
|
|
29
|
-
"@atlaspack/logger": "2.14.5-canary.
|
|
30
|
-
"@atlaspack/rust": "3.2.1-canary.
|
|
31
|
-
"@atlaspack/utils": "2.14.5-canary.
|
|
25
|
+
"@atlaspack/build-cache": "2.13.3-canary.549+a1d772935",
|
|
26
|
+
"@atlaspack/feature-flags": "2.14.1-canary.549+a1d772935",
|
|
27
|
+
"@atlaspack/fs": "2.14.5-canary.481+a1d772935",
|
|
28
|
+
"@atlaspack/logger": "2.14.5-canary.481+a1d772935",
|
|
29
|
+
"@atlaspack/rust": "3.2.1-canary.481+a1d772935",
|
|
30
|
+
"@atlaspack/utils": "2.14.5-canary.481+a1d772935",
|
|
32
31
|
"ncp": "^2.0.0"
|
|
33
32
|
},
|
|
34
33
|
"devDependencies": {
|
|
35
|
-
"idb": "^
|
|
34
|
+
"idb": "^8.0.0"
|
|
36
35
|
},
|
|
37
36
|
"browser": {
|
|
38
37
|
"./src/IDBCache.js": "./src/IDBCache.browser.js"
|
|
39
38
|
},
|
|
40
|
-
"gitHead": "
|
|
41
|
-
}
|
|
39
|
+
"gitHead": "a1d772935c9ed74c6d8eafbee6b65eb91ddc38fd"
|
|
40
|
+
}
|
|
@@ -1,5 +1,3 @@
|
|
|
1
|
-
// @flow strict-local
|
|
2
|
-
|
|
3
1
|
import type {Readable, Writable} from 'stream';
|
|
4
2
|
import type {FilePath} from '@atlaspack/types';
|
|
5
3
|
import type {FileSystem} from '@atlaspack/fs';
|
|
@@ -9,8 +7,6 @@ import stream from 'stream';
|
|
|
9
7
|
import path from 'path';
|
|
10
8
|
import {promisify} from 'util';
|
|
11
9
|
|
|
12
|
-
import {hashString} from '@atlaspack/rust';
|
|
13
|
-
import {getFeatureFlag} from '@atlaspack/feature-flags';
|
|
14
10
|
import logger from '@atlaspack/logger';
|
|
15
11
|
import {
|
|
16
12
|
deserialize,
|
|
@@ -23,7 +19,7 @@ import packageJson from '../package.json';
|
|
|
23
19
|
|
|
24
20
|
import {WRITE_LIMIT_CHUNK} from './constants';
|
|
25
21
|
|
|
26
|
-
const pipeline: (Readable, Writable) => Promise<void> = promisify(
|
|
22
|
+
const pipeline: (arg1: Readable, arg2: Writable) => Promise<void> = promisify(
|
|
27
23
|
stream.pipeline,
|
|
28
24
|
);
|
|
29
25
|
|
|
@@ -42,9 +38,10 @@ export class FSCache implements Cache {
|
|
|
42
38
|
|
|
43
39
|
// In parallel, create sub-directories for every possible hex value
|
|
44
40
|
// This speeds up large caches on many file systems since there are fewer files in a single directory.
|
|
45
|
-
let dirPromises = [];
|
|
41
|
+
let dirPromises: Array<Promise<undefined>> = [];
|
|
46
42
|
for (let i = 0; i < 256; i++) {
|
|
47
43
|
dirPromises.push(
|
|
44
|
+
// @ts-expect-error TS2345
|
|
48
45
|
this.fs.mkdirp(path.join(this.dir, ('00' + i.toString(16)).slice(-2))),
|
|
49
46
|
);
|
|
50
47
|
}
|
|
@@ -53,10 +50,6 @@ export class FSCache implements Cache {
|
|
|
53
50
|
}
|
|
54
51
|
|
|
55
52
|
_getCachePath(cacheId: string): FilePath {
|
|
56
|
-
if (getFeatureFlag('cachePerformanceImprovements')) {
|
|
57
|
-
const cleanId = hashString(cacheId);
|
|
58
|
-
return path.join(this.dir, cleanId.slice(0, 2), cleanId.slice(2));
|
|
59
|
-
}
|
|
60
53
|
return path.join(this.dir, cacheId.slice(0, 2), cacheId.slice(2));
|
|
61
54
|
}
|
|
62
55
|
|
|
@@ -83,10 +76,10 @@ export class FSCache implements Cache {
|
|
|
83
76
|
await this.fs.writeFile(this._getCachePath(key), contents);
|
|
84
77
|
}
|
|
85
78
|
|
|
86
|
-
async getBuffer(key: string): Promise
|
|
79
|
+
async getBuffer(key: string): Promise<Buffer | null | undefined> {
|
|
87
80
|
try {
|
|
88
81
|
return await this.fs.readFile(this._getCachePath(key));
|
|
89
|
-
} catch (err) {
|
|
82
|
+
} catch (err: any) {
|
|
90
83
|
if (err.code === 'ENOENT') {
|
|
91
84
|
return null;
|
|
92
85
|
} else {
|
|
@@ -96,17 +89,14 @@ export class FSCache implements Cache {
|
|
|
96
89
|
}
|
|
97
90
|
|
|
98
91
|
#getFilePath(key: string, index: number): string {
|
|
99
|
-
if (getFeatureFlag('cachePerformanceImprovements')) {
|
|
100
|
-
return path.join(this.dir, `${hashString(key)}-${index}`);
|
|
101
|
-
}
|
|
102
92
|
return path.join(this.dir, `${key}-${index}`);
|
|
103
93
|
}
|
|
104
94
|
|
|
105
|
-
async #unlinkChunks(key: string, index: number): Promise<
|
|
95
|
+
async #unlinkChunks(key: string, index: number): Promise<undefined> {
|
|
106
96
|
try {
|
|
107
97
|
await this.fs.unlink(this.#getFilePath(key, index));
|
|
108
98
|
await this.#unlinkChunks(key, index + 1);
|
|
109
|
-
} catch (err) {
|
|
99
|
+
} catch (err: any) {
|
|
110
100
|
// If there's an error, no more chunks are left to delete
|
|
111
101
|
}
|
|
112
102
|
}
|
|
@@ -129,21 +119,26 @@ export class FSCache implements Cache {
|
|
|
129
119
|
async setLargeBlob(
|
|
130
120
|
key: string,
|
|
131
121
|
contents: Buffer | string,
|
|
132
|
-
options?: {
|
|
122
|
+
options?: {
|
|
123
|
+
signal?: AbortSignal;
|
|
124
|
+
},
|
|
133
125
|
): Promise<void> {
|
|
134
126
|
const chunks = Math.ceil(contents.length / WRITE_LIMIT_CHUNK);
|
|
135
127
|
|
|
136
|
-
const writePromises: Promise<
|
|
128
|
+
const writePromises: Promise<undefined>[] = [];
|
|
137
129
|
if (chunks === 1) {
|
|
138
130
|
// If there's one chunk, don't slice the content
|
|
139
131
|
writePromises.push(
|
|
132
|
+
// @ts-expect-error TS2345
|
|
140
133
|
this.fs.writeFile(this.#getFilePath(key, 0), contents, {
|
|
134
|
+
// @ts-expect-error TS2353
|
|
141
135
|
signal: options?.signal,
|
|
142
136
|
}),
|
|
143
137
|
);
|
|
144
138
|
} else {
|
|
145
139
|
for (let i = 0; i < chunks; i += 1) {
|
|
146
140
|
writePromises.push(
|
|
141
|
+
// @ts-expect-error TS2345
|
|
147
142
|
this.fs.writeFile(
|
|
148
143
|
this.#getFilePath(key, i),
|
|
149
144
|
typeof contents === 'string'
|
|
@@ -155,6 +150,7 @@ export class FSCache implements Cache {
|
|
|
155
150
|
i * WRITE_LIMIT_CHUNK,
|
|
156
151
|
(i + 1) * WRITE_LIMIT_CHUNK,
|
|
157
152
|
),
|
|
153
|
+
// @ts-expect-error TS2353
|
|
158
154
|
{signal: options?.signal},
|
|
159
155
|
),
|
|
160
156
|
);
|
|
@@ -168,12 +164,13 @@ export class FSCache implements Cache {
|
|
|
168
164
|
}
|
|
169
165
|
|
|
170
166
|
async deleteLargeBlob(key: string): Promise<void> {
|
|
171
|
-
const deletePromises: Promise<
|
|
167
|
+
const deletePromises: Promise<undefined>[] = [];
|
|
172
168
|
|
|
173
169
|
let i = 0;
|
|
174
170
|
let filePath = this.#getFilePath(key, i);
|
|
175
171
|
|
|
176
172
|
while (await this.fs.exists(filePath)) {
|
|
173
|
+
// @ts-expect-error TS2345
|
|
177
174
|
deletePromises.push(this.fs.rimraf(filePath));
|
|
178
175
|
i += 1;
|
|
179
176
|
filePath = this.#getFilePath(key, i);
|
|
@@ -182,11 +179,11 @@ export class FSCache implements Cache {
|
|
|
182
179
|
await Promise.all(deletePromises);
|
|
183
180
|
}
|
|
184
181
|
|
|
185
|
-
async get<T>(key: string): Promise
|
|
182
|
+
async get<T>(key: string): Promise<T | null | undefined> {
|
|
186
183
|
try {
|
|
187
184
|
let data = await this.fs.readFile(this._getCachePath(key));
|
|
188
185
|
return deserialize(data);
|
|
189
|
-
} catch (err) {
|
|
186
|
+
} catch (err: any) {
|
|
190
187
|
if (err.code === 'ENOENT') {
|
|
191
188
|
return null;
|
|
192
189
|
} else {
|
|
@@ -195,13 +192,13 @@ export class FSCache implements Cache {
|
|
|
195
192
|
}
|
|
196
193
|
}
|
|
197
194
|
|
|
198
|
-
async set(key: string, value:
|
|
195
|
+
async set(key: string, value: unknown): Promise<void> {
|
|
199
196
|
try {
|
|
200
197
|
let blobPath = this._getCachePath(key);
|
|
201
198
|
let data = serialize(value);
|
|
202
199
|
|
|
203
200
|
await this.fs.writeFile(blobPath, data);
|
|
204
|
-
} catch (err) {
|
|
201
|
+
} catch (err: any) {
|
|
205
202
|
logger.error(err, '@atlaspack/cache');
|
|
206
203
|
}
|
|
207
204
|
}
|
|
@@ -1,4 +1,3 @@
|
|
|
1
|
-
// @flow strict-local
|
|
2
1
|
import type {Cache} from './types';
|
|
3
2
|
|
|
4
3
|
import {Readable} from 'stream';
|
|
@@ -9,21 +8,19 @@ import {
|
|
|
9
8
|
serialize,
|
|
10
9
|
} from '@atlaspack/build-cache';
|
|
11
10
|
import {bufferStream} from '@atlaspack/utils';
|
|
12
|
-
//
|
|
11
|
+
// @ts-expect-error TS1479: idb is ESM-only but we need to import it in this browser-specific CJS file
|
|
13
12
|
import {openDB} from 'idb';
|
|
14
13
|
|
|
15
|
-
// $FlowFixMe[untyped-import]
|
|
16
14
|
import packageJson from '../package.json';
|
|
17
15
|
|
|
18
16
|
const STORE_NAME = 'cache';
|
|
19
17
|
|
|
20
18
|
export class IDBCache implements Cache {
|
|
21
|
-
// $FlowFixMe
|
|
22
19
|
store: any;
|
|
23
20
|
|
|
24
21
|
constructor() {
|
|
25
22
|
this.store = openDB('REPL-parcel-cache', 1, {
|
|
26
|
-
upgrade(db) {
|
|
23
|
+
upgrade(db: any) {
|
|
27
24
|
db.createObjectStore(STORE_NAME);
|
|
28
25
|
},
|
|
29
26
|
blocked() {},
|
|
@@ -36,7 +33,7 @@ export class IDBCache implements Cache {
|
|
|
36
33
|
return Promise.resolve();
|
|
37
34
|
}
|
|
38
35
|
|
|
39
|
-
serialize():
|
|
36
|
+
serialize(): Record<any, any> {
|
|
40
37
|
return {
|
|
41
38
|
/*::...null*/
|
|
42
39
|
};
|
|
@@ -50,7 +47,7 @@ export class IDBCache implements Cache {
|
|
|
50
47
|
return Promise.resolve(this.store.get(key) != null);
|
|
51
48
|
}
|
|
52
49
|
|
|
53
|
-
async get<T>(key: string): Promise
|
|
50
|
+
async get<T>(key: string): Promise<T | null | undefined> {
|
|
54
51
|
let data = await (await this.store).get(STORE_NAME, key);
|
|
55
52
|
if (data == null) {
|
|
56
53
|
return null;
|
|
@@ -59,17 +56,19 @@ export class IDBCache implements Cache {
|
|
|
59
56
|
return Promise.resolve(deserialize(data));
|
|
60
57
|
}
|
|
61
58
|
|
|
62
|
-
async set(key: string, value:
|
|
59
|
+
async set(key: string, value: unknown): Promise<void> {
|
|
63
60
|
await (await this.store).put(STORE_NAME, serialize(value), key);
|
|
64
61
|
}
|
|
65
62
|
|
|
66
63
|
getStream(key: string): Readable {
|
|
67
64
|
let dataPromise = this.store
|
|
65
|
+
// @ts-expect-error TS7006
|
|
68
66
|
.then((s) => s.get(STORE_NAME, key))
|
|
67
|
+
// @ts-expect-error TS7006
|
|
69
68
|
.then((d) => Buffer.from(d))
|
|
69
|
+
// @ts-expect-error TS7006
|
|
70
70
|
.catch((e) => e);
|
|
71
71
|
const stream = new Readable({
|
|
72
|
-
// $FlowFixMe(incompatible-call)
|
|
73
72
|
async read() {
|
|
74
73
|
let data = await dataPromise;
|
|
75
74
|
if (data instanceof Error) {
|
|
@@ -118,7 +117,7 @@ export class IDBCache implements Cache {
|
|
|
118
117
|
// ]);
|
|
119
118
|
// }
|
|
120
119
|
|
|
121
|
-
async getBuffer(key: string): Promise
|
|
120
|
+
async getBuffer(key: string): Promise<Buffer | null | undefined> {
|
|
122
121
|
let data = await (await this.store).get(STORE_NAME, key);
|
|
123
122
|
if (data == null) {
|
|
124
123
|
return null;
|