@edge-base/server 0.2.4 → 0.2.5
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/admin-build/_app/immutable/chunks/{Dj-E9-FO.js → 6oMK_164.js} +1 -1
- package/admin-build/_app/immutable/chunks/{BME_U9TJ.js → B2TnDKF7.js} +1 -1
- package/admin-build/_app/immutable/chunks/{Dj0QUuOf.js → B6MschND.js} +1 -1
- package/admin-build/_app/immutable/chunks/{fYEKMQ-Z.js → B94PilAN.js} +1 -1
- package/admin-build/_app/immutable/chunks/{C6lpZLE2.js → BEW7Ez_g.js} +1 -1
- package/admin-build/_app/immutable/chunks/{BYI6CUvd.js → BoOooyH6.js} +1 -1
- package/admin-build/_app/immutable/chunks/{5RQRbp5q.js → BqTb6Mxk.js} +1 -1
- package/admin-build/_app/immutable/chunks/{wCNueVYy.js → BvHnF5tV.js} +1 -1
- package/admin-build/_app/immutable/chunks/{XQM1k9PM.js → CaVKAiCe.js} +1 -1
- package/admin-build/_app/immutable/chunks/{BjWZuf8W.js → Cdm5zBRA.js} +1 -1
- package/admin-build/_app/immutable/chunks/CrOZMmdF.js +1 -0
- package/admin-build/_app/immutable/chunks/Cw6OYcq-.js +1 -0
- package/admin-build/_app/immutable/chunks/{BgDzp0i0.js → D2j3I1VQ.js} +1 -1
- package/admin-build/_app/immutable/chunks/{D5GswVnI.js → DPdQ7z0T.js} +3 -3
- package/admin-build/_app/immutable/chunks/{DYaCRWMA.js → J2Gw0SMu.js} +1 -1
- package/admin-build/_app/immutable/chunks/{g_-Kpxu3.js → pUxw8jfq.js} +1 -1
- package/admin-build/_app/immutable/entry/{app.C8ylfBe6.js → app.D3flihMw.js} +2 -2
- package/admin-build/_app/immutable/entry/start.Cl6sLxnz.js +1 -0
- package/admin-build/_app/immutable/nodes/{0.CJJ6HZbp.js → 0.CdczqZLK.js} +1 -1
- package/admin-build/_app/immutable/nodes/{1.B4sI5cB4.js → 1.DxcSsEqS.js} +1 -1
- package/admin-build/_app/immutable/nodes/{10.D6hvCer6.js → 10.DuAd4aIm.js} +1 -1
- package/admin-build/_app/immutable/nodes/{11.Dx7b8aQ5.js → 11.0jgHQL92.js} +1 -1
- package/admin-build/_app/immutable/nodes/{12.Bqmy5KIF.js → 12.CKNPqmyy.js} +1 -1
- package/admin-build/_app/immutable/nodes/{13.CC6KpXgS.js → 13.B1p2POXS.js} +1 -1
- package/admin-build/_app/immutable/nodes/{14.yCo1Ix8E.js → 14.Bb-REBND.js} +1 -1
- package/admin-build/_app/immutable/nodes/{15.co0UfPlh.js → 15.1uBFCX0X.js} +1 -1
- package/admin-build/_app/immutable/nodes/{16.D0xkPUBW.js → 16.BR7WwQrS.js} +1 -1
- package/admin-build/_app/immutable/nodes/{17.CebNqPeh.js → 17.Cm57KKXV.js} +1 -1
- package/admin-build/_app/immutable/nodes/{18.JUoLOZxh.js → 18.CoiwfAuQ.js} +1 -1
- package/admin-build/_app/immutable/nodes/{19.ND8kmQJe.js → 19.B8ZdLlXj.js} +1 -1
- package/admin-build/_app/immutable/nodes/{20.DYb-q3W8.js → 20.DnHeFlTv.js} +1 -1
- package/admin-build/_app/immutable/nodes/21.CJFaf0Ia.js +1 -0
- package/admin-build/_app/immutable/nodes/{22.UOzm8WYV.js → 22.CItETFzy.js} +1 -1
- package/admin-build/_app/immutable/nodes/{23.BLgq21om.js → 23.CWSGMcKJ.js} +1 -1
- package/admin-build/_app/immutable/nodes/{24.DN9usmUs.js → 24.CWbEqNMB.js} +1 -1
- package/admin-build/_app/immutable/nodes/{25.BddRfAyE.js → 25.DRkLEhKi.js} +1 -1
- package/admin-build/_app/immutable/nodes/{26.Dl6XHIeT.js → 26.BRxO8AYH.js} +1 -1
- package/admin-build/_app/immutable/nodes/{27.D0iNwALG.js → 27.BLs-nVHz.js} +1 -1
- package/admin-build/_app/immutable/nodes/{28.9dKQmdGi.js → 28.G79qkdBK.js} +1 -1
- package/admin-build/_app/immutable/nodes/{29.wXzfJUXp.js → 29.BOcI6g0N.js} +1 -1
- package/admin-build/_app/immutable/nodes/{3.z8ut3jS-.js → 3.B6q-7qr8.js} +1 -1
- package/admin-build/_app/immutable/nodes/{30.BtZETNsL.js → 30.DAIC7dKd.js} +1 -1
- package/admin-build/_app/immutable/nodes/{31.CYonj2Jh.js → 31.pl0XXjXF.js} +1 -1
- package/admin-build/_app/immutable/nodes/{4.COtDPQ9b.js → 4.DOdvVlZj.js} +1 -1
- package/admin-build/_app/immutable/nodes/{5.CTRCeIhp.js → 5.BW_zlgye.js} +1 -1
- package/admin-build/_app/immutable/nodes/{6.ChHi3QkR.js → 6.Dxy1CAI2.js} +1 -1
- package/admin-build/_app/immutable/nodes/{7.CCMtr6Ac.js → 7.BG98w_o7.js} +1 -1
- package/admin-build/_app/immutable/nodes/{8.DpWJ-X_-.js → 8.DoG5R2rG.js} +1 -1
- package/admin-build/_app/immutable/nodes/{9.DOkvfmir.js → 9.Dmxf6zAC.js} +1 -1
- package/admin-build/_app/version.json +1 -1
- package/admin-build/index.html +7 -7
- package/package.json +3 -3
- package/src/__tests__/database-do-route-validation.test.ts +10 -7
- package/src/__tests__/meta-route-registration.test.ts +20 -15
- package/src/__tests__/room-auth-state-loss.test.ts +122 -0
- package/src/__tests__/room-handler-context.test.ts +4 -4
- package/src/__tests__/room-rate-limit-scopes.test.ts +38 -0
- package/src/__tests__/runtime-startup.test.ts +49 -0
- package/src/durable-objects/database-do.ts +14 -0
- package/src/durable-objects/database-live-do.ts +15 -0
- package/src/durable-objects/room-runtime-base.ts +387 -129
- package/src/durable-objects/rooms-do.ts +31 -24
- package/src/index.ts +326 -280
- package/src/lib/runtime-startup.ts +53 -0
- package/admin-build/_app/immutable/chunks/DBsVqhuh.js +0 -1
- package/admin-build/_app/immutable/chunks/D__dwMuW.js +0 -1
- package/admin-build/_app/immutable/entry/start.CtsqDyfj.js +0 -1
- package/admin-build/_app/immutable/nodes/21.cz3IN9Cc.js +0 -1
|
@@ -1,12 +1,11 @@
|
|
|
1
1
|
import {
|
|
2
|
-
getRoomHooks,
|
|
3
2
|
type AuthContext as SharedAuthContext,
|
|
4
3
|
type RoomMemberInfo,
|
|
4
|
+
type RoomNamespaceConfig,
|
|
5
5
|
type RoomSender,
|
|
6
6
|
type RoomServerAPI,
|
|
7
7
|
} from '@edge-base/shared';
|
|
8
8
|
import {
|
|
9
|
-
createCloudflareRealtimeClient,
|
|
10
9
|
type CloudflareRealtimeCloseTracksRequest,
|
|
11
10
|
type CloudflareRealtimeNewSessionRequest,
|
|
12
11
|
type CloudflareRealtimeNewSessionResponse,
|
|
@@ -14,7 +13,6 @@ import {
|
|
|
14
13
|
type CloudflareRealtimeTracksRequest,
|
|
15
14
|
type CloudflareRealtimeTracksResponse,
|
|
16
15
|
} from '../lib/cloudflare-realtime.js';
|
|
17
|
-
import { resolveAuthContextFromToken } from '../middleware/auth.js';
|
|
18
16
|
import type { Env } from '../types.js';
|
|
19
17
|
import { RoomRuntimeBaseDO, type RoomWSMeta } from './room-runtime-base.js';
|
|
20
18
|
|
|
@@ -117,6 +115,10 @@ const MEDIA_DENIED = Symbol('rooms.media.denied');
|
|
|
117
115
|
const WEBSOCKET_OPEN = 1;
|
|
118
116
|
const CLOUDFLARE_REALTIME_KIT_MEETING_STORAGE_KEY = 'cloudflareRealtimeKitMeetingId';
|
|
119
117
|
|
|
118
|
+
function getRoomHooks(namespaceConfig?: RoomNamespaceConfig | null) {
|
|
119
|
+
return namespaceConfig?.hooks;
|
|
120
|
+
}
|
|
121
|
+
|
|
120
122
|
function computeStateDelta(
|
|
121
123
|
previous: Record<string, unknown>,
|
|
122
124
|
next: Record<string, unknown>,
|
|
@@ -250,7 +252,7 @@ export class RoomsDO extends RoomRuntimeBaseDO {
|
|
|
250
252
|
});
|
|
251
253
|
}
|
|
252
254
|
|
|
253
|
-
const client = this.buildRealtimeClient();
|
|
255
|
+
const client = await this.buildRealtimeClient();
|
|
254
256
|
const response = await client.createSession(
|
|
255
257
|
{
|
|
256
258
|
sessionDescription: body.sessionDescription,
|
|
@@ -311,7 +313,7 @@ export class RoomsDO extends RoomRuntimeBaseDO {
|
|
|
311
313
|
try {
|
|
312
314
|
const body = await this.readJsonBody<{ ttl?: number }>(request);
|
|
313
315
|
await this.authenticateRealtimeRequest(request, url);
|
|
314
|
-
const client = this.buildRealtimeClient();
|
|
316
|
+
const client = await this.buildRealtimeClient();
|
|
315
317
|
const ttl = typeof body.ttl === 'number' && Number.isFinite(body.ttl) && body.ttl > 0
|
|
316
318
|
? Math.floor(body.ttl)
|
|
317
319
|
: 3600;
|
|
@@ -354,7 +356,8 @@ export class RoomsDO extends RoomRuntimeBaseDO {
|
|
|
354
356
|
throw new Error('tracks is required');
|
|
355
357
|
}
|
|
356
358
|
|
|
357
|
-
const
|
|
359
|
+
const client = await this.buildRealtimeClient();
|
|
360
|
+
const response = await client.addTracks(sessionId, {
|
|
358
361
|
sessionDescription: body.sessionDescription,
|
|
359
362
|
tracks: body.tracks,
|
|
360
363
|
autoDiscover: body.autoDiscover === true,
|
|
@@ -410,7 +413,8 @@ export class RoomsDO extends RoomRuntimeBaseDO {
|
|
|
410
413
|
throw new Error('sessionDescription is required');
|
|
411
414
|
}
|
|
412
415
|
|
|
413
|
-
const
|
|
416
|
+
const client = await this.buildRealtimeClient();
|
|
417
|
+
const response = await client.renegotiate(sessionId, {
|
|
414
418
|
sessionDescription: body.sessionDescription,
|
|
415
419
|
});
|
|
416
420
|
this.assertRealtimeTracksResponseSuccess(response);
|
|
@@ -447,7 +451,8 @@ export class RoomsDO extends RoomRuntimeBaseDO {
|
|
|
447
451
|
throw new Error('tracks is required');
|
|
448
452
|
}
|
|
449
453
|
|
|
450
|
-
const
|
|
454
|
+
const client = await this.buildRealtimeClient();
|
|
455
|
+
const response = await client.closeTracks(sessionId, {
|
|
451
456
|
sessionDescription: body.sessionDescription,
|
|
452
457
|
tracks: body.tracks,
|
|
453
458
|
force: body.force === true,
|
|
@@ -472,7 +477,8 @@ export class RoomsDO extends RoomRuntimeBaseDO {
|
|
|
472
477
|
}
|
|
473
478
|
}
|
|
474
479
|
|
|
475
|
-
private buildRealtimeClient() {
|
|
480
|
+
private async buildRealtimeClient() {
|
|
481
|
+
const { createCloudflareRealtimeClient } = await import('../lib/cloudflare-realtime.js');
|
|
476
482
|
return createCloudflareRealtimeClient(this.env as unknown as Env);
|
|
477
483
|
}
|
|
478
484
|
|
|
@@ -636,6 +642,7 @@ export class RoomsDO extends RoomRuntimeBaseDO {
|
|
|
636
642
|
throw new Error('Authentication required');
|
|
637
643
|
}
|
|
638
644
|
|
|
645
|
+
const { resolveAuthContextFromToken } = await import('../middleware/auth.js');
|
|
639
646
|
const auth = await resolveAuthContextFromToken(this.env, token, request);
|
|
640
647
|
const memberId = auth.id;
|
|
641
648
|
const member = this.members.get(memberId);
|
|
@@ -758,7 +765,7 @@ export class RoomsDO extends RoomRuntimeBaseDO {
|
|
|
758
765
|
|
|
759
766
|
const event = typeof msg.event === 'string' ? msg.event : '';
|
|
760
767
|
const requestId = typeof msg.requestId === 'string' ? msg.requestId : undefined;
|
|
761
|
-
if (!this.checkRateLimit(meta.connectionId)) {
|
|
768
|
+
if (!this.checkRateLimit(meta.connectionId, 'signals')) {
|
|
762
769
|
this.safeSend(ws, {
|
|
763
770
|
type: 'signal_error',
|
|
764
771
|
event,
|
|
@@ -806,7 +813,7 @@ export class RoomsDO extends RoomRuntimeBaseDO {
|
|
|
806
813
|
|
|
807
814
|
const operation = typeof msg.operation === 'string' ? msg.operation : '';
|
|
808
815
|
const requestId = typeof msg.requestId === 'string' ? msg.requestId : undefined;
|
|
809
|
-
if (!this.checkRateLimit(meta.connectionId)) {
|
|
816
|
+
if (!this.checkRateLimit(meta.connectionId, 'admin')) {
|
|
810
817
|
this.safeSend(ws, {
|
|
811
818
|
type: 'admin_error',
|
|
812
819
|
operation,
|
|
@@ -833,7 +840,7 @@ export class RoomsDO extends RoomRuntimeBaseDO {
|
|
|
833
840
|
const operation = this.normalizeMediaOperation(msg.operation);
|
|
834
841
|
const kind = this.normalizeMediaKind(msg.kind);
|
|
835
842
|
const requestId = typeof msg.requestId === 'string' ? msg.requestId : undefined;
|
|
836
|
-
if (!this.checkRateLimit(meta.connectionId)) {
|
|
843
|
+
if (!this.checkRateLimit(meta.connectionId, 'media')) {
|
|
837
844
|
this.safeSend(ws, {
|
|
838
845
|
type: 'media_error',
|
|
839
846
|
operation: operation ?? '',
|
|
@@ -1450,7 +1457,7 @@ export class RoomsDO extends RoomRuntimeBaseDO {
|
|
|
1450
1457
|
const beforeSend = getRoomHooks(this.namespaceConfig ?? undefined)?.signals?.beforeSend;
|
|
1451
1458
|
if (!beforeSend) return signal.payload;
|
|
1452
1459
|
|
|
1453
|
-
const ctx = this.buildHandlerContext();
|
|
1460
|
+
const ctx = await this.buildHandlerContext();
|
|
1454
1461
|
const result = await Promise.resolve(
|
|
1455
1462
|
beforeSend(signal.event, signal.payload, signal.sender, signal.roomApi, ctx),
|
|
1456
1463
|
);
|
|
@@ -1468,7 +1475,7 @@ export class RoomsDO extends RoomRuntimeBaseDO {
|
|
|
1468
1475
|
if (!onSend) return;
|
|
1469
1476
|
|
|
1470
1477
|
try {
|
|
1471
|
-
const ctx = this.buildHandlerContext();
|
|
1478
|
+
const ctx = await this.buildHandlerContext();
|
|
1472
1479
|
await Promise.resolve(onSend(event, payload, sender, roomApi, ctx));
|
|
1473
1480
|
} catch (err) {
|
|
1474
1481
|
console.error(`[Rooms] signal.onSend error: ${err instanceof Error ? err.message : String(err)}`);
|
|
@@ -1481,7 +1488,7 @@ export class RoomsDO extends RoomRuntimeBaseDO {
|
|
|
1481
1488
|
|
|
1482
1489
|
try {
|
|
1483
1490
|
const roomApi = this.buildRoomServerAPI();
|
|
1484
|
-
const ctx = this.buildHandlerContext();
|
|
1491
|
+
const ctx = await this.buildHandlerContext();
|
|
1485
1492
|
await Promise.resolve(onJoin(member, roomApi, ctx));
|
|
1486
1493
|
} catch (err) {
|
|
1487
1494
|
console.error(`[Rooms] members.onJoin error: ${err instanceof Error ? err.message : String(err)}`);
|
|
@@ -1497,7 +1504,7 @@ export class RoomsDO extends RoomRuntimeBaseDO {
|
|
|
1497
1504
|
|
|
1498
1505
|
try {
|
|
1499
1506
|
const roomApi = this.buildRoomServerAPI();
|
|
1500
|
-
const ctx = this.buildHandlerContext();
|
|
1507
|
+
const ctx = await this.buildHandlerContext();
|
|
1501
1508
|
await Promise.resolve(onLeave(member, roomApi, ctx, reason));
|
|
1502
1509
|
} catch (err) {
|
|
1503
1510
|
console.error(`[Rooms] members.onLeave error: ${err instanceof Error ? err.message : String(err)}`);
|
|
@@ -1513,7 +1520,7 @@ export class RoomsDO extends RoomRuntimeBaseDO {
|
|
|
1513
1520
|
|
|
1514
1521
|
try {
|
|
1515
1522
|
const roomApi = this.buildRoomServerAPI();
|
|
1516
|
-
const ctx = this.buildHandlerContext();
|
|
1523
|
+
const ctx = await this.buildHandlerContext();
|
|
1517
1524
|
await Promise.resolve(onStateChange(member, state, roomApi, ctx));
|
|
1518
1525
|
} catch (err) {
|
|
1519
1526
|
console.error(`[Rooms] members.onStateChange error: ${err instanceof Error ? err.message : String(err)}`);
|
|
@@ -1528,7 +1535,7 @@ export class RoomsDO extends RoomRuntimeBaseDO {
|
|
|
1528
1535
|
if (!onStateChange) return;
|
|
1529
1536
|
|
|
1530
1537
|
try {
|
|
1531
|
-
const ctx = this.buildHandlerContext();
|
|
1538
|
+
const ctx = await this.buildHandlerContext();
|
|
1532
1539
|
await Promise.resolve(onStateChange(delta, roomApi, ctx));
|
|
1533
1540
|
} catch (err) {
|
|
1534
1541
|
console.error(`[Rooms] state.onStateChange error: ${err instanceof Error ? err.message : String(err)}`);
|
|
@@ -1541,7 +1548,7 @@ export class RoomsDO extends RoomRuntimeBaseDO {
|
|
|
1541
1548
|
|
|
1542
1549
|
try {
|
|
1543
1550
|
const roomApi = this.buildRoomServerAPI();
|
|
1544
|
-
const ctx = this.buildHandlerContext();
|
|
1551
|
+
const ctx = await this.buildHandlerContext();
|
|
1545
1552
|
await Promise.resolve(onReconnect(sender, roomApi, ctx));
|
|
1546
1553
|
} catch (err) {
|
|
1547
1554
|
console.error(`[Rooms] session.onReconnect error: ${err instanceof Error ? err.message : String(err)}`);
|
|
@@ -1554,7 +1561,7 @@ export class RoomsDO extends RoomRuntimeBaseDO {
|
|
|
1554
1561
|
|
|
1555
1562
|
try {
|
|
1556
1563
|
const roomApi = this.buildRoomServerAPI();
|
|
1557
|
-
const ctx = this.buildHandlerContext();
|
|
1564
|
+
const ctx = await this.buildHandlerContext();
|
|
1558
1565
|
await Promise.resolve(onDisconnectTimeout(sender, roomApi, ctx));
|
|
1559
1566
|
} catch (err) {
|
|
1560
1567
|
console.error(`[Rooms] session.onDisconnectTimeout error: ${err instanceof Error ? err.message : String(err)}`);
|
|
@@ -1919,7 +1926,7 @@ export class RoomsDO extends RoomRuntimeBaseDO {
|
|
|
1919
1926
|
return undefined;
|
|
1920
1927
|
}
|
|
1921
1928
|
|
|
1922
|
-
const ctx = this.buildHandlerContext();
|
|
1929
|
+
const ctx = await this.buildHandlerContext();
|
|
1923
1930
|
const result = await Promise.resolve(beforePublish(kind, sender, roomApi, ctx));
|
|
1924
1931
|
if (result === false) {
|
|
1925
1932
|
return MEDIA_DENIED;
|
|
@@ -1936,7 +1943,7 @@ export class RoomsDO extends RoomRuntimeBaseDO {
|
|
|
1936
1943
|
if (!onPublished) return;
|
|
1937
1944
|
|
|
1938
1945
|
try {
|
|
1939
|
-
const ctx = this.buildHandlerContext();
|
|
1946
|
+
const ctx = await this.buildHandlerContext();
|
|
1940
1947
|
await Promise.resolve(onPublished(kind, sender, roomApi, ctx));
|
|
1941
1948
|
} catch (err) {
|
|
1942
1949
|
console.error(`[Rooms] media.onPublished error: ${err instanceof Error ? err.message : String(err)}`);
|
|
@@ -1952,7 +1959,7 @@ export class RoomsDO extends RoomRuntimeBaseDO {
|
|
|
1952
1959
|
if (!onUnpublished) return;
|
|
1953
1960
|
|
|
1954
1961
|
try {
|
|
1955
|
-
const ctx = this.buildHandlerContext();
|
|
1962
|
+
const ctx = await this.buildHandlerContext();
|
|
1956
1963
|
await Promise.resolve(onUnpublished(kind, sender, roomApi, ctx));
|
|
1957
1964
|
} catch (err) {
|
|
1958
1965
|
console.error(`[Rooms] media.onUnpublished error: ${err instanceof Error ? err.message : String(err)}`);
|
|
@@ -1969,7 +1976,7 @@ export class RoomsDO extends RoomRuntimeBaseDO {
|
|
|
1969
1976
|
if (!onMuteChange) return;
|
|
1970
1977
|
|
|
1971
1978
|
try {
|
|
1972
|
-
const ctx = this.buildHandlerContext();
|
|
1979
|
+
const ctx = await this.buildHandlerContext();
|
|
1973
1980
|
await Promise.resolve(onMuteChange(kind, sender, muted, roomApi, ctx));
|
|
1974
1981
|
} catch (err) {
|
|
1975
1982
|
console.error(`[Rooms] media.onMuteChange error: ${err instanceof Error ? err.message : String(err)}`);
|