@bsb/events-rabbitmq 0.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (32) hide show
  1. package/LICENSE +661 -0
  2. package/README.md +109 -0
  3. package/lib/plugins/events-rabbitmq/events/broadcast.d.ts +19 -0
  4. package/lib/plugins/events-rabbitmq/events/broadcast.js +105 -0
  5. package/lib/plugins/events-rabbitmq/events/emit.d.ts +17 -0
  6. package/lib/plugins/events-rabbitmq/events/emit.js +89 -0
  7. package/lib/plugins/events-rabbitmq/events/emitAndReturn.d.ts +20 -0
  8. package/lib/plugins/events-rabbitmq/events/emitAndReturn.js +207 -0
  9. package/lib/plugins/events-rabbitmq/events/emitStreamAndReceiveStream.d.ts +24 -0
  10. package/lib/plugins/events-rabbitmq/events/emitStreamAndReceiveStream.js +515 -0
  11. package/lib/plugins/events-rabbitmq/events/lib.d.ts +12 -0
  12. package/lib/plugins/events-rabbitmq/events/lib.js +59 -0
  13. package/lib/plugins/events-rabbitmq/index.d.ts +55 -0
  14. package/lib/plugins/events-rabbitmq/index.js +150 -0
  15. package/lib/plugins/events-rabbitmq/plugin.config.json +39 -0
  16. package/lib/schemas/events-rabbitmq.json +118 -0
  17. package/lib/schemas/events-rabbitmq.plugin.json +124 -0
  18. package/lib/tests/mocks.d.ts +3 -0
  19. package/lib/tests/mocks.js +65 -0
  20. package/lib/tests/plugins/events/events/broadcast.d.ts +4 -0
  21. package/lib/tests/plugins/events/events/broadcast.js +320 -0
  22. package/lib/tests/plugins/events/events/emit.d.ts +4 -0
  23. package/lib/tests/plugins/events/events/emit.js +316 -0
  24. package/lib/tests/plugins/events/events/emitAndReturn.d.ts +4 -0
  25. package/lib/tests/plugins/events/events/emitAndReturn.js +307 -0
  26. package/lib/tests/plugins/events/events/emitStreamAndReceiveStream.d.ts +4 -0
  27. package/lib/tests/plugins/events/events/emitStreamAndReceiveStream.js +199 -0
  28. package/lib/tests/plugins/events/plugin.d.ts +2 -0
  29. package/lib/tests/plugins/events/plugin.js +47 -0
  30. package/lib/tests/trace.d.ts +4 -0
  31. package/lib/tests/trace.js +39 -0
  32. package/package.json +70 -0
