From 817f19530a30fc119d57c66c1d290d8289a87a18 Mon Sep 17 00:00:00 2001 From: Steven Roebert Date: Mon, 7 Oct 2024 10:58:12 +0200 Subject: [PATCH] Added keyv version 5 support to KeyvAdapter --- .changeset/afraid-badgers-glow.md | 5 + packages/keyvAdapter/package.json | 2 +- .../src/__tests__/KeyvAdapter.test.ts | 91 ++++++++----------- packages/keyvAdapter/src/index.ts | 12 +-- 4 files changed, 49 insertions(+), 61 deletions(-) create mode 100644 .changeset/afraid-badgers-glow.md diff --git a/.changeset/afraid-badgers-glow.md b/.changeset/afraid-badgers-glow.md new file mode 100644 index 00000000..1c0e4d82 --- /dev/null +++ b/.changeset/afraid-badgers-glow.md @@ -0,0 +1,5 @@ +--- +"@apollo/utils.keyvadapter": major +--- + +Added keyv 5 support diff --git a/packages/keyvAdapter/package.json b/packages/keyvAdapter/package.json index 61eb2c7a..e5cd4c8a 100644 --- a/packages/keyvAdapter/package.json +++ b/packages/keyvAdapter/package.json @@ -23,6 +23,6 @@ "dependencies": { "@apollo/utils.keyvaluecache": "^3.1.0", "dataloader": "^2.1.0", - "keyv": "^4.4.0" + "keyv": "^5.1.0" } } diff --git a/packages/keyvAdapter/src/__tests__/KeyvAdapter.test.ts b/packages/keyvAdapter/src/__tests__/KeyvAdapter.test.ts index b89fe015..53d6069e 100644 --- a/packages/keyvAdapter/src/__tests__/KeyvAdapter.test.ts +++ b/packages/keyvAdapter/src/__tests__/KeyvAdapter.test.ts @@ -1,5 +1,5 @@ import type { KeyValueCache } from "@apollo/utils.keyvaluecache"; -import Keyv, { type Store } from "keyv"; +import Keyv, { type KeyvStoreAdapter } from "keyv"; import { expectType } from "ts-expect"; import { KeyvAdapter } from ".."; @@ -26,44 +26,6 @@ describe("KeyvAdapter", () => { expectType>(new KeyvAdapter(numberKeyv)); }); - it("Keyv class generics `Option`", () => { - interface RedisOption { - sentinels: { - port?: number; - host?: string; - family?: number; - }[]; - } - const keyv = new Keyv({ - sentinels: [], - }); - const keyvAdapter = new KeyvAdapter(keyv); - expectType>(keyvAdapter); - }); - - it("Keyv class generics `Option` default", () => { - const keyv = new Keyv({ - sentinels: [], - }); - const keyvAdapter = new KeyvAdapter(keyv); - expectType>>(keyvAdapter); - }); - - it("Keyv class generics with incompatible `Option`", () => { - interface Option { - sentinels: { - port?: number; - host?: string; - family?: number; - }[]; - } - const keyv = new Keyv({ - sentinels: [], - }); - // @ts-expect-error - new KeyvAdapter(keyv); - }); - describe("Keyv methods", () => { let keyv: Keyv; let keyvAdapter: KeyvAdapter; @@ -124,12 +86,32 @@ describe("KeyvAdapter", () => { }); it("multiple `get`s are batched", async () => { - const storeWithGetMany: Store = new (class extends Map< - string, - string - > { - getMany = jest.fn((keys: string[]) => keys.map((key) => this.get(key))); - })(); + class MapStore implements KeyvStoreAdapter { + private map = new Map(); + opts: any = {}; + namespace?: string; + getMany = jest.fn((keys: string[]) => + Promise.resolve(keys.map((key) => this.map.get(key))), + ); + get(key: string) { + return Promise.resolve(this.map.get(key) as Value); + } + set(key: string, value: any) { + this.map.set(key, value); + } + delete(key: string) { + return Promise.resolve(this.map.delete(key)); + } + clear() { + this.map.clear(); + return Promise.resolve(); + } + on(): this { + return this; + } + } + + const storeWithGetMany = new MapStore(); const keyv = new Keyv({ store: storeWithGetMany }); const keyvAdapter = new KeyvAdapter(keyv); @@ -160,23 +142,26 @@ describe("KeyvAdapter", () => { describe("Dataloader implementation details", () => { it("enforces the Dataloader contract (1:1 key to value)", async () => { - class GetManyReturnsSingularUndefinedStore implements Store { - getMany(_keys: string[]) { - // really we would prefer an array of undefined of the length of - // _keys, but that isn't a contract that `Keyv` enforces - return undefined; + class GetManyReturnsSingularUndefinedStore implements KeyvStoreAdapter { + opts: any = {}; + namespace?: string; + getMany(keys: string[]) { + return Promise.resolve(Array(keys.length).fill(undefined)); } get() { - return "hello"; + return Promise.resolve(undefined); } set() { return; } delete() { - return true; + return Promise.resolve(true); } clear() { - return; + return Promise.resolve(); + } + on(): this { + return this; } } diff --git a/packages/keyvAdapter/src/index.ts b/packages/keyvAdapter/src/index.ts index 7381d44b..3e7149dc 100644 --- a/packages/keyvAdapter/src/index.ts +++ b/packages/keyvAdapter/src/index.ts @@ -9,16 +9,14 @@ interface KeyvAdapterOptions { disableBatchReads?: boolean; } -export class KeyvAdapter< - V = string, - O extends Record = Record, -> implements KeyValueCache +export class KeyvAdapter + implements KeyValueCache { - private readonly keyv: Keyv; + private readonly keyv: Keyv; private readonly dataLoader: DataLoader | undefined; - constructor(keyv?: Keyv, options?: KeyvAdapterOptions) { - this.keyv = keyv ?? new Keyv(); + constructor(keyv?: Keyv, options?: KeyvAdapterOptions) { + this.keyv = keyv ?? new Keyv(); this.dataLoader = options?.disableBatchReads ? undefined : new DataLoader(