@chriscdn/file-cache 0.0.4 → 0.0.5
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 +2 -3
- package/__tests__/file-cache.test.ts +1 -1
- package/lib/index.d.ts +2 -2
- package/lib/index.js +10 -7
- package/lib/index.js.map +1 -1
- package/package.json +3 -3
- package/src/index.ts +12 -9
package/README.md
CHANGED
|
@@ -61,9 +61,8 @@ const options: FileCacheOptions<MyCallbackArgs> = {
|
|
|
61
61
|
await downloadAndConvertToJPG(url, filePath);
|
|
62
62
|
},
|
|
63
63
|
|
|
64
|
-
// Specifies the file extension for
|
|
65
|
-
|
|
66
|
-
ext: ".jpg",
|
|
64
|
+
// Specifies the file extension for the cached file. Can be synchronous or asynchronous.
|
|
65
|
+
ext: (context: MyCallbackArgs) => ".jpg",
|
|
67
66
|
|
|
68
67
|
// Determines the time-to-live (TTL) of a cached file, in milliseconds,
|
|
69
68
|
// based on when it was last accessed.
|
package/lib/index.d.ts
CHANGED
|
@@ -5,7 +5,7 @@ export type FileCacheOptions<T extends Record<string, any>> = {
|
|
|
5
5
|
cachePath: DirectoryPath;
|
|
6
6
|
autoCreateCachePath?: boolean;
|
|
7
7
|
cb: (filePath: FilePath, context: T, cache: FileCache<T>) => Promise<void>;
|
|
8
|
-
ext: string
|
|
8
|
+
ext: (context: T) => string | Promise<string>;
|
|
9
9
|
ttl: Milliseconds;
|
|
10
10
|
cleanupInterval?: Milliseconds;
|
|
11
11
|
};
|
|
@@ -60,6 +60,6 @@ declare class FileCache<T extends Record<string, any>> {
|
|
|
60
60
|
* @param args The arguments used to resolve the file path
|
|
61
61
|
* @returns The full path to the cached file
|
|
62
62
|
*/
|
|
63
|
-
resolveFilePath(args: T): FilePath
|
|
63
|
+
resolveFilePath(args: T): Promise<FilePath>;
|
|
64
64
|
}
|
|
65
65
|
export { type DirectoryPath, FileCache, type FilePath };
|
package/lib/index.js
CHANGED
|
@@ -7,6 +7,7 @@ import touch from "touch";
|
|
|
7
7
|
import { findNuke } from "@chriscdn/find-nuke";
|
|
8
8
|
import { Duration } from "@chriscdn/duration";
|
|
9
9
|
import { rimraf } from "rimraf";
|
|
10
|
+
import { Memoize } from "@chriscdn/memoize";
|
|
10
11
|
const fsp = fs.promises;
|
|
11
12
|
class FileCache {
|
|
12
13
|
_cachePath;
|
|
@@ -36,6 +37,8 @@ class FileCache {
|
|
|
36
37
|
// fire and forget
|
|
37
38
|
this.cleanup();
|
|
38
39
|
this._intervalId = setInterval(this.cleanup.bind(this), this._cleanupInterval);
|
|
40
|
+
this.resolveFileName = Memoize(this.resolveFileName.bind(this));
|
|
41
|
+
this.resolveFilePath = Memoize(this.resolveFilePath.bind(this));
|
|
39
42
|
}
|
|
40
43
|
/**
|
|
41
44
|
* Runs a cleanup pass to remove files older than 1 day from the cache.
|
|
@@ -65,7 +68,7 @@ class FileCache {
|
|
|
65
68
|
* @returns The path to the cached or newly created file
|
|
66
69
|
*/
|
|
67
70
|
async getFile(args) {
|
|
68
|
-
const filePath = this.resolveFilePath(args);
|
|
71
|
+
const filePath = await this.resolveFilePath(args);
|
|
69
72
|
try {
|
|
70
73
|
await Promise.all([
|
|
71
74
|
this._semaphore.acquire(filePath),
|
|
@@ -86,7 +89,7 @@ class FileCache {
|
|
|
86
89
|
return filePath;
|
|
87
90
|
}
|
|
88
91
|
async has(args) {
|
|
89
|
-
const filePath = this.resolveFilePath(args);
|
|
92
|
+
const filePath = await this.resolveFilePath(args);
|
|
90
93
|
return await pathExists(filePath);
|
|
91
94
|
}
|
|
92
95
|
/**
|
|
@@ -96,7 +99,7 @@ class FileCache {
|
|
|
96
99
|
* @returns True if the file was deleted, false if it didn't exist
|
|
97
100
|
*/
|
|
98
101
|
async expire(args) {
|
|
99
|
-
const filePath = this.resolveFilePath(args);
|
|
102
|
+
const filePath = await this.resolveFilePath(args);
|
|
100
103
|
try {
|
|
101
104
|
await this._semaphore.acquire(filePath);
|
|
102
105
|
if (await pathExists(filePath)) {
|
|
@@ -126,11 +129,11 @@ class FileCache {
|
|
|
126
129
|
* Uses the provided `resolveFileName` function if available, or falls back to
|
|
127
130
|
* generating a hash from the arguments to create a unique file name.
|
|
128
131
|
*/
|
|
129
|
-
resolveFileName(args) {
|
|
132
|
+
async resolveFileName(args) {
|
|
130
133
|
const baseName = sha1(JSON.stringify(args));
|
|
131
134
|
return path.format({
|
|
132
135
|
name: baseName,
|
|
133
|
-
ext: this._ext,
|
|
136
|
+
ext: await this._ext(args),
|
|
134
137
|
});
|
|
135
138
|
}
|
|
136
139
|
/**
|
|
@@ -139,8 +142,8 @@ class FileCache {
|
|
|
139
142
|
* @param args The arguments used to resolve the file path
|
|
140
143
|
* @returns The full path to the cached file
|
|
141
144
|
*/
|
|
142
|
-
resolveFilePath(args) {
|
|
143
|
-
const fileName = this.resolveFileName(args);
|
|
145
|
+
async resolveFilePath(args) {
|
|
146
|
+
const fileName = await this.resolveFileName(args);
|
|
144
147
|
const filePath = path.resolve(this._cachePath, fileName[0], fileName[1], fileName[2],
|
|
145
148
|
// fileName[3],
|
|
146
149
|
fileName);
|
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;
|
|
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.5",
|
|
4
4
|
"description": "File cache ",
|
|
5
5
|
"repository": "https://github.com/chriscdn/file-cache",
|
|
6
6
|
"author": "Christopher Meyer <chris@schwiiz.org>",
|
|
@@ -10,7 +10,6 @@
|
|
|
10
10
|
"module": "./lib/index.js",
|
|
11
11
|
"types": "./lib/index.d.ts",
|
|
12
12
|
"exports": {
|
|
13
|
-
"types": "./lib/index.d.ts",
|
|
14
13
|
"default": "./lib/index.js"
|
|
15
14
|
},
|
|
16
15
|
"scripts": {
|
|
@@ -20,7 +19,8 @@
|
|
|
20
19
|
"dependencies": {
|
|
21
20
|
"@chriscdn/duration": "^1.0.3",
|
|
22
21
|
"@chriscdn/find-nuke": "^0.0.4",
|
|
23
|
-
"@chriscdn/
|
|
22
|
+
"@chriscdn/memoize": "^1.0.9",
|
|
23
|
+
"@chriscdn/promise-semaphore": "^2.0.12",
|
|
24
24
|
"path-exists": "^5.0.0",
|
|
25
25
|
"rimraf": "^6.0.1",
|
|
26
26
|
"sha1": "^1.1.1",
|
package/src/index.ts
CHANGED
|
@@ -7,7 +7,7 @@ import touch from "touch";
|
|
|
7
7
|
import { findNuke } from "@chriscdn/find-nuke";
|
|
8
8
|
import { Duration } from "@chriscdn/duration";
|
|
9
9
|
import { rimraf } from "rimraf";
|
|
10
|
-
|
|
10
|
+
import { Memoize } from "@chriscdn/memoize";
|
|
11
11
|
const fsp = fs.promises;
|
|
12
12
|
|
|
13
13
|
type DirectoryPath = string;
|
|
@@ -18,7 +18,7 @@ export type FileCacheOptions<T extends Record<string, any>> = {
|
|
|
18
18
|
cachePath: DirectoryPath;
|
|
19
19
|
autoCreateCachePath?: boolean;
|
|
20
20
|
cb: (filePath: FilePath, context: T, cache: FileCache<T>) => Promise<void>;
|
|
21
|
-
ext: string
|
|
21
|
+
ext: (context: T) => string | Promise<string>;
|
|
22
22
|
ttl: Milliseconds;
|
|
23
23
|
cleanupInterval?: Milliseconds;
|
|
24
24
|
};
|
|
@@ -62,6 +62,9 @@ class FileCache<T extends Record<string, any>> {
|
|
|
62
62
|
this.cleanup.bind(this),
|
|
63
63
|
this._cleanupInterval,
|
|
64
64
|
);
|
|
65
|
+
|
|
66
|
+
this.resolveFileName = Memoize(this.resolveFileName.bind(this));
|
|
67
|
+
this.resolveFilePath = Memoize(this.resolveFilePath.bind(this));
|
|
65
68
|
}
|
|
66
69
|
|
|
67
70
|
/**
|
|
@@ -92,7 +95,7 @@ class FileCache<T extends Record<string, any>> {
|
|
|
92
95
|
* @returns The path to the cached or newly created file
|
|
93
96
|
*/
|
|
94
97
|
async getFile(args: T): Promise<FilePath> {
|
|
95
|
-
const filePath = this.resolveFilePath(args);
|
|
98
|
+
const filePath = await this.resolveFilePath(args);
|
|
96
99
|
|
|
97
100
|
try {
|
|
98
101
|
await Promise.all([
|
|
@@ -115,7 +118,7 @@ class FileCache<T extends Record<string, any>> {
|
|
|
115
118
|
}
|
|
116
119
|
|
|
117
120
|
async has(args: T): Promise<boolean> {
|
|
118
|
-
const filePath = this.resolveFilePath(args);
|
|
121
|
+
const filePath = await this.resolveFilePath(args);
|
|
119
122
|
return await pathExists(filePath);
|
|
120
123
|
}
|
|
121
124
|
|
|
@@ -126,7 +129,7 @@ class FileCache<T extends Record<string, any>> {
|
|
|
126
129
|
* @returns True if the file was deleted, false if it didn't exist
|
|
127
130
|
*/
|
|
128
131
|
async expire(args: T): Promise<boolean> {
|
|
129
|
-
const filePath = this.resolveFilePath(args);
|
|
132
|
+
const filePath = await this.resolveFilePath(args);
|
|
130
133
|
|
|
131
134
|
try {
|
|
132
135
|
await this._semaphore.acquire(filePath);
|
|
@@ -158,12 +161,12 @@ class FileCache<T extends Record<string, any>> {
|
|
|
158
161
|
* Uses the provided `resolveFileName` function if available, or falls back to
|
|
159
162
|
* generating a hash from the arguments to create a unique file name.
|
|
160
163
|
*/
|
|
161
|
-
private resolveFileName(args: T): string {
|
|
164
|
+
private async resolveFileName(args: T): Promise<string> {
|
|
162
165
|
const baseName = sha1(JSON.stringify(args));
|
|
163
166
|
|
|
164
167
|
return path.format({
|
|
165
168
|
name: baseName,
|
|
166
|
-
ext: this._ext,
|
|
169
|
+
ext: await this._ext(args),
|
|
167
170
|
});
|
|
168
171
|
}
|
|
169
172
|
|
|
@@ -173,8 +176,8 @@ class FileCache<T extends Record<string, any>> {
|
|
|
173
176
|
* @param args The arguments used to resolve the file path
|
|
174
177
|
* @returns The full path to the cached file
|
|
175
178
|
*/
|
|
176
|
-
resolveFilePath(args: T): FilePath {
|
|
177
|
-
const fileName = this.resolveFileName(args);
|
|
179
|
+
async resolveFilePath(args: T): Promise<FilePath> {
|
|
180
|
+
const fileName = await this.resolveFileName(args);
|
|
178
181
|
|
|
179
182
|
const filePath = path.resolve(
|
|
180
183
|
this._cachePath,
|