Skip to content

Commit

Permalink
Added keyv version 5 support to KeyvAdapter
Browse files Browse the repository at this point in the history
  • Loading branch information
sroebert committed Oct 7, 2024
1 parent 419aac0 commit 817f195
Show file tree
Hide file tree
Showing 4 changed files with 49 additions and 61 deletions.
5 changes: 5 additions & 0 deletions .changeset/afraid-badgers-glow.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"@apollo/utils.keyvadapter": major
---

Added keyv 5 support
2 changes: 1 addition & 1 deletion packages/keyvAdapter/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,6 @@
"dependencies": {
"@apollo/utils.keyvaluecache": "^3.1.0",
"dataloader": "^2.1.0",
"keyv": "^4.4.0"
"keyv": "^5.1.0"
}
}
91 changes: 38 additions & 53 deletions packages/keyvAdapter/src/__tests__/KeyvAdapter.test.ts
Original file line number Diff line number Diff line change
@@ -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 "..";

Expand All @@ -26,44 +26,6 @@ describe("KeyvAdapter", () => {
expectType<KeyValueCache<number>>(new KeyvAdapter(numberKeyv));
});

it("Keyv class generics `Option`", () => {
interface RedisOption {
sentinels: {
port?: number;
host?: string;
family?: number;
}[];
}
const keyv = new Keyv<string, RedisOption>({
sentinels: [],
});
const keyvAdapter = new KeyvAdapter<string, RedisOption>(keyv);
expectType<KeyvAdapter<string, RedisOption>>(keyvAdapter);
});

it("Keyv class generics `Option` default", () => {
const keyv = new Keyv<string>({
sentinels: [],
});
const keyvAdapter = new KeyvAdapter<string>(keyv);
expectType<KeyvAdapter<string, Record<string, unknown>>>(keyvAdapter);
});

it("Keyv class generics with incompatible `Option`", () => {
interface Option {
sentinels: {
port?: number;
host?: string;
family?: number;
}[];
}
const keyv = new Keyv<string, Option>({
sentinels: [],
});
// @ts-expect-error
new KeyvAdapter<string>(keyv);
});

describe("Keyv methods", () => {
let keyv: Keyv<number>;
let keyvAdapter: KeyvAdapter<number>;
Expand Down Expand Up @@ -124,12 +86,32 @@ describe("KeyvAdapter", () => {
});

it("multiple `get`s are batched", async () => {
const storeWithGetMany: Store<string> = 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<string, any>();
opts: any = {};
namespace?: string;
getMany = jest.fn((keys: string[]) =>
Promise.resolve(keys.map((key) => this.map.get(key))),
);
get<Value>(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);

Expand Down Expand Up @@ -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<string> {
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;
}
}

Expand Down
12 changes: 5 additions & 7 deletions packages/keyvAdapter/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,16 +9,14 @@ interface KeyvAdapterOptions {
disableBatchReads?: boolean;
}

export class KeyvAdapter<
V = string,
O extends Record<string, any> = Record<string, unknown>,
> implements KeyValueCache<V, KeyValueCacheSetOptions>
export class KeyvAdapter<V = string>
implements KeyValueCache<V, KeyValueCacheSetOptions>
{
private readonly keyv: Keyv<V, O>;
private readonly keyv: Keyv<V>;
private readonly dataLoader: DataLoader<string, V | undefined> | undefined;

constructor(keyv?: Keyv<V, O>, options?: KeyvAdapterOptions) {
this.keyv = keyv ?? new Keyv<V, O>();
constructor(keyv?: Keyv<V>, options?: KeyvAdapterOptions) {
this.keyv = keyv ?? new Keyv<V>();
this.dataLoader = options?.disableBatchReads
? undefined
: new DataLoader(
Expand Down

0 comments on commit 817f195

Please sign in to comment.