dialcache 0.1.1

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.
@@ -0,0 +1,329 @@
1
+ "use strict";
2
+ var __defProp = Object.defineProperty;
3
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
4
+ var __getOwnPropNames = Object.getOwnPropertyNames;
5
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
6
+ var __export = (target, all) => {
7
+ for (var name in all)
8
+ __defProp(target, name, { get: all[name], enumerable: true });
9
+ };
10
+ var __copyProps = (to, from, except, desc) => {
11
+ if (from && typeof from === "object" || typeof from === "function") {
12
+ for (let key of __getOwnPropNames(from))
13
+ if (!__hasOwnProp.call(to, key) && key !== except)
14
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
15
+ }
16
+ return to;
17
+ };
18
+ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
19
+
20
+ // src/node-redis.ts
21
+ var node_redis_exports = {};
22
+ __export(node_redis_exports, {
23
+ createNodeRedisDialCacheClient: () => createNodeRedisDialCacheClient,
24
+ dialcacheRedisScripts: () => dialcacheRedisScripts
25
+ });
26
+ module.exports = __toCommonJS(node_redis_exports);
27
+ var import_redis = require("redis");
28
+
29
+ // src/internal/redis-scripts.ts
30
+ var REDIS_FRAME_VERSION = 1;
31
+ var REDIS_ENCODING_UTF8 = 0;
32
+ var REDIS_ENCODING_BINARY = 1;
33
+ var WATERMARK_TTL_MARGIN_MS = 6e4;
34
+ var PARSE_WATERMARK_LUA = String.raw`local function parse_watermark(raw)
35
+ if not string.match(raw, "^%d+$") and not string.match(raw, "^%d+%.%d+$") then
36
+ return nil
37
+ end
38
+ local value = tonumber(raw)
39
+ if not value or value >= math.huge then
40
+ return nil
41
+ end
42
+ return value
43
+ end`;
44
+ var CEIL_FINITE_NUMBER_LUA = String.raw`local function ceil_finite_number(raw)
45
+ local value = tonumber(raw)
46
+ if not value or value ~= value or value >= math.huge or value <= -math.huge then
47
+ return nil
48
+ end
49
+ return math.ceil(value)
50
+ end`;
51
+ var READ_FRAME_LUA = String.raw`local value = redis.call("GET", KEYS[1])
52
+ if not value or string.len(value) < 10 then
53
+ return false
54
+ end
55
+
56
+ if string.byte(value, 1) ~= ${REDIS_FRAME_VERSION} then
57
+ return false
58
+ end`;
59
+ var RETURN_PAYLOAD_LUA = String.raw`return string.sub(value, 10)`;
60
+ var VALIDATE_WRITE_ARGUMENTS_LUA = String.raw`local cache_ttl_ms = ceil_finite_number(ARGV[1])
61
+ local encoding = tonumber(ARGV[2])
62
+ if not cache_ttl_ms or cache_ttl_ms <= 0 then
63
+ return redis.error_reply("ERR invalid DialCache TTL")
64
+ end
65
+ if not encoding or (encoding ~= ${REDIS_ENCODING_UTF8} and encoding ~= ${REDIS_ENCODING_BINARY}) then
66
+ return redis.error_reply("ERR invalid DialCache payload encoding")
67
+ end`;
68
+ var REDIS_TIME_LUA = String.raw`local redis_time = redis.call("TIME")
69
+ local now_ms = tonumber(redis_time[1]) * 1000 + math.floor(tonumber(redis_time[2]) / 1000)`;
70
+ var WRITE_FRAME_LUA = String.raw`local frame = string.char(${REDIS_FRAME_VERSION})
71
+ .. struct.pack(">I8", now_ms)
72
+ .. string.char(encoding)
73
+ .. ARGV[3]
74
+ redis.call("SET", KEYS[1], frame, "PX", cache_ttl_ms)`;
75
+ var READ_CACHE_SCRIPT = [READ_FRAME_LUA, RETURN_PAYLOAD_LUA].join("\n\n");
76
+ var READ_TRACKED_CACHE_SCRIPT = [
77
+ PARSE_WATERMARK_LUA,
78
+ READ_FRAME_LUA,
79
+ String.raw`local raw_watermark = redis.call("GET", KEYS[2])
80
+ if not raw_watermark then
81
+ return false
82
+ end
83
+
84
+ local watermark = parse_watermark(raw_watermark)
85
+ if not watermark then
86
+ return false
87
+ end
88
+
89
+ local created_at = struct.unpack(">I8", string.sub(value, 2, 9))
90
+ if created_at <= watermark then
91
+ return false
92
+ end`,
93
+ RETURN_PAYLOAD_LUA
94
+ ].join("\n\n");
95
+ var WRITE_CACHE_SCRIPT = [
96
+ CEIL_FINITE_NUMBER_LUA,
97
+ VALIDATE_WRITE_ARGUMENTS_LUA,
98
+ REDIS_TIME_LUA,
99
+ WRITE_FRAME_LUA,
100
+ "return 1"
101
+ ].join("\n\n");
102
+ var WRITE_TRACKED_CACHE_SCRIPT = [
103
+ PARSE_WATERMARK_LUA,
104
+ CEIL_FINITE_NUMBER_LUA,
105
+ VALIDATE_WRITE_ARGUMENTS_LUA,
106
+ String.raw`local watermark_ttl_floor_ms = ceil_finite_number(ARGV[4])
107
+ if not watermark_ttl_floor_ms or watermark_ttl_floor_ms <= 0 then
108
+ return redis.error_reply("ERR invalid DialCache watermark TTL")
109
+ end`,
110
+ REDIS_TIME_LUA,
111
+ String.raw`local raw_watermark = redis.call("GET", KEYS[2])
112
+ local watermark = 0
113
+ if raw_watermark then
114
+ watermark = parse_watermark(raw_watermark)
115
+ if not watermark then
116
+ return redis.error_reply("ERR invalid DialCache watermark")
117
+ end
118
+ end
119
+
120
+ if watermark >= now_ms then
121
+ return 0
122
+ end`,
123
+ WRITE_FRAME_LUA,
124
+ String.raw`local desired_ttl_ms = math.max(watermark_ttl_floor_ms, cache_ttl_ms + ${WATERMARK_TTL_MARGIN_MS})
125
+ if not raw_watermark then
126
+ redis.call("SET", KEYS[2], "0", "PX", desired_ttl_ms)
127
+ else
128
+ local current_ttl_ms = redis.call("PTTL", KEYS[2])
129
+ if current_ttl_ms == -2 then
130
+ redis.call("SET", KEYS[2], raw_watermark, "PX", desired_ttl_ms)
131
+ elseif current_ttl_ms ~= -1 and current_ttl_ms < desired_ttl_ms then
132
+ redis.call("PEXPIRE", KEYS[2], desired_ttl_ms)
133
+ end
134
+ end`,
135
+ "return 1"
136
+ ].join("\n\n");
137
+ var INVALIDATE_CACHE_SCRIPT = [
138
+ PARSE_WATERMARK_LUA,
139
+ CEIL_FINITE_NUMBER_LUA,
140
+ String.raw`local future_buffer_ms = ceil_finite_number(ARGV[1])
141
+ local watermark_ttl_floor_ms = ceil_finite_number(ARGV[2])
142
+ if not future_buffer_ms or future_buffer_ms < 0 then
143
+ return redis.error_reply("ERR invalid DialCache future buffer")
144
+ end
145
+ if not watermark_ttl_floor_ms or watermark_ttl_floor_ms <= 0 then
146
+ return redis.error_reply("ERR invalid DialCache watermark TTL")
147
+ end`,
148
+ REDIS_TIME_LUA,
149
+ String.raw`local proposed_watermark = now_ms + future_buffer_ms
150
+ local raw_watermark = redis.call("GET", KEYS[1])
151
+ local current_watermark = 0
152
+
153
+ if raw_watermark then
154
+ local parsed_watermark = parse_watermark(raw_watermark)
155
+ if parsed_watermark then
156
+ current_watermark = parsed_watermark
157
+ end
158
+ end
159
+
160
+ local watermark = math.ceil(math.max(current_watermark, proposed_watermark))
161
+ local current_ttl_ms = -2
162
+ if raw_watermark then
163
+ current_ttl_ms = redis.call("PTTL", KEYS[1])
164
+ end
165
+ local desired_ttl_ms = math.max(
166
+ watermark_ttl_floor_ms,
167
+ future_buffer_ms + ${WATERMARK_TTL_MARGIN_MS},
168
+ watermark - now_ms + ${WATERMARK_TTL_MARGIN_MS}
169
+ )
170
+ if current_ttl_ms > desired_ttl_ms then
171
+ desired_ttl_ms = current_ttl_ms
172
+ end
173
+
174
+ local encoded_watermark = string.format("%.0f", watermark)
175
+ if current_ttl_ms == -1 then
176
+ redis.call("SET", KEYS[1], encoded_watermark)
177
+ else
178
+ redis.call("SET", KEYS[1], encoded_watermark, "PX", desired_ttl_ms)
179
+ end`,
180
+ "return 1"
181
+ ].join("\n\n");
182
+
183
+ // src/redis-client.ts
184
+ var DialCacheRedisPayloadError = class extends Error {
185
+ constructor(message) {
186
+ super(message);
187
+ this.name = "DialCacheRedisPayloadError";
188
+ }
189
+ };
190
+ var DialCacheRedisPayloadEncodingError = class extends Error {
191
+ constructor(message) {
192
+ super(message);
193
+ this.name = "DialCacheRedisPayloadEncodingError";
194
+ }
195
+ };
196
+
197
+ // src/internal/redis-payload.ts
198
+ function redisPayloadEncoding(value) {
199
+ return Buffer.isBuffer(value) ? REDIS_ENCODING_BINARY : REDIS_ENCODING_UTF8;
200
+ }
201
+ function decodeRedisPayload(raw) {
202
+ if (raw.length === 0) {
203
+ throw new DialCacheRedisPayloadError("Invalid DialCache Redis payload");
204
+ }
205
+ const encoding = raw[0];
206
+ const payload = raw.subarray(1);
207
+ if (encoding === REDIS_ENCODING_UTF8) {
208
+ return payload.toString("utf8");
209
+ }
210
+ if (encoding === REDIS_ENCODING_BINARY) {
211
+ return payload;
212
+ }
213
+ throw new DialCacheRedisPayloadEncodingError("Invalid DialCache Redis payload encoding");
214
+ }
215
+
216
+ // src/node-redis.ts
217
+ var bufferReplyOptions = (0, import_redis.commandOptions)({ returnBuffers: true });
218
+ var readReply = (reply) => reply;
219
+ var integerReply = (reply) => reply;
220
+ function defineDialCacheScript(config) {
221
+ return (0, import_redis.defineScript)(config);
222
+ }
223
+ var dialcacheRedisScripts = {
224
+ dialcacheRead: defineDialCacheScript({
225
+ SCRIPT: READ_CACHE_SCRIPT,
226
+ NUMBER_OF_KEYS: 1,
227
+ FIRST_KEY_INDEX: 0,
228
+ IS_READ_ONLY: true,
229
+ transformArguments(valueKey) {
230
+ return [valueKey];
231
+ },
232
+ transformReply: readReply
233
+ }),
234
+ dialcacheReadTracked: defineDialCacheScript({
235
+ SCRIPT: READ_TRACKED_CACHE_SCRIPT,
236
+ NUMBER_OF_KEYS: 2,
237
+ FIRST_KEY_INDEX: 0,
238
+ // Replica lag must not hide a newly-written invalidation watermark.
239
+ IS_READ_ONLY: false,
240
+ transformArguments(valueKey, watermarkKey) {
241
+ return [valueKey, watermarkKey];
242
+ },
243
+ transformReply: readReply
244
+ }),
245
+ dialcacheWrite: defineDialCacheScript({
246
+ SCRIPT: WRITE_CACHE_SCRIPT,
247
+ NUMBER_OF_KEYS: 1,
248
+ FIRST_KEY_INDEX: 0,
249
+ IS_READ_ONLY: false,
250
+ transformArguments(valueKey, cacheTtlMs, encoding, payload) {
251
+ return [valueKey, String(cacheTtlMs), String(encoding), payload];
252
+ },
253
+ transformReply: integerReply
254
+ }),
255
+ dialcacheWriteTracked: defineDialCacheScript({
256
+ SCRIPT: WRITE_TRACKED_CACHE_SCRIPT,
257
+ NUMBER_OF_KEYS: 2,
258
+ FIRST_KEY_INDEX: 0,
259
+ IS_READ_ONLY: false,
260
+ transformArguments(valueKey, watermarkKey, cacheTtlMs, encoding, payload, watermarkTtlFloorMs) {
261
+ return [valueKey, watermarkKey, String(cacheTtlMs), String(encoding), payload, String(watermarkTtlFloorMs)];
262
+ },
263
+ transformReply: integerReply
264
+ }),
265
+ dialcacheInvalidate: defineDialCacheScript({
266
+ SCRIPT: INVALIDATE_CACHE_SCRIPT,
267
+ NUMBER_OF_KEYS: 1,
268
+ FIRST_KEY_INDEX: 0,
269
+ IS_READ_ONLY: false,
270
+ transformArguments(watermarkKey, futureBufferMs, watermarkTtlFloorMs) {
271
+ return [watermarkKey, String(futureBufferMs), String(watermarkTtlFloorMs)];
272
+ },
273
+ transformReply: integerReply
274
+ })
275
+ };
276
+ function createNodeRedisDialCacheClient(client) {
277
+ return {
278
+ async read({ valueKey, watermarkKey }) {
279
+ const raw = watermarkKey === void 0 ? await client.dialcacheRead(bufferReplyOptions, valueKey) : await client.dialcacheReadTracked(bufferReplyOptions, valueKey, watermarkKey);
280
+ return raw === null ? null : decodeRedisPayload(raw);
281
+ },
282
+ async write(request) {
283
+ const { valueKey, watermarkKey, cacheTtlMs, value } = request;
284
+ const encodingByte = redisPayloadEncoding(value);
285
+ const result = watermarkKey === void 0 ? await client.dialcacheWrite(valueKey, cacheTtlMs, encodingByte, value) : await client.dialcacheWriteTracked(
286
+ valueKey,
287
+ watermarkKey,
288
+ cacheTtlMs,
289
+ encodingByte,
290
+ value,
291
+ request.watermarkTtlFloorMs
292
+ );
293
+ return result === 1;
294
+ },
295
+ async invalidate({ watermarkKey, futureBufferMs, watermarkTtlFloorMs }) {
296
+ await client.dialcacheInvalidate(watermarkKey, futureBufferMs, watermarkTtlFloorMs);
297
+ },
298
+ async flushAll() {
299
+ const cluster = clusterCommands(client);
300
+ if (cluster === null) {
301
+ if (client.flushAll === void 0) {
302
+ throw new Error("Node-redis client does not implement flushAll");
303
+ }
304
+ await client.flushAll();
305
+ return;
306
+ }
307
+ if (cluster.masters.length === 0) {
308
+ throw new Error("Node-redis cluster has no connected masters");
309
+ }
310
+ await Promise.all(
311
+ cluster.masters.map(async (master) => {
312
+ const node = await cluster.nodeClient(master);
313
+ await node.flushAll();
314
+ })
315
+ );
316
+ }
317
+ };
318
+ }
319
+ function clusterCommands(client) {
320
+ if (!("masters" in client) || !("nodeClient" in client) || !Array.isArray(client.masters)) {
321
+ return null;
322
+ }
323
+ return client;
324
+ }
325
+ // Annotate the CommonJS export names for ESM import in node:
326
+ 0 && (module.exports = {
327
+ createNodeRedisDialCacheClient,
328
+ dialcacheRedisScripts
329
+ });
@@ -0,0 +1,52 @@
1
+ import { commandOptions } from 'redis';
2
+ import { k as DialCacheRedisClient } from './config-B7bGp-Xj.cjs';
3
+ import 'prom-client';
4
+
5
+ type BufferReplyOptions = ReturnType<typeof commandOptions<{
6
+ readonly returnBuffers: true;
7
+ }>>;
8
+ type NodeRedisArgument = string | Buffer;
9
+ interface NodeRedisScript<Args extends Array<unknown>, Reply> {
10
+ readonly SCRIPT: string;
11
+ readonly SHA1: string;
12
+ readonly NUMBER_OF_KEYS: number;
13
+ readonly FIRST_KEY_INDEX: number;
14
+ readonly IS_READ_ONLY: boolean;
15
+ transformArguments(...args: Args): Array<NodeRedisArgument>;
16
+ transformReply(reply: Reply): Reply;
17
+ }
18
+ type DialCacheNodeRedisScripts = {
19
+ readonly dialcacheRead: NodeRedisScript<[valueKey: string], string | null>;
20
+ readonly dialcacheReadTracked: NodeRedisScript<[valueKey: string, watermarkKey: string], string | null>;
21
+ readonly dialcacheWrite: NodeRedisScript<[
22
+ valueKey: string,
23
+ cacheTtlMs: number,
24
+ encoding: number,
25
+ payload: string | Buffer
26
+ ], number>;
27
+ readonly dialcacheWriteTracked: NodeRedisScript<[
28
+ valueKey: string,
29
+ watermarkKey: string,
30
+ cacheTtlMs: number,
31
+ encoding: number,
32
+ payload: string | Buffer,
33
+ watermarkTtlFloorMs: number
34
+ ], number>;
35
+ readonly dialcacheInvalidate: NodeRedisScript<[
36
+ watermarkKey: string,
37
+ futureBufferMs: number,
38
+ watermarkTtlFloorMs: number
39
+ ], number>;
40
+ };
41
+ declare const dialcacheRedisScripts: DialCacheNodeRedisScripts;
42
+ interface NodeRedisScriptClient {
43
+ dialcacheRead(options: BufferReplyOptions, valueKey: string): Promise<Buffer | null>;
44
+ dialcacheReadTracked(options: BufferReplyOptions, valueKey: string, watermarkKey: string): Promise<Buffer | null>;
45
+ dialcacheWrite(valueKey: string, cacheTtlMs: number, encoding: number, payload: string | Buffer): Promise<number>;
46
+ dialcacheWriteTracked(valueKey: string, watermarkKey: string, cacheTtlMs: number, encoding: number, payload: string | Buffer, watermarkTtlFloorMs: number): Promise<number>;
47
+ dialcacheInvalidate(watermarkKey: string, futureBufferMs: number, watermarkTtlFloorMs: number): Promise<number>;
48
+ flushAll?(): Promise<unknown>;
49
+ }
50
+ declare function createNodeRedisDialCacheClient(client: NodeRedisScriptClient): DialCacheRedisClient;
51
+
52
+ export { type DialCacheNodeRedisScripts, createNodeRedisDialCacheClient, dialcacheRedisScripts };
@@ -0,0 +1,52 @@
1
+ import { commandOptions } from 'redis';
2
+ import { k as DialCacheRedisClient } from './config-B7bGp-Xj.js';
3
+ import 'prom-client';
4
+
5
+ type BufferReplyOptions = ReturnType<typeof commandOptions<{
6
+ readonly returnBuffers: true;
7
+ }>>;
8
+ type NodeRedisArgument = string | Buffer;
9
+ interface NodeRedisScript<Args extends Array<unknown>, Reply> {
10
+ readonly SCRIPT: string;
11
+ readonly SHA1: string;
12
+ readonly NUMBER_OF_KEYS: number;
13
+ readonly FIRST_KEY_INDEX: number;
14
+ readonly IS_READ_ONLY: boolean;
15
+ transformArguments(...args: Args): Array<NodeRedisArgument>;
16
+ transformReply(reply: Reply): Reply;
17
+ }
18
+ type DialCacheNodeRedisScripts = {
19
+ readonly dialcacheRead: NodeRedisScript<[valueKey: string], string | null>;
20
+ readonly dialcacheReadTracked: NodeRedisScript<[valueKey: string, watermarkKey: string], string | null>;
21
+ readonly dialcacheWrite: NodeRedisScript<[
22
+ valueKey: string,
23
+ cacheTtlMs: number,
24
+ encoding: number,
25
+ payload: string | Buffer
26
+ ], number>;
27
+ readonly dialcacheWriteTracked: NodeRedisScript<[
28
+ valueKey: string,
29
+ watermarkKey: string,
30
+ cacheTtlMs: number,
31
+ encoding: number,
32
+ payload: string | Buffer,
33
+ watermarkTtlFloorMs: number
34
+ ], number>;
35
+ readonly dialcacheInvalidate: NodeRedisScript<[
36
+ watermarkKey: string,
37
+ futureBufferMs: number,
38
+ watermarkTtlFloorMs: number
39
+ ], number>;
40
+ };
41
+ declare const dialcacheRedisScripts: DialCacheNodeRedisScripts;
42
+ interface NodeRedisScriptClient {
43
+ dialcacheRead(options: BufferReplyOptions, valueKey: string): Promise<Buffer | null>;
44
+ dialcacheReadTracked(options: BufferReplyOptions, valueKey: string, watermarkKey: string): Promise<Buffer | null>;
45
+ dialcacheWrite(valueKey: string, cacheTtlMs: number, encoding: number, payload: string | Buffer): Promise<number>;
46
+ dialcacheWriteTracked(valueKey: string, watermarkKey: string, cacheTtlMs: number, encoding: number, payload: string | Buffer, watermarkTtlFloorMs: number): Promise<number>;
47
+ dialcacheInvalidate(watermarkKey: string, futureBufferMs: number, watermarkTtlFloorMs: number): Promise<number>;
48
+ flushAll?(): Promise<unknown>;
49
+ }
50
+ declare function createNodeRedisDialCacheClient(client: NodeRedisScriptClient): DialCacheRedisClient;
51
+
52
+ export { type DialCacheNodeRedisScripts, createNodeRedisDialCacheClient, dialcacheRedisScripts };
@@ -0,0 +1,127 @@
1
+ import {
2
+ decodeRedisPayload,
3
+ redisPayloadEncoding
4
+ } from "./chunk-BF6XTPTS.js";
5
+ import "./chunk-S5VCTJID.js";
6
+ import {
7
+ INVALIDATE_CACHE_SCRIPT,
8
+ READ_CACHE_SCRIPT,
9
+ READ_TRACKED_CACHE_SCRIPT,
10
+ WRITE_CACHE_SCRIPT,
11
+ WRITE_TRACKED_CACHE_SCRIPT
12
+ } from "./chunk-2TPHNNE7.js";
13
+
14
+ // src/node-redis.ts
15
+ import { commandOptions, defineScript } from "redis";
16
+ var bufferReplyOptions = commandOptions({ returnBuffers: true });
17
+ var readReply = (reply) => reply;
18
+ var integerReply = (reply) => reply;
19
+ function defineDialCacheScript(config) {
20
+ return defineScript(config);
21
+ }
22
+ var dialcacheRedisScripts = {
23
+ dialcacheRead: defineDialCacheScript({
24
+ SCRIPT: READ_CACHE_SCRIPT,
25
+ NUMBER_OF_KEYS: 1,
26
+ FIRST_KEY_INDEX: 0,
27
+ IS_READ_ONLY: true,
28
+ transformArguments(valueKey) {
29
+ return [valueKey];
30
+ },
31
+ transformReply: readReply
32
+ }),
33
+ dialcacheReadTracked: defineDialCacheScript({
34
+ SCRIPT: READ_TRACKED_CACHE_SCRIPT,
35
+ NUMBER_OF_KEYS: 2,
36
+ FIRST_KEY_INDEX: 0,
37
+ // Replica lag must not hide a newly-written invalidation watermark.
38
+ IS_READ_ONLY: false,
39
+ transformArguments(valueKey, watermarkKey) {
40
+ return [valueKey, watermarkKey];
41
+ },
42
+ transformReply: readReply
43
+ }),
44
+ dialcacheWrite: defineDialCacheScript({
45
+ SCRIPT: WRITE_CACHE_SCRIPT,
46
+ NUMBER_OF_KEYS: 1,
47
+ FIRST_KEY_INDEX: 0,
48
+ IS_READ_ONLY: false,
49
+ transformArguments(valueKey, cacheTtlMs, encoding, payload) {
50
+ return [valueKey, String(cacheTtlMs), String(encoding), payload];
51
+ },
52
+ transformReply: integerReply
53
+ }),
54
+ dialcacheWriteTracked: defineDialCacheScript({
55
+ SCRIPT: WRITE_TRACKED_CACHE_SCRIPT,
56
+ NUMBER_OF_KEYS: 2,
57
+ FIRST_KEY_INDEX: 0,
58
+ IS_READ_ONLY: false,
59
+ transformArguments(valueKey, watermarkKey, cacheTtlMs, encoding, payload, watermarkTtlFloorMs) {
60
+ return [valueKey, watermarkKey, String(cacheTtlMs), String(encoding), payload, String(watermarkTtlFloorMs)];
61
+ },
62
+ transformReply: integerReply
63
+ }),
64
+ dialcacheInvalidate: defineDialCacheScript({
65
+ SCRIPT: INVALIDATE_CACHE_SCRIPT,
66
+ NUMBER_OF_KEYS: 1,
67
+ FIRST_KEY_INDEX: 0,
68
+ IS_READ_ONLY: false,
69
+ transformArguments(watermarkKey, futureBufferMs, watermarkTtlFloorMs) {
70
+ return [watermarkKey, String(futureBufferMs), String(watermarkTtlFloorMs)];
71
+ },
72
+ transformReply: integerReply
73
+ })
74
+ };
75
+ function createNodeRedisDialCacheClient(client) {
76
+ return {
77
+ async read({ valueKey, watermarkKey }) {
78
+ const raw = watermarkKey === void 0 ? await client.dialcacheRead(bufferReplyOptions, valueKey) : await client.dialcacheReadTracked(bufferReplyOptions, valueKey, watermarkKey);
79
+ return raw === null ? null : decodeRedisPayload(raw);
80
+ },
81
+ async write(request) {
82
+ const { valueKey, watermarkKey, cacheTtlMs, value } = request;
83
+ const encodingByte = redisPayloadEncoding(value);
84
+ const result = watermarkKey === void 0 ? await client.dialcacheWrite(valueKey, cacheTtlMs, encodingByte, value) : await client.dialcacheWriteTracked(
85
+ valueKey,
86
+ watermarkKey,
87
+ cacheTtlMs,
88
+ encodingByte,
89
+ value,
90
+ request.watermarkTtlFloorMs
91
+ );
92
+ return result === 1;
93
+ },
94
+ async invalidate({ watermarkKey, futureBufferMs, watermarkTtlFloorMs }) {
95
+ await client.dialcacheInvalidate(watermarkKey, futureBufferMs, watermarkTtlFloorMs);
96
+ },
97
+ async flushAll() {
98
+ const cluster = clusterCommands(client);
99
+ if (cluster === null) {
100
+ if (client.flushAll === void 0) {
101
+ throw new Error("Node-redis client does not implement flushAll");
102
+ }
103
+ await client.flushAll();
104
+ return;
105
+ }
106
+ if (cluster.masters.length === 0) {
107
+ throw new Error("Node-redis cluster has no connected masters");
108
+ }
109
+ await Promise.all(
110
+ cluster.masters.map(async (master) => {
111
+ const node = await cluster.nodeClient(master);
112
+ await node.flushAll();
113
+ })
114
+ );
115
+ }
116
+ };
117
+ }
118
+ function clusterCommands(client) {
119
+ if (!("masters" in client) || !("nodeClient" in client) || !Array.isArray(client.masters)) {
120
+ return null;
121
+ }
122
+ return client;
123
+ }
124
+ export {
125
+ createNodeRedisDialCacheClient,
126
+ dialcacheRedisScripts
127
+ };