@forklaunch/core 0.6.5 → 0.7.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/lib/{openTelemetryCollector-CWrfzmmW.d.mts → openTelemetryCollector-CmZ3T_2T.d.mts} +9 -1
- package/lib/{openTelemetryCollector-CWrfzmmW.d.ts → openTelemetryCollector-CmZ3T_2T.d.ts} +9 -1
- package/lib/src/cache/index.d.mts +210 -24
- package/lib/src/cache/index.d.ts +210 -24
- package/lib/src/cache/index.js +364 -31
- package/lib/src/cache/index.js.map +1 -1
- package/lib/src/cache/index.mjs +374 -31
- package/lib/src/cache/index.mjs.map +1 -1
- package/lib/src/controllers/index.d.mts +10 -0
- package/lib/src/controllers/index.d.ts +10 -0
- package/lib/src/http/index.d.mts +51 -4
- package/lib/src/http/index.d.ts +51 -4
- package/lib/src/http/index.js +24 -1
- package/lib/src/http/index.js.map +1 -1
- package/lib/src/http/index.mjs +23 -1
- package/lib/src/http/index.mjs.map +1 -1
- package/lib/src/{dtoMapper → mappers}/index.d.mts +3 -3
- package/lib/src/{dtoMapper → mappers}/index.d.ts +3 -3
- package/lib/src/{dtoMapper → mappers}/index.js +12 -12
- package/lib/src/mappers/index.js.map +1 -0
- package/lib/src/{dtoMapper → mappers}/index.mjs +8 -8
- package/lib/src/mappers/index.mjs.map +1 -0
- package/lib/src/persistence/index.d.mts +120 -0
- package/lib/src/persistence/index.d.ts +120 -0
- package/lib/src/persistence/index.js +152 -0
- package/lib/src/persistence/index.js.map +1 -0
- package/lib/src/persistence/index.mjs +127 -0
- package/lib/src/persistence/index.mjs.map +1 -0
- package/lib/src/services/index.d.mts +3 -2
- package/lib/src/services/index.d.ts +3 -2
- package/lib/src/services/index.js.map +1 -1
- package/lib/src/services/index.mjs.map +1 -1
- package/package.json +15 -9
- package/lib/src/dtoMapper/index.js.map +0 -1
- package/lib/src/dtoMapper/index.mjs.map +0 -1
package/lib/src/cache/index.mjs
CHANGED
@@ -1,104 +1,447 @@
|
|
1
|
+
// src/cache/cacheKey.ts
|
2
|
+
var createCacheKey = (cacheKeyPrefix) => (id) => {
|
3
|
+
return `${cacheKeyPrefix}:${id}`;
|
4
|
+
};
|
5
|
+
|
1
6
|
// src/cache/redisTtlCache.ts
|
2
7
|
import { createClient } from "redis";
|
8
|
+
|
9
|
+
// src/http/middleware/request/cors.middleware.ts
|
10
|
+
import corsMiddleware from "cors";
|
11
|
+
|
12
|
+
// src/http/middleware/request/createContext.middleware.ts
|
13
|
+
import { trace } from "@opentelemetry/api";
|
14
|
+
import { v4 } from "uuid";
|
15
|
+
|
16
|
+
// src/http/telemetry/constants.ts
|
17
|
+
import {
|
18
|
+
ATTR_HTTP_REQUEST_METHOD,
|
19
|
+
ATTR_HTTP_RESPONSE_STATUS_CODE,
|
20
|
+
ATTR_HTTP_ROUTE,
|
21
|
+
ATTR_SERVICE_NAME
|
22
|
+
} from "@opentelemetry/semantic-conventions";
|
23
|
+
|
24
|
+
// src/http/guards/isExpressLikeSchemaHandler.ts
|
25
|
+
import { extractArgumentNames } from "@forklaunch/common";
|
26
|
+
|
27
|
+
// src/http/middleware/request/auth.middleware.ts
|
28
|
+
import { jwtVerify } from "jose";
|
29
|
+
|
30
|
+
// src/services/getEnvVar.ts
|
31
|
+
function getEnvVar(name) {
|
32
|
+
const value = process.env[name];
|
33
|
+
return value;
|
34
|
+
}
|
35
|
+
|
36
|
+
// src/http/telemetry/openTelemetryCollector.ts
|
37
|
+
import { HyperExpressInstrumentation } from "@forklaunch/opentelemetry-instrumentation-hyper-express";
|
38
|
+
import {
|
39
|
+
metrics
|
40
|
+
} from "@opentelemetry/api";
|
41
|
+
import { OTLPLogExporter } from "@opentelemetry/exporter-logs-otlp-http";
|
42
|
+
import { OTLPMetricExporter } from "@opentelemetry/exporter-metrics-otlp-http";
|
43
|
+
import { OTLPTraceExporter } from "@opentelemetry/exporter-trace-otlp-http";
|
44
|
+
import { ExpressInstrumentation } from "@opentelemetry/instrumentation-express";
|
45
|
+
import { HttpInstrumentation } from "@opentelemetry/instrumentation-http";
|
46
|
+
import { resourceFromAttributes } from "@opentelemetry/resources";
|
47
|
+
import { BatchLogRecordProcessor } from "@opentelemetry/sdk-logs";
|
48
|
+
import { PeriodicExportingMetricReader } from "@opentelemetry/sdk-metrics";
|
49
|
+
import { NodeSDK } from "@opentelemetry/sdk-node";
|
50
|
+
import {
|
51
|
+
ATTR_SERVICE_NAME as ATTR_SERVICE_NAME2
|
52
|
+
} from "@opentelemetry/semantic-conventions";
|
53
|
+
import dotenv from "dotenv";
|
54
|
+
|
55
|
+
// src/http/guards/isForklaunchRequest.ts
|
56
|
+
function isForklaunchRequest(request) {
|
57
|
+
return request != null && typeof request === "object" && "contractDetails" in request;
|
58
|
+
}
|
59
|
+
|
60
|
+
// src/http/telemetry/pinoLogger.ts
|
61
|
+
import { isNever } from "@forklaunch/common";
|
62
|
+
import { trace as trace2 } from "@opentelemetry/api";
|
63
|
+
import { logs } from "@opentelemetry/api-logs";
|
64
|
+
import pino from "pino";
|
65
|
+
import PinoPretty from "pino-pretty";
|
66
|
+
|
67
|
+
// src/http/telemetry/openTelemetryCollector.ts
|
68
|
+
dotenv.config({ path: getEnvVar("ENV_FILE_PATH") });
|
69
|
+
new NodeSDK({
|
70
|
+
resource: resourceFromAttributes({
|
71
|
+
[ATTR_SERVICE_NAME2]: getEnvVar("OTEL_SERVICE_NAME")
|
72
|
+
}),
|
73
|
+
traceExporter: new OTLPTraceExporter({
|
74
|
+
url: `${getEnvVar("OTEL_EXPORTER_OTLP_ENDPOINT") ?? "http://localhost:4318"}/v1/traces`
|
75
|
+
}),
|
76
|
+
metricReader: new PeriodicExportingMetricReader({
|
77
|
+
exporter: new OTLPMetricExporter({
|
78
|
+
url: `${getEnvVar("OTEL_EXPORTER_OTLP_ENDPOINT") ?? "http://localhost:4318"}/v1/metrics`
|
79
|
+
}),
|
80
|
+
exportIntervalMillis: 5e3
|
81
|
+
}),
|
82
|
+
logRecordProcessors: [
|
83
|
+
new BatchLogRecordProcessor(
|
84
|
+
new OTLPLogExporter({
|
85
|
+
url: `${getEnvVar("OTEL_EXPORTER_OTLP_ENDPOINT") ?? "http://localhost:4318"}/v1/logs`
|
86
|
+
})
|
87
|
+
)
|
88
|
+
],
|
89
|
+
instrumentations: [
|
90
|
+
new HttpInstrumentation({
|
91
|
+
applyCustomAttributesOnSpan: (span, request) => {
|
92
|
+
span.setAttribute(
|
93
|
+
"service.name",
|
94
|
+
getEnvVar("OTEL_SERVICE_NAME") ?? "unknown"
|
95
|
+
);
|
96
|
+
if (isForklaunchRequest(request)) {
|
97
|
+
span.setAttribute("api.name", request.contractDetails?.name);
|
98
|
+
}
|
99
|
+
}
|
100
|
+
}),
|
101
|
+
new ExpressInstrumentation(),
|
102
|
+
new HyperExpressInstrumentation()
|
103
|
+
]
|
104
|
+
}).start();
|
105
|
+
var httpRequestsTotalCounter = metrics.getMeter(getEnvVar("OTEL_SERVICE_NAME") || "unknown").createCounter("http_requests_total", {
|
106
|
+
description: "Number of HTTP requests"
|
107
|
+
});
|
108
|
+
var httpServerDurationHistogram = metrics.getMeter(getEnvVar("OTEL_SERVICE_NAME") || "unknown").createHistogram("http_server_duration", {
|
109
|
+
description: "Duration of HTTP server requests",
|
110
|
+
unit: "s"
|
111
|
+
});
|
112
|
+
|
113
|
+
// src/http/middleware/request/parse.middleware.ts
|
114
|
+
import {
|
115
|
+
prettyPrintParseErrors
|
116
|
+
} from "@forklaunch/validator";
|
117
|
+
|
118
|
+
// src/http/middleware/response/parse.middleware.ts
|
119
|
+
import {
|
120
|
+
prettyPrintParseErrors as prettyPrintParseErrors2
|
121
|
+
} from "@forklaunch/validator";
|
122
|
+
|
123
|
+
// src/http/telemetry/recordMetric.ts
|
124
|
+
import {
|
125
|
+
ATTR_HTTP_REQUEST_METHOD as ATTR_HTTP_REQUEST_METHOD3,
|
126
|
+
ATTR_HTTP_RESPONSE_STATUS_CODE as ATTR_HTTP_RESPONSE_STATUS_CODE3,
|
127
|
+
ATTR_HTTP_ROUTE as ATTR_HTTP_ROUTE3,
|
128
|
+
ATTR_SERVICE_NAME as ATTR_SERVICE_NAME3
|
129
|
+
} from "@opentelemetry/semantic-conventions";
|
130
|
+
|
131
|
+
// src/services/configInjector.ts
|
132
|
+
import { extractArgumentNames as extractArgumentNames2, isNever as isNever2 } from "@forklaunch/common";
|
133
|
+
import {
|
134
|
+
prettyPrintParseErrors as prettyPrintParseErrors3
|
135
|
+
} from "@forklaunch/validator";
|
136
|
+
|
137
|
+
// src/http/telemetry/evaluateTelemetryOptions.ts
|
138
|
+
function evaluateTelemetryOptions(telemetryOptions) {
|
139
|
+
return {
|
140
|
+
enabled: typeof telemetryOptions.enabled === "boolean" ? {
|
141
|
+
metrics: telemetryOptions.enabled,
|
142
|
+
tracing: telemetryOptions.enabled,
|
143
|
+
logging: telemetryOptions.enabled
|
144
|
+
} : {
|
145
|
+
metrics: telemetryOptions.enabled.metrics,
|
146
|
+
tracing: telemetryOptions.enabled.tracing,
|
147
|
+
logging: telemetryOptions.enabled.logging
|
148
|
+
},
|
149
|
+
level: telemetryOptions.level
|
150
|
+
};
|
151
|
+
}
|
152
|
+
|
153
|
+
// src/cache/redisTtlCache.ts
|
3
154
|
var RedisTtlCache = class {
|
4
155
|
/**
|
5
156
|
* Creates an instance of RedisTtlCache.
|
6
157
|
*
|
7
|
-
* @param {number} ttlMilliseconds - The default
|
8
|
-
* @param {
|
158
|
+
* @param {number} ttlMilliseconds - The default Time-To-Live in milliseconds for cache entries
|
159
|
+
* @param {OpenTelemetryCollector<MetricsDefinition>} openTelemetryCollector - Collector for OpenTelemetry metrics
|
160
|
+
* @param {RedisClientOptions} hostingOptions - Configuration options for the Redis client
|
161
|
+
* @param {TelemetryOptions} telemetryOptions - Configuration options for telemetry
|
9
162
|
*/
|
10
|
-
constructor(ttlMilliseconds, openTelemetryCollector, hostingOptions) {
|
163
|
+
constructor(ttlMilliseconds, openTelemetryCollector, hostingOptions, telemetryOptions) {
|
11
164
|
this.ttlMilliseconds = ttlMilliseconds;
|
12
165
|
this.openTelemetryCollector = openTelemetryCollector;
|
166
|
+
this.telemetryOptions = evaluateTelemetryOptions(telemetryOptions);
|
13
167
|
this.client = createClient(hostingOptions);
|
14
|
-
this.
|
15
|
-
|
168
|
+
if (this.telemetryOptions.enabled.logging) {
|
169
|
+
this.client.on("error", (err) => this.openTelemetryCollector.error(err));
|
170
|
+
this.client.connect().catch(this.openTelemetryCollector.error);
|
171
|
+
}
|
16
172
|
}
|
17
173
|
client;
|
174
|
+
telemetryOptions;
|
175
|
+
/**
|
176
|
+
* Parses a raw Redis reply into the expected type.
|
177
|
+
* Handles null values, arrays, buffers, and JSON strings.
|
178
|
+
*
|
179
|
+
* @template T - The expected type of the parsed value
|
180
|
+
* @param {RedisCommandRawReply} value - The raw value from Redis to parse
|
181
|
+
* @returns {T} The parsed value cast to type T
|
182
|
+
*/
|
183
|
+
parseValue(value) {
|
184
|
+
if (value == null) {
|
185
|
+
return null;
|
186
|
+
}
|
187
|
+
if (Array.isArray(value)) {
|
188
|
+
return value.map((v) => this.parseValue(v));
|
189
|
+
}
|
190
|
+
if (Buffer.isBuffer(value)) {
|
191
|
+
return value.toJSON();
|
192
|
+
}
|
193
|
+
switch (typeof value) {
|
194
|
+
case "object":
|
195
|
+
case "string":
|
196
|
+
return JSON.parse(value);
|
197
|
+
case "number":
|
198
|
+
return value;
|
199
|
+
}
|
200
|
+
}
|
18
201
|
/**
|
19
202
|
* Puts a record into the Redis cache.
|
20
203
|
*
|
21
|
-
* @
|
22
|
-
* @
|
204
|
+
* @template T - The type of value being cached
|
205
|
+
* @param {TtlCacheRecord<T>} param0 - The cache record containing key, value and optional TTL
|
206
|
+
* @param {string} param0.key - The key to store the value under
|
207
|
+
* @param {T} param0.value - The value to cache
|
208
|
+
* @param {number} [param0.ttlMilliseconds] - Optional TTL in milliseconds, defaults to constructor value
|
209
|
+
* @returns {Promise<void>} A promise that resolves when the value is cached
|
23
210
|
*/
|
24
211
|
async putRecord({
|
25
212
|
key,
|
26
213
|
value,
|
27
214
|
ttlMilliseconds = this.ttlMilliseconds
|
28
215
|
}) {
|
216
|
+
if (this.telemetryOptions.enabled.logging) {
|
217
|
+
this.openTelemetryCollector.info(`Putting record into cache: ${key}`);
|
218
|
+
}
|
29
219
|
await this.client.set(key, JSON.stringify(value), {
|
30
220
|
PX: ttlMilliseconds
|
31
221
|
});
|
32
222
|
}
|
223
|
+
/**
|
224
|
+
* Puts multiple records into the Redis cache in a single transaction.
|
225
|
+
*
|
226
|
+
* @template T - The type of values being cached
|
227
|
+
* @param {TtlCacheRecord<T>[]} cacheRecords - Array of cache records to store
|
228
|
+
* @returns {Promise<void>} A promise that resolves when all values are cached
|
229
|
+
*/
|
230
|
+
async putBatchRecords(cacheRecords) {
|
231
|
+
let multiCommand = this.client.multi();
|
232
|
+
for (const { key, value, ttlMilliseconds } of cacheRecords) {
|
233
|
+
multiCommand = multiCommand.set(key, JSON.stringify(value), {
|
234
|
+
PX: ttlMilliseconds || this.ttlMilliseconds
|
235
|
+
});
|
236
|
+
}
|
237
|
+
await multiCommand.exec();
|
238
|
+
}
|
239
|
+
/**
|
240
|
+
* Adds a value to the left end of a Redis list.
|
241
|
+
*
|
242
|
+
* @template T - The type of value being enqueued
|
243
|
+
* @param {string} queueName - The name of the Redis list
|
244
|
+
* @param {T} value - The value to add to the list
|
245
|
+
* @returns {Promise<void>} A promise that resolves when the value is enqueued
|
246
|
+
*/
|
247
|
+
async enqueueRecord(queueName, value) {
|
248
|
+
await this.client.lPush(queueName, JSON.stringify(value));
|
249
|
+
}
|
250
|
+
/**
|
251
|
+
* Adds multiple values to the left end of a Redis list in a single transaction.
|
252
|
+
*
|
253
|
+
* @template T - The type of values being enqueued
|
254
|
+
* @param {string} queueName - The name of the Redis list
|
255
|
+
* @param {T[]} values - Array of values to add to the list
|
256
|
+
* @returns {Promise<void>} A promise that resolves when all values are enqueued
|
257
|
+
*/
|
258
|
+
async enqueueBatchRecords(queueName, values) {
|
259
|
+
let multiCommand = this.client.multi();
|
260
|
+
for (const value of values) {
|
261
|
+
multiCommand = multiCommand.lPush(queueName, JSON.stringify(value));
|
262
|
+
}
|
263
|
+
await multiCommand.exec();
|
264
|
+
}
|
33
265
|
/**
|
34
266
|
* Deletes a record from the Redis cache.
|
35
267
|
*
|
36
|
-
* @param {string} cacheRecordKey - The key of the
|
37
|
-
* @returns {Promise<void>}
|
268
|
+
* @param {string} cacheRecordKey - The key of the record to delete
|
269
|
+
* @returns {Promise<void>} A promise that resolves when the record is deleted
|
38
270
|
*/
|
39
271
|
async deleteRecord(cacheRecordKey) {
|
40
272
|
await this.client.del(cacheRecordKey);
|
41
273
|
}
|
274
|
+
/**
|
275
|
+
* Deletes multiple records from the Redis cache in a single transaction.
|
276
|
+
*
|
277
|
+
* @param {string[]} cacheRecordKeys - Array of keys to delete
|
278
|
+
* @returns {Promise<void>} A promise that resolves when all records are deleted
|
279
|
+
*/
|
280
|
+
async deleteBatchRecords(cacheRecordKeys) {
|
281
|
+
let multiCommand = this.client.multi();
|
282
|
+
for (const key of cacheRecordKeys) {
|
283
|
+
multiCommand = multiCommand.del(key);
|
284
|
+
}
|
285
|
+
await multiCommand.exec();
|
286
|
+
}
|
287
|
+
/**
|
288
|
+
* Removes and returns the rightmost element from a Redis list.
|
289
|
+
*
|
290
|
+
* @template T - The type of value being dequeued
|
291
|
+
* @param {string} queueName - The name of the Redis list
|
292
|
+
* @returns {Promise<T>} A promise that resolves with the dequeued value
|
293
|
+
* @throws {Error} If the queue is empty
|
294
|
+
*/
|
295
|
+
async dequeueRecord(queueName) {
|
296
|
+
const value = await this.client.rPop(queueName);
|
297
|
+
if (value === null) {
|
298
|
+
throw new Error(`Queue is empty: ${queueName}`);
|
299
|
+
}
|
300
|
+
return JSON.parse(value);
|
301
|
+
}
|
302
|
+
/**
|
303
|
+
* Removes and returns multiple elements from the right end of a Redis list.
|
304
|
+
*
|
305
|
+
* @template T - The type of values being dequeued
|
306
|
+
* @param {string} queueName - The name of the Redis list
|
307
|
+
* @param {number} pageSize - Maximum number of elements to dequeue
|
308
|
+
* @returns {Promise<T[]>} A promise that resolves with an array of dequeued values
|
309
|
+
*/
|
310
|
+
async dequeueBatchRecords(queueName, pageSize) {
|
311
|
+
let multiCommand = this.client.multi();
|
312
|
+
for (let i = 0; i < pageSize; i++) {
|
313
|
+
multiCommand = multiCommand.rPop(queueName);
|
314
|
+
}
|
315
|
+
const values = await multiCommand.exec();
|
316
|
+
return values.map((value) => this.parseValue(value));
|
317
|
+
}
|
42
318
|
/**
|
43
319
|
* Reads a record from the Redis cache.
|
44
320
|
*
|
45
|
-
* @
|
46
|
-
* @
|
47
|
-
* @
|
321
|
+
* @template T - The type of value being read
|
322
|
+
* @param {string} cacheRecordKey - The key of the record to read
|
323
|
+
* @returns {Promise<TtlCacheRecord<T>>} A promise that resolves with the cache record
|
324
|
+
* @throws {Error} If the record is not found
|
48
325
|
*/
|
49
326
|
async readRecord(cacheRecordKey) {
|
50
|
-
const value = await this.client.get(cacheRecordKey);
|
327
|
+
const [value, ttl] = await this.client.multi().get(cacheRecordKey).ttl(cacheRecordKey).exec();
|
51
328
|
if (value === null) {
|
52
329
|
throw new Error(`Record not found for key: ${cacheRecordKey}`);
|
53
330
|
}
|
54
|
-
const ttl = await this.client.ttl(cacheRecordKey);
|
55
331
|
return {
|
56
332
|
key: cacheRecordKey,
|
57
|
-
value:
|
58
|
-
ttlMilliseconds: ttl * 1e3
|
333
|
+
value: this.parseValue(value),
|
334
|
+
ttlMilliseconds: this.parseValue(ttl) * 1e3
|
59
335
|
};
|
60
336
|
}
|
61
337
|
/**
|
62
|
-
*
|
338
|
+
* Reads multiple records from the Redis cache.
|
339
|
+
*
|
340
|
+
* @template T - The type of values being read
|
341
|
+
* @param {string[] | string} cacheRecordKeysOrPrefix - Array of keys to read, or a prefix pattern
|
342
|
+
* @returns {Promise<TtlCacheRecord<T>[]>} A promise that resolves with an array of cache records
|
343
|
+
*/
|
344
|
+
async readBatchRecords(cacheRecordKeysOrPrefix) {
|
345
|
+
const keys = Array.isArray(cacheRecordKeysOrPrefix) ? cacheRecordKeysOrPrefix : await this.client.keys(cacheRecordKeysOrPrefix + "*");
|
346
|
+
let multiCommand = this.client.multi();
|
347
|
+
for (const key of keys) {
|
348
|
+
multiCommand = multiCommand.get(key);
|
349
|
+
multiCommand = multiCommand.ttl(key);
|
350
|
+
}
|
351
|
+
const values = await multiCommand.exec();
|
352
|
+
return values.reduce((acc, value, index) => {
|
353
|
+
if (index % 2 === 0) {
|
354
|
+
acc.push({
|
355
|
+
key: keys[index / 2],
|
356
|
+
value: this.parseValue(value),
|
357
|
+
ttlMilliseconds: this.parseValue(values[index + 1]) * 1e3
|
358
|
+
});
|
359
|
+
}
|
360
|
+
return acc;
|
361
|
+
}, []);
|
362
|
+
}
|
363
|
+
/**
|
364
|
+
* Lists all keys in the Redis cache that match a pattern prefix.
|
63
365
|
*
|
64
|
-
* @param {string} pattern_prefix - The pattern
|
65
|
-
* @returns {Promise<string[]>}
|
366
|
+
* @param {string} pattern_prefix - The prefix pattern to match keys against
|
367
|
+
* @returns {Promise<string[]>} A promise that resolves with an array of matching keys
|
66
368
|
*/
|
67
369
|
async listKeys(pattern_prefix) {
|
68
370
|
const keys = await this.client.keys(pattern_prefix + "*");
|
69
371
|
return keys;
|
70
372
|
}
|
71
373
|
/**
|
72
|
-
*
|
374
|
+
* Checks if a record exists in the Redis cache.
|
73
375
|
*
|
74
|
-
* @param {string} cacheRecordKey - The key
|
75
|
-
* @returns {Promise<boolean>}
|
376
|
+
* @param {string} cacheRecordKey - The key to check
|
377
|
+
* @returns {Promise<boolean>} A promise that resolves with true if the record exists, false otherwise
|
76
378
|
*/
|
77
379
|
async peekRecord(cacheRecordKey) {
|
78
380
|
const result = await this.client.exists(cacheRecordKey);
|
79
381
|
return result === 1;
|
80
382
|
}
|
81
383
|
/**
|
82
|
-
*
|
384
|
+
* Checks if multiple records exist in the Redis cache.
|
83
385
|
*
|
84
|
-
* @
|
386
|
+
* @param {string[] | string} cacheRecordKeysOrPrefix - Array of keys to check, or a prefix pattern
|
387
|
+
* @returns {Promise<boolean[]>} A promise that resolves with an array of existence booleans
|
388
|
+
*/
|
389
|
+
async peekBatchRecords(cacheRecordKeysOrPrefix) {
|
390
|
+
const keys = Array.isArray(cacheRecordKeysOrPrefix) ? cacheRecordKeysOrPrefix : await this.client.keys(cacheRecordKeysOrPrefix + "*");
|
391
|
+
let multiCommand = this.client.multi();
|
392
|
+
for (const key of keys) {
|
393
|
+
multiCommand = multiCommand.exists(key);
|
394
|
+
}
|
395
|
+
const results = await multiCommand.exec();
|
396
|
+
return results.map((result) => result === 1);
|
397
|
+
}
|
398
|
+
/**
|
399
|
+
* Peeks at a record in the Redis cache.
|
400
|
+
*
|
401
|
+
* @template T - The type of value being peeked at
|
402
|
+
* @param {string} queueName - The name of the Redis queue
|
403
|
+
* @returns {Promise<T>} A promise that resolves with the peeked value
|
404
|
+
*/
|
405
|
+
async peekQueueRecord(queueName) {
|
406
|
+
const value = await this.client.lRange(queueName, 0, 0);
|
407
|
+
return this.parseValue(value[0]);
|
408
|
+
}
|
409
|
+
/**
|
410
|
+
* Peeks at multiple records in the Redis cache.
|
411
|
+
*
|
412
|
+
* @template T - The type of values being peeked at
|
413
|
+
* @param {string} queueName - The name of the Redis queue
|
414
|
+
* @param {number} pageSize - The number of records to peek at
|
415
|
+
* @returns {Promise<T[]>} A promise that resolves with an array of peeked values
|
416
|
+
*/
|
417
|
+
async peekQueueRecords(queueName, pageSize) {
|
418
|
+
const values = await this.client.lRange(queueName, 0, pageSize - 1);
|
419
|
+
return values.map((value) => this.parseValue(value));
|
420
|
+
}
|
421
|
+
/**
|
422
|
+
* Gracefully disconnects from the Redis server.
|
423
|
+
*
|
424
|
+
* @returns {Promise<void>} A promise that resolves when the connection is closed
|
85
425
|
*/
|
86
426
|
async disconnect() {
|
87
427
|
await this.client.quit();
|
88
428
|
}
|
89
429
|
/**
|
90
|
-
* Gets the default
|
430
|
+
* Gets the default Time-To-Live value in milliseconds.
|
91
431
|
*
|
92
|
-
* @returns {number}
|
432
|
+
* @returns {number} The default TTL in milliseconds
|
93
433
|
*/
|
94
434
|
getTtlMilliseconds() {
|
95
435
|
return this.ttlMilliseconds;
|
96
436
|
}
|
97
|
-
|
98
|
-
|
99
|
-
|
100
|
-
|
101
|
-
|
437
|
+
/**
|
438
|
+
* Gets the underlying Redis client instance.
|
439
|
+
*
|
440
|
+
* @returns {typeof this.client} The Redis client instance
|
441
|
+
*/
|
442
|
+
getClient() {
|
443
|
+
return this.client;
|
444
|
+
}
|
102
445
|
};
|
103
446
|
export {
|
104
447
|
RedisTtlCache,
|