@flowcore/pathways 0.8.0 → 0.9.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (33) hide show
  1. package/CHANGELOG.md +19 -0
  2. package/README.md +95 -0
  3. package/esm/pathways/builder.d.ts +31 -1
  4. package/esm/pathways/builder.d.ts.map +1 -1
  5. package/esm/pathways/builder.js +47 -5
  6. package/esm/pathways/kv/kv-adapter.d.ts +59 -2
  7. package/esm/pathways/kv/kv-adapter.d.ts.map +1 -1
  8. package/esm/pathways/kv/kv-adapter.js +31 -1
  9. package/esm/pathways/postgres/postgres-pathway-state.d.ts +131 -1
  10. package/esm/pathways/postgres/postgres-pathway-state.d.ts.map +1 -1
  11. package/esm/pathways/postgres/postgres-pathway-state.js +131 -1
  12. package/esm/pathways/session-pathway.d.ts +63 -1
  13. package/esm/pathways/session-pathway.d.ts.map +1 -1
  14. package/esm/pathways/session-pathway.js +65 -0
  15. package/esm/router/index.d.ts +83 -2
  16. package/esm/router/index.d.ts.map +1 -1
  17. package/esm/router/index.js +83 -2
  18. package/package.json +4 -5
  19. package/script/pathways/builder.d.ts +31 -1
  20. package/script/pathways/builder.d.ts.map +1 -1
  21. package/script/pathways/builder.js +47 -5
  22. package/script/pathways/kv/kv-adapter.d.ts +59 -2
  23. package/script/pathways/kv/kv-adapter.d.ts.map +1 -1
  24. package/script/pathways/kv/kv-adapter.js +31 -1
  25. package/script/pathways/postgres/postgres-pathway-state.d.ts +131 -1
  26. package/script/pathways/postgres/postgres-pathway-state.d.ts.map +1 -1
  27. package/script/pathways/postgres/postgres-pathway-state.js +131 -1
  28. package/script/pathways/session-pathway.d.ts +63 -1
  29. package/script/pathways/session-pathway.d.ts.map +1 -1
  30. package/script/pathways/session-pathway.js +65 -0
  31. package/script/router/index.d.ts +83 -2
  32. package/script/router/index.d.ts.map +1 -1
  33. package/script/router/index.js +83 -2
