@arvo-tools/postgres 1.1.0 → 1.2.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/broker/index.d.ts +287 -0
- package/dist/broker/index.d.ts.map +1 -0
- package/dist/broker/index.js +629 -0
- package/dist/broker/index.js.map +1 -0
- package/dist/broker/types.d.ts +96 -0
- package/dist/broker/types.d.ts.map +1 -0
- package/dist/broker/types.js +3 -0
- package/dist/broker/types.js.map +1 -0
- package/dist/broker/utils.d.ts +11 -0
- package/dist/broker/utils.d.ts.map +1 -0
- package/dist/broker/utils.js +78 -0
- package/dist/broker/utils.js.map +1 -0
- package/dist/index.d.ts +2 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +3 -1
- package/dist/index.js.map +1 -1
- package/dist/memory/v1/schema.d.ts +8 -8
- package/package.json +3 -2
|
@@ -0,0 +1,287 @@
|
|
|
1
|
+
import { type ArvoEvent } from 'arvo-core';
|
|
2
|
+
import type { IArvoEventHandler } from 'arvo-event-handler';
|
|
3
|
+
import { PgBoss, type Queue } from 'pg-boss';
|
|
4
|
+
import type { HandlerRegistrationOptions, ILogger } from './types';
|
|
5
|
+
type PromiseLike<T> = Promise<T> | T;
|
|
6
|
+
/**
|
|
7
|
+
* Queue-based event broker for ArvoEvent handlers with automatic routing,
|
|
8
|
+
* retry logic, and OpenTelemetry tracing support.
|
|
9
|
+
*
|
|
10
|
+
* PostgresEventBroker extends PgBoss to provide event-driven workflow management
|
|
11
|
+
* through persistent PostgreSQL-backed queues. It automatically routes events between
|
|
12
|
+
* registered handlers, ensures reliable delivery with configurable retry policies,
|
|
13
|
+
* and maintains distributed tracing context across the entire workflow.
|
|
14
|
+
*
|
|
15
|
+
* Key capabilities include handler registration with dedicated queues, automatic
|
|
16
|
+
* event routing based on the 'to' field, workflow completion handling, support for
|
|
17
|
+
* domained events, and comprehensive queue statistics for monitoring.
|
|
18
|
+
*
|
|
19
|
+
* @example
|
|
20
|
+
* ```typescript
|
|
21
|
+
* const broker = new PostgresEventBroker({ connectionString: 'postgres://...' });
|
|
22
|
+
* await broker.start();
|
|
23
|
+
*
|
|
24
|
+
* // Register handlers with retry configuration
|
|
25
|
+
* await broker.register(calculatorHandler, {
|
|
26
|
+
* recreateQueue: true,
|
|
27
|
+
* worker: {
|
|
28
|
+
* concurrency: 5,
|
|
29
|
+
* retryLimit: 3,
|
|
30
|
+
* retryBackoff: true
|
|
31
|
+
* }
|
|
32
|
+
* });
|
|
33
|
+
*
|
|
34
|
+
* // Set up workflow completion handler
|
|
35
|
+
* await broker.onWorkflowComplete({
|
|
36
|
+
* source: 'my.workflow',
|
|
37
|
+
* listener: async (event) => {
|
|
38
|
+
* this.logger.log('Workflow completed:', event.data);
|
|
39
|
+
* }
|
|
40
|
+
* });
|
|
41
|
+
*
|
|
42
|
+
* // Handle domained events (e.g., human approval requests)
|
|
43
|
+
* broker.onDomainedEvent(async (event) => {
|
|
44
|
+
* if (event.domain === 'human.interaction') {
|
|
45
|
+
* await handleHumanApproval(event);
|
|
46
|
+
* }
|
|
47
|
+
* });
|
|
48
|
+
*
|
|
49
|
+
* // Dispatch events using ArvoEventFactory
|
|
50
|
+
* const event = createArvoEventFactory(contract.version('1.0.0')).accepts({
|
|
51
|
+
* source: 'my.workflow',
|
|
52
|
+
* data: { numbers: [1, 2, 3] }
|
|
53
|
+
* });
|
|
54
|
+
* await broker.dispatch(event);
|
|
55
|
+
*
|
|
56
|
+
* // Monitor queue health
|
|
57
|
+
* const stats = await broker.getStats();
|
|
58
|
+
* ```
|
|
59
|
+
*/
|
|
60
|
+
export declare class PostgresEventBroker extends PgBoss {
|
|
61
|
+
/**
|
|
62
|
+
* Internal registry of handler configurations keyed by handler source.
|
|
63
|
+
*/
|
|
64
|
+
private handlers;
|
|
65
|
+
/**
|
|
66
|
+
* Internal list of all registered queue names.
|
|
67
|
+
*/
|
|
68
|
+
private _queues;
|
|
69
|
+
/**
|
|
70
|
+
* List of all registered queue names in the broker.
|
|
71
|
+
*/
|
|
72
|
+
get queues(): string[];
|
|
73
|
+
/**
|
|
74
|
+
* Logger instance used for all broker operational logging.
|
|
75
|
+
* Defaults to console but can be replaced via setLogger().
|
|
76
|
+
*/
|
|
77
|
+
private logger;
|
|
78
|
+
/**
|
|
79
|
+
* Sets a custom logger for broker operations.
|
|
80
|
+
*
|
|
81
|
+
* Allows integration with existing logging infrastructure (Winston, Pino, etc.)
|
|
82
|
+
* by providing a logger that implements the ILogger interface.
|
|
83
|
+
*
|
|
84
|
+
* @param logger - Logger instance implementing ILogger interface
|
|
85
|
+
*
|
|
86
|
+
* @example
|
|
87
|
+
* ```typescript
|
|
88
|
+
* import winston from 'winston';
|
|
89
|
+
*
|
|
90
|
+
* const logger = winston.createLogger({
|
|
91
|
+
* level: 'info',
|
|
92
|
+
* format: winston.format.json(),
|
|
93
|
+
* transports: [new winston.transports.Console()]
|
|
94
|
+
* });
|
|
95
|
+
*
|
|
96
|
+
* broker.setLogger(logger);
|
|
97
|
+
* ```
|
|
98
|
+
*/
|
|
99
|
+
setLogger(logger: ILogger): void;
|
|
100
|
+
/**
|
|
101
|
+
* The configured event source for workflow completion.
|
|
102
|
+
*/
|
|
103
|
+
private injectionEventSource;
|
|
104
|
+
/**
|
|
105
|
+
* Default callback invoked when an event has no registered destination handler.
|
|
106
|
+
*/
|
|
107
|
+
private _onHandlerNotFound;
|
|
108
|
+
/**
|
|
109
|
+
* Callback invoked when a domained event is encountered during routing.
|
|
110
|
+
*/
|
|
111
|
+
private _onDomainedEvent;
|
|
112
|
+
/**
|
|
113
|
+
* Registers a handler for workflow completion events.
|
|
114
|
+
*
|
|
115
|
+
* This sets up the terminal point where events return after flowing through
|
|
116
|
+
* the handler chain. The handler receives events whose 'to' field matches
|
|
117
|
+
* the configured source, typically indicating workflow completion.
|
|
118
|
+
*
|
|
119
|
+
* Sets the injection event source that must match the source of events
|
|
120
|
+
* dispatched via the dispatch() method.
|
|
121
|
+
*
|
|
122
|
+
* **Note:** The listener must handle its own errors. Exceptions are caught
|
|
123
|
+
* and logged but do not cause job failures. This is by design.
|
|
124
|
+
*
|
|
125
|
+
* @param param - Configuration object
|
|
126
|
+
* @param param.source - Event source identifier for completion events
|
|
127
|
+
* @param param.listener - Callback invoked when completion events are received
|
|
128
|
+
* @param param.options - Optional queue and worker configuration
|
|
129
|
+
*
|
|
130
|
+
* @example
|
|
131
|
+
* ```typescript
|
|
132
|
+
* await broker.onWorkflowComplete({
|
|
133
|
+
* source: 'test.test.test',
|
|
134
|
+
* listener: async (event) => {
|
|
135
|
+
* try {
|
|
136
|
+
* this.logger.log('Final result:', event.data);
|
|
137
|
+
* } catch (error) {
|
|
138
|
+
* logger.error('Completion handler failed', error);
|
|
139
|
+
* }
|
|
140
|
+
* },
|
|
141
|
+
* });
|
|
142
|
+
* ```
|
|
143
|
+
*/
|
|
144
|
+
onWorkflowComplete(param: {
|
|
145
|
+
source: string;
|
|
146
|
+
listener: (event: ArvoEvent) => PromiseLike<void>;
|
|
147
|
+
options?: HandlerRegistrationOptions;
|
|
148
|
+
}): Promise<void>;
|
|
149
|
+
/**
|
|
150
|
+
* Sets a custom handler for events with no registered destination.
|
|
151
|
+
*
|
|
152
|
+
* When a handler emits an event whose 'to' field doesn't match any
|
|
153
|
+
* registered handler, this callback is invoked. Useful for logging
|
|
154
|
+
* routing errors or implementing fallback behavior.
|
|
155
|
+
*
|
|
156
|
+
* **Note:** The listener must handle its own errors. Exceptions are
|
|
157
|
+
* suppressed by design to prevent routing failures from cascading.
|
|
158
|
+
*
|
|
159
|
+
* @param listner - Callback invoked with unroutable events
|
|
160
|
+
*
|
|
161
|
+
* @example
|
|
162
|
+
* ```typescript
|
|
163
|
+
* broker.onHandlerNotFound(async (event) => {
|
|
164
|
+
* try {
|
|
165
|
+
* logger.error('No handler for', event.to);
|
|
166
|
+
* } catch (error) {
|
|
167
|
+
* this.logger.error('Failed to log missing handler', error);
|
|
168
|
+
* }
|
|
169
|
+
* });
|
|
170
|
+
* ```
|
|
171
|
+
*/
|
|
172
|
+
onHandlerNotFound(listner: (event: ArvoEvent) => PromiseLike<void>): void;
|
|
173
|
+
/**
|
|
174
|
+
* Sets a custom handler for domained events.
|
|
175
|
+
*
|
|
176
|
+
* Domained events are intercepted during routing and passed to this handler
|
|
177
|
+
* instead of being sent to a queue. Useful for handling external system
|
|
178
|
+
* interactions like human approvals or notifications.
|
|
179
|
+
*
|
|
180
|
+
* **Note:** The listener must handle its own errors. Exceptions are
|
|
181
|
+
* suppressed by design to prevent domained event failures from breaking workflows.
|
|
182
|
+
*
|
|
183
|
+
* @param listner - Callback invoked when domained events are encountered
|
|
184
|
+
*
|
|
185
|
+
* @example
|
|
186
|
+
* ```typescript
|
|
187
|
+
* broker.onDomainedEvent(async (event) => {
|
|
188
|
+
* try {
|
|
189
|
+
* if (event.domain === 'notification') {
|
|
190
|
+
* await alerting.notify(event);
|
|
191
|
+
* }
|
|
192
|
+
* } catch (error) {
|
|
193
|
+
* logger.error('Domained event handler failed', error);
|
|
194
|
+
* }
|
|
195
|
+
* });
|
|
196
|
+
* ```
|
|
197
|
+
*/
|
|
198
|
+
onDomainedEvent(listner: (event: ArvoEvent) => PromiseLike<void>): void;
|
|
199
|
+
/**
|
|
200
|
+
* Creates a queue and tracks it in the internal queue registry.
|
|
201
|
+
* Overrides the base class method to maintain queue tracking.
|
|
202
|
+
*
|
|
203
|
+
* @param name - Queue name
|
|
204
|
+
* @param options - Queue configuration options
|
|
205
|
+
*/
|
|
206
|
+
createQueue(name: string, options?: Omit<Queue, 'name'>): Promise<void>;
|
|
207
|
+
/**
|
|
208
|
+
* Registers an event handler with the broker.
|
|
209
|
+
*
|
|
210
|
+
* Creates a dedicated queue for the handler and spawns worker instances
|
|
211
|
+
* to process incoming events. Events emitted by the handler are automatically
|
|
212
|
+
* routed to their destinations based on the 'to' field.
|
|
213
|
+
*
|
|
214
|
+
* @param handler - The ArvoEvent handler to register
|
|
215
|
+
* @param options - Configuration for queue behavior, worker concurrency, and retry policies
|
|
216
|
+
* @throws {Error} If a handler with the same source is already registered
|
|
217
|
+
*
|
|
218
|
+
* @example
|
|
219
|
+
* ```typescript
|
|
220
|
+
* await broker.register(calculatorHandler, {
|
|
221
|
+
* recreateQueue: true,
|
|
222
|
+
* queue: { deadLetter: 'dlq' },
|
|
223
|
+
* worker: {
|
|
224
|
+
* concurrency: 5,
|
|
225
|
+
* onError: async (job, error) => {
|
|
226
|
+
* if (error.message.includes('timeout')) return 'RETRY';
|
|
227
|
+
* return 'FAIL';
|
|
228
|
+
* }
|
|
229
|
+
* }
|
|
230
|
+
* });
|
|
231
|
+
* ```
|
|
232
|
+
*/
|
|
233
|
+
register(handler: IArvoEventHandler, options?: HandlerRegistrationOptions): Promise<void>;
|
|
234
|
+
/**
|
|
235
|
+
* Routes an ArvoEvent to its destination queue.
|
|
236
|
+
*
|
|
237
|
+
* Internal method that filters out worker configuration options and includes
|
|
238
|
+
* only job-level options when sending the event. This method performs no
|
|
239
|
+
* validation and assumes the event and handler have already been verified.
|
|
240
|
+
*
|
|
241
|
+
* @param event - The ArvoEvent to route
|
|
242
|
+
* @returns Job ID if sent successfully, null if handler not found
|
|
243
|
+
*/
|
|
244
|
+
private _emitArvoEvent;
|
|
245
|
+
/**
|
|
246
|
+
* Dispatches an ArvoEvent into the broker system with validation.
|
|
247
|
+
*
|
|
248
|
+
* This is the primary entry point for injecting events into the workflow.
|
|
249
|
+
* The event must originate from the source configured in onWorkflowComplete()
|
|
250
|
+
* and target a registered handler.
|
|
251
|
+
*
|
|
252
|
+
* @param event - The ArvoEvent to dispatch
|
|
253
|
+
* @returns Job ID assigned by the queue system
|
|
254
|
+
* @throws {Error} If workflow completion handler is not configured
|
|
255
|
+
* @throws {Error} If event source doesn't match configured workflow source
|
|
256
|
+
* @throws {Error} If target handler is not registered
|
|
257
|
+
*
|
|
258
|
+
* @example
|
|
259
|
+
* ```typescript
|
|
260
|
+
* const event = createArvoEvent({
|
|
261
|
+
* source: 'my.workflow',
|
|
262
|
+
* to: 'calculator.handler',
|
|
263
|
+
* type: 'calculate.request',
|
|
264
|
+
* data: { operation: 'add', values: [1, 2] }
|
|
265
|
+
* });
|
|
266
|
+
*
|
|
267
|
+
* await broker.dispatch(event);
|
|
268
|
+
* ```
|
|
269
|
+
*/
|
|
270
|
+
dispatch(event: ArvoEvent): Promise<string | null>;
|
|
271
|
+
/**
|
|
272
|
+
* Retrieves statistics for all registered queues in the broker.
|
|
273
|
+
*
|
|
274
|
+
* @returns Array of queue statistics including active, queued, and total job counts
|
|
275
|
+
*
|
|
276
|
+
* @example
|
|
277
|
+
* ```typescript
|
|
278
|
+
* const stats = await broker.getStats();
|
|
279
|
+
* stats.forEach(stat => {
|
|
280
|
+
* this.logger.log(`Queue ${stat.name}: ${stat.activeCount} active, ${stat.queuedCount} queued`);
|
|
281
|
+
* });
|
|
282
|
+
* ```
|
|
283
|
+
*/
|
|
284
|
+
getStats(): Promise<import("pg-boss").QueueResult[]>;
|
|
285
|
+
}
|
|
286
|
+
export {};
|
|
287
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/broker/index.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,KAAK,SAAS,EAAe,MAAM,WAAW,CAAC;AACxD,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,oBAAoB,CAAC;AAC5D,OAAO,EAAE,MAAM,EAAE,KAAK,KAAK,EAAoB,MAAM,SAAS,CAAC;AAC/D,OAAO,KAAK,EAAE,0BAA0B,EAAE,OAAO,EAAE,MAAM,SAAS,CAAC;AAGnE,KAAK,WAAW,CAAC,CAAC,IAAI,OAAO,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC;AAErC;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAqDG;AACH,qBAAa,mBAAoB,SAAQ,MAAM;IAC7C;;OAEG;IACH,OAAO,CAAC,QAAQ,CAKT;IAEP;;OAEG;IACH,OAAO,CAAC,OAAO,CAAgB;IAE/B;;OAEG;IACH,IAAW,MAAM,IAAI,MAAM,EAAE,CAE5B;IAED;;;OAGG;IACH,OAAO,CAAC,MAAM,CAAoB;IAElC;;;;;;;;;;;;;;;;;;;;OAoBG;IACI,SAAS,CAAC,MAAM,EAAE,OAAO;IAIhC;;OAEG;IACH,OAAO,CAAC,oBAAoB,CAAuB;IAEnD;;OAEG;IACH,OAAO,CAAC,kBAAkB,CAC4C;IAEtE;;OAEG;IACH,OAAO,CAAC,gBAAgB,CAC4C;IAEpE;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;OA+BG;IACG,kBAAkB,CAAC,KAAK,EAAE;QAC9B,MAAM,EAAE,MAAM,CAAC;QACf,QAAQ,EAAE,CAAC,KAAK,EAAE,SAAS,KAAK,WAAW,CAAC,IAAI,CAAC,CAAC;QAClD,OAAO,CAAC,EAAE,0BAA0B,CAAC;KACtC;IA+BD;;;;;;;;;;;;;;;;;;;;;;OAsBG;IACH,iBAAiB,CAAC,OAAO,EAAE,CAAC,KAAK,EAAE,SAAS,KAAK,WAAW,CAAC,IAAI,CAAC;IAIlE;;;;;;;;;;;;;;;;;;;;;;;;OAwBG;IACH,eAAe,CAAC,OAAO,EAAE,CAAC,KAAK,EAAE,SAAS,KAAK,WAAW,CAAC,IAAI,CAAC;IAIhE;;;;;;OAMG;IACY,WAAW,CAAC,IAAI,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,IAAI,CAAC,KAAK,EAAE,MAAM,CAAC,GAAG,OAAO,CAAC,IAAI,CAAC;IAKtF;;;;;;;;;;;;;;;;;;;;;;;;;OAyBG;IACG,QAAQ,CAAC,OAAO,EAAE,iBAAiB,EAAE,OAAO,CAAC,EAAE,0BAA0B,GAAG,OAAO,CAAC,IAAI,CAAC;IA6D/F;;;;;;;;;OASG;YACW,cAAc;IAiB5B;;;;;;;;;;;;;;;;;;;;;;;;OAwBG;IACG,QAAQ,CAAC,KAAK,EAAE,SAAS;IAgC/B;;;;;;;;;;;;OAYG;IACG,QAAQ;CAGf"}
|
|
@@ -0,0 +1,629 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __extends = (this && this.__extends) || (function () {
|
|
3
|
+
var extendStatics = function (d, b) {
|
|
4
|
+
extendStatics = Object.setPrototypeOf ||
|
|
5
|
+
({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||
|
|
6
|
+
function (d, b) { for (var p in b) if (Object.prototype.hasOwnProperty.call(b, p)) d[p] = b[p]; };
|
|
7
|
+
return extendStatics(d, b);
|
|
8
|
+
};
|
|
9
|
+
return function (d, b) {
|
|
10
|
+
if (typeof b !== "function" && b !== null)
|
|
11
|
+
throw new TypeError("Class extends value " + String(b) + " is not a constructor or null");
|
|
12
|
+
extendStatics(d, b);
|
|
13
|
+
function __() { this.constructor = d; }
|
|
14
|
+
d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
|
|
15
|
+
};
|
|
16
|
+
})();
|
|
17
|
+
var __assign = (this && this.__assign) || function () {
|
|
18
|
+
__assign = Object.assign || function(t) {
|
|
19
|
+
for (var s, i = 1, n = arguments.length; i < n; i++) {
|
|
20
|
+
s = arguments[i];
|
|
21
|
+
for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p))
|
|
22
|
+
t[p] = s[p];
|
|
23
|
+
}
|
|
24
|
+
return t;
|
|
25
|
+
};
|
|
26
|
+
return __assign.apply(this, arguments);
|
|
27
|
+
};
|
|
28
|
+
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
|
29
|
+
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
|
30
|
+
return new (P || (P = Promise))(function (resolve, reject) {
|
|
31
|
+
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
|
32
|
+
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
|
33
|
+
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
|
|
34
|
+
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
35
|
+
});
|
|
36
|
+
};
|
|
37
|
+
var __generator = (this && this.__generator) || function (thisArg, body) {
|
|
38
|
+
var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g = Object.create((typeof Iterator === "function" ? Iterator : Object).prototype);
|
|
39
|
+
return g.next = verb(0), g["throw"] = verb(1), g["return"] = verb(2), typeof Symbol === "function" && (g[Symbol.iterator] = function() { return this; }), g;
|
|
40
|
+
function verb(n) { return function (v) { return step([n, v]); }; }
|
|
41
|
+
function step(op) {
|
|
42
|
+
if (f) throw new TypeError("Generator is already executing.");
|
|
43
|
+
while (g && (g = 0, op[0] && (_ = 0)), _) try {
|
|
44
|
+
if (f = 1, y && (t = op[0] & 2 ? y["return"] : op[0] ? y["throw"] || ((t = y["return"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) return t;
|
|
45
|
+
if (y = 0, t) op = [op[0] & 2, t.value];
|
|
46
|
+
switch (op[0]) {
|
|
47
|
+
case 0: case 1: t = op; break;
|
|
48
|
+
case 4: _.label++; return { value: op[1], done: false };
|
|
49
|
+
case 5: _.label++; y = op[1]; op = [0]; continue;
|
|
50
|
+
case 7: op = _.ops.pop(); _.trys.pop(); continue;
|
|
51
|
+
default:
|
|
52
|
+
if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; }
|
|
53
|
+
if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; }
|
|
54
|
+
if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; }
|
|
55
|
+
if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; }
|
|
56
|
+
if (t[2]) _.ops.pop();
|
|
57
|
+
_.trys.pop(); continue;
|
|
58
|
+
}
|
|
59
|
+
op = body.call(thisArg, _);
|
|
60
|
+
} catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; }
|
|
61
|
+
if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true };
|
|
62
|
+
}
|
|
63
|
+
};
|
|
64
|
+
var __rest = (this && this.__rest) || function (s, e) {
|
|
65
|
+
var t = {};
|
|
66
|
+
for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0)
|
|
67
|
+
t[p] = s[p];
|
|
68
|
+
if (s != null && typeof Object.getOwnPropertySymbols === "function")
|
|
69
|
+
for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++) {
|
|
70
|
+
if (e.indexOf(p[i]) < 0 && Object.prototype.propertyIsEnumerable.call(s, p[i]))
|
|
71
|
+
t[p[i]] = s[p[i]];
|
|
72
|
+
}
|
|
73
|
+
return t;
|
|
74
|
+
};
|
|
75
|
+
var __read = (this && this.__read) || function (o, n) {
|
|
76
|
+
var m = typeof Symbol === "function" && o[Symbol.iterator];
|
|
77
|
+
if (!m) return o;
|
|
78
|
+
var i = m.call(o), r, ar = [], e;
|
|
79
|
+
try {
|
|
80
|
+
while ((n === void 0 || n-- > 0) && !(r = i.next()).done) ar.push(r.value);
|
|
81
|
+
}
|
|
82
|
+
catch (error) { e = { error: error }; }
|
|
83
|
+
finally {
|
|
84
|
+
try {
|
|
85
|
+
if (r && !r.done && (m = i["return"])) m.call(i);
|
|
86
|
+
}
|
|
87
|
+
finally { if (e) throw e.error; }
|
|
88
|
+
}
|
|
89
|
+
return ar;
|
|
90
|
+
};
|
|
91
|
+
var __spreadArray = (this && this.__spreadArray) || function (to, from, pack) {
|
|
92
|
+
if (pack || arguments.length === 2) for (var i = 0, l = from.length, ar; i < l; i++) {
|
|
93
|
+
if (ar || !(i in from)) {
|
|
94
|
+
if (!ar) ar = Array.prototype.slice.call(from, 0, i);
|
|
95
|
+
ar[i] = from[i];
|
|
96
|
+
}
|
|
97
|
+
}
|
|
98
|
+
return to.concat(ar || Array.prototype.slice.call(from));
|
|
99
|
+
};
|
|
100
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
101
|
+
exports.PostgresEventBroker = void 0;
|
|
102
|
+
var api_1 = require("@opentelemetry/api");
|
|
103
|
+
var arvo_core_1 = require("arvo-core");
|
|
104
|
+
var pg_boss_1 = require("pg-boss");
|
|
105
|
+
var utils_1 = require("./utils");
|
|
106
|
+
/**
|
|
107
|
+
* Queue-based event broker for ArvoEvent handlers with automatic routing,
|
|
108
|
+
* retry logic, and OpenTelemetry tracing support.
|
|
109
|
+
*
|
|
110
|
+
* PostgresEventBroker extends PgBoss to provide event-driven workflow management
|
|
111
|
+
* through persistent PostgreSQL-backed queues. It automatically routes events between
|
|
112
|
+
* registered handlers, ensures reliable delivery with configurable retry policies,
|
|
113
|
+
* and maintains distributed tracing context across the entire workflow.
|
|
114
|
+
*
|
|
115
|
+
* Key capabilities include handler registration with dedicated queues, automatic
|
|
116
|
+
* event routing based on the 'to' field, workflow completion handling, support for
|
|
117
|
+
* domained events, and comprehensive queue statistics for monitoring.
|
|
118
|
+
*
|
|
119
|
+
* @example
|
|
120
|
+
* ```typescript
|
|
121
|
+
* const broker = new PostgresEventBroker({ connectionString: 'postgres://...' });
|
|
122
|
+
* await broker.start();
|
|
123
|
+
*
|
|
124
|
+
* // Register handlers with retry configuration
|
|
125
|
+
* await broker.register(calculatorHandler, {
|
|
126
|
+
* recreateQueue: true,
|
|
127
|
+
* worker: {
|
|
128
|
+
* concurrency: 5,
|
|
129
|
+
* retryLimit: 3,
|
|
130
|
+
* retryBackoff: true
|
|
131
|
+
* }
|
|
132
|
+
* });
|
|
133
|
+
*
|
|
134
|
+
* // Set up workflow completion handler
|
|
135
|
+
* await broker.onWorkflowComplete({
|
|
136
|
+
* source: 'my.workflow',
|
|
137
|
+
* listener: async (event) => {
|
|
138
|
+
* this.logger.log('Workflow completed:', event.data);
|
|
139
|
+
* }
|
|
140
|
+
* });
|
|
141
|
+
*
|
|
142
|
+
* // Handle domained events (e.g., human approval requests)
|
|
143
|
+
* broker.onDomainedEvent(async (event) => {
|
|
144
|
+
* if (event.domain === 'human.interaction') {
|
|
145
|
+
* await handleHumanApproval(event);
|
|
146
|
+
* }
|
|
147
|
+
* });
|
|
148
|
+
*
|
|
149
|
+
* // Dispatch events using ArvoEventFactory
|
|
150
|
+
* const event = createArvoEventFactory(contract.version('1.0.0')).accepts({
|
|
151
|
+
* source: 'my.workflow',
|
|
152
|
+
* data: { numbers: [1, 2, 3] }
|
|
153
|
+
* });
|
|
154
|
+
* await broker.dispatch(event);
|
|
155
|
+
*
|
|
156
|
+
* // Monitor queue health
|
|
157
|
+
* const stats = await broker.getStats();
|
|
158
|
+
* ```
|
|
159
|
+
*/
|
|
160
|
+
var PostgresEventBroker = /** @class */ (function (_super) {
|
|
161
|
+
__extends(PostgresEventBroker, _super);
|
|
162
|
+
function PostgresEventBroker() {
|
|
163
|
+
var _this = _super.apply(this, __spreadArray([], __read(arguments), false)) || this;
|
|
164
|
+
/**
|
|
165
|
+
* Internal registry of handler configurations keyed by handler source.
|
|
166
|
+
*/
|
|
167
|
+
_this.handlers = {};
|
|
168
|
+
/**
|
|
169
|
+
* Internal list of all registered queue names.
|
|
170
|
+
*/
|
|
171
|
+
_this._queues = [];
|
|
172
|
+
/**
|
|
173
|
+
* Logger instance used for all broker operational logging.
|
|
174
|
+
* Defaults to console but can be replaced via setLogger().
|
|
175
|
+
*/
|
|
176
|
+
_this.logger = console;
|
|
177
|
+
/**
|
|
178
|
+
* The configured event source for workflow completion.
|
|
179
|
+
*/
|
|
180
|
+
_this.injectionEventSource = null;
|
|
181
|
+
/**
|
|
182
|
+
* Default callback invoked when an event has no registered destination handler.
|
|
183
|
+
*/
|
|
184
|
+
_this._onHandlerNotFound = function (event) {
|
|
185
|
+
return _this.logger.error('Handler not found for event', event.toString(2));
|
|
186
|
+
};
|
|
187
|
+
/**
|
|
188
|
+
* Callback invoked when a domained event is encountered during routing.
|
|
189
|
+
*/
|
|
190
|
+
_this._onDomainedEvent = function (event) {
|
|
191
|
+
return _this.logger.info('Domained event encountered', event.toString(2));
|
|
192
|
+
};
|
|
193
|
+
return _this;
|
|
194
|
+
}
|
|
195
|
+
Object.defineProperty(PostgresEventBroker.prototype, "queues", {
|
|
196
|
+
/**
|
|
197
|
+
* List of all registered queue names in the broker.
|
|
198
|
+
*/
|
|
199
|
+
get: function () {
|
|
200
|
+
return this._queues;
|
|
201
|
+
},
|
|
202
|
+
enumerable: false,
|
|
203
|
+
configurable: true
|
|
204
|
+
});
|
|
205
|
+
/**
|
|
206
|
+
* Sets a custom logger for broker operations.
|
|
207
|
+
*
|
|
208
|
+
* Allows integration with existing logging infrastructure (Winston, Pino, etc.)
|
|
209
|
+
* by providing a logger that implements the ILogger interface.
|
|
210
|
+
*
|
|
211
|
+
* @param logger - Logger instance implementing ILogger interface
|
|
212
|
+
*
|
|
213
|
+
* @example
|
|
214
|
+
* ```typescript
|
|
215
|
+
* import winston from 'winston';
|
|
216
|
+
*
|
|
217
|
+
* const logger = winston.createLogger({
|
|
218
|
+
* level: 'info',
|
|
219
|
+
* format: winston.format.json(),
|
|
220
|
+
* transports: [new winston.transports.Console()]
|
|
221
|
+
* });
|
|
222
|
+
*
|
|
223
|
+
* broker.setLogger(logger);
|
|
224
|
+
* ```
|
|
225
|
+
*/
|
|
226
|
+
PostgresEventBroker.prototype.setLogger = function (logger) {
|
|
227
|
+
this.logger = logger;
|
|
228
|
+
};
|
|
229
|
+
/**
|
|
230
|
+
* Registers a handler for workflow completion events.
|
|
231
|
+
*
|
|
232
|
+
* This sets up the terminal point where events return after flowing through
|
|
233
|
+
* the handler chain. The handler receives events whose 'to' field matches
|
|
234
|
+
* the configured source, typically indicating workflow completion.
|
|
235
|
+
*
|
|
236
|
+
* Sets the injection event source that must match the source of events
|
|
237
|
+
* dispatched via the dispatch() method.
|
|
238
|
+
*
|
|
239
|
+
* **Note:** The listener must handle its own errors. Exceptions are caught
|
|
240
|
+
* and logged but do not cause job failures. This is by design.
|
|
241
|
+
*
|
|
242
|
+
* @param param - Configuration object
|
|
243
|
+
* @param param.source - Event source identifier for completion events
|
|
244
|
+
* @param param.listener - Callback invoked when completion events are received
|
|
245
|
+
* @param param.options - Optional queue and worker configuration
|
|
246
|
+
*
|
|
247
|
+
* @example
|
|
248
|
+
* ```typescript
|
|
249
|
+
* await broker.onWorkflowComplete({
|
|
250
|
+
* source: 'test.test.test',
|
|
251
|
+
* listener: async (event) => {
|
|
252
|
+
* try {
|
|
253
|
+
* this.logger.log('Final result:', event.data);
|
|
254
|
+
* } catch (error) {
|
|
255
|
+
* logger.error('Completion handler failed', error);
|
|
256
|
+
* }
|
|
257
|
+
* },
|
|
258
|
+
* });
|
|
259
|
+
* ```
|
|
260
|
+
*/
|
|
261
|
+
PostgresEventBroker.prototype.onWorkflowComplete = function (param) {
|
|
262
|
+
return __awaiter(this, void 0, void 0, function () {
|
|
263
|
+
var i;
|
|
264
|
+
var _this = this;
|
|
265
|
+
var _a, _b, _c, _d, _e, _f, _g, _h;
|
|
266
|
+
return __generator(this, function (_j) {
|
|
267
|
+
switch (_j.label) {
|
|
268
|
+
case 0:
|
|
269
|
+
this.injectionEventSource = param.source;
|
|
270
|
+
this.handlers[param.source] = { options: param.options };
|
|
271
|
+
if (!((_a = param.options) === null || _a === void 0 ? void 0 : _a.recreateQueue)) return [3 /*break*/, 2];
|
|
272
|
+
return [4 /*yield*/, this.deleteQueue(param.source)];
|
|
273
|
+
case 1:
|
|
274
|
+
_j.sent();
|
|
275
|
+
_j.label = 2;
|
|
276
|
+
case 2: return [4 /*yield*/, this.createQueue(param.source, (_b = param.options) === null || _b === void 0 ? void 0 : _b.queue)];
|
|
277
|
+
case 3:
|
|
278
|
+
_j.sent();
|
|
279
|
+
i = 0;
|
|
280
|
+
_j.label = 4;
|
|
281
|
+
case 4:
|
|
282
|
+
if (!(i < Math.max((_e = (_d = (_c = param.options) === null || _c === void 0 ? void 0 : _c.worker) === null || _d === void 0 ? void 0 : _d.concurrency) !== null && _e !== void 0 ? _e : 0, 1))) return [3 /*break*/, 7];
|
|
283
|
+
return [4 /*yield*/, this.work(param.source, {
|
|
284
|
+
pollingIntervalSeconds: (_h = (_g = (_f = param.options) === null || _f === void 0 ? void 0 : _f.worker) === null || _g === void 0 ? void 0 : _g.pollingIntervalSeconds) !== null && _h !== void 0 ? _h : 2,
|
|
285
|
+
batchSize: 1,
|
|
286
|
+
}, function (_a) { return __awaiter(_this, [_a], void 0, function (_b) {
|
|
287
|
+
var eventFromJob_1, error_1;
|
|
288
|
+
var _this = this;
|
|
289
|
+
var _c = __read(_b, 1), job = _c[0];
|
|
290
|
+
return __generator(this, function (_d) {
|
|
291
|
+
switch (_d.label) {
|
|
292
|
+
case 0:
|
|
293
|
+
_d.trys.push([0, 2, , 3]);
|
|
294
|
+
eventFromJob_1 = (0, utils_1.createArvoEventFromJob)(job);
|
|
295
|
+
return [4 /*yield*/, api_1.context.with((0, utils_1.otelParentContext)(eventFromJob_1), function () { return __awaiter(_this, void 0, void 0, function () {
|
|
296
|
+
return __generator(this, function (_a) {
|
|
297
|
+
switch (_a.label) {
|
|
298
|
+
case 0: return [4 /*yield*/, param.listener(eventFromJob_1)];
|
|
299
|
+
case 1: return [2 /*return*/, _a.sent()];
|
|
300
|
+
}
|
|
301
|
+
});
|
|
302
|
+
}); })];
|
|
303
|
+
case 1:
|
|
304
|
+
_d.sent();
|
|
305
|
+
return [3 /*break*/, 3];
|
|
306
|
+
case 2:
|
|
307
|
+
error_1 = _d.sent();
|
|
308
|
+
this.logger.error("[onWorkflowComplete] Error in worker handler for ".concat(param.source), error_1);
|
|
309
|
+
return [3 /*break*/, 3];
|
|
310
|
+
case 3: return [2 /*return*/];
|
|
311
|
+
}
|
|
312
|
+
});
|
|
313
|
+
}); })];
|
|
314
|
+
case 5:
|
|
315
|
+
_j.sent();
|
|
316
|
+
_j.label = 6;
|
|
317
|
+
case 6:
|
|
318
|
+
i++;
|
|
319
|
+
return [3 /*break*/, 4];
|
|
320
|
+
case 7: return [2 /*return*/];
|
|
321
|
+
}
|
|
322
|
+
});
|
|
323
|
+
});
|
|
324
|
+
};
|
|
325
|
+
/**
|
|
326
|
+
* Sets a custom handler for events with no registered destination.
|
|
327
|
+
*
|
|
328
|
+
* When a handler emits an event whose 'to' field doesn't match any
|
|
329
|
+
* registered handler, this callback is invoked. Useful for logging
|
|
330
|
+
* routing errors or implementing fallback behavior.
|
|
331
|
+
*
|
|
332
|
+
* **Note:** The listener must handle its own errors. Exceptions are
|
|
333
|
+
* suppressed by design to prevent routing failures from cascading.
|
|
334
|
+
*
|
|
335
|
+
* @param listner - Callback invoked with unroutable events
|
|
336
|
+
*
|
|
337
|
+
* @example
|
|
338
|
+
* ```typescript
|
|
339
|
+
* broker.onHandlerNotFound(async (event) => {
|
|
340
|
+
* try {
|
|
341
|
+
* logger.error('No handler for', event.to);
|
|
342
|
+
* } catch (error) {
|
|
343
|
+
* this.logger.error('Failed to log missing handler', error);
|
|
344
|
+
* }
|
|
345
|
+
* });
|
|
346
|
+
* ```
|
|
347
|
+
*/
|
|
348
|
+
PostgresEventBroker.prototype.onHandlerNotFound = function (listner) {
|
|
349
|
+
this._onHandlerNotFound = listner;
|
|
350
|
+
};
|
|
351
|
+
/**
|
|
352
|
+
* Sets a custom handler for domained events.
|
|
353
|
+
*
|
|
354
|
+
* Domained events are intercepted during routing and passed to this handler
|
|
355
|
+
* instead of being sent to a queue. Useful for handling external system
|
|
356
|
+
* interactions like human approvals or notifications.
|
|
357
|
+
*
|
|
358
|
+
* **Note:** The listener must handle its own errors. Exceptions are
|
|
359
|
+
* suppressed by design to prevent domained event failures from breaking workflows.
|
|
360
|
+
*
|
|
361
|
+
* @param listner - Callback invoked when domained events are encountered
|
|
362
|
+
*
|
|
363
|
+
* @example
|
|
364
|
+
* ```typescript
|
|
365
|
+
* broker.onDomainedEvent(async (event) => {
|
|
366
|
+
* try {
|
|
367
|
+
* if (event.domain === 'notification') {
|
|
368
|
+
* await alerting.notify(event);
|
|
369
|
+
* }
|
|
370
|
+
* } catch (error) {
|
|
371
|
+
* logger.error('Domained event handler failed', error);
|
|
372
|
+
* }
|
|
373
|
+
* });
|
|
374
|
+
* ```
|
|
375
|
+
*/
|
|
376
|
+
PostgresEventBroker.prototype.onDomainedEvent = function (listner) {
|
|
377
|
+
this._onDomainedEvent = listner;
|
|
378
|
+
};
|
|
379
|
+
/**
|
|
380
|
+
* Creates a queue and tracks it in the internal queue registry.
|
|
381
|
+
* Overrides the base class method to maintain queue tracking.
|
|
382
|
+
*
|
|
383
|
+
* @param name - Queue name
|
|
384
|
+
* @param options - Queue configuration options
|
|
385
|
+
*/
|
|
386
|
+
PostgresEventBroker.prototype.createQueue = function (name, options) {
|
|
387
|
+
return __awaiter(this, void 0, void 0, function () {
|
|
388
|
+
return __generator(this, function (_a) {
|
|
389
|
+
this._queues.push(name);
|
|
390
|
+
return [2 /*return*/, _super.prototype.createQueue.call(this, name, options)];
|
|
391
|
+
});
|
|
392
|
+
});
|
|
393
|
+
};
|
|
394
|
+
/**
|
|
395
|
+
* Registers an event handler with the broker.
|
|
396
|
+
*
|
|
397
|
+
* Creates a dedicated queue for the handler and spawns worker instances
|
|
398
|
+
* to process incoming events. Events emitted by the handler are automatically
|
|
399
|
+
* routed to their destinations based on the 'to' field.
|
|
400
|
+
*
|
|
401
|
+
* @param handler - The ArvoEvent handler to register
|
|
402
|
+
* @param options - Configuration for queue behavior, worker concurrency, and retry policies
|
|
403
|
+
* @throws {Error} If a handler with the same source is already registered
|
|
404
|
+
*
|
|
405
|
+
* @example
|
|
406
|
+
* ```typescript
|
|
407
|
+
* await broker.register(calculatorHandler, {
|
|
408
|
+
* recreateQueue: true,
|
|
409
|
+
* queue: { deadLetter: 'dlq' },
|
|
410
|
+
* worker: {
|
|
411
|
+
* concurrency: 5,
|
|
412
|
+
* onError: async (job, error) => {
|
|
413
|
+
* if (error.message.includes('timeout')) return 'RETRY';
|
|
414
|
+
* return 'FAIL';
|
|
415
|
+
* }
|
|
416
|
+
* }
|
|
417
|
+
* });
|
|
418
|
+
* ```
|
|
419
|
+
*/
|
|
420
|
+
PostgresEventBroker.prototype.register = function (handler, options) {
|
|
421
|
+
return __awaiter(this, void 0, void 0, function () {
|
|
422
|
+
var handlerSource, workHandler, i;
|
|
423
|
+
var _this = this;
|
|
424
|
+
var _a, _b, _c, _d;
|
|
425
|
+
return __generator(this, function (_e) {
|
|
426
|
+
switch (_e.label) {
|
|
427
|
+
case 0:
|
|
428
|
+
if (this.handlers[handler.source]) {
|
|
429
|
+
throw new Error((0, arvo_core_1.cleanString)("\n Handler registration failed: A handler with source '".concat(handler.source, "' is already registered.\n Each handler must have a unique source identifier. Attempted duplicate registration will be\n ignored to prevent queue conflicts.\n ")));
|
|
430
|
+
}
|
|
431
|
+
this.handlers[handler.source] = { options: __assign({}, options) };
|
|
432
|
+
if (!(options === null || options === void 0 ? void 0 : options.recreateQueue)) return [3 /*break*/, 2];
|
|
433
|
+
return [4 /*yield*/, this.deleteQueue(handler.source)];
|
|
434
|
+
case 1:
|
|
435
|
+
_e.sent();
|
|
436
|
+
_e.label = 2;
|
|
437
|
+
case 2: return [4 /*yield*/, this.createQueue(handler.source, options === null || options === void 0 ? void 0 : options.queue)];
|
|
438
|
+
case 3:
|
|
439
|
+
_e.sent();
|
|
440
|
+
handlerSource = handler.source;
|
|
441
|
+
workHandler = function (_a) { return __awaiter(_this, [_a], void 0, function (_b) {
|
|
442
|
+
var eventFromJob_2, events, error_2;
|
|
443
|
+
var _this = this;
|
|
444
|
+
var _c = __read(_b, 1), job = _c[0];
|
|
445
|
+
return __generator(this, function (_d) {
|
|
446
|
+
switch (_d.label) {
|
|
447
|
+
case 0:
|
|
448
|
+
_d.trys.push([0, 3, , 4]);
|
|
449
|
+
eventFromJob_2 = (0, utils_1.createArvoEventFromJob)(job);
|
|
450
|
+
return [4 /*yield*/, api_1.context.with((0, utils_1.otelParentContext)(eventFromJob_2), function () { return __awaiter(_this, void 0, void 0, function () {
|
|
451
|
+
return __generator(this, function (_a) {
|
|
452
|
+
switch (_a.label) {
|
|
453
|
+
case 0: return [4 /*yield*/, handler.execute(eventFromJob_2, {
|
|
454
|
+
inheritFrom: 'EVENT',
|
|
455
|
+
})];
|
|
456
|
+
case 1: return [2 /*return*/, _a.sent()];
|
|
457
|
+
}
|
|
458
|
+
});
|
|
459
|
+
}); })];
|
|
460
|
+
case 1:
|
|
461
|
+
events = (_d.sent()).events;
|
|
462
|
+
return [4 /*yield*/, Promise.all(events.map(function (evt) { return __awaiter(_this, void 0, void 0, function () {
|
|
463
|
+
var error_3;
|
|
464
|
+
var _a;
|
|
465
|
+
return __generator(this, function (_b) {
|
|
466
|
+
switch (_b.label) {
|
|
467
|
+
case 0:
|
|
468
|
+
if (!evt.domain) return [3 /*break*/, 5];
|
|
469
|
+
_b.label = 1;
|
|
470
|
+
case 1:
|
|
471
|
+
_b.trys.push([1, 3, , 4]);
|
|
472
|
+
return [4 /*yield*/, ((_a = this._onDomainedEvent) === null || _a === void 0 ? void 0 : _a.call(this, evt))];
|
|
473
|
+
case 2:
|
|
474
|
+
_b.sent();
|
|
475
|
+
return [3 /*break*/, 4];
|
|
476
|
+
case 3:
|
|
477
|
+
error_3 = _b.sent();
|
|
478
|
+
this.logger.error('Error in onDomainedEvent', error_3);
|
|
479
|
+
return [3 /*break*/, 4];
|
|
480
|
+
case 4: return [2 /*return*/, undefined];
|
|
481
|
+
case 5: return [4 /*yield*/, this._emitArvoEvent(evt)];
|
|
482
|
+
case 6: return [2 /*return*/, _b.sent()];
|
|
483
|
+
}
|
|
484
|
+
});
|
|
485
|
+
}); }))];
|
|
486
|
+
case 2:
|
|
487
|
+
_d.sent();
|
|
488
|
+
return [3 /*break*/, 4];
|
|
489
|
+
case 3:
|
|
490
|
+
error_2 = _d.sent();
|
|
491
|
+
this.logger.error("Error in worker handler for ".concat(handlerSource), error_2);
|
|
492
|
+
throw error_2;
|
|
493
|
+
case 4: return [2 /*return*/];
|
|
494
|
+
}
|
|
495
|
+
});
|
|
496
|
+
}); };
|
|
497
|
+
i = 0;
|
|
498
|
+
_e.label = 4;
|
|
499
|
+
case 4:
|
|
500
|
+
if (!(i < Math.max((_b = (_a = options === null || options === void 0 ? void 0 : options.worker) === null || _a === void 0 ? void 0 : _a.concurrency) !== null && _b !== void 0 ? _b : 0, 1))) return [3 /*break*/, 7];
|
|
501
|
+
return [4 /*yield*/, this.work(handler.source, {
|
|
502
|
+
pollingIntervalSeconds: (_d = (_c = options === null || options === void 0 ? void 0 : options.worker) === null || _c === void 0 ? void 0 : _c.pollingIntervalSeconds) !== null && _d !== void 0 ? _d : 2,
|
|
503
|
+
batchSize: 1,
|
|
504
|
+
}, workHandler)];
|
|
505
|
+
case 5:
|
|
506
|
+
_e.sent();
|
|
507
|
+
_e.label = 6;
|
|
508
|
+
case 6:
|
|
509
|
+
i++;
|
|
510
|
+
return [3 /*break*/, 4];
|
|
511
|
+
case 7: return [2 /*return*/];
|
|
512
|
+
}
|
|
513
|
+
});
|
|
514
|
+
});
|
|
515
|
+
};
|
|
516
|
+
/**
|
|
517
|
+
* Routes an ArvoEvent to its destination queue.
|
|
518
|
+
*
|
|
519
|
+
* Internal method that filters out worker configuration options and includes
|
|
520
|
+
* only job-level options when sending the event. This method performs no
|
|
521
|
+
* validation and assumes the event and handler have already been verified.
|
|
522
|
+
*
|
|
523
|
+
* @param event - The ArvoEvent to route
|
|
524
|
+
* @returns Job ID if sent successfully, null if handler not found
|
|
525
|
+
*/
|
|
526
|
+
PostgresEventBroker.prototype._emitArvoEvent = function (event) {
|
|
527
|
+
return __awaiter(this, void 0, void 0, function () {
|
|
528
|
+
var e_1, _a, concurrency, pollingIntervalSeconds, rest;
|
|
529
|
+
var _b, _c, _d;
|
|
530
|
+
return __generator(this, function (_e) {
|
|
531
|
+
switch (_e.label) {
|
|
532
|
+
case 0:
|
|
533
|
+
if (!(!event.to || !this._queues.includes(event.to))) return [3 /*break*/, 5];
|
|
534
|
+
_e.label = 1;
|
|
535
|
+
case 1:
|
|
536
|
+
_e.trys.push([1, 3, , 4]);
|
|
537
|
+
return [4 /*yield*/, ((_b = this._onHandlerNotFound) === null || _b === void 0 ? void 0 : _b.call(this, event))];
|
|
538
|
+
case 2:
|
|
539
|
+
_e.sent();
|
|
540
|
+
return [3 /*break*/, 4];
|
|
541
|
+
case 3:
|
|
542
|
+
e_1 = _e.sent();
|
|
543
|
+
this.logger.error('Error in onHandlerNotFound ', e_1);
|
|
544
|
+
return [3 /*break*/, 4];
|
|
545
|
+
case 4: return [2 /*return*/, null];
|
|
546
|
+
case 5:
|
|
547
|
+
_a = (_d = (_c = this.handlers[event.to].options) === null || _c === void 0 ? void 0 : _c.worker) !== null && _d !== void 0 ? _d : {}, concurrency = _a.concurrency, pollingIntervalSeconds = _a.pollingIntervalSeconds, rest = __rest(_a, ["concurrency", "pollingIntervalSeconds"]);
|
|
548
|
+
return [4 /*yield*/, this.send(event.to, event.toJSON(), __assign({}, (rest !== null && rest !== void 0 ? rest : {})))];
|
|
549
|
+
case 6: return [2 /*return*/, _e.sent()];
|
|
550
|
+
}
|
|
551
|
+
});
|
|
552
|
+
});
|
|
553
|
+
};
|
|
554
|
+
/**
|
|
555
|
+
* Dispatches an ArvoEvent into the broker system with validation.
|
|
556
|
+
*
|
|
557
|
+
* This is the primary entry point for injecting events into the workflow.
|
|
558
|
+
* The event must originate from the source configured in onWorkflowComplete()
|
|
559
|
+
* and target a registered handler.
|
|
560
|
+
*
|
|
561
|
+
* @param event - The ArvoEvent to dispatch
|
|
562
|
+
* @returns Job ID assigned by the queue system
|
|
563
|
+
* @throws {Error} If workflow completion handler is not configured
|
|
564
|
+
* @throws {Error} If event source doesn't match configured workflow source
|
|
565
|
+
* @throws {Error} If target handler is not registered
|
|
566
|
+
*
|
|
567
|
+
* @example
|
|
568
|
+
* ```typescript
|
|
569
|
+
* const event = createArvoEvent({
|
|
570
|
+
* source: 'my.workflow',
|
|
571
|
+
* to: 'calculator.handler',
|
|
572
|
+
* type: 'calculate.request',
|
|
573
|
+
* data: { operation: 'add', values: [1, 2] }
|
|
574
|
+
* });
|
|
575
|
+
*
|
|
576
|
+
* await broker.dispatch(event);
|
|
577
|
+
* ```
|
|
578
|
+
*/
|
|
579
|
+
PostgresEventBroker.prototype.dispatch = function (event) {
|
|
580
|
+
return __awaiter(this, void 0, void 0, function () {
|
|
581
|
+
var _a;
|
|
582
|
+
return __generator(this, function (_b) {
|
|
583
|
+
switch (_b.label) {
|
|
584
|
+
case 0:
|
|
585
|
+
if (!this.injectionEventSource) {
|
|
586
|
+
throw new Error((0, arvo_core_1.cleanString)("\n Workflow completion handler not configured: Cannot dispatch ArvoEvent without setting up\n the workflow completion handler. Call onWorkflowComplete({ source: string, handler: Function })\n to register the completion point before dispatching events into the system.\n "));
|
|
587
|
+
}
|
|
588
|
+
if (this.injectionEventSource !== event.source) {
|
|
589
|
+
throw new Error((0, arvo_core_1.cleanString)("\n Event source mismatch: The dispatched event source '".concat(event.source, "' does not match the\n configured workflow completion source '").concat(this.injectionEventSource, "'. Events dispatched\n through dispatch() must originate from the source specified in onWorkflowComplete().\n Verify the event's source property matches '").concat(this.injectionEventSource, "'.\n ")));
|
|
590
|
+
}
|
|
591
|
+
if (!this._queues.includes((_a = event.to) !== null && _a !== void 0 ? _a : '')) {
|
|
592
|
+
throw new Error((0, arvo_core_1.cleanString)("\n Handler not registered: No handler found for destination '".concat(event.to, "'. The target handler\n must be registered using register() before events can be routed to it. Register the required\n handler or verify the event's 'to' property is correct.\n ")));
|
|
593
|
+
}
|
|
594
|
+
return [4 /*yield*/, this._emitArvoEvent(event)];
|
|
595
|
+
case 1: return [2 /*return*/, _b.sent()];
|
|
596
|
+
}
|
|
597
|
+
});
|
|
598
|
+
});
|
|
599
|
+
};
|
|
600
|
+
/**
|
|
601
|
+
* Retrieves statistics for all registered queues in the broker.
|
|
602
|
+
*
|
|
603
|
+
* @returns Array of queue statistics including active, queued, and total job counts
|
|
604
|
+
*
|
|
605
|
+
* @example
|
|
606
|
+
* ```typescript
|
|
607
|
+
* const stats = await broker.getStats();
|
|
608
|
+
* stats.forEach(stat => {
|
|
609
|
+
* this.logger.log(`Queue ${stat.name}: ${stat.activeCount} active, ${stat.queuedCount} queued`);
|
|
610
|
+
* });
|
|
611
|
+
* ```
|
|
612
|
+
*/
|
|
613
|
+
PostgresEventBroker.prototype.getStats = function () {
|
|
614
|
+
return __awaiter(this, void 0, void 0, function () {
|
|
615
|
+
var _this = this;
|
|
616
|
+
return __generator(this, function (_a) {
|
|
617
|
+
switch (_a.label) {
|
|
618
|
+
case 0: return [4 /*yield*/, Promise.all(this._queues.map(function (q) { return __awaiter(_this, void 0, void 0, function () { return __generator(this, function (_a) {
|
|
619
|
+
return [2 /*return*/, this.getQueueStats(q)];
|
|
620
|
+
}); }); }))];
|
|
621
|
+
case 1: return [2 /*return*/, _a.sent()];
|
|
622
|
+
}
|
|
623
|
+
});
|
|
624
|
+
});
|
|
625
|
+
};
|
|
626
|
+
return PostgresEventBroker;
|
|
627
|
+
}(pg_boss_1.PgBoss));
|
|
628
|
+
exports.PostgresEventBroker = PostgresEventBroker;
|
|
629
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/broker/index.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,96 @@
|
|
|
1
|
+
import type { QueuePolicy } from 'pg-boss';
|
|
2
|
+
/**
|
|
3
|
+
* Job-level options that control how individual jobs are processed by PgBoss.
|
|
4
|
+
* These options are applied when sending jobs to queues.
|
|
5
|
+
*/
|
|
6
|
+
export type WorkerJobOptions = {
|
|
7
|
+
/** Job priority. Higher numbers have higher priority */
|
|
8
|
+
priority?: number;
|
|
9
|
+
/** Number of retries to complete a job. Default: 2 */
|
|
10
|
+
retryLimit?: number;
|
|
11
|
+
/** Delay between retries of failed jobs, in seconds. Default: 0 */
|
|
12
|
+
retryDelay?: number;
|
|
13
|
+
/** Enables exponential backoff retries based on retryDelay. Default: false */
|
|
14
|
+
retryBackoff?: boolean;
|
|
15
|
+
/** Maximum delay between retries when retryBackoff is true, in seconds */
|
|
16
|
+
retryDelayMax?: number;
|
|
17
|
+
/** How many seconds a job may be in active state before being retried or failed. Default: 15 minutes */
|
|
18
|
+
expireInSeconds?: number;
|
|
19
|
+
/** How many seconds a job may be in created or retry state before deletion. Default: 14 days */
|
|
20
|
+
retentionSeconds?: number;
|
|
21
|
+
/** How long a job should be retained after completion, in seconds. Default: 7 days */
|
|
22
|
+
deleteAfterSeconds?: number;
|
|
23
|
+
/** Delay job execution. Can be seconds (number), ISO 8601 string, or Date object */
|
|
24
|
+
startAfter?: number | string | Date;
|
|
25
|
+
/** Throttle to one job per time slot, in seconds */
|
|
26
|
+
singletonSeconds?: number;
|
|
27
|
+
/** Schedule throttled job for next time slot. Default: false */
|
|
28
|
+
singletonNextSlot?: boolean;
|
|
29
|
+
/** Extend throttling to allow one job per key within the time slot */
|
|
30
|
+
singletonKey?: string;
|
|
31
|
+
};
|
|
32
|
+
/**
|
|
33
|
+
* Worker-level configuration options that control how the worker processes jobs.
|
|
34
|
+
* These options are not sent with individual jobs.
|
|
35
|
+
*/
|
|
36
|
+
export type WorkerConfigOptions = {
|
|
37
|
+
/** Polling interval for checking new jobs, in seconds. Default: 2 */
|
|
38
|
+
pollingIntervalSeconds?: number;
|
|
39
|
+
/** Number of concurrent worker instances to spawn for this handler. Default: 1 */
|
|
40
|
+
concurrency?: number;
|
|
41
|
+
};
|
|
42
|
+
/**
|
|
43
|
+
* Combined worker options including both configuration and job-level settings.
|
|
44
|
+
*/
|
|
45
|
+
export type WorkerOptions = WorkerConfigOptions & WorkerJobOptions;
|
|
46
|
+
/**
|
|
47
|
+
* Queue configuration options that define queue behavior and policies.
|
|
48
|
+
*/
|
|
49
|
+
export type QueueOptions = {
|
|
50
|
+
/** Queue policy determining job uniqueness and processing behavior */
|
|
51
|
+
policy?: QueuePolicy;
|
|
52
|
+
/** Enable queue partitioning for scalability */
|
|
53
|
+
partition?: boolean;
|
|
54
|
+
/** Name of the dead letter queue for failed jobs */
|
|
55
|
+
deadLetter?: string;
|
|
56
|
+
/** Queue size threshold for warnings */
|
|
57
|
+
warningQueueSize?: number;
|
|
58
|
+
};
|
|
59
|
+
/**
|
|
60
|
+
* Options for registering an event handler with the ArvoPgBoss system.
|
|
61
|
+
*/
|
|
62
|
+
export type HandlerRegistrationOptions = {
|
|
63
|
+
/** Delete and recreate the queue before registration. Default: false */
|
|
64
|
+
recreateQueue?: boolean;
|
|
65
|
+
/** Queue-level configuration options */
|
|
66
|
+
queue?: QueueOptions;
|
|
67
|
+
/** Worker-level configuration and job options */
|
|
68
|
+
worker?: WorkerOptions;
|
|
69
|
+
};
|
|
70
|
+
/**
|
|
71
|
+
* Logger interface for broker operations.
|
|
72
|
+
*
|
|
73
|
+
* Allows users to inject their own logging implementation (Winston, Pino, etc.)
|
|
74
|
+
* or use the default console logger. All broker operational logs use this interface.
|
|
75
|
+
*/
|
|
76
|
+
export interface ILogger {
|
|
77
|
+
/**
|
|
78
|
+
* Log informational messages about broker operations.
|
|
79
|
+
* @param message - Primary log message
|
|
80
|
+
* @param optionalParams - Additional context or data
|
|
81
|
+
*/
|
|
82
|
+
log(message?: any, ...optionalParams: any[]): void;
|
|
83
|
+
/**
|
|
84
|
+
* Log error messages for failures or exceptions.
|
|
85
|
+
* @param message - Error message or description
|
|
86
|
+
* @param optionalParams - Error object or additional context
|
|
87
|
+
*/
|
|
88
|
+
error(message?: any, ...optionalParams: any[]): void;
|
|
89
|
+
/**
|
|
90
|
+
* Log informational messages (alias for log).
|
|
91
|
+
* @param message - Primary log message
|
|
92
|
+
* @param optionalParams - Additional context or data
|
|
93
|
+
*/
|
|
94
|
+
info(message?: any, ...optionalParams: any[]): void;
|
|
95
|
+
}
|
|
96
|
+
//# sourceMappingURL=types.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/broker/types.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,SAAS,CAAC;AAE3C;;;GAGG;AACH,MAAM,MAAM,gBAAgB,GAAG;IAC7B,wDAAwD;IACxD,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,sDAAsD;IACtD,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,mEAAmE;IACnE,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,8EAA8E;IAC9E,YAAY,CAAC,EAAE,OAAO,CAAC;IACvB,0EAA0E;IAC1E,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,wGAAwG;IACxG,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,gGAAgG;IAChG,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAC1B,sFAAsF;IACtF,kBAAkB,CAAC,EAAE,MAAM,CAAC;IAC5B,oFAAoF;IACpF,UAAU,CAAC,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CAAC;IACpC,oDAAoD;IACpD,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAC1B,gEAAgE;IAChE,iBAAiB,CAAC,EAAE,OAAO,CAAC;IAC5B,sEAAsE;IACtE,YAAY,CAAC,EAAE,MAAM,CAAC;CACvB,CAAC;AAEF;;;GAGG;AACH,MAAM,MAAM,mBAAmB,GAAG;IAChC,qEAAqE;IACrE,sBAAsB,CAAC,EAAE,MAAM,CAAC;IAChC,kFAAkF;IAClF,WAAW,CAAC,EAAE,MAAM,CAAC;CACtB,CAAC;AAEF;;GAEG;AACH,MAAM,MAAM,aAAa,GAAG,mBAAmB,GAAG,gBAAgB,CAAC;AAEnE;;GAEG;AACH,MAAM,MAAM,YAAY,GAAG;IACzB,sEAAsE;IACtE,MAAM,CAAC,EAAE,WAAW,CAAC;IACrB,gDAAgD;IAChD,SAAS,CAAC,EAAE,OAAO,CAAC;IACpB,oDAAoD;IACpD,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,wCAAwC;IACxC,gBAAgB,CAAC,EAAE,MAAM,CAAC;CAC3B,CAAC;AAEF;;GAEG;AACH,MAAM,MAAM,0BAA0B,GAAG;IACvC,wEAAwE;IACxE,aAAa,CAAC,EAAE,OAAO,CAAC;IACxB,wCAAwC;IACxC,KAAK,CAAC,EAAE,YAAY,CAAC;IACrB,iDAAiD;IACjD,MAAM,CAAC,EAAE,aAAa,CAAC;CACxB,CAAC;AAEF;;;;;GAKG;AACH,MAAM,WAAW,OAAO;IACtB;;;;OAIG;IAEH,GAAG,CAAC,OAAO,CAAC,EAAE,GAAG,EAAE,GAAG,cAAc,EAAE,GAAG,EAAE,GAAG,IAAI,CAAC;IAEnD;;;;OAIG;IAEH,KAAK,CAAC,OAAO,CAAC,EAAE,GAAG,EAAE,GAAG,cAAc,EAAE,GAAG,EAAE,GAAG,IAAI,CAAC;IAErD;;;;OAIG;IAEH,IAAI,CAAC,OAAO,CAAC,EAAE,GAAG,EAAE,GAAG,cAAc,EAAE,GAAG,EAAE,GAAG,IAAI,CAAC;CACrD"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.js","sourceRoot":"","sources":["../../src/broker/types.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import { ArvoEvent } from 'arvo-core';
|
|
2
|
+
import type { Job } from 'pg-boss';
|
|
3
|
+
export declare const createArvoEventFromJob: (job: Job<ReturnType<ArvoEvent["toJSON"]>>) => ArvoEvent;
|
|
4
|
+
/**
|
|
5
|
+
* Extracts and creates an OpenTelemetry context from an ArvoEvent's traceparent.
|
|
6
|
+
*
|
|
7
|
+
* @param event - The ArvoEvent containing trace information
|
|
8
|
+
* @returns OpenTelemetry context with the event's trace information
|
|
9
|
+
*/
|
|
10
|
+
export declare const otelParentContext: (event: ArvoEvent) => import("@opentelemetry/api").Context;
|
|
11
|
+
//# sourceMappingURL=utils.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"utils.d.ts","sourceRoot":"","sources":["../../src/broker/utils.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,SAAS,EAAE,MAAM,WAAW,CAAC;AACtC,OAAO,KAAK,EAAE,GAAG,EAAE,MAAM,SAAS,CAAC;AAEnC,eAAO,MAAM,sBAAsB,GAAI,KAAK,GAAG,CAAC,UAAU,CAAC,SAAS,CAAC,QAAQ,CAAC,CAAC,CAAC,KAAG,SA2ClF,CAAC;AAEF;;;;;GAKG;AACH,eAAO,MAAM,iBAAiB,GAAI,OAAO,SAAS,yCAejD,CAAC"}
|
|
@@ -0,0 +1,78 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __rest = (this && this.__rest) || function (s, e) {
|
|
3
|
+
var t = {};
|
|
4
|
+
for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0)
|
|
5
|
+
t[p] = s[p];
|
|
6
|
+
if (s != null && typeof Object.getOwnPropertySymbols === "function")
|
|
7
|
+
for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++) {
|
|
8
|
+
if (e.indexOf(p[i]) < 0 && Object.prototype.propertyIsEnumerable.call(s, p[i]))
|
|
9
|
+
t[p[i]] = s[p[i]];
|
|
10
|
+
}
|
|
11
|
+
return t;
|
|
12
|
+
};
|
|
13
|
+
var __read = (this && this.__read) || function (o, n) {
|
|
14
|
+
var m = typeof Symbol === "function" && o[Symbol.iterator];
|
|
15
|
+
if (!m) return o;
|
|
16
|
+
var i = m.call(o), r, ar = [], e;
|
|
17
|
+
try {
|
|
18
|
+
while ((n === void 0 || n-- > 0) && !(r = i.next()).done) ar.push(r.value);
|
|
19
|
+
}
|
|
20
|
+
catch (error) { e = { error: error }; }
|
|
21
|
+
finally {
|
|
22
|
+
try {
|
|
23
|
+
if (r && !r.done && (m = i["return"])) m.call(i);
|
|
24
|
+
}
|
|
25
|
+
finally { if (e) throw e.error; }
|
|
26
|
+
}
|
|
27
|
+
return ar;
|
|
28
|
+
};
|
|
29
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
30
|
+
exports.otelParentContext = exports.createArvoEventFromJob = void 0;
|
|
31
|
+
var api_1 = require("@opentelemetry/api");
|
|
32
|
+
var arvo_core_1 = require("arvo-core");
|
|
33
|
+
var createArvoEventFromJob = function (job) {
|
|
34
|
+
var _a = job.data, id = _a.id, source = _a.source, type = _a.type, subject = _a.subject, time = _a.time, specversion = _a.specversion, datacontenttype = _a.datacontenttype, dataschema = _a.dataschema, to = _a.to, accesscontrol = _a.accesscontrol, redirectto = _a.redirectto, executionunits = _a.executionunits, parentid = _a.parentid, domain = _a.domain, traceparent = _a.traceparent, tracestate = _a.tracestate, data = _a.data, extensions = __rest(_a, ["id", "source", "type", "subject", "time", "specversion", "datacontenttype", "dataschema", "to", "accesscontrol", "redirectto", "executionunits", "parentid", "domain", "traceparent", "tracestate", "data"]);
|
|
35
|
+
return new arvo_core_1.ArvoEvent({
|
|
36
|
+
id: id,
|
|
37
|
+
source: source,
|
|
38
|
+
type: type,
|
|
39
|
+
subject: subject,
|
|
40
|
+
time: time,
|
|
41
|
+
specversion: specversion,
|
|
42
|
+
datacontenttype: datacontenttype,
|
|
43
|
+
dataschema: dataschema,
|
|
44
|
+
to: to,
|
|
45
|
+
accesscontrol: accesscontrol,
|
|
46
|
+
redirectto: redirectto,
|
|
47
|
+
executionunits: executionunits,
|
|
48
|
+
parentid: parentid,
|
|
49
|
+
domain: domain,
|
|
50
|
+
traceparent: traceparent,
|
|
51
|
+
tracestate: tracestate,
|
|
52
|
+
}, data, extensions !== null && extensions !== void 0 ? extensions : {});
|
|
53
|
+
};
|
|
54
|
+
exports.createArvoEventFromJob = createArvoEventFromJob;
|
|
55
|
+
/**
|
|
56
|
+
* Extracts and creates an OpenTelemetry context from an ArvoEvent's traceparent.
|
|
57
|
+
*
|
|
58
|
+
* @param event - The ArvoEvent containing trace information
|
|
59
|
+
* @returns OpenTelemetry context with the event's trace information
|
|
60
|
+
*/
|
|
61
|
+
var otelParentContext = function (event) {
|
|
62
|
+
var parentContext = api_1.context.active();
|
|
63
|
+
if (event.traceparent) {
|
|
64
|
+
var parts = event.traceparent.split('-');
|
|
65
|
+
if (parts.length === 4) {
|
|
66
|
+
var _a = __read(parts, 4), _ = _a[0], traceId = _a[1], spanId = _a[2], traceFlags = _a[3];
|
|
67
|
+
var spanContext = {
|
|
68
|
+
traceId: traceId,
|
|
69
|
+
spanId: spanId,
|
|
70
|
+
traceFlags: Number.parseInt(traceFlags, 10),
|
|
71
|
+
};
|
|
72
|
+
parentContext = api_1.trace.setSpanContext(api_1.context.active(), spanContext);
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
return parentContext;
|
|
76
|
+
};
|
|
77
|
+
exports.otelParentContext = otelParentContext;
|
|
78
|
+
//# sourceMappingURL=utils.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"utils.js","sourceRoot":"","sources":["../../src/broker/utils.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA,0CAAsE;AACtE,uCAAsC;AAG/B,IAAM,sBAAsB,GAAG,UAAC,GAAyC;IAC9E,IAAM,KAmBF,GAAG,CAAC,IAAI,EAlBV,EAAE,QAAA,EACF,MAAM,YAAA,EACN,IAAI,UAAA,EACJ,OAAO,aAAA,EACP,IAAI,UAAA,EACJ,WAAW,iBAAA,EACX,eAAe,qBAAA,EACf,UAAU,gBAAA,EACV,EAAE,QAAA,EACF,aAAa,mBAAA,EACb,UAAU,gBAAA,EACV,cAAc,oBAAA,EACd,QAAQ,cAAA,EACR,MAAM,YAAA,EACN,WAAW,iBAAA,EACX,UAAU,gBAAA,EACV,IAAI,UAAA,EACD,UAAU,cAlBT,6MAmBL,CAAW,CAAC;IACb,OAAO,IAAI,qBAAS,CAClB;QACE,EAAE,IAAA;QACF,MAAM,QAAA;QACN,IAAI,MAAA;QACJ,OAAO,SAAA;QACP,IAAI,MAAA;QACJ,WAAW,EAAE,WAAoB;QACjC,eAAe,iBAAA;QACf,UAAU,YAAA;QACV,EAAE,IAAA;QACF,aAAa,eAAA;QACb,UAAU,YAAA;QACV,cAAc,gBAAA;QACd,QAAQ,UAAA;QACR,MAAM,QAAA;QACN,WAAW,aAAA;QACX,UAAU,YAAA;KACX,EACD,IAAI,EACJ,UAAU,aAAV,UAAU,cAAV,UAAU,GAAI,EAAE,CACjB,CAAC;AACJ,CAAC,CAAC;AA3CW,QAAA,sBAAsB,0BA2CjC;AAEF;;;;;GAKG;AACI,IAAM,iBAAiB,GAAG,UAAC,KAAgB;IAChD,IAAI,aAAa,GAAG,aAAO,CAAC,MAAM,EAAE,CAAC;IACrC,IAAI,KAAK,CAAC,WAAW,EAAE,CAAC;QACtB,IAAM,KAAK,GAAG,KAAK,CAAC,WAAW,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC;QAC3C,IAAI,KAAK,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;YACjB,IAAA,KAAA,OAAmC,KAAK,IAAA,EAAvC,CAAC,QAAA,EAAE,OAAO,QAAA,EAAE,MAAM,QAAA,EAAE,UAAU,QAAS,CAAC;YAC/C,IAAM,WAAW,GAAgB;gBAC/B,OAAO,SAAA;gBACP,MAAM,QAAA;gBACN,UAAU,EAAE,MAAM,CAAC,QAAQ,CAAC,UAAU,EAAE,EAAE,CAAC;aAC5C,CAAC;YACF,aAAa,GAAG,WAAK,CAAC,cAAc,CAAC,aAAO,CAAC,MAAM,EAAE,EAAE,WAAW,CAAC,CAAC;QACtE,CAAC;IACH,CAAC;IACD,OAAO,aAAa,CAAC;AACvB,CAAC,CAAC;AAfW,QAAA,iBAAiB,qBAe5B"}
|
package/dist/index.d.ts
CHANGED
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
export { PostgresEventBroker } from './broker';
|
|
2
|
+
export type { HandlerRegistrationOptions, QueueOptions, WorkerConfigOptions, WorkerJobOptions, WorkerOptions, } from './broker/types';
|
|
1
3
|
export { connectPostgresMachineMemory, releasePostgressMachineMemory, } from './memory/factory';
|
|
2
4
|
export type { ConnectPostgresMachineMemoryParam, PostgresMachineMemory, } from './memory/factory/type';
|
|
3
5
|
export type { PostgressConnectionConfig } from './memory/types';
|
package/dist/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,4BAA4B,EAC5B,6BAA6B,GAC9B,MAAM,kBAAkB,CAAC;AAC1B,YAAY,EACV,iCAAiC,EACjC,qBAAqB,GACtB,MAAM,uBAAuB,CAAC;AAC/B,YAAY,EAAE,yBAAyB,EAAE,MAAM,gBAAgB,CAAC;AAChE,OAAO,EAAE,wBAAwB,EAAE,MAAM,aAAa,CAAC"}
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,mBAAmB,EAAE,MAAM,UAAU,CAAC;AAC/C,YAAY,EACV,0BAA0B,EAC1B,YAAY,EACZ,mBAAmB,EACnB,gBAAgB,EAChB,aAAa,GACd,MAAM,gBAAgB,CAAC;AACxB,OAAO,EACL,4BAA4B,EAC5B,6BAA6B,GAC9B,MAAM,kBAAkB,CAAC;AAC1B,YAAY,EACV,iCAAiC,EACjC,qBAAqB,GACtB,MAAM,uBAAuB,CAAC;AAC/B,YAAY,EAAE,yBAAyB,EAAE,MAAM,gBAAgB,CAAC;AAChE,OAAO,EAAE,wBAAwB,EAAE,MAAM,aAAa,CAAC"}
|
package/dist/index.js
CHANGED
|
@@ -1,6 +1,8 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.PostgressMachineMemoryV1 = exports.releasePostgressMachineMemory = exports.connectPostgresMachineMemory = void 0;
|
|
3
|
+
exports.PostgressMachineMemoryV1 = exports.releasePostgressMachineMemory = exports.connectPostgresMachineMemory = exports.PostgresEventBroker = void 0;
|
|
4
|
+
var broker_1 = require("./broker");
|
|
5
|
+
Object.defineProperty(exports, "PostgresEventBroker", { enumerable: true, get: function () { return broker_1.PostgresEventBroker; } });
|
|
4
6
|
var factory_1 = require("./memory/factory");
|
|
5
7
|
Object.defineProperty(exports, "connectPostgresMachineMemory", { enumerable: true, get: function () { return factory_1.connectPostgresMachineMemory; } });
|
|
6
8
|
Object.defineProperty(exports, "releasePostgressMachineMemory", { enumerable: true, get: function () { return factory_1.releasePostgressMachineMemory; } });
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";;;AAAA,4CAG0B;AAFxB,uHAAA,4BAA4B,OAAA;AAC5B,wHAAA,6BAA6B,OAAA;AAO/B,kCAAuD;AAA9C,8GAAA,wBAAwB,OAAA"}
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";;;AAAA,mCAA+C;AAAtC,6GAAA,mBAAmB,OAAA;AAQ5B,4CAG0B;AAFxB,uHAAA,4BAA4B,OAAA;AAC5B,wHAAA,6BAA6B,OAAA;AAO/B,kCAAuD;AAA9C,8GAAA,wBAAwB,OAAA"}
|
|
@@ -95,6 +95,10 @@ declare const tableSchema: {
|
|
|
95
95
|
is_nullable: "YES";
|
|
96
96
|
}>;
|
|
97
97
|
}, "strip", z.ZodTypeAny, {
|
|
98
|
+
source: {
|
|
99
|
+
data_type: "character varying";
|
|
100
|
+
is_nullable: "NO";
|
|
101
|
+
};
|
|
98
102
|
subject: {
|
|
99
103
|
data_type: "character varying";
|
|
100
104
|
is_nullable: "NO";
|
|
@@ -119,10 +123,6 @@ declare const tableSchema: {
|
|
|
119
123
|
data_type: "character varying";
|
|
120
124
|
is_nullable: "YES";
|
|
121
125
|
};
|
|
122
|
-
source: {
|
|
123
|
-
data_type: "character varying";
|
|
124
|
-
is_nullable: "NO";
|
|
125
|
-
};
|
|
126
126
|
created_at: {
|
|
127
127
|
data_type: "timestamp without time zone";
|
|
128
128
|
is_nullable: "YES";
|
|
@@ -132,6 +132,10 @@ declare const tableSchema: {
|
|
|
132
132
|
is_nullable: "YES";
|
|
133
133
|
};
|
|
134
134
|
}, {
|
|
135
|
+
source: {
|
|
136
|
+
data_type: "character varying";
|
|
137
|
+
is_nullable: "NO";
|
|
138
|
+
};
|
|
135
139
|
subject: {
|
|
136
140
|
data_type: "character varying";
|
|
137
141
|
is_nullable: "NO";
|
|
@@ -156,10 +160,6 @@ declare const tableSchema: {
|
|
|
156
160
|
data_type: "character varying";
|
|
157
161
|
is_nullable: "YES";
|
|
158
162
|
};
|
|
159
|
-
source: {
|
|
160
|
-
data_type: "character varying";
|
|
161
|
-
is_nullable: "NO";
|
|
162
|
-
};
|
|
163
163
|
created_at: {
|
|
164
164
|
data_type: "timestamp without time zone";
|
|
165
165
|
is_nullable: "YES";
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@arvo-tools/postgres",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.2.0",
|
|
4
4
|
"description": "The official package for Arvo's execution components in Postgres",
|
|
5
5
|
"main": "dist/index.js",
|
|
6
6
|
"types": "dist/index.d.ts",
|
|
@@ -29,6 +29,7 @@
|
|
|
29
29
|
"dependencies": {
|
|
30
30
|
"arvo-core": "3.0.28",
|
|
31
31
|
"pg": "8.16.3",
|
|
32
|
+
"pg-boss": "12.5.4",
|
|
32
33
|
"pg-format": "1.0.4",
|
|
33
34
|
"zod": "3.25.76"
|
|
34
35
|
},
|
|
@@ -41,7 +42,7 @@
|
|
|
41
42
|
"vitest": "4.0.13"
|
|
42
43
|
},
|
|
43
44
|
"engines": {
|
|
44
|
-
"node": ">=
|
|
45
|
+
"node": ">=22.12.0"
|
|
45
46
|
},
|
|
46
47
|
"scripts": {
|
|
47
48
|
"build": "tsc",
|