@blokjs/trigger-websocket 0.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/CHANGELOG.md +22 -0
- package/dist/WebSocketTrigger.d.ts +264 -0
- package/dist/WebSocketTrigger.d.ts.map +1 -0
- package/dist/WebSocketTrigger.js +626 -0
- package/dist/WebSocketTrigger.js.map +1 -0
- package/dist/index.d.ts +113 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +117 -0
- package/dist/index.js.map +1 -0
- package/package.json +43 -0
- package/src/WebSocketTrigger.test.ts +490 -0
- package/src/WebSocketTrigger.ts +869 -0
- package/src/WebSocketTriggerMonitoring.test.ts +371 -0
- package/src/index.ts +127 -0
- package/tsconfig.json +22 -0
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,113 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @blok/trigger-websocket
|
|
3
|
+
*
|
|
4
|
+
* WebSocket trigger for Blok workflows.
|
|
5
|
+
* Handle real-time bidirectional communication.
|
|
6
|
+
*
|
|
7
|
+
* Features:
|
|
8
|
+
* - Connection management (connect, disconnect, reconnect)
|
|
9
|
+
* - Room/channel support for broadcasting
|
|
10
|
+
* - Message routing to workflows
|
|
11
|
+
* - Heartbeat/ping-pong for connection health
|
|
12
|
+
* - Authentication middleware
|
|
13
|
+
* - Binary message support
|
|
14
|
+
*
|
|
15
|
+
* @example
|
|
16
|
+
* ```typescript
|
|
17
|
+
* import { WebSocketTrigger } from "@blok/trigger-websocket";
|
|
18
|
+
* import { WebSocketServer } from "ws";
|
|
19
|
+
*
|
|
20
|
+
* class MyWebSocketTrigger extends WebSocketTrigger {
|
|
21
|
+
* protected nodes = myNodes;
|
|
22
|
+
* protected workflows = myWorkflows;
|
|
23
|
+
* }
|
|
24
|
+
*
|
|
25
|
+
* const trigger = new MyWebSocketTrigger();
|
|
26
|
+
* await trigger.listen();
|
|
27
|
+
*
|
|
28
|
+
* // Create WebSocket server
|
|
29
|
+
* const wss = new WebSocketServer({ port: 8080 });
|
|
30
|
+
*
|
|
31
|
+
* wss.on("connection", async (ws, req) => {
|
|
32
|
+
* const headers = req.headers as Record<string, string>;
|
|
33
|
+
* const client = await trigger.handleConnection(
|
|
34
|
+
* {
|
|
35
|
+
* send: (data) => ws.send(data),
|
|
36
|
+
* close: (code, reason) => ws.close(code, reason),
|
|
37
|
+
* ping: () => ws.ping(),
|
|
38
|
+
* },
|
|
39
|
+
* req,
|
|
40
|
+
* headers
|
|
41
|
+
* );
|
|
42
|
+
*
|
|
43
|
+
* if (!client) return;
|
|
44
|
+
*
|
|
45
|
+
* ws.on("message", async (data, isBinary) => {
|
|
46
|
+
* await trigger.handleMessage(client.id, data, isBinary);
|
|
47
|
+
* });
|
|
48
|
+
*
|
|
49
|
+
* ws.on("close", (code, reason) => {
|
|
50
|
+
* trigger.handleClose(client.id, code, reason.toString());
|
|
51
|
+
* });
|
|
52
|
+
*
|
|
53
|
+
* ws.on("error", (error) => {
|
|
54
|
+
* trigger.handleError(client.id, error);
|
|
55
|
+
* });
|
|
56
|
+
*
|
|
57
|
+
* ws.on("ping", () => trigger.handlePing(client.id));
|
|
58
|
+
* ws.on("pong", () => trigger.handlePong(client.id));
|
|
59
|
+
* });
|
|
60
|
+
* ```
|
|
61
|
+
*
|
|
62
|
+
* Workflow Definition:
|
|
63
|
+
* ```typescript
|
|
64
|
+
* Workflow({ name: "chat-message", version: "1.0.0" })
|
|
65
|
+
* .addTrigger("websocket", {
|
|
66
|
+
* events: ["message", "chat.*"],
|
|
67
|
+
* rooms: ["general", "support"],
|
|
68
|
+
* })
|
|
69
|
+
* .addStep({ ... });
|
|
70
|
+
* ```
|
|
71
|
+
*
|
|
72
|
+
* Authentication:
|
|
73
|
+
* ```typescript
|
|
74
|
+
* trigger.setAuthHandler(async (request, headers) => {
|
|
75
|
+
* const token = headers["authorization"]?.replace("Bearer ", "");
|
|
76
|
+
* if (!token) {
|
|
77
|
+
* return { authenticated: false, error: "No token provided" };
|
|
78
|
+
* }
|
|
79
|
+
*
|
|
80
|
+
* const user = await verifyToken(token);
|
|
81
|
+
* if (!user) {
|
|
82
|
+
* return { authenticated: false, error: "Invalid token" };
|
|
83
|
+
* }
|
|
84
|
+
*
|
|
85
|
+
* return {
|
|
86
|
+
* authenticated: true,
|
|
87
|
+
* clientId: user.id,
|
|
88
|
+
* metadata: { userId: user.id, role: user.role },
|
|
89
|
+
* };
|
|
90
|
+
* });
|
|
91
|
+
* ```
|
|
92
|
+
*
|
|
93
|
+
* Room Management:
|
|
94
|
+
* ```typescript
|
|
95
|
+
* // Join a room
|
|
96
|
+
* await trigger.joinRoom(clientId, "room-name");
|
|
97
|
+
*
|
|
98
|
+
* // Leave a room
|
|
99
|
+
* await trigger.leaveRoom(clientId, "room-name");
|
|
100
|
+
*
|
|
101
|
+
* // Broadcast to room
|
|
102
|
+
* trigger.broadcastToRoom("room-name", "event", { message: "Hello!" });
|
|
103
|
+
*
|
|
104
|
+
* // Send to specific client
|
|
105
|
+
* trigger.sendToClient(clientId, "event", { message: "Private message" });
|
|
106
|
+
*
|
|
107
|
+
* // Broadcast to all
|
|
108
|
+
* trigger.broadcastToAll("event", { message: "System message" });
|
|
109
|
+
* ```
|
|
110
|
+
*/
|
|
111
|
+
export { WebSocketTrigger, type WebSocketMessage, type WebSocketMessageType, type WebSocketState, type WebSocketClient, type WebSocketRoom, type WebSocketEventType, type WebSocketEvent, type AuthResult, type AuthHandler, } from "./WebSocketTrigger";
|
|
112
|
+
export type { WebSocketTriggerOpts } from "@blok/helper";
|
|
113
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA6GG;AAGH,OAAO,EACN,gBAAgB,EAChB,KAAK,gBAAgB,EACrB,KAAK,oBAAoB,EACzB,KAAK,cAAc,EACnB,KAAK,eAAe,EACpB,KAAK,aAAa,EAClB,KAAK,kBAAkB,EACvB,KAAK,cAAc,EACnB,KAAK,UAAU,EACf,KAAK,WAAW,GAChB,MAAM,oBAAoB,CAAC;AAG5B,YAAY,EAAE,oBAAoB,EAAE,MAAM,cAAc,CAAC"}
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,117 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* @blok/trigger-websocket
|
|
4
|
+
*
|
|
5
|
+
* WebSocket trigger for Blok workflows.
|
|
6
|
+
* Handle real-time bidirectional communication.
|
|
7
|
+
*
|
|
8
|
+
* Features:
|
|
9
|
+
* - Connection management (connect, disconnect, reconnect)
|
|
10
|
+
* - Room/channel support for broadcasting
|
|
11
|
+
* - Message routing to workflows
|
|
12
|
+
* - Heartbeat/ping-pong for connection health
|
|
13
|
+
* - Authentication middleware
|
|
14
|
+
* - Binary message support
|
|
15
|
+
*
|
|
16
|
+
* @example
|
|
17
|
+
* ```typescript
|
|
18
|
+
* import { WebSocketTrigger } from "@blok/trigger-websocket";
|
|
19
|
+
* import { WebSocketServer } from "ws";
|
|
20
|
+
*
|
|
21
|
+
* class MyWebSocketTrigger extends WebSocketTrigger {
|
|
22
|
+
* protected nodes = myNodes;
|
|
23
|
+
* protected workflows = myWorkflows;
|
|
24
|
+
* }
|
|
25
|
+
*
|
|
26
|
+
* const trigger = new MyWebSocketTrigger();
|
|
27
|
+
* await trigger.listen();
|
|
28
|
+
*
|
|
29
|
+
* // Create WebSocket server
|
|
30
|
+
* const wss = new WebSocketServer({ port: 8080 });
|
|
31
|
+
*
|
|
32
|
+
* wss.on("connection", async (ws, req) => {
|
|
33
|
+
* const headers = req.headers as Record<string, string>;
|
|
34
|
+
* const client = await trigger.handleConnection(
|
|
35
|
+
* {
|
|
36
|
+
* send: (data) => ws.send(data),
|
|
37
|
+
* close: (code, reason) => ws.close(code, reason),
|
|
38
|
+
* ping: () => ws.ping(),
|
|
39
|
+
* },
|
|
40
|
+
* req,
|
|
41
|
+
* headers
|
|
42
|
+
* );
|
|
43
|
+
*
|
|
44
|
+
* if (!client) return;
|
|
45
|
+
*
|
|
46
|
+
* ws.on("message", async (data, isBinary) => {
|
|
47
|
+
* await trigger.handleMessage(client.id, data, isBinary);
|
|
48
|
+
* });
|
|
49
|
+
*
|
|
50
|
+
* ws.on("close", (code, reason) => {
|
|
51
|
+
* trigger.handleClose(client.id, code, reason.toString());
|
|
52
|
+
* });
|
|
53
|
+
*
|
|
54
|
+
* ws.on("error", (error) => {
|
|
55
|
+
* trigger.handleError(client.id, error);
|
|
56
|
+
* });
|
|
57
|
+
*
|
|
58
|
+
* ws.on("ping", () => trigger.handlePing(client.id));
|
|
59
|
+
* ws.on("pong", () => trigger.handlePong(client.id));
|
|
60
|
+
* });
|
|
61
|
+
* ```
|
|
62
|
+
*
|
|
63
|
+
* Workflow Definition:
|
|
64
|
+
* ```typescript
|
|
65
|
+
* Workflow({ name: "chat-message", version: "1.0.0" })
|
|
66
|
+
* .addTrigger("websocket", {
|
|
67
|
+
* events: ["message", "chat.*"],
|
|
68
|
+
* rooms: ["general", "support"],
|
|
69
|
+
* })
|
|
70
|
+
* .addStep({ ... });
|
|
71
|
+
* ```
|
|
72
|
+
*
|
|
73
|
+
* Authentication:
|
|
74
|
+
* ```typescript
|
|
75
|
+
* trigger.setAuthHandler(async (request, headers) => {
|
|
76
|
+
* const token = headers["authorization"]?.replace("Bearer ", "");
|
|
77
|
+
* if (!token) {
|
|
78
|
+
* return { authenticated: false, error: "No token provided" };
|
|
79
|
+
* }
|
|
80
|
+
*
|
|
81
|
+
* const user = await verifyToken(token);
|
|
82
|
+
* if (!user) {
|
|
83
|
+
* return { authenticated: false, error: "Invalid token" };
|
|
84
|
+
* }
|
|
85
|
+
*
|
|
86
|
+
* return {
|
|
87
|
+
* authenticated: true,
|
|
88
|
+
* clientId: user.id,
|
|
89
|
+
* metadata: { userId: user.id, role: user.role },
|
|
90
|
+
* };
|
|
91
|
+
* });
|
|
92
|
+
* ```
|
|
93
|
+
*
|
|
94
|
+
* Room Management:
|
|
95
|
+
* ```typescript
|
|
96
|
+
* // Join a room
|
|
97
|
+
* await trigger.joinRoom(clientId, "room-name");
|
|
98
|
+
*
|
|
99
|
+
* // Leave a room
|
|
100
|
+
* await trigger.leaveRoom(clientId, "room-name");
|
|
101
|
+
*
|
|
102
|
+
* // Broadcast to room
|
|
103
|
+
* trigger.broadcastToRoom("room-name", "event", { message: "Hello!" });
|
|
104
|
+
*
|
|
105
|
+
* // Send to specific client
|
|
106
|
+
* trigger.sendToClient(clientId, "event", { message: "Private message" });
|
|
107
|
+
*
|
|
108
|
+
* // Broadcast to all
|
|
109
|
+
* trigger.broadcastToAll("event", { message: "System message" });
|
|
110
|
+
* ```
|
|
111
|
+
*/
|
|
112
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
113
|
+
exports.WebSocketTrigger = void 0;
|
|
114
|
+
// Core exports
|
|
115
|
+
var WebSocketTrigger_1 = require("./WebSocketTrigger");
|
|
116
|
+
Object.defineProperty(exports, "WebSocketTrigger", { enumerable: true, get: function () { return WebSocketTrigger_1.WebSocketTrigger; } });
|
|
117
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA6GG;;;AAEH,eAAe;AACf,uDAW4B;AAV3B,oHAAA,gBAAgB,OAAA"}
|
package/package.json
ADDED
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@blokjs/trigger-websocket",
|
|
3
|
+
"version": "0.2.0",
|
|
4
|
+
"description": "WebSocket trigger for Blok workflows - real-time bidirectional communication",
|
|
5
|
+
"type": "module",
|
|
6
|
+
"main": "dist/index.js",
|
|
7
|
+
"types": "dist/index.d.ts",
|
|
8
|
+
"scripts": {
|
|
9
|
+
"build": "rm -rf dist && bun run tsc",
|
|
10
|
+
"build:dev": "tsc --watch",
|
|
11
|
+
"test": "vitest run",
|
|
12
|
+
"test:dev": "vitest"
|
|
13
|
+
},
|
|
14
|
+
"author": "Deskree Technologies Inc.",
|
|
15
|
+
"license": "Apache-2.0",
|
|
16
|
+
"dependencies": {
|
|
17
|
+
"@blokjs/helper": "workspace:*",
|
|
18
|
+
"@blokjs/runner": "workspace:*",
|
|
19
|
+
"@blokjs/shared": "workspace:*",
|
|
20
|
+
"@opentelemetry/api": "^1.9.0",
|
|
21
|
+
"uuid": "^11.1.0"
|
|
22
|
+
},
|
|
23
|
+
"peerDependencies": {
|
|
24
|
+
"ws": "^8.19.0"
|
|
25
|
+
},
|
|
26
|
+
"peerDependenciesMeta": {
|
|
27
|
+
"ws": {
|
|
28
|
+
"optional": true
|
|
29
|
+
}
|
|
30
|
+
},
|
|
31
|
+
"devDependencies": {
|
|
32
|
+
"@types/node": "^22.15.21",
|
|
33
|
+
"@types/uuid": "^11.0.0",
|
|
34
|
+
"@types/ws": "^8.18.1",
|
|
35
|
+
"typescript": "^5.8.3",
|
|
36
|
+
"vitest": "^4.0.18",
|
|
37
|
+
"ws": "^8.19.0"
|
|
38
|
+
},
|
|
39
|
+
"private": false,
|
|
40
|
+
"publishConfig": {
|
|
41
|
+
"access": "public"
|
|
42
|
+
}
|
|
43
|
+
}
|