@colyseus/core 0.15.40 → 0.16.0-preview.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 (45) hide show
  1. package/build/IPC.js.map +1 -1
  2. package/build/IPC.mjs.map +1 -1
  3. package/build/MatchMaker.d.ts +1 -10
  4. package/build/MatchMaker.js +3 -10
  5. package/build/MatchMaker.js.map +2 -2
  6. package/build/MatchMaker.mjs +3 -9
  7. package/build/MatchMaker.mjs.map +2 -2
  8. package/build/Protocol.d.ts +1 -5
  9. package/build/Protocol.js +10 -41
  10. package/build/Protocol.js.map +2 -2
  11. package/build/Protocol.mjs +10 -40
  12. package/build/Protocol.mjs.map +2 -2
  13. package/build/Room.d.ts +13 -16
  14. package/build/Room.js +4 -22
  15. package/build/Room.js.map +3 -3
  16. package/build/Room.mjs +5 -23
  17. package/build/Room.mjs.map +2 -2
  18. package/build/Transport.d.ts +13 -6
  19. package/build/Transport.js.map +2 -2
  20. package/build/Transport.mjs.map +2 -2
  21. package/build/index.d.ts +1 -1
  22. package/build/index.js +2 -2
  23. package/build/index.js.map +2 -2
  24. package/build/index.mjs +2 -2
  25. package/build/index.mjs.map +2 -2
  26. package/build/presence/LocalPresence.d.ts +1 -1
  27. package/build/presence/LocalPresence.js.map +2 -2
  28. package/build/presence/LocalPresence.mjs.map +2 -2
  29. package/build/rooms/RelayRoom.js +2 -3
  30. package/build/rooms/RelayRoom.js.map +2 -2
  31. package/build/rooms/RelayRoom.mjs +3 -4
  32. package/build/rooms/RelayRoom.mjs.map +2 -2
  33. package/build/serializer/SchemaSerializer.d.ts +9 -6
  34. package/build/serializer/SchemaSerializer.js +58 -43
  35. package/build/serializer/SchemaSerializer.js.map +2 -2
  36. package/build/serializer/SchemaSerializer.mjs +59 -44
  37. package/build/serializer/SchemaSerializer.mjs.map +2 -2
  38. package/build/serializer/Serializer.d.ts +2 -1
  39. package/build/serializer/Serializer.js.map +1 -1
  40. package/build/utils/Utils.d.ts +1 -8
  41. package/build/utils/Utils.js +3 -3
  42. package/build/utils/Utils.js.map +2 -2
  43. package/build/utils/Utils.mjs +2 -2
  44. package/build/utils/Utils.mjs.map +2 -2
  45. package/package.json +4 -5
@@ -5,11 +5,10 @@
5
5
  import * as http from 'http';
6
6
  import * as https from 'https';
7
7
  import * as net from 'net';
8
- import { Schema } from '@colyseus/schema';
8
+ import { Schema, StateView } from '@colyseus/schema';
9
9
  import { EventEmitter } from 'events';
