@nowarajs/elysia-cache 1.2.9 โ 1.3.1
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/AGENTS.md +44 -0
- package/README.md +18 -55
- package/dist/cache.d.ts +7 -13
- package/dist/index.js +66 -47
- package/dist/types/cache-item.d.ts +0 -1
- package/dist/types/cache-options.d.ts +2 -11
- package/package.json +24 -22
- package/dist/chunk-kqx0zdcn.js +0 -29
- package/dist/utils/index.d.ts +0 -1
- package/dist/utils/index.js +0 -7
package/AGENTS.md
ADDED
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: Development_Workflow_and_Code_Standards
|
|
3
|
+
description: Guidelines for development workflow and code standards
|
|
4
|
+
applyTo: '**'
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
## TypeScript and Project Conventions
|
|
8
|
+
1. Use underscore prefix for private or non-exported elements (e.g., _privateMethod)
|
|
9
|
+
2. Always specify visibility modifiers (private, protected, public), plus readonly, override, etc. when applicable
|
|
10
|
+
3. Naming conventions: camelCase for variables/functions/methods; PascalCase for classes/interfaces/types; SCREAMING_CASE for constants
|
|
11
|
+
4. Explicit typing: Always specify types for variables, parameters, and return values; never use any; prefer unknown if type cannot be determined; prefer interface over type alias for extendable objects
|
|
12
|
+
5. Documentation: Use TSDoc style; explain purpose, parameters, return values, and behavior; only document code when requested; for @throws, use format "@throws ({@link Type}) โ description"; for object/interface properties, write comment above each property instead of @param
|
|
13
|
+
6. Control structures: Omit curly braces for single-statement bodies
|
|
14
|
+
7. Path Aliases: Use $ for internal imports; do not import barrel files except as entry points
|
|
15
|
+
8. Export Pattern: Each directory has index.ts re-exporting public items; types exported in types/index.ts
|
|
16
|
+
9. Function style: Class methods use standard method syntax; helpers/callbacks/HOFs prefer arrow functions unless function syntax is required
|
|
17
|
+
|
|
18
|
+
## Contribution Principles
|
|
19
|
+
1. Follow TypeScript best practices and idiomatic patterns
|
|
20
|
+
2. Maintain existing code structure and modular organization
|
|
21
|
+
3. Keep developer experience in mind
|
|
22
|
+
4. Keep pull requests focused and well-documented (with TsDoc if asked)
|
|
23
|
+
5. Commit different types of changes separately; avoid mixing tests and features in one commit
|
|
24
|
+
|
|
25
|
+
## Commit Message Convention (Conventional Commits + Emoji)
|
|
26
|
+
Format: <type>(<emoji>): [summary up to 72 chars]
|
|
27
|
+
(blank line, then context or description)
|
|
28
|
+
|
|
29
|
+
<type> is lowercase
|
|
30
|
+
summary is surrounded by brackets `[summary]`
|
|
31
|
+
|
|
32
|
+
Types:
|
|
33
|
+
feat(๐) โ New features
|
|
34
|
+
fix(๐ง) โ Bug fixes
|
|
35
|
+
perf(โก) โ Performance improvements
|
|
36
|
+
refactor(๐งน) โ Refactoring
|
|
37
|
+
build(๐ฆ) โ Build tools / dependency changes
|
|
38
|
+
types(๐) โ Type definitions
|
|
39
|
+
chore(๐ฆ) โ Maintenance, non-code/test changes
|
|
40
|
+
examples(๐) โ Example updates
|
|
41
|
+
docs(๐) โ Documentation changes
|
|
42
|
+
test(๐งช) โ Test code updates
|
|
43
|
+
style(๐จ) โ Style/formatting only
|
|
44
|
+
ci(๐ค) โ CI/CD configuration
|
package/README.md
CHANGED
|
@@ -8,6 +8,11 @@
|
|
|
8
8
|
- [โจ Features](#-features)
|
|
9
9
|
- [๐ง Installation](#-installation)
|
|
10
10
|
- [โ๏ธ Usage](#-usage)
|
|
11
|
+
- [Basic Setup (In-Memory Store)](#basic-setup-in-memory-store)
|
|
12
|
+
- [Cache Configuration](#cache-configuration)
|
|
13
|
+
- [Redis Store Setup (Production)](#redis-store-setup-production)
|
|
14
|
+
- [Route-specific Caching](#route-specific-caching)
|
|
15
|
+
- [Storage Options](#storage-options)
|
|
11
16
|
- [๐ Cache Headers](#-cache-headers)
|
|
12
17
|
- [๐ API Reference](#-api-reference)
|
|
13
18
|
- [โ๏ธ License](#-license)
|
|
@@ -56,7 +61,9 @@ const app = new Elysia()
|
|
|
56
61
|
// This response will be cached automatically
|
|
57
62
|
return await fetchUsers()
|
|
58
63
|
}, {
|
|
59
|
-
isCached:
|
|
64
|
+
isCached: {
|
|
65
|
+
ttl: 300 // Cache for 5 minutes
|
|
66
|
+
}
|
|
60
67
|
})
|
|
61
68
|
.listen(3000)
|
|
62
69
|
```
|
|
@@ -66,18 +73,15 @@ const app = new Elysia()
|
|
|
66
73
|
```ts
|
|
67
74
|
import { cache } from '@nowarajs/elysia-cache'
|
|
68
75
|
|
|
76
|
+
// Using in-memory store (default)
|
|
69
77
|
const app = new Elysia()
|
|
70
|
-
.use(cache(
|
|
71
|
-
defaultTtl: 300, // Cache for 5 minutes by default
|
|
72
|
-
prefix: 'api:', // Add prefix to cache keys
|
|
73
|
-
storage: ':memory:' // Use in-memory storage (default)
|
|
74
|
-
}))
|
|
78
|
+
.use(cache())
|
|
75
79
|
```
|
|
76
80
|
|
|
77
81
|
### Redis Store Setup (Production)
|
|
78
82
|
|
|
79
83
|
```ts
|
|
80
|
-
import { IoRedisStore } from '@nowarajs/kv-store'
|
|
84
|
+
import { IoRedisStore } from '@nowarajs/kv-store/ioredis' // or you can use BunRedis with /bun-redis
|
|
81
85
|
import { cache } from '@nowarajs/elysia-cache'
|
|
82
86
|
|
|
83
87
|
// Create Redis store instance
|
|
@@ -89,36 +93,25 @@ await redisStore.connect()
|
|
|
89
93
|
|
|
90
94
|
// Create application with Redis-backed caching
|
|
91
95
|
const app = new Elysia()
|
|
92
|
-
.use(cache(
|
|
93
|
-
storage: redisStore,
|
|
94
|
-
defaultTtl: 600
|
|
95
|
-
}))
|
|
96
|
+
.use(cache(redisStore))
|
|
96
97
|
```
|
|
97
98
|
|
|
98
99
|
### Route-specific Caching
|
|
99
100
|
|
|
100
101
|
```ts
|
|
101
102
|
const app = new Elysia()
|
|
102
|
-
.use(cache(
|
|
103
|
+
.use(cache())
|
|
103
104
|
.get('/fast', () => getData(), {
|
|
104
|
-
isCached: 30 // Cache for 30 seconds
|
|
105
|
+
isCached: { ttl: 30 } // Cache for 30 seconds
|
|
105
106
|
})
|
|
106
107
|
.get('/slow', () => getSlowData(), {
|
|
107
|
-
isCached: 3600 // Cache for 1 hour
|
|
108
|
+
isCached: { ttl: 3600 } // Cache for 1 hour
|
|
108
109
|
})
|
|
109
|
-
.get('/
|
|
110
|
-
isCached:
|
|
110
|
+
.get('/prefixed', () => getData(), {
|
|
111
|
+
isCached: { ttl: 60, prefix: 'api:' } // With custom prefix
|
|
111
112
|
})
|
|
112
113
|
```
|
|
113
114
|
|
|
114
|
-
### Storage Options
|
|
115
|
-
|
|
116
|
-
| Store Type | Usage | Best For |
|
|
117
|
-
|------------|-------|----------|
|
|
118
|
-
| Default (`:memory:`) | `cache({ defaultTtl: 60 })` | Development, single instance |
|
|
119
|
-
| Explicit Memory | `cache({ storage: new MemoryStore(), ... })` | When you need store reference |
|
|
120
|
-
| Redis Store | `cache({ storage: redisStore, ... })` | Production, distributed systems |
|
|
121
|
-
|
|
122
115
|
## ๐ Cache Headers
|
|
123
116
|
|
|
124
117
|
The plugin automatically adds these headers to all responses:
|
|
@@ -143,36 +136,6 @@ X-Cache: HIT
|
|
|
143
136
|
|
|
144
137
|
## ๐ API Reference
|
|
145
138
|
|
|
146
|
-
### Cache Options
|
|
147
|
-
|
|
148
|
-
```ts
|
|
149
|
-
interface CacheOptions {
|
|
150
|
-
/** Default TTL in seconds (default: 60) */
|
|
151
|
-
defaultTtl?: number
|
|
152
|
-
|
|
153
|
-
/** Cache key prefix (default: '') */
|
|
154
|
-
prefix?: string
|
|
155
|
-
|
|
156
|
-
/** Storage backend (default: ':memory:') */
|
|
157
|
-
storage?: ':memory:' | KvStore
|
|
158
|
-
}
|
|
159
|
-
```
|
|
160
|
-
|
|
161
|
-
### Macro: `isCached`
|
|
162
|
-
|
|
163
|
-
The `isCached` macro enables caching for specific routes:
|
|
164
|
-
|
|
165
|
-
```ts
|
|
166
|
-
// Enable with default TTL
|
|
167
|
-
{ isCached: true }
|
|
168
|
-
|
|
169
|
-
// Enable with custom TTL (in seconds)
|
|
170
|
-
{ isCached: 300 }
|
|
171
|
-
|
|
172
|
-
// Disable caching
|
|
173
|
-
{ isCached: false }
|
|
174
|
-
```
|
|
175
|
-
|
|
176
139
|
You can find the complete API reference documentation for `Elysia Cache` at:
|
|
177
140
|
|
|
178
141
|
- [TypeDoc Documentation](https://nowarajs.github.io/elysia-cache)
|
|
@@ -183,6 +146,6 @@ Distributed under the MIT License. See [LICENSE](./LICENSE) for more information
|
|
|
183
146
|
|
|
184
147
|
## ๐ง Contact
|
|
185
148
|
|
|
149
|
+
- Mail: [nowarajs@pm.me](mailto:nowarajs@pm.me)
|
|
186
150
|
- GitHub: [NowaraJS](https://github.com/NowaraJS)
|
|
187
|
-
- Package: [@nowarajs/elysia-cache](https://www.npmjs.com/package/@nowarajs/elysia-cache)
|
|
188
151
|
|
package/dist/cache.d.ts
CHANGED
|
@@ -1,12 +1,9 @@
|
|
|
1
|
+
import type { KvStore } from '@nowarajs/kv-store/types';
|
|
1
2
|
import { Elysia } from 'elysia';
|
|
2
|
-
import { MemoryStore } from '@nowarajs/kv-store/memory';
|
|
3
3
|
import type { CacheOptions } from './types/cache-options';
|
|
4
|
-
export declare const cache: (
|
|
4
|
+
export declare const cache: (store?: KvStore) => Elysia<"", {
|
|
5
5
|
decorator: {};
|
|
6
|
-
store: {
|
|
7
|
-
kvStore: import("@nowarajs/kv-store/types").KvStore | MemoryStore;
|
|
8
|
-
_cachedRoutes: Set<string>;
|
|
9
|
-
};
|
|
6
|
+
store: {};
|
|
10
7
|
derive: {};
|
|
11
8
|
resolve: {};
|
|
12
9
|
}, {
|
|
@@ -16,11 +13,11 @@ export declare const cache: ({ defaultTtl, prefix, store }?: CacheOptions) => El
|
|
|
16
13
|
schema: {};
|
|
17
14
|
standaloneSchema: {};
|
|
18
15
|
macro: Partial<{
|
|
19
|
-
readonly isCached:
|
|
16
|
+
readonly isCached: CacheOptions;
|
|
20
17
|
}>;
|
|
21
18
|
macroFn: {
|
|
22
|
-
readonly isCached: (
|
|
23
|
-
readonly afterHandle: ({ set, responseValue,
|
|
19
|
+
readonly isCached: ({ ttl, prefix }: CacheOptions) => {
|
|
20
|
+
readonly afterHandle: ({ set, responseValue, request }: {
|
|
24
21
|
body: unknown;
|
|
25
22
|
query: Record<string, string>;
|
|
26
23
|
params: {};
|
|
@@ -37,10 +34,7 @@ export declare const cache: ({ defaultTtl, prefix, store }?: CacheOptions) => El
|
|
|
37
34
|
path: string;
|
|
38
35
|
route: string;
|
|
39
36
|
request: Request;
|
|
40
|
-
store: {
|
|
41
|
-
kvStore: import("@nowarajs/kv-store/types").KvStore | MemoryStore;
|
|
42
|
-
_cachedRoutes: Set<string>;
|
|
43
|
-
};
|
|
37
|
+
store: {};
|
|
44
38
|
status: <const Code extends number | keyof import("elysia").StatusMap, const T = Code extends 100 | 101 | 102 | 103 | 200 | 201 | 202 | 203 | 204 | 205 | 206 | 207 | 208 | 300 | 301 | 302 | 303 | 304 | 307 | 308 | 400 | 401 | 402 | 403 | 404 | 405 | 406 | 407 | 408 | 409 | 410 | 411 | 412 | 413 | 414 | 415 | 416 | 417 | 418 | 420 | 421 | 422 | 423 | 424 | 425 | 426 | 428 | 429 | 431 | 451 | 500 | 501 | 502 | 503 | 504 | 505 | 506 | 507 | 508 | 510 | 511 ? {
|
|
45
39
|
readonly 100: "Continue";
|
|
46
40
|
readonly 101: "Switching Protocols";
|
package/dist/index.js
CHANGED
|
@@ -1,66 +1,85 @@
|
|
|
1
1
|
// @bun
|
|
2
|
-
import {
|
|
3
|
-
generateCacheKey
|
|
4
|
-
} from "./chunk-kqx0zdcn.js";
|
|
5
|
-
|
|
6
2
|
// source/cache.ts
|
|
7
|
-
import { Elysia } from "elysia";
|
|
8
3
|
import { MemoryStore } from "@nowarajs/kv-store/memory";
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
const { response, metadata } = cachedData;
|
|
24
|
-
set.headers["cache-control"] = `max-age=${metadata.ttl}, public`;
|
|
25
|
-
set.headers["x-cache"] = "HIT";
|
|
26
|
-
set.headers["etag"] = `"${prefix}${cacheKey}"`;
|
|
27
|
-
set.headers["expires"] = new Date(Date.now() + metadata.ttl * 1000).toUTCString();
|
|
28
|
-
set.headers["last-modified"] = metadata.createdAt;
|
|
29
|
-
if (response instanceof Response)
|
|
30
|
-
return response.clone();
|
|
31
|
-
return response;
|
|
4
|
+
import { Elysia } from "elysia";
|
|
5
|
+
|
|
6
|
+
// source/utils/generate-cache-key.ts
|
|
7
|
+
var _calculateBodyHash = async (body, hasher) => {
|
|
8
|
+
if (!body)
|
|
9
|
+
return;
|
|
10
|
+
const reader = body.getReader();
|
|
11
|
+
try {
|
|
12
|
+
while (true) {
|
|
13
|
+
const { done, value } = await reader.read();
|
|
14
|
+
if (done)
|
|
15
|
+
break;
|
|
16
|
+
if (value)
|
|
17
|
+
hasher.update(new Uint8Array(value));
|
|
32
18
|
}
|
|
33
|
-
|
|
19
|
+
} finally {
|
|
20
|
+
reader.releaseLock();
|
|
34
21
|
}
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
22
|
+
};
|
|
23
|
+
var generateCacheKey = async (request) => {
|
|
24
|
+
const { method, url, headers } = request;
|
|
25
|
+
const hasher = new Bun.CryptoHasher("sha256");
|
|
26
|
+
hasher.update(method);
|
|
27
|
+
hasher.update(url);
|
|
28
|
+
hasher.update(JSON.stringify(headers));
|
|
29
|
+
await _calculateBodyHash(request.body, hasher);
|
|
30
|
+
return hasher.digest("hex");
|
|
31
|
+
};
|
|
32
|
+
|
|
33
|
+
// source/cache.ts
|
|
34
|
+
var cache = (store = new MemoryStore) => {
|
|
35
|
+
const cachedRoutes = new Map;
|
|
36
|
+
return new Elysia().onRequest(async ({ request, set }) => {
|
|
37
|
+
const route = `${request.method}:${new URL(request.url).pathname}`;
|
|
38
|
+
if (cachedRoutes.has(route)) {
|
|
39
|
+
const { ttl, prefix } = cachedRoutes.get(route);
|
|
40
|
+
const cacheKey = await generateCacheKey(request.clone());
|
|
41
|
+
const cacheItem = await store.get(`${prefix}${cacheKey}`);
|
|
42
|
+
if (cacheItem && typeof cacheItem === "object" && "response" in cacheItem && "metadata" in cacheItem) {
|
|
43
|
+
const createdAt = new Date(cacheItem.metadata.createdAt);
|
|
44
|
+
const expiresAt = new Date(createdAt.getTime() + ttl * 1000);
|
|
45
|
+
const now = Date.now();
|
|
46
|
+
const remaining = Math.max(0, Math.ceil((expiresAt.getTime() - now) / 1000));
|
|
47
|
+
set.headers["cache-control"] = `max-age=${remaining}, public`;
|
|
48
|
+
set.headers["etag"] = `"${prefix}${cacheKey}"`;
|
|
49
|
+
set.headers["last-modified"] = cacheItem.metadata.createdAt;
|
|
50
|
+
set.headers["expires"] = expiresAt.toUTCString();
|
|
51
|
+
set.headers["x-cache"] = "HIT";
|
|
52
|
+
if (cacheItem.response instanceof Response)
|
|
53
|
+
return cacheItem.response.clone();
|
|
54
|
+
return cacheItem.response;
|
|
55
|
+
}
|
|
56
|
+
set.headers["x-cache"] = "MISS";
|
|
57
|
+
}
|
|
58
|
+
return;
|
|
59
|
+
}).macro({
|
|
60
|
+
isCached: ({ ttl, prefix = "" }) => ({
|
|
61
|
+
async afterHandle({ set, responseValue, request }) {
|
|
62
|
+
const route = `${request.method}:${new URL(request.url).pathname}`;
|
|
63
|
+
if (!cachedRoutes.has(route))
|
|
64
|
+
cachedRoutes.set(route, { ttl, prefix });
|
|
44
65
|
const cacheKey = await generateCacheKey(request.clone());
|
|
45
66
|
const now = new Date;
|
|
46
67
|
set.headers["cache-control"] = `max-age=${ttl}, public`;
|
|
47
68
|
set.headers["etag"] = `"${prefix}${cacheKey}"`;
|
|
48
69
|
set.headers["last-modified"] = now.toUTCString();
|
|
49
70
|
set.headers["expires"] = new Date(now.getTime() + ttl * 1000).toUTCString();
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
const cacheData = {
|
|
71
|
+
set.headers["x-cache"] = "MISS";
|
|
72
|
+
const cacheItem = {
|
|
53
73
|
response: responseValue instanceof Response ? responseValue.clone() : responseValue,
|
|
54
74
|
metadata: {
|
|
55
|
-
createdAt: now.toUTCString()
|
|
56
|
-
ttl
|
|
75
|
+
createdAt: now.toUTCString()
|
|
57
76
|
}
|
|
58
77
|
};
|
|
59
|
-
await
|
|
78
|
+
await store.set(`${prefix}${cacheKey}`, cacheItem, ttl);
|
|
60
79
|
}
|
|
61
|
-
}
|
|
62
|
-
}
|
|
63
|
-
}
|
|
80
|
+
})
|
|
81
|
+
});
|
|
82
|
+
};
|
|
64
83
|
export {
|
|
65
84
|
cache
|
|
66
85
|
};
|
|
@@ -1,21 +1,12 @@
|
|
|
1
|
-
import type { KvStore } from '@nowarajs/kv-store/types';
|
|
2
1
|
export interface CacheOptions {
|
|
3
2
|
/**
|
|
4
|
-
*
|
|
5
|
-
*
|
|
6
|
-
* @defaultValue 60
|
|
3
|
+
* TTL in seconds
|
|
7
4
|
*/
|
|
8
|
-
|
|
5
|
+
ttl: number;
|
|
9
6
|
/**
|
|
10
7
|
* Cache key prefix
|
|
11
8
|
*
|
|
12
9
|
* @defaultValue ''
|
|
13
10
|
*/
|
|
14
11
|
prefix?: string;
|
|
15
|
-
/**
|
|
16
|
-
* Storage backend
|
|
17
|
-
*
|
|
18
|
-
* @defaultValue ':memory:'
|
|
19
|
-
*/
|
|
20
|
-
store?: ':memory:' | KvStore;
|
|
21
12
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@nowarajs/elysia-cache",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.3.1",
|
|
4
4
|
"author": "NowaraJS",
|
|
5
5
|
"description": "A template to create a bun package.",
|
|
6
6
|
"type": "module",
|
|
@@ -23,24 +23,24 @@
|
|
|
23
23
|
"test": "bun test --coverage"
|
|
24
24
|
},
|
|
25
25
|
"devDependencies": {
|
|
26
|
-
"@eslint/js": "^9.
|
|
27
|
-
"@nowarajs/error": "^1.3.
|
|
28
|
-
"@nowarajs/kv-store": "^1.
|
|
29
|
-
"@stylistic/eslint-plugin": "^5.
|
|
30
|
-
"@types/bun": "^1.
|
|
31
|
-
"
|
|
32
|
-
"
|
|
33
|
-
"
|
|
34
|
-
"typescript": "^5.9.
|
|
26
|
+
"@eslint/js": "^9.39.2",
|
|
27
|
+
"@nowarajs/error": "^1.3.10",
|
|
28
|
+
"@nowarajs/kv-store": "^1.3.0",
|
|
29
|
+
"@stylistic/eslint-plugin": "^5.6.1",
|
|
30
|
+
"@types/bun": "^1.3.5",
|
|
31
|
+
"elysia": "^1.4.19",
|
|
32
|
+
"eslint": "^9.39.2",
|
|
33
|
+
"globals": "^16.5.0",
|
|
34
|
+
"typescript": "^5.9.3",
|
|
35
|
+
"typescript-eslint": "^8.51.0"
|
|
35
36
|
},
|
|
36
37
|
"peerDependencies": {
|
|
37
|
-
"@nowarajs/error": "^1.3.
|
|
38
|
-
"@nowarajs/kv-store": "^1.
|
|
39
|
-
"elysia": "^1.4.
|
|
38
|
+
"@nowarajs/error": "^1.3.10",
|
|
39
|
+
"@nowarajs/kv-store": "^1.3.0",
|
|
40
|
+
"elysia": "^1.4.19"
|
|
40
41
|
},
|
|
41
42
|
"exports": {
|
|
42
43
|
"./types": "./dist/types/index.js",
|
|
43
|
-
"./utils": "./dist/utils/index.js",
|
|
44
44
|
".": "./dist/index.js"
|
|
45
45
|
},
|
|
46
46
|
"changelog": {
|
|
@@ -74,19 +74,24 @@
|
|
|
74
74
|
"semver": "patch"
|
|
75
75
|
},
|
|
76
76
|
"chore": {
|
|
77
|
-
"title": "๐ฆ Chore"
|
|
77
|
+
"title": "๐ฆ Chore",
|
|
78
|
+
"semver": "patch"
|
|
78
79
|
},
|
|
79
80
|
"examples": {
|
|
80
|
-
"title": "๐ Examples"
|
|
81
|
+
"title": "๐ Examples",
|
|
82
|
+
"semver": "patch"
|
|
81
83
|
},
|
|
82
84
|
"test": {
|
|
83
|
-
"title": "๐งช Tests"
|
|
85
|
+
"title": "๐งช Tests",
|
|
86
|
+
"semver": "patch"
|
|
84
87
|
},
|
|
85
88
|
"style": {
|
|
86
|
-
"title": "๐จ Styles"
|
|
89
|
+
"title": "๐จ Styles",
|
|
90
|
+
"semver": "patch"
|
|
87
91
|
},
|
|
88
92
|
"ci": {
|
|
89
|
-
"title": "๐ค CI"
|
|
93
|
+
"title": "๐ค CI",
|
|
94
|
+
"semver": "patch"
|
|
90
95
|
}
|
|
91
96
|
},
|
|
92
97
|
"templates": {
|
|
@@ -98,8 +103,5 @@
|
|
|
98
103
|
"repository": {
|
|
99
104
|
"type": "git",
|
|
100
105
|
"url": "https://github.com/NowaraJS/elysia-cache.git"
|
|
101
|
-
},
|
|
102
|
-
"dependencies": {
|
|
103
|
-
"ioredis": "^5.8.0"
|
|
104
106
|
}
|
|
105
107
|
}
|
package/dist/chunk-kqx0zdcn.js
DELETED
|
@@ -1,29 +0,0 @@
|
|
|
1
|
-
// @bun
|
|
2
|
-
// source/utils/generate-cache-key.ts
|
|
3
|
-
var _calculateBodyHash = async (body, hasher) => {
|
|
4
|
-
if (!body)
|
|
5
|
-
return;
|
|
6
|
-
const reader = body.getReader();
|
|
7
|
-
try {
|
|
8
|
-
while (true) {
|
|
9
|
-
const { done, value } = await reader.read();
|
|
10
|
-
if (done)
|
|
11
|
-
break;
|
|
12
|
-
if (value)
|
|
13
|
-
hasher.update(new Uint8Array(value));
|
|
14
|
-
}
|
|
15
|
-
} finally {
|
|
16
|
-
reader.releaseLock();
|
|
17
|
-
}
|
|
18
|
-
};
|
|
19
|
-
var generateCacheKey = async (request) => {
|
|
20
|
-
const { method, url, headers } = request;
|
|
21
|
-
const hasher = new Bun.CryptoHasher("sha256");
|
|
22
|
-
hasher.update(method);
|
|
23
|
-
hasher.update(url);
|
|
24
|
-
hasher.update(JSON.stringify(headers));
|
|
25
|
-
await _calculateBodyHash(request.body, hasher);
|
|
26
|
-
return hasher.digest("hex");
|
|
27
|
-
};
|
|
28
|
-
|
|
29
|
-
export { generateCacheKey };
|
package/dist/utils/index.d.ts
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
export { generateCacheKey } from './generate-cache-key';
|