@voltro/kv 0.87.0 → 0.88.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 (50) hide show
  1. package/CHANGELOG.md +169 -6
  2. package/THIRD-PARTY-NOTICES.md +2 -1345
  3. package/dist/Kv.js +1 -2
  4. package/dist/KvStore.js +1 -2
  5. package/dist/analytics.js +1 -2
  6. package/dist/backendMemory.js +1 -2
  7. package/dist/backendRedis.js +1 -2
  8. package/dist/cacheAtomicProtocol.js +34 -24
  9. package/dist/cacheAtomicScript.js +19 -2
  10. package/dist/cacheAtomicState.js +1 -2
  11. package/dist/connection.js +74 -70
  12. package/dist/connectionAnalyticsConfig.js +1 -2
  13. package/dist/connectionConfigError.js +10 -0
  14. package/dist/connectionConfigProvider.js +1 -2
  15. package/dist/connectionDefinitions.js +1 -2
  16. package/dist/connectionMemory.js +1 -2
  17. package/dist/connectionMetrics.js +1 -2
  18. package/dist/connectionNamespace.js +1 -2
  19. package/dist/connectionNats.js +44 -44
  20. package/dist/connectionNatsConfig.js +1 -2
  21. package/dist/connectionNatsSubjects.js +1 -2
  22. package/dist/connectionOwner.js +1 -2
  23. package/dist/connectionPool.js +252 -252
  24. package/dist/connectionPrefix.js +1 -2
  25. package/dist/connectionScripts.js +1 -2
  26. package/dist/connectionSqlConfig.js +1 -2
  27. package/dist/connectionStorageConfig.js +1 -2
  28. package/dist/connectionStorageFacade.js +1 -2
  29. package/dist/connectionSubscriber.js +47 -47
  30. package/dist/driverModule.js +9 -0
  31. package/dist/errors.js +1 -2
  32. package/dist/expirySweep.js +1 -2
  33. package/dist/hot-contract.js +1 -2
  34. package/dist/hot-testing.d.ts +14 -1
  35. package/dist/hotMemory.js +1 -2
  36. package/dist/hotOperations.js +1 -2
  37. package/dist/hotRateLimit.js +1 -2
  38. package/dist/hotReadAvailability.js +1 -2
  39. package/dist/hotRedis.js +1 -2
  40. package/dist/hotRedisScript.js +1 -2
  41. package/dist/hotRouting.js +2 -3
  42. package/dist/hotState.js +1 -2
  43. package/dist/hotStoreConformance.js +76 -78
  44. package/dist/nativeRedisReads.js +2 -3
  45. package/dist/nativeRedisTopology.js +64 -63
  46. package/dist/redisDiagnostics.js +1 -2
  47. package/dist/redisReadPolicy.js +1 -2
  48. package/dist/storage.js +1 -2
  49. package/dist/storageAddress.js +1 -2
  50. package/package.json +13 -10
@@ -1,17 +1,16 @@
1
1
  import { HotStore as e } from "./hot-contract.js";
2
2
  import { Effect as t, Option as n, Result as r, Stream as i } from "effect";
