Initial Save

This commit is contained in:
jackbeeby
2025-03-28 12:30:19 +11:00
parent e381994f19
commit d8773925e8
9910 changed files with 982718 additions and 0 deletions

21
node_modules/apollo-server-caching/LICENSE generated vendored Normal file
View File

@@ -0,0 +1,21 @@
The MIT License (MIT)
Copyright (c) 2016-2020 Apollo Graph, Inc. (Formerly Meteor Development Group, Inc.)
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.

46
node_modules/apollo-server-caching/README.md generated vendored Normal file
View File

@@ -0,0 +1,46 @@
# apollo-server-caching
[![npm version](https://badge.fury.io/js/apollo-server-caching.svg)](https://badge.fury.io/js/apollo-server-caching)
[![Build Status](https://circleci.com/gh/apollographql/apollo-server/tree/main.svg?style=svg)](https://circleci.com/gh/apollographql/apollo-server)
## Implementing your own Cache
Internally, Apollo Server uses the `KeyValueCache` interface to provide a caching store for the Data Sources. An in-memory LRU cache is used by default, and we provide connectors for [Memcached](../apollo-server-cache-memcached)/[Redis](../apollo-server-cache-redis) backends.
Built with extensibility in mind, you can also implement your own cache to use with Apollo Server, in a way that best suits your application needs. It needs to implement the following interface that can be exported from `apollo-server-caching`:
```typescript
export interface KeyValueCache {
get(key: string): Promise<string | undefined>;
set(key: string, value: string, options?: { ttl?: number }): Promise<void>;
}
```
> The `ttl` value for the `set` method's `options` is specified in __seconds__.
## Testing cache implementations
### Test helpers
You can export and run a jest test suite from `apollo-server-caching` to test your implementation:
```typescript
// ../__tests__/YourKeyValueCache.test.ts
import YourKeyValueCache from '../src/YourKeyValueCache';
import { testKeyValueCache } from 'apollo-server-caching';
testKeyValueCache(new MemcachedCache('localhost'));
```
The default `testKeyValueCache` helper will run all key-value store tests on the specified store, including basic `get` and `set` functionality, along with time-based expunging rules.
Some key-value cache implementations may not be able to support the full suite of tests (for example, some tests might not be able to expire based on time). For those cases, there are more granular implementations which can be used:
* `testKeyValueCache_Basic`
* `testKeyValueCache_Expiration`
For more details, consult the [source for `apollo-server-caching`](./src/__tests__/testsuite.ts).
### Running tests
Run tests with `jest --verbose`

View File

@@ -0,0 +1,17 @@
import { TestableKeyValueCache } from './KeyValueCache';
export declare class InMemoryLRUCache<V = string> implements TestableKeyValueCache<V> {
private store;
constructor({ maxSize, sizeCalculator, onDispose, }?: {
maxSize?: number;
sizeCalculator?: (value: V, key: string) => number;
onDispose?: (key: string, value: V) => void;
});
get(key: string): Promise<V | undefined>;
set(key: string, value: V, options?: {
ttl?: number;
}): Promise<void>;
delete(key: string): Promise<void>;
flush(): Promise<void>;
getTotalSize(): Promise<number>;
}
//# sourceMappingURL=InMemoryLRUCache.d.ts.map

View File

@@ -0,0 +1 @@
{"version":3,"file":"InMemoryLRUCache.d.ts","sourceRoot":"","sources":["../src/InMemoryLRUCache.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,qBAAqB,EAAE,MAAM,iBAAiB,CAAC;AAYxD,qBAAa,gBAAgB,CAAC,CAAC,GAAG,MAAM,CAAE,YAAW,qBAAqB,CAAC,CAAC,CAAC;IAC3E,OAAO,CAAC,KAAK,CAAsB;gBAGvB,EACV,OAAkB,EAClB,cAAyC,EACzC,SAAS,GACV,GAAE;QACD,OAAO,CAAC,EAAE,MAAM,CAAC;QACjB,cAAc,CAAC,EAAE,CAAC,KAAK,EAAE,CAAC,EAAE,GAAG,EAAE,MAAM,KAAK,MAAM,CAAC;QACnD,SAAS,CAAC,EAAE,CAAC,GAAG,EAAE,MAAM,EAAE,KAAK,EAAE,CAAC,KAAK,IAAI,CAAC;KACxC;IAQA,GAAG,CAAC,GAAG,EAAE,MAAM;IAGf,GAAG,CAAC,GAAG,EAAE,MAAM,EAAE,KAAK,EAAE,CAAC,EAAE,OAAO,CAAC,EAAE;QAAE,GAAG,CAAC,EAAE,MAAM,CAAA;KAAE;IAIrD,MAAM,CAAC,GAAG,EAAE,MAAM;IAMlB,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC;IAGtB,YAAY;CAGnB"}

View File

@@ -0,0 +1,59 @@
"use strict";
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
return new (P || (P = Promise))(function (resolve, reject) {
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
step((generator = generator.apply(thisArg, _arguments || [])).next());
});
};
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.InMemoryLRUCache = void 0;
const lru_cache_1 = __importDefault(require("lru-cache"));
function defaultLengthCalculation(item) {
if (Array.isArray(item) || typeof item === 'string') {
return item.length;
}
return 1;
}
class InMemoryLRUCache {
constructor({ maxSize = Infinity, sizeCalculator = defaultLengthCalculation, onDispose, } = {}) {
this.store = new lru_cache_1.default({
max: maxSize,
length: sizeCalculator,
dispose: onDispose,
});
}
get(key) {
return __awaiter(this, void 0, void 0, function* () {
return this.store.get(key);
});
}
set(key, value, options) {
return __awaiter(this, void 0, void 0, function* () {
const maxAge = options && options.ttl && options.ttl * 1000;
this.store.set(key, value, maxAge);
});
}
delete(key) {
return __awaiter(this, void 0, void 0, function* () {
this.store.del(key);
});
}
flush() {
return __awaiter(this, void 0, void 0, function* () {
this.store.reset();
});
}
getTotalSize() {
return __awaiter(this, void 0, void 0, function* () {
return this.store.length;
});
}
}
exports.InMemoryLRUCache = InMemoryLRUCache;
//# sourceMappingURL=InMemoryLRUCache.js.map

View File

@@ -0,0 +1 @@
{"version":3,"file":"InMemoryLRUCache.js","sourceRoot":"","sources":["../src/InMemoryLRUCache.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;AAAA,0DAAiC;AAGjC,SAAS,wBAAwB,CAAC,IAAS;IACzC,IAAI,KAAK,CAAC,OAAO,CAAC,IAAI,CAAC,IAAI,OAAO,IAAI,KAAK,QAAQ,EAAE;QACnD,OAAO,IAAI,CAAC,MAAM,CAAC;KACpB;IAID,OAAO,CAAC,CAAC;AACX,CAAC;AAED,MAAa,gBAAgB;IAI3B,YAAY,EACV,OAAO,GAAG,QAAQ,EAClB,cAAc,GAAG,wBAAwB,EACzC,SAAS,MAKP,EAAE;QACJ,IAAI,CAAC,KAAK,GAAG,IAAI,mBAAQ,CAAC;YACxB,GAAG,EAAE,OAAO;YACZ,MAAM,EAAE,cAAc;YACtB,OAAO,EAAE,SAAS;SACnB,CAAC,CAAC;IACL,CAAC;IAEK,GAAG,CAAC,GAAW;;YACnB,OAAO,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;QAC7B,CAAC;KAAA;IACK,GAAG,CAAC,GAAW,EAAE,KAAQ,EAAE,OAA0B;;YACzD,MAAM,MAAM,GAAG,OAAO,IAAI,OAAO,CAAC,GAAG,IAAI,OAAO,CAAC,GAAG,GAAG,IAAI,CAAC;YAC5D,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,GAAG,EAAE,KAAK,EAAE,MAAM,CAAC,CAAC;QACrC,CAAC;KAAA;IACK,MAAM,CAAC,GAAW;;YACtB,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;QACtB,CAAC;KAAA;IAIK,KAAK;;YACT,IAAI,CAAC,KAAK,CAAC,KAAK,EAAE,CAAC;QACrB,CAAC;KAAA;IACK,YAAY;;YAChB,OAAO,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC;QAC3B,CAAC;KAAA;CACF;AAvCD,4CAuCC"}

View File

@@ -0,0 +1,13 @@
export interface KeyValueCacheSetOptions {
ttl?: number | null;
}
export interface KeyValueCache<V = string> {
get(key: string): Promise<V | undefined>;
set(key: string, value: V, options?: KeyValueCacheSetOptions): Promise<void>;
delete(key: string): Promise<boolean | void>;
}
export interface TestableKeyValueCache<V = string> extends KeyValueCache<V> {
flush?(): Promise<void>;
close?(): Promise<void>;
}
//# sourceMappingURL=KeyValueCache.d.ts.map

View File

@@ -0,0 +1 @@
{"version":3,"file":"KeyValueCache.d.ts","sourceRoot":"","sources":["../src/KeyValueCache.ts"],"names":[],"mappings":"AACA,MAAM,WAAW,uBAAuB;IAKtC,GAAG,CAAC,EAAE,MAAM,GAAG,IAAI,CAAA;CACpB;AAED,MAAM,WAAW,aAAa,CAAC,CAAC,GAAG,MAAM;IACvC,GAAG,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,CAAC,GAAG,SAAS,CAAC,CAAC;IACzC,GAAG,CAAC,GAAG,EAAE,MAAM,EAAE,KAAK,EAAE,CAAC,EAAE,OAAO,CAAC,EAAE,uBAAuB,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IAC7E,MAAM,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,GAAG,IAAI,CAAC,CAAC;CAC9C;AAED,MAAM,WAAW,qBAAqB,CAAC,CAAC,GAAG,MAAM,CAAE,SAAQ,aAAa,CAAC,CAAC,CAAC;IAIzE,KAAK,CAAC,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC;IAExB,KAAK,CAAC,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC;CACzB"}

View File

@@ -0,0 +1,4 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
;
//# sourceMappingURL=KeyValueCache.js.map

View File

@@ -0,0 +1 @@
{"version":3,"file":"KeyValueCache.js","sourceRoot":"","sources":["../src/KeyValueCache.ts"],"names":[],"mappings":";;AAOC,CAAC"}

View File

@@ -0,0 +1,10 @@
import { KeyValueCache, KeyValueCacheSetOptions } from './KeyValueCache';
export declare class PrefixingKeyValueCache<V = string> implements KeyValueCache<V> {
private wrapped;
private prefix;
constructor(wrapped: KeyValueCache<V>, prefix: string);
get(key: string): Promise<V | undefined>;
set(key: string, value: V, options?: KeyValueCacheSetOptions): Promise<void>;
delete(key: string): Promise<boolean | void>;
}
//# sourceMappingURL=PrefixingKeyValueCache.d.ts.map

View File

@@ -0,0 +1 @@
{"version":3,"file":"PrefixingKeyValueCache.d.ts","sourceRoot":"","sources":["../src/PrefixingKeyValueCache.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAAE,uBAAuB,EAAE,MAAM,iBAAiB,CAAC;AAYzE,qBAAa,sBAAsB,CAAC,CAAC,GAAG,MAAM,CAAE,YAAW,aAAa,CAAC,CAAC,CAAC;IAC7D,OAAO,CAAC,OAAO;IAAoB,OAAO,CAAC,MAAM;gBAAzC,OAAO,EAAE,aAAa,CAAC,CAAC,CAAC,EAAU,MAAM,EAAE,MAAM;IAErE,GAAG,CAAC,GAAG,EAAE,MAAM;IAGf,GAAG,CAAC,GAAG,EAAE,MAAM,EAAE,KAAK,EAAE,CAAC,EAAE,OAAO,CAAC,EAAE,uBAAuB;IAG5D,MAAM,CAAC,GAAG,EAAE,MAAM;CAGnB"}

View File

@@ -0,0 +1,20 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.PrefixingKeyValueCache = void 0;
class PrefixingKeyValueCache {
constructor(wrapped, prefix) {
this.wrapped = wrapped;
this.prefix = prefix;
}
get(key) {
return this.wrapped.get(this.prefix + key);
}
set(key, value, options) {
return this.wrapped.set(this.prefix + key, value, options);
}
delete(key) {
return this.wrapped.delete(this.prefix + key);
}
}
exports.PrefixingKeyValueCache = PrefixingKeyValueCache;
//# sourceMappingURL=PrefixingKeyValueCache.js.map

View File

@@ -0,0 +1 @@
{"version":3,"file":"PrefixingKeyValueCache.js","sourceRoot":"","sources":["../src/PrefixingKeyValueCache.ts"],"names":[],"mappings":";;;AAYA,MAAa,sBAAsB;IACjC,YAAoB,OAAyB,EAAU,MAAc;QAAjD,YAAO,GAAP,OAAO,CAAkB;QAAU,WAAM,GAAN,MAAM,CAAQ;IAAG,CAAC;IAEzE,GAAG,CAAC,GAAW;QACb,OAAO,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,IAAI,CAAC,MAAM,GAAG,GAAG,CAAC,CAAC;IAC7C,CAAC;IACD,GAAG,CAAC,GAAW,EAAE,KAAQ,EAAE,OAAiC;QAC1D,OAAO,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,IAAI,CAAC,MAAM,GAAG,GAAG,EAAE,KAAK,EAAE,OAAO,CAAC,CAAC;IAC7D,CAAC;IACD,MAAM,CAAC,GAAW;QAChB,OAAO,IAAI,CAAC,OAAO,CAAC,MAAM,CAAC,IAAI,CAAC,MAAM,GAAG,GAAG,CAAC,CAAC;IAChD,CAAC;CACF;AAZD,wDAYC"}

4
node_modules/apollo-server-caching/dist/index.d.ts generated vendored Normal file
View File

@@ -0,0 +1,4 @@
export { KeyValueCache, TestableKeyValueCache, KeyValueCacheSetOptions, } from './KeyValueCache';
export { InMemoryLRUCache } from './InMemoryLRUCache';
export { PrefixingKeyValueCache } from './PrefixingKeyValueCache';
//# sourceMappingURL=index.d.ts.map

View File

@@ -0,0 +1 @@
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,aAAa,EACb,qBAAqB,EACrB,uBAAuB,GACxB,MAAM,iBAAiB,CAAC;AACzB,OAAO,EAAE,gBAAgB,EAAE,MAAM,oBAAoB,CAAC;AACtD,OAAO,EAAE,sBAAsB,EAAE,MAAM,0BAA0B,CAAC"}

7
node_modules/apollo-server-caching/dist/index.js generated vendored Normal file
View File

@@ -0,0 +1,7 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
var InMemoryLRUCache_1 = require("./InMemoryLRUCache");
Object.defineProperty(exports, "InMemoryLRUCache", { enumerable: true, get: function () { return InMemoryLRUCache_1.InMemoryLRUCache; } });
var PrefixingKeyValueCache_1 = require("./PrefixingKeyValueCache");
Object.defineProperty(exports, "PrefixingKeyValueCache", { enumerable: true, get: function () { return PrefixingKeyValueCache_1.PrefixingKeyValueCache; } });
//# sourceMappingURL=index.js.map

1
node_modules/apollo-server-caching/dist/index.js.map generated vendored Normal file
View File

@@ -0,0 +1 @@
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";;AAKA,uDAAsD;AAA7C,oHAAA,gBAAgB,OAAA;AACzB,mEAAkE;AAAzD,gIAAA,sBAAsB,OAAA"}

24
node_modules/apollo-server-caching/package.json generated vendored Normal file
View File

@@ -0,0 +1,24 @@
{
"name": "apollo-server-caching",
"version": "0.7.0",
"author": "Apollo <opensource@apollographql.com>",
"license": "MIT",
"repository": {
"type": "git",
"url": "https://github.com/apollographql/apollo-server",
"directory": "packages/apollo-server-caching"
},
"homepage": "https://github.com/apollographql/apollo-server#readme",
"bugs": {
"url": "https://github.com/apollographql/apollo-server/issues"
},
"main": "dist/index.js",
"types": "dist/index.d.ts",
"engines": {
"node": ">=6"
},
"dependencies": {
"lru-cache": "^6.0.0"
},
"gitHead": "f2349d0e10633ee79bed152f682e53730175d59b"
}

View File

@@ -0,0 +1,53 @@
import LRUCache from 'lru-cache';
import { TestableKeyValueCache } from './KeyValueCache';
function defaultLengthCalculation(item: any) {
if (Array.isArray(item) || typeof item === 'string') {
return item.length;
}
// Go with the lru-cache default "naive" size, in lieu anything better:
// https://github.com/isaacs/node-lru-cache/blob/a71be6cd/index.js#L17
return 1;
}
export class InMemoryLRUCache<V = string> implements TestableKeyValueCache<V> {
private store: LRUCache<string, V>;
// TODO: Define reasonable default max size of the cache
constructor({
maxSize = Infinity,
sizeCalculator = defaultLengthCalculation,
onDispose,
}: {
maxSize?: number;
sizeCalculator?: (value: V, key: string) => number;
onDispose?: (key: string, value: V) => void;
} = {}) {
this.store = new LRUCache({
max: maxSize,
length: sizeCalculator,
dispose: onDispose,
});
}
async get(key: string) {
return this.store.get(key);
}
async set(key: string, value: V, options?: { ttl?: number }) {
const maxAge = options && options.ttl && options.ttl * 1000;
this.store.set(key, value, maxAge);
}
async delete(key: string) {
this.store.del(key);
}
// Drops all data from the cache. This should only be used by test suites ---
// production code should never drop all data from an end user cache.
async flush(): Promise<void> {
this.store.reset();
}
async getTotalSize() {
return this.store.length;
}
}

View File

@@ -0,0 +1,23 @@
/** Options for {@link KeyValueCache.set} */
export interface KeyValueCacheSetOptions {
/**
* Specified in **seconds**, the time-to-live (TTL) value limits the lifespan
* of the data being stored in the cache.
*/
ttl?: number | null
};
export interface KeyValueCache<V = string> {
get(key: string): Promise<V | undefined>;
set(key: string, value: V, options?: KeyValueCacheSetOptions): Promise<void>;
delete(key: string): Promise<boolean | void>;
}
export interface TestableKeyValueCache<V = string> extends KeyValueCache<V> {
// Drops all data from the cache. This should only be used by test suites ---
// production code should never drop all data from an end user cache (and
// notably, PrefixingKeyValueCache intentionally doesn't implement this).
flush?(): Promise<void>;
// Close connections associated with this cache.
close?(): Promise<void>;
}

View File

@@ -0,0 +1,25 @@
import { KeyValueCache, KeyValueCacheSetOptions } from './KeyValueCache';
// PrefixingKeyValueCache wraps another cache and adds a prefix to all keys used
// by all operations. This allows multiple features to share the same
// underlying cache without conflicts.
//
// Note that PrefixingKeyValueCache explicitly does not implement
// TestableKeyValueCache, and notably does not implement the flush()
// method. Most implementations of TestableKeyValueCache.flush() send a simple
// command that wipes the entire backend cache system, which wouldn't support
// "only wipe the part of the cache with this prefix", so trying to provide a
// flush() method here could be confusingly dangerous.
export class PrefixingKeyValueCache<V = string> implements KeyValueCache<V> {
constructor(private wrapped: KeyValueCache<V>, private prefix: string) {}
get(key: string) {
return this.wrapped.get(this.prefix + key);
}
set(key: string, value: V, options?: KeyValueCacheSetOptions) {
return this.wrapped.set(this.prefix + key, value, options);
}
delete(key: string) {
return this.wrapped.delete(this.prefix + key);
}
}

View File

@@ -0,0 +1,11 @@
import {
testKeyValueCache_Basics,
testKeyValueCache_Expiration,
} from '../../../apollo-server-caching/src/__tests__/testsuite';
import { InMemoryLRUCache } from '../InMemoryLRUCache';
describe('InMemoryLRUCache', () => {
const cache = new InMemoryLRUCache();
testKeyValueCache_Basics(cache);
testKeyValueCache_Expiration(cache);
});

View File

@@ -0,0 +1,14 @@
import { InMemoryLRUCache } from '../InMemoryLRUCache';
import { PrefixingKeyValueCache } from '../PrefixingKeyValueCache';
describe('PrefixingKeyValueCache', () => {
it('prefixes', async () => {
const inner = new InMemoryLRUCache();
const prefixing = new PrefixingKeyValueCache(inner, 'prefix:');
await prefixing.set('foo', 'bar');
expect(await prefixing.get('foo')).toBe('bar');
expect(await inner.get('prefix:foo')).toBe('bar');
await prefixing.delete('foo');
expect(await prefixing.get('foo')).toBe(undefined);
});
});

View File

@@ -0,0 +1,81 @@
import { advanceTimeBy, mockDate, unmockDate } from '__mocks__/date';
import { TestableKeyValueCache } from '../';
export function testKeyValueCache_Basics(keyValueCache: TestableKeyValueCache) {
describe('basic cache functionality', () => {
beforeEach(() => {
keyValueCache.flush && keyValueCache.flush();
});
it('can do a basic get and set', async () => {
await keyValueCache.set('hello', 'world');
expect(await keyValueCache.get('hello')).toBe('world');
expect(await keyValueCache.get('missing')).toBeUndefined();
});
it('can do a basic set and delete', async () => {
await keyValueCache.set('hello', 'world');
expect(await keyValueCache.get('hello')).toBe('world');
await keyValueCache.delete('hello');
expect(await keyValueCache.get('hello')).toBeUndefined();
});
});
}
export function testKeyValueCache_Expiration(
keyValueCache: TestableKeyValueCache,
) {
describe('time-based cache expunging', () => {
beforeAll(() => {
mockDate();
jest.useFakeTimers();
});
beforeEach(() => {
keyValueCache.flush && keyValueCache.flush();
});
afterAll(() => {
jest.useRealTimers();
unmockDate();
});
it('is able to expire keys based on ttl', async () => {
await keyValueCache.set('short', 's', { ttl: 1 });
await keyValueCache.set('long', 'l', { ttl: 5 });
expect(await keyValueCache.get('short')).toBe('s');
expect(await keyValueCache.get('long')).toBe('l');
advanceTimeBy(1500);
jest.advanceTimersByTime(1500);
expect(await keyValueCache.get('short')).toBeUndefined();
expect(await keyValueCache.get('long')).toBe('l');
advanceTimeBy(4000);
jest.advanceTimersByTime(4000);
expect(await keyValueCache.get('short')).toBeUndefined();
expect(await keyValueCache.get('long')).toBeUndefined();
});
it('does not expire when ttl is null', async () => {
await keyValueCache.set('forever', 'yours', { ttl: null });
expect(await keyValueCache.get('forever')).toBe('yours');
advanceTimeBy(1500);
jest.advanceTimersByTime(1500);
expect(await keyValueCache.get('forever')).toBe('yours');
advanceTimeBy(4000);
jest.advanceTimersByTime(4000);
expect(await keyValueCache.get('forever')).toBe('yours');
});
});
}
export function testKeyValueCache(keyValueCache: TestableKeyValueCache) {
describe('KeyValueCache Test Suite', () => {
afterAll(async () => {
if (keyValueCache.close) {
await keyValueCache.close();
}
});
testKeyValueCache_Basics(keyValueCache);
testKeyValueCache_Expiration(keyValueCache);
});
}

View File

@@ -0,0 +1,7 @@
{
"extends": "../../../../tsconfig.test.base",
"include": ["**/*", "../../../../__mocks__"],
"references": [
{ "path": "../../" },
]
}

7
node_modules/apollo-server-caching/src/index.ts generated vendored Normal file
View File

@@ -0,0 +1,7 @@
export {
KeyValueCache,
TestableKeyValueCache,
KeyValueCacheSetOptions,
} from './KeyValueCache';
export { InMemoryLRUCache } from './InMemoryLRUCache';
export { PrefixingKeyValueCache } from './PrefixingKeyValueCache';