From 599f0dc9d6ead6cdcecb3d05ceb0e99ae299a82b Mon Sep 17 00:00:00 2001 From: Manjot Virdi Date: Tue, 30 Jan 2024 16:26:05 -0800 Subject: [PATCH 1/6] remove redis4 code and tests; update readme --- README.md | 18 +-------------- src/adapters.ts | 41 ---------------------------------- src/cachified.spec.ts | 51 ------------------------------------------- 3 files changed, 1 insertion(+), 109 deletions(-) diff --git a/README.md b/README.md index a02ccaf..a52ead8 100644 --- a/README.md +++ b/README.md @@ -252,23 +252,7 @@ await cachified({ -```ts -import { createClient } from 'redis'; -import { cachified, redisCacheAdapter } from '@epic-web/cachified'; - -const redis = createClient({ - /* ...opts */ -}); -const cache = redisCacheAdapter(redis); - -await cachified({ - cache, - key: 'user-1', - getFreshValue() { - return 'user@example.org'; - }, -}); -``` +[cachified-redis-adapter](https://www.npmjs.com/package/cachified-redis-adapter) ### Adapter for [redis@3](https://www.npmjs.com/package/redis/v/3.1.2) diff --git a/src/adapters.ts b/src/adapters.ts index 47a79a4..93e1f6d 100644 --- a/src/adapters.ts +++ b/src/adapters.ts @@ -101,44 +101,3 @@ export function redis3CacheAdapter(redisCache: Redis3LikeCache): Cache { }, }; } - -export interface RedisLikeCache { - name?: string; - set( - key: string, - value: string, - options?: { EXAT: number }, - ): Promise; - get(key: string): Promise; - del(key: string): Promise; -} - -export function redisCacheAdapter(redisCache: RedisLikeCache): Cache { - return { - name: redisCache.name || 'Redis', - set(key, value) { - const ttl = totalTtl(value?.metadata); - const createdTime = value?.metadata?.createdTime; - - return redisCache.set( - key, - JSON.stringify(value), - ttl > 0 && ttl < Infinity && typeof createdTime === 'number' - ? { - EXAT: Math.ceil((ttl + createdTime) / 1000), - } - : undefined, - ); - }, - async get(key) { - const value = await redisCache.get(key); - if (value == null) { - return null; - } - return JSON.parse(value); - }, - delete(key) { - return redisCache.del(key); - }, - }; -} diff --git a/src/cachified.spec.ts b/src/cachified.spec.ts index 3bd796a..6591051 100644 --- a/src/cachified.spec.ts +++ b/src/cachified.spec.ts @@ -11,8 +11,6 @@ import { CacheEntry, lruCacheAdapter, redis3CacheAdapter, - redisCacheAdapter, - RedisLikeCache, GetFreshValue, createCacheEntry, } from './index'; @@ -1491,55 +1489,6 @@ describe('cachified', () => { }); }); - it('works with redis4 cache', async () => { - const set = jest.fn(); - const get = jest.fn(); - const del = jest.fn(); - const redis4: RedisLikeCache = { set, get, del }; - const cache = redisCacheAdapter(redis4); - - const ttlValue = await cachified({ - cache, - key: 'test-3', - ttl: 1, - getFreshValue() { - return 'FOUR'; - }, - }); - expect(ttlValue).toBe('FOUR'); - expect(get).toHaveBeenCalledTimes(1); - expect(get).toHaveBeenCalledWith('test-3'); - expect(set).toHaveBeenCalledTimes(1); - expect(set).toHaveBeenCalledWith('test-3', expect.any(String), { EXAT: 1 }); - expect(JSON.parse(set.mock.calls[0][1])).toEqual( - createCacheEntry('FOUR', { createdTime: 0, swr: 0, ttl: 1 }), - ); - - await cache.set('lel', undefined as any); - - get.mockImplementationOnce(() => - Promise.resolve( - JSON.stringify({ - metadata: { ttl: null, swr: 0, createdTime: 0 }, - value: 'FIVE', - }), - ), - ); - const nextValue = await cachified({ - cache, - key: 'test-3', - checkValue(value) { - return value !== 'FIVE'; - }, - getFreshValue() { - return 'SIX'; - }, - }); - expect(nextValue).toBe('SIX'); - expect(del).toHaveBeenCalledTimes(1); - expect(del).toHaveBeenCalledWith('test-3'); - }); - it('works with redis3 cache', async () => { const redis = createRedis3Client(); const cache = redis3CacheAdapter(redis); From b5166fd1a1cfc1f102f115b2d42098d570e28a01 Mon Sep 17 00:00:00 2001 From: Manjot Virdi Date: Tue, 30 Jan 2024 18:07:09 -0800 Subject: [PATCH 2/6] remove redis test --- src/readme.test.ts | 1 - 1 file changed, 1 deletion(-) diff --git a/src/readme.test.ts b/src/readme.test.ts index 704f38b..5a43cd0 100644 --- a/src/readme.test.ts +++ b/src/readme.test.ts @@ -11,7 +11,6 @@ import runFineTuneExample from '../examples/metadata-fine-tuning'; import runBatchExample from '../examples/batch-operations'; /* We just check that there are no ts errors in these */ -import runRedis4AdapterExample from '../examples/redis-adapter'; import runRedis3AdapterExample from '../examples/redis-3-adapter'; import runReporterExample from '../examples/verbose-reporter'; From 073bae2f4acd1b4cdb88012677ceb598fe679b4c Mon Sep 17 00:00:00 2001 From: Manjot Virdi Date: Wed, 31 Jan 2024 14:40:03 -0800 Subject: [PATCH 3/6] refactor: removed redis3 adapter code and from readme BREAKING CHANGE: remove redis adapter to external package --- README.md | 22 ----- package-lock.json | 218 ------------------------------------------ package.json | 3 - src/adapters.ts | 75 --------------- src/cachified.spec.ts | 103 -------------------- src/readme.test.ts | 1 - 6 files changed, 422 deletions(-) diff --git a/README.md b/README.md index a52ead8..7c79748 100644 --- a/README.md +++ b/README.md @@ -254,28 +254,6 @@ await cachified({ [cachified-redis-adapter](https://www.npmjs.com/package/cachified-redis-adapter) -### Adapter for [redis@3](https://www.npmjs.com/package/redis/v/3.1.2) - - - -```ts -import { createClient } from 'redis'; -import { cachified, redis3CacheAdapter } from '@epic-web/cachified'; - -const redis = createClient({ - /* ...opts */ -}); -const cache = redis3CacheAdapter(redis); - -const data = await cachified({ - cache, - key: 'user-1', - getFreshValue() { - return 'user@example.org'; - }, -}); -``` - ### Adapter for [Cloudflare KV](https://developers.cloudflare.com/kv/) For additional information or to report issues, please visit the [cachified-adapter-cloudflare-kv repository](https://github.com/AdiRishi/cachified-adapter-cloudflare-kv). diff --git a/package-lock.json b/package-lock.json index f3c5cad..331e80b 100644 --- a/package-lock.json +++ b/package-lock.json @@ -11,12 +11,9 @@ "devDependencies": { "@types/jest": "29.5.11", "@types/node": "20.10.7", - "@types/redis-mock": "0.17.3", "esbuild": "0.19.11", "jest": "29.7.0", "lru-cache": "10.1.0", - "redis-mock": "0.56.3", - "redis4": "npm:redis@4.6.12", "ts-jest": "29.1.1", "typescript": "5.3.3", "zod": "3.22.4" @@ -1367,65 +1364,6 @@ "@jridgewell/sourcemap-codec": "1.4.14" } }, - "node_modules/@redis/bloom": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/@redis/bloom/-/bloom-1.2.0.tgz", - "integrity": "sha512-HG2DFjYKbpNmVXsa0keLHp/3leGJz1mjh09f2RLGGLQZzSHpkmZWuwJbAvo3QcRY8p80m5+ZdXZdYOSBLlp7Cg==", - "dev": true, - "peerDependencies": { - "@redis/client": "^1.0.0" - } - }, - "node_modules/@redis/client": { - "version": "1.5.13", - "resolved": "https://registry.npmjs.org/@redis/client/-/client-1.5.13.tgz", - "integrity": "sha512-epkUM9D0Sdmt93/8Ozk43PNjLi36RZzG+d/T1Gdu5AI8jvghonTeLYV69WVWdilvFo+PYxbP0TZ0saMvr6nscQ==", - "dev": true, - "dependencies": { - "cluster-key-slot": "1.1.2", - "generic-pool": "3.9.0", - "yallist": "4.0.0" - }, - "engines": { - "node": ">=14" - } - }, - "node_modules/@redis/graph": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/@redis/graph/-/graph-1.1.1.tgz", - "integrity": "sha512-FEMTcTHZozZciLRl6GiiIB4zGm5z5F3F6a6FZCyrfxdKOhFlGkiAqlexWMBzCi4DcRoyiOsuLfW+cjlGWyExOw==", - "dev": true, - "peerDependencies": { - "@redis/client": "^1.0.0" - } - }, - "node_modules/@redis/json": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/@redis/json/-/json-1.0.6.tgz", - "integrity": "sha512-rcZO3bfQbm2zPRpqo82XbW8zg4G/w4W3tI7X8Mqleq9goQjAGLL7q/1n1ZX4dXEAmORVZ4s1+uKLaUOg7LrUhw==", - "dev": true, - "peerDependencies": { - "@redis/client": "^1.0.0" - } - }, - "node_modules/@redis/search": { - "version": "1.1.6", - "resolved": "https://registry.npmjs.org/@redis/search/-/search-1.1.6.tgz", - "integrity": "sha512-mZXCxbTYKBQ3M2lZnEddwEAks0Kc7nauire8q20oA0oA/LoA+E/b5Y5KZn232ztPb1FkIGqo12vh3Lf+Vw5iTw==", - "dev": true, - "peerDependencies": { - "@redis/client": "^1.0.0" - } - }, - "node_modules/@redis/time-series": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/@redis/time-series/-/time-series-1.0.5.tgz", - "integrity": "sha512-IFjIgTusQym2B5IZJG3XKr5llka7ey84fw/NOYqESP5WUfQs9zz1ww/9+qoz4ka/S6KcGBodzlCeZ5UImKbscg==", - "dev": true, - "peerDependencies": { - "@redis/client": "^1.0.0" - } - }, "node_modules/@sinclair/typebox": { "version": "0.27.8", "resolved": "https://registry.npmjs.org/@sinclair/typebox/-/typebox-0.27.8.tgz", @@ -1543,24 +1481,6 @@ "undici-types": "~5.26.4" } }, - "node_modules/@types/redis": { - "version": "2.8.32", - "resolved": "https://registry.npmjs.org/@types/redis/-/redis-2.8.32.tgz", - "integrity": "sha512-7jkMKxcGq9p242exlbsVzuJb57KqHRhNl4dHoQu2Y5v9bCAbtIXXH0R3HleSQW4CTOqpHIYUW3t6tpUj4BVQ+w==", - "dev": true, - "dependencies": { - "@types/node": "*" - } - }, - "node_modules/@types/redis-mock": { - "version": "0.17.3", - "resolved": "https://registry.npmjs.org/@types/redis-mock/-/redis-mock-0.17.3.tgz", - "integrity": "sha512-1baXyGxRKEDog8p1ReiypODwiST2n3/0pBbgUKEuv9pBXnY6ttRzKATcW5Xz20ZOl9qkKtPIeq20tHgHSdQBAQ==", - "dev": true, - "dependencies": { - "@types/redis": "^2.8.0" - } - }, "node_modules/@types/stack-utils": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/@types/stack-utils/-/stack-utils-2.0.1.tgz", @@ -1902,15 +1822,6 @@ "node": ">=12" } }, - "node_modules/cluster-key-slot": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/cluster-key-slot/-/cluster-key-slot-1.1.2.tgz", - "integrity": "sha512-RMr0FhtfXemyinomL4hrWcYJxmX6deFdCxpJzhDttxgO1+bcCnkk+9drydLVDmAMG7NE6aN/fl4F7ucU/90gAA==", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, "node_modules/co": { "version": "4.6.0", "resolved": "https://registry.npmjs.org/co/-/co-4.6.0.tgz", @@ -2269,15 +2180,6 @@ "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/generic-pool": { - "version": "3.9.0", - "resolved": "https://registry.npmjs.org/generic-pool/-/generic-pool-3.9.0.tgz", - "integrity": "sha512-hymDOu5B53XvN4QT9dBmZxPX4CWhBPPLguTZ9MMFeFa/Kg0xWVfylOVNlJji/E7yTZWFd/q9GO5TxDLq156D7g==", - "dev": true, - "engines": { - "node": ">= 4" - } - }, "node_modules/gensync": { "version": "1.0.0-beta.2", "resolved": "https://registry.npmjs.org/gensync/-/gensync-1.0.0-beta.2.tgz", @@ -3611,30 +3513,6 @@ "integrity": "sha512-xWGDIW6x921xtzPkhiULtthJHoJvBbF3q26fzloPCK0hsvxtPVelvftw3zjbHWSkR2km9Z+4uxbDDK/6Zw9B8w==", "dev": true }, - "node_modules/redis-mock": { - "version": "0.56.3", - "resolved": "https://registry.npmjs.org/redis-mock/-/redis-mock-0.56.3.tgz", - "integrity": "sha512-ynaJhqk0Qf3Qajnwvy4aOjS4Mdf9IBkELWtjd+NYhpiqu4QCNq6Vf3Q7c++XRPGiKiwRj9HWr0crcwy7EiPjYQ==", - "dev": true, - "engines": { - "node": ">=6" - } - }, - "node_modules/redis4": { - "name": "redis", - "version": "4.6.12", - "resolved": "https://registry.npmjs.org/redis/-/redis-4.6.12.tgz", - "integrity": "sha512-41Xuuko6P4uH4VPe5nE3BqXHB7a9lkFL0J29AlxKaIfD6eWO8VO/5PDF9ad2oS+mswMsfFxaM5DlE3tnXT+P8Q==", - "dev": true, - "dependencies": { - "@redis/bloom": "1.2.0", - "@redis/client": "1.5.13", - "@redis/graph": "1.1.1", - "@redis/json": "1.0.6", - "@redis/search": "1.1.6", - "@redis/time-series": "1.0.5" - } - }, "node_modules/require-directory": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz", @@ -5107,52 +4985,6 @@ "@jridgewell/sourcemap-codec": "1.4.14" } }, - "@redis/bloom": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/@redis/bloom/-/bloom-1.2.0.tgz", - "integrity": "sha512-HG2DFjYKbpNmVXsa0keLHp/3leGJz1mjh09f2RLGGLQZzSHpkmZWuwJbAvo3QcRY8p80m5+ZdXZdYOSBLlp7Cg==", - "dev": true, - "requires": {} - }, - "@redis/client": { - "version": "1.5.13", - "resolved": "https://registry.npmjs.org/@redis/client/-/client-1.5.13.tgz", - "integrity": "sha512-epkUM9D0Sdmt93/8Ozk43PNjLi36RZzG+d/T1Gdu5AI8jvghonTeLYV69WVWdilvFo+PYxbP0TZ0saMvr6nscQ==", - "dev": true, - "requires": { - "cluster-key-slot": "1.1.2", - "generic-pool": "3.9.0", - "yallist": "4.0.0" - } - }, - "@redis/graph": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/@redis/graph/-/graph-1.1.1.tgz", - "integrity": "sha512-FEMTcTHZozZciLRl6GiiIB4zGm5z5F3F6a6FZCyrfxdKOhFlGkiAqlexWMBzCi4DcRoyiOsuLfW+cjlGWyExOw==", - "dev": true, - "requires": {} - }, - "@redis/json": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/@redis/json/-/json-1.0.6.tgz", - "integrity": "sha512-rcZO3bfQbm2zPRpqo82XbW8zg4G/w4W3tI7X8Mqleq9goQjAGLL7q/1n1ZX4dXEAmORVZ4s1+uKLaUOg7LrUhw==", - "dev": true, - "requires": {} - }, - "@redis/search": { - "version": "1.1.6", - "resolved": "https://registry.npmjs.org/@redis/search/-/search-1.1.6.tgz", - "integrity": "sha512-mZXCxbTYKBQ3M2lZnEddwEAks0Kc7nauire8q20oA0oA/LoA+E/b5Y5KZn232ztPb1FkIGqo12vh3Lf+Vw5iTw==", - "dev": true, - "requires": {} - }, - "@redis/time-series": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/@redis/time-series/-/time-series-1.0.5.tgz", - "integrity": "sha512-IFjIgTusQym2B5IZJG3XKr5llka7ey84fw/NOYqESP5WUfQs9zz1ww/9+qoz4ka/S6KcGBodzlCeZ5UImKbscg==", - "dev": true, - "requires": {} - }, "@sinclair/typebox": { "version": "0.27.8", "resolved": "https://registry.npmjs.org/@sinclair/typebox/-/typebox-0.27.8.tgz", @@ -5270,24 +5102,6 @@ "undici-types": "~5.26.4" } }, - "@types/redis": { - "version": "2.8.32", - "resolved": "https://registry.npmjs.org/@types/redis/-/redis-2.8.32.tgz", - "integrity": "sha512-7jkMKxcGq9p242exlbsVzuJb57KqHRhNl4dHoQu2Y5v9bCAbtIXXH0R3HleSQW4CTOqpHIYUW3t6tpUj4BVQ+w==", - "dev": true, - "requires": { - "@types/node": "*" - } - }, - "@types/redis-mock": { - "version": "0.17.3", - "resolved": "https://registry.npmjs.org/@types/redis-mock/-/redis-mock-0.17.3.tgz", - "integrity": "sha512-1baXyGxRKEDog8p1ReiypODwiST2n3/0pBbgUKEuv9pBXnY6ttRzKATcW5Xz20ZOl9qkKtPIeq20tHgHSdQBAQ==", - "dev": true, - "requires": { - "@types/redis": "^2.8.0" - } - }, "@types/stack-utils": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/@types/stack-utils/-/stack-utils-2.0.1.tgz", @@ -5540,12 +5354,6 @@ "wrap-ansi": "^7.0.0" } }, - "cluster-key-slot": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/cluster-key-slot/-/cluster-key-slot-1.1.2.tgz", - "integrity": "sha512-RMr0FhtfXemyinomL4hrWcYJxmX6deFdCxpJzhDttxgO1+bcCnkk+9drydLVDmAMG7NE6aN/fl4F7ucU/90gAA==", - "dev": true - }, "co": { "version": "4.6.0", "resolved": "https://registry.npmjs.org/co/-/co-4.6.0.tgz", @@ -5810,12 +5618,6 @@ "integrity": "sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==", "dev": true }, - "generic-pool": { - "version": "3.9.0", - "resolved": "https://registry.npmjs.org/generic-pool/-/generic-pool-3.9.0.tgz", - "integrity": "sha512-hymDOu5B53XvN4QT9dBmZxPX4CWhBPPLguTZ9MMFeFa/Kg0xWVfylOVNlJji/E7yTZWFd/q9GO5TxDLq156D7g==", - "dev": true - }, "gensync": { "version": "1.0.0-beta.2", "resolved": "https://registry.npmjs.org/gensync/-/gensync-1.0.0-beta.2.tgz", @@ -6811,26 +6613,6 @@ "integrity": "sha512-xWGDIW6x921xtzPkhiULtthJHoJvBbF3q26fzloPCK0hsvxtPVelvftw3zjbHWSkR2km9Z+4uxbDDK/6Zw9B8w==", "dev": true }, - "redis-mock": { - "version": "0.56.3", - "resolved": "https://registry.npmjs.org/redis-mock/-/redis-mock-0.56.3.tgz", - "integrity": "sha512-ynaJhqk0Qf3Qajnwvy4aOjS4Mdf9IBkELWtjd+NYhpiqu4QCNq6Vf3Q7c++XRPGiKiwRj9HWr0crcwy7EiPjYQ==", - "dev": true - }, - "redis4": { - "version": "npm:redis@4.6.12", - "resolved": "https://registry.npmjs.org/redis/-/redis-4.6.12.tgz", - "integrity": "sha512-41Xuuko6P4uH4VPe5nE3BqXHB7a9lkFL0J29AlxKaIfD6eWO8VO/5PDF9ad2oS+mswMsfFxaM5DlE3tnXT+P8Q==", - "dev": true, - "requires": { - "@redis/bloom": "1.2.0", - "@redis/client": "1.5.13", - "@redis/graph": "1.1.1", - "@redis/json": "1.0.6", - "@redis/search": "1.1.6", - "@redis/time-series": "1.0.5" - } - }, "require-directory": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz", diff --git a/package.json b/package.json index 49378d5..428d6c5 100644 --- a/package.json +++ b/package.json @@ -48,12 +48,9 @@ "devDependencies": { "@types/jest": "29.5.11", "@types/node": "20.10.7", - "@types/redis-mock": "0.17.3", "esbuild": "0.19.11", "jest": "29.7.0", "lru-cache": "10.1.0", - "redis-mock": "0.56.3", - "redis4": "npm:redis@4.6.12", "ts-jest": "29.1.1", "typescript": "5.3.3", "zod": "3.22.4" diff --git a/src/adapters.ts b/src/adapters.ts index 93e1f6d..e01167e 100644 --- a/src/adapters.ts +++ b/src/adapters.ts @@ -26,78 +26,3 @@ export function lruCacheAdapter(lruCache: LRUishCache): Cache { }, }; } - -interface Redis3Multi { - set(key: string, value: string): Redis3Multi; - expireat(key: string, timestamp: number): Redis3Multi; - exec(cb: (err: Error | null, replies: (number | 'OK')[]) => void): unknown; -} -export interface Redis3LikeCache { - name?: string; - set( - key: string, - value: string, - cb: (err: Error | null, reply: 'OK') => void, - ): unknown; - get( - key: string, - cb?: (err: Error | null, reply: string | null) => void, - ): unknown; - del(key: string, cb?: (err: Error | null, reply: number) => void): unknown; - multi(): Redis3Multi; -} - -export function redis3CacheAdapter(redisCache: Redis3LikeCache): Cache { - return { - name: redisCache.name || 'Redis3', - set(key, value) { - return new Promise((res, rej) => { - const ttl = totalTtl(value?.metadata); - const createdTime = value?.metadata?.createdTime; - const cb = (err: unknown) => { - if (err) { - return rej(err); - } - res(); - }; - - if (ttl > 0 && ttl < Infinity && typeof createdTime === 'number') { - redisCache - .multi() - .set(key, JSON.stringify(value)) - .expireat(key, (ttl + createdTime) / 1000) - .exec(cb); - } else { - redisCache.set(key, JSON.stringify(value), cb); - } - }); - }, - get(key) { - return new Promise((res, rej) => { - redisCache.get(key, (err, reply) => { - if (err) { - rej(err); - } else if (reply == null) { - res(null); - } else { - try { - res(JSON.parse(reply)); - } catch (err) { - rej(err); - } - } - }); - }); - }, - delete(key) { - return new Promise((res, rej) => { - redisCache.del(key, (err) => { - if (err) { - rej(err); - } - res(); - }); - }); - }, - }; -} diff --git a/src/cachified.spec.ts b/src/cachified.spec.ts index 6591051..f56acc6 100644 --- a/src/cachified.spec.ts +++ b/src/cachified.spec.ts @@ -1,5 +1,4 @@ import { LRUCache } from 'lru-cache'; -import { createClient as createRedis3Client } from 'redis-mock'; import z from 'zod'; import { cachified, @@ -10,7 +9,6 @@ import { CacheMetadata, CacheEntry, lruCacheAdapter, - redis3CacheAdapter, GetFreshValue, createCacheEntry, } from './index'; @@ -1488,107 +1486,6 @@ describe('cachified', () => { value: 'THREE', }); }); - - it('works with redis3 cache', async () => { - const redis = createRedis3Client(); - const cache = redis3CacheAdapter(redis); - - const value = await cachified({ - cache, - key: 'test', - getFreshValue() { - return 'ONE'; - }, - }); - - expect(value).toBe('ONE'); - - await cache.set('test-2', 'TWO' as any); - expect(() => cache.set('test-2', undefined as any)).rejects.toThrow(); - - currentTime = 2; - const value3 = await cachified({ - cache, - key: 'test-2', - getFreshValue() { - return 'THREE'; - }, - }); - expect(value3).toBe('THREE'); - expect(await cache.get('test-2')).toEqual({ - metadata: { createdTime: 2, swr: 0, ttl: null }, - value: 'THREE', - }); - - // handle redis get failure - jest.spyOn(redis, 'get').mockImplementationOnce((_, cb) => { - cb!(new Error('Nope'), null); - return false; - }); - await expect(() => - cachified({ - cache, - key: 'test-2', - getFreshValue() { - throw new Error('Nope Nope Nope'); - }, - }), - ).rejects.toThrowErrorMatchingInlineSnapshot(`"Nope Nope Nope"`); - - // handle redis del failure - jest.spyOn(redis, 'del').mockImplementationOnce((_, cb) => { - (cb as Function)(new Error('Nope2'), null); - return false; - }); - expect(cache.delete('test-0')).rejects.toThrowErrorMatchingInlineSnapshot( - `"Nope2"`, - ); - - // handle corrupt cache - await new Promise((res) => redis.set('test-3', '{{{', res)); - await expect(() => - cachified({ - cache, - key: 'test-2', - getFreshValue() { - throw new Error('Broken'); - }, - }), - ).rejects.toThrowErrorMatchingInlineSnapshot(`"Broken"`); - - // value is cleared from cache after ttl - const ttlValue = await cachified({ - cache, - key: 'test-3', - ttl: 1, - getFreshValue() { - return 'FOUR'; - }, - }); - expect(ttlValue).toBe('FOUR'); - - await delay(2); - expect(await cache.get('test-3')).toBe(null); - - // handles delete fails - jest.spyOn(redis, 'del').mockImplementationOnce((key, cb) => { - (cb as Function)(new Error('Nope')); - return false; - }); - - await expect(() => - cachified({ - cache, - checkValue() { - return false; - }, - key: 'test', - getFreshValue() { - throw new Error('Boom'); - }, - }), - ).rejects.toThrowErrorMatchingInlineSnapshot(`"Boom"`); - }); }); function createReporter() { diff --git a/src/readme.test.ts b/src/readme.test.ts index 5a43cd0..e043331 100644 --- a/src/readme.test.ts +++ b/src/readme.test.ts @@ -11,7 +11,6 @@ import runFineTuneExample from '../examples/metadata-fine-tuning'; import runBatchExample from '../examples/batch-operations'; /* We just check that there are no ts errors in these */ -import runRedis3AdapterExample from '../examples/redis-3-adapter'; import runReporterExample from '../examples/verbose-reporter'; import { createCacheEntry } from './common'; From ecf28dbccda796bb672332c06309b7680c9f0062 Mon Sep 17 00:00:00 2001 From: Manjot Virdi Date: Sat, 3 Feb 2024 15:30:38 -0800 Subject: [PATCH 4/6] remove all adapters and related tests; remove readme example tests --- README.md | 122 ++++++++----------------- extractExamples.js | 68 -------------- package-lock.json | 16 ---- package.json | 7 +- src/adapters.ts | 28 ------ src/cachified.spec.ts | 45 --------- src/index.ts | 1 - src/readme.test.ts | 207 ------------------------------------------ 8 files changed, 38 insertions(+), 456 deletions(-) delete mode 100644 extractExamples.js delete mode 100644 src/adapters.ts delete mode 100644 src/readme.test.ts diff --git a/README.md b/README.md index 7c79748..4f33aca 100644 --- a/README.md +++ b/README.md @@ -52,10 +52,40 @@ npm install @epic-web/cachified ```ts import { LRUCache } from 'lru-cache'; -import { cachified, CacheEntry } from '@epic-web/cachified'; +import { cachified, CacheEntry, Cache, totalTtl } from '@epic-web/cachified'; /* lru cache is not part of this package but a simple non-persistent cache */ -const lru = new LRUCache({ max: 1000 }); +const lruInstance = new LRUCache({ max: 1000 }); + +/* defines options for the set method for lru cache */ +interface LRUishCache extends Omit { + set( + key: string, + value: CacheEntry, + options?: { ttl?: number; start?: number }, + ): void; +} + +/* creates a wrapper for the lru cache so that it can easily work with cachified and ensures the lru cache cleans up outdated values itself*/ +function lruCacheAdapter(lruCache: LRUishCache): Cache { + return { + set(key, value) { + const ttl = totalTtl(value?.metadata); + return lruCache.set(key, value, { + ttl: ttl === Infinity ? undefined : ttl, + start: value?.metadata?.createdTime, + }); + }, + get(key) { + return lruCache.get(key); + }, + delete(key) { + return lruCache.delete(key); + }, + }; +} + +const lru = lruCacheAdapter(lruInstance); function getUserById(userId: number) { return cachified({ @@ -225,91 +255,11 @@ interface CachifiedOptions { ## Adapters -There are some build-in adapters for common caches, using them makes sure -the used caches cleanup outdated values themselves. - -### Adapter for [lru-cache](https://www.npmjs.com/package/lru-cache) - - - -```ts -import { LRUCache } from 'lru-cache'; -import { cachified, lruCacheAdapter, CacheEntry } from '@epic-web/cachified'; - -const lru = new LRUCache({ max: 1000 }); -const cache = lruCacheAdapter(lru); - -await cachified({ - cache, - key: 'user-1', - getFreshValue() { - return 'user@example.org'; - }, -}); -``` - -### Adapter for [redis](https://www.npmjs.com/package/redis) - - - -[cachified-redis-adapter](https://www.npmjs.com/package/cachified-redis-adapter) - -### Adapter for [Cloudflare KV](https://developers.cloudflare.com/kv/) - -For additional information or to report issues, please visit the [cachified-adapter-cloudflare-kv repository](https://github.com/AdiRishi/cachified-adapter-cloudflare-kv). - -```ts -import { cachified, Cache } from '@epic-web/cachified'; -import { cloudflareKvCacheAdapter } from 'cachified-adapter-cloudflare-kv'; - -export interface Env { - KV: KVNamespace; - CACHIFIED_KV_CACHE: Cache; -} - -export async function getUserById( - userId: number, - env: Env, -): Promise> { - return cachified({ - key: `user-${userId}`, - cache: env.CACHIFIED_KV_CACHE, - async getFreshValue() { - const response = await fetch( - `https://jsonplaceholder.typicode.com/users/${userId}`, - ); - return response.json(); - }, - ttl: 60_000, // 1 minute - staleWhileRevalidate: 300_000, // 5 minutes - }); -} - -export default { - async fetch( - request: Request, - env: Env, - ctx: ExecutionContext, - ): Promise { - env.CACHIFIED_KV_CACHE = cloudflareKvCacheAdapter({ - kv: env.KV, - keyPrefix: 'mycache', // optional - name: 'CloudflareKV', // optional - }); - const userId = Math.floor(Math.random() * 10) + 1; - const user = await getUserById(userId, env); - return new Response(JSON.stringify(user), { - headers: { - 'Content-Type': 'application/json', - }, - }); - }, -}; -``` - -### Adapter for [redis-json](https://www.npmjs.com/package/@redis/json) +There are some adapters available for common caches. Using them makes sure the used caches cleanup outdated values themselves. -[cachified-redis-json-adapter](https://www.npmjs.com/package/cachified-redis-json-adapter) +- Adapter for [redis](https://www.npmjs.com/package/redis) : [cachified-redis-adapter](https://www.npmjs.com/package/cachified-redis-adapter) +- Adapter for [redis-json](https://www.npmjs.com/package/@redis/json) : [cachified-redis-json-adapter](https://www.npmjs.com/package/cachified-redis-json-adapter) +- Adapter for [Cloudflare KV](https://developers.cloudflare.com/kv/) : [cachified-adapter-cloudflare-kv repository](https://github.com/AdiRishi/cachified-adapter-cloudflare-kv) ## Advanced Usage diff --git a/extractExamples.js b/extractExamples.js deleted file mode 100644 index d8322ec..0000000 --- a/extractExamples.js +++ /dev/null @@ -1,68 +0,0 @@ -const fs = require('fs'); - -try { - fs.rmSync('./examples', { recursive: true }); -} catch { - // ¯\_(ツ)_/¯ -} -fs.mkdirSync('./examples'); - -const TICK = ' await new Promise((resolve) => setTimeout(resolve, 0));'; - -const codeBlocks = fs - .readFileSync('./README.md', 'utf8') - .matchAll(/()?\n*```ts(?(.|\n)*?)```/gm); - -Array.from(codeBlocks).forEach(({ groups }, index) => { - const id = groups?.id?.trim()?.replace(/\s/g, '-') || `example-${index}`; - const code = groups?.code.trim(); - if (id === 'ignore' || !code) { - return; - } - - const importRegex = - /^import\s+(?:{[^}]*}|[\w*]+)\s+from\s+['"][^'"]+['"];\s*$/gm; - let imports = - code - .match(importRegex) - ?.join('\n') - .replace( - /from ('|")@epic-web\/cachified('|");/, - 'from $1../src/index$2;', - ) || ''; - - if (index === 3) { - imports = imports.replace(/from ('|")redis('|");/, 'from $1redis4$2;'); - } - - let restOfTheCode = code - .replace(importRegex, '') - .trim() - .replace(/\n/gm, '\n ') - .replace( - /\/\/ (\d+) seconds? later/gm, - (_, seconds) => `time.current += ${seconds} * 1000;\n${TICK}`, - ) - .replace( - /\/\/ (\d+) minutes? later/gm, - (_, minutes) => `time.current += ${minutes} * 60_000;\n${TICK}`, - ); - - fs.writeFileSync( - `./examples/${id}.ts`, - `${imports} -interface Opts { - console?: Console; - fetch?: typeof global.fetch; - time?: { current: number }; -} -export default async function run({ - console = global.console, - fetch = global.fetch, - time = { current: 0 }, -}: Opts = {}) { - ${restOfTheCode} - ${restOfTheCode.includes('const cache =') ? 'return cache' : ''} -}`, - ); -}); diff --git a/package-lock.json b/package-lock.json index 331e80b..f15afde 100644 --- a/package-lock.json +++ b/package-lock.json @@ -13,7 +13,6 @@ "@types/node": "20.10.7", "esbuild": "0.19.11", "jest": "29.7.0", - "lru-cache": "10.1.0", "ts-jest": "29.1.1", "typescript": "5.3.3", "zod": "3.22.4" @@ -3136,15 +3135,6 @@ "integrity": "sha512-t7j+NzmgnQzTAYXcsHYLgimltOV1MXHtlOWf6GjL9Kj8GK5FInw5JotxvbOs+IvV1/Dzo04/fCGfLVs7aXb4Ag==", "dev": true }, - "node_modules/lru-cache": { - "version": "10.1.0", - "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-10.1.0.tgz", - "integrity": "sha512-/1clY/ui8CzjKFyjdvwPWJUYKiFVXG2I2cY0ssG7h4+hwk+XOIX7ZSG9Q7TW8TW3Kp3BUSqgFWBLgL4PJ+Blag==", - "dev": true, - "engines": { - "node": "14 || >=16.14" - } - }, "node_modules/make-dir": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-4.0.0.tgz", @@ -6336,12 +6326,6 @@ "integrity": "sha512-t7j+NzmgnQzTAYXcsHYLgimltOV1MXHtlOWf6GjL9Kj8GK5FInw5JotxvbOs+IvV1/Dzo04/fCGfLVs7aXb4Ag==", "dev": true }, - "lru-cache": { - "version": "10.1.0", - "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-10.1.0.tgz", - "integrity": "sha512-/1clY/ui8CzjKFyjdvwPWJUYKiFVXG2I2cY0ssG7h4+hwk+XOIX7ZSG9Q7TW8TW3Kp3BUSqgFWBLgL4PJ+Blag==", - "dev": true - }, "make-dir": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-4.0.0.tgz", diff --git a/package.json b/package.json index 428d6c5..1f25df3 100644 --- a/package.json +++ b/package.json @@ -18,12 +18,10 @@ "scripts": { "prepare": "rm -rf dist && npm run build", "build": "npm run build:declarations && npm run build:esm && npm run build:cjs", - "build:declarations": "tsc && rm dist/src/*.spec.d.ts; rm -rf dist/examples && rm dist/src/testHelpers.d.ts", + "build:declarations": "tsc && rm dist/src/*.spec.d.ts; && rm dist/src/testHelpers.d.ts", "build:esm": "esbuild src/index.ts --outfile=dist/index.mjs --format=esm --bundle --target=es2020 --sourcemap --minify", "build:cjs": "esbuild src/index.ts --outfile=dist/index.cjs --format=cjs --bundle --target=es2016 --sourcemap", - "test": "jest", - "pretest": "node ./extractExamples.js", - "prebuild": "node ./extractExamples.js" + "test": "jest" }, "repository": { "type": "git", @@ -50,7 +48,6 @@ "@types/node": "20.10.7", "esbuild": "0.19.11", "jest": "29.7.0", - "lru-cache": "10.1.0", "ts-jest": "29.1.1", "typescript": "5.3.3", "zod": "3.22.4" diff --git a/src/adapters.ts b/src/adapters.ts deleted file mode 100644 index e01167e..0000000 --- a/src/adapters.ts +++ /dev/null @@ -1,28 +0,0 @@ -import { Cache, CacheEntry, totalTtl } from './common'; - -export interface LRUishCache extends Omit { - set( - key: string, - value: CacheEntry, - options?: { ttl?: number; start?: number }, - ): void; -} - -export function lruCacheAdapter(lruCache: LRUishCache): Cache { - return { - name: lruCache.name || 'LRU', - set(key, value) { - const ttl = totalTtl(value?.metadata); - return lruCache.set(key, value, { - ttl: ttl === Infinity ? undefined : ttl, - start: value?.metadata?.createdTime, - }); - }, - get(key) { - return lruCache.get(key); - }, - delete(key) { - return lruCache.delete(key); - }, - }; -} diff --git a/src/cachified.spec.ts b/src/cachified.spec.ts index f56acc6..03960d0 100644 --- a/src/cachified.spec.ts +++ b/src/cachified.spec.ts @@ -1,4 +1,3 @@ -import { LRUCache } from 'lru-cache'; import z from 'zod'; import { cachified, @@ -8,7 +7,6 @@ import { CreateReporter, CacheMetadata, CacheEntry, - lruCacheAdapter, GetFreshValue, createCacheEntry, } from './index'; @@ -1443,49 +1441,6 @@ describe('cachified', () => { }); expect(await getValue(() => () => {})).toBe('FOUR'); }); - - it('works with LRU cache', async () => { - const lru = new LRUCache({ max: 5 }); - const cache = lruCacheAdapter(lru); - - const value = await cachified({ - // works with LRU directly - cache: lru, - key: 'test', - getFreshValue() { - return 'ONE'; - }, - }); - - const value2 = await cachified({ - cache, - key: 'test', - getFreshValue() { - throw new Error('🚧'); - }, - }); - - expect(value).toBe('ONE'); - expect(value2).toBe('ONE'); - - cache.set('test-2', undefined as any); - cache.set('test-2', 'TWO' as any); - - currentTime = 2; - const value3 = await cachified({ - cache, - key: 'test-2', - getFreshValue() { - return 'THREE'; - }, - }); - - expect(value3).toBe('THREE'); - expect(cache.get('test-2')).toEqual({ - metadata: { createdTime: 2, swr: 0, ttl: null }, - value: 'THREE', - }); - }); }); function createReporter() { diff --git a/src/index.ts b/src/index.ts index 1522023..d65ddcd 100644 --- a/src/index.ts +++ b/src/index.ts @@ -9,7 +9,6 @@ export type { } from './common'; export { staleWhileRevalidate, totalTtl, createCacheEntry } from './common'; export * from './reporter'; -export * from './adapters'; export { createBatch } from './createBatch'; export { cachified } from './cachified'; export { cachified as default } from './cachified'; diff --git a/src/readme.test.ts b/src/readme.test.ts deleted file mode 100644 index e043331..0000000 --- a/src/readme.test.ts +++ /dev/null @@ -1,207 +0,0 @@ -import runIntroExample from '../examples/usage-intro'; -import runLruAdapterExample from '../examples/lru-adapter'; -import runStaleWhileRevalidateExample from '../examples/stale-while-revalidate'; -import runForceFreshExample from '../examples/force-fresh'; -import runTypeSafetyExample from '../examples/type-safety'; -import runTypeSafetyZodExample from '../examples/type-safety-zod'; -import runManualExample from '../examples/manual-cache-interactions'; -import runMigrateExample from '../examples/migrating-values'; -import runSoftPurgeExample from '../examples/soft-purge'; -import runFineTuneExample from '../examples/metadata-fine-tuning'; -import runBatchExample from '../examples/batch-operations'; - -/* We just check that there are no ts errors in these */ -import runReporterExample from '../examples/verbose-reporter'; - -import { createCacheEntry } from './common'; - -let time = { current: 0 }; -beforeEach(() => { - time.current = 0; - jest.spyOn(Date, 'now').mockImplementation(() => time.current); -}); - -describe('readme', () => { - test('intro', async () => { - const console = createConsole(); - const fetch = createCountingFetch(); - await runIntroExample({ console, fetch, time }); - - expect(fetch).toHaveBeenCalledTimes(2); - expect(console.log).toHaveBeenCalledTimes(3); - expect(console.log).toHaveBeenNthCalledWith(1, fetchCallNr(0)); - expect(console.log).toHaveBeenNthCalledWith(2, fetchCallNr(0)); - expect(console.log).toHaveBeenNthCalledWith(3, fetchCallNr(1)); - }); - - test('lru-adapter', async () => { - const cache = await runLruAdapterExample(); - - expect(cache.get('user-1')).toEqual(createCacheEntry('user@example.org')); - }); - - test('stale-while-revalidate', async () => { - const console = createConsole(); - const fetch = createCountingFetch(); - await runStaleWhileRevalidateExample({ console, fetch, time }); - - expect(fetch).toHaveBeenCalledTimes(2); - expect(console.log).toHaveBeenCalledTimes(4); - expect(console.log).toHaveBeenNthCalledWith(1, fetchCallNr(0)); - expect(console.log).toHaveBeenNthCalledWith(2, fetchCallNr(0)); - expect(console.log).toHaveBeenNthCalledWith(3, fetchCallNr(0)); - expect(console.log).toHaveBeenNthCalledWith(4, fetchCallNr(1)); - }); - - test('force-fresh', async () => { - const console = createConsole(); - const fetch = createCountingFetch(); - await runForceFreshExample({ console, fetch, time }); - - expect(fetch).toHaveBeenCalledTimes(2); - expect(console.log).toHaveBeenCalledTimes(2); - expect(console.log).toHaveBeenNthCalledWith(1, fetchCallNr(0)); - expect(console.log).toHaveBeenNthCalledWith(2, fetchCallNr(1)); - }); - - test('type-safety', async () => { - const console = createConsole(); - const fetch = createCountingFetch(); - await runTypeSafetyExample({ console, time, fetch }); - - expect(fetch).toHaveBeenCalledTimes(1); - expect(console.log).toHaveBeenCalledTimes(2); - expect(console.log).toHaveBeenNthCalledWith(1, fetchCallNr(0)); - expect(console.log).toHaveBeenNthCalledWith(2, fetchCallNr(0)); - }); - - test('type-safety-zod', async () => { - const console = createConsole(); - const fetch = createCountingFetch(); - await runTypeSafetyZodExample({ console, time, fetch }); - - expect(fetch).toHaveBeenCalledTimes(1); - expect(console.log).toHaveBeenCalledTimes(2); - expect(console.log).toHaveBeenNthCalledWith(1, fetchCallNr(0)); - expect(console.log).toHaveBeenNthCalledWith(2, fetchCallNr(0)); - }); - - test('manual-working', async () => { - const console = createConsole(); - const cache = await runManualExample({ console, time }); - - expect(console.log).toHaveBeenCalledTimes(2); - expect(console.log).toHaveBeenNthCalledWith(1, 'someone@example.org'); - expect(console.log).toHaveBeenNthCalledWith(2, 'someone@example.org'); - - expect(cache.size).toBe(0); - }); - - test('migrating', async () => { - const console = createConsole(); - await runMigrateExample({ console, time }); - - expect(console.log).toHaveBeenCalledTimes(2); - expect(console.log).toHaveBeenNthCalledWith(1, { - email: 'someone@example.org', - }); - expect(console.log).toHaveBeenNthCalledWith(2, { - email: 'someone@example.org', - }); - }); - - test('soft-purge', async () => { - const console = createConsole(); - const fetch = createCountingFetch(); - await runSoftPurgeExample({ console, time, fetch }); - - expect(fetch).toHaveBeenCalledTimes(3); - expect(console.log).toHaveBeenCalledTimes(4); - expect(console.log).toHaveBeenNthCalledWith(1, fetchCallNr(0)); - expect(console.log).toHaveBeenNthCalledWith(2, fetchCallNr(0)); - expect(console.log).toHaveBeenNthCalledWith(3, fetchCallNr(1)); - expect(console.log).toHaveBeenNthCalledWith(4, fetchCallNr(2)); - }); - - test('fine-tune', async () => { - const cache = await runFineTuneExample({ - fetch: (() => { - return Promise.resolve({ - json() { - return null; - }, - }); - }) as any as typeof global.fetch, - }); - - expect(cache.size).toBe(0); - }); - - test('batch', async () => { - const console = createConsole(); - let i = 0; - const fetch = jest.fn((url: string) => { - const params = new URL(url).searchParams; - const ids = params.get('ids')!.split(','); - const callId = i++; - - return Promise.resolve({ - json() { - const data = ids.map((id) => ({ - email: `hi-${id}-${callId}@example.org`, - username: 'asd', - })); - - return Promise.resolve(data); - }, - }); - }) as any as typeof global.fetch; - await runBatchExample({ console, time, fetch }); - - expect(fetch).toHaveBeenCalledTimes(2); - expect(console.log).toHaveBeenCalledTimes(2); - expect(console.log).toHaveBeenNthCalledWith(1, [ - expect.objectContaining({ - email: `hi-1-0@example.org`, - }), - expect.objectContaining({ - email: `hi-2-0@example.org`, - }), - ]); - expect(console.log).toHaveBeenNthCalledWith(2, [ - expect.objectContaining({ - email: `hi-2-0@example.org`, - }), - expect.objectContaining({ - email: `hi-3-1@example.org`, - }), - ]); - }); -}); - -function fetchCallNr(i: number) { - return expect.objectContaining({ - email: `hi-${i}@example.org`, - }); -} - -function createConsole() { - return { - ...console, - log: jest.fn(), - }; -} - -function createCountingFetch() { - let i = 0; - return jest.fn(() => { - return Promise.resolve({ - json() { - return Promise.resolve({ - email: `hi-${i++}@example.org`, - username: 'asd', - }); - }, - }); - }) as any as typeof global.fetch; -} From a0c1536fdf4ff325d56071fdd57a623cc9c3140d Mon Sep 17 00:00:00 2001 From: Manjot Virdi <123426666+mannyv123@users.noreply.github.com> Date: Tue, 6 Feb 2024 13:54:22 -0800 Subject: [PATCH 5/6] Update readme usage example (#2) --- README.md | 43 +++++++++++++------------------------------ 1 file changed, 13 insertions(+), 30 deletions(-) diff --git a/README.md b/README.md index 4f33aca..2ce9619 100644 --- a/README.md +++ b/README.md @@ -52,40 +52,23 @@ npm install @epic-web/cachified ```ts import { LRUCache } from 'lru-cache'; -import { cachified, CacheEntry, Cache, totalTtl } from '@epic-web/cachified'; +import { cachified, CacheEntry, Cache } from '@epic-web/cachified'; /* lru cache is not part of this package but a simple non-persistent cache */ const lruInstance = new LRUCache({ max: 1000 }); -/* defines options for the set method for lru cache */ -interface LRUishCache extends Omit { - set( - key: string, - value: CacheEntry, - options?: { ttl?: number; start?: number }, - ): void; -} - -/* creates a wrapper for the lru cache so that it can easily work with cachified and ensures the lru cache cleans up outdated values itself*/ -function lruCacheAdapter(lruCache: LRUishCache): Cache { - return { - set(key, value) { - const ttl = totalTtl(value?.metadata); - return lruCache.set(key, value, { - ttl: ttl === Infinity ? undefined : ttl, - start: value?.metadata?.createdTime, - }); - }, - get(key) { - return lruCache.get(key); - }, - delete(key) { - return lruCache.delete(key); - }, - }; -} - -const lru = lruCacheAdapter(lruInstance); +const lru: Cache = { + /* Note that value here exposes metadata that includes things such as ttl and createdTime */ + set(key, value) { + return lruInstance.set(key, value); + }, + get(key) { + return lruInstance.get(key); + }, + delete(key) { + return lruInstance.delete(key); + }, +}; function getUserById(userId: number) { return cachified({ From c0125675170412bc851ea211e742d601093650d1 Mon Sep 17 00:00:00 2001 From: Manjot Virdi Date: Wed, 7 Feb 2024 10:01:46 -0800 Subject: [PATCH 6/6] update readme usage example with ttl --- README.md | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index 2ce9619..0d07d08 100644 --- a/README.md +++ b/README.md @@ -52,15 +52,18 @@ npm install @epic-web/cachified ```ts import { LRUCache } from 'lru-cache'; -import { cachified, CacheEntry, Cache } from '@epic-web/cachified'; +import { cachified, CacheEntry, Cache, totalTtl } from '@epic-web/cachified'; /* lru cache is not part of this package but a simple non-persistent cache */ const lruInstance = new LRUCache({ max: 1000 }); const lru: Cache = { - /* Note that value here exposes metadata that includes things such as ttl and createdTime */ set(key, value) { - return lruInstance.set(key, value); + const ttl = totalTtl(value?.metadata); + return lruInstance.set(key, value, { + ttl: ttl === Infinity ? undefined : ttl, + start: value?.metadata?.createdTime, + }); }, get(key) { return lruInstance.get(key);