@commandkit/cache 0.0.0-dev.20250512141518
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/LICENSE +5 -0
- package/README.md +63 -0
- package/dist/cache-plugin.d.ts +9 -0
- package/dist/cache-plugin.js +34 -0
- package/dist/cache-provider.d.ts +12 -0
- package/dist/cache-provider.js +7 -0
- package/dist/index.d.ts +15 -0
- package/dist/index.js +35 -0
- package/dist/memory-cache.d.ts +10 -0
- package/dist/memory-cache.js +58 -0
- package/dist/use-cache-directive.d.ts +6 -0
- package/dist/use-cache-directive.js +23 -0
- package/dist/use-cache.d.ts +104 -0
- package/dist/use-cache.js +232 -0
- package/dist/utils.d.ts +1 -0
- package/dist/utils.js +47 -0
- package/package.json +40 -0
package/LICENSE
ADDED
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
Copyright 2025 Avraj Sahota
|
|
2
|
+
|
|
3
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the “Software”), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so.
|
|
4
|
+
|
|
5
|
+
THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
package/README.md
ADDED
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
# `@commandkit/cache`
|
|
2
|
+
|
|
3
|
+
CommandKit plugin for cache management.
|
|
4
|
+
|
|
5
|
+
## Installation
|
|
6
|
+
|
|
7
|
+
```bash
|
|
8
|
+
npm install @commandkit/cache
|
|
9
|
+
```
|
|
10
|
+
|
|
11
|
+
## Usage
|
|
12
|
+
|
|
13
|
+
To use the `@commandkit/cache` plugin, you need to add it to your CommandKit application. This can be done by importing the plugin and adding it to your configuration.
|
|
14
|
+
|
|
15
|
+
```ts
|
|
16
|
+
import { cache } from '@commandkit/cache';
|
|
17
|
+
|
|
18
|
+
export default defineConfig({
|
|
19
|
+
plugins: [
|
|
20
|
+
cache(),
|
|
21
|
+
],
|
|
22
|
+
})
|
|
23
|
+
```
|
|
24
|
+
|
|
25
|
+
Next, you can define advanced configurations for the plugin if needed. For example, you can set a custom cache provider:
|
|
26
|
+
|
|
27
|
+
```ts
|
|
28
|
+
import { setCacheProvider } from '@commandkit/cache';
|
|
29
|
+
import { RedisCache } from '@commandkit/redis';
|
|
30
|
+
|
|
31
|
+
setCacheProvider(new RedisCache({...}));
|
|
32
|
+
```
|
|
33
|
+
|
|
34
|
+
Then, you can add `"use cache"` directive to the function you want to cache. For example:
|
|
35
|
+
|
|
36
|
+
```ts
|
|
37
|
+
import { cacheTag, cacheLife } from '@commandkit/cache';
|
|
38
|
+
|
|
39
|
+
async function fetchDogs() {
|
|
40
|
+
"use cache";
|
|
41
|
+
|
|
42
|
+
cacheTag('dogs');
|
|
43
|
+
cacheLife('1h');
|
|
44
|
+
|
|
45
|
+
const dogs = await fetch('https://example.com/dogs');
|
|
46
|
+
return dogs.json();
|
|
47
|
+
}
|
|
48
|
+
```
|
|
49
|
+
|
|
50
|
+
Now the `fetchDogs` function will be cached for 1 hour. You can perform on-demand cache invalidation or revalidation using the `invalidate` and `revalidate` methods:
|
|
51
|
+
|
|
52
|
+
```ts
|
|
53
|
+
import { invalidate, revalidate } from '@commandkit/cache';
|
|
54
|
+
|
|
55
|
+
async function refreshCache() {
|
|
56
|
+
// invalidate the cache for the "dogs" tag. This will remove the cached data.
|
|
57
|
+
// calling the function again will fetch fresh data.
|
|
58
|
+
await invalidate('dogs');
|
|
59
|
+
|
|
60
|
+
// revalidate the cache for the "dogs" tag. This will fetch fresh data and update the cache.
|
|
61
|
+
await revalidate('dogs');
|
|
62
|
+
}
|
|
63
|
+
```
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import { RuntimePlugin } from 'commandkit';
|
|
2
|
+
import type { CacheProvider } from './cache-provider';
|
|
3
|
+
export declare function setCacheProvider(provider: CacheProvider): void;
|
|
4
|
+
export declare function getCacheProvider(): CacheProvider;
|
|
5
|
+
export declare class CachePlugin extends RuntimePlugin {
|
|
6
|
+
name: string;
|
|
7
|
+
activate(): Promise<void>;
|
|
8
|
+
deactivate(): Promise<void>;
|
|
9
|
+
}
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.CachePlugin = void 0;
|
|
4
|
+
exports.setCacheProvider = setCacheProvider;
|
|
5
|
+
exports.getCacheProvider = getCacheProvider;
|
|
6
|
+
const commandkit_1 = require("commandkit");
|
|
7
|
+
const memory_cache_1 = require("./memory-cache");
|
|
8
|
+
let cacheProvider = null;
|
|
9
|
+
function setCacheProvider(provider) {
|
|
10
|
+
cacheProvider = provider;
|
|
11
|
+
}
|
|
12
|
+
function getCacheProvider() {
|
|
13
|
+
if (!cacheProvider) {
|
|
14
|
+
throw new Error('Cache provider is not set. Please set a cache provider.');
|
|
15
|
+
}
|
|
16
|
+
return cacheProvider;
|
|
17
|
+
}
|
|
18
|
+
class CachePlugin extends commandkit_1.RuntimePlugin {
|
|
19
|
+
constructor() {
|
|
20
|
+
super(...arguments);
|
|
21
|
+
this.name = 'CommandKitCachePlugin';
|
|
22
|
+
}
|
|
23
|
+
async activate() {
|
|
24
|
+
if (!cacheProvider) {
|
|
25
|
+
cacheProvider = new memory_cache_1.MemoryCache();
|
|
26
|
+
}
|
|
27
|
+
commandkit_1.Logger.info('CommandKit CachePlugin has been activated!');
|
|
28
|
+
}
|
|
29
|
+
async deactivate() {
|
|
30
|
+
cacheProvider = null;
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
exports.CachePlugin = CachePlugin;
|
|
34
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiY2FjaGUtcGx1Z2luLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vc3JjL2NhY2hlLXBsdWdpbi50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOzs7QUFNQSw0Q0FFQztBQUVELDRDQU1DO0FBaEJELDJDQUFtRDtBQUVuRCxpREFBNkM7QUFFN0MsSUFBSSxhQUFhLEdBQXlCLElBQUksQ0FBQztBQUUvQyxTQUFnQixnQkFBZ0IsQ0FBQyxRQUF1QjtJQUN0RCxhQUFhLEdBQUcsUUFBUSxDQUFDO0FBQzNCLENBQUM7QUFFRCxTQUFnQixnQkFBZ0I7SUFDOUIsSUFBSSxDQUFDLGFBQWEsRUFBRSxDQUFDO1FBQ25CLE1BQU0sSUFBSSxLQUFLLENBQUMseURBQXlELENBQUMsQ0FBQztJQUM3RSxDQUFDO0lBRUQsT0FBTyxhQUFhLENBQUM7QUFDdkIsQ0FBQztBQUVELE1BQWEsV0FBWSxTQUFRLDBCQUFhO0lBQTlDOztRQUNTLFNBQUksR0FBRyx1QkFBdUIsQ0FBQztJQWF4QyxDQUFDO0lBWFEsS0FBSyxDQUFDLFFBQVE7UUFDbkIsSUFBSSxDQUFDLGFBQWEsRUFBRSxDQUFDO1lBQ25CLGFBQWEsR0FBRyxJQUFJLDBCQUFXLEVBQUUsQ0FBQztRQUNwQyxDQUFDO1FBRUQsbUJBQU0sQ0FBQyxJQUFJLENBQUMsNENBQTRDLENBQUMsQ0FBQztJQUM1RCxDQUFDO0lBRU0sS0FBSyxDQUFDLFVBQVU7UUFDckIsYUFBYSxHQUFHLElBQUksQ0FBQztJQUN2QixDQUFDO0NBQ0Y7QUFkRCxrQ0FjQyJ9
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
export interface CacheEntry<T = unknown> {
|
|
2
|
+
value: T;
|
|
3
|
+
ttl?: number;
|
|
4
|
+
}
|
|
5
|
+
export declare abstract class CacheProvider {
|
|
6
|
+
abstract get<T>(key: string): Promise<CacheEntry<T> | undefined>;
|
|
7
|
+
abstract set<T>(key: string, value: T, ttl?: number): Promise<void>;
|
|
8
|
+
abstract exists(key: string): Promise<boolean>;
|
|
9
|
+
abstract delete(key: string): Promise<void>;
|
|
10
|
+
abstract clear(): Promise<void>;
|
|
11
|
+
abstract expire(key: string, ttl: number): Promise<void>;
|
|
12
|
+
}
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.CacheProvider = void 0;
|
|
4
|
+
class CacheProvider {
|
|
5
|
+
}
|
|
6
|
+
exports.CacheProvider = CacheProvider;
|
|
7
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiY2FjaGUtcHJvdmlkZXIuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi9zcmMvY2FjaGUtcHJvdmlkZXIudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7O0FBS0EsTUFBc0IsYUFBYTtDQU9sQztBQVBELHNDQU9DIn0=
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import type { CommonDirectiveTransformerOptions, CommandKitPlugin } from 'commandkit';
|
|
2
|
+
export * from './cache-provider';
|
|
3
|
+
export * from './memory-cache';
|
|
4
|
+
export * from './use-cache';
|
|
5
|
+
export * from './use-cache-directive';
|
|
6
|
+
export * from './cache-plugin';
|
|
7
|
+
/**
|
|
8
|
+
* The cache plugin for CommandKit.
|
|
9
|
+
* @param options The options for the cache plugin.
|
|
10
|
+
* @returns The cache plugin for CommandKit.
|
|
11
|
+
*/
|
|
12
|
+
export declare function cache(options?: Partial<{
|
|
13
|
+
compiler: CommonDirectiveTransformerOptions;
|
|
14
|
+
runtime: Record<never, never>;
|
|
15
|
+
}>): CommandKitPlugin[];
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
+
if (k2 === undefined) k2 = k;
|
|
4
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
+
}
|
|
8
|
+
Object.defineProperty(o, k2, desc);
|
|
9
|
+
}) : (function(o, m, k, k2) {
|
|
10
|
+
if (k2 === undefined) k2 = k;
|
|
11
|
+
o[k2] = m[k];
|
|
12
|
+
}));
|
|
13
|
+
var __exportStar = (this && this.__exportStar) || function(m, exports) {
|
|
14
|
+
for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
|
|
15
|
+
};
|
|
16
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
17
|
+
exports.cache = cache;
|
|
18
|
+
const use_cache_directive_1 = require("./use-cache-directive");
|
|
19
|
+
const cache_plugin_1 = require("./cache-plugin");
|
|
20
|
+
__exportStar(require("./cache-provider"), exports);
|
|
21
|
+
__exportStar(require("./memory-cache"), exports);
|
|
22
|
+
__exportStar(require("./use-cache"), exports);
|
|
23
|
+
__exportStar(require("./use-cache-directive"), exports);
|
|
24
|
+
__exportStar(require("./cache-plugin"), exports);
|
|
25
|
+
/**
|
|
26
|
+
* The cache plugin for CommandKit.
|
|
27
|
+
* @param options The options for the cache plugin.
|
|
28
|
+
* @returns The cache plugin for CommandKit.
|
|
29
|
+
*/
|
|
30
|
+
function cache(options) {
|
|
31
|
+
const compiler = new use_cache_directive_1.UseCacheDirectivePlugin(options?.compiler);
|
|
32
|
+
const runtime = new cache_plugin_1.CachePlugin(options?.runtime ?? {});
|
|
33
|
+
return [compiler, runtime];
|
|
34
|
+
}
|
|
35
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaW5kZXguanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi9zcmMvaW5kZXgudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7Ozs7Ozs7Ozs7Ozs7OztBQWtCQSxzQkFVQztBQXhCRCwrREFBZ0U7QUFDaEUsaURBQTZDO0FBRTdDLG1EQUFpQztBQUNqQyxpREFBK0I7QUFDL0IsOENBQTRCO0FBQzVCLHdEQUFzQztBQUN0QyxpREFBK0I7QUFFL0I7Ozs7R0FJRztBQUNILFNBQWdCLEtBQUssQ0FDbkIsT0FHRTtJQUVGLE1BQU0sUUFBUSxHQUFHLElBQUksNkNBQXVCLENBQUMsT0FBTyxFQUFFLFFBQVEsQ0FBQyxDQUFDO0lBQ2hFLE1BQU0sT0FBTyxHQUFHLElBQUksMEJBQVcsQ0FBQyxPQUFPLEVBQUUsT0FBTyxJQUFJLEVBQUUsQ0FBQyxDQUFDO0lBRXhELE9BQU8sQ0FBQyxRQUFRLEVBQUUsT0FBTyxDQUFDLENBQUM7QUFDN0IsQ0FBQyJ9
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import { CacheEntry, CacheProvider } from './cache-provider';
|
|
2
|
+
export declare class MemoryCache extends CacheProvider {
|
|
3
|
+
#private;
|
|
4
|
+
get<T>(key: string): Promise<CacheEntry<T> | undefined>;
|
|
5
|
+
set<T>(key: string, value: T, ttl?: number): Promise<void>;
|
|
6
|
+
exists(key: string): Promise<boolean>;
|
|
7
|
+
delete(key: string): Promise<void>;
|
|
8
|
+
clear(): Promise<void>;
|
|
9
|
+
expire(key: string, ttl: number): Promise<void>;
|
|
10
|
+
}
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __classPrivateFieldGet = (this && this.__classPrivateFieldGet) || function (receiver, state, kind, f) {
|
|
3
|
+
if (kind === "a" && !f) throw new TypeError("Private accessor was defined without a getter");
|
|
4
|
+
if (typeof state === "function" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError("Cannot read private member from an object whose class did not declare it");
|
|
5
|
+
return kind === "m" ? f : kind === "a" ? f.call(receiver) : f ? f.value : state.get(receiver);
|
|
6
|
+
};
|
|
7
|
+
var _MemoryCache_cache;
|
|
8
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
9
|
+
exports.MemoryCache = void 0;
|
|
10
|
+
const cache_provider_1 = require("./cache-provider");
|
|
11
|
+
class MemoryCache extends cache_provider_1.CacheProvider {
|
|
12
|
+
constructor() {
|
|
13
|
+
super(...arguments);
|
|
14
|
+
_MemoryCache_cache.set(this, new Map());
|
|
15
|
+
}
|
|
16
|
+
async get(key) {
|
|
17
|
+
const entry = __classPrivateFieldGet(this, _MemoryCache_cache, "f").get(key);
|
|
18
|
+
if (!entry) {
|
|
19
|
+
return undefined;
|
|
20
|
+
}
|
|
21
|
+
if (entry.ttl && Date.now() > entry.ttl) {
|
|
22
|
+
__classPrivateFieldGet(this, _MemoryCache_cache, "f").delete(key);
|
|
23
|
+
return undefined;
|
|
24
|
+
}
|
|
25
|
+
return entry;
|
|
26
|
+
}
|
|
27
|
+
async set(key, value, ttl) {
|
|
28
|
+
const entry = {
|
|
29
|
+
value,
|
|
30
|
+
ttl: ttl != null ? Date.now() + ttl : undefined,
|
|
31
|
+
};
|
|
32
|
+
__classPrivateFieldGet(this, _MemoryCache_cache, "f").set(key, entry);
|
|
33
|
+
}
|
|
34
|
+
async exists(key) {
|
|
35
|
+
return __classPrivateFieldGet(this, _MemoryCache_cache, "f").has(key);
|
|
36
|
+
}
|
|
37
|
+
async delete(key) {
|
|
38
|
+
__classPrivateFieldGet(this, _MemoryCache_cache, "f").delete(key);
|
|
39
|
+
}
|
|
40
|
+
async clear() {
|
|
41
|
+
__classPrivateFieldGet(this, _MemoryCache_cache, "f").clear();
|
|
42
|
+
}
|
|
43
|
+
async expire(key, ttl) {
|
|
44
|
+
const entry = __classPrivateFieldGet(this, _MemoryCache_cache, "f").get(key);
|
|
45
|
+
if (!entry)
|
|
46
|
+
return;
|
|
47
|
+
const _ttl = Date.now() + ttl;
|
|
48
|
+
// delete if _ttl is in the past
|
|
49
|
+
if (_ttl < Date.now()) {
|
|
50
|
+
__classPrivateFieldGet(this, _MemoryCache_cache, "f").delete(key);
|
|
51
|
+
return;
|
|
52
|
+
}
|
|
53
|
+
entry.ttl = _ttl;
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
exports.MemoryCache = MemoryCache;
|
|
57
|
+
_MemoryCache_cache = new WeakMap();
|
|
58
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoibWVtb3J5LWNhY2hlLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vc3JjL21lbW9yeS1jYWNoZS50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOzs7Ozs7Ozs7QUFBQSxxREFBNkQ7QUFFN0QsTUFBYSxXQUFZLFNBQVEsOEJBQWE7SUFBOUM7O1FBQ0UsNkJBQVMsSUFBSSxHQUFHLEVBQXNCLEVBQUM7SUFxRHpDLENBQUM7SUFuRFEsS0FBSyxDQUFDLEdBQUcsQ0FBSSxHQUFXO1FBQzdCLE1BQU0sS0FBSyxHQUFHLHVCQUFBLElBQUksMEJBQU8sQ0FBQyxHQUFHLENBQUMsR0FBRyxDQUFDLENBQUM7UUFFbkMsSUFBSSxDQUFDLEtBQUssRUFBRSxDQUFDO1lBQ1gsT0FBTyxTQUFTLENBQUM7UUFDbkIsQ0FBQztRQUVELElBQUksS0FBSyxDQUFDLEdBQUcsSUFBSSxJQUFJLENBQUMsR0FBRyxFQUFFLEdBQUcsS0FBSyxDQUFDLEdBQUcsRUFBRSxDQUFDO1lBQ3hDLHVCQUFBLElBQUksMEJBQU8sQ0FBQyxNQUFNLENBQUMsR0FBRyxDQUFDLENBQUM7WUFDeEIsT0FBTyxTQUFTLENBQUM7UUFDbkIsQ0FBQztRQUVELE9BQU8sS0FBc0IsQ0FBQztJQUNoQyxDQUFDO0lBRU0sS0FBSyxDQUFDLEdBQUcsQ0FBSSxHQUFXLEVBQUUsS0FBUSxFQUFFLEdBQVk7UUFDckQsTUFBTSxLQUFLLEdBQWtCO1lBQzNCLEtBQUs7WUFDTCxHQUFHLEVBQUUsR0FBRyxJQUFJLElBQUksQ0FBQyxDQUFDLENBQUMsSUFBSSxDQUFDLEdBQUcsRUFBRSxHQUFHLEdBQUcsQ0FBQyxDQUFDLENBQUMsU0FBUztTQUNoRCxDQUFDO1FBRUYsdUJBQUEsSUFBSSwwQkFBTyxDQUFDLEdBQUcsQ0FBQyxHQUFHLEVBQUUsS0FBSyxDQUFDLENBQUM7SUFDOUIsQ0FBQztJQUVNLEtBQUssQ0FBQyxNQUFNLENBQUMsR0FBVztRQUM3QixPQUFPLHVCQUFBLElBQUksMEJBQU8sQ0FBQyxHQUFHLENBQUMsR0FBRyxDQUFDLENBQUM7SUFDOUIsQ0FBQztJQUVNLEtBQUssQ0FBQyxNQUFNLENBQUMsR0FBVztRQUM3Qix1QkFBQSxJQUFJLDBCQUFPLENBQUMsTUFBTSxDQUFDLEdBQUcsQ0FBQyxDQUFDO0lBQzFCLENBQUM7SUFFTSxLQUFLLENBQUMsS0FBSztRQUNoQix1QkFBQSxJQUFJLDBCQUFPLENBQUMsS0FBSyxFQUFFLENBQUM7SUFDdEIsQ0FBQztJQUVNLEtBQUssQ0FBQyxNQUFNLENBQUMsR0FBVyxFQUFFLEdBQVc7UUFDMUMsTUFBTSxLQUFLLEdBQUcsdUJBQUEsSUFBSSwwQkFBTyxDQUFDLEdBQUcsQ0FBQyxHQUFHLENBQUMsQ0FBQztRQUVuQyxJQUFJLENBQUMsS0FBSztZQUFFLE9BQU87UUFFbkIsTUFBTSxJQUFJLEdBQUcsSUFBSSxDQUFDLEdBQUcsRUFBRSxHQUFHLEdBQUcsQ0FBQztRQUU5QixnQ0FBZ0M7UUFDaEMsSUFBSSxJQUFJLEdBQUcsSUFBSSxDQUFDLEdBQUcsRUFBRSxFQUFFLENBQUM7WUFDdEIsdUJBQUEsSUFBSSwwQkFBTyxDQUFDLE1BQU0sQ0FBQyxHQUFHLENBQUMsQ0FBQztZQUN4QixPQUFPO1FBQ1QsQ0FBQztRQUVELEtBQUssQ0FBQyxHQUFHLEdBQUcsSUFBSSxDQUFDO0lBQ25CLENBQUM7Q0FDRjtBQXRERCxrQ0FzREMifQ==
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
import { CommonDirectiveTransformer, CommonDirectiveTransformerOptions, CompilerPluginRuntime } from 'commandkit';
|
|
2
|
+
export declare class UseCacheDirectivePlugin extends CommonDirectiveTransformer {
|
|
3
|
+
readonly name = "UseCacheDirectivePlugin";
|
|
4
|
+
constructor(options?: Partial<CommonDirectiveTransformerOptions>);
|
|
5
|
+
activate(ctx: CompilerPluginRuntime): Promise<void>;
|
|
6
|
+
}
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.UseCacheDirectivePlugin = void 0;
|
|
4
|
+
const commandkit_1 = require("commandkit");
|
|
5
|
+
class UseCacheDirectivePlugin extends commandkit_1.CommonDirectiveTransformer {
|
|
6
|
+
constructor(options) {
|
|
7
|
+
super({
|
|
8
|
+
enabled: true,
|
|
9
|
+
...options,
|
|
10
|
+
directive: 'use cache',
|
|
11
|
+
importPath: '@commandkit/cache',
|
|
12
|
+
importName: '__SECRET_USE_CACHE_INTERNAL_DO_NOT_USE_OR_YOU_WILL_BE_FIRED',
|
|
13
|
+
asyncOnly: true,
|
|
14
|
+
});
|
|
15
|
+
this.name = 'UseCacheDirectivePlugin';
|
|
16
|
+
}
|
|
17
|
+
async activate(ctx) {
|
|
18
|
+
super.activate(ctx);
|
|
19
|
+
commandkit_1.Logger.info('"use cache" directive compiler plugin activated');
|
|
20
|
+
}
|
|
21
|
+
}
|
|
22
|
+
exports.UseCacheDirectivePlugin = UseCacheDirectivePlugin;
|
|
23
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidXNlLWNhY2hlLWRpcmVjdGl2ZS5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uL3NyYy91c2UtY2FjaGUtZGlyZWN0aXZlLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7OztBQUFBLDJDQUtvQjtBQUVwQixNQUFhLHVCQUF3QixTQUFRLHVDQUEwQjtJQUdyRSxZQUFtQixPQUFvRDtRQUNyRSxLQUFLLENBQUM7WUFDSixPQUFPLEVBQUUsSUFBSTtZQUNiLEdBQUcsT0FBTztZQUNWLFNBQVMsRUFBRSxXQUFXO1lBQ3RCLFVBQVUsRUFBRSxtQkFBbUI7WUFDL0IsVUFBVSxFQUFFLDZEQUE2RDtZQUN6RSxTQUFTLEVBQUUsSUFBSTtTQUNoQixDQUFDLENBQUM7UUFWVyxTQUFJLEdBQUcseUJBQXlCLENBQUM7SUFXakQsQ0FBQztJQUVNLEtBQUssQ0FBQyxRQUFRLENBQUMsR0FBMEI7UUFDOUMsS0FBSyxDQUFDLFFBQVEsQ0FBQyxHQUFHLENBQUMsQ0FBQztRQUNwQixtQkFBTSxDQUFDLElBQUksQ0FBQyxpREFBaUQsQ0FBQyxDQUFDO0lBQ2pFLENBQUM7Q0FDRjtBQWxCRCwwREFrQkMifQ==
|
|
@@ -0,0 +1,104 @@
|
|
|
1
|
+
import { AsyncFunction, GenericFunction } from 'commandkit';
|
|
2
|
+
/**
|
|
3
|
+
* Context for managing cache operations within an async scope
|
|
4
|
+
*/
|
|
5
|
+
export interface CacheContext {
|
|
6
|
+
params: {
|
|
7
|
+
/** Custom name for the cache entry */
|
|
8
|
+
name?: string;
|
|
9
|
+
/** Time-to-live in milliseconds */
|
|
10
|
+
ttl?: number;
|
|
11
|
+
};
|
|
12
|
+
}
|
|
13
|
+
/**
|
|
14
|
+
* Configuration options for cache behavior
|
|
15
|
+
*/
|
|
16
|
+
export interface CacheMetadata {
|
|
17
|
+
/** Time-to-live duration in milliseconds or as a string (e.g., '1h', '5m') */
|
|
18
|
+
ttl?: number | string;
|
|
19
|
+
/** Custom name for the cache entry */
|
|
20
|
+
name?: string;
|
|
21
|
+
}
|
|
22
|
+
/**
|
|
23
|
+
* Wraps an async function with caching capability
|
|
24
|
+
* @template R - Array of argument types
|
|
25
|
+
* @template F - Type of the async function
|
|
26
|
+
* @param fn - The async function to cache
|
|
27
|
+
* @param params - Optional cache configuration
|
|
28
|
+
* @returns The wrapped function with caching behavior
|
|
29
|
+
* @example
|
|
30
|
+
* ```ts
|
|
31
|
+
* const cachedFetch = cache(async (id: string) => {
|
|
32
|
+
* return await db.findOne(id);
|
|
33
|
+
* }, { ttl: '1h' });
|
|
34
|
+
* ```
|
|
35
|
+
*/
|
|
36
|
+
export declare function cache<R extends any[], F extends AsyncFunction<R>>(fn: F, params?: CacheMetadata): F;
|
|
37
|
+
/**
|
|
38
|
+
* Sets a custom identifier for the current cache operation
|
|
39
|
+
* @param tag - The custom cache tag
|
|
40
|
+
* @throws {Error} When called outside a cached function or without a tag
|
|
41
|
+
* @example
|
|
42
|
+
* ```ts
|
|
43
|
+
* const fetchUser = cache(async (id: string) => {
|
|
44
|
+
* cacheTag(`user:${id}`);
|
|
45
|
+
* return await db.users.findOne(id);
|
|
46
|
+
* });
|
|
47
|
+
* ```
|
|
48
|
+
*/
|
|
49
|
+
export declare function cacheTag(tag: string): void;
|
|
50
|
+
/**
|
|
51
|
+
* Sets the TTL for the current cache operation
|
|
52
|
+
* @param ttl - Time-to-live in milliseconds or as a string (e.g., '1h', '5m')
|
|
53
|
+
* @throws {Error} When called outside a cached function or with invalid TTL
|
|
54
|
+
* @example
|
|
55
|
+
* ```ts
|
|
56
|
+
* const fetchData = cache(async () => {
|
|
57
|
+
* cacheLife('30m');
|
|
58
|
+
* return await expensiveOperation();
|
|
59
|
+
* });
|
|
60
|
+
* ```
|
|
61
|
+
*/
|
|
62
|
+
export declare function cacheLife(ttl: number | string): void;
|
|
63
|
+
/**
|
|
64
|
+
* Removes a cached value by its tag
|
|
65
|
+
* @param tag - The cache tag to invalidate. Can be a single tag or an array of tags.
|
|
66
|
+
* @throws {Error} When the cache key is not found
|
|
67
|
+
* @example
|
|
68
|
+
* ```ts
|
|
69
|
+
* await invalidate('user:123');
|
|
70
|
+
* // or
|
|
71
|
+
* await invalidate(['user:123', 'user:456']);
|
|
72
|
+
* ```
|
|
73
|
+
*/
|
|
74
|
+
export declare function invalidate(tag: string | string[]): Promise<void>;
|
|
75
|
+
/**
|
|
76
|
+
* Forces a refresh of cached data by its tag (on-demand revalidation)
|
|
77
|
+
* @template T - Type of the cached value
|
|
78
|
+
* @param tag - The cache tag to revalidate
|
|
79
|
+
* @param args - Arguments to pass to the cached function
|
|
80
|
+
* @returns Fresh data from the cached function
|
|
81
|
+
* @throws {Error} When the cache key or function is not found
|
|
82
|
+
* @example
|
|
83
|
+
* ```ts
|
|
84
|
+
* const freshData = await revalidate('user:123');
|
|
85
|
+
* ```
|
|
86
|
+
*/
|
|
87
|
+
export declare function revalidate<T = unknown>(tag: string, ...args: any[]): Promise<T>;
|
|
88
|
+
/**
|
|
89
|
+
* Checks if a function is wrapped with cache functionality
|
|
90
|
+
* @param fn - Function to check
|
|
91
|
+
* @returns True if the function is cached
|
|
92
|
+
* @example
|
|
93
|
+
* ```ts
|
|
94
|
+
* if (isCachedFunction(myFunction)) {
|
|
95
|
+
* console.log('Function is cached');
|
|
96
|
+
* }
|
|
97
|
+
* ```
|
|
98
|
+
*/
|
|
99
|
+
export declare function isCachedFunction(fn: GenericFunction): boolean;
|
|
100
|
+
/**
|
|
101
|
+
* @private
|
|
102
|
+
* @internal
|
|
103
|
+
*/
|
|
104
|
+
export declare const __SECRET_USE_CACHE_INTERNAL_DO_NOT_USE_OR_YOU_WILL_BE_FIRED: any;
|
|
@@ -0,0 +1,232 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
+
};
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
exports.__SECRET_USE_CACHE_INTERNAL_DO_NOT_USE_OR_YOU_WILL_BE_FIRED = void 0;
|
|
7
|
+
exports.cache = cache;
|
|
8
|
+
exports.cacheTag = cacheTag;
|
|
9
|
+
exports.cacheLife = cacheLife;
|
|
10
|
+
exports.invalidate = invalidate;
|
|
11
|
+
exports.revalidate = revalidate;
|
|
12
|
+
exports.isCachedFunction = isCachedFunction;
|
|
13
|
+
const node_async_hooks_1 = require("node:async_hooks");
|
|
14
|
+
const node_crypto_1 = require("node:crypto");
|
|
15
|
+
const ms_1 = __importDefault(require("ms"));
|
|
16
|
+
const utils_1 = require("./utils");
|
|
17
|
+
const cache_plugin_1 = require("./cache-plugin");
|
|
18
|
+
const cacheContext = new node_async_hooks_1.AsyncLocalStorage();
|
|
19
|
+
const fnStore = new Map();
|
|
20
|
+
const DEFAULT_TTL = (0, ms_1.default)('15m');
|
|
21
|
+
const CACHE_FN_ID = `__cache_fn_id_${Date.now()}__${Math.random()}__`;
|
|
22
|
+
const CACHED_FN_SYMBOL = Symbol('commandkit.cache.sentinel');
|
|
23
|
+
/**
|
|
24
|
+
* Internal cache implementation
|
|
25
|
+
* @internal
|
|
26
|
+
* @private
|
|
27
|
+
* This is used directly by the compiler if the function is annotated with `"use cache"` directive.
|
|
28
|
+
* @example
|
|
29
|
+
* ```ts
|
|
30
|
+
* async function myCachedFunction() {
|
|
31
|
+
* "use cache";
|
|
32
|
+
* // can use cacheTag() and cacheLife() here to customize cache behavior
|
|
33
|
+
* return await db.query('SELECT * FROM users');
|
|
34
|
+
* }
|
|
35
|
+
* ```
|
|
36
|
+
*/
|
|
37
|
+
function useCache(fn, id, params) {
|
|
38
|
+
const isLocal = id === CACHE_FN_ID;
|
|
39
|
+
if (id && !isLocal) {
|
|
40
|
+
throw new Error('Illegal use of cache function.');
|
|
41
|
+
}
|
|
42
|
+
const fnId = (0, node_crypto_1.randomUUID)();
|
|
43
|
+
const memo = (async (...args) => {
|
|
44
|
+
const forcedName = isLocal ? params?.name : null;
|
|
45
|
+
const keyHash = forcedName ?? (await (0, utils_1.createObjectHash)(fnId, ...args));
|
|
46
|
+
const resolvedTTL = isLocal && params?.ttl != null
|
|
47
|
+
? typeof params.ttl === 'string'
|
|
48
|
+
? (0, ms_1.default)(params.ttl)
|
|
49
|
+
: params.ttl
|
|
50
|
+
: null;
|
|
51
|
+
return cacheContext.run({
|
|
52
|
+
params: {
|
|
53
|
+
name: keyHash,
|
|
54
|
+
ttl: resolvedTTL ?? DEFAULT_TTL,
|
|
55
|
+
},
|
|
56
|
+
}, async () => {
|
|
57
|
+
const provider = (0, cache_plugin_1.getCacheProvider)();
|
|
58
|
+
const context = cacheContext.getStore();
|
|
59
|
+
if (!context) {
|
|
60
|
+
throw new Error('Cache context was not found.');
|
|
61
|
+
}
|
|
62
|
+
// Get the effective cache key, preferring any existing association
|
|
63
|
+
const storedFn = fnStore.get(keyHash);
|
|
64
|
+
const effectiveKey = storedFn?.key ?? context.params.name;
|
|
65
|
+
// Try to get cached value using effective key
|
|
66
|
+
const cached = await provider.get(effectiveKey);
|
|
67
|
+
if (cached && cached.value != null)
|
|
68
|
+
return cached.value;
|
|
69
|
+
// If we reach here, we need to cache the value
|
|
70
|
+
const result = await fn(...args);
|
|
71
|
+
// Only cache if result is not null/undefined
|
|
72
|
+
if (result != null) {
|
|
73
|
+
// Get the final key name (might have been modified by cacheTag)
|
|
74
|
+
const finalKey = context.params.name;
|
|
75
|
+
const ttl = context.params.ttl ?? DEFAULT_TTL;
|
|
76
|
+
// Store the result
|
|
77
|
+
await provider.set(finalKey, result, ttl);
|
|
78
|
+
// Update function store
|
|
79
|
+
fnStore.set(keyHash, {
|
|
80
|
+
key: finalKey,
|
|
81
|
+
hash: keyHash,
|
|
82
|
+
ttl,
|
|
83
|
+
original: fn,
|
|
84
|
+
memo,
|
|
85
|
+
});
|
|
86
|
+
}
|
|
87
|
+
return result;
|
|
88
|
+
});
|
|
89
|
+
});
|
|
90
|
+
if (!Object.prototype.hasOwnProperty.call(fn, CACHED_FN_SYMBOL)) {
|
|
91
|
+
Object.defineProperty(memo, CACHED_FN_SYMBOL, {
|
|
92
|
+
get() {
|
|
93
|
+
return true;
|
|
94
|
+
},
|
|
95
|
+
configurable: false,
|
|
96
|
+
enumerable: false,
|
|
97
|
+
});
|
|
98
|
+
}
|
|
99
|
+
return memo;
|
|
100
|
+
}
|
|
101
|
+
/**
|
|
102
|
+
* Wraps an async function with caching capability
|
|
103
|
+
* @template R - Array of argument types
|
|
104
|
+
* @template F - Type of the async function
|
|
105
|
+
* @param fn - The async function to cache
|
|
106
|
+
* @param params - Optional cache configuration
|
|
107
|
+
* @returns The wrapped function with caching behavior
|
|
108
|
+
* @example
|
|
109
|
+
* ```ts
|
|
110
|
+
* const cachedFetch = cache(async (id: string) => {
|
|
111
|
+
* return await db.findOne(id);
|
|
112
|
+
* }, { ttl: '1h' });
|
|
113
|
+
* ```
|
|
114
|
+
*/
|
|
115
|
+
function cache(fn, params) {
|
|
116
|
+
return useCache(fn, CACHE_FN_ID, params);
|
|
117
|
+
}
|
|
118
|
+
/**
|
|
119
|
+
* Sets a custom identifier for the current cache operation
|
|
120
|
+
* @param tag - The custom cache tag
|
|
121
|
+
* @throws {Error} When called outside a cached function or without a tag
|
|
122
|
+
* @example
|
|
123
|
+
* ```ts
|
|
124
|
+
* const fetchUser = cache(async (id: string) => {
|
|
125
|
+
* cacheTag(`user:${id}`);
|
|
126
|
+
* return await db.users.findOne(id);
|
|
127
|
+
* });
|
|
128
|
+
* ```
|
|
129
|
+
*/
|
|
130
|
+
function cacheTag(tag) {
|
|
131
|
+
const context = cacheContext.getStore();
|
|
132
|
+
if (!context) {
|
|
133
|
+
throw new Error('cacheTag() must be called inside a cached function.');
|
|
134
|
+
}
|
|
135
|
+
if (!tag) {
|
|
136
|
+
throw new Error('cacheTag() must be called with a tag name.');
|
|
137
|
+
}
|
|
138
|
+
context.params.name = tag;
|
|
139
|
+
}
|
|
140
|
+
/**
|
|
141
|
+
* Sets the TTL for the current cache operation
|
|
142
|
+
* @param ttl - Time-to-live in milliseconds or as a string (e.g., '1h', '5m')
|
|
143
|
+
* @throws {Error} When called outside a cached function or with invalid TTL
|
|
144
|
+
* @example
|
|
145
|
+
* ```ts
|
|
146
|
+
* const fetchData = cache(async () => {
|
|
147
|
+
* cacheLife('30m');
|
|
148
|
+
* return await expensiveOperation();
|
|
149
|
+
* });
|
|
150
|
+
* ```
|
|
151
|
+
*/
|
|
152
|
+
function cacheLife(ttl) {
|
|
153
|
+
const context = cacheContext.getStore();
|
|
154
|
+
if (!context) {
|
|
155
|
+
throw new Error('cacheLife() must be called inside a cached function.');
|
|
156
|
+
}
|
|
157
|
+
if (ttl == null || !['string', 'number'].includes(typeof ttl)) {
|
|
158
|
+
throw new Error('cacheLife() must be called with a ttl.');
|
|
159
|
+
}
|
|
160
|
+
context.params.ttl = typeof ttl === 'string' ? (0, ms_1.default)(ttl) : ttl;
|
|
161
|
+
}
|
|
162
|
+
/**
|
|
163
|
+
* Removes a cached value by its tag
|
|
164
|
+
* @param tag - The cache tag to invalidate. Can be a single tag or an array of tags.
|
|
165
|
+
* @throws {Error} When the cache key is not found
|
|
166
|
+
* @example
|
|
167
|
+
* ```ts
|
|
168
|
+
* await invalidate('user:123');
|
|
169
|
+
* // or
|
|
170
|
+
* await invalidate(['user:123', 'user:456']);
|
|
171
|
+
* ```
|
|
172
|
+
*/
|
|
173
|
+
async function invalidate(tag) {
|
|
174
|
+
const provider = (0, cache_plugin_1.getCacheProvider)();
|
|
175
|
+
let errors = [];
|
|
176
|
+
for (const t of Array.isArray(tag) ? tag : [tag]) {
|
|
177
|
+
try {
|
|
178
|
+
const entry = Array.from(fnStore.values()).find((v) => v.key === t || v.hash === t);
|
|
179
|
+
if (!entry)
|
|
180
|
+
continue;
|
|
181
|
+
await provider.delete(entry.key);
|
|
182
|
+
}
|
|
183
|
+
catch (e) {
|
|
184
|
+
errors.push(e);
|
|
185
|
+
}
|
|
186
|
+
}
|
|
187
|
+
if (errors.length > 0) {
|
|
188
|
+
throw new Error(`Failed to invalidate cache for tags: ${errors
|
|
189
|
+
.map((e) => e.message)
|
|
190
|
+
.join(', ')}`);
|
|
191
|
+
}
|
|
192
|
+
}
|
|
193
|
+
/**
|
|
194
|
+
* Forces a refresh of cached data by its tag (on-demand revalidation)
|
|
195
|
+
* @template T - Type of the cached value
|
|
196
|
+
* @param tag - The cache tag to revalidate
|
|
197
|
+
* @param args - Arguments to pass to the cached function
|
|
198
|
+
* @returns Fresh data from the cached function
|
|
199
|
+
* @throws {Error} When the cache key or function is not found
|
|
200
|
+
* @example
|
|
201
|
+
* ```ts
|
|
202
|
+
* const freshData = await revalidate('user:123');
|
|
203
|
+
* ```
|
|
204
|
+
*/
|
|
205
|
+
async function revalidate(tag, ...args) {
|
|
206
|
+
const provider = (0, cache_plugin_1.getCacheProvider)();
|
|
207
|
+
const entry = Array.from(fnStore.values()).find((v) => v.key === tag || v.hash === tag);
|
|
208
|
+
if (!entry)
|
|
209
|
+
return undefined;
|
|
210
|
+
await provider.delete(entry.key);
|
|
211
|
+
return entry.memo(...args);
|
|
212
|
+
}
|
|
213
|
+
/**
|
|
214
|
+
* Checks if a function is wrapped with cache functionality
|
|
215
|
+
* @param fn - Function to check
|
|
216
|
+
* @returns True if the function is cached
|
|
217
|
+
* @example
|
|
218
|
+
* ```ts
|
|
219
|
+
* if (isCachedFunction(myFunction)) {
|
|
220
|
+
* console.log('Function is cached');
|
|
221
|
+
* }
|
|
222
|
+
* ```
|
|
223
|
+
*/
|
|
224
|
+
function isCachedFunction(fn) {
|
|
225
|
+
return Object.prototype.hasOwnProperty.call(fn, CACHED_FN_SYMBOL);
|
|
226
|
+
}
|
|
227
|
+
/**
|
|
228
|
+
* @private
|
|
229
|
+
* @internal
|
|
230
|
+
*/
|
|
231
|
+
exports.__SECRET_USE_CACHE_INTERNAL_DO_NOT_USE_OR_YOU_WILL_BE_FIRED = useCache;
|
|
232
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidXNlLWNhY2hlLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vc3JjL3VzZS1jYWNoZS50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOzs7Ozs7QUErSkEsc0JBS0M7QUFjRCw0QkFZQztBQWNELDhCQVlDO0FBYUQsZ0NBeUJDO0FBY0QsZ0NBY0M7QUFhRCw0Q0FFQztBQXpTRCx1REFBcUQ7QUFFckQsNkNBQXlDO0FBQ3pDLDRDQUFvQjtBQUNwQixtQ0FBMkM7QUFDM0MsaURBQWtEO0FBRWxELE1BQU0sWUFBWSxHQUFHLElBQUksb0NBQWlCLEVBQWdCLENBQUM7QUFDM0QsTUFBTSxPQUFPLEdBQUcsSUFBSSxHQUFHLEVBU3BCLENBQUM7QUFDSixNQUFNLFdBQVcsR0FBRyxJQUFBLFlBQUUsRUFBQyxLQUFLLENBQUMsQ0FBQztBQUM5QixNQUFNLFdBQVcsR0FBRyxpQkFBaUIsSUFBSSxDQUFDLEdBQUcsRUFBRSxLQUFLLElBQUksQ0FBQyxNQUFNLEVBQUUsSUFBSSxDQUFDO0FBQ3RFLE1BQU0sZ0JBQWdCLEdBQUcsTUFBTSxDQUFDLDJCQUEyQixDQUFDLENBQUM7QUF3QjdEOzs7Ozs7Ozs7Ozs7O0dBYUc7QUFDSCxTQUFTLFFBQVEsQ0FDZixFQUFLLEVBQ0wsRUFBVyxFQUNYLE1BQXNCO0lBRXRCLE1BQU0sT0FBTyxHQUFHLEVBQUUsS0FBSyxXQUFXLENBQUM7SUFFbkMsSUFBSSxFQUFFLElBQUksQ0FBQyxPQUFPLEVBQUUsQ0FBQztRQUNuQixNQUFNLElBQUksS0FBSyxDQUFDLGdDQUFnQyxDQUFDLENBQUM7SUFDcEQsQ0FBQztJQUVELE1BQU0sSUFBSSxHQUFHLElBQUEsd0JBQVUsR0FBRSxDQUFDO0lBRTFCLE1BQU0sSUFBSSxHQUFHLENBQUMsS0FBSyxFQUFFLEdBQUcsSUFBSSxFQUFFLEVBQUU7UUFDOUIsTUFBTSxVQUFVLEdBQUcsT0FBTyxDQUFDLENBQUMsQ0FBQyxNQUFNLEVBQUUsSUFBSSxDQUFDLENBQUMsQ0FBQyxJQUFJLENBQUM7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
|
package/dist/utils.d.ts
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export declare function createObjectHash(...args: any[]): Promise<string>;
|
package/dist/utils.js
ADDED
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.createObjectHash = createObjectHash;
|
|
4
|
+
const node_crypto_1 = require("node:crypto");
|
|
5
|
+
let tracker = 0n;
|
|
6
|
+
const references = new WeakMap();
|
|
7
|
+
const PRIMITIVE_TYPES = new Set([
|
|
8
|
+
'string',
|
|
9
|
+
'number',
|
|
10
|
+
'boolean',
|
|
11
|
+
'bigint',
|
|
12
|
+
'undefined',
|
|
13
|
+
]);
|
|
14
|
+
function isSerializablePrimitive(value) {
|
|
15
|
+
return value === null || PRIMITIVE_TYPES.has(typeof value);
|
|
16
|
+
}
|
|
17
|
+
function createKey(val) {
|
|
18
|
+
return `commandkit:cache:object:${val}`;
|
|
19
|
+
}
|
|
20
|
+
// returns runtime object id of the given argument
|
|
21
|
+
function getObjectId(obj) {
|
|
22
|
+
const primitive = isSerializablePrimitive(obj);
|
|
23
|
+
if (primitive)
|
|
24
|
+
return createKey(obj);
|
|
25
|
+
if (obj instanceof Date)
|
|
26
|
+
return createKey(obj.getTime());
|
|
27
|
+
if (obj instanceof RegExp)
|
|
28
|
+
return createKey(obj);
|
|
29
|
+
const ref = references.get(obj);
|
|
30
|
+
if (ref)
|
|
31
|
+
return createKey(ref);
|
|
32
|
+
const id = tracker++;
|
|
33
|
+
references.set(obj, id);
|
|
34
|
+
return createKey(id);
|
|
35
|
+
}
|
|
36
|
+
async function createObjectHash(...args) {
|
|
37
|
+
const serializedKey = args.map(getObjectId).join(':');
|
|
38
|
+
try {
|
|
39
|
+
const hash = (0, node_crypto_1.createHash)('sha256');
|
|
40
|
+
hash.update(serializedKey);
|
|
41
|
+
return hash.digest('hex');
|
|
42
|
+
}
|
|
43
|
+
catch {
|
|
44
|
+
return serializedKey;
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidXRpbHMuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi9zcmMvdXRpbHMudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7QUF1Q0EsNENBVUM7QUFqREQsNkNBQXlDO0FBRXpDLElBQUksT0FBTyxHQUFHLEVBQUUsQ0FBQztBQUVqQixNQUFNLFVBQVUsR0FBRyxJQUFJLE9BQU8sRUFBZSxDQUFDO0FBQzlDLE1BQU0sZUFBZSxHQUFHLElBQUksR0FBRyxDQUFDO0lBQzlCLFFBQVE7SUFDUixRQUFRO0lBQ1IsU0FBUztJQUNULFFBQVE7SUFDUixXQUFXO0NBQ1osQ0FBQyxDQUFDO0FBRUgsU0FBUyx1QkFBdUIsQ0FBQyxLQUFVO0lBQ3pDLE9BQU8sS0FBSyxLQUFLLElBQUksSUFBSSxlQUFlLENBQUMsR0FBRyxDQUFDLE9BQU8sS0FBSyxDQUFDLENBQUM7QUFDN0QsQ0FBQztBQUVELFNBQVMsU0FBUyxDQUFDLEdBQVE7SUFDekIsT0FBTywyQkFBMkIsR0FBRyxFQUFFLENBQUM7QUFDMUMsQ0FBQztBQUVELGtEQUFrRDtBQUNsRCxTQUFTLFdBQVcsQ0FBQyxHQUFRO0lBQzNCLE1BQU0sU0FBUyxHQUFHLHVCQUF1QixDQUFDLEdBQUcsQ0FBQyxDQUFDO0lBQy9DLElBQUksU0FBUztRQUFFLE9BQU8sU0FBUyxDQUFDLEdBQUcsQ0FBQyxDQUFDO0lBRXJDLElBQUksR0FBRyxZQUFZLElBQUk7UUFBRSxPQUFPLFNBQVMsQ0FBQyxHQUFHLENBQUMsT0FBTyxFQUFFLENBQUMsQ0FBQztJQUN6RCxJQUFJLEdBQUcsWUFBWSxNQUFNO1FBQUUsT0FBTyxTQUFTLENBQUMsR0FBRyxDQUFDLENBQUM7SUFFakQsTUFBTSxHQUFHLEdBQUcsVUFBVSxDQUFDLEdBQUcsQ0FBQyxHQUFHLENBQUMsQ0FBQztJQUNoQyxJQUFJLEdBQUc7UUFBRSxPQUFPLFNBQVMsQ0FBQyxHQUFHLENBQUMsQ0FBQztJQUUvQixNQUFNLEVBQUUsR0FBRyxPQUFPLEVBQUUsQ0FBQztJQUVyQixVQUFVLENBQUMsR0FBRyxDQUFDLEdBQUcsRUFBRSxFQUFFLENBQUMsQ0FBQztJQUV4QixPQUFPLFNBQVMsQ0FBQyxFQUFFLENBQUMsQ0FBQztBQUN2QixDQUFDO0FBRU0sS0FBSyxVQUFVLGdCQUFnQixDQUFDLEdBQUcsSUFBVztJQUNuRCxNQUFNLGFBQWEsR0FBRyxJQUFJLENBQUMsR0FBRyxDQUFDLFdBQVcsQ0FBQyxDQUFDLElBQUksQ0FBQyxHQUFHLENBQUMsQ0FBQztJQUV0RCxJQUFJLENBQUM7UUFDSCxNQUFNLElBQUksR0FBRyxJQUFBLHdCQUFVLEVBQUMsUUFBUSxDQUFDLENBQUM7UUFDbEMsSUFBSSxDQUFDLE1BQU0sQ0FBQyxhQUFhLENBQUMsQ0FBQztRQUMzQixPQUFPLElBQUksQ0FBQyxNQUFNLENBQUMsS0FBSyxDQUFDLENBQUM7SUFDNUIsQ0FBQztJQUFDLE1BQU0sQ0FBQztRQUNQLE9BQU8sYUFBYSxDQUFDO0lBQ3ZCLENBQUM7QUFDSCxDQUFDIn0=
|
package/package.json
ADDED
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@commandkit/cache",
|
|
3
|
+
"version": "0.0.0-dev.20250512141518",
|
|
4
|
+
"description": "CommandKit plugin that provides caching apis",
|
|
5
|
+
"main": "dist/index.js",
|
|
6
|
+
"types": "dist/index.d.ts",
|
|
7
|
+
"files": [
|
|
8
|
+
"dist"
|
|
9
|
+
],
|
|
10
|
+
"repository": {
|
|
11
|
+
"type": "git",
|
|
12
|
+
"url": "git+https://github.com/underctrl-io/commandkit.git"
|
|
13
|
+
},
|
|
14
|
+
"keywords": [
|
|
15
|
+
"commandkit",
|
|
16
|
+
"cache",
|
|
17
|
+
"caching",
|
|
18
|
+
"cache management",
|
|
19
|
+
"commandkit cache"
|
|
20
|
+
],
|
|
21
|
+
"author": "twilight <hello@twlite.dev>",
|
|
22
|
+
"license": "MIT",
|
|
23
|
+
"bugs": {
|
|
24
|
+
"url": "https://github.com/underctrl-io/commandkit/issues"
|
|
25
|
+
},
|
|
26
|
+
"homepage": "https://github.com/underctrl-io/commandkit#readme",
|
|
27
|
+
"devDependencies": {
|
|
28
|
+
"@types/ms": "^0.7.34",
|
|
29
|
+
"typescript": "^5.7.3",
|
|
30
|
+
"commandkit": "1.0.0",
|
|
31
|
+
"tsconfig": "0.0.0"
|
|
32
|
+
},
|
|
33
|
+
"dependencies": {
|
|
34
|
+
"ms": "^2.1.3"
|
|
35
|
+
},
|
|
36
|
+
"scripts": {
|
|
37
|
+
"lint": "tsc --noEmit",
|
|
38
|
+
"build": "tsc"
|
|
39
|
+
}
|
|
40
|
+
}
|