Skip to content

Commit

Permalink
feat(KVPeer): add prefix option (#165)
Browse files Browse the repository at this point in the history
  • Loading branch information
PierreDemailly authored Jan 9, 2025
1 parent 4d12f5b commit d9da206
Show file tree
Hide file tree
Showing 3 changed files with 53 additions and 4 deletions.
2 changes: 2 additions & 0 deletions docs/KVPeer.md
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,8 @@ export interface KVOptions<T extends StringOrObject = Record<string, any>, K ext
adapter: DatabaseConnection;
type?: KVType;
mapValue?: KVMapper<T, K>;
prefix?: string;
prefixSeparator?: string;
}

export type KVPeerSetValueOptions<T extends StringOrObject = StringOrObject> = Omit<
Expand Down
18 changes: 14 additions & 4 deletions src/class/KVPeer.class.ts
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,8 @@ export interface KVOptions<T extends StringOrObject = Record<string, any>, K ext
adapter: DatabaseConnection;
type?: KVType;
mapValue?: KVMapper<T, K>;
prefix?: string;
prefixSeparator?: string;
}

export type KVPeerSetValueOptions<T extends StringOrObject = StringOrObject> = Omit<
Expand All @@ -47,13 +49,17 @@ export class KVPeer<T extends StringOrObject = StringOrObject, K extends Record<
protected type: KVType;
protected mapValue: KVMapper<T, K>;
protected adapter: DatabaseConnection;
protected prefix: string;
protected prefixSeparator: string;

constructor(options: KVOptions<T, K>) {
super();

const { type, mapValue, adapter } = options;
const { type, mapValue, adapter, prefix = "", prefixSeparator = "-" } = options;

this.adapter = adapter;
this.prefix = prefix;
this.prefixSeparator = prefix.length ? prefixSeparator : "";

this.type = type ?? kDefaultKVType;
this.mapValue = mapValue ?? this.defaultMapValue;
Expand All @@ -63,25 +69,29 @@ export class KVPeer<T extends StringOrObject = StringOrObject, K extends Record<
const { key, value, ...rest } = options;

return this.adapter.setValue({
key,
key: this.keyWithPrefix(key),
value,
type: this.type,
...rest
});
}

async getValue(key: KeyType): Promise<MappedValue<T, K> | null> {
const result = await this.adapter.getValue(key, this.type);
const result = await this.adapter.getValue(this.keyWithPrefix(key), this.type);

return result === null ? null : this.mapValue(result as T);
}

async deleteValue(key: KeyType): Promise<number> {
return this.adapter.deleteValue(key);
return this.adapter.deleteValue(this.keyWithPrefix(key));
}

private defaultMapValue(value: T): MappedValue<T, K> {
return value as MappedValue<T, K>;
}

protected keyWithPrefix(key: KeyType) {
return `${this.prefix}${this.prefixSeparator}${key}`;
}
}

37 changes: 37 additions & 0 deletions test/class/KVPeer.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -205,6 +205,43 @@ describe("KVPeer", () => {
});
});
});

test("With prefix", async() => {
const kvPeer = new KVPeer({
type: "raw",
adapter: redisAdapter,
prefix: "super-prefix"
});
await kvPeer.setValue({ key: "super-key", value: "boo" });

const valueWithNoPrefix = await redisAdapter.getValue("super-key", "raw");
assert.strictEqual(valueWithNoPrefix, null);

const valueWithPrefix = await redisAdapter.getValue("super-prefix-super-key", "raw");
assert.strictEqual(valueWithPrefix, "boo");

const valueFromKVPeer = await kvPeer.getValue("super-key");
assert.strictEqual(valueFromKVPeer, "boo");
});

test("With prefix and prefixSeparator", async() => {
const kvPeer = new KVPeer({
type: "raw",
adapter: redisAdapter,
prefix: "super-prefix",
prefixSeparator: ":::"
});
await kvPeer.setValue({ key: "super-key", value: "boo" });

const valueWithNoPrefix = await redisAdapter.getValue("super-key", "raw");
assert.strictEqual(valueWithNoPrefix, null);

const valueWithPrefix = await redisAdapter.getValue("super-prefix:::super-key", "raw");
assert.strictEqual(valueWithPrefix, "boo");

const valueFromKVPeer = await kvPeer.getValue("super-key");
assert.strictEqual(valueFromKVPeer, "boo");
});
});

describe("MemoryAdapter", () => {
Expand Down

0 comments on commit d9da206

Please sign in to comment.