@@ -24,6 +24,38 @@ function generateUUID() {
24
24
  *
25
25
  * This provides a convenient way to track operations within a user session
26
26
  * by automatically including the session ID in metadata.
27
+ *
28
+ * Key features:
29
+ * - Automatic session ID generation if none is provided
30
+ * - Cross-platform UUID generation (works in Deno, Bun, and Node.js)
31
+ * - Simple API for accessing the current session ID
32
+ * - Convenient integration with session-specific user resolvers
33
+ * - Automatic inclusion of session ID in all write operations
34
+ * - Support for overriding the session ID on specific writes
35
+ *
36
+ * Use cases:
37
+ * - Tracking user actions across multiple pathway writes
38
+ * - Connecting related events in a single user session
39
+ * - Supporting multi-user environments where different users' operations need to be tracked separately
40
+ * - Building user activity logs with session grouping
41
+ *
42
+ * @example
43
+ * ```typescript
44
+ * // Create a session pathway with auto-generated ID
45
+ * const session = new SessionPathwayBuilder(pathwaysBuilder);
46
+ *
47
+ * // Get the auto-generated session ID
48
+ * const sessionId = session.getSessionId();
49
+ *
50
+ * // Register a user resolver for this session
51
+ * session.withUserResolver(async () => getCurrentUserId());
52
+ *
53
+ * // Write events with session context
54
+ * await session.write("order/placed", orderData);
55
+ * await session.write("user/action", actionData);
56
+ *
57
+ * // All events will be associated with the same session ID
58
+ * ```
27
59
  */
28
60
  class SessionPathwayBuilder {
29
61
  /**
@@ -56,6 +88,39 @@ class SessionPathwayBuilder {
56
88
  getSessionId() {
57
89
  return this.sessionId;
58
90
  }
91
+ /**
92
+ * Registers a user resolver for this session
93
+ *
94
+ * This is a convenience method that calls `pathwaysBuilder.withSessionUserResolver`
95
+ * with the current session ID, allowing you to set up a resolver specific to this session
96
+ * without having to manually pass the session ID.
97
+ *
98
+ * The resolver will be called whenever events are written through this session,
99
+ * and the resolved user ID will be included in the event metadata.
100
+ *
101
+ * @param resolver The function that resolves to the user ID for this session
102
+ * @returns The SessionPathwayBuilder instance for chaining
103
+ *
104
+ * @throws Error if the underlying PathwaysBuilder does not have session user resolvers configured
105
+ *
106
+ * @example
107
+ * ```typescript
108
+ * const session = new SessionPathwayBuilder(pathwaysBuilder);
109
+ *
110
+ * // Register a user resolver for this session
111
+ * session.withUserResolver(async () => {
112
+ * // Get the user ID associated with this session
113
+ * return getUserIdFromSession();
114
+ * });
115
+ *
116
+ * // When writing events, the user ID will be automatically included
117
+ * await session.write("user/action", actionData);
118
+ * ```
119
+ */
120
+ withUserResolver(resolver) {
121
+ this.pathwaysBuilder.withSessionUserResolver(this.sessionId, resolver);
122
+ return this;
123
+ }
59
124
  /**
60
125
  * Writes data to a pathway, proxying to the underlying PathwaysBuilder
61
126
  *
@@ -11,6 +11,49 @@ import type { PathwaysBuilder } from "../pathways/index.js";
11
11
  import type { Logger } from "../pathways/logger.js";
12
12
  /**
13
13
  * Router class that handles directing events to the appropriate pathway handlers
14
+ *
15
+ * The PathwayRouter serves as a bridge between incoming webhook events and the PathwaysBuilder,
16
+ * ensuring events are routed to the correct pathway handlers based on flow type and event type.
17
+ *
18
+ * Key features:
19
+ * - Secure authentication using a secret key
20
+ * - Automatic mapping of events to the correct pathway handlers
21
+ * - Compatibility with both legacy and modern Flowcore event formats
22
+ * - Detailed error handling and logging
23
+ *
24
+ * Use cases:
25
+ * - Building webhook endpoints that receive Flowcore events
26
+ * - Creating API routes that process events from external systems
27
+ * - Implementing event-driven microservices that consume Flowcore events
28
+ *
29
+ * @example
30
+ * ```typescript
31
+ * // Create a router with authentication
32
+ * const SECRET_KEY = "your-webhook-secret";
33
+ * const router = new PathwayRouter(pathwaysBuilder, SECRET_KEY);
34
+ *
35
+ * // In your HTTP handler:
36
+ * async function handleWebhook(req: Request) {
37
+ * const event = await req.json();
38
+ * const secret = req.headers.get("X-Webhook-Secret");
39
+ *
40
+ * try {
41
+ * const result = await router.processEvent(event, secret);
42
+ * return new Response(JSON.stringify(result), {
43
+ * status: 200,
44
+ * headers: { "Content-Type": "application/json" }
45
+ * });
46
+ * } catch (error) {
47
+ * console.error("Error processing event:", error);
48
+ * return new Response(JSON.stringify({
49
+ * error: error.message
50
+ * }), {
51
+ * status: 401,
52
+ * headers: { "Content-Type": "application/json" }
53
+ * });
54
+ * }
55
+ * }
56
+ * ```
14
57
  */
15
58
  export declare class PathwayRouter {
16
59
  private readonly pathways;
@@ -28,10 +71,48 @@ export declare class PathwayRouter {
28
71
  /**
29
72
  * Process an incoming event by routing it to the appropriate pathway handler
30
73
  *
31
- * @param event The event to process
74
+ * This method handles the complete lifecycle of an incoming event:
75
+ * 1. Validates the authentication using the provided secret key
76
+ * 2. Maps the event to the correct pathway based on flowType and eventType
77
+ * 3. Delegates processing to the PathwaysBuilder
78
+ * 4. Provides detailed error handling and feedback
79
+ *
80
+ * The method supports both modern Flowcore events and legacy events that used
81
+ * the "aggregator" field instead of "flowType". It automatically converts legacy
82
+ * events to the modern format before processing.
83
+ *
84
+ * @param event The event to process, containing flowType, eventType, and payload
32
85
  * @param providedSecret The secret key provided for authentication
33
86
  * @returns Result of the event processing with success status and message
34
- * @throws Error if authentication fails, pathway is not found, or processing fails
87
+ *
88
+ * @throws Error if authentication fails (401 unauthorized)
89
+ * @throws Error if the pathway is not found (404 not found)
90
+ * @throws Error if processing fails (includes the original error message)
91
+ *
92
+ * @example
93
+ * ```typescript
94
+ * // Basic usage
95
+ * try {
96
+ * const result = await router.processEvent(incomingEvent, secretFromHeader);
97
+ * console.log("Success:", result.message);
98
+ * } catch (error) {
99
+ * console.error("Failed to process event:", error.message);
100
+ * }
101
+ *
102
+ * // With error handling for different error types
103
+ * try {
104
+ * const result = await router.processEvent(event, secret);
105
+ * return { status: 200, body: result };
106
+ * } catch (error) {
107
+ * if (error.message.includes("Invalid secret key")) {
108
+ * return { status: 401, body: { error: "Unauthorized" } };
109
+ * } else if (error.message.includes("not found")) {
110
+ * return { status: 404, body: { error: "Pathway not found" } };
111
+ * } else {
112
+ * return { status: 500, body: { error: "Processing failed" } };
113
+ * }
114
+ * }
115
+ * ```
35
116
  */
36
117
  processEvent(event: FlowcoreLegacyEvent, providedSecret: string): Promise<{
37
118
  success: boolean;
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/router/index.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AACH,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,4BAA4B,CAAA;AAErE,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,sBAAsB,CAAA;AAC3D,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,uBAAuB,CAAA;AAGnD;;GAEG;AACH,qBAAa,aAAa;IAatB,OAAO,CAAC,QAAQ,CAAC,QAAQ;IACzB,OAAO,CAAC,QAAQ,CAAC,SAAS;IAb5B,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAS;IAEhC;;;;;;;OAOG;gBAGgB,QAAQ,EAAE,eAAe,CAAC,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC,EAC9C,SAAS,EAAE,MAAM,EAClC,MAAM,CAAC,EAAE,MAAM;IAajB;;;;;;;OAOG;IACG,YAAY,CAAC,KAAK,EAAE,mBAAmB,EAAE,cAAc,EAAE,MAAM,GAAG,OAAO,CAAC;QAAE,OAAO,EAAE,OAAO,CAAC;QAAC,OAAO,EAAE,MAAM,CAAA;KAAE,CAAC;CAkDvH"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/router/index.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AACH,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,4BAA4B,CAAA;AAErE,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,sBAAsB,CAAA;AAC3D,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,uBAAuB,CAAA;AAGnD;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA6CG;AACH,qBAAa,aAAa;IAatB,OAAO,CAAC,QAAQ,CAAC,QAAQ;IACzB,OAAO,CAAC,QAAQ,CAAC,SAAS;IAb5B,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAS;IAEhC;;;;;;;OAOG;gBAGgB,QAAQ,EAAE,eAAe,CAAC,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC,EAC9C,SAAS,EAAE,MAAM,EAClC,MAAM,CAAC,EAAE,MAAM;IAajB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;OA6CG;IACG,YAAY,CAAC,KAAK,EAAE,mBAAmB,EAAE,cAAc,EAAE,MAAM,GAAG,OAAO,CAAC;QAAE,OAAO,EAAE,OAAO,CAAC;QAAC,OAAO,EAAE,MAAM,CAAA;KAAE,CAAC;CAkDvH"}
@@ -4,6 +4,49 @@ exports.PathwayRouter = void 0;
4
4
  const logger_js_1 = require("../pathways/logger.js");
5
5
  /**
6
6
  * Router class that handles directing events to the appropriate pathway handlers
7
+ *
8
+ * The PathwayRouter serves as a bridge between incoming webhook events and the PathwaysBuilder,
9
+ * ensuring events are routed to the correct pathway handlers based on flow type and event type.
10
+ *
11
+ * Key features:
12
+ * - Secure authentication using a secret key
13
+ * - Automatic mapping of events to the correct pathway handlers
14
+ * - Compatibility with both legacy and modern Flowcore event formats
15
+ * - Detailed error handling and logging
16
+ *
17
+ * Use cases:
18
+ * - Building webhook endpoints that receive Flowcore events
19
+ * - Creating API routes that process events from external systems
20
+ * - Implementing event-driven microservices that consume Flowcore events
21
+ *
22
+ * @example
23
+ * ```typescript
24
+ * // Create a router with authentication
25
+ * const SECRET_KEY = "your-webhook-secret";
26
+ * const router = new PathwayRouter(pathwaysBuilder, SECRET_KEY);
27
+ *
28
+ * // In your HTTP handler:
29
+ * async function handleWebhook(req: Request) {
30
+ * const event = await req.json();
31
+ * const secret = req.headers.get("X-Webhook-Secret");
32
+ *
33
+ * try {
34
+ * const result = await router.processEvent(event, secret);
35
+ * return new Response(JSON.stringify(result), {
36
+ * status: 200,
37
+ * headers: { "Content-Type": "application/json" }
38
+ * });
39
+ * } catch (error) {
40
+ * console.error("Error processing event:", error);
41
+ * return new Response(JSON.stringify({
42
+ * error: error.message
43
+ * }), {
44
+ * status: 401,
45
+ * headers: { "Content-Type": "application/json" }
46
+ * });
47
+ * }
48
+ * }
49
+ * ```
7
50
  */
8
51
  class PathwayRouter {
9
52
  /**
@@ -46,10 +89,48 @@ class PathwayRouter {
46
89
  /**
47
90
  * Process an incoming event by routing it to the appropriate pathway handler
48
91
  *
49
- * @param event The event to process
92
+ * This method handles the complete lifecycle of an incoming event:
93
+ * 1. Validates the authentication using the provided secret key
94
+ * 2. Maps the event to the correct pathway based on flowType and eventType
95
+ * 3. Delegates processing to the PathwaysBuilder
96
+ * 4. Provides detailed error handling and feedback
97
+ *
98
+ * The method supports both modern Flowcore events and legacy events that used
99
+ * the "aggregator" field instead of "flowType". It automatically converts legacy
100
+ * events to the modern format before processing.
101
+ *
102
+ * @param event The event to process, containing flowType, eventType, and payload
50
103
  * @param providedSecret The secret key provided for authentication
51
104
  * @returns Result of the event processing with success status and message
52
- * @throws Error if authentication fails, pathway is not found, or processing fails
105
+ *
106
+ * @throws Error if authentication fails (401 unauthorized)
107
+ * @throws Error if the pathway is not found (404 not found)
108
+ * @throws Error if processing fails (includes the original error message)
109
+ *
110
+ * @example
111
+ * ```typescript
112
+ * // Basic usage
113
+ * try {
114
+ * const result = await router.processEvent(incomingEvent, secretFromHeader);
115
+ * console.log("Success:", result.message);
116
+ * } catch (error) {
117
+ * console.error("Failed to process event:", error.message);
118
+ * }
119
+ *
120
+ * // With error handling for different error types
121
+ * try {
122
+ * const result = await router.processEvent(event, secret);
123
+ * return { status: 200, body: result };
124
+ * } catch (error) {
125
+ * if (error.message.includes("Invalid secret key")) {
126
+ * return { status: 401, body: { error: "Unauthorized" } };
127
+ * } else if (error.message.includes("not found")) {
128
+ * return { status: 404, body: { error: "Pathway not found" } };
129
+ * } else {
130
+ * return { status: 500, body: { error: "Processing failed" } };
131
+ * }
132
+ * }
133
+ * ```
53
134
  */
54
135
  async processEvent(event, providedSecret) {
55
136
  // Validate secret key