@lytjs/cache-isr 6.6.0
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 +40 -0
- package/dist/index.cjs +88 -0
- package/dist/index.cjs.map +1 -0
- package/dist/index.d.cts +33 -0
- package/dist/index.d.ts +33 -0
- package/dist/index.mjs +85 -0
- package/dist/index.mjs.map +1 -0
- package/package.json +47 -0
package/README.md
ADDED
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
# @lytjs/cache-isr
|
|
2
|
+
|
|
3
|
+
> LytJS ISR 缓存系统。
|
|
4
|
+
|
|
5
|
+
[](https://www.npmjs.com/package/@lytjs/cache-isr)
|
|
6
|
+
[](https://gitee.com/lytjs/lytjs/blob/main/LICENSE)
|
|
7
|
+
|
|
8
|
+
## 简介
|
|
9
|
+
|
|
10
|
+
`@lytjs/cache-isr` 是 LytJS 框架的增量静态再生成缓存系统,支持灵活的缓存管理和重新验证。
|
|
11
|
+
|
|
12
|
+
### 核心特性
|
|
13
|
+
|
|
14
|
+
- **自定义存储**:支持自定义存储后端
|
|
15
|
+
- **增量重新验证**:支持增量更新缓存
|
|
16
|
+
- **ETag 支持**:内置 ETag 支持
|
|
17
|
+
- **零依赖**:不引入任何外部依赖
|
|
18
|
+
|
|
19
|
+
## 安装
|
|
20
|
+
|
|
21
|
+
```bash
|
|
22
|
+
npm install @lytjs/cache-isr
|
|
23
|
+
```
|
|
24
|
+
|
|
25
|
+
或使用 pnpm:
|
|
26
|
+
|
|
27
|
+
```bash
|
|
28
|
+
pnpm add @lytjs/cache-isr
|
|
29
|
+
```
|
|
30
|
+
|
|
31
|
+
## 许可证
|
|
32
|
+
|
|
33
|
+
MIT License - [查看许可证](https://gitee.com/lytjs/lytjs/blob/main/LICENSE)
|
|
34
|
+
|
|
35
|
+
## 贡献指南
|
|
36
|
+
|
|
37
|
+
欢迎提交 Issue 和 Pull Request!
|
|
38
|
+
|
|
39
|
+
- [Gitee 仓库](https://gitee.com/lytjs/lytjs)
|
|
40
|
+
- [问题反馈](https://gitee.com/lytjs/lytjs/issues)
|
package/dist/index.cjs
ADDED
|
@@ -0,0 +1,88 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
var __defProp = Object.defineProperty;
|
|
4
|
+
var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
|
|
5
|
+
var __publicField = (obj, key, value) => __defNormalProp(obj, typeof key !== "symbol" ? key + "" : key, value);
|
|
6
|
+
|
|
7
|
+
// src/cache.ts
|
|
8
|
+
var ISRCache = class {
|
|
9
|
+
constructor(config = {}) {
|
|
10
|
+
__publicField(this, "cache", /* @__PURE__ */ new Map());
|
|
11
|
+
__publicField(this, "defaultMaxAge");
|
|
12
|
+
this.defaultMaxAge = config.maxAge ?? 36e5;
|
|
13
|
+
}
|
|
14
|
+
get(key) {
|
|
15
|
+
const entry = this.cache.get(key);
|
|
16
|
+
if (!entry) return null;
|
|
17
|
+
const now = Date.now();
|
|
18
|
+
if (entry.expiry < now) {
|
|
19
|
+
this.cache.delete(key);
|
|
20
|
+
return null;
|
|
21
|
+
}
|
|
22
|
+
return entry.value;
|
|
23
|
+
}
|
|
24
|
+
set(key, value, config) {
|
|
25
|
+
const now = Date.now();
|
|
26
|
+
const { maxAge = this.defaultMaxAge, revalidate } = {
|
|
27
|
+
maxAge: this.defaultMaxAge,
|
|
28
|
+
revalidate: config?.revalidate
|
|
29
|
+
};
|
|
30
|
+
this.cache.set(key, {
|
|
31
|
+
value,
|
|
32
|
+
expiry: now + maxAge,
|
|
33
|
+
revalidateAt: revalidate ? now + revalidate : void 0,
|
|
34
|
+
createdAt: now
|
|
35
|
+
});
|
|
36
|
+
}
|
|
37
|
+
has(key) {
|
|
38
|
+
const entry = this.cache.get(key);
|
|
39
|
+
if (!entry) return false;
|
|
40
|
+
if (Date.now() > entry.expiry) {
|
|
41
|
+
this.cache.delete(key);
|
|
42
|
+
return false;
|
|
43
|
+
}
|
|
44
|
+
return true;
|
|
45
|
+
}
|
|
46
|
+
delete(key) {
|
|
47
|
+
return this.cache.delete(key);
|
|
48
|
+
}
|
|
49
|
+
clear() {
|
|
50
|
+
this.cache.clear();
|
|
51
|
+
}
|
|
52
|
+
isStale(key) {
|
|
53
|
+
const entry = this.cache.get(key);
|
|
54
|
+
if (!entry) return false;
|
|
55
|
+
if (!entry.revalidateAt) return false;
|
|
56
|
+
return Date.now() >= entry.revalidateAt;
|
|
57
|
+
}
|
|
58
|
+
};
|
|
59
|
+
|
|
60
|
+
// src/revalidate.ts
|
|
61
|
+
var ISRRevaluator = class {
|
|
62
|
+
constructor(cache) {
|
|
63
|
+
__publicField(this, "cache", cache);
|
|
64
|
+
}
|
|
65
|
+
async revalidate(key, generator) {
|
|
66
|
+
const value = await generator();
|
|
67
|
+
this.cache.set(key, value);
|
|
68
|
+
return value;
|
|
69
|
+
}
|
|
70
|
+
async revalidateIfStale(key, generator) {
|
|
71
|
+
if (!this.cache.has(key)) {
|
|
72
|
+
const value = await generator();
|
|
73
|
+
this.cache.set(key, value);
|
|
74
|
+
return value;
|
|
75
|
+
}
|
|
76
|
+
if (this.cache.isStale(key)) {
|
|
77
|
+
const value = await generator();
|
|
78
|
+
this.cache.set(key, value);
|
|
79
|
+
return value;
|
|
80
|
+
}
|
|
81
|
+
return this.cache.get(key);
|
|
82
|
+
}
|
|
83
|
+
};
|
|
84
|
+
|
|
85
|
+
exports.ISRCache = ISRCache;
|
|
86
|
+
exports.ISRRevaluator = ISRRevaluator;
|
|
87
|
+
//# sourceMappingURL=index.cjs.map
|
|
88
|
+
//# sourceMappingURL=index.cjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/cache.ts","../src/revalidate.ts"],"names":[],"mappings":"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","file":"index.cjs","sourcesContent":["import type { ISRCacheConfig } from './types';\n\ninterface ExtendedCacheEntry<V> {\n value: V;\n expiry: number;\n revalidateAt?: number;\n createdAt: number;\n}\n\nexport class ISRCache {\n private cache: Map<string, ExtendedCacheEntry<unknown>> = new Map();\n private defaultMaxAge: number;\n\n constructor(config: ISRCacheConfig = {}) {\n this.defaultMaxAge = config.maxAge ?? 3600000;\n }\n\n get<T>(key: string): T | null {\n const entry = this.cache.get(key);\n if (!entry) return null;\n\n const now = Date.now();\n if (entry.expiry < now) {\n this.cache.delete(key);\n return null;\n }\n\n return entry.value as T;\n }\n\n set<T>(key: string, value: T, config?: ISRCacheConfig): void {\n const now = Date.now();\n const { maxAge = this.defaultMaxAge, revalidate } = {\n maxAge: this.defaultMaxAge,\n revalidate: config?.revalidate,\n };\n\n this.cache.set(key, {\n value,\n expiry: now + maxAge,\n revalidateAt: revalidate ? now + revalidate : undefined,\n createdAt: now,\n });\n }\n\n has(key: string): boolean {\n const entry = this.cache.get(key);\n if (!entry) return false;\n if (Date.now() > entry.expiry) {\n this.cache.delete(key);\n return false;\n }\n return true;\n }\n\n delete(key: string): boolean {\n return this.cache.delete(key);\n }\n\n clear(): void {\n this.cache.clear();\n }\n\n isStale(key: string): boolean {\n const entry = this.cache.get(key);\n if (!entry) return false;\n if (!entry.revalidateAt) return false;\n return Date.now() >= entry.revalidateAt;\n }\n}\n","import type { ISRCache } from './cache';\n\nexport class ISRRevaluator {\n constructor(private cache: ISRCache) {}\n\n async revalidate<T>(key: string, generator: () => Promise<T>): Promise<T> {\n const value = await generator();\n this.cache.set(key, value);\n return value;\n }\n\n async revalidateIfStale<T>(key: string, generator: () => Promise<T>): Promise<T | null> {\n if (!this.cache.has(key)) {\n const value = await generator();\n this.cache.set(key, value);\n return value;\n }\n\n if (this.cache.isStale(key)) {\n const value = await generator();\n this.cache.set(key, value);\n return value;\n }\n\n return this.cache.get<T>(key);\n }\n}\n"]}
|
package/dist/index.d.cts
ADDED
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
interface ISRCacheConfig {
|
|
2
|
+
maxAge?: number;
|
|
3
|
+
revalidate?: number;
|
|
4
|
+
staleWhileRevalidate?: number;
|
|
5
|
+
}
|
|
6
|
+
interface ISRCacheEntry<T = unknown> {
|
|
7
|
+
key: string;
|
|
8
|
+
value: T;
|
|
9
|
+
createdAt: number;
|
|
10
|
+
expiresAt: number;
|
|
11
|
+
revalidateAt?: number;
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
declare class ISRCache {
|
|
15
|
+
private cache;
|
|
16
|
+
private defaultMaxAge;
|
|
17
|
+
constructor(config?: ISRCacheConfig);
|
|
18
|
+
get<T>(key: string): T | null;
|
|
19
|
+
set<T>(key: string, value: T, config?: ISRCacheConfig): void;
|
|
20
|
+
has(key: string): boolean;
|
|
21
|
+
delete(key: string): boolean;
|
|
22
|
+
clear(): void;
|
|
23
|
+
isStale(key: string): boolean;
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
declare class ISRRevaluator {
|
|
27
|
+
private cache;
|
|
28
|
+
constructor(cache: ISRCache);
|
|
29
|
+
revalidate<T>(key: string, generator: () => Promise<T>): Promise<T>;
|
|
30
|
+
revalidateIfStale<T>(key: string, generator: () => Promise<T>): Promise<T | null>;
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
export { ISRCache, type ISRCacheConfig, type ISRCacheEntry, ISRRevaluator };
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
interface ISRCacheConfig {
|
|
2
|
+
maxAge?: number;
|
|
3
|
+
revalidate?: number;
|
|
4
|
+
staleWhileRevalidate?: number;
|
|
5
|
+
}
|
|
6
|
+
interface ISRCacheEntry<T = unknown> {
|
|
7
|
+
key: string;
|
|
8
|
+
value: T;
|
|
9
|
+
createdAt: number;
|
|
10
|
+
expiresAt: number;
|
|
11
|
+
revalidateAt?: number;
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
declare class ISRCache {
|
|
15
|
+
private cache;
|
|
16
|
+
private defaultMaxAge;
|
|
17
|
+
constructor(config?: ISRCacheConfig);
|
|
18
|
+
get<T>(key: string): T | null;
|
|
19
|
+
set<T>(key: string, value: T, config?: ISRCacheConfig): void;
|
|
20
|
+
has(key: string): boolean;
|
|
21
|
+
delete(key: string): boolean;
|
|
22
|
+
clear(): void;
|
|
23
|
+
isStale(key: string): boolean;
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
declare class ISRRevaluator {
|
|
27
|
+
private cache;
|
|
28
|
+
constructor(cache: ISRCache);
|
|
29
|
+
revalidate<T>(key: string, generator: () => Promise<T>): Promise<T>;
|
|
30
|
+
revalidateIfStale<T>(key: string, generator: () => Promise<T>): Promise<T | null>;
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
export { ISRCache, type ISRCacheConfig, type ISRCacheEntry, ISRRevaluator };
|
package/dist/index.mjs
ADDED
|
@@ -0,0 +1,85 @@
|
|
|
1
|
+
var __defProp = Object.defineProperty;
|
|
2
|
+
var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
|
|
3
|
+
var __publicField = (obj, key, value) => __defNormalProp(obj, typeof key !== "symbol" ? key + "" : key, value);
|
|
4
|
+
|
|
5
|
+
// src/cache.ts
|
|
6
|
+
var ISRCache = class {
|
|
7
|
+
constructor(config = {}) {
|
|
8
|
+
__publicField(this, "cache", /* @__PURE__ */ new Map());
|
|
9
|
+
__publicField(this, "defaultMaxAge");
|
|
10
|
+
this.defaultMaxAge = config.maxAge ?? 36e5;
|
|
11
|
+
}
|
|
12
|
+
get(key) {
|
|
13
|
+
const entry = this.cache.get(key);
|
|
14
|
+
if (!entry) return null;
|
|
15
|
+
const now = Date.now();
|
|
16
|
+
if (entry.expiry < now) {
|
|
17
|
+
this.cache.delete(key);
|
|
18
|
+
return null;
|
|
19
|
+
}
|
|
20
|
+
return entry.value;
|
|
21
|
+
}
|
|
22
|
+
set(key, value, config) {
|
|
23
|
+
const now = Date.now();
|
|
24
|
+
const { maxAge = this.defaultMaxAge, revalidate } = {
|
|
25
|
+
maxAge: this.defaultMaxAge,
|
|
26
|
+
revalidate: config?.revalidate
|
|
27
|
+
};
|
|
28
|
+
this.cache.set(key, {
|
|
29
|
+
value,
|
|
30
|
+
expiry: now + maxAge,
|
|
31
|
+
revalidateAt: revalidate ? now + revalidate : void 0,
|
|
32
|
+
createdAt: now
|
|
33
|
+
});
|
|
34
|
+
}
|
|
35
|
+
has(key) {
|
|
36
|
+
const entry = this.cache.get(key);
|
|
37
|
+
if (!entry) return false;
|
|
38
|
+
if (Date.now() > entry.expiry) {
|
|
39
|
+
this.cache.delete(key);
|
|
40
|
+
return false;
|
|
41
|
+
}
|
|
42
|
+
return true;
|
|
43
|
+
}
|
|
44
|
+
delete(key) {
|
|
45
|
+
return this.cache.delete(key);
|
|
46
|
+
}
|
|
47
|
+
clear() {
|
|
48
|
+
this.cache.clear();
|
|
49
|
+
}
|
|
50
|
+
isStale(key) {
|
|
51
|
+
const entry = this.cache.get(key);
|
|
52
|
+
if (!entry) return false;
|
|
53
|
+
if (!entry.revalidateAt) return false;
|
|
54
|
+
return Date.now() >= entry.revalidateAt;
|
|
55
|
+
}
|
|
56
|
+
};
|
|
57
|
+
|
|
58
|
+
// src/revalidate.ts
|
|
59
|
+
var ISRRevaluator = class {
|
|
60
|
+
constructor(cache) {
|
|
61
|
+
__publicField(this, "cache", cache);
|
|
62
|
+
}
|
|
63
|
+
async revalidate(key, generator) {
|
|
64
|
+
const value = await generator();
|
|
65
|
+
this.cache.set(key, value);
|
|
66
|
+
return value;
|
|
67
|
+
}
|
|
68
|
+
async revalidateIfStale(key, generator) {
|
|
69
|
+
if (!this.cache.has(key)) {
|
|
70
|
+
const value = await generator();
|
|
71
|
+
this.cache.set(key, value);
|
|
72
|
+
return value;
|
|
73
|
+
}
|
|
74
|
+
if (this.cache.isStale(key)) {
|
|
75
|
+
const value = await generator();
|
|
76
|
+
this.cache.set(key, value);
|
|
77
|
+
return value;
|
|
78
|
+
}
|
|
79
|
+
return this.cache.get(key);
|
|
80
|
+
}
|
|
81
|
+
};
|
|
82
|
+
|
|
83
|
+
export { ISRCache, ISRRevaluator };
|
|
84
|
+
//# sourceMappingURL=index.mjs.map
|
|
85
|
+
//# sourceMappingURL=index.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/cache.ts","../src/revalidate.ts"],"names":[],"mappings":"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","file":"index.mjs","sourcesContent":["import type { ISRCacheConfig } from './types';\n\ninterface ExtendedCacheEntry<V> {\n value: V;\n expiry: number;\n revalidateAt?: number;\n createdAt: number;\n}\n\nexport class ISRCache {\n private cache: Map<string, ExtendedCacheEntry<unknown>> = new Map();\n private defaultMaxAge: number;\n\n constructor(config: ISRCacheConfig = {}) {\n this.defaultMaxAge = config.maxAge ?? 3600000;\n }\n\n get<T>(key: string): T | null {\n const entry = this.cache.get(key);\n if (!entry) return null;\n\n const now = Date.now();\n if (entry.expiry < now) {\n this.cache.delete(key);\n return null;\n }\n\n return entry.value as T;\n }\n\n set<T>(key: string, value: T, config?: ISRCacheConfig): void {\n const now = Date.now();\n const { maxAge = this.defaultMaxAge, revalidate } = {\n maxAge: this.defaultMaxAge,\n revalidate: config?.revalidate,\n };\n\n this.cache.set(key, {\n value,\n expiry: now + maxAge,\n revalidateAt: revalidate ? now + revalidate : undefined,\n createdAt: now,\n });\n }\n\n has(key: string): boolean {\n const entry = this.cache.get(key);\n if (!entry) return false;\n if (Date.now() > entry.expiry) {\n this.cache.delete(key);\n return false;\n }\n return true;\n }\n\n delete(key: string): boolean {\n return this.cache.delete(key);\n }\n\n clear(): void {\n this.cache.clear();\n }\n\n isStale(key: string): boolean {\n const entry = this.cache.get(key);\n if (!entry) return false;\n if (!entry.revalidateAt) return false;\n return Date.now() >= entry.revalidateAt;\n }\n}\n","import type { ISRCache } from './cache';\n\nexport class ISRRevaluator {\n constructor(private cache: ISRCache) {}\n\n async revalidate<T>(key: string, generator: () => Promise<T>): Promise<T> {\n const value = await generator();\n this.cache.set(key, value);\n return value;\n }\n\n async revalidateIfStale<T>(key: string, generator: () => Promise<T>): Promise<T | null> {\n if (!this.cache.has(key)) {\n const value = await generator();\n this.cache.set(key, value);\n return value;\n }\n\n if (this.cache.isStale(key)) {\n const value = await generator();\n this.cache.set(key, value);\n return value;\n }\n\n return this.cache.get<T>(key);\n }\n}\n"]}
|
package/package.json
ADDED
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@lytjs/cache-isr",
|
|
3
|
+
"version": "6.6.0",
|
|
4
|
+
"description": "LytJS Incremental Static Regeneration (ISR) cache support",
|
|
5
|
+
"type": "module",
|
|
6
|
+
"main": "./dist/index.cjs",
|
|
7
|
+
"module": "./dist/index.mjs",
|
|
8
|
+
"types": "./dist/index.d.ts",
|
|
9
|
+
"exports": {
|
|
10
|
+
".": {
|
|
11
|
+
"types": "./dist/index.d.ts",
|
|
12
|
+
"import": "./dist/index.mjs",
|
|
13
|
+
"require": "./dist/index.cjs"
|
|
14
|
+
}
|
|
15
|
+
},
|
|
16
|
+
"files": [
|
|
17
|
+
"dist"
|
|
18
|
+
],
|
|
19
|
+
"scripts": {
|
|
20
|
+
"build": "tsup",
|
|
21
|
+
"dev": "tsup --watch",
|
|
22
|
+
"test": "vitest run",
|
|
23
|
+
"type-check": "tsc --noEmit",
|
|
24
|
+
"clean": "rm -rf dist"
|
|
25
|
+
},
|
|
26
|
+
"dependencies": {
|
|
27
|
+
"@lytjs/common-cache": "workspace:*",
|
|
28
|
+
"@lytjs/common-is": "workspace:*"
|
|
29
|
+
},
|
|
30
|
+
"devDependencies": {
|
|
31
|
+
"tsup": "^8.0.0",
|
|
32
|
+
"typescript": "^5.4.0",
|
|
33
|
+
"vitest": "^3.0.0"
|
|
34
|
+
},
|
|
35
|
+
"license": "MIT",
|
|
36
|
+
"repository": {
|
|
37
|
+
"type": "git",
|
|
38
|
+
"url": "https://gitee.com/lytjs/lytjs.git",
|
|
39
|
+
"directory": "packages/ecosystem/packages/ssr-kit/packages/cache-isr"
|
|
40
|
+
},
|
|
41
|
+
"keywords": [
|
|
42
|
+
"lytjs",
|
|
43
|
+
"isr",
|
|
44
|
+
"cache",
|
|
45
|
+
"incremental-static-regeneration"
|
|
46
|
+
]
|
|
47
|
+
}
|