Huge News!Announcing our $40M Series B led by Abstract Ventures.Learn More
Socket
Sign inDemoInstall
Socket

@apollo/utils.keyvaluecache

Package Overview
Dependencies
Maintainers
4
Versions
9
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

@apollo/utils.keyvaluecache - npm Package Compare versions

Comparing version 3.0.0 to 3.1.0

10

dist/ErrorsAreMissesCache.d.ts

@@ -1,13 +0,11 @@

import type { KeyValueCache } from "./KeyValueCache";
import type { KeyValueCache, KeyValueCacheSetOptions } from "./KeyValueCache";
import type { Logger } from "@apollo/utils.logger";
export declare class ErrorsAreMissesCache<V = string> implements KeyValueCache<V> {
export declare class ErrorsAreMissesCache<V = string, SO extends KeyValueCacheSetOptions = KeyValueCacheSetOptions> implements KeyValueCache<V, SO> {
private cache;
private logger?;
constructor(cache: KeyValueCache<V>, logger?: Logger | undefined);
constructor(cache: KeyValueCache<V, SO>, logger?: Logger | undefined);
get(key: string): Promise<V | undefined>;
set(key: string, value: V, opts?: {
ttl?: number;
}): Promise<void>;
set(key: string, value: V, opts?: SO): Promise<void>;
delete(key: string): Promise<boolean | void>;
}
//# sourceMappingURL=ErrorsAreMissesCache.d.ts.map

2

dist/index.d.ts
export type { KeyValueCache, KeyValueCacheSetOptions } from "./KeyValueCache";
export { PrefixingKeyValueCache } from "./PrefixingKeyValueCache";
export { InMemoryLRUCache } from "./InMemoryLRUCache";
export { InMemoryLRUCache, type InMemoryLRUCacheSetOptions, } from "./InMemoryLRUCache";
export { ErrorsAreMissesCache } from "./ErrorsAreMissesCache";
//# sourceMappingURL=index.d.ts.map
import { LRUCache } from "lru-cache";
import type { KeyValueCache, KeyValueCacheSetOptions } from "./KeyValueCache";
export declare class InMemoryLRUCache<V extends {} = string> implements KeyValueCache<V> {
export type InMemoryLRUCacheSetOptions<V extends {} = string, FC = unknown> = Omit<LRUCache.SetOptions<string, V, FC>, "ttl"> & KeyValueCacheSetOptions;
export declare class InMemoryLRUCache<V extends {} = string, SO extends InMemoryLRUCacheSetOptions<V> = InMemoryLRUCacheSetOptions<V>> implements KeyValueCache<V, SO> {
private cache;
constructor(lruCacheOpts?: LRUCache.Options<string, V, any>);
static sizeCalculation<V extends {}>(item: V): number;
set(key: string, value: V, options?: KeyValueCacheSetOptions): Promise<void>;
set(key: string, value: V, options?: SO): Promise<void>;
get(key: string): Promise<V | undefined>;

@@ -9,0 +10,0 @@ delete(key: string): Promise<boolean>;

@@ -23,8 +23,6 @@ "use strict";

async set(key, value, options) {
if (options?.ttl) {
this.cache.set(key, value, { ttl: options.ttl * 1000 });
}
else {
this.cache.set(key, value);
}
const lruOptions = options
? { ...options, ttl: options.ttl ? options.ttl * 1000 : 0 }
: undefined;
this.cache.set(key, value, lruOptions);
}

@@ -31,0 +29,0 @@ async get(key) {

@@ -1,4 +0,4 @@

export interface KeyValueCache<V = string> {
export interface KeyValueCache<V = string, SO extends KeyValueCacheSetOptions = KeyValueCacheSetOptions> {
get(key: string): Promise<V | undefined>;
set(key: string, value: V, options?: KeyValueCacheSetOptions): Promise<void>;
set(key: string, value: V, options?: SO): Promise<void>;
delete(key: string): Promise<boolean | void>;

@@ -5,0 +5,0 @@ }

import type { KeyValueCache, KeyValueCacheSetOptions } from ".";
declare const prefixesAreUnnecessaryForIsolationSymbol: unique symbol;
export declare class PrefixingKeyValueCache<V = string> implements KeyValueCache<V> {
export declare class PrefixingKeyValueCache<V = string, SO extends KeyValueCacheSetOptions = KeyValueCacheSetOptions> implements KeyValueCache<V, SO> {
private wrapped;
private prefix;
[prefixesAreUnnecessaryForIsolationSymbol]?: true;
constructor(wrapped: KeyValueCache<V>, prefix: string);
constructor(wrapped: KeyValueCache<V, SO>, prefix: string);
get(key: string): Promise<V | undefined>;
set(key: string, value: V, options?: KeyValueCacheSetOptions): Promise<void>;
set(key: string, value: V, options?: SO): Promise<void>;
delete(key: string): Promise<boolean | void>;
static prefixesAreUnnecessaryForIsolation<V = string>(c: KeyValueCache<V>): boolean;
static cacheDangerouslyDoesNotNeedPrefixesForIsolation<V = string>(c: KeyValueCache<V>): KeyValueCache<V>;
static prefixesAreUnnecessaryForIsolation<V = string, SO extends KeyValueCacheSetOptions = KeyValueCacheSetOptions>(c: KeyValueCache<V, SO>): boolean;
static cacheDangerouslyDoesNotNeedPrefixesForIsolation<V = string, SO extends KeyValueCacheSetOptions = KeyValueCacheSetOptions>(c: KeyValueCache<V, SO>): KeyValueCache<V, SO>;
}
export {};
//# sourceMappingURL=PrefixingKeyValueCache.d.ts.map
{
"name": "@apollo/utils.keyvaluecache",
"version": "3.0.0",
"version": "3.1.0",
"description": "Minimal key-value cache interface",

@@ -25,4 +25,4 @@ "main": "dist/index.js",

"@apollo/utils.logger": "^3.0.0",
"lru-cache": "^9.0.3"
"lru-cache": "^10.0.0"
}
}
# KeyValueCache interface
```ts
export interface KeyValueCache<V = string> {
export interface KeyValueCache<
V = string,
SO extends KeyValueCacheSetOptions = KeyValueCacheSetOptions,
> {
get(key: string): Promise<V | undefined>;
set(key: string, value: V, options?: KeyValueCacheSetOptions): Promise<void>;
set(key: string, value: V, options?: SO): Promise<void>;
delete(key: string): Promise<boolean | void>;

@@ -8,0 +11,0 @@ }

import type { Logger } from "@apollo/utils.logger";
import { ErrorsAreMissesCache } from "../ErrorsAreMissesCache";
import type { KeyValueCache } from "../KeyValueCache";
import type { KeyValueCache, KeyValueCacheSetOptions } from "../KeyValueCache";
interface CustomKeyValueCacheSetOptions extends KeyValueCacheSetOptions {
noDisposeOnSet?: boolean;
noUpdateTTL?: boolean;
}
describe("ErrorsAreMissesCache", () => {

@@ -38,3 +43,3 @@ const knownErrorMessage = "Service is down";

it("passes through calls to the underlying cache", async () => {
const mockCache: KeyValueCache = {
const mockCache: KeyValueCache<string, CustomKeyValueCacheSetOptions> = {
get: jest.fn(async () => "foo"),

@@ -51,6 +56,12 @@ set: jest.fn(),

expect(mockCache.set).toHaveBeenCalledWith("key", "foo", undefined);
await errorsAreMisses.set("keyWithTTL", "foo", { ttl: 1000 });
expect(mockCache.set).toHaveBeenLastCalledWith("keyWithTTL", "foo", {
await errorsAreMisses.set("keyWithOptions", "foo", {
ttl: 1000,
noDisposeOnSet: true,
noUpdateTTL: true,
});
expect(mockCache.set).toHaveBeenLastCalledWith("keyWithOptions", "foo", {
ttl: 1000,
noDisposeOnSet: true,
noUpdateTTL: true,
});

@@ -57,0 +68,0 @@ await errorsAreMisses.delete("key");

@@ -0,3 +1,9 @@

import type { LRUCache } from "lru-cache";
import { InMemoryLRUCache } from "..";
interface CustomKeyValueCacheSetOptions
extends LRUCache.SetOptions<string, string, Record<string, string>> {
tags?: string[];
}
describe("InMemoryLRUCache", () => {

@@ -43,2 +49,30 @@ const cache = new InMemoryLRUCache();

});
it("with custom extended options", async () => {
const customCache = new InMemoryLRUCache<
string,
CustomKeyValueCacheSetOptions
>();
const spyOnCacheSet = jest.spyOn((customCache as any).cache, "set");
await customCache.set("key", "foo");
expect(spyOnCacheSet).toBeCalledWith("key", "foo", undefined);
expect(await customCache.get("key")).toBe("foo");
await customCache.delete("key");
expect(await customCache.get("key")).toBe(undefined);
await customCache.set("keyWithOptions", "bar", {
ttl: 1000,
tags: ["tag1", "tag2"],
});
expect(spyOnCacheSet).toBeCalledWith("keyWithOptions", "bar", {
ttl: 1000000,
tags: ["tag1", "tag2"],
});
expect(await customCache.get("keyWithOptions")).toBe("bar");
await customCache.delete("keyWithOptions");
expect(await customCache.get("keyWithOptions")).toBe(undefined);
});
});

@@ -45,0 +79,0 @@

@@ -1,4 +0,8 @@

import { InMemoryLRUCache } from "..";
import { InMemoryLRUCache, type InMemoryLRUCacheSetOptions } from "..";
import { PrefixingKeyValueCache } from "../PrefixingKeyValueCache";
interface CustomKeyValueCacheSetOptions extends InMemoryLRUCacheSetOptions {
tags?: string[];
}
describe("PrefixingKeyValueCache", () => {

@@ -14,2 +18,3 @@ it("prefixes", async () => {

});
it("PrefixesAreUnnecessaryForIsolationCache", async () => {

@@ -49,2 +54,30 @@ const inner = new InMemoryLRUCache();

});
it("prefixes with custom extended options", async () => {
const inner = new InMemoryLRUCache<string, CustomKeyValueCacheSetOptions>();
const spyOnCacheSet = jest.spyOn(inner, "set");
const prefixing = new PrefixingKeyValueCache(inner, "prefix:");
await prefixing.set("key", "foo");
expect(spyOnCacheSet).toBeCalledWith("prefix:key", "foo", undefined);
expect(await prefixing.get("key")).toBe("foo");
expect(await inner.get("prefix:key")).toBe("foo");
await prefixing.delete("key");
expect(await prefixing.get("key")).toBe(undefined);
await prefixing.set("keyWithOptions", "bar", {
ttl: 1000,
tags: ["tag1", "tag2"],
});
expect(spyOnCacheSet).toBeCalledWith("prefix:keyWithOptions", "bar", {
ttl: 1000,
tags: ["tag1", "tag2"],
});
expect(await prefixing.get("keyWithOptions")).toBe("bar");
expect(await inner.get("prefix:keyWithOptions")).toBe("bar");
await prefixing.delete("keyWithOptions");
expect(await prefixing.get("keyWithOptions")).toBe(undefined);
});
});

@@ -1,2 +0,2 @@

import type { KeyValueCache } from "./KeyValueCache";
import type { KeyValueCache, KeyValueCacheSetOptions } from "./KeyValueCache";
import type { Logger } from "@apollo/utils.logger";

@@ -9,4 +9,11 @@

*/
export class ErrorsAreMissesCache<V = string> implements KeyValueCache<V> {
constructor(private cache: KeyValueCache<V>, private logger?: Logger) {}
export class ErrorsAreMissesCache<
V = string,
SO extends KeyValueCacheSetOptions = KeyValueCacheSetOptions,
> implements KeyValueCache<V, SO>
{
constructor(
private cache: KeyValueCache<V, SO>,
private logger?: Logger,
) {}

@@ -28,3 +35,3 @@ async get(key: string): Promise<V | undefined> {

async set(key: string, value: V, opts?: { ttl?: number }): Promise<void> {
async set(key: string, value: V, opts?: SO): Promise<void> {
return this.cache.set(key, value, opts);

@@ -31,0 +38,0 @@ }

export type { KeyValueCache, KeyValueCacheSetOptions } from "./KeyValueCache";
export { PrefixingKeyValueCache } from "./PrefixingKeyValueCache";
export { InMemoryLRUCache } from "./InMemoryLRUCache";
export {
InMemoryLRUCache,
type InMemoryLRUCacheSetOptions,
} from "./InMemoryLRUCache";
export { ErrorsAreMissesCache } from "./ErrorsAreMissesCache";
import { LRUCache } from "lru-cache";
import type { KeyValueCache, KeyValueCacheSetOptions } from "./KeyValueCache";
export type InMemoryLRUCacheSetOptions<
V extends {} = string,
FC = unknown,
> = Omit<LRUCache.SetOptions<string, V, FC>, "ttl"> & KeyValueCacheSetOptions;
// LRUCache wrapper to implement the KeyValueCache interface.
export class InMemoryLRUCache<V extends {} = string>
implements KeyValueCache<V>
export class InMemoryLRUCache<
V extends {} = string,
SO extends InMemoryLRUCacheSetOptions<V> = InMemoryLRUCacheSetOptions<V>,
> implements KeyValueCache<V, SO>
{

@@ -35,8 +42,9 @@ private cache: LRUCache<string, V>;

async set(key: string, value: V, options?: KeyValueCacheSetOptions) {
if (options?.ttl) {
this.cache.set(key, value, { ttl: options.ttl * 1000 });
} else {
this.cache.set(key, value);
}
async set(key: string, value: V, options?: SO) {
// If a TTL in seconds is provided, convert it to milliseconds.
// Otherwise, default it to 0 to indicate "no TTL".
const lruOptions = options
? { ...options, ttl: options.ttl ? options.ttl * 1000 : 0 }
: undefined;
this.cache.set(key, value, lruOptions);
}

@@ -43,0 +51,0 @@

@@ -1,4 +0,7 @@

export interface KeyValueCache<V = string> {
export interface KeyValueCache<
V = string,
SO extends KeyValueCacheSetOptions = KeyValueCacheSetOptions,
> {
get(key: string): Promise<V | undefined>;
set(key: string, value: V, options?: KeyValueCacheSetOptions): Promise<void>;
set(key: string, value: V, options?: SO): Promise<void>;
delete(key: string): Promise<boolean | void>;

@@ -5,0 +8,0 @@ }

@@ -17,7 +17,14 @@ import type { KeyValueCache, KeyValueCacheSetOptions } from ".";

// trying to provide a flush() method here could be confusingly dangerous.
export class PrefixingKeyValueCache<V = string> implements KeyValueCache<V> {
export class PrefixingKeyValueCache<
V = string,
SO extends KeyValueCacheSetOptions = KeyValueCacheSetOptions,
> implements KeyValueCache<V, SO>
{
private prefix: string;
[prefixesAreUnnecessaryForIsolationSymbol]?: true;
constructor(private wrapped: KeyValueCache<V>, prefix: string) {
constructor(
private wrapped: KeyValueCache<V, SO>,
prefix: string,
) {
if (PrefixingKeyValueCache.prefixesAreUnnecessaryForIsolation(wrapped)) {

@@ -38,3 +45,3 @@ this.prefix = "";

}
set(key: string, value: V, options?: KeyValueCacheSetOptions) {
set(key: string, value: V, options?: SO) {
return this.wrapped.set(this.prefix + key, value, options);

@@ -49,11 +56,13 @@ }

// package doesn't break things).
static prefixesAreUnnecessaryForIsolation<V = string>(
c: KeyValueCache<V>,
): boolean {
static prefixesAreUnnecessaryForIsolation<
V = string,
SO extends KeyValueCacheSetOptions = KeyValueCacheSetOptions,
>(c: KeyValueCache<V, SO>): boolean {
return prefixesAreUnnecessaryForIsolationSymbol in c;
}
static cacheDangerouslyDoesNotNeedPrefixesForIsolation<V = string>(
c: KeyValueCache<V>,
): KeyValueCache<V> {
static cacheDangerouslyDoesNotNeedPrefixesForIsolation<
V = string,
SO extends KeyValueCacheSetOptions = KeyValueCacheSetOptions,
>(c: KeyValueCache<V, SO>): KeyValueCache<V, SO> {
return new PrefixesAreUnnecessaryForIsolationCache(c);

@@ -65,8 +74,10 @@ }

// PrefixingKeyValueCache. See the README for details.
class PrefixesAreUnnecessaryForIsolationCache<V = string>
implements KeyValueCache<V>
class PrefixesAreUnnecessaryForIsolationCache<
V = string,
SO extends KeyValueCacheSetOptions = KeyValueCacheSetOptions,
> implements KeyValueCache<V, SO>
{
[prefixesAreUnnecessaryForIsolationSymbol] = true;
constructor(private wrapped: KeyValueCache<V>) {}
constructor(private wrapped: KeyValueCache<V, SO>) {}

@@ -76,3 +87,3 @@ get(key: string) {

}
set(key: string, value: V, options?: KeyValueCacheSetOptions) {
set(key: string, value: V, options?: SO) {
return this.wrapped.set(key, value, options);

@@ -79,0 +90,0 @@ }

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc