@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/dist/status.js ADDED
@@ -0,0 +1,115 @@
1
+ /**
2
+ * Snapshot shape produced by the cache-manager platform status helpers.
3
+ */
4
+
5
+ /**
6
+ * Backing store categories recognized by the cache-manager status adapter.
7
+ */
8
+
9
+ /**
10
+ * Ownership modes used to describe who is responsible for the backing store lifecycle.
11
+ */
12
+
13
+ /**
14
+ * Input consumed by cache-manager status and diagnostic helpers.
15
+ */
16
+
17
+ function resolveStoreOwnershipMode(input) {
18
+ if (input.storeOwnershipMode) {
19
+ return input.storeOwnershipMode;
20
+ }
21
+ return input.storeKind === 'memory' ? 'framework' : 'external';
22
+ }
23
+ function isBackingStoreReady(input) {
24
+ if (input.backingStoreReady !== undefined) {
25
+ return input.backingStoreReady;
26
+ }
27
+ return true;
28
+ }
29
+ function createReadiness(input) {
30
+ const critical = input.cacheCriticalPath ?? false;
31
+ if (isBackingStoreReady(input)) {
32
+ return {
33
+ critical,
34
+ status: 'ready'
35
+ };
36
+ }
37
+ return {
38
+ critical,
39
+ reason: input.backingStoreReason ?? 'Cache backing store is unavailable.',
40
+ status: critical ? 'not-ready' : 'degraded'
41
+ };
42
+ }
43
+ function createHealth(input) {
44
+ if (!isBackingStoreReady(input)) {
45
+ return {
46
+ reason: input.backingStoreReason ?? 'Cache backing store is unavailable.',
47
+ status: 'degraded'
48
+ };
49
+ }
50
+ return {
51
+ status: 'healthy'
52
+ };
53
+ }
54
+
55
+ /**
56
+ * Create a platform status snapshot for cache-manager readiness, health, and telemetry.
57
+ *
58
+ * @param input Store metadata and readiness hints collected during bootstrap.
59
+ * @returns A cache-manager status snapshot suitable for platform diagnostics.
60
+ */
61
+ export function createCacheManagerPlatformStatusSnapshot(input) {
62
+ const storeOwnershipMode = resolveStoreOwnershipMode(input);
63
+ const backingReady = isBackingStoreReady(input);
64
+ const componentId = input.componentId ?? 'cache-manager.default';
65
+ return {
66
+ details: {
67
+ backingStore: {
68
+ dependencyId: input.dependencyId,
69
+ reason: input.backingStoreReason,
70
+ ready: backingReady
71
+ },
72
+ cacheCriticalPath: input.cacheCriticalPath ?? false,
73
+ storeKind: input.storeKind,
74
+ storeOwnershipMode,
75
+ telemetry: {
76
+ labels: {
77
+ component_id: componentId,
78
+ component_kind: 'cache-manager',
79
+ operation: 'cache-availability',
80
+ result: backingReady ? 'ready' : 'degraded'
81
+ },
82
+ namespace: 'cache-manager'
83
+ }
84
+ },
85
+ health: createHealth(input),
86
+ ownership: {
87
+ externallyManaged: storeOwnershipMode === 'external',
88
+ ownsResources: storeOwnershipMode === 'framework'
89
+ },
90
+ readiness: createReadiness(input)
91
+ };
92
+ }
93
+
94
+ /**
95
+ * Translate cache-manager readiness input into platform diagnostic issues.
96
+ *
97
+ * @param input Store metadata and readiness hints collected during bootstrap.
98
+ * @returns Zero or more diagnostic issues describing degraded or unavailable cache backing stores.
99
+ */
100
+ export function createCacheManagerPlatformDiagnosticIssues(input) {
101
+ if (isBackingStoreReady(input)) {
102
+ return [];
103
+ }
104
+ const componentId = input.componentId ?? 'cache-manager.default';
105
+ const critical = input.cacheCriticalPath ?? false;
106
+ return [{
107
+ code: 'CACHE_MANAGER_BACKING_STORE_NOT_READY',
108
+ componentId,
109
+ cause: input.backingStoreReason,
110
+ dependsOn: input.dependencyId ? [input.dependencyId] : undefined,
111
+ fixHint: input.storeKind === 'redis' ? 'Verify Redis connectivity, or treat cache as non-critical by keeping cacheCriticalPath disabled.' : 'Restore cache backing store availability or disable cache-critical readiness requirements.',
112
+ message: critical ? 'Cache manager is part of a declared critical path, but the backing store is not ready.' : 'Cache backing store is degraded; request handling can continue with cache misses in non-critical mode.',
113
+ severity: critical ? 'error' : 'warning'
114
+ }];
115
+ }
@@ -0,0 +1,10 @@
1
+ import type { CacheStore } from '../types.js';
2
+ export declare class MemoryStore implements CacheStore {
3
+ private readonly entries;
4
+ private nextSweepAt;
5
+ get<T = unknown>(key: string): Promise<T | undefined>;
6
+ set<T = unknown>(key: string, value: T, ttlSeconds?: number): Promise<void>;
7
+ del(key: string): Promise<void>;
8
+ reset(): Promise<void>;
9
+ }
10
+ //# sourceMappingURL=memory-store.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"memory-store.d.ts","sourceRoot":"","sources":["../../src/stores/memory-store.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AAyC9C,qBAAa,WAAY,YAAW,UAAU;IAC5C,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAuC;IAC/D,OAAO,CAAC,WAAW,CAAK;IAElB,GAAG,CAAC,CAAC,GAAG,OAAO,EAAE,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,CAAC,GAAG,SAAS,CAAC;IAsBrD,GAAG,CAAC,CAAC,GAAG,OAAO,EAAE,GAAG,EAAE,MAAM,EAAE,KAAK,EAAE,CAAC,EAAE,UAAU,SAAI,GAAG,OAAO,CAAC,IAAI,CAAC;IAyBtE,GAAG,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAI/B,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC;CAI7B"}
@@ -0,0 +1,71 @@
1
+ import { cloneCacheValue } from '../clone.js';
2
+ const DEFAULT_MAX_MEMORY_CACHE_ENTRIES = 1_000;
3
+ function sweepExpiredEntries(entries, now) {
4
+ let nextSweepAt = Number.POSITIVE_INFINITY;
5
+ for (const [key, entry] of entries) {
6
+ if (entry.expiresAt === undefined) {
7
+ continue;
8
+ }
9
+ if (now >= entry.expiresAt) {
10
+ entries.delete(key);
11
+ continue;
12
+ }
13
+ nextSweepAt = Math.min(nextSweepAt, entry.expiresAt);
14
+ }
15
+ return Number.isFinite(nextSweepAt) ? nextSweepAt : 0;
16
+ }
17
+ function enforceEntryLimit(entries) {
18
+ while (entries.size > DEFAULT_MAX_MEMORY_CACHE_ENTRIES) {
19
+ const oldestKey = entries.keys().next().value;
20
+ if (oldestKey === undefined) {
21
+ return;
22
+ }
23
+ entries.delete(oldestKey);
24
+ }
25
+ }
26
+ export class MemoryStore {
27
+ entries = new Map();
28
+ nextSweepAt = 0;
29
+ async get(key) {
30
+ const now = Date.now();
31
+ if (now >= this.nextSweepAt) {
32
+ this.nextSweepAt = sweepExpiredEntries(this.entries, now);
33
+ }
34
+ const entry = this.entries.get(key);
35
+ if (!entry) {
36
+ return undefined;
37
+ }
38
+ if (entry.expiresAt !== undefined && now >= entry.expiresAt) {
39
+ this.entries.delete(key);
40
+ this.nextSweepAt = sweepExpiredEntries(this.entries, now);
41
+ return undefined;
42
+ }
43
+ return cloneCacheValue(entry.value);
44
+ }
45
+ async set(key, value, ttlSeconds = 0) {
46
+ const now = Date.now();
47
+ if (now >= this.nextSweepAt) {
48
+ this.nextSweepAt = sweepExpiredEntries(this.entries, now);
49
+ }
50
+ const entry = {
51
+ value: cloneCacheValue(value)
52
+ };
53
+ if (ttlSeconds > 0) {
54
+ const ttlMilliseconds = Math.max(1, Math.floor(ttlSeconds * 1000));
55
+ entry.expiresAt = now + ttlMilliseconds;
56
+ }
57
+ this.entries.delete(key);
58
+ this.entries.set(key, entry);
59
+ enforceEntryLimit(this.entries);
60
+ if (entry.expiresAt !== undefined) {
61
+ this.nextSweepAt = this.nextSweepAt === 0 ? entry.expiresAt : Math.min(this.nextSweepAt, entry.expiresAt);
62
+ }
63
+ }
64
+ async del(key) {
65
+ this.entries.delete(key);
66
+ }
67
+ async reset() {
68
+ this.entries.clear();
69
+ this.nextSweepAt = 0;
70
+ }
71
+ }
@@ -0,0 +1,17 @@
1
+ import type { CacheStore, RedisCompatibleClient } from '../types.js';
2
+ export interface RedisStoreOptions {
3
+ keyPrefix?: string;
4
+ scanCount?: number;
5
+ }
6
+ export declare class RedisStore implements CacheStore {
7
+ private readonly client;
8
+ private readonly keyPrefix;
9
+ private readonly scanCount;
10
+ constructor(client: RedisCompatibleClient, options?: RedisStoreOptions);
11
+ private toRedisKey;
12
+ get<T = unknown>(key: string): Promise<T | undefined>;
13
+ set<T = unknown>(key: string, value: T, ttlSeconds?: number): Promise<void>;
14
+ del(key: string): Promise<void>;
15
+ reset(): Promise<void>;
16
+ }
17
+ //# sourceMappingURL=redis-store.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"redis-store.d.ts","sourceRoot":"","sources":["../../src/stores/redis-store.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,UAAU,EAAE,qBAAqB,EAAE,MAAM,aAAa,CAAC;AAErE,MAAM,WAAW,iBAAiB;IAChC,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAwCD,qBAAa,UAAW,YAAW,UAAU;IAKzC,OAAO,CAAC,QAAQ,CAAC,MAAM;IAJzB,OAAO,CAAC,QAAQ,CAAC,SAAS,CAAS;IACnC,OAAO,CAAC,QAAQ,CAAC,SAAS,CAAS;gBAGhB,MAAM,EAAE,qBAAqB,EAC9C,OAAO,GAAE,iBAAsB;IAMjC,OAAO,CAAC,UAAU;IAIZ,GAAG,CAAC,CAAC,GAAG,OAAO,EAAE,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,CAAC,GAAG,SAAS,CAAC;IAiBrD,GAAG,CAAC,CAAC,GAAG,OAAO,EAAE,GAAG,EAAE,MAAM,EAAE,KAAK,EAAE,CAAC,EAAE,UAAU,SAAI,GAAG,OAAO,CAAC,IAAI,CAAC;IAiBtE,GAAG,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAI/B,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC;CAmB7B"}
@@ -0,0 +1,81 @@
1
+ const DEFAULT_KEY_PREFIX = 'fluo:cache:';
2
+ const DEFAULT_SCAN_COUNT = 100;
3
+ function parseEntry(raw) {
4
+ try {
5
+ const decoded = JSON.parse(raw);
6
+ if (!decoded || typeof decoded !== 'object' || !('value' in decoded)) {
7
+ return undefined;
8
+ }
9
+ if (decoded.expiresAt !== undefined && (typeof decoded.expiresAt !== 'number' || !Number.isFinite(decoded.expiresAt))) {
10
+ return undefined;
11
+ }
12
+ return {
13
+ expiresAt: decoded.expiresAt,
14
+ value: decoded.value
15
+ };
16
+ } catch {
17
+ return undefined;
18
+ }
19
+ }
20
+ function normalizeScanResponse(result) {
21
+ const [cursor, keys] = result;
22
+ return {
23
+ cursor: String(cursor),
24
+ keys
25
+ };
26
+ }
27
+ export class RedisStore {
28
+ keyPrefix;
29
+ scanCount;
30
+ constructor(client, options = {}) {
31
+ this.client = client;
32
+ this.keyPrefix = options.keyPrefix ?? DEFAULT_KEY_PREFIX;
33
+ this.scanCount = options.scanCount ?? DEFAULT_SCAN_COUNT;
34
+ }
35
+ toRedisKey(key) {
36
+ return `${this.keyPrefix}${key}`;
37
+ }
38
+ async get(key) {
39
+ const redisKey = this.toRedisKey(key);
40
+ const raw = await this.client.get(redisKey);
41
+ if (raw === null) {
42
+ return undefined;
43
+ }
44
+ const decoded = parseEntry(raw);
45
+ if (!decoded) {
46
+ return undefined;
47
+ }
48
+ return decoded.value;
49
+ }
50
+ async set(key, value, ttlSeconds = 0) {
51
+ const now = Date.now();
52
+ const entry = {
53
+ value
54
+ };
55
+ if (ttlSeconds > 0) {
56
+ const ttlMilliseconds = Math.max(1, Math.floor(ttlSeconds * 1000));
57
+ entry.expiresAt = now + ttlMilliseconds;
58
+ const ttlSecondsRounded = Math.max(1, Math.ceil(ttlMilliseconds / 1000));
59
+ await this.client.set(this.toRedisKey(key), JSON.stringify(entry), 'EX', ttlSecondsRounded);
60
+ return;
61
+ }
62
+ await this.client.set(this.toRedisKey(key), JSON.stringify(entry));
63
+ }
64
+ async del(key) {
65
+ await this.client.del(this.toRedisKey(key));
66
+ }
67
+ async reset() {
68
+ let cursor = '0';
69
+ const pattern = `${this.keyPrefix}*`;
70
+ do {
71
+ const scanResult = normalizeScanResponse(await this.client.scan(cursor, 'MATCH', pattern, 'COUNT', this.scanCount));
72
+ cursor = scanResult.cursor;
73
+ if (scanResult.keys.length > 0) {
74
+ const [firstKey, ...restKeys] = scanResult.keys;
75
+ if (firstKey) {
76
+ await this.client.del(firstKey, ...restKeys);
77
+ }
78
+ }
79
+ } while (cursor !== '0');
80
+ }
81
+ }
@@ -0,0 +1,9 @@
1
+ /**
2
+ * DI token for providing cache module options.
3
+ */
4
+ export declare const CACHE_OPTIONS: unique symbol;
5
+ /**
6
+ * DI token for providing a custom cache store implementation.
7
+ */
8
+ export declare const CACHE_STORE: unique symbol;
9
+ //# sourceMappingURL=tokens.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"tokens.d.ts","sourceRoot":"","sources":["../src/tokens.ts"],"names":[],"mappings":"AAAA;;GAEG;AACH,eAAO,MAAM,aAAa,eAAmC,CAAC;AAC9D;;GAEG;AACH,eAAO,MAAM,WAAW,eAAiC,CAAC"}
package/dist/tokens.js ADDED
@@ -0,0 +1,8 @@
1
+ /**
2
+ * DI token for providing cache module options.
3
+ */
4
+ export const CACHE_OPTIONS = Symbol.for('fluo.cache.options');
5
+ /**
6
+ * DI token for providing a custom cache store implementation.
7
+ */
8
+ export const CACHE_STORE = Symbol.for('fluo.cache.store');
@@ -0,0 +1,80 @@
1
+ import type { InterceptorContext } from '@fluojs/http';
2
+ type Awaitable<T> = T | Promise<T>;
3
+ /**
4
+ * Minimal cache-store contract implemented by built-in and custom cache adapters.
5
+ */
6
+ export interface CacheStore {
7
+ get<T>(key: string): Promise<T | undefined>;
8
+ set<T>(key: string, value: T, ttlSeconds?: number): Promise<void>;
9
+ del(key: string): Promise<void>;
10
+ reset(): Promise<void>;
11
+ }
12
+ /**
13
+ * Redis client subset required by `RedisStore`.
14
+ */
15
+ export interface RedisCompatibleClient {
16
+ del(key: string, ...keys: string[]): Promise<number> | number;
17
+ get(key: string): Promise<string | null> | string | null;
18
+ scan(cursor: string, ...args: Array<string | number>): Promise<[string | number, string[]]> | [string | number, string[]];
19
+ set(key: string, value: string, ...args: Array<string | number>): Promise<unknown> | unknown;
20
+ }
21
+ /**
22
+ * Redis-specific cache bootstrap options.
23
+ */
24
+ export interface RedisCacheOptions {
25
+ client?: RedisCompatibleClient;
26
+ clientName?: string;
27
+ scanCount?: number;
28
+ }
29
+ interface CacheModuleInternalOptions {
30
+ keyPrefix?: string;
31
+ redis?: RedisCacheOptions;
32
+ }
33
+ /**
34
+ * Resolves the principal-scope suffix appended by built-in HTTP cache-key strategies.
35
+ */
36
+ export type PrincipalScopeResolver = (context: InterceptorContext) => string | undefined;
37
+ /**
38
+ * Public configuration options for `CacheModule.forRoot(...)`.
39
+ */
40
+ export interface CacheModuleOptions extends CacheModuleInternalOptions {
41
+ isGlobal?: boolean;
42
+ store?: 'memory' | 'redis' | CacheStore;
43
+ ttl?: number;
44
+ httpKeyStrategy?: CacheKeyStrategy;
45
+ principalScopeResolver?: PrincipalScopeResolver;
46
+ }
47
+ /**
48
+ * Normalized cache-module configuration consumed internally after defaults are applied.
49
+ */
50
+ export interface NormalizedCacheModuleOptions {
51
+ isGlobal: boolean;
52
+ keyPrefix: string;
53
+ redis?: RedisCacheOptions;
54
+ store: 'memory' | 'redis' | CacheStore;
55
+ ttl: number;
56
+ httpKeyStrategy: CacheKeyStrategy;
57
+ principalScopeResolver: PrincipalScopeResolver | undefined;
58
+ }
59
+ /**
60
+ * Computes a cache key from the active interceptor context.
61
+ */
62
+ export type CacheKeyFactory = (context: InterceptorContext) => Awaitable<string>;
63
+ /**
64
+ * Accepted input for `@CacheKey(...)`.
65
+ */
66
+ export type CacheKeyDecoratorValue = string | CacheKeyFactory;
67
+ /**
68
+ * Computes one or more cache keys to evict after a successful handler write.
69
+ */
70
+ export type CacheEvictFactory = (context: InterceptorContext, value: unknown) => Awaitable<string | readonly string[]>;
71
+ /**
72
+ * Accepted input for `@CacheEvict(...)`.
73
+ */
74
+ export type CacheEvictDecoratorValue = string | readonly string[] | CacheEvictFactory;
75
+ /**
76
+ * Built-in or custom strategy used by `CacheInterceptor` when no `@CacheKey(...)` override is present.
77
+ */
78
+ export type CacheKeyStrategy = 'route' | 'route+query' | 'full' | ((context: InterceptorContext) => string);
79
+ export {};
80
+ //# sourceMappingURL=types.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"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"}
package/dist/types.js ADDED
@@ -0,0 +1 @@
1
+ export {};
package/package.json ADDED
@@ -0,0 +1,67 @@
1
+ {
2
+ "name": "@fluojs/cache-manager",
3
+ "description": "Decorator-driven HTTP response caching and standalone cache service for Fluo, with memory and Redis backends.",
4
+ "keywords": [
5
+ "fluo",
6
+ "cache",
7
+ "caching",
8
+ "http-cache",
9
+ "redis",
10
+ "memory-store",
11
+ "decorator"
12
+ ],
13
+ "version": "1.0.0-beta.1",
14
+ "private": false,
15
+ "license": "MIT",
16
+ "repository": {
17
+ "type": "git",
18
+ "url": "https://github.com/fluojs/fluo.git",
19
+ "directory": "packages/cache-manager"
20
+ },
21
+ "engines": {
22
+ "node": ">=20.0.0"
23
+ },
24
+ "publishConfig": {
25
+ "access": "public"
26
+ },
27
+ "type": "module",
28
+ "exports": {
29
+ ".": {
30
+ "types": "./dist/index.d.ts",
31
+ "import": "./dist/index.js"
32
+ }
33
+ },
34
+ "main": "./dist/index.js",
35
+ "types": "./dist/index.d.ts",
36
+ "files": [
37
+ "dist"
38
+ ],
39
+ "dependencies": {
40
+ "@fluojs/http": "^1.0.0-beta.1",
41
+ "@fluojs/core": "^1.0.0-beta.1",
42
+ "@fluojs/di": "^1.0.0-beta.1",
43
+ "@fluojs/runtime": "^1.0.0-beta.1"
44
+ },
45
+ "peerDependencies": {
46
+ "ioredis": "^5.0.0",
47
+ "@fluojs/redis": "^1.0.0-beta.1"
48
+ },
49
+ "peerDependenciesMeta": {
50
+ "@fluojs/redis": {
51
+ "optional": true
52
+ },
53
+ "ioredis": {
54
+ "optional": true
55
+ }
56
+ },
57
+ "devDependencies": {
58
+ "vitest": "^3.2.4"
59
+ },
60
+ "scripts": {
61
+ "prebuild": "node ../../tooling/scripts/clean-dist.mjs",
62
+ "build": "pnpm exec babel src --extensions .ts --ignore 'src/**/*.test.ts' --out-dir dist --config-file ../../tooling/babel/babel.config.cjs && pnpm exec tsc -p tsconfig.build.json",
63
+ "typecheck": "pnpm exec tsc -p tsconfig.json --noEmit",
64
+ "test": "pnpm exec vitest run -c vitest.config.ts",
65
+ "test:watch": "pnpm exec vitest -c vitest.config.ts"
66
+ }
67
+ }