@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.
Files changed (68) hide show
  1. package/admin-build/_app/immutable/chunks/{Dj-E9-FO.js → 6oMK_164.js} +1 -1
  2. package/admin-build/_app/immutable/chunks/{BME_U9TJ.js → B2TnDKF7.js} +1 -1
  3. package/admin-build/_app/immutable/chunks/{Dj0QUuOf.js → B6MschND.js} +1 -1
  4. package/admin-build/_app/immutable/chunks/{fYEKMQ-Z.js → B94PilAN.js} +1 -1
  5. package/admin-build/_app/immutable/chunks/{C6lpZLE2.js → BEW7Ez_g.js} +1 -1
  6. package/admin-build/_app/immutable/chunks/{BYI6CUvd.js → BoOooyH6.js} +1 -1
  7. package/admin-build/_app/immutable/chunks/{5RQRbp5q.js → BqTb6Mxk.js} +1 -1
  8. package/admin-build/_app/immutable/chunks/{wCNueVYy.js → BvHnF5tV.js} +1 -1
  9. package/admin-build/_app/immutable/chunks/{XQM1k9PM.js → CaVKAiCe.js} +1 -1
  10. package/admin-build/_app/immutable/chunks/{BjWZuf8W.js → Cdm5zBRA.js} +1 -1
  11. package/admin-build/_app/immutable/chunks/CrOZMmdF.js +1 -0
  12. package/admin-build/_app/immutable/chunks/Cw6OYcq-.js +1 -0
  13. package/admin-build/_app/immutable/chunks/{BgDzp0i0.js → D2j3I1VQ.js} +1 -1
  14. package/admin-build/_app/immutable/chunks/{D5GswVnI.js → DPdQ7z0T.js} +3 -3
  15. package/admin-build/_app/immutable/chunks/{DYaCRWMA.js → J2Gw0SMu.js} +1 -1
  16. package/admin-build/_app/immutable/chunks/{g_-Kpxu3.js → pUxw8jfq.js} +1 -1
  17. package/admin-build/_app/immutable/entry/{app.C8ylfBe6.js → app.D3flihMw.js} +2 -2
  18. package/admin-build/_app/immutable/entry/start.Cl6sLxnz.js +1 -0
  19. package/admin-build/_app/immutable/nodes/{0.CJJ6HZbp.js → 0.CdczqZLK.js} +1 -1
  20. package/admin-build/_app/immutable/nodes/{1.B4sI5cB4.js → 1.DxcSsEqS.js} +1 -1
  21. package/admin-build/_app/immutable/nodes/{10.D6hvCer6.js → 10.DuAd4aIm.js} +1 -1
  22. package/admin-build/_app/immutable/nodes/{11.Dx7b8aQ5.js → 11.0jgHQL92.js} +1 -1
  23. package/admin-build/_app/immutable/nodes/{12.Bqmy5KIF.js → 12.CKNPqmyy.js} +1 -1
  24. package/admin-build/_app/immutable/nodes/{13.CC6KpXgS.js → 13.B1p2POXS.js} +1 -1
  25. package/admin-build/_app/immutable/nodes/{14.yCo1Ix8E.js → 14.Bb-REBND.js} +1 -1
  26. package/admin-build/_app/immutable/nodes/{15.co0UfPlh.js → 15.1uBFCX0X.js} +1 -1
  27. package/admin-build/_app/immutable/nodes/{16.D0xkPUBW.js → 16.BR7WwQrS.js} +1 -1
  28. package/admin-build/_app/immutable/nodes/{17.CebNqPeh.js → 17.Cm57KKXV.js} +1 -1
  29. package/admin-build/_app/immutable/nodes/{18.JUoLOZxh.js → 18.CoiwfAuQ.js} +1 -1
  30. package/admin-build/_app/immutable/nodes/{19.ND8kmQJe.js → 19.B8ZdLlXj.js} +1 -1
  31. package/admin-build/_app/immutable/nodes/{20.DYb-q3W8.js → 20.DnHeFlTv.js} +1 -1
  32. package/admin-build/_app/immutable/nodes/21.CJFaf0Ia.js +1 -0
  33. package/admin-build/_app/immutable/nodes/{22.UOzm8WYV.js → 22.CItETFzy.js} +1 -1
  34. package/admin-build/_app/immutable/nodes/{23.BLgq21om.js → 23.CWSGMcKJ.js} +1 -1
  35. package/admin-build/_app/immutable/nodes/{24.DN9usmUs.js → 24.CWbEqNMB.js} +1 -1
  36. package/admin-build/_app/immutable/nodes/{25.BddRfAyE.js → 25.DRkLEhKi.js} +1 -1
  37. package/admin-build/_app/immutable/nodes/{26.Dl6XHIeT.js → 26.BRxO8AYH.js} +1 -1
  38. package/admin-build/_app/immutable/nodes/{27.D0iNwALG.js → 27.BLs-nVHz.js} +1 -1
  39. package/admin-build/_app/immutable/nodes/{28.9dKQmdGi.js → 28.G79qkdBK.js} +1 -1
  40. package/admin-build/_app/immutable/nodes/{29.wXzfJUXp.js → 29.BOcI6g0N.js} +1 -1
  41. package/admin-build/_app/immutable/nodes/{3.z8ut3jS-.js → 3.B6q-7qr8.js} +1 -1
  42. package/admin-build/_app/immutable/nodes/{30.BtZETNsL.js → 30.DAIC7dKd.js} +1 -1
  43. package/admin-build/_app/immutable/nodes/{31.CYonj2Jh.js → 31.pl0XXjXF.js} +1 -1
  44. package/admin-build/_app/immutable/nodes/{4.COtDPQ9b.js → 4.DOdvVlZj.js} +1 -1
  45. package/admin-build/_app/immutable/nodes/{5.CTRCeIhp.js → 5.BW_zlgye.js} +1 -1
  46. package/admin-build/_app/immutable/nodes/{6.ChHi3QkR.js → 6.Dxy1CAI2.js} +1 -1
  47. package/admin-build/_app/immutable/nodes/{7.CCMtr6Ac.js → 7.BG98w_o7.js} +1 -1
  48. package/admin-build/_app/immutable/nodes/{8.DpWJ-X_-.js → 8.DoG5R2rG.js} +1 -1
  49. package/admin-build/_app/immutable/nodes/{9.DOkvfmir.js → 9.Dmxf6zAC.js} +1 -1
  50. package/admin-build/_app/version.json +1 -1
  51. package/admin-build/index.html +7 -7
  52. package/package.json +3 -3
  53. package/src/__tests__/database-do-route-validation.test.ts +10 -7
  54. package/src/__tests__/meta-route-registration.test.ts +20 -15
  55. package/src/__tests__/room-auth-state-loss.test.ts +122 -0
  56. package/src/__tests__/room-handler-context.test.ts +4 -4
  57. package/src/__tests__/room-rate-limit-scopes.test.ts +38 -0
  58. package/src/__tests__/runtime-startup.test.ts +49 -0
  59. package/src/durable-objects/database-do.ts +14 -0
  60. package/src/durable-objects/database-live-do.ts +15 -0
  61. package/src/durable-objects/room-runtime-base.ts +387 -129
  62. package/src/durable-objects/rooms-do.ts +31 -24
  63. package/src/index.ts +326 -280
  64. package/src/lib/runtime-startup.ts +53 -0
  65. package/admin-build/_app/immutable/chunks/DBsVqhuh.js +0 -1
  66. package/admin-build/_app/immutable/chunks/D__dwMuW.js +0 -1
  67. package/admin-build/_app/immutable/entry/start.CtsqDyfj.js +0 -1
  68. 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 response = await this.buildRealtimeClient().addTracks(sessionId, {
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 response = await this.buildRealtimeClient().renegotiate(sessionId, {
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 response = await this.buildRealtimeClient().closeTracks(sessionId, {
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)}`);