@signe/room 2.10.0 → 3.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.
Files changed (82) hide show
  1. package/CHANGELOG.md +7 -0
  2. package/dist/chunk-EUXUH3YW.js +15 -0
  3. package/dist/chunk-EUXUH3YW.js.map +1 -0
  4. package/dist/cloudflare/index.d.ts +71 -0
  5. package/dist/cloudflare/index.js +320 -0
  6. package/dist/cloudflare/index.js.map +1 -0
  7. package/dist/index.d.ts +66 -187
  8. package/dist/index.js +727 -106
  9. package/dist/index.js.map +1 -1
  10. package/dist/node/index.d.ts +164 -0
  11. package/dist/node/index.js +786 -0
  12. package/dist/node/index.js.map +1 -0
  13. package/dist/party-dNs-hqkq.d.ts +175 -0
  14. package/examples/cloudflare/README.md +62 -0
  15. package/examples/cloudflare/node_modules/.bin/tsc +17 -0
  16. package/examples/cloudflare/node_modules/.bin/tsserver +17 -0
  17. package/examples/cloudflare/node_modules/.bin/wrangler +17 -0
  18. package/examples/cloudflare/node_modules/.bin/wrangler2 +17 -0
  19. package/examples/cloudflare/package.json +24 -0
  20. package/examples/cloudflare/public/index.html +443 -0
  21. package/examples/cloudflare/src/index.ts +28 -0
  22. package/examples/cloudflare/src/room.ts +44 -0
  23. package/examples/cloudflare/tsconfig.json +10 -0
  24. package/examples/cloudflare/wrangler.jsonc +25 -0
  25. package/examples/node/README.md +57 -0
  26. package/examples/node/node_modules/.bin/tsc +17 -0
  27. package/examples/node/node_modules/.bin/tsserver +17 -0
  28. package/examples/node/node_modules/.bin/tsx +17 -0
  29. package/examples/node/package.json +23 -0
  30. package/examples/node/public/index.html +443 -0
  31. package/examples/node/room.ts +44 -0
  32. package/examples/node/server.sqlite.ts +52 -0
  33. package/examples/node/server.ts +51 -0
  34. package/examples/node/tsconfig.json +10 -0
  35. package/examples/node-game/README.md +66 -0
  36. package/examples/node-game/package.json +23 -0
  37. package/examples/node-game/public/index.html +705 -0
  38. package/examples/node-game/room.ts +145 -0
  39. package/examples/node-game/server.sqlite.ts +54 -0
  40. package/examples/node-game/server.ts +53 -0
  41. package/examples/node-game/tsconfig.json +10 -0
  42. package/examples/node-shard/README.md +32 -0
  43. package/examples/node-shard/dev.ts +39 -0
  44. package/examples/node-shard/package.json +24 -0
  45. package/examples/node-shard/public/index.html +777 -0
  46. package/examples/node-shard/room-server.ts +68 -0
  47. package/examples/node-shard/room.ts +105 -0
  48. package/examples/node-shard/shared.ts +6 -0
  49. package/examples/node-shard/tsconfig.json +14 -0
  50. package/examples/node-shard/world-server.ts +169 -0
  51. package/package.json +14 -5
  52. package/readme.md +371 -4
  53. package/src/cloudflare/index.ts +474 -0
  54. package/src/jwt.ts +1 -5
  55. package/src/mock.ts +29 -7
  56. package/src/node/index.ts +1112 -0
  57. package/src/server.ts +600 -51
  58. package/src/session.guard.ts +6 -2
  59. package/src/shard.ts +91 -23
  60. package/src/storage.ts +29 -5
  61. package/src/testing.ts +4 -3
  62. package/src/types/party.ts +4 -1
  63. package/src/world.guard.ts +23 -4
  64. package/src/world.ts +121 -21
  65. package/examples/game/.vscode/launch.json +0 -11
  66. package/examples/game/.vscode/settings.json +0 -11
  67. package/examples/game/README.md +0 -40
  68. package/examples/game/app/client.tsx +0 -15
  69. package/examples/game/app/components/Admin.tsx +0 -1089
  70. package/examples/game/app/components/Room.tsx +0 -162
  71. package/examples/game/app/styles.css +0 -31
  72. package/examples/game/package-lock.json +0 -225
  73. package/examples/game/package.json +0 -20
  74. package/examples/game/party/game.room.ts +0 -32
  75. package/examples/game/party/server.ts +0 -10
  76. package/examples/game/party/shard.ts +0 -5
  77. package/examples/game/partykit.json +0 -14
  78. package/examples/game/public/favicon.ico +0 -0
  79. package/examples/game/public/index.html +0 -27
  80. package/examples/game/public/normalize.css +0 -351
  81. package/examples/game/shared/room.schema.ts +0 -14
  82. package/examples/game/tsconfig.json +0 -109