10
- import { DummyServer } from './utils/Utils';
11
10
  export declare abstract class Transport {
12
- server?: net.Server | http.Server | https.Server | DummyServer;
11
+ server?: net.Server | http.Server | https.Server;
13
12
  abstract listen(port?: number, hostname?: string, backlog?: number, listeningListener?: Function): this;
14
13
  abstract shutdown(): void;
15
14
  abstract simulateLatency(milliseconds: number): void;
@@ -33,14 +32,23 @@ export declare enum ClientState {
33
32
  */
34
33
  export interface Client<UserData = any, AuthData = any> {
35
34
  readyState: number;
35
+ ref: EventEmitter;
36
+ /**
37
+ * @deprecated use `sessionId` instead.
38
+ */
36
39
  id: string;
37
40
  /**
38
41
  * Unique id per session.
39
42
  */
40
43
  sessionId: string;
44
+ /**
45
+ * Connection state
46
+ */
41
47
  state: ClientState;
42
- ref: EventEmitter;
43
- upgradeReq?: http.IncomingMessage;
48
+ /**
49
+ * Optional: when using `@view()` decorator in your state properties, this will be the view instance for this client.
50
+ */
51
+ view?: StateView;
44
52
  /**
45
53
  * User-defined data can be attached to the Client instance through this variable.
46
54
  * - Can be used to store custom data about the client's connection. userData is not synchronized with the client,
@@ -51,7 +59,6 @@ export interface Client<UserData = any, AuthData = any> {
51
59
  * auth data provided by your `onAuth`
52
60
  */
53
61
  auth?: AuthData;
54
- pingCount?: number;
55
62
  _reconnectionToken: string;
56
63
  _enqueuedMessages?: any[];
57
64
  _afterNextPatchQueue: Array<[string | Client, IArguments]>;
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../src/Transport.ts"],
4
- "sourcesContent": ["import * as http from 'http';\nimport * as https from 'https';\nimport * as net from 'net';\n\nimport { Schema } from '@colyseus/schema';\nimport { EventEmitter } from 'events';\nimport { DummyServer, spliceOne } from './utils/Utils';\n\nexport abstract class Transport {\n public server?: net.Server | http.Server | https.Server | DummyServer;\n\n public abstract listen(port?: number, hostname?: string, backlog?: number, listeningListener?: Function): this;\n public abstract shutdown(): void;\n\n public abstract simulateLatency(milliseconds: number): void;\n}\n\nexport interface ISendOptions {\n afterNextPatch?: boolean;\n}\n\nexport enum ClientState { JOINING, JOINED, RECONNECTED, LEAVING }\n\n/**\n * The client instance from the server-side is responsible for the transport layer between the server and the client.\n * It should not be confused with the Client from the client-side SDK, as they have completely different purposes!\n * You operate on client instances from `this.clients`, `Room#onJoin()`, `Room#onLeave()` and `Room#onMessage()`.\n *\n * - This is the raw WebSocket connection coming from the `ws` package. There are more methods available which aren't\n * encouraged to use along with Colyseus.\n */\nexport interface Client<UserData=any, AuthData=any> {\n readyState: number;\n\n id: string;\n /**\n * Unique id per session.\n */\n sessionId: string; // TODO: remove sessionId on version 1.0.0\n state: ClientState;\n\n ref: EventEmitter;\n\n upgradeReq?: http.IncomingMessage; // cross-compatibility for ws (v3.x+) and uws\n\n /**\n * User-defined data can be attached to the Client instance through this variable.\n * - Can be used to store custom data about the client's connection. userData is not synchronized with the client,\n * and should be used only to keep player-specific with its connection.\n */\n userData?: UserData;\n\n /**\n * auth data provided by your `onAuth`\n */\n auth?: AuthData;\n pingCount?: number; // ping / pong\n\n _reconnectionToken: string;\n _enqueuedMessages?: any[];\n _afterNextPatchQueue: Array<[string | Client, IArguments]>;\n\n raw(data: ArrayLike<number>, options?: ISendOptions, cb?: (err?: Error) => void): void;\n enqueueRaw(data: ArrayLike<number>, options?: ISendOptions): void;\n\n /**\n * Send a type of message to the client. Messages are encoded with MsgPack and can hold any\n * JSON-serializable data structure.\n *\n * @param type String or Number identifier the client SDK will use to receive this message\n * @param message Message payload. (automatically encoded with msgpack.)\n * @param options\n */\n send(type: string | number, message?: any, options?: ISendOptions): void;\n send(message: Schema, options?: ISendOptions): void;\n\n /**\n * Send raw bytes to this specific client.\n *\n * @param type String or Number identifier the client SDK will use to receive this message\n * @param bytes Raw byte array payload\n * @param options\n */\n sendBytes(type: string | number, bytes: number[] | Uint8Array, options?: ISendOptions): void;\n\n /**\n * Disconnect this client from the room.\n *\n * @param code Custom close code. Default value is 1000.\n * @param data\n * @see {@link https://docs.colyseus.io/colyseus/server/room/#leavecode-number}\n */\n leave(code?: number, data?: string): void;\n\n /**\n * @deprecated Use .leave() instead.\n */\n close(code?: number, data?: string): void;\n\n /**\n * Triggers `onError` with specified code to the client-side.\n *\n * @param code\n * @param message\n */\n error(code: number, message?: string): void;\n}\n\nexport class ClientArray<UserData = any, AuthData = any> extends Array<Client<UserData, AuthData>> {\n public getById(sessionId: string): Client<UserData, AuthData> | undefined {\n return this.find((client) => client.sessionId === sessionId);\n }\n\n public delete(client: Client<UserData, AuthData>): boolean {\n return spliceOne(this, this.indexOf(client));\n }\n}"],
5
- "mappings": ";;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAMA,mBAAuC;AAEhC,MAAe,UAAU;AAOhC;AAMO,IAAK,cAAL,kBAAKA,iBAAL;AAAmB,EAAAA,0BAAA;AAAS,EAAAA,0BAAA;AAAQ,EAAAA,0BAAA;AAAa,EAAAA,0BAAA;AAA5C,SAAAA;AAAA,GAAA;AAuFL,MAAM,oBAAoD,MAAkC;AAAA,EAC1F,QAAQ,WAA2D;AACxE,WAAO,KAAK,KAAK,CAAC,WAAW,OAAO,cAAc,SAAS;AAAA,EAC7D;AAAA,EAEO,OAAO,QAA6C;AACzD,eAAO,wBAAU,MAAM,KAAK,QAAQ,MAAM,CAAC;AAAA,EAC7C;AACF;",
4
+ "sourcesContent": ["import * as http from 'http';\nimport * as https from 'https';\nimport * as net from 'net';\n\nimport { Schema, StateView } from '@colyseus/schema';\nimport { EventEmitter } from 'events';\nimport { spliceOne } from './utils/Utils';\n\nexport abstract class Transport {\n public server?: net.Server | http.Server | https.Server;\n\n public abstract listen(port?: number, hostname?: string, backlog?: number, listeningListener?: Function): this;\n public abstract shutdown(): void;\n\n public abstract simulateLatency(milliseconds: number): void;\n}\n\nexport interface ISendOptions {\n afterNextPatch?: boolean;\n}\n\nexport enum ClientState { JOINING, JOINED, RECONNECTED, LEAVING }\n\n/**\n * The client instance from the server-side is responsible for the transport layer between the server and the client.\n * It should not be confused with the Client from the client-side SDK, as they have completely different purposes!\n * You operate on client instances from `this.clients`, `Room#onJoin()`, `Room#onLeave()` and `Room#onMessage()`.\n *\n * - This is the raw WebSocket connection coming from the `ws` package. There are more methods available which aren't\n * encouraged to use along with Colyseus.\n */\nexport interface Client<UserData=any, AuthData=any> {\n readyState: number; // TODO: remove readyState on version 1.0.0. Use only \"state\" instead.\n ref: EventEmitter;\n\n /**\n * @deprecated use `sessionId` instead.\n */\n id: string;\n\n /**\n * Unique id per session.\n */\n sessionId: string; // TODO: remove sessionId on version 1.0.0\n\n /**\n * Connection state\n */\n state: ClientState;\n\n /**\n * Optional: when using `@view()` decorator in your state properties, this will be the view instance for this client.\n */\n view?: StateView;\n\n /**\n * User-defined data can be attached to the Client instance through this variable.\n * - Can be used to store custom data about the client's connection. userData is not synchronized with the client,\n * and should be used only to keep player-specific with its connection.\n */\n userData?: UserData;\n\n /**\n * auth data provided by your `onAuth`\n */\n auth?: AuthData;\n\n _reconnectionToken: string;\n _enqueuedMessages?: any[];\n _afterNextPatchQueue: Array<[string | Client, IArguments]>;\n\n raw(data: ArrayLike<number>, options?: ISendOptions, cb?: (err?: Error) => void): void;\n enqueueRaw(data: ArrayLike<number>, options?: ISendOptions): void;\n\n /**\n * Send a type of message to the client. Messages are encoded with MsgPack and can hold any\n * JSON-serializable data structure.\n *\n * @param type String or Number identifier the client SDK will use to receive this message\n * @param message Message payload. (automatically encoded with msgpack.)\n * @param options\n */\n send(type: string | number, message?: any, options?: ISendOptions): void;\n send(message: Schema, options?: ISendOptions): void;\n\n /**\n * Send raw bytes to this specific client.\n *\n * @param type String or Number identifier the client SDK will use to receive this message\n * @param bytes Raw byte array payload\n * @param options\n */\n sendBytes(type: string | number, bytes: number[] | Uint8Array, options?: ISendOptions): void;\n\n /**\n * Disconnect this client from the room.\n *\n * @param code Custom close code. Default value is 1000.\n * @param data\n * @see {@link https://docs.colyseus.io/colyseus/server/room/#leavecode-number}\n */\n leave(code?: number, data?: string): void;\n\n /**\n * @deprecated Use .leave() instead.\n */\n close(code?: number, data?: string): void;\n\n /**\n * Triggers `onError` with specified code to the client-side.\n *\n * @param code\n * @param message\n */\n error(code: number, message?: string): void;\n}\n\nexport class ClientArray<UserData = any, AuthData = any> extends Array<Client<UserData, AuthData>> {\n public getById(sessionId: string): Client<UserData, AuthData> | undefined {\n return this.find((client) => client.sessionId === sessionId);\n }\n\n public delete(client: Client<UserData, AuthData>): boolean {\n return spliceOne(this, this.indexOf(client));\n }\n}"],
5
+ "mappings": ";;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAMA,mBAA0B;AAEnB,MAAe,UAAU;AAOhC;AAMO,IAAK,cAAL,kBAAKA,iBAAL;AAAmB,EAAAA,0BAAA;AAAS,EAAAA,0BAAA;AAAQ,EAAAA,0BAAA;AAAa,EAAAA,0BAAA;AAA5C,SAAAA;AAAA,GAAA;AAgGL,MAAM,oBAAoD,MAAkC;AAAA,EAC1F,QAAQ,WAA2D;AACxE,WAAO,KAAK,KAAK,CAAC,WAAW,OAAO,cAAc,SAAS;AAAA,EAC7D;AAAA,EAEO,OAAO,QAA6C;AACzD,eAAO,wBAAU,MAAM,KAAK,QAAQ,MAAM,CAAC;AAAA,EAC7C;AACF;",
6
6
  "names": ["ClientState"]
7
7
  }
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../src/Transport.ts"],
4
- "sourcesContent": ["import * as http from 'http';\nimport * as https from 'https';\nimport * as net from 'net';\n\nimport { Schema } from '@colyseus/schema';\nimport { EventEmitter } from 'events';\nimport { DummyServer, spliceOne } from './utils/Utils';\n\nexport abstract class Transport {\n public server?: net.Server | http.Server | https.Server | DummyServer;\n\n public abstract listen(port?: number, hostname?: string, backlog?: number, listeningListener?: Function): this;\n public abstract shutdown(): void;\n\n public abstract simulateLatency(milliseconds: number): void;\n}\n\nexport interface ISendOptions {\n afterNextPatch?: boolean;\n}\n\nexport enum ClientState { JOINING, JOINED, RECONNECTED, LEAVING }\n\n/**\n * The client instance from the server-side is responsible for the transport layer between the server and the client.\n * It should not be confused with the Client from the client-side SDK, as they have completely different purposes!\n * You operate on client instances from `this.clients`, `Room#onJoin()`, `Room#onLeave()` and `Room#onMessage()`.\n *\n * - This is the raw WebSocket connection coming from the `ws` package. There are more methods available which aren't\n * encouraged to use along with Colyseus.\n */\nexport interface Client<UserData=any, AuthData=any> {\n readyState: number;\n\n id: string;\n /**\n * Unique id per session.\n */\n sessionId: string; // TODO: remove sessionId on version 1.0.0\n state: ClientState;\n\n ref: EventEmitter;\n\n upgradeReq?: http.IncomingMessage; // cross-compatibility for ws (v3.x+) and uws\n\n /**\n * User-defined data can be attached to the Client instance through this variable.\n * - Can be used to store custom data about the client's connection. userData is not synchronized with the client,\n * and should be used only to keep player-specific with its connection.\n */\n userData?: UserData;\n\n /**\n * auth data provided by your `onAuth`\n */\n auth?: AuthData;\n pingCount?: number; // ping / pong\n\n _reconnectionToken: string;\n _enqueuedMessages?: any[];\n _afterNextPatchQueue: Array<[string | Client, IArguments]>;\n\n raw(data: ArrayLike<number>, options?: ISendOptions, cb?: (err?: Error) => void): void;\n enqueueRaw(data: ArrayLike<number>, options?: ISendOptions): void;\n\n /**\n * Send a type of message to the client. Messages are encoded with MsgPack and can hold any\n * JSON-serializable data structure.\n *\n * @param type String or Number identifier the client SDK will use to receive this message\n * @param message Message payload. (automatically encoded with msgpack.)\n * @param options\n */\n send(type: string | number, message?: any, options?: ISendOptions): void;\n send(message: Schema, options?: ISendOptions): void;\n\n /**\n * Send raw bytes to this specific client.\n *\n * @param type String or Number identifier the client SDK will use to receive this message\n * @param bytes Raw byte array payload\n * @param options\n */\n sendBytes(type: string | number, bytes: number[] | Uint8Array, options?: ISendOptions): void;\n\n /**\n * Disconnect this client from the room.\n *\n * @param code Custom close code. Default value is 1000.\n * @param data\n * @see {@link https://docs.colyseus.io/colyseus/server/room/#leavecode-number}\n */\n leave(code?: number, data?: string): void;\n\n /**\n * @deprecated Use .leave() instead.\n */\n close(code?: number, data?: string): void;\n\n /**\n * Triggers `onError` with specified code to the client-side.\n *\n * @param code\n * @param message\n */\n error(code: number, message?: string): void;\n}\n\nexport class ClientArray<UserData = any, AuthData = any> extends Array<Client<UserData, AuthData>> {\n public getById(sessionId: string): Client<UserData, AuthData> | undefined {\n return this.find((client) => client.sessionId === sessionId);\n }\n\n public delete(client: Client<UserData, AuthData>): boolean {\n return spliceOne(this, this.indexOf(client));\n }\n}"],
5
- "mappings": "AAMA,SAAsB,iBAAiB;AAEhC,MAAe,UAAU;AAOhC;AAMO,IAAK,cAAL,kBAAKA,iBAAL;AAAmB,EAAAA,0BAAA;AAAS,EAAAA,0BAAA;AAAQ,EAAAA,0BAAA;AAAa,EAAAA,0BAAA;AAA5C,SAAAA;AAAA,GAAA;AAuFL,MAAM,oBAAoD,MAAkC;AAAA,EAC1F,QAAQ,WAA2D;AACxE,WAAO,KAAK,KAAK,CAAC,WAAW,OAAO,cAAc,SAAS;AAAA,EAC7D;AAAA,EAEO,OAAO,QAA6C;AACzD,WAAO,UAAU,MAAM,KAAK,QAAQ,MAAM,CAAC;AAAA,EAC7C;AACF;",
4
+ "sourcesContent": ["import * as http from 'http';\nimport * as https from 'https';\nimport * as net from 'net';\n\nimport { Schema, StateView } from '@colyseus/schema';\nimport { EventEmitter } from 'events';\nimport { spliceOne } from './utils/Utils';\n\nexport abstract class Transport {\n public server?: net.Server | http.Server | https.Server;\n\n public abstract listen(port?: number, hostname?: string, backlog?: number, listeningListener?: Function): this;\n public abstract shutdown(): void;\n\n public abstract simulateLatency(milliseconds: number): void;\n}\n\nexport interface ISendOptions {\n afterNextPatch?: boolean;\n}\n\nexport enum ClientState { JOINING, JOINED, RECONNECTED, LEAVING }\n\n/**\n * The client instance from the server-side is responsible for the transport layer between the server and the client.\n * It should not be confused with the Client from the client-side SDK, as they have completely different purposes!\n * You operate on client instances from `this.clients`, `Room#onJoin()`, `Room#onLeave()` and `Room#onMessage()`.\n *\n * - This is the raw WebSocket connection coming from the `ws` package. There are more methods available which aren't\n * encouraged to use along with Colyseus.\n */\nexport interface Client<UserData=any, AuthData=any> {\n readyState: number; // TODO: remove readyState on version 1.0.0. Use only \"state\" instead.\n ref: EventEmitter;\n\n /**\n * @deprecated use `sessionId` instead.\n */\n id: string;\n\n /**\n * Unique id per session.\n */\n sessionId: string; // TODO: remove sessionId on version 1.0.0\n\n /**\n * Connection state\n */\n state: ClientState;\n\n /**\n * Optional: when using `@view()` decorator in your state properties, this will be the view instance for this client.\n */\n view?: StateView;\n\n /**\n * User-defined data can be attached to the Client instance through this variable.\n * - Can be used to store custom data about the client's connection. userData is not synchronized with the client,\n * and should be used only to keep player-specific with its connection.\n */\n userData?: UserData;\n\n /**\n * auth data provided by your `onAuth`\n */\n auth?: AuthData;\n\n _reconnectionToken: string;\n _enqueuedMessages?: any[];\n _afterNextPatchQueue: Array<[string | Client, IArguments]>;\n\n raw(data: ArrayLike<number>, options?: ISendOptions, cb?: (err?: Error) => void): void;\n enqueueRaw(data: ArrayLike<number>, options?: ISendOptions): void;\n\n /**\n * Send a type of message to the client. Messages are encoded with MsgPack and can hold any\n * JSON-serializable data structure.\n *\n * @param type String or Number identifier the client SDK will use to receive this message\n * @param message Message payload. (automatically encoded with msgpack.)\n * @param options\n */\n send(type: string | number, message?: any, options?: ISendOptions): void;\n send(message: Schema, options?: ISendOptions): void;\n\n /**\n * Send raw bytes to this specific client.\n *\n * @param type String or Number identifier the client SDK will use to receive this message\n * @param bytes Raw byte array payload\n * @param options\n */\n sendBytes(type: string | number, bytes: number[] | Uint8Array, options?: ISendOptions): void;\n\n /**\n * Disconnect this client from the room.\n *\n * @param code Custom close code. Default value is 1000.\n * @param data\n * @see {@link https://docs.colyseus.io/colyseus/server/room/#leavecode-number}\n */\n leave(code?: number, data?: string): void;\n\n /**\n * @deprecated Use .leave() instead.\n */\n close(code?: number, data?: string): void;\n\n /**\n * Triggers `onError` with specified code to the client-side.\n *\n * @param code\n * @param message\n */\n error(code: number, message?: string): void;\n}\n\nexport class ClientArray<UserData = any, AuthData = any> extends Array<Client<UserData, AuthData>> {\n public getById(sessionId: string): Client<UserData, AuthData> | undefined {\n return this.find((client) => client.sessionId === sessionId);\n }\n\n public delete(client: Client<UserData, AuthData>): boolean {\n return spliceOne(this, this.indexOf(client));\n }\n}"],
5
+ "mappings": "AAMA,SAAS,iBAAiB;AAEnB,MAAe,UAAU;AAOhC;AAMO,IAAK,cAAL,kBAAKA,iBAAL;AAAmB,EAAAA,0BAAA;AAAS,EAAAA,0BAAA;AAAQ,EAAAA,0BAAA;AAAa,EAAAA,0BAAA;AAA5C,SAAAA;AAAA,GAAA;AAgGL,MAAM,oBAAoD,MAAkC;AAAA,EAC1F,QAAQ,WAA2D;AACxE,WAAO,KAAK,KAAK,CAAC,WAAW,OAAO,cAAc,SAAS;AAAA,EAC7D;AAAA,EAEO,OAAO,QAA6C;AACzD,WAAO,UAAU,MAAM,KAAK,QAAQ,MAAM,CAAC;AAAA,EAC7C;AACF;",
6
6
  "names": ["ClientState"]
7
7
  }
package/build/index.d.ts CHANGED
@@ -14,7 +14,7 @@ export { LocalPresence } from './presence/LocalPresence';
14
14
  export { type Serializer } from './serializer/Serializer';
15
15
  export { SchemaSerializer } from './serializer/SchemaSerializer';
16
16
  export { Clock, Delayed };
17
- export { generateId, Deferred, DummyServer, spliceOne, getBearerToken } from './utils/Utils';
17
+ export { generateId, Deferred, HttpServerMock, spliceOne, getBearerToken } from './utils/Utils';
18
18
  export { isDevMode } from './utils/DevMode';
19
19
  export { debugMatchMaking, debugMessage, debugPatch, debugError, debugConnection, debugDriver, debugPresence, debugAndPrintError, } from './Debug';
20
20
  export { LobbyRoom } from './rooms/LobbyRoom';
package/build/index.js CHANGED
@@ -29,8 +29,8 @@ __export(src_exports, {
29
29
  Clock: () => import_timer.default,
30
30
  Deferred: () => import_Utils.Deferred,
31
31
  Delayed: () => import_timer.Delayed,
32
- DummyServer: () => import_Utils.DummyServer,
33
32
  ErrorCode: () => import_Protocol.ErrorCode,
33
+ HttpServerMock: () => import_Utils.HttpServerMock,
34
34
  LobbyRoom: () => import_LobbyRoom.LobbyRoom,
35
35
  LocalPresence: () => import_LocalPresence.LocalPresence,
36
36
  Protocol: () => import_Protocol.Protocol,
@@ -88,8 +88,8 @@ var import_Logger = require("./Logger");
88
88
  Clock,
89
89
  Deferred,
90
90
  Delayed,
91
- DummyServer,
92
91
  ErrorCode,
92
+ HttpServerMock,
93
93
  LobbyRoom,
94
94
  LocalPresence,
95
95
  Protocol,
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../src/index.ts"],
4
- "sourcesContent": ["import Clock, { Delayed } from '@gamestdio/timer';\n\n// Core classes\nexport { Server, type ServerOptions } from './Server';\nexport { Room, RoomInternalState } from './Room';\nexport { Protocol, ErrorCode, getMessageBytes } from './Protocol';\nexport { RegisteredHandler } from './matchmaker/RegisteredHandler';\nexport { ServerError } from './errors/ServerError';\n\n// MatchMaker\nimport * as matchMaker from './MatchMaker';\nexport { matchMaker };\nexport { updateLobby, subscribeLobby } from './matchmaker/Lobby';\n\n// Driver\nexport * from './matchmaker/driver';\n\n// Transport\nexport { type Client, ClientState, ClientArray, Transport, type ISendOptions } from './Transport';\n\n// Presence\nexport { type Presence } from './presence/Presence';\nexport { LocalPresence } from './presence/LocalPresence';\n\n// Serializers\nexport { type Serializer } from './serializer/Serializer';\nexport { SchemaSerializer } from './serializer/SchemaSerializer';\n\n// Utilities\nexport { Clock, Delayed };\nexport { generateId, Deferred, DummyServer, spliceOne, getBearerToken } from './utils/Utils';\nexport { isDevMode } from './utils/DevMode';\n\n// Debug\nexport {\n debugMatchMaking,\n debugMessage,\n debugPatch,\n debugError,\n debugConnection,\n debugDriver,\n debugPresence,\n debugAndPrintError,\n} from './Debug';\n\n// Default rooms\nexport { LobbyRoom } from './rooms/LobbyRoom';\nexport { RelayRoom } from './rooms/RelayRoom';\n\n// Abstract logging support\nexport { logger } from './Logger'\n"],
5
- "mappings": ";;;;;;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA,4BAAAA;AAAA,EAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,mBAA+B;AAG/B,oBAA2C;AAC3C,kBAAwC;AACxC,sBAAqD;AACrD,+BAAkC;AAClC,yBAA4B;AAG5B,iBAA4B;AAE5B,mBAA4C;AAG5C,wBAAc,gCAfd;AAkBA,uBAAoF;AAGpF,sBAA8B;AAC9B,2BAA8B;AAG9B,wBAAgC;AAChC,8BAAiC;AAIjC,mBAA6E;AAC7E,qBAA0B;AAG1B,mBASO;AAGP,uBAA0B;AAC1B,uBAA0B;AAG1B,oBAAuB;",
4
+ "sourcesContent": ["import Clock, { Delayed } from '@gamestdio/timer';\n\n// Core classes\nexport { Server, type ServerOptions } from './Server';\nexport { Room, RoomInternalState } from './Room';\nexport { Protocol, ErrorCode, getMessageBytes } from './Protocol';\nexport { RegisteredHandler } from './matchmaker/RegisteredHandler';\nexport { ServerError } from './errors/ServerError';\n\n// MatchMaker\nimport * as matchMaker from './MatchMaker';\nexport { matchMaker };\nexport { updateLobby, subscribeLobby } from './matchmaker/Lobby';\n\n// Driver\nexport * from './matchmaker/driver';\n\n// Transport\nexport { type Client, ClientState, ClientArray, Transport, type ISendOptions } from './Transport';\n\n// Presence\nexport { type Presence } from './presence/Presence';\nexport { LocalPresence } from './presence/LocalPresence';\n\n// Serializers\nexport { type Serializer } from './serializer/Serializer';\nexport { SchemaSerializer } from './serializer/SchemaSerializer';\n\n// Utilities\nexport { Clock, Delayed };\nexport { generateId, Deferred, HttpServerMock, spliceOne, getBearerToken } from './utils/Utils';\nexport { isDevMode } from './utils/DevMode';\n\n// Debug\nexport {\n debugMatchMaking,\n debugMessage,\n debugPatch,\n debugError,\n debugConnection,\n debugDriver,\n debugPresence,\n debugAndPrintError,\n} from './Debug';\n\n// Default rooms\nexport { LobbyRoom } from './rooms/LobbyRoom';\nexport { RelayRoom } from './rooms/RelayRoom';\n\n// Abstract logging support\nexport { logger } from './Logger'\n"],
5
+ "mappings": ";;;;;;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA,4BAAAA;AAAA,EAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,mBAA+B;AAG/B,oBAA2C;AAC3C,kBAAwC;AACxC,sBAAqD;AACrD,+BAAkC;AAClC,yBAA4B;AAG5B,iBAA4B;AAE5B,mBAA4C;AAG5C,wBAAc,gCAfd;AAkBA,uBAAoF;AAGpF,sBAA8B;AAC9B,2BAA8B;AAG9B,wBAAgC;AAChC,8BAAiC;AAIjC,mBAAgF;AAChF,qBAA0B;AAG1B,mBASO;AAGP,uBAA0B;AAC1B,uBAA0B;AAG1B,oBAAuB;",
6
6
  "names": ["Clock"]
7
7
  }
package/build/index.mjs CHANGED
@@ -12,7 +12,7 @@ import {} from "./presence/Presence";
12
12
  import { LocalPresence } from "./presence/LocalPresence";
13
13
  import {} from "./serializer/Serializer";
14
14
  import { SchemaSerializer } from "./serializer/SchemaSerializer";
15
- import { generateId, Deferred, DummyServer, spliceOne, getBearerToken } from "./utils/Utils";
15
+ import { generateId, Deferred, HttpServerMock, spliceOne, getBearerToken } from "./utils/Utils";
16
16
  import { isDevMode } from "./utils/DevMode";
17
17
  import {
18
18
  debugMatchMaking,
@@ -33,8 +33,8 @@ export {
33
33
  Clock,
34
34
  Deferred,
35
35
  Delayed,
36
- DummyServer,
37
36
  ErrorCode,
37
+ HttpServerMock,
38
38
  LobbyRoom,
39
39
  LocalPresence,
40
40
  Protocol,
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../src/index.ts"],
4
- "sourcesContent": ["import Clock, { Delayed } from '@gamestdio/timer';\n\n// Core classes\nexport { Server, type ServerOptions } from './Server';\nexport { Room, RoomInternalState } from './Room';\nexport { Protocol, ErrorCode, getMessageBytes } from './Protocol';\nexport { RegisteredHandler } from './matchmaker/RegisteredHandler';\nexport { ServerError } from './errors/ServerError';\n\n// MatchMaker\nimport * as matchMaker from './MatchMaker';\nexport { matchMaker };\nexport { updateLobby, subscribeLobby } from './matchmaker/Lobby';\n\n// Driver\nexport * from './matchmaker/driver';\n\n// Transport\nexport { type Client, ClientState, ClientArray, Transport, type ISendOptions } from './Transport';\n\n// Presence\nexport { type Presence } from './presence/Presence';\nexport { LocalPresence } from './presence/LocalPresence';\n\n// Serializers\nexport { type Serializer } from './serializer/Serializer';\nexport { SchemaSerializer } from './serializer/SchemaSerializer';\n\n// Utilities\nexport { Clock, Delayed };\nexport { generateId, Deferred, DummyServer, spliceOne, getBearerToken } from './utils/Utils';\nexport { isDevMode } from './utils/DevMode';\n\n// Debug\nexport {\n debugMatchMaking,\n debugMessage,\n debugPatch,\n debugError,\n debugConnection,\n debugDriver,\n debugPresence,\n debugAndPrintError,\n} from './Debug';\n\n// Default rooms\nexport { LobbyRoom } from './rooms/LobbyRoom';\nexport { RelayRoom } from './rooms/RelayRoom';\n\n// Abstract logging support\nexport { logger } from './Logger'\n"],
5
- "mappings": "AAAA,OAAO,SAAS,eAAe;AAG/B,SAAS,cAAkC;AAC3C,SAAS,MAAM,yBAAyB;AACxC,SAAS,UAAU,WAAW,uBAAuB;AACrD,SAAS,yBAAyB;AAClC,SAAS,mBAAmB;AAG5B,YAAY,gBAAgB;AAE5B,SAAS,aAAa,sBAAsB;AAG5C,cAAc;AAGd,SAAsB,aAAa,aAAa,iBAAoC;AAGpF,eAA8B;AAC9B,SAAS,qBAAqB;AAG9B,eAAgC;AAChC,SAAS,wBAAwB;AAIjC,SAAS,YAAY,UAAU,aAAa,WAAW,sBAAsB;AAC7E,SAAS,iBAAiB;AAG1B;AAAA,EACE;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,OACK;AAGP,SAAS,iBAAiB;AAC1B,SAAS,iBAAiB;AAG1B,SAAS,cAAc;",
4
+ "sourcesContent": ["import Clock, { Delayed } from '@gamestdio/timer';\n\n// Core classes\nexport { Server, type ServerOptions } from './Server';\nexport { Room, RoomInternalState } from './Room';\nexport { Protocol, ErrorCode, getMessageBytes } from './Protocol';\nexport { RegisteredHandler } from './matchmaker/RegisteredHandler';\nexport { ServerError } from './errors/ServerError';\n\n// MatchMaker\nimport * as matchMaker from './MatchMaker';\nexport { matchMaker };\nexport { updateLobby, subscribeLobby } from './matchmaker/Lobby';\n\n// Driver\nexport * from './matchmaker/driver';\n\n// Transport\nexport { type Client, ClientState, ClientArray, Transport, type ISendOptions } from './Transport';\n\n// Presence\nexport { type Presence } from './presence/Presence';\nexport { LocalPresence } from './presence/LocalPresence';\n\n// Serializers\nexport { type Serializer } from './serializer/Serializer';\nexport { SchemaSerializer } from './serializer/SchemaSerializer';\n\n// Utilities\nexport { Clock, Delayed };\nexport { generateId, Deferred, HttpServerMock, spliceOne, getBearerToken } from './utils/Utils';\nexport { isDevMode } from './utils/DevMode';\n\n// Debug\nexport {\n debugMatchMaking,\n debugMessage,\n debugPatch,\n debugError,\n debugConnection,\n debugDriver,\n debugPresence,\n debugAndPrintError,\n} from './Debug';\n\n// Default rooms\nexport { LobbyRoom } from './rooms/LobbyRoom';\nexport { RelayRoom } from './rooms/RelayRoom';\n\n// Abstract logging support\nexport { logger } from './Logger'\n"],
5
+ "mappings": "AAAA,OAAO,SAAS,eAAe;AAG/B,SAAS,cAAkC;AAC3C,SAAS,MAAM,yBAAyB;AACxC,SAAS,UAAU,WAAW,uBAAuB;AACrD,SAAS,yBAAyB;AAClC,SAAS,mBAAmB;AAG5B,YAAY,gBAAgB;AAE5B,SAAS,aAAa,sBAAsB;AAG5C,cAAc;AAGd,SAAsB,aAAa,aAAa,iBAAoC;AAGpF,eAA8B;AAC9B,SAAS,qBAAqB;AAG9B,eAAgC;AAChC,SAAS,wBAAwB;AAIjC,SAAS,YAAY,UAAU,gBAAgB,WAAW,sBAAsB;AAChF,SAAS,iBAAiB;AAG1B;AAAA,EACE;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,OACK;AAGP,SAAS,iBAAiB;AAC1B,SAAS,iBAAiB;AAG1B,SAAS,cAAc;",
6
6
  "names": []
7
7
  }
@@ -3,7 +3,7 @@ import { EventEmitter } from 'events';
3
3
  import { Presence } from './Presence';
4
4
  type Callback = (...args: any[]) => void;
5
5
  export declare class LocalPresence implements Presence {
6
- channels: EventEmitter;
6
+ channels: EventEmitter<[never]>;
7
7
  data: {
8
8
  [roomName: string]: string[];
9
9
  };
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../../src/presence/LocalPresence.ts"],
4
- "sourcesContent": ["import fs from \"fs\";\nimport path from \"path\";\n\nimport { EventEmitter } from 'events';\nimport { spliceOne } from '../utils/Utils';\nimport { Presence } from './Presence';\n\nimport { isDevMode } from '../utils/DevMode';\n\ntype Callback = (...args: any[]) => void;\n\nconst DEVMODE_CACHE_FILE_PATH = path.resolve(\".devmode.json\");\n\nexport class LocalPresence implements Presence {\n public channels = new EventEmitter();\n\n public data: {[roomName: string]: string[]} = {};\n public hash: {[roomName: string]: {[key: string]: string}} = {};\n\n public keys: {[name: string]: string | number} = {};\n\n protected subscriptions: {[id: string]: Callback[]} = {};\n private timeouts: {[name: string]: NodeJS.Timer} = {};\n\n constructor() {\n //\n // reload from local cache on devMode\n //\n if (\n isDevMode &&\n fs.existsSync(DEVMODE_CACHE_FILE_PATH)\n ) {\n const cache = fs.readFileSync(DEVMODE_CACHE_FILE_PATH).toString('utf-8') || \"{}\";\n const parsed = JSON.parse(cache);\n if (parsed.data) { this.data = parsed.data; }\n if (parsed.hash) { this.hash = parsed.hash; }\n if (parsed.keys) { this.keys = parsed.keys; }\n }\n }\n\n public subscribe(topic: string, callback: (...args: any[]) => void) {\n if (!this.subscriptions[topic]) { this.subscriptions[topic] = []; }\n this.subscriptions[topic].push(callback);\n this.channels.on(topic, callback);\n return this;\n }\n\n public unsubscribe(topic: string, callback?: Callback) {\n const topicCallbacks = this.subscriptions[topic];\n if (!topicCallbacks) { return; }\n\n if (callback) {\n const idx = topicCallbacks.indexOf(callback);\n if (idx !== -1) {\n topicCallbacks.splice(idx, 1);\n this.channels.removeListener(topic, callback);\n }\n\n if (topicCallbacks.length === 0) {\n delete this.subscriptions[topic];\n }\n\n } else {\n topicCallbacks.forEach((cb) =>\n this.channels.removeListener(topic, cb));\n\n delete this.subscriptions[topic];\n }\n\n return this;\n }\n\n public publish(topic: string, data: any) {\n this.channels.emit(topic, data);\n return this;\n }\n\n public async exists(roomId: string): Promise<boolean> {\n return this.channels.listenerCount(roomId) > 0;\n }\n\n public set(key: string, value: string) {\n this.keys[key] = value;\n }\n\n public setex(key: string, value: string, seconds: number) {\n // ensure previous timeout is clear before setting another one.\n if (this.timeouts[key]) {\n clearTimeout(this.timeouts[key]);\n }\n\n this.keys[key] = value;\n this.timeouts[key] = setTimeout(() => {\n delete this.keys[key];\n delete this.timeouts[key];\n }, seconds * 1000);\n }\n\n public get(key: string) {\n return this.keys[key];\n }\n\n public del(key: string) {\n delete this.keys[key];\n delete this.data[key];\n delete this.hash[key];\n }\n\n public sadd(key: string, value: any) {\n if (!this.data[key]) {\n this.data[key] = [];\n }\n\n if (this.data[key].indexOf(value) === -1) {\n this.data[key].push(value);\n }\n }\n\n public async smembers(key: string): Promise<string[]> {\n return this.data[key] || [];\n }\n\n public async sismember(key: string, field: string) {\n return this.data[key] && this.data[key].includes(field) ? 1 : 0;\n }\n\n public srem(key: string, value: any) {\n if (this.data[key]) {\n spliceOne(this.data[key], this.data[key].indexOf(value));\n }\n }\n\n public scard(key: string) {\n return (this.data[key] || []).length;\n }\n\n public async sinter(...keys: string[]) {\n const intersection: {[value: string]: number} = {};\n\n for (let i = 0, l = keys.length; i < l; i++) {\n (await this.smembers(keys[i])).forEach((member) => {\n if (!intersection[member]) {\n intersection[member] = 0;\n }\n\n intersection[member]++;\n });\n }\n\n return Object.keys(intersection).reduce((prev, curr) => {\n if (intersection[curr] > 1) {\n prev.push(curr);\n }\n return prev;\n }, []);\n }\n\n public hset(key: string, field: string, value: string) {\n if (!this.hash[key]) { this.hash[key] = {}; }\n this.hash[key][field] = value;\n }\n\n public hincrby(key: string, field: string, incrBy: number) {\n if (!this.hash[key]) { this.hash[key] = {}; }\n let value = Number(this.hash[key][field] || '0');\n value += incrBy;\n this.hash[key][field] = value.toString();\n return value;\n }\n\n public async hget(key: string, field: string) {\n return this.hash[key] && this.hash[key][field];\n }\n\n public async hgetall(key: string) {\n return this.hash[key] || {};\n }\n\n public hdel(key: string, field: any) {\n const success = this.hash?.[key]?.[field] !== undefined;\n if (success) {\n delete this.hash[key][field];\n }\n return success;\n }\n\n public async hlen(key: string) {\n return this.hash[key] && Object.keys(this.hash[key]).length || 0;\n }\n\n public async incr(key: string) {\n if (!this.keys[key]) {\n this.keys[key] = 0;\n }\n (this.keys[key] as number)++;\n return Promise.resolve(this.keys[key] as number);\n }\n\n public async decr(key: string) {\n if (!this.keys[key]) {\n this.keys[key] = 0;\n }\n (this.keys[key] as number)--;\n return Promise.resolve(this.keys[key] as number);\n }\n\n public shutdown() {\n if (isDevMode) {\n const cache = JSON.stringify({\n data: this.data,\n hash: this.hash,\n keys: this.keys\n });\n fs.writeFileSync(DEVMODE_CACHE_FILE_PATH, cache, { encoding: \"utf-8\" });\n }\n }\n\n}\n"],
5
- "mappings": "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",
4
+ "sourcesContent": ["import fs from \"fs\";\nimport path from \"path\";\n\nimport { EventEmitter } from 'events';\nimport { spliceOne } from '../utils/Utils';\nimport { Presence } from './Presence';\n\nimport { isDevMode } from '../utils/DevMode';\n\ntype Callback = (...args: any[]) => void;\n\nconst DEVMODE_CACHE_FILE_PATH = path.resolve(\".devmode.json\");\n\nexport class LocalPresence implements Presence {\n public channels = new EventEmitter();\n\n public data: {[roomName: string]: string[]} = {};\n public hash: {[roomName: string]: {[key: string]: string}} = {};\n\n public keys: {[name: string]: string | number} = {};\n\n protected subscriptions: {[id: string]: Callback[]} = {};\n private timeouts: {[name: string]: NodeJS.Timeout} = {};\n\n constructor() {\n //\n // reload from local cache on devMode\n //\n if (\n isDevMode &&\n fs.existsSync(DEVMODE_CACHE_FILE_PATH)\n ) {\n const cache = fs.readFileSync(DEVMODE_CACHE_FILE_PATH).toString('utf-8') || \"{}\";\n const parsed = JSON.parse(cache);\n if (parsed.data) { this.data = parsed.data; }\n if (parsed.hash) { this.hash = parsed.hash; }\n if (parsed.keys) { this.keys = parsed.keys; }\n }\n }\n\n public subscribe(topic: string, callback: (...args: any[]) => void) {\n if (!this.subscriptions[topic]) { this.subscriptions[topic] = []; }\n this.subscriptions[topic].push(callback);\n this.channels.on(topic, callback);\n return this;\n }\n\n public unsubscribe(topic: string, callback?: Callback) {\n const topicCallbacks = this.subscriptions[topic];\n if (!topicCallbacks) { return; }\n\n if (callback) {\n const idx = topicCallbacks.indexOf(callback);\n if (idx !== -1) {\n topicCallbacks.splice(idx, 1);\n this.channels.removeListener(topic, callback);\n }\n\n if (topicCallbacks.length === 0) {\n delete this.subscriptions[topic];\n }\n\n } else {\n topicCallbacks.forEach((cb) =>\n this.channels.removeListener(topic, cb));\n\n delete this.subscriptions[topic];\n }\n\n return this;\n }\n\n public publish(topic: string, data: any) {\n this.channels.emit(topic, data);\n return this;\n }\n\n public async exists(roomId: string): Promise<boolean> {\n return this.channels.listenerCount(roomId) > 0;\n }\n\n public set(key: string, value: string) {\n this.keys[key] = value;\n }\n\n public setex(key: string, value: string, seconds: number) {\n // ensure previous timeout is clear before setting another one.\n if (this.timeouts[key]) {\n clearTimeout(this.timeouts[key]);\n }\n\n this.keys[key] = value;\n this.timeouts[key] = setTimeout(() => {\n delete this.keys[key];\n delete this.timeouts[key];\n }, seconds * 1000);\n }\n\n public get(key: string) {\n return this.keys[key];\n }\n\n public del(key: string) {\n delete this.keys[key];\n delete this.data[key];\n delete this.hash[key];\n }\n\n public sadd(key: string, value: any) {\n if (!this.data[key]) {\n this.data[key] = [];\n }\n\n if (this.data[key].indexOf(value) === -1) {\n this.data[key].push(value);\n }\n }\n\n public async smembers(key: string): Promise<string[]> {\n return this.data[key] || [];\n }\n\n public async sismember(key: string, field: string) {\n return this.data[key] && this.data[key].includes(field) ? 1 : 0;\n }\n\n public srem(key: string, value: any) {\n if (this.data[key]) {\n spliceOne(this.data[key], this.data[key].indexOf(value));\n }\n }\n\n public scard(key: string) {\n return (this.data[key] || []).length;\n }\n\n public async sinter(...keys: string[]) {\n const intersection: {[value: string]: number} = {};\n\n for (let i = 0, l = keys.length; i < l; i++) {\n (await this.smembers(keys[i])).forEach((member) => {\n if (!intersection[member]) {\n intersection[member] = 0;\n }\n\n intersection[member]++;\n });\n }\n\n return Object.keys(intersection).reduce((prev, curr) => {\n if (intersection[curr] > 1) {\n prev.push(curr);\n }\n return prev;\n }, []);\n }\n\n public hset(key: string, field: string, value: string) {\n if (!this.hash[key]) { this.hash[key] = {}; }\n this.hash[key][field] = value;\n }\n\n public hincrby(key: string, field: string, incrBy: number) {\n if (!this.hash[key]) { this.hash[key] = {}; }\n let value = Number(this.hash[key][field] || '0');\n value += incrBy;\n this.hash[key][field] = value.toString();\n return value;\n }\n\n public async hget(key: string, field: string) {\n return this.hash[key] && this.hash[key][field];\n }\n\n public async hgetall(key: string) {\n return this.hash[key] || {};\n }\n\n public hdel(key: string, field: any) {\n const success = this.hash?.[key]?.[field] !== undefined;\n if (success) {\n delete this.hash[key][field];\n }\n return success;\n }\n\n public async hlen(key: string) {\n return this.hash[key] && Object.keys(this.hash[key]).length || 0;\n }\n\n public async incr(key: string) {\n if (!this.keys[key]) {\n this.keys[key] = 0;\n }\n (this.keys[key] as number)++;\n return Promise.resolve(this.keys[key] as number);\n }\n\n public async decr(key: string) {\n if (!this.keys[key]) {\n this.keys[key] = 0;\n }\n (this.keys[key] as number)--;\n return Promise.resolve(this.keys[key] as number);\n }\n\n public shutdown() {\n if (isDevMode) {\n const cache = JSON.stringify({\n data: this.data,\n hash: this.hash,\n keys: this.keys\n });\n fs.writeFileSync(DEVMODE_CACHE_FILE_PATH, cache, { encoding: \"utf-8\" });\n }\n }\n\n}\n"],
5
+ "mappings": "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",
6
6
  "names": ["path", "fs"]
7
7
  }
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../../src/presence/LocalPresence.ts"],
4
- "sourcesContent": ["import fs from \"fs\";\nimport path from \"path\";\n\nimport { EventEmitter } from 'events';\nimport { spliceOne } from '../utils/Utils';\nimport { Presence } from './Presence';\n\nimport { isDevMode } from '../utils/DevMode';\n\ntype Callback = (...args: any[]) => void;\n\nconst DEVMODE_CACHE_FILE_PATH = path.resolve(\".devmode.json\");\n\nexport class LocalPresence implements Presence {\n public channels = new EventEmitter();\n\n public data: {[roomName: string]: string[]} = {};\n public hash: {[roomName: string]: {[key: string]: string}} = {};\n\n public keys: {[name: string]: string | number} = {};\n\n protected subscriptions: {[id: string]: Callback[]} = {};\n private timeouts: {[name: string]: NodeJS.Timer} = {};\n\n constructor() {\n //\n // reload from local cache on devMode\n //\n if (\n isDevMode &&\n fs.existsSync(DEVMODE_CACHE_FILE_PATH)\n ) {\n const cache = fs.readFileSync(DEVMODE_CACHE_FILE_PATH).toString('utf-8') || \"{}\";\n const parsed = JSON.parse(cache);\n if (parsed.data) { this.data = parsed.data; }\n if (parsed.hash) { this.hash = parsed.hash; }\n if (parsed.keys) { this.keys = parsed.keys; }\n }\n }\n\n public subscribe(topic: string, callback: (...args: any[]) => void) {\n if (!this.subscriptions[topic]) { this.subscriptions[topic] = []; }\n this.subscriptions[topic].push(callback);\n this.channels.on(topic, callback);\n return this;\n }\n\n public unsubscribe(topic: string, callback?: Callback) {\n const topicCallbacks = this.subscriptions[topic];\n if (!topicCallbacks) { return; }\n\n if (callback) {\n const idx = topicCallbacks.indexOf(callback);\n if (idx !== -1) {\n topicCallbacks.splice(idx, 1);\n this.channels.removeListener(topic, callback);\n }\n\n if (topicCallbacks.length === 0) {\n delete this.subscriptions[topic];\n }\n\n } else {\n topicCallbacks.forEach((cb) =>\n this.channels.removeListener(topic, cb));\n\n delete this.subscriptions[topic];\n }\n\n return this;\n }\n\n public publish(topic: string, data: any) {\n this.channels.emit(topic, data);\n return this;\n }\n\n public async exists(roomId: string): Promise<boolean> {\n return this.channels.listenerCount(roomId) > 0;\n }\n\n public set(key: string, value: string) {\n this.keys[key] = value;\n }\n\n public setex(key: string, value: string, seconds: number) {\n // ensure previous timeout is clear before setting another one.\n if (this.timeouts[key]) {\n clearTimeout(this.timeouts[key]);\n }\n\n this.keys[key] = value;\n this.timeouts[key] = setTimeout(() => {\n delete this.keys[key];\n delete this.timeouts[key];\n }, seconds * 1000);\n }\n\n public get(key: string) {\n return this.keys[key];\n }\n\n public del(key: string) {\n delete this.keys[key];\n delete this.data[key];\n delete this.hash[key];\n }\n\n public sadd(key: string, value: any) {\n if (!this.data[key]) {\n this.data[key] = [];\n }\n\n if (this.data[key].indexOf(value) === -1) {\n this.data[key].push(value);\n }\n }\n\n public async smembers(key: string): Promise<string[]> {\n return this.data[key] || [];\n }\n\n public async sismember(key: string, field: string) {\n return this.data[key] && this.data[key].includes(field) ? 1 : 0;\n }\n\n public srem(key: string, value: any) {\n if (this.data[key]) {\n spliceOne(this.data[key], this.data[key].indexOf(value));\n }\n }\n\n public scard(key: string) {\n return (this.data[key] || []).length;\n }\n\n public async sinter(...keys: string[]) {\n const intersection: {[value: string]: number} = {};\n\n for (let i = 0, l = keys.length; i < l; i++) {\n (await this.smembers(keys[i])).forEach((member) => {\n if (!intersection[member]) {\n intersection[member] = 0;\n }\n\n intersection[member]++;\n });\n }\n\n return Object.keys(intersection).reduce((prev, curr) => {\n if (intersection[curr] > 1) {\n prev.push(curr);\n }\n return prev;\n }, []);\n }\n\n public hset(key: string, field: string, value: string) {\n if (!this.hash[key]) { this.hash[key] = {}; }\n this.hash[key][field] = value;\n }\n\n public hincrby(key: string, field: string, incrBy: number) {\n if (!this.hash[key]) { this.hash[key] = {}; }\n let value = Number(this.hash[key][field] || '0');\n value += incrBy;\n this.hash[key][field] = value.toString();\n return value;\n }\n\n public async hget(key: string, field: string) {\n return this.hash[key] && this.hash[key][field];\n }\n\n public async hgetall(key: string) {\n return this.hash[key] || {};\n }\n\n public hdel(key: string, field: any) {\n const success = this.hash?.[key]?.[field] !== undefined;\n if (success) {\n delete this.hash[key][field];\n }\n return success;\n }\n\n public async hlen(key: string) {\n return this.hash[key] && Object.keys(this.hash[key]).length || 0;\n }\n\n public async incr(key: string) {\n if (!this.keys[key]) {\n this.keys[key] = 0;\n }\n (this.keys[key] as number)++;\n return Promise.resolve(this.keys[key] as number);\n }\n\n public async decr(key: string) {\n if (!this.keys[key]) {\n this.keys[key] = 0;\n }\n (this.keys[key] as number)--;\n return Promise.resolve(this.keys[key] as number);\n }\n\n public shutdown() {\n if (isDevMode) {\n const cache = JSON.stringify({\n data: this.data,\n hash: this.hash,\n keys: this.keys\n });\n fs.writeFileSync(DEVMODE_CACHE_FILE_PATH, cache, { encoding: \"utf-8\" });\n }\n }\n\n}\n"],
5
- "mappings": "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",
4
+ "sourcesContent": ["import fs from \"fs\";\nimport path from \"path\";\n\nimport { EventEmitter } from 'events';\nimport { spliceOne } from '../utils/Utils';\nimport { Presence } from './Presence';\n\nimport { isDevMode } from '../utils/DevMode';\n\ntype Callback = (...args: any[]) => void;\n\nconst DEVMODE_CACHE_FILE_PATH = path.resolve(\".devmode.json\");\n\nexport class LocalPresence implements Presence {\n public channels = new EventEmitter();\n\n public data: {[roomName: string]: string[]} = {};\n public hash: {[roomName: string]: {[key: string]: string}} = {};\n\n public keys: {[name: string]: string | number} = {};\n\n protected subscriptions: {[id: string]: Callback[]} = {};\n private timeouts: {[name: string]: NodeJS.Timeout} = {};\n\n constructor() {\n //\n // reload from local cache on devMode\n //\n if (\n isDevMode &&\n fs.existsSync(DEVMODE_CACHE_FILE_PATH)\n ) {\n const cache = fs.readFileSync(DEVMODE_CACHE_FILE_PATH).toString('utf-8') || \"{}\";\n const parsed = JSON.parse(cache);\n if (parsed.data) { this.data = parsed.data; }\n if (parsed.hash) { this.hash = parsed.hash; }\n if (parsed.keys) { this.keys = parsed.keys; }\n }\n }\n\n public subscribe(topic: string, callback: (...args: any[]) => void) {\n if (!this.subscriptions[topic]) { this.subscriptions[topic] = []; }\n this.subscriptions[topic].push(callback);\n this.channels.on(topic, callback);\n return this;\n }\n\n public unsubscribe(topic: string, callback?: Callback) {\n const topicCallbacks = this.subscriptions[topic];\n if (!topicCallbacks) { return; }\n\n if (callback) {\n const idx = topicCallbacks.indexOf(callback);\n if (idx !== -1) {\n topicCallbacks.splice(idx, 1);\n this.channels.removeListener(topic, callback);\n }\n\n if (topicCallbacks.length === 0) {\n delete this.subscriptions[topic];\n }\n\n } else {\n topicCallbacks.forEach((cb) =>\n this.channels.removeListener(topic, cb));\n\n delete this.subscriptions[topic];\n }\n\n return this;\n }\n\n public publish(topic: string, data: any) {\n this.channels.emit(topic, data);\n return this;\n }\n\n public async exists(roomId: string): Promise<boolean> {\n return this.channels.listenerCount(roomId) > 0;\n }\n\n public set(key: string, value: string) {\n this.keys[key] = value;\n }\n\n public setex(key: string, value: string, seconds: number) {\n // ensure previous timeout is clear before setting another one.\n if (this.timeouts[key]) {\n clearTimeout(this.timeouts[key]);\n }\n\n this.keys[key] = value;\n this.timeouts[key] = setTimeout(() => {\n delete this.keys[key];\n delete this.timeouts[key];\n }, seconds * 1000);\n }\n\n public get(key: string) {\n return this.keys[key];\n }\n\n public del(key: string) {\n delete this.keys[key];\n delete this.data[key];\n delete this.hash[key];\n }\n\n public sadd(key: string, value: any) {\n if (!this.data[key]) {\n this.data[key] = [];\n }\n\n if (this.data[key].indexOf(value) === -1) {\n this.data[key].push(value);\n }\n }\n\n public async smembers(key: string): Promise<string[]> {\n return this.data[key] || [];\n }\n\n public async sismember(key: string, field: string) {\n return this.data[key] && this.data[key].includes(field) ? 1 : 0;\n }\n\n public srem(key: string, value: any) {\n if (this.data[key]) {\n spliceOne(this.data[key], this.data[key].indexOf(value));\n }\n }\n\n public scard(key: string) {\n return (this.data[key] || []).length;\n }\n\n public async sinter(...keys: string[]) {\n const intersection: {[value: string]: number} = {};\n\n for (let i = 0, l = keys.length; i < l; i++) {\n (await this.smembers(keys[i])).forEach((member) => {\n if (!intersection[member]) {\n intersection[member] = 0;\n }\n\n intersection[member]++;\n });\n }\n\n return Object.keys(intersection).reduce((prev, curr) => {\n if (intersection[curr] > 1) {\n prev.push(curr);\n }\n return prev;\n }, []);\n }\n\n public hset(key: string, field: string, value: string) {\n if (!this.hash[key]) { this.hash[key] = {}; }\n this.hash[key][field] = value;\n }\n\n public hincrby(key: string, field: string, incrBy: number) {\n if (!this.hash[key]) { this.hash[key] = {}; }\n let value = Number(this.hash[key][field] || '0');\n value += incrBy;\n this.hash[key][field] = value.toString();\n return value;\n }\n\n public async hget(key: string, field: string) {\n return this.hash[key] && this.hash[key][field];\n }\n\n public async hgetall(key: string) {\n return this.hash[key] || {};\n }\n\n public hdel(key: string, field: any) {\n const success = this.hash?.[key]?.[field] !== undefined;\n if (success) {\n delete this.hash[key][field];\n }\n return success;\n }\n\n public async hlen(key: string) {\n return this.hash[key] && Object.keys(this.hash[key]).length || 0;\n }\n\n public async incr(key: string) {\n if (!this.keys[key]) {\n this.keys[key] = 0;\n }\n (this.keys[key] as number)++;\n return Promise.resolve(this.keys[key] as number);\n }\n\n public async decr(key: string) {\n if (!this.keys[key]) {\n this.keys[key] = 0;\n }\n (this.keys[key] as number)--;\n return Promise.resolve(this.keys[key] as number);\n }\n\n public shutdown() {\n if (isDevMode) {\n const cache = JSON.stringify({\n data: this.data,\n hash: this.hash,\n keys: this.keys\n });\n fs.writeFileSync(DEVMODE_CACHE_FILE_PATH, cache, { encoding: \"utf-8\" });\n }\n }\n\n}\n"],
5
+ "mappings": "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",
6
6
  "names": []
7
7
  }
@@ -22,14 +22,13 @@ __export(RelayRoom_exports, {
22
22
  module.exports = __toCommonJS(RelayRoom_exports);
23
23
  var import_schema = require("@colyseus/schema");
24
24
  var import_Room = require("../Room");
25
- const context = new import_schema.Context();
26
25
  class Player extends import_schema.Schema {
27
26
  }
28
27
  (0, import_schema.defineTypes)(Player, {
29
28
  connected: "boolean",
30
29
  name: "string",
31
30
  sessionId: "string"
32
- }, { context });
31
+ });
33
32
  class State extends import_schema.Schema {
34
33
  constructor() {
35
34
  super(...arguments);
@@ -38,7 +37,7 @@ class State extends import_schema.Schema {
38
37
  }
39
38
  (0, import_schema.defineTypes)(State, {
40
39
  players: { map: Player }
41
- }, { context });
40
+ });
42
41
  class RelayRoom extends import_Room.Room {
43
42
  constructor() {
44
43
  super(...arguments);
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../../src/rooms/RelayRoom.ts"],
4
- "sourcesContent": ["import { Context, defineTypes, MapSchema, Schema } from '@colyseus/schema';\n\nimport { Room } from '../Room';\nimport { Client } from '../Transport';\n\n/**\n * Create another context to avoid these types from being in the user's global `Context`\n */\nconst context = new Context();\n\nclass Player extends Schema { // tslint:disable-line\n public connected: boolean;\n public name: string;\n public sessionId: string;\n}\ndefineTypes(Player, {\n connected: 'boolean',\n name: 'string',\n sessionId: 'string',\n}, { context });\n\nclass State extends Schema { // tslint:disable-line\n public players = new MapSchema<Player>();\n}\ndefineTypes(State, {\n players: { map: Player },\n}, { context });\n\n/**\n * client.joinOrCreate(\"relayroom\", {\n * maxClients: 10,\n * allowReconnectionTime: 20\n * });\n */\n\nexport class RelayRoom extends Room<State> { // tslint:disable-line\n public allowReconnectionTime: number = 0;\n\n public onCreate(options: Partial<{\n maxClients: number,\n allowReconnectionTime: number,\n metadata: any,\n }>) {\n this.setState(new State());\n\n if (options.maxClients) {\n this.maxClients = options.maxClients;\n }\n\n if (options.allowReconnectionTime) {\n this.allowReconnectionTime = Math.min(options.allowReconnectionTime, 40);\n }\n\n if (options.metadata) {\n this.setMetadata(options.metadata);\n }\n\n this.onMessage('*', (client: Client, type: string, message: any) => {\n this.broadcast(type, [client.sessionId, message], { except: client });\n });\n }\n\n public onJoin(client: Client, options: any = {}) {\n const player = new Player();\n\n player.connected = true;\n player.sessionId = client.sessionId;\n\n if (options.name) {\n player.name = options.name;\n }\n\n this.state.players.set(client.sessionId, player);\n }\n\n public async onLeave(client: Client, consented: boolean) {\n if (this.allowReconnectionTime > 0) {\n const player = this.state.players.get(client.sessionId);\n player.connected = false;\n\n try {\n if (consented) {\n throw new Error('consented leave');\n }\n\n await this.allowReconnection(client, this.allowReconnectionTime);\n player.connected = true;\n\n } catch (e) {\n this.state.players.delete(client.sessionId);\n }\n }\n }\n\n}\n"],
5
- "mappings": ";;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,oBAAwD;AAExD,kBAAqB;AAMrB,MAAM,UAAU,IAAI,sBAAQ;AAE5B,MAAM,eAAe,qBAAO;AAI5B;AAAA,IACA,2BAAY,QAAQ;AAAA,EAClB,WAAW;AAAA,EACX,MAAM;AAAA,EACN,WAAW;AACb,GAAG,EAAE,QAAQ,CAAC;AAEd,MAAM,cAAc,qBAAO;AAAA,EAA3B;AAAA;AACE,SAAO,UAAU,IAAI,wBAAkB;AAAA;AACzC;AAAA,IACA,2BAAY,OAAO;AAAA,EACjB,SAAS,EAAE,KAAK,OAAO;AACzB,GAAG,EAAE,QAAQ,CAAC;AASP,MAAM,kBAAkB,iBAAY;AAAA,EAApC;AAAA;AACL,SAAO,wBAAgC;AAAA;AAAA,EAEhC,SAAS,SAIZ;AACF,SAAK,SAAS,IAAI,MAAM,CAAC;AAEzB,QAAI,QAAQ,YAAY;AACtB,WAAK,aAAa,QAAQ;AAAA,IAC5B;AAEA,QAAI,QAAQ,uBAAuB;AACjC,WAAK,wBAAwB,KAAK,IAAI,QAAQ,uBAAuB,EAAE;AAAA,IACzE;AAEA,QAAI,QAAQ,UAAU;AACpB,WAAK,YAAY,QAAQ,QAAQ;AAAA,IACnC;AAEA,SAAK,UAAU,KAAK,CAAC,QAAgB,MAAc,YAAiB;AAClE,WAAK,UAAU,MAAM,CAAC,OAAO,WAAW,OAAO,GAAG,EAAE,QAAQ,OAAO,CAAC;AAAA,IACtE,CAAC;AAAA,EACH;AAAA,EAEO,OAAO,QAAgB,UAAe,CAAC,GAAG;AAC/C,UAAM,SAAS,IAAI,OAAO;AAE1B,WAAO,YAAY;AACnB,WAAO,YAAY,OAAO;AAE1B,QAAI,QAAQ,MAAM;AAChB,aAAO,OAAO,QAAQ;AAAA,IACxB;AAEA,SAAK,MAAM,QAAQ,IAAI,OAAO,WAAW,MAAM;AAAA,EACjD;AAAA,EAEA,MAAa,QAAQ,QAAgB,WAAoB;AACvD,QAAI,KAAK,wBAAwB,GAAG;AAClC,YAAM,SAAS,KAAK,MAAM,QAAQ,IAAI,OAAO,SAAS;AACtD,aAAO,YAAY;AAEnB,UAAI;AACF,YAAI,WAAW;AACb,gBAAM,IAAI,MAAM,iBAAiB;AAAA,QACnC;AAEA,cAAM,KAAK,kBAAkB,QAAQ,KAAK,qBAAqB;AAC/D,eAAO,YAAY;AAAA,MAErB,SAAS,GAAP;AACA,aAAK,MAAM,QAAQ,OAAO,OAAO,SAAS;AAAA,MAC5C;AAAA,IACF;AAAA,EACF;AAEF;",
4
+ "sourcesContent": ["import { defineTypes, MapSchema, Schema } from '@colyseus/schema';\n\nimport { Room } from '../Room';\nimport { Client } from '../Transport';\n\nclass Player extends Schema { // tslint:disable-line\n public connected: boolean;\n public name: string;\n public sessionId: string;\n}\ndefineTypes(Player, {\n connected: 'boolean',\n name: 'string',\n sessionId: 'string',\n});\n\nclass State extends Schema { // tslint:disable-line\n public players = new MapSchema<Player>();\n}\ndefineTypes(State, {\n players: { map: Player },\n});\n\n/**\n * client.joinOrCreate(\"relayroom\", {\n * maxClients: 10,\n * allowReconnectionTime: 20\n * });\n */\n\nexport class RelayRoom extends Room<State> { // tslint:disable-line\n public allowReconnectionTime: number = 0;\n\n public onCreate(options: Partial<{\n maxClients: number,\n allowReconnectionTime: number,\n metadata: any,\n }>) {\n this.setState(new State());\n\n if (options.maxClients) {\n this.maxClients = options.maxClients;\n }\n\n if (options.allowReconnectionTime) {\n this.allowReconnectionTime = Math.min(options.allowReconnectionTime, 40);\n }\n\n if (options.metadata) {\n this.setMetadata(options.metadata);\n }\n\n this.onMessage('*', (client: Client, type: string, message: any) => {\n this.broadcast(type, [client.sessionId, message], { except: client });\n });\n }\n\n public onJoin(client: Client, options: any = {}) {\n const player = new Player();\n\n player.connected = true;\n player.sessionId = client.sessionId;\n\n if (options.name) {\n player.name = options.name;\n }\n\n this.state.players.set(client.sessionId, player);\n }\n\n public async onLeave(client: Client, consented: boolean) {\n if (this.allowReconnectionTime > 0) {\n const player = this.state.players.get(client.sessionId);\n player.connected = false;\n\n try {\n if (consented) {\n throw new Error('consented leave');\n }\n\n await this.allowReconnection(client, this.allowReconnectionTime);\n player.connected = true;\n\n } catch (e) {\n this.state.players.delete(client.sessionId);\n }\n }\n }\n\n}\n"],
5
+ "mappings": ";;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,oBAA+C;AAE/C,kBAAqB;AAGrB,MAAM,eAAe,qBAAO;AAI5B;AAAA,IACA,2BAAY,QAAQ;AAAA,EAClB,WAAW;AAAA,EACX,MAAM;AAAA,EACN,WAAW;AACb,CAAC;AAED,MAAM,cAAc,qBAAO;AAAA,EAA3B;AAAA;AACE,SAAO,UAAU,IAAI,wBAAkB;AAAA;AACzC;AAAA,IACA,2BAAY,OAAO;AAAA,EACjB,SAAS,EAAE,KAAK,OAAO;AACzB,CAAC;AASM,MAAM,kBAAkB,iBAAY;AAAA,EAApC;AAAA;AACL,SAAO,wBAAgC;AAAA;AAAA,EAEhC,SAAS,SAIZ;AACF,SAAK,SAAS,IAAI,MAAM,CAAC;AAEzB,QAAI,QAAQ,YAAY;AACtB,WAAK,aAAa,QAAQ;AAAA,IAC5B;AAEA,QAAI,QAAQ,uBAAuB;AACjC,WAAK,wBAAwB,KAAK,IAAI,QAAQ,uBAAuB,EAAE;AAAA,IACzE;AAEA,QAAI,QAAQ,UAAU;AACpB,WAAK,YAAY,QAAQ,QAAQ;AAAA,IACnC;AAEA,SAAK,UAAU,KAAK,CAAC,QAAgB,MAAc,YAAiB;AAClE,WAAK,UAAU,MAAM,CAAC,OAAO,WAAW,OAAO,GAAG,EAAE,QAAQ,OAAO,CAAC;AAAA,IACtE,CAAC;AAAA,EACH;AAAA,EAEO,OAAO,QAAgB,UAAe,CAAC,GAAG;AAC/C,UAAM,SAAS,IAAI,OAAO;AAE1B,WAAO,YAAY;AACnB,WAAO,YAAY,OAAO;AAE1B,QAAI,QAAQ,MAAM;AAChB,aAAO,OAAO,QAAQ;AAAA,IACxB;AAEA,SAAK,MAAM,QAAQ,IAAI,OAAO,WAAW,MAAM;AAAA,EACjD;AAAA,EAEA,MAAa,QAAQ,QAAgB,WAAoB;AACvD,QAAI,KAAK,wBAAwB,GAAG;AAClC,YAAM,SAAS,KAAK,MAAM,QAAQ,IAAI,OAAO,SAAS;AACtD,aAAO,YAAY;AAEnB,UAAI;AACF,YAAI,WAAW;AACb,gBAAM,IAAI,MAAM,iBAAiB;AAAA,QACnC;AAEA,cAAM,KAAK,kBAAkB,QAAQ,KAAK,qBAAqB;AAC/D,eAAO,YAAY;AAAA,MAErB,SAAS,GAAP;AACA,aAAK,MAAM,QAAQ,OAAO,OAAO,SAAS;AAAA,MAC5C;AAAA,IACF;AAAA,EACF;AAEF;",
6
6
  "names": []
7
7
  }
@@ -1,13 +1,12 @@
1
- import { Context, defineTypes, MapSchema, Schema } from "@colyseus/schema";
1
+ import { defineTypes, MapSchema, Schema } from "@colyseus/schema";
2
2
  import { Room } from "../Room";
3
- const context = new Context();
4
3
  class Player extends Schema {
5
4
  }
6
5
  defineTypes(Player, {
7
6
  connected: "boolean",
8
7
  name: "string",
9
8
  sessionId: "string"
10
- }, { context });
9
+ });
11
10
  class State extends Schema {
12
11
  constructor() {
13
12
  super(...arguments);
@@ -16,7 +15,7 @@ class State extends Schema {
16
15
  }
17
16
  defineTypes(State, {
18
17
  players: { map: Player }
19
- }, { context });
18
+ });
20
19
  class RelayRoom extends Room {
21
20
  constructor() {
22
21
  super(...arguments);
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../../src/rooms/RelayRoom.ts"],
4
- "sourcesContent": ["import { Context, defineTypes, MapSchema, Schema } from '@colyseus/schema';\n\nimport { Room } from '../Room';\nimport { Client } from '../Transport';\n\n/**\n * Create another context to avoid these types from being in the user's global `Context`\n */\nconst context = new Context();\n\nclass Player extends Schema { // tslint:disable-line\n public connected: boolean;\n public name: string;\n public sessionId: string;\n}\ndefineTypes(Player, {\n connected: 'boolean',\n name: 'string',\n sessionId: 'string',\n}, { context });\n\nclass State extends Schema { // tslint:disable-line\n public players = new MapSchema<Player>();\n}\ndefineTypes(State, {\n players: { map: Player },\n}, { context });\n\n/**\n * client.joinOrCreate(\"relayroom\", {\n * maxClients: 10,\n * allowReconnectionTime: 20\n * });\n */\n\nexport class RelayRoom extends Room<State> { // tslint:disable-line\n public allowReconnectionTime: number = 0;\n\n public onCreate(options: Partial<{\n maxClients: number,\n allowReconnectionTime: number,\n metadata: any,\n }>) {\n this.setState(new State());\n\n if (options.maxClients) {\n this.maxClients = options.maxClients;\n }\n\n if (options.allowReconnectionTime) {\n this.allowReconnectionTime = Math.min(options.allowReconnectionTime, 40);\n }\n\n if (options.metadata) {\n this.setMetadata(options.metadata);\n }\n\n this.onMessage('*', (client: Client, type: string, message: any) => {\n this.broadcast(type, [client.sessionId, message], { except: client });\n });\n }\n\n public onJoin(client: Client, options: any = {}) {\n const player = new Player();\n\n player.connected = true;\n player.sessionId = client.sessionId;\n\n if (options.name) {\n player.name = options.name;\n }\n\n this.state.players.set(client.sessionId, player);\n }\n\n public async onLeave(client: Client, consented: boolean) {\n if (this.allowReconnectionTime > 0) {\n const player = this.state.players.get(client.sessionId);\n player.connected = false;\n\n try {\n if (consented) {\n throw new Error('consented leave');\n }\n\n await this.allowReconnection(client, this.allowReconnectionTime);\n player.connected = true;\n\n } catch (e) {\n this.state.players.delete(client.sessionId);\n }\n }\n }\n\n}\n"],
5
- "mappings": "AAAA,SAAS,SAAS,aAAa,WAAW,cAAc;AAExD,SAAS,YAAY;AAMrB,MAAM,UAAU,IAAI,QAAQ;AAE5B,MAAM,eAAe,OAAO;AAI5B;AACA,YAAY,QAAQ;AAAA,EAClB,WAAW;AAAA,EACX,MAAM;AAAA,EACN,WAAW;AACb,GAAG,EAAE,QAAQ,CAAC;AAEd,MAAM,cAAc,OAAO;AAAA,EAA3B;AAAA;AACE,SAAO,UAAU,IAAI,UAAkB;AAAA;AACzC;AACA,YAAY,OAAO;AAAA,EACjB,SAAS,EAAE,KAAK,OAAO;AACzB,GAAG,EAAE,QAAQ,CAAC;AASP,MAAM,kBAAkB,KAAY;AAAA,EAApC;AAAA;AACL,SAAO,wBAAgC;AAAA;AAAA,EAEhC,SAAS,SAIZ;AACF,SAAK,SAAS,IAAI,MAAM,CAAC;AAEzB,QAAI,QAAQ,YAAY;AACtB,WAAK,aAAa,QAAQ;AAAA,IAC5B;AAEA,QAAI,QAAQ,uBAAuB;AACjC,WAAK,wBAAwB,KAAK,IAAI,QAAQ,uBAAuB,EAAE;AAAA,IACzE;AAEA,QAAI,QAAQ,UAAU;AACpB,WAAK,YAAY,QAAQ,QAAQ;AAAA,IACnC;AAEA,SAAK,UAAU,KAAK,CAAC,QAAgB,MAAc,YAAiB;AAClE,WAAK,UAAU,MAAM,CAAC,OAAO,WAAW,OAAO,GAAG,EAAE,QAAQ,OAAO,CAAC;AAAA,IACtE,CAAC;AAAA,EACH;AAAA,EAEO,OAAO,QAAgB,UAAe,CAAC,GAAG;AAC/C,UAAM,SAAS,IAAI,OAAO;AAE1B,WAAO,YAAY;AACnB,WAAO,YAAY,OAAO;AAE1B,QAAI,QAAQ,MAAM;AAChB,aAAO,OAAO,QAAQ;AAAA,IACxB;AAEA,SAAK,MAAM,QAAQ,IAAI,OAAO,WAAW,MAAM;AAAA,EACjD;AAAA,EAEA,MAAa,QAAQ,QAAgB,WAAoB;AACvD,QAAI,KAAK,wBAAwB,GAAG;AAClC,YAAM,SAAS,KAAK,MAAM,QAAQ,IAAI,OAAO,SAAS;AACtD,aAAO,YAAY;AAEnB,UAAI;AACF,YAAI,WAAW;AACb,gBAAM,IAAI,MAAM,iBAAiB;AAAA,QACnC;AAEA,cAAM,KAAK,kBAAkB,QAAQ,KAAK,qBAAqB;AAC/D,eAAO,YAAY;AAAA,MAErB,SAAS,GAAP;AACA,aAAK,MAAM,QAAQ,OAAO,OAAO,SAAS;AAAA,MAC5C;AAAA,IACF;AAAA,EACF;AAEF;",
4
+ "sourcesContent": ["import { defineTypes, MapSchema, Schema } from '@colyseus/schema';\n\nimport { Room } from '../Room';\nimport { Client } from '../Transport';\n\nclass Player extends Schema { // tslint:disable-line\n public connected: boolean;\n public name: string;\n public sessionId: string;\n}\ndefineTypes(Player, {\n connected: 'boolean',\n name: 'string',\n sessionId: 'string',\n});\n\nclass State extends Schema { // tslint:disable-line\n public players = new MapSchema<Player>();\n}\ndefineTypes(State, {\n players: { map: Player },\n});\n\n/**\n * client.joinOrCreate(\"relayroom\", {\n * maxClients: 10,\n * allowReconnectionTime: 20\n * });\n */\n\nexport class RelayRoom extends Room<State> { // tslint:disable-line\n public allowReconnectionTime: number = 0;\n\n public onCreate(options: Partial<{\n maxClients: number,\n allowReconnectionTime: number,\n metadata: any,\n }>) {\n this.setState(new State());\n\n if (options.maxClients) {\n this.maxClients = options.maxClients;\n }\n\n if (options.allowReconnectionTime) {\n this.allowReconnectionTime = Math.min(options.allowReconnectionTime, 40);\n }\n\n if (options.metadata) {\n this.setMetadata(options.metadata);\n }\n\n this.onMessage('*', (client: Client, type: string, message: any) => {\n this.broadcast(type, [client.sessionId, message], { except: client });\n });\n }\n\n public onJoin(client: Client, options: any = {}) {\n const player = new Player();\n\n player.connected = true;\n player.sessionId = client.sessionId;\n\n if (options.name) {\n player.name = options.name;\n }\n\n this.state.players.set(client.sessionId, player);\n }\n\n public async onLeave(client: Client, consented: boolean) {\n if (this.allowReconnectionTime > 0) {\n const player = this.state.players.get(client.sessionId);\n player.connected = false;\n\n try {\n if (consented) {\n throw new Error('consented leave');\n }\n\n await this.allowReconnection(client, this.allowReconnectionTime);\n player.connected = true;\n\n } catch (e) {\n this.state.players.delete(client.sessionId);\n }\n }\n }\n\n}\n"],
5
+ "mappings": "AAAA,SAAS,aAAa,WAAW,cAAc;AAE/C,SAAS,YAAY;AAGrB,MAAM,eAAe,OAAO;AAI5B;AACA,YAAY,QAAQ;AAAA,EAClB,WAAW;AAAA,EACX,MAAM;AAAA,EACN,WAAW;AACb,CAAC;AAED,MAAM,cAAc,OAAO;AAAA,EAA3B;AAAA;AACE,SAAO,UAAU,IAAI,UAAkB;AAAA;AACzC;AACA,YAAY,OAAO;AAAA,EACjB,SAAS,EAAE,KAAK,OAAO;AACzB,CAAC;AASM,MAAM,kBAAkB,KAAY;AAAA,EAApC;AAAA;AACL,SAAO,wBAAgC;AAAA;AAAA,EAEhC,SAAS,SAIZ;AACF,SAAK,SAAS,IAAI,MAAM,CAAC;AAEzB,QAAI,QAAQ,YAAY;AACtB,WAAK,aAAa,QAAQ;AAAA,IAC5B;AAEA,QAAI,QAAQ,uBAAuB;AACjC,WAAK,wBAAwB,KAAK,IAAI,QAAQ,uBAAuB,EAAE;AAAA,IACzE;AAEA,QAAI,QAAQ,UAAU;AACpB,WAAK,YAAY,QAAQ,QAAQ;AAAA,IACnC;AAEA,SAAK,UAAU,KAAK,CAAC,QAAgB,MAAc,YAAiB;AAClE,WAAK,UAAU,MAAM,CAAC,OAAO,WAAW,OAAO,GAAG,EAAE,QAAQ,OAAO,CAAC;AAAA,IACtE,CAAC;AAAA,EACH;AAAA,EAEO,OAAO,QAAgB,UAAe,CAAC,GAAG;AAC/C,UAAM,SAAS,IAAI,OAAO;AAE1B,WAAO,YAAY;AACnB,WAAO,YAAY,OAAO;AAE1B,QAAI,QAAQ,MAAM;AAChB,aAAO,OAAO,QAAQ;AAAA,IACxB;AAEA,SAAK,MAAM,QAAQ,IAAI,OAAO,WAAW,MAAM;AAAA,EACjD;AAAA,EAEA,MAAa,QAAQ,QAAgB,WAAoB;AACvD,QAAI,KAAK,wBAAwB,GAAG;AAClC,YAAM,SAAS,KAAK,MAAM,QAAQ,IAAI,OAAO,SAAS;AACtD,aAAO,YAAY;AAEnB,UAAI;AACF,YAAI,WAAW;AACb,gBAAM,IAAI,MAAM,iBAAiB;AAAA,QACnC;AAEA,cAAM,KAAK,kBAAkB,QAAQ,KAAK,qBAAqB;AAC/D,eAAO,YAAY;AAAA,MAErB,SAAS,GAAP;AACA,aAAK,MAAM,QAAQ,OAAO,OAAO,SAAS;AAAA,MAC5C;AAAA,IACF;AAAA,EACF;AAEF;",
6
6
  "names": []
7
7
  }
@@ -1,15 +1,18 @@
1
- import { Client } from '..';
1
+ /// <reference types="node" />
2
2
  import { Serializer } from './Serializer';
3
3
  import { Schema } from '@colyseus/schema';
4
+ import { Client } from '../Transport';
4
5
  export declare class SchemaSerializer<T> implements Serializer<T> {
5
6
  id: string;
6
- private state;
7
- private useFilters;
7
+ private encoder;
8
+ private hasFilters;
8
9
  private handshakeCache;
10
+ private fullEncodeCache;
11
+ private sharedOffsetCache;
12
+ private views;
9
13
  private needFullEncode;
10
- private fullEncodedState;
11
14
  reset(newState: T & Schema): void;
12
- getFullState(client?: Client): number[];
15
+ getFullState(client?: Client): Buffer;
13
16
  applyPatches(clients: Client[]): boolean;
14
- handshake(): number[];
17
+ handshake(): Buffer;
15
18
  }
@@ -23,68 +23,83 @@ module.exports = __toCommonJS(SchemaSerializer_exports);
23
23
  var import_schema = require("@colyseus/schema");
24
24
  var import_Debug = require("../Debug");
25
25
  var import_Protocol = require("../Protocol");
26
- var import_Transport = require("../Transport");
26
+ const STATE_PATCH_BUFFER = Buffer.from([import_Protocol.Protocol.ROOM_STATE_PATCH]);
27
+ const SHARED_VIEW = {};
27
28
  class SchemaSerializer {
28
29
  constructor() {
29
30
  this.id = "schema";
30
- this.useFilters = false;
31
+ this.hasFilters = false;
32
+ this.sharedOffsetCache = { offset: 0 };
33
+ this.views = /* @__PURE__ */ new WeakMap();
31
34
  this.needFullEncode = true;
32
35
  }
33
36
  reset(newState) {
34
- this.state = newState;
35
- this.useFilters = (0, import_schema.hasFilter)(newState.constructor);
37
+ this.encoder = new import_schema.Encoder(newState);
38
+ this.hasFilters = this.encoder.context.hasFilters;
39
+ if (this.hasFilters) {
40
+ this.views = /* @__PURE__ */ new WeakMap();
41
+ }
36
42
  }
37
43
  getFullState(client) {
38
- const fullEncodedState = this.needFullEncode ? this.state.encodeAll(this.useFilters) : this.fullEncodedState;
39
- this.fullEncodedState = fullEncodedState;
40
- this.needFullEncode = false;
41
- if (client && this.useFilters) {
42
- return this.state.applyFilters(client, true);
44
+ if (this.needFullEncode) {
45
+ this.sharedOffsetCache = { offset: 0 };
46
+ this.fullEncodeCache = this.encoder.encodeAll(this.sharedOffsetCache);
47
+ this.needFullEncode = false;
48
+ }
49
+ if (this.hasFilters && client?.view) {
50
+ return this.encoder.encodeAllView(
51
+ client.view,
52
+ this.sharedOffsetCache.offset,
53
+ { ...this.sharedOffsetCache },
54
+ this.fullEncodeCache
55
+ );
43
56
  } else {
44
- return fullEncodedState;
57
+ return this.fullEncodeCache;
45
58
  }
46
59
  }
47
60
  applyPatches(clients) {
48
- const hasChanges = this.state["$changes"].changes.size > 0;
49
- if (hasChanges) {
50
- this.needFullEncode = true;
51
- let numClients = clients.length;
52
- if (import_Debug.debugPatch.enabled) {
53
- import_Debug.debugPatch.dumpChanges = (0, import_schema.dumpChanges)(this.state);
61
+ this.needFullEncode = this.encoder.root.changes.size > 0;
62
+ if (!this.needFullEncode && (!this.hasFilters || this.encoder.root.filteredChanges.size === 0)) {
63
+ return false;
64
+ }
65
+ let numClients = clients.length;
66
+ if (import_Debug.debugPatch.enabled) {
67
+ import_Debug.debugPatch.dumpChanges = (0, import_schema.dumpChanges)(this.encoder.state);
68
+ }
69
+ const it = { offset: 0 };
70
+ const encodedChanges = this.encoder.encode(it);
71
+ if (!this.hasFilters) {
72
+ const sharedChanges = Buffer.concat([STATE_PATCH_BUFFER, encodedChanges]);
73
+ while (numClients--) {
74
+ clients[numClients].raw(sharedChanges);
54
75
  }
55
- const patches = this.state.encode(false, [], this.useFilters);
56
- if (!this.useFilters) {
57
- patches.unshift(import_Protocol.Protocol.ROOM_STATE_PATCH);
58
- while (numClients--) {
59
- const client = clients[numClients];
60
- if (client.state === import_Transport.ClientState.JOINED) {
61
- client.raw(patches);
62
- }
63
- }
64
- } else {
65
- while (numClients--) {
66
- const client = clients[numClients];
67
- if (client.state === import_Transport.ClientState.JOINED) {
68
- const filteredPatches = this.state.applyFilters(client);
69
- client.raw([import_Protocol.Protocol.ROOM_STATE_PATCH, ...filteredPatches]);
70
- }
76
+ } else {
77
+ const sharedOffset = it.offset;
78
+ while (numClients--) {
79
+ const client = clients[numClients];
80
+ const view = client.view || SHARED_VIEW;
81
+ let encodedView = this.views.get(view);
82
+ if (encodedView === void 0) {
83
+ encodedView = view === SHARED_VIEW ? Buffer.concat([STATE_PATCH_BUFFER, encodedChanges]) : this.encoder.encodeView(client.view, sharedOffset, it);
84
+ this.views.set(view, encodedView);
71
85
  }
72
- this.state.discardAllChanges();
73
- }
74
- if (import_Debug.debugPatch.enabled) {
75
- (0, import_Debug.debugPatch)(
76
- "%d bytes sent to %d clients, %j",
77
- patches.length,
78
- clients.length,
79
- import_Debug.debugPatch.dumpChanges
80
- );
86
+ client.raw(Buffer.concat([STATE_PATCH_BUFFER, encodedView]));
81
87
  }
82
88
  }
83
- return hasChanges;
89
+ this.encoder.discardChanges();
90
+ if (import_Debug.debugPatch.enabled) {
91
+ (0, import_Debug.debugPatch)(
92
+ "%d bytes sent to %d clients, %j",
93
+ encodedChanges.length,
94
+ clients.length,
95
+ import_Debug.debugPatch.dumpChanges
96
+ );
97
+ }
98
+ return true;
84
99
  }
85
100
  handshake() {
86
101
  if (!this.handshakeCache) {
87
- this.handshakeCache = this.state && import_schema.Reflection.encode(this.state);
102
+ this.handshakeCache = this.encoder.state && import_schema.Reflection.encode(this.encoder.state);
88
103
  }
89
104
  return this.handshakeCache;
90
105
  }