@cequrebackends/cequre-ts 0.11.4
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/dist/adapters/bun/bun-cron.d.ts +20 -0
- package/dist/adapters/bun/bun-media.d.ts +9 -0
- package/dist/adapters/bun/bun-redis-cache.d.ts +33 -0
- package/dist/adapters/bun/bun-response.d.ts +13 -0
- package/dist/adapters/bun/bun-server.d.ts +6 -0
- package/dist/adapters/bun/bun-storage.d.ts +10 -0
- package/dist/adapters/bun/bun-websocket.d.ts +104 -0
- package/dist/adapters/bun/index.d.ts +9 -0
- package/dist/adapters/bun/index.js +547 -0
- package/dist/adapters/node/index.d.ts +9 -0
- package/dist/adapters/node/index.js +902 -0
- package/dist/adapters/node/node-cron.d.ts +20 -0
- package/dist/adapters/node/node-media.d.ts +9 -0
- package/dist/adapters/node/node-redis-cache.d.ts +32 -0
- package/dist/adapters/node/node-response.d.ts +13 -0
- package/dist/adapters/node/node-server.d.ts +6 -0
- package/dist/adapters/node/node-storage.d.ts +10 -0
- package/dist/adapters/node/node-websocket.d.ts +102 -0
- package/dist/index-17yswtmg.js +175 -0
- package/dist/index-kyvy0s1x.js +2662 -0
- package/dist/index-mfqj7cwr.js +165 -0
- package/dist/index-rf1kdn5b.js +732 -0
- package/dist/index.d.ts +18 -0
- package/dist/index.js +3152 -0
- package/dist/interface-map.d.ts +175 -0
- package/dist/shared/core/adapter.d.ts +84 -0
- package/dist/shared/core/base-sql-adapter.d.ts +34 -0
- package/dist/shared/core/cache.d.ts +8 -0
- package/dist/shared/core/email.d.ts +53 -0
- package/dist/shared/core/index.d.ts +12 -0
- package/dist/shared/core/index.js +47 -0
- package/dist/shared/core/openapi.d.ts +24 -0
- package/dist/shared/core/plugins.d.ts +2 -0
- package/dist/shared/core/request.d.ts +32 -0
- package/dist/shared/core/sdk.d.ts +3 -0
- package/dist/shared/core/stream.d.ts +24 -0
- package/dist/shared/core/types-generator.d.ts +0 -0
- package/dist/shared/core/types.d.ts +304 -0
- package/dist/shared/core/ulid.d.ts +5 -0
- package/dist/shared/core/validator.d.ts +32 -0
- package/dist/shared/main/access-evaluator.d.ts +13 -0
- package/dist/shared/main/access.d.ts +34 -0
- package/dist/shared/main/aot.d.ts +3 -0
- package/dist/shared/main/hooks.d.ts +76 -0
- package/dist/shared/main/population.d.ts +13 -0
- package/dist/shared/main/router.d.ts +112 -0
- package/dist/shared/main/runtime.d.ts +195 -0
- package/dist/shared/main/sse.d.ts +87 -0
- package/dist/shared/utils/crypto.d.ts +23 -0
- package/dist/shared/utils/durable-queue.d.ts +20 -0
- package/dist/shared/utils/duration.d.ts +15 -0
- package/dist/shared/utils/error.d.ts +52 -0
- package/dist/shared/utils/kv/adapters/memory.d.ts +20 -0
- package/dist/shared/utils/kv/adapters/sqlite.d.ts +32 -0
- package/dist/shared/utils/kv/index.d.ts +37 -0
- package/dist/shared/utils/kv/types.d.ts +38 -0
- package/dist/shared/utils/logger.d.ts +42 -0
- package/dist/shared/utils/queue-manager.d.ts +64 -0
- package/dist/shared/utils/url.d.ts +13 -0
- package/package.json +63 -0
|
@@ -0,0 +1,547 @@
|
|
|
1
|
+
// @bun
|
|
2
|
+
import {
|
|
3
|
+
CequreStreamMedia,
|
|
4
|
+
UPGRADED,
|
|
5
|
+
empty,
|
|
6
|
+
error,
|
|
7
|
+
file,
|
|
8
|
+
json,
|
|
9
|
+
methodNotAllowed,
|
|
10
|
+
notFound,
|
|
11
|
+
redirect,
|
|
12
|
+
routeErrorToResponse,
|
|
13
|
+
stream,
|
|
14
|
+
toResponse
|
|
15
|
+
} from "../../index-mfqj7cwr.js";
|
|
16
|
+
import {
|
|
17
|
+
CequreQueueManager,
|
|
18
|
+
RedisAdapter,
|
|
19
|
+
init_bun_redis_cache,
|
|
20
|
+
init_logger,
|
|
21
|
+
logger
|
|
22
|
+
} from "../../index-rf1kdn5b.js";
|
|
23
|
+
import {
|
|
24
|
+
CequreError,
|
|
25
|
+
ulid
|
|
26
|
+
} from "../../index-17yswtmg.js";
|
|
27
|
+
|
|
28
|
+
// adapters/bun/bun-server.ts
|
|
29
|
+
class BunServerProvider {
|
|
30
|
+
server;
|
|
31
|
+
start(config) {
|
|
32
|
+
const tls = config.tls;
|
|
33
|
+
let finalTls = tls;
|
|
34
|
+
if (tls && tls.cert && tls.key) {
|
|
35
|
+
finalTls = {
|
|
36
|
+
cert: Bun.file(tls.cert),
|
|
37
|
+
key: Bun.file(tls.key),
|
|
38
|
+
passphrase: tls.passphrase,
|
|
39
|
+
serverName: tls.serverName
|
|
40
|
+
};
|
|
41
|
+
}
|
|
42
|
+
this.server = Bun.serve({
|
|
43
|
+
port: config.port ?? (process.env.PORT ? parseInt(process.env.PORT, 10) : 3000),
|
|
44
|
+
hostname: config.hostname,
|
|
45
|
+
tls: finalTls,
|
|
46
|
+
...config.maxRequestBodySize ? { maxRequestBodySize: config.maxRequestBodySize } : {},
|
|
47
|
+
...config.routes ? { routes: config.routes } : {},
|
|
48
|
+
fetch: config.fetch
|
|
49
|
+
});
|
|
50
|
+
console.log(`\uD83D\uDE80 Cequre starting on http://${this.server.hostname}:${this.server.port}`);
|
|
51
|
+
return this.server;
|
|
52
|
+
}
|
|
53
|
+
async stop() {
|
|
54
|
+
if (this.server) {
|
|
55
|
+
this.server.stop(true);
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
// adapters/bun/bun-cron.ts
|
|
60
|
+
init_logger();
|
|
61
|
+
|
|
62
|
+
class BunCronProvider {
|
|
63
|
+
localJobs = new Map;
|
|
64
|
+
useBullMQ = false;
|
|
65
|
+
constructor() {
|
|
66
|
+
try {
|
|
67
|
+
CequreQueueManager.getInstance();
|
|
68
|
+
this.useBullMQ = true;
|
|
69
|
+
} catch {
|
|
70
|
+
this.useBullMQ = false;
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
registerJob(name, schedule, handler) {
|
|
74
|
+
if (this.useBullMQ) {
|
|
75
|
+
const qm = CequreQueueManager.getInstance();
|
|
76
|
+
qm.registerWorker("cequre_cron", async (job) => {
|
|
77
|
+
if (job.name === name) {
|
|
78
|
+
try {
|
|
79
|
+
await Promise.resolve(handler());
|
|
80
|
+
} catch (err) {
|
|
81
|
+
logger.error(err, `[Cequre Cron (BullMQ)] Job "${name}" failed:`);
|
|
82
|
+
throw new Error(String(err instanceof Error ? err.message : err));
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
}).catch((err) => {
|
|
86
|
+
logger.error(err, `[Cequre Cron (BullMQ)] Failed to register worker for "${name}":`);
|
|
87
|
+
});
|
|
88
|
+
qm.addJob("cequre_cron", name, {}, {
|
|
89
|
+
repeat: { pattern: schedule },
|
|
90
|
+
jobId: `cron_${name}`,
|
|
91
|
+
removeOnComplete: true,
|
|
92
|
+
removeOnFail: 100
|
|
93
|
+
}).catch((err) => {
|
|
94
|
+
logger.error(err, `[Cequre Cron (BullMQ)] Failed to register job "${name}":`);
|
|
95
|
+
});
|
|
96
|
+
} else {
|
|
97
|
+
if (this.localJobs.has(name)) {
|
|
98
|
+
throw CequreError.Conflict(`[Cequre Cron] A cron job with the name "${name}" is already registered.`);
|
|
99
|
+
}
|
|
100
|
+
const job = Bun.cron(schedule, async () => {
|
|
101
|
+
try {
|
|
102
|
+
await handler();
|
|
103
|
+
} catch (err) {
|
|
104
|
+
logger.error(err, `[Cequre Cron] Job "${name}" failed:`);
|
|
105
|
+
}
|
|
106
|
+
});
|
|
107
|
+
this.localJobs.set(name, job);
|
|
108
|
+
}
|
|
109
|
+
}
|
|
110
|
+
async stop(name) {
|
|
111
|
+
if (this.useBullMQ) {
|
|
112
|
+
const qm = CequreQueueManager.getInstance();
|
|
113
|
+
const queue = qm.getQueue("cequre_cron");
|
|
114
|
+
const repeatableJobs = await queue.getRepeatableJobs();
|
|
115
|
+
const job = repeatableJobs.find((j) => j.name === name);
|
|
116
|
+
if (job) {
|
|
117
|
+
await queue.removeRepeatableByKey(job.key);
|
|
118
|
+
return true;
|
|
119
|
+
}
|
|
120
|
+
return false;
|
|
121
|
+
} else {
|
|
122
|
+
const job = this.localJobs.get(name);
|
|
123
|
+
if (job && typeof job.stop === "function") {
|
|
124
|
+
job.stop();
|
|
125
|
+
this.localJobs.delete(name);
|
|
126
|
+
return true;
|
|
127
|
+
}
|
|
128
|
+
return false;
|
|
129
|
+
}
|
|
130
|
+
}
|
|
131
|
+
async stopAll() {
|
|
132
|
+
if (this.useBullMQ) {
|
|
133
|
+
const qm = CequreQueueManager.getInstance();
|
|
134
|
+
const queue = qm.getQueue("cequre_cron");
|
|
135
|
+
const repeatableJobs = await queue.getRepeatableJobs();
|
|
136
|
+
for (const job of repeatableJobs) {
|
|
137
|
+
await queue.removeRepeatableByKey(job.key);
|
|
138
|
+
}
|
|
139
|
+
} else {
|
|
140
|
+
for (const [name, job] of this.localJobs.entries()) {
|
|
141
|
+
if (typeof job.stop === "function") {
|
|
142
|
+
try {
|
|
143
|
+
job.stop();
|
|
144
|
+
} catch (e) {
|
|
145
|
+
logger.error(e, `[Cequre Cron] Error stopping job "${name}":`);
|
|
146
|
+
}
|
|
147
|
+
}
|
|
148
|
+
}
|
|
149
|
+
this.localJobs.clear();
|
|
150
|
+
}
|
|
151
|
+
}
|
|
152
|
+
async list() {
|
|
153
|
+
if (this.useBullMQ) {
|
|
154
|
+
const qm = CequreQueueManager.getInstance();
|
|
155
|
+
const queue = qm.getQueue("cequre_cron");
|
|
156
|
+
const jobs = await queue.getRepeatableJobs();
|
|
157
|
+
return jobs.map((j) => j.name);
|
|
158
|
+
} else {
|
|
159
|
+
return Array.from(this.localJobs.keys());
|
|
160
|
+
}
|
|
161
|
+
}
|
|
162
|
+
startAll() {}
|
|
163
|
+
}
|
|
164
|
+
// adapters/bun/bun-websocket.ts
|
|
165
|
+
class WebSocketManager {
|
|
166
|
+
connections = new Map;
|
|
167
|
+
rooms = new Map;
|
|
168
|
+
connectionRooms = new Map;
|
|
169
|
+
metadata = new Map;
|
|
170
|
+
lastPong = new Map;
|
|
171
|
+
heartbeatTimer = null;
|
|
172
|
+
register(ws) {
|
|
173
|
+
this.connections.set(ws.id, ws);
|
|
174
|
+
this.connectionRooms.set(ws.id, new Set);
|
|
175
|
+
this.metadata.set(ws.id, {});
|
|
176
|
+
this.lastPong.set(ws.id, Date.now());
|
|
177
|
+
}
|
|
178
|
+
remove(wsOrId) {
|
|
179
|
+
const id = typeof wsOrId === "string" ? wsOrId : wsOrId.id;
|
|
180
|
+
for (const room of this.connectionRooms.get(id) ?? []) {
|
|
181
|
+
this.leaveRoom(id, room);
|
|
182
|
+
}
|
|
183
|
+
this.connections.delete(id);
|
|
184
|
+
this.connectionRooms.delete(id);
|
|
185
|
+
this.metadata.delete(id);
|
|
186
|
+
this.lastPong.delete(id);
|
|
187
|
+
}
|
|
188
|
+
pong(id) {
|
|
189
|
+
if (this.lastPong.has(id))
|
|
190
|
+
this.lastPong.set(id, Date.now());
|
|
191
|
+
}
|
|
192
|
+
startHeartbeat(intervalMs = 30000, timeoutMs = 1e4) {
|
|
193
|
+
if (this.heartbeatTimer !== null)
|
|
194
|
+
return;
|
|
195
|
+
const deadline = intervalMs + timeoutMs;
|
|
196
|
+
this.heartbeatTimer = setInterval(() => {
|
|
197
|
+
const now = Date.now();
|
|
198
|
+
for (const [id, lastSeen] of this.lastPong) {
|
|
199
|
+
if (now - lastSeen > deadline)
|
|
200
|
+
this.remove(id);
|
|
201
|
+
}
|
|
202
|
+
for (const ws of this.connections.values()) {
|
|
203
|
+
ws.send(JSON.stringify({ type: "ping" }));
|
|
204
|
+
}
|
|
205
|
+
}, intervalMs);
|
|
206
|
+
if (this.heartbeatTimer.unref)
|
|
207
|
+
this.heartbeatTimer.unref();
|
|
208
|
+
}
|
|
209
|
+
stopHeartbeat() {
|
|
210
|
+
if (this.heartbeatTimer)
|
|
211
|
+
clearInterval(this.heartbeatTimer);
|
|
212
|
+
this.heartbeatTimer = null;
|
|
213
|
+
}
|
|
214
|
+
joinRoom(id, room) {
|
|
215
|
+
if (!this.rooms.has(room))
|
|
216
|
+
this.rooms.set(room, new Set);
|
|
217
|
+
this.rooms.get(room).add(id);
|
|
218
|
+
this.connectionRooms.get(id)?.add(room);
|
|
219
|
+
}
|
|
220
|
+
leaveRoom(id, room) {
|
|
221
|
+
this.rooms.get(room)?.delete(id);
|
|
222
|
+
if (this.rooms.get(room)?.size === 0)
|
|
223
|
+
this.rooms.delete(room);
|
|
224
|
+
this.connectionRooms.get(id)?.delete(room);
|
|
225
|
+
}
|
|
226
|
+
getRoomMembers(room) {
|
|
227
|
+
return [...this.rooms.get(room) ?? []];
|
|
228
|
+
}
|
|
229
|
+
getConnectionRooms(id) {
|
|
230
|
+
return [...this.connectionRooms.get(id) ?? []];
|
|
231
|
+
}
|
|
232
|
+
listRooms() {
|
|
233
|
+
return [...this.rooms.keys()];
|
|
234
|
+
}
|
|
235
|
+
sendTo(id, payload) {
|
|
236
|
+
const ws = this.connections.get(id);
|
|
237
|
+
if (!ws)
|
|
238
|
+
return false;
|
|
239
|
+
ws.send(JSON.stringify(payload));
|
|
240
|
+
return true;
|
|
241
|
+
}
|
|
242
|
+
broadcastToRoom(room, payload, { exclude = [] } = {}) {
|
|
243
|
+
const ids = this.rooms.get(room);
|
|
244
|
+
if (!ids)
|
|
245
|
+
return 0;
|
|
246
|
+
let sent = 0;
|
|
247
|
+
for (const id of ids) {
|
|
248
|
+
if (exclude.includes(id))
|
|
249
|
+
continue;
|
|
250
|
+
if (this.sendTo(id, payload))
|
|
251
|
+
sent++;
|
|
252
|
+
}
|
|
253
|
+
return sent;
|
|
254
|
+
}
|
|
255
|
+
broadcastAll(payload, { exclude = [] } = {}) {
|
|
256
|
+
let sent = 0;
|
|
257
|
+
for (const id of this.connections.keys()) {
|
|
258
|
+
if (exclude.includes(id))
|
|
259
|
+
continue;
|
|
260
|
+
if (this.sendTo(id, payload))
|
|
261
|
+
sent++;
|
|
262
|
+
}
|
|
263
|
+
return sent;
|
|
264
|
+
}
|
|
265
|
+
setMeta(id, key, value) {
|
|
266
|
+
const meta = this.metadata.get(id);
|
|
267
|
+
if (meta)
|
|
268
|
+
meta[key] = value;
|
|
269
|
+
}
|
|
270
|
+
getMeta(id, key) {
|
|
271
|
+
return this.metadata.get(id)?.[key];
|
|
272
|
+
}
|
|
273
|
+
get connectionCount() {
|
|
274
|
+
return this.connections.size;
|
|
275
|
+
}
|
|
276
|
+
get roomCount() {
|
|
277
|
+
return this.rooms.size;
|
|
278
|
+
}
|
|
279
|
+
getStats() {
|
|
280
|
+
return {
|
|
281
|
+
connections: this.connectionCount,
|
|
282
|
+
rooms: Object.fromEntries([...this.rooms.entries()].map(([room, ids]) => [room, ids.size])),
|
|
283
|
+
heartbeatActive: this.heartbeatTimer !== null
|
|
284
|
+
};
|
|
285
|
+
}
|
|
286
|
+
}
|
|
287
|
+
var wsManager = new WebSocketManager;
|
|
288
|
+
function toServerWebSocket(ws) {
|
|
289
|
+
return {
|
|
290
|
+
id: ws.data.id,
|
|
291
|
+
data: ws.data,
|
|
292
|
+
send: (message, compress) => ws.send(message, compress)
|
|
293
|
+
};
|
|
294
|
+
}
|
|
295
|
+
function parseMessage(message) {
|
|
296
|
+
if (typeof message !== "string") {
|
|
297
|
+
return { type: "binary", payload: message };
|
|
298
|
+
}
|
|
299
|
+
try {
|
|
300
|
+
const parsed = JSON.parse(message);
|
|
301
|
+
return parsed && typeof parsed === "object" ? parsed : { type: "message", payload: parsed };
|
|
302
|
+
} catch {
|
|
303
|
+
return { type: "message", payload: message };
|
|
304
|
+
}
|
|
305
|
+
}
|
|
306
|
+
function createWebSocketHandler({
|
|
307
|
+
heartbeat,
|
|
308
|
+
onJoinRoom
|
|
309
|
+
} = {}) {
|
|
310
|
+
const startHeartbeat = () => {
|
|
311
|
+
if (heartbeat === false)
|
|
312
|
+
return;
|
|
313
|
+
wsManager.startHeartbeat(heartbeat?.interval, heartbeat?.timeout);
|
|
314
|
+
};
|
|
315
|
+
return {
|
|
316
|
+
open(ws) {
|
|
317
|
+
const wrapped = toServerWebSocket(ws);
|
|
318
|
+
wsManager.register(wrapped);
|
|
319
|
+
startHeartbeat();
|
|
320
|
+
ws.send(JSON.stringify({ type: "connected", id: wrapped.id }));
|
|
321
|
+
},
|
|
322
|
+
async message(ws, rawMessage) {
|
|
323
|
+
const message = parseMessage(rawMessage);
|
|
324
|
+
const wrapped = toServerWebSocket(ws);
|
|
325
|
+
const { id } = wrapped;
|
|
326
|
+
switch (message.type) {
|
|
327
|
+
case "join":
|
|
328
|
+
if (!message.room)
|
|
329
|
+
return;
|
|
330
|
+
if (onJoinRoom && !await onJoinRoom(message.room, wrapped)) {
|
|
331
|
+
ws.send(JSON.stringify({ type: "error", message: `Access denied to room '${message.room}'` }));
|
|
332
|
+
return;
|
|
333
|
+
}
|
|
334
|
+
wsManager.joinRoom(id, message.room);
|
|
335
|
+
ws.send(JSON.stringify({ type: "joined", room: message.room }));
|
|
336
|
+
return;
|
|
337
|
+
case "leave":
|
|
338
|
+
if (!message.room)
|
|
339
|
+
return;
|
|
340
|
+
wsManager.leaveRoom(id, message.room);
|
|
341
|
+
ws.send(JSON.stringify({ type: "left", room: message.room }));
|
|
342
|
+
return;
|
|
343
|
+
case "broadcast":
|
|
344
|
+
if (message.room) {
|
|
345
|
+
if (!wsManager.getConnectionRooms(id).includes(message.room)) {
|
|
346
|
+
ws.send(JSON.stringify({ type: "error", message: "Not in room" }));
|
|
347
|
+
return;
|
|
348
|
+
}
|
|
349
|
+
wsManager.broadcastToRoom(message.room, { type: "message", from: id, payload: message.payload }, { exclude: [id] });
|
|
350
|
+
}
|
|
351
|
+
return;
|
|
352
|
+
case "ping":
|
|
353
|
+
ws.send(JSON.stringify({ type: "pong" }));
|
|
354
|
+
return;
|
|
355
|
+
case "pong":
|
|
356
|
+
wsManager.pong(id);
|
|
357
|
+
return;
|
|
358
|
+
default:
|
|
359
|
+
ws.send(JSON.stringify({ type: "error", message: `Unknown type: ${message.type}` }));
|
|
360
|
+
}
|
|
361
|
+
},
|
|
362
|
+
close(ws) {
|
|
363
|
+
wsManager.remove(ws.data.id);
|
|
364
|
+
}
|
|
365
|
+
};
|
|
366
|
+
}
|
|
367
|
+
function createBunWebSocketRoute({
|
|
368
|
+
path = "/ws",
|
|
369
|
+
heartbeat,
|
|
370
|
+
onJoinRoom
|
|
371
|
+
} = {}) {
|
|
372
|
+
const handler = createWebSocketHandler({ heartbeat, onJoinRoom });
|
|
373
|
+
return async (request, server) => {
|
|
374
|
+
if (!server)
|
|
375
|
+
return new Response(JSON.stringify({ message: "WebSocket upgrade requires Bun.serve to pass the server into fetch" }), { status: 500 });
|
|
376
|
+
const didUpgrade = server.upgrade(request, {
|
|
377
|
+
data: {
|
|
378
|
+
id: ulid(),
|
|
379
|
+
path,
|
|
380
|
+
handler
|
|
381
|
+
}
|
|
382
|
+
});
|
|
383
|
+
if (didUpgrade) {
|
|
384
|
+
return;
|
|
385
|
+
}
|
|
386
|
+
return new Response(JSON.stringify({ message: "WebSocket upgrade failed" }), { status: 400 });
|
|
387
|
+
};
|
|
388
|
+
}
|
|
389
|
+
function createBunWebSocketHandlers() {
|
|
390
|
+
return {
|
|
391
|
+
open(ws) {
|
|
392
|
+
return ws.data.handler.open?.(ws);
|
|
393
|
+
},
|
|
394
|
+
message(ws, message) {
|
|
395
|
+
return ws.data.handler.message?.(ws, message);
|
|
396
|
+
},
|
|
397
|
+
close(ws, code, reason) {
|
|
398
|
+
return ws.data.handler.close?.(ws, code, reason);
|
|
399
|
+
},
|
|
400
|
+
drain(ws) {
|
|
401
|
+
return ws.data.handler.drain?.(ws);
|
|
402
|
+
}
|
|
403
|
+
};
|
|
404
|
+
}
|
|
405
|
+
|
|
406
|
+
class CequreWebsocket {
|
|
407
|
+
static get manager() {
|
|
408
|
+
return wsManager;
|
|
409
|
+
}
|
|
410
|
+
static route(options = {}) {
|
|
411
|
+
return createBunWebSocketRoute(options);
|
|
412
|
+
}
|
|
413
|
+
static handler(options = {}) {
|
|
414
|
+
return createWebSocketHandler(options);
|
|
415
|
+
}
|
|
416
|
+
static handlers() {
|
|
417
|
+
return createBunWebSocketHandlers();
|
|
418
|
+
}
|
|
419
|
+
static register(ws) {
|
|
420
|
+
return wsManager.register(ws);
|
|
421
|
+
}
|
|
422
|
+
static remove(wsOrId) {
|
|
423
|
+
return wsManager.remove(wsOrId);
|
|
424
|
+
}
|
|
425
|
+
static pong(id) {
|
|
426
|
+
return wsManager.pong(id);
|
|
427
|
+
}
|
|
428
|
+
static startHeartbeat(intervalMs, timeoutMs) {
|
|
429
|
+
return wsManager.startHeartbeat(intervalMs, timeoutMs);
|
|
430
|
+
}
|
|
431
|
+
static stopHeartbeat() {
|
|
432
|
+
return wsManager.stopHeartbeat();
|
|
433
|
+
}
|
|
434
|
+
static joinRoom(id, room) {
|
|
435
|
+
return wsManager.joinRoom(id, room);
|
|
436
|
+
}
|
|
437
|
+
static leaveRoom(id, room) {
|
|
438
|
+
return wsManager.leaveRoom(id, room);
|
|
439
|
+
}
|
|
440
|
+
static getRoomMembers(room) {
|
|
441
|
+
return wsManager.getRoomMembers(room);
|
|
442
|
+
}
|
|
443
|
+
static getConnectionRooms(id) {
|
|
444
|
+
return wsManager.getConnectionRooms(id);
|
|
445
|
+
}
|
|
446
|
+
static listRooms() {
|
|
447
|
+
return wsManager.listRooms();
|
|
448
|
+
}
|
|
449
|
+
static sendTo(id, payload) {
|
|
450
|
+
return wsManager.sendTo(id, payload);
|
|
451
|
+
}
|
|
452
|
+
static broadcastToRoom(room, payload, opts) {
|
|
453
|
+
return wsManager.broadcastToRoom(room, payload, opts);
|
|
454
|
+
}
|
|
455
|
+
static broadcastAll(payload, opts) {
|
|
456
|
+
return wsManager.broadcastAll(payload, opts);
|
|
457
|
+
}
|
|
458
|
+
static setMeta(id, key, value) {
|
|
459
|
+
return wsManager.setMeta(id, key, value);
|
|
460
|
+
}
|
|
461
|
+
static getMeta(id, key) {
|
|
462
|
+
return wsManager.getMeta(id, key);
|
|
463
|
+
}
|
|
464
|
+
static get connectionCount() {
|
|
465
|
+
return wsManager.connectionCount;
|
|
466
|
+
}
|
|
467
|
+
static get roomCount() {
|
|
468
|
+
return wsManager.roomCount;
|
|
469
|
+
}
|
|
470
|
+
static getStats() {
|
|
471
|
+
return wsManager.getStats();
|
|
472
|
+
}
|
|
473
|
+
}
|
|
474
|
+
// adapters/bun/bun-storage.ts
|
|
475
|
+
import fs from "fs";
|
|
476
|
+
import path from "path";
|
|
477
|
+
class LocalStorageProvider {
|
|
478
|
+
uploadDir;
|
|
479
|
+
apiPrefix;
|
|
480
|
+
constructor(uploadDir = "uploads", apiPrefix = "/api") {
|
|
481
|
+
this.apiPrefix = apiPrefix;
|
|
482
|
+
this.uploadDir = path.resolve(process.cwd(), uploadDir);
|
|
483
|
+
if (!fs.existsSync(this.uploadDir)) {
|
|
484
|
+
fs.mkdirSync(this.uploadDir, { recursive: true });
|
|
485
|
+
}
|
|
486
|
+
}
|
|
487
|
+
async saveFile(file2, options) {
|
|
488
|
+
const ext = file2.name ? path.extname(file2.name) : "";
|
|
489
|
+
const safeName = options?.filename ? options.filename : `${ulid()}${ext}`;
|
|
490
|
+
const filePath = path.join(this.uploadDir, safeName);
|
|
491
|
+
await Bun.write(filePath, file2);
|
|
492
|
+
return {
|
|
493
|
+
filename: safeName,
|
|
494
|
+
originalName: file2.name || "upload",
|
|
495
|
+
mimetype: file2.type || "application/octet-stream",
|
|
496
|
+
size: file2.size,
|
|
497
|
+
url: `${this.apiPrefix}/uploads/${safeName}`
|
|
498
|
+
};
|
|
499
|
+
}
|
|
500
|
+
async deleteFile(filename) {
|
|
501
|
+
const filePath = path.join(this.uploadDir, filename);
|
|
502
|
+
try {
|
|
503
|
+
if (fs.existsSync(filePath)) {
|
|
504
|
+
await fs.promises.unlink(filePath);
|
|
505
|
+
}
|
|
506
|
+
} catch (e) {
|
|
507
|
+
console.error(`Failed to delete file ${filePath}`, e);
|
|
508
|
+
}
|
|
509
|
+
}
|
|
510
|
+
}
|
|
511
|
+
|
|
512
|
+
// adapters/bun/index.ts
|
|
513
|
+
init_bun_redis_cache();
|
|
514
|
+
function withBun(config) {
|
|
515
|
+
return {
|
|
516
|
+
...config,
|
|
517
|
+
serverProvider: config.serverProvider || new BunServerProvider,
|
|
518
|
+
cronProvider: config.cronProvider || new BunCronProvider,
|
|
519
|
+
realtimeProvider: config.realtimeProvider || { websocket: CequreWebsocket },
|
|
520
|
+
storageProvider: config.storageProvider || new LocalStorageProvider
|
|
521
|
+
};
|
|
522
|
+
}
|
|
523
|
+
export {
|
|
524
|
+
wsManager,
|
|
525
|
+
withBun,
|
|
526
|
+
toResponse,
|
|
527
|
+
stream,
|
|
528
|
+
routeErrorToResponse,
|
|
529
|
+
redirect,
|
|
530
|
+
notFound,
|
|
531
|
+
methodNotAllowed,
|
|
532
|
+
json,
|
|
533
|
+
file,
|
|
534
|
+
error,
|
|
535
|
+
empty,
|
|
536
|
+
createWebSocketHandler,
|
|
537
|
+
createBunWebSocketRoute,
|
|
538
|
+
createBunWebSocketHandlers,
|
|
539
|
+
WebSocketManager,
|
|
540
|
+
UPGRADED,
|
|
541
|
+
RedisAdapter,
|
|
542
|
+
LocalStorageProvider,
|
|
543
|
+
CequreWebsocket,
|
|
544
|
+
CequreStreamMedia,
|
|
545
|
+
BunServerProvider,
|
|
546
|
+
BunCronProvider
|
|
547
|
+
};
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
export * from "./node-server";
|
|
2
|
+
export * from "./node-cron";
|
|
3
|
+
export * from "./node-websocket";
|
|
4
|
+
export * from "./node-storage";
|
|
5
|
+
export * from "./node-redis-cache";
|
|
6
|
+
export * from "./node-response";
|
|
7
|
+
export * from "./node-media";
|
|
8
|
+
import type { CequreConfig } from "../../shared/main/runtime";
|
|
9
|
+
export declare function withNode(config: CequreConfig): CequreConfig;
|