@fluojs/cache-manager 1.0.0-beta.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/LICENSE +21 -0
- package/README.ko.md +189 -0
- package/README.md +189 -0
- package/dist/clone.d.ts +2 -0
- package/dist/clone.d.ts.map +1 -0
- package/dist/clone.js +3 -0
- package/dist/decorators.d.ts +70 -0
- package/dist/decorators.d.ts.map +1 -0
- package/dist/decorators.js +120 -0
- package/dist/index.d.ts +10 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +9 -0
- package/dist/interceptor.d.ts +20 -0
- package/dist/interceptor.d.ts.map +1 -0
- package/dist/interceptor.js +216 -0
- package/dist/module.d.ts +32 -0
- package/dist/module.d.ts.map +1 -0
- package/dist/module.js +166 -0
- package/dist/service.d.ts +54 -0
- package/dist/service.d.ts.map +1 -0
- package/dist/service.js +130 -0
- package/dist/status.d.ts +45 -0
- package/dist/status.d.ts.map +1 -0
- package/dist/status.js +115 -0
- package/dist/stores/memory-store.d.ts +10 -0
- package/dist/stores/memory-store.d.ts.map +1 -0
- package/dist/stores/memory-store.js +71 -0
- package/dist/stores/redis-store.d.ts +17 -0
- package/dist/stores/redis-store.d.ts.map +1 -0
- package/dist/stores/redis-store.js +81 -0
- package/dist/tokens.d.ts +9 -0
- package/dist/tokens.d.ts.map +1 -0
- package/dist/tokens.js +8 -0
- package/dist/types.d.ts +80 -0
- package/dist/types.d.ts.map +1 -0
- package/dist/types.js +1 -0
- package/package.json +67 -0
|
@@ -0,0 +1,216 @@
|
|
|
1
|
+
let _initClass;
|
|
2
|
+
function _applyDecs(e, t, n, r, o, i) { var a, c, u, s, f, l, p, d = Symbol.metadata || Symbol.for("Symbol.metadata"), m = Object.defineProperty, h = Object.create, y = [h(null), h(null)], v = t.length; function g(t, n, r) { return function (o, i) { n && (i = o, o = e); for (var a = 0; a < t.length; a++) i = t[a].apply(o, r ? [i] : []); return r ? i : o; }; } function b(e, t, n, r) { if ("function" != typeof e && (r || void 0 !== e)) throw new TypeError(t + " must " + (n || "be") + " a function" + (r ? "" : " or undefined")); return e; } function applyDec(e, t, n, r, o, i, u, s, f, l, p) { function d(e) { if (!p(e)) throw new TypeError("Attempted to access private element on non-instance"); } var h = [].concat(t[0]), v = t[3], w = !u, D = 1 === o, S = 3 === o, j = 4 === o, E = 2 === o; function I(t, n, r) { return function (o, i) { return n && (i = o, o = e), r && r(o), P[t].call(o, i); }; } if (!w) { var P = {}, k = [], F = S ? "get" : j || D ? "set" : "value"; if (f ? (l || D ? P = { get: _setFunctionName(function () { return v(this); }, r, "get"), set: function (e) { t[4](this, e); } } : P[F] = v, l || _setFunctionName(P[F], r, E ? "" : F)) : l || (P = Object.getOwnPropertyDescriptor(e, r)), !l && !f) { if ((c = y[+s][r]) && 7 !== (c ^ o)) throw Error("Decorating two elements with the same name (" + P[F].name + ") is not supported yet"); y[+s][r] = o < 3 ? 1 : o; } } for (var N = e, O = h.length - 1; O >= 0; O -= n ? 2 : 1) { var T = b(h[O], "A decorator", "be", !0), z = n ? h[O - 1] : void 0, A = {}, H = { kind: ["field", "accessor", "method", "getter", "setter", "class"][o], name: r, metadata: a, addInitializer: function (e, t) { if (e.v) throw new TypeError("attempted to call addInitializer after decoration was finished"); b(t, "An initializer", "be", !0), i.push(t); }.bind(null, A) }; if (w) c = T.call(z, N, H), A.v = 1, b(c, "class decorators", "return") && (N = c);else if (H.static = s, H.private = f, c = H.access = { has: f ? p.bind() : function (e) { return r in e; } }, j || (c.get = f ? E ? function (e) { return d(e), P.value; } : I("get", 0, d) : function (e) { return e[r]; }), E || S || (c.set = f ? I("set", 0, d) : function (e, t) { e[r] = t; }), N = T.call(z, D ? { get: P.get, set: P.set } : P[F], H), A.v = 1, D) { if ("object" == typeof N && N) (c = b(N.get, "accessor.get")) && (P.get = c), (c = b(N.set, "accessor.set")) && (P.set = c), (c = b(N.init, "accessor.init")) && k.unshift(c);else if (void 0 !== N) throw new TypeError("accessor decorators must return an object with get, set, or init properties or undefined"); } else b(N, (l ? "field" : "method") + " decorators", "return") && (l ? k.unshift(N) : P[F] = N); } return o < 2 && u.push(g(k, s, 1), g(i, s, 0)), l || w || (f ? D ? u.splice(-1, 0, I("get", s), I("set", s)) : u.push(E ? P[F] : b.call.bind(P[F])) : m(e, r, P)), N; } function w(e) { return m(e, d, { configurable: !0, enumerable: !0, value: a }); } return void 0 !== i && (a = i[d]), a = h(null == a ? null : a), f = [], l = function (e) { e && f.push(g(e)); }, p = function (t, r) { for (var i = 0; i < n.length; i++) { var a = n[i], c = a[1], l = 7 & c; if ((8 & c) == t && !l == r) { var p = a[2], d = !!a[3], m = 16 & c; applyDec(t ? e : e.prototype, a, m, d ? "#" + p : _toPropertyKey(p), l, l < 2 ? [] : t ? s = s || [] : u = u || [], f, !!t, d, r, t && d ? function (t) { return _checkInRHS(t) === e; } : o); } } }, p(8, 0), p(0, 0), p(8, 1), p(0, 1), l(u), l(s), c = f, v || w(e), { e: c, get c() { var n = []; return v && [w(e = applyDec(e, [t], r, e.name, 5, n)), g(n, 1)]; } }; }
|
|
3
|
+
function _toPropertyKey(t) { var i = _toPrimitive(t, "string"); return "symbol" == typeof i ? i : i + ""; }
|
|
4
|
+
function _toPrimitive(t, r) { if ("object" != typeof t || !t) return t; var e = t[Symbol.toPrimitive]; if (void 0 !== e) { var i = e.call(t, r || "default"); if ("object" != typeof i) return i; throw new TypeError("@@toPrimitive must return a primitive value."); } return ("string" === r ? String : Number)(t); }
|
|
5
|
+
function _setFunctionName(e, t, n) { "symbol" == typeof t && (t = (t = t.description) ? "[" + t + "]" : ""); try { Object.defineProperty(e, "name", { configurable: !0, value: n ? n + " " + t : t }); } catch (e) {} return e; }
|
|
6
|
+
function _checkInRHS(e) { if (Object(e) !== e) throw TypeError("right-hand side of 'in' should be an object, got " + (null !== e ? typeof e : "null")); return e; }
|
|
7
|
+
import { Inject } from '@fluojs/core';
|
|
8
|
+
import { metadataSymbol } from '@fluojs/core/internal';
|
|
9
|
+
import { SseResponse } from '@fluojs/http';
|
|
10
|
+
import { cacheRouteMetadataKey, getCacheEvictMetadata, getCacheKeyMetadata, getCacheTtlMetadata } from './decorators.js';
|
|
11
|
+
import { CacheService } from './service.js';
|
|
12
|
+
import { CACHE_OPTIONS } from './tokens.js';
|
|
13
|
+
function isMetadataBag(value) {
|
|
14
|
+
return typeof value === 'object' && value !== null;
|
|
15
|
+
}
|
|
16
|
+
function getMethodMetadataBag(controllerToken, methodName) {
|
|
17
|
+
const classBag = Reflect.get(controllerToken, metadataSymbol);
|
|
18
|
+
if (!isMetadataBag(classBag)) {
|
|
19
|
+
return undefined;
|
|
20
|
+
}
|
|
21
|
+
const routeMap = classBag[cacheRouteMetadataKey];
|
|
22
|
+
if (!(routeMap instanceof Map)) {
|
|
23
|
+
return undefined;
|
|
24
|
+
}
|
|
25
|
+
const methodMetadata = routeMap.get(methodName);
|
|
26
|
+
return isMetadataBag(methodMetadata) ? methodMetadata : undefined;
|
|
27
|
+
}
|
|
28
|
+
function normalizeCacheMethod(method) {
|
|
29
|
+
return method.toUpperCase();
|
|
30
|
+
}
|
|
31
|
+
function buildSortedQueryString(query) {
|
|
32
|
+
const entries = Object.entries(query).filter(([, value]) => value !== undefined).sort(([a], [b]) => a.localeCompare(b)).map(([key, value]) => {
|
|
33
|
+
if (Array.isArray(value)) {
|
|
34
|
+
return value.map(v => `${encodeURIComponent(key)}=${encodeURIComponent(String(v))}`).join('&');
|
|
35
|
+
}
|
|
36
|
+
return `${encodeURIComponent(key)}=${encodeURIComponent(String(value))}`;
|
|
37
|
+
});
|
|
38
|
+
return entries.join('&');
|
|
39
|
+
}
|
|
40
|
+
function appendPrincipalScope(key, context, resolver) {
|
|
41
|
+
if (resolver) {
|
|
42
|
+
const scope = resolver(context);
|
|
43
|
+
return scope !== undefined ? `${key}|principal:${scope}` : key;
|
|
44
|
+
}
|
|
45
|
+
const principal = context.requestContext.principal;
|
|
46
|
+
if (!principal) {
|
|
47
|
+
return key;
|
|
48
|
+
}
|
|
49
|
+
const issuer = encodeURIComponent(principal.issuer ?? 'unknown');
|
|
50
|
+
const subject = encodeURIComponent(principal.subject);
|
|
51
|
+
return `${key}|principal:${issuer}:${subject}`;
|
|
52
|
+
}
|
|
53
|
+
function defaultCacheKey(context, strategy, resolver) {
|
|
54
|
+
if (typeof strategy === 'function') {
|
|
55
|
+
return strategy(context);
|
|
56
|
+
}
|
|
57
|
+
const path = context.handler.metadata.effectivePath;
|
|
58
|
+
const query = context.requestContext.request.query;
|
|
59
|
+
if (strategy === 'route') {
|
|
60
|
+
return appendPrincipalScope(path, context, resolver);
|
|
61
|
+
}
|
|
62
|
+
const queryString = buildSortedQueryString(query);
|
|
63
|
+
if (!queryString) {
|
|
64
|
+
return appendPrincipalScope(path, context, resolver);
|
|
65
|
+
}
|
|
66
|
+
return appendPrincipalScope(`${path}?${queryString}`, context, resolver);
|
|
67
|
+
}
|
|
68
|
+
function normalizeTtl(ttlSeconds, fallback) {
|
|
69
|
+
const candidate = ttlSeconds ?? fallback;
|
|
70
|
+
if (!Number.isFinite(candidate) || candidate < 0) {
|
|
71
|
+
return undefined;
|
|
72
|
+
}
|
|
73
|
+
return candidate;
|
|
74
|
+
}
|
|
75
|
+
function normalizeEvictKeys(value) {
|
|
76
|
+
if (typeof value === 'string') {
|
|
77
|
+
return value.length > 0 ? [value] : [];
|
|
78
|
+
}
|
|
79
|
+
if (Array.isArray(value)) {
|
|
80
|
+
return value.filter(key => key.length > 0);
|
|
81
|
+
}
|
|
82
|
+
return [];
|
|
83
|
+
}
|
|
84
|
+
async function resolveCacheKeyValue(metadata, context, strategy, resolver) {
|
|
85
|
+
if (!metadata) {
|
|
86
|
+
return defaultCacheKey(context, strategy, resolver);
|
|
87
|
+
}
|
|
88
|
+
if (typeof metadata === 'string') {
|
|
89
|
+
return metadata;
|
|
90
|
+
}
|
|
91
|
+
return metadata(context);
|
|
92
|
+
}
|
|
93
|
+
const EVICTION_FALLBACK_TIMEOUT_MS = 5_000;
|
|
94
|
+
function installDeferredEviction(response, evict) {
|
|
95
|
+
const originalSend = response.send.bind(response);
|
|
96
|
+
let restored = false;
|
|
97
|
+
let completed = false;
|
|
98
|
+
const runEviction = () => {
|
|
99
|
+
if (completed) {
|
|
100
|
+
return;
|
|
101
|
+
}
|
|
102
|
+
completed = true;
|
|
103
|
+
void evict().catch(() => {});
|
|
104
|
+
};
|
|
105
|
+
const restore = () => {
|
|
106
|
+
if (restored) {
|
|
107
|
+
return;
|
|
108
|
+
}
|
|
109
|
+
clearTimeout(fallbackTimer);
|
|
110
|
+
response.send = originalSend;
|
|
111
|
+
restored = true;
|
|
112
|
+
};
|
|
113
|
+
const fallbackTimer = setTimeout(() => {
|
|
114
|
+
runEviction();
|
|
115
|
+
restore();
|
|
116
|
+
}, EVICTION_FALLBACK_TIMEOUT_MS);
|
|
117
|
+
response.send = async body => {
|
|
118
|
+
await originalSend(body);
|
|
119
|
+
runEviction();
|
|
120
|
+
restore();
|
|
121
|
+
};
|
|
122
|
+
return restore;
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
/**
|
|
126
|
+
* Caches GET responses and evicts related entries after successful write operations.
|
|
127
|
+
*/
|
|
128
|
+
let _CacheInterceptor;
|
|
129
|
+
class CacheInterceptor {
|
|
130
|
+
static {
|
|
131
|
+
[_CacheInterceptor, _initClass] = _applyDecs(this, [Inject(CacheService, CACHE_OPTIONS)], []).c;
|
|
132
|
+
}
|
|
133
|
+
constructor(cache, options) {
|
|
134
|
+
this.cache = cache;
|
|
135
|
+
this.options = options;
|
|
136
|
+
}
|
|
137
|
+
async intercept(context, next) {
|
|
138
|
+
const method = normalizeCacheMethod(context.requestContext.request.method);
|
|
139
|
+
const metadataBag = getMethodMetadataBag(context.handler.controllerToken, context.handler.methodName);
|
|
140
|
+
if (method === 'GET') {
|
|
141
|
+
return this.interceptGet(context, next, metadataBag);
|
|
142
|
+
}
|
|
143
|
+
const result = await next.handle();
|
|
144
|
+
await this.evictAfterWrite(context, metadataBag, result);
|
|
145
|
+
return result;
|
|
146
|
+
}
|
|
147
|
+
async interceptGet(context, next, metadataBag) {
|
|
148
|
+
const keyMetadata = metadataBag ? getCacheKeyMetadata(metadataBag) : undefined;
|
|
149
|
+
const key = await resolveCacheKeyValue(keyMetadata, context, this.options.httpKeyStrategy, this.options.principalScopeResolver);
|
|
150
|
+
const ttl = normalizeTtl(metadataBag ? getCacheTtlMetadata(metadataBag) : undefined, this.options.ttl);
|
|
151
|
+
if (ttl !== undefined) {
|
|
152
|
+
const cached = await this.safeGet(key);
|
|
153
|
+
if (cached !== undefined) {
|
|
154
|
+
return cached;
|
|
155
|
+
}
|
|
156
|
+
}
|
|
157
|
+
const value = await next.handle();
|
|
158
|
+
if (ttl !== undefined && this.shouldCacheValue(context, value)) {
|
|
159
|
+
await this.safeSet(key, value, ttl);
|
|
160
|
+
}
|
|
161
|
+
return value;
|
|
162
|
+
}
|
|
163
|
+
async evictAfterWrite(context, metadataBag, value) {
|
|
164
|
+
const evictMetadata = metadataBag ? getCacheEvictMetadata(metadataBag) : undefined;
|
|
165
|
+
if (!evictMetadata) {
|
|
166
|
+
return;
|
|
167
|
+
}
|
|
168
|
+
const runEviction = async () => {
|
|
169
|
+
const keys = await this.resolveEvictKeys(evictMetadata, context, value);
|
|
170
|
+
await Promise.all(Array.from(new Set(keys)).map(async key => {
|
|
171
|
+
await this.safeDel(key);
|
|
172
|
+
}));
|
|
173
|
+
};
|
|
174
|
+
if (context.requestContext.response.committed) {
|
|
175
|
+
await runEviction();
|
|
176
|
+
return;
|
|
177
|
+
}
|
|
178
|
+
installDeferredEviction(context.requestContext.response, runEviction);
|
|
179
|
+
}
|
|
180
|
+
async resolveEvictKeys(metadata, context, value) {
|
|
181
|
+
if (typeof metadata === 'function') {
|
|
182
|
+
return normalizeEvictKeys(await metadata(context, value));
|
|
183
|
+
}
|
|
184
|
+
return normalizeEvictKeys(metadata);
|
|
185
|
+
}
|
|
186
|
+
shouldCacheValue(context, value) {
|
|
187
|
+
if (value === undefined) {
|
|
188
|
+
return false;
|
|
189
|
+
}
|
|
190
|
+
if (value instanceof SseResponse) {
|
|
191
|
+
return false;
|
|
192
|
+
}
|
|
193
|
+
return context.requestContext.response.committed !== true;
|
|
194
|
+
}
|
|
195
|
+
async safeGet(key) {
|
|
196
|
+
try {
|
|
197
|
+
return await this.cache.get(key);
|
|
198
|
+
} catch {
|
|
199
|
+
return undefined;
|
|
200
|
+
}
|
|
201
|
+
}
|
|
202
|
+
async safeSet(key, value, ttl) {
|
|
203
|
+
try {
|
|
204
|
+
await this.cache.set(key, value, ttl);
|
|
205
|
+
} catch {}
|
|
206
|
+
}
|
|
207
|
+
async safeDel(key) {
|
|
208
|
+
try {
|
|
209
|
+
await this.cache.del(key);
|
|
210
|
+
} catch {}
|
|
211
|
+
}
|
|
212
|
+
static {
|
|
213
|
+
_initClass();
|
|
214
|
+
}
|
|
215
|
+
}
|
|
216
|
+
export { _CacheInterceptor as CacheInterceptor };
|
package/dist/module.d.ts
ADDED
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
import { type ModuleType } from '@fluojs/runtime';
|
|
2
|
+
import type { CacheModuleOptions } from './types.js';
|
|
3
|
+
/**
|
|
4
|
+
* Runtime module entrypoint for cache-manager services and interceptor wiring.
|
|
5
|
+
*
|
|
6
|
+
* @remarks
|
|
7
|
+
* This module only wires providers and store resolution. The documented cache
|
|
8
|
+
* semantics remain defined by the decorators, interceptor, and `CacheService`.
|
|
9
|
+
*/
|
|
10
|
+
export declare class CacheModule {
|
|
11
|
+
/**
|
|
12
|
+
* Register cache providers for the current application module graph.
|
|
13
|
+
*
|
|
14
|
+
* @remarks
|
|
15
|
+
* This is the primary package entrypoint, including custom
|
|
16
|
+
* `defineModule(...)` composition. Root-package consumers should treat
|
|
17
|
+
* low-level provider wiring as an internal implementation detail.
|
|
18
|
+
*
|
|
19
|
+
* @param options Cache module options.
|
|
20
|
+
* @returns A runtime module exporting `CacheService` and `CacheInterceptor`.
|
|
21
|
+
*
|
|
22
|
+
* @example
|
|
23
|
+
* ```ts
|
|
24
|
+
* CacheModule.forRoot({
|
|
25
|
+
* store: 'redis',
|
|
26
|
+
* ttl: 300,
|
|
27
|
+
* });
|
|
28
|
+
* ```
|
|
29
|
+
*/
|
|
30
|
+
static forRoot(options?: CacheModuleOptions): ModuleType;
|
|
31
|
+
}
|
|
32
|
+
//# sourceMappingURL=module.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"module.d.ts","sourceRoot":"","sources":["../src/module.ts"],"names":[],"mappings":"AAEA,OAAO,EAAgB,KAAK,UAAU,EAAE,MAAM,iBAAiB,CAAC;AAQhE,OAAO,KAAK,EAAE,kBAAkB,EAAuD,MAAM,YAAY,CAAC;AAqL1G;;;;;;GAMG;AACH,qBAAa,WAAW;IACtB;;;;;;;;;;;;;;;;;;OAkBG;IACH,MAAM,CAAC,OAAO,CAAC,OAAO,GAAE,kBAAuB,GAAG,UAAU;CAU7D"}
|
package/dist/module.js
ADDED
|
@@ -0,0 +1,166 @@
|
|
|
1
|
+
import { defineModule } from '@fluojs/runtime';
|
|
2
|
+
import { RUNTIME_CONTAINER } from '@fluojs/runtime/internal';
|
|
3
|
+
import { CacheInterceptor } from './interceptor.js';
|
|
4
|
+
import { MemoryStore } from './stores/memory-store.js';
|
|
5
|
+
import { RedisStore } from './stores/redis-store.js';
|
|
6
|
+
import { CacheService } from './service.js';
|
|
7
|
+
import { CACHE_OPTIONS, CACHE_STORE } from './tokens.js';
|
|
8
|
+
const DEFAULT_MEMORY_STORE_TTL_SECONDS = 300;
|
|
9
|
+
const REDIS_PEER_MODULE_SPECIFIER = '@fluojs/redis';
|
|
10
|
+
const loadOptionalModule = async specifier => import(specifier);
|
|
11
|
+
function isMissingRedisPeer(error) {
|
|
12
|
+
if (!(error instanceof Error)) {
|
|
13
|
+
return false;
|
|
14
|
+
}
|
|
15
|
+
const code = 'code' in error ? error.code : undefined;
|
|
16
|
+
return code === 'ERR_MODULE_NOT_FOUND' && error.message.includes(REDIS_PEER_MODULE_SPECIFIER);
|
|
17
|
+
}
|
|
18
|
+
function isRedisPeerModule(value) {
|
|
19
|
+
if (!value || typeof value !== 'object') {
|
|
20
|
+
return false;
|
|
21
|
+
}
|
|
22
|
+
return 'getRedisClientToken' in value && typeof value.getRedisClientToken === 'function';
|
|
23
|
+
}
|
|
24
|
+
function createRedisBootstrapError() {
|
|
25
|
+
return new Error(['@fluojs/cache-manager redis store requires a Redis client at bootstrap.', 'Install and import @fluojs/redis, configure options.redis.clientName, or provide options.redis.client directly.'].join(' '));
|
|
26
|
+
}
|
|
27
|
+
async function resolveRedisPeerModule() {
|
|
28
|
+
try {
|
|
29
|
+
const moduleNamespace = await loadOptionalModule(REDIS_PEER_MODULE_SPECIFIER);
|
|
30
|
+
if (!isRedisPeerModule(moduleNamespace)) {
|
|
31
|
+
throw new Error('@fluojs/cache-manager expected @fluojs/redis to export getRedisClientToken().');
|
|
32
|
+
}
|
|
33
|
+
return moduleNamespace;
|
|
34
|
+
} catch (error) {
|
|
35
|
+
if (isMissingRedisPeer(error)) {
|
|
36
|
+
throw createRedisBootstrapError();
|
|
37
|
+
}
|
|
38
|
+
throw error;
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
function normalizeCacheModuleOptions(options = {}) {
|
|
42
|
+
const store = options.store ?? 'memory';
|
|
43
|
+
return {
|
|
44
|
+
isGlobal: options.isGlobal ?? false,
|
|
45
|
+
keyPrefix: options.keyPrefix ?? 'fluo:cache:',
|
|
46
|
+
redis: options.redis,
|
|
47
|
+
store,
|
|
48
|
+
ttl: options.ttl ?? (store === 'memory' ? DEFAULT_MEMORY_STORE_TTL_SECONDS : 0),
|
|
49
|
+
httpKeyStrategy: options.httpKeyStrategy ?? 'route',
|
|
50
|
+
principalScopeResolver: options.principalScopeResolver
|
|
51
|
+
};
|
|
52
|
+
}
|
|
53
|
+
function isNormalizedCacheModuleOptions(value) {
|
|
54
|
+
if (!value || typeof value !== 'object') {
|
|
55
|
+
return false;
|
|
56
|
+
}
|
|
57
|
+
const candidate = value;
|
|
58
|
+
return 'store' in candidate && (typeof candidate.store === 'string' || typeof candidate.store === 'object') && typeof candidate.keyPrefix === 'string' && typeof candidate.ttl === 'number' && typeof candidate.isGlobal === 'boolean' && 'httpKeyStrategy' in candidate;
|
|
59
|
+
}
|
|
60
|
+
function isContainer(value) {
|
|
61
|
+
if (!value || typeof value !== 'object') {
|
|
62
|
+
return false;
|
|
63
|
+
}
|
|
64
|
+
return 'has' in value && 'resolve' in value;
|
|
65
|
+
}
|
|
66
|
+
async function resolveRedisClient(options, container) {
|
|
67
|
+
let resolvedClient = options.redis?.client;
|
|
68
|
+
if (!resolvedClient) {
|
|
69
|
+
let redisToken;
|
|
70
|
+
try {
|
|
71
|
+
const {
|
|
72
|
+
getRedisClientToken
|
|
73
|
+
} = await resolveRedisPeerModule();
|
|
74
|
+
redisToken = getRedisClientToken(options.redis?.clientName);
|
|
75
|
+
} catch (error) {
|
|
76
|
+
if (isMissingRedisPeer(error)) {
|
|
77
|
+
throw createRedisBootstrapError();
|
|
78
|
+
}
|
|
79
|
+
throw error;
|
|
80
|
+
}
|
|
81
|
+
if (container.has(redisToken)) {
|
|
82
|
+
resolvedClient = await container.resolve(redisToken);
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
if (!resolvedClient) {
|
|
86
|
+
throw createRedisBootstrapError();
|
|
87
|
+
}
|
|
88
|
+
return resolvedClient;
|
|
89
|
+
}
|
|
90
|
+
async function createStore(options, container) {
|
|
91
|
+
if (typeof options.store === 'object' && options.store !== null) {
|
|
92
|
+
return options.store;
|
|
93
|
+
}
|
|
94
|
+
if (options.store === 'redis') {
|
|
95
|
+
return new RedisStore(await resolveRedisClient(options, container), {
|
|
96
|
+
keyPrefix: options.keyPrefix,
|
|
97
|
+
scanCount: options.redis?.scanCount
|
|
98
|
+
});
|
|
99
|
+
}
|
|
100
|
+
return new MemoryStore();
|
|
101
|
+
}
|
|
102
|
+
function createCacheModuleProviders(options = {}) {
|
|
103
|
+
const normalized = normalizeCacheModuleOptions(options);
|
|
104
|
+
return [{
|
|
105
|
+
provide: CACHE_OPTIONS,
|
|
106
|
+
useValue: normalized
|
|
107
|
+
}, {
|
|
108
|
+
inject: [CACHE_OPTIONS, RUNTIME_CONTAINER],
|
|
109
|
+
provide: CACHE_STORE,
|
|
110
|
+
useFactory: (...deps) => {
|
|
111
|
+
const moduleOptions = deps[0];
|
|
112
|
+
const container = deps[1];
|
|
113
|
+
if (!isNormalizedCacheModuleOptions(moduleOptions)) {
|
|
114
|
+
throw new Error('Cache module options provider resolved an invalid configuration object.');
|
|
115
|
+
}
|
|
116
|
+
if (!isContainer(container)) {
|
|
117
|
+
throw new Error('Cache module requires runtime container access to resolve optional Redis client.');
|
|
118
|
+
}
|
|
119
|
+
return createStore(moduleOptions, container);
|
|
120
|
+
}
|
|
121
|
+
}, {
|
|
122
|
+
provide: CacheService,
|
|
123
|
+
useClass: CacheService
|
|
124
|
+
}, {
|
|
125
|
+
provide: CacheInterceptor,
|
|
126
|
+
useClass: CacheInterceptor
|
|
127
|
+
}];
|
|
128
|
+
}
|
|
129
|
+
|
|
130
|
+
/**
|
|
131
|
+
* Runtime module entrypoint for cache-manager services and interceptor wiring.
|
|
132
|
+
*
|
|
133
|
+
* @remarks
|
|
134
|
+
* This module only wires providers and store resolution. The documented cache
|
|
135
|
+
* semantics remain defined by the decorators, interceptor, and `CacheService`.
|
|
136
|
+
*/
|
|
137
|
+
export class CacheModule {
|
|
138
|
+
/**
|
|
139
|
+
* Register cache providers for the current application module graph.
|
|
140
|
+
*
|
|
141
|
+
* @remarks
|
|
142
|
+
* This is the primary package entrypoint, including custom
|
|
143
|
+
* `defineModule(...)` composition. Root-package consumers should treat
|
|
144
|
+
* low-level provider wiring as an internal implementation detail.
|
|
145
|
+
*
|
|
146
|
+
* @param options Cache module options.
|
|
147
|
+
* @returns A runtime module exporting `CacheService` and `CacheInterceptor`.
|
|
148
|
+
*
|
|
149
|
+
* @example
|
|
150
|
+
* ```ts
|
|
151
|
+
* CacheModule.forRoot({
|
|
152
|
+
* store: 'redis',
|
|
153
|
+
* ttl: 300,
|
|
154
|
+
* });
|
|
155
|
+
* ```
|
|
156
|
+
*/
|
|
157
|
+
static forRoot(options = {}) {
|
|
158
|
+
const normalized = normalizeCacheModuleOptions(options);
|
|
159
|
+
class CacheRootModule extends CacheModule {}
|
|
160
|
+
return defineModule(CacheRootModule, {
|
|
161
|
+
exports: [CacheService, CacheInterceptor],
|
|
162
|
+
global: normalized.isGlobal,
|
|
163
|
+
providers: createCacheModuleProviders(options)
|
|
164
|
+
});
|
|
165
|
+
}
|
|
166
|
+
}
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
import type { CacheStore, NormalizedCacheModuleOptions } from './types.js';
|
|
2
|
+
/**
|
|
3
|
+
* Application-level cache facade used for direct cache reads, writes, and read-through loading.
|
|
4
|
+
*/
|
|
5
|
+
export declare class CacheService {
|
|
6
|
+
private readonly store;
|
|
7
|
+
private readonly options;
|
|
8
|
+
private readonly inflight;
|
|
9
|
+
private readonly pendingLoads;
|
|
10
|
+
private readonly invalidatedInflight;
|
|
11
|
+
private resetVersion;
|
|
12
|
+
private beginPendingLoad;
|
|
13
|
+
private endPendingLoad;
|
|
14
|
+
constructor(store: CacheStore, options: NormalizedCacheModuleOptions);
|
|
15
|
+
/**
|
|
16
|
+
* Read a cached value by key.
|
|
17
|
+
*
|
|
18
|
+
* @param key Cache entry key.
|
|
19
|
+
* @returns The cached value, or `undefined` when the key is missing or expired.
|
|
20
|
+
*/
|
|
21
|
+
get<T = unknown>(key: string): Promise<T | undefined>;
|
|
22
|
+
/**
|
|
23
|
+
* Store a value in the configured cache store.
|
|
24
|
+
*
|
|
25
|
+
* @param key Cache entry key.
|
|
26
|
+
* @param value Value to cache.
|
|
27
|
+
* @param ttlSeconds Optional per-call TTL override in seconds.
|
|
28
|
+
* @returns A promise that resolves after the write completes.
|
|
29
|
+
*/
|
|
30
|
+
set<T = unknown>(key: string, value: T, ttlSeconds?: number): Promise<void>;
|
|
31
|
+
/**
|
|
32
|
+
* Load a value through the cache, de-duplicating concurrent misses for the same key.
|
|
33
|
+
*
|
|
34
|
+
* @param key Cache entry key.
|
|
35
|
+
* @param loader Async loader invoked on cache miss.
|
|
36
|
+
* @param ttlSeconds Optional per-call TTL override in seconds.
|
|
37
|
+
* @returns The cached or freshly loaded value.
|
|
38
|
+
*/
|
|
39
|
+
remember<T = unknown>(key: string, loader: () => Promise<T>, ttlSeconds?: number): Promise<T>;
|
|
40
|
+
/**
|
|
41
|
+
* Delete a single cache entry.
|
|
42
|
+
*
|
|
43
|
+
* @param key Cache entry key.
|
|
44
|
+
* @returns A promise that resolves after the entry is removed.
|
|
45
|
+
*/
|
|
46
|
+
del(key: string): Promise<void>;
|
|
47
|
+
/**
|
|
48
|
+
* Clear every cache entry owned by the configured store.
|
|
49
|
+
*
|
|
50
|
+
* @returns A promise that resolves after the store reset completes.
|
|
51
|
+
*/
|
|
52
|
+
reset(): Promise<void>;
|
|
53
|
+
}
|
|
54
|
+
//# sourceMappingURL=service.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"service.d.ts","sourceRoot":"","sources":["../src/service.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,UAAU,EAAE,4BAA4B,EAAE,MAAM,YAAY,CAAC;AAE3E;;GAEG;AACH,qBACa,YAAY;IAsBrB,OAAO,CAAC,QAAQ,CAAC,KAAK;IACtB,OAAO,CAAC,QAAQ,CAAC,OAAO;IAtB1B,OAAO,CAAC,QAAQ,CAAC,QAAQ,CAAuC;IAChE,OAAO,CAAC,QAAQ,CAAC,YAAY,CAA6B;IAC1D,OAAO,CAAC,QAAQ,CAAC,mBAAmB,CAAqB;IACzD,OAAO,CAAC,YAAY,CAAK;IAEzB,OAAO,CAAC,gBAAgB;IAIxB,OAAO,CAAC,cAAc;gBAYH,KAAK,EAAE,UAAU,EACjB,OAAO,EAAE,4BAA4B;IAGxD;;;;;OAKG;IACH,GAAG,CAAC,CAAC,GAAG,OAAO,EAAE,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,CAAC,GAAG,SAAS,CAAC;IAIrD;;;;;;;OAOG;IACG,GAAG,CAAC,CAAC,GAAG,OAAO,EAAE,GAAG,EAAE,MAAM,EAAE,KAAK,EAAE,CAAC,EAAE,UAAU,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAUjF;;;;;;;OAOG;IACG,QAAQ,CAAC,CAAC,GAAG,OAAO,EACxB,GAAG,EAAE,MAAM,EACX,MAAM,EAAE,MAAM,OAAO,CAAC,CAAC,CAAC,EACxB,UAAU,CAAC,EAAE,MAAM,GAClB,OAAO,CAAC,CAAC,CAAC;IAyCb;;;;;OAKG;IACG,GAAG,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAQrC;;;;OAIG;IACG,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC;CAK7B"}
|
package/dist/service.js
ADDED
|
@@ -0,0 +1,130 @@
|
|
|
1
|
+
let _initClass;
|
|
2
|
+
function _applyDecs(e, t, n, r, o, i) { var a, c, u, s, f, l, p, d = Symbol.metadata || Symbol.for("Symbol.metadata"), m = Object.defineProperty, h = Object.create, y = [h(null), h(null)], v = t.length; function g(t, n, r) { return function (o, i) { n && (i = o, o = e); for (var a = 0; a < t.length; a++) i = t[a].apply(o, r ? [i] : []); return r ? i : o; }; } function b(e, t, n, r) { if ("function" != typeof e && (r || void 0 !== e)) throw new TypeError(t + " must " + (n || "be") + " a function" + (r ? "" : " or undefined")); return e; } function applyDec(e, t, n, r, o, i, u, s, f, l, p) { function d(e) { if (!p(e)) throw new TypeError("Attempted to access private element on non-instance"); } var h = [].concat(t[0]), v = t[3], w = !u, D = 1 === o, S = 3 === o, j = 4 === o, E = 2 === o; function I(t, n, r) { return function (o, i) { return n && (i = o, o = e), r && r(o), P[t].call(o, i); }; } if (!w) { var P = {}, k = [], F = S ? "get" : j || D ? "set" : "value"; if (f ? (l || D ? P = { get: _setFunctionName(function () { return v(this); }, r, "get"), set: function (e) { t[4](this, e); } } : P[F] = v, l || _setFunctionName(P[F], r, E ? "" : F)) : l || (P = Object.getOwnPropertyDescriptor(e, r)), !l && !f) { if ((c = y[+s][r]) && 7 !== (c ^ o)) throw Error("Decorating two elements with the same name (" + P[F].name + ") is not supported yet"); y[+s][r] = o < 3 ? 1 : o; } } for (var N = e, O = h.length - 1; O >= 0; O -= n ? 2 : 1) { var T = b(h[O], "A decorator", "be", !0), z = n ? h[O - 1] : void 0, A = {}, H = { kind: ["field", "accessor", "method", "getter", "setter", "class"][o], name: r, metadata: a, addInitializer: function (e, t) { if (e.v) throw new TypeError("attempted to call addInitializer after decoration was finished"); b(t, "An initializer", "be", !0), i.push(t); }.bind(null, A) }; if (w) c = T.call(z, N, H), A.v = 1, b(c, "class decorators", "return") && (N = c);else if (H.static = s, H.private = f, c = H.access = { has: f ? p.bind() : function (e) { return r in e; } }, j || (c.get = f ? E ? function (e) { return d(e), P.value; } : I("get", 0, d) : function (e) { return e[r]; }), E || S || (c.set = f ? I("set", 0, d) : function (e, t) { e[r] = t; }), N = T.call(z, D ? { get: P.get, set: P.set } : P[F], H), A.v = 1, D) { if ("object" == typeof N && N) (c = b(N.get, "accessor.get")) && (P.get = c), (c = b(N.set, "accessor.set")) && (P.set = c), (c = b(N.init, "accessor.init")) && k.unshift(c);else if (void 0 !== N) throw new TypeError("accessor decorators must return an object with get, set, or init properties or undefined"); } else b(N, (l ? "field" : "method") + " decorators", "return") && (l ? k.unshift(N) : P[F] = N); } return o < 2 && u.push(g(k, s, 1), g(i, s, 0)), l || w || (f ? D ? u.splice(-1, 0, I("get", s), I("set", s)) : u.push(E ? P[F] : b.call.bind(P[F])) : m(e, r, P)), N; } function w(e) { return m(e, d, { configurable: !0, enumerable: !0, value: a }); } return void 0 !== i && (a = i[d]), a = h(null == a ? null : a), f = [], l = function (e) { e && f.push(g(e)); }, p = function (t, r) { for (var i = 0; i < n.length; i++) { var a = n[i], c = a[1], l = 7 & c; if ((8 & c) == t && !l == r) { var p = a[2], d = !!a[3], m = 16 & c; applyDec(t ? e : e.prototype, a, m, d ? "#" + p : _toPropertyKey(p), l, l < 2 ? [] : t ? s = s || [] : u = u || [], f, !!t, d, r, t && d ? function (t) { return _checkInRHS(t) === e; } : o); } } }, p(8, 0), p(0, 0), p(8, 1), p(0, 1), l(u), l(s), c = f, v || w(e), { e: c, get c() { var n = []; return v && [w(e = applyDec(e, [t], r, e.name, 5, n)), g(n, 1)]; } }; }
|
|
3
|
+
function _toPropertyKey(t) { var i = _toPrimitive(t, "string"); return "symbol" == typeof i ? i : i + ""; }
|
|
4
|
+
function _toPrimitive(t, r) { if ("object" != typeof t || !t) return t; var e = t[Symbol.toPrimitive]; if (void 0 !== e) { var i = e.call(t, r || "default"); if ("object" != typeof i) return i; throw new TypeError("@@toPrimitive must return a primitive value."); } return ("string" === r ? String : Number)(t); }
|
|
5
|
+
function _setFunctionName(e, t, n) { "symbol" == typeof t && (t = (t = t.description) ? "[" + t + "]" : ""); try { Object.defineProperty(e, "name", { configurable: !0, value: n ? n + " " + t : t }); } catch (e) {} return e; }
|
|
6
|
+
function _checkInRHS(e) { if (Object(e) !== e) throw TypeError("right-hand side of 'in' should be an object, got " + (null !== e ? typeof e : "null")); return e; }
|
|
7
|
+
import { Inject } from '@fluojs/core';
|
|
8
|
+
import { CACHE_OPTIONS, CACHE_STORE } from './tokens.js';
|
|
9
|
+
let _CacheService;
|
|
10
|
+
/**
|
|
11
|
+
* Application-level cache facade used for direct cache reads, writes, and read-through loading.
|
|
12
|
+
*/
|
|
13
|
+
class CacheService {
|
|
14
|
+
static {
|
|
15
|
+
[_CacheService, _initClass] = _applyDecs(this, [Inject(CACHE_STORE, CACHE_OPTIONS)], []).c;
|
|
16
|
+
}
|
|
17
|
+
inflight = new Map();
|
|
18
|
+
pendingLoads = new Map();
|
|
19
|
+
invalidatedInflight = new Set();
|
|
20
|
+
resetVersion = 0;
|
|
21
|
+
beginPendingLoad(key) {
|
|
22
|
+
this.pendingLoads.set(key, (this.pendingLoads.get(key) ?? 0) + 1);
|
|
23
|
+
}
|
|
24
|
+
endPendingLoad(key) {
|
|
25
|
+
const remaining = (this.pendingLoads.get(key) ?? 0) - 1;
|
|
26
|
+
if (remaining > 0) {
|
|
27
|
+
this.pendingLoads.set(key, remaining);
|
|
28
|
+
return;
|
|
29
|
+
}
|
|
30
|
+
this.pendingLoads.delete(key);
|
|
31
|
+
}
|
|
32
|
+
constructor(store, options) {
|
|
33
|
+
this.store = store;
|
|
34
|
+
this.options = options;
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
/**
|
|
38
|
+
* Read a cached value by key.
|
|
39
|
+
*
|
|
40
|
+
* @param key Cache entry key.
|
|
41
|
+
* @returns The cached value, or `undefined` when the key is missing or expired.
|
|
42
|
+
*/
|
|
43
|
+
get(key) {
|
|
44
|
+
return Promise.resolve(this.store.get(key));
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
/**
|
|
48
|
+
* Store a value in the configured cache store.
|
|
49
|
+
*
|
|
50
|
+
* @param key Cache entry key.
|
|
51
|
+
* @param value Value to cache.
|
|
52
|
+
* @param ttlSeconds Optional per-call TTL override in seconds.
|
|
53
|
+
* @returns A promise that resolves after the write completes.
|
|
54
|
+
*/
|
|
55
|
+
async set(key, value, ttlSeconds) {
|
|
56
|
+
const resolvedTtl = ttlSeconds ?? this.options.ttl;
|
|
57
|
+
if (!Number.isFinite(resolvedTtl) || resolvedTtl < 0) {
|
|
58
|
+
return;
|
|
59
|
+
}
|
|
60
|
+
await this.store.set(key, value, resolvedTtl);
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
/**
|
|
64
|
+
* Load a value through the cache, de-duplicating concurrent misses for the same key.
|
|
65
|
+
*
|
|
66
|
+
* @param key Cache entry key.
|
|
67
|
+
* @param loader Async loader invoked on cache miss.
|
|
68
|
+
* @param ttlSeconds Optional per-call TTL override in seconds.
|
|
69
|
+
* @returns The cached or freshly loaded value.
|
|
70
|
+
*/
|
|
71
|
+
async remember(key, loader, ttlSeconds) {
|
|
72
|
+
this.beginPendingLoad(key);
|
|
73
|
+
try {
|
|
74
|
+
const resetVersion = this.resetVersion;
|
|
75
|
+
const cached = await this.get(key);
|
|
76
|
+
if (cached !== undefined) {
|
|
77
|
+
return cached;
|
|
78
|
+
}
|
|
79
|
+
const existing = this.inflight.get(key);
|
|
80
|
+
if (existing) {
|
|
81
|
+
return existing;
|
|
82
|
+
}
|
|
83
|
+
const promise = loader().then(async value => {
|
|
84
|
+
if (this.invalidatedInflight.has(key) || this.resetVersion !== resetVersion) {
|
|
85
|
+
return value;
|
|
86
|
+
}
|
|
87
|
+
await this.set(key, value, ttlSeconds);
|
|
88
|
+
if (this.invalidatedInflight.has(key) || this.resetVersion !== resetVersion) {
|
|
89
|
+
await this.store.del(key);
|
|
90
|
+
}
|
|
91
|
+
return value;
|
|
92
|
+
}).finally(() => {
|
|
93
|
+
this.inflight.delete(key);
|
|
94
|
+
this.invalidatedInflight.delete(key);
|
|
95
|
+
});
|
|
96
|
+
this.inflight.set(key, promise);
|
|
97
|
+
return promise;
|
|
98
|
+
} finally {
|
|
99
|
+
this.endPendingLoad(key);
|
|
100
|
+
}
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
/**
|
|
104
|
+
* Delete a single cache entry.
|
|
105
|
+
*
|
|
106
|
+
* @param key Cache entry key.
|
|
107
|
+
* @returns A promise that resolves after the entry is removed.
|
|
108
|
+
*/
|
|
109
|
+
async del(key) {
|
|
110
|
+
if (this.pendingLoads.has(key) || this.inflight.has(key)) {
|
|
111
|
+
this.invalidatedInflight.add(key);
|
|
112
|
+
}
|
|
113
|
+
await this.store.del(key);
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
/**
|
|
117
|
+
* Clear every cache entry owned by the configured store.
|
|
118
|
+
*
|
|
119
|
+
* @returns A promise that resolves after the store reset completes.
|
|
120
|
+
*/
|
|
121
|
+
async reset() {
|
|
122
|
+
this.resetVersion += 1;
|
|
123
|
+
this.invalidatedInflight.clear();
|
|
124
|
+
await this.store.reset();
|
|
125
|
+
}
|
|
126
|
+
static {
|
|
127
|
+
_initClass();
|
|
128
|
+
}
|
|
129
|
+
}
|
|
130
|
+
export { _CacheService as CacheService };
|
package/dist/status.d.ts
ADDED
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
import type { PlatformDiagnosticIssue, PlatformHealthReport, PlatformReadinessReport, PlatformSnapshot } from '@fluojs/runtime';
|
|
2
|
+
/**
|
|
3
|
+
* Snapshot shape produced by the cache-manager platform status helpers.
|
|
4
|
+
*/
|
|
5
|
+
export interface CacheManagerPlatformStatusSnapshot {
|
|
6
|
+
readiness: PlatformReadinessReport;
|
|
7
|
+
health: PlatformHealthReport;
|
|
8
|
+
ownership: PlatformSnapshot['ownership'];
|
|
9
|
+
details: Record<string, unknown>;
|
|
10
|
+
}
|
|
11
|
+
/**
|
|
12
|
+
* Backing store categories recognized by the cache-manager status adapter.
|
|
13
|
+
*/
|
|
14
|
+
export type CacheManagerStoreKind = 'memory' | 'redis' | 'custom';
|
|
15
|
+
/**
|
|
16
|
+
* Ownership modes used to describe who is responsible for the backing store lifecycle.
|
|
17
|
+
*/
|
|
18
|
+
export type CacheManagerStoreOwnershipMode = 'framework' | 'external';
|
|
19
|
+
/**
|
|
20
|
+
* Input consumed by cache-manager status and diagnostic helpers.
|
|
21
|
+
*/
|
|
22
|
+
export interface CacheManagerStatusAdapterInput {
|
|
23
|
+
componentId?: string;
|
|
24
|
+
storeKind: CacheManagerStoreKind;
|
|
25
|
+
storeOwnershipMode?: CacheManagerStoreOwnershipMode;
|
|
26
|
+
backingStoreReady?: boolean;
|
|
27
|
+
backingStoreReason?: string;
|
|
28
|
+
dependencyId?: string;
|
|
29
|
+
cacheCriticalPath?: boolean;
|
|
30
|
+
}
|
|
31
|
+
/**
|
|
32
|
+
* Create a platform status snapshot for cache-manager readiness, health, and telemetry.
|
|
33
|
+
*
|
|
34
|
+
* @param input Store metadata and readiness hints collected during bootstrap.
|
|
35
|
+
* @returns A cache-manager status snapshot suitable for platform diagnostics.
|
|
36
|
+
*/
|
|
37
|
+
export declare function createCacheManagerPlatformStatusSnapshot(input: CacheManagerStatusAdapterInput): CacheManagerPlatformStatusSnapshot;
|
|
38
|
+
/**
|
|
39
|
+
* Translate cache-manager readiness input into platform diagnostic issues.
|
|
40
|
+
*
|
|
41
|
+
* @param input Store metadata and readiness hints collected during bootstrap.
|
|
42
|
+
* @returns Zero or more diagnostic issues describing degraded or unavailable cache backing stores.
|
|
43
|
+
*/
|
|
44
|
+
export declare function createCacheManagerPlatformDiagnosticIssues(input: CacheManagerStatusAdapterInput): PlatformDiagnosticIssue[];
|
|
45
|
+
//# sourceMappingURL=status.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"status.d.ts","sourceRoot":"","sources":["../src/status.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,uBAAuB,EAAE,oBAAoB,EAAE,uBAAuB,EAAE,gBAAgB,EAAE,MAAM,iBAAiB,CAAC;AAEhI;;GAEG;AACH,MAAM,WAAW,kCAAkC;IACjD,SAAS,EAAE,uBAAuB,CAAC;IACnC,MAAM,EAAE,oBAAoB,CAAC;IAC7B,SAAS,EAAE,gBAAgB,CAAC,WAAW,CAAC,CAAC;IACzC,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;CAClC;AAED;;GAEG;AACH,MAAM,MAAM,qBAAqB,GAAG,QAAQ,GAAG,OAAO,GAAG,QAAQ,CAAC;AAElE;;GAEG;AACH,MAAM,MAAM,8BAA8B,GAAG,WAAW,GAAG,UAAU,CAAC;AAEtE;;GAEG;AACH,MAAM,WAAW,8BAA8B;IAC7C,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,SAAS,EAAE,qBAAqB,CAAC;IACjC,kBAAkB,CAAC,EAAE,8BAA8B,CAAC;IACpD,iBAAiB,CAAC,EAAE,OAAO,CAAC;IAC5B,kBAAkB,CAAC,EAAE,MAAM,CAAC;IAC5B,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,iBAAiB,CAAC,EAAE,OAAO,CAAC;CAC7B;AAgDD;;;;;GAKG;AACH,wBAAgB,wCAAwC,CAAC,KAAK,EAAE,8BAA8B,GAAG,kCAAkC,CAgClI;AAED;;;;;GAKG;AACH,wBAAgB,0CAA0C,CAAC,KAAK,EAAE,8BAA8B,GAAG,uBAAuB,EAAE,CAuB3H"}
|