@autonomaai/event-bus 1.0.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/RedisEventBus.d.ts +11 -0
- package/dist/RedisEventBus.d.ts.map +1 -0
- package/dist/RedisEventBus.js +92 -0
- package/dist/RedisEventBus.js.map +1 -0
- package/dist/index.d.ts +3 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +19 -0
- package/dist/index.js.map +1 -0
- package/dist/types.d.ts +15 -0
- package/dist/types.d.ts.map +1 -0
- package/dist/types.js +3 -0
- package/dist/types.js.map +1 -0
- package/package.json +41 -0
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import { DomainEvent, DomainEventName, EventBus } from './types';
|
|
2
|
+
export declare class RedisEventBus implements EventBus {
|
|
3
|
+
private publisher;
|
|
4
|
+
private subscribers;
|
|
5
|
+
private isClosing;
|
|
6
|
+
constructor(redisUrl: string);
|
|
7
|
+
publish<E extends DomainEvent>(topic: DomainEventName, event: E): Promise<void>;
|
|
8
|
+
subscribe<E extends DomainEvent>(topic: DomainEventName, group: string, consumer: string, handler: (event: E) => Promise<void>): Promise<() => Promise<void>>;
|
|
9
|
+
close(): Promise<void>;
|
|
10
|
+
}
|
|
11
|
+
//# sourceMappingURL=RedisEventBus.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"RedisEventBus.d.ts","sourceRoot":"","sources":["../src/RedisEventBus.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,WAAW,EAAE,eAAe,EAAE,QAAQ,EAAE,MAAM,SAAS,CAAC;AAEjE,qBAAa,aAAc,YAAW,QAAQ;IAC5C,OAAO,CAAC,SAAS,CAAQ;IACzB,OAAO,CAAC,WAAW,CAAiC;IACpD,OAAO,CAAC,SAAS,CAAS;gBAEd,QAAQ,EAAE,MAAM;IAItB,OAAO,CAAC,CAAC,SAAS,WAAW,EAAE,KAAK,EAAE,eAAe,EAAE,KAAK,EAAE,CAAC,GAAG,OAAO,CAAC,IAAI,CAAC;IAK/E,SAAS,CAAC,CAAC,SAAS,WAAW,EACnC,KAAK,EAAE,eAAe,EACtB,KAAK,EAAE,MAAM,EACb,QAAQ,EAAE,MAAM,EAChB,OAAO,EAAE,CAAC,KAAK,EAAE,CAAC,KAAK,OAAO,CAAC,IAAI,CAAC,GACnC,OAAO,CAAC,MAAM,OAAO,CAAC,IAAI,CAAC,CAAC;IA2EzB,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC;CAQ7B"}
|
|
@@ -0,0 +1,92 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
+
};
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
exports.RedisEventBus = void 0;
|
|
7
|
+
const ioredis_1 = __importDefault(require("ioredis"));
|
|
8
|
+
class RedisEventBus {
|
|
9
|
+
publisher;
|
|
10
|
+
subscribers = new Map();
|
|
11
|
+
isClosing = false;
|
|
12
|
+
constructor(redisUrl) {
|
|
13
|
+
this.publisher = new ioredis_1.default(redisUrl);
|
|
14
|
+
}
|
|
15
|
+
async publish(topic, event) {
|
|
16
|
+
const message = JSON.stringify(event);
|
|
17
|
+
await this.publisher.xadd(topic, '*', 'event', message);
|
|
18
|
+
}
|
|
19
|
+
async subscribe(topic, group, consumer, handler) {
|
|
20
|
+
// Create a dedicated connection for this subscription to avoid blocking
|
|
21
|
+
// In a real app, we might pool these or use a single connection with a loop,
|
|
22
|
+
// but for simplicity and robustness in Stage 1, we'll use a loop on a dedicated connection per consumer type if needed,
|
|
23
|
+
// or just reuse a connection if we are careful.
|
|
24
|
+
// Actually, for XREADGROUP, we can share a connection if we are careful, but blocking calls (BLOCK) block the connection.
|
|
25
|
+
// So we need a dedicated connection for the blocking loop.
|
|
26
|
+
const redis = this.publisher.duplicate();
|
|
27
|
+
this.subscribers.set(`${topic}-${group}-${consumer}`, redis);
|
|
28
|
+
// Ensure group exists
|
|
29
|
+
try {
|
|
30
|
+
await redis.xgroup('CREATE', topic, group, '$', 'MKSTREAM');
|
|
31
|
+
}
|
|
32
|
+
catch (err) {
|
|
33
|
+
if (!err.message.includes('BUSYGROUP')) {
|
|
34
|
+
throw err;
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
let isRunning = true;
|
|
38
|
+
const loop = async () => {
|
|
39
|
+
while (isRunning && !this.isClosing) {
|
|
40
|
+
try {
|
|
41
|
+
// Read new messages
|
|
42
|
+
const results = await redis.xreadgroup('GROUP', group, consumer, 'BLOCK', 2000, // 2 seconds block
|
|
43
|
+
'STREAMS', topic, '>');
|
|
44
|
+
if (results) {
|
|
45
|
+
for (const [_stream, messages] of results) {
|
|
46
|
+
for (const [id, fields] of messages) {
|
|
47
|
+
// fields is ['event', '{"json":...}']
|
|
48
|
+
const eventData = fields[1];
|
|
49
|
+
if (eventData) {
|
|
50
|
+
try {
|
|
51
|
+
const event = JSON.parse(eventData);
|
|
52
|
+
await handler(event);
|
|
53
|
+
await redis.xack(topic, group, id);
|
|
54
|
+
}
|
|
55
|
+
catch (error) {
|
|
56
|
+
console.error(`Error processing event ${id} from ${topic}:`, error);
|
|
57
|
+
// In a real system, we might move to a DLQ here
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
catch (error) {
|
|
65
|
+
if (this.isClosing)
|
|
66
|
+
break;
|
|
67
|
+
console.error(`Error in subscription loop for ${topic}:`, error);
|
|
68
|
+
// Wait a bit before retrying to avoid tight loops on error
|
|
69
|
+
await new Promise((resolve) => setTimeout(resolve, 1000));
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
};
|
|
73
|
+
// Start the loop
|
|
74
|
+
loop();
|
|
75
|
+
// Return unsubscribe function
|
|
76
|
+
return async () => {
|
|
77
|
+
isRunning = false;
|
|
78
|
+
this.subscribers.delete(`${topic}-${group}-${consumer}`);
|
|
79
|
+
await redis.quit();
|
|
80
|
+
};
|
|
81
|
+
}
|
|
82
|
+
async close() {
|
|
83
|
+
this.isClosing = true;
|
|
84
|
+
await this.publisher.quit();
|
|
85
|
+
for (const redis of this.subscribers.values()) {
|
|
86
|
+
await redis.quit();
|
|
87
|
+
}
|
|
88
|
+
this.subscribers.clear();
|
|
89
|
+
}
|
|
90
|
+
}
|
|
91
|
+
exports.RedisEventBus = RedisEventBus;
|
|
92
|
+
//# sourceMappingURL=RedisEventBus.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"RedisEventBus.js","sourceRoot":"","sources":["../src/RedisEventBus.ts"],"names":[],"mappings":"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"}
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,cAAc,SAAS,CAAC;AACxB,cAAc,iBAAiB,CAAC"}
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,19 @@
|
|
|
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("./types"), exports);
|
|
18
|
+
__exportStar(require("./RedisEventBus"), exports);
|
|
19
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;AAAA,0CAAwB;AACxB,kDAAgC"}
|
package/dist/types.d.ts
ADDED
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
export type DomainEventName = 'trade.executed' | 'strategy.updated' | 'risk.alert' | 'portfolio.snapshot.created' | 'market.tick' | 'signal.created' | 'agent.message.created';
|
|
2
|
+
export interface DomainEvent<TPayload = any> {
|
|
3
|
+
id: string;
|
|
4
|
+
name: DomainEventName;
|
|
5
|
+
version: number;
|
|
6
|
+
timestamp: string;
|
|
7
|
+
source: string;
|
|
8
|
+
payload: TPayload;
|
|
9
|
+
}
|
|
10
|
+
export interface EventBus {
|
|
11
|
+
publish<E extends DomainEvent>(topic: DomainEventName, event: E): Promise<void>;
|
|
12
|
+
subscribe<E extends DomainEvent>(topic: DomainEventName, group: string, consumer: string, handler: (event: E) => Promise<void>): Promise<() => Promise<void>>;
|
|
13
|
+
close(): Promise<void>;
|
|
14
|
+
}
|
|
15
|
+
//# sourceMappingURL=types.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAAA,MAAM,MAAM,eAAe,GACvB,gBAAgB,GAChB,kBAAkB,GAClB,YAAY,GACZ,4BAA4B,GAC5B,aAAa,GACb,gBAAgB,GAChB,uBAAuB,CAAC;AAE5B,MAAM,WAAW,WAAW,CAAC,QAAQ,GAAG,GAAG;IACzC,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,EAAE,eAAe,CAAC;IACtB,OAAO,EAAE,MAAM,CAAC;IAChB,SAAS,EAAE,MAAM,CAAC;IAClB,MAAM,EAAE,MAAM,CAAC;IACf,OAAO,EAAE,QAAQ,CAAC;CACnB;AAED,MAAM,WAAW,QAAQ;IACvB,OAAO,CAAC,CAAC,SAAS,WAAW,EAC3B,KAAK,EAAE,eAAe,EACtB,KAAK,EAAE,CAAC,GACP,OAAO,CAAC,IAAI,CAAC,CAAC;IAEjB,SAAS,CAAC,CAAC,SAAS,WAAW,EAC7B,KAAK,EAAE,eAAe,EACtB,KAAK,EAAE,MAAM,EACb,QAAQ,EAAE,MAAM,EAChB,OAAO,EAAE,CAAC,KAAK,EAAE,CAAC,KAAK,OAAO,CAAC,IAAI,CAAC,GACnC,OAAO,CAAC,MAAM,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC;IAEhC,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC;CACxB"}
|
package/dist/types.js
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.js","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":""}
|
package/package.json
ADDED
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@autonomaai/event-bus",
|
|
3
|
+
"version": "1.0.0",
|
|
4
|
+
"description": "Shared event bus abstraction and implementations for autonoma microservices",
|
|
5
|
+
"main": "dist/index.js",
|
|
6
|
+
"types": "dist/index.d.ts",
|
|
7
|
+
"scripts": {
|
|
8
|
+
"build": "tsc",
|
|
9
|
+
"dev": "tsc --watch",
|
|
10
|
+
"test": "jest",
|
|
11
|
+
"lint": "eslint src/**/*.ts"
|
|
12
|
+
},
|
|
13
|
+
"keywords": [
|
|
14
|
+
"event-bus",
|
|
15
|
+
"redis",
|
|
16
|
+
"microservices",
|
|
17
|
+
"messaging"
|
|
18
|
+
],
|
|
19
|
+
"author": "autonoma Team",
|
|
20
|
+
"license": "MIT",
|
|
21
|
+
"files": [
|
|
22
|
+
"dist/**/*",
|
|
23
|
+
"README.md"
|
|
24
|
+
],
|
|
25
|
+
"repository": {
|
|
26
|
+
"type": "git",
|
|
27
|
+
"url": "https://github.com/Stack3Labs/autonoma-typescript-packages"
|
|
28
|
+
},
|
|
29
|
+
"publishConfig": {
|
|
30
|
+
"access": "public"
|
|
31
|
+
},
|
|
32
|
+
"dependencies": {
|
|
33
|
+
"ioredis": "^5.3.2",
|
|
34
|
+
"uuid": "^9.0.1"
|
|
35
|
+
},
|
|
36
|
+
"devDependencies": {
|
|
37
|
+
"@types/node": "^20.11.0",
|
|
38
|
+
"@types/uuid": "^9.0.8",
|
|
39
|
+
"typescript": "^5.3.3"
|
|
40
|
+
}
|
|
41
|
+
}
|