package/dist/index.d.ts CHANGED
@@ -1,176 +1,7 @@
1
- import { Request as Request$2, DurableObjectStorage, WebSocket, DurableObjectState, AnalyticsEngineDataset, VectorizeIndex, R2Bucket, KVNamespace } from '@cloudflare/workers-types';
1
+ import { C as Connection, R as Request$1, a as Room$1, b as ConnectionContext, S as Server$1, c as Storage$1 } from './party-dNs-hqkq.js';
2
2
  import { z } from 'zod';
3
3
  import * as _signe_reactive from '@signe/reactive';
4
-
5
- type AssetFetcher = {
6
- fetch(path: string): Promise<Response | null>;
7
- };
8
- type StandardRequest = globalThis.Request;
9
- interface Request$1 extends Request$2 {
10
- }
11
- type ReturnRequest = StandardRequest | Request$2;
12
- /** Per-party key-value storage */
13
- interface Storage$1 extends DurableObjectStorage {
14
- }
15
- /** Connection metadata only available when the connection is made */
16
- type ConnectionContext = {
17
- request: Request$2;
18
- };
19
- type Stub = {
20
- /** @deprecated Use `await socket()` instead */
21
- connect: () => WebSocket;
22
- socket(pathOrInit?: string | RequestInit): Promise<WebSocket>;
23
- socket(path: string, init?: RequestInit): Promise<WebSocket>;
24
- fetch(pathOrInit?: string | RequestInit | ReturnRequest): Promise<Response>;
25
- fetch(path: string, init?: RequestInit | ReturnRequest): Promise<Response>;
26
- };
27
- /** Additional information about other resources in the current project */
28
- type Context = {
29
- /** Access other parties in this project */
30
- parties: Record<string, {
31
- get(id: string): Stub;
32
- }>;
33
- /**
34
- * A binding to the Cloudflare AI service.
35
- */
36
- ai: AI;
37
- /**
38
- * A binding to the Cloudflare Vectorize service.
39
- */
40
- vectorize: Record<string, VectorizeIndex>;
41
- /**
42
- * A binding to fetch static assets
43
- */
44
- assets: AssetFetcher;
45
- /**
46
- * Custom bindings
47
- */
48
- bindings: CustomBindings;
49
- };
50
- type AI = Record<string, never>;
51
- type ImmutablePrimitive = undefined | null | boolean | string | number;
52
- type Immutable<T> = T extends ImmutablePrimitive ? T : T extends Array<infer U> ? ImmutableArray<U> : T extends Map<infer K, infer V> ? ImmutableMap<K, V> : T extends Set<infer M> ? ImmutableSet<M> : ImmutableObject<T>;
53
- type ImmutableArray<T> = ReadonlyArray<Immutable<T>>;
54
- type ImmutableMap<K, V> = ReadonlyMap<Immutable<K>, Immutable<V>>;
55
- type ImmutableSet<T> = ReadonlySet<Immutable<T>>;
56
- type ImmutableObject<T> = {
57
- readonly [K in keyof T]: Immutable<T[K]>;
58
- };
59
- type ConnectionState<T> = ImmutableObject<T> | null;
60
- type ConnectionSetStateFn<T> = (prevState: ConnectionState<T>) => T;
61
- /** A WebSocket connected to the Room */
62
- type Connection<TState = unknown> = WebSocket & {
63
- /** Connection identifier */
64
- id: string;
65
- /** @deprecated You can access the socket properties directly on the connection*/
66
- socket: WebSocket;
67
- uri: string;
68
- /**
69
- * Arbitrary state associated with this connection.
70
- * Read-only, use Connection.setState to update the state.
71
- */
72
- state: ConnectionState<TState>;
73
- setState(state: TState | ConnectionSetStateFn<TState> | null): ConnectionState<TState>;
74
- /** @deprecated use Connection.setState instead */
75
- serializeAttachment<T = unknown>(attachment: T): void;
76
- /** @deprecated use Connection.state instead */
77
- deserializeAttachment<T = unknown>(): T | null;
78
- };
79
- type CustomBindings = {
80
- r2: Record<string, R2Bucket>;
81
- kv: Record<string, KVNamespace>;
82
- };
83
- /** Room represents a single, self-contained, long-lived session. */
84
- type Room$1 = {
85
- /** Room ID defined in the Party URL, e.g. /parties/:name/:id */
86
- id: string;
87
- /** Internal ID assigned by the platform. Use Party.id instead. */
88
- internalID: string;
89
- /** Party name defined in the Party URL, e.g. /parties/:name/:id */
90
- name: string;
91
- /** Environment variables (--var, partykit.json#vars, or .env) */
92
- env: Record<string, unknown>;
93
- /** A per-room key-value storage */
94
- storage: Storage$1;
95
- /** `blockConcurrencyWhile()` ensures no requests are delivered until */
96
- blockConcurrencyWhile: DurableObjectState["blockConcurrencyWhile"];
97
- /** Additional information about other resources in the current project */
98
- context: Context;
99
- /** @deprecated Use `room.getConnections` instead */
100
- connections: Map<string, Connection>;
101
- /** @deprecated Use `room.context.parties` instead */
102
- parties: Context["parties"];
103
- /** Send a message to all connected clients, except connection ids listed `without` */
104
- broadcast: (msg: string | ArrayBuffer | ArrayBufferView, without?: string[] | undefined) => void;
105
- /** Get a connection by connection id */
106
- getConnection<TState = unknown>(id: string): Connection<TState> | undefined;
107
- /**
108
- * Get all connections. Optionally, you can provide a tag to filter returned connections.
109
- * Use `Party.Server#getConnectionTags` to tag the connection on connect.
110
- */
111
- getConnections<TState = unknown>(tag?: string): Iterable<Connection<TState>>;
112
- /**
113
- * Cloudflare Analytics Engine dataset. Use this to log custom events and metrics.
114
- */
115
- analytics: AnalyticsEngineDataset;
116
- };
117
- type Server$1 = {
118
- /**
119
- * You can define an `options` field to customise the Party.Server behaviour.
120
- */
121
- readonly options?: ServerOptions;
122
- /**
123
- * You can tag a connection to filter them in Party#getConnections.
124
- * Each connection supports up to 9 tags, each tag max length is 256 characters.
125
- */
126
- getConnectionTags?(connection: Connection, context: ConnectionContext): string[] | Promise<string[]>;
127
- /**
128
- * Called when the server is started, before first `onConnect` or `onRequest`.
129
- * Useful for loading data from storage.
130
- *
131
- * You can use this to load data from storage and perform other asynchronous
132
- * initialization, such as retrieving data or configuration from other
133
- * services or databases.
134
- */
135
- onStart?(): void | Promise<void>;
136
- /**
137
- * Called when a new incoming WebSocket connection is opened.
138
- */
139
- onConnect?(connection: Connection, ctx: ConnectionContext): void | Promise<void>;
140
- /**
141
- * Called when a WebSocket connection receives a message from a client, or another connected party.
142
- */
143
- onMessage?(message: string | ArrayBuffer | ArrayBufferView, sender: Connection): void | Promise<void>;
144
- /**
145
- * Called when a WebSocket connection is closed by the client.
146
- */
147
- onClose?(connection: Connection): void | Promise<void>;
148
- /**
149
- * Called when a WebSocket connection is closed due to a connection error.
150
- */
151
- onError?(connection: Connection, error: Error): void | Promise<void>;
152
- /**
153
- * Called when a HTTP request is made to the room URL.
154
- */
155
- onRequest?(req: Request$1): Response | Promise<Response>;
156
- /**
157
- * Called when an alarm is triggered. Use Party.storage.setAlarm to set an alarm.
158
- *
159
- * Alarms have access to most Party resources such as storage, but not Party.id
160
- * and Party.context.parties properties. Attempting to access them will result in a
161
- * runtime error.
162
- */
163
- onAlarm?(): void | Promise<void>;
164
- };
165
- type ServerOptions = {
166
- /**
167
- * Whether the PartyKit platform should remove the server from memory
168
- * between HTTP requests and WebSocket messages.
169
- *
170
- * The default value is `false`.
171
- */
172
- hibernate?: boolean;
173
- };
4
+ import '@cloudflare/workers-types';
174
5
 
