@signe/room 1.4.1 → 2.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/dist/index.d.ts CHANGED
@@ -1,19 +1,20 @@
1
- import { Request as Request$1, DurableObjectStorage, WebSocket, DurableObjectState, AnalyticsEngineDataset, VectorizeIndex, R2Bucket, KVNamespace } from '@cloudflare/workers-types';
1
+ import { Request as Request$2, DurableObjectStorage, WebSocket, DurableObjectState, AnalyticsEngineDataset, VectorizeIndex, R2Bucket, KVNamespace } from '@cloudflare/workers-types';
2
2
  import { z } from 'zod';
3
+ import * as _signe_reactive from '@signe/reactive';
3
4
 
4
5
  type AssetFetcher = {
5
6
  fetch(path: string): Promise<Response | null>;
6
7
  };
7
8
  type StandardRequest = globalThis.Request;
8
- interface Request extends Request$1 {
9
+ interface Request$1 extends Request$2 {
9
10
  }
10
- type ReturnRequest = StandardRequest | Request$1;
11
+ type ReturnRequest = StandardRequest | Request$2;
11
12
  /** Per-party key-value storage */
12
13
  interface Storage$1 extends DurableObjectStorage {
13
14
  }
14
15
  /** Connection metadata only available when the connection is made */
15
16
  type ConnectionContext = {
16
- request: Request$1;
17
+ request: Request$2;
17
18
  };
18
19
  type Stub = {
19
20
  /** @deprecated Use `await socket()` instead */
@@ -151,7 +152,7 @@ type Server$1 = {
151
152
  /**
152
153
  * Called when a HTTP request is made to the room URL.
153
154
  */
154
- onRequest?(req: Request): Response | Promise<Response>;
155
+ onRequest?(req: Request$1): Response | Promise<Response>;
155
156
  /**
156
157
  * Called when an alarm is triggered. Use Party.storage.setAlarm to set an alarm.
157
158
  *
@@ -171,9 +172,19 @@ type ServerOptions = {
171
172
  hibernate?: boolean;
172
173
  };
173
174
 
174
- type GuardFn = (sender: Connection, value: any) => boolean | Promise<boolean>;
175
- type RoomGuardFn = (conn: Connection, ctx: ConnectionContext) => boolean | Promise<boolean>;
175
+ type GuardFn = (sender: Connection, value: any | Request$1, room: Room$1) => boolean | Promise<boolean | Response>;
176
+ type RoomGuardFn = (conn: Connection, ctx: ConnectionContext, room: Room$1) => boolean | Promise<boolean | Response>;
176
177
  declare function Action(name: string, bodyValidation?: z.ZodSchema): (target: any, propertyKey: string) => void;
178
+ /**
179
+ * Request decorator for handling HTTP requests with path and method routing
180
+ * @param options Configuration for the HTTP request handler
181
+ * @param bodyValidation Optional Zod schema for request body validation
182
+ */
183
+ interface RequestOptions {
184
+ path: string;
185
+ method?: 'GET' | 'POST' | 'PUT' | 'DELETE' | 'PATCH' | 'OPTIONS' | 'HEAD';
186
+ }
187
+ declare function Request(options: RequestOptions, bodyValidation?: z.ZodSchema): (target: any, propertyKey: string) => void;
177
188
  interface RoomOptions {
178
189
  path: string;
179
190
  maxUsers?: number;
@@ -244,6 +255,8 @@ declare class Server implements Server$1 {
244
255
  */
245
256
  get isHibernate(): boolean;
246
257
  get roomStorage(): Storage$1;
258
+ send(conn: Connection, obj: any, subRoom: any): Promise<void>;
259
+ broadcast(obj: any, subRoom: any): void;
247
260
  /**
248
261
  * @method onStart
249
262
  * @async
@@ -315,6 +328,7 @@ declare class Server implements Server$1 {
315
328
  private saveSession;
316
329
  private updateSessionConnection;
317
330
  private deleteSession;
331
+ onConnectClient(conn: Connection, ctx: ConnectionContext): Promise<void>;
318
332
  /**
319
333
  * @method onConnect
320
334
  * @async
@@ -332,23 +346,64 @@ declare class Server implements Server$1 {
332
346
  * ```
333
347
  */
334
348
  onConnect(conn: Connection, ctx: ConnectionContext): Promise<void>;
349
+ /**
350
+ * @method onConnectShard
351
+ * @private
352
+ * @param {Party.Connection} conn - The connection object for the new shard.
353
+ * @param {Party.ConnectionContext} ctx - The context of the shard connection.
354
+ * @description Handles a new shard connection, setting up the necessary state.
355
+ * @returns {void}
356
+ */
357
+ onConnectShard(conn: Connection, ctx: ConnectionContext): void;
335
358
  /**
336
359
  * @method onMessage
337
360
  * @async
338
- * @param {string} message - The message received from a user.
361
+ * @param {string} message - The message received from a user or shard.
339
362
  * @param {Party.Connection} sender - The connection object of the sender.
340
- * @description Processes incoming messages and triggers corresponding actions in the sub-room.
363
+ * @description Processes incoming messages, handling differently based on if sender is shard or client.
341
364
  * @returns {Promise<void>}
342
- *
343
- * @example
344
- * ```typescript
345
- * server.onMessage = async (message, sender) => {
346
- * await server.onMessage(message, sender);
347
- * console.log("Message processed from:", sender.id);
348
- * };
349
- * ```
350
365
  */
351
366
  onMessage(message: string, sender: Connection): Promise<void>;
367
+ /**
368
+ * @method handleShardMessage
369
+ * @private
370
+ * @async
371
+ * @param {string} message - The message received from a shard.
372
+ * @param {Party.Connection} shardConnection - The connection object of the shard.
373
+ * @description Processes messages from shards, extracting client information.
374
+ * @returns {Promise<void>}
375
+ */
376
+ private handleShardMessage;
377
+ /**
378
+ * @method handleShardClientConnect
379
+ * @private
380
+ * @async
381
+ * @param {Object} message - The client connection message from a shard.
382
+ * @param {Party.Connection} shardConnection - The connection object of the shard.
383
+ * @description Handles a new client connection via a shard.
384
+ * @returns {Promise<void>}
385
+ */
386
+ private handleShardClientConnect;
387
+ /**
388
+ * @method handleShardClientMessage
389
+ * @private
390
+ * @async
391
+ * @param {Object} message - The client message from a shard.
392
+ * @param {Party.Connection} shardConnection - The connection object of the shard.
393
+ * @description Handles a message from a client via a shard.
394
+ * @returns {Promise<void>}
395
+ */
396
+ private handleShardClientMessage;
397
+ /**
398
+ * @method handleShardClientDisconnect
399
+ * @private
400
+ * @async
401
+ * @param {Object} message - The client disconnection message from a shard.
402
+ * @param {Party.Connection} shardConnection - The connection object of the shard.
403
+ * @description Handles a client disconnection via a shard.
404
+ * @returns {Promise<void>}
405
+ */
406
+ private handleShardClientDisconnect;
352
407
  /**
353
408
  * @method onClose
354
409
  * @async
@@ -367,7 +422,70 @@ declare class Server implements Server$1 {
367
422
  onClose(conn: Connection): Promise<void>;
368
423
  onAlarm(): Promise<void>;
369
424
  onError(connection: Connection, error: Error): Promise<void>;
370
- onRequest(req: Request): Promise<Response>;
425
+ /**
426
+ * @method onRequest
427
+ * @async
428
+ * @param {Party.Request} req - The HTTP request to handle
429
+ * @description Handles HTTP requests, either directly from clients or forwarded by shards
430
+ * @returns {Promise<Response>} The response to return to the client
431
+ */
432
+ onRequest(req: Request$1): Promise<Response>;
433
+ /**
434
+ * @method handleDirectRequest
435
+ * @private
436
+ * @async
437
+ * @param {Party.Request} req - The HTTP request received directly from a client
438
+ * @description Processes requests received directly from clients
439
+ * @returns {Promise<Response>} The response to return to the client
440
+ */
441
+ private handleDirectRequest;
442
+ /**
443
+ * @method tryMatchRequestHandler
444
+ * @private
445
+ * @async
446
+ * @param {Party.Request} req - The HTTP request to handle
447
+ * @param {Object} subRoom - The room instance
448
+ * @description Attempts to match the request to a registered @Request handler
449
+ * @returns {Promise<Response | null>} The response or null if no handler matched
450
+ */
451
+ private tryMatchRequestHandler;
452
+ /**
453
+ * @method pathMatches
454
+ * @private
455
+ * @param {string} requestPath - The path from the request
456
+ * @param {string} handlerPath - The path pattern from the handler
457
+ * @description Checks if a request path matches a handler path pattern
458
+ * @returns {boolean} True if the paths match
459
+ */
460
+ private pathMatches;
461
+ /**
462
+ * @method extractPathParams
463
+ * @private
464
+ * @param {string} requestPath - The path from the request
465
+ * @param {string} handlerPath - The path pattern from the handler
466
+ * @description Extracts path parameters from the request path based on the handler pattern
467
+ * @returns {Object} An object containing the path parameters
468
+ */
469
+ private extractPathParams;
470
+ /**
471
+ * @method handleShardRequest
472
+ * @private
473
+ * @async
474
+ * @param {Party.Request} req - The HTTP request forwarded by a shard
475
+ * @param {string | null} shardId - The ID of the shard that forwarded the request
476
+ * @description Processes requests forwarded by shards, preserving client context
477
+ * @returns {Promise<Response>} The response to return to the shard (which will forward it to the client)
478
+ */
479
+ private handleShardRequest;
480
+ /**
481
+ * @method createEnhancedRequest
482
+ * @private
483
+ * @param {Party.Request} originalReq - The original request received from the shard
484
+ * @param {string | null} originalClientIp - The original client IP, if available
485
+ * @description Creates an enhanced request object that preserves the original client context
486
+ * @returns {Party.Request} The enhanced request object
487
+ */
488
+ private createEnhancedRequest;
371
489
  }
372
490
 
373
491
  declare class Storage {
@@ -389,16 +507,24 @@ declare class MockPartyClient {
389
507
  _trigger(event: any, data: any): void;
390
508
  send(data: any): Promise<void>;
391
509
  }
510
+ declare class MockContext {
511
+ room: MockPartyRoom;
512
+ parties: {
513
+ main: Map<string, any>;
514
+ };
515
+ constructor(room: MockPartyRoom, options?: any);
516
+ }
392
517
  declare class MockPartyRoom {
393
518
  id?: string;
394
519
  clients: Map<string, MockPartyClient>;
395
520
  storage: Storage;
521
+ context: MockContext;
396
522
  env: {};
397
- constructor(id?: string);
523
+ constructor(id?: string, options?: any);
398
524
  connection(server: Server): Promise<MockPartyClient>;
399
525
  broadcast(data: any): void;
400
526
  getConnection(id: string): MockPartyClient;
401
- getConnections(): Map<string, MockPartyClient>;
527
+ getConnections(): MockConnection[];
402
528
  clear(): void;
403
529
  }
404
530
  declare class MockConnection {
@@ -414,6 +540,50 @@ declare class MockConnection {
414
540
  declare const ServerIo: typeof MockPartyRoom;
415
541
  declare const ClientIo: typeof MockPartyClient;
416
542
 
543
+ interface PartyWebSocket {
544
+ send: (data: string | ArrayBufferLike | Blob | ArrayBufferView) => void;
545
+ addEventListener: (type: string, listener: (event: any) => void) => void;
546
+ close: () => void;
547
+ }
548
+ interface ShardOptions {
549
+ worldUrl?: string;
550
+ worldId?: string;
551
+ statsInterval?: number;
552
+ }
553
+ declare class Shard {
554
+ private room;
555
+ ws: PartyWebSocket;
556
+ connectionMap: Map<string, Connection<unknown>>;
557
+ mainServerStub: any;
558
+ worldUrl: string | null;
559
+ worldId: string;
560
+ lastReportedConnections: number;
561
+ statsInterval: number;
562
+ statsIntervalId: any;
563
+ constructor(room: Room$1);
564
+ onStart(): Promise<void>;
565
+ private startPeriodicStatsUpdates;
566
+ private stopPeriodicStatsUpdates;
567
+ onConnect(conn: Connection, ctx: ConnectionContext): void;
568
+ onMessage(message: string | ArrayBuffer | ArrayBufferView, sender: Connection): void;
569
+ onClose(conn: Connection): void;
570
+ updateWorldStats(): Promise<boolean>;
571
+ /**
572
+ * @method onRequest
573
+ * @async
574
+ * @param {Party.Request} req - The HTTP request to handle
575
+ * @description Forwards HTTP requests to the main server, preserving client context
576
+ * @returns {Promise<Response>} The response from the main server
577
+ */
578
+ onRequest(req: Request$1): Promise<Response>;
579
+ /**
580
+ * @method onAlarm
581
+ * @async
582
+ * @description Executed periodically, used to perform maintenance tasks
583
+ */
584
+ onAlarm(): Promise<void>;
585
+ }
586
+
417
587
  /**
418
588
  * @description Test the room with a mock server and client
419
589
  * @param Room - The room class to test
@@ -441,10 +611,76 @@ declare const ClientIo: typeof MockPartyClient;
441
611
  */
442
612
  declare function testRoom(Room: any, options?: {
443
613
  hibernate?: boolean;
614
+ shard?: boolean;
615
+ env?: Record<string, string>;
444
616
  }): Promise<{
445
- server: Server;
617
+ server: Server | Shard;
446
618
  room: any;
447
619
  createClient: () => Promise<MockPartyClient>;
448
620
  }>;
621
+ declare function request(room: Server, path: string, options?: {
622
+ method: 'GET' | 'POST' | 'PUT' | 'DELETE';
623
+ body?: any;
624
+ headers?: Record<string, string>;
625
+ }): Promise<Response>;
626
+
627
+ interface RoomInterceptorPacket {
628
+ interceptorPacket(user: any, obj: any, conn: Connection): Promise<any> | null | any;
629
+ }
630
+ interface RoomOnJoin {
631
+ onJoin(user: any, conn: Connection, ctx: ConnectionContext): Promise<any> | null | any;
632
+ }
633
+ interface RoomOnLeave {
634
+ onLeave(user: any, conn: Connection, ctx: ConnectionContext): Promise<any> | null | any;
635
+ }
636
+
637
+ type BalancingStrategy = 'round-robin' | 'least-connections' | 'random';
638
+ type ShardStatus = 'active' | 'maintenance' | 'draining';
639
+ declare class RoomConfig {
640
+ id: string;
641
+ name: _signe_reactive.WritableSignal<string>;
642
+ balancingStrategy: _signe_reactive.WritableSignal<BalancingStrategy>;
643
+ public: _signe_reactive.WritableSignal<boolean>;
644
+ maxPlayersPerShard: _signe_reactive.WritableSignal<number>;
645
+ minShards: _signe_reactive.WritableSignal<number>;
646
+ maxShards: _signe_reactive.WritableSignal<number>;
647
+ }
648
+ declare class ShardInfo {
649
+ id: string;
650
+ roomId: _signe_reactive.WritableSignal<string>;
651
+ url: _signe_reactive.WritableSignal<string>;
652
+ currentConnections: _signe_reactive.WritableSignal<number>;
653
+ maxConnections: _signe_reactive.WritableSignal<number>;
654
+ status: _signe_reactive.WritableSignal<ShardStatus>;
655
+ lastHeartbeat: _signe_reactive.WritableSignal<number>;
656
+ }
657
+ declare class WorldRoom implements RoomInterceptorPacket, RoomOnJoin {
658
+ private room;
659
+ rooms: _signe_reactive.WritableObjectSignal<Record<string, RoomConfig>>;
660
+ shards: _signe_reactive.WritableObjectSignal<Record<string, ShardInfo>>;
661
+ rrCounters: _signe_reactive.WritableObjectSignal<Record<string, number>>;
662
+ defaultShardUrlTemplate: _signe_reactive.WritableSignal<string>;
663
+ defaultMaxConnectionsPerShard: _signe_reactive.WritableSignal<number>;
664
+ constructor(room: Room$1);
665
+ onJoin(user: any, conn: Connection, ctx: ConnectionContext): Promise<void>;
666
+ interceptorPacket(_: any, obj: any, conn: Connection): any;
667
+ private cleanupInactiveShards;
668
+ registerRoom(req: Request$1): Promise<void>;
669
+ updateShardStats(req: Request$1): Promise<{
670
+ error: string;
671
+ }>;
672
+ scaleRoom(req: Request$1): Promise<{
673
+ error: string;
674
+ roomId?: undefined;
675
+ currentShardCount?: undefined;
676
+ } | {
677
+ error: string;
678
+ roomId: string;
679
+ currentShardCount: number;
680
+ }>;
681
+ connect(req: Request$1): Promise<Response>;
682
+ private findOptimalShard;
683
+ private createShard;
684
+ }
449
685
 
450
- export { Action, ClientIo, Guard, MockConnection, Room, RoomGuard, type RoomOptions, Server, ServerIo, testRoom };
686
+ export { Action, ClientIo, Guard, MockConnection, Request, type RequestOptions, Room, RoomGuard, type RoomInterceptorPacket, type RoomOnJoin, type RoomOnLeave, type RoomOptions, Server, ServerIo, Shard, type ShardOptions, WorldRoom, request, testRoom };