@bitspacerlabs/rabbit-relay 0.5.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.
@@ -0,0 +1,66 @@
1
+ # Sample workflow for building and deploying a VitePress site to GitHub Pages
2
+ #
3
+ name: Deploy VitePress site to Pages
4
+
5
+ on:
6
+ # Runs on pushes targeting the `main` branch. Change this to `master` if you're
7
+ # using the `master` branch as the default branch.
8
+ push:
9
+ branches: [main]
10
+
11
+ # Allows you to run this workflow manually from the Actions tab
12
+ workflow_dispatch:
13
+
14
+ # Sets permissions of the GITHUB_TOKEN to allow deployment to GitHub Pages
15
+ permissions:
16
+ contents: read
17
+ pages: write
18
+ id-token: write
19
+
20
+ # Allow only one concurrent deployment, skipping runs queued between the run in-progress and latest queued.
21
+ # However, do NOT cancel in-progress runs as we want to allow these production deployments to complete.
22
+ concurrency:
23
+ group: pages
24
+ cancel-in-progress: false
25
+
26
+ jobs:
27
+ # Build job
28
+ build:
29
+ runs-on: ubuntu-latest
30
+ steps:
31
+ - name: Checkout
32
+ uses: actions/checkout@v5
33
+ with:
34
+ fetch-depth: 0 # Not needed if lastUpdated is not enabled
35
+ # - uses: pnpm/action-setup@v4 # Uncomment this block if you're using pnpm
36
+ # with:
37
+ # version: 9 # Not needed if you've set "packageManager" in package.json
38
+ # - uses: oven-sh/setup-bun@v1 # Uncomment this if you're using Bun
39
+ - name: Setup Node
40
+ uses: actions/setup-node@v6
41
+ with:
42
+ node-version: 24
43
+ cache: npm # or pnpm / yarn
44
+ - name: Setup Pages
45
+ uses: actions/configure-pages@v4
46
+ - name: Install dependencies
47
+ run: npm ci # or pnpm install / yarn install / bun install
48
+ - name: Build with VitePress
49
+ run: npm run docs:build # or pnpm docs:build / yarn docs:build / bun run docs:build
50
+ - name: Upload artifact
51
+ uses: actions/upload-pages-artifact@v3
52
+ with:
53
+ path: docs/.vitepress/dist
54
+
55
+ # Deployment job
56
+ deploy:
57
+ environment:
58
+ name: github-pages
59
+ url: ${{ steps.deployment.outputs.page_url }}
60
+ needs: build
61
+ runs-on: ubuntu-latest
62
+ name: Deploy
63
+ steps:
64
+ - name: Deploy to GitHub Pages
65
+ id: deployment
66
+ uses: actions/deploy-pages@v4
@@ -0,0 +1,3 @@
1
+ {
2
+ "typescript.tsdk": "node_modules/typescript/lib"
3
+ }
package/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 BitSpacer Labs
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md ADDED
@@ -0,0 +1,90 @@
1
+ <p align="center">
2
+ <img src="assets/logo.svg" alt="Rabbit Relay" width="260">
3
+ </p>
4
+
5
+ <p align="center">
6
+ <a href="https://www.npmjs.com/package/rabbit-relay">
7
+ <img src="https://img.shields.io/npm/v/rabbit-relay.svg?style=flat-square" alt="NPM Version">
8
+ </a>
9
+ <a href="https://github.com/bitspacerlabs/rabbit-relay">
10
+ <img src="https://img.shields.io/github/stars/bitspacerlabs/rabbit-relay.svg?style=flat-square" alt="GitHub Stars">
11
+ </a>
12
+ <a href="https://github.com/bitspacerlabs/rabbit-relay/issues">
13
+ <img src="https://img.shields.io/github/issues/bitspacerlabs/rabbit-relay.svg?style=flat-square" alt="Issues">
14
+ </a>
15
+ <a href="https://opensource.org/licenses/MIT">
16
+ <img src="https://img.shields.io/badge/license-MIT-blue.svg?style=flat-square" alt="License">
17
+ </a>
18
+ </p>
19
+
20
+ ---
21
+
22
+ ## Rabbit Relay
23
+
24
+ **Rabbit Relay** is a type-safe RabbitMQ framework for Node.js.
25
+
26
+ It helps you publish and consume events using real RabbitMQ concepts, with TypeScript types and reliable defaults.
27
+
28
+ ---
29
+
30
+ ## Start Here
31
+
32
+ **Documentation & Guides**
33
+ https://bitspacerlabs.github.io/rabbit-relay/
34
+
35
+
36
+ ---
37
+
38
+ ## Installation
39
+
40
+ ```bash
41
+ npm install rabbit-relay
42
+ ```
43
+
44
+ ---
45
+
46
+ ## Minimal Examples
47
+
48
+ ```ts
49
+ import { RabbitMQBroker, event } from "rabbit-relay";
50
+
51
+ const broker = new RabbitMQBroker("example.service");
52
+
53
+ const pub = await broker.queue("example.q").exchange("example.exchange", { exchangeType: "topic" });
54
+
55
+ const send = event("send", "v1").of<{ message: string }>();
56
+
57
+ const api = pub.with({ send });
58
+
59
+ await api.send({ message: "hello world" });
60
+ ```
61
+
62
+ ---
63
+
64
+
65
+ ```ts
66
+ import { RabbitMQBroker, event } from "rabbit-relay";
67
+
68
+ const broker = new RabbitMQBroker("example.publisher");
69
+
70
+ const pub = await broker.queue("example.q").exchange("example.direct", { exchangeType: "direct" });
71
+
72
+ const hello = event("hello", "v1").of<{ msg: string }>();
73
+
74
+ await pub.produce(hello({ msg: "world" }));
75
+ ```
76
+
77
+ ---
78
+
79
+ ## When to Use Rabbit Relay
80
+
81
+ - You already use RabbitMQ
82
+ - You want type-safe events
83
+ - You prefer explicit topology and ownership
84
+ - You don’t want hidden abstractions
85
+
86
+ ---
87
+
88
+ ## License
89
+
90
+ MIT © BitSpacerLabs
@@ -0,0 +1,154 @@
1
+ <?xml version="1.0" standalone="no"?>
2
+ <!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 20010904//EN"
3
+ "http://www.w3.org/TR/2001/REC-SVG-20010904/DTD/svg10.dtd">
4
+ <svg version="1.0" xmlns="http://www.w3.org/2000/svg"
5
+ width="512.000000pt" height="512.000000pt" viewBox="0 0 512.000000 512.000000"
6
+ preserveAspectRatio="xMidYMid meet">
7
+ <metadata>
8
+ Created by potrace 1.16, written by Peter Selinger 2001-2019
9
+ </metadata>
10
+ <g transform="translate(0.000000,512.000000) scale(0.100000,-0.100000)"
11
+ fill="#000000" stroke="none">
12
+ <path d="M2940 4706 c-165 -36 -364 -210 -502 -438 l-33 -55 -2 93 c-4 160
13
+ -38 267 -106 332 -99 95 -223 22 -327 -192 -55 -113 -75 -180 -90 -304 -11
14
+ -88 -9 -133 17 -325 16 -126 13 -175 -15 -200 -9 -9 -58 -36 -109 -62 -96 -48
15
+ -187 -121 -224 -181 l-21 -35 -24 67 c-19 56 -67 144 -77 144 -2 0 11 -30 29
16
+ -67 18 -38 40 -93 48 -123 l16 -55 -23 30 c-12 16 -35 43 -50 60 -19 21 -16
17
+ 12 13 -29 35 -53 51 -96 34 -96 -3 0 -19 9 -35 21 -47 33 -144 68 -201 73 -29
18
+ 2 -42 2 -28 -1 66 -11 141 -38 198 -71 52 -30 62 -40 58 -58 -3 -11 -9 -54
19
+ -12 -95 -7 -70 -10 -77 -67 -154 -32 -44 -61 -82 -64 -85 -3 -3 -27 20 -55 50
20
+ -36 39 -42 44 -21 15 52 -70 64 -92 57 -108 -5 -14 -13 -12 -58 13 -63 36
21
+ -146 65 -207 74 -38 5 -35 3 20 -13 75 -22 211 -89 218 -108 3 -7 3 -19 0 -27
22
+ -5 -12 -15 -12 -69 -1 -82 17 -230 28 -203 16 11 -5 38 -10 60 -11 38 0 87
23
+ -10 168 -31 48 -13 50 -39 4 -39 -84 0 -264 -65 -300 -108 -6 -9 6 -4 29 10
24
+ 65 41 196 77 287 78 38 0 15 -29 -35 -45 -52 -17 -173 -79 -182 -93 -2 -4 26
25
+ 7 62 25 37 17 91 38 120 47 70 20 68 2 -4 -44 -31 -19 -75 -57 -98 -85 -71
26
+ -86 -73 -92 -6 -24 63 65 155 128 167 115 4 -3 -5 -19 -20 -34 -36 -38 -79
27
+ -136 -83 -191 l-3 -46 8 46 c5 25 18 63 29 85 23 44 98 130 86 99 -22 -62 -34
28
+ -126 -33 -175 l2 -55 7 70 c4 39 14 88 24 109 l16 40 33 -47 c17 -26 46 -54
29
+ 62 -63 17 -9 46 -25 65 -35 24 -13 55 -19 99 -19 48 0 62 -3 58 -13 -3 -7 -17
30
+ -51 -33 -98 -28 -85 -29 -114 -24 -379 2 -79 -8 -220 -20 -290 -37 -223 28
31
+ -393 235 -609 l98 -101 -6 -65 c-3 -35 -13 -78 -22 -95 -14 -28 -18 -29 -59
32
+ -24 -88 12 -176 -68 -176 -161 l0 -42 -72 -6 c-91 -8 -138 -17 -138 -27 0 -4
33
+ 15 -11 33 -14 45 -8 391 -26 515 -26 106 0 131 -11 65 -30 -48 -13 -68 -26
34
+ -55 -34 38 -23 383 -40 553 -27 139 11 163 17 155 37 -4 12 32 14 212 14 258
35
+ 0 483 14 566 35 34 9 96 19 139 24 43 5 81 12 84 15 9 9 -39 24 -103 31 -144
36
+ 16 -187 62 -89 94 149 49 239 161 353 441 55 133 65 186 60 295 -6 110 -33
37
+ 177 -80 201 -77 40 -152 -37 -188 -191 l-16 -70 -8 93 c-19 237 -109 471 -280
38
+ 731 -84 127 -173 223 -269 289 -131 90 -221 127 -350 143 -78 10 -81 11 -150
39
+ 72 -137 120 -139 123 -130 154 16 57 6 156 -25 253 -41 129 -43 147 -31 242
40
+ 23 184 70 257 234 358 304 189 439 357 499 623 38 166 52 207 101 282 73 112
41
+ 58 149 -67 166 -40 6 -82 14 -93 19 -38 16 -70 18 -125 6z m6 -51 c-235 -96
42
+ -424 -356 -511 -704 -21 -83 -86 -426 -85 -448 2 -28 140 411 140 443 0 4 2 5
43
+ 6 2 3 -3 -8 -64 -25 -134 -16 -71 -32 -144 -36 -163 l-7 -34 48 28 c62 35 113
44
+ 73 142 105 45 51 102 183 132 310 51 213 70 273 103 328 32 54 103 130 112
45
+ 121 3 -3 8 -39 11 -80 8 -92 -17 -200 -74 -322 -68 -145 -146 -250 -318 -427
46
+ -169 -175 -197 -212 -240 -325 -38 -100 -36 -190 5 -310 42 -120 49 -187 26
47
+ -259 -32 -101 -120 -178 -261 -226 l-56 -20 -31 24 c-72 54 -249 121 -299 114
48
+ -15 -2 1 -9 44 -20 79 -20 203 -71 238 -98 l25 -19 -26 -9 c-14 -6 -46 -13
49
+ -70 -17 -40 -6 -49 -3 -89 28 -58 43 -139 91 -146 84 -3 -2 14 -16 38 -30 24
50
+ -14 63 -40 88 -58 39 -29 42 -33 25 -40 -45 -18 -80 -9 -139 36 -33 25 -62 42
51
+ -65 39 -3 -4 0 -9 7 -11 25 -9 11 -33 -28 -43 -86 -23 -180 34 -180 108 0 34
52
+ 5 44 38 68 95 73 94 101 -3 61 l-75 -31 -27 21 c-53 39 -46 67 48 198 88 122
53
+ 97 145 115 263 8 51 23 110 34 131 33 67 113 127 266 203 132 65 148 71 207
54
+ 71 35 0 74 -4 86 -8 21 -6 22 -8 6 -26 -10 -10 -15 -25 -12 -34 7 -18 27 -20
55
+ 27 -3 0 19 31 47 46 41 8 -3 14 1 14 10 0 8 12 40 26 71 14 31 46 122 70 204
56
+ 50 163 107 290 178 399 138 213 280 343 431 395 74 26 89 21 21 -7z m-819 -88
57
+ c-49 -72 -95 -175 -129 -292 -21 -75 -23 -98 -23 -347 0 -200 -3 -270 -12
58
+ -279 -11 -10 -13 0 -13 50 0 34 -7 117 -16 184 -19 144 -14 265 16 382 28 111
59
+ 102 255 161 316 26 27 50 49 53 49 3 0 -14 -28 -37 -63z m161 6 c28 -40 49
60
+ -108 62 -204 15 -108 6 -210 -30 -324 -16 -49 -45 -146 -65 -214 -49 -164 -63
61
+ -193 -89 -185 -44 14 -47 57 -11 170 43 136 68 274 90 494 7 72 -11 18 -60
62
+ -185 -24 -99 -59 -230 -78 -290 -19 -61 -38 -125 -42 -142 -4 -22 -12 -33 -24
63
+ -33 -16 0 -19 14 -24 122 -14 249 -2 395 43 543 29 92 93 215 136 259 39 41
64
+ 57 38 92 -11z m922 38 c0 -5 -11 -23 -25 -39 -40 -48 -63 -111 -100 -274 -54
65
+ -240 -128 -368 -292 -510 -37 -32 -94 -75 -128 -97 l-62 -38 112 111 c95 95
66
+ 119 124 158 201 59 116 78 170 122 335 20 74 48 155 62 180 47 80 153 171 153
67
+ 131z m-475 -333 c-29 -57 -70 -147 -90 -200 -21 -54 -40 -96 -43 -94 -9 9 41
68
+ 152 80 231 34 67 95 165 104 165 1 0 -22 -46 -51 -102z m-1205 -1048 c0 -11
69
+ -4 -20 -9 -20 -5 0 -7 9 -4 20 3 11 7 20 9 20 2 0 4 -9 4 -20z m-150 -525 c5
70
+ 3 12 0 16 -6 4 -8 3 -9 -4 -5 -18 11 -14 -5 7 -28 28 -32 47 -112 31 -131 -12
71
+ -14 -16 -13 -36 6 -28 27 -60 100 -69 161 -10 64 3 81 27 34 10 -20 23 -34 28
72
+ -31z m1127 -107 c30 -22 74 -64 99 -92 25 -28 43 -43 40 -33 -14 42 87 -48
73
+ 125 -112 22 -36 39 -59 39 -52 0 17 -48 110 -76 147 l-23 31 51 -9 c125 -23
74
+ 306 -126 406 -231 70 -75 202 -278 267 -412 66 -137 101 -242 120 -359 22
75
+ -137 17 -164 -10 -57 -25 96 -43 136 -31 68 61 -337 41 -553 -66 -718 -34 -54
76
+ -39 -68 -34 -100 13 -83 -32 -189 -81 -189 -34 0 -48 18 -47 60 1 22 -2 40 -6
77
+ 40 -10 0 -30 -48 -30 -73 0 -35 -19 -47 -77 -47 -43 0 -54 4 -64 21 -11 21 -9
78
+ 60 7 109 6 22 5 23 -8 13 -16 -14 -43 -73 -52 -115 -12 -56 -56 -26 -56 38 0
79
+ 51 32 102 80 127 48 25 176 19 243 -11 70 -31 62 -1 -9 34 -42 20 -76 29 -134
80
+ 32 -71 4 -82 2 -130 -24 -58 -32 -87 -67 -105 -127 l-12 -42 -112 -3 c-107 -3
81
+ -111 -2 -111 18 0 37 29 78 72 104 26 16 36 26 25 26 -48 0 -120 -65 -132
82
+ -120 -6 -26 -11 -30 -41 -30 -45 0 -54 32 -24 90 28 55 81 79 172 80 37 0 69
83
+ -4 73 -10 3 -5 21 2 41 15 42 28 135 65 167 65 12 0 29 5 37 11 11 8 0 9 -40
84
+ 5 -174 -19 -176 -19 -208 -2 -38 19 -56 49 -46 78 3 11 32 67 64 125 32 57 68
85
+ 131 80 164 13 33 25 57 29 54 3 -4 11 -41 17 -83 16 -110 47 -183 103 -244 48
86
+ -52 131 -109 131 -89 0 5 -4 13 -10 16 -27 17 -5 22 36 8 64 -22 64 -11 1 25
87
+ -138 78 -229 274 -230 497 -2 153 40 283 117 372 44 50 126 93 179 93 49 0 40
88
+ 16 -14 25 -89 15 -197 -50 -258 -157 l-28 -49 -7 62 c-6 62 -56 188 -82 210
89
+ -9 8 -9 -1 2 -37 22 -73 34 -233 23 -316 -20 -163 -80 -276 -244 -463 -183
90
+ -208 -212 -271 -234 -505 -8 -82 -12 -97 -34 -116 -14 -12 -42 -25 -62 -28
91
+ -53 -10 -69 9 -69 79 0 49 -2 53 -12 33 -7 -13 -16 -45 -19 -71 -7 -47 -8 -48
92
+ -38 -45 -44 4 -63 44 -48 101 5 23 8 43 6 46 -7 7 -45 -82 -45 -107 0 -17 -5
93
+ -22 -17 -20 -14 3 -18 14 -17 51 0 54 22 90 77 126 21 14 42 39 51 61 18 45
94
+ 37 183 35 255 -1 33 -3 40 -6 20 -17 -121 -71 -301 -73 -240 0 11 9 43 19 70
95
+ 23 60 29 108 41 330 11 194 31 288 85 397 l37 73 -30 -28 c-37 -35 -87 -133
96
+ -106 -207 -12 -47 -15 -51 -20 -30 -4 14 -15 59 -26 100 l-19 75 4 -145 c2
97
+ -80 7 -162 11 -184 l7 -38 -25 23 c-83 79 -198 179 -198 172 0 -14 50 -85 89
98
+ -127 35 -38 34 -37 -39 15 -208 147 -365 376 -395 574 -6 38 -5 37 32 -29 43
99
+ -80 171 -220 242 -265 26 -17 51 -31 56 -31 4 0 -22 31 -59 68 -94 96 -142
100
+ 163 -192 267 -88 181 -107 361 -54 515 30 85 43 100 94 100 45 0 45 0 98 -95
101
+ 39 -70 35 -44 -6 38 -28 55 -31 67 -18 67 10 0 24 -6 32 -13 25 -20 85 -99
102
+ 110 -144 13 -24 25 -41 27 -39 7 6 -36 86 -74 140 -36 51 -34 74 6 61 29 -9
103
+ 114 -116 153 -192 18 -34 34 -60 36 -58 7 7 -67 142 -107 195 -26 35 -37 58
104
+ -31 64 25 25 170 -141 215 -249 14 -33 23 -46 20 -30 -13 60 -70 158 -133 226
105
+ -54 58 -60 69 -42 69 35 0 200 58 256 91 28 16 69 49 90 73 22 24 43 45 48 45
106
+ 5 1 33 -18 63 -41z m-762 -108 c9 -14 -86 -40 -150 -40 -65 0 -115 24 -115 55
107
+ 0 12 6 12 35 -1 19 -7 51 -14 71 -14 36 0 94 26 94 43 0 9 55 -28 65 -43z
108
+ m-16 -1063 c43 -71 55 -105 90 -242 l40 -160 -68 71 c-76 79 -134 174 -162
109
+ 266 -19 60 -25 175 -12 238 l6 33 28 -62 c15 -34 50 -99 78 -144z m2100 47
110
+ c47 -59 52 -227 11 -336 -12 -32 -25 -60 -30 -63 -5 -3 -17 14 -28 37 -26 60
111
+ -46 75 -83 61 -36 -14 -36 -15 -9 119 22 105 38 148 73 186 26 29 41 28 66 -4z
112
+ m-1887 -345 c74 -88 108 -148 139 -243 l26 -80 17 77 c17 77 23 86 43 66 7 -7
113
+ 5 -28 -8 -70 -29 -92 -35 -183 -15 -213 16 -25 15 -27 -18 -71 -19 -24 -37
114
+ -54 -41 -65 -6 -18 -15 -20 -76 -20 -72 0 -75 2 -59 44 14 37 -1 32 -29 -10
115
+ -23 -34 -26 -35 -80 -32 -53 3 -56 4 -59 31 -2 16 5 46 16 68 11 23 15 38 8
116
+ 36 -22 -7 -56 -70 -56 -103 0 -29 -3 -34 -25 -34 -56 0 -53 79 5 135 25 24 37
117
+ 28 97 29 l68 1 20 40 c16 32 20 60 20 140 0 86 -5 118 -38 227 -20 70 -37 131
118
+ -37 135 0 9 12 -3 82 -88z m1778 -47 c0 -39 -7 -58 -35 -97 -19 -27 -33 -51
119
+ -31 -53 6 -5 75 26 107 48 l29 21 -35 -77 c-71 -155 -159 -237 -185 -170 -11
120
+ 31 13 153 46 226 27 61 85 150 97 150 4 0 7 -22 7 -48z"/>
121
+ <path d="M1916 3536 c-67 -29 -117 -66 -155 -116 -23 -31 -20 -30 25 12 83 76
122
+ 145 102 236 103 86 0 90 14 7 21 -43 4 -67 -1 -113 -20z"/>
123
+ <path d="M1924 3325 c-10 -8 -14 -14 -9 -14 6 0 19 6 29 14 11 8 15 15 10 15
124
+ -6 0 -19 -7 -30 -15z"/>
125
+ <path d="M1791 3285 c-41 -47 -61 -120 -68 -243 l-6 -104 -54 -40 c-80 -61
126
+ -58 -56 38 8 136 92 176 107 306 114 91 5 117 9 131 24 16 18 16 18 -3 8 -11
127
+ -5 -66 -12 -123 -16 -57 -4 -130 -15 -163 -25 -32 -11 -59 -15 -59 -9 0 5 -5
128
+ 52 -11 103 -12 103 -4 151 34 193 11 12 18 22 15 22 -3 0 -20 -16 -37 -35z"/>
129
+ <path d="M2138 3304 c-16 -16 -41 -18 -166 -11 -39 2 -70 2 -68 -1 3 -2 -6
130
+ -16 -20 -30 -35 -38 -54 -84 -65 -155 -5 -34 -12 -70 -15 -80 -5 -17 -4 -17
131
+ 33 -2 21 9 69 20 106 25 97 12 137 57 137 153 0 20 5 27 19 27 10 0 29 9 42
132
+ 21 l24 20 -25 -7 -25 -6 24 26 c26 28 25 46 -1 20z m-134 -57 c11 -8 17 -23
133
+ 14 -38 -2 -20 -8 -23 -33 -20 -16 1 -38 7 -47 12 -12 6 -25 6 -39 -1 -19 -11
134
+ -20 -10 -10 9 25 46 80 64 115 38z"/>
135
+ <path d="M2088 3163 c-3 -41 -10 -69 -23 -83 -10 -11 -13 -20 -7 -20 29 0 59
136
+ 102 43 145 -6 14 -10 1 -13 -42z"/>
137
+ <path d="M1715 2800 c-87 -23 -52 -26 42 -4 44 10 93 14 138 11 41 -3 60 -1
138
+ 45 3 -44 14 -153 9 -225 -10z"/>
139
+ <path d="M1660 2763 c0 -24 32 -33 126 -37 90 -4 144 -16 228 -51 13 -6 17 -5
140
+ 12 3 -17 28 -122 55 -231 59 -85 4 -113 9 -122 21 -7 9 -13 11 -13 5z"/>
141
+ <path d="M1625 2640 c-3 -5 -2 -10 4 -10 5 0 13 5 16 10 3 6 2 10 -4 10 -5 0
142
+ -13 -4 -16 -10z"/>
143
+ <path d="M1585 2620 c-3 -5 -1 -10 4 -10 6 0 11 5 11 10 0 6 -2 10 -4 10 -3 0
144
+ -8 -4 -11 -10z"/>
145
+ <path d="M1605 2590 c-8 -13 9 -20 24 -11 10 6 9 10 -3 14 -8 3 -18 2 -21 -3z"/>
146
+ <path d="M2515 2510 c10 -11 20 -20 23 -20 3 0 -3 9 -13 20 -10 11 -20 20 -23
147
+ 20 -3 0 3 -9 13 -20z"/>
148
+ <path d="M2623 2377 c81 -113 135 -253 137 -362 l1 -30 11 25 c5 14 8 55 5 91
149
+ -5 82 -52 175 -138 278 -33 39 -62 71 -64 71 -2 0 19 -33 48 -73z"/>
150
+ <path d="M1390 3585 c13 -14 26 -25 28 -25 3 0 -5 11 -18 25 -13 14 -26 25
151
+ -28 25 -3 0 5 -11 18 -25z"/>
152
+ <path d="M938 2803 c6 -2 18 -2 25 0 6 3 1 5 -13 5 -14 0 -19 -2 -12 -5z"/>
153
+ </g>
154
+ </svg>
@@ -0,0 +1,5 @@
1
+ import { Channel, ConfirmChannel, ChannelModel } from "amqplib";
2
+ export declare const rabbitMQUrl: string;
3
+ export declare function getRabbitMQConnection(): Promise<ChannelModel>;
4
+ export declare function getRabbitMQChannel(): Promise<Channel>;
5
+ export declare function getRabbitMQConfirmChannel(): Promise<ConfirmChannel>;
@@ -0,0 +1,120 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ var _a;
6
+ Object.defineProperty(exports, "__esModule", { value: true });
7
+ exports.rabbitMQUrl = void 0;
8
+ exports.getRabbitMQConnection = getRabbitMQConnection;
9
+ exports.getRabbitMQChannel = getRabbitMQChannel;
10
+ exports.getRabbitMQConfirmChannel = getRabbitMQConfirmChannel;
11
+ const amqplib_1 = require("amqplib");
12
+ const node_os_1 = __importDefault(require("node:os"));
13
+ exports.rabbitMQUrl = (_a = process.env.RABBITMQ_URL) !== null && _a !== void 0 ? _a : "amqp://user:password@localhost";
14
+ let conn = null;
15
+ let ch = null;
16
+ let opening = null;
17
+ let cch = null;
18
+ let cOpening = null;
19
+ function attachConnHandlers(c) {
20
+ c.on("blocked", (reason) => console.warn("[amqp] connection blocked:", reason));
21
+ c.on("unblocked", () => console.log("[amqp] connection unblocked"));
22
+ c.on("close", () => {
23
+ console.error("[amqp] connection closed");
24
+ conn = null;
25
+ ch = null;
26
+ opening = null;
27
+ cch = null;
28
+ cOpening = null;
29
+ });
30
+ c.on("error", (err) => {
31
+ console.error("[amqp] connection error:", err);
32
+ // 'close' will clear caches
33
+ });
34
+ }
35
+ function attachChannelHandlers(channel, kind) {
36
+ channel.on("close", () => {
37
+ console.error(`[amqp] ${kind === "confirm" ? "confirm channel" : "channel"} closed`);
38
+ if (kind === "ch") {
39
+ ch = null;
40
+ opening = null;
41
+ }
42
+ else {
43
+ cch = null;
44
+ cOpening = null;
45
+ }
46
+ });
47
+ channel.on("error", (err) => {
48
+ console.error(`[amqp] ${kind === "confirm" ? "confirm channel" : "channel"} error:`, err);
49
+ });
50
+ }
51
+ async function getConn() {
52
+ if (conn)
53
+ return conn;
54
+ const c = await (0, amqplib_1.connect)(exports.rabbitMQUrl, {
55
+ clientProperties: {
56
+ connection_name: process.env.AMQP_CONN_NAME ||
57
+ `app:${process.title || "node"}@${node_os_1.default.hostname()}#${process.pid}`,
58
+ },
59
+ });
60
+ attachConnHandlers(c);
61
+ conn = c;
62
+ return c;
63
+ }
64
+ /** Always return a live channel */
65
+ async function openChannelFresh() {
66
+ if (ch)
67
+ return ch;
68
+ if (opening)
69
+ return opening;
70
+ opening = (async () => {
71
+ try {
72
+ const c = await getConn();
73
+ const channel = await c.createChannel();
74
+ attachChannelHandlers(channel, "ch");
75
+ ch = channel;
76
+ return channel;
77
+ }
78
+ catch (err) {
79
+ opening = null;
80
+ ch = null;
81
+ conn = null;
82
+ throw err;
83
+ }
84
+ })();
85
+ return opening;
86
+ }
87
+ async function openConfirmChannelFresh() {
88
+ if (cch)
89
+ return cch;
90
+ if (cOpening)
91
+ return cOpening;
92
+ cOpening = (async () => {
93
+ try {
94
+ const c = await getConn();
95
+ const channel = await c.createConfirmChannel();
96
+ attachChannelHandlers(channel, "confirm");
97
+ cch = channel;
98
+ return channel;
99
+ }
100
+ catch (err) {
101
+ cOpening = null;
102
+ cch = null;
103
+ conn = null;
104
+ throw err;
105
+ }
106
+ })();
107
+ return cOpening;
108
+ }
109
+ async function getRabbitMQConnection() {
110
+ if (conn)
111
+ return conn;
112
+ await openChannelFresh();
113
+ return conn;
114
+ }
115
+ async function getRabbitMQChannel() {
116
+ return openChannelFresh();
117
+ }
118
+ async function getRabbitMQConfirmChannel() {
119
+ return openConfirmChannelFresh();
120
+ }
@@ -0,0 +1,31 @@
1
+ /** Optional metadata carried alongside the event payload. */
2
+ export interface EventMeta {
3
+ corrId?: string;
4
+ causationId?: string;
5
+ /** Optional application headers. */
6
+ headers?: Record<string, string>;
7
+ expectsReply?: boolean;
8
+ timeoutMs?: number;
9
+ }
10
+ export interface EventEnvelope<T = unknown> {
11
+ id: string;
12
+ name: string;
13
+ v: string;
14
+ time: number;
15
+ data: T;
16
+ meta?: EventMeta;
17
+ }
18
+ export type EnvelopeFactory<T> = (data: T, meta?: EventMeta) => EventEnvelope<T>;
19
+ export declare function expectReply(meta?: EventMeta, timeoutMs?: number): EventMeta;
20
+ export declare function event(name: string, v?: string): {
21
+ of: <T = unknown>() => EnvelopeFactory<T>;
22
+ };
23
+ export declare function eventWithReply(name: string, v?: string): {
24
+ of: <T = unknown, R = unknown>() => EnvelopeFactory<T>;
25
+ };
26
+ /**
27
+ * Augment an events map so calling a factory publishes via broker.produce().
28
+ */
29
+ export declare function augmentEvents<T extends object>(events: Record<string, (...args: any[]) => EventEnvelope>, broker: {
30
+ produce: (...evts: EventEnvelope[]) => Promise<unknown>;
31
+ }): T & Record<string, (...args: any[]) => Promise<unknown>>;
@@ -0,0 +1,54 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.expectReply = expectReply;
4
+ exports.event = event;
5
+ exports.eventWithReply = eventWithReply;
6
+ exports.augmentEvents = augmentEvents;
7
+ const crypto_1 = require("crypto");
8
+ function expectReply(meta, timeoutMs) {
9
+ return { ...(meta !== null && meta !== void 0 ? meta : {}), expectsReply: true, ...(timeoutMs != null ? { timeoutMs } : {}) };
10
+ }
11
+ function randomId() {
12
+ var _a;
13
+ try {
14
+ return (_a = crypto_1.randomUUID === null || crypto_1.randomUUID === void 0 ? void 0 : (0, crypto_1.randomUUID)()) !== null && _a !== void 0 ? _a : `evt_${Date.now()}_${Math.random().toString(36).slice(2)}`;
15
+ }
16
+ catch {
17
+ return `evt_${Date.now()}_${Math.random().toString(36).slice(2)}`;
18
+ }
19
+ }
20
+ function event(name, v = "1.0.0") {
21
+ return {
22
+ of: () => (data, meta) => ({
23
+ id: randomId(),
24
+ name,
25
+ v,
26
+ time: Date.now(),
27
+ data,
28
+ meta,
29
+ }),
30
+ };
31
+ }
32
+ function eventWithReply(name, v = "1.0.0") {
33
+ return {
34
+ of: () => (data, meta) => ({
35
+ id: randomId(),
36
+ name,
37
+ v,
38
+ time: Date.now(),
39
+ data,
40
+ meta: { expectsReply: false, ...(meta !== null && meta !== void 0 ? meta : {}) },
41
+ }),
42
+ };
43
+ }
44
+ /**
45
+ * Augment an events map so calling a factory publishes via broker.produce().
46
+ */
47
+ function augmentEvents(events, broker) {
48
+ const augmented = { ...events, ...broker };
49
+ for (const key of Object.keys(events)) {
50
+ const factory = events[key];
51
+ augmented[key] = async (...args) => broker.produce(factory(...args));
52
+ }
53
+ return augmented;
54
+ }
@@ -0,0 +1,4 @@
1
+ export * from "./rabbitmqBroker";
2
+ export * from "./eventFactories";
3
+ export * from "./pluginManager";
4
+ export * from "./utils/dedupe";
@@ -0,0 +1,20 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __exportStar = (this && this.__exportStar) || function(m, exports) {
14
+ for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
15
+ };
16
+ Object.defineProperty(exports, "__esModule", { value: true });
17
+ __exportStar(require("./rabbitmqBroker"), exports);
18
+ __exportStar(require("./eventFactories"), exports);
19
+ __exportStar(require("./pluginManager"), exports);
20
+ __exportStar(require("./utils/dedupe"), exports);
@@ -0,0 +1,13 @@
1
+ import { EventEnvelope } from "./eventFactories";
2
+ export interface Plugin {
3
+ beforeProduce?(event: EventEnvelope): Promise<void>;
4
+ afterProduce?(event: EventEnvelope, result: unknown): Promise<void>;
5
+ beforeProcess?(id: string | number, event: EventEnvelope): Promise<void>;
6
+ afterProcess?(id: string | number, event: EventEnvelope, result: unknown): Promise<void>;
7
+ }
8
+ export declare class PluginManager {
9
+ private plugins;
10
+ register(plugin: Plugin): void;
11
+ executeHook<K extends keyof Plugin>(hookName: K, ...args: Parameters<NonNullable<Plugin[K]>>): Promise<void>;
12
+ }
13
+ export declare const pluginManager: PluginManager;
@@ -0,0 +1,27 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.pluginManager = exports.PluginManager = void 0;
4
+ class PluginManager {
5
+ constructor() {
6
+ this.plugins = [];
7
+ }
8
+ register(plugin) {
9
+ this.plugins.push(plugin);
10
+ }
11
+ async executeHook(hookName, ...args) {
12
+ for (const plugin of this.plugins) {
13
+ const fn = plugin[hookName];
14
+ if (typeof fn === "function") {
15
+ try {
16
+ await fn
17
+ .call(plugin, ...args);
18
+ }
19
+ catch (err) {
20
+ console.error(`Error executing hook ${String(hookName)}:`, err);
21
+ }
22
+ }
23
+ }
24
+ }
25
+ }
26
+ exports.PluginManager = PluginManager;
27
+ exports.pluginManager = new PluginManager();