lemon-core 4.1.14 → 4.2.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.
Files changed (154) hide show
  1. package/dist/common/test-helper.d.ts +2 -2
  2. package/dist/common/test-helper.js +24 -26
  3. package/dist/common/test-helper.js.map +1 -1
  4. package/dist/controllers/dummy-controller.js +39 -46
  5. package/dist/controllers/dummy-controller.js.map +1 -1
  6. package/dist/controllers/general-api-controller.js +95 -100
  7. package/dist/controllers/general-api-controller.js.map +1 -1
  8. package/dist/controllers/general-controller.js +81 -82
  9. package/dist/controllers/general-controller.js.map +1 -1
  10. package/dist/cores/api/api-service.d.ts +1 -1
  11. package/dist/cores/api/api-service.js +228 -269
  12. package/dist/cores/api/api-service.js.map +1 -1
  13. package/dist/cores/aws/aws-kms-service.d.ts +1 -2
  14. package/dist/cores/aws/aws-kms-service.js +143 -153
  15. package/dist/cores/aws/aws-kms-service.js.map +1 -1
  16. package/dist/cores/aws/aws-s3-service.d.ts +2 -4
  17. package/dist/cores/aws/aws-s3-service.js +306 -330
  18. package/dist/cores/aws/aws-s3-service.js.map +1 -1
  19. package/dist/cores/aws/aws-sns-service.js +147 -153
  20. package/dist/cores/aws/aws-sns-service.js.map +1 -1
  21. package/dist/cores/aws/aws-sqs-service.js +149 -170
  22. package/dist/cores/aws/aws-sqs-service.js.map +1 -1
  23. package/dist/cores/aws/index.js +10 -20
  24. package/dist/cores/aws/index.js.map +1 -1
  25. package/dist/cores/cache/cache-service.d.ts +2 -2
  26. package/dist/cores/cache/cache-service.js +435 -499
  27. package/dist/cores/cache/cache-service.js.map +1 -1
  28. package/dist/cores/config/config-service.d.ts +1 -1
  29. package/dist/cores/config/config-service.js +56 -63
  30. package/dist/cores/config/config-service.js.map +1 -1
  31. package/dist/cores/config/index.js +14 -24
  32. package/dist/cores/config/index.js.map +1 -1
  33. package/dist/cores/core-services.d.ts +1 -1
  34. package/dist/cores/dynamo/dynamo-query-service.js +37 -51
  35. package/dist/cores/dynamo/dynamo-query-service.js.map +1 -1
  36. package/dist/cores/dynamo/dynamo-scan-service.d.ts +2 -2
  37. package/dist/cores/dynamo/dynamo-scan-service.js +29 -40
  38. package/dist/cores/dynamo/dynamo-scan-service.js.map +1 -1
  39. package/dist/cores/dynamo/dynamo-service.d.ts +2 -2
  40. package/dist/cores/dynamo/dynamo-service.js +528 -601
  41. package/dist/cores/dynamo/dynamo-service.js.map +1 -1
  42. package/dist/cores/dynamo/tools/expressions.js +17 -7
  43. package/dist/cores/dynamo/tools/expressions.js.map +1 -1
  44. package/dist/cores/dynamo/tools/query.js +142 -127
  45. package/dist/cores/dynamo/tools/query.js.map +1 -1
  46. package/dist/cores/dynamo/tools/scan.js +111 -97
  47. package/dist/cores/dynamo/tools/scan.js.map +1 -1
  48. package/dist/cores/dynamo/tools/serializer.js +17 -7
  49. package/dist/cores/dynamo/tools/serializer.js.map +1 -1
  50. package/dist/cores/dynamo/tools/utils.d.ts +0 -2
  51. package/dist/cores/dynamo/tools/utils.js.map +1 -1
  52. package/dist/cores/elastic/elastic6-query-service.js +307 -324
  53. package/dist/cores/elastic/elastic6-query-service.js.map +1 -1
  54. package/dist/cores/elastic/elastic6-service.d.ts +3 -3
  55. package/dist/cores/elastic/elastic6-service.js +568 -647
  56. package/dist/cores/elastic/elastic6-service.js.map +1 -1
  57. package/dist/cores/elastic/hangul-service.js +52 -54
  58. package/dist/cores/elastic/hangul-service.js.map +1 -1
  59. package/dist/cores/lambda/index.js +42 -36
  60. package/dist/cores/lambda/index.js.map +1 -1
  61. package/dist/cores/lambda/lambda-alb-handler.d.ts +2 -2
  62. package/dist/cores/lambda/lambda-alb-handler.js +59 -72
  63. package/dist/cores/lambda/lambda-alb-handler.js.map +1 -1
  64. package/dist/cores/lambda/lambda-cognito-handler.js +10 -19
  65. package/dist/cores/lambda/lambda-cognito-handler.js.map +1 -1
  66. package/dist/cores/lambda/lambda-cron-handler.d.ts +1 -1
  67. package/dist/cores/lambda/lambda-cron-handler.js +14 -23
  68. package/dist/cores/lambda/lambda-cron-handler.js.map +1 -1
  69. package/dist/cores/lambda/lambda-dynamo-stream-handler.d.ts +2 -2
  70. package/dist/cores/lambda/lambda-dynamo-stream-handler.js +57 -67
  71. package/dist/cores/lambda/lambda-dynamo-stream-handler.js.map +1 -1
  72. package/dist/cores/lambda/lambda-handler.d.ts +22 -22
  73. package/dist/cores/lambda/lambda-handler.js +93 -106
  74. package/dist/cores/lambda/lambda-handler.js.map +1 -1
  75. package/dist/cores/lambda/lambda-notification-handler.d.ts +1 -1
  76. package/dist/cores/lambda/lambda-notification-handler.js +39 -50
  77. package/dist/cores/lambda/lambda-notification-handler.js.map +1 -1
  78. package/dist/cores/lambda/lambda-sns-handler.js +79 -88
  79. package/dist/cores/lambda/lambda-sns-handler.js.map +1 -1
  80. package/dist/cores/lambda/lambda-sqs-handler.js +79 -88
  81. package/dist/cores/lambda/lambda-sqs-handler.js.map +1 -1
  82. package/dist/cores/lambda/lambda-web-handler.d.ts +21 -43
  83. package/dist/cores/lambda/lambda-web-handler.js +392 -482
  84. package/dist/cores/lambda/lambda-web-handler.js.map +1 -1
  85. package/dist/cores/lambda/lambda-wss-handler.js +23 -32
  86. package/dist/cores/lambda/lambda-wss-handler.js.map +1 -1
  87. package/dist/cores/protocol/index.js +10 -20
  88. package/dist/cores/protocol/index.js.map +1 -1
  89. package/dist/cores/protocol/protocol-service.d.ts +3 -3
  90. package/dist/cores/protocol/protocol-service.js +235 -227
  91. package/dist/cores/protocol/protocol-service.js.map +1 -1
  92. package/dist/cores/storage/http-storage-service.js +65 -85
  93. package/dist/cores/storage/http-storage-service.js.map +1 -1
  94. package/dist/cores/storage/model-manager.js +66 -85
  95. package/dist/cores/storage/model-manager.js.map +1 -1
  96. package/dist/cores/storage/proxy-storage-service.d.ts +2 -2
  97. package/dist/cores/storage/proxy-storage-service.js +562 -599
  98. package/dist/cores/storage/proxy-storage-service.js.map +1 -1
  99. package/dist/cores/storage/redis-storage-service.js +163 -177
  100. package/dist/cores/storage/redis-storage-service.js.map +1 -1
  101. package/dist/cores/storage/storage-service.js +281 -322
  102. package/dist/cores/storage/storage-service.js.map +1 -1
  103. package/dist/engine/builder.d.ts +1 -1
  104. package/dist/engine/builder.js +59 -63
  105. package/dist/engine/builder.js.map +1 -1
  106. package/dist/engine/engine.d.ts +4 -4
  107. package/dist/engine/engine.js +9 -18
  108. package/dist/engine/engine.js.map +1 -1
  109. package/dist/engine/types.d.ts +1 -1
  110. package/dist/engine/utilities.d.ts +14 -10
  111. package/dist/engine/utilities.js +301 -280
  112. package/dist/engine/utilities.js.map +1 -1
  113. package/dist/environ.js +4 -6
  114. package/dist/environ.js.map +1 -1
  115. package/dist/extended/abstract-service.js +595 -645
  116. package/dist/extended/abstract-service.js.map +1 -1
  117. package/dist/extended/libs/sig-v4.js.map +1 -1
  118. package/dist/generated/field-registry.d.ts +10 -0
  119. package/dist/generated/field-registry.js +17 -0
  120. package/dist/generated/field-registry.js.map +1 -0
  121. package/dist/helpers/helpers.d.ts +17 -9
  122. package/dist/helpers/helpers.js +88 -78
  123. package/dist/helpers/helpers.js.map +1 -1
  124. package/dist/index.js +17 -7
  125. package/dist/index.js.map +1 -1
  126. package/dist/lib/dynamodb-value.js +2 -3
  127. package/dist/lib/dynamodb-value.js.map +1 -1
  128. package/dist/tools/express.js +4 -5
  129. package/dist/tools/express.js.map +1 -1
  130. package/dist/tools/tools.d.ts +3 -1
  131. package/dist/tools/tools.js +14 -21
  132. package/dist/tools/tools.js.map +1 -1
  133. package/package.json +19 -18
  134. package/dist/exec-cli.d.ts +0 -2
  135. package/dist/exec-cli.js +0 -211
  136. package/dist/exec-cli.js.map +0 -1
  137. package/dist/lib/dynamo/expressions.d.ts +0 -14
  138. package/dist/lib/dynamo/expressions.js +0 -212
  139. package/dist/lib/dynamo/expressions.js.map +0 -1
  140. package/dist/lib/dynamo/query.d.ts +0 -43
  141. package/dist/lib/dynamo/query.js +0 -246
  142. package/dist/lib/dynamo/query.js.map +0 -1
  143. package/dist/lib/dynamo/scan.d.ts +0 -33
  144. package/dist/lib/dynamo/scan.js +0 -172
  145. package/dist/lib/dynamo/scan.js.map +0 -1
  146. package/dist/lib/dynamo/serializer.d.ts +0 -12
  147. package/dist/lib/dynamo/serializer.js +0 -243
  148. package/dist/lib/dynamo/serializer.js.map +0 -1
  149. package/dist/lib/dynamo/utils.d.ts +0 -15
  150. package/dist/lib/dynamo/utils.js +0 -129
  151. package/dist/lib/dynamo/utils.js.map +0 -1
  152. package/dist/tools/shared.d.ts +0 -37
  153. package/dist/tools/shared.js +0 -130
  154. package/dist/tools/shared.js.map +0 -1
