@classytic/arc 2.41.1 → 2.44.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/{EventTransport-CbUKDzZZ.d.mts → EventTransport-CiicKz2Z.d.mts} +1 -1
- package/dist/{EventTransport-DSqD_Xsg.mjs → EventTransport-DZWDsaPa.mjs} +22 -17
- package/dist/{HookSystem-CMF94SEA.mjs → HookSystem-yjEgn7Cm.mjs} +2 -2
- package/dist/{QueryCache-DFA-QrU9.d.mts → QueryCache--5uAuYPW.d.mts} +7 -3
- package/dist/{ResourceRegistry-MGpXoxHZ.mjs → ResourceRegistry-DJxHUpE4.mjs} +44 -13
- package/dist/acquire-BozJ-9yt.mjs +35 -0
- package/dist/actionPermissions-5N04zBL4.mjs +772 -0
- package/dist/audit/index.d.mts +46 -8
- package/dist/audit/index.mjs +48 -26
- package/dist/auth/audit.d.mts +8 -8
- package/dist/auth/audit.mjs +1 -1
- package/dist/auth/index.d.mts +46 -16
- package/dist/auth/index.mjs +134 -156
- package/dist/auth/redis-session.d.mts +4 -5
- package/dist/auth/redis-session.mjs +1 -1
- package/dist/{authorizationDecision-DawKGoXb.mjs → authorizationDecision-wX3SA9w_.mjs} +7 -102
- package/dist/{base-CxrV1LmG.d.mts → base-CZyixEQR.d.mts} +27 -5
- package/dist/boundedMap-DWiKW7lP.mjs +57 -0
- package/dist/{buildHandler-CvxKOc0m.mjs → buildHandler-Bswu_vNb.mjs} +4 -4
- package/dist/cache/index.d.mts +31 -43
- package/dist/cache/index.mjs +4 -4
- package/dist/{caching-DbCBxlgw.mjs → caching-Drp68DIS.mjs} +3 -3
- package/dist/claimed-DYvQoZLv.mjs +8 -0
- package/dist/cleanup/index.d.mts +18 -22
- package/dist/cleanup/index.mjs +27 -73
- package/dist/cli/commands/describe.d.mts +7 -5
- package/dist/cli/commands/describe.mjs +7 -4
- package/dist/cli/commands/docs.d.mts +2 -3
- package/dist/cli/commands/docs.mjs +3 -3
- package/dist/cli/commands/doctor.d.mts +2 -3
- package/dist/cli/commands/doctor.mjs +1 -1
- package/dist/cli/commands/generate.mjs +2 -3
- package/dist/cli/commands/init.mjs +2 -3
- package/dist/cli/commands/introspect.d.mts +2 -3
- package/dist/cli/commands/introspect.mjs +2 -2
- package/dist/cli/index.mjs +3 -3
- package/dist/{constants-D5Ubn1fe.mjs → constants-B2QHb6u6.mjs} +4 -2
- package/dist/context/index.d.mts +11 -14
- package/dist/context/index.mjs +18 -38
- package/dist/core/index.d.mts +3 -3
- package/dist/core/index.mjs +8 -8
- package/dist/{core-5lazhva9.mjs → core-COcqo0Cp.mjs} +15 -5
- package/dist/{createActionRouter-DNqoaK81.mjs → createActionRouter-zG13rpPJ.mjs} +97 -39
- package/dist/{createAggregationRouter-BcbQJf10.mjs → createAggregationRouter-CWRz96Vr.mjs} +11 -8
- package/dist/{preloadResources-f3boenVZ.mjs → createApp-BGLYtErt.mjs} +305 -394
- package/dist/{createMcpServer-CbDWkZ1T.d.mts → createMcpServer-DSztofa9.d.mts} +1 -1
- package/dist/{defineAggregation-D_eJjm5A.mjs → defineAggregation--3xguLkk.mjs} +1 -1
- package/dist/{defineResource-DxkMTjRn.mjs → defineResource-gUp9ug66.mjs} +118 -1024
- package/dist/discovery/index.d.mts +6 -7
- package/dist/discovery/index.mjs +1 -1
- package/dist/docs/index.d.mts +11 -5
- package/dist/docs/index.mjs +4 -4
- package/dist/{elevation-CkvG0LG2.mjs → elevation-BG4gnMsJ.mjs} +41 -12
- package/dist/{elevation-BXCfVcNG.d.mts → elevation-BW2J3tNj.d.mts} +1 -2
- package/dist/encryption/index.d.mts +5 -5
- package/dist/encryption/index.mjs +3 -3
- package/dist/{errorHandler-D1GHKGlV.mjs → errorHandler-COHw3N1b.mjs} +26 -5
- package/dist/{errors-BH7YU_9O.mjs → errors-CW4anJBy.mjs} +58 -23
- package/dist/{errors-BGdVwP25.d.mts → errors-JYc9vwqE.d.mts} +9 -0
- package/dist/{eventPlugin-B52abJ8W.d.mts → eventPlugin-BtmA4-3P.d.mts} +65 -9
- package/dist/{eventPlugin-zZY-unhr.mjs → eventPlugin-BweHAVws.mjs} +82 -21
- package/dist/{subscribe-helpers-DatDkcuG.mjs → eventTypes-N4-omQFR.mjs} +151 -17
- package/dist/events/index.d.mts +43 -18
- package/dist/events/index.mjs +49 -53
- package/dist/events/transports/redis-stream-entry.d.mts +1 -1
- package/dist/events/transports/redis-stream-entry.mjs +139 -157
- package/dist/events/transports/redis.d.mts +5 -6
- package/dist/events/transports/redis.mjs +2 -2
- package/dist/factory/index.d.mts +42 -27
- package/dist/factory/index.mjs +213 -32
- package/dist/{fastify-augmentation-Cq2nHVaW.d.mts → fastify-augmentation-DRlCIWE9.d.mts} +11 -25
- package/dist/{fields-BHrkoF5y.mjs → fields-A5crhsJb.mjs} +1 -1
- package/dist/{fields-I_EeRWND.d.mts → fields-BBSpf8pS.d.mts} +1 -1
- package/dist/filter-merge-DGM-GQ1J.mjs +99 -0
- package/dist/{generate-BLRf2m3y.mjs → generate-BXKo2Gc8.mjs} +2 -2
- package/dist/{headers-BIXWKrzQ.mjs → headers-DKZQKL-Z.mjs} +2 -2
- package/dist/health-BYAwA6YS.mjs +22 -0
- package/dist/{health-ZRHeDHXH.mjs → health-CrqUp3sz.mjs} +115 -55
- package/dist/hooks/index.d.mts +2 -2
- package/dist/hooks/index.mjs +2 -3
- package/dist/idempotency/index.d.mts +36 -10
- package/dist/idempotency/index.mjs +230 -111
- package/dist/idempotency/redis.d.mts +1 -1
- package/dist/idempotency/redis.mjs +77 -12
- package/dist/{index-D4u76eQW.d.mts → index-Beg3aNnK.d.mts} +23 -101
- package/dist/{preloadResources-CjS2OfpU.d.mts → index-BkV55WlV.d.mts} +37 -38
- package/dist/{index-BHdZD8zK.d.mts → index-Bxriq3so.d.mts} +84 -21
- package/dist/index-CUJvoyw3.d.mts +510 -0
- package/dist/{index-CbJiYrfv.d.mts → index-Chgz3d0i.d.mts} +1 -1
- package/dist/{index-DHbyPo5j.d.mts → index-WH7xgvxS.d.mts} +304 -254
- package/dist/index.d.mts +9 -9
- package/dist/index.mjs +11 -11
- package/dist/{init-CpLkjU18.mjs → init-BPzK5Lnr.mjs} +1 -1
- package/dist/integrations/event-gateway.d.mts +11 -7
- package/dist/integrations/event-gateway.mjs +4 -4
- package/dist/integrations/index.d.mts +3 -3
- package/dist/integrations/index.mjs +1 -1
- package/dist/integrations/jobs/index.d.mts +1 -1
- package/dist/integrations/jobs/index.mjs +18 -5
- package/dist/integrations/mcp/index.d.mts +102 -89
- package/dist/integrations/mcp/index.mjs +19 -4
- package/dist/integrations/mcp/testing.d.mts +8 -9
- package/dist/integrations/mcp/testing.mjs +2 -2
- package/dist/integrations/streamline.d.mts +85 -144
- package/dist/integrations/streamline.mjs +131 -55
- package/dist/integrations/webhooks.d.mts +83 -143
- package/dist/integrations/webhooks.mjs +36 -80
- package/dist/integrations/websocket-pushref-redis.d.mts +5 -6
- package/dist/integrations/websocket-pushref-redis.mjs +1 -1
- package/dist/integrations/websocket-redis.d.mts +5 -6
- package/dist/integrations/websocket-redis.mjs +1 -1
- package/dist/integrations/websocket.d.mts +3 -3
- package/dist/integrations/websocket.mjs +2 -2
- package/dist/{interface-DEWNOMza.d.mts → interface-JJzwH4Ro.d.mts} +34 -2
- package/dist/{jsonBody-ELR9lfeU.mjs → jsonBody-YIq-vGLv.mjs} +2 -2
- package/dist/{keys-cpZCtcIE.mjs → keys-CpoiZ8hU.mjs} +7 -18
- package/dist/{loadResources-BPfWiI5s.mjs → loadResources-6jO52-RR.mjs} +3 -3
- package/dist/{loadResourcesFromEntry-ixtfL3J2.mjs → loadResourcesFromEntry-MP8xEppu.mjs} +2 -2
- package/dist/logger/index.d.mts +9 -17
- package/dist/logger/index.mjs +2 -153
- package/dist/logger-D4V1zGLI.mjs +160 -0
- package/dist/{mcpPlugin-BX5PujI0.mjs → mcpPlugin-srPc7ItN.mjs} +446 -170
- package/dist/{memory-Iotz0cCx.mjs → memory-CTa5pOCW.mjs} +36 -34
- package/dist/{metrics-NMsmpRmY.mjs → metrics-DsZrvnpB.mjs} +39 -72
- package/dist/middleware/index.d.mts +5 -5
- package/dist/middleware/index.mjs +3 -3
- package/dist/migrations/index.d.mts +13 -13
- package/dist/migrations/index.mjs +2 -2
- package/dist/{module-DpLJG2_N.mjs → module--L0iBIZz.mjs} +8 -8
- package/dist/mongodb-memory-server-CHhYSq5y.mjs +35539 -0
- package/dist/mongoose-CYJCLyi-.mjs +67451 -0
- package/dist/multiTenant-CAtYlW6H.d.mts +104 -0
- package/dist/{multipartBody-DtRWM6_U.mjs → multipartBody-Cc7eZ9cq.mjs} +46 -7
- package/dist/node-D8UZv_8c.mjs +41236 -0
- package/dist/{openapi-CmFf3yq_.mjs → openapi-CMegfsm8.mjs} +48 -10
- package/dist/outbox-admin/index.d.mts +5 -5
- package/dist/outbox-admin/index.mjs +6 -18
- package/dist/{outbox-module-D2z5WkDY.mjs → outbox-module-Ryk270jd.mjs} +203 -33
- package/dist/{outbox-module-BHdUnuuK.d.mts → outbox-module-gZCHoE4H.d.mts} +79 -6
- package/dist/permissions/index.d.mts +5 -4
- package/dist/permissions/index.mjs +8 -6
- package/dist/{permissions-D8TBH44E.mjs → permissions-C5ijIz5Q.mjs} +149 -33
- package/dist/{pipe-FMWNheSO.mjs → pipe-D81zMtWs.mjs} +2 -2
- package/dist/pipeline/index.d.mts +7 -7
- package/dist/pipeline/index.mjs +2 -2
- package/dist/plan-CJGMKoui.mjs +565 -0
- package/dist/{BaseController-CYEwjyjN.mjs → plugin-DALd9dcF.mjs} +1269 -346
- package/dist/plugins/index.d.mts +17 -14
- package/dist/plugins/index.mjs +44 -22
- package/dist/plugins/response-cache.d.mts +5 -6
- package/dist/plugins/response-cache.mjs +8 -14
- package/dist/plugins/tracing-entry.mjs +2 -2
- package/dist/{pluralize-CXWZIzTv.mjs → pluralize-COUNYo3d.mjs} +1 -1
- package/dist/presets/filesUpload.d.mts +8 -8
- package/dist/presets/filesUpload.mjs +5 -5
- package/dist/presets/index.d.mts +35 -40
- package/dist/presets/index.mjs +4 -4
- package/dist/presets/multiTenant.d.mts +2 -107
- package/dist/presets/multiTenant.mjs +22 -162
- package/dist/presets/search.d.mts +9 -10
- package/dist/presets/search.mjs +2 -2
- package/dist/{presets-ZJSPgmT2.mjs → presets-CONf2Qem.mjs} +99 -107
- package/dist/{projection-BzIgzoKZ.mjs → projection-wFoLqdss.mjs} +2 -2
- package/dist/{pushref-registry-Dov9l4qE.d.mts → pushref-registry-UxCkoA4C.d.mts} +1 -1
- package/dist/{queryCachePlugin-DZHPOm9p.mjs → queryCachePlugin-BATECpyh.mjs} +12 -14
- package/dist/{queryCachePlugin-BzqxconG.d.mts → queryCachePlugin-C2lZjTxk.d.mts} +1 -1
- package/dist/{rateLimitKey-BvOvcBDi.mjs → rateLimitKey-DVEZ_UpV.mjs} +1 -1
- package/dist/{realtime-8tIQWZz4.mjs → realtime-xyubMKSB.mjs} +25 -21
- package/dist/{redis-Bzi1y3F9.d.mts → redis-BDgv9Glw.d.mts} +17 -24
- package/dist/redis-stream-BMk-bpQS.d.mts +219 -0
- package/dist/redisShapes-CQksY67q.d.mts +55 -0
- package/dist/registry/index.d.mts +15 -10
- package/dist/registry/index.mjs +4 -4
- package/dist/{registry-DNkgGQcK.mjs → registry-Bdzg-hdm.mjs} +13 -10
- package/dist/{renewingLease-yF8BdW4b.mjs → renewingLease-BFJxGPuh.mjs} +1 -1
- package/dist/{replyHelpers-CNdvMfM4.mjs → replyHelpers-Bnc6lJyy.mjs} +2 -2
- package/dist/{requestContext-cDkAUr-P.mjs → requestContext-C10UeFe5.mjs} +1 -1
- package/dist/requirement-Bu50QALH.mjs +35 -0
- package/dist/requirement-CbiLdQ1n.d.mts +22 -0
- package/dist/resourceRateLimit-Wf6d6FL9.d.mts +30 -0
- package/dist/resourceRateLimit-urWPJxrt.mjs +180 -0
- package/dist/rolldown-runtime-MYrLNGnq.mjs +45 -0
- package/dist/routeValidator-DHtpzrzk.mjs +70 -0
- package/dist/{runtimeCapabilities-CkhS6jn6.mjs → runtimeCapabilities-DIMKMV2G.mjs} +1 -1
- package/dist/{schedules-j6uXXAeJ.mjs → schedules-CKTs5ys8.mjs} +46 -37
- package/dist/{schemaConverter-BVA7cFRG.mjs → schemaConverter-BVjkQ5DD.mjs} +2 -2
- package/dist/{schemaIR-CTvPDoPB.mjs → schemaIR-BA0Hb21Y.mjs} +2 -2
- package/dist/schemas/index.d.mts +20 -10
- package/dist/schemas/index.mjs +8 -3
- package/dist/scim/index.d.mts +13 -13
- package/dist/scim/index.mjs +2 -2
- package/dist/scope/index.d.mts +4 -4
- package/dist/scope/index.mjs +6 -6
- package/dist/{scope-BUi1xV1I.mjs → scope-DINaj7Ax.mjs} +4 -4
- package/dist/shutdown-LpLMH8T1.mjs +59 -0
- package/dist/{simpleEqualityMatcher-C9bzq2gO.mjs → simpleEqualityMatcher-DbwIM1f1.mjs} +1 -1
- package/dist/{sse-BeqVKQKu.mjs → sse-BzJFPX_1.mjs} +11 -15
- package/dist/{sseStream-Ppzo-WUH.mjs → sseStream-DQChzGTs.mjs} +2 -2
- package/dist/{store-helpers-dW71XVWL.mjs → store-helpers-Coj9RhOZ.mjs} +1 -1
- package/dist/{streaming-IcRFjWQU.mjs → streaming-JzB5CAga.mjs} +1 -1
- package/dist/subscriberIdentity-DeyppIif.mjs +28 -0
- package/dist/tenancy-DxV8OuX2.mjs +43 -0
- package/dist/tenantPreparation-CBvvAcAj.mjs +67 -0
- package/dist/testing/cleanupStoreContract.d.mts +4 -5
- package/dist/testing/cleanupStoreContract.mjs +1 -1
- package/dist/testing/index.d.mts +215 -197
- package/dist/testing/index.mjs +289 -214
- package/dist/testing/outboxStoreContract.d.mts +4 -5
- package/dist/testing/outboxStoreContract.mjs +137 -2
- package/dist/testing/requiredPorts.d.mts +16 -0
- package/dist/testing/requiredPorts.mjs +65 -0
- package/dist/testing/storageContract.d.mts +4 -5
- package/dist/testing/storageContract.mjs +1 -1
- package/dist/timing-CntavTlR.mjs +46 -0
- package/dist/{transactionContext-CPbdlnVw.mjs → transactionContext-orvnGu4F.mjs} +1 -1
- package/dist/{typeGuards-BLjPgVBm.mjs → typeGuards-kEaP_WmO.mjs} +1 -1
- package/dist/types/index.d.mts +4 -4
- package/dist/types/index.mjs +1 -1
- package/dist/types/storage.mjs +1 -1
- package/dist/{types-DfVDvkdP.d.mts → types-BJ-2XqVF.d.mts} +189 -204
- package/dist/{types-CWQn9-IC.d.mts → types-D3Ixsh00.d.mts} +22 -9
- package/dist/{types-CgenB1gv.mjs → types-fvO6Ovzx.mjs} +4 -4
- package/dist/usage/index.d.mts +5 -6
- package/dist/usage/index.mjs +5 -5
- package/dist/{userHelpers-ChRvkuSZ.mjs → userHelpers-C76zD5pa.mjs} +1 -1
- package/dist/utils/index.d.mts +125 -264
- package/dist/utils/index.mjs +13 -12
- package/dist/{utils-CxcctrAh.mjs → utils-BpkVZ8rB.mjs} +315 -404
- package/dist/{validate-DrYWnOzI.mjs → validate-CWp-lsrm.mjs} +6 -14
- package/dist/{versioning-D6JIK8Tk.d.mts → versioning-Bsb51gGT.d.mts} +28 -13
- package/dist/{versioning-DKkT4hNJ.mjs → versioning-CHhL9P3o.mjs} +4 -4
- package/dist/{websocket-BOXVggMf.d.mts → websocket-Cs4awVyD.d.mts} +1 -1
- package/dist/{workScope-CxKqoIFn.mjs → workScope-n9a7d_lZ.mjs} +2 -2
- package/package.json +57 -59
- package/skills/arc/SKILL.md +13 -4
- package/skills/arc/references/auth.md +8 -5
- package/skills/arc/references/integrations.md +1 -1
- package/skills/arc/references/mcp.md +8 -6
- package/skills/arc/references/multi-tenancy.md +19 -14
- package/skills/arc/references/production.md +27 -10
- package/dist/actionPermissions-BoPGQ5-4.mjs +0 -350
- package/dist/index-CFfLKMH4.d.mts +0 -290
- package/dist/interface-YzIbF7Ii.mjs +0 -17
- package/dist/redis-stream-BPKscsTB.d.mts +0 -260
- package/dist/registerRoute-Bsnk6NiZ.mjs +0 -364
- package/dist/rolldown-runtime-eysyzFAF.mjs +0 -15
- package/dist/sync/changelog.d.mts +0 -3
- package/dist/sync/changelog.mjs +0 -3
|
@@ -1,3 +1,3 @@
|
|
|
1
1
|
|
|
2
|
-
import { n as RedisStreamTransport, r as RedisStreamTransportOptions, t as RedisStreamLike } from "../../redis-stream-
|
|
2
|
+
import { n as RedisStreamTransport, r as RedisStreamTransportOptions, t as RedisStreamLike } from "../../redis-stream-BMk-bpQS.mjs";
|
|
3
3
|
export { type RedisStreamLike, RedisStreamTransport, type RedisStreamTransportOptions };
|
|
@@ -1,25 +1,17 @@
|
|
|
1
|
-
/*! @classytic/arc v2.
|
|
2
|
-
import {
|
|
1
|
+
/*! @classytic/arc v2.44.0 | MIT | https://classytic.com */
|
|
2
|
+
import { n as evictToSize } from "../../boundedMap-DWiKW7lP.mjs";
|
|
3
|
+
import { r as workSeedFromEvent, t as runWorkScope } from "../../workScope-n9a7d_lZ.mjs";
|
|
4
|
+
import { t as getSubscriberId } from "../../subscriberIdentity-DeyppIif.mjs";
|
|
3
5
|
import sjson from "secure-json-parse";
|
|
4
|
-
import {
|
|
6
|
+
import { createEventRouter } from "@classytic/primitives/events";
|
|
5
7
|
//#region src/events/transports/redis-stream.ts
|
|
6
8
|
/**
|
|
7
|
-
* Redis Stream Event Transport —
|
|
9
|
+
* Redis Stream Event Transport — durable, at-least-once delivery via
|
|
10
|
+
* `XADD`/`XREADGROUP` consumer groups (one consumer per group gets each event).
|
|
8
11
|
*
|
|
9
|
-
*
|
|
10
|
-
*
|
|
11
|
-
*
|
|
12
|
-
*
|
|
13
|
-
* **Delivery guarantee:** at-least-once. Failed messages are left unacked and
|
|
14
|
-
* reclaimed after `claimTimeoutMs`, which can result in duplicate handler
|
|
15
|
-
* execution. Consumers must be idempotent (e.g. use `event.meta.id` as a
|
|
16
|
-
* deduplication key) to achieve effectively-once processing.
|
|
17
|
-
*
|
|
18
|
-
* Key features:
|
|
19
|
-
* - Consumer groups: each event delivered to exactly one consumer per group
|
|
20
|
-
* - Crash recovery: pending entries are auto-claimed after `claimTimeoutMs`
|
|
21
|
-
* - Dead letter stream: events exceeding `maxRetries` are moved to a DLQ
|
|
22
|
-
* - Backpressure: configurable block time and batch size
|
|
12
|
+
* Failed messages stay unacked and are reclaimed after `claimTimeoutMs`, so
|
|
13
|
+
* handlers may run more than once — they must be idempotent (dedupe on
|
|
14
|
+
* `event.meta.id`). Entries exceeding `maxRetries` move to a dead-letter stream.
|
|
23
15
|
*
|
|
24
16
|
* @example
|
|
25
17
|
* ```typescript
|
|
@@ -36,13 +28,9 @@ import { matchEventPattern } from "@classytic/primitives/events";
|
|
|
36
28
|
* ```
|
|
37
29
|
*/
|
|
38
30
|
/**
|
|
39
|
-
*
|
|
40
|
-
*
|
|
41
|
-
*
|
|
42
|
-
* locally — without a cap the map grows for the life of the process in
|
|
43
|
-
* multi-consumer deployments. Eviction is oldest-first (Map insertion
|
|
44
|
-
* order); an evicted entry only degrades the eventual DLQ envelope to the
|
|
45
|
-
* existing cross-consumer fallback message, never loses the event itself.
|
|
31
|
+
* Cap on the failure-context map: a message that fails here but is resolved by
|
|
32
|
+
* ANOTHER consumer is never cleared locally. Eviction is oldest-first and only
|
|
33
|
+
* degrades the DLQ envelope's error detail, never loses the event.
|
|
46
34
|
*/
|
|
47
35
|
const MAX_FAILURE_CONTEXT_ENTRIES = 1024;
|
|
48
36
|
var RedisStreamTransport = class {
|
|
@@ -58,36 +46,34 @@ var RedisStreamTransport = class {
|
|
|
58
46
|
claimTimeoutMs;
|
|
59
47
|
deadLetterStream;
|
|
60
48
|
maxLen;
|
|
49
|
+
groupStartId;
|
|
61
50
|
maxPayloadBytes;
|
|
62
51
|
logger;
|
|
63
|
-
/** Tracks the lifecycle policy — set in constructor, read in close(). */
|
|
64
52
|
externalLifecycle;
|
|
65
53
|
closeTimeoutMs;
|
|
66
|
-
|
|
54
|
+
router = createEventRouter();
|
|
67
55
|
running = false;
|
|
68
56
|
pollPromise = null;
|
|
69
57
|
/**
|
|
70
|
-
*
|
|
71
|
-
*
|
|
72
|
-
*
|
|
73
|
-
* `this.generation` no longer matches. Prevents the
|
|
74
|
-
* subscribe → unsubscribe → fast-resubscribe race where the old loop
|
|
75
|
-
* would still be in `XREADGROUP BLOCK` while a new loop started, leading
|
|
76
|
-
* to two concurrent poll loops on the same consumer name.
|
|
58
|
+
* Bumped whenever the poll loop should stop (last unsubscribe, `close()`).
|
|
59
|
+
* Each loop exits once its captured generation is stale, so a fast
|
|
60
|
+
* unsubscribe → resubscribe never leaves two loops on one consumer name.
|
|
77
61
|
*/
|
|
78
62
|
generation = 0;
|
|
79
63
|
groupCreated = false;
|
|
80
64
|
/**
|
|
81
|
-
* Last
|
|
82
|
-
*
|
|
83
|
-
* {@link moveToDlq} so the dead-letter envelope carries the actual error
|
|
84
|
-
* message instead of opaque "reclaimed without context". Entries are
|
|
85
|
-
* deleted on ack and on DLQ write; messages resolved by ANOTHER consumer
|
|
86
|
-
* never drain locally, so the map is additionally hard-capped at
|
|
87
|
-
* {@link MAX_FAILURE_CONTEXT_ENTRIES} with oldest-first eviction.
|
|
65
|
+
* Last handler failure per message id, so the DLQ envelope carries the real
|
|
66
|
+
* error. Cleared on ack / DLQ write; capped at {@link MAX_FAILURE_CONTEXT_ENTRIES}.
|
|
88
67
|
*/
|
|
89
68
|
failureContext = /* @__PURE__ */ new Map();
|
|
90
|
-
/**
|
|
69
|
+
/** Set by `hold()`: subscriptions register, consumption waits for `start()`. */
|
|
70
|
+
held = false;
|
|
71
|
+
/** Handler → a key stable across replicas: pattern, name, and order among same-named handlers. */
|
|
72
|
+
handlerKeys = /* @__PURE__ */ new Map();
|
|
73
|
+
handlerKeyOwners = /* @__PURE__ */ new Map();
|
|
74
|
+
handlerPatterns = /* @__PURE__ */ new Map();
|
|
75
|
+
handlerProgressTtlMs;
|
|
76
|
+
tracksProgress;
|
|
91
77
|
xrangeWarningEmitted = false;
|
|
92
78
|
constructor(redis, options = {}) {
|
|
93
79
|
this.redis = redis;
|
|
@@ -100,15 +86,25 @@ var RedisStreamTransport = class {
|
|
|
100
86
|
this.maxRetries = options.maxRetries ?? 5;
|
|
101
87
|
this.claimTimeoutMs = options.claimTimeoutMs ?? 3e4;
|
|
102
88
|
this.deadLetterStream = options.deadLetterStream ?? "arc:events:dlq";
|
|
103
|
-
this.maxLen = options.maxLen ??
|
|
89
|
+
this.maxLen = options.maxLen ?? 0;
|
|
90
|
+
this.groupStartId = options.groupStart === "beginning" ? "0" : "$";
|
|
104
91
|
this.maxPayloadBytes = options.maxPayloadBytes ?? 1e6;
|
|
105
92
|
this.externalLifecycle = options.externalLifecycle ?? false;
|
|
106
93
|
this.closeTimeoutMs = options.closeTimeoutMs ?? 1e3;
|
|
107
94
|
this.logger = options.logger ?? console;
|
|
95
|
+
this.handlerProgressTtlMs = options.handlerProgressTtlMs ?? 6048e5;
|
|
96
|
+
this.tracksProgress = [
|
|
97
|
+
"hset",
|
|
98
|
+
"hgetall",
|
|
99
|
+
"del",
|
|
100
|
+
"pexpire"
|
|
101
|
+
].every((m) => typeof redis[m] === "function");
|
|
102
|
+
if (!this.tracksProgress) this.logger.warn("[RedisStreamTransport] redis client lacks hset/hgetall/del/pexpire — a retried message re-runs handlers that already succeeded. Use ioredis or add them to the wrapper.");
|
|
108
103
|
}
|
|
109
104
|
async publish(event) {
|
|
110
105
|
const serialized = JSON.stringify(event);
|
|
111
|
-
|
|
106
|
+
const payloadBytes = Buffer.byteLength(serialized, "utf8");
|
|
107
|
+
if (payloadBytes > this.maxPayloadBytes) throw new Error(`[RedisStreamTransport] Event payload (${payloadBytes} bytes) exceeds limit (${this.maxPayloadBytes}). Consider breaking into smaller events or increasing maxPayloadBytes.`);
|
|
112
108
|
const args = [
|
|
113
109
|
this.stream,
|
|
114
110
|
...this.maxLen > 0 ? [
|
|
@@ -125,66 +121,77 @@ var RedisStreamTransport = class {
|
|
|
125
121
|
await this.redis.xadd(...args);
|
|
126
122
|
}
|
|
127
123
|
async subscribe(pattern, handler) {
|
|
128
|
-
if (!this.
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
this.
|
|
135
|
-
this.logger.error("[RedisStreamTransport] Poll loop crashed:", err);
|
|
136
|
-
if (this.generation === myGen) this.running = false;
|
|
137
|
-
});
|
|
124
|
+
if (!this.handlerKeys.has(handler)) {
|
|
125
|
+
const id = getSubscriberId(handler);
|
|
126
|
+
const key = id === void 0 ? `${pattern}#${handler.name || "anonymous"}` : `subscriber:${id}`;
|
|
127
|
+
const owner = this.handlerKeyOwners.get(key);
|
|
128
|
+
if (owner && owner !== handler) throw new Error(`[RedisStreamTransport] Ambiguous subscriber identity '${key}' — wrap each handler withSubscriberId using a stable unique id.`);
|
|
129
|
+
this.handlerKeyOwners.set(key, handler);
|
|
130
|
+
this.handlerKeys.set(handler, key);
|
|
138
131
|
}
|
|
132
|
+
const patterns = this.handlerPatterns.get(handler) ?? /* @__PURE__ */ new Set();
|
|
133
|
+
patterns.add(pattern);
|
|
134
|
+
this.handlerPatterns.set(handler, patterns);
|
|
135
|
+
this.router.add(pattern, handler);
|
|
136
|
+
if (!this.held) await this.startPolling();
|
|
139
137
|
return () => {
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
138
|
+
this.router.remove(pattern, handler);
|
|
139
|
+
patterns.delete(pattern);
|
|
140
|
+
if (patterns.size === 0) {
|
|
141
|
+
const key = this.handlerKeys.get(handler);
|
|
142
|
+
if (key && this.handlerKeyOwners.get(key) === handler) this.handlerKeyOwners.delete(key);
|
|
143
|
+
this.handlerKeys.delete(handler);
|
|
144
|
+
this.handlerPatterns.delete(handler);
|
|
144
145
|
}
|
|
145
|
-
if (this.
|
|
146
|
+
if (this.router.size === 0 && this.running) {
|
|
146
147
|
this.running = false;
|
|
147
148
|
this.generation++;
|
|
148
149
|
}
|
|
149
150
|
};
|
|
150
151
|
}
|
|
151
152
|
/**
|
|
152
|
-
*
|
|
153
|
-
*
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
153
|
+
* Register subscriptions without consuming until `start()`. arc holds consumption for the whole
|
|
154
|
+
* boot, so an entry for a module whose handler installs later is not acked with no handler.
|
|
155
|
+
*/
|
|
156
|
+
hold() {
|
|
157
|
+
this.held = true;
|
|
158
|
+
}
|
|
159
|
+
/** Begin consuming — every handler registered while held sees the stream from here. */
|
|
160
|
+
async start() {
|
|
161
|
+
this.held = false;
|
|
162
|
+
if (this.router.size > 0) await this.startPolling();
|
|
163
|
+
}
|
|
164
|
+
async startPolling() {
|
|
165
|
+
if (this.running) return;
|
|
166
|
+
await this.ensureGroup();
|
|
167
|
+
this.running = true;
|
|
168
|
+
const myGen = ++this.generation;
|
|
169
|
+
this.pollPromise = this.pollLoop(myGen).catch((err) => {
|
|
170
|
+
this.logger.error("[RedisStreamTransport] Poll loop crashed:", err);
|
|
171
|
+
if (this.generation === myGen) this.running = false;
|
|
172
|
+
});
|
|
173
|
+
}
|
|
174
|
+
/**
|
|
175
|
+
* Stop polling and release transport state. Waits up to `closeTimeoutMs`
|
|
176
|
+
* for the in-flight `XREADGROUP BLOCK`, then:
|
|
171
177
|
*
|
|
172
|
-
*
|
|
173
|
-
*
|
|
174
|
-
*
|
|
175
|
-
*
|
|
176
|
-
*
|
|
177
|
-
*
|
|
178
|
+
* - default: force-disconnects the client to break the BLOCK and awaits the
|
|
179
|
+
* loop — the transport is fully closed on return.
|
|
180
|
+
* - `externalLifecycle: true`: returns without touching the host's client;
|
|
181
|
+
* the loop drains in the background (up to `blockTimeMs` — keep it low)
|
|
182
|
+
* with its outcome silenced. Handlers are already cleared, so nothing
|
|
183
|
+
* dispatches meanwhile.
|
|
178
184
|
*
|
|
179
|
-
*
|
|
180
|
-
* `subscribe()` spawns a fresh poll loop with a new generation — the
|
|
181
|
-
* stale loop exits on its next iteration and never overlaps the new one.
|
|
185
|
+
* A later `subscribe()` starts a fresh loop that never overlaps the stale one.
|
|
182
186
|
*/
|
|
183
187
|
async close() {
|
|
184
188
|
this.running = false;
|
|
185
189
|
this.generation++;
|
|
186
|
-
this.
|
|
190
|
+
this.router.clear();
|
|
187
191
|
this.failureContext.clear();
|
|
192
|
+
this.handlerKeys.clear();
|
|
193
|
+
this.handlerKeyOwners.clear();
|
|
194
|
+
this.handlerPatterns.clear();
|
|
188
195
|
if (this.pollPromise !== null) {
|
|
189
196
|
if (await Promise.race([this.pollPromise.then(() => "drained"), this.sleep(this.closeTimeoutMs).then(() => "timeout")]) === "timeout") {
|
|
190
197
|
if (!this.externalLifecycle) {
|
|
@@ -202,7 +209,7 @@ var RedisStreamTransport = class {
|
|
|
202
209
|
async ensureGroup() {
|
|
203
210
|
if (this.groupCreated) return;
|
|
204
211
|
try {
|
|
205
|
-
await this.redis.xgroup("CREATE", this.stream, this.group,
|
|
212
|
+
await this.redis.xgroup("CREATE", this.stream, this.group, this.groupStartId, "MKSTREAM");
|
|
206
213
|
} catch (err) {
|
|
207
214
|
if (err instanceof Error && !err.message.includes("BUSYGROUP")) throw err;
|
|
208
215
|
}
|
|
@@ -227,13 +234,8 @@ var RedisStreamTransport = class {
|
|
|
227
234
|
if (!result) return;
|
|
228
235
|
for (const [, entries] of result) await this.processEntries(entries);
|
|
229
236
|
}
|
|
230
|
-
/**
|
|
231
|
-
|
|
232
|
-
* (`processingConcurrency`, default 1 = strict order). Worker-pool over a
|
|
233
|
-
* shared index — at most N entries in flight, each entry's own handlers
|
|
234
|
-
* still sequential inside `processEntry`.
|
|
235
|
-
*/
|
|
236
|
-
async processEntries(entries) {
|
|
237
|
+
/** Process a batch with at most `processingConcurrency` entries in flight. */
|
|
238
|
+
async processEntries(entries, retry = false) {
|
|
237
239
|
const live = [];
|
|
238
240
|
const ghostIds = [];
|
|
239
241
|
for (const [messageId, fields] of entries) if (fields) live.push([messageId, fields]);
|
|
@@ -244,14 +246,14 @@ var RedisStreamTransport = class {
|
|
|
244
246
|
this.logger.error(`[RedisStreamTransport] Failed to ack ${ghostIds.length} trimmed entr(ies):`, err);
|
|
245
247
|
}
|
|
246
248
|
if (this.processingConcurrency <= 1) {
|
|
247
|
-
for (const [messageId, fields] of live) await this.processEntry(messageId, fields);
|
|
249
|
+
for (const [messageId, fields] of live) await this.processEntry(messageId, fields, retry);
|
|
248
250
|
return;
|
|
249
251
|
}
|
|
250
252
|
let next = 0;
|
|
251
253
|
const workers = Array.from({ length: Math.min(this.processingConcurrency, live.length) }, async () => {
|
|
252
254
|
while (next < live.length) {
|
|
253
255
|
const entry = live[next++];
|
|
254
|
-
if (entry) await this.processEntry(entry[0], entry[1]);
|
|
256
|
+
if (entry) await this.processEntry(entry[0], entry[1], retry);
|
|
255
257
|
}
|
|
256
258
|
});
|
|
257
259
|
await Promise.all(workers);
|
|
@@ -272,13 +274,13 @@ var RedisStreamTransport = class {
|
|
|
272
274
|
if (overRetryIds.length > 0) await this.moveToDlq(overRetryIds);
|
|
273
275
|
if (staleIds.length > 0) {
|
|
274
276
|
const claimed = await this.redis.xclaim(this.stream, this.group, this.consumer, this.claimTimeoutMs, ...staleIds);
|
|
275
|
-
await this.processEntries(claimed);
|
|
277
|
+
await this.processEntries(claimed, true);
|
|
276
278
|
}
|
|
277
279
|
} catch (err) {
|
|
278
280
|
this.logger.error("[RedisStreamTransport] claimPending error:", err);
|
|
279
281
|
}
|
|
280
282
|
}
|
|
281
|
-
async processEntry(messageId, fields) {
|
|
283
|
+
async processEntry(messageId, fields, retry = false) {
|
|
282
284
|
const event = parseStreamFields(fields);
|
|
283
285
|
if (!event) {
|
|
284
286
|
this.logger.warn(`[RedisStreamTransport] Malformed entry ${messageId} — missing type/data or invalid JSON, acking and skipping`);
|
|
@@ -286,24 +288,37 @@ var RedisStreamTransport = class {
|
|
|
286
288
|
return;
|
|
287
289
|
}
|
|
288
290
|
const matchingHandlers = this.getMatchingHandlers(event.type);
|
|
291
|
+
const progressKey = `${this.stream}:handled:${this.group}:${messageId}`;
|
|
292
|
+
const alreadyDone = retry && this.tracksProgress ? new Set(Object.keys(await this.redis.hgetall?.(progressKey) ?? {})) : /* @__PURE__ */ new Set();
|
|
293
|
+
const completed = [];
|
|
289
294
|
let allSucceeded = true;
|
|
290
295
|
let lastError;
|
|
291
296
|
let lastHandlerName;
|
|
292
297
|
await runWorkScope(workSeedFromEvent(event), async () => {
|
|
293
|
-
for (const handler of matchingHandlers)
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
298
|
+
for (const handler of matchingHandlers) {
|
|
299
|
+
const key = this.handlerKeys.get(handler) ?? handler.name;
|
|
300
|
+
if (alreadyDone.has(key)) continue;
|
|
301
|
+
try {
|
|
302
|
+
await handler(event);
|
|
303
|
+
completed.push(key);
|
|
304
|
+
} catch (err) {
|
|
305
|
+
allSucceeded = false;
|
|
306
|
+
lastError = err instanceof Error ? err : new Error(String(err));
|
|
307
|
+
lastHandlerName = handler.name || lastHandlerName;
|
|
308
|
+
this.logger.error(`[RedisStreamTransport] Handler error for ${event.type}:`, err);
|
|
309
|
+
}
|
|
300
310
|
}
|
|
301
311
|
});
|
|
302
312
|
if (allSucceeded) {
|
|
303
313
|
await this.redis.xack(this.stream, this.group, messageId);
|
|
314
|
+
if (alreadyDone.size > 0) await this.redis.del?.(progressKey);
|
|
304
315
|
this.failureContext.delete(messageId);
|
|
305
316
|
return;
|
|
306
317
|
}
|
|
318
|
+
if (this.tracksProgress && completed.length > 0) {
|
|
319
|
+
await this.redis.hset?.(progressKey, ...completed.flatMap((k) => [k, "1"]));
|
|
320
|
+
await this.redis.pexpire?.(progressKey, this.handlerProgressTtlMs);
|
|
321
|
+
}
|
|
307
322
|
const now = /* @__PURE__ */ new Date();
|
|
308
323
|
const prior = this.failureContext.get(messageId);
|
|
309
324
|
this.failureContext.delete(messageId);
|
|
@@ -314,21 +329,15 @@ var RedisStreamTransport = class {
|
|
|
314
329
|
attempts: (prior?.attempts ?? 0) + 1,
|
|
315
330
|
handlerName: lastHandlerName ?? prior?.handlerName
|
|
316
331
|
});
|
|
317
|
-
|
|
318
|
-
const oldest = this.failureContext.keys().next().value;
|
|
319
|
-
if (oldest !== void 0) this.failureContext.delete(oldest);
|
|
320
|
-
}
|
|
332
|
+
evictToSize(this.failureContext, MAX_FAILURE_CONTEXT_ENTRIES);
|
|
321
333
|
}
|
|
322
334
|
/**
|
|
323
|
-
*
|
|
324
|
-
* transport
|
|
325
|
-
*
|
|
326
|
-
* nothing after a move to the stream, with no error.
|
|
335
|
+
* Uses the primitives router — the same glob rules (and dedup) as the memory
|
|
336
|
+
* transport. Don't swap in a private matcher: subscriptions must behave
|
|
337
|
+
* identically in-process and on the stream.
|
|
327
338
|
*/
|
|
328
339
|
getMatchingHandlers(eventType) {
|
|
329
|
-
|
|
330
|
-
for (const [pattern, handlers] of this.handlers) if (matchEventPattern(pattern, eventType)) for (const h of handlers) matched.push(h);
|
|
331
|
-
return matched;
|
|
340
|
+
return this.router.route(eventType);
|
|
332
341
|
}
|
|
333
342
|
async moveToDlq(ids) {
|
|
334
343
|
if (this.deadLetterStream === false) {
|
|
@@ -354,17 +363,10 @@ var RedisStreamTransport = class {
|
|
|
354
363
|
}
|
|
355
364
|
}
|
|
356
365
|
/**
|
|
357
|
-
*
|
|
358
|
-
*
|
|
359
|
-
*
|
|
360
|
-
*
|
|
361
|
-
*
|
|
362
|
-
* Graceful degradation paths:
|
|
363
|
-
* - Client lacks `xrange` (older custom wrappers) → log once, build the
|
|
364
|
-
* envelope from `failureContext` alone. Payload is absent but the
|
|
365
|
-
* error reason + attempt accounting still survive.
|
|
366
|
-
* - `xrange` throws (network blip, ACL) → same fallback.
|
|
367
|
-
* - Source entry trimmed before DLQ write → same fallback.
|
|
366
|
+
* Build a `DeadLetteredEvent` from the original entry (via `xrange`) plus
|
|
367
|
+
* any local failure context. If the entry is unreadable (no `xrange`, error,
|
|
368
|
+
* or trimmed) the envelope keeps just the error and attempts. Returns `null`
|
|
369
|
+
* only when both are missing.
|
|
368
370
|
*/
|
|
369
371
|
async buildDlqEnvelope(id) {
|
|
370
372
|
const ctx = this.failureContext.get(id);
|
|
@@ -404,24 +406,14 @@ var RedisStreamTransport = class {
|
|
|
404
406
|
return new Promise((resolve) => setTimeout(resolve, ms));
|
|
405
407
|
}
|
|
406
408
|
};
|
|
407
|
-
/** Poll-error backoff tuning — see {@link fullJitterBackoffMs}. */
|
|
408
409
|
const POLL_ERROR_BACKOFF_BASE_MS = 1e3;
|
|
409
410
|
const POLL_ERROR_BACKOFF_MAX_MS = 3e4;
|
|
410
411
|
const POLL_ERROR_BACKOFF_FLOOR_MS = 100;
|
|
411
412
|
/**
|
|
412
|
-
*
|
|
413
|
-
*
|
|
414
|
-
*
|
|
415
|
-
*
|
|
416
|
-
* strategy. Full jitter decorrelates a fleet of consumers that all observed
|
|
417
|
-
* the same Redis blip; the small floor keeps a near-zero draw from
|
|
418
|
-
* hot-spinning the loop while Redis is hard-down.
|
|
419
|
-
*
|
|
420
|
-
* Sibling of `exponentialBackoff()` in `src/events/outbox.ts`, which is a
|
|
421
|
-
* PUBLIC store-author helper with additive jitter and `Date` (retryAt)
|
|
422
|
-
* semantics. Deliberately not shared: the two have different jitter models
|
|
423
|
-
* and audiences, and coupling them would hang this internal tuning off the
|
|
424
|
-
* public API surface.
|
|
413
|
+
* Poll-error delay drawn uniformly from `[floor, min(max, base * 2^(attempt-1))]`
|
|
414
|
+
* ("full jitter"). The floor stops a near-zero draw from hot-spinning while
|
|
415
|
+
* Redis is down. Intentionally separate from the public `exponentialBackoff()`
|
|
416
|
+
* (different jitter model and audience).
|
|
425
417
|
*
|
|
426
418
|
* @param attempt 1-indexed consecutive poll-error count (reset on success)
|
|
427
419
|
* @param random injectable for deterministic tests; defaults to `Math.random`
|
|
@@ -431,11 +423,7 @@ function fullJitterBackoffMs(attempt, random = Math.random) {
|
|
|
431
423
|
const capped = Math.min(POLL_ERROR_BACKOFF_MAX_MS, exp);
|
|
432
424
|
return POLL_ERROR_BACKOFF_FLOOR_MS + random() * (capped - POLL_ERROR_BACKOFF_FLOOR_MS);
|
|
433
425
|
}
|
|
434
|
-
/**
|
|
435
|
-
* Convert a thrown value into the `DeadLetteredEvent.error` shape — message
|
|
436
|
-
* always present, optional `code` (string only) and `stack`. Centralised so
|
|
437
|
-
* the failure-context tracker and the DLQ envelope writer agree.
|
|
438
|
-
*/
|
|
426
|
+
/** Convert a thrown value into the `DeadLetteredEvent.error` shape. */
|
|
439
427
|
function toErrorRecord(err) {
|
|
440
428
|
const e = err instanceof Error ? err : new Error(String(err));
|
|
441
429
|
const code = e.code;
|
|
@@ -446,15 +434,9 @@ function toErrorRecord(err) {
|
|
|
446
434
|
};
|
|
447
435
|
}
|
|
448
436
|
/**
|
|
449
|
-
* Parse a
|
|
450
|
-
*
|
|
451
|
-
*
|
|
452
|
-
* structure).
|
|
453
|
-
*
|
|
454
|
-
* Pure on purpose — used by both `processEntry` (the live consumer path)
|
|
455
|
-
* and `buildDlqEnvelope` (the dead-letter writer). Keeping the parse logic
|
|
456
|
-
* in one place avoids the silent drift class that produced the original
|
|
457
|
-
* "DLQ has no payload" bug.
|
|
437
|
+
* Parse a stream entry's flat `[key, value, ...]` fields into a `DomainEvent`,
|
|
438
|
+
* or `null` when malformed. Shared by the consumer and the DLQ writer so the
|
|
439
|
+
* two can't drift.
|
|
458
440
|
*/
|
|
459
441
|
function parseStreamFields(fields) {
|
|
460
442
|
let eventType;
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
|
|
2
|
-
import { a as EventTransport, i as EventLogger, n as DomainEvent, r as EventHandler } from "../../EventTransport-
|
|
2
|
+
import { a as EventTransport, i as EventLogger, n as DomainEvent, r as EventHandler } from "../../EventTransport-CiicKz2Z.mjs";
|
|
3
3
|
//#region src/events/transports/redis.d.ts
|
|
4
|
-
interface RedisLike {
|
|
4
|
+
export interface RedisLike {
|
|
5
5
|
publish(channel: string, message: string): Promise<number>;
|
|
6
6
|
subscribe(...channels: string[]): Promise<unknown>;
|
|
7
7
|
psubscribe(...patterns: string[]): Promise<unknown>;
|
|
@@ -9,7 +9,7 @@ interface RedisLike {
|
|
|
9
9
|
duplicate(): RedisLike;
|
|
10
10
|
quit(): Promise<unknown>;
|
|
11
11
|
}
|
|
12
|
-
interface RedisEventTransportOptions {
|
|
12
|
+
export interface RedisEventTransportOptions {
|
|
13
13
|
/**
|
|
14
14
|
* Redis channel prefix for all events.
|
|
15
15
|
* Events are published to `<channel>:<event.type>`.
|
|
@@ -28,7 +28,7 @@ interface RedisEventTransportOptions {
|
|
|
28
28
|
*/
|
|
29
29
|
logger?: EventLogger;
|
|
30
30
|
}
|
|
31
|
-
declare class RedisEventTransport implements EventTransport {
|
|
31
|
+
export declare class RedisEventTransport implements EventTransport {
|
|
32
32
|
readonly name = "redis";
|
|
33
33
|
/** Publish-side client (the original client or a duplicate). */
|
|
34
34
|
private pub;
|
|
@@ -72,5 +72,4 @@ declare class RedisEventTransport implements EventTransport {
|
|
|
72
72
|
*/
|
|
73
73
|
private isGlob;
|
|
74
74
|
}
|
|
75
|
-
//#endregion
|
|
76
|
-
export { RedisEventTransport, RedisEventTransportOptions, RedisLike };
|
|
75
|
+
//#endregion
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
/*! @classytic/arc v2.
|
|
2
|
-
import { r as workSeedFromEvent, t as runWorkScope } from "../../workScope-
|
|
1
|
+
/*! @classytic/arc v2.44.0 | MIT | https://classytic.com */
|
|
2
|
+
import { r as workSeedFromEvent, t as runWorkScope } from "../../workScope-n9a7d_lZ.mjs";
|
|
3
3
|
import sjson from "secure-json-parse";
|
|
4
4
|
//#region src/events/transports/redis.ts
|
|
5
5
|
/**
|