@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 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 each cached file.
65
- // Currently, all files share the same extension (this may change in the future).
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.
@@ -18,7 +18,7 @@ describe("Cache Expiration", async () => {
18
18
  filePath,
19
19
  );
20
20
  },
21
- ext: "pdf",
21
+ ext: () => ".pdf",
22
22
  ttl: Duration.toMilliseconds({ seconds: 1 }),
23
23
  cleanupInterval: Duration.toMilliseconds({ seconds: 2 }),
24
24
  });
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":"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"}
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.4",
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/promise-semaphore": "^2.0.11",
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,