@@ -1,18 +1,12 @@
1
1
  "use strict";
2
- var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
3
- function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
4
- return new (P || (P = Promise))(function (resolve, reject) {
5
- function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
6
- function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
7
- function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
8
- step((generator = generator.apply(thisArg, _arguments || [])).next());
9
- });
10
- };
11
2
  var __importDefault = (this && this.__importDefault) || function (mod) {
12
3
  return (mod && mod.__esModule) ? mod : { "default": mod };
13
4
  };
14
5
  Object.defineProperty(exports, "__esModule", { value: true });
15
- exports.fromTTL = exports.toTTL = exports.sleep = exports.DummyCacheService = exports.CacheService = void 0;
6
+ exports.DummyCacheService = exports.CacheService = void 0;
7
+ exports.sleep = sleep;
8
+ exports.toTTL = toTTL;
9
+ exports.fromTTL = fromTTL;
16
10
  /**
17
11
  * `cache-services.ts`
18
12
  * - common service for remote cache
@@ -36,23 +30,43 @@ const NS = engine_1.$U.NS('CCHS', 'green'); // NAMESPACE TO BE PRINTED.
36
30
  */
37
31
  class CacheService {
38
32
  /**
39
- * Protected constructor -> use CacheService.create()
40
- * WARN! - do not create directly.˜
41
- *
42
- * @param backend cache backend object
43
- * @param params params to create service.
44
- * @protected
33
+ * Environment variable name for cache server endpoint
34
+ * @static
45
35
  */
46
- constructor(backend, params) {
47
- if (!backend)
48
- throw new Error(`@backend (cache-backend) is required!`);
49
- const ns = (params === null || params === void 0 ? void 0 : params.ns) || '';
50
- (0, engine_1._inf)(NS, `! cache-service instantiated with [${backend.name}] backend. [ns=${ns}]`);
51
- this.backend = backend;
52
- this.ns = ns;
53
- this.options = params.options;
54
- this.maker = params === null || params === void 0 ? void 0 : params.maker;
55
- }
36
+ static ENV_CACHE_ENDPOINT = 'CACHE_ENDPOINT';
37
+ /**
38
+ * Environment variable name for default cache timeout
39
+ * @static
40
+ */
41
+ static ENV_CACHE_DEFAULT_TIMEOUT = 'CACHE_DEFAULT_TIMEOUT';
42
+ /**
43
+ * Default cache timeout
44
+ * @static
45
+ */
46
+ static DEF_CACHE_DEFAULT_TIMEOUT = 24 * 60 * 60; // 1-day
47
+ /**
48
+ * Namespace delimiter
49
+ * @private
50
+ * @static
51
+ */
52
+ static NAMESPACE_DELIMITER = '::';
53
+ /**
54
+ * Namespace of cache key
55
+ */
56
+ ns;
57
+ /**
58
+ * the final options to create this service.
59
+ */
60
+ options;
61
+ /**
62
+ * maker of cache-key
63
+ */
64
+ maker;
65
+ /**
66
+ * Cache backend instance
67
+ * @private
68
+ */
69
+ backend;
56
70
  /**
57
71
  * Factory method
58
72
  *
@@ -61,11 +75,11 @@ class CacheService {
61
75
  * @static
62
76
  */
63
77
  static create(options, maker) {
64
- const type = (options === null || options === void 0 ? void 0 : options.type) || 'redis';
65
- const endpoint = (options === null || options === void 0 ? void 0 : options.endpoint) || engine_1.$U.env(CacheService.ENV_CACHE_ENDPOINT);
66
- const ns = (options === null || options === void 0 ? void 0 : options.ns) || '';
67
- const defTimeout = engine_1.$U.N(options === null || options === void 0 ? void 0 : options.defTimeout, engine_1.$U.N(engine_1.$U.env(CacheService.ENV_CACHE_DEFAULT_TIMEOUT), CacheService.DEF_CACHE_DEFAULT_TIMEOUT));
68
- options = Object.assign(Object.assign({}, options), { type, endpoint, ns, defTimeout });
78
+ const type = options?.type || 'redis';
79
+ const endpoint = options?.endpoint || engine_1.$U.env(CacheService.ENV_CACHE_ENDPOINT);
80
+ const ns = options?.ns || '';
81
+ const defTimeout = engine_1.$U.N(options?.defTimeout, engine_1.$U.N(engine_1.$U.env(CacheService.ENV_CACHE_DEFAULT_TIMEOUT), CacheService.DEF_CACHE_DEFAULT_TIMEOUT));
82
+ options = { ...options, type, endpoint, ns, defTimeout };
69
83
  (0, engine_1._log)(NS, `constructing [${type}] cache ...`);
70
84
  (0, engine_1._log)(NS, ` > endpoint =`, endpoint);
71
85
  (0, engine_1._log)(NS, ` > ns =`, ns);
@@ -83,6 +97,24 @@ class CacheService {
83
97
  }
84
98
  return new CacheService(backend, { ns, options, maker });
85
99
  }
100
+ /**
101
+ * Protected constructor -> use CacheService.create()
102
+ * WARN! - do not create directly.˜
103
+ *
104
+ * @param backend cache backend object
105
+ * @param params params to create service.
106
+ * @protected
107
+ */
108
+ constructor(backend, params) {
109
+ if (!backend)
110
+ throw new Error(`@backend (cache-backend) is required!`);
111
+ const ns = params?.ns || '';
112
+ (0, engine_1._inf)(NS, `! cache-service instantiated with [${backend.name}] backend. [ns=${ns}]`);
113
+ this.backend = backend;
114
+ this.ns = ns;
115
+ this.options = params.options;
116
+ this.maker = params?.maker;
117
+ }
86
118
  /**
87
119
  * Say hello
88
120
  */
@@ -105,41 +137,35 @@ class CacheService {
105
137
  /**
106
138
  * Close backend and connection
107
139
  */
108
- close() {
109
- return __awaiter(this, void 0, void 0, function* () {
110
- yield this.backend.close();
111
- });
140
+ async close() {
141
+ await this.backend.close();
112
142
  }
113
143
  /**
114
144
  * Check whether the key is cached
115
145
  *
116
146
  * @return true if the key is cached
117
147
  */
118
- exists(key) {
119
- return __awaiter(this, void 0, void 0, function* () {
120
- const namespacedKey = this.asNamespacedKey(key);
121
- const ret = yield this.backend.has(namespacedKey);
122
- (0, engine_1._log)(NS, `.exists ${namespacedKey} / ret =`, typeof ret === 'string' ? ret : engine_1.$U.json(ret));
123
- return ret;
124
- });
148
+ async exists(key) {
149
+ const namespacedKey = this.asNamespacedKey(key);
150
+ const ret = await this.backend.has(namespacedKey);
151
+ (0, engine_1._log)(NS, `.exists ${namespacedKey} / ret =`, typeof ret === 'string' ? ret : engine_1.$U.json(ret));
152
+ return ret;
125
153
  }
126
154
  /**
127
155
  * List all keys
128
156
  *
129
157
  * @return list of keys
130
158
  */
131
- keys() {
132
- return __awaiter(this, void 0, void 0, function* () {
133
- const namespacedKeys = yield this.backend.keys();
134
- const ret = namespacedKeys.reduce((keys, namespacedKey) => {
135
- const [ns, key] = namespacedKey.split(CacheService.NAMESPACE_DELIMITER);
136
- if (ns === this.ns)
137
- keys.push(key);
138
- return keys;
139
- }, []);
140
- (0, engine_1._log)(NS, `.keys / ret =`, typeof ret === 'string' ? ret : engine_1.$U.json(ret));
141
- return ret;
142
- });
159
+ async keys() {
160
+ const namespacedKeys = await this.backend.keys();
161
+ const ret = namespacedKeys.reduce((keys, namespacedKey) => {
162
+ const [ns, key] = namespacedKey.split(CacheService.NAMESPACE_DELIMITER);
163
+ if (ns === this.ns)
164
+ keys.push(key);
165
+ return keys;
166
+ }, []);
167
+ (0, engine_1._log)(NS, `.keys / ret =`, typeof ret === 'string' ? ret : engine_1.$U.json(ret));
168
+ return ret;
143
169
  }
144
170
  /**
145
171
  * Store a key
@@ -149,18 +175,16 @@ class CacheService {
149
175
  * @param timeout (optional) TTL in seconds or Timeout object
150
176
  * @return true on success
151
177
  */
152
- set(key, val, timeout) {
153
- return __awaiter(this, void 0, void 0, function* () {
154
- if (!key)
155
- throw new Error(`@key (CacheKey) is required.`);
156
- if (val === undefined)
157
- throw new Error(`@val (CacheValue) cannot be undefined.`);
158
- const namespacedKey = this.asNamespacedKey(key);
159
- const ttl = timeout && toTTL(timeout);
160
- const ret = yield this.backend.set(namespacedKey, val, ttl);
161
- (0, engine_1._log)(NS, `.set ${namespacedKey} ${val} / ret =`, typeof ret === 'string' ? ret : engine_1.$U.json(ret));
162
- return ret;
163
- });
178
+ async set(key, val, timeout) {
179
+ if (!key)
180
+ throw new Error(`@key (CacheKey) is required.`);
181
+ if (val === undefined)
182
+ throw new Error(`@val (CacheValue) cannot be undefined.`);
183
+ const namespacedKey = this.asNamespacedKey(key);
184
+ const ttl = timeout && toTTL(timeout);
185
+ const ret = await this.backend.set(namespacedKey, val, ttl);
186
+ (0, engine_1._log)(NS, `.set ${namespacedKey} ${val} / ret =`, typeof ret === 'string' ? ret : engine_1.$U.json(ret));
187
+ return ret;
164
188
  }
165
189
  /**
166
190
  * Store multiple keys
@@ -168,61 +192,55 @@ class CacheService {
168
192
  * @param entries
169
193
  * @return true on success
170
194
  */
171
- setMulti(entries) {
172
- return __awaiter(this, void 0, void 0, function* () {
173
- const param = entries.map(({ key, val, timeout }, idx) => {
174
- if (!key)
175
- throw new Error(`.key (CacheKey) is required (at @entries[${idx}]).`);
176
- if (val === undefined)
177
- throw new Error(`.val (CacheValue) cannot be undefined (at @entries[${idx}]).`);
178
- return {
179
- key: this.asNamespacedKey(key),
180
- val,
181
- ttl: timeout && toTTL(timeout),
182
- };
183
- });
184
- const ret = yield this.backend.mset(param);
185
- (0, engine_1._log)(NS, `.setMulti ${entries.map(entry => entry.key)} / ret =`, typeof ret === 'string' ? ret : engine_1.$U.json(ret));
186
- return ret;
195
+ async setMulti(entries) {
196
+ const param = entries.map(({ key, val, timeout }, idx) => {
197
+ if (!key)
198
+ throw new Error(`.key (CacheKey) is required (at @entries[${idx}]).`);
199
+ if (val === undefined)
200
+ throw new Error(`.val (CacheValue) cannot be undefined (at @entries[${idx}]).`);
201
+ return {
202
+ key: this.asNamespacedKey(key),
203
+ val,
204
+ ttl: timeout && toTTL(timeout),
205
+ };
187
206
  });
207
+ const ret = await this.backend.mset(param);
208
+ (0, engine_1._log)(NS, `.setMulti ${entries.map(entry => entry.key)} / ret =`, typeof ret === 'string' ? ret : engine_1.$U.json(ret));
209
+ return ret;
188
210
  }
189
211
  /**
190
212
  * Retrieve a key
191
213
  *
192
214
  * @param key
193
215
  */
194
- get(key) {
195
- return __awaiter(this, void 0, void 0, function* () {
196
- if (!key)
197
- throw new Error(`@key (CacheKey) is required.`);
198
- const namespacedKey = this.asNamespacedKey(key);
199
- const ret = yield this.backend.get(namespacedKey);
200
- (0, engine_1._log)(NS, `.get ${namespacedKey} / ret =`, typeof ret === 'string' ? ret : engine_1.$U.json(ret));
201
- return ret;
202
- });
216
+ async get(key) {
217
+ if (!key)
218
+ throw new Error(`@key (CacheKey) is required.`);
219
+ const namespacedKey = this.asNamespacedKey(key);
220
+ const ret = await this.backend.get(namespacedKey);
221
+ (0, engine_1._log)(NS, `.get ${namespacedKey} / ret =`, typeof ret === 'string' ? ret : engine_1.$U.json(ret));
222
+ return ret;
203
223
  }
204
224
  /**
205
225
  * Get multiple keys
206
226
  *
207
227
  * @param keys
208
228
  */
209
- getMulti(keys) {
210
- return __awaiter(this, void 0, void 0, function* () {
211
- const namespacedKeys = keys.map((key, idx) => {
212
- if (!key)
213
- throw new Error(`@key (CacheKey) is required (at @keys[${idx}]).`);
214
- return this.asNamespacedKey(key);
215
- });
216
- const map = yield this.backend.mget(namespacedKeys);
217
- // Remove namespace prefix from keys
218
- const ret = Object.entries(map).reduce((newMap, [namespacedKey, val]) => {
219
- const key = namespacedKey.split(CacheService.NAMESPACE_DELIMITER)[1];
220
- newMap[key] = val;
221
- return newMap;
222
- }, {});
223
- (0, engine_1._log)(NS, `.getMulti ${namespacedKeys} / ret =`, typeof ret === 'string' ? ret : engine_1.$U.json(ret));
224
- return ret;
229
+ async getMulti(keys) {
230
+ const namespacedKeys = keys.map((key, idx) => {
231
+ if (!key)
232
+ throw new Error(`@key (CacheKey) is required (at @keys[${idx}]).`);
233
+ return this.asNamespacedKey(key);
225
234
  });
235
+ const map = await this.backend.mget(namespacedKeys);
236
+ // Remove namespace prefix from keys
237
+ const ret = Object.entries(map).reduce((newMap, [namespacedKey, val]) => {
238
+ const key = namespacedKey.split(CacheService.NAMESPACE_DELIMITER)[1];
239
+ newMap[key] = val;
240
+ return newMap;
241
+ }, {});
242
+ (0, engine_1._log)(NS, `.getMulti ${namespacedKeys} / ret =`, typeof ret === 'string' ? ret : engine_1.$U.json(ret));
243
+ return ret;
226
244
  }
227
245
  /**
228
246
  * Increment the integer value of a key
@@ -230,17 +248,15 @@ class CacheService {
230
248
  * @param key
231
249
  * @param inc number to increment
232
250
  */
233
- increment(key, inc) {
234
- return __awaiter(this, void 0, void 0, function* () {
235
- if (!key)
236
- throw new Error(`@key (CacheKey) is required.`);
237
- if (inc === undefined)
238
- throw new Error(`@inc (number) cannot be undefined.`);
239
- const namespacedKey = this.asNamespacedKey(key);
240
- const ret = yield this.backend.incr(namespacedKey, inc);
241
- (0, engine_1._log)(NS, `.increment ${namespacedKey} ${inc} / ret =`, typeof ret === 'string' ? ret : engine_1.$U.json(ret));
242
- return ret;
243
- });
251
+ async increment(key, inc) {
252
+ if (!key)
253
+ throw new Error(`@key (CacheKey) is required.`);
254
+ if (inc === undefined)
255
+ throw new Error(`@inc (number) cannot be undefined.`);
256
+ const namespacedKey = this.asNamespacedKey(key);
257
+ const ret = await this.backend.incr(namespacedKey, inc);
258
+ (0, engine_1._log)(NS, `.increment ${namespacedKey} ${inc} / ret =`, typeof ret === 'string' ? ret : engine_1.$U.json(ret));
259
+ return ret;
244
260
  }
245
261
  /**
246
262
  * same as increment()
@@ -251,52 +267,48 @@ class CacheService {
251
267
  /**
252
268
  * Set the value of a key and return its old value
253
269
  */
254
- getAndSet(key, val) {
255
- return __awaiter(this, void 0, void 0, function* () {
256
- if (!key)
257
- throw new Error(`@key (CacheKey) is required.`);
258
- if (val === undefined)
259
- throw new Error(`@val (CacheValue) cannot be undefined.`);
260
- const namespacedKey = this.asNamespacedKey(key);
261
- let ret;
262
- if (this.backend.getset) {
263
- ret = yield this.backend.getset(namespacedKey, val);
264
- }
265
- else {
266
- ret = yield this.backend.get(namespacedKey);
267
- // Best effort to keep remaining TTL
268
- let ttl = yield this.backend.ttl(namespacedKey);
269
- if (ttl !== undefined) {
270
- ttl = Math.ceil(ttl / 1000);
271
- }
272
- if (!(yield this.backend.set(namespacedKey, val, ttl)))
273
- throw new Error(`getAndSet() failed`);
270
+ async getAndSet(key, val) {
271
+ if (!key)
272
+ throw new Error(`@key (CacheKey) is required.`);
273
+ if (val === undefined)
274
+ throw new Error(`@val (CacheValue) cannot be undefined.`);
275
+ const namespacedKey = this.asNamespacedKey(key);
276
+ let ret;
277
+ if (this.backend.getset) {
278
+ ret = await this.backend.getset(namespacedKey, val);
279
+ }
280
+ else {
281
+ ret = await this.backend.get(namespacedKey);
282
+ // Best effort to keep remaining TTL
283
+ let ttl = await this.backend.ttl(namespacedKey);
284
+ if (ttl !== undefined) {
285
+ ttl = Math.ceil(ttl / 1000);
274
286
  }
275
- (0, engine_1._log)(NS, `.getAndSet ${namespacedKey} ${val} / ret =`, typeof ret === 'string' ? ret : engine_1.$U.json(ret));
276
- return ret;
277
- });
287
+ if (!(await this.backend.set(namespacedKey, val, ttl)))
288
+ throw new Error(`getAndSet() failed`);
289
+ }
290
+ (0, engine_1._log)(NS, `.getAndSet ${namespacedKey} ${val} / ret =`, typeof ret === 'string' ? ret : engine_1.$U.json(ret));
291
+ return ret;
278
292
  }
279
293
  /**
280
294
  * Get and delete the key
281
295
  *
282
296
  * @param key
283
297
  */
284
- getAndDelete(key) {
285
- return __awaiter(this, void 0, void 0, function* () {
286
- if (!key)
287
- throw new Error(`@key (CacheKey) is required.`);
288
- const namespacedKey = this.asNamespacedKey(key);
289
- let ret;
290
- if (this.backend.pop) {
291
- ret = yield this.backend.pop(namespacedKey);
292
- }
293
- else {
294
- ret = yield this.backend.get(namespacedKey);
295
- yield this.backend.del(namespacedKey);
296
- }
297
- (0, engine_1._log)(NS, `.getAndDelete ${namespacedKey} / ret =`, typeof ret === 'string' ? ret : engine_1.$U.json(ret));
298
- return ret;
299
- });
298
+ async getAndDelete(key) {
299
+ if (!key)
300
+ throw new Error(`@key (CacheKey) is required.`);
301
+ const namespacedKey = this.asNamespacedKey(key);
302
+ let ret;
303
+ if (this.backend.pop) {
304
+ ret = await this.backend.pop(namespacedKey);
305
+ }
306
+ else {
307
+ ret = await this.backend.get(namespacedKey);
308
+ await this.backend.del(namespacedKey);
309
+ }
310
+ (0, engine_1._log)(NS, `.getAndDelete ${namespacedKey} / ret =`, typeof ret === 'string' ? ret : engine_1.$U.json(ret));
311
+ return ret;
300
312
  }
301
313
  /**
302
314
  * Delete a key
@@ -304,15 +316,13 @@ class CacheService {
304
316
  * @param key
305
317
  * @return true on success
306
318
  */
307
- delete(key) {
308
- return __awaiter(this, void 0, void 0, function* () {
309
- if (!key)
310
- throw new Error(`@key (CacheKey) is required.`);
311
- const namespacedKey = this.asNamespacedKey(key);
312
- const ret = yield this.backend.del(namespacedKey);
313
- (0, engine_1._log)(NS, `.delete ${namespacedKey} / ret =`, typeof ret === 'string' ? ret : engine_1.$U.json(ret));
314
- return ret;
315
- });
319
+ async delete(key) {
320
+ if (!key)
321
+ throw new Error(`@key (CacheKey) is required.`);
322
+ const namespacedKey = this.asNamespacedKey(key);
323
+ const ret = await this.backend.del(namespacedKey);
324
+ (0, engine_1._log)(NS, `.delete ${namespacedKey} / ret =`, typeof ret === 'string' ? ret : engine_1.$U.json(ret));
325
+ return ret;
316
326
  }
317
327
  /**
318
328
  * Delete multiple keys
@@ -320,18 +330,16 @@ class CacheService {
320
330
  * @param keys
321
331
  * @return number of deleted entries
322
332
  */
323
- deleteMulti(keys) {
324
- return __awaiter(this, void 0, void 0, function* () {
325
- const namespacedKeys = keys.map((key, idx) => {
326
- if (!key)
327
- throw new Error(`@key (CacheKey) is required (at @keys[${idx}]).`);
328
- return this.asNamespacedKey(key);
329
- });
330
- const promises = namespacedKeys.map(namespacedKey => this.backend.del(namespacedKey));
331
- const ret = yield Promise.all(promises);
332
- (0, engine_1._log)(NS, `.deleteMulti ${namespacedKeys} / ret =`, typeof ret === 'string' ? ret : engine_1.$U.json(ret));
333
- return ret;
333
+ async deleteMulti(keys) {
334
+ const namespacedKeys = keys.map((key, idx) => {
335
+ if (!key)
336
+ throw new Error(`@key (CacheKey) is required (at @keys[${idx}]).`);
337
+ return this.asNamespacedKey(key);
334
338
  });
339
+ const promises = namespacedKeys.map(namespacedKey => this.backend.del(namespacedKey));
340
+ const ret = await Promise.all(promises);
341
+ (0, engine_1._log)(NS, `.deleteMulti ${namespacedKeys} / ret =`, typeof ret === 'string' ? ret : engine_1.$U.json(ret));
342
+ return ret;
335
343
  }
336
344
  /**
337
345
  * Set or update the timeout of a key
@@ -340,15 +348,13 @@ class CacheService {
340
348
  * @param timeout TTL in seconds or Timeout object
341
349
  * @return true on success
342
350
  */
343
- setTimeout(key, timeout) {
344
- return __awaiter(this, void 0, void 0, function* () {
345
- if (!key)
346
- throw new Error(`@key (CacheKey) is required.`);
347
- const namespacedKey = this.asNamespacedKey(key);
348
- const ret = yield this.backend.expire(namespacedKey, toTTL(timeout));
349
- (0, engine_1._log)(NS, `.setTimeout ${namespacedKey} ${timeout} / ret =`, typeof ret === 'string' ? ret : engine_1.$U.json(ret));
350
- return ret;
351
- });
351
+ async setTimeout(key, timeout) {
352
+ if (!key)
353
+ throw new Error(`@key (CacheKey) is required.`);
354
+ const namespacedKey = this.asNamespacedKey(key);
355
+ const ret = await this.backend.expire(namespacedKey, toTTL(timeout));
356
+ (0, engine_1._log)(NS, `.setTimeout ${namespacedKey} ${timeout} / ret =`, typeof ret === 'string' ? ret : engine_1.$U.json(ret));
357
+ return ret;
352
358
  }
353
359
  /**
354
360
  * Get remaining time to live in milliseconds
@@ -358,30 +364,26 @@ class CacheService {
358
364
  * - undefined if the key does not exist
359
365
  * - 0 if the key has no timeout
360
366
  */
361
- getTimeout(key) {
362
- return __awaiter(this, void 0, void 0, function* () {
363
- if (!key)
364
- throw new Error(`@key (CacheKey) is required.`);
365
- const namespacedKey = this.asNamespacedKey(key);
366
- const ret = yield this.backend.ttl(namespacedKey);
367
- (0, engine_1._log)(NS, `.getTimeout ${namespacedKey} / ret =`, typeof ret === 'string' ? ret : engine_1.$U.json(ret));
368
- return ret;
369
- });
367
+ async getTimeout(key) {
368
+ if (!key)
369
+ throw new Error(`@key (CacheKey) is required.`);
370
+ const namespacedKey = this.asNamespacedKey(key);
371
+ const ret = await this.backend.ttl(namespacedKey);
372
+ (0, engine_1._log)(NS, `.getTimeout ${namespacedKey} / ret =`, typeof ret === 'string' ? ret : engine_1.$U.json(ret));
373
+ return ret;
370
374
  }
371
375
  /**
372
376
  * Remove the timeout from a key
373
377
  *
374
378
  * @param key
375
379
  */
376
- removeTimeout(key) {
377
- return __awaiter(this, void 0, void 0, function* () {
378
- if (!key)
379
- throw new Error(`@key (CacheKey) is required.`);
380
- const namespacedKey = this.asNamespacedKey(key);
381
- const ret = yield this.backend.expire(namespacedKey, 0);
382
- (0, engine_1._log)(NS, `.removeTimeout ${namespacedKey} / ret =`, typeof ret === 'string' ? ret : engine_1.$U.json(ret));
383
- return ret;
384
- });
380
+ async removeTimeout(key) {
381
+ if (!key)
382
+ throw new Error(`@key (CacheKey) is required.`);
383
+ const namespacedKey = this.asNamespacedKey(key);
384
+ const ret = await this.backend.expire(namespacedKey, 0);
385
+ (0, engine_1._log)(NS, `.removeTimeout ${namespacedKey} / ret =`, typeof ret === 'string' ? ret : engine_1.$U.json(ret));
386
+ return ret;
385
387
  }
386
388
  /**
387
389
  * Get namespace prefixed cache key
@@ -397,31 +399,17 @@ class CacheService {
397
399
  }
398
400
  }
399
401
  exports.CacheService = CacheService;
400
- /**
401
- * Environment variable name for cache server endpoint
402
- * @static
403
- */
404
- CacheService.ENV_CACHE_ENDPOINT = 'CACHE_ENDPOINT';
405
- /**
406
- * Environment variable name for default cache timeout
407
- * @static
408
- */
409
- CacheService.ENV_CACHE_DEFAULT_TIMEOUT = 'CACHE_DEFAULT_TIMEOUT';
410
- /**
411
- * Default cache timeout
412
- * @static
413
- */
414
- CacheService.DEF_CACHE_DEFAULT_TIMEOUT = 24 * 60 * 60; // 1-day
415
- /**
416
- * Namespace delimiter
417
- * @private
418
- * @static
419
- */
420
- CacheService.NAMESPACE_DELIMITER = '::';
421
402
  /**
422
403
  * class `DummyCacheService`: use 'node-cache' library
423
404
  */
424
405
  class DummyCacheService extends CacheService {
406
+ /**
407
+ * Singleton node-cache backend
408
+ *
409
+ * @private
410
+ * @static
411
+ */
412
+ static backend;
425
413
  /**
426
414
  * Factory method
427
415
  *
@@ -429,9 +417,9 @@ class DummyCacheService extends CacheService {
429
417
  * @static
430
418
  */
431
419
  static create(options) {
432
- const ns = (options === null || options === void 0 ? void 0 : options.ns) || '';
433
- const defTimeout = engine_1.$U.N(options === null || options === void 0 ? void 0 : options.defTimeout, engine_1.$U.N(engine_1.$U.env(CacheService.ENV_CACHE_DEFAULT_TIMEOUT), CacheService.DEF_CACHE_DEFAULT_TIMEOUT));
434
- options = Object.assign(Object.assign({}, options), { ns, defTimeout });
420
+ const ns = options?.ns || '';
421
+ const defTimeout = engine_1.$U.N(options?.defTimeout, engine_1.$U.N(engine_1.$U.env(CacheService.ENV_CACHE_DEFAULT_TIMEOUT), CacheService.DEF_CACHE_DEFAULT_TIMEOUT));
422
+ options = { ...options, ns, defTimeout };
435
423
  (0, engine_1._log)(NS, `constructing dummy cache ...`);
436
424
  // NOTE: Use singleton backend instance
437
425
  // because node-cache is volatile and client instance does not share keys with other instance
@@ -451,12 +439,9 @@ exports.DummyCacheService = DummyCacheService;
451
439
  * function `sleep`
452
440
  * @param ms duration in milliseconds
453
441
  */
454
- function sleep(ms) {
455
- return __awaiter(this, void 0, void 0, function* () {
456
- return new Promise(resolve => setTimeout(resolve, ms));
457
- });
442
+ async function sleep(ms) {
443
+ return new Promise(resolve => setTimeout(resolve, ms));
458
444
  }
459
- exports.sleep = sleep;
460
445
  /**
461
446
  * Get TTL from timeout
462
447
  * @param timeout timeout in seconds or Timeout object
@@ -480,7 +465,6 @@ function toTTL(timeout) {
480
465
  }
481
466
  throw new Error(`@timeout (number | Timeout) is invalid.`);
482
467
  }
483
- exports.toTTL = toTTL;
484
468
  /**
485
469
  * Get timestamp of expiration from TTL
486
470
  * @param ttl remaining time to live in seconds
@@ -489,7 +473,6 @@ exports.toTTL = toTTL;
489
473
  function fromTTL(ttl) {
490
474
  return ttl > 0 ? Date.now() + ttl * 1000 : 0;
491
475
  }
492
- exports.fromTTL = fromTTL;
493
476
  /** ********************************************************************************************************************
494
477
  * Internal Classes
495
478
  ** ********************************************************************************************************************/
@@ -498,117 +481,98 @@ exports.fromTTL = fromTTL;
498
481
  * @internal
499
482
  */
500
483
  class NodeCacheBackend {
484
+ /**
485
+ * node-cache client
486
+ * @private
487
+ */
488
+ cache;
489
+ /**
490
+ * backend type
491
+ */
492
+ name = 'node-cache';
501
493
  /**
502
494
  * Public constructor
503
495
  */
504
496
  constructor(defTTL = 0) {
505
- /**
506
- * backend type
507
- */
508
- this.name = 'node-cache';
509
497
  this.cache = new node_cache_1.default({ stdTTL: defTTL });
510
498
  }
511
499
  /**
512
500
  * CacheBackend.set implementation
513
501
  */
514
- set(key, val, ttl) {
515
- return __awaiter(this, void 0, void 0, function* () {
516
- return this.cache.set(key, val, ttl);
517
- });
502
+ async set(key, val, ttl) {
503
+ return this.cache.set(key, val, ttl);
518
504
  }
519
505
  /**
520
506
  * CacheBackend.get implementation
521
507
  */
522
- get(key) {
523
- return __awaiter(this, void 0, void 0, function* () {
524
- return this.cache.get(key);
525
- });
508
+ async get(key) {
509
+ return this.cache.get(key);
526
510
  }
527
511
  /**
528
512
  * CacheBackend.mset implementation
529
513
  */
530
- mset(entries) {
531
- return __awaiter(this, void 0, void 0, function* () {
532
- return this.cache.mset(entries);
533
- });
514
+ async mset(entries) {
515
+ return this.cache.mset(entries);
534
516
  }
535
517
  /**
536
518
  * CacheBackend.mget implementation
537
519
  */
538
- mget(keys) {
539
- return __awaiter(this, void 0, void 0, function* () {
540
- return this.cache.mget(keys);
541
- });
520
+ async mget(keys) {
521
+ return this.cache.mget(keys);
542
522
  }
543
523
  /**
544
524
  * CacheBackend.pop implementation
545
525
  */
546
- pop(key) {
547
- return __awaiter(this, void 0, void 0, function* () {
548
- return this.cache.take(key);
549
- });
526
+ async pop(key) {
527
+ return this.cache.take(key);
550
528
  }
551
529
  /**
552
530
  * CacheBackend.incr implementation
553
531
  */
554
- incr(key, increment) {
555
- return __awaiter(this, void 0, void 0, function* () {
556
- const org = this.cache.get(key);
557
- if (typeof org !== 'number')
558
- throw new Error(`@key [${key}] does not hold a number value.`);
559
- const newVal = org + increment;
560
- this.cache.set(key, newVal);
561
- return newVal;
562
- });
532
+ async incr(key, increment) {
533
+ const org = this.cache.get(key);
534
+ if (typeof org !== 'number')
535
+ throw new Error(`@key [${key}] does not hold a number value.`);
536
+ const newVal = org + increment;
537
+ this.cache.set(key, newVal);
538
+ return newVal;
563
539
  }
564
540
  /**
565
541
  * CacheBackend.keys implementation
566
542
  */
567
- keys() {
568
- return __awaiter(this, void 0, void 0, function* () {
569
- return this.cache.keys();
570
- });
543
+ async keys() {
544
+ return this.cache.keys();
571
545
  }
572
546
  /**
573
547
  * CacheBackend.has implementation
574
548
  */
575
- has(key) {
576
- return __awaiter(this, void 0, void 0, function* () {
577
- return this.cache.has(key);
578
- });
549
+ async has(key) {
550
+ return this.cache.has(key);
579
551
  }
580
552
  /**
581
553
  * CacheBackend.del implementation
582
554
  */
583
- del(key) {
584
- return __awaiter(this, void 0, void 0, function* () {
585
- return this.cache.del(key) === 1;
586
- });
555
+ async del(key) {
556
+ return this.cache.del(key) === 1;
587
557
  }
588
558
  /**
589
559
  * CacheBackend.expire implementation
590
560
  */
591
- expire(key, ttl) {
592
- return __awaiter(this, void 0, void 0, function* () {
593
- return this.cache.ttl(key, ttl);
594
- });
561
+ async expire(key, ttl) {
562
+ return this.cache.ttl(key, ttl);
595
563
  }
596
564
  /**
597
565
  * CacheBackend.ttl implementation
598
566
  */
599
- ttl(key) {
600
- return __awaiter(this, void 0, void 0, function* () {
601
- const ts = this.cache.getTtl(key); // Timestamp in milliseconds
602
- return ts && ts - Date.now();
603
- });
567
+ async ttl(key) {
568
+ const ts = this.cache.getTtl(key); // Timestamp in milliseconds
569
+ return ts && ts - Date.now();
604
570
  }
605
571
  /**
606
572
  * CacheBackend.close implementation
607
573
  */
608
- close() {
609
- return __awaiter(this, void 0, void 0, function* () {
610
- this.cache.close();
611
- });
574
+ async close() {
575
+ this.cache.close();
612
576
  }
613
577
  }
614
578
  /**
@@ -616,14 +580,24 @@ class NodeCacheBackend {
616
580
  * @internal
617
581
  */
618
582
  class MemcachedBackend {
583
+ /**
584
+ * Memcached promisified APIs
585
+ * @private
586
+ */
587
+ api;
588
+ /**
589
+ * Default TTL as number in seconds
590
+ * @private
591
+ */
592
+ defTTL;
593
+ /**
594
+ * backend type
595
+ */
596
+ name = 'memcached';
619
597
  /**
620
598
  * Public constructor
621
599
  */
622
600
  constructor(endpoint, defTTL = 0) {
623
- /**
624
- * backend type
625
- */
626
- this.name = 'memcached';
627
601
  const memcached = new memcached_1.default(endpoint || 'localhost:11211');
628
602
  // Build promisified API map
629
603
  this.api = {
@@ -654,159 +628,137 @@ class MemcachedBackend {
654
628
  /**
655
629
  * CacheBackend.set implementation
656
630
  */
657
- set(key, val, ttl = this.defTTL) {
658
- return __awaiter(this, void 0, void 0, function* () {
659
- const entry = { val, exp: fromTTL(ttl) };
660
- (0, engine_1._log)(NS, `[${this.name}-backend] storing to key [${key}] =`, engine_1.$U.json(entry));
661
- return yield this.api.set(key, entry, ttl);
662
- });
631
+ async set(key, val, ttl = this.defTTL) {
632
+ const entry = { val, exp: fromTTL(ttl) };
633
+ (0, engine_1._log)(NS, `[${this.name}-backend] storing to key [${key}] =`, engine_1.$U.json(entry));
634
+ return await this.api.set(key, entry, ttl);
663
635
  }
664
636
  /**
665
637
  * CacheBackend.get implementation
666
638
  */
667
- get(key) {
668
- return __awaiter(this, void 0, void 0, function* () {
669
- const entry = yield this.api.get(key);
670
- (0, engine_1._log)(NS, `[${this.name}-backend] entry fetched =`, engine_1.$U.json(entry));
671
- return entry && entry.val;
672
- });
639
+ async get(key) {
640
+ const entry = await this.api.get(key);
641
+ (0, engine_1._log)(NS, `[${this.name}-backend] entry fetched =`, engine_1.$U.json(entry));
642
+ return entry && entry.val;
673
643
  }
674
644
  /**
675
645
  * CacheBackend.mset implementation
676
646
  */
677
- mset(entries) {
678
- return __awaiter(this, void 0, void 0, function* () {
679
- (0, engine_1._log)(NS, `[${this.name}-backend] storing multiple keys ...`);
680
- const promises = entries.map(({ key, val, ttl = this.defTTL }, idx) => {
681
- const entry = { val, exp: fromTTL(ttl) };
682
- (0, engine_1._log)(NS, ` ${idx}) key [${key}] =`, engine_1.$U.json(entry));
683
- return this.api.set(key, entry, ttl);
684
- });
685
- const results = yield Promise.all(promises);
686
- return results.every(result => result === true);
647
+ async mset(entries) {
648
+ (0, engine_1._log)(NS, `[${this.name}-backend] storing multiple keys ...`);
649
+ const promises = entries.map(({ key, val, ttl = this.defTTL }, idx) => {
650
+ const entry = { val, exp: fromTTL(ttl) };
651
+ (0, engine_1._log)(NS, ` ${idx}) key [${key}] =`, engine_1.$U.json(entry));
652
+ return this.api.set(key, entry, ttl);
687
653
  });
654
+ const results = await Promise.all(promises);
655
+ return results.every(result => result === true);
688
656
  }
689
657
  /**
690
658
  * CacheBackend.mget implementation
691
659
  */
692
- mget(keys) {
693
- return __awaiter(this, void 0, void 0, function* () {
694
- const map = yield this.api.getMulti(keys);
695
- (0, engine_1._log)(NS, `[${this.name}-backend] entry map fetched =`, engine_1.$U.json(map));
696
- Object.keys(map).forEach(key => {
697
- const entry = map[key];
698
- map[key] = entry.val;
699
- });
700
- return map;
660
+ async mget(keys) {
661
+ const map = await this.api.getMulti(keys);
662
+ (0, engine_1._log)(NS, `[${this.name}-backend] entry map fetched =`, engine_1.$U.json(map));
663
+ Object.keys(map).forEach(key => {
664
+ const entry = map[key];
665
+ map[key] = entry.val;
701
666
  });
667
+ return map;
702
668
  }
703
669
  /**
704
670
  * CacheBackend.incr implementation
705
671
  */
706
- incr(key, increment) {
707
- return __awaiter(this, void 0, void 0, function* () {
708
- // NOTE:
709
- // Memcached는 음수에 대한 incr/decr를 지원하지 않으며 0 미만으로 decr 되지 않는다.
710
- // 이런 이유로 sets & cas 조합을 이용해 직접 구현함
711
- (0, engine_1._log)(NS, `[${this.name}-backend] incrementing (${increment}) to key [${key}] ...`);
712
- // Use get/check-and-save + retry strategy for consistency
713
- for (let retry = 0; retry < 5; yield sleep(10), retry++) {
714
- const result = yield this.api.gets(key); // Get entry w/ CAS id
715
- if (result === undefined) {
716
- // Initialize to increment value if the key does not exist
717
- if (!(yield this.set(key, increment, 0)))
718
- break;
719
- return increment;
720
- }
721
- else {
722
- const { [key]: oldEntry, cas } = result;
723
- if (typeof oldEntry.val !== 'number')
724
- throw new Error(`.key [${key}] has non-numeric value.`);
725
- // Preserve remaining lifetime w/ best effort strategy, not accurate
726
- const now = Date.now();
727
- const ttl = oldEntry.exp && Math.round((oldEntry.exp - now) / 1000);
728
- const entry = {
729
- val: oldEntry.val + increment,
730
- exp: ttl && now + ttl * 1000,
731
- };
732
- if (yield this.api.cas(key, entry, cas, ttl))
733
- return entry.val;
734
- }
672
+ async incr(key, increment) {
673
+ // NOTE:
674
+ // Memcached는 음수에 대한 incr/decr를 지원하지 않으며 0 미만으로 decr 되지 않는다.
675
+ // 이런 이유로 sets & cas 조합을 이용해 직접 구현함
676
+ (0, engine_1._log)(NS, `[${this.name}-backend] incrementing (${increment}) to key [${key}] ...`);
677
+ // Use get/check-and-save + retry strategy for consistency
678
+ for (let retry = 0; retry < 5; await sleep(10), retry++) {
679
+ const result = await this.api.gets(key); // Get entry w/ CAS id
680
+ if (result === undefined) {
681
+ // Initialize to increment value if the key does not exist
682
+ if (!(await this.set(key, increment, 0)))
683
+ break;
684
+ return increment;
735
685
  }
736
- throw new Error(`[memcached] failed to increment key [${key}].`);
737
- });
686
+ else {
687
+ const { [key]: oldEntry, cas } = result;
688
+ if (typeof oldEntry.val !== 'number')
689
+ throw new Error(`.key [${key}] has non-numeric value.`);
690
+ // Preserve remaining lifetime w/ best effort strategy, not accurate
691
+ const now = Date.now();
692
+ const ttl = oldEntry.exp && Math.round((oldEntry.exp - now) / 1000);
693
+ const entry = {
694
+ val: oldEntry.val + increment,
695
+ exp: ttl && now + ttl * 1000,
696
+ };
697
+ if (await this.api.cas(key, entry, cas, ttl))
698
+ return entry.val;
699
+ }
700
+ }
701
+ throw new Error(`[memcached] failed to increment key [${key}].`);
738
702
  }
739
703
  /**
740
704
  * CacheBackend.keys implementation
741
705
  */
742
- keys() {
743
- return __awaiter(this, void 0, void 0, function* () {
744
- // NOTE:
745
- // memcached는 원래 keys 기능을 지원하지 않으며
746
- // 아래와 같이 cachedump를 사용하여 가능하지만 set한 key가 dump 될 때 까지 상당한 시간이 소요되는 것으로 보인다.
747
- // 따라서 operation의 결과를 신뢰하지 않도록 한다.
748
- const item = (yield this.api.items())[0];
749
- if (!item || Object.keys(item).length === 0)
750
- return [];
751
- const [server, slabid] = [item.server, Number(Object.keys(item)[0])];
752
- const number = item[slabid].number;
753
- const cachedump = yield this.api.cachedump(server, slabid, number);
754
- return cachedump.map(({ key }) => key);
755
- });
706
+ async keys() {
707
+ // NOTE:
708
+ // memcached는 원래 keys 기능을 지원하지 않으며
709
+ // 아래와 같이 cachedump를 사용하여 가능하지만 set한 key가 dump 될 때 까지 상당한 시간이 소요되는 것으로 보인다.
710
+ // 따라서 operation의 결과를 신뢰하지 않도록 한다.
711
+ const item = (await this.api.items())[0];
712
+ if (!item || Object.keys(item).length === 0)
713
+ return [];
714
+ const [server, slabid] = [item.server, Number(Object.keys(item)[0])];
715
+ const number = item[slabid].number;
716
+ const cachedump = await this.api.cachedump(server, slabid, number);
717
+ return cachedump.map(({ key }) => key);
756
718
  }
757
719
  /**
758
720
  * CacheBackend.has implementation
759
721
  */
760
- has(key) {
761
- return __awaiter(this, void 0, void 0, function* () {
762
- return (yield this.api.get(key)) !== undefined;
763
- });
722
+ async has(key) {
723
+ return (await this.api.get(key)) !== undefined;
764
724
  }
765
725
  /**
766
726
  * CacheBackend.del implementation
767
727
  */
768
- del(key) {
769
- return __awaiter(this, void 0, void 0, function* () {
770
- return yield this.api.del(key);
771
- });
728
+ async del(key) {
729
+ return await this.api.del(key);
772
730
  }
773
731
  /**
774
732
  * CacheBackend.expire implementation
775
733
  */
776
- expire(key, ttl) {
777
- return __awaiter(this, void 0, void 0, function* () {
778
- let saved = false;
779
- for (let retry = 0; !saved && retry < 5; yield sleep(10), retry++) {
780
- const result = yield this.api.gets(key); // Get entry w/ CAS id
781
- if (result === undefined)
782
- break; // If key does not exist or already expired
783
- // Refresh timeout
784
- const { [key]: oldEntry, cas } = result;
785
- const newEntry = {
786
- val: oldEntry.val,
787
- exp: ttl && Date.now() + ttl * 1000,
788
- };
789
- saved = yield this.api.cas(key, newEntry, cas, ttl);
790
- }
791
- return saved;
792
- });
734
+ async expire(key, ttl) {
735
+ let saved = false;
736
+ for (let retry = 0; !saved && retry < 5; await sleep(10), retry++) {
737
+ const result = await this.api.gets(key); // Get entry w/ CAS id
738
+ if (result === undefined)
739
+ break; // If key does not exist or already expired
740
+ // Refresh timeout
741
+ const { [key]: oldEntry, cas } = result;
742
+ const newEntry = {
743
+ val: oldEntry.val,
744
+ exp: ttl && Date.now() + ttl * 1000,
745
+ };
746
+ saved = await this.api.cas(key, newEntry, cas, ttl);
747
+ }
748
+ return saved;
793
749
  }
794
750
  /**
795
751
  * CacheBackend.ttl implementation
796
752
  */
797
- ttl(key) {
798
- return __awaiter(this, void 0, void 0, function* () {
799
- const entry = yield this.api.get(key); // undefined if key does not exist
800
- return (entry === null || entry === void 0 ? void 0 : entry.exp) && entry.exp - Date.now();
801
- });
753
+ async ttl(key) {
754
+ const entry = await this.api.get(key); // undefined if key does not exist
755
+ return entry?.exp && entry.exp - Date.now();
802
756
  }
803
757
  /**
804
758
  * CacheBackend.close implementation
805
759
  */
806
- close() {
807
- return __awaiter(this, void 0, void 0, function* () {
808
- this.api.end();
809
- });
760
+ async close() {
761
+ this.api.end();
810
762
  }
811
763
  }
812
764
  /**
@@ -814,156 +766,140 @@ class MemcachedBackend {
814
766
  * @internal
815
767
  */
816
768
  class RedisBackend {
769
+ /**
770
+ * ioredis client
771
+ * @private
772
+ */
773
+ redis;
774
+ /**
775
+ * Default TTL as number in seconds
776
+ * @private
777
+ */
778
+ defTTL;
779
+ /**
780
+ * backend type
781
+ */
782
+ name = 'redis';
817
783
  /**
818
784
  * Public constructor
819
785
  */
820
786
  constructor(endpoint, defTTL = 0) {
821
- /**
822
- * backend type
823
- */
824
- this.name = 'redis';
825
787
  this.redis = new ioredis_1.default(endpoint || 'localhost:6379');
826
788
  this.defTTL = defTTL;
827
789
  }
828
790
  /**
829
791
  * CacheBackend.set implementation
830
792
  */
831
- set(key, val, ttl = this.defTTL) {
832
- return __awaiter(this, void 0, void 0, function* () {
833
- const data = JSON.stringify(val); // Serialize
834
- ttl > 0 ? yield this.redis.set(key, data, 'EX', ttl) : yield this.redis.set(key, data);
835
- return true; // 'set' command always return OK
836
- });
793
+ async set(key, val, ttl = this.defTTL) {
794
+ const data = JSON.stringify(val); // Serialize
795
+ ttl > 0 ? await this.redis.set(key, data, 'EX', ttl) : await this.redis.set(key, data);
796
+ return true; // 'set' command always return OK
837
797
  }
838
798
  /**
839
799
  * CacheBackend.get implementation
840
800
  */
841
- get(key) {
842
- return __awaiter(this, void 0, void 0, function* () {
843
- const data = yield this.redis.get(key);
844
- if (data !== null)
845
- return JSON.parse(data); // Deserialize
846
- });
801
+ async get(key) {
802
+ const data = await this.redis.get(key);
803
+ if (data !== null)
804
+ return JSON.parse(data); // Deserialize
847
805
  }
848
806
  /**
849
807
  * CacheBackend.mset implementation
850
808
  */
851
- mset(entries) {
852
- return __awaiter(this, void 0, void 0, function* () {
853
- // Create transaction pipeline
854
- // -> MSET command를 사용할 수도 있으나 ttl 지정이 불가능하여 pipeline으로 구현함
855
- const pipeline = entries.reduce((pipeline, { key, val, ttl = this.defTTL }) => {
856
- const data = JSON.stringify(val); // Serialize
857
- return ttl > 0 ? pipeline.set(key, data, 'EX', ttl) : pipeline.set(key, data);
858
- }, this.redis.multi());
859
- // Execute transaction
860
- yield pipeline.exec(); // Always OK
861
- return true;
862
- });
809
+ async mset(entries) {
810
+ // Create transaction pipeline
811
+ // -> MSET command를 사용할 수도 있으나 ttl 지정이 불가능하여 pipeline으로 구현함
812
+ const pipeline = entries.reduce((pipeline, { key, val, ttl = this.defTTL }) => {
813
+ const data = JSON.stringify(val); // Serialize
814
+ return ttl > 0 ? pipeline.set(key, data, 'EX', ttl) : pipeline.set(key, data);
815
+ }, this.redis.multi());
816
+ // Execute transaction
817
+ await pipeline.exec(); // Always OK
818
+ return true;
863
819
  }
864
820
  /**
865
821
  * CacheBackend.mget implementation
866
822
  */
867
- mget(keys) {
868
- return __awaiter(this, void 0, void 0, function* () {
869
- const list = yield this.redis.mget(keys);
870
- // Deserialize and map array into object
871
- return list.reduce((map, data, idx) => {
872
- if (data !== null) {
873
- const key = keys[idx];
874
- map[key] = JSON.parse(data); // Deserialize
875
- }
876
- return map;
877
- }, {});
878
- });
823
+ async mget(keys) {
824
+ const list = await this.redis.mget(keys);
825
+ // Deserialize and map array into object
826
+ return list.reduce((map, data, idx) => {
827
+ if (data !== null) {
828
+ const key = keys[idx];
829
+ map[key] = JSON.parse(data); // Deserialize
830
+ }
831
+ return map;
832
+ }, {});
879
833
  }
880
834
  /**
881
835
  * CacheBackend.getset implementation
882
836
  */
883
- getset(key, val) {
884
- return __awaiter(this, void 0, void 0, function* () {
885
- const newData = JSON.stringify(val); // Serialize
886
- const oldData = yield this.redis.getset(key, newData);
887
- if (oldData !== null)
888
- return JSON.parse(oldData); // Deserialize
889
- });
837
+ async getset(key, val) {
838
+ const newData = JSON.stringify(val); // Serialize
839
+ const oldData = await this.redis.getset(key, newData);
840
+ if (oldData !== null)
841
+ return JSON.parse(oldData); // Deserialize
890
842
  }
891
843
  /**
892
844
  * CacheBackend.pop implementation
893
845
  */
894
- pop(key) {
895
- return __awaiter(this, void 0, void 0, function* () {
896
- const [[err, data]] = yield this.redis
897
- .multi()
898
- .get(key) // read
899
- .del(key) // and delete
900
- .exec();
901
- if (!err && data !== null)
902
- return JSON.parse(data);
903
- });
846
+ async pop(key) {
847
+ const [[err, data]] = await this.redis
848
+ .multi()
849
+ .get(key) // read
850
+ .del(key) // and delete
851
+ .exec();
852
+ if (!err && data !== null)
853
+ return JSON.parse(data);
904
854
  }
905
855
  /**
906
856
  * CacheBackend.incr implementation
907
857
  */
908
- incr(key, increment) {
909
- return __awaiter(this, void 0, void 0, function* () {
910
- // Support both integer and floating point
911
- const ret = yield this.redis.incrbyfloat(key, increment);
912
- return Number(ret);
913
- });
858
+ async incr(key, increment) {
859
+ // Support both integer and floating point
860
+ const ret = await this.redis.incrbyfloat(key, increment);
861
+ return Number(ret);
914
862
  }
915
863
  /**
916
864
  * CacheBackend.keys implementation
917
865
  */
918
- keys() {
919
- return __awaiter(this, void 0, void 0, function* () {
920
- return yield this.redis.keys('*');
921
- });
866
+ async keys() {
867
+ return await this.redis.keys('*');
922
868
  }
923
869
  /**
924
870
  * CacheBackend.has implementation
925
871
  */
926
- has(key) {
927
- return __awaiter(this, void 0, void 0, function* () {
928
- return (yield this.redis.exists(key)) > 0; // 1: exists / 0: does not exist
929
- });
872
+ async has(key) {
873
+ return (await this.redis.exists(key)) > 0; // 1: exists / 0: does not exist
930
874
  }
931
875
  /**
932
876
  * CacheBackend.del implementation
933
877
  */
934
- del(key) {
935
- return __awaiter(this, void 0, void 0, function* () {
936
- return (yield this.redis.del(key)) === 1; // number of keys removed
937
- });
878
+ async del(key) {
879
+ return (await this.redis.del(key)) === 1; // number of keys removed
938
880
  }
939
881
  /**
940
882
  * CacheBackend.expire implementation
941
883
  */
942
- expire(key, ttl) {
943
- return __awaiter(this, void 0, void 0, function* () {
944
- const ret = ttl > 0 ? yield this.redis.expire(key, ttl) : yield this.redis.persist(key);
945
- return ret > 0; // 1: success / 0: key does not exist
946
- });
884
+ async expire(key, ttl) {
885
+ const ret = ttl > 0 ? await this.redis.expire(key, ttl) : await this.redis.persist(key);
886
+ return ret > 0; // 1: success / 0: key does not exist
947
887
  }
948
888
  /**
949
889
  * CacheBackend.ttl implementation
950
890
  */
951
- ttl(key) {
952
- return __awaiter(this, void 0, void 0, function* () {
953
- const ms = yield this.redis.pttl(key); // -2: key does not exist / -1: no timeout
954
- if (ms >= 0)
955
- return ms;
956
- if (ms === -1)
957
- return 0;
958
- });
891
+ async ttl(key) {
892
+ const ms = await this.redis.pttl(key); // -2: key does not exist / -1: no timeout
893
+ if (ms >= 0)
894
+ return ms;
895
+ if (ms === -1)
896
+ return 0;
959
897
  }
960
898
  /**
961
899
  * CacheBackend.close implementation
962
900
  */
963
- close() {
964
- return __awaiter(this, void 0, void 0, function* () {
965
- yield this.redis.quit();
966
- });
901
+ async close() {
902
+ await this.redis.quit();
967
903
  }
968
904
  }
969
905
  //# sourceMappingURL=cache-service.js.map