@flowcore/pathways 0.9.1 → 0.11.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/CHANGELOG.md +21 -0
- package/esm/pathways/builder.d.ts +10 -8
- package/esm/pathways/builder.d.ts.map +1 -1
- package/esm/pathways/builder.js +148 -37
- package/esm/pathways/postgres/postgres-pathway-state.d.ts.map +1 -1
- package/esm/pathways/postgres/postgres-pathway-state.js +27 -17
- package/esm/pathways/types.d.ts +7 -2
- package/esm/pathways/types.d.ts.map +1 -1
- package/package.json +1 -1
- package/script/pathways/builder.d.ts +10 -8
- package/script/pathways/builder.d.ts.map +1 -1
- package/script/pathways/builder.js +148 -37
- package/script/pathways/postgres/postgres-pathway-state.d.ts.map +1 -1
- package/script/pathways/postgres/postgres-pathway-state.js +27 -17
- package/script/pathways/types.d.ts +7 -2
- package/script/pathways/types.d.ts.map +1 -1
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@flowcore/pathways",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.11.0",
|
|
4
4
|
"description": "A TypeScript Library for creating Flowcore Pathways, simplifying the integration with the flowcore platform",
|
|
5
5
|
"homepage": "https://github.com/flowcore-io/flowcore-pathways#readme",
|
|
6
6
|
"repository": {
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type
|
|
1
|
+
import { type Static, type TSchema } from "@sinclair/typebox";
|
|
2
2
|
import type { WebhookSendOptions } from "@flowcore/sdk-transformer-core";
|
|
3
3
|
import type { FlowcoreEvent } from "../contracts/event.js";
|
|
4
4
|
import type { KvAdapter } from "./kv/kv-adapter.js";
|
|
@@ -52,6 +52,7 @@ export declare class PathwaysBuilder<TPathway extends Record<string, unknown> =
|
|
|
52
52
|
private readonly errorObservers;
|
|
53
53
|
private readonly globalErrorSubject;
|
|
54
54
|
private readonly writers;
|
|
55
|
+
private readonly batchWriters;
|
|
55
56
|
private readonly schemas;
|
|
56
57
|
private readonly writable;
|
|
57
58
|
private readonly timeouts;
|
|
@@ -187,31 +188,31 @@ export declare class PathwaysBuilder<TPathway extends Record<string, unknown> =
|
|
|
187
188
|
* @param handler The function that will process events for this pathway
|
|
188
189
|
* @throws Error if the pathway doesn't exist or already has a handler
|
|
189
190
|
*/
|
|
190
|
-
handle<TPath extends keyof TPathway>(path: TPath, handler: (event: Omit<FlowcoreEvent,
|
|
191
|
+
handle<TPath extends keyof TPathway>(path: TPath, handler: (event: Omit<FlowcoreEvent, "payload"> & {
|
|
191
192
|
payload: TPathway[TPath];
|
|
192
|
-
}) =>
|
|
193
|
+
}) => Promise<void> | void): PathwaysBuilder<TPathway, TWritablePaths>;
|
|
193
194
|
/**
|
|
194
195
|
* Subscribe to pathway events (before or after processing)
|
|
195
196
|
* @param path The pathway to subscribe to
|
|
196
197
|
* @param handler The handler function for the events
|
|
197
198
|
* @param type The event type to subscribe to (before, after, or all)
|
|
198
199
|
*/
|
|
199
|
-
subscribe<TPath extends keyof TPathway>(path: TPath, handler: (event: Omit<FlowcoreEvent,
|
|
200
|
+
subscribe<TPath extends keyof TPathway>(path: TPath, handler: (event: Omit<FlowcoreEvent, "payload"> & {
|
|
200
201
|
payload: TPathway[TPath];
|
|
201
|
-
}) => void, type?: "before" | "after" | "all"):
|
|
202
|
+
}) => void, type?: "before" | "after" | "all"): PathwaysBuilder<TPathway, TWritablePaths>;
|
|
202
203
|
/**
|
|
203
204
|
* Subscribe to errors for a specific pathway
|
|
204
205
|
* @param path The pathway to subscribe to errors for
|
|
205
206
|
* @param handler The handler function that receives the error and event
|
|
206
207
|
*/
|
|
207
|
-
onError<TPath extends keyof TPathway>(path: TPath, handler: (error: Error, event: Omit<FlowcoreEvent,
|
|
208
|
+
onError<TPath extends keyof TPathway>(path: TPath, handler: (error: Error, event: Omit<FlowcoreEvent, "payload"> & {
|
|
208
209
|
payload: TPathway[TPath];
|
|
209
|
-
}) => void):
|
|
210
|
+
}) => void): PathwaysBuilder<TPathway, TWritablePaths>;
|
|
210
211
|
/**
|
|
211
212
|
* Subscribe to errors for all pathways
|
|
212
213
|
* @param handler The handler function that receives the error, event, and pathway name
|
|
213
214
|
*/
|
|
214
|
-
onAnyError(handler: (error: Error, event: FlowcoreEvent, pathway: string) => void):
|
|
215
|
+
onAnyError(handler: (error: Error, event: FlowcoreEvent, pathway: string) => void): PathwaysBuilder<TPathway, TWritablePaths>;
|
|
215
216
|
/**
|
|
216
217
|
* Writes data to a pathway with optional audit metadata
|
|
217
218
|
* @param path The pathway to write to
|
|
@@ -221,6 +222,7 @@ export declare class PathwaysBuilder<TPathway extends Record<string, unknown> =
|
|
|
221
222
|
* @returns A promise that resolves to the event ID(s)
|
|
222
223
|
*/
|
|
223
224
|
write<TPath extends TWritablePaths>(path: TPath, data: TPathway[TPath], metadata?: EventMetadata, options?: PathwayWriteOptions): Promise<string | string[]>;
|
|
225
|
+
writeBatch<TPath extends TWritablePaths>(path: TPath, data: TPathway[TPath][], metadata?: EventMetadata, options?: PathwayWriteOptions): Promise<string | string[]>;
|
|
224
226
|
/**
|
|
225
227
|
* Waits for a specific event to be processed
|
|
226
228
|
*
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"builder.d.ts","sourceRoot":"","sources":["../../src/pathways/builder.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,
|
|
1
|
+
{"version":3,"file":"builder.d.ts","sourceRoot":"","sources":["../../src/pathways/builder.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,MAAM,EAAE,KAAK,OAAO,EAAQ,MAAM,mBAAmB,CAAA;AAEnE,OAAO,KAAK,EAGV,kBAAkB,EACnB,MAAM,gCAAgC,CAAA;AAGvC,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,uBAAuB,CAAA;AAE1D,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,oBAAoB,CAAA;AACnD,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,aAAa,CAAA;AAEzC,OAAO,KAAK,EACV,aAAa,EACb,eAAe,EACf,UAAU,EACV,YAAY,EACZ,mBAAmB,EAInB,eAAe,EAChB,MAAM,YAAY,CAAA;AAsBnB;;;;GAIG;AACH,MAAM,MAAM,SAAS,GAAG,MAAM,GAAG,QAAQ,CAAA;AAEzC;;;;GAIG;AACH,MAAM,MAAM,YAAY,GAAG,CAAC,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE,aAAa,KAAK,IAAI,CAAA;AAEvE;;;GAGG;AACH,MAAM,MAAM,cAAc,GAAG,MAAM,OAAO,CAAC,MAAM,CAAC,CAAA;AAElD;;GAEG;AACH,MAAM,WAAW,uBAAwB,SAAQ,kBAAkB;IACjE;;OAEG;IACH,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAA;CACjC;AAED;;;;;;;;;;;;;GAaG;AACH,qBAAa,eAAe,CAE1B,QAAQ,SAAS,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,EAAE,EAC7C,cAAc,SAAS,MAAM,QAAQ,GAAG,KAAK;IAE7C,OAAO,CAAC,QAAQ,CAAC,QAAQ,CAA2B;IACpD,OAAO,CAAC,QAAQ,CAAC,QAAQ,CAGxB;IACD,OAAO,CAAC,QAAQ,CAAC,gBAAgB,CAGhC;IACD,OAAO,CAAC,QAAQ,CAAC,cAAc,CAG9B;IACD,OAAO,CAAC,QAAQ,CAAC,cAAc,CAI5B;IACH,OAAO,CAAC,QAAQ,CAAC,kBAAkB,CAAyE;IAC5G,OAAO,CAAC,QAAQ,CAAC,OAAO,CAIrB;IACH,OAAO,CAAC,QAAQ,CAAC,YAAY,CAG5B;IACD,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAyE;IACjG,OAAO,CAAC,QAAQ,CAAC,QAAQ,CAAyE;IAClG,OAAO,CAAC,QAAQ,CAAC,QAAQ,CAAuE;IAChG,OAAO,CAAC,QAAQ,CAAC,UAAU,CAAuE;IAClG,OAAO,CAAC,QAAQ,CAAC,WAAW,CAAuE;IACnG,OAAO,CAAC,QAAQ,CAAC,YAAY,CAAiC;IAC9D,OAAO,CAAC,QAAQ,CAAC,qBAAqB,CAA0B;IAChE,OAAO,CAAC,YAAY,CAA2C;IAC/D,OAAO,CAAC,gBAAgB,CAAqC;IAG7D,OAAO,CAAC,YAAY,CAAC,CAAc;IACnC,OAAO,CAAC,cAAc,CAAC,CAAgB;IAGvC,OAAO,CAAC,QAAQ,CAAC,oBAAoB,CAAyB;IAG9D,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAQ;IAG/B,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAQ;IAChC,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAQ;IAC/B,OAAO,CAAC,QAAQ,CAAC,QAAQ,CAAQ;IACjC,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAQ;IAE/B;;;;;;;;;;OAUG;gBACS,EACV,OAAO,EACP,MAAM,EACN,QAAQ,EACR,MAAM,EACN,gBAAgB,EAChB,MAAM,EACN,oBAAoB,GACrB,EAAE;QACD,OAAO,EAAE,MAAM,CAAA;QACf,MAAM,EAAE,MAAM,CAAA;QACd,QAAQ,EAAE,MAAM,CAAA;QAChB,MAAM,EAAE,MAAM,CAAA;QACd,gBAAgB,CAAC,EAAE,MAAM,CAAA;QACzB,MAAM,CAAC,EAAE,MAAM,CAAA;QACf,oBAAoB,CAAC,EAAE,SAAS,CAAA;KACjC;IAsCD;;;;OAIG;IACH,gBAAgB,CAAC,KAAK,EAAE,YAAY,GAAG,eAAe,CAAC,QAAQ,EAAE,cAAc,CAAC;IAMhF;;;;OAIG;IACH,SAAS,CAAC,OAAO,EAAE,YAAY,GAAG,eAAe,CAAC,QAAQ,EAAE,cAAc,CAAC;IAM3E;;;;OAIG;IACH,gBAAgB,CAAC,QAAQ,EAAE,cAAc,GAAG,eAAe,CAAC,QAAQ,EAAE,cAAc,CAAC;IAMrF;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;OAgCG;IACH,uBAAuB,CAAC,SAAS,EAAE,MAAM,EAAE,QAAQ,EAAE,cAAc,GAAG,eAAe,CAAC,QAAQ,EAAE,cAAc,CAAC;IAU/G;;;;OAIG;IACH,sBAAsB,CAAC,SAAS,EAAE,MAAM,GAAG,cAAc,GAAG,SAAS;IAQrE;;;;;OAKG;IACU,OAAO,CAAC,OAAO,EAAE,MAAM,QAAQ,EAAE,IAAI,EAAE,aAAa;IA+IjE;;;;;;;;OAQG;IACH,QAAQ,CACN,CAAC,SAAS,MAAM,EAChB,CAAC,SAAS,MAAM,EAChB,CAAC,SAAS,OAAO,EACjB,CAAC,SAAS,OAAO,GAAG,IAAI,EAExB,QAAQ,EAAE,eAAe,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,GAAG;QAAE,QAAQ,CAAC,EAAE,CAAC,CAAC;QAAC,UAAU,CAAC,EAAE,MAAM,CAAC;QAAC,YAAY,CAAC,EAAE,MAAM,CAAA;KAAE,GAChG,eAAe,CAChB,QAAQ,GAAG,MAAM,CAAC,UAAU,CAAC,CAAC,EAAE,CAAC,CAAC,EAAE,MAAM,CAAC,CAAC,CAAC,CAAC,EAC9C,cAAc,GAAG,eAAe,CAAC,UAAU,CAAC,CAAC,EAAE,CAAC,CAAC,EAAE,CAAC,CAAC,CACtD;IAgED;;;;;;OAMG;IACH,GAAG,CAAC,KAAK,SAAS,MAAM,QAAQ,EAAE,IAAI,EAAE,KAAK,GAAG,QAAQ,CAAC,KAAK,CAAC;IAK/D;;;;;;;;;;OAUG;IACH,MAAM,CAAC,KAAK,SAAS,MAAM,QAAQ,EACjC,IAAI,EAAE,KAAK,EACX,OAAO,EAAE,CAAC,KAAK,EAAE,IAAI,CAAC,aAAa,EAAE,SAAS,CAAC,GAAG;QAAE,OAAO,EAAE,QAAQ,CAAC,KAAK,CAAC,CAAA;KAAE,KAAK,OAAO,CAAC,IAAI,CAAC,GAAG,IAAI,GACtG,eAAe,CAAC,QAAQ,EAAE,cAAc,CAAC;IAsB5C;;;;;OAKG;IACH,SAAS,CAAC,KAAK,SAAS,MAAM,QAAQ,EACpC,IAAI,EAAE,KAAK,EACX,OAAO,EAAE,CAAC,KAAK,EAAE,IAAI,CAAC,aAAa,EAAE,SAAS,CAAC,GAAG;QAAE,OAAO,EAAE,QAAQ,CAAC,KAAK,CAAC,CAAA;KAAE,KAAK,IAAI,EACvF,IAAI,GAAE,QAAQ,GAAG,OAAO,GAAG,KAAgB,GAC1C,eAAe,CAAC,QAAQ,EAAE,cAAc,CAAC;IA8B5C;;;;OAIG;IACH,OAAO,CAAC,KAAK,SAAS,MAAM,QAAQ,EAClC,IAAI,EAAE,KAAK,EACX,OAAO,EAAE,CAAC,KAAK,EAAE,KAAK,EAAE,KAAK,EAAE,IAAI,CAAC,aAAa,EAAE,SAAS,CAAC,GAAG;QAAE,OAAO,EAAE,QAAQ,CAAC,KAAK,CAAC,CAAA;KAAE,KAAK,IAAI,GACpG,eAAe,CAAC,QAAQ,EAAE,cAAc,CAAC;IAqB5C;;;OAGG;IACH,UAAU,CACR,OAAO,EAAE,CAAC,KAAK,EAAE,KAAK,EAAE,KAAK,EAAE,aAAa,EAAE,OAAO,EAAE,MAAM,KAAK,IAAI,GACrE,eAAe,CAAC,QAAQ,EAAE,cAAc,CAAC;IAQ5C;;;;;;;OAOG;IACG,KAAK,CAAC,KAAK,SAAS,cAAc,EACtC,IAAI,EAAE,KAAK,EACX,IAAI,EAAE,QAAQ,CAAC,KAAK,CAAC,EACrB,QAAQ,CAAC,EAAE,aAAa,EACxB,OAAO,CAAC,EAAE,mBAAmB,GAC5B,OAAO,CAAC,MAAM,GAAG,MAAM,EAAE,CAAC;IA4HvB,UAAU,CAAC,KAAK,SAAS,cAAc,EAC3C,IAAI,EAAE,KAAK,EACX,IAAI,EAAE,QAAQ,CAAC,KAAK,CAAC,EAAE,EACvB,QAAQ,CAAC,EAAE,aAAa,EACxB,OAAO,CAAC,EAAE,mBAAmB,GAC5B,OAAO,CAAC,MAAM,GAAG,MAAM,EAAE,CAAC;IAsH7B;;;;;;;;;;OAUG;YACW,2BAA2B;CA4C1C"}
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.PathwaysBuilder = void 0;
|
|
4
|
+
const typebox_1 = require("@sinclair/typebox");
|
|
4
5
|
const value_1 = require("@sinclair/typebox/value");
|
|
5
6
|
const rxjs_1 = require("rxjs");
|
|
6
7
|
const flowcore_transformer_core_sdk_js_1 = require("../compatibility/flowcore-transformer-core.sdk.js");
|
|
@@ -91,6 +92,12 @@ class PathwaysBuilder {
|
|
|
91
92
|
writable: true,
|
|
92
93
|
value: {}
|
|
93
94
|
});
|
|
95
|
+
Object.defineProperty(this, "batchWriters", {
|
|
96
|
+
enumerable: true,
|
|
97
|
+
configurable: true,
|
|
98
|
+
writable: true,
|
|
99
|
+
value: {}
|
|
100
|
+
});
|
|
94
101
|
Object.defineProperty(this, "schemas", {
|
|
95
102
|
enumerable: true,
|
|
96
103
|
configurable: true,
|
|
@@ -207,11 +214,11 @@ class PathwaysBuilder {
|
|
|
207
214
|
if (sessionUserResolvers) {
|
|
208
215
|
this.sessionUserResolvers = sessionUserResolvers;
|
|
209
216
|
}
|
|
210
|
-
this.logger.debug(
|
|
217
|
+
this.logger.debug("Initializing PathwaysBuilder", {
|
|
211
218
|
baseUrl,
|
|
212
219
|
tenant,
|
|
213
220
|
dataCore,
|
|
214
|
-
pathwayTimeoutMs
|
|
221
|
+
pathwayTimeoutMs,
|
|
215
222
|
});
|
|
216
223
|
this.webhookBuilderFactory = new flowcore_transformer_core_sdk_js_1.WebhookBuilder({
|
|
217
224
|
baseUrl,
|
|
@@ -234,7 +241,7 @@ class PathwaysBuilder {
|
|
|
234
241
|
* @returns The PathwaysBuilder instance with custom state configured
|
|
235
242
|
*/
|
|
236
243
|
withPathwayState(state) {
|
|
237
|
-
this.logger.debug(
|
|
244
|
+
this.logger.debug("Setting custom pathway state");
|
|
238
245
|
this.pathwayState = state;
|
|
239
246
|
return this;
|
|
240
247
|
}
|
|
@@ -244,7 +251,7 @@ class PathwaysBuilder {
|
|
|
244
251
|
* @returns The PathwaysBuilder instance with audit configured
|
|
245
252
|
*/
|
|
246
253
|
withAudit(handler) {
|
|
247
|
-
this.logger.debug(
|
|
254
|
+
this.logger.debug("Configuring audit functionality");
|
|
248
255
|
this.auditHandler = handler;
|
|
249
256
|
return this;
|
|
250
257
|
}
|
|
@@ -254,7 +261,7 @@ class PathwaysBuilder {
|
|
|
254
261
|
* @returns The PathwaysBuilder instance with custom user ID resolver configured
|
|
255
262
|
*/
|
|
256
263
|
withUserResolver(resolver) {
|
|
257
|
-
this.logger.debug(
|
|
264
|
+
this.logger.debug("Configuring user resolver");
|
|
258
265
|
this.userIdResolver = resolver;
|
|
259
266
|
return this;
|
|
260
267
|
}
|
|
@@ -293,9 +300,9 @@ class PathwaysBuilder {
|
|
|
293
300
|
*/
|
|
294
301
|
withSessionUserResolver(sessionId, resolver) {
|
|
295
302
|
if (!this.sessionUserResolvers) {
|
|
296
|
-
throw new Error(
|
|
303
|
+
throw new Error("Session user resolvers not configured");
|
|
297
304
|
}
|
|
298
|
-
this.logger.debug(
|
|
305
|
+
this.logger.debug("Configuring session-specific user resolver", { sessionId });
|
|
299
306
|
this.sessionUserResolvers.set(sessionId, resolver, DEFAULT_SESSION_USER_RESOLVER_TTL_MS);
|
|
300
307
|
return this;
|
|
301
308
|
}
|
|
@@ -321,7 +328,7 @@ class PathwaysBuilder {
|
|
|
321
328
|
const pathwayStr = String(pathway);
|
|
322
329
|
this.logger.debug(`Processing pathway event`, {
|
|
323
330
|
pathway: pathwayStr,
|
|
324
|
-
eventId: data.eventId
|
|
331
|
+
eventId: data.eventId,
|
|
325
332
|
});
|
|
326
333
|
if (!this.pathways[pathway]) {
|
|
327
334
|
const error = `Pathway ${pathwayStr} not found`;
|
|
@@ -348,7 +355,7 @@ class PathwaysBuilder {
|
|
|
348
355
|
if (this.auditHandler) {
|
|
349
356
|
this.logger.debug(`Calling audit handler for pathway`, {
|
|
350
357
|
pathway: pathwayStr,
|
|
351
|
-
eventId: data.eventId
|
|
358
|
+
eventId: data.eventId,
|
|
352
359
|
});
|
|
353
360
|
this.auditHandler(pathwayStr, data);
|
|
354
361
|
}
|
|
@@ -358,7 +365,7 @@ class PathwaysBuilder {
|
|
|
358
365
|
const retryDelayMs = this.retryDelays[pathway] ?? DEFAULT_RETRY_DELAY_MS;
|
|
359
366
|
this.logger.debug(`Emitting 'before' event`, {
|
|
360
367
|
pathway: pathwayStr,
|
|
361
|
-
eventId: data.eventId
|
|
368
|
+
eventId: data.eventId,
|
|
362
369
|
});
|
|
363
370
|
this.beforeObservable[pathway].next(data);
|
|
364
371
|
while (true) {
|
|
@@ -366,7 +373,7 @@ class PathwaysBuilder {
|
|
|
366
373
|
this.logger.debug(`Executing handler for pathway`, {
|
|
367
374
|
pathway: pathwayStr,
|
|
368
375
|
eventId: data.eventId,
|
|
369
|
-
attempt: retryCount + 1
|
|
376
|
+
attempt: retryCount + 1,
|
|
370
377
|
});
|
|
371
378
|
// Execute the handler
|
|
372
379
|
const handle = this.handlers[pathway](data);
|
|
@@ -374,13 +381,13 @@ class PathwaysBuilder {
|
|
|
374
381
|
// If successful, emit success event and mark as processed
|
|
375
382
|
this.logger.debug(`Handler executed successfully, emitting 'after' event`, {
|
|
376
383
|
pathway: pathwayStr,
|
|
377
|
-
eventId: data.eventId
|
|
384
|
+
eventId: data.eventId,
|
|
378
385
|
});
|
|
379
386
|
this.afterObservers[pathway].next(data);
|
|
380
387
|
await this.pathwayState.setProcessed(data.eventId);
|
|
381
388
|
this.logger.info(`Successfully processed pathway event`, {
|
|
382
389
|
pathway: pathwayStr,
|
|
383
|
-
eventId: data.eventId
|
|
390
|
+
eventId: data.eventId,
|
|
384
391
|
});
|
|
385
392
|
return;
|
|
386
393
|
}
|
|
@@ -391,7 +398,7 @@ class PathwaysBuilder {
|
|
|
391
398
|
pathway: pathwayStr,
|
|
392
399
|
eventId: data.eventId,
|
|
393
400
|
retryCount,
|
|
394
|
-
maxRetries
|
|
401
|
+
maxRetries,
|
|
395
402
|
});
|
|
396
403
|
// Emit error event with both error and event data
|
|
397
404
|
this.errorObservers[pathway].next({ event: data, error: errorObj });
|
|
@@ -399,7 +406,7 @@ class PathwaysBuilder {
|
|
|
399
406
|
this.globalErrorSubject.next({
|
|
400
407
|
pathway: pathwayStr,
|
|
401
408
|
event: data,
|
|
402
|
-
error: errorObj
|
|
409
|
+
error: errorObj,
|
|
403
410
|
});
|
|
404
411
|
// Check if we should retry
|
|
405
412
|
if (retryCount < maxRetries) {
|
|
@@ -410,10 +417,10 @@ class PathwaysBuilder {
|
|
|
410
417
|
eventId: data.eventId,
|
|
411
418
|
attempt: retryCount,
|
|
412
419
|
maxRetries,
|
|
413
|
-
nextDelay
|
|
420
|
+
nextDelay,
|
|
414
421
|
});
|
|
415
422
|
// Wait for delay before retrying
|
|
416
|
-
await new Promise(resolve => setTimeout(resolve, nextDelay));
|
|
423
|
+
await new Promise((resolve) => setTimeout(resolve, nextDelay));
|
|
417
424
|
continue;
|
|
418
425
|
}
|
|
419
426
|
// If we've exhausted retries, mark as processed to avoid hanging
|
|
@@ -421,7 +428,7 @@ class PathwaysBuilder {
|
|
|
421
428
|
pathway: pathwayStr,
|
|
422
429
|
eventId: data.eventId,
|
|
423
430
|
retryCount,
|
|
424
|
-
maxRetries
|
|
431
|
+
maxRetries,
|
|
425
432
|
});
|
|
426
433
|
await this.pathwayState.setProcessed(data.eventId);
|
|
427
434
|
throw error;
|
|
@@ -432,7 +439,7 @@ class PathwaysBuilder {
|
|
|
432
439
|
// No handler, just emit events and mark as processed
|
|
433
440
|
this.logger.debug(`No handler for pathway, emitting events and marking as processed`, {
|
|
434
441
|
pathway: pathwayStr,
|
|
435
|
-
eventId: data.eventId
|
|
442
|
+
eventId: data.eventId,
|
|
436
443
|
});
|
|
437
444
|
this.beforeObservable[pathway].next(data);
|
|
438
445
|
this.afterObservers[pathway].next(data);
|
|
@@ -459,9 +466,9 @@ class PathwaysBuilder {
|
|
|
459
466
|
isFilePathway: contract.isFilePathway,
|
|
460
467
|
timeoutMs: contract.timeoutMs,
|
|
461
468
|
maxRetries: contract.maxRetries,
|
|
462
|
-
retryDelayMs: contract.retryDelayMs
|
|
463
|
-
})
|
|
464
|
-
|
|
469
|
+
retryDelayMs: contract.retryDelayMs,
|
|
470
|
+
}) // deno-lint-ignore no-explicit-any
|
|
471
|
+
;
|
|
465
472
|
this.pathways[path] = true;
|
|
466
473
|
this.beforeObservable[path] = new rxjs_1.Subject();
|
|
467
474
|
this.afterObservers[path] = new rxjs_1.Subject();
|
|
@@ -475,6 +482,8 @@ class PathwaysBuilder {
|
|
|
475
482
|
else {
|
|
476
483
|
this.writers[path] = this.webhookBuilderFactory()
|
|
477
484
|
.buildWebhook(contract.flowType, contract.eventType).send;
|
|
485
|
+
this.batchWriters[path] = this.webhookBuilderFactory()
|
|
486
|
+
.buildWebhook(contract.flowType, contract.eventType).sendBatch;
|
|
478
487
|
}
|
|
479
488
|
}
|
|
480
489
|
if (contract.timeoutMs) {
|
|
@@ -492,7 +501,7 @@ class PathwaysBuilder {
|
|
|
492
501
|
pathway: path,
|
|
493
502
|
flowType: contract.flowType,
|
|
494
503
|
eventType: contract.eventType,
|
|
495
|
-
writable
|
|
504
|
+
writable,
|
|
496
505
|
});
|
|
497
506
|
return this;
|
|
498
507
|
}
|
|
@@ -534,6 +543,7 @@ class PathwaysBuilder {
|
|
|
534
543
|
}
|
|
535
544
|
this.handlers[path] = handler;
|
|
536
545
|
this.logger.info(`Handler set for pathway`, { pathway: pathStr });
|
|
546
|
+
return this;
|
|
537
547
|
}
|
|
538
548
|
/**
|
|
539
549
|
* Subscribe to pathway events (before or after processing)
|
|
@@ -560,8 +570,9 @@ class PathwaysBuilder {
|
|
|
560
570
|
}
|
|
561
571
|
this.logger.info(`Subscription to pathway events set up`, {
|
|
562
572
|
pathway: pathStr,
|
|
563
|
-
type
|
|
573
|
+
type,
|
|
564
574
|
});
|
|
575
|
+
return this;
|
|
565
576
|
}
|
|
566
577
|
/**
|
|
567
578
|
* Subscribe to errors for a specific pathway
|
|
@@ -581,6 +592,7 @@ class PathwaysBuilder {
|
|
|
581
592
|
const typedHandler = (payload) => handler(payload.error, payload.event);
|
|
582
593
|
this.errorObservers[path].subscribe(typedHandler);
|
|
583
594
|
this.logger.info(`Error handler set for pathway`, { pathway: pathStr });
|
|
595
|
+
return this;
|
|
584
596
|
}
|
|
585
597
|
/**
|
|
586
598
|
* Subscribe to errors for all pathways
|
|
@@ -590,6 +602,7 @@ class PathwaysBuilder {
|
|
|
590
602
|
this.logger.debug(`Subscribing to all pathway errors`);
|
|
591
603
|
this.globalErrorSubject.subscribe(({ pathway, event, error }) => handler(error, event, pathway));
|
|
592
604
|
this.logger.debug(`Subscribed to all pathway errors`);
|
|
605
|
+
return this;
|
|
593
606
|
}
|
|
594
607
|
/**
|
|
595
608
|
* Writes data to a pathway with optional audit metadata
|
|
@@ -606,8 +619,8 @@ class PathwaysBuilder {
|
|
|
606
619
|
metadata,
|
|
607
620
|
options: {
|
|
608
621
|
fireAndForget: options?.fireAndForget,
|
|
609
|
-
sessionId: options?.sessionId
|
|
610
|
-
}
|
|
622
|
+
sessionId: options?.sessionId,
|
|
623
|
+
},
|
|
611
624
|
});
|
|
612
625
|
if (!this.pathways[path]) {
|
|
613
626
|
const error = `Pathway ${pathStr} not found`;
|
|
@@ -624,7 +637,7 @@ class PathwaysBuilder {
|
|
|
624
637
|
const errorMessage = `Invalid data for pathway ${pathStr}`;
|
|
625
638
|
this.logger.error(errorMessage, new Error(errorMessage), {
|
|
626
639
|
pathway: pathStr,
|
|
627
|
-
schema: schema.toString()
|
|
640
|
+
schema: schema.toString(),
|
|
628
641
|
});
|
|
629
642
|
throw new Error(errorMessage);
|
|
630
643
|
}
|
|
@@ -640,13 +653,13 @@ class PathwaysBuilder {
|
|
|
640
653
|
this.logger.debug(`Using session-specific user resolver`, {
|
|
641
654
|
pathway: pathStr,
|
|
642
655
|
sessionId: options.sessionId,
|
|
643
|
-
userId
|
|
656
|
+
userId,
|
|
644
657
|
});
|
|
645
658
|
}
|
|
646
659
|
catch (error) {
|
|
647
660
|
this.logger.error(`Error resolving session user ID`, error instanceof Error ? error : new Error(String(error)), {
|
|
648
661
|
pathway: pathStr,
|
|
649
|
-
sessionId: options.sessionId
|
|
662
|
+
sessionId: options.sessionId,
|
|
650
663
|
});
|
|
651
664
|
}
|
|
652
665
|
}
|
|
@@ -664,7 +677,7 @@ class PathwaysBuilder {
|
|
|
664
677
|
this.logger.debug(`Adding audit metadata`, {
|
|
665
678
|
pathway: pathStr,
|
|
666
679
|
auditMode,
|
|
667
|
-
userId
|
|
680
|
+
userId,
|
|
668
681
|
});
|
|
669
682
|
if (userId) {
|
|
670
683
|
// Add appropriate audit metadata based on mode
|
|
@@ -691,15 +704,113 @@ class PathwaysBuilder {
|
|
|
691
704
|
this.logger.info(`Successfully wrote to pathway`, {
|
|
692
705
|
pathway: pathStr,
|
|
693
706
|
eventIds: Array.isArray(eventIds) ? eventIds : [eventIds],
|
|
694
|
-
fireAndForget: options?.fireAndForget
|
|
707
|
+
fireAndForget: options?.fireAndForget,
|
|
695
708
|
});
|
|
696
709
|
if (!options?.fireAndForget) {
|
|
697
710
|
this.logger.debug(`Waiting for pathway to be processed`, {
|
|
698
711
|
pathway: pathStr,
|
|
699
|
-
eventIds: Array.isArray(eventIds) ? eventIds : [eventIds]
|
|
712
|
+
eventIds: Array.isArray(eventIds) ? eventIds : [eventIds],
|
|
700
713
|
});
|
|
701
714
|
await Promise.all(Array.isArray(eventIds)
|
|
702
|
-
? eventIds.map(id => this.waitForPathwayToBeProcessed(id))
|
|
715
|
+
? eventIds.map((id) => this.waitForPathwayToBeProcessed(id))
|
|
716
|
+
: [this.waitForPathwayToBeProcessed(eventIds)]);
|
|
717
|
+
}
|
|
718
|
+
return eventIds;
|
|
719
|
+
}
|
|
720
|
+
async writeBatch(path, data, metadata, options) {
|
|
721
|
+
const pathStr = String(path);
|
|
722
|
+
this.logger.debug(`Writing batch to pathway`, {
|
|
723
|
+
pathway: pathStr,
|
|
724
|
+
metadata,
|
|
725
|
+
options: {
|
|
726
|
+
fireAndForget: options?.fireAndForget,
|
|
727
|
+
sessionId: options?.sessionId,
|
|
728
|
+
},
|
|
729
|
+
});
|
|
730
|
+
if (!this.pathways[path]) {
|
|
731
|
+
const error = `Pathway ${pathStr} not found`;
|
|
732
|
+
this.logger.error(error);
|
|
733
|
+
throw new Error(error);
|
|
734
|
+
}
|
|
735
|
+
if (!this.writable[path]) {
|
|
736
|
+
const error = `Pathway ${pathStr} is not writable`;
|
|
737
|
+
this.logger.error(error);
|
|
738
|
+
throw new Error(error);
|
|
739
|
+
}
|
|
740
|
+
const schema = this.schemas[path];
|
|
741
|
+
if (!value_1.Value.Check(typebox_1.Type.Array(schema), data)) {
|
|
742
|
+
const errorMessage = `Invalid batch data for pathway ${pathStr}`;
|
|
743
|
+
this.logger.error(errorMessage, new Error(errorMessage), {
|
|
744
|
+
pathway: pathStr,
|
|
745
|
+
schema: schema.toString(),
|
|
746
|
+
});
|
|
747
|
+
throw new Error(errorMessage);
|
|
748
|
+
}
|
|
749
|
+
// Create a copy of the metadata to avoid modifying the original
|
|
750
|
+
const finalMetadata = metadata ? { ...metadata } : {};
|
|
751
|
+
// Check for session-specific user resolver
|
|
752
|
+
let userId;
|
|
753
|
+
if (options?.sessionId) {
|
|
754
|
+
const sessionUserResolver = this.getSessionUserResolver(options.sessionId);
|
|
755
|
+
if (sessionUserResolver) {
|
|
756
|
+
try {
|
|
757
|
+
userId = await sessionUserResolver();
|
|
758
|
+
this.logger.debug(`Using session-specific user resolver`, {
|
|
759
|
+
pathway: pathStr,
|
|
760
|
+
sessionId: options.sessionId,
|
|
761
|
+
userId,
|
|
762
|
+
});
|
|
763
|
+
}
|
|
764
|
+
catch (error) {
|
|
765
|
+
this.logger.error(`Error resolving session user ID`, error instanceof Error ? error : new Error(String(error)), {
|
|
766
|
+
pathway: pathStr,
|
|
767
|
+
sessionId: options.sessionId,
|
|
768
|
+
});
|
|
769
|
+
}
|
|
770
|
+
}
|
|
771
|
+
}
|
|
772
|
+
// Process audit metadata if audit is configured
|
|
773
|
+
if (this.userIdResolver) {
|
|
774
|
+
// Only use global resolver if we don't already have a user ID from a session resolver
|
|
775
|
+
if (!userId) {
|
|
776
|
+
this.logger.debug(`Resolving user ID for audit metadata`, { pathway: pathStr });
|
|
777
|
+
userId = await this.userIdResolver();
|
|
778
|
+
}
|
|
779
|
+
}
|
|
780
|
+
// Determine the audit mode: default is "user" unless explicitly specified as "system"
|
|
781
|
+
const auditMode = options?.auditMode ?? "user";
|
|
782
|
+
this.logger.debug(`Adding audit metadata`, {
|
|
783
|
+
pathway: pathStr,
|
|
784
|
+
auditMode,
|
|
785
|
+
userId,
|
|
786
|
+
});
|
|
787
|
+
if (userId) {
|
|
788
|
+
// Add appropriate audit metadata based on mode
|
|
789
|
+
if (auditMode === "system") {
|
|
790
|
+
finalMetadata["audit/user-id"] = "system";
|
|
791
|
+
finalMetadata["audit/on-behalf-of"] = userId;
|
|
792
|
+
finalMetadata["audit/mode"] = "system";
|
|
793
|
+
}
|
|
794
|
+
else {
|
|
795
|
+
finalMetadata["audit/user-id"] = userId;
|
|
796
|
+
finalMetadata["audit/mode"] = "user"; // Always set mode for user
|
|
797
|
+
}
|
|
798
|
+
}
|
|
799
|
+
let eventIds = [];
|
|
800
|
+
this.logger.debug(`Writing batch webhook data to pathway`, { pathway: pathStr });
|
|
801
|
+
eventIds = await this.batchWriters[path](data, finalMetadata, options);
|
|
802
|
+
this.logger.info(`Successfully wrote to pathway`, {
|
|
803
|
+
pathway: pathStr,
|
|
804
|
+
eventIds: Array.isArray(eventIds) ? eventIds : [eventIds],
|
|
805
|
+
fireAndForget: options?.fireAndForget,
|
|
806
|
+
});
|
|
807
|
+
if (!options?.fireAndForget) {
|
|
808
|
+
this.logger.debug(`Waiting for pathway to be processed`, {
|
|
809
|
+
pathway: pathStr,
|
|
810
|
+
eventIds: Array.isArray(eventIds) ? eventIds : [eventIds],
|
|
811
|
+
});
|
|
812
|
+
await Promise.all(Array.isArray(eventIds)
|
|
813
|
+
? eventIds.map((id) => this.waitForPathwayToBeProcessed(id))
|
|
703
814
|
: [this.waitForPathwayToBeProcessed(eventIds)]);
|
|
704
815
|
}
|
|
705
816
|
return eventIds;
|
|
@@ -720,7 +831,7 @@ class PathwaysBuilder {
|
|
|
720
831
|
const timeoutMs = this.timeouts[eventId] ?? this.pathwayTimeoutMs;
|
|
721
832
|
this.logger.debug(`Waiting for event to be processed`, {
|
|
722
833
|
eventId,
|
|
723
|
-
timeoutMs
|
|
834
|
+
timeoutMs,
|
|
724
835
|
});
|
|
725
836
|
let attempts = 0;
|
|
726
837
|
while (!(await this.pathwayState.isProcessed(eventId))) {
|
|
@@ -732,7 +843,7 @@ class PathwaysBuilder {
|
|
|
732
843
|
eventId,
|
|
733
844
|
timeoutMs,
|
|
734
845
|
elapsedTime,
|
|
735
|
-
attempts
|
|
846
|
+
attempts,
|
|
736
847
|
});
|
|
737
848
|
throw new Error(errorMessage);
|
|
738
849
|
}
|
|
@@ -741,7 +852,7 @@ class PathwaysBuilder {
|
|
|
741
852
|
eventId,
|
|
742
853
|
elapsedTime,
|
|
743
854
|
attempts,
|
|
744
|
-
timeoutMs
|
|
855
|
+
timeoutMs,
|
|
745
856
|
});
|
|
746
857
|
}
|
|
747
858
|
await new Promise((resolve) => setTimeout(resolve, 100));
|
|
@@ -749,7 +860,7 @@ class PathwaysBuilder {
|
|
|
749
860
|
this.logger.debug(`Event has been processed`, {
|
|
750
861
|
eventId,
|
|
751
862
|
elapsedTime: Date.now() - startTime,
|
|
752
|
-
attempts
|
|
863
|
+
attempts,
|
|
753
864
|
});
|
|
754
865
|
}
|
|
755
866
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"postgres-pathway-state.d.ts","sourceRoot":"","sources":["../../../src/pathways/postgres/postgres-pathway-state.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,aAAa,
|
|
1
|
+
{"version":3,"file":"postgres-pathway-state.d.ts","sourceRoot":"","sources":["../../../src/pathways/postgres/postgres-pathway-state.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,aAAa,CAAA;AAI/C;;GAEG;AACH,MAAM,WAAW,0CAA0C;IACzD,gHAAgH;IAChH,gBAAgB,EAAE,MAAM,CAAA;IAExB,yEAAyE;IACzE,IAAI,CAAC,EAAE,KAAK,CAAA;IACZ,IAAI,CAAC,EAAE,KAAK,CAAA;IACZ,IAAI,CAAC,EAAE,KAAK,CAAA;IACZ,QAAQ,CAAC,EAAE,KAAK,CAAA;IAChB,QAAQ,CAAC,EAAE,KAAK,CAAA;IAChB,GAAG,CAAC,EAAE,KAAK,CAAA;IAEX,sEAAsE;IACtE,SAAS,CAAC,EAAE,MAAM,CAAA;IAClB,6EAA6E;IAC7E,KAAK,CAAC,EAAE,MAAM,CAAA;CACf;AAED;;GAEG;AACH,MAAM,WAAW,oCAAoC;IACnD,uDAAuD;IACvD,gBAAgB,CAAC,EAAE,KAAK,CAAA;IAExB,iCAAiC;IACjC,IAAI,EAAE,MAAM,CAAA;IACZ,6BAA6B;IAC7B,IAAI,EAAE,MAAM,CAAA;IACZ,0BAA0B;IAC1B,IAAI,EAAE,MAAM,CAAA;IACZ,0BAA0B;IAC1B,QAAQ,EAAE,MAAM,CAAA;IAChB,+BAA+B;IAC/B,QAAQ,EAAE,MAAM,CAAA;IAChB,4CAA4C;IAC5C,GAAG,CAAC,EAAE,OAAO,CAAA;IAEb,sEAAsE;IACtE,SAAS,CAAC,EAAE,MAAM,CAAA;IAClB,6EAA6E;IAC7E,KAAK,CAAC,EAAE,MAAM,CAAA;CACf;AAED;;;;;;GAMG;AACH,MAAM,MAAM,0BAA0B,GAClC,0CAA0C,GAC1C,oCAAoC,CAAA;AAExC;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA8CG;AACH,qBAAa,oBAAqB,YAAW,YAAY;IA0C3C,OAAO,CAAC,MAAM;IAzC1B;;;OAGG;IACH,OAAO,CAAC,MAAM,CAAC,QAAQ,CAAC,cAAc,CAAgB;IAEtD;;;OAGG;IACH,OAAO,CAAC,MAAM,CAAC,QAAQ,CAAC,kBAAkB,CAAkB;IAE5D;;;OAGG;IACH,OAAO,CAAC,QAAQ,CAAiB;IAEjC;;;OAGG;IACH,OAAO,CAAC,SAAS,CAAQ;IAEzB;;;OAGG;IACH,OAAO,CAAC,KAAK,CAAQ;IAErB;;;OAGG;IACH,OAAO,CAAC,WAAW,CAAQ;IAE3B;;;;OAIG;gBACiB,MAAM,EAAE,0BAA0B;IAMtD;;;;;OAKG;YACW,UAAU;IAuDxB;;;;;;;;;;;;;;;;;;;;;;;;;;;OA2BG;IACG,WAAW,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC;IAiBpD;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;OAkCG;IACG,YAAY,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAkBlD;;;;;OAKG;YACW,cAAc;IAQ5B;;;;OAIG;IACG,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC;CAK7B;AAED;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA2CG;AACH,wBAAgB,0BAA0B,CAAC,MAAM,EAAE,0BAA0B,GAAG,oBAAoB,CAGnG"}
|
|
@@ -118,10 +118,10 @@ class PostgresPathwayState {
|
|
|
118
118
|
return;
|
|
119
119
|
}
|
|
120
120
|
// Create adapter using either connection string or individual parameters
|
|
121
|
-
if (
|
|
121
|
+
if ("connectionString" in this.config && this.config.connectionString) {
|
|
122
122
|
// Use connection string if provided
|
|
123
123
|
this.postgres = await (0, postgres_adapter_js_1.createPostgresAdapter)({
|
|
124
|
-
connectionString: this.config.connectionString
|
|
124
|
+
connectionString: this.config.connectionString,
|
|
125
125
|
});
|
|
126
126
|
}
|
|
127
127
|
else {
|
|
@@ -136,19 +136,29 @@ class PostgresPathwayState {
|
|
|
136
136
|
ssl: this.config.ssl,
|
|
137
137
|
});
|
|
138
138
|
}
|
|
139
|
-
//
|
|
140
|
-
await this.postgres.
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
expires_at TIMESTAMP WITH TIME ZONE NOT NULL
|
|
139
|
+
// Check if the table exists
|
|
140
|
+
const tableExists = await this.postgres.query(`
|
|
141
|
+
SELECT EXISTS (
|
|
142
|
+
SELECT 1
|
|
143
|
+
FROM information_schema.tables
|
|
144
|
+
WHERE table_name = $1
|
|
146
145
|
)
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
146
|
+
`, [this.tableName]);
|
|
147
|
+
if (!tableExists[0]?.exists) {
|
|
148
|
+
// Create table if it doesn't exist
|
|
149
|
+
await this.postgres.execute(`
|
|
150
|
+
CREATE TABLE IF NOT EXISTS ${this.tableName} (
|
|
151
|
+
event_id TEXT PRIMARY KEY,
|
|
152
|
+
processed BOOLEAN NOT NULL,
|
|
153
|
+
created_at TIMESTAMP WITH TIME ZONE DEFAULT CURRENT_TIMESTAMP,
|
|
154
|
+
expires_at TIMESTAMP WITH TIME ZONE NOT NULL
|
|
155
|
+
)
|
|
156
|
+
`);
|
|
157
|
+
// Create index on expires_at to help with cleanup
|
|
158
|
+
await this.postgres.execute(`
|
|
159
|
+
CREATE INDEX IF NOT EXISTS ${this.tableName}_expires_at_idx ON ${this.tableName} (expires_at)
|
|
160
|
+
`);
|
|
161
|
+
}
|
|
152
162
|
this.initialized = true;
|
|
153
163
|
}
|
|
154
164
|
/**
|
|
@@ -231,9 +241,9 @@ class PostgresPathwayState {
|
|
|
231
241
|
await this.postgres.execute(`
|
|
232
242
|
INSERT INTO ${this.tableName} (event_id, processed, expires_at)
|
|
233
243
|
VALUES ($1, TRUE, NOW() + interval '${Math.floor(this.ttlMs / 1000)} seconds')
|
|
234
|
-
ON CONFLICT (event_id)
|
|
235
|
-
DO UPDATE SET
|
|
236
|
-
processed = TRUE,
|
|
244
|
+
ON CONFLICT (event_id)
|
|
245
|
+
DO UPDATE SET
|
|
246
|
+
processed = TRUE,
|
|
237
247
|
expires_at = NOW() + interval '${Math.floor(this.ttlMs / 1000)} seconds'
|
|
238
248
|
`, [eventId]);
|
|
239
249
|
}
|
|
@@ -89,6 +89,11 @@ export interface EventMetadata extends Record<string, unknown> {
|
|
|
89
89
|
* @template EventPayload The type of the event payload
|
|
90
90
|
*/
|
|
91
91
|
export type SendWebhook<EventPayload> = (payload: EventPayload, metadata?: EventMetadata, options?: WebhookSendOptions) => Promise<string>;
|
|
92
|
+
/**
|
|
93
|
+
* Function type for sending batch events to a webhook
|
|
94
|
+
* @template EventPayload The type of the event payload
|
|
95
|
+
*/
|
|
96
|
+
export type SendWebhookBatch<EventPayload> = (payload: EventPayload[], metadata?: EventMetadata, options?: WebhookSendOptions) => Promise<string[]>;
|
|
92
97
|
/**
|
|
93
98
|
* Function type for sending a file to a webhook
|
|
94
99
|
*/
|
|
@@ -108,12 +113,12 @@ export type PathwayState = {
|
|
|
108
113
|
* @param eventId The ID of the event to check
|
|
109
114
|
* @returns Boolean indicating if the event has been processed
|
|
110
115
|
*/
|
|
111
|
-
isProcessed: (eventId: string) =>
|
|
116
|
+
isProcessed: (eventId: string) => boolean | Promise<boolean>;
|
|
112
117
|
/**
|
|
113
118
|
* Marks an event as processed
|
|
114
119
|
* @param eventId The ID of the event to mark as processed
|
|
115
120
|
*/
|
|
116
|
-
setProcessed: (eventId: string) =>
|
|
121
|
+
setProcessed: (eventId: string) => void | Promise<void>;
|
|
117
122
|
};
|
|
118
123
|
/**
|
|
119
124
|
* Options for pathway writes, extending WebhookSendOptions
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/pathways/types.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,mBAAmB,CAAA;AAChD,OAAO,KAAK,EAAE,eAAe,EAAE,kBAAkB,EAAE,MAAM,gCAAgC,CAAA;AAEzF;;;GAGG;AACH,KAAK,uBAAuB,CAAC,CAAC,SAAS,MAAM,IAAI,CAAC,GAAG;IACnD,QAAQ,CAAC,yBAAyB,
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/pathways/types.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,mBAAmB,CAAA;AAChD,OAAO,KAAK,EAAE,eAAe,EAAE,kBAAkB,EAAE,MAAM,gCAAgC,CAAA;AAEzF;;;GAGG;AACH,KAAK,uBAAuB,CAAC,CAAC,SAAS,MAAM,IAAI,CAAC,GAAG;IACnD,QAAQ,CAAC,yBAAyB,EAChC,wGAAwG,CAAA;CAC3G,CAAA;AAED;;;;;GAKG;AACH,MAAM,WAAW,eAAe,CAAC,CAAC,SAAS,MAAM,EAAE,CAAC,SAAS,MAAM,EAAE,CAAC,SAAS,OAAO;IACpF;;OAEG;IACH,QAAQ,EAAE,CAAC,CAAA;IAEX;;OAEG;IACH,SAAS,EAAE,CAAC,CAAA;IAEZ;;OAEG;IACH,MAAM,EAAE,CAAC,CAAA;IAET;;;;;;;;;;;;;;;;;;;;OAoBG;IACH,QAAQ,CAAC,EAAE,OAAO,CAAA;IAElB;;;OAGG;IACH,UAAU,CAAC,EAAE,MAAM,CAAA;IAEnB;;;;OAIG;IACH,YAAY,CAAC,EAAE,MAAM,CAAA;IAErB;;;OAGG;IACH,gBAAgB,CAAC,EAAE,MAAM,EAAE,CAAA;IAE3B;;OAEG;IACH,SAAS,CAAC,EAAE,MAAM,CAAA;IAElB;;OAEG;IACH,aAAa,CAAC,EAAE,OAAO,CAAA;CACxB;AAED;;;;GAIG;AACH,MAAM,MAAM,UAAU,CAAC,CAAC,SAAS,MAAM,EAAE,CAAC,SAAS,MAAM,IAAI,GAAG,CAAC,IAAI,CAAC,EAAE,CAAA;AAExE;;GAEG;AACH,MAAM,WAAW,aAAc,SAAQ,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC;CAAG;AAEjE;;;GAGG;AACH,MAAM,MAAM,WAAW,CAAC,YAAY,IAAI,CACtC,OAAO,EAAE,YAAY,EACrB,QAAQ,CAAC,EAAE,aAAa,EACxB,OAAO,CAAC,EAAE,kBAAkB,KACzB,OAAO,CAAC,MAAM,CAAC,CAAA;AAEpB;;;GAGG;AACH,MAAM,MAAM,gBAAgB,CAAC,YAAY,IAAI,CAC3C,OAAO,EAAE,YAAY,EAAE,EACvB,QAAQ,CAAC,EAAE,aAAa,EACxB,OAAO,CAAC,EAAE,kBAAkB,KACzB,OAAO,CAAC,MAAM,EAAE,CAAC,CAAA;AAEtB;;GAEG;AACH,MAAM,MAAM,YAAY,GAAG,CACzB,OAAO,EAAE,eAAe,EACxB,QAAQ,CAAC,EAAE,aAAa,EACxB,OAAO,CAAC,EAAE,kBAAkB,KACzB,OAAO,CAAC,MAAM,EAAE,CAAC,CAAA;AAEtB;;;;GAIG;AACH,MAAM,MAAM,eAAe,CAAC,CAAC,SAAS,MAAM,EAAE,UAAU,SAAS,OAAO,IAAI,UAAU,SAAS,KAAK,GAChG,uBAAuB,CAAC,CAAC,CAAC,GAC1B,CAAC,CAAA;AAEL;;GAEG;AACH,MAAM,MAAM,YAAY,GAAG;IACzB;;;;OAIG;IACH,WAAW,EAAE,CAAC,OAAO,EAAE,MAAM,KAAK,OAAO,GAAG,OAAO,CAAC,OAAO,CAAC,CAAA;IAE5D;;;OAGG;IACH,YAAY,EAAE,CAAC,OAAO,EAAE,MAAM,KAAK,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,CAAA;CACxD,CAAA;AAED;;GAEG;AACH,MAAM,MAAM,mBAAmB,GAAG,kBAAkB,GAAG;IACrD;;OAEG;IACH,aAAa,CAAC,EAAE,OAAO,CAAA;IAEvB;;OAEG;IACH,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAA;IAEhC;;;OAGG;IACH,SAAS,CAAC,EAAE,MAAM,GAAG,QAAQ,CAAA;IAE7B;;;OAGG;IACH,SAAS,CAAC,EAAE,MAAM,CAAA;CACnB,CAAA"}
|