@objectstack/service-cluster-redis 17.0.0-rc.0 → 17.0.0-rc.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +320 -0
- package/package.json +11 -5
- package/.turbo/turbo-build.log +0 -22
- package/src/client.ts +0 -75
- package/src/counter.ts +0 -63
- package/src/index.ts +0 -111
- package/src/kv.ts +0 -187
- package/src/lock.ts +0 -205
- package/src/pubsub.ts +0 -188
- package/src/redis.contract.test.ts +0 -163
- package/tsconfig.json +0 -10
- package/tsup.config.ts +0 -14
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,325 @@
|
|
|
1
1
|
# @objectstack/service-cluster-redis
|
|
2
2
|
|
|
3
|
+
## 17.0.0-rc.2
|
|
4
|
+
|
|
5
|
+
### Patch Changes
|
|
6
|
+
|
|
7
|
+
- Updated dependencies [430dcc2]
|
|
8
|
+
- Updated dependencies [e6ac4bd]
|
|
9
|
+
- Updated dependencies [80334c7]
|
|
10
|
+
- Updated dependencies [ce5242c]
|
|
11
|
+
- Updated dependencies [a7163ea]
|
|
12
|
+
- Updated dependencies [e6e9379]
|
|
13
|
+
- Updated dependencies [98877c9]
|
|
14
|
+
- Updated dependencies [98877c9]
|
|
15
|
+
- Updated dependencies [e6b1b69]
|
|
16
|
+
- Updated dependencies [ad047d2]
|
|
17
|
+
- Updated dependencies [2826d1e]
|
|
18
|
+
- Updated dependencies [5a84d41]
|
|
19
|
+
- Updated dependencies [20b1a9e]
|
|
20
|
+
- Updated dependencies [203a449]
|
|
21
|
+
- Updated dependencies [ac37fc6]
|
|
22
|
+
- Updated dependencies [4820f55]
|
|
23
|
+
- Updated dependencies [462d9c4]
|
|
24
|
+
- Updated dependencies [7d21581]
|
|
25
|
+
- Updated dependencies [f2445c9]
|
|
26
|
+
- Updated dependencies [23338c3]
|
|
27
|
+
- Updated dependencies [5b843fb]
|
|
28
|
+
- Updated dependencies [b4487aa]
|
|
29
|
+
- Updated dependencies [65ca83a]
|
|
30
|
+
- Updated dependencies [67bf2e2]
|
|
31
|
+
- Updated dependencies [c6d1cb4]
|
|
32
|
+
- Updated dependencies [36030ff]
|
|
33
|
+
- Updated dependencies [6117f7b]
|
|
34
|
+
- Updated dependencies [e533b0b]
|
|
35
|
+
- Updated dependencies [cdf4d9a]
|
|
36
|
+
- Updated dependencies [aee1806]
|
|
37
|
+
- Updated dependencies [c13350b]
|
|
38
|
+
- Updated dependencies [c13350b]
|
|
39
|
+
- Updated dependencies [9ca2d85]
|
|
40
|
+
- Updated dependencies [c13350b]
|
|
41
|
+
- Updated dependencies [891d345]
|
|
42
|
+
- Updated dependencies [a52e2ef]
|
|
43
|
+
- Updated dependencies [5293114]
|
|
44
|
+
- Updated dependencies [20bc357]
|
|
45
|
+
- Updated dependencies [5966c2a]
|
|
46
|
+
- Updated dependencies [2382580]
|
|
47
|
+
- Updated dependencies [d9fa683]
|
|
48
|
+
- Updated dependencies [3c7bcc0]
|
|
49
|
+
- Updated dependencies [4b6cac7]
|
|
50
|
+
- Updated dependencies [7631964]
|
|
51
|
+
- Updated dependencies [ac471a0]
|
|
52
|
+
- Updated dependencies [60ae58e]
|
|
53
|
+
- Updated dependencies [ce92674]
|
|
54
|
+
- Updated dependencies [9f601e8]
|
|
55
|
+
- Updated dependencies [51c5227]
|
|
56
|
+
- Updated dependencies [a4a85c8]
|
|
57
|
+
- Updated dependencies [07a4e26]
|
|
58
|
+
- Updated dependencies [ec975f1]
|
|
59
|
+
- Updated dependencies [eb4204b]
|
|
60
|
+
- Updated dependencies [4f13be2]
|
|
61
|
+
- Updated dependencies [61cc079]
|
|
62
|
+
- Updated dependencies [0e96e46]
|
|
63
|
+
- Updated dependencies [d52d4fe]
|
|
64
|
+
- Updated dependencies [742cebb]
|
|
65
|
+
- Updated dependencies [ce92674]
|
|
66
|
+
- Updated dependencies [cf2c9b7]
|
|
67
|
+
- Updated dependencies [0f9faa2]
|
|
68
|
+
- Updated dependencies [7cf42fe]
|
|
69
|
+
- Updated dependencies [5966c2a]
|
|
70
|
+
- Updated dependencies [f78dd83]
|
|
71
|
+
- Updated dependencies [a2cd18a]
|
|
72
|
+
- Updated dependencies [4638aaa]
|
|
73
|
+
- Updated dependencies [0222d3c]
|
|
74
|
+
- Updated dependencies [0a936ea]
|
|
75
|
+
- Updated dependencies [023c00b]
|
|
76
|
+
- Updated dependencies [155507e]
|
|
77
|
+
- Updated dependencies [7bba90b]
|
|
78
|
+
- Updated dependencies [7e05d8e]
|
|
79
|
+
- Updated dependencies [061406d]
|
|
80
|
+
- Updated dependencies [c1f344b]
|
|
81
|
+
- Updated dependencies [9c93465]
|
|
82
|
+
- Updated dependencies [ebb209c]
|
|
83
|
+
- Updated dependencies [63b33e6]
|
|
84
|
+
- Updated dependencies [2a44c1d]
|
|
85
|
+
- Updated dependencies [695cfbd]
|
|
86
|
+
- Updated dependencies [7445149]
|
|
87
|
+
- Updated dependencies [071d0dc]
|
|
88
|
+
- Updated dependencies [0848bea]
|
|
89
|
+
- Updated dependencies [d51bed2]
|
|
90
|
+
- Updated dependencies [b8b3c64]
|
|
91
|
+
- Updated dependencies [0c0fbd9]
|
|
92
|
+
- Updated dependencies [f3141d8]
|
|
93
|
+
- Updated dependencies [5a84d41]
|
|
94
|
+
- Updated dependencies [fd3013a]
|
|
95
|
+
- Updated dependencies [21676eb]
|
|
96
|
+
- Updated dependencies [e336549]
|
|
97
|
+
- Updated dependencies [d40f43a]
|
|
98
|
+
- Updated dependencies [e5e7ee0]
|
|
99
|
+
- Updated dependencies [a2ebea2]
|
|
100
|
+
- Updated dependencies [800bdb0]
|
|
101
|
+
- Updated dependencies [04f1182]
|
|
102
|
+
- Updated dependencies [5647006]
|
|
103
|
+
- Updated dependencies [38f7e4f]
|
|
104
|
+
- Updated dependencies [c57f3cf]
|
|
105
|
+
- Updated dependencies [97faca3]
|
|
106
|
+
- Updated dependencies [ad5fe25]
|
|
107
|
+
- Updated dependencies [ea90179]
|
|
108
|
+
- Updated dependencies [ce92674]
|
|
109
|
+
- Updated dependencies [5ef0b5b]
|
|
110
|
+
- Updated dependencies [48fbacb]
|
|
111
|
+
- Updated dependencies [355e951]
|
|
112
|
+
- Updated dependencies [dadb43f]
|
|
113
|
+
- @objectstack/spec@17.0.0-rc.2
|
|
114
|
+
- @objectstack/service-cluster@17.0.0-rc.2
|
|
115
|
+
|
|
116
|
+
## 17.0.0-rc.1
|
|
117
|
+
|
|
118
|
+
### Patch Changes
|
|
119
|
+
|
|
120
|
+
- 2e836de: chore(packaging): CHANGELOG.md ships in every npm tarball (#4261)
|
|
121
|
+
|
|
122
|
+
The AGENTS.md post-task checklist requires breaking changesets to carry their
|
|
123
|
+
FROM → TO migration because "this text ships to consumers as `CHANGELOG.md`
|
|
124
|
+
inside the npm package and is what an upgrading agent greps after the tombstone
|
|
125
|
+
error." That delivery path was severed for 68 of the 69 publishable packages:
|
|
126
|
+
npm packs `package.json` / `README*` / `LICENSE*` unconditionally but — unlike
|
|
127
|
+
older npm versions — not `CHANGELOG.md`, and the canonical
|
|
128
|
+
`"files": ["dist", "README.md"]` whitelist never named it. Measured on npm
|
|
129
|
+
10.9.7: `npm pack --dry-run` on `@objectstack/types` shipped 3 files while its
|
|
130
|
+
70KB `CHANGELOG.md` stayed behind. Only `@objectstack/spec` listed it
|
|
131
|
+
explicitly.
|
|
132
|
+
|
|
133
|
+
The tombstone-error scenario is precisely the one where the repo is out of
|
|
134
|
+
reach — the upgrading agent has `node_modules` and nothing else — so the
|
|
135
|
+
migration text has to ride in the tarball. Every publishable package now
|
|
136
|
+
declares `CHANGELOG.md` in `files`, and the canonical whitelist is
|
|
137
|
+
`["dist", "README.md", "CHANGELOG.md"]`.
|
|
138
|
+
|
|
139
|
+
The other half is the gate: `check:published-files` gains a fifth invariant,
|
|
140
|
+
COMPLETE — a whitelist that fails to cover `CHANGELOG.md` fails the
|
|
141
|
+
always-required lint job, so the next package cannot silently sever the path
|
|
142
|
+
again. `@objectstack/spec`'s per-package EXTRA_ENTRIES exemption dissolves
|
|
143
|
+
into the canonical set.
|
|
144
|
+
|
|
145
|
+
Consumer-visible change: one more file per install (the package's changelog,
|
|
146
|
+
e.g. 70.8KB for `@objectstack/types`), and `grep -r "removed key"
|
|
147
|
+
node_modules/@objectstack/*/CHANGELOG.md` now finds the migration it was
|
|
148
|
+
promised.
|
|
149
|
+
|
|
150
|
+
- cc2de0e: chore(packaging): 20 packages stop publishing their sources, tests and build tooling (#4248)
|
|
151
|
+
|
|
152
|
+
These 20 packages declared no `files` field, so npm fell back to packing the
|
|
153
|
+
whole package directory. `npm pack --dry-run` on `@objectstack/plugin-webhooks`
|
|
154
|
+
listed **21 files** — 15 under `src/`, three of them unit tests
|
|
155
|
+
(`auto-enqueuer.test.ts`, `bootstrap-declared-webhooks.test.ts`, …), plus the
|
|
156
|
+
build-time `scripts/i18n-extract.config.ts`. `dist/` lands on top of that at
|
|
157
|
+
publish time rather than instead of it, so consumers were installing the
|
|
158
|
+
TypeScript sources and the test suite alongside the artifact they asked for.
|
|
159
|
+
|
|
160
|
+
Each now declares `"files": ["dist", "README.md"]`, matching the 29 packages
|
|
161
|
+
that already did. Nothing a consumer imports moves: every `main` / `types` /
|
|
162
|
+
`exports` target in all 20 already resolved inside `dist/`, which the new
|
|
163
|
+
`check:published-files` guard verifies rather than assumes. The visible change
|
|
164
|
+
is a smaller install and a smaller dependency-scanning surface — `npm pack` on
|
|
165
|
+
`@objectstack/plugin-webhooks` now yields 2 files plus `dist/`.
|
|
166
|
+
|
|
167
|
+
The other half of the fix is the gate. Half the packages declaring `files` and
|
|
168
|
+
half not was the #3786 shape — a hand-copied convention with nothing enforcing
|
|
169
|
+
it, where whoever forgets the line gets no signal at all. `check:published-files`
|
|
170
|
+
(new, wired into the always-required `lint` job) holds every non-private
|
|
171
|
+
workspace package to four invariants: `files` is **declared**; it is
|
|
172
|
+
**sufficient** (covers every entry point, so tightening a whitelist cannot ship
|
|
173
|
+
a package that fails to resolve); it is **minimal** (admits no test, test-harness
|
|
174
|
+
config or build script); and anything beyond `dist` + `README.md` is
|
|
175
|
+
**registered** with a reason, reconciled in both directions so a stale exemption
|
|
176
|
+
is an error rather than dead text. `@objectstack/spec` is the one package with
|
|
177
|
+
registered extras — its `.zod.ts` sources, JSON Schemas, liveness ledgers and
|
|
178
|
+
`CHANGELOG.md` are product, not build input.
|
|
179
|
+
|
|
180
|
+
This also closes an assumption #4206 was resting on. Excluding `<pkg>/scripts/**`
|
|
181
|
+
from the docs-drift implementation test is sound only while no package publishes
|
|
182
|
+
`scripts/` as runtime code; that held, but it held because someone read all three
|
|
183
|
+
offenders by hand. It is now checked on every PR.
|
|
184
|
+
|
|
185
|
+
- Updated dependencies [6a67d7a]
|
|
186
|
+
- Updated dependencies [0ecc656]
|
|
187
|
+
- Updated dependencies [06772eb]
|
|
188
|
+
- Updated dependencies [270650f]
|
|
189
|
+
- Updated dependencies [3aef718]
|
|
190
|
+
- Updated dependencies [1ea6bce]
|
|
191
|
+
- Updated dependencies [c1dcacd]
|
|
192
|
+
- Updated dependencies [ad303ed]
|
|
193
|
+
- Updated dependencies [32ccb23]
|
|
194
|
+
- Updated dependencies [f5a4ef0]
|
|
195
|
+
- Updated dependencies [2d3e255]
|
|
196
|
+
- Updated dependencies [7d7521f]
|
|
197
|
+
- Updated dependencies [5dc4d02]
|
|
198
|
+
- Updated dependencies [05154a1]
|
|
199
|
+
- Updated dependencies [9b6fe7c]
|
|
200
|
+
- Updated dependencies [8c711fb]
|
|
201
|
+
- Updated dependencies [09e4547]
|
|
202
|
+
- Updated dependencies [91f4c78]
|
|
203
|
+
- Updated dependencies [820eff9]
|
|
204
|
+
- Updated dependencies [8d895ff]
|
|
205
|
+
- Updated dependencies [f6472d7]
|
|
206
|
+
- Updated dependencies [78caf51]
|
|
207
|
+
- Updated dependencies [62a789b]
|
|
208
|
+
- Updated dependencies [789ad63]
|
|
209
|
+
- Updated dependencies [2af1988]
|
|
210
|
+
- Updated dependencies [2e836de]
|
|
211
|
+
- Updated dependencies [12a19a8]
|
|
212
|
+
- Updated dependencies [41dcda3]
|
|
213
|
+
- Updated dependencies [c8124e5]
|
|
214
|
+
- Updated dependencies [a1a4140]
|
|
215
|
+
- Updated dependencies [217e2e6]
|
|
216
|
+
- Updated dependencies [86a71d1]
|
|
217
|
+
- Updated dependencies [d5c75e2]
|
|
218
|
+
- Updated dependencies [03d26f7]
|
|
219
|
+
- Updated dependencies [4384921]
|
|
220
|
+
- Updated dependencies [3c628ce]
|
|
221
|
+
- Updated dependencies [7cb922e]
|
|
222
|
+
- Updated dependencies [1d22114]
|
|
223
|
+
- Updated dependencies [b5f9397]
|
|
224
|
+
- Updated dependencies [ed77493]
|
|
225
|
+
- Updated dependencies [58a03d2]
|
|
226
|
+
- Updated dependencies [dc530b4]
|
|
227
|
+
- Updated dependencies [e59786e]
|
|
228
|
+
- Updated dependencies [bcf1112]
|
|
229
|
+
- Updated dependencies [9774b78]
|
|
230
|
+
- Updated dependencies [b07d829]
|
|
231
|
+
- Updated dependencies [a648e96]
|
|
232
|
+
- Updated dependencies [a47ac06]
|
|
233
|
+
- Updated dependencies [e4c61a7]
|
|
234
|
+
- Updated dependencies [cc60165]
|
|
235
|
+
- Updated dependencies [081aa6f]
|
|
236
|
+
- Updated dependencies [91f4c78]
|
|
237
|
+
- Updated dependencies [e8d0c21]
|
|
238
|
+
- Updated dependencies [c1d44f7]
|
|
239
|
+
- Updated dependencies [ab9fb5c]
|
|
240
|
+
- Updated dependencies [f985b3f]
|
|
241
|
+
- Updated dependencies [9a4932a]
|
|
242
|
+
- Updated dependencies [f9fc874]
|
|
243
|
+
- Updated dependencies [011b386]
|
|
244
|
+
- Updated dependencies [7777e8f]
|
|
245
|
+
- Updated dependencies [507b92a]
|
|
246
|
+
- Updated dependencies [7309c81]
|
|
247
|
+
- Updated dependencies [20bc1ec]
|
|
248
|
+
- Updated dependencies [90c2b15]
|
|
249
|
+
- Updated dependencies [42eeb7d]
|
|
250
|
+
- Updated dependencies [01e124d]
|
|
251
|
+
- Updated dependencies [7ce02eb]
|
|
252
|
+
- Updated dependencies [a13827e]
|
|
253
|
+
- Updated dependencies [7733604]
|
|
254
|
+
- Updated dependencies [40e420f]
|
|
255
|
+
- Updated dependencies [d13004a]
|
|
256
|
+
- Updated dependencies [be7360c]
|
|
257
|
+
- Updated dependencies [cc2de0e]
|
|
258
|
+
- Updated dependencies [5b47ab5]
|
|
259
|
+
- Updated dependencies [b09d8d9]
|
|
260
|
+
- Updated dependencies [b09d8d9]
|
|
261
|
+
- Updated dependencies [8675db6]
|
|
262
|
+
- Updated dependencies [b09d8d9]
|
|
263
|
+
- Updated dependencies [3eb1b2b]
|
|
264
|
+
- Updated dependencies [59b85c0]
|
|
265
|
+
- Updated dependencies [6e357ed]
|
|
266
|
+
- Updated dependencies [d6938bf]
|
|
267
|
+
- Updated dependencies [31e0be9]
|
|
268
|
+
- Updated dependencies [4bfd455]
|
|
269
|
+
- Updated dependencies [ffd2ce2]
|
|
270
|
+
- Updated dependencies [62f8017]
|
|
271
|
+
- Updated dependencies [a831df1]
|
|
272
|
+
- Updated dependencies [f752ee3]
|
|
273
|
+
- Updated dependencies [a1b61e0]
|
|
274
|
+
- Updated dependencies [cd6b9f2]
|
|
275
|
+
- Updated dependencies [2cb6d3c]
|
|
276
|
+
- Updated dependencies [af2a095]
|
|
277
|
+
- Updated dependencies [ec796d5]
|
|
278
|
+
- Updated dependencies [e87fea1]
|
|
279
|
+
- Updated dependencies [c65e529]
|
|
280
|
+
- Updated dependencies [3ca34c1]
|
|
281
|
+
- Updated dependencies [239c3a3]
|
|
282
|
+
- Updated dependencies [94a0bbc]
|
|
283
|
+
- Updated dependencies [d6bfb3d]
|
|
284
|
+
- Updated dependencies [a2266a6]
|
|
285
|
+
- Updated dependencies [d25a0ec]
|
|
286
|
+
- Updated dependencies [667b83e]
|
|
287
|
+
- Updated dependencies [627b188]
|
|
288
|
+
- Updated dependencies [8d4eae7]
|
|
289
|
+
- Updated dependencies [65a3a84]
|
|
290
|
+
- Updated dependencies [ccd9397]
|
|
291
|
+
- Updated dependencies [bca935b]
|
|
292
|
+
- Updated dependencies [c54c822]
|
|
293
|
+
- Updated dependencies [8dcc0f5]
|
|
294
|
+
- Updated dependencies [75b9e51]
|
|
295
|
+
- Updated dependencies [0a2f233]
|
|
296
|
+
- Updated dependencies [8621cdd]
|
|
297
|
+
- Updated dependencies [6f23667]
|
|
298
|
+
- Updated dependencies [5d21a48]
|
|
299
|
+
- Updated dependencies [19365b7]
|
|
300
|
+
- Updated dependencies [b7ed26d]
|
|
301
|
+
- Updated dependencies [b3a3d83]
|
|
302
|
+
- Updated dependencies [7a55913]
|
|
303
|
+
- Updated dependencies [35accbf]
|
|
304
|
+
- Updated dependencies [6038de7]
|
|
305
|
+
- Updated dependencies [eb95d97]
|
|
306
|
+
- Updated dependencies [e4c2dc8]
|
|
307
|
+
- Updated dependencies [1bd2795]
|
|
308
|
+
- Updated dependencies [8186a70]
|
|
309
|
+
- Updated dependencies [a329cca]
|
|
310
|
+
- Updated dependencies [6eec18c]
|
|
311
|
+
- Updated dependencies [4d7bebf]
|
|
312
|
+
- Updated dependencies [821ac7a]
|
|
313
|
+
- Updated dependencies [8f81731]
|
|
314
|
+
- Updated dependencies [8b50cb3]
|
|
315
|
+
- Updated dependencies [8c2db68]
|
|
316
|
+
- Updated dependencies [22b5e54]
|
|
317
|
+
- Updated dependencies [0166bd5]
|
|
318
|
+
- Updated dependencies [9b702dc]
|
|
319
|
+
- Updated dependencies [ab16331]
|
|
320
|
+
- @objectstack/spec@17.0.0-rc.1
|
|
321
|
+
- @objectstack/service-cluster@17.0.0-rc.1
|
|
322
|
+
|
|
3
323
|
## 17.0.0-rc.0
|
|
4
324
|
|
|
5
325
|
### Patch Changes
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@objectstack/service-cluster-redis",
|
|
3
|
-
"version": "17.0.0-rc.
|
|
3
|
+
"version": "17.0.0-rc.2",
|
|
4
4
|
"license": "Apache-2.0",
|
|
5
5
|
"description": "Redis cluster driver for ObjectStack — implements IPubSub/ILock/IKV/ICounter against Redis using ioredis.",
|
|
6
6
|
"type": "module",
|
|
@@ -15,11 +15,11 @@
|
|
|
15
15
|
},
|
|
16
16
|
"dependencies": {
|
|
17
17
|
"ioredis": "^5.11.1",
|
|
18
|
-
"@objectstack/service-cluster": "17.0.0-rc.
|
|
19
|
-
"@objectstack/spec": "17.0.0-rc.
|
|
18
|
+
"@objectstack/service-cluster": "17.0.0-rc.2",
|
|
19
|
+
"@objectstack/spec": "17.0.0-rc.2"
|
|
20
20
|
},
|
|
21
21
|
"devDependencies": {
|
|
22
|
-
"@types/node": "^26.1.
|
|
22
|
+
"@types/node": "^26.1.2",
|
|
23
23
|
"ioredis-mock": "^8.13.1",
|
|
24
24
|
"typescript": "^6.0.3",
|
|
25
25
|
"vitest": "^4.1.10"
|
|
@@ -38,8 +38,14 @@
|
|
|
38
38
|
"url": "https://github.com/objectstack-ai/objectstack.git",
|
|
39
39
|
"directory": "packages/services/service-cluster-redis"
|
|
40
40
|
},
|
|
41
|
+
"files": [
|
|
42
|
+
"dist",
|
|
43
|
+
"README.md",
|
|
44
|
+
"CHANGELOG.md"
|
|
45
|
+
],
|
|
41
46
|
"scripts": {
|
|
42
47
|
"build": "tsup",
|
|
43
|
-
"test": "vitest run"
|
|
48
|
+
"test": "vitest run",
|
|
49
|
+
"typecheck": "tsc --noEmit"
|
|
44
50
|
}
|
|
45
51
|
}
|
package/.turbo/turbo-build.log
DELETED
|
@@ -1,22 +0,0 @@
|
|
|
1
|
-
|
|
2
|
-
> @objectstack/service-cluster-redis@17.0.0-rc.0 build /home/runner/work/objectstack/objectstack/packages/services/service-cluster-redis
|
|
3
|
-
> tsup
|
|
4
|
-
|
|
5
|
-
[34mCLI[39m Building entry: src/index.ts
|
|
6
|
-
[34mCLI[39m Using tsconfig: tsconfig.json
|
|
7
|
-
[34mCLI[39m tsup v8.5.1
|
|
8
|
-
[34mCLI[39m Using tsup config: /home/runner/work/objectstack/objectstack/packages/services/service-cluster-redis/tsup.config.ts
|
|
9
|
-
[34mCLI[39m Target: es2020
|
|
10
|
-
[34mCLI[39m Cleaning output folder
|
|
11
|
-
[34mESM[39m Build start
|
|
12
|
-
[34mCJS[39m Build start
|
|
13
|
-
[32mESM[39m [1mdist/index.js [22m[32m13.20 KB[39m
|
|
14
|
-
[32mESM[39m [1mdist/index.js.map [22m[32m37.77 KB[39m
|
|
15
|
-
[32mESM[39m ⚡️ Build success in 733ms
|
|
16
|
-
[32mCJS[39m [1mdist/index.cjs [22m[32m14.57 KB[39m
|
|
17
|
-
[32mCJS[39m [1mdist/index.cjs.map [22m[32m35.25 KB[39m
|
|
18
|
-
[32mCJS[39m ⚡️ Build success in 740ms
|
|
19
|
-
[34mDTS[39m Build start
|
|
20
|
-
[32mDTS[39m ⚡️ Build success in 10919ms
|
|
21
|
-
[32mDTS[39m [1mdist/index.d.ts [22m[32m9.99 KB[39m
|
|
22
|
-
[32mDTS[39m [1mdist/index.d.cts [22m[32m9.99 KB[39m
|
package/src/client.ts
DELETED
|
@@ -1,75 +0,0 @@
|
|
|
1
|
-
// Copyright (c) 2026 ObjectStack. Licensed under the Apache-2.0 license.
|
|
2
|
-
|
|
3
|
-
import { Redis, type RedisOptions } from 'ioredis';
|
|
4
|
-
|
|
5
|
-
/**
|
|
6
|
-
* Options accepted by {@link createRedisClient}.
|
|
7
|
-
*
|
|
8
|
-
* Either pass `url` (e.g. `redis://user:pass@host:6379/0`) or a full
|
|
9
|
-
* ioredis `options` bag. The two are merged with `options` taking
|
|
10
|
-
* precedence so callers can override individual fields parsed from the
|
|
11
|
-
* URL.
|
|
12
|
-
*
|
|
13
|
-
* This factory is intended to be the single Redis-client construction
|
|
14
|
-
* point across ObjectStack — `service-cluster-redis` uses it for the
|
|
15
|
-
* driver, and `service-cache` will eventually share the same connection
|
|
16
|
-
* pool via {@link CreateRedisOptions.existing}.
|
|
17
|
-
*/
|
|
18
|
-
export interface CreateRedisOptions {
|
|
19
|
-
/** Connection URL. Ignored when `existing` is provided. */
|
|
20
|
-
url?: string;
|
|
21
|
-
/** Extra ioredis options merged on top of `url`. */
|
|
22
|
-
options?: RedisOptions;
|
|
23
|
-
/**
|
|
24
|
-
* Bring-your-own client. When provided, this exact instance is
|
|
25
|
-
* returned and `url`/`options` are ignored — useful for sharing one
|
|
26
|
-
* pool across cluster + cache.
|
|
27
|
-
*/
|
|
28
|
-
existing?: Redis;
|
|
29
|
-
/**
|
|
30
|
-
* If true, the returned client is created in lazyConnect mode so the
|
|
31
|
-
* TCP connection happens on first command rather than at construction.
|
|
32
|
-
* Default: true (matches ObjectStack's "fail at usage, not boot" stance).
|
|
33
|
-
*/
|
|
34
|
-
lazyConnect?: boolean;
|
|
35
|
-
}
|
|
36
|
-
|
|
37
|
-
/**
|
|
38
|
-
* Construct (or reuse) an ioredis client with ObjectStack defaults.
|
|
39
|
-
*
|
|
40
|
-
* Defaults applied when `existing` is absent:
|
|
41
|
-
* - `lazyConnect: true` — don't crash boot if Redis is briefly down
|
|
42
|
-
* - `maxRetriesPerRequest: 3` — bound the failure window before surfacing
|
|
43
|
-
* - `enableAutoPipelining: true` — modest throughput boost for batch workloads
|
|
44
|
-
*
|
|
45
|
-
* @example
|
|
46
|
-
* const client = createRedisClient({ url: 'redis://localhost:6379' });
|
|
47
|
-
*
|
|
48
|
-
* @example reuse one pool across services
|
|
49
|
-
* const shared = createRedisClient({ url });
|
|
50
|
-
* const clusterClient = createRedisClient({ existing: shared });
|
|
51
|
-
* const cacheClient = createRedisClient({ existing: shared });
|
|
52
|
-
*/
|
|
53
|
-
export function createRedisClient(opts: CreateRedisOptions = {}): Redis {
|
|
54
|
-
if (opts.existing) return opts.existing;
|
|
55
|
-
|
|
56
|
-
const base: RedisOptions = {
|
|
57
|
-
lazyConnect: opts.lazyConnect ?? true,
|
|
58
|
-
maxRetriesPerRequest: 3,
|
|
59
|
-
enableAutoPipelining: true,
|
|
60
|
-
};
|
|
61
|
-
|
|
62
|
-
if (opts.url) {
|
|
63
|
-
return new Redis(opts.url, { ...base, ...opts.options });
|
|
64
|
-
}
|
|
65
|
-
return new Redis({ ...base, ...opts.options });
|
|
66
|
-
}
|
|
67
|
-
|
|
68
|
-
/**
|
|
69
|
-
* Duplicate a Redis client so that pub/sub commands (which monopolize
|
|
70
|
-
* the connection) don't block regular commands. Mirrors the standard
|
|
71
|
-
* ioredis "two clients" pattern.
|
|
72
|
-
*/
|
|
73
|
-
export function duplicateForPubSub(client: Redis): Redis {
|
|
74
|
-
return client.duplicate();
|
|
75
|
-
}
|
package/src/counter.ts
DELETED
|
@@ -1,63 +0,0 @@
|
|
|
1
|
-
// Copyright (c) 2026 ObjectStack. Licensed under the Apache-2.0 license.
|
|
2
|
-
|
|
3
|
-
import type { Redis } from 'ioredis';
|
|
4
|
-
import type { ICounter, CounterIncrOptions } from '@objectstack/spec/contracts';
|
|
5
|
-
|
|
6
|
-
export interface RedisCounterOptions {
|
|
7
|
-
client: Redis;
|
|
8
|
-
keyPrefix?: string;
|
|
9
|
-
}
|
|
10
|
-
|
|
11
|
-
/**
|
|
12
|
-
* Redis-backed monotonic counter using INCRBY. Each counter key lives at
|
|
13
|
-
* `{prefix}ctr:{key}` so the same Redis instance can host multiple
|
|
14
|
-
* tenants without collision.
|
|
15
|
-
*
|
|
16
|
-
* Values are stored as ASCII decimals (Redis convention). We surface
|
|
17
|
-
* them as `bigint` to match the contract — INCRBY accepts up to a
|
|
18
|
-
* signed 64-bit range, well beyond Number.MAX_SAFE_INTEGER.
|
|
19
|
-
*/
|
|
20
|
-
export class RedisCounter implements ICounter {
|
|
21
|
-
private readonly client: Redis;
|
|
22
|
-
private readonly keyPrefix: string;
|
|
23
|
-
private closed = false;
|
|
24
|
-
|
|
25
|
-
constructor(opts: RedisCounterOptions) {
|
|
26
|
-
this.client = opts.client;
|
|
27
|
-
this.keyPrefix = opts.keyPrefix ?? 'os:';
|
|
28
|
-
}
|
|
29
|
-
|
|
30
|
-
async incr(key: string, opts: CounterIncrOptions = {}): Promise<bigint> {
|
|
31
|
-
if (this.closed) throw new Error('RedisCounter is closed');
|
|
32
|
-
const by = opts.by ?? 1;
|
|
33
|
-
const next = await this.client.incrby(this.ctrKey(key), by);
|
|
34
|
-
return BigInt(next);
|
|
35
|
-
}
|
|
36
|
-
|
|
37
|
-
async peek(key: string): Promise<bigint> {
|
|
38
|
-
const raw = await this.client.get(this.ctrKey(key));
|
|
39
|
-
if (raw === null) return 0n;
|
|
40
|
-
try {
|
|
41
|
-
return BigInt(raw);
|
|
42
|
-
} catch {
|
|
43
|
-
return 0n;
|
|
44
|
-
}
|
|
45
|
-
}
|
|
46
|
-
|
|
47
|
-
async reset(key: string, value: bigint = 0n): Promise<void> {
|
|
48
|
-
if (this.closed) throw new Error('RedisCounter is closed');
|
|
49
|
-
if (value === 0n) {
|
|
50
|
-
await this.client.del(this.ctrKey(key));
|
|
51
|
-
return;
|
|
52
|
-
}
|
|
53
|
-
await this.client.set(this.ctrKey(key), value.toString());
|
|
54
|
-
}
|
|
55
|
-
|
|
56
|
-
async close(): Promise<void> {
|
|
57
|
-
this.closed = true;
|
|
58
|
-
}
|
|
59
|
-
|
|
60
|
-
private ctrKey(key: string): string {
|
|
61
|
-
return `${this.keyPrefix}ctr:${key}`;
|
|
62
|
-
}
|
|
63
|
-
}
|
package/src/index.ts
DELETED
|
@@ -1,111 +0,0 @@
|
|
|
1
|
-
// Copyright (c) 2026 ObjectStack. Licensed under the Apache-2.0 license.
|
|
2
|
-
|
|
3
|
-
/**
|
|
4
|
-
* @objectstack/service-cluster-redis
|
|
5
|
-
*
|
|
6
|
-
* Redis driver for `@objectstack/service-cluster`. Import this package
|
|
7
|
-
* once at process start to register the `'redis'` driver:
|
|
8
|
-
*
|
|
9
|
-
* ```ts
|
|
10
|
-
* import '@objectstack/service-cluster-redis';
|
|
11
|
-
* import { defineCluster } from '@objectstack/service-cluster';
|
|
12
|
-
*
|
|
13
|
-
* const cluster = defineCluster({
|
|
14
|
-
* driver: 'redis',
|
|
15
|
-
* url: 'redis://localhost:6379',
|
|
16
|
-
* nodeId: 'web-1',
|
|
17
|
-
* });
|
|
18
|
-
* ```
|
|
19
|
-
*
|
|
20
|
-
* The driver also exports raw constructors so callers who already own
|
|
21
|
-
* an ioredis client can compose primitives by hand.
|
|
22
|
-
*/
|
|
23
|
-
|
|
24
|
-
import type { Redis } from 'ioredis';
|
|
25
|
-
import {
|
|
26
|
-
ComposedClusterService,
|
|
27
|
-
registerClusterDriver,
|
|
28
|
-
type DriverFactoryConfig,
|
|
29
|
-
} from '@objectstack/service-cluster';
|
|
30
|
-
import { createRedisClient } from './client.js';
|
|
31
|
-
import { RedisPubSub } from './pubsub.js';
|
|
32
|
-
import { RedisLock } from './lock.js';
|
|
33
|
-
import { RedisKV } from './kv.js';
|
|
34
|
-
import { RedisCounter } from './counter.js';
|
|
35
|
-
|
|
36
|
-
// Re-exports for advanced composition.
|
|
37
|
-
export { createRedisClient, duplicateForPubSub, type CreateRedisOptions } from './client.js';
|
|
38
|
-
export { RedisPubSub, type RedisPubSubOptions } from './pubsub.js';
|
|
39
|
-
export { RedisLock, type RedisLockOptions } from './lock.js';
|
|
40
|
-
export { RedisKV, VersionMismatchError, type RedisKVOptions } from './kv.js';
|
|
41
|
-
export { RedisCounter, type RedisCounterOptions } from './counter.js';
|
|
42
|
-
|
|
43
|
-
/**
|
|
44
|
-
* Driver-specific options accepted under `driverOptions` in
|
|
45
|
-
* `ClusterCapabilityConfig`. All are optional — supply a `client` to
|
|
46
|
-
* share a Redis pool with other services (e.g. `service-cache`).
|
|
47
|
-
*/
|
|
48
|
-
export interface RedisDriverOptions {
|
|
49
|
-
/** Pre-built ioredis client. When provided, `url` is ignored. */
|
|
50
|
-
client?: Redis;
|
|
51
|
-
/** Key prefix applied to every Redis key (default: 'os:'). */
|
|
52
|
-
keyPrefix?: string;
|
|
53
|
-
/** Default lock TTL in ms. Overridden by `LockAcquireOptions.ttlMs`. */
|
|
54
|
-
lockTtlMs?: number;
|
|
55
|
-
/** Pub/sub subscriber error sink. */
|
|
56
|
-
onError?: (err: unknown, channel: string) => void;
|
|
57
|
-
}
|
|
58
|
-
|
|
59
|
-
/**
|
|
60
|
-
* Factory consumed by `defineCluster({ driver: 'redis' })`. Builds an
|
|
61
|
-
* `IClusterService` backed by Redis. Owns the underlying ioredis client
|
|
62
|
-
* iff it created it (i.e. when caller didn't pass `driverOptions.client`).
|
|
63
|
-
*/
|
|
64
|
-
function redisDriverFactory(config: DriverFactoryConfig) {
|
|
65
|
-
const driverOpts = (config.driverOptions ?? {}) as RedisDriverOptions;
|
|
66
|
-
const ownsClient = !driverOpts.client;
|
|
67
|
-
const client =
|
|
68
|
-
driverOpts.client ??
|
|
69
|
-
createRedisClient({ url: config.url });
|
|
70
|
-
|
|
71
|
-
const keyPrefix = driverOpts.keyPrefix ?? 'os:';
|
|
72
|
-
const ttlMs = config.lockTtlMs ?? driverOpts.lockTtlMs;
|
|
73
|
-
|
|
74
|
-
const pubsub = new RedisPubSub({
|
|
75
|
-
client,
|
|
76
|
-
nodeId: config.nodeId,
|
|
77
|
-
keyPrefix,
|
|
78
|
-
onError: driverOpts.onError,
|
|
79
|
-
});
|
|
80
|
-
const lock = new RedisLock({
|
|
81
|
-
client,
|
|
82
|
-
keyPrefix,
|
|
83
|
-
defaultTtlMs: ttlMs,
|
|
84
|
-
nodeId: config.nodeId,
|
|
85
|
-
});
|
|
86
|
-
const kv = new RedisKV({ client, keyPrefix });
|
|
87
|
-
const counter = new RedisCounter({ client, keyPrefix });
|
|
88
|
-
|
|
89
|
-
const facade = new ComposedClusterService(
|
|
90
|
-
config.nodeId,
|
|
91
|
-
'redis',
|
|
92
|
-
pubsub,
|
|
93
|
-
lock,
|
|
94
|
-
kv,
|
|
95
|
-
counter,
|
|
96
|
-
);
|
|
97
|
-
|
|
98
|
-
// Wrap close() so we also tear down the publisher client if we own it.
|
|
99
|
-
const originalClose = facade.close.bind(facade);
|
|
100
|
-
facade.close = async () => {
|
|
101
|
-
await originalClose();
|
|
102
|
-
if (ownsClient) {
|
|
103
|
-
try { await client.quit(); } catch { /* swallow */ }
|
|
104
|
-
}
|
|
105
|
-
};
|
|
106
|
-
|
|
107
|
-
return facade;
|
|
108
|
-
}
|
|
109
|
-
|
|
110
|
-
// Module-load registration — importing this package is enough.
|
|
111
|
-
registerClusterDriver('redis', redisDriverFactory);
|