@flowcore/pathways 0.10.0 → 0.12.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 +98 -55
- package/README.md +128 -124
- package/esm/common/index.d.ts.map +1 -1
- package/esm/contracts/index.d.ts.map +1 -1
- package/esm/mod.d.ts.map +1 -1
- package/esm/pathways/builder.d.ts +63 -9
- package/esm/pathways/builder.d.ts.map +1 -1
- package/esm/pathways/builder.js +203 -41
- package/esm/pathways/index.d.ts.map +1 -1
- package/esm/pathways/internal-pathway.state.d.ts.map +1 -1
- package/esm/pathways/kv/bun-kv-adapter.d.ts.map +1 -1
- package/esm/pathways/kv/kv-adapter.d.ts +2 -2
- package/esm/pathways/kv/kv-adapter.d.ts.map +1 -1
- package/esm/pathways/kv/node-kv-adapter.d.ts.map +1 -1
- package/esm/pathways/kv/node-kv-adapter.js +1 -1
- package/esm/pathways/logger.js +7 -7
- package/esm/pathways/postgres/index.d.ts.map +1 -1
- package/esm/pathways/postgres/postgres-adapter.d.ts.map +1 -1
- package/esm/pathways/postgres/postgres-adapter.js +3 -2
- package/esm/pathways/session-pathway.d.ts.map +1 -1
- package/esm/pathways/session-pathway.js +3 -3
- package/esm/pathways/types.d.ts +7 -2
- package/esm/pathways/types.d.ts.map +1 -1
- package/esm/router/index.d.ts.map +1 -1
- package/esm/router/index.js +4 -4
- package/package.json +1 -1
- package/script/common/index.d.ts.map +1 -1
- package/script/contracts/index.d.ts.map +1 -1
- package/script/mod.d.ts.map +1 -1
- package/script/pathways/builder.d.ts +63 -9
- package/script/pathways/builder.d.ts.map +1 -1
- package/script/pathways/builder.js +205 -42
- package/script/pathways/index.d.ts.map +1 -1
- package/script/pathways/internal-pathway.state.d.ts.map +1 -1
- package/script/pathways/kv/bun-kv-adapter.d.ts.map +1 -1
- package/script/pathways/kv/kv-adapter.d.ts +2 -2
- package/script/pathways/kv/kv-adapter.d.ts.map +1 -1
- package/script/pathways/kv/node-kv-adapter.d.ts.map +1 -1
- package/script/pathways/kv/node-kv-adapter.js +1 -1
- package/script/pathways/logger.js +7 -7
- package/script/pathways/postgres/index.d.ts.map +1 -1
- package/script/pathways/postgres/postgres-adapter.d.ts.map +1 -1
- package/script/pathways/postgres/postgres-adapter.js +3 -2
- package/script/pathways/session-pathway.d.ts.map +1 -1
- package/script/pathways/session-pathway.js +3 -3
- package/script/pathways/types.d.ts +7 -2
- package/script/pathways/types.d.ts.map +1 -1
- package/script/router/index.d.ts.map +1 -1
- package/script/router/index.js +4 -4
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.PathwaysBuilder = void 0;
|
|
3
|
+
exports.PathwaysBuilder = exports.SessionUser = 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");
|
|
@@ -22,6 +23,61 @@ const DEFAULT_RETRY_DELAY_MS = 500;
|
|
|
22
23
|
* Default TTL for session-specific user resolvers in milliseconds (10seconds)
|
|
23
24
|
*/
|
|
24
25
|
const DEFAULT_SESSION_USER_RESOLVER_TTL_MS = 10 * 1000;
|
|
26
|
+
/**
|
|
27
|
+
* SessionUserResolver implementation that uses a Map to store UserIdResolver functions
|
|
28
|
+
* with a TTL (time to live).
|
|
29
|
+
*/
|
|
30
|
+
class SessionUser {
|
|
31
|
+
/**
|
|
32
|
+
* Creates a new SessionUser instance
|
|
33
|
+
*/
|
|
34
|
+
constructor() {
|
|
35
|
+
/**
|
|
36
|
+
* The underlying Map that stores UserIdResolver functions and their timeouts
|
|
37
|
+
* Using unknown for timeout to support both Node.js and Deno timer types
|
|
38
|
+
*/
|
|
39
|
+
Object.defineProperty(this, "store", {
|
|
40
|
+
enumerable: true,
|
|
41
|
+
configurable: true,
|
|
42
|
+
writable: true,
|
|
43
|
+
value: void 0
|
|
44
|
+
});
|
|
45
|
+
this.store = new Map();
|
|
46
|
+
}
|
|
47
|
+
/**
|
|
48
|
+
* Retrieves a UserIdResolver from the session user resolver store
|
|
49
|
+
* @param key The key to retrieve the UserIdResolver for
|
|
50
|
+
* @returns The UserIdResolver or undefined if it doesn't exist
|
|
51
|
+
*/
|
|
52
|
+
get(key) {
|
|
53
|
+
const entry = this.store.get(key);
|
|
54
|
+
if (!entry) {
|
|
55
|
+
return undefined;
|
|
56
|
+
}
|
|
57
|
+
return entry.value;
|
|
58
|
+
}
|
|
59
|
+
/**
|
|
60
|
+
* Stores a UserIdResolver in the session user resolver store
|
|
61
|
+
* @param key The key to store the UserIdResolver under
|
|
62
|
+
* @param value The UserIdResolver to store
|
|
63
|
+
* @param ttlMs The time to live for the UserIdResolver in milliseconds
|
|
64
|
+
* @default 5 minutes
|
|
65
|
+
*/
|
|
66
|
+
set(key, value, ttlMs = 1000 * 60 * 5) {
|
|
67
|
+
// Clear any existing timeout for this key
|
|
68
|
+
const existingEntry = this.store.get(key);
|
|
69
|
+
if (existingEntry) {
|
|
70
|
+
clearTimeout(existingEntry.timeout);
|
|
71
|
+
}
|
|
72
|
+
// Set up new timeout
|
|
73
|
+
const timeout = setTimeout(() => {
|
|
74
|
+
this.store.delete(key);
|
|
75
|
+
}, ttlMs);
|
|
76
|
+
// Store the new value and its timeout
|
|
77
|
+
this.store.set(key, { value, timeout });
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
exports.SessionUser = SessionUser;
|
|
25
81
|
/**
|
|
26
82
|
* Main builder class for creating and managing Flowcore pathways
|
|
27
83
|
*
|
|
@@ -46,9 +102,10 @@ class PathwaysBuilder {
|
|
|
46
102
|
* @param options.apiKey The API key for authentication
|
|
47
103
|
* @param options.pathwayTimeoutMs Optional timeout for pathway processing in milliseconds
|
|
48
104
|
* @param options.logger Optional logger instance
|
|
49
|
-
* @param options.
|
|
105
|
+
* @param options.enableSessionUserResolvers Whether to enable session user resolvers
|
|
106
|
+
* @param options.overrideSessionUserResolvers Optional SessionUserResolver instance to override the default
|
|
50
107
|
*/
|
|
51
|
-
constructor({ baseUrl, tenant, dataCore, apiKey, pathwayTimeoutMs, logger,
|
|
108
|
+
constructor({ baseUrl, tenant, dataCore, apiKey, pathwayTimeoutMs, logger, enableSessionUserResolvers, overrideSessionUserResolvers, }) {
|
|
52
109
|
Object.defineProperty(this, "pathways", {
|
|
53
110
|
enumerable: true,
|
|
54
111
|
configurable: true,
|
|
@@ -91,6 +148,12 @@ class PathwaysBuilder {
|
|
|
91
148
|
writable: true,
|
|
92
149
|
value: {}
|
|
93
150
|
});
|
|
151
|
+
Object.defineProperty(this, "batchWriters", {
|
|
152
|
+
enumerable: true,
|
|
153
|
+
configurable: true,
|
|
154
|
+
writable: true,
|
|
155
|
+
value: {}
|
|
156
|
+
});
|
|
94
157
|
Object.defineProperty(this, "schemas", {
|
|
95
158
|
enumerable: true,
|
|
96
159
|
configurable: true,
|
|
@@ -204,14 +267,14 @@ class PathwaysBuilder {
|
|
|
204
267
|
this.tenant = tenant;
|
|
205
268
|
this.dataCore = dataCore;
|
|
206
269
|
this.apiKey = apiKey;
|
|
207
|
-
if (
|
|
208
|
-
this.sessionUserResolvers =
|
|
270
|
+
if (enableSessionUserResolvers) {
|
|
271
|
+
this.sessionUserResolvers = overrideSessionUserResolvers ?? new SessionUser();
|
|
209
272
|
}
|
|
210
|
-
this.logger.debug(
|
|
273
|
+
this.logger.debug("Initializing PathwaysBuilder", {
|
|
211
274
|
baseUrl,
|
|
212
275
|
tenant,
|
|
213
276
|
dataCore,
|
|
214
|
-
pathwayTimeoutMs
|
|
277
|
+
pathwayTimeoutMs,
|
|
215
278
|
});
|
|
216
279
|
this.webhookBuilderFactory = new flowcore_transformer_core_sdk_js_1.WebhookBuilder({
|
|
217
280
|
baseUrl,
|
|
@@ -234,7 +297,7 @@ class PathwaysBuilder {
|
|
|
234
297
|
* @returns The PathwaysBuilder instance with custom state configured
|
|
235
298
|
*/
|
|
236
299
|
withPathwayState(state) {
|
|
237
|
-
this.logger.debug(
|
|
300
|
+
this.logger.debug("Setting custom pathway state");
|
|
238
301
|
this.pathwayState = state;
|
|
239
302
|
return this;
|
|
240
303
|
}
|
|
@@ -244,7 +307,7 @@ class PathwaysBuilder {
|
|
|
244
307
|
* @returns The PathwaysBuilder instance with audit configured
|
|
245
308
|
*/
|
|
246
309
|
withAudit(handler) {
|
|
247
|
-
this.logger.debug(
|
|
310
|
+
this.logger.debug("Configuring audit functionality");
|
|
248
311
|
this.auditHandler = handler;
|
|
249
312
|
return this;
|
|
250
313
|
}
|
|
@@ -254,7 +317,7 @@ class PathwaysBuilder {
|
|
|
254
317
|
* @returns The PathwaysBuilder instance with custom user ID resolver configured
|
|
255
318
|
*/
|
|
256
319
|
withUserResolver(resolver) {
|
|
257
|
-
this.logger.debug(
|
|
320
|
+
this.logger.debug("Configuring user resolver");
|
|
258
321
|
this.userIdResolver = resolver;
|
|
259
322
|
return this;
|
|
260
323
|
}
|
|
@@ -293,9 +356,9 @@ class PathwaysBuilder {
|
|
|
293
356
|
*/
|
|
294
357
|
withSessionUserResolver(sessionId, resolver) {
|
|
295
358
|
if (!this.sessionUserResolvers) {
|
|
296
|
-
throw new Error(
|
|
359
|
+
throw new Error("Session user resolvers not configured");
|
|
297
360
|
}
|
|
298
|
-
this.logger.debug(
|
|
361
|
+
this.logger.debug("Configuring session-specific user resolver", { sessionId });
|
|
299
362
|
this.sessionUserResolvers.set(sessionId, resolver, DEFAULT_SESSION_USER_RESOLVER_TTL_MS);
|
|
300
363
|
return this;
|
|
301
364
|
}
|
|
@@ -321,7 +384,7 @@ class PathwaysBuilder {
|
|
|
321
384
|
const pathwayStr = String(pathway);
|
|
322
385
|
this.logger.debug(`Processing pathway event`, {
|
|
323
386
|
pathway: pathwayStr,
|
|
324
|
-
eventId: data.eventId
|
|
387
|
+
eventId: data.eventId,
|
|
325
388
|
});
|
|
326
389
|
if (!this.pathways[pathway]) {
|
|
327
390
|
const error = `Pathway ${pathwayStr} not found`;
|
|
@@ -348,7 +411,7 @@ class PathwaysBuilder {
|
|
|
348
411
|
if (this.auditHandler) {
|
|
349
412
|
this.logger.debug(`Calling audit handler for pathway`, {
|
|
350
413
|
pathway: pathwayStr,
|
|
351
|
-
eventId: data.eventId
|
|
414
|
+
eventId: data.eventId,
|
|
352
415
|
});
|
|
353
416
|
this.auditHandler(pathwayStr, data);
|
|
354
417
|
}
|
|
@@ -358,7 +421,7 @@ class PathwaysBuilder {
|
|
|
358
421
|
const retryDelayMs = this.retryDelays[pathway] ?? DEFAULT_RETRY_DELAY_MS;
|
|
359
422
|
this.logger.debug(`Emitting 'before' event`, {
|
|
360
423
|
pathway: pathwayStr,
|
|
361
|
-
eventId: data.eventId
|
|
424
|
+
eventId: data.eventId,
|
|
362
425
|
});
|
|
363
426
|
this.beforeObservable[pathway].next(data);
|
|
364
427
|
while (true) {
|
|
@@ -366,7 +429,7 @@ class PathwaysBuilder {
|
|
|
366
429
|
this.logger.debug(`Executing handler for pathway`, {
|
|
367
430
|
pathway: pathwayStr,
|
|
368
431
|
eventId: data.eventId,
|
|
369
|
-
attempt: retryCount + 1
|
|
432
|
+
attempt: retryCount + 1,
|
|
370
433
|
});
|
|
371
434
|
// Execute the handler
|
|
372
435
|
const handle = this.handlers[pathway](data);
|
|
@@ -374,13 +437,13 @@ class PathwaysBuilder {
|
|
|
374
437
|
// If successful, emit success event and mark as processed
|
|
375
438
|
this.logger.debug(`Handler executed successfully, emitting 'after' event`, {
|
|
376
439
|
pathway: pathwayStr,
|
|
377
|
-
eventId: data.eventId
|
|
440
|
+
eventId: data.eventId,
|
|
378
441
|
});
|
|
379
442
|
this.afterObservers[pathway].next(data);
|
|
380
443
|
await this.pathwayState.setProcessed(data.eventId);
|
|
381
444
|
this.logger.info(`Successfully processed pathway event`, {
|
|
382
445
|
pathway: pathwayStr,
|
|
383
|
-
eventId: data.eventId
|
|
446
|
+
eventId: data.eventId,
|
|
384
447
|
});
|
|
385
448
|
return;
|
|
386
449
|
}
|
|
@@ -391,7 +454,7 @@ class PathwaysBuilder {
|
|
|
391
454
|
pathway: pathwayStr,
|
|
392
455
|
eventId: data.eventId,
|
|
393
456
|
retryCount,
|
|
394
|
-
maxRetries
|
|
457
|
+
maxRetries,
|
|
395
458
|
});
|
|
396
459
|
// Emit error event with both error and event data
|
|
397
460
|
this.errorObservers[pathway].next({ event: data, error: errorObj });
|
|
@@ -399,7 +462,7 @@ class PathwaysBuilder {
|
|
|
399
462
|
this.globalErrorSubject.next({
|
|
400
463
|
pathway: pathwayStr,
|
|
401
464
|
event: data,
|
|
402
|
-
error: errorObj
|
|
465
|
+
error: errorObj,
|
|
403
466
|
});
|
|
404
467
|
// Check if we should retry
|
|
405
468
|
if (retryCount < maxRetries) {
|
|
@@ -410,10 +473,10 @@ class PathwaysBuilder {
|
|
|
410
473
|
eventId: data.eventId,
|
|
411
474
|
attempt: retryCount,
|
|
412
475
|
maxRetries,
|
|
413
|
-
nextDelay
|
|
476
|
+
nextDelay,
|
|
414
477
|
});
|
|
415
478
|
// Wait for delay before retrying
|
|
416
|
-
await new Promise(resolve => setTimeout(resolve, nextDelay));
|
|
479
|
+
await new Promise((resolve) => setTimeout(resolve, nextDelay));
|
|
417
480
|
continue;
|
|
418
481
|
}
|
|
419
482
|
// If we've exhausted retries, mark as processed to avoid hanging
|
|
@@ -421,7 +484,7 @@ class PathwaysBuilder {
|
|
|
421
484
|
pathway: pathwayStr,
|
|
422
485
|
eventId: data.eventId,
|
|
423
486
|
retryCount,
|
|
424
|
-
maxRetries
|
|
487
|
+
maxRetries,
|
|
425
488
|
});
|
|
426
489
|
await this.pathwayState.setProcessed(data.eventId);
|
|
427
490
|
throw error;
|
|
@@ -432,7 +495,7 @@ class PathwaysBuilder {
|
|
|
432
495
|
// No handler, just emit events and mark as processed
|
|
433
496
|
this.logger.debug(`No handler for pathway, emitting events and marking as processed`, {
|
|
434
497
|
pathway: pathwayStr,
|
|
435
|
-
eventId: data.eventId
|
|
498
|
+
eventId: data.eventId,
|
|
436
499
|
});
|
|
437
500
|
this.beforeObservable[pathway].next(data);
|
|
438
501
|
this.afterObservers[pathway].next(data);
|
|
@@ -459,9 +522,9 @@ class PathwaysBuilder {
|
|
|
459
522
|
isFilePathway: contract.isFilePathway,
|
|
460
523
|
timeoutMs: contract.timeoutMs,
|
|
461
524
|
maxRetries: contract.maxRetries,
|
|
462
|
-
retryDelayMs: contract.retryDelayMs
|
|
463
|
-
})
|
|
464
|
-
|
|
525
|
+
retryDelayMs: contract.retryDelayMs,
|
|
526
|
+
}) // deno-lint-ignore no-explicit-any
|
|
527
|
+
;
|
|
465
528
|
this.pathways[path] = true;
|
|
466
529
|
this.beforeObservable[path] = new rxjs_1.Subject();
|
|
467
530
|
this.afterObservers[path] = new rxjs_1.Subject();
|
|
@@ -475,6 +538,8 @@ class PathwaysBuilder {
|
|
|
475
538
|
else {
|
|
476
539
|
this.writers[path] = this.webhookBuilderFactory()
|
|
477
540
|
.buildWebhook(contract.flowType, contract.eventType).send;
|
|
541
|
+
this.batchWriters[path] = this.webhookBuilderFactory()
|
|
542
|
+
.buildWebhook(contract.flowType, contract.eventType).sendBatch;
|
|
478
543
|
}
|
|
479
544
|
}
|
|
480
545
|
if (contract.timeoutMs) {
|
|
@@ -492,7 +557,7 @@ class PathwaysBuilder {
|
|
|
492
557
|
pathway: path,
|
|
493
558
|
flowType: contract.flowType,
|
|
494
559
|
eventType: contract.eventType,
|
|
495
|
-
writable
|
|
560
|
+
writable,
|
|
496
561
|
});
|
|
497
562
|
return this;
|
|
498
563
|
}
|
|
@@ -561,7 +626,7 @@ class PathwaysBuilder {
|
|
|
561
626
|
}
|
|
562
627
|
this.logger.info(`Subscription to pathway events set up`, {
|
|
563
628
|
pathway: pathStr,
|
|
564
|
-
type
|
|
629
|
+
type,
|
|
565
630
|
});
|
|
566
631
|
return this;
|
|
567
632
|
}
|
|
@@ -610,8 +675,8 @@ class PathwaysBuilder {
|
|
|
610
675
|
metadata,
|
|
611
676
|
options: {
|
|
612
677
|
fireAndForget: options?.fireAndForget,
|
|
613
|
-
sessionId: options?.sessionId
|
|
614
|
-
}
|
|
678
|
+
sessionId: options?.sessionId,
|
|
679
|
+
},
|
|
615
680
|
});
|
|
616
681
|
if (!this.pathways[path]) {
|
|
617
682
|
const error = `Pathway ${pathStr} not found`;
|
|
@@ -628,7 +693,7 @@ class PathwaysBuilder {
|
|
|
628
693
|
const errorMessage = `Invalid data for pathway ${pathStr}`;
|
|
629
694
|
this.logger.error(errorMessage, new Error(errorMessage), {
|
|
630
695
|
pathway: pathStr,
|
|
631
|
-
schema: schema.toString()
|
|
696
|
+
schema: schema.toString(),
|
|
632
697
|
});
|
|
633
698
|
throw new Error(errorMessage);
|
|
634
699
|
}
|
|
@@ -644,13 +709,13 @@ class PathwaysBuilder {
|
|
|
644
709
|
this.logger.debug(`Using session-specific user resolver`, {
|
|
645
710
|
pathway: pathStr,
|
|
646
711
|
sessionId: options.sessionId,
|
|
647
|
-
userId
|
|
712
|
+
userId,
|
|
648
713
|
});
|
|
649
714
|
}
|
|
650
715
|
catch (error) {
|
|
651
716
|
this.logger.error(`Error resolving session user ID`, error instanceof Error ? error : new Error(String(error)), {
|
|
652
717
|
pathway: pathStr,
|
|
653
|
-
sessionId: options.sessionId
|
|
718
|
+
sessionId: options.sessionId,
|
|
654
719
|
});
|
|
655
720
|
}
|
|
656
721
|
}
|
|
@@ -668,7 +733,7 @@ class PathwaysBuilder {
|
|
|
668
733
|
this.logger.debug(`Adding audit metadata`, {
|
|
669
734
|
pathway: pathStr,
|
|
670
735
|
auditMode,
|
|
671
|
-
userId
|
|
736
|
+
userId,
|
|
672
737
|
});
|
|
673
738
|
if (userId) {
|
|
674
739
|
// Add appropriate audit metadata based on mode
|
|
@@ -695,15 +760,113 @@ class PathwaysBuilder {
|
|
|
695
760
|
this.logger.info(`Successfully wrote to pathway`, {
|
|
696
761
|
pathway: pathStr,
|
|
697
762
|
eventIds: Array.isArray(eventIds) ? eventIds : [eventIds],
|
|
698
|
-
fireAndForget: options?.fireAndForget
|
|
763
|
+
fireAndForget: options?.fireAndForget,
|
|
699
764
|
});
|
|
700
765
|
if (!options?.fireAndForget) {
|
|
701
766
|
this.logger.debug(`Waiting for pathway to be processed`, {
|
|
702
767
|
pathway: pathStr,
|
|
703
|
-
eventIds: Array.isArray(eventIds) ? eventIds : [eventIds]
|
|
768
|
+
eventIds: Array.isArray(eventIds) ? eventIds : [eventIds],
|
|
704
769
|
});
|
|
705
770
|
await Promise.all(Array.isArray(eventIds)
|
|
706
|
-
? eventIds.map(id => this.waitForPathwayToBeProcessed(id))
|
|
771
|
+
? eventIds.map((id) => this.waitForPathwayToBeProcessed(id))
|
|
772
|
+
: [this.waitForPathwayToBeProcessed(eventIds)]);
|
|
773
|
+
}
|
|
774
|
+
return eventIds;
|
|
775
|
+
}
|
|
776
|
+
async writeBatch(path, data, metadata, options) {
|
|
777
|
+
const pathStr = String(path);
|
|
778
|
+
this.logger.debug(`Writing batch to pathway`, {
|
|
779
|
+
pathway: pathStr,
|
|
780
|
+
metadata,
|
|
781
|
+
options: {
|
|
782
|
+
fireAndForget: options?.fireAndForget,
|
|
783
|
+
sessionId: options?.sessionId,
|
|
784
|
+
},
|
|
785
|
+
});
|
|
786
|
+
if (!this.pathways[path]) {
|
|
787
|
+
const error = `Pathway ${pathStr} not found`;
|
|
788
|
+
this.logger.error(error);
|
|
789
|
+
throw new Error(error);
|
|
790
|
+
}
|
|
791
|
+
if (!this.writable[path]) {
|
|
792
|
+
const error = `Pathway ${pathStr} is not writable`;
|
|
793
|
+
this.logger.error(error);
|
|
794
|
+
throw new Error(error);
|
|
795
|
+
}
|
|
796
|
+
const schema = this.schemas[path];
|
|
797
|
+
if (!value_1.Value.Check(typebox_1.Type.Array(schema), data)) {
|
|
798
|
+
const errorMessage = `Invalid batch data for pathway ${pathStr}`;
|
|
799
|
+
this.logger.error(errorMessage, new Error(errorMessage), {
|
|
800
|
+
pathway: pathStr,
|
|
801
|
+
schema: schema.toString(),
|
|
802
|
+
});
|
|
803
|
+
throw new Error(errorMessage);
|
|
804
|
+
}
|
|
805
|
+
// Create a copy of the metadata to avoid modifying the original
|
|
806
|
+
const finalMetadata = metadata ? { ...metadata } : {};
|
|
807
|
+
// Check for session-specific user resolver
|
|
808
|
+
let userId;
|
|
809
|
+
if (options?.sessionId) {
|
|
810
|
+
const sessionUserResolver = this.getSessionUserResolver(options.sessionId);
|
|
811
|
+
if (sessionUserResolver) {
|
|
812
|
+
try {
|
|
813
|
+
userId = await sessionUserResolver();
|
|
814
|
+
this.logger.debug(`Using session-specific user resolver`, {
|
|
815
|
+
pathway: pathStr,
|
|
816
|
+
sessionId: options.sessionId,
|
|
817
|
+
userId,
|
|
818
|
+
});
|
|
819
|
+
}
|
|
820
|
+
catch (error) {
|
|
821
|
+
this.logger.error(`Error resolving session user ID`, error instanceof Error ? error : new Error(String(error)), {
|
|
822
|
+
pathway: pathStr,
|
|
823
|
+
sessionId: options.sessionId,
|
|
824
|
+
});
|
|
825
|
+
}
|
|
826
|
+
}
|
|
827
|
+
}
|
|
828
|
+
// Process audit metadata if audit is configured
|
|
829
|
+
if (this.userIdResolver) {
|
|
830
|
+
// Only use global resolver if we don't already have a user ID from a session resolver
|
|
831
|
+
if (!userId) {
|
|
832
|
+
this.logger.debug(`Resolving user ID for audit metadata`, { pathway: pathStr });
|
|
833
|
+
userId = await this.userIdResolver();
|
|
834
|
+
}
|
|
835
|
+
}
|
|
836
|
+
// Determine the audit mode: default is "user" unless explicitly specified as "system"
|
|
837
|
+
const auditMode = options?.auditMode ?? "user";
|
|
838
|
+
this.logger.debug(`Adding audit metadata`, {
|
|
839
|
+
pathway: pathStr,
|
|
840
|
+
auditMode,
|
|
841
|
+
userId,
|
|
842
|
+
});
|
|
843
|
+
if (userId) {
|
|
844
|
+
// Add appropriate audit metadata based on mode
|
|
845
|
+
if (auditMode === "system") {
|
|
846
|
+
finalMetadata["audit/user-id"] = "system";
|
|
847
|
+
finalMetadata["audit/on-behalf-of"] = userId;
|
|
848
|
+
finalMetadata["audit/mode"] = "system";
|
|
849
|
+
}
|
|
850
|
+
else {
|
|
851
|
+
finalMetadata["audit/user-id"] = userId;
|
|
852
|
+
finalMetadata["audit/mode"] = "user"; // Always set mode for user
|
|
853
|
+
}
|
|
854
|
+
}
|
|
855
|
+
let eventIds = [];
|
|
856
|
+
this.logger.debug(`Writing batch webhook data to pathway`, { pathway: pathStr });
|
|
857
|
+
eventIds = await this.batchWriters[path](data, finalMetadata, options);
|
|
858
|
+
this.logger.info(`Successfully wrote to pathway`, {
|
|
859
|
+
pathway: pathStr,
|
|
860
|
+
eventIds: Array.isArray(eventIds) ? eventIds : [eventIds],
|
|
861
|
+
fireAndForget: options?.fireAndForget,
|
|
862
|
+
});
|
|
863
|
+
if (!options?.fireAndForget) {
|
|
864
|
+
this.logger.debug(`Waiting for pathway to be processed`, {
|
|
865
|
+
pathway: pathStr,
|
|
866
|
+
eventIds: Array.isArray(eventIds) ? eventIds : [eventIds],
|
|
867
|
+
});
|
|
868
|
+
await Promise.all(Array.isArray(eventIds)
|
|
869
|
+
? eventIds.map((id) => this.waitForPathwayToBeProcessed(id))
|
|
707
870
|
: [this.waitForPathwayToBeProcessed(eventIds)]);
|
|
708
871
|
}
|
|
709
872
|
return eventIds;
|
|
@@ -724,7 +887,7 @@ class PathwaysBuilder {
|
|
|
724
887
|
const timeoutMs = this.timeouts[eventId] ?? this.pathwayTimeoutMs;
|
|
725
888
|
this.logger.debug(`Waiting for event to be processed`, {
|
|
726
889
|
eventId,
|
|
727
|
-
timeoutMs
|
|
890
|
+
timeoutMs,
|
|
728
891
|
});
|
|
729
892
|
let attempts = 0;
|
|
730
893
|
while (!(await this.pathwayState.isProcessed(eventId))) {
|
|
@@ -736,7 +899,7 @@ class PathwaysBuilder {
|
|
|
736
899
|
eventId,
|
|
737
900
|
timeoutMs,
|
|
738
901
|
elapsedTime,
|
|
739
|
-
attempts
|
|
902
|
+
attempts,
|
|
740
903
|
});
|
|
741
904
|
throw new Error(errorMessage);
|
|
742
905
|
}
|
|
@@ -745,7 +908,7 @@ class PathwaysBuilder {
|
|
|
745
908
|
eventId,
|
|
746
909
|
elapsedTime,
|
|
747
910
|
attempts,
|
|
748
|
-
timeoutMs
|
|
911
|
+
timeoutMs,
|
|
749
912
|
});
|
|
750
913
|
}
|
|
751
914
|
await new Promise((resolve) => setTimeout(resolve, 100));
|
|
@@ -753,7 +916,7 @@ class PathwaysBuilder {
|
|
|
753
916
|
this.logger.debug(`Event has been processed`, {
|
|
754
917
|
eventId,
|
|
755
918
|
elapsedTime: Date.now() - startTime,
|
|
756
|
-
attempts
|
|
919
|
+
attempts,
|
|
757
920
|
});
|
|
758
921
|
}
|
|
759
922
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/pathways/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AACH,cAAc,cAAc,
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/pathways/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AACH,cAAc,cAAc,CAAA;AAC5B,cAAc,6BAA6B,CAAA;AAC3C,cAAc,oBAAoB,CAAA;AAClC,cAAc,aAAa,CAAA;AAC3B,cAAc,qBAAqB,CAAA;AACnC,cAAc,sBAAsB,CAAA;AACpC,cAAc,YAAY,CAAA"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"internal-pathway.state.d.ts","sourceRoot":"","sources":["../../src/pathways/internal-pathway.state.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,YAAY,
|
|
1
|
+
{"version":3,"file":"internal-pathway.state.d.ts","sourceRoot":"","sources":["../../src/pathways/internal-pathway.state.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,YAAY,CAAA;AAE9C;;;GAGG;AACH,qBAAa,oBAAqB,YAAW,YAAY;IACvD;;;OAGG;IACH,OAAO,CAAC,MAAM,CAAC,QAAQ,CAAC,cAAc,CAAgB;IAEtD;;;OAGG;IACH,OAAO,CAAC,EAAE,CAAyB;IAEnC;;;;;OAKG;YACW,KAAK;IAOnB;;;;;OAKG;IACG,WAAW,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC;IAMpD;;;;;OAKG;IACG,YAAY,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;CAInD"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"bun-kv-adapter.d.ts","sourceRoot":"","sources":["../../../src/pathways/kv/bun-kv-adapter.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,iBAAiB,
|
|
1
|
+
{"version":3,"file":"bun-kv-adapter.d.ts","sourceRoot":"","sources":["../../../src/pathways/kv/bun-kv-adapter.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,iBAAiB,CAAA;AAEhD;;;;GAIG;AACH,qBAAa,YAAa,YAAW,SAAS;IAC5C;;;OAGG;IACH,OAAO,CAAC,KAAK,CAAmB;IAEhC;;OAEG;;IAKH;;;;;;OAMG;IACH,GAAG,CAAC,CAAC,EAAE,GAAG,EAAE,MAAM,GAAG,CAAC,GAAG,IAAI;IAK7B;;;;;;OAMG;IACH,GAAG,CAAC,GAAG,EAAE,MAAM,EAAE,KAAK,EAAE,OAAO,EAAE,KAAK,EAAE,MAAM,GAAG,IAAI;CAGtD"}
|
|
@@ -39,7 +39,7 @@ export interface KvAdapter {
|
|
|
39
39
|
* @param key The key to retrieve
|
|
40
40
|
* @returns The stored value or null if not found
|
|
41
41
|
*/
|
|
42
|
-
get<T>(key: string):
|
|
42
|
+
get<T>(key: string): Promise<T | null> | T | null;
|
|
43
43
|
/**
|
|
44
44
|
* Stores a value in storage with the specified key and TTL
|
|
45
45
|
*
|
|
@@ -48,7 +48,7 @@ export interface KvAdapter {
|
|
|
48
48
|
* @param ttlMs Time-to-live in milliseconds
|
|
49
49
|
* @returns Promise or void when the operation completes
|
|
50
50
|
*/
|
|
51
|
-
set(key: string, value: unknown, ttlMs: number):
|
|
51
|
+
set(key: string, value: unknown, ttlMs: number): Promise<void> | void;
|
|
52
52
|
}
|
|
53
53
|
/**
|
|
54
54
|
* Creates an appropriate KV adapter based on the runtime environment
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"kv-adapter.d.ts","sourceRoot":"","sources":["../../../src/pathways/kv/kv-adapter.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAgCG;AACH,MAAM,WAAW,SAAS;IACxB;;;;;;OAMG;IACH,GAAG,CAAC,CAAC,EAAE,GAAG,EAAE,MAAM,GAAG,
|
|
1
|
+
{"version":3,"file":"kv-adapter.d.ts","sourceRoot":"","sources":["../../../src/pathways/kv/kv-adapter.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAgCG;AACH,MAAM,WAAW,SAAS;IACxB;;;;;;OAMG;IACH,GAAG,CAAC,CAAC,EAAE,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,CAAC,GAAG,IAAI,CAAC,GAAG,CAAC,GAAG,IAAI,CAAA;IAEjD;;;;;;;OAOG;IACH,GAAG,CAAC,GAAG,EAAE,MAAM,EAAE,KAAK,EAAE,OAAO,EAAE,KAAK,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,GAAG,IAAI,CAAA;CACtE;AAED;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAoCG;AACH,wBAAsB,eAAe,IAAI,OAAO,CAAC,SAAS,CAAC,CAU1D"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"node-kv-adapter.d.ts","sourceRoot":"","sources":["../../../src/pathways/kv/node-kv-adapter.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,iBAAiB,
|
|
1
|
+
{"version":3,"file":"node-kv-adapter.d.ts","sourceRoot":"","sources":["../../../src/pathways/kv/node-kv-adapter.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,iBAAiB,CAAA;AAEhD;;;;GAIG;AACH,qBAAa,aAAc,YAAW,SAAS;IAC7C;;;OAGG;IACH,OAAO,CAAC,QAAQ,CAAC,EAAE,CAAkB;IAErC;;;;;;OAMG;IACG,GAAG,CAAC,CAAC,EAAE,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,CAAC,GAAG,IAAI,CAAC;IAK5C;;;;;;;OAOG;IACG,GAAG,CAAC,GAAG,EAAE,MAAM,EAAE,KAAK,EAAE,OAAO,EAAE,KAAK,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;CAGrE"}
|
|
@@ -43,7 +43,7 @@ class NodeKvAdapter {
|
|
|
43
43
|
* @returns Promise that resolves when the operation completes
|
|
44
44
|
*/
|
|
45
45
|
async set(key, value, ttlMs) {
|
|
46
|
-
await this.kv.set(key, value,
|
|
46
|
+
await this.kv.set(key, value, ttlMs / 1000);
|
|
47
47
|
}
|
|
48
48
|
}
|
|
49
49
|
exports.NodeKvAdapter = NodeKvAdapter;
|
|
@@ -14,7 +14,7 @@ class ConsoleLogger {
|
|
|
14
14
|
* @param context Optional context data to include
|
|
15
15
|
*/
|
|
16
16
|
debug(message, context) {
|
|
17
|
-
console.debug(message, context ? JSON.stringify(context) :
|
|
17
|
+
console.debug(message, context ? JSON.stringify(context) : "");
|
|
18
18
|
}
|
|
19
19
|
/**
|
|
20
20
|
* Log informational messages to the console
|
|
@@ -22,7 +22,7 @@ class ConsoleLogger {
|
|
|
22
22
|
* @param context Optional context data to include
|
|
23
23
|
*/
|
|
24
24
|
info(message, context) {
|
|
25
|
-
console.info(message, context ? JSON.stringify(context) :
|
|
25
|
+
console.info(message, context ? JSON.stringify(context) : "");
|
|
26
26
|
}
|
|
27
27
|
/**
|
|
28
28
|
* Log warning messages to the console
|
|
@@ -30,7 +30,7 @@ class ConsoleLogger {
|
|
|
30
30
|
* @param context Optional context data to include
|
|
31
31
|
*/
|
|
32
32
|
warn(message, context) {
|
|
33
|
-
console.warn(message, context ? JSON.stringify(context) :
|
|
33
|
+
console.warn(message, context ? JSON.stringify(context) : "");
|
|
34
34
|
}
|
|
35
35
|
/**
|
|
36
36
|
* Log error messages to the console
|
|
@@ -43,19 +43,19 @@ class ConsoleLogger {
|
|
|
43
43
|
* @param context Optional context data (only for signature 1)
|
|
44
44
|
*/
|
|
45
45
|
error(messageOrError, errorOrContext, context) {
|
|
46
|
-
if (typeof messageOrError ===
|
|
46
|
+
if (typeof messageOrError === "string") {
|
|
47
47
|
if (errorOrContext instanceof Error) {
|
|
48
48
|
// Signature 1: error(message: string, error: Error, context?: LoggerMeta)
|
|
49
|
-
console.error(messageOrError, errorOrContext, context ? JSON.stringify(context) :
|
|
49
|
+
console.error(messageOrError, errorOrContext, context ? JSON.stringify(context) : "");
|
|
50
50
|
}
|
|
51
51
|
else {
|
|
52
52
|
// Signature 1 (no error) or Signature 2: error(message: string, context?: LoggerMeta)
|
|
53
|
-
console.error(messageOrError, errorOrContext ? JSON.stringify(errorOrContext) :
|
|
53
|
+
console.error(messageOrError, errorOrContext ? JSON.stringify(errorOrContext) : "");
|
|
54
54
|
}
|
|
55
55
|
}
|
|
56
56
|
else {
|
|
57
57
|
// Signature 2: error(error: Error, context?: LoggerMeta)
|
|
58
|
-
console.error(messageOrError, errorOrContext ? JSON.stringify(errorOrContext) :
|
|
58
|
+
console.error(messageOrError, errorOrContext ? JSON.stringify(errorOrContext) : "");
|
|
59
59
|
}
|
|
60
60
|
}
|
|
61
61
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/pathways/postgres/index.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AACH,cAAc,uBAAuB,
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/pathways/postgres/index.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AACH,cAAc,uBAAuB,CAAA;AACrC,cAAc,6BAA6B,CAAA"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"postgres-adapter.d.ts","sourceRoot":"","sources":["../../../src/pathways/postgres/postgres-adapter.ts"],"names":[],"mappings":"AAAA;;GAEG;AACH,MAAM,WAAW,8BAA8B;IAC7C,gHAAgH;IAChH,gBAAgB,EAAE,MAAM,
|
|
1
|
+
{"version":3,"file":"postgres-adapter.d.ts","sourceRoot":"","sources":["../../../src/pathways/postgres/postgres-adapter.ts"],"names":[],"mappings":"AAAA;;GAEG;AACH,MAAM,WAAW,8BAA8B;IAC7C,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;CACZ;AAED;;GAEG;AACH,MAAM,WAAW,wBAAwB;IACvC,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;CACd;AAED;;;;;;GAMG;AACH,MAAM,MAAM,cAAc,GAAG,8BAA8B,GAAG,wBAAwB,CAAA;AAEtF;;;;GAIG;AACH,MAAM,WAAW,eAAe;IAC9B;;;OAGG;IACH,OAAO,IAAI,OAAO,CAAC,IAAI,CAAC,CAAA;IAExB;;;OAGG;IACH,UAAU,IAAI,OAAO,CAAC,IAAI,CAAC,CAAA;IAE3B;;;;;;OAMG;IACH,KAAK,CAAC,CAAC,EAAE,GAAG,EAAE,MAAM,EAAE,MAAM,CAAC,EAAE,OAAO,EAAE,GAAG,OAAO,CAAC,CAAC,CAAC,CAAA;IAErD;;;;;OAKG;IACH,OAAO,CAAC,GAAG,EAAE,MAAM,EAAE,MAAM,CAAC,EAAE,OAAO,EAAE,GAAG,OAAO,CAAC,IAAI,CAAC,CAAA;CACxD;AAoBD;;GAEG;AACH,qBAAa,iBAAkB,YAAW,eAAe;IACvD,8CAA8C;IAC9C,OAAO,CAAC,QAAQ,CAA8D;IAC9E,oCAAoC;IACpC,OAAO,CAAC,GAAG,CAA8B;IACzC,mCAAmC;IACnC,OAAO,CAAC,MAAM,CAAgB;IAC9B,yDAAyD;IACzD,OAAO,CAAC,gBAAgB,CAAQ;IAEhC;;;;OAIG;gBACS,MAAM,EAAE,cAAc;IAgBlC;;;;;OAKG;IACG,OAAO,IAAI,OAAO,CAAC,IAAI,CAAC;IAW9B;;;OAGG;IACG,UAAU,IAAI,OAAO,CAAC,IAAI,CAAC;IAOjC;;;;;;OAMG;IACG,KAAK,CAAC,CAAC,EAAE,GAAG,EAAE,MAAM,EAAE,MAAM,GAAE,OAAO,EAAO,GAAG,OAAO,CAAC,CAAC,CAAC;IAO/D;;;;;OAKG;IACG,OAAO,CAAC,GAAG,EAAE,MAAM,EAAE,MAAM,GAAE,OAAO,EAAO,GAAG,OAAO,CAAC,IAAI,CAAC;CAMlE;AAED;;;;;GAKG;AACH,wBAAsB,qBAAqB,CAAC,MAAM,EAAE,cAAc,GAAG,OAAO,CAAC,eAAe,CAAC,CAI5F"}
|
|
@@ -64,13 +64,14 @@ class PostgresJsAdapter {
|
|
|
64
64
|
value: void 0
|
|
65
65
|
});
|
|
66
66
|
this.config = config;
|
|
67
|
-
if (
|
|
67
|
+
if ("connectionString" in config && config.connectionString) {
|
|
68
68
|
// Use the provided connection string directly
|
|
69
69
|
this.connectionString = config.connectionString;
|
|
70
70
|
}
|
|
71
71
|
else {
|
|
72
72
|
// Build connection string from individual parameters
|
|
73
|
-
this.connectionString =
|
|
73
|
+
this.connectionString =
|
|
74
|
+
`postgres://${config.user}:${config.password}@${config.host}:${config.port}/${config.database}`;
|
|
74
75
|
if (config.ssl) {
|
|
75
76
|
this.connectionString += "?sslmode=require";
|
|
76
77
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"session-pathway.d.ts","sourceRoot":"","sources":["../../src/pathways/session-pathway.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,eAAe,EAAE,cAAc,EAAE,MAAM,cAAc,
|
|
1
|
+
{"version":3,"file":"session-pathway.d.ts","sourceRoot":"","sources":["../../src/pathways/session-pathway.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,eAAe,EAAE,cAAc,EAAE,MAAM,cAAc,CAAA;AACnE,OAAO,KAAK,EAAE,aAAa,EAAE,mBAAmB,EAAE,MAAM,YAAY,CAAA;AAqBpE;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAsCG;AACH,qBAAa,qBAAqB,CAEhC,QAAQ,SAAS,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,EAAE,EAC7C,cAAc,SAAS,MAAM,QAAQ,GAAG,KAAK;IAE7C,OAAO,CAAC,QAAQ,CAAC,eAAe,CAA2C;IAC3E,OAAO,CAAC,QAAQ,CAAC,SAAS,CAAQ;IAElC;;;;;OAKG;gBAED,eAAe,EAAE,eAAe,CAAC,QAAQ,EAAE,cAAc,CAAC,EAC1D,SAAS,CAAC,EAAE,MAAM;IAMpB;;;;OAIG;IACH,YAAY,IAAI,MAAM;IAItB;;;;;;;;;;;;;;;;;;;;;;;;;;;;OA4BG;IACH,gBAAgB,CAAC,QAAQ,EAAE,cAAc,GAAG,IAAI;IAKhD;;;;;;;;OAQG;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;CAU9B"}
|
|
@@ -7,14 +7,14 @@ exports.SessionPathwayBuilder = void 0;
|
|
|
7
7
|
*/
|
|
8
8
|
function generateUUID() {
|
|
9
9
|
// Check for Deno or browser crypto.randomUUID support
|
|
10
|
-
if (typeof crypto !==
|
|
10
|
+
if (typeof crypto !== "undefined" && crypto.randomUUID) {
|
|
11
11
|
return crypto.randomUUID();
|
|
12
12
|
}
|
|
13
13
|
// Fallback to manual UUID generation (compatible with all platforms)
|
|
14
14
|
// Implementation based on RFC4122 version 4
|
|
15
|
-
return
|
|
15
|
+
return "xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx".replace(/[xy]/g, (c) => {
|
|
16
16
|
const r = Math.random() * 16 | 0;
|
|
17
|
-
const v = c ===
|
|
17
|
+
const v = c === "x" ? r : (r & 0x3 | 0x8);
|
|
18
18
|
return v.toString(16);
|
|
19
19
|
});
|
|
20
20
|
}
|