-
-
Notifications
You must be signed in to change notification settings - Fork 0
/
mod.js
76 lines (65 loc) · 2.66 KB
/
mod.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
import { crocks, R, redis, redisCluster } from './deps.js'
import createAdapter from './adapter.js'
const { Async } = crocks
const { Rejected, Resolved, of } = Async
const { defaultTo, mergeRight, isEmpty } = R
/**
* @typedef RedisClientArgs
* @property {string} [hostname]
* @property {number} [port] - defaults to 6379
* @property {string} [url] - a connection string that is parsed to determine Redis configuration
* @property {{ connect: () => Promise<{}> }} [client]
* @property {boolean} [cluster] - defaults to false
* @property {number} [scanCount] - The workload size of scan calls. Defaults to 1000
* @property {boolean} [hashSlot] - whether to hash all keys in each store to a single slot. This is really only necessary,
* if your redis is a cluster. Using the default is recommended. Defaults to true
*
* @param {RedisClientArgs} config
*/
export default function RedisCacheAdapter(config) {
const checkClientArgs = (config) => {
if (config.url) return Resolved(config)
if (config.hostname) return Resolved(config)
return Rejected({
message: 'either a url or hostname must be provided in order to connect to Redis',
})
}
const setPort = (config) => mergeRight({ port: 6379 }, config)
const setScanCount = (config) => mergeRight({ scanCount: 10000 }, config)
const setClient = Async.fromPromise(async (config) => {
const { hostname: _hostname, port: _port, url, cluster, client: _client, hashSlot } = config
const Client = _client || (cluster ? redisCluster : redis)
const configFromUrl = url ? new URL(url) : {}
const hostname = configFromUrl.hostname || _hostname
const port = !isEmpty(configFromUrl)
? Number(configFromUrl.port) || (configFromUrl.protocol === 'https:' ? 443 : 80)
: _port
const password = configFromUrl.password || undefined
let client
if (cluster) {
// redis cluster client
client = await Client.connect({
nodes: [{ hostname, port }],
})
} else {
// regular redis client
client = await Client.connect({ hostname, port, password })
}
return mergeRight(config, { redis: client, hashSlot: hashSlot != null ? hashSlot : true })
})
return Object.freeze({
id: 'redis-cache-adapter',
port: 'cache',
load: (prevLoad) =>
of(prevLoad)
.map(defaultTo({}))
.map((prevLoad) => mergeRight(prevLoad, config || {}))
.chain(checkClientArgs)
.map(setScanCount)
.map(setPort)
.chain(setClient)
.toPromise()
.catch((e) => console.log('Error: In Load Method', e.message)),
link: ({ redis, scanCount, hashSlot }) => (_) => createAdapter({ redis, scanCount, hashSlot }),
})
}