@hyperttp/cache 1.1.5 → 1.1.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/package.json +1 -1
- package/plugin.d.ts +3 -15
- package/plugin.d.ts.map +1 -1
- package/plugin.js +52 -105
- package/plugin.js.map +1 -1
- package/utils/createHttpResponse.d.ts +21 -0
- package/utils/createHttpResponse.d.ts.map +1 -0
- package/utils/createHttpResponse.js +60 -0
- package/utils/createHttpResponse.js.map +1 -0
package/package.json
CHANGED
package/plugin.d.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import
|
|
2
|
-
import type { CacheManagerOptions, LightweightResponse } from "./types/cache.js";
|
|
1
|
+
import { CacheManagerOptions, LightweightResponse } from "./types/cache.js";
|
|
3
2
|
import { CacheManager } from "./utils/CacheManager.js";
|
|
3
|
+
import type { HyperPlugin } from "@hyperttp/types";
|
|
4
4
|
/**
|
|
5
5
|
* @en Extends the PluginContext to include the cache manager instance.
|
|
6
6
|
* @ru Расширяет PluginContext, добавляя экземпляр менеджера кэша.
|
|
@@ -46,19 +46,7 @@ declare module "@hyperttp/types" {
|
|
|
46
46
|
* @param key - Optional cache key to delete.
|
|
47
47
|
*/
|
|
48
48
|
clearCache(key?: string): void;
|
|
49
|
-
/**
|
|
50
|
-
* @en Returns runtime statistics, including cache size.
|
|
51
|
-
* @ru Возвращает статистику выполнения, включая размер кэша.
|
|
52
|
-
*/
|
|
53
|
-
getStats?(): Record<string, any>;
|
|
54
49
|
}
|
|
55
50
|
}
|
|
56
|
-
|
|
57
|
-
* @en Creates a caching plugin for Hyperttp.
|
|
58
|
-
* Handles in-memory caching, conditional requests (ETag/Last-Modified), and request deduplication.
|
|
59
|
-
* @ru Создает плагин кэширования для Hyperttp.
|
|
60
|
-
* Обрабатывает кэширование в памяти, условные запросы (ETag/Last-Modified) и дедупликацию запросов.
|
|
61
|
-
* @returns The configured HyperPlugin instance.
|
|
62
|
-
*/
|
|
63
|
-
export declare function withCache(): HyperPlugin;
|
|
51
|
+
export declare function withCache(options?: CacheManagerOptions): HyperPlugin;
|
|
64
52
|
//# sourceMappingURL=plugin.d.ts.map
|
package/plugin.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"plugin.d.ts","sourceRoot":"","sources":["../src/plugin.ts"],"names":[],"mappings":"AAAA,OAAO,
|
|
1
|
+
{"version":3,"file":"plugin.d.ts","sourceRoot":"","sources":["../src/plugin.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,mBAAmB,EAAE,mBAAmB,EAAE,MAAM,kBAAkB,CAAC;AAC5E,OAAO,EAAE,YAAY,EAAE,MAAM,yBAAyB,CAAC;AAEvD,OAAO,KAAK,EAGV,WAAW,EAEZ,MAAM,iBAAiB,CAAC;AAEzB;;;GAGG;AACH,OAAO,QAAQ,iBAAiB,CAAC;IAC/B,UAAU,aAAa;QACrB;;;WAGG;QACH,KAAK,CAAC,EAAE,YAAY,CAAC,mBAAmB,CAAC,CAAC;KAC3C;IACD;;;OAGG;IACH,UAAU,wBAAwB;QAChC;;;WAGG;QACH,KAAK,CAAC,EAAE,mBAAmB,GAAG;YAC5B;;;eAGG;YACH,OAAO,EAAE,OAAO,CAAC;YACjB;;;eAGG;YACH,OAAO,CAAC,EAAE,MAAM,EAAE,CAAC;SACpB,CAAC;KACH;IAED;;;OAGG;IACH,UAAU,UAAU;QAClB;;;;WAIG;QACH,UAAU,CAAC,GAAG,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;KAChC;CACF;AAUD,wBAAgB,SAAS,CAAC,OAAO,CAAC,EAAE,mBAAmB,GAAG,WAAW,CAiIpE"}
|
package/plugin.js
CHANGED
|
@@ -1,63 +1,26 @@
|
|
|
1
1
|
import { CacheManager } from "./utils/CacheManager.js";
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
*/
|
|
8
|
-
const createHttpResponse = (data) => ({
|
|
9
|
-
status: data.status,
|
|
10
|
-
headers: data.headers,
|
|
11
|
-
body: data.body,
|
|
12
|
-
url: data.url,
|
|
13
|
-
clone: () => createHttpResponse(data),
|
|
14
|
-
});
|
|
15
|
-
/**
|
|
16
|
-
* @en Creates a caching plugin for Hyperttp.
|
|
17
|
-
* Handles in-memory caching, conditional requests (ETag/Last-Modified), and request deduplication.
|
|
18
|
-
* @ru Создает плагин кэширования для Hyperttp.
|
|
19
|
-
* Обрабатывает кэширование в памяти, условные запросы (ETag/Last-Modified) и дедупликацию запросов.
|
|
20
|
-
* @returns The configured HyperPlugin instance.
|
|
21
|
-
*/
|
|
22
|
-
export function withCache() {
|
|
2
|
+
import { createHttpResponse } from "./utils/createHttpResponse.js";
|
|
3
|
+
export function withCache(options) {
|
|
4
|
+
if (options?.enabled === false) {
|
|
5
|
+
return { name: "hyperttp-cache" };
|
|
6
|
+
}
|
|
23
7
|
let cache;
|
|
24
|
-
|
|
8
|
+
const allowedMethods = new Set(options?.methods
|
|
9
|
+
? options.methods.map((m) => m.toUpperCase())
|
|
10
|
+
: ["GET", "HEAD"]);
|
|
25
11
|
const inFlight = new Map();
|
|
26
12
|
return {
|
|
27
13
|
name: "hyperttp-cache",
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
cache = new CacheManager(config?.cache);
|
|
35
|
-
ctx.cache = cache;
|
|
36
|
-
const methods = config?.cache?.methods ?? ["GET"];
|
|
37
|
-
allowedMethods = new Set(methods.map((m) => m.toUpperCase()));
|
|
38
|
-
if (core && typeof core.getStats === "function") {
|
|
39
|
-
const originalGetStats = core.getStats.bind(core);
|
|
40
|
-
core.getStats = function () {
|
|
41
|
-
const stats = originalGetStats();
|
|
42
|
-
return {
|
|
43
|
-
...stats,
|
|
44
|
-
cacheSize: cache.size,
|
|
45
|
-
};
|
|
46
|
-
};
|
|
47
|
-
}
|
|
48
|
-
core.clearCache = (key) => {
|
|
49
|
-
if (key) {
|
|
50
|
-
cache.delete(key);
|
|
51
|
-
}
|
|
52
|
-
else {
|
|
53
|
-
cache.clear();
|
|
54
|
-
}
|
|
55
|
-
};
|
|
14
|
+
setup() {
|
|
15
|
+
cache = new CacheManager({
|
|
16
|
+
maxSize: options?.maxSize ?? 1000,
|
|
17
|
+
ttl: options?.ttl ?? 300_000,
|
|
18
|
+
updateAgeOnGet: options?.updateAgeOnGet ?? true,
|
|
19
|
+
});
|
|
56
20
|
},
|
|
57
21
|
onRequest(req) {
|
|
58
|
-
if (!allowedMethods.has(req.method.toUpperCase()))
|
|
22
|
+
if (!allowedMethods.has(req.method.toUpperCase()))
|
|
59
23
|
return;
|
|
60
|
-
}
|
|
61
24
|
const cacheKey = req.url;
|
|
62
25
|
const cachedEntry = cache.getWithMetadata(cacheKey);
|
|
63
26
|
if (cachedEntry && !cachedEntry.etag && !cachedEntry.lastModified) {
|
|
@@ -65,84 +28,68 @@ export function withCache() {
|
|
|
65
28
|
}
|
|
66
29
|
if (cachedEntry) {
|
|
67
30
|
req.headers = { ...req.headers };
|
|
68
|
-
if (cachedEntry.etag)
|
|
31
|
+
if (cachedEntry.etag)
|
|
69
32
|
req.headers["if-none-match"] = cachedEntry.etag;
|
|
70
|
-
}
|
|
71
33
|
if (cachedEntry.lastModified) {
|
|
72
34
|
req.headers["if-modified-since"] = cachedEntry.lastModified;
|
|
73
35
|
}
|
|
74
36
|
}
|
|
75
37
|
const currentInFlight = inFlight.get(cacheKey);
|
|
76
38
|
if (currentInFlight) {
|
|
77
|
-
return
|
|
39
|
+
return new Promise((resolve, reject) => {
|
|
40
|
+
currentInFlight.listeners.push({ resolve, reject });
|
|
41
|
+
});
|
|
78
42
|
}
|
|
79
|
-
|
|
80
|
-
let rejectFn;
|
|
81
|
-
const promise = new Promise((resolve, reject) => {
|
|
82
|
-
resolveFn = resolve;
|
|
83
|
-
rejectFn = reject;
|
|
84
|
-
});
|
|
85
|
-
const trigger = {
|
|
86
|
-
promise,
|
|
87
|
-
resolve: resolveFn,
|
|
88
|
-
reject: (err) => {
|
|
89
|
-
inFlight.delete(cacheKey);
|
|
90
|
-
rejectFn(err);
|
|
91
|
-
},
|
|
92
|
-
};
|
|
93
|
-
inFlight.set(cacheKey, trigger);
|
|
94
|
-
setTimeout(() => {
|
|
95
|
-
if (inFlight.has(cacheKey)) {
|
|
96
|
-
console.warn(`[Cache] Warning: Request hung for ${cacheKey}, forcing cleanup`);
|
|
97
|
-
trigger.reject(new Error("Request timed out in cache plugin"));
|
|
98
|
-
}
|
|
99
|
-
}, 30_000);
|
|
100
|
-
return;
|
|
43
|
+
inFlight.set(cacheKey, { listeners: [], timestamp: Date.now() });
|
|
101
44
|
},
|
|
102
45
|
onResponse(res, req) {
|
|
103
46
|
if (!req)
|
|
104
47
|
return;
|
|
105
48
|
const cacheKey = req.url;
|
|
106
49
|
const trigger = inFlight.get(cacheKey);
|
|
107
|
-
if (!trigger)
|
|
108
|
-
return;
|
|
109
|
-
inFlight.delete(cacheKey);
|
|
110
50
|
if (res.status === 304) {
|
|
51
|
+
if (res.body &&
|
|
52
|
+
typeof res.body.cancel === "function") {
|
|
53
|
+
res.body.cancel().catch(() => { });
|
|
54
|
+
}
|
|
111
55
|
const cachedEntry = cache.getWithMetadata(cacheKey);
|
|
112
56
|
if (cachedEntry) {
|
|
113
|
-
const
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
}
|
|
121
|
-
trigger.resolve(restoredRes);
|
|
57
|
+
const restoredRes = createHttpResponse(cachedEntry.data);
|
|
58
|
+
res.status = restoredRes.status;
|
|
59
|
+
res.headers = restoredRes.headers;
|
|
60
|
+
res.body = restoredRes.body;
|
|
61
|
+
if (trigger) {
|
|
62
|
+
inFlight.delete(cacheKey);
|
|
63
|
+
trigger.listeners.forEach((l) => l.resolve(restoredRes.clone()));
|
|
64
|
+
}
|
|
122
65
|
return;
|
|
123
66
|
}
|
|
124
|
-
|
|
125
|
-
|
|
67
|
+
const err = new Error("304 status received, but cache entry is missing");
|
|
68
|
+
if (trigger) {
|
|
69
|
+
inFlight.delete(cacheKey);
|
|
70
|
+
trigger.listeners.forEach((l) => l.reject(err));
|
|
126
71
|
}
|
|
72
|
+
throw err;
|
|
127
73
|
}
|
|
128
74
|
if (res.status >= 200 && res.status < 300) {
|
|
129
|
-
const
|
|
130
|
-
|
|
75
|
+
const cleanHeaders = { ...res.headers };
|
|
76
|
+
cache.setWithMetadata(cacheKey, {
|
|
131
77
|
body: res.body,
|
|
132
78
|
status: res.status,
|
|
133
|
-
headers:
|
|
134
|
-
url: res.url,
|
|
135
|
-
}
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
? headers["etag"][0]
|
|
139
|
-
: headers["etag"],
|
|
140
|
-
lastModified: Array.isArray(headers["last-modified"])
|
|
141
|
-
? headers["last-modified"][0]
|
|
142
|
-
: headers["last-modified"],
|
|
79
|
+
headers: cleanHeaders,
|
|
80
|
+
url: res.url ?? "",
|
|
81
|
+
}, {
|
|
82
|
+
etag: cleanHeaders["etag"] ?? cleanHeaders["ETag"],
|
|
83
|
+
lastModified: cleanHeaders["last-modified"] ?? cleanHeaders["Last-Modified"],
|
|
143
84
|
});
|
|
144
85
|
}
|
|
145
|
-
trigger
|
|
86
|
+
if (trigger) {
|
|
87
|
+
inFlight.delete(cacheKey);
|
|
88
|
+
if (trigger.listeners.length > 0) {
|
|
89
|
+
const clonedForDependents = res.clone();
|
|
90
|
+
trigger.listeners.forEach((l) => l.resolve(clonedForDependents));
|
|
91
|
+
}
|
|
92
|
+
}
|
|
146
93
|
},
|
|
147
94
|
onError(err, req) {
|
|
148
95
|
if (!req)
|
|
@@ -150,7 +97,7 @@ export function withCache() {
|
|
|
150
97
|
const trigger = inFlight.get(req.url);
|
|
151
98
|
if (trigger) {
|
|
152
99
|
inFlight.delete(req.url);
|
|
153
|
-
trigger.reject(err);
|
|
100
|
+
trigger.listeners.forEach((l) => l.reject(err));
|
|
154
101
|
}
|
|
155
102
|
},
|
|
156
103
|
};
|
package/plugin.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"plugin.js","sourceRoot":"","sources":["../src/plugin.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"plugin.js","sourceRoot":"","sources":["../src/plugin.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import type { HttpResponse } from "@hyperttp/types";
|
|
2
|
+
import { LightweightResponse } from "../types/cache.js";
|
|
3
|
+
/**
|
|
4
|
+
* @en Reconstructs a full HttpResponse object from a lightweight cache response.
|
|
5
|
+
* @ru Реконструирует полный объект HttpResponse из легковесного ответа кэша.
|
|
6
|
+
*
|
|
7
|
+
* @param snapshot - Lightweight response object containing cached data.
|
|
8
|
+
* @returns A fully compatible HttpResponse object with methods like .text(), .json(), and .clone().
|
|
9
|
+
*
|
|
10
|
+
* @example
|
|
11
|
+
* const cached = {
|
|
12
|
+
* status: 200,
|
|
13
|
+
* headers: { 'content-type': 'application/json' },
|
|
14
|
+
* url: 'https://api.example.com/data',
|
|
15
|
+
* body: { id: 1, name: 'John' }
|
|
16
|
+
* };
|
|
17
|
+
* const response = createHttpResponse(cached);
|
|
18
|
+
* const data = await response.json(); // { id: 1, name: 'John' }
|
|
19
|
+
*/
|
|
20
|
+
export declare function createHttpResponse(snapshot: LightweightResponse<unknown>): HttpResponse<unknown>;
|
|
21
|
+
//# sourceMappingURL=createHttpResponse.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"createHttpResponse.d.ts","sourceRoot":"","sources":["../../src/utils/createHttpResponse.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,iBAAiB,CAAC;AACpD,OAAO,EAAE,mBAAmB,EAAE,MAAM,mBAAmB,CAAC;AAExD;;;;;;;;;;;;;;;;GAgBG;AACH,wBAAgB,kBAAkB,CAChC,QAAQ,EAAE,mBAAmB,CAAC,OAAO,CAAC,GACrC,YAAY,CAAC,OAAO,CAAC,CA6CvB"}
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @en Reconstructs a full HttpResponse object from a lightweight cache response.
|
|
3
|
+
* @ru Реконструирует полный объект HttpResponse из легковесного ответа кэша.
|
|
4
|
+
*
|
|
5
|
+
* @param snapshot - Lightweight response object containing cached data.
|
|
6
|
+
* @returns A fully compatible HttpResponse object with methods like .text(), .json(), and .clone().
|
|
7
|
+
*
|
|
8
|
+
* @example
|
|
9
|
+
* const cached = {
|
|
10
|
+
* status: 200,
|
|
11
|
+
* headers: { 'content-type': 'application/json' },
|
|
12
|
+
* url: 'https://api.example.com/data',
|
|
13
|
+
* body: { id: 1, name: 'John' }
|
|
14
|
+
* };
|
|
15
|
+
* const response = createHttpResponse(cached);
|
|
16
|
+
* const data = await response.json(); // { id: 1, name: 'John' }
|
|
17
|
+
*/
|
|
18
|
+
export function createHttpResponse(snapshot) {
|
|
19
|
+
return {
|
|
20
|
+
status: snapshot.status,
|
|
21
|
+
headers: { ...snapshot.headers },
|
|
22
|
+
url: snapshot.url,
|
|
23
|
+
body: snapshot.body,
|
|
24
|
+
text() {
|
|
25
|
+
if (typeof snapshot.body === "string") {
|
|
26
|
+
return Promise.resolve(snapshot.body);
|
|
27
|
+
}
|
|
28
|
+
try {
|
|
29
|
+
return Promise.resolve(JSON.stringify(snapshot.body));
|
|
30
|
+
}
|
|
31
|
+
catch {
|
|
32
|
+
return Promise.resolve("");
|
|
33
|
+
}
|
|
34
|
+
},
|
|
35
|
+
json() {
|
|
36
|
+
return Promise.resolve(snapshot.body);
|
|
37
|
+
},
|
|
38
|
+
dump() {
|
|
39
|
+
return Promise.resolve();
|
|
40
|
+
},
|
|
41
|
+
clone() {
|
|
42
|
+
let clonedBody = snapshot.body;
|
|
43
|
+
if (snapshot.body && typeof snapshot.body === "object") {
|
|
44
|
+
if (!(snapshot.body instanceof ReadableStream)) {
|
|
45
|
+
try {
|
|
46
|
+
clonedBody = structuredClone(snapshot.body);
|
|
47
|
+
}
|
|
48
|
+
catch {
|
|
49
|
+
clonedBody = JSON.parse(JSON.stringify(snapshot.body));
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
return createHttpResponse({
|
|
54
|
+
...snapshot,
|
|
55
|
+
body: clonedBody,
|
|
56
|
+
});
|
|
57
|
+
},
|
|
58
|
+
};
|
|
59
|
+
}
|
|
60
|
+
//# sourceMappingURL=createHttpResponse.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"createHttpResponse.js","sourceRoot":"","sources":["../../src/utils/createHttpResponse.ts"],"names":[],"mappings":"AAGA;;;;;;;;;;;;;;;;GAgBG;AACH,MAAM,UAAU,kBAAkB,CAChC,QAAsC;IAEtC,OAAO;QACL,MAAM,EAAE,QAAQ,CAAC,MAAM;QACvB,OAAO,EAAE,EAAE,GAAG,QAAQ,CAAC,OAAO,EAAE;QAChC,GAAG,EAAE,QAAQ,CAAC,GAAG;QACjB,IAAI,EAAE,QAAQ,CAAC,IAAI;QAEnB,IAAI;YACF,IAAI,OAAO,QAAQ,CAAC,IAAI,KAAK,QAAQ,EAAE,CAAC;gBACtC,OAAO,OAAO,CAAC,OAAO,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC;YACxC,CAAC;YACD,IAAI,CAAC;gBACH,OAAO,OAAO,CAAC,OAAO,CAAC,IAAI,CAAC,SAAS,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC,CAAC;YACxD,CAAC;YAAC,MAAM,CAAC;gBACP,OAAO,OAAO,CAAC,OAAO,CAAC,EAAE,CAAC,CAAC;YAC7B,CAAC;QACH,CAAC;QAED,IAAI;YACF,OAAO,OAAO,CAAC,OAAO,CAAC,QAAQ,CAAC,IAAS,CAAC,CAAC;QAC7C,CAAC;QAED,IAAI;YACF,OAAO,OAAO,CAAC,OAAO,EAAE,CAAC;QAC3B,CAAC;QAED,KAAK;YACH,IAAI,UAAU,GAAG,QAAQ,CAAC,IAAI,CAAC;YAE/B,IAAI,QAAQ,CAAC,IAAI,IAAI,OAAO,QAAQ,CAAC,IAAI,KAAK,QAAQ,EAAE,CAAC;gBACvD,IAAI,CAAC,CAAC,QAAQ,CAAC,IAAI,YAAY,cAAc,CAAC,EAAE,CAAC;oBAC/C,IAAI,CAAC;wBACH,UAAU,GAAG,eAAe,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC;oBAC9C,CAAC;oBAAC,MAAM,CAAC;wBACP,UAAU,GAAG,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,SAAS,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC,CAAC;oBACzD,CAAC;gBACH,CAAC;YACH,CAAC;YAED,OAAO,kBAAkB,CAAC;gBACxB,GAAG,QAAQ;gBACX,IAAI,EAAE,UAAU;aACjB,CAAC,CAAC;QACL,CAAC;KACF,CAAC;AACJ,CAAC"}
|