@chriscdn/file-cache 0.0.9 → 0.0.11
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 +7 -19
- package/lib/index.d.ts +2 -1
- package/lib/index.js +4 -8
- package/lib/index.js.map +1 -1
- package/package.json +5 -6
- package/src/index.ts +7 -10
package/README.md
CHANGED
|
@@ -1,17 +1,11 @@
|
|
|
1
1
|
# @chriscdn/file-cache
|
|
2
2
|
|
|
3
|
-
`FileCache` is a node utility for caching generated and remote files. Common use
|
|
4
|
-
cases include:
|
|
3
|
+
`FileCache` is a node utility for caching generated and remote files. Common use cases include:
|
|
5
4
|
|
|
6
|
-
- **Caching files stored in Amazon S3**: Keep a local cache of frequently
|
|
7
|
-
|
|
8
|
-
- **Thumbnail caching**: Store generated thumbnails locally for quick access
|
|
9
|
-
instead of regenerating them every time.
|
|
5
|
+
- **Caching files stored in Amazon S3**: Keep a local cache of frequently accessed files to avoid repeatedly fetching them.
|
|
6
|
+
- **Thumbnail caching**: Store generated thumbnails locally for quick access instead of regenerating them every time.
|
|
10
7
|
|
|
11
|
-
`FileCache` does not store state in memory, meaning your cache remains
|
|
12
|
-
unaffected by application restarts. Cached files are automatically expired using
|
|
13
|
-
a time-to-live (TTL) policy and the file's modified date. The file's modified
|
|
14
|
-
date is updated each time the file is accessed.
|
|
8
|
+
`FileCache` does not store state in memory, meaning your cache remains unaffected by application restarts. Cached files are automatically expired using a time-to-live (TTL) policy and the file's modified date. The file's modified date is updated each time the file is accessed.
|
|
15
9
|
|
|
16
10
|
## Installing
|
|
17
11
|
|
|
@@ -31,11 +25,8 @@ yarn add @chriscdn/file-cache
|
|
|
31
25
|
|
|
32
26
|
The general approach is this:
|
|
33
27
|
|
|
34
|
-
- **Create a callback** — Write an async function that takes a file path and
|
|
35
|
-
|
|
36
|
-
it to the path.
|
|
37
|
-
- **Set up the cache** — Initialize a `FileCache` with your callback and some
|
|
38
|
-
options (like where to store files and how long to keep them).
|
|
28
|
+
- **Create a callback** — Write an async function that takes a file path and your custom input (like a URL), then generates or downloads the file and saves it to the path.
|
|
29
|
+
- **Set up the cache** — Initialize a `FileCache` with your callback and some options (like where to store files and how long to keep them).
|
|
39
30
|
- **Get a file** — Call the cache with your input. It will:
|
|
40
31
|
- Hash the input to create a unique file name.
|
|
41
32
|
- If the file is already cached and still valid, return its path.
|
|
@@ -94,10 +85,7 @@ const imageFilePath = await imageCache({
|
|
|
94
85
|
|
|
95
86
|
## Cleanup
|
|
96
87
|
|
|
97
|
-
`FileCache` instances are intended to be instantiated as singletons, persisting
|
|
98
|
-
throughout the lifecycle of your app. If you need to deallocate an instance, be
|
|
99
|
-
sure to call the `destroy()` method to prevent a memory leak. This does not
|
|
100
|
-
cleanup the cache directory.
|
|
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. This does not cleanup the cache directory.
|
|
101
89
|
|
|
102
90
|
## Tests
|
|
103
91
|
|
package/lib/index.d.ts
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
type DirectoryPath = string;
|
|
2
|
+
type FileName = string;
|
|
2
3
|
type FilePath = string;
|
|
3
4
|
type Milliseconds = number;
|
|
4
5
|
export type FileCacheOptions<T extends Record<string, any>> = {
|
|
@@ -64,4 +65,4 @@ declare class FileCache<T extends Record<string, any>> {
|
|
|
64
65
|
*/
|
|
65
66
|
resolveFilePath(args: T): Promise<FilePath>;
|
|
66
67
|
}
|
|
67
|
-
export { type DirectoryPath, FileCache, type FilePath };
|
|
68
|
+
export { type DirectoryPath, FileCache, type FileName, type FilePath };
|
package/lib/index.js
CHANGED
|
@@ -6,7 +6,7 @@ import { GroupSemaphore, Semaphore } from "@chriscdn/promise-semaphore";
|
|
|
6
6
|
import touch from "touch";
|
|
7
7
|
import { findNuke } from "@chriscdn/find-nuke";
|
|
8
8
|
import { Duration } from "@chriscdn/duration";
|
|
9
|
-
import { Memoize } from "@chriscdn/memoize";
|
|
9
|
+
// import { Memoize } from "@chriscdn/memoize";
|
|
10
10
|
const fsp = fs.promises;
|
|
11
11
|
const deleteFile = async (filepath) => await fs.promises.unlink(filepath);
|
|
12
12
|
class FileCache {
|
|
@@ -41,8 +41,8 @@ class FileCache {
|
|
|
41
41
|
// fire and forget
|
|
42
42
|
this.cleanup();
|
|
43
43
|
this._intervalId = setInterval(this.cleanup.bind(this), this._cleanupInterval);
|
|
44
|
-
this.resolveFileName = Memoize(this.resolveFileName.bind(this));
|
|
45
|
-
this.resolveFilePath = Memoize(this.resolveFilePath.bind(this));
|
|
44
|
+
// this.resolveFileName = Memoize(this.resolveFileName.bind(this));
|
|
45
|
+
// this.resolveFilePath = Memoize(this.resolveFilePath.bind(this));
|
|
46
46
|
}
|
|
47
47
|
/**
|
|
48
48
|
* Runs a cleanup pass to remove files older than 1 day from the cache.
|
|
@@ -74,8 +74,6 @@ class FileCache {
|
|
|
74
74
|
async getFile(args) {
|
|
75
75
|
const filePath = await this.resolveFilePath(args);
|
|
76
76
|
try {
|
|
77
|
-
// await this._cleanupGroupSemaphore.acquire("thumbnail");
|
|
78
|
-
// await this._semaphore.acquire(filePath);
|
|
79
77
|
await Promise.all([
|
|
80
78
|
this._cleanupGroupSemaphore.acquire("getFile"),
|
|
81
79
|
this._semaphore.acquire(filePath),
|
|
@@ -158,9 +156,7 @@ class FileCache {
|
|
|
158
156
|
*/
|
|
159
157
|
async resolveFilePath(args) {
|
|
160
158
|
const fileName = await this.resolveFileName(args);
|
|
161
|
-
const filePath = path.resolve(this._cachePath, fileName[0], fileName[1], fileName[2],
|
|
162
|
-
// fileName[3],
|
|
163
|
-
fileName);
|
|
159
|
+
const filePath = path.resolve(this._cachePath, fileName[0], fileName[1], fileName[2], fileName);
|
|
164
160
|
return filePath;
|
|
165
161
|
}
|
|
166
162
|
}
|
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,EAAE,cAAc,EAAE,SAAS,EAAE,MAAM,6BAA6B,CAAC;AACxE,OAAO,KAAK,MAAM,OAAO,CAAC;AAC1B,OAAO,EAAE,QAAQ,EAAE,MAAM,qBAAqB,CAAC;AAC/C,OAAO,EAAE,QAAQ,EAAE,MAAM,oBAAoB,CAAC;AAE9C
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@chriscdn/file-cache",
|
|
3
|
-
"version": "0.0.
|
|
3
|
+
"version": "0.0.11",
|
|
4
4
|
"description": "File cache ",
|
|
5
5
|
"repository": "https://github.com/chriscdn/file-cache",
|
|
6
6
|
"author": "Christopher Meyer <chris@schwiiz.org>",
|
|
@@ -19,18 +19,17 @@
|
|
|
19
19
|
"dependencies": {
|
|
20
20
|
"@chriscdn/duration": "^1.0.3",
|
|
21
21
|
"@chriscdn/find-nuke": "^0.0.5",
|
|
22
|
-
"@chriscdn/
|
|
23
|
-
"@chriscdn/promise-semaphore": "^3.0.1",
|
|
22
|
+
"@chriscdn/promise-semaphore": "^3.1.1",
|
|
24
23
|
"path-exists": "^5.0.0",
|
|
25
24
|
"sha1": "^1.1.1",
|
|
26
25
|
"temp": "^0.9.4",
|
|
27
26
|
"touch": "^3.1.1"
|
|
28
27
|
},
|
|
29
28
|
"devDependencies": {
|
|
30
|
-
"@tsconfig/node22": "^22.0.
|
|
29
|
+
"@tsconfig/node22": "^22.0.2",
|
|
31
30
|
"@types/sha1": "^1.1.5",
|
|
32
31
|
"@types/touch": "^3.1.5",
|
|
33
|
-
"typescript": "^5.
|
|
34
|
-
"vitest": "^3.
|
|
32
|
+
"typescript": "^5.9.2",
|
|
33
|
+
"vitest": "^3.2.4"
|
|
35
34
|
}
|
|
36
35
|
}
|
package/src/index.ts
CHANGED
|
@@ -7,11 +7,12 @@ import touch from "touch";
|
|
|
7
7
|
import { findNuke } from "@chriscdn/find-nuke";
|
|
8
8
|
import { Duration } from "@chriscdn/duration";
|
|
9
9
|
|
|
10
|
-
import { Memoize } from "@chriscdn/memoize";
|
|
10
|
+
// import { Memoize } from "@chriscdn/memoize";
|
|
11
11
|
|
|
12
12
|
const fsp = fs.promises;
|
|
13
13
|
|
|
14
14
|
type DirectoryPath = string;
|
|
15
|
+
type FileName = string;
|
|
15
16
|
type FilePath = string;
|
|
16
17
|
type Milliseconds = number;
|
|
17
18
|
|
|
@@ -85,8 +86,8 @@ class FileCache<T extends Record<string, any>> {
|
|
|
85
86
|
this._cleanupInterval,
|
|
86
87
|
);
|
|
87
88
|
|
|
88
|
-
this.resolveFileName = Memoize(this.resolveFileName.bind(this));
|
|
89
|
-
this.resolveFilePath = Memoize(this.resolveFilePath.bind(this));
|
|
89
|
+
// this.resolveFileName = Memoize(this.resolveFileName.bind(this));
|
|
90
|
+
// this.resolveFilePath = Memoize(this.resolveFilePath.bind(this));
|
|
90
91
|
}
|
|
91
92
|
|
|
92
93
|
/**
|
|
@@ -120,9 +121,6 @@ class FileCache<T extends Record<string, any>> {
|
|
|
120
121
|
const filePath = await this.resolveFilePath(args);
|
|
121
122
|
|
|
122
123
|
try {
|
|
123
|
-
// await this._cleanupGroupSemaphore.acquire("thumbnail");
|
|
124
|
-
// await this._semaphore.acquire(filePath);
|
|
125
|
-
|
|
126
124
|
await Promise.all([
|
|
127
125
|
this._cleanupGroupSemaphore.acquire("getFile"),
|
|
128
126
|
this._semaphore.acquire(filePath),
|
|
@@ -191,7 +189,7 @@ class FileCache<T extends Record<string, any>> {
|
|
|
191
189
|
* Uses the provided `resolveFileName` function if available, or falls back to
|
|
192
190
|
* generating a hash from the arguments to create a unique file name.
|
|
193
191
|
*/
|
|
194
|
-
private async resolveFileName(args: T): Promise<
|
|
192
|
+
private async resolveFileName(args: T): Promise<FileName> {
|
|
195
193
|
const [name, ext] = await Promise.all([
|
|
196
194
|
this._resolveCacheFileKey(args),
|
|
197
195
|
this._ext(args),
|
|
@@ -200,7 +198,7 @@ class FileCache<T extends Record<string, any>> {
|
|
|
200
198
|
return path.format({
|
|
201
199
|
name,
|
|
202
200
|
ext,
|
|
203
|
-
});
|
|
201
|
+
}) as FileName;
|
|
204
202
|
}
|
|
205
203
|
|
|
206
204
|
/**
|
|
@@ -217,7 +215,6 @@ class FileCache<T extends Record<string, any>> {
|
|
|
217
215
|
fileName[0],
|
|
218
216
|
fileName[1],
|
|
219
217
|
fileName[2],
|
|
220
|
-
// fileName[3],
|
|
221
218
|
fileName,
|
|
222
219
|
);
|
|
223
220
|
|
|
@@ -225,4 +222,4 @@ class FileCache<T extends Record<string, any>> {
|
|
|
225
222
|
}
|
|
226
223
|
}
|
|
227
224
|
|
|
228
|
-
export { type DirectoryPath, FileCache, type FilePath };
|
|
225
|
+
export { type DirectoryPath, FileCache, type FileName, type FilePath };
|