redis-kv-store 1.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/CHANGELOG.md ADDED
@@ -0,0 +1,9 @@
1
+ # 1.0.0 (2022-05-26)
2
+
3
+
4
+ ### Features
5
+
6
+ * **redis:** first working version ([9078b25](https://github.com/nfroidure/redis-kv-store/commit/9078b255bb2d52ff6154224b6f2c013d1bb6fff8))
7
+
8
+
9
+
package/LICENSE ADDED
@@ -0,0 +1,20 @@
1
+ The MIT License (MIT)
2
+ Copyright © 2017 Nicolas Froidure
3
+
4
+ Permission is hereby granted, free of charge, to any person obtaining a copy
5
+ of this software and associated documentation files (the “Software”), to deal
6
+ in the Software without restriction, including without limitation the rights
7
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
8
+ copies of the Software, and to permit persons to whom the Software is
9
+ furnished to do so, subject to the following conditions:
10
+
11
+ The above copyright notice and this permission notice shall be included in
12
+ all copies or substantial portions of the Software.
13
+
14
+ THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
17
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
18
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
19
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
20
+ THE SOFTWARE.
package/README.md ADDED
@@ -0,0 +1,64 @@
1
+ [//]: # ( )
2
+ [//]: # (This file is automatically generated by a `metapak`)
3
+ [//]: # (module. Do not change it except between the)
4
+ [//]: # (`content:start/end` flags, your changes would)
5
+ [//]: # (be overridden.)
6
+ [//]: # ( )
7
+ # redis-kv-store
8
+ > A simple Redis based key/value store.
9
+
10
+ [![GitHub license](https://img.shields.io/badge/license-MIT-blue.svg)](https://github.com/nfroidure/redis-kv-store/blob/master/LICENSE)
11
+ [![Coverage Status](https://coveralls.io/repos/github/nfroidure/redis-kv-store/badge.svg?branch=master)](https://coveralls.io/github/nfroidure/redis-kv-store?branch=master)
12
+
13
+
14
+ [//]: # (::contents:start)
15
+
16
+ This simple project provides a key/value store based on Redis. It has the exact
17
+ same API then the
18
+ [`memory-kv-store`](https://github.com/nfroidure/memory-kv-store) module and
19
+ relies on the [`redis-service`](https://github.com/nfroidure/redis-service)
20
+ module.
21
+
22
+ [//]: # (::contents:end)
23
+
24
+ # API
25
+ <a name="initRedisKV"></a>
26
+
27
+ ## initRedisKV(services) ⇒ <code>Promise.&lt;RedisKVService&gt;</code>
28
+ Instantiate the Redis Key/Value service
29
+
30
+ **Kind**: global function
31
+ **Returns**: <code>Promise.&lt;RedisKVService&gt;</code> - A promise of the Redis Key Value service
32
+
33
+ | Param | Type | Description |
34
+ | --- | --- | --- |
35
+ | services | <code>Object</code> | The services to inject |
36
+ | services.redis | <code>function</code> | A `simple-redis-service` instance |
37
+ | services.log | <code>function</code> | A logging function |
38
+
39
+ **Example**
40
+ ```js
41
+ import initRedisService from 'simple-redis-service';
42
+ import initRedisKV from 'redis-kv-store';
43
+
44
+ const redis = await initRedisService({
45
+ REDIS: {
46
+ host: 'localhost',
47
+ port: 6379,
48
+ },
49
+ ENV: process.env,
50
+ log: console.log.bind(console),
51
+ });
52
+ const redisKV = await initRedisKV({
53
+ redis,
54
+ log: console.log.bind(console),
55
+ });
56
+
57
+ const value = await redisKV.get('my_key');
58
+ ```
59
+
60
+ # Authors
61
+ - [Nicolas Froidure](http://insertafter.com/en/index.html)
62
+
63
+ # License
64
+ [MIT](https://github.com/nfroidure/redis-kv-store/blob/master/LICENSE)
@@ -0,0 +1,10 @@
1
+ import type { LogService } from 'common-services';
2
+ import type { KVStoreService } from 'memory-kv-store';
3
+ import type { RedisService } from 'simple-redis-service';
4
+ export declare type RedisKVService<T> = KVStoreService<T>;
5
+ export declare type RedisKVDependencies = {
6
+ redis: RedisService;
7
+ log: LogService;
8
+ };
9
+ declare const _default: import("knifecycle").ServiceInitializer<RedisKVDependencies, KVStoreService<unknown>>;
10
+ export default _default;
package/dist/index.js ADDED
@@ -0,0 +1,89 @@
1
+ "use strict";
2
+
3
+ Object.defineProperty(exports, "__esModule", {
4
+ value: true
5
+ });
6
+ exports.default = void 0;
7
+
8
+ var _knifecycle = require("knifecycle");
9
+
10
+ var _default = (0, _knifecycle.autoService)(initRedisKV);
11
+ /**
12
+ * Instantiate the Redis Key/Value service
13
+ * @name initRedisKV
14
+ * @function
15
+ * @param {Object} services
16
+ * The services to inject
17
+ * @param {Function} services.redis
18
+ * A `simple-redis-service` instance
19
+ * @param {Function} services.log
20
+ * A logging function
21
+ * @return {Promise<RedisKVService>}
22
+ * A promise of the Redis Key Value service
23
+ * @example
24
+ * import initRedisService from 'simple-redis-service';
25
+ * import initRedisKV from 'redis-kv-store';
26
+ *
27
+ * const redis = await initRedisService({
28
+ * REDIS: {
29
+ * host: 'localhost',
30
+ * port: 6379,
31
+ * },
32
+ * ENV: process.env,
33
+ * log: console.log.bind(console),
34
+ * });
35
+ * const redisKV = await initRedisKV({
36
+ * redis,
37
+ * log: console.log.bind(console),
38
+ * });
39
+ *
40
+ * const value = await redisKV.get('my_key');
41
+ */
42
+
43
+
44
+ exports.default = _default;
45
+
46
+ async function initRedisKV({
47
+ redis,
48
+ log
49
+ }) {
50
+ log('warning', `🏧 - Redis KV Store Service initialized!`);
51
+ const redisKV = {
52
+ get: async key => {
53
+ const result = await redis.get(key);
54
+ return castRedisResult(result);
55
+ },
56
+ set: async (key, value, ttl) => {
57
+ if (typeof ttl !== 'undefined') {
58
+ await redis.set(key, prepareRedisValue(value), 'PX', ttl);
59
+ } else {
60
+ await redis.set(key, prepareRedisValue(value));
61
+ }
62
+ },
63
+ delete: async key => {
64
+ await redis.del(key);
65
+ },
66
+ bulkGet: async keys => {
67
+ return (await redis.mget(keys)).map(result => castRedisResult(result));
68
+ },
69
+ bulkSet: async (keys, values, ttls = []) => {
70
+ await Promise.all(keys.map((key, index) => {
71
+ const value = values[index];
72
+ return redisKV.set(key, value, ttls[index]);
73
+ }));
74
+ },
75
+ bulkDelete: async keys => {
76
+ await redis.del(...keys);
77
+ }
78
+ };
79
+ return redisKV;
80
+ }
81
+
82
+ function castRedisResult(result) {
83
+ return result == null || result === '' ? undefined : JSON.parse(result);
84
+ }
85
+
86
+ function prepareRedisValue(value) {
87
+ return value == null ? '' : JSON.stringify(value);
88
+ }
89
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","names":["autoService","initRedisKV","redis","log","redisKV","get","key","result","castRedisResult","set","value","ttl","prepareRedisValue","delete","del","bulkGet","keys","mget","map","bulkSet","values","ttls","Promise","all","index","bulkDelete","undefined","JSON","parse","stringify"],"sources":["../src/index.ts"],"sourcesContent":["import { autoService } from 'knifecycle';\nimport type { LogService } from 'common-services';\nimport type { KVStoreService } from 'memory-kv-store';\nimport type { RedisService } from 'simple-redis-service';\n\n/* Architecture Note #1: Redis Key/Value Service\n\nA `redis` based key/value service.\n*/\n\nexport type RedisKVService<T> = KVStoreService<T>;\nexport type RedisKVDependencies = {\n redis: RedisService;\n log: LogService;\n};\n\nexport default autoService(initRedisKV);\n\n/**\n * Instantiate the Redis Key/Value service\n * @name initRedisKV\n * @function\n * @param {Object} services\n * The services to inject\n * @param {Function} services.redis\n * A `simple-redis-service` instance\n * @param {Function} services.log\n * A logging function\n * @return {Promise<RedisKVService>}\n * A promise of the Redis Key Value service\n * @example\n * import initRedisService from 'simple-redis-service';\n * import initRedisKV from 'redis-kv-store';\n *\n * const redis = await initRedisService({\n * REDIS: {\n * host: 'localhost',\n * port: 6379,\n * },\n * ENV: process.env,\n * log: console.log.bind(console),\n * });\n * const redisKV = await initRedisKV({\n * redis,\n * log: console.log.bind(console),\n * });\n *\n * const value = await redisKV.get('my_key');\n */\nasync function initRedisKV<T>({\n redis,\n log,\n}: RedisKVDependencies): Promise<KVStoreService<T>> {\n log('warning', `🏧 - Redis KV Store Service initialized!`);\n\n const redisKV = {\n get: async (key: string): Promise<T | undefined> => {\n const result = await redis.get(key);\n return castRedisResult<T>(result);\n },\n set: async (\n key: string,\n value: T | undefined,\n ttl?: number,\n ): Promise<void> => {\n if (typeof ttl !== 'undefined') {\n await redis.set(key, prepareRedisValue<T>(value), 'PX', ttl);\n } else {\n await redis.set(key, prepareRedisValue<T>(value));\n }\n },\n delete: async (key: string): Promise<void> => {\n await redis.del(key);\n },\n bulkGet: async (keys: string[]): Promise<(T | undefined)[]> => {\n return (await redis.mget(keys)).map((result) =>\n castRedisResult<T>(result),\n );\n },\n bulkSet: async (\n keys: string[],\n values: (T | undefined)[],\n ttls: number[] = [],\n ) => {\n await Promise.all(\n keys.map((key, index) => {\n const value = values[index];\n\n return redisKV.set(key, value, ttls[index]);\n }),\n );\n },\n bulkDelete: async (keys: string[]) => {\n await redis.del(...keys);\n },\n };\n\n return redisKV;\n}\n\nfunction castRedisResult<T>(result: string | null | undefined): T {\n return result == null || result === '' ? undefined : JSON.parse(result);\n}\n\nfunction prepareRedisValue<T>(value: T | undefined): string {\n return value == null ? '' : JSON.stringify(value);\n}\n"],"mappings":";;;;;;;AAAA;;eAgBe,IAAAA,uBAAA,EAAYC,WAAZ,C;AAEf;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;AACA,eAAeA,WAAf,CAA8B;EAC5BC,KAD4B;EAE5BC;AAF4B,CAA9B,EAGoD;EAClDA,GAAG,CAAC,SAAD,EAAa,0CAAb,CAAH;EAEA,MAAMC,OAAO,GAAG;IACdC,GAAG,EAAE,MAAOC,GAAP,IAA+C;MAClD,MAAMC,MAAM,GAAG,MAAML,KAAK,CAACG,GAAN,CAAUC,GAAV,CAArB;MACA,OAAOE,eAAe,CAAID,MAAJ,CAAtB;IACD,CAJa;IAKdE,GAAG,EAAE,OACHH,GADG,EAEHI,KAFG,EAGHC,GAHG,KAIe;MAClB,IAAI,OAAOA,GAAP,KAAe,WAAnB,EAAgC;QAC9B,MAAMT,KAAK,CAACO,GAAN,CAAUH,GAAV,EAAeM,iBAAiB,CAAIF,KAAJ,CAAhC,EAA4C,IAA5C,EAAkDC,GAAlD,CAAN;MACD,CAFD,MAEO;QACL,MAAMT,KAAK,CAACO,GAAN,CAAUH,GAAV,EAAeM,iBAAiB,CAAIF,KAAJ,CAAhC,CAAN;MACD;IACF,CAfa;IAgBdG,MAAM,EAAE,MAAOP,GAAP,IAAsC;MAC5C,MAAMJ,KAAK,CAACY,GAAN,CAAUR,GAAV,CAAN;IACD,CAlBa;IAmBdS,OAAO,EAAE,MAAOC,IAAP,IAAsD;MAC7D,OAAO,CAAC,MAAMd,KAAK,CAACe,IAAN,CAAWD,IAAX,CAAP,EAAyBE,GAAzB,CAA8BX,MAAD,IAClCC,eAAe,CAAID,MAAJ,CADV,CAAP;IAGD,CAvBa;IAwBdY,OAAO,EAAE,OACPH,IADO,EAEPI,MAFO,EAGPC,IAAc,GAAG,EAHV,KAIJ;MACH,MAAMC,OAAO,CAACC,GAAR,CACJP,IAAI,CAACE,GAAL,CAAS,CAACZ,GAAD,EAAMkB,KAAN,KAAgB;QACvB,MAAMd,KAAK,GAAGU,MAAM,CAACI,KAAD,CAApB;QAEA,OAAOpB,OAAO,CAACK,GAAR,CAAYH,GAAZ,EAAiBI,KAAjB,EAAwBW,IAAI,CAACG,KAAD,CAA5B,CAAP;MACD,CAJD,CADI,CAAN;IAOD,CApCa;IAqCdC,UAAU,EAAE,MAAOT,IAAP,IAA0B;MACpC,MAAMd,KAAK,CAACY,GAAN,CAAU,GAAGE,IAAb,CAAN;IACD;EAvCa,CAAhB;EA0CA,OAAOZ,OAAP;AACD;;AAED,SAASI,eAAT,CAA4BD,MAA5B,EAAkE;EAChE,OAAOA,MAAM,IAAI,IAAV,IAAkBA,MAAM,KAAK,EAA7B,GAAkCmB,SAAlC,GAA8CC,IAAI,CAACC,KAAL,CAAWrB,MAAX,CAArD;AACD;;AAED,SAASK,iBAAT,CAA8BF,KAA9B,EAA4D;EAC1D,OAAOA,KAAK,IAAI,IAAT,GAAgB,EAAhB,GAAqBiB,IAAI,CAACE,SAAL,CAAenB,KAAf,CAA5B;AACD"}
package/dist/index.mjs ADDED
@@ -0,0 +1,47 @@
1
+ import { autoService } from 'knifecycle';
2
+ export default autoService(initRedisKV);
3
+
4
+ async function initRedisKV({
5
+ redis,
6
+ log
7
+ }) {
8
+ log('warning', `🏧 - Redis KV Store Service initialized!`);
9
+ const redisKV = {
10
+ get: async key => {
11
+ const result = await redis.get(key);
12
+ return castRedisResult(result);
13
+ },
14
+ set: async (key, value, ttl) => {
15
+ if (typeof ttl !== 'undefined') {
16
+ await redis.set(key, prepareRedisValue(value), 'PX', ttl);
17
+ } else {
18
+ await redis.set(key, prepareRedisValue(value));
19
+ }
20
+ },
21
+ delete: async key => {
22
+ await redis.del(key);
23
+ },
24
+ bulkGet: async keys => {
25
+ return (await redis.mget(keys)).map(result => castRedisResult(result));
26
+ },
27
+ bulkSet: async (keys, values, ttls = []) => {
28
+ await Promise.all(keys.map((key, index) => {
29
+ const value = values[index];
30
+ return redisKV.set(key, value, ttls[index]);
31
+ }));
32
+ },
33
+ bulkDelete: async keys => {
34
+ await redis.del(...keys);
35
+ }
36
+ };
37
+ return redisKV;
38
+ }
39
+
40
+ function castRedisResult(result) {
41
+ return result == null || result === '' ? undefined : JSON.parse(result);
42
+ }
43
+
44
+ function prepareRedisValue(value) {
45
+ return value == null ? '' : JSON.stringify(value);
46
+ }
47
+ //# sourceMappingURL=index.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.mjs","names":["autoService","initRedisKV","redis","log","redisKV","get","key","result","castRedisResult","set","value","ttl","prepareRedisValue","delete","del","bulkGet","keys","mget","map","bulkSet","values","ttls","Promise","all","index","bulkDelete","undefined","JSON","parse","stringify"],"sources":["../src/index.ts"],"sourcesContent":["import { autoService } from 'knifecycle';\nimport type { LogService } from 'common-services';\nimport type { KVStoreService } from 'memory-kv-store';\nimport type { RedisService } from 'simple-redis-service';\n\n/* Architecture Note #1: Redis Key/Value Service\n\nA `redis` based key/value service.\n*/\n\nexport type RedisKVService<T> = KVStoreService<T>;\nexport type RedisKVDependencies = {\n redis: RedisService;\n log: LogService;\n};\n\nexport default autoService(initRedisKV);\n\n/**\n * Instantiate the Redis Key/Value service\n * @name initRedisKV\n * @function\n * @param {Object} services\n * The services to inject\n * @param {Function} services.redis\n * A `simple-redis-service` instance\n * @param {Function} services.log\n * A logging function\n * @return {Promise<RedisKVService>}\n * A promise of the Redis Key Value service\n * @example\n * import initRedisService from 'simple-redis-service';\n * import initRedisKV from 'redis-kv-store';\n *\n * const redis = await initRedisService({\n * REDIS: {\n * host: 'localhost',\n * port: 6379,\n * },\n * ENV: process.env,\n * log: console.log.bind(console),\n * });\n * const redisKV = await initRedisKV({\n * redis,\n * log: console.log.bind(console),\n * });\n *\n * const value = await redisKV.get('my_key');\n */\nasync function initRedisKV<T>({\n redis,\n log,\n}: RedisKVDependencies): Promise<KVStoreService<T>> {\n log('warning', `🏧 - Redis KV Store Service initialized!`);\n\n const redisKV = {\n get: async (key: string): Promise<T | undefined> => {\n const result = await redis.get(key);\n return castRedisResult<T>(result);\n },\n set: async (\n key: string,\n value: T | undefined,\n ttl?: number,\n ): Promise<void> => {\n if (typeof ttl !== 'undefined') {\n await redis.set(key, prepareRedisValue<T>(value), 'PX', ttl);\n } else {\n await redis.set(key, prepareRedisValue<T>(value));\n }\n },\n delete: async (key: string): Promise<void> => {\n await redis.del(key);\n },\n bulkGet: async (keys: string[]): Promise<(T | undefined)[]> => {\n return (await redis.mget(keys)).map((result) =>\n castRedisResult<T>(result),\n );\n },\n bulkSet: async (\n keys: string[],\n values: (T | undefined)[],\n ttls: number[] = [],\n ) => {\n await Promise.all(\n keys.map((key, index) => {\n const value = values[index];\n\n return redisKV.set(key, value, ttls[index]);\n }),\n );\n },\n bulkDelete: async (keys: string[]) => {\n await redis.del(...keys);\n },\n };\n\n return redisKV;\n}\n\nfunction castRedisResult<T>(result: string | null | undefined): T {\n return result == null || result === '' ? undefined : JSON.parse(result);\n}\n\nfunction prepareRedisValue<T>(value: T | undefined): string {\n return value == null ? '' : JSON.stringify(value);\n}\n"],"mappings":"AAAA,SAASA,WAAT,QAA4B,YAA5B;AAgBA,eAAeA,WAAW,CAACC,WAAD,CAA1B;;AAiCA,eAAeA,WAAf,CAA8B;EAC5BC,KAD4B;EAE5BC;AAF4B,CAA9B,EAGoD;EAClDA,GAAG,CAAC,SAAD,EAAa,0CAAb,CAAH;EAEA,MAAMC,OAAO,GAAG;IACdC,GAAG,EAAE,MAAOC,GAAP,IAA+C;MAClD,MAAMC,MAAM,GAAG,MAAML,KAAK,CAACG,GAAN,CAAUC,GAAV,CAArB;MACA,OAAOE,eAAe,CAAID,MAAJ,CAAtB;IACD,CAJa;IAKdE,GAAG,EAAE,OACHH,GADG,EAEHI,KAFG,EAGHC,GAHG,KAIe;MAClB,IAAI,OAAOA,GAAP,KAAe,WAAnB,EAAgC;QAC9B,MAAMT,KAAK,CAACO,GAAN,CAAUH,GAAV,EAAeM,iBAAiB,CAAIF,KAAJ,CAAhC,EAA4C,IAA5C,EAAkDC,GAAlD,CAAN;MACD,CAFD,MAEO;QACL,MAAMT,KAAK,CAACO,GAAN,CAAUH,GAAV,EAAeM,iBAAiB,CAAIF,KAAJ,CAAhC,CAAN;MACD;IACF,CAfa;IAgBdG,MAAM,EAAE,MAAOP,GAAP,IAAsC;MAC5C,MAAMJ,KAAK,CAACY,GAAN,CAAUR,GAAV,CAAN;IACD,CAlBa;IAmBdS,OAAO,EAAE,MAAOC,IAAP,IAAsD;MAC7D,OAAO,CAAC,MAAMd,KAAK,CAACe,IAAN,CAAWD,IAAX,CAAP,EAAyBE,GAAzB,CAA8BX,MAAD,IAClCC,eAAe,CAAID,MAAJ,CADV,CAAP;IAGD,CAvBa;IAwBdY,OAAO,EAAE,OACPH,IADO,EAEPI,MAFO,EAGPC,IAAc,GAAG,EAHV,KAIJ;MACH,MAAMC,OAAO,CAACC,GAAR,CACJP,IAAI,CAACE,GAAL,CAAS,CAACZ,GAAD,EAAMkB,KAAN,KAAgB;QACvB,MAAMd,KAAK,GAAGU,MAAM,CAACI,KAAD,CAApB;QAEA,OAAOpB,OAAO,CAACK,GAAR,CAAYH,GAAZ,EAAiBI,KAAjB,EAAwBW,IAAI,CAACG,KAAD,CAA5B,CAAP;MACD,CAJD,CADI,CAAN;IAOD,CApCa;IAqCdC,UAAU,EAAE,MAAOT,IAAP,IAA0B;MACpC,MAAMd,KAAK,CAACY,GAAN,CAAU,GAAGE,IAAb,CAAN;IACD;EAvCa,CAAhB;EA0CA,OAAOZ,OAAP;AACD;;AAED,SAASI,eAAT,CAA4BD,MAA5B,EAAkE;EAChE,OAAOA,MAAM,IAAI,IAAV,IAAkBA,MAAM,KAAK,EAA7B,GAAkCmB,SAAlC,GAA8CC,IAAI,CAACC,KAAL,CAAWrB,MAAX,CAArD;AACD;;AAED,SAASK,iBAAT,CAA8BF,KAA9B,EAA4D;EAC1D,OAAOA,KAAK,IAAI,IAAT,GAAgB,EAAhB,GAAqBiB,IAAI,CAACE,SAAL,CAAenB,KAAf,CAA5B;AACD"}
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,86 @@
1
+ "use strict";
2
+
3
+ var _knifecycle = require("knifecycle");
4
+
5
+ var _ = _interopRequireDefault(require("."));
6
+
7
+ var _simpleRedisService = _interopRequireDefault(require("simple-redis-service"));
8
+
9
+ function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
10
+
11
+ describe('Redis service', () => {
12
+ let $;
13
+ const log = jest.fn();
14
+ beforeEach(() => {
15
+ log.mockReset();
16
+ $ = new _knifecycle.Knifecycle();
17
+ $.register((0, _knifecycle.constant)('ENV', {}));
18
+ $.register((0, _knifecycle.constant)('log', log));
19
+ $.register((0, _knifecycle.constant)('REDIS', {
20
+ host: 'localhost',
21
+ port: 6379
22
+ }));
23
+ $.register(_simpleRedisService.default);
24
+ $.register(_.default);
25
+ });
26
+ afterEach(async () => {
27
+ await $.destroy();
28
+ });
29
+ it('should init well', async () => {
30
+ const {
31
+ log,
32
+ redisKV
33
+ } = await $.run(['log', 'redisKV']);
34
+ expect(typeof redisKV.get).toEqual('function');
35
+ expect(typeof redisKV.set).toEqual('function');
36
+ expect(log.mock.calls).toMatchInlineSnapshot(`
37
+ Array [
38
+ Array [
39
+ "warning",
40
+ "🏧 - Redis Service initialized!",
41
+ ],
42
+ Array [
43
+ "warning",
44
+ "🏧 - Redis KV Store Service initialized!",
45
+ ],
46
+ ]
47
+ `);
48
+ });
49
+ it('should allow to get a undefined value by its key', async () => {
50
+ const {
51
+ redisKV
52
+ } = await $.run(['redisKV']);
53
+ const value = await redisKV.get('lol');
54
+ expect(value).toEqual(undefined);
55
+ });
56
+ ['trololol', {
57
+ lol: 'lol'
58
+ }, 1, true].forEach(value => {
59
+ it('should allow to set and get a ' + typeof value + ' by its key', async () => {
60
+ const {
61
+ redisKV
62
+ } = await $.run(['redisKV']);
63
+ await redisKV.set('lol', value);
64
+ const retrievedValue = await redisKV.get('lol');
65
+ expect(retrievedValue).toEqual(value);
66
+ });
67
+ });
68
+ it('should allow to bulk get a undefined values by their keys', async () => {
69
+ const {
70
+ redisKV
71
+ } = await $.run(['redisKV']);
72
+ const values = await redisKV.bulkGet(['lollolo', 'kikoolol']);
73
+ expect(values).toEqual([undefined, undefined]);
74
+ });
75
+ it('should allow to set and get values by their keys', async () => {
76
+ const keys = ['a', 'b', 'c', 'd'];
77
+ const values = [1, 2, undefined, 4];
78
+ const {
79
+ redisKV
80
+ } = await $.run(['redisKV']);
81
+ await redisKV.bulkSet(keys, values);
82
+ const retrievedValues = await redisKV.bulkGet(keys);
83
+ expect(retrievedValues).toEqual(values);
84
+ });
85
+ });
86
+ //# sourceMappingURL=index.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.test.js","names":["describe","$","log","jest","fn","beforeEach","mockReset","Knifecycle","register","constant","host","port","initRedisService","initRedisKVService","afterEach","destroy","it","redisKV","run","expect","get","toEqual","set","mock","calls","toMatchInlineSnapshot","value","undefined","lol","forEach","retrievedValue","values","bulkGet","keys","bulkSet","retrievedValues"],"sources":["../src/index.test.ts"],"sourcesContent":["import { constant, Knifecycle } from 'knifecycle';\nimport initRedisKVService from '.';\nimport initRedisService from 'simple-redis-service';\nimport type { RedisKVService } from '.';\nimport type { RedisConfig } from 'simple-redis-service';\n\ndescribe('Redis service', () => {\n let $: Knifecycle;\n const log = jest.fn();\n\n beforeEach(() => {\n log.mockReset();\n $ = new Knifecycle();\n $.register(constant('ENV', {}));\n $.register(constant('log', log));\n $.register(\n constant('REDIS', {\n host: 'localhost',\n port: 6379,\n } as RedisConfig),\n );\n $.register(initRedisService);\n $.register(initRedisKVService);\n });\n\n afterEach(async () => {\n await $.destroy();\n });\n\n it('should init well', async () => {\n const { log, redisKV } = (await $.run(['log', 'redisKV'])) as {\n redisKV: RedisKVService<unknown>;\n log: jest.Mock;\n };\n\n expect(typeof redisKV.get).toEqual('function');\n expect(typeof redisKV.set).toEqual('function');\n expect(log.mock.calls).toMatchInlineSnapshot(`\n Array [\n Array [\n \"warning\",\n \"🏧 - Redis Service initialized!\",\n ],\n Array [\n \"warning\",\n \"🏧 - Redis KV Store Service initialized!\",\n ],\n ]\n `);\n });\n\n it('should allow to get a undefined value by its key', async () => {\n const { redisKV } = (await $.run(['redisKV'])) as {\n redisKV: RedisKVService<number>;\n };\n\n const value = await redisKV.get('lol');\n\n expect(value).toEqual(undefined);\n });\n\n ['trololol', { lol: 'lol' }, 1, true].forEach((value) => {\n it(\n 'should allow to set and get a ' + typeof value + ' by its key',\n async () => {\n const { redisKV } = (await $.run(['redisKV'])) as {\n redisKV: RedisKVService<typeof value>;\n };\n\n await redisKV.set('lol', value);\n\n const retrievedValue = await redisKV.get('lol');\n\n expect(retrievedValue).toEqual(value);\n },\n );\n });\n\n it('should allow to bulk get a undefined values by their keys', async () => {\n const { redisKV } = (await $.run(['redisKV'])) as {\n redisKV: RedisKVService<number>;\n };\n\n const values = await redisKV.bulkGet(['lollolo', 'kikoolol']);\n\n expect(values).toEqual([undefined, undefined]);\n });\n\n it('should allow to set and get values by their keys', async () => {\n const keys = ['a', 'b', 'c', 'd'];\n const values = [1, 2, undefined, 4];\n\n const { redisKV } = (await $.run(['redisKV'])) as {\n redisKV: RedisKVService<number>;\n };\n\n await redisKV.bulkSet(keys, values);\n\n const retrievedValues = await redisKV.bulkGet(keys);\n\n expect(retrievedValues).toEqual(values);\n });\n});\n"],"mappings":"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"}
@@ -0,0 +1,79 @@
1
+ import { constant, Knifecycle } from 'knifecycle';
2
+ import initRedisKVService from '.';
3
+ import initRedisService from 'simple-redis-service';
4
+ describe('Redis service', () => {
5
+ let $;
6
+ const log = jest.fn();
7
+ beforeEach(() => {
8
+ log.mockReset();
9
+ $ = new Knifecycle();
10
+ $.register(constant('ENV', {}));
11
+ $.register(constant('log', log));
12
+ $.register(constant('REDIS', {
13
+ host: 'localhost',
14
+ port: 6379
15
+ }));
16
+ $.register(initRedisService);
17
+ $.register(initRedisKVService);
18
+ });
19
+ afterEach(async () => {
20
+ await $.destroy();
21
+ });
22
+ it('should init well', async () => {
23
+ const {
24
+ log,
25
+ redisKV
26
+ } = await $.run(['log', 'redisKV']);
27
+ expect(typeof redisKV.get).toEqual('function');
28
+ expect(typeof redisKV.set).toEqual('function');
29
+ expect(log.mock.calls).toMatchInlineSnapshot(`
30
+ Array [
31
+ Array [
32
+ "warning",
33
+ "🏧 - Redis Service initialized!",
34
+ ],
35
+ Array [
36
+ "warning",
37
+ "🏧 - Redis KV Store Service initialized!",
38
+ ],
39
+ ]
40
+ `);
41
+ });
42
+ it('should allow to get a undefined value by its key', async () => {
43
+ const {
44
+ redisKV
45
+ } = await $.run(['redisKV']);
46
+ const value = await redisKV.get('lol');
47
+ expect(value).toEqual(undefined);
48
+ });
49
+ ['trololol', {
50
+ lol: 'lol'
51
+ }, 1, true].forEach(value => {
52
+ it('should allow to set and get a ' + typeof value + ' by its key', async () => {
53
+ const {
54
+ redisKV
55
+ } = await $.run(['redisKV']);
56
+ await redisKV.set('lol', value);
57
+ const retrievedValue = await redisKV.get('lol');
58
+ expect(retrievedValue).toEqual(value);
59
+ });
60
+ });
61
+ it('should allow to bulk get a undefined values by their keys', async () => {
62
+ const {
63
+ redisKV
64
+ } = await $.run(['redisKV']);
65
+ const values = await redisKV.bulkGet(['lollolo', 'kikoolol']);
66
+ expect(values).toEqual([undefined, undefined]);
67
+ });
68
+ it('should allow to set and get values by their keys', async () => {
69
+ const keys = ['a', 'b', 'c', 'd'];
70
+ const values = [1, 2, undefined, 4];
71
+ const {
72
+ redisKV
73
+ } = await $.run(['redisKV']);
74
+ await redisKV.bulkSet(keys, values);
75
+ const retrievedValues = await redisKV.bulkGet(keys);
76
+ expect(retrievedValues).toEqual(values);
77
+ });
78
+ });
79
+ //# sourceMappingURL=index.test.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.test.mjs","names":["constant","Knifecycle","initRedisKVService","initRedisService","describe","$","log","jest","fn","beforeEach","mockReset","register","host","port","afterEach","destroy","it","redisKV","run","expect","get","toEqual","set","mock","calls","toMatchInlineSnapshot","value","undefined","lol","forEach","retrievedValue","values","bulkGet","keys","bulkSet","retrievedValues"],"sources":["../src/index.test.ts"],"sourcesContent":["import { constant, Knifecycle } from 'knifecycle';\nimport initRedisKVService from '.';\nimport initRedisService from 'simple-redis-service';\nimport type { RedisKVService } from '.';\nimport type { RedisConfig } from 'simple-redis-service';\n\ndescribe('Redis service', () => {\n let $: Knifecycle;\n const log = jest.fn();\n\n beforeEach(() => {\n log.mockReset();\n $ = new Knifecycle();\n $.register(constant('ENV', {}));\n $.register(constant('log', log));\n $.register(\n constant('REDIS', {\n host: 'localhost',\n port: 6379,\n } as RedisConfig),\n );\n $.register(initRedisService);\n $.register(initRedisKVService);\n });\n\n afterEach(async () => {\n await $.destroy();\n });\n\n it('should init well', async () => {\n const { log, redisKV } = (await $.run(['log', 'redisKV'])) as {\n redisKV: RedisKVService<unknown>;\n log: jest.Mock;\n };\n\n expect(typeof redisKV.get).toEqual('function');\n expect(typeof redisKV.set).toEqual('function');\n expect(log.mock.calls).toMatchInlineSnapshot(`\n Array [\n Array [\n \"warning\",\n \"🏧 - Redis Service initialized!\",\n ],\n Array [\n \"warning\",\n \"🏧 - Redis KV Store Service initialized!\",\n ],\n ]\n `);\n });\n\n it('should allow to get a undefined value by its key', async () => {\n const { redisKV } = (await $.run(['redisKV'])) as {\n redisKV: RedisKVService<number>;\n };\n\n const value = await redisKV.get('lol');\n\n expect(value).toEqual(undefined);\n });\n\n ['trololol', { lol: 'lol' }, 1, true].forEach((value) => {\n it(\n 'should allow to set and get a ' + typeof value + ' by its key',\n async () => {\n const { redisKV } = (await $.run(['redisKV'])) as {\n redisKV: RedisKVService<typeof value>;\n };\n\n await redisKV.set('lol', value);\n\n const retrievedValue = await redisKV.get('lol');\n\n expect(retrievedValue).toEqual(value);\n },\n );\n });\n\n it('should allow to bulk get a undefined values by their keys', async () => {\n const { redisKV } = (await $.run(['redisKV'])) as {\n redisKV: RedisKVService<number>;\n };\n\n const values = await redisKV.bulkGet(['lollolo', 'kikoolol']);\n\n expect(values).toEqual([undefined, undefined]);\n });\n\n it('should allow to set and get values by their keys', async () => {\n const keys = ['a', 'b', 'c', 'd'];\n const values = [1, 2, undefined, 4];\n\n const { redisKV } = (await $.run(['redisKV'])) as {\n redisKV: RedisKVService<number>;\n };\n\n await redisKV.bulkSet(keys, values);\n\n const retrievedValues = await redisKV.bulkGet(keys);\n\n expect(retrievedValues).toEqual(values);\n });\n});\n"],"mappings":"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"}
package/package.json ADDED
@@ -0,0 +1,243 @@
1
+ {
2
+ "name": "redis-kv-store",
3
+ "version": "1.0.0",
4
+ "description": "A simple Redis based key/value store.",
5
+ "main": "dist/index",
6
+ "module": "dist/index.mjs",
7
+ "types": "dist/index.d.ts",
8
+ "metapak": {
9
+ "data": {
10
+ "files": "'src/**/*.ts'",
11
+ "testsFiles": "'src/**/*.tests.ts'",
12
+ "distFiles": "'dist/**/*.js'",
13
+ "ignore": [
14
+ "dist"
15
+ ],
16
+ "bundleFiles": [
17
+ "dist",
18
+ "src"
19
+ ]
20
+ },
21
+ "configs": [
22
+ "main",
23
+ "readme",
24
+ "eslint",
25
+ "babel",
26
+ "typescript",
27
+ "jest",
28
+ "jsdocs",
29
+ "jsarch",
30
+ "codeclimate"
31
+ ]
32
+ },
33
+ "scripts": {
34
+ "architecture": "jsarch 'src/**/*.ts' > ARCHITECTURE.md && git add ARCHITECTURE.md",
35
+ "changelog": "conventional-changelog -p angular -i CHANGELOG.md -s && git add CHANGELOG.md",
36
+ "cli": "env NODE_ENV=${NODE_ENV:-cli}",
37
+ "compile": "rimraf -f 'dist' && npm run compile:cjs && npm run compile:mjs",
38
+ "compile:cjs": "babel --env-name=cjs --out-dir=dist --extensions '.ts,.js' --source-maps=true src",
39
+ "compile:mjs": "babel --env-name=mjs --out-file-extension=.mjs --out-dir=dist --extensions '.ts,.js' --source-maps=true src",
40
+ "cover": "npm run jest -- --coverage",
41
+ "coveralls": "npm run cover && cat ./coverage/lcov.info | coveralls && rm -rf ./coverage",
42
+ "cz": "env NODE_ENV=${NODE_ENV:-cli} git cz",
43
+ "doc": "echo \"# API\" > API.md; jsdoc2md 'dist/**/*.js' >> API.md && git add API.md",
44
+ "jest": "NODE_ENV=test jest",
45
+ "lint": "eslint 'src/**/*.ts'",
46
+ "metapak": "metapak",
47
+ "precz": "npm run compile && npm run types && npm run doc && npm run architecture && npm t && npm run lint && npm run metapak -- -s",
48
+ "prettier": "prettier --write 'src/**/*.ts'",
49
+ "preversion": "npm run compile && npm run types && npm run doc && npm run architecture && npm t && npm run lint && npm run metapak -- -s",
50
+ "test": "npm run jest",
51
+ "types": "rimraf -f 'dist/**/*.d.ts' && tsc --project . --declaration --emitDeclarationOnly --outDir dist",
52
+ "version": "npm run changelog && git add CHANGELOG.md"
53
+ },
54
+ "repository": {
55
+ "type": "git",
56
+ "url": "git+https://github.com/nfroidure/redis-kv-store.git"
57
+ },
58
+ "author": {
59
+ "name": "Nicolas Froidure",
60
+ "email": "nicolas.froidure@insertafter.com",
61
+ "url": "http://insertafter.com/en/index.html"
62
+ },
63
+ "license": "MIT",
64
+ "bugs": {
65
+ "url": "https://github.com/nfroidure/redis-kv-store/issues"
66
+ },
67
+ "homepage": "https://github.com/nfroidure/redis-kv-store#readme",
68
+ "dependencies": {
69
+ "common-services": "^10.0.2",
70
+ "knifecycle": "12.0.4",
71
+ "memory-kv-store": "^5.0.1",
72
+ "simple-redis-service": "^1.0.0"
73
+ },
74
+ "devDependencies": {
75
+ "@babel/cli": "^7.17.10",
76
+ "@babel/core": "^7.18.2",
77
+ "@babel/eslint-parser": "^7.18.2",
78
+ "@babel/plugin-proposal-class-properties": "^7.17.12",
79
+ "@babel/plugin-proposal-object-rest-spread": "^7.18.0",
80
+ "@babel/preset-env": "^7.18.2",
81
+ "@babel/preset-typescript": "^7.17.12",
82
+ "@babel/register": "^7.17.7",
83
+ "@types/jest": "^27.0.2",
84
+ "@typescript-eslint/eslint-plugin": "^5.26.0",
85
+ "@typescript-eslint/parser": "^5.26.0",
86
+ "commitizen": "^4.2.4",
87
+ "conventional-changelog-cli": "^2.2.2",
88
+ "coveralls": "^3.1.1",
89
+ "cz-conventional-changelog": "^3.3.0",
90
+ "eslint": "^8.16.0",
91
+ "eslint-plugin-prettier": "^4.0.0",
92
+ "jest": "^28.1.0",
93
+ "jsarch": "^5.0.1",
94
+ "jsdoc-to-markdown": "^7.1.1",
95
+ "metapak": "^4.0.3",
96
+ "metapak-nfroidure": "11.2.1",
97
+ "prettier": "^2.6.2",
98
+ "rimraf": "^3.0.2",
99
+ "typescript": "^4.7.2"
100
+ },
101
+ "engines": {
102
+ "node": ">=12.19.0"
103
+ },
104
+ "config": {
105
+ "commitizen": {
106
+ "path": "./node_modules/cz-conventional-changelog"
107
+ }
108
+ },
109
+ "greenkeeper": {
110
+ "ignore": [
111
+ "commitizen",
112
+ "cz-conventional-changelog",
113
+ "conventional-changelog-cli",
114
+ "eslint",
115
+ "eslint-config-prettier",
116
+ "prettier",
117
+ "@typescript-eslint/parser",
118
+ "@babel/cli",
119
+ "@babel/core",
120
+ "@babel/register",
121
+ "@babel/preset-env",
122
+ "@babel/plugin-proposal-object-rest-spread",
123
+ "@babel/preset-typescript",
124
+ "@babel/plugin-proposal-class-properties",
125
+ "babel-eslint",
126
+ "babel-core",
127
+ "typescript",
128
+ "jest",
129
+ "coveralls",
130
+ "jsdoc-to-markdown",
131
+ "jsarch"
132
+ ]
133
+ },
134
+ "eslintConfig": {
135
+ "extends": [
136
+ "eslint:recommended",
137
+ "plugin:@typescript-eslint/eslint-recommended",
138
+ "plugin:@typescript-eslint/recommended"
139
+ ],
140
+ "parserOptions": {
141
+ "ecmaVersion": 2018,
142
+ "sourceType": "module",
143
+ "modules": true
144
+ },
145
+ "env": {
146
+ "es6": true,
147
+ "node": true,
148
+ "jest": true,
149
+ "mocha": true
150
+ },
151
+ "plugins": [
152
+ "prettier"
153
+ ],
154
+ "rules": {
155
+ "prettier/prettier": "error"
156
+ },
157
+ "parser": "@typescript-eslint/parser",
158
+ "ignorePatterns": [
159
+ "*.d.ts"
160
+ ]
161
+ },
162
+ "prettier": {
163
+ "semi": true,
164
+ "printWidth": 80,
165
+ "singleQuote": true,
166
+ "trailingComma": "all",
167
+ "proseWrap": "always"
168
+ },
169
+ "contributors": [],
170
+ "files": [
171
+ "dist",
172
+ "src",
173
+ "LICENSE",
174
+ "README.md",
175
+ "CHANGELOG.md"
176
+ ],
177
+ "jsarch": {
178
+ "parserOptions": {
179
+ "plugins": [
180
+ "typescript"
181
+ ]
182
+ }
183
+ },
184
+ "jest": {
185
+ "coverageReporters": [
186
+ "lcov"
187
+ ],
188
+ "testPathIgnorePatterns": [
189
+ "/node_modules/"
190
+ ],
191
+ "roots": [
192
+ "<rootDir>/src"
193
+ ]
194
+ },
195
+ "babel": {
196
+ "plugins": [
197
+ "@babel/proposal-class-properties",
198
+ "@babel/plugin-proposal-object-rest-spread"
199
+ ],
200
+ "presets": [
201
+ "@babel/typescript",
202
+ [
203
+ "@babel/env",
204
+ {
205
+ "targets": {
206
+ "node": "12.19.0"
207
+ }
208
+ }
209
+ ]
210
+ ],
211
+ "env": {
212
+ "cjs": {
213
+ "presets": [
214
+ [
215
+ "@babel/env",
216
+ {
217
+ "targets": {
218
+ "node": "10"
219
+ },
220
+ "modules": "commonjs"
221
+ }
222
+ ]
223
+ ],
224
+ "comments": true
225
+ },
226
+ "mjs": {
227
+ "presets": [
228
+ [
229
+ "@babel/env",
230
+ {
231
+ "targets": {
232
+ "node": "12"
233
+ },
234
+ "modules": false
235
+ }
236
+ ]
237
+ ],
238
+ "comments": false
239
+ }
240
+ },
241
+ "sourceMaps": true
242
+ }
243
+ }
@@ -0,0 +1,103 @@
1
+ import { constant, Knifecycle } from 'knifecycle';
2
+ import initRedisKVService from '.';
3
+ import initRedisService from 'simple-redis-service';
4
+ import type { RedisKVService } from '.';
5
+ import type { RedisConfig } from 'simple-redis-service';
6
+
7
+ describe('Redis service', () => {
8
+ let $: Knifecycle;
9
+ const log = jest.fn();
10
+
11
+ beforeEach(() => {
12
+ log.mockReset();
13
+ $ = new Knifecycle();
14
+ $.register(constant('ENV', {}));
15
+ $.register(constant('log', log));
16
+ $.register(
17
+ constant('REDIS', {
18
+ host: 'localhost',
19
+ port: 6379,
20
+ } as RedisConfig),
21
+ );
22
+ $.register(initRedisService);
23
+ $.register(initRedisKVService);
24
+ });
25
+
26
+ afterEach(async () => {
27
+ await $.destroy();
28
+ });
29
+
30
+ it('should init well', async () => {
31
+ const { log, redisKV } = (await $.run(['log', 'redisKV'])) as {
32
+ redisKV: RedisKVService<unknown>;
33
+ log: jest.Mock;
34
+ };
35
+
36
+ expect(typeof redisKV.get).toEqual('function');
37
+ expect(typeof redisKV.set).toEqual('function');
38
+ expect(log.mock.calls).toMatchInlineSnapshot(`
39
+ Array [
40
+ Array [
41
+ "warning",
42
+ "🏧 - Redis Service initialized!",
43
+ ],
44
+ Array [
45
+ "warning",
46
+ "🏧 - Redis KV Store Service initialized!",
47
+ ],
48
+ ]
49
+ `);
50
+ });
51
+
52
+ it('should allow to get a undefined value by its key', async () => {
53
+ const { redisKV } = (await $.run(['redisKV'])) as {
54
+ redisKV: RedisKVService<number>;
55
+ };
56
+
57
+ const value = await redisKV.get('lol');
58
+
59
+ expect(value).toEqual(undefined);
60
+ });
61
+
62
+ ['trololol', { lol: 'lol' }, 1, true].forEach((value) => {
63
+ it(
64
+ 'should allow to set and get a ' + typeof value + ' by its key',
65
+ async () => {
66
+ const { redisKV } = (await $.run(['redisKV'])) as {
67
+ redisKV: RedisKVService<typeof value>;
68
+ };
69
+
70
+ await redisKV.set('lol', value);
71
+
72
+ const retrievedValue = await redisKV.get('lol');
73
+
74
+ expect(retrievedValue).toEqual(value);
75
+ },
76
+ );
77
+ });
78
+
79
+ it('should allow to bulk get a undefined values by their keys', async () => {
80
+ const { redisKV } = (await $.run(['redisKV'])) as {
81
+ redisKV: RedisKVService<number>;
82
+ };
83
+
84
+ const values = await redisKV.bulkGet(['lollolo', 'kikoolol']);
85
+
86
+ expect(values).toEqual([undefined, undefined]);
87
+ });
88
+
89
+ it('should allow to set and get values by their keys', async () => {
90
+ const keys = ['a', 'b', 'c', 'd'];
91
+ const values = [1, 2, undefined, 4];
92
+
93
+ const { redisKV } = (await $.run(['redisKV'])) as {
94
+ redisKV: RedisKVService<number>;
95
+ };
96
+
97
+ await redisKV.bulkSet(keys, values);
98
+
99
+ const retrievedValues = await redisKV.bulkGet(keys);
100
+
101
+ expect(retrievedValues).toEqual(values);
102
+ });
103
+ });
package/src/index.ts ADDED
@@ -0,0 +1,107 @@
1
+ import { autoService } from 'knifecycle';
2
+ import type { LogService } from 'common-services';
3
+ import type { KVStoreService } from 'memory-kv-store';
4
+ import type { RedisService } from 'simple-redis-service';
5
+
6
+ /* Architecture Note #1: Redis Key/Value Service
7
+
8
+ A `redis` based key/value service.
9
+ */
10
+
11
+ export type RedisKVService<T> = KVStoreService<T>;
12
+ export type RedisKVDependencies = {
13
+ redis: RedisService;
14
+ log: LogService;
15
+ };
16
+
17
+ export default autoService(initRedisKV);
18
+
19
+ /**
20
+ * Instantiate the Redis Key/Value service
21
+ * @name initRedisKV
22
+ * @function
23
+ * @param {Object} services
24
+ * The services to inject
25
+ * @param {Function} services.redis
26
+ * A `simple-redis-service` instance
27
+ * @param {Function} services.log
28
+ * A logging function
29
+ * @return {Promise<RedisKVService>}
30
+ * A promise of the Redis Key Value service
31
+ * @example
32
+ * import initRedisService from 'simple-redis-service';
33
+ * import initRedisKV from 'redis-kv-store';
34
+ *
35
+ * const redis = await initRedisService({
36
+ * REDIS: {
37
+ * host: 'localhost',
38
+ * port: 6379,
39
+ * },
40
+ * ENV: process.env,
41
+ * log: console.log.bind(console),
42
+ * });
43
+ * const redisKV = await initRedisKV({
44
+ * redis,
45
+ * log: console.log.bind(console),
46
+ * });
47
+ *
48
+ * const value = await redisKV.get('my_key');
49
+ */
50
+ async function initRedisKV<T>({
51
+ redis,
52
+ log,
53
+ }: RedisKVDependencies): Promise<KVStoreService<T>> {
54
+ log('warning', `🏧 - Redis KV Store Service initialized!`);
55
+
56
+ const redisKV = {
57
+ get: async (key: string): Promise<T | undefined> => {
58
+ const result = await redis.get(key);
59
+ return castRedisResult<T>(result);
60
+ },
61
+ set: async (
62
+ key: string,
63
+ value: T | undefined,
64
+ ttl?: number,
65
+ ): Promise<void> => {
66
+ if (typeof ttl !== 'undefined') {
67
+ await redis.set(key, prepareRedisValue<T>(value), 'PX', ttl);
68
+ } else {
69
+ await redis.set(key, prepareRedisValue<T>(value));
70
+ }
71
+ },
72
+ delete: async (key: string): Promise<void> => {
73
+ await redis.del(key);
74
+ },
75
+ bulkGet: async (keys: string[]): Promise<(T | undefined)[]> => {
76
+ return (await redis.mget(keys)).map((result) =>
77
+ castRedisResult<T>(result),
78
+ );
79
+ },
80
+ bulkSet: async (
81
+ keys: string[],
82
+ values: (T | undefined)[],
83
+ ttls: number[] = [],
84
+ ) => {
85
+ await Promise.all(
86
+ keys.map((key, index) => {
87
+ const value = values[index];
88
+
89
+ return redisKV.set(key, value, ttls[index]);
90
+ }),
91
+ );
92
+ },
93
+ bulkDelete: async (keys: string[]) => {
94
+ await redis.del(...keys);
95
+ },
96
+ };
97
+
98
+ return redisKV;
99
+ }
100
+
101
+ function castRedisResult<T>(result: string | null | undefined): T {
102
+ return result == null || result === '' ? undefined : JSON.parse(result);
103
+ }
104
+
105
+ function prepareRedisValue<T>(value: T | undefined): string {
106
+ return value == null ? '' : JSON.stringify(value);
107
+ }