Skip to content

Commit

Permalink
Merge branch 'master' into master
Browse files Browse the repository at this point in the history
  • Loading branch information
jaredwray authored Dec 18, 2023
2 parents 0dee93e + 0771b7f commit a433a5c
Show file tree
Hide file tree
Showing 5 changed files with 72 additions and 10 deletions.
2 changes: 1 addition & 1 deletion .github/workflows/test.yml
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ jobs:

strategy:
matrix:
node-version: ['16', '18', '20']
node-version: ['18', '20']

steps:
- uses: actions/checkout@v3
Expand Down
26 changes: 26 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -84,6 +84,32 @@ You can use your own custom store by creating one with the same API as the built
- [Example Custom Store redis](https://github.com/node-cache-manager/node-cache-manager-redis-yet)
- [Example Custom Store ioredis](https://github.com/node-cache-manager/node-cache-manager-ioredis-yet)

#### Create single cache store synchronously

As `caching()` requires async functionality to resolve some stores, this is not well-suited to use for default function/constructor parameters etc.

If you need to create a cache store synchronously, you can instead use `createCache()`:

```typescript
import { createCache, memoryStore } from 'node-cache-manager';

// Create memory cache synchronously
const memoryCache = createCache(memoryStore(), {
max: 100,
ttl: 10 * 1000 /*milliseconds*/,
});

// Default parameter in function
function myService(cache = createCache(memoryStore())) {}

// Default parameter in class constructor
const DEFAULT_CACHE = createCache(memoryStore(), { ttl: 60 * 1000 });
// ...
class MyService {
constructor(private cache = DEFAULT_CACHE) {}
}
```

### Multi-Store

```typescript
Expand Down
5 changes: 4 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -5,10 +5,12 @@
"main": "dist/index.js",
"types": "dist/index.d.ts",
"files": [
"dist"
"dist/**/*.js",
"dist/**/*.d.ts"
],
"scripts": {
"build": "rm -rf dist && tsc -p tsconfig.build.json",
"clean": "rimraf ./dist ./coverage ./node_modules ./package-lock.json ./yarn.lock",
"test": "vitest run --coverage",
"release": "yarn check && yarn test -- --run && yarn build",
"prepare": "yarn build",
Expand Down Expand Up @@ -62,6 +64,7 @@
"eslint-plugin-prettier": "5.0.1",
"lint-staged": "15.1.0",
"prettier": "3.1.0",
"rimraf": "^5.0.5",
"typescript": "5.2.2",
"vitest": "0.34.6"
},
Expand Down
35 changes: 28 additions & 7 deletions src/caching.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { coalesceAsync } from 'promise-coalesce';
import { MemoryCache, MemoryConfig, memoryStore } from './stores';
import { MemoryCache, MemoryConfig, MemoryStore, memoryStore } from './stores';

export type Config = {
ttl?: Milliseconds;
Expand Down Expand Up @@ -63,13 +63,34 @@ export async function caching<S extends Store, T extends object = never>(
export async function caching<S extends Store, T extends object = never>(
factory: Stores<S, T>,
args?: CachingConfig<T>,
): Promise<Cache<S> | MemoryCache> {
let store: Store;
if (factory === 'memory') store = memoryStore(args as MemoryConfig);
else if (typeof factory === 'function')
store = await factory(args as FactoryConfig<T>);
else store = factory;
): Promise<Cache<S> | Cache<Store> | MemoryCache> {
if (factory === 'memory') {
const store = memoryStore(args as MemoryConfig);
return createCache(store, args as MemoryConfig);
}
if (typeof factory === 'function') {
const store = await factory(args as FactoryConfig<T>);
return createCache(store, args);
}

const store = factory;
return createCache(store, args);
}

export function createCache(
store: MemoryStore,
args?: MemoryConfig,
): MemoryCache;

export function createCache(store: Store, args?: Config): Cache<Store>;

/**
* Create cache instance by store (non-async).
*/
export function createCache<S extends Store, C extends Config>(
store: S,
args?: C,
): Cache<S> {
return {
/**
* Wraps a function in cache. I.e., the first time the function is run,
Expand Down
14 changes: 13 additions & 1 deletion test/caching.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import { faker } from '@faker-js/faker';
import promiseCoalesce from 'promise-coalesce';
import { beforeEach, describe, expect, it, vi } from 'vitest';

import { Cache, MemoryConfig, caching, memoryStore } from '../src';
import { caching, Cache, MemoryConfig, memoryStore, createCache } from '../src';
import { sleep } from './utils';

// Allow the module to be mocked so we can assert
Expand Down Expand Up @@ -425,3 +425,15 @@ describe('caching', () => {
expect(callCount).toEqual(2);
});
});

describe('createCache', () => {
it('should create cache instance by store', async () => {
const store = memoryStore();
const cache1 = await caching(store);
const cache2 = createCache(store);
expect(cache1.store).toBe(cache2.store);
Object.entries(cache1).forEach(([key, value]) => {
expect(cache2[key as keyof Cache].toString()).toBe(value.toString());
});
});
});

0 comments on commit a433a5c

Please sign in to comment.