@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
|
@@ -0,0 +1,626 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* WebSocketTrigger - Real-time bidirectional communication trigger
|
|
4
|
+
*
|
|
5
|
+
* Extends TriggerBase to handle WebSocket connections for:
|
|
6
|
+
* - Real-time messaging
|
|
7
|
+
* - Live updates and notifications
|
|
8
|
+
* - Collaborative features
|
|
9
|
+
* - Streaming data
|
|
10
|
+
*
|
|
11
|
+
* Features:
|
|
12
|
+
* - Connection management (connect, disconnect, reconnect)
|
|
13
|
+
* - Room/channel support for broadcasting
|
|
14
|
+
* - Message routing to workflows
|
|
15
|
+
* - Heartbeat/ping-pong for connection health
|
|
16
|
+
* - Authentication middleware
|
|
17
|
+
* - Binary message support
|
|
18
|
+
*/
|
|
19
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
20
|
+
exports.WebSocketTrigger = void 0;
|
|
21
|
+
const runner_1 = require("@blok/runner");
|
|
22
|
+
const api_1 = require("@opentelemetry/api");
|
|
23
|
+
const uuid_1 = require("uuid");
|
|
24
|
+
/**
|
|
25
|
+
* WebSocketTrigger - Handle WebSocket connections and messages
|
|
26
|
+
*/
|
|
27
|
+
class WebSocketTrigger extends runner_1.TriggerBase {
|
|
28
|
+
nodeMap = {};
|
|
29
|
+
tracer = api_1.trace.getTracer(process.env.PROJECT_NAME || "trigger-websocket-workflow", process.env.PROJECT_VERSION || "0.0.1");
|
|
30
|
+
logger = new runner_1.DefaultLogger();
|
|
31
|
+
websocketWorkflows = [];
|
|
32
|
+
// Connection management
|
|
33
|
+
clients = new Map();
|
|
34
|
+
rooms = new Map();
|
|
35
|
+
// Metrics
|
|
36
|
+
activeConnections = 0;
|
|
37
|
+
totalMessages = 0;
|
|
38
|
+
// Configuration
|
|
39
|
+
heartbeatInterval = null;
|
|
40
|
+
heartbeatIntervalMs = 30000; // 30 seconds
|
|
41
|
+
maxClients = 10000;
|
|
42
|
+
messageRateLimit = 100; // messages per second per client
|
|
43
|
+
// Optional auth handler
|
|
44
|
+
authHandler;
|
|
45
|
+
constructor() {
|
|
46
|
+
super();
|
|
47
|
+
this.loadNodes();
|
|
48
|
+
this.loadWorkflows();
|
|
49
|
+
}
|
|
50
|
+
/**
|
|
51
|
+
* Load nodes into the node map
|
|
52
|
+
*/
|
|
53
|
+
loadNodes() {
|
|
54
|
+
this.nodeMap.nodes = new runner_1.NodeMap();
|
|
55
|
+
if (this.nodes) {
|
|
56
|
+
const nodeKeys = Object.keys(this.nodes);
|
|
57
|
+
for (const key of nodeKeys) {
|
|
58
|
+
this.nodeMap.nodes.addNode(key, this.nodes[key]);
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
/**
|
|
63
|
+
* Load workflows into the workflow map
|
|
64
|
+
*/
|
|
65
|
+
loadWorkflows() {
|
|
66
|
+
this.nodeMap.workflows = this.workflows || {};
|
|
67
|
+
}
|
|
68
|
+
/**
|
|
69
|
+
* Set authentication handler
|
|
70
|
+
*/
|
|
71
|
+
setAuthHandler(handler) {
|
|
72
|
+
this.authHandler = handler;
|
|
73
|
+
}
|
|
74
|
+
/**
|
|
75
|
+
* Initialize WebSocket trigger
|
|
76
|
+
*/
|
|
77
|
+
async listen() {
|
|
78
|
+
const startTime = this.startCounter();
|
|
79
|
+
// Find all workflows with WebSocket triggers
|
|
80
|
+
this.websocketWorkflows = this.getWebSocketWorkflows();
|
|
81
|
+
if (this.websocketWorkflows.length === 0) {
|
|
82
|
+
this.logger.log("No workflows with WebSocket triggers found");
|
|
83
|
+
}
|
|
84
|
+
else {
|
|
85
|
+
this.logger.log(`WebSocket trigger initialized. ${this.websocketWorkflows.length} workflow(s) registered`);
|
|
86
|
+
}
|
|
87
|
+
// Start heartbeat monitoring
|
|
88
|
+
this.startHeartbeat();
|
|
89
|
+
// Enable HMR in development mode
|
|
90
|
+
if (process.env.BLOK_HMR === "true" || process.env.NODE_ENV === "development") {
|
|
91
|
+
await this.enableHotReload();
|
|
92
|
+
}
|
|
93
|
+
return this.endCounter(startTime);
|
|
94
|
+
}
|
|
95
|
+
/**
|
|
96
|
+
* Stop the WebSocket trigger
|
|
97
|
+
*/
|
|
98
|
+
async stop() {
|
|
99
|
+
// Stop heartbeat
|
|
100
|
+
this.stopHeartbeat();
|
|
101
|
+
// Close all client connections
|
|
102
|
+
for (const client of this.clients.values()) {
|
|
103
|
+
client.close(1001, "Server shutting down");
|
|
104
|
+
}
|
|
105
|
+
// Clear state
|
|
106
|
+
this.clients.clear();
|
|
107
|
+
this.rooms.clear();
|
|
108
|
+
this.websocketWorkflows = [];
|
|
109
|
+
this.activeConnections = 0;
|
|
110
|
+
this.logger.log("WebSocket trigger stopped");
|
|
111
|
+
}
|
|
112
|
+
async onHmrWorkflowChange() {
|
|
113
|
+
// Lightweight: refresh workflow list without disconnecting clients
|
|
114
|
+
this.loadWorkflows();
|
|
115
|
+
this.websocketWorkflows = this.getWebSocketWorkflows();
|
|
116
|
+
this.logger.log(`[HMR] WebSocket workflows reloaded. ${this.websocketWorkflows.length} workflow(s) registered`);
|
|
117
|
+
}
|
|
118
|
+
/**
|
|
119
|
+
* Handle new WebSocket connection
|
|
120
|
+
*/
|
|
121
|
+
async handleConnection(socket, request, headers = {}) {
|
|
122
|
+
// Check max connections
|
|
123
|
+
if (this.clients.size >= this.maxClients) {
|
|
124
|
+
this.logger.error("Max connections reached, rejecting new connection");
|
|
125
|
+
socket.close(1013, "Server at capacity");
|
|
126
|
+
return null;
|
|
127
|
+
}
|
|
128
|
+
// Authenticate if handler is set
|
|
129
|
+
let clientId = (0, uuid_1.v4)();
|
|
130
|
+
let metadata = {};
|
|
131
|
+
if (this.authHandler) {
|
|
132
|
+
const authResult = await this.authHandler(request, headers);
|
|
133
|
+
if (!authResult.authenticated) {
|
|
134
|
+
this.logger.error(`Authentication failed: ${authResult.error}`);
|
|
135
|
+
socket.close(4001, authResult.error || "Authentication failed");
|
|
136
|
+
return null;
|
|
137
|
+
}
|
|
138
|
+
if (authResult.clientId) {
|
|
139
|
+
clientId = authResult.clientId;
|
|
140
|
+
}
|
|
141
|
+
if (authResult.metadata) {
|
|
142
|
+
metadata = authResult.metadata;
|
|
143
|
+
}
|
|
144
|
+
}
|
|
145
|
+
// Create client object
|
|
146
|
+
const client = {
|
|
147
|
+
id: clientId,
|
|
148
|
+
state: "connected",
|
|
149
|
+
rooms: new Set(),
|
|
150
|
+
metadata,
|
|
151
|
+
connectedAt: new Date(),
|
|
152
|
+
lastActivity: new Date(),
|
|
153
|
+
send: (data) => {
|
|
154
|
+
if (client.state === "connected") {
|
|
155
|
+
socket.send(data);
|
|
156
|
+
}
|
|
157
|
+
},
|
|
158
|
+
close: (code, reason) => {
|
|
159
|
+
client.state = "disconnecting";
|
|
160
|
+
socket.close(code, reason);
|
|
161
|
+
},
|
|
162
|
+
ping: () => {
|
|
163
|
+
socket.ping();
|
|
164
|
+
},
|
|
165
|
+
};
|
|
166
|
+
// Register client
|
|
167
|
+
this.clients.set(clientId, client);
|
|
168
|
+
this.activeConnections++;
|
|
169
|
+
// Trigger connection event
|
|
170
|
+
await this.triggerEvent({
|
|
171
|
+
type: "connection",
|
|
172
|
+
clientId,
|
|
173
|
+
});
|
|
174
|
+
this.logger.log(`Client connected: ${clientId} (${this.activeConnections} active)`);
|
|
175
|
+
return client;
|
|
176
|
+
}
|
|
177
|
+
/**
|
|
178
|
+
* Handle WebSocket message
|
|
179
|
+
*/
|
|
180
|
+
async handleMessage(clientId, data, isBinary) {
|
|
181
|
+
const client = this.clients.get(clientId);
|
|
182
|
+
if (!client) {
|
|
183
|
+
this.logger.error(`Message from unknown client: ${clientId}`);
|
|
184
|
+
return null;
|
|
185
|
+
}
|
|
186
|
+
// Update activity timestamp
|
|
187
|
+
client.lastActivity = new Date();
|
|
188
|
+
this.totalMessages++;
|
|
189
|
+
// Parse message
|
|
190
|
+
let message;
|
|
191
|
+
try {
|
|
192
|
+
if (isBinary) {
|
|
193
|
+
message = {
|
|
194
|
+
id: (0, uuid_1.v4)(),
|
|
195
|
+
type: "binary",
|
|
196
|
+
event: "binary",
|
|
197
|
+
data: data,
|
|
198
|
+
timestamp: new Date(),
|
|
199
|
+
raw: data,
|
|
200
|
+
};
|
|
201
|
+
}
|
|
202
|
+
else {
|
|
203
|
+
const text = data.toString();
|
|
204
|
+
let parsed = {};
|
|
205
|
+
try {
|
|
206
|
+
parsed = JSON.parse(text);
|
|
207
|
+
}
|
|
208
|
+
catch {
|
|
209
|
+
parsed = { event: "message", data: text };
|
|
210
|
+
}
|
|
211
|
+
message = {
|
|
212
|
+
id: (0, uuid_1.v4)(),
|
|
213
|
+
type: "text",
|
|
214
|
+
event: parsed.event || "message",
|
|
215
|
+
data: parsed.data ?? parsed,
|
|
216
|
+
timestamp: new Date(),
|
|
217
|
+
raw: text,
|
|
218
|
+
};
|
|
219
|
+
}
|
|
220
|
+
}
|
|
221
|
+
catch (error) {
|
|
222
|
+
this.logger.error(`Failed to parse message: ${error.message}`);
|
|
223
|
+
return null;
|
|
224
|
+
}
|
|
225
|
+
// Trigger message event
|
|
226
|
+
return this.triggerEvent({
|
|
227
|
+
type: "message",
|
|
228
|
+
clientId,
|
|
229
|
+
message,
|
|
230
|
+
});
|
|
231
|
+
}
|
|
232
|
+
/**
|
|
233
|
+
* Handle WebSocket close
|
|
234
|
+
*/
|
|
235
|
+
async handleClose(clientId, code, reason) {
|
|
236
|
+
const client = this.clients.get(clientId);
|
|
237
|
+
if (!client)
|
|
238
|
+
return;
|
|
239
|
+
client.state = "disconnected";
|
|
240
|
+
// Remove from all rooms
|
|
241
|
+
for (const roomName of client.rooms) {
|
|
242
|
+
const room = this.rooms.get(roomName);
|
|
243
|
+
if (room) {
|
|
244
|
+
room.clients.delete(clientId);
|
|
245
|
+
// Clean up empty rooms
|
|
246
|
+
if (room.clients.size === 0) {
|
|
247
|
+
this.rooms.delete(roomName);
|
|
248
|
+
}
|
|
249
|
+
}
|
|
250
|
+
}
|
|
251
|
+
// Unregister client
|
|
252
|
+
this.clients.delete(clientId);
|
|
253
|
+
this.activeConnections--;
|
|
254
|
+
// Trigger close event
|
|
255
|
+
await this.triggerEvent({
|
|
256
|
+
type: "close",
|
|
257
|
+
clientId,
|
|
258
|
+
closeCode: code,
|
|
259
|
+
closeReason: reason,
|
|
260
|
+
});
|
|
261
|
+
this.logger.log(`Client disconnected: ${clientId} (code: ${code}, reason: ${reason})`);
|
|
262
|
+
}
|
|
263
|
+
/**
|
|
264
|
+
* Handle WebSocket error
|
|
265
|
+
*/
|
|
266
|
+
async handleError(clientId, error) {
|
|
267
|
+
this.logger.error(`WebSocket error for client ${clientId}: ${error.message}`);
|
|
268
|
+
await this.triggerEvent({
|
|
269
|
+
type: "error",
|
|
270
|
+
clientId,
|
|
271
|
+
error,
|
|
272
|
+
});
|
|
273
|
+
}
|
|
274
|
+
/**
|
|
275
|
+
* Handle ping from client
|
|
276
|
+
*/
|
|
277
|
+
handlePing(clientId) {
|
|
278
|
+
const client = this.clients.get(clientId);
|
|
279
|
+
if (client) {
|
|
280
|
+
client.lastActivity = new Date();
|
|
281
|
+
}
|
|
282
|
+
}
|
|
283
|
+
/**
|
|
284
|
+
* Handle pong from client
|
|
285
|
+
*/
|
|
286
|
+
handlePong(clientId) {
|
|
287
|
+
const client = this.clients.get(clientId);
|
|
288
|
+
if (client) {
|
|
289
|
+
client.lastActivity = new Date();
|
|
290
|
+
}
|
|
291
|
+
}
|
|
292
|
+
/**
|
|
293
|
+
* Join a room/channel
|
|
294
|
+
*/
|
|
295
|
+
async joinRoom(clientId, roomName) {
|
|
296
|
+
const client = this.clients.get(clientId);
|
|
297
|
+
if (!client)
|
|
298
|
+
return false;
|
|
299
|
+
// Create room if it doesn't exist
|
|
300
|
+
if (!this.rooms.has(roomName)) {
|
|
301
|
+
this.rooms.set(roomName, {
|
|
302
|
+
name: roomName,
|
|
303
|
+
clients: new Set(),
|
|
304
|
+
metadata: {},
|
|
305
|
+
createdAt: new Date(),
|
|
306
|
+
});
|
|
307
|
+
}
|
|
308
|
+
const room = this.rooms.get(roomName);
|
|
309
|
+
room.clients.add(clientId);
|
|
310
|
+
client.rooms.add(roomName);
|
|
311
|
+
// Trigger join event
|
|
312
|
+
await this.triggerEvent({
|
|
313
|
+
type: "join_room",
|
|
314
|
+
clientId,
|
|
315
|
+
room: roomName,
|
|
316
|
+
});
|
|
317
|
+
this.logger.log(`Client ${clientId} joined room: ${roomName}`);
|
|
318
|
+
return true;
|
|
319
|
+
}
|
|
320
|
+
/**
|
|
321
|
+
* Leave a room/channel
|
|
322
|
+
*/
|
|
323
|
+
async leaveRoom(clientId, roomName) {
|
|
324
|
+
const client = this.clients.get(clientId);
|
|
325
|
+
if (!client)
|
|
326
|
+
return false;
|
|
327
|
+
const room = this.rooms.get(roomName);
|
|
328
|
+
if (!room)
|
|
329
|
+
return false;
|
|
330
|
+
room.clients.delete(clientId);
|
|
331
|
+
client.rooms.delete(roomName);
|
|
332
|
+
// Clean up empty rooms
|
|
333
|
+
if (room.clients.size === 0) {
|
|
334
|
+
this.rooms.delete(roomName);
|
|
335
|
+
}
|
|
336
|
+
// Trigger leave event
|
|
337
|
+
await this.triggerEvent({
|
|
338
|
+
type: "leave_room",
|
|
339
|
+
clientId,
|
|
340
|
+
room: roomName,
|
|
341
|
+
});
|
|
342
|
+
this.logger.log(`Client ${clientId} left room: ${roomName}`);
|
|
343
|
+
return true;
|
|
344
|
+
}
|
|
345
|
+
/**
|
|
346
|
+
* Send message to a specific client
|
|
347
|
+
*/
|
|
348
|
+
sendToClient(clientId, event, data) {
|
|
349
|
+
const client = this.clients.get(clientId);
|
|
350
|
+
if (!client || client.state !== "connected")
|
|
351
|
+
return false;
|
|
352
|
+
const message = JSON.stringify({ event, data });
|
|
353
|
+
client.send(message);
|
|
354
|
+
return true;
|
|
355
|
+
}
|
|
356
|
+
/**
|
|
357
|
+
* Broadcast message to all clients in a room
|
|
358
|
+
*/
|
|
359
|
+
broadcastToRoom(roomName, event, data, excludeClient) {
|
|
360
|
+
const room = this.rooms.get(roomName);
|
|
361
|
+
if (!room)
|
|
362
|
+
return 0;
|
|
363
|
+
const message = JSON.stringify({ event, data });
|
|
364
|
+
let sent = 0;
|
|
365
|
+
for (const clientId of room.clients) {
|
|
366
|
+
if (excludeClient && clientId === excludeClient)
|
|
367
|
+
continue;
|
|
368
|
+
const client = this.clients.get(clientId);
|
|
369
|
+
if (client && client.state === "connected") {
|
|
370
|
+
client.send(message);
|
|
371
|
+
sent++;
|
|
372
|
+
}
|
|
373
|
+
}
|
|
374
|
+
return sent;
|
|
375
|
+
}
|
|
376
|
+
/**
|
|
377
|
+
* Broadcast message to all connected clients
|
|
378
|
+
*/
|
|
379
|
+
broadcastToAll(event, data, excludeClient) {
|
|
380
|
+
const message = JSON.stringify({ event, data });
|
|
381
|
+
let sent = 0;
|
|
382
|
+
for (const [clientId, client] of this.clients) {
|
|
383
|
+
if (excludeClient && clientId === excludeClient)
|
|
384
|
+
continue;
|
|
385
|
+
if (client.state === "connected") {
|
|
386
|
+
client.send(message);
|
|
387
|
+
sent++;
|
|
388
|
+
}
|
|
389
|
+
}
|
|
390
|
+
return sent;
|
|
391
|
+
}
|
|
392
|
+
/**
|
|
393
|
+
* Get client by ID
|
|
394
|
+
*/
|
|
395
|
+
getClient(clientId) {
|
|
396
|
+
return this.clients.get(clientId);
|
|
397
|
+
}
|
|
398
|
+
/**
|
|
399
|
+
* Get all clients in a room
|
|
400
|
+
*/
|
|
401
|
+
getClientsInRoom(roomName) {
|
|
402
|
+
const room = this.rooms.get(roomName);
|
|
403
|
+
if (!room)
|
|
404
|
+
return [];
|
|
405
|
+
const clients = [];
|
|
406
|
+
for (const clientId of room.clients) {
|
|
407
|
+
const client = this.clients.get(clientId);
|
|
408
|
+
if (client) {
|
|
409
|
+
clients.push(client);
|
|
410
|
+
}
|
|
411
|
+
}
|
|
412
|
+
return clients;
|
|
413
|
+
}
|
|
414
|
+
/**
|
|
415
|
+
* Get connection stats
|
|
416
|
+
*/
|
|
417
|
+
getStats() {
|
|
418
|
+
const clientsByRoom = {};
|
|
419
|
+
for (const [name, room] of this.rooms) {
|
|
420
|
+
clientsByRoom[name] = room.clients.size;
|
|
421
|
+
}
|
|
422
|
+
return {
|
|
423
|
+
activeConnections: this.activeConnections,
|
|
424
|
+
totalMessages: this.totalMessages,
|
|
425
|
+
roomCount: this.rooms.size,
|
|
426
|
+
clientsByRoom,
|
|
427
|
+
};
|
|
428
|
+
}
|
|
429
|
+
/**
|
|
430
|
+
* Get all workflows that have WebSocket triggers
|
|
431
|
+
*/
|
|
432
|
+
getWebSocketWorkflows() {
|
|
433
|
+
const workflows = [];
|
|
434
|
+
for (const [path, workflow] of Object.entries(this.nodeMap.workflows || {})) {
|
|
435
|
+
const workflowConfig = workflow._config;
|
|
436
|
+
if (workflowConfig?.trigger) {
|
|
437
|
+
const triggerType = Object.keys(workflowConfig.trigger)[0];
|
|
438
|
+
if (triggerType === "websocket" && workflowConfig.trigger.websocket) {
|
|
439
|
+
workflows.push({
|
|
440
|
+
path,
|
|
441
|
+
config: workflowConfig,
|
|
442
|
+
});
|
|
443
|
+
}
|
|
444
|
+
}
|
|
445
|
+
}
|
|
446
|
+
return workflows;
|
|
447
|
+
}
|
|
448
|
+
/**
|
|
449
|
+
* Find workflow matching the WebSocket event
|
|
450
|
+
*/
|
|
451
|
+
findMatchingWorkflow(event) {
|
|
452
|
+
for (const workflow of this.websocketWorkflows) {
|
|
453
|
+
const config = workflow.config.trigger?.websocket;
|
|
454
|
+
if (!config)
|
|
455
|
+
continue;
|
|
456
|
+
// Check event type match
|
|
457
|
+
if (config.events && config.events.length > 0) {
|
|
458
|
+
const eventName = event.type === "message" ? event.message?.event || "message" : event.type;
|
|
459
|
+
const matches = config.events.some((pattern) => {
|
|
460
|
+
if (pattern === "*")
|
|
461
|
+
return true;
|
|
462
|
+
if (pattern.endsWith(".*")) {
|
|
463
|
+
const prefix = pattern.slice(0, -2);
|
|
464
|
+
return eventName.startsWith(prefix);
|
|
465
|
+
}
|
|
466
|
+
return pattern === eventName;
|
|
467
|
+
});
|
|
468
|
+
if (!matches)
|
|
469
|
+
continue;
|
|
470
|
+
}
|
|
471
|
+
// Check room filter
|
|
472
|
+
if (config.rooms && config.rooms.length > 0 && event.room) {
|
|
473
|
+
if (!config.rooms.includes(event.room))
|
|
474
|
+
continue;
|
|
475
|
+
}
|
|
476
|
+
return workflow;
|
|
477
|
+
}
|
|
478
|
+
return null;
|
|
479
|
+
}
|
|
480
|
+
/**
|
|
481
|
+
* Trigger a workflow based on WebSocket event
|
|
482
|
+
*/
|
|
483
|
+
async triggerEvent(event) {
|
|
484
|
+
// Find matching workflow
|
|
485
|
+
const workflow = this.findMatchingWorkflow(event);
|
|
486
|
+
if (!workflow) {
|
|
487
|
+
return null;
|
|
488
|
+
}
|
|
489
|
+
const config = workflow.config.trigger?.websocket;
|
|
490
|
+
return this.executeWorkflow(event, workflow, config);
|
|
491
|
+
}
|
|
492
|
+
/**
|
|
493
|
+
* Execute a workflow for a WebSocket event
|
|
494
|
+
*/
|
|
495
|
+
async executeWorkflow(event, workflow, _config) {
|
|
496
|
+
const executionId = (0, uuid_1.v4)();
|
|
497
|
+
const defaultMeter = api_1.metrics.getMeter("default");
|
|
498
|
+
const wsExecutions = defaultMeter.createCounter("websocket_executions", {
|
|
499
|
+
description: "WebSocket workflow executions",
|
|
500
|
+
});
|
|
501
|
+
const wsErrors = defaultMeter.createCounter("websocket_errors", {
|
|
502
|
+
description: "WebSocket execution errors",
|
|
503
|
+
});
|
|
504
|
+
return new Promise((resolve) => {
|
|
505
|
+
this.tracer.startActiveSpan(`websocket:${event.type}`, async (span) => {
|
|
506
|
+
try {
|
|
507
|
+
const start = performance.now();
|
|
508
|
+
// Initialize configuration for this workflow
|
|
509
|
+
await this.configuration.init(workflow.path, this.nodeMap);
|
|
510
|
+
// Create context
|
|
511
|
+
const ctx = this.createContext(undefined, workflow.path, executionId);
|
|
512
|
+
// Get client info
|
|
513
|
+
const client = this.clients.get(event.clientId);
|
|
514
|
+
// Populate request with WebSocket event
|
|
515
|
+
ctx.request = {
|
|
516
|
+
body: event.message?.data ?? event,
|
|
517
|
+
headers: {},
|
|
518
|
+
query: {},
|
|
519
|
+
params: {
|
|
520
|
+
clientId: event.clientId,
|
|
521
|
+
eventType: event.type,
|
|
522
|
+
messageEvent: event.message?.event,
|
|
523
|
+
room: event.room,
|
|
524
|
+
},
|
|
525
|
+
};
|
|
526
|
+
// Store WebSocket context in vars (use type assertion for flexibility)
|
|
527
|
+
if (!ctx.vars)
|
|
528
|
+
ctx.vars = {};
|
|
529
|
+
ctx.vars._websocket = {
|
|
530
|
+
clientId: event.clientId,
|
|
531
|
+
eventType: event.type,
|
|
532
|
+
messageId: event.message?.id,
|
|
533
|
+
messageEvent: event.message?.event,
|
|
534
|
+
room: event.room,
|
|
535
|
+
clientRooms: client ? Array.from(client.rooms) : [],
|
|
536
|
+
clientMetadata: client?.metadata || {},
|
|
537
|
+
timestamp: new Date().toISOString(),
|
|
538
|
+
};
|
|
539
|
+
// Add helper functions to context for sending responses
|
|
540
|
+
ctx.vars._websocket_send = (data) => {
|
|
541
|
+
this.sendToClient(event.clientId, "response", data);
|
|
542
|
+
};
|
|
543
|
+
ctx.vars._websocket_broadcast = (room, data) => {
|
|
544
|
+
this.broadcastToRoom(room, "broadcast", data, event.clientId);
|
|
545
|
+
};
|
|
546
|
+
ctx.logger.log(`Processing WebSocket event: ${event.type} from ${event.clientId}`);
|
|
547
|
+
// Execute workflow
|
|
548
|
+
const response = await this.run(ctx);
|
|
549
|
+
const end = performance.now();
|
|
550
|
+
// Set span attributes
|
|
551
|
+
span.setAttribute("success", true);
|
|
552
|
+
span.setAttribute("client_id", event.clientId);
|
|
553
|
+
span.setAttribute("event_type", event.type);
|
|
554
|
+
span.setAttribute("workflow_path", workflow.path);
|
|
555
|
+
span.setAttribute("elapsed_ms", end - start);
|
|
556
|
+
span.setStatus({ code: api_1.SpanStatusCode.OK });
|
|
557
|
+
// Record metrics
|
|
558
|
+
wsExecutions.add(1, {
|
|
559
|
+
env: process.env.NODE_ENV,
|
|
560
|
+
event_type: event.type,
|
|
561
|
+
workflow_name: this.configuration.name,
|
|
562
|
+
success: "true",
|
|
563
|
+
});
|
|
564
|
+
ctx.logger.log(`WebSocket event processed in ${(end - start).toFixed(2)}ms`);
|
|
565
|
+
resolve(response);
|
|
566
|
+
}
|
|
567
|
+
catch (error) {
|
|
568
|
+
const errorMessage = error.message;
|
|
569
|
+
// Set span error
|
|
570
|
+
span.setAttribute("success", false);
|
|
571
|
+
span.recordException(error);
|
|
572
|
+
span.setStatus({ code: api_1.SpanStatusCode.ERROR, message: errorMessage });
|
|
573
|
+
// Record error metrics
|
|
574
|
+
wsErrors.add(1, {
|
|
575
|
+
env: process.env.NODE_ENV,
|
|
576
|
+
event_type: event.type,
|
|
577
|
+
workflow_name: this.configuration?.name || "unknown",
|
|
578
|
+
});
|
|
579
|
+
this.logger.error(`WebSocket workflow failed: ${errorMessage}`, error.stack);
|
|
580
|
+
throw error;
|
|
581
|
+
}
|
|
582
|
+
finally {
|
|
583
|
+
span.end();
|
|
584
|
+
}
|
|
585
|
+
});
|
|
586
|
+
});
|
|
587
|
+
}
|
|
588
|
+
/**
|
|
589
|
+
* Start heartbeat monitoring
|
|
590
|
+
*/
|
|
591
|
+
startHeartbeat() {
|
|
592
|
+
this.heartbeatInterval = setInterval(() => {
|
|
593
|
+
const now = Date.now();
|
|
594
|
+
const staleThreshold = this.heartbeatIntervalMs * 2;
|
|
595
|
+
for (const [clientId, client] of this.clients) {
|
|
596
|
+
const lastActivity = client.lastActivity.getTime();
|
|
597
|
+
// Check for stale connections
|
|
598
|
+
if (now - lastActivity > staleThreshold) {
|
|
599
|
+
this.logger.log(`Closing stale connection: ${clientId}`);
|
|
600
|
+
client.close(1000, "Connection timed out");
|
|
601
|
+
}
|
|
602
|
+
else {
|
|
603
|
+
// Ping active connections
|
|
604
|
+
try {
|
|
605
|
+
client.ping();
|
|
606
|
+
}
|
|
607
|
+
catch (error) {
|
|
608
|
+
this.logger.error(`Ping failed for ${clientId}: ${error.message}`);
|
|
609
|
+
}
|
|
610
|
+
}
|
|
611
|
+
}
|
|
612
|
+
}, this.heartbeatIntervalMs);
|
|
613
|
+
}
|
|
614
|
+
/**
|
|
615
|
+
* Stop heartbeat monitoring
|
|
616
|
+
*/
|
|
617
|
+
stopHeartbeat() {
|
|
618
|
+
if (this.heartbeatInterval) {
|
|
619
|
+
clearInterval(this.heartbeatInterval);
|
|
620
|
+
this.heartbeatInterval = null;
|
|
621
|
+
}
|
|
622
|
+
}
|
|
623
|
+
}
|
|
624
|
+
exports.WebSocketTrigger = WebSocketTrigger;
|
|
625
|
+
exports.default = WebSocketTrigger;
|
|
626
|
+
//# sourceMappingURL=WebSocketTrigger.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"WebSocketTrigger.js","sourceRoot":"","sources":["../src/WebSocketTrigger.ts"],"names":[],"mappings":"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"}
|