bunqueue 1.0.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/LICENSE +21 -0
- package/README.md +640 -0
- package/dist/application/dlqManager.d.ts +19 -0
- package/dist/application/dlqManager.d.ts.map +1 -0
- package/dist/application/dlqManager.js +44 -0
- package/dist/application/dlqManager.js.map +1 -0
- package/dist/application/eventsManager.d.ts +28 -0
- package/dist/application/eventsManager.d.ts.map +1 -0
- package/dist/application/eventsManager.js +59 -0
- package/dist/application/eventsManager.js.map +1 -0
- package/dist/application/jobLogsManager.d.ts +20 -0
- package/dist/application/jobLogsManager.d.ts.map +1 -0
- package/dist/application/jobLogsManager.js +28 -0
- package/dist/application/jobLogsManager.js.map +1 -0
- package/dist/application/metricsExporter.d.ts +24 -0
- package/dist/application/metricsExporter.d.ts.map +1 -0
- package/dist/application/metricsExporter.js +80 -0
- package/dist/application/metricsExporter.js.map +1 -0
- package/dist/application/operations/ack.d.ts +48 -0
- package/dist/application/operations/ack.d.ts.map +1 -0
- package/dist/application/operations/ack.js +109 -0
- package/dist/application/operations/ack.js.map +1 -0
- package/dist/application/operations/index.d.ts +10 -0
- package/dist/application/operations/index.d.ts.map +1 -0
- package/dist/application/operations/index.js +10 -0
- package/dist/application/operations/index.js.map +1 -0
- package/dist/application/operations/jobManagement.d.ts +32 -0
- package/dist/application/operations/jobManagement.d.ts.map +1 -0
- package/dist/application/operations/jobManagement.js +122 -0
- package/dist/application/operations/jobManagement.js.map +1 -0
- package/dist/application/operations/pull.d.ts +36 -0
- package/dist/application/operations/pull.d.ts.map +1 -0
- package/dist/application/operations/pull.js +109 -0
- package/dist/application/operations/pull.js.map +1 -0
- package/dist/application/operations/push.d.ts +36 -0
- package/dist/application/operations/push.d.ts.map +1 -0
- package/dist/application/operations/push.js +94 -0
- package/dist/application/operations/push.js.map +1 -0
- package/dist/application/operations/queryOperations.d.ts +33 -0
- package/dist/application/operations/queryOperations.d.ts.map +1 -0
- package/dist/application/operations/queryOperations.js +57 -0
- package/dist/application/operations/queryOperations.js.map +1 -0
- package/dist/application/operations/queueControl.d.ts +32 -0
- package/dist/application/operations/queueControl.d.ts.map +1 -0
- package/dist/application/operations/queueControl.js +72 -0
- package/dist/application/operations/queueControl.js.map +1 -0
- package/dist/application/queueManager.d.ts +113 -0
- package/dist/application/queueManager.d.ts.map +1 -0
- package/dist/application/queueManager.js +406 -0
- package/dist/application/queueManager.js.map +1 -0
- package/dist/application/webhookManager.d.ts +35 -0
- package/dist/application/webhookManager.d.ts.map +1 -0
- package/dist/application/webhookManager.js +109 -0
- package/dist/application/webhookManager.js.map +1 -0
- package/dist/application/workerManager.d.ts +48 -0
- package/dist/application/workerManager.d.ts.map +1 -0
- package/dist/application/workerManager.js +121 -0
- package/dist/application/workerManager.js.map +1 -0
- package/dist/domain/queue/index.d.ts +6 -0
- package/dist/domain/queue/index.d.ts.map +1 -0
- package/dist/domain/queue/index.js +6 -0
- package/dist/domain/queue/index.js.map +1 -0
- package/dist/domain/queue/priorityQueue.d.ts +45 -0
- package/dist/domain/queue/priorityQueue.d.ts.map +1 -0
- package/dist/domain/queue/priorityQueue.js +203 -0
- package/dist/domain/queue/priorityQueue.js.map +1 -0
- package/dist/domain/queue/shard.d.ts +98 -0
- package/dist/domain/queue/shard.d.ts.map +1 -0
- package/dist/domain/queue/shard.js +245 -0
- package/dist/domain/queue/shard.js.map +1 -0
- package/dist/domain/types/command.d.ts +270 -0
- package/dist/domain/types/command.d.ts.map +1 -0
- package/dist/domain/types/command.js +6 -0
- package/dist/domain/types/command.js.map +1 -0
- package/dist/domain/types/cron.d.ts +32 -0
- package/dist/domain/types/cron.d.ts.map +1 -0
- package/dist/domain/types/cron.js +31 -0
- package/dist/domain/types/cron.js.map +1 -0
- package/dist/domain/types/index.d.ts +9 -0
- package/dist/domain/types/index.d.ts.map +1 -0
- package/dist/domain/types/index.js +9 -0
- package/dist/domain/types/index.js.map +1 -0
- package/dist/domain/types/job.d.ts +94 -0
- package/dist/domain/types/job.d.ts.map +1 -0
- package/dist/domain/types/job.js +81 -0
- package/dist/domain/types/job.js.map +1 -0
- package/dist/domain/types/queue.d.ts +86 -0
- package/dist/domain/types/queue.d.ts.map +1 -0
- package/dist/domain/types/queue.js +84 -0
- package/dist/domain/types/queue.js.map +1 -0
- package/dist/domain/types/response.d.ts +158 -0
- package/dist/domain/types/response.d.ts.map +1 -0
- package/dist/domain/types/response.js +86 -0
- package/dist/domain/types/response.js.map +1 -0
- package/dist/domain/types/webhook.d.ts +33 -0
- package/dist/domain/types/webhook.d.ts.map +1 -0
- package/dist/domain/types/webhook.js +20 -0
- package/dist/domain/types/webhook.js.map +1 -0
- package/dist/domain/types/worker.d.ts +27 -0
- package/dist/domain/types/worker.d.ts.map +1 -0
- package/dist/domain/types/worker.js +27 -0
- package/dist/domain/types/worker.js.map +1 -0
- package/dist/infrastructure/persistence/index.d.ts +6 -0
- package/dist/infrastructure/persistence/index.d.ts.map +1 -0
- package/dist/infrastructure/persistence/index.js +6 -0
- package/dist/infrastructure/persistence/index.js.map +1 -0
- package/dist/infrastructure/persistence/schema.d.ts +14 -0
- package/dist/infrastructure/persistence/schema.d.ts.map +1 -0
- package/dist/infrastructure/persistence/schema.js +123 -0
- package/dist/infrastructure/persistence/schema.js.map +1 -0
- package/dist/infrastructure/persistence/sqlite.d.ts +42 -0
- package/dist/infrastructure/persistence/sqlite.d.ts.map +1 -0
- package/dist/infrastructure/persistence/sqlite.js +164 -0
- package/dist/infrastructure/persistence/sqlite.js.map +1 -0
- package/dist/infrastructure/persistence/statements.d.ts +55 -0
- package/dist/infrastructure/persistence/statements.d.ts.map +1 -0
- package/dist/infrastructure/persistence/statements.js +42 -0
- package/dist/infrastructure/persistence/statements.js.map +1 -0
- package/dist/infrastructure/scheduler/cronParser.d.ts +44 -0
- package/dist/infrastructure/scheduler/cronParser.d.ts.map +1 -0
- package/dist/infrastructure/scheduler/cronParser.js +90 -0
- package/dist/infrastructure/scheduler/cronParser.js.map +1 -0
- package/dist/infrastructure/scheduler/cronScheduler.d.ts +68 -0
- package/dist/infrastructure/scheduler/cronScheduler.d.ts.map +1 -0
- package/dist/infrastructure/scheduler/cronScheduler.js +172 -0
- package/dist/infrastructure/scheduler/cronScheduler.js.map +1 -0
- package/dist/infrastructure/scheduler/index.d.ts +6 -0
- package/dist/infrastructure/scheduler/index.d.ts.map +1 -0
- package/dist/infrastructure/scheduler/index.js +6 -0
- package/dist/infrastructure/scheduler/index.js.map +1 -0
- package/dist/infrastructure/server/handler.d.ts +13 -0
- package/dist/infrastructure/server/handler.d.ts.map +1 -0
- package/dist/infrastructure/server/handler.js +167 -0
- package/dist/infrastructure/server/handler.js.map +1 -0
- package/dist/infrastructure/server/handlers/advanced.d.ts +68 -0
- package/dist/infrastructure/server/handlers/advanced.d.ts.map +1 -0
- package/dist/infrastructure/server/handlers/advanced.js +99 -0
- package/dist/infrastructure/server/handlers/advanced.js.map +1 -0
- package/dist/infrastructure/server/handlers/core.d.ts +36 -0
- package/dist/infrastructure/server/handlers/core.d.ts.map +1 -0
- package/dist/infrastructure/server/handlers/core.js +82 -0
- package/dist/infrastructure/server/handlers/core.js.map +1 -0
- package/dist/infrastructure/server/handlers/cron.d.ts +20 -0
- package/dist/infrastructure/server/handlers/cron.d.ts.map +1 -0
- package/dist/infrastructure/server/handlers/cron.js +56 -0
- package/dist/infrastructure/server/handlers/cron.js.map +1 -0
- package/dist/infrastructure/server/handlers/dlq.d.ts +20 -0
- package/dist/infrastructure/server/handlers/dlq.d.ts.map +1 -0
- package/dist/infrastructure/server/handlers/dlq.js +31 -0
- package/dist/infrastructure/server/handlers/dlq.js.map +1 -0
- package/dist/infrastructure/server/handlers/index.d.ts +7 -0
- package/dist/infrastructure/server/handlers/index.d.ts.map +1 -0
- package/dist/infrastructure/server/handlers/index.js +7 -0
- package/dist/infrastructure/server/handlers/index.js.map +1 -0
- package/dist/infrastructure/server/handlers/management.d.ts +36 -0
- package/dist/infrastructure/server/handlers/management.d.ts.map +1 -0
- package/dist/infrastructure/server/handlers/management.js +75 -0
- package/dist/infrastructure/server/handlers/management.js.map +1 -0
- package/dist/infrastructure/server/handlers/monitoring.d.ts +18 -0
- package/dist/infrastructure/server/handlers/monitoring.d.ts.map +1 -0
- package/dist/infrastructure/server/handlers/monitoring.js +102 -0
- package/dist/infrastructure/server/handlers/monitoring.js.map +1 -0
- package/dist/infrastructure/server/handlers/query.d.ts +32 -0
- package/dist/infrastructure/server/handlers/query.d.ts.map +1 -0
- package/dist/infrastructure/server/handlers/query.js +61 -0
- package/dist/infrastructure/server/handlers/query.js.map +1 -0
- package/dist/infrastructure/server/http.d.ts +43 -0
- package/dist/infrastructure/server/http.d.ts.map +1 -0
- package/dist/infrastructure/server/http.js +344 -0
- package/dist/infrastructure/server/http.js.map +1 -0
- package/dist/infrastructure/server/index.d.ts +8 -0
- package/dist/infrastructure/server/index.d.ts.map +1 -0
- package/dist/infrastructure/server/index.js +8 -0
- package/dist/infrastructure/server/index.js.map +1 -0
- package/dist/infrastructure/server/protocol.d.ts +44 -0
- package/dist/infrastructure/server/protocol.d.ts.map +1 -0
- package/dist/infrastructure/server/protocol.js +129 -0
- package/dist/infrastructure/server/protocol.js.map +1 -0
- package/dist/infrastructure/server/rateLimiter.d.ts +31 -0
- package/dist/infrastructure/server/rateLimiter.d.ts.map +1 -0
- package/dist/infrastructure/server/rateLimiter.js +79 -0
- package/dist/infrastructure/server/rateLimiter.js.map +1 -0
- package/dist/infrastructure/server/tcp.d.ts +36 -0
- package/dist/infrastructure/server/tcp.d.ts.map +1 -0
- package/dist/infrastructure/server/tcp.js +101 -0
- package/dist/infrastructure/server/tcp.js.map +1 -0
- package/dist/infrastructure/server/types.d.ts +11 -0
- package/dist/infrastructure/server/types.d.ts.map +1 -0
- package/dist/infrastructure/server/types.js +5 -0
- package/dist/infrastructure/server/types.js.map +1 -0
- package/dist/main.d.ts +6 -0
- package/dist/main.d.ts.map +1 -0
- package/dist/main.js +111 -0
- package/dist/main.js.map +1 -0
- package/dist/shared/hash.d.ts +30 -0
- package/dist/shared/hash.d.ts.map +1 -0
- package/dist/shared/hash.js +69 -0
- package/dist/shared/hash.js.map +1 -0
- package/dist/shared/index.d.ts +6 -0
- package/dist/shared/index.d.ts.map +1 -0
- package/dist/shared/index.js +6 -0
- package/dist/shared/index.js.map +1 -0
- package/dist/shared/lock.d.ts +70 -0
- package/dist/shared/lock.d.ts.map +1 -0
- package/dist/shared/lock.js +207 -0
- package/dist/shared/lock.js.map +1 -0
- package/dist/shared/logger.d.ts +38 -0
- package/dist/shared/logger.d.ts.map +1 -0
- package/dist/shared/logger.js +74 -0
- package/dist/shared/logger.js.map +1 -0
- package/dist/shared/serialization.d.ts +23 -0
- package/dist/shared/serialization.d.ts.map +1 -0
- package/dist/shared/serialization.js +63 -0
- package/dist/shared/serialization.js.map +1 -0
- package/package.json +82 -0
|
@@ -0,0 +1,344 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* HTTP Server
|
|
3
|
+
* REST API and WebSocket support
|
|
4
|
+
*/
|
|
5
|
+
import { handleCommand } from './handler';
|
|
6
|
+
import { parseCommand, serializeResponse, errorResponse } from './protocol';
|
|
7
|
+
import { constantTimeEqual, uuid } from '../../shared/hash';
|
|
8
|
+
import { httpLog, wsLog } from '../../shared/logger';
|
|
9
|
+
import { getRateLimiter } from './rateLimiter';
|
|
10
|
+
/**
|
|
11
|
+
* Create and start HTTP server
|
|
12
|
+
*/
|
|
13
|
+
export function createHttpServer(queueManager, config) {
|
|
14
|
+
const authTokens = new Set(config.authTokens ?? []);
|
|
15
|
+
const wsClients = new Map();
|
|
16
|
+
const sseClients = new Map();
|
|
17
|
+
const corsOrigins = new Set(config.corsOrigins ?? ['*']);
|
|
18
|
+
// Subscribe to queue events for WebSocket and SSE broadcast
|
|
19
|
+
queueManager.subscribe((event) => {
|
|
20
|
+
const message = JSON.stringify(event);
|
|
21
|
+
// WebSocket clients
|
|
22
|
+
for (const [, ws] of wsClients) {
|
|
23
|
+
if (!ws.data.queueFilter || ws.data.queueFilter === event.queue) {
|
|
24
|
+
ws.send(message);
|
|
25
|
+
}
|
|
26
|
+
}
|
|
27
|
+
// SSE clients
|
|
28
|
+
const sseMessage = `data: ${message}\n\n`;
|
|
29
|
+
for (const [, client] of sseClients) {
|
|
30
|
+
if (!client.queueFilter || client.queueFilter === event.queue) {
|
|
31
|
+
try {
|
|
32
|
+
client.controller.enqueue(new TextEncoder().encode(sseMessage));
|
|
33
|
+
}
|
|
34
|
+
catch {
|
|
35
|
+
// Client disconnected, will be cleaned up
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
});
|
|
40
|
+
const server = Bun.serve({
|
|
41
|
+
hostname: config.hostname ?? '0.0.0.0',
|
|
42
|
+
port: config.port,
|
|
43
|
+
async fetch(req, server) {
|
|
44
|
+
const url = new URL(req.url);
|
|
45
|
+
const path = url.pathname;
|
|
46
|
+
// CORS preflight
|
|
47
|
+
if (req.method === 'OPTIONS') {
|
|
48
|
+
return corsResponse(corsOrigins);
|
|
49
|
+
}
|
|
50
|
+
// Health check (no auth, no rate limit)
|
|
51
|
+
if (path === '/health') {
|
|
52
|
+
return jsonResponse({ ok: true, status: 'healthy' });
|
|
53
|
+
}
|
|
54
|
+
// Rate limiting (use IP as client ID for HTTP)
|
|
55
|
+
const clientIp = req.headers.get('x-forwarded-for')?.split(',')[0]?.trim() ??
|
|
56
|
+
req.headers.get('x-real-ip') ??
|
|
57
|
+
'unknown';
|
|
58
|
+
if (!getRateLimiter().isAllowed(clientIp)) {
|
|
59
|
+
return jsonResponse({ ok: false, error: 'Rate limit exceeded' }, 429);
|
|
60
|
+
}
|
|
61
|
+
// WebSocket upgrade
|
|
62
|
+
if (path === '/ws' || path.startsWith('/ws/')) {
|
|
63
|
+
const queueFilter = path.startsWith('/ws/queues/')
|
|
64
|
+
? path.slice('/ws/queues/'.length)
|
|
65
|
+
: null;
|
|
66
|
+
const upgraded = server.upgrade(req, {
|
|
67
|
+
data: {
|
|
68
|
+
id: uuid(),
|
|
69
|
+
authenticated: authTokens.size === 0,
|
|
70
|
+
queueFilter,
|
|
71
|
+
},
|
|
72
|
+
});
|
|
73
|
+
if (!upgraded) {
|
|
74
|
+
return new Response('WebSocket upgrade failed', { status: 400 });
|
|
75
|
+
}
|
|
76
|
+
return undefined;
|
|
77
|
+
}
|
|
78
|
+
// SSE (Server-Sent Events) endpoint - no auth required for basic events
|
|
79
|
+
if (path === '/events' || path.startsWith('/events/')) {
|
|
80
|
+
const queueFilter = path.startsWith('/events/queues/')
|
|
81
|
+
? path.slice('/events/queues/'.length)
|
|
82
|
+
: null;
|
|
83
|
+
const clientId = uuid();
|
|
84
|
+
const stream = new ReadableStream({
|
|
85
|
+
start(controller) {
|
|
86
|
+
sseClients.set(clientId, {
|
|
87
|
+
id: clientId,
|
|
88
|
+
controller,
|
|
89
|
+
queueFilter,
|
|
90
|
+
});
|
|
91
|
+
// Send initial connection message
|
|
92
|
+
controller.enqueue(new TextEncoder().encode(`data: {"connected":true,"clientId":"${clientId}"}\n\n`));
|
|
93
|
+
},
|
|
94
|
+
cancel() {
|
|
95
|
+
sseClients.delete(clientId);
|
|
96
|
+
},
|
|
97
|
+
});
|
|
98
|
+
return new Response(stream, {
|
|
99
|
+
headers: {
|
|
100
|
+
'Content-Type': 'text/event-stream',
|
|
101
|
+
'Cache-Control': 'no-cache',
|
|
102
|
+
Connection: 'keep-alive',
|
|
103
|
+
'Access-Control-Allow-Origin': corsOrigins.has('*')
|
|
104
|
+
? '*'
|
|
105
|
+
: Array.from(corsOrigins).join(', '),
|
|
106
|
+
},
|
|
107
|
+
});
|
|
108
|
+
}
|
|
109
|
+
// Prometheus metrics endpoint (auth optional via config)
|
|
110
|
+
if (path === '/prometheus' && req.method === 'GET') {
|
|
111
|
+
if (config.requireAuthForMetrics && authTokens.size > 0) {
|
|
112
|
+
const authHeader = req.headers.get('Authorization');
|
|
113
|
+
const token = authHeader?.replace('Bearer ', '') ?? '';
|
|
114
|
+
let authenticated = false;
|
|
115
|
+
for (const validToken of authTokens) {
|
|
116
|
+
if (constantTimeEqual(token, validToken)) {
|
|
117
|
+
authenticated = true;
|
|
118
|
+
break;
|
|
119
|
+
}
|
|
120
|
+
}
|
|
121
|
+
if (!authenticated) {
|
|
122
|
+
return jsonResponse({ ok: false, error: 'Unauthorized' }, 401);
|
|
123
|
+
}
|
|
124
|
+
}
|
|
125
|
+
const metrics = queueManager.getPrometheusMetrics();
|
|
126
|
+
return new Response(metrics, {
|
|
127
|
+
headers: { 'Content-Type': 'text/plain; version=0.0.4; charset=utf-8' },
|
|
128
|
+
});
|
|
129
|
+
}
|
|
130
|
+
// Check authentication
|
|
131
|
+
if (authTokens.size > 0) {
|
|
132
|
+
const authHeader = req.headers.get('Authorization');
|
|
133
|
+
const token = authHeader?.replace('Bearer ', '') ?? '';
|
|
134
|
+
let authenticated = false;
|
|
135
|
+
for (const validToken of authTokens) {
|
|
136
|
+
if (constantTimeEqual(token, validToken)) {
|
|
137
|
+
authenticated = true;
|
|
138
|
+
break;
|
|
139
|
+
}
|
|
140
|
+
}
|
|
141
|
+
if (!authenticated) {
|
|
142
|
+
return jsonResponse({ ok: false, error: 'Unauthorized' }, 401);
|
|
143
|
+
}
|
|
144
|
+
}
|
|
145
|
+
// Create handler context
|
|
146
|
+
const ctx = {
|
|
147
|
+
queueManager,
|
|
148
|
+
authTokens,
|
|
149
|
+
authenticated: true,
|
|
150
|
+
};
|
|
151
|
+
// Route request
|
|
152
|
+
try {
|
|
153
|
+
return await routeRequest(req, path, ctx, corsOrigins);
|
|
154
|
+
}
|
|
155
|
+
catch (err) {
|
|
156
|
+
const message = err instanceof Error ? err.message : 'Internal error';
|
|
157
|
+
return jsonResponse({ ok: false, error: message }, 500);
|
|
158
|
+
}
|
|
159
|
+
},
|
|
160
|
+
websocket: {
|
|
161
|
+
open(ws) {
|
|
162
|
+
wsClients.set(ws.data.id, ws);
|
|
163
|
+
wsLog.info('Client connected', { clientId: ws.data.id });
|
|
164
|
+
},
|
|
165
|
+
async message(ws, message) {
|
|
166
|
+
const text = typeof message === 'string' ? message : new TextDecoder().decode(message);
|
|
167
|
+
const cmd = parseCommand(text);
|
|
168
|
+
if (!cmd) {
|
|
169
|
+
ws.send(errorResponse('Invalid command'));
|
|
170
|
+
return;
|
|
171
|
+
}
|
|
172
|
+
const ctx = {
|
|
173
|
+
queueManager,
|
|
174
|
+
authTokens,
|
|
175
|
+
authenticated: ws.data.authenticated,
|
|
176
|
+
};
|
|
177
|
+
try {
|
|
178
|
+
const response = await handleCommand(cmd, ctx);
|
|
179
|
+
// Update authentication state
|
|
180
|
+
if (cmd.cmd === 'Auth' && response.ok) {
|
|
181
|
+
ws.data.authenticated = true;
|
|
182
|
+
}
|
|
183
|
+
ws.send(serializeResponse(response));
|
|
184
|
+
}
|
|
185
|
+
catch (err) {
|
|
186
|
+
const message = err instanceof Error ? err.message : 'Unknown error';
|
|
187
|
+
ws.send(errorResponse(message, cmd.reqId));
|
|
188
|
+
}
|
|
189
|
+
},
|
|
190
|
+
close(ws) {
|
|
191
|
+
wsClients.delete(ws.data.id);
|
|
192
|
+
wsLog.info('Client disconnected', { clientId: ws.data.id });
|
|
193
|
+
},
|
|
194
|
+
},
|
|
195
|
+
});
|
|
196
|
+
httpLog.info('Server listening', { host: config.hostname ?? '0.0.0.0', port: config.port });
|
|
197
|
+
return {
|
|
198
|
+
server,
|
|
199
|
+
wsClients,
|
|
200
|
+
sseClients,
|
|
201
|
+
/** Get WebSocket client count */
|
|
202
|
+
getWsClientCount() {
|
|
203
|
+
return wsClients.size;
|
|
204
|
+
},
|
|
205
|
+
/** Get SSE client count */
|
|
206
|
+
getSseClientCount() {
|
|
207
|
+
return sseClients.size;
|
|
208
|
+
},
|
|
209
|
+
/** Stop the server */
|
|
210
|
+
stop() {
|
|
211
|
+
// Close all SSE connections
|
|
212
|
+
for (const [, client] of sseClients) {
|
|
213
|
+
try {
|
|
214
|
+
client.controller.close();
|
|
215
|
+
}
|
|
216
|
+
catch {
|
|
217
|
+
// Ignore
|
|
218
|
+
}
|
|
219
|
+
}
|
|
220
|
+
sseClients.clear();
|
|
221
|
+
void server.stop();
|
|
222
|
+
httpLog.info('Server stopped');
|
|
223
|
+
},
|
|
224
|
+
};
|
|
225
|
+
}
|
|
226
|
+
/**
|
|
227
|
+
* Route HTTP request to appropriate handler
|
|
228
|
+
*/
|
|
229
|
+
async function routeRequest(req, path, ctx, corsOrigins) {
|
|
230
|
+
const method = req.method;
|
|
231
|
+
// Stats endpoint
|
|
232
|
+
if (path === '/stats' && method === 'GET') {
|
|
233
|
+
const stats = ctx.queueManager.getStats();
|
|
234
|
+
return jsonResponse({
|
|
235
|
+
ok: true,
|
|
236
|
+
stats: {
|
|
237
|
+
...stats,
|
|
238
|
+
totalPushed: Number(stats.totalPushed),
|
|
239
|
+
totalPulled: Number(stats.totalPulled),
|
|
240
|
+
totalCompleted: Number(stats.totalCompleted),
|
|
241
|
+
totalFailed: Number(stats.totalFailed),
|
|
242
|
+
},
|
|
243
|
+
}, 200, corsOrigins);
|
|
244
|
+
}
|
|
245
|
+
// Metrics endpoint
|
|
246
|
+
if (path === '/metrics' && method === 'GET') {
|
|
247
|
+
const stats = ctx.queueManager.getStats();
|
|
248
|
+
return jsonResponse({
|
|
249
|
+
ok: true,
|
|
250
|
+
metrics: {
|
|
251
|
+
totalPushed: Number(stats.totalPushed),
|
|
252
|
+
totalPulled: Number(stats.totalPulled),
|
|
253
|
+
totalCompleted: Number(stats.totalCompleted),
|
|
254
|
+
totalFailed: Number(stats.totalFailed),
|
|
255
|
+
},
|
|
256
|
+
}, 200, corsOrigins);
|
|
257
|
+
}
|
|
258
|
+
// Queue operations: POST /queues/:queue/jobs
|
|
259
|
+
const queueJobsMatch = path.match(/^\/queues\/([^/]+)\/jobs$/);
|
|
260
|
+
if (queueJobsMatch) {
|
|
261
|
+
const queue = decodeURIComponent(queueJobsMatch[1]);
|
|
262
|
+
if (method === 'POST') {
|
|
263
|
+
let body;
|
|
264
|
+
try {
|
|
265
|
+
body = (await req.json());
|
|
266
|
+
}
|
|
267
|
+
catch {
|
|
268
|
+
return jsonResponse({ ok: false, error: 'Invalid JSON body' }, 400, corsOrigins);
|
|
269
|
+
}
|
|
270
|
+
const cmd = { cmd: 'PUSH', queue, ...body };
|
|
271
|
+
const response = await handleCommand(cmd, ctx);
|
|
272
|
+
return jsonResponse(response, response.ok ? 200 : 400, corsOrigins);
|
|
273
|
+
}
|
|
274
|
+
if (method === 'GET') {
|
|
275
|
+
// Pull job
|
|
276
|
+
const timeout = parseInt(new URL(req.url).searchParams.get('timeout') ?? '0');
|
|
277
|
+
const cmd = { cmd: 'PULL', queue, timeout };
|
|
278
|
+
const response = await handleCommand(cmd, ctx);
|
|
279
|
+
return jsonResponse(response, 200, corsOrigins);
|
|
280
|
+
}
|
|
281
|
+
}
|
|
282
|
+
// Job operations: GET/DELETE /jobs/:id
|
|
283
|
+
const jobMatch = path.match(/^\/jobs\/(\d+)$/);
|
|
284
|
+
if (jobMatch) {
|
|
285
|
+
const id = jobMatch[1];
|
|
286
|
+
if (method === 'GET') {
|
|
287
|
+
const cmd = { cmd: 'GetJob', id };
|
|
288
|
+
const response = await handleCommand(cmd, ctx);
|
|
289
|
+
return jsonResponse(response, response.ok ? 200 : 404, corsOrigins);
|
|
290
|
+
}
|
|
291
|
+
if (method === 'DELETE') {
|
|
292
|
+
const cmd = { cmd: 'Cancel', id };
|
|
293
|
+
const response = await handleCommand(cmd, ctx);
|
|
294
|
+
return jsonResponse(response, 200, corsOrigins);
|
|
295
|
+
}
|
|
296
|
+
}
|
|
297
|
+
// Job ack: POST /jobs/:id/ack
|
|
298
|
+
const ackMatch = path.match(/^\/jobs\/(\d+)\/ack$/);
|
|
299
|
+
if (ackMatch && method === 'POST') {
|
|
300
|
+
const id = ackMatch[1];
|
|
301
|
+
const body = (await req.json().catch(() => ({})));
|
|
302
|
+
const cmd = { cmd: 'ACK', id, result: body['result'] };
|
|
303
|
+
const response = await handleCommand(cmd, ctx);
|
|
304
|
+
return jsonResponse(response, response.ok ? 200 : 400, corsOrigins);
|
|
305
|
+
}
|
|
306
|
+
// Job fail: POST /jobs/:id/fail
|
|
307
|
+
const failMatch = path.match(/^\/jobs\/(\d+)\/fail$/);
|
|
308
|
+
if (failMatch && method === 'POST') {
|
|
309
|
+
const id = failMatch[1];
|
|
310
|
+
const body = (await req.json().catch(() => ({})));
|
|
311
|
+
const cmd = { cmd: 'FAIL', id, error: body['error'] };
|
|
312
|
+
const response = await handleCommand(cmd, ctx);
|
|
313
|
+
return jsonResponse(response, response.ok ? 200 : 400, corsOrigins);
|
|
314
|
+
}
|
|
315
|
+
// Not found
|
|
316
|
+
return jsonResponse({ ok: false, error: 'Not found' }, 404, corsOrigins);
|
|
317
|
+
}
|
|
318
|
+
/** Create JSON response with CORS headers */
|
|
319
|
+
function jsonResponse(data, status = 200, corsOrigins) {
|
|
320
|
+
const headers = {
|
|
321
|
+
'Content-Type': 'application/json',
|
|
322
|
+
};
|
|
323
|
+
if (corsOrigins) {
|
|
324
|
+
headers['Access-Control-Allow-Origin'] = corsOrigins.has('*')
|
|
325
|
+
? '*'
|
|
326
|
+
: Array.from(corsOrigins).join(', ');
|
|
327
|
+
}
|
|
328
|
+
return new Response(JSON.stringify(data), { status, headers });
|
|
329
|
+
}
|
|
330
|
+
/** Create CORS preflight response */
|
|
331
|
+
function corsResponse(corsOrigins) {
|
|
332
|
+
return new Response(null, {
|
|
333
|
+
status: 204,
|
|
334
|
+
headers: {
|
|
335
|
+
'Access-Control-Allow-Origin': corsOrigins.has('*')
|
|
336
|
+
? '*'
|
|
337
|
+
: Array.from(corsOrigins).join(', '),
|
|
338
|
+
'Access-Control-Allow-Methods': 'GET, POST, PUT, DELETE, OPTIONS',
|
|
339
|
+
'Access-Control-Allow-Headers': 'Content-Type, Authorization',
|
|
340
|
+
'Access-Control-Max-Age': '86400',
|
|
341
|
+
},
|
|
342
|
+
});
|
|
343
|
+
}
|
|
344
|
+
//# sourceMappingURL=http.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"http.js","sourceRoot":"","sources":["../../../src/infrastructure/server/http.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/infrastructure/server/index.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,cAAc,YAAY,CAAC;AAC3B,cAAc,WAAW,CAAC;AAC1B,cAAc,OAAO,CAAC;AACtB,cAAc,QAAQ,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/infrastructure/server/index.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,cAAc,YAAY,CAAC;AAC3B,cAAc,WAAW,CAAC;AAC1B,cAAc,OAAO,CAAC;AACtB,cAAc,QAAQ,CAAC"}
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Protocol Parser
|
|
3
|
+
* Handles JSON text protocol parsing and serialization
|
|
4
|
+
*/
|
|
5
|
+
import type { Command } from '../../domain/types/command';
|
|
6
|
+
import { type Response } from '../../domain/types/response';
|
|
7
|
+
/** Parse a command from JSON string */
|
|
8
|
+
export declare function parseCommand(data: string): Command | null;
|
|
9
|
+
/** Serialize response to JSON string */
|
|
10
|
+
export declare function serializeResponse(response: Response): string;
|
|
11
|
+
/** Parse multiple commands from newline-delimited JSON */
|
|
12
|
+
export declare function parseCommands(data: string): Command[];
|
|
13
|
+
/** Validate queue name */
|
|
14
|
+
export declare function validateQueueName(name: string): string | null;
|
|
15
|
+
/** Validate job data size */
|
|
16
|
+
export declare function validateJobData(data: unknown): string | null;
|
|
17
|
+
/** Connection state */
|
|
18
|
+
export interface ConnectionState {
|
|
19
|
+
authenticated: boolean;
|
|
20
|
+
clientId: string;
|
|
21
|
+
}
|
|
22
|
+
/** Create initial connection state */
|
|
23
|
+
export declare function createConnectionState(clientId: string): ConnectionState;
|
|
24
|
+
/** Error response helper */
|
|
25
|
+
export declare function errorResponse(message: string, reqId?: string): string;
|
|
26
|
+
/** Line buffer for TCP connections */
|
|
27
|
+
export declare class LineBuffer {
|
|
28
|
+
private buffer;
|
|
29
|
+
/** Add data to buffer and extract complete lines */
|
|
30
|
+
addData(data: string): string[];
|
|
31
|
+
/** Get remaining buffer content */
|
|
32
|
+
getRemaining(): string;
|
|
33
|
+
/** Clear buffer */
|
|
34
|
+
clear(): void;
|
|
35
|
+
}
|
|
36
|
+
/** Binary protocol frame parser */
|
|
37
|
+
export declare class FrameParser {
|
|
38
|
+
private buffer;
|
|
39
|
+
/** Add data and extract complete frames */
|
|
40
|
+
addData(data: Uint8Array): Uint8Array[];
|
|
41
|
+
/** Create a framed message */
|
|
42
|
+
static frame(data: Uint8Array): Uint8Array;
|
|
43
|
+
}
|
|
44
|
+
//# sourceMappingURL=protocol.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"protocol.d.ts","sourceRoot":"","sources":["../../../src/infrastructure/server/protocol.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,4BAA4B,CAAC;AAC1D,OAAO,EAAE,KAAK,QAAQ,EAAS,MAAM,6BAA6B,CAAC;AAEnE,uCAAuC;AACvC,wBAAgB,YAAY,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,GAAG,IAAI,CAUzD;AAED,wCAAwC;AACxC,wBAAgB,iBAAiB,CAAC,QAAQ,EAAE,QAAQ,GAAG,MAAM,CAE5D;AAED,0DAA0D;AAC1D,wBAAgB,aAAa,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,EAAE,CAYrD;AAED,0BAA0B;AAC1B,wBAAgB,iBAAiB,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CAW7D;AAED,6BAA6B;AAC7B,wBAAgB,eAAe,CAAC,IAAI,EAAE,OAAO,GAAG,MAAM,GAAG,IAAI,CAM5D;AAED,uBAAuB;AACvB,MAAM,WAAW,eAAe;IAC9B,aAAa,EAAE,OAAO,CAAC;IACvB,QAAQ,EAAE,MAAM,CAAC;CAClB;AAED,sCAAsC;AACtC,wBAAgB,qBAAqB,CAAC,QAAQ,EAAE,MAAM,GAAG,eAAe,CAKvE;AAED,4BAA4B;AAC5B,wBAAgB,aAAa,CAAC,OAAO,EAAE,MAAM,EAAE,KAAK,CAAC,EAAE,MAAM,GAAG,MAAM,CAErE;AAED,sCAAsC;AACtC,qBAAa,UAAU;IACrB,OAAO,CAAC,MAAM,CAAM;IAEpB,oDAAoD;IACpD,OAAO,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,EAAE;IAgB/B,mCAAmC;IACnC,YAAY,IAAI,MAAM;IAItB,mBAAmB;IACnB,KAAK,IAAI,IAAI;CAGd;AAED,mCAAmC;AACnC,qBAAa,WAAW;IACtB,OAAO,CAAC,MAAM,CAAiC;IAE/C,2CAA2C;IAC3C,OAAO,CAAC,IAAI,EAAE,UAAU,GAAG,UAAU,EAAE;IA2BvC,8BAA8B;IAC9B,MAAM,CAAC,KAAK,CAAC,IAAI,EAAE,UAAU,GAAG,UAAU;CAU3C"}
|
|
@@ -0,0 +1,129 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Protocol Parser
|
|
3
|
+
* Handles JSON text protocol parsing and serialization
|
|
4
|
+
*/
|
|
5
|
+
import { error } from '../../domain/types/response';
|
|
6
|
+
/** Parse a command from JSON string */
|
|
7
|
+
export function parseCommand(data) {
|
|
8
|
+
try {
|
|
9
|
+
const parsed = JSON.parse(data);
|
|
10
|
+
if (!parsed['cmd']) {
|
|
11
|
+
return null;
|
|
12
|
+
}
|
|
13
|
+
return parsed;
|
|
14
|
+
}
|
|
15
|
+
catch {
|
|
16
|
+
return null;
|
|
17
|
+
}
|
|
18
|
+
}
|
|
19
|
+
/** Serialize response to JSON string */
|
|
20
|
+
export function serializeResponse(response) {
|
|
21
|
+
return JSON.stringify(response);
|
|
22
|
+
}
|
|
23
|
+
/** Parse multiple commands from newline-delimited JSON */
|
|
24
|
+
export function parseCommands(data) {
|
|
25
|
+
const lines = data.split('\n').filter((line) => line.trim().length > 0);
|
|
26
|
+
const commands = [];
|
|
27
|
+
for (const line of lines) {
|
|
28
|
+
const cmd = parseCommand(line);
|
|
29
|
+
if (cmd) {
|
|
30
|
+
commands.push(cmd);
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
return commands;
|
|
34
|
+
}
|
|
35
|
+
/** Validate queue name */
|
|
36
|
+
export function validateQueueName(name) {
|
|
37
|
+
if (!name || name.length === 0) {
|
|
38
|
+
return 'Queue name is required';
|
|
39
|
+
}
|
|
40
|
+
if (name.length > 256) {
|
|
41
|
+
return 'Queue name too long (max 256 characters)';
|
|
42
|
+
}
|
|
43
|
+
if (!/^[a-zA-Z0-9_\-.:]+$/.test(name)) {
|
|
44
|
+
return 'Queue name contains invalid characters';
|
|
45
|
+
}
|
|
46
|
+
return null;
|
|
47
|
+
}
|
|
48
|
+
/** Validate job data size */
|
|
49
|
+
export function validateJobData(data) {
|
|
50
|
+
const json = JSON.stringify(data);
|
|
51
|
+
if (json.length > 10 * 1024 * 1024) {
|
|
52
|
+
return 'Job data too large (max 10MB)';
|
|
53
|
+
}
|
|
54
|
+
return null;
|
|
55
|
+
}
|
|
56
|
+
/** Create initial connection state */
|
|
57
|
+
export function createConnectionState(clientId) {
|
|
58
|
+
return {
|
|
59
|
+
authenticated: false,
|
|
60
|
+
clientId,
|
|
61
|
+
};
|
|
62
|
+
}
|
|
63
|
+
/** Error response helper */
|
|
64
|
+
export function errorResponse(message, reqId) {
|
|
65
|
+
return serializeResponse(error(message, reqId));
|
|
66
|
+
}
|
|
67
|
+
/** Line buffer for TCP connections */
|
|
68
|
+
export class LineBuffer {
|
|
69
|
+
buffer = '';
|
|
70
|
+
/** Add data to buffer and extract complete lines */
|
|
71
|
+
addData(data) {
|
|
72
|
+
this.buffer += data;
|
|
73
|
+
const lines = [];
|
|
74
|
+
let newlineIdx;
|
|
75
|
+
while ((newlineIdx = this.buffer.indexOf('\n')) !== -1) {
|
|
76
|
+
const line = this.buffer.slice(0, newlineIdx).trim();
|
|
77
|
+
this.buffer = this.buffer.slice(newlineIdx + 1);
|
|
78
|
+
if (line.length > 0) {
|
|
79
|
+
lines.push(line);
|
|
80
|
+
}
|
|
81
|
+
}
|
|
82
|
+
return lines;
|
|
83
|
+
}
|
|
84
|
+
/** Get remaining buffer content */
|
|
85
|
+
getRemaining() {
|
|
86
|
+
return this.buffer;
|
|
87
|
+
}
|
|
88
|
+
/** Clear buffer */
|
|
89
|
+
clear() {
|
|
90
|
+
this.buffer = '';
|
|
91
|
+
}
|
|
92
|
+
}
|
|
93
|
+
/** Binary protocol frame parser */
|
|
94
|
+
export class FrameParser {
|
|
95
|
+
buffer = new Uint8Array(0);
|
|
96
|
+
/** Add data and extract complete frames */
|
|
97
|
+
addData(data) {
|
|
98
|
+
// Concatenate buffers
|
|
99
|
+
const newBuffer = new Uint8Array(this.buffer.length + data.length);
|
|
100
|
+
newBuffer.set(this.buffer);
|
|
101
|
+
newBuffer.set(data, this.buffer.length);
|
|
102
|
+
this.buffer = newBuffer;
|
|
103
|
+
const frames = [];
|
|
104
|
+
while (this.buffer.length >= 4) {
|
|
105
|
+
// Read length prefix (big-endian u32)
|
|
106
|
+
const length = (this.buffer[0] << 24) | (this.buffer[1] << 16) | (this.buffer[2] << 8) | this.buffer[3];
|
|
107
|
+
if (this.buffer.length < 4 + length) {
|
|
108
|
+
// Not enough data
|
|
109
|
+
break;
|
|
110
|
+
}
|
|
111
|
+
// Extract frame
|
|
112
|
+
frames.push(this.buffer.slice(4, 4 + length));
|
|
113
|
+
this.buffer = this.buffer.slice(4 + length);
|
|
114
|
+
}
|
|
115
|
+
return frames;
|
|
116
|
+
}
|
|
117
|
+
/** Create a framed message */
|
|
118
|
+
static frame(data) {
|
|
119
|
+
const frame = new Uint8Array(4 + data.length);
|
|
120
|
+
// Write length prefix (big-endian u32)
|
|
121
|
+
frame[0] = (data.length >> 24) & 0xff;
|
|
122
|
+
frame[1] = (data.length >> 16) & 0xff;
|
|
123
|
+
frame[2] = (data.length >> 8) & 0xff;
|
|
124
|
+
frame[3] = data.length & 0xff;
|
|
125
|
+
frame.set(data, 4);
|
|
126
|
+
return frame;
|
|
127
|
+
}
|
|
128
|
+
}
|
|
129
|
+
//# sourceMappingURL=protocol.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"protocol.js","sourceRoot":"","sources":["../../../src/infrastructure/server/protocol.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Protocol Rate Limiter
|
|
3
|
+
* Prevents abuse by limiting requests per client
|
|
4
|
+
*/
|
|
5
|
+
export interface RateLimiterConfig {
|
|
6
|
+
windowMs: number;
|
|
7
|
+
maxRequests: number;
|
|
8
|
+
cleanupIntervalMs?: number;
|
|
9
|
+
}
|
|
10
|
+
/** Rate limiter for protocol-level request limiting */
|
|
11
|
+
export declare class ProtocolRateLimiter {
|
|
12
|
+
private readonly requests;
|
|
13
|
+
private readonly config;
|
|
14
|
+
private cleanupInterval;
|
|
15
|
+
constructor(config?: Partial<RateLimiterConfig>);
|
|
16
|
+
/** Check if a request from clientId is allowed */
|
|
17
|
+
isAllowed(clientId: string): boolean;
|
|
18
|
+
/** Get remaining requests for a client */
|
|
19
|
+
getRemaining(clientId: string): number;
|
|
20
|
+
/** Remove a client from tracking */
|
|
21
|
+
removeClient(clientId: string): void;
|
|
22
|
+
/** Start cleanup interval */
|
|
23
|
+
private startCleanup;
|
|
24
|
+
/** Clean up old entries */
|
|
25
|
+
private cleanup;
|
|
26
|
+
/** Stop the rate limiter */
|
|
27
|
+
stop(): void;
|
|
28
|
+
}
|
|
29
|
+
/** Get or create global rate limiter */
|
|
30
|
+
export declare function getRateLimiter(config?: Partial<RateLimiterConfig>): ProtocolRateLimiter;
|
|
31
|
+
//# sourceMappingURL=rateLimiter.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"rateLimiter.d.ts","sourceRoot":"","sources":["../../../src/infrastructure/server/rateLimiter.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,MAAM,WAAW,iBAAiB;IAChC,QAAQ,EAAE,MAAM,CAAC;IACjB,WAAW,EAAE,MAAM,CAAC;IACpB,iBAAiB,CAAC,EAAE,MAAM,CAAC;CAC5B;AAQD,uDAAuD;AACvD,qBAAa,mBAAmB;IAC9B,OAAO,CAAC,QAAQ,CAAC,QAAQ,CAA+B;IACxD,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAoB;IAC3C,OAAO,CAAC,eAAe,CAA+C;gBAE1D,MAAM,GAAE,OAAO,CAAC,iBAAiB,CAAM;IAKnD,kDAAkD;IAClD,SAAS,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO;IAgBpC,0CAA0C;IAC1C,YAAY,CAAC,QAAQ,EAAE,MAAM,GAAG,MAAM;IAOtC,oCAAoC;IACpC,YAAY,CAAC,QAAQ,EAAE,MAAM,GAAG,IAAI;IAIpC,6BAA6B;IAC7B,OAAO,CAAC,YAAY;IAQpB,2BAA2B;IAC3B,OAAO,CAAC,OAAO;IAYf,4BAA4B;IAC5B,IAAI,IAAI,IAAI;CAMb;AAKD,wCAAwC;AACxC,wBAAgB,cAAc,CAAC,MAAM,CAAC,EAAE,OAAO,CAAC,iBAAiB,CAAC,GAAG,mBAAmB,CAGvF"}
|