3
- import { describe as a, expect as o, it as s } from "vitest";
4
- //#region src/hotStoreConformance.ts
5
- var c = (c, l) => {
6
- let u = (n, r) => s(n, async () => {
7
- let n = l();
3
+ // src/hotStoreConformance.ts
4
+ var a = (a, o, s) => {
5
+ let { describe: c, expect: l, it: u } = s, d = (n, r) => u(n, async () => {
6
+ let n = o();
8
7
  await t.runPromise(t.gen(function* () {
9
8
  let t = yield* e;
10
- o(t.capabilities).toEqual(n.capabilities), yield* r(t, n.advance);
9
+ l(t.capabilities).toEqual(n.capabilities), yield* r(t, n.advance);
11
10
  }).pipe(t.provide(n.layer)));
12
11
  });
13
- a(`hotStoreConformance — ${c}`, () => {
14
- u("sorted-set order, reverse ties, negative ranks, inclusive score bounds and limits", (e) => t.gen(function* () {
12
+ c(`hotStoreConformance — ${a}`, () => {
13
+ d("sorted-set order, reverse ties, negative ranks, inclusive score bounds and limits", (e) => t.gen(function* () {
15
14
  yield* e.zadd("board", [
16
15
  {
17
16
  member: "b",
@@ -33,25 +32,25 @@ var c = (c, l) => {
33
32
  member: "",
34
33
  score: 30
35
34
  }
36
- ]), o((yield* e.zrange("board", { byRank: [0, -1] }, "asc")).map((e) => e.member)).toEqual([
35
+ ]), l((yield* e.zrange("board", { byRank: [0, -1] }, "asc")).map((e) => e.member)).toEqual([
37
36
  "a",
38
37
  "b",
39
38
  "c",
40
39
  "",
41
40
  "𐀀"
42
- ]), o((yield* e.zrange("board", { byScore: [10, 20] }, "desc")).map((e) => e.member)).toEqual([
41
+ ]), l((yield* e.zrange("board", { byScore: [10, 20] }, "desc")).map((e) => e.member)).toEqual([
43
42
  "c",
44
43
  "b",
45
44
  "a"
46
- ]), o(yield* e.zrange("board", { byRank: [0, -1] }, "asc", { limit: 0 })).toEqual([]), o((yield* e.zrange("board", { byRank: [-2, -1] }, "asc")).length).toBe(2), o((yield* e.zrange("board", { byScore: [10, 20] }, "asc", { limit: 1 }))[0]?.member).toBe("a"), o(n.getOrNull(yield* e.zrank("board", "b", "asc"))).toBe(1), o(n.getOrNull(yield* e.zrank("board", "b", "desc"))).toBe(3), o(n.isNone(yield* e.zrank("board", "absent", "asc"))).toBe(!0), o(yield* e.zcard("board")).toBe(5);
47
- })), u("score modes, duplicate members and removal by rank/score", (e) => t.gen(function* () {
45
+ ]), l(yield* e.zrange("board", { byRank: [0, -1] }, "asc", { limit: 0 })).toEqual([]), l((yield* e.zrange("board", { byRank: [-2, -1] }, "asc")).length).toBe(2), l((yield* e.zrange("board", { byScore: [10, 20] }, "asc", { limit: 1 }))[0]?.member).toBe("a"), l(n.getOrNull(yield* e.zrank("board", "b", "asc"))).toBe(1), l(n.getOrNull(yield* e.zrank("board", "b", "desc"))).toBe(3), l(n.isNone(yield* e.zrank("board", "absent", "asc"))).toBe(!0), l(yield* e.zcard("board")).toBe(5);
46
+ })), d("score modes, duplicate members and removal by rank/score", (e) => t.gen(function* () {
48
47
  yield* e.zadd("z", [{
49
48
  member: "a",
50
49
  score: 10
51
50
  }]), yield* e.zadd("z", [{
52
51
  member: "a",
53
52
  score: 5
54
- }], { mode: "max" }), o(n.getOrNull(yield* e.zscore("z", "a"))).toBe(10), yield* e.zadd("z", [{
53
+ }], { mode: "max" }), l(n.getOrNull(yield* e.zscore("z", "a"))).toBe(10), yield* e.zadd("z", [{
55
54
  member: "a",
56
55
  score: 7
57
56
  }], { mode: "min" }), yield* e.zadd("z", [{
@@ -60,36 +59,36 @@ var c = (c, l) => {
60
59
  }, {
61
60
  member: "a",
62
61
  score: 3
63
- }], { mode: "incr" }), o(n.getOrNull(yield* e.zscore("z", "a"))).toBe(12), yield* e.zadd("z", [{
62
+ }], { mode: "incr" }), l(n.getOrNull(yield* e.zscore("z", "a"))).toBe(12), yield* e.zadd("z", [{
64
63
  member: "b",
65
64
  score: 20
66
65
  }, {
67
66
  member: "c",
68
67
  score: 30
69
- }]), o(yield* e.zremRange("z", { byScore: [20, 20] })).toBe(1), o(yield* e.zremRange("z", { byRank: [-1, -1] })).toBe(1), o(yield* e.zrem("z", ["a", "a"])).toBe(1), o(yield* e.zrange("z", { byRank: [0, -1] }, "asc")).toEqual([]), o(n.isNone(yield* e.zscore("z", "a"))).toBe(!0), yield* e.zadd("precise", [{
68
+ }]), l(yield* e.zremRange("z", { byScore: [20, 20] })).toBe(1), l(yield* e.zremRange("z", { byRank: [-1, -1] })).toBe(1), l(yield* e.zrem("z", ["a", "a"])).toBe(1), l(yield* e.zrange("z", { byRank: [0, -1] }, "asc")).toEqual([]), l(n.isNone(yield* e.zscore("z", "a"))).toBe(!0), yield* e.zadd("precise", [{
70
69
  member: "p",
71
70
  score: 1.2345678901234567
72
- }]), o(n.getOrNull(yield* e.zscore("precise", "p"))).toBe(1.2345678901234567), o((yield* e.zrange("precise", { byRank: [0, -1] }, "asc"))[0]?.score).toBe(1.2345678901234567), o((yield* e.zrange("precise", { byScore: [1.2345678901234567, 1.2345678901234567] }, "asc"))[0]?.score).toBe(1.2345678901234567), o(yield* e.zremRange("precise", { byScore: [1.2345678901234567, 1.2345678901234567] })).toBe(1);
73
- })), u("hashes preserve arbitrary field names and sets count unique changes", (e) => t.gen(function* () {
71
+ }]), l(n.getOrNull(yield* e.zscore("precise", "p"))).toBe(1.2345678901234567), l((yield* e.zrange("precise", { byRank: [0, -1] }, "asc"))[0]?.score).toBe(1.2345678901234567), l((yield* e.zrange("precise", { byScore: [1.2345678901234567, 1.2345678901234567] }, "asc"))[0]?.score).toBe(1.2345678901234567), l(yield* e.zremRange("precise", { byScore: [1.2345678901234567, 1.2345678901234567] })).toBe(1);
72
+ })), d("hashes preserve arbitrary field names and sets count unique changes", (e) => t.gen(function* () {
74
73
  yield* e.hset("hash", Object.fromEntries([
75
74
  ["__proto__", "p"],
76
75
  ["constructor", "c"],
77
76
  ["a", "1"]
78
- ])), o(n.getOrNull(yield* e.hget("hash", "__proto__"))).toBe("p"), o(yield* e.hgetAll("hash")).toEqual(Object.fromEntries([
77
+ ])), l(n.getOrNull(yield* e.hget("hash", "__proto__"))).toBe("p"), l(yield* e.hgetAll("hash")).toEqual(Object.fromEntries([
79
78
  ["__proto__", "p"],
80
79
  ["constructor", "c"],
81
80
  ["a", "1"]
82
- ])), o(yield* e.hdel("hash", ["a", "a"])).toBe(1), o(n.isNone(yield* e.hget("hash", "a"))).toBe(!0), o(yield* e.sadd("set", [
81
+ ])), l(yield* e.hdel("hash", ["a", "a"])).toBe(1), l(n.isNone(yield* e.hget("hash", "a"))).toBe(!0), l(yield* e.sadd("set", [
83
82
  "b",
84
83
  "a",
85
84
  "a"
86
- ])).toBe(2), o(yield* e.sadd("set", ["b"])).toBe(0), o(yield* e.smembers("set")).toEqual(["a", "b"]), o(yield* e.sismember("set", "a")).toBe(!0), o(yield* e.srem("set", ["a", "a"])).toBe(1), o(yield* e.sismember("set", "a")).toBe(!1), o(yield* e.hgetAll("absent")).toEqual({});
87
- })), u("counter bounds fail without changing the value; increments are atomic", (e) => t.gen(function* () {
85
+ ])).toBe(2), l(yield* e.sadd("set", ["b"])).toBe(0), l(yield* e.smembers("set")).toEqual(["a", "b"]), l(yield* e.sismember("set", "a")).toBe(!0), l(yield* e.srem("set", ["a", "a"])).toBe(1), l(yield* e.sismember("set", "a")).toBe(!1), l(yield* e.hgetAll("absent")).toEqual({});
86
+ })), d("counter bounds fail without changing the value; increments are atomic", (e) => t.gen(function* () {
88
87
  let n = yield* t.all(Array.from({ length: 100 }, () => e.incrBy("counter", 1)), { concurrency: "unbounded" });
89
- o(new Set(n).size).toBe(100), o(yield* e.incrBy("counter", 0)).toBe(100);
88
+ l(new Set(n).size).toBe(100), l(yield* e.incrBy("counter", 0)).toBe(100);
90
89
  let i = yield* e.incrBy("counter", 1, { max: 100 }).pipe(t.result);
91
- o(r.isFailure(i)).toBe(!0), r.isFailure(i) && o(i.failure.reason).toBe("limit"), o(yield* e.incrBy("counter", -20)).toBe(80);
92
- })), u("concurrent batches do not interleave and concurrent leases have one winner", (e) => t.gen(function* () {
90
+ l(r.isFailure(i)).toBe(!0), r.isFailure(i) && l(i.failure.reason).toBe("limit"), l(yield* e.incrBy("counter", -20)).toBe(80);
91
+ })), d("concurrent batches do not interleave and concurrent leases have one winner", (e) => t.gen(function* () {
93
92
  let n = yield* t.all(Array.from({ length: 20 }, () => e.multi([{
94
93
  op: "incrBy",
95
94
  key: "atomic",
@@ -99,14 +98,14 @@ var c = (c, l) => {
99
98
  key: "atomic",
100
99
  delta: 1
101
100
  }])), { concurrency: "unbounded" });
102
- for (let e of n) o(e[1]).toBe(Number(e[0]) + 1);
103
- o(yield* e.incrBy("atomic", 0)).toBe(40);
101
+ for (let e of n) l(e[1]).toBe(Number(e[0]) + 1);
102
+ l(yield* e.incrBy("atomic", 0)).toBe(40);
104
103
  let r = yield* t.all(Array.from({ length: 100 }, (t, n) => e.setNx("seat", String(n), 2e3)), { concurrency: "unbounded" });
105
- o(r.filter(Boolean)).toHaveLength(1);
106
- })), u("conditional lease release and renewal refuse expired owners without changing a successor", (e, n) => t.gen(function* () {
107
- o(yield* e.compareDelete("conditional", "old")).toBe(!1), o(yield* e.compareExpire("conditional", "old", 1e3)).toBe(!1), o(yield* e.setNx("conditional", "old", 1e3)).toBe(!0), o(yield* e.compareDelete("conditional", "other")).toBe(!1), o(yield* e.compareExpire("conditional", "other", 1e4)).toBe(!1), yield* n(1100), o(yield* e.setNx("conditional", "successor", 1e3)).toBe(!0), o(yield* e.compareDelete("conditional", "old")).toBe(!1), o(yield* e.compareExpire("conditional", "old", 1e4)).toBe(!1), o(yield* e.setNx("conditional", "contender", 1e3)).toBe(!1), yield* n(1100), o(yield* e.setNx("conditional", "next", 1e3)).toBe(!0), o(yield* e.compareDelete("conditional", "next")).toBe(!0), o(yield* e.compareDelete("conditional", "next")).toBe(!1);
108
- })), u("matching renewals reset TTL and batches retain ordered lease comparisons", (e, n) => t.gen(function* () {
109
- yield* e.setNx("renewal", "Grüße 🎮", 1e3), o(yield* e.compareExpire("renewal", "Grüße 🎮", 3e3)).toBe(!0), yield* n(1100), o(yield* e.setNx("renewal", "other", 1e3)).toBe(!1), yield* n(2100), o(yield* e.setNx("renewal", "", 1e3)).toBe(!0), o(yield* e.multi([
104
+ l(r.filter(Boolean)).toHaveLength(1);
105
+ })), d("conditional lease release and renewal refuse expired owners without changing a successor", (e, n) => t.gen(function* () {
106
+ l(yield* e.compareDelete("conditional", "old")).toBe(!1), l(yield* e.compareExpire("conditional", "old", 1e3)).toBe(!1), l(yield* e.setNx("conditional", "old", 1e3)).toBe(!0), l(yield* e.compareDelete("conditional", "other")).toBe(!1), l(yield* e.compareExpire("conditional", "other", 1e4)).toBe(!1), yield* n(1100), l(yield* e.setNx("conditional", "successor", 1e3)).toBe(!0), l(yield* e.compareDelete("conditional", "old")).toBe(!1), l(yield* e.compareExpire("conditional", "old", 1e4)).toBe(!1), l(yield* e.setNx("conditional", "contender", 1e3)).toBe(!1), yield* n(1100), l(yield* e.setNx("conditional", "next", 1e3)).toBe(!0), l(yield* e.compareDelete("conditional", "next")).toBe(!0), l(yield* e.compareDelete("conditional", "next")).toBe(!1);
107
+ })), d("matching renewals reset TTL and batches retain ordered lease comparisons", (e, n) => t.gen(function* () {
108
+ yield* e.setNx("renewal", "Grüße 🎮", 1e3), l(yield* e.compareExpire("renewal", "Grüße 🎮", 3e3)).toBe(!0), yield* n(1100), l(yield* e.setNx("renewal", "other", 1e3)).toBe(!1), yield* n(2100), l(yield* e.setNx("renewal", "", 1e3)).toBe(!0), l(yield* e.multi([
110
109
  {
111
110
  op: "compareExpire",
112
111
  key: "renewal",
@@ -134,8 +133,8 @@ var c = (c, l) => {
134
133
  !0,
135
134
  !0,
136
135
  !1
137
- ]), o(yield* e.compareDelete("renewal", "successor")).toBe(!0);
138
- })), u("conditional lease operations refuse other structures and validate before batch mutation", (e) => t.gen(function* () {
136
+ ]), l(yield* e.compareDelete("renewal", "successor")).toBe(!0);
137
+ })), d("conditional lease operations refuse other structures and validate before batch mutation", (e) => t.gen(function* () {
139
138
  yield* e.hset("conditional:hash", { value: "retained" }), yield* e.incrBy("conditional:counter", 7), yield* e.tokenBucket("conditional:bucket", {
140
139
  capacity: 1,
141
140
  refillPerSec: .001
@@ -152,9 +151,9 @@ var c = (c, l) => {
152
151
  "conditional:quota"
153
152
  ]) for (let i of [e.compareDelete(n, "7"), e.compareExpire(n, "7", 1e3)]) {
154
153
  let e = yield* i.pipe(t.result);
155
- o(r.isFailure(e)).toBe(!0), r.isFailure(e) && o(e.failure.reason).toBe("wrongType");
154
+ l(r.isFailure(e)).toBe(!0), r.isFailure(e) && l(e.failure.reason).toBe("wrongType");
156
155
  }
157
- o(yield* e.hgetAll("conditional:hash")).toEqual({ value: "retained" }), o(yield* e.incrBy("conditional:counter", 0)).toBe(7);
156
+ l(yield* e.hgetAll("conditional:hash")).toEqual({ value: "retained" }), l(yield* e.incrBy("conditional:counter", 0)).toBe(7);
158
157
  let n = yield* e.multi([{
159
158
  op: "setNx",
160
159
  key: "conditional:untouched",
@@ -166,81 +165,81 @@ var c = (c, l) => {
166
165
  value: "owner",
167
166
  ttlMs: 0
168
167
  }]).pipe(t.result);
169
- o(r.isFailure(n)).toBe(!0), o(yield* e.setNx("conditional:untouched", "new", 1e3)).toBe(!0);
168
+ l(r.isFailure(n)).toBe(!0), l(yield* e.setNx("conditional:untouched", "new", 1e3)).toBe(!0);
170
169
  let i = yield* t.all(Array.from({ length: 40 }, () => e.compareDelete("conditional:untouched", "new")), { concurrency: "unbounded" });
171
- o(i.filter(Boolean)).toHaveLength(1);
172
- })), u("token bucket admits once per token and refills with elapsed time", (e, n) => t.gen(function* () {
170
+ l(i.filter(Boolean)).toHaveLength(1);
171
+ })), d("token bucket admits once per token and refills with elapsed time", (e, n) => t.gen(function* () {
173
172
  let t = {
174
173
  capacity: 2,
175
174
  refillPerSec: 1
176
175
  };
177
- o((yield* e.tokenBucket("bucket", t)).allowed).toBe(!0), o((yield* e.tokenBucket("bucket", t)).allowed).toBe(!0);
176
+ l((yield* e.tokenBucket("bucket", t)).allowed).toBe(!0), l((yield* e.tokenBucket("bucket", t)).allowed).toBe(!0);
178
177
  let r = yield* e.tokenBucket("bucket", t);
179
- o(r.allowed).toBe(!1), o(r.retryAfterMs).toBeGreaterThan(0), o(r.retryAfterMs).toBeLessThanOrEqual(1e3), yield* n(1100), o((yield* e.tokenBucket("bucket", t)).allowed).toBe(!0);
180
- })), u("concurrent token consumption cannot oversubscribe capacity", (e) => t.gen(function* () {
178
+ l(r.allowed).toBe(!1), l(r.retryAfterMs).toBeGreaterThan(0), l(r.retryAfterMs).toBeLessThanOrEqual(1e3), yield* n(1100), l((yield* e.tokenBucket("bucket", t)).allowed).toBe(!0);
179
+ })), d("concurrent token consumption cannot oversubscribe capacity", (e) => t.gen(function* () {
181
180
  let n = yield* t.all(Array.from({ length: 50 }, () => e.tokenBucket("parallel:bucket", {
182
181
  capacity: 10,
183
182
  refillPerSec: .001
184
183
  })), { concurrency: "unbounded" });
185
- o(n.filter((e) => e.allowed)).toHaveLength(10);
184
+ l(n.filter((e) => e.allowed)).toHaveLength(10);
186
185
  }));
187
186
  for (let e of [
188
187
  "fixed-window",
189
188
  "sliding-window",
190
189
  "token-bucket"
191
- ]) u(`${e} quotas cannot oversubscribe under concurrent requests`, (n) => t.gen(function* () {
190
+ ]) d(`${e} quotas cannot oversubscribe under concurrent requests`, (n) => t.gen(function* () {
192
191
  let r = {
193
192
  algorithm: e,
194
193
  limit: 10,
195
194
  windowMs: 6e4,
196
195
  burst: 10
197
196
  }, i = yield* t.all(Array.from({ length: 120 }, () => n.rateLimit("quota:" + e, r, 1e3)), { concurrency: "unbounded" });
198
- o(i.filter((e) => e.allowed)).toHaveLength(10), o(i.filter((e) => !e.allowed).every((e) => e.remaining === 0 && e.retryAfterMs > 0)).toBe(!0);
197
+ l(i.filter((e) => e.allowed)).toHaveLength(10), l(i.filter((e) => !e.allowed).every((e) => e.remaining === 0 && e.retryAfterMs > 0)).toBe(!0);
199
198
  }));
200
- u("rate-limit window edges, weighted previous window and token refill preserve exact decisions", (e) => t.gen(function* () {
199
+ d("rate-limit window edges, weighted previous window and token refill preserve exact decisions", (e) => t.gen(function* () {
201
200
  let t = {
202
201
  algorithm: "fixed-window",
203
202
  limit: 2,
204
203
  windowMs: 1e3,
205
204
  burst: 2
206
205
  };
207
- o(yield* e.rateLimit("fixed", t, 0)).toEqual({
206
+ l(yield* e.rateLimit("fixed", t, 0)).toEqual({
208
207
  allowed: !0,
209
208
  remaining: 1,
210
209
  resetAtMs: 1e3,
211
210
  retryAfterMs: 0
212
- }), yield* e.rateLimit("fixed", t, 0), o(yield* e.rateLimit("fixed", t, 999)).toEqual({
211
+ }), yield* e.rateLimit("fixed", t, 0), l(yield* e.rateLimit("fixed", t, 999)).toEqual({
213
212
  allowed: !1,
214
213
  remaining: 0,
215
214
  resetAtMs: 1e3,
216
215
  retryAfterMs: 1
217
- }), o((yield* e.rateLimit("fixed", t, 1e3)).remaining).toBe(1);
216
+ }), l((yield* e.rateLimit("fixed", t, 1e3)).remaining).toBe(1);
218
217
  let n = {
219
218
  ...t,
220
219
  algorithm: "sliding-window"
221
220
  };
222
- yield* e.rateLimit("sliding", n, 0), yield* e.rateLimit("sliding", n, 0), o((yield* e.rateLimit("sliding", n, 1e3)).allowed).toBe(!1), o(yield* e.rateLimit("sliding", n, 1500)).toEqual({
221
+ yield* e.rateLimit("sliding", n, 0), yield* e.rateLimit("sliding", n, 0), l((yield* e.rateLimit("sliding", n, 1e3)).allowed).toBe(!1), l(yield* e.rateLimit("sliding", n, 1500)).toEqual({
223
222
  allowed: !0,
224
223
  remaining: 0,
225
224
  resetAtMs: 2e3,
226
225
  retryAfterMs: 0
227
- }), o((yield* e.rateLimit("sliding", n, 1500)).allowed).toBe(!1), o((yield* e.rateLimit("sliding", n, 4e3)).remaining).toBe(1);
226
+ }), l((yield* e.rateLimit("sliding", n, 1500)).allowed).toBe(!1), l((yield* e.rateLimit("sliding", n, 4e3)).remaining).toBe(1);
228
227
  let r = {
229
228
  ...t,
230
229
  algorithm: "token-bucket",
231
230
  burst: 1
232
231
  };
233
- o((yield* e.rateLimit("token", r, 0)).allowed).toBe(!0), o(yield* e.rateLimit("token", r, 499)).toEqual({
232
+ l((yield* e.rateLimit("token", r, 0)).allowed).toBe(!0), l(yield* e.rateLimit("token", r, 499)).toEqual({
234
233
  allowed: !1,
235
234
  remaining: 0,
236
235
  resetAtMs: 501,
237
236
  retryAfterMs: 2
238
- }), o((yield* e.rateLimit("token", r, 500)).allowed).toBe(!0), o((yield* e.rateLimit("fixed", r, 1100)).allowed).toBe(!0), o((yield* e.rateLimit("zero", {
237
+ }), l((yield* e.rateLimit("token", r, 500)).allowed).toBe(!0), l((yield* e.rateLimit("fixed", r, 1100)).allowed).toBe(!0), l((yield* e.rateLimit("zero", {
239
238
  ...t,
240
239
  limit: 0,
241
240
  burst: 0
242
241
  }, 0)).allowed).toBe(!1);
243
- })), u("rate-limit validation precedes batch mutation; wrong types do not destroy data", (e) => t.gen(function* () {
242
+ })), d("rate-limit validation precedes batch mutation; wrong types do not destroy data", (e) => t.gen(function* () {
244
243
  let n = {
245
244
  algorithm: "fixed-window",
246
245
  limit: 1,
@@ -258,10 +257,10 @@ var c = (c, l) => {
258
257
  limit: -1
259
258
  }
260
259
  }]).pipe(t.result);
261
- o(r.isFailure(i)).toBe(!0), o(yield* e.incrBy("validation", 0)).toBe(0), yield* e.hset("typed", { value: "retained" });
260
+ l(r.isFailure(i)).toBe(!0), l(yield* e.incrBy("validation", 0)).toBe(0), yield* e.hset("typed", { value: "retained" });
262
261
  let a = yield* e.rateLimit("typed", n).pipe(t.result);
263
- o(r.isFailure(a)).toBe(!0), r.isFailure(a) && o(a.failure.reason).toBe("wrongType"), o(yield* e.hgetAll("typed")).toEqual({ value: "retained" });
264
- let s = yield* e.multi([{
262
+ l(r.isFailure(a)).toBe(!0), r.isFailure(a) && l(a.failure.reason).toBe("wrongType"), l(yield* e.hgetAll("typed")).toEqual({ value: "retained" });
263
+ let o = yield* e.multi([{
265
264
  op: "rateLimit",
266
265
  key: "batched",
267
266
  config: n,
@@ -272,7 +271,7 @@ var c = (c, l) => {
272
271
  config: n,
273
272
  nowMs: 0
274
273
  }]);
275
- o(s).toEqual([{
274
+ l(o).toEqual([{
276
275
  allowed: !0,
277
276
  remaining: 0,
278
277
  resetAtMs: 1e3,
@@ -283,24 +282,24 @@ var c = (c, l) => {
283
282
  resetAtMs: 1e3,
284
283
  retryAfterMs: 1e3
285
284
  }]);
286
- })), u("rate-limit state expires with its structure TTL and remains scan/delete addressable", (e, n) => t.gen(function* () {
285
+ })), d("rate-limit state expires with its structure TTL and remains scan/delete addressable", (e, n) => t.gen(function* () {
287
286
  let t = {
288
287
  algorithm: "fixed-window",
289
288
  limit: 1,
290
289
  windowMs: 1e3,
291
290
  burst: 1
292
291
  };
293
- yield* e.rateLimit("ttl:quota", t, 0), yield* e.expire("ttl:quota", 20), yield* n(40), o((yield* e.rateLimit("ttl:quota", t, 0)).allowed).toBe(!0), o(yield* i.runCollect(e.scanPrefix("ttl:quota"))).toEqual(["ttl:quota"]), o(yield* e.delete("ttl:quota")).toBe(!0);
294
- })), u("TTL expires every structure; reads and rejected lease attempts do not extend it", (e, n) => t.gen(function* () {
292
+ yield* e.rateLimit("ttl:quota", t, 0), yield* e.expire("ttl:quota", 20), yield* n(40), l((yield* e.rateLimit("ttl:quota", t, 0)).allowed).toBe(!0), l(yield* i.runCollect(e.scanPrefix("ttl:quota"))).toEqual(["ttl:quota"]), l(yield* e.delete("ttl:quota")).toBe(!0);
293
+ })), d("TTL expires every structure; reads and rejected lease attempts do not extend it", (e, n) => t.gen(function* () {
295
294
  yield* e.zadd("ttl:z", [{
296
295
  member: "a",
297
296
  score: 1
298
- }], { ttlMs: 1e3 }), yield* e.hset("ttl:h", { a: "b" }, { ttlMs: 1e3 }), yield* e.sadd("ttl:s", ["a"], { ttlMs: 1e3 }), yield* e.incrBy("ttl:c", 1, { ttlMs: 1e3 }), o(yield* e.setNx("ttl:l", "owner", 1e3)).toBe(!0), o(yield* e.setNx("ttl:l", "other", 1e4)).toBe(!1), o(yield* e.zcard("ttl:z")).toBe(1), yield* n(1100), o(yield* e.zcard("ttl:z")).toBe(0), o(yield* e.hgetAll("ttl:h")).toEqual({}), o(yield* e.smembers("ttl:s")).toEqual([]), o(yield* e.incrBy("ttl:c", 1)).toBe(1), o(yield* e.setNx("ttl:l", "newOwner", 1e3)).toBe(!0);
299
- })), u("explicit expiry and deletion are scoped; scans treat glob symbols literally", (e, n) => t.gen(function* () {
297
+ }], { ttlMs: 1e3 }), yield* e.hset("ttl:h", { a: "b" }, { ttlMs: 1e3 }), yield* e.sadd("ttl:s", ["a"], { ttlMs: 1e3 }), yield* e.incrBy("ttl:c", 1, { ttlMs: 1e3 }), l(yield* e.setNx("ttl:l", "owner", 1e3)).toBe(!0), l(yield* e.setNx("ttl:l", "other", 1e4)).toBe(!1), l(yield* e.zcard("ttl:z")).toBe(1), yield* n(1100), l(yield* e.zcard("ttl:z")).toBe(0), l(yield* e.hgetAll("ttl:h")).toEqual({}), l(yield* e.smembers("ttl:s")).toEqual([]), l(yield* e.incrBy("ttl:c", 1)).toBe(1), l(yield* e.setNx("ttl:l", "newOwner", 1e3)).toBe(!0);
298
+ })), d("explicit expiry and deletion are scoped; scans treat glob symbols literally", (e, n) => t.gen(function* () {
300
299
  yield* e.sadd("literal:*?[]a", ["a"]), yield* e.sadd("literal:other", ["a"]);
301
300
  let t = yield* i.runCollect(e.scanPrefix("literal:*?[]"));
302
- o(t).toEqual(["literal:*?[]a"]), yield* e.expire("literal:*?[]a", 1e3), yield* n(1100), o(yield* i.runCollect(e.scanPrefix("literal:*?[]"))).toEqual([]), o(yield* e.delete("literal:other")).toBe(!0), o(yield* e.delete("literal:other")).toBe(!1);
303
- })), u("scans traverse multiple pages without duplicates or other prefixes", (e) => t.gen(function* () {
301
+ l(t).toEqual(["literal:*?[]a"]), yield* e.expire("literal:*?[]a", 1e3), yield* n(1100), l(yield* i.runCollect(e.scanPrefix("literal:*?[]"))).toEqual([]), l(yield* e.delete("literal:other")).toBe(!0), l(yield* e.delete("literal:other")).toBe(!1);
302
+ })), d("scans traverse multiple pages without duplicates or other prefixes", (e) => t.gen(function* () {
304
303
  let t = Array.from({ length: 250 }, (e, t) => `pages:${t}`);
305
304
  yield* e.multi(t.map((e) => ({
306
305
  op: "sadd",
@@ -308,9 +307,9 @@ var c = (c, l) => {
308
307
  members: ["a"]
309
308
  }))), yield* e.sadd("unrelated", ["a"]);
310
309
  let n = yield* i.runCollect(e.scanPrefix("pages:"));
311
- o(n.length).toBe(t.length), o([...n].sort()).toEqual([...t].sort());
312
- })), u("batch results reflect ordered writes and reads; arguments validate before writes", (e) => t.gen(function* () {
313
- o(yield* e.multi([])).toEqual([]), o(yield* e.multi([
310
+ l(n.length).toBe(t.length), l([...n].sort()).toEqual([...t].sort());
311
+ })), d("batch results reflect ordered writes and reads; arguments validate before writes", (e) => t.gen(function* () {
312
+ l(yield* e.multi([])).toEqual([]), l(yield* e.multi([
314
313
  {
315
314
  op: "incrBy",
316
315
  key: "batch:c",
@@ -336,7 +335,7 @@ var c = (c, l) => {
336
335
  5,
337
336
  1,
338
337
  !0
339
- ]), o(r.isFailure(yield* e.multi([{
338
+ ]), l(r.isFailure(yield* e.multi([{
340
339
  op: "incrBy",
341
340
  key: "untouched",
342
341
  delta: 10
@@ -344,24 +343,23 @@ var c = (c, l) => {
344
343
  op: "expire",
345
344
  key: "bad",
346
345
  ttlMs: -1
347
- }]).pipe(t.result))).toBe(!0), o(yield* e.incrBy("untouched", 0)).toBe(0);
348
- })), u("wrong types and non-finite/unsafe arguments are typed failures", (e) => t.gen(function* () {
346
+ }]).pipe(t.result))).toBe(!0), l(yield* e.incrBy("untouched", 0)).toBe(0);
347
+ })), d("wrong types and non-finite/unsafe arguments are typed failures", (e) => t.gen(function* () {
349
348
  yield* e.sadd("typed", ["a"]);
350
349
  let n = yield* e.zcard("typed").pipe(t.result);
351
- o(r.isFailure(n)).toBe(!0), r.isFailure(n) && o(n.failure.reason).toBe("wrongType"), o(r.isFailure(yield* e.incrBy("bad", .5).pipe(t.result))).toBe(!0), o(r.isFailure(yield* e.zadd("bad", [{
350
+ l(r.isFailure(n)).toBe(!0), r.isFailure(n) && l(n.failure.reason).toBe("wrongType"), l(r.isFailure(yield* e.incrBy("bad", .5).pipe(t.result))).toBe(!0), l(r.isFailure(yield* e.zadd("bad", [{
352
351
  member: "a",
353
352
  score: NaN
354
- }]).pipe(t.result))).toBe(!0), o(r.isFailure(yield* e.setNx("bad", "a", 0).pipe(t.result))).toBe(!0), o(r.isFailure(yield* e.tokenBucket("bad", {
353
+ }]).pipe(t.result))).toBe(!0), l(r.isFailure(yield* e.setNx("bad", "a", 0).pipe(t.result))).toBe(!0), l(r.isFailure(yield* e.tokenBucket("bad", {
355
354
  capacity: 1,
356
355
  refillPerSec: 1
357
- }, 2).pipe(t.result))).toBe(!0), o(r.isFailure(yield* e.sadd("\ud800", ["a"]).pipe(t.result))).toBe(!0), o(r.isFailure(yield* e.tokenBucket("bad", {
356
+ }, 2).pipe(t.result))).toBe(!0), l(r.isFailure(yield* e.sadd("\ud800", ["a"]).pipe(t.result))).toBe(!0), l(r.isFailure(yield* e.tokenBucket("bad", {
358
357
  capacity: 1e300,
359
358
  refillPerSec: 1
360
- }).pipe(t.result))).toBe(!0), yield* e.incrBy("safe", 2 ** 53 - 1), o(r.isFailure(yield* e.incrBy("safe", 1).pipe(t.result))).toBe(!0), o(yield* e.incrBy("safe", 0)).toBe(2 ** 53 - 1);
361
- })), u("empty writes do not create keys and deleting last members removes structures", (e) => t.gen(function* () {
362
- yield* e.zadd("empty:z", []), yield* e.hset("empty:h", {}), yield* e.sadd("empty:s", []), o(yield* i.runCollect(e.scanPrefix("empty:"))).toEqual([]), yield* e.hset("empty:h", { a: "1" }), yield* e.hdel("empty:h", ["a"]), yield* e.sadd("empty:s", ["a"]), yield* e.srem("empty:s", ["a"]), o(yield* i.runCollect(e.scanPrefix("empty:"))).toEqual([]);
359
+ }).pipe(t.result))).toBe(!0), yield* e.incrBy("safe", 2 ** 53 - 1), l(r.isFailure(yield* e.incrBy("safe", 1).pipe(t.result))).toBe(!0), l(yield* e.incrBy("safe", 0)).toBe(2 ** 53 - 1);
360
+ })), d("empty writes do not create keys and deleting last members removes structures", (e) => t.gen(function* () {
361
+ yield* e.zadd("empty:z", []), yield* e.hset("empty:h", {}), yield* e.sadd("empty:s", []), l(yield* i.runCollect(e.scanPrefix("empty:"))).toEqual([]), yield* e.hset("empty:h", { a: "1" }), yield* e.hdel("empty:h", ["a"]), yield* e.sadd("empty:s", ["a"]), yield* e.srem("empty:s", ["a"]), l(yield* i.runCollect(e.scanPrefix("empty:"))).toEqual([]);
363
362
  }));
364
363
  });
365
364
  };
366
- //#endregion
367
- export { c as hotStoreConformance };
365
+ export { a as hotStoreConformance };
@@ -1,6 +1,6 @@
1
1
  import { createNativeRedisConnection as e, disconnectNativeRedis as t, nativeRedisTopology as n } from "./nativeRedisTopology.js";
2
2
  import { measuredRedisReader as r } from "./redisReadPolicy.js";
3
- //#region src/nativeRedisReads.ts
3
+ // src/nativeRedisReads.ts
4
4
  var i = () => {
5
5
  throw Error("No confirmed native Redis reader is available");
6
6
  }, a = (e, t, n) => {
@@ -61,7 +61,7 @@ var i = () => {
61
61
  } else {
62
62
  if (await e.client.ping() !== "PONG" && i(), e !== s) {
63
63
  let [t, n] = await Promise.all([s.client.info("replication"), e.client.info("replication")]), r = (e, t) => e.split(/\r?\n/).find((e) => e.startsWith(t + ":"))?.slice(t.length + 1);
64
- (r(n, "role") !== "slave" || r(n, "master_link_status") !== "up" || !r(t, "master_replid") || r(t, "master_replid") !== r(n, "master_replid")) && i();
64
+ r(n, "role") === "slave" && r(n, "master_link_status") === "up" && r(t, "master_replid") && r(t, "master_replid") === r(n, "master_replid") || i();
65
65
  }
66
66
  Number(await e.client.call("eval_ro", "return 1", 0)) !== 1 && i();
67
67
  }
@@ -74,5 +74,4 @@ var i = () => {
74
74
  throw await p(), e;
75
75
  }
76
76
  };
77
- //#endregion
78
77
  export { o as nativeRedisReadConfigs, s as openNativeRedisReaders, a as selectNativeReadNode };
@@ -1,49 +1,50 @@
1
1
  import { connectionMetadataProblem as e, redisTimeoutsProblem as t } from "./connectionDefinitions.js";
2
- //#region src/nativeRedisTopology.ts
3
- var n = (e) => {
2
+ import { missingDriver as n } from "./driverModule.js";
3
+ // src/nativeRedisTopology.ts
4
+ var r = (e) => {
4
5
  throw Error(`Invalid native Redis topology: ${e}`);
5
- }, r = (e) => !/^\d+$/.test(e) || !Number.isSafeInteger(Number(e)) ? n("database must be a nonnegative integer") : Number(e), i = (i) => {
6
- let a = t(i, i.driver);
7
- if (a) return n(a);
6
+ }, i = (e) => !/^\d+$/.test(e) || !Number.isSafeInteger(Number(e)) ? r("database must be a nonnegative integer") : Number(e), a = (n) => {
7
+ let a = t(n, n.driver);
8
+ if (a) return r(a);
8
9
  try {
9
- let t = e(i);
10
- if (t) return n(t);
11
- if (typeof i.url != "string" || !i.url.trim()) return n("URL is required");
12
- if (i.url !== i.url.trim()) return n("URL must not contain surrounding whitespace");
13
- if (i.cluster !== void 0 && typeof i.cluster != "boolean") return n("cluster must be boolean");
14
- let a = /^([a-z][a-z\d+.-]*):\/\/([^/?#]+)(.*)$/i.exec(i.url);
15
- if (!a) return n("URL must declare a native Redis scheme and endpoint");
10
+ let t = e(n);
11
+ if (t) return r(t);
12
+ if (typeof n.url != "string" || !n.url.trim()) return r("URL is required");
13
+ if (n.url !== n.url.trim()) return r("URL must not contain surrounding whitespace");
14
+ if (n.cluster !== void 0 && typeof n.cluster != "boolean") return r("cluster must be boolean");
15
+ let a = /^([a-z][a-z\d+.-]*):\/\/([^/?#]+)(.*)$/i.exec(n.url);
16
+ if (!a) return r("URL must declare a native Redis scheme and endpoint");
16
17
  let o = a[1].toLowerCase(), s = o === "redis+cluster" || o === "rediss+cluster", c = o === "redis+sentinel" || o === "rediss+sentinel";
17
- if (!s && !c && o !== "redis" && o !== "rediss") return n("scheme is not native Redis");
18
- if (s && i.cluster === !1) return n("cluster URL conflicts with cluster: false");
19
- if (c && i.cluster === !0) return n("Sentinel URL conflicts with cluster: true");
18
+ if (!s && !c && o !== "redis" && o !== "rediss") return r("scheme is not native Redis");
19
+ if (s && n.cluster === !1) return r("cluster URL conflicts with cluster: false");
20
+ if (c && n.cluster === !0) return r("Sentinel URL conflicts with cluster: true");
20
21
  let l = o.startsWith("rediss");
21
- if (i.tls === "required" && !l) return n("TLS requires a secure Redis scheme");
22
- let u = s || i.cluster === !0, d = a[2], f = d.lastIndexOf("@"), p = f < 0 ? "" : d.slice(0, f + 1), m = (f < 0 ? d : d.slice(f + 1)).split(",");
23
- if (!u && !c && m.length !== 1) return n("standalone URL must contain one endpoint");
22
+ if (n.tls === "required" && !l) return r("TLS requires a secure Redis scheme");
23
+ let u = s || n.cluster === !0, d = a[2], f = d.lastIndexOf("@"), p = f < 0 ? "" : d.slice(0, f + 1), m = (f < 0 ? d : d.slice(f + 1)).split(",");
24
+ if (!u && !c && m.length !== 1) return r("standalone URL must contain one endpoint");
24
25
  let h = m.map((e) => {
25
- if (!e) return n("endpoint list contains an empty entry");
26
+ if (!e) return r("endpoint list contains an empty entry");
26
27
  let t = new URL(`redis://${e}`);
27
- if (t.username || t.password || t.pathname !== "" || t.search || t.hash || !t.hostname || /\s|%/.test(t.hostname)) return n("endpoint shape is invalid");
28
- let r = t.port ? Number(t.port) : c ? 26379 : 6379;
29
- return !Number.isInteger(r) || r < 1 || r > 65535 ? n("endpoint port is invalid") : {
28
+ if (t.username || t.password || t.pathname !== "" || t.search || t.hash || !t.hostname || /\s|%/.test(t.hostname)) return r("endpoint shape is invalid");
29
+ let n = t.port ? Number(t.port) : c ? 26379 : 6379;
30
+ return !Number.isInteger(n) || n < 1 || n > 65535 ? r("endpoint port is invalid") : {
30
31
  host: t.hostname.replace(/^\[|\]$/g, ""),
31
- port: r
32
+ port: n
32
33
  };
33
34
  }), g = new URL(`redis://${p}${m[0]}${a[3]}`);
34
- if (g.hash) return n("URL fragments are not permitted");
35
+ if (g.hash) return r("URL fragments are not permitted");
35
36
  let _ = decodeURIComponent(g.username), v = decodeURIComponent(g.password), y = c ? [
36
37
  "db",
37
38
  "sentinelUsername",
38
39
  "sentinelPassword"
39
40
  ] : ["db"];
40
- for (let e of g.searchParams.keys()) if (!y.includes(e) || g.searchParams.getAll(e).length !== 1) return n("query parameter is unknown or repeated");
41
+ for (let e of g.searchParams.keys()) if (!y.includes(e) || g.searchParams.getAll(e).length !== 1) return r("query parameter is unknown or repeated");
41
42
  if (!u && !c) {
42
- let e = g.pathname === "" || g.pathname === "/" ? void 0 : r(g.pathname.slice(1)), t = g.searchParams.get("db");
43
- return t !== null && e !== void 0 && r(t) !== e ? n("database declarations conflict") : {
43
+ let e = g.pathname === "" || g.pathname === "/" ? void 0 : i(g.pathname.slice(1)), t = g.searchParams.get("db");
44
+ return t !== null && e !== void 0 && i(t) !== e ? r("database declarations conflict") : {
44
45
  kind: "standalone",
45
- url: i.url,
46
- db: t === null ? e ?? 0 : r(t)
46
+ url: n.url,
47
+ db: t === null ? e ?? 0 : i(t)
47
48
  };
48
49
  }
49
50
  let b = {
@@ -52,15 +53,15 @@ var n = (e) => {
52
53
  ...l ? { tls: {} } : {}
53
54
  }, x = [...new Map(h.map((e) => [JSON.stringify([e.host, e.port]), e])).values()];
54
55
  if (u) {
55
- let e = g.pathname === "" || g.pathname === "/" ? 0 : r(g.pathname.slice(1)), t = g.searchParams.get("db");
56
- return e !== 0 || t !== null && r(t) !== 0 ? n("Cluster requires database zero") : {
56
+ let e = g.pathname === "" || g.pathname === "/" ? 0 : i(g.pathname.slice(1)), t = g.searchParams.get("db");
57
+ return e !== 0 || t !== null && i(t) !== 0 ? r("Cluster requires database zero") : {
57
58
  kind: "cluster",
58
59
  nodes: x,
59
60
  options: b
60
61
  };
61
62
  }
62
63
  let S = decodeURIComponent(g.pathname.slice(1));
63
- if (!S || /[\s/\\?#]/.test(S)) return n("Sentinel requires one master group name");
64
+ if (!S || /[\s/\\?#]/.test(S)) return r("Sentinel requires one master group name");
64
65
  let C = g.searchParams.get("sentinelUsername"), w = g.searchParams.get("sentinelPassword"), T = g.searchParams.get("db");
65
66
  return {
66
67
  kind: "sentinel",
@@ -68,7 +69,7 @@ var n = (e) => {
68
69
  name: S,
69
70
  options: {
70
71
  ...b,
71
- db: T === null ? 0 : r(T),
72
+ db: T === null ? 0 : i(T),
72
73
  ...C === null ? {} : { sentinelUsername: C },
73
74
  ...w === null ? {} : { sentinelPassword: w },
74
75
  ...l ? {
@@ -79,9 +80,9 @@ var n = (e) => {
79
80
  };
80
81
  } catch (e) {
81
82
  if (e instanceof Error && e.message.startsWith("Invalid native Redis topology:")) throw e;
82
- return n("URL or encoded component is invalid");
83
+ return r("URL or encoded component is invalid");
83
84
  }
84
- }, a = (e, t = "master") => {
85
+ }, o = (e, t = "master") => {
85
86
  let n = /* @__PURE__ */ new WeakMap(), r = () => /* @__PURE__ */ Error("Native Redis Cluster sockets are not confirmed"), i = (e) => {
86
87
  if (e.status === "ready") return Promise.resolve();
87
88
  let t = n.get(e);
@@ -116,7 +117,7 @@ var n = (e) => {
116
117
  let a = e.nodes(t);
117
118
  if (e.status !== "ready" || a.length !== n.length || a.some((e) => e.status !== "ready" || !n.includes(e))) throw r();
118
119
  };
119
- }, o = (e, t) => {
120
+ }, s = (e, t) => {
120
121
  let n = 0, r, i = () => /* @__PURE__ */ Error("Native Redis database is not confirmed");
121
122
  return t !== 0 && (e.on("close", () => {
122
123
  n++, r = void 0;
@@ -136,7 +137,7 @@ var n = (e) => {
136
137
  let n = r;
137
138
  if (e.status !== "ready" || t !== 0 && n === void 0 || (await n, e.status !== "ready" || r !== n)) throw i();
138
139
  };
139
- }, s = (e) => {
140
+ }, c = (e) => {
140
141
  let t = (e.kind === "cluster" ? [e.client, ...e.client.nodes("all")] : [e.client]).map((e) => [
141
142
  "end",
142
143
  "wait",
@@ -149,7 +150,8 @@ var n = (e) => {
149
150
  e.once("close", n), e.once("end", n);
150
151
  }));
151
152
  return e.client.status !== "end" && e.client.disconnect(), Promise.all(t).then(() => void 0);
152
- }, c = (e, t = {}) => ({
153
+ }, l = (e, t = {}) => ({
154
+ protocol: 2,
153
155
  lazyConnect: !0,
154
156
  autoResendUnfulfilledCommands: !1,
155
157
  maxRetriesPerRequest: 0,
@@ -165,43 +167,43 @@ var n = (e) => {
165
167
  retryStrategy: () => null,
166
168
  sentinelRetryStrategy: () => null
167
169
  } : {}
168
- }), l = async (e, t = "command", n = "primary", r) => {
169
- let s = i(e), l = await import("ioredis"), u = l.default, d = c(t, e);
170
- if (s.kind === "cluster") {
171
- let e = new l.Cluster([...s.nodes], {
170
+ }), u = async (e, t = "command", r = "primary", i) => {
171
+ let c = a(e), u = await import("ioredis").catch(n("ioredis", "A Redis connection")), d = u.default, f = l(t, e);
172
+ if (c.kind === "cluster") {
173
+ let e = new u.Cluster([...c.nodes], {
172
174
  lazyConnect: !0,
173
175
  enableOfflineQueue: !1,
174
- scaleReads: r ?? "master",
176
+ scaleReads: i ?? "master",
175
177
  retryDelayOnFailover: 0,
176
178
  redisOptions: {
177
- ...s.options,
178
- ...d
179
+ ...c.options,
180
+ ...f
179
181
  },
180
182
  ...t === "subscriber" ? { clusterRetryStrategy: () => null } : {}
181
183
  });
182
184
  return {
183
185
  kind: "cluster",
184
186
  client: e,
185
- ready: a(e, n === "primary" ? "master" : "all")
187
+ ready: o(e, r === "primary" ? "master" : "all")
186
188
  };
187
189
  }
188
- let f = s.kind === "standalone" ? new u(s.url, {
189
- ...d,
190
- db: s.db,
191
- .../^rediss:\/\//i.test(s.url) ? { tls: {} } : {}
192
- }) : new u({
193
- ...s.options,
194
- ...d,
195
- name: s.name,
196
- sentinels: [...s.nodes],
197
- role: n === "primary" ? "master" : "slave"
198
- }), p = s.kind === "standalone" ? s.db : s.options.db ?? 0;
190
+ let p = c.kind === "standalone" ? new d(c.url, {
191
+ ...f,
192
+ db: c.db,
193
+ .../^rediss:\/\//i.test(c.url) ? { tls: {} } : {}
194
+ }) : new d({
195
+ ...c.options,
196
+ ...f,
197
+ name: c.name,
198
+ sentinels: [...c.nodes],
199
+ role: r === "primary" ? "master" : "slave"
200
+ }), m = c.kind === "standalone" ? c.db : c.options.db ?? 0;
199
201
  return {
200
- kind: s.kind,
201
- client: f,
202
- ready: o(f, p)
202
+ kind: c.kind,
203
+ client: p,
204
+ ready: s(p, m)
203
205
  };
204
- }, u = async (e, t, n, r) => {
206
+ }, d = async (e, t, n, r) => {
205
207
  if (e.kind !== "cluster") {
206
208
  let [i, a] = await e.client.scan(t, "MATCH", n, "COUNT", r);
207
209
  return {
@@ -217,5 +219,4 @@ var n = (e) => {
217
219
  keys: c
218
220
  };
219
221
  };
220
- //#endregion
221
- export { l as createNativeRedisConnection, s as disconnectNativeRedis, a as nativeClusterReadiness, o as nativeDatabaseReadiness, c as nativeRedisOptions, i as nativeRedisTopology, u as scanNativeRedis };
222
+ export { u as createNativeRedisConnection, c as disconnectNativeRedis, o as nativeClusterReadiness, s as nativeDatabaseReadiness, l as nativeRedisOptions, a as nativeRedisTopology, d as scanNativeRedis };
@@ -1,4 +1,4 @@
1
- //#region src/redisDiagnostics.ts
1
+ // src/redisDiagnostics.ts
2
2
  var e = [
3
3
  "noeviction",
4
4
  "allkeys-lru",
@@ -23,5 +23,4 @@ var e = [
23
23
  e.info("memory"),
24
24
  e.config("GET", "save")
25
25
  ])).map((e) => e.status === "fulfilled" ? e.value : void 0));
26
- //#endregion
27
26
  export { r as readRedisNodeDiagnostics, n as redisNodeDiagnostics };