@@ -0,0 +1,307 @@
1
+ import * as assert from "assert";
2
+ import { randomUUID } from "crypto";
3
+ import { SmartFunctionCallSync } from "@bsb/base";
4
+ import { createTestObservable } from "../../../trace.js";
5
+ const randomName = () => randomUUID();
6
+ export function emitAndReturn(genNewPlugin, maxTimeoutToExpectAResponse) {
7
+ let emitter;
8
+ beforeEach(async () => {
9
+ emitter = await genNewPlugin();
10
+ });
11
+ afterEach(function () {
12
+ SmartFunctionCallSync(emitter, emitter.dispose);
13
+ });
14
+ describe("EmitAndReturn", async () => {
15
+ const timermaxTimeoutToExpectAResponse = maxTimeoutToExpectAResponse + 10;
16
+ describe("emitEventAndReturn", async () => {
17
+ const emitData = true;
18
+ const emitData2 = false;
19
+ it("should be able to emit to events with plugin name defined", async () => {
20
+ const thisPlugin = randomName();
21
+ const thisEvent = randomName();
22
+ const obs = createTestObservable();
23
+ const emitTimeout = setTimeout(() => {
24
+ assert.fail("Event not received");
25
+ }, timermaxTimeoutToExpectAResponse);
26
+ await emitter.onReturnableEvent(obs, thisPlugin, thisEvent, async (receivedObs, data) => {
27
+ return emitData2;
28
+ });
29
+ await emitter.emitEventAndReturn(obs, thisPlugin, thisEvent, maxTimeoutToExpectAResponse / 1000, []);
30
+ clearTimeout(emitTimeout);
31
+ assert.ok(true, "Received Response");
32
+ });
33
+ it("should be able to emit to events with self", async () => {
34
+ const thisCaller = randomName();
35
+ const thisEvent = randomName();
36
+ const obs = createTestObservable();
37
+ const emitTimeout = setTimeout(() => {
38
+ assert.fail("Event not received");
39
+ }, timermaxTimeoutToExpectAResponse);
40
+ await emitter.onReturnableEvent(obs, thisCaller, thisEvent, async (receivedObs, data) => {
41
+ return emitData2;
42
+ });
43
+ await emitter.emitEventAndReturn(obs, thisCaller, thisEvent, maxTimeoutToExpectAResponse / 1000, [emitData]);
44
+ clearTimeout(emitTimeout);
45
+ assert.ok(true, "Received Response");
46
+ });
47
+ it("should not be able to emit to other events with plugin name defined", async () => {
48
+ const thisPlugin = randomName();
49
+ const thisEvent = randomName();
50
+ const thisEvent2 = randomName();
51
+ const obs = createTestObservable();
52
+ const emitTimeout = setTimeout(() => {
53
+ assert.ok(true);
54
+ }, timermaxTimeoutToExpectAResponse);
55
+ await emitter.onReturnableEvent(obs, thisPlugin, thisEvent, async () => {
56
+ assert.fail("EEAR MSG Received");
57
+ });
58
+ try {
59
+ await emitter.emitEventAndReturn(obs, thisPlugin, thisEvent2, maxTimeoutToExpectAResponse / 1000, [emitData]);
60
+ clearTimeout(emitTimeout);
61
+ assert.fail("EEAR Returned");
62
+ }
63
+ catch {
64
+ clearTimeout(emitTimeout);
65
+ assert.ok("Timeout of EEAR");
66
+ }
67
+ });
68
+ it("should not be able to emit to other events with self", async () => {
69
+ const thisCaller = randomName();
70
+ const thisEvent = randomName();
71
+ const thisEvent2 = randomName();
72
+ const obs = createTestObservable();
73
+ const emitTimeout = setTimeout(() => {
74
+ assert.ok(true);
75
+ }, timermaxTimeoutToExpectAResponse);
76
+ await emitter.onReturnableEvent(obs, thisCaller, thisEvent, async () => {
77
+ assert.fail("EEAR MSG Received");
78
+ });
79
+ try {
80
+ await emitter.emitEventAndReturn(obs, thisCaller, thisEvent2, maxTimeoutToExpectAResponse / 1000, [emitData]);
81
+ clearTimeout(emitTimeout);
82
+ assert.fail("EEAR Returned");
83
+ }
84
+ catch {
85
+ clearTimeout(emitTimeout);
86
+ assert.ok("Timeout of EEAR");
87
+ }
88
+ });
89
+ it("should timeout correctly", async () => {
90
+ const thisCaller = randomName();
91
+ const thisEvent = randomName();
92
+ const obs = createTestObservable();
93
+ const emitTimeout = setTimeout(() => {
94
+ assert.fail("Event not received");
95
+ }, timermaxTimeoutToExpectAResponse);
96
+ await emitter.onReturnableEvent(obs, thisCaller, thisEvent, async () => { });
97
+ try {
98
+ await emitter.emitEventAndReturn(obs, thisCaller, thisEvent, maxTimeoutToExpectAResponse / 1000, [emitData]);
99
+ clearTimeout(emitTimeout);
100
+ assert.fail("EEAR Returned");
101
+ }
102
+ catch {
103
+ clearTimeout(emitTimeout);
104
+ assert.ok("Timeout of EEAR");
105
+ }
106
+ });
107
+ it("should response error correctly", async () => {
108
+ const thisCaller = randomName();
109
+ const thisEvent = randomName();
110
+ const obs = createTestObservable();
111
+ const emitTimeout = setTimeout(() => {
112
+ assert.fail("Event not received");
113
+ }, timermaxTimeoutToExpectAResponse);
114
+ await emitter.onReturnableEvent(obs, thisCaller, thisEvent, async () => {
115
+ throw "THISISANERROR";
116
+ });
117
+ try {
118
+ await emitter.emitEventAndReturn(obs, thisCaller, thisEvent, maxTimeoutToExpectAResponse / 1000, [emitData]);
119
+ clearTimeout(emitTimeout);
120
+ assert.fail("EEAR Returned");
121
+ }
122
+ catch (exc) {
123
+ clearTimeout(emitTimeout);
124
+ assert.ok("EEAR");
125
+ assert.strictEqual(exc, "THISISANERROR");
126
+ }
127
+ });
128
+ });
129
+ const typesToTest = [
130
+ {
131
+ name: "DiffData",
132
+ data: null,
133
+ rData: "HELLO WORLD",
134
+ },
135
+ {
136
+ name: "Null",
137
+ data: null,
138
+ },
139
+ {
140
+ name: "Boolean true",
141
+ data: true,
142
+ },
143
+ {
144
+ name: "Boolean false",
145
+ data: false,
146
+ },
147
+ {
148
+ name: "String",
149
+ data: "HELLO WO4lD",
150
+ },
151
+ {
152
+ name: "Min Number",
153
+ data: Number.MIN_SAFE_INTEGER,
154
+ },
155
+ {
156
+ name: "Max Number",
157
+ data: Number.MAX_SAFE_INTEGER,
158
+ },
159
+ {
160
+ name: "Array",
161
+ data: [0, "Hello", true],
162
+ },
163
+ {
164
+ name: "Object",
165
+ data: {
166
+ name: "Sarah",
167
+ surname: "Blond",
168
+ age: 24,
169
+ meta: {
170
+ location: [-12212, 55336],
171
+ },
172
+ },
173
+ },
174
+ ];
175
+ for (const typeToTest of typesToTest) {
176
+ describe(`emitEventAndReturn ${typeToTest.name}`, async () => {
177
+ it("should be able to emit to events with plugin name defined", async () => {
178
+ const thisPlugin = randomName();
179
+ const thisEvent = randomName();
180
+ const obs = createTestObservable();
181
+ const emitTimeout = setTimeout(() => {
182
+ assert.fail("Event not received");
183
+ }, timermaxTimeoutToExpectAResponse);
184
+ await emitter.onReturnableEvent(obs, thisPlugin, thisEvent, async () => {
185
+ return typeToTest.rData !== undefined ? typeToTest.rData : typeToTest.data;
186
+ });
187
+ const resp = await emitter.emitEventAndReturn(obs, thisPlugin, thisEvent, maxTimeoutToExpectAResponse / 1000, [typeToTest.data]);
188
+ clearTimeout(emitTimeout);
189
+ assert.strictEqual(JSON.stringify(resp), JSON.stringify(typeToTest.rData !== undefined ? typeToTest.rData : typeToTest.data));
190
+ });
191
+ it("should be able to emit to events with self", async () => {
192
+ const thisCaller = randomName();
193
+ const thisEvent = randomName();
194
+ const obs = createTestObservable();
195
+ const emitTimeout = setTimeout(() => {
196
+ assert.fail("Event not received - timeout");
197
+ }, timermaxTimeoutToExpectAResponse);
198
+ await emitter.onReturnableEvent(obs, thisCaller, thisEvent, async (receivedObs, data) => {
199
+ clearTimeout(emitTimeout);
200
+ assert.strictEqual(JSON.stringify(data[0]), JSON.stringify(typeToTest.data), "Received data");
201
+ return typeToTest.rData || typeToTest.data;
202
+ });
203
+ assert.strictEqual(JSON.stringify(await emitter.emitEventAndReturn(obs, thisCaller, thisEvent, maxTimeoutToExpectAResponse / 1000, [typeToTest.data])), JSON.stringify(typeToTest.rData || typeToTest.data), "Returned data");
204
+ clearTimeout(emitTimeout);
205
+ });
206
+ it("should not be able to emit to other events with plugin name defined", async () => {
207
+ const thisPlugin = randomName();
208
+ const thisEvent = randomName();
209
+ const thisEvent2 = randomName();
210
+ const obs = createTestObservable();
211
+ const emitTimeout = setTimeout(() => {
212
+ assert.ok(true);
213
+ }, timermaxTimeoutToExpectAResponse);
214
+ await emitter.onReturnableEvent(obs, thisPlugin, thisEvent, async () => {
215
+ assert.fail("EEAR MSG Received");
216
+ });
217
+ try {
218
+ await emitter.emitEventAndReturn(obs, thisPlugin, thisEvent2, maxTimeoutToExpectAResponse / 1000, [typeToTest.data]);
219
+ clearTimeout(emitTimeout);
220
+ assert.fail("EEAR Returned");
221
+ }
222
+ catch {
223
+ clearTimeout(emitTimeout);
224
+ assert.ok("Timeout of EEAR");
225
+ }
226
+ });
227
+ it("should not be able to emit to other events with self", async () => {
228
+ const thisCaller = randomName();
229
+ const thisEvent = randomName();
230
+ const thisEvent2 = randomName();
231
+ const obs = createTestObservable();
232
+ const emitTimeout = setTimeout(() => {
233
+ assert.ok(true);
234
+ }, timermaxTimeoutToExpectAResponse);
235
+ await emitter.onReturnableEvent(obs, thisCaller, thisEvent, async () => {
236
+ assert.fail("EEAR MSG Received");
237
+ });
238
+ try {
239
+ await emitter.emitEventAndReturn(obs, thisCaller, thisEvent2, maxTimeoutToExpectAResponse / 1000, [typeToTest.data]);
240
+ clearTimeout(emitTimeout);
241
+ assert.fail("EEAR Returned");
242
+ }
243
+ catch {
244
+ clearTimeout(emitTimeout);
245
+ assert.ok("Timeout of EEAR");
246
+ }
247
+ });
248
+ it("should timeout correctly - general timeout", async () => {
249
+ const thisCaller = randomName();
250
+ const thisEvent = randomName();
251
+ const obs = createTestObservable();
252
+ const emitTimeout = setTimeout(() => {
253
+ assert.fail("Event not received");
254
+ }, timermaxTimeoutToExpectAResponse + 10);
255
+ await emitter.onReturnableEvent(obs, thisCaller, thisEvent, async () => { });
256
+ try {
257
+ await emitter.emitEventAndReturn(obs, thisCaller, thisEvent, maxTimeoutToExpectAResponse / 1000, [typeToTest.data]);
258
+ clearTimeout(emitTimeout);
259
+ assert.fail("EEAR Returned");
260
+ }
261
+ catch {
262
+ clearTimeout(emitTimeout);
263
+ assert.ok("Timeout of EEAR");
264
+ }
265
+ });
266
+ it("should timeout correctly - no receipt", async () => {
267
+ const thisCaller = randomName();
268
+ const thisEvent = randomName();
269
+ const obs = createTestObservable();
270
+ const emitTimeout = setTimeout(() => {
271
+ assert.fail("Event not received");
272
+ }, timermaxTimeoutToExpectAResponse + 10);
273
+ try {
274
+ await emitter.emitEventAndReturn(obs, thisCaller, thisEvent, maxTimeoutToExpectAResponse / 1000, [typeToTest.data]);
275
+ clearTimeout(emitTimeout);
276
+ assert.fail("EEAR Returned");
277
+ }
278
+ catch {
279
+ clearTimeout(emitTimeout);
280
+ assert.ok("Timeout of EEAR");
281
+ }
282
+ });
283
+ it("should response error correctly", async () => {
284
+ const thisCaller = randomName();
285
+ const thisEvent = randomName();
286
+ const obs = createTestObservable();
287
+ const emitTimeout = setTimeout(() => {
288
+ assert.fail("Event not received");
289
+ }, timermaxTimeoutToExpectAResponse);
290
+ await emitter.onReturnableEvent(obs, thisCaller, thisEvent, async () => {
291
+ throw typeToTest.rData || typeToTest.data;
292
+ });
293
+ try {
294
+ await emitter.emitEventAndReturn(obs, thisCaller, thisEvent, maxTimeoutToExpectAResponse / 1000, [typeToTest.data]);
295
+ clearTimeout(emitTimeout);
296
+ assert.fail("EEAR Returned");
297
+ }
298
+ catch (exc) {
299
+ clearTimeout(emitTimeout);
300
+ assert.ok("EEAR");
301
+ assert.strictEqual(JSON.stringify(exc), JSON.stringify(typeToTest.rData || typeToTest.data));
302
+ }
303
+ });
304
+ });
305
+ }
306
+ });
307
+ }
@@ -0,0 +1,4 @@
1
+ import { BSBEvents } from "@bsb/base";
2
+ export declare function emitStreamAndReceiveStream(genNewPlugin: {
3
+ (): Promise<BSBEvents>;
4
+ }, maxTimeoutToExpectAResponse: number): void;
@@ -0,0 +1,199 @@
1
+ import * as fs from "fs";
2
+ import * as crypto from "crypto";
3
+ import { pipeline } from "stream";
4
+ import * as assert from "assert";
5
+ import { SmartFunctionCallSync } from "@bsb/base";
6
+ import { createTestObservable } from "../../../trace.js";
7
+ const randomName = () => crypto.randomUUID();
8
+ const mockBareFakeStream = () => {
9
+ const obj = {
10
+ listeners: {},
11
+ emit: (name, data) => {
12
+ if (obj.listeners[name] !== undefined) {
13
+ obj.listeners[name](data);
14
+ }
15
+ },
16
+ on: (name, listn) => {
17
+ obj.listeners[name] = listn;
18
+ },
19
+ destroy: () => { },
20
+ };
21
+ return obj;
22
+ };
23
+ const getFileHash = (filename) => new Promise((resolve, reject) => {
24
+ const fd = fs.createReadStream(filename);
25
+ const hash = crypto.createHash("sha1");
26
+ hash.setEncoding("hex");
27
+ fd.on("error", reject);
28
+ fd.on("end", () => {
29
+ hash.end();
30
+ resolve(hash.read());
31
+ });
32
+ fd.pipe(hash);
33
+ });
34
+ const createTestFile = (filePath, sizeStr) => {
35
+ return new Promise((resolve, reject) => {
36
+ const match = sizeStr.match(/^(\d+)(KB|MB)$/);
37
+ if (!match) {
38
+ return reject(new Error(`Invalid size format: ${sizeStr}`));
39
+ }
40
+ const num = parseInt(match[1], 10);
41
+ const unit = match[2];
42
+ const sizeBytes = unit === "KB" ? num * 1024 : num * 1024 * 1024;
43
+ const writeStream = fs.createWriteStream(filePath);
44
+ const chunkSize = 64 * 1024;
45
+ let written = 0;
46
+ const writeChunk = () => {
47
+ while (written < sizeBytes) {
48
+ const remaining = sizeBytes - written;
49
+ const size = Math.min(chunkSize, remaining);
50
+ const buffer = crypto.randomBytes(size);
51
+ const canContinue = writeStream.write(buffer);
52
+ written += size;
53
+ if (!canContinue) {
54
+ writeStream.once("drain", writeChunk);
55
+ return;
56
+ }
57
+ }
58
+ writeStream.end();
59
+ };
60
+ writeStream.on("finish", () => resolve());
61
+ writeStream.on("error", reject);
62
+ writeChunk();
63
+ });
64
+ };
65
+ export function emitStreamAndReceiveStream(genNewPlugin, maxTimeoutToExpectAResponse) {
66
+ let emitter;
67
+ beforeEach(async () => {
68
+ emitter = await genNewPlugin();
69
+ });
70
+ afterEach(function () {
71
+ SmartFunctionCallSync(emitter, emitter.dispose);
72
+ });
73
+ describe("EmitStreamAndReceiveStream", async () => {
74
+ const timermaxTimeoutToExpectAResponse = maxTimeoutToExpectAResponse + 10;
75
+ it("receiveStream creates a should generate a valid string", async () => {
76
+ const thisCaller = randomName();
77
+ const thisCallerEvent = randomName();
78
+ const obs = createTestObservable();
79
+ const uuid = await emitter.receiveStream(obs, thisCaller, thisCallerEvent, async (receivedObs, error, stream) => { }, maxTimeoutToExpectAResponse);
80
+ assert.ok(`${uuid}`.length >= 10, "Not a valid unique ID for stream");
81
+ });
82
+ it("sendStream triggers timeout when no receiveStream setup", async () => {
83
+ const thisCaller = randomName();
84
+ const thisEvent = randomName();
85
+ const streamId = `${randomName()}=1`;
86
+ const obs = createTestObservable();
87
+ try {
88
+ await emitter.sendStream(obs, thisCaller, thisEvent, streamId, mockBareFakeStream());
89
+ assert.fail("Timeout not called");
90
+ }
91
+ catch {
92
+ assert.ok(true, "Timeout called exception");
93
+ }
94
+ });
95
+ it("sendStream triggers receiveStream listener", async () => {
96
+ const thisCaller = randomName();
97
+ const thisCallerEvent = randomName();
98
+ const obs = createTestObservable();
99
+ const emitTimeout = setTimeout(() => {
100
+ assert.fail("Event not received");
101
+ }, timermaxTimeoutToExpectAResponse);
102
+ const uuid = await emitter.receiveStream(obs, thisCaller, thisCallerEvent, async (receivedObs, error, stream) => {
103
+ clearTimeout(emitTimeout);
104
+ stream.emit("end");
105
+ assert.ok(true, "Listener called");
106
+ }, maxTimeoutToExpectAResponse);
107
+ try {
108
+ await emitter.sendStream(obs, thisCaller, thisCallerEvent, uuid, mockBareFakeStream());
109
+ }
110
+ catch { }
111
+ });
112
+ describe("sendStream triggers receiveStream listener passing in the stream", async () => {
113
+ it("should not call the listener with an error", async () => {
114
+ const thisCaller = randomName();
115
+ const thisCallerEvent = randomName();
116
+ const obs = createTestObservable();
117
+ const emitTimeout = setTimeout(() => {
118
+ assert.fail("Event not received");
119
+ }, timermaxTimeoutToExpectAResponse);
120
+ const uuid = await emitter.receiveStream(obs, thisCaller, thisCallerEvent, async (receivedObs, error, stream) => {
121
+ clearTimeout(emitTimeout);
122
+ stream.emit("end");
123
+ assert.strictEqual(error, null, "Error is not null");
124
+ }, maxTimeoutToExpectAResponse);
125
+ try {
126
+ await emitter.sendStream(obs, thisCaller, thisCallerEvent, uuid, mockBareFakeStream());
127
+ }
128
+ catch { }
129
+ });
130
+ it("should call the listener with a stream", async () => {
131
+ const thisCaller = randomName();
132
+ const thisCallerEvent = randomName();
133
+ const obs = createTestObservable();
134
+ const emitTimeout = setTimeout(() => {
135
+ assert.fail("Event not received");
136
+ }, timermaxTimeoutToExpectAResponse);
137
+ const uuid = await emitter.receiveStream(obs, thisCaller, thisCallerEvent, async (receivedObs, error, stream) => {
138
+ clearTimeout(emitTimeout);
139
+ stream.emit("end");
140
+ assert.strictEqual(typeof stream, typeof mockBareFakeStream(), "Listener called");
141
+ }, maxTimeoutToExpectAResponse);
142
+ try {
143
+ await emitter.sendStream(obs, thisCaller, thisCallerEvent, uuid, mockBareFakeStream());
144
+ }
145
+ catch { }
146
+ });
147
+ });
148
+ describe("sendStream triggers receiveStream files", function () {
149
+ this.timeout(120000);
150
+ const runTest = async (size, count = 1) => {
151
+ it(`should be able to fully stream a file - ${size}`, async function () {
152
+ this.timeout(120000);
153
+ const thisCaller = randomName();
154
+ const thisCallerEvent = randomName();
155
+ const obs = createTestObservable();
156
+ const fileName = `./test-file-${size}`;
157
+ const fileNameOut = fileName + "-out";
158
+ try {
159
+ await createTestFile(fileName, size);
160
+ const srcFileHash = await getFileHash(fileName);
161
+ const emitTimeout = setTimeout(() => {
162
+ assert.fail("Event not received");
163
+ }, timermaxTimeoutToExpectAResponse);
164
+ const uuid = await emitter.receiveStream(obs, thisCaller, thisCallerEvent, async (receivedObs, error, stream) => {
165
+ if (error) {
166
+ return assert.fail(error);
167
+ }
168
+ clearTimeout(emitTimeout);
169
+ pipeline(stream, fs.createWriteStream(fileNameOut), (errf) => {
170
+ if (errf) {
171
+ assert.fail(errf);
172
+ }
173
+ });
174
+ }, maxTimeoutToExpectAResponse);
175
+ await emitter.sendStream(obs, thisCaller, thisCallerEvent, uuid, fs.createReadStream(fileName));
176
+ fs.unlinkSync(fileName);
177
+ assert.strictEqual(await getFileHash(fileNameOut), srcFileHash, "Validate data equals");
178
+ fs.unlinkSync(fileNameOut);
179
+ }
180
+ catch (xx) {
181
+ if (fs.existsSync(fileName)) {
182
+ fs.unlinkSync(fileName);
183
+ }
184
+ if (fs.existsSync(fileNameOut)) {
185
+ fs.unlinkSync(fileNameOut);
186
+ }
187
+ assert.fail(xx.toString());
188
+ }
189
+ });
190
+ };
191
+ runTest("1KB");
192
+ runTest("16KB");
193
+ runTest("128KB");
194
+ runTest("512KB");
195
+ runTest("1MB");
196
+ runTest("16MB");
197
+ });
198
+ });
199
+ }
@@ -0,0 +1,2 @@
1
+ import { BSBEventsRef } from "@bsb/base";
2
+ export declare const RunEventsPluginTests: (eventsPlugin: typeof BSBEventsRef, config?: any) => void;
@@ -0,0 +1,47 @@
1
+ import { Plugin } from "../../../plugins/events-rabbitmq/index.js";
2
+ import { broadcast } from "./events/broadcast.js";
3
+ import { emit } from "./events/emit.js";
4
+ import { emitAndReturn } from "./events/emitAndReturn.js";
5
+ import { emitStreamAndReceiveStream } from "./events/emitStreamAndReceiveStream.js";
6
+ import { getEventsConstructorConfig } from "../../mocks.js";
7
+ import { createTestObservable } from "../../trace.js";
8
+ export const RunEventsPluginTests = (eventsPlugin, config = undefined) => {
9
+ broadcast(async () => {
10
+ const refP = new eventsPlugin(getEventsConstructorConfig(config));
11
+ if (refP.init !== undefined) {
12
+ await refP.init(createTestObservable());
13
+ }
14
+ return refP;
15
+ }, 30);
16
+ emit(async () => {
17
+ const refP = new eventsPlugin(getEventsConstructorConfig(config));
18
+ if (refP.init !== undefined) {
19
+ await refP.init(createTestObservable());
20
+ }
21
+ return refP;
22
+ }, 30);
23
+ emitAndReturn(async () => {
24
+ const refP = new eventsPlugin(getEventsConstructorConfig(config));
25
+ if (refP.init !== undefined) {
26
+ await refP.init(createTestObservable());
27
+ }
28
+ return refP;
29
+ }, 30);
30
+ emitStreamAndReceiveStream(async () => {
31
+ const refP = new eventsPlugin(getEventsConstructorConfig(config));
32
+ if (refP.init !== undefined) {
33
+ await refP.init(createTestObservable());
34
+ }
35
+ return refP;
36
+ }, 500);
37
+ };
38
+ describe("plugins/events-rabbitmq", () => RunEventsPluginTests(Plugin, {
39
+ platformKey: null,
40
+ fatalOnDisconnect: false,
41
+ prefetch: 10,
42
+ endpoints: ["amqp://127.0.0.1:5670"],
43
+ credentials: {
44
+ username: "guest",
45
+ password: "guest",
46
+ },
47
+ }));
@@ -0,0 +1,4 @@
1
+ import { DTrace } from "@bsb/base";
2
+ import { Observable } from "@bsb/base";
3
+ export declare function createFakeDTrace(trace?: string, span?: string): DTrace;
4
+ export declare function createTestObservable(trace?: string, span?: string, pluginName?: string): Observable;
@@ -0,0 +1,39 @@
1
+ import { PluginObservable } from "@bsb/base";
2
+ export function createFakeDTrace(trace, span) {
3
+ return {
4
+ t: trace ?? "",
5
+ s: span ?? "",
6
+ };
7
+ }
8
+ export function createTestObservable(trace, span, pluginName = "test-plugin") {
9
+ const dTrace = createFakeDTrace(trace ?? "test-trace", span ?? "test-span");
10
+ const resource = {
11
+ "service.name": pluginName,
12
+ "service.version": "1.0.0-test",
13
+ "service.instance.id": "test-instance",
14
+ "deployment.environment": "test",
15
+ };
16
+ const backend = {
17
+ debug: () => { },
18
+ info: () => { },
19
+ warn: () => { },
20
+ error: () => { },
21
+ createCounter: () => ({ increment: () => { } }),
22
+ createGauge: () => ({ set: () => { }, increment: () => { }, decrement: () => { } }),
23
+ createHistogram: () => ({ record: () => { } }),
24
+ createTimer: () => ({ stop: () => 0 }),
25
+ createTrace: () => ({
26
+ id: "test-trace-id",
27
+ trace: createFakeDTrace("test-trace", "test-span"),
28
+ error: () => { },
29
+ end: () => { },
30
+ }),
31
+ createSpan: (parentTrace, name) => ({
32
+ id: "child-span-" + name,
33
+ trace: createFakeDTrace(parentTrace.t, "child-span-" + name),
34
+ error: () => { },
35
+ end: () => { },
36
+ }),
37
+ };
38
+ return new PluginObservable(dTrace, resource, backend, {});
39
+ }
package/package.json ADDED
@@ -0,0 +1,70 @@
1
+ {
2
+ "name": "@bsb/events-rabbitmq",
3
+ "version": "0.0.1",
4
+ "type": "module",
5
+ "license": "(AGPL-3.0-only OR Commercial)",
6
+ "author": {
7
+ "name": "BetterCorp (PTY) Ltd",
8
+ "email": "ninja@bettercorp.dev",
9
+ "url": "https://bettercorp.dev/"
10
+ },
11
+ "description": "RabbitMQ events plugin for BSB - distributed event bus using RabbitMQ",
12
+ "keywords": [
13
+ "bsb",
14
+ "events",
15
+ "rabbitmq",
16
+ "amqp",
17
+ "event-bus",
18
+ "distributed"
19
+ ],
20
+ "repository": {
21
+ "type": "git",
22
+ "url": "https://github.com/BetterCorp/better-service-base",
23
+ "directory": "plugins/nodejs/events-rabbitmq"
24
+ },
25
+ "main": "lib/plugins/events-rabbitmq/index.js",
26
+ "types": "lib/plugins/events-rabbitmq/index.d.ts",
27
+ "files": [
28
+ "lib/**/*",
29
+ "README.md",
30
+ "LICENSE"
31
+ ],
32
+ "scripts": {
33
+ "clean": "bsb-plugin-cli clean",
34
+ "build": "bsb-plugin-cli build",
35
+ "start": "bsb-plugin-cli start",
36
+ "dev": "bsb-plugin-cli dev",
37
+ "test": "bsb-plugin-cli test",
38
+ "publish:client": "bsb client publish",
39
+ "lint": "eslint src/ --ext .js,.jsx,.ts,.tsx",
40
+ "prepublishOnly": "npm run build",
41
+ "test:run": "cross-env TS_NODE_PROJECT=tsconfig.test.json NODE_OPTIONS= mocha --reporter json --reporter-options output=junit.json",
42
+ "testDev": "cross-env TS_NODE_PROJECT=tsconfig.test.json NODE_OPTIONS= mocha"
43
+ },
44
+ "peerDependencies": {
45
+ "@bsb/base": "^9.1.11"
46
+ },
47
+ "dependencies": {
48
+ "amqp-connection-manager": "^5.0.0",
49
+ "amqplib": "^2.0.1",
50
+ "anyvali": "^1.0.6"
51
+ },
52
+ "devDependencies": {
53
+ "@bsb/base": "^9.1.11",
54
+ "@types/amqplib": "^0.10.4",
55
+ "@types/mocha": "^10.0.6",
56
+ "@types/node": "^25.6.0",
57
+ "@typescript-eslint/eslint-plugin": "^8.54.0",
58
+ "@typescript-eslint/parser": "^8.54.0",
59
+ "cross-env": "^10.1.0",
60
+ "eslint": "^9.39.2",
61
+ "mocha": "^11.7.6",
62
+ "rimraf": "^6.1.2",
63
+ "typescript": "^6.0.3"
64
+ },
65
+ "engines": {
66
+ "node": ">=24.0.0",
67
+ "npm": ">=11.0.0"
68
+ },
69
+ "homepage": "https://io.bsbcode.dev/packages/nodejs/@bsb/events-rabbitmq"
70
+ }