175
6
  type GuardFn = (sender: Connection, value: any | Request$1, room: Room$1) => boolean | Promise<boolean | Response>;
176
7
  type RoomGuardFn = (conn: Connection, ctx: ConnectionContext, room: Room$1) => boolean | Promise<boolean | Response>;
@@ -211,6 +42,13 @@ declare function RoomGuard(guards: RoomGuardFn[]): (target: any) => void;
211
42
  */
212
43
  declare function Guard(guards: GuardFn[]): (target: any, propertyKey: string, descriptor: PropertyDescriptor) => void;
213
44
 
45
+ type SessionData = {
46
+ publicId: string;
47
+ state?: any;
48
+ created?: number;
49
+ connected?: boolean;
50
+ disconnectedAt?: number;
51
+ };
214
52
  /**
215
53
  * @class Server
216
54
  * @implements {Party.Server}
@@ -260,6 +98,21 @@ declare class Server implements Server$1 {
260
98
  */
261
99
  get isHibernate(): boolean;
262
100
  get roomStorage(): Storage$1;
101
+ private stateKey;
102
+ private sessionKey;
103
+ private sessionPublicKey;
104
+ private transferKey;
105
+ private isInternalStorageKey;
106
+ private listStorage;
107
+ private loadStatePath;
108
+ private saveStatePath;
109
+ private putStorageEntries;
110
+ private deleteStorageKeys;
111
+ private deleteStatePath;
112
+ private createStorageMetrics;
113
+ private getTransferExpiryTime;
114
+ private getPrivateId;
115
+ private hasActiveSessionConnection;
263
116
  send(conn: Connection, obj: any, subRoom: any): Promise<void>;
264
117
  broadcast(obj: any, subRoom: any): void;
265
118
  /**
@@ -279,6 +132,14 @@ declare class Server implements Server$1 {
279
132
  onStart(): Promise<void>;
280
133
  runGarbageCollector(): Promise<void>;
281
134
  private garbageCollector;
135
+ private scheduleSessionGarbageCollector;
136
+ private getSessionExpiryTime;
137
+ private shouldRunSessionGarbageCollector;
138
+ private shouldRunInterval;
139
+ private repairSessionPublicIndexes;
140
+ private isTransferExpired;
141
+ private cleanupExpiredTransfers;
142
+ private expireDisconnectedSession;
282
143
  /**
283
144
  * @method createRoom
284
145
  * @private
@@ -359,12 +220,12 @@ declare class Server implements Server$1 {
359
220
  * console.log(session);
360
221
  * ```
361
222
  */
362
- getSession(privateId: string): Promise<{
363
- publicId: string;
364
- state?: any;
365
- created?: number;
366
- connected?: boolean;
367
- } | null>;
223
+ getSession(privateId: string): Promise<SessionData | null>;
224
+ private getSessionPrivateIds;
225
+ private saveSessionPrivateIds;
226
+ private addSessionToPublicIndex;
227
+ private removeSessionFromPublicIndex;
228
+ private getSessionEntryByPublicId;
368
229
  private saveSession;
369
230
  private updateSessionConnection;
370
231
  /**
@@ -397,6 +258,7 @@ declare class Server implements Server$1 {
397
258
  * ```
398
259
  */
399
260
  onConnect(conn: Connection, ctx: ConnectionContext): Promise<void>;
261
+ private isAuthorizedShardRequest;
400
262
  /**
401
263
  * @method onConnectShard
402
264
  * @private
@@ -551,10 +413,12 @@ declare class Server implements Server$1 {
551
413
 
552
414
  declare class Storage {
553
415
  private memory;
554
- put(key: any, value: any): Promise<void>;
416
+ put(key: any, value?: any): Promise<void>;
555
417
  get(key: any): Promise<any>;
556
- delete(key: any): Promise<void>;
557
- list(): Promise<Map<any, any>>;
418
+ delete(key: any): Promise<number | boolean>;
419
+ list(options?: {
420
+ prefix?: string;
421
+ }): Promise<Map<any, any>>;
558
422
  }
559
423
 
560
424
  declare class MockPartyClient {
@@ -562,7 +426,7 @@ declare class MockPartyClient {
562
426
  private events;
563
427
  id: string;
564
428
  conn: MockConnection;
565
- constructor(server: Server, id?: string);
429
+ constructor(server: Server, sessionId?: string);
566
430
  addEventListener(event: any, cb: any): void;
567
431
  removeEventListener(event: any, cb: any): void;
568
432
  _trigger(event: any, data: any): void;
@@ -591,15 +455,17 @@ declare class MockPartyRoom {
591
455
  headers?: Record<string, string>;
592
456
  }): Promise<MockPartyClient>;
593
457
  broadcast(data: any): void;
594
- getConnection(id: string): MockPartyClient;
458
+ getConnection(id: string): MockConnection;
595
459
  getConnections(): MockConnection[];
596
460
  clear(): void;
461
+ deleteConnection(id: string, connection?: MockConnection): void;
597
462
  }
598
463
  declare class MockConnection {
599
464
  client: MockPartyClient;
600
465
  server: Server;
601
466
  id: string;
602
- constructor(client: MockPartyClient);
467
+ sessionId: string;
468
+ constructor(client: MockPartyClient, sessionId: string);
603
469
  state: any;
604
470
  setState(value: any): void;
605
471
  send(data: any): void;
@@ -621,21 +487,25 @@ interface ShardOptions {
621
487
  declare class Shard {
622
488
  private room;
623
489
  ws: PartyWebSocket;
624
- connectionMap: Map<string, Connection<unknown>>;
490
+ connectionMap: Map<string, Set<Connection<unknown>>>;
625
491
  mainServerStub: any;
626
492
  worldUrl: string | null;
627
493
  worldId: string;
628
494
  lastReportedConnections: number;
629
495
  statsInterval: number;
630
496
  statsIntervalId: any;
631
- constructor(room: Room$1);
497
+ constructor(room: Room$1, options?: ShardOptions);
498
+ private getPrivateId;
499
+ private getEnvString;
500
+ private getRoomIdFromShardId;
501
+ private getWorldIdFromShardId;
632
502
  onStart(): Promise<void>;
633
503
  private startPeriodicStatsUpdates;
634
504
  private stopPeriodicStatsUpdates;
635
505
  onConnect(conn: Connection, ctx: ConnectionContext): void;
636
506
  onMessage(message: string | ArrayBuffer | ArrayBufferView, sender: Connection): void;
637
507
  onClose(conn: Connection): void;
638
- updateWorldStats(): Promise<boolean>;
508
+ updateWorldStats(force?: boolean): Promise<boolean>;
639
509
  /**
640
510
  * @method onRequest
641
511
  * @async
@@ -680,6 +550,7 @@ declare class Shard {
680
550
  declare function testRoom(Room: any, options?: {
681
551
  hibernate?: boolean;
682
552
  shard?: boolean;
553
+ id?: string;
683
554
  env?: Record<string, string>;
684
555
  parties?: Record<string, (io: any) => any>;
685
556
  partyFn?: (io: any) => any;
@@ -849,6 +720,7 @@ declare class RoomConfig {
849
720
  declare class ShardInfo {
850
721
  id: string;
851
722
  roomId: _signe_reactive.WritableSignal<string>;
723
+ worldId: _signe_reactive.WritableSignal<string>;
852
724
  url: _signe_reactive.WritableSignal<string>;
853
725
  currentConnections: _signe_reactive.WritableSignal<number>;
854
726
  maxConnections: _signe_reactive.WritableSignal<number>;
@@ -865,13 +737,20 @@ declare class WorldRoom implements RoomInterceptorPacket, RoomOnJoin {
865
737
  constructor(room: Room$1);
866
738
  onJoin(user: any, conn: Connection, ctx: ConnectionContext): Promise<void>;
867
739
  interceptorPacket(_: any, obj: any, conn: Connection): any;
740
+ private getWorldId;
741
+ private scheduleInactiveShardCleanup;
868
742
  private cleanupInactiveShards;
869
- registerRoom(req: Request$1): Promise<void>;
743
+ private removeShard;
744
+ private shouldCompleteDrain;
745
+ registerRoom(req: Request$1, res?: ServerResponse): Promise<Response>;
870
746
  updateShardStats(req: Request$1, res: ServerResponse): Promise<Response>;
871
747
  scaleRoom(req: Request$1, res: ServerResponse): Promise<Response>;
872
748
  connect(req: Request$1, res: ServerResponse): Promise<Response>;
873
749
  private findOptimalShard;
750
+ private getAvailableShards;
751
+ private canCreateShard;
874
752
  private createShard;
753
+ private ensureMinShards;
875
754
  }
876
755
 
877
756
  /**