@chriscdn/file-cache 0.0.5 → 0.0.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 +4 -0
- package/lib/index.d.ts +6 -4
- package/lib/index.js +12 -5
- package/lib/index.js.map +1 -1
- package/package.json +1 -1
- package/src/index.ts +29 -8
package/README.md
CHANGED
|
@@ -53,6 +53,9 @@ const options: FileCacheOptions<MyCallbackArgs> = {
|
|
|
53
53
|
// anything else in this directory.
|
|
54
54
|
cachePath: "/some/path/on/your/filesystem/",
|
|
55
55
|
|
|
56
|
+
// optional, automatically create cachePath if it doesn't exist
|
|
57
|
+
autoCreateCachePath: false,
|
|
58
|
+
|
|
56
59
|
// An asynchronous callback function, which is executed if no matching cached
|
|
57
60
|
// file is found. It is the responsibility of this function to use `context`
|
|
58
61
|
// to write a file to `filePath`.
|
|
@@ -83,6 +86,7 @@ const imageFilePath = await imageCache({
|
|
|
83
86
|
## Cleanup
|
|
84
87
|
|
|
85
88
|
`FileCache` instances are intended to be instantiated as singletons, persisting throughout the lifecycle of your app. If you need to deallocate an instance, be sure to call the `destroy()` method to prevent a memory leak.
|
|
89
|
+
This does not cleanup the cache directory.
|
|
86
90
|
|
|
87
91
|
## Tests
|
|
88
92
|
|
package/lib/index.d.ts
CHANGED
|
@@ -4,21 +4,23 @@ type Milliseconds = number;
|
|
|
4
4
|
export type FileCacheOptions<T extends Record<string, any>> = {
|
|
5
5
|
cachePath: DirectoryPath;
|
|
6
6
|
autoCreateCachePath?: boolean;
|
|
7
|
-
cb: (filePath: FilePath,
|
|
8
|
-
ext: (
|
|
7
|
+
cb: (filePath: FilePath, args: T, cache: FileCache<T>) => Promise<void>;
|
|
8
|
+
ext: (args: T) => string | Promise<string>;
|
|
9
|
+
resolveCacheFileKey?: (args: T) => string | Promise<string>;
|
|
9
10
|
ttl: Milliseconds;
|
|
10
11
|
cleanupInterval?: Milliseconds;
|
|
11
12
|
};
|
|
12
13
|
declare class FileCache<T extends Record<string, any>> {
|
|
13
14
|
private _cachePath;
|
|
14
15
|
private _cb;
|
|
15
|
-
private _ext;
|
|
16
16
|
private _ttl;
|
|
17
17
|
private _cleanupInterval;
|
|
18
|
+
private _resolveCacheFileKey;
|
|
19
|
+
private _ext;
|
|
18
20
|
private _intervalId;
|
|
19
21
|
private _semaphore;
|
|
20
22
|
private _cleanupSemaphore;
|
|
21
|
-
constructor({ cachePath, autoCreateCachePath, cb, ext, ttl, cleanupInterval }: FileCacheOptions<T>);
|
|
23
|
+
constructor({ cachePath, autoCreateCachePath, cb, ext, ttl, cleanupInterval, resolveCacheFileKey, }: FileCacheOptions<T>);
|
|
22
24
|
/**
|
|
23
25
|
* Runs a cleanup pass to remove files older than 1 day from the cache.
|
|
24
26
|
* This is called periodically, but can be triggered manually.
|
package/lib/index.js
CHANGED
|
@@ -12,19 +12,23 @@ const fsp = fs.promises;
|
|
|
12
12
|
class FileCache {
|
|
13
13
|
_cachePath;
|
|
14
14
|
_cb;
|
|
15
|
-
_ext;
|
|
16
15
|
_ttl;
|
|
17
16
|
_cleanupInterval;
|
|
17
|
+
_resolveCacheFileKey;
|
|
18
|
+
_ext;
|
|
18
19
|
_intervalId = null;
|
|
19
20
|
_semaphore = new Semaphore();
|
|
20
21
|
_cleanupSemaphore = new Semaphore();
|
|
21
|
-
|
|
22
|
+
// private _fileNameResover(args:T) =>
|
|
23
|
+
constructor({ cachePath, autoCreateCachePath, cb, ext, ttl, cleanupInterval, resolveCacheFileKey, }) {
|
|
22
24
|
this._cachePath = cachePath;
|
|
23
25
|
this._cb = cb;
|
|
24
26
|
this._ext = ext;
|
|
25
27
|
this._ttl = ttl;
|
|
26
28
|
this._cleanupInterval = cleanupInterval ??
|
|
27
29
|
Duration.toMilliseconds({ days: 1 });
|
|
30
|
+
this._resolveCacheFileKey = resolveCacheFileKey ??
|
|
31
|
+
((args) => sha1(JSON.stringify(args)));
|
|
28
32
|
if ((pathExistsSync(cachePath))) {
|
|
29
33
|
// we're good
|
|
30
34
|
}
|
|
@@ -130,10 +134,13 @@ class FileCache {
|
|
|
130
134
|
* generating a hash from the arguments to create a unique file name.
|
|
131
135
|
*/
|
|
132
136
|
async resolveFileName(args) {
|
|
133
|
-
const
|
|
137
|
+
const [name, ext] = await Promise.all([
|
|
138
|
+
this._resolveCacheFileKey(args),
|
|
139
|
+
this._ext(args),
|
|
140
|
+
]);
|
|
134
141
|
return path.format({
|
|
135
|
-
name
|
|
136
|
-
ext
|
|
142
|
+
name,
|
|
143
|
+
ext,
|
|
137
144
|
});
|
|
138
145
|
}
|
|
139
146
|
/**
|
package/lib/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,IAAI,MAAM,MAAM,CAAC;AACxB,OAAO,EAAE,MAAM,IAAI,CAAC;AACpB,OAAO,EAAE,UAAU,EAAE,cAAc,EAAE,MAAM,aAAa,CAAC;AACzD,OAAO,IAAI,MAAM,MAAM,CAAC;AACxB,OAAO,SAAS,MAAM,6BAA6B,CAAC;AACpD,OAAO,KAAK,MAAM,OAAO,CAAC;AAC1B,OAAO,EAAE,QAAQ,EAAE,MAAM,qBAAqB,CAAC;AAC/C,OAAO,EAAE,QAAQ,EAAE,MAAM,oBAAoB,CAAC;AAC9C,OAAO,EAAE,MAAM,EAAE,MAAM,QAAQ,CAAC;AAChC,OAAO,EAAE,OAAO,EAAE,MAAM,mBAAmB,CAAC;AAC5C,MAAM,GAAG,GAAG,EAAE,CAAC,QAAQ,CAAC;
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
|
package/package.json
CHANGED
package/src/index.ts
CHANGED
|
@@ -17,8 +17,9 @@ type Milliseconds = number;
|
|
|
17
17
|
export type FileCacheOptions<T extends Record<string, any>> = {
|
|
18
18
|
cachePath: DirectoryPath;
|
|
19
19
|
autoCreateCachePath?: boolean;
|
|
20
|
-
cb: (filePath: FilePath,
|
|
21
|
-
ext: (
|
|
20
|
+
cb: (filePath: FilePath, args: T, cache: FileCache<T>) => Promise<void>;
|
|
21
|
+
ext: (args: T) => string | Promise<string>;
|
|
22
|
+
resolveCacheFileKey?: (args: T) => string | Promise<string>;
|
|
22
23
|
ttl: Milliseconds;
|
|
23
24
|
cleanupInterval?: Milliseconds;
|
|
24
25
|
};
|
|
@@ -27,18 +28,32 @@ class FileCache<T extends Record<string, any>> {
|
|
|
27
28
|
private _cachePath: FileCacheOptions<T>["cachePath"];
|
|
28
29
|
|
|
29
30
|
private _cb: FileCacheOptions<T>["cb"];
|
|
30
|
-
|
|
31
|
+
|
|
31
32
|
private _ttl: FileCacheOptions<T>["ttl"];
|
|
32
33
|
private _cleanupInterval: FileCacheOptions<T>["cleanupInterval"];
|
|
33
34
|
|
|
35
|
+
private _resolveCacheFileKey: Required<
|
|
36
|
+
FileCacheOptions<T>
|
|
37
|
+
>["resolveCacheFileKey"];
|
|
38
|
+
private _ext: FileCacheOptions<T>["ext"];
|
|
39
|
+
|
|
34
40
|
private _intervalId: ReturnType<typeof setInterval> | null = null;
|
|
35
41
|
|
|
36
42
|
private _semaphore: Semaphore = new Semaphore();
|
|
37
43
|
private _cleanupSemaphore: Semaphore = new Semaphore();
|
|
38
44
|
|
|
45
|
+
// private _fileNameResover(args:T) =>
|
|
46
|
+
|
|
39
47
|
constructor(
|
|
40
|
-
{
|
|
41
|
-
|
|
48
|
+
{
|
|
49
|
+
cachePath,
|
|
50
|
+
autoCreateCachePath,
|
|
51
|
+
cb,
|
|
52
|
+
ext,
|
|
53
|
+
ttl,
|
|
54
|
+
cleanupInterval,
|
|
55
|
+
resolveCacheFileKey,
|
|
56
|
+
}: FileCacheOptions<T>,
|
|
42
57
|
) {
|
|
43
58
|
this._cachePath = cachePath;
|
|
44
59
|
this._cb = cb;
|
|
@@ -47,6 +62,9 @@ class FileCache<T extends Record<string, any>> {
|
|
|
47
62
|
this._cleanupInterval = cleanupInterval ??
|
|
48
63
|
Duration.toMilliseconds({ days: 1 });
|
|
49
64
|
|
|
65
|
+
this._resolveCacheFileKey = resolveCacheFileKey ??
|
|
66
|
+
((args: T) => sha1(JSON.stringify(args)));
|
|
67
|
+
|
|
50
68
|
if ((pathExistsSync(cachePath))) {
|
|
51
69
|
// we're good
|
|
52
70
|
} else if (autoCreateCachePath) {
|
|
@@ -162,11 +180,14 @@ class FileCache<T extends Record<string, any>> {
|
|
|
162
180
|
* generating a hash from the arguments to create a unique file name.
|
|
163
181
|
*/
|
|
164
182
|
private async resolveFileName(args: T): Promise<string> {
|
|
165
|
-
const
|
|
183
|
+
const [name, ext] = await Promise.all([
|
|
184
|
+
this._resolveCacheFileKey(args),
|
|
185
|
+
this._ext(args),
|
|
186
|
+
]);
|
|
166
187
|
|
|
167
188
|
return path.format({
|
|
168
|
-
name
|
|
169
|
-
ext
|
|
189
|
+
name,
|
|
190
|
+
ext,
|
|
170
191
|
});
|
|
171
192
|
}
|
|
172
193
|
|