@colyseus/core 0.16.0-preview.21 → 0.16.0-preview.27
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/build/MatchMaker.d.ts +15 -14
- package/build/MatchMaker.js +81 -65
- package/build/MatchMaker.js.map +2 -2
- package/build/MatchMaker.mjs +80 -64
- package/build/MatchMaker.mjs.map +2 -2
- package/build/Protocol.d.ts +3 -4
- package/build/Protocol.js +22 -20
- package/build/Protocol.js.map +2 -2
- package/build/Protocol.mjs +22 -20
- package/build/Protocol.mjs.map +2 -2
- package/build/Room.d.ts +30 -29
- package/build/Room.js +123 -84
- package/build/Room.js.map +2 -2
- package/build/Room.mjs +123 -84
- package/build/Room.mjs.map +2 -2
- package/build/Server.d.ts +0 -1
- package/build/Server.js +2 -2
- package/build/Server.js.map +2 -2
- package/build/Server.mjs +1 -1
- package/build/Server.mjs.map +2 -2
- package/build/Transport.d.ts +0 -5
- package/build/index.d.ts +1 -1
- package/build/index.js +1 -1
- package/build/index.js.map +2 -2
- package/build/index.mjs +1 -1
- package/build/index.mjs.map +1 -1
- package/build/matchmaker/Lobby.d.ts +2 -2
- package/build/matchmaker/Lobby.js.map +2 -2
- package/build/matchmaker/Lobby.mjs.map +2 -2
- package/build/matchmaker/RegisteredHandler.d.ts +4 -5
- package/build/matchmaker/RegisteredHandler.js +4 -3
- package/build/matchmaker/RegisteredHandler.js.map +2 -2
- package/build/matchmaker/RegisteredHandler.mjs +4 -3
- package/build/matchmaker/RegisteredHandler.mjs.map +2 -2
- package/build/matchmaker/controller.d.ts +1 -2
- package/build/matchmaker/driver/RoomData.d.ts +3 -3
- package/build/matchmaker/driver/RoomData.js +3 -3
- package/build/matchmaker/driver/RoomData.js.map +2 -2
- package/build/matchmaker/driver/RoomData.mjs +2 -2
- package/build/matchmaker/driver/RoomData.mjs.map +2 -2
- package/build/matchmaker/driver/api.d.ts +104 -0
- package/build/matchmaker/driver/api.js +29 -0
- package/build/matchmaker/driver/api.js.map +7 -0
- package/build/matchmaker/driver/api.mjs +6 -0
- package/build/matchmaker/driver/api.mjs.map +7 -0
- package/build/matchmaker/driver/index.d.ts +7 -7
- package/build/matchmaker/driver/index.js +1 -1
- package/build/matchmaker/driver/index.js.map +2 -2
- package/build/matchmaker/driver/index.mjs +2 -2
- package/build/matchmaker/driver/index.mjs.map +2 -2
- package/build/matchmaker/driver/interfaces.d.ts +7 -11
- package/build/matchmaker/driver/interfaces.js.map +1 -1
- package/build/matchmaker/driver/local/LocalDriver.d.ts +13 -0
- package/build/matchmaker/driver/local/LocalDriver.js +65 -0
- package/build/matchmaker/driver/local/LocalDriver.js.map +7 -0
- package/build/matchmaker/driver/local/LocalDriver.mjs +42 -0
- package/build/matchmaker/driver/local/LocalDriver.mjs.map +7 -0
- package/build/matchmaker/driver/local/Query.d.ts +9 -0
- package/build/matchmaker/driver/local/Query.js +78 -0
- package/build/matchmaker/driver/local/Query.js.map +7 -0
- package/build/matchmaker/driver/local/Query.mjs +55 -0
- package/build/matchmaker/driver/local/Query.mjs.map +7 -0
- package/build/matchmaker/driver/local/RoomData.d.ts +19 -0
- package/build/matchmaker/driver/local/RoomData.js +79 -0
- package/build/matchmaker/driver/local/RoomData.js.map +7 -0
- package/build/matchmaker/driver/local/RoomData.mjs +56 -0
- package/build/matchmaker/driver/local/RoomData.mjs.map +7 -0
- package/build/presence/LocalPresence.d.ts +9 -2
- package/build/presence/LocalPresence.js +77 -3
- package/build/presence/LocalPresence.js.map +3 -3
- package/build/presence/LocalPresence.mjs +77 -3
- package/build/presence/LocalPresence.mjs.map +3 -3
- package/build/presence/Presence.d.ts +38 -2
- package/build/presence/Presence.js.map +1 -1
- package/build/rooms/LobbyRoom.d.ts +4 -4
- package/build/rooms/LobbyRoom.js.map +2 -2
- package/build/rooms/LobbyRoom.mjs.map +2 -2
- package/build/serializer/SchemaSerializer.d.ts +11 -10
- package/build/serializer/SchemaSerializer.js.map +2 -2
- package/build/serializer/SchemaSerializer.mjs.map +2 -2
- package/build/serializer/Serializer.d.ts +0 -1
- package/build/utils/Utils.d.ts +4 -2
- package/build/utils/Utils.js +11 -2
- package/build/utils/Utils.js.map +2 -2
- package/build/utils/Utils.mjs +10 -2
- package/build/utils/Utils.mjs.map +2 -2
- package/package.json +2 -2
|
@@ -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.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(
|
|
5
|
-
"mappings": ";;;;;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,gBAAe;AACf,kBAAiB;AAEjB,oBAA6B;AAC7B,mBAA0B;AAG1B,qBAA0B;AAI1B,MAAM,0BAA0B,YAAAA,QAAK,QAAQ,eAAe;AAErD,MAAM,cAAkC;AAAA,EAW3C,cAAc;AAVd,SAAO,WAAW,IAAI,2BAAa;AAEnC,SAAO,OAAuC,CAAC;AAC/C,SAAO,OAAsD,CAAC;AAE9D,SAAO,OAA0C,CAAC;AAElD,SAAU,gBAA4C,CAAC;AACvD,SAAQ,WAA6C,CAAC;AAMpD,QACE,4BACA,UAAAC,QAAG,WAAW,uBAAuB,GACrC;AACA,YAAM,QAAQ,UAAAA,QAAG,aAAa,uBAAuB,EAAE,SAAS,OAAO,KAAK;AAC5E,YAAM,SAAS,KAAK,MAAM,KAAK;AAC/B,UAAI,OAAO,MAAM;AAAE,aAAK,OAAO,OAAO;AAAA,MAAM;AAC5C,UAAI,OAAO,MAAM;AAAE,aAAK,OAAO,OAAO;AAAA,MAAM;AAC5C,UAAI,OAAO,MAAM;AAAE,aAAK,OAAO,OAAO;AAAA,MAAM;AAAA,IAC9C;AAAA,EACF;AAAA,EAEO,UAAU,OAAe,UAAoC;AAChE,QAAI,CAAC,KAAK,cAAc,QAAQ;AAAE,WAAK,cAAc,SAAS,CAAC;AAAA,IAAG;AAClE,SAAK,cAAc,OAAO,KAAK,QAAQ;AACvC,SAAK,SAAS,GAAG,OAAO,QAAQ;AAChC,WAAO;AAAA,EACX;AAAA,EAEO,YAAY,OAAe,UAAqB;AACnD,UAAM,iBAAiB,KAAK,cAAc;AAC1C,QAAI,CAAC,gBAAgB;AAAE;AAAA,IAAQ;AAE/B,QAAI,UAAW;AACX,YAAM,MAAM,eAAe,QAAQ,QAAQ;AAC3C,UAAI,QAAQ,IAAI;AACZ,uBAAe,OAAO,KAAK,CAAC;AAC5B,aAAK,SAAS,eAAe,OAAO,QAAQ;AAAA,MAChD;AAEA,UAAI,eAAe,WAAW,GAAG;AAC7B,eAAO,KAAK,cAAc;AAAA,MAC9B;AAAA,IAEJ,OAAO;AACL,qBAAe,QAAQ,CAAC,OACtB,KAAK,SAAS,eAAe,OAAO,EAAE,CAAC;AAEzC,aAAO,KAAK,cAAc;AAAA,IAC5B;AAEA,WAAO;AAAA,EACX;AAAA,EAEO,QAAQ,OAAe,MAAW;AACrC,SAAK,SAAS,KAAK,OAAO,IAAI;AAC9B,WAAO;AAAA,EACX;AAAA,EAEA,MAAa,OAAO,
|
|
6
|
-
"names": ["path", "fs"]
|
|
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(key: string): Promise<boolean> {\n return this.channels.listenerCount(key) > 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 this.keys[key] = value;\n this.expire(key, seconds);\n }\n\n public expire(key: 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 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 hincrbyex(key: string, field: string, incrBy: number, expireInSeconds: 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 this.setex(key, field, expireInSeconds);\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 llen(key: string): number {\n return (this.data[key] && this.data[key].length) || 0;\n }\n\n public rpush(key: string, ...values: string[]): number {\n if (!this.data[key]) { this.data[key] = []; }\n\n let lastLength: number = 0;\n\n values.forEach(value => {\n lastLength = this.data[key].push(value);\n });\n\n return lastLength;\n }\n\n public lpush(key: string, ...values: string[]): number {\n if (!this.data[key]) { this.data[key] = []; }\n\n let lastLength: number = 0;\n\n values.forEach(value => {\n lastLength = this.data[key].unshift(value);\n });\n\n return lastLength;\n }\n\n\n public lpop(key: string): string {\n return Array.isArray(this.data[key]) && this.data[key].shift();\n }\n\n public rpop(key: string): string {\n return this.data[key].pop();\n }\n\n public brpop(...args: [...keys: string[], timeoutInSeconds: number]): Promise<[string, string] | null> {\n const keys = args.slice(0, -2) as string[];\n const timeoutInSeconds = args[args.length - 1] as number;\n\n const getFirstPopulated = (): [string, string] | null => {\n const keyWithValue = keys.find(key => this.data[key] && this.data[key].length > 0);\n if (keyWithValue) {\n return [keyWithValue, this.data[keyWithValue].pop()];\n } else {\n return null;\n }\n }\n\n const firstPopulated = getFirstPopulated();\n\n if (firstPopulated) {\n // return first populated key + item\n return Promise.resolve(firstPopulated);\n\n } else {\n // 8 retries per second\n const maxRetries = timeoutInSeconds * 8;\n\n let tries = 0;\n return new Promise((resolve) => {\n const interval = setInterval(() => {\n tries++;\n\n const firstPopulated = getFirstPopulated();\n if (firstPopulated) {\n clearInterval(interval);\n return resolve(firstPopulated);\n\n } else if (tries >= maxRetries) {\n clearInterval(interval);\n return resolve(undefined);\n }\n\n }, (timeoutInSeconds * 1000) / maxRetries);\n });\n }\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
|
+
"names": ["path", "fs", "firstPopulated"]
|
|
7
7
|
}
|
|
@@ -58,17 +58,20 @@ class LocalPresence {
|
|
|
58
58
|
this.channels.emit(topic, data);
|
|
59
59
|
return this;
|
|
60
60
|
}
|
|
61
|
-
async exists(
|
|
62
|
-
return this.channels.listenerCount(
|
|
61
|
+
async exists(key) {
|
|
62
|
+
return this.channels.listenerCount(key) > 0;
|
|
63
63
|
}
|
|
64
64
|
set(key, value) {
|
|
65
65
|
this.keys[key] = value;
|
|
66
66
|
}
|
|
67
67
|
setex(key, value, seconds) {
|
|
68
|
+
this.keys[key] = value;
|
|
69
|
+
this.expire(key, seconds);
|
|
70
|
+
}
|
|
71
|
+
expire(key, seconds) {
|
|
68
72
|
if (this.timeouts[key]) {
|
|
69
73
|
clearTimeout(this.timeouts[key]);
|
|
70
74
|
}
|
|
71
|
-
this.keys[key] = value;
|
|
72
75
|
this.timeouts[key] = setTimeout(() => {
|
|
73
76
|
delete this.keys[key];
|
|
74
77
|
delete this.timeouts[key];
|
|
@@ -136,6 +139,16 @@ class LocalPresence {
|
|
|
136
139
|
this.hash[key][field] = value.toString();
|
|
137
140
|
return value;
|
|
138
141
|
}
|
|
142
|
+
hincrbyex(key, field, incrBy, expireInSeconds) {
|
|
143
|
+
if (!this.hash[key]) {
|
|
144
|
+
this.hash[key] = {};
|
|
145
|
+
}
|
|
146
|
+
let value = Number(this.hash[key][field] || "0");
|
|
147
|
+
value += incrBy;
|
|
148
|
+
this.hash[key][field] = value.toString();
|
|
149
|
+
this.setex(key, field, expireInSeconds);
|
|
150
|
+
return value;
|
|
151
|
+
}
|
|
139
152
|
async hget(key, field) {
|
|
140
153
|
return this.hash[key] && this.hash[key][field];
|
|
141
154
|
}
|
|
@@ -166,6 +179,67 @@ class LocalPresence {
|
|
|
166
179
|
this.keys[key]--;
|
|
167
180
|
return Promise.resolve(this.keys[key]);
|
|
168
181
|
}
|
|
182
|
+
llen(key) {
|
|
183
|
+
return this.data[key] && this.data[key].length || 0;
|
|
184
|
+
}
|
|
185
|
+
rpush(key, ...values) {
|
|
186
|
+
if (!this.data[key]) {
|
|
187
|
+
this.data[key] = [];
|
|
188
|
+
}
|
|
189
|
+
let lastLength = 0;
|
|
190
|
+
values.forEach((value) => {
|
|
191
|
+
lastLength = this.data[key].push(value);
|
|
192
|
+
});
|
|
193
|
+
return lastLength;
|
|
194
|
+
}
|
|
195
|
+
lpush(key, ...values) {
|
|
196
|
+
if (!this.data[key]) {
|
|
197
|
+
this.data[key] = [];
|
|
198
|
+
}
|
|
199
|
+
let lastLength = 0;
|
|
200
|
+
values.forEach((value) => {
|
|
201
|
+
lastLength = this.data[key].unshift(value);
|
|
202
|
+
});
|
|
203
|
+
return lastLength;
|
|
204
|
+
}
|
|
205
|
+
lpop(key) {
|
|
206
|
+
return Array.isArray(this.data[key]) && this.data[key].shift();
|
|
207
|
+
}
|
|
208
|
+
rpop(key) {
|
|
209
|
+
return this.data[key].pop();
|
|
210
|
+
}
|
|
211
|
+
brpop(...args) {
|
|
212
|
+
const keys = args.slice(0, -2);
|
|
213
|
+
const timeoutInSeconds = args[args.length - 1];
|
|
214
|
+
const getFirstPopulated = () => {
|
|
215
|
+
const keyWithValue = keys.find((key) => this.data[key] && this.data[key].length > 0);
|
|
216
|
+
if (keyWithValue) {
|
|
217
|
+
return [keyWithValue, this.data[keyWithValue].pop()];
|
|
218
|
+
} else {
|
|
219
|
+
return null;
|
|
220
|
+
}
|
|
221
|
+
};
|
|
222
|
+
const firstPopulated = getFirstPopulated();
|
|
223
|
+
if (firstPopulated) {
|
|
224
|
+
return Promise.resolve(firstPopulated);
|
|
225
|
+
} else {
|
|
226
|
+
const maxRetries = timeoutInSeconds * 8;
|
|
227
|
+
let tries = 0;
|
|
228
|
+
return new Promise((resolve) => {
|
|
229
|
+
const interval = setInterval(() => {
|
|
230
|
+
tries++;
|
|
231
|
+
const firstPopulated2 = getFirstPopulated();
|
|
232
|
+
if (firstPopulated2) {
|
|
233
|
+
clearInterval(interval);
|
|
234
|
+
return resolve(firstPopulated2);
|
|
235
|
+
} else if (tries >= maxRetries) {
|
|
236
|
+
clearInterval(interval);
|
|
237
|
+
return resolve(void 0);
|
|
238
|
+
}
|
|
239
|
+
}, timeoutInSeconds * 1e3 / maxRetries);
|
|
240
|
+
});
|
|
241
|
+
}
|
|
242
|
+
}
|
|
169
243
|
shutdown() {
|
|
170
244
|
if (isDevMode) {
|
|
171
245
|
const cache = JSON.stringify({
|
|
@@ -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.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(
|
|
5
|
-
"mappings": "AAAA,OAAO,QAAQ;AACf,OAAO,UAAU;AAEjB,SAAS,oBAAoB;AAC7B,SAAS,iBAAiB;AAG1B,SAAS,iBAAiB;AAI1B,MAAM,0BAA0B,KAAK,QAAQ,eAAe;AAErD,MAAM,cAAkC;AAAA,EAW3C,cAAc;AAVd,SAAO,WAAW,IAAI,aAAa;AAEnC,SAAO,OAAuC,CAAC;AAC/C,SAAO,OAAsD,CAAC;AAE9D,SAAO,OAA0C,CAAC;AAElD,SAAU,gBAA4C,CAAC;AACvD,SAAQ,WAA6C,CAAC;AAMpD,QACE,aACA,GAAG,WAAW,uBAAuB,GACrC;AACA,YAAM,QAAQ,GAAG,aAAa,uBAAuB,EAAE,SAAS,OAAO,KAAK;AAC5E,YAAM,SAAS,KAAK,MAAM,KAAK;AAC/B,UAAI,OAAO,MAAM;AAAE,aAAK,OAAO,OAAO;AAAA,MAAM;AAC5C,UAAI,OAAO,MAAM;AAAE,aAAK,OAAO,OAAO;AAAA,MAAM;AAC5C,UAAI,OAAO,MAAM;AAAE,aAAK,OAAO,OAAO;AAAA,MAAM;AAAA,IAC9C;AAAA,EACF;AAAA,EAEO,UAAU,OAAe,UAAoC;AAChE,QAAI,CAAC,KAAK,cAAc,QAAQ;AAAE,WAAK,cAAc,SAAS,CAAC;AAAA,IAAG;AAClE,SAAK,cAAc,OAAO,KAAK,QAAQ;AACvC,SAAK,SAAS,GAAG,OAAO,QAAQ;AAChC,WAAO;AAAA,EACX;AAAA,EAEO,YAAY,OAAe,UAAqB;AACnD,UAAM,iBAAiB,KAAK,cAAc;AAC1C,QAAI,CAAC,gBAAgB;AAAE;AAAA,IAAQ;AAE/B,QAAI,UAAW;AACX,YAAM,MAAM,eAAe,QAAQ,QAAQ;AAC3C,UAAI,QAAQ,IAAI;AACZ,uBAAe,OAAO,KAAK,CAAC;AAC5B,aAAK,SAAS,eAAe,OAAO,QAAQ;AAAA,MAChD;AAEA,UAAI,eAAe,WAAW,GAAG;AAC7B,eAAO,KAAK,cAAc;AAAA,MAC9B;AAAA,IAEJ,OAAO;AACL,qBAAe,QAAQ,CAAC,OACtB,KAAK,SAAS,eAAe,OAAO,EAAE,CAAC;AAEzC,aAAO,KAAK,cAAc;AAAA,IAC5B;AAEA,WAAO;AAAA,EACX;AAAA,EAEO,QAAQ,OAAe,MAAW;AACrC,SAAK,SAAS,KAAK,OAAO,IAAI;AAC9B,WAAO;AAAA,EACX;AAAA,EAEA,MAAa,OAAO,
|
|
6
|
-
"names": []
|
|
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(key: string): Promise<boolean> {\n return this.channels.listenerCount(key) > 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 this.keys[key] = value;\n this.expire(key, seconds);\n }\n\n public expire(key: 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 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 hincrbyex(key: string, field: string, incrBy: number, expireInSeconds: 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 this.setex(key, field, expireInSeconds);\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 llen(key: string): number {\n return (this.data[key] && this.data[key].length) || 0;\n }\n\n public rpush(key: string, ...values: string[]): number {\n if (!this.data[key]) { this.data[key] = []; }\n\n let lastLength: number = 0;\n\n values.forEach(value => {\n lastLength = this.data[key].push(value);\n });\n\n return lastLength;\n }\n\n public lpush(key: string, ...values: string[]): number {\n if (!this.data[key]) { this.data[key] = []; }\n\n let lastLength: number = 0;\n\n values.forEach(value => {\n lastLength = this.data[key].unshift(value);\n });\n\n return lastLength;\n }\n\n\n public lpop(key: string): string {\n return Array.isArray(this.data[key]) && this.data[key].shift();\n }\n\n public rpop(key: string): string {\n return this.data[key].pop();\n }\n\n public brpop(...args: [...keys: string[], timeoutInSeconds: number]): Promise<[string, string] | null> {\n const keys = args.slice(0, -2) as string[];\n const timeoutInSeconds = args[args.length - 1] as number;\n\n const getFirstPopulated = (): [string, string] | null => {\n const keyWithValue = keys.find(key => this.data[key] && this.data[key].length > 0);\n if (keyWithValue) {\n return [keyWithValue, this.data[keyWithValue].pop()];\n } else {\n return null;\n }\n }\n\n const firstPopulated = getFirstPopulated();\n\n if (firstPopulated) {\n // return first populated key + item\n return Promise.resolve(firstPopulated);\n\n } else {\n // 8 retries per second\n const maxRetries = timeoutInSeconds * 8;\n\n let tries = 0;\n return new Promise((resolve) => {\n const interval = setInterval(() => {\n tries++;\n\n const firstPopulated = getFirstPopulated();\n if (firstPopulated) {\n clearInterval(interval);\n return resolve(firstPopulated);\n\n } else if (tries >= maxRetries) {\n clearInterval(interval);\n return resolve(undefined);\n }\n\n }, (timeoutInSeconds * 1000) / maxRetries);\n });\n }\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
|
+
"names": ["firstPopulated"]
|
|
7
7
|
}
|
|
@@ -34,9 +34,9 @@ export interface Presence {
|
|
|
34
34
|
/**
|
|
35
35
|
* Returns if key exists.
|
|
36
36
|
*
|
|
37
|
-
* @param
|
|
37
|
+
* @param key
|
|
38
38
|
*/
|
|
39
|
-
exists(
|
|
39
|
+
exists(key: string): Promise<boolean>;
|
|
40
40
|
/**
|
|
41
41
|
* Set key to hold the string value.
|
|
42
42
|
*
|
|
@@ -52,6 +52,13 @@ export interface Presence {
|
|
|
52
52
|
* @param seconds - Timeout value.
|
|
53
53
|
*/
|
|
54
54
|
setex(key: string, value: string, seconds: number): any;
|
|
55
|
+
/**
|
|
56
|
+
* Expire the key in seconds.
|
|
57
|
+
*
|
|
58
|
+
* @param key - Identifier.
|
|
59
|
+
* @param seconds - Seconds to expire the key.
|
|
60
|
+
*/
|
|
61
|
+
expire(key: string, seconds: number): any;
|
|
55
62
|
/**
|
|
56
63
|
* Get the value of key.
|
|
57
64
|
*
|
|
@@ -118,6 +125,11 @@ export interface Presence {
|
|
|
118
125
|
* holding a hash is created. If field does not exist the value is set to 0 before the operation is performed.
|
|
119
126
|
*/
|
|
120
127
|
hincrby(key: string, field: string, value: number): number | Promise<number>;
|
|
128
|
+
/**
|
|
129
|
+
* WARNING: DO NOT USE THIS METHOD. It is meant for internal use only.
|
|
130
|
+
* @private
|
|
131
|
+
*/
|
|
132
|
+
hincrbyex(key: string, field: string, value: number, expireInSeconds: number): number | Promise<number>;
|
|
121
133
|
/**
|
|
122
134
|
* Returns the value associated with field in the hash stored at key.
|
|
123
135
|
*/
|
|
@@ -149,5 +161,29 @@ export interface Presence {
|
|
|
149
161
|
* that can not be represented as integer. This operation is limited to 64-bit signed integers.
|
|
150
162
|
*/
|
|
151
163
|
decr(key: string): Promise<number>;
|
|
164
|
+
/**
|
|
165
|
+
* Returns the length of the list stored at key.
|
|
166
|
+
*/
|
|
167
|
+
llen(key: string): number | Promise<number>;
|
|
168
|
+
/**
|
|
169
|
+
* Adds the string value to the end of the list stored at key. If key does not exist, it is created as empty list before performing the push operation.
|
|
170
|
+
*/
|
|
171
|
+
rpush(key: string, ...values: string[]): number | Promise<number>;
|
|
172
|
+
/**
|
|
173
|
+
* Adds the string value to the begginning of the list stored at key. If key does not exist, it is created as empty list before performing the push operation.
|
|
174
|
+
*/
|
|
175
|
+
lpush(key: string, ...values: string[]): number | Promise<number>;
|
|
176
|
+
/**
|
|
177
|
+
* Removes and returns the last element of the list stored at key.
|
|
178
|
+
*/
|
|
179
|
+
rpop(key: string): string | Promise<string>;
|
|
180
|
+
/**
|
|
181
|
+
* Removes and returns the first element of the list stored at key.
|
|
182
|
+
*/
|
|
183
|
+
lpop(key: string): string | Promise<string>;
|
|
184
|
+
/**
|
|
185
|
+
* Removes and returns the last element of the list stored at key. If the list is empty, the execution is halted until an element is available or the timeout is reached.
|
|
186
|
+
*/
|
|
187
|
+
brpop(...args: [...keys: string[], timeoutInSeconds: number]): Promise<[string, string]>;
|
|
152
188
|
shutdown(): void;
|
|
153
189
|
}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../../src/presence/Presence.ts"],
|
|
4
|
-
"sourcesContent": ["/**\n * When you need to scale your server on multiple processes and/or machines, you'd need to provide\n * the Presence option to the Server. The purpose of Presence is to allow communicating and\n * sharing data between different processes, specially during match-making.\n *\n * - Local presence - This is the default option. It's meant to be used when you're running Colyseus in\n * a single process.\n * - Redis presence - Use this option when you're running Colyseus on multiple processes and/or machines.\n *\n * @default Local presence\n */\nexport interface Presence {\n /**\n * Subscribes to the given topic. The callback will be triggered whenever a message is published on topic.\n *\n * @param topic - Topic name.\n * @param callback - Callback to trigger on subscribing.\n */\n subscribe(topic: string, callback: Function);\n\n /**\n * Unsubscribe from given topic.\n *\n * @param topic - Topic name.\n * @param callback - Callback to trigger on topic unsubscribing.\n */\n unsubscribe(topic: string, callback?: Function);\n\n /**\n * Posts a message to given topic.\n *\n * @param topic - Topic name.\n * @param data - Message body/object.\n */\n publish(topic: string, data: any);\n\n /**\n * Returns if key exists.\n *\n * @param
|
|
4
|
+
"sourcesContent": ["/**\n * When you need to scale your server on multiple processes and/or machines, you'd need to provide\n * the Presence option to the Server. The purpose of Presence is to allow communicating and\n * sharing data between different processes, specially during match-making.\n *\n * - Local presence - This is the default option. It's meant to be used when you're running Colyseus in\n * a single process.\n * - Redis presence - Use this option when you're running Colyseus on multiple processes and/or machines.\n *\n * @default Local presence\n */\nexport interface Presence {\n /**\n * Subscribes to the given topic. The callback will be triggered whenever a message is published on topic.\n *\n * @param topic - Topic name.\n * @param callback - Callback to trigger on subscribing.\n */\n subscribe(topic: string, callback: Function);\n\n /**\n * Unsubscribe from given topic.\n *\n * @param topic - Topic name.\n * @param callback - Callback to trigger on topic unsubscribing.\n */\n unsubscribe(topic: string, callback?: Function);\n\n /**\n * Posts a message to given topic.\n *\n * @param topic - Topic name.\n * @param data - Message body/object.\n */\n publish(topic: string, data: any);\n\n /**\n * Returns if key exists.\n *\n * @param key\n */\n exists(key: string): Promise<boolean>;\n\n /**\n * Set key to hold the string value.\n *\n * @param key - Identifier.\n * @param value - Message body/object.\n */\n set(key: string, value: string);\n\n /**\n * Set key to hold the string value and set key to timeout after a given number of seconds.\n *\n * @param key - Identifier.\n * @param value - Message body/object.\n * @param seconds - Timeout value.\n */\n setex(key: string, value: string, seconds: number);\n\n /**\n * Expire the key in seconds.\n *\n * @param key - Identifier.\n * @param seconds - Seconds to expire the key.\n */\n expire(key: string, seconds: number);\n\n /**\n * Get the value of key.\n *\n * @param key - Identifier.\n */\n get(key: string);\n\n /**\n * Removes the specified key.\n *\n * @param key - Identifier of the object to removed.\n */\n del(key: string): void;\n\n /**\n * Add the specified members to the set stored at key. Specified members that are already\n * a member of this set are ignored. If key does not exist, a new set is created before\n * adding the specified members.\n *\n * @param key - Name/Identifier of the set.\n * @param value - Message body/object.\n */\n sadd(key: string, value: any);\n\n /**\n * Returns all the members of the set value stored at key.\n *\n * @param key - Name/Identifier of the set.\n */\n smembers(key: string): Promise<string[]>;\n\n /**\n * Returns if member is a member of the set stored at key.\n *\n * @param key - Name/Identifier of the set.\n * @param field - Key value within the set.\n * @returns `1` if the element is a member of the set else `0`.\n */\n sismember(key: string, field: string);\n\n /**\n * Remove the specified members from the set stored at key. Specified members that are not a\n * member of this set are ignored. If key does not exist, it is treated as an empty set\n * and this command returns 0.\n *\n * @param key - Name/Identifier of the set.\n * @param value - Key value within the set.\n */\n srem(key: string, value: any);\n\n /**\n * Returns the set cardinality (number of elements) of the set stored at key.\n *\n * @param key - Name/Identifier of the set.\n */\n scard(key: string);\n\n /**\n * Returns the members of the set resulting from the intersection of all the given sets.\n *\n * @param keys - Key values within the set.\n */\n sinter(...keys: string[]): Promise<string[]>;\n\n /**\n * Sets field in the hash stored at key to value. If key does not exist, a new key holding a hash is created.\n * If field already exists in the hash, it is overwritten.\n */\n hset(key: string, field: string, value: string);\n\n /**\n * Increments the number stored at field in the hash stored at key by increment. If key does not exist, a new key\n * holding a hash is created. If field does not exist the value is set to 0 before the operation is performed.\n */\n hincrby(key: string, field: string, value: number): number | Promise<number>;\n\n /**\n * WARNING: DO NOT USE THIS METHOD. It is meant for internal use only.\n * @private\n */\n hincrbyex(key: string, field: string, value: number, expireInSeconds: number): number | Promise<number>;\n\n /**\n * Returns the value associated with field in the hash stored at key.\n */\n hget(key: string, field: string): Promise<string>;\n\n /**\n * Returns all fields and values of the hash stored at key.\n */\n hgetall(key: string): Promise<{ [key: string]: string }>;\n\n /**\n * Removes the specified fields from the hash stored at key. Specified fields that do not exist within\n * this hash are ignored. If key does not exist, it is treated as an empty hash and this command returns 0.\n */\n hdel(key: string, field: string): boolean | Promise<boolean>;\n\n /**\n * Returns the number of fields contained in the hash stored at key\n */\n hlen(key: string): Promise<number>;\n\n /**\n * Increments the number stored at key by one. If the key does not exist, it is set to 0 before performing\n * the operation. An error is returned if the key contains a value of the wrong type or\n * contains a string that can not be represented as integer. This operation is limited to 64-bit signed integers.\n */\n incr(key: string): Promise<number>;\n\n /**\n * Decrements the number stored at key by one. If the key does not exist, it is set to 0 before performing\n * the operation. An error is returned if the key contains a value of the wrong type or contains a string\n * that can not be represented as integer. This operation is limited to 64-bit signed integers.\n */\n decr(key: string): Promise<number>;\n\n /**\n * Returns the length of the list stored at key.\n */\n llen(key: string): number | Promise<number>;\n\n /**\n * Adds the string value to the end of the list stored at key. If key does not exist, it is created as empty list before performing the push operation.\n */\n rpush(key: string, ...values: string[]): number | Promise<number>;\n\n /**\n * Adds the string value to the begginning of the list stored at key. If key does not exist, it is created as empty list before performing the push operation.\n */\n lpush(key: string, ...values: string[]): number | Promise<number>;\n\n /**\n * Removes and returns the last element of the list stored at key.\n */\n rpop(key: string): string | Promise<string>;\n\n /**\n * Removes and returns the first element of the list stored at key.\n */\n lpop(key: string): string | Promise<string>;\n\n /**\n * Removes and returns the last element of the list stored at key. If the list is empty, the execution is halted until an element is available or the timeout is reached.\n */\n brpop(...args: [...keys: string[], timeoutInSeconds: number]): Promise<[string, string]>;\n\n shutdown(): void;\n}\n"],
|
|
5
5
|
"mappings": ";;;;;;;;;;;;;AAAA;AAAA;",
|
|
6
6
|
"names": []
|
|
7
7
|
}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { IRoomCache } from '../matchmaker/driver/local/LocalDriver';
|
|
2
2
|
import { Room } from '../Room';
|
|
3
3
|
import { Client } from '../Transport';
|
|
4
4
|
export interface FilterInput {
|
|
@@ -9,7 +9,7 @@ export interface LobbyOptions {
|
|
|
9
9
|
filter?: FilterInput;
|
|
10
10
|
}
|
|
11
11
|
export declare class LobbyRoom extends Room {
|
|
12
|
-
rooms:
|
|
12
|
+
rooms: IRoomCache[];
|
|
13
13
|
unsubscribeLobby: () => void;
|
|
14
14
|
clientOptions: {
|
|
15
15
|
[sessionId: string]: LobbyOptions;
|
|
@@ -18,6 +18,6 @@ export declare class LobbyRoom extends Room {
|
|
|
18
18
|
onJoin(client: Client, options: LobbyOptions): void;
|
|
19
19
|
onLeave(client: Client): void;
|
|
20
20
|
onDispose(): void;
|
|
21
|
-
protected filterItemsForClient(options: LobbyOptions):
|
|
22
|
-
protected filterItemForClient(room:
|
|
21
|
+
protected filterItemsForClient(options: LobbyOptions): IRoomCache[];
|
|
22
|
+
protected filterItemForClient(room: IRoomCache, filter?: LobbyOptions['filter']): boolean;
|
|
23
23
|
}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../../src/rooms/LobbyRoom.ts"],
|
|
4
|
-
"sourcesContent": ["\nimport * as matchMaker from '../MatchMaker';\nimport {
|
|
5
|
-
"mappings": ";;;;;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AACA,iBAA4B;AAE5B,mBAA+B;AAC/B,kBAAqB;AAkBd,MAAM,kBAAkB,iBAAK;AAAA,EAA7B;AAAA;AACL,SAAO,
|
|
4
|
+
"sourcesContent": ["\nimport * as matchMaker from '../MatchMaker';\nimport { IRoomCache } from '../matchmaker/driver/local/LocalDriver';\nimport { subscribeLobby } from '../matchmaker/Lobby';\nimport { Room } from '../Room';\nimport { Client } from '../Transport';\n\n// TODO: use Schema state & filters on version 1.0.0\n\n// class DummyLobbyState extends Schema { // tslint:disable-line\n// @type(\"number\") public _: number;\n// }\n\nexport interface FilterInput {\n name?: string;\n metadata?: any;\n}\n\nexport interface LobbyOptions {\n filter?: FilterInput;\n}\n\nexport class LobbyRoom extends Room { // tslint:disable-line\n public rooms: IRoomCache[] = [];\n public unsubscribeLobby: () => void;\n\n public clientOptions: { [sessionId: string]: LobbyOptions } = {};\n\n public async onCreate(options: any) {\n // prevent LobbyRoom to notify itself\n this.listing.unlisted = true;\n\n this.unsubscribeLobby = await subscribeLobby((roomId, data) => {\n const roomIndex = this.rooms.findIndex((room) => room.roomId === roomId);\n const clients = this.clients.filter((client) => this.clientOptions[client.sessionId]);\n\n if (!data) {\n // remove room listing data\n if (roomIndex !== -1) {\n const previousData = this.rooms[roomIndex];\n\n this.rooms.splice(roomIndex, 1);\n\n clients.forEach((client) => {\n if (this.filterItemForClient(previousData, this.clientOptions[client.sessionId].filter)) {\n client.send('-', roomId);\n }\n });\n }\n\n } else if (roomIndex === -1) {\n // append room listing data\n this.rooms.push(data);\n\n clients.forEach((client) => {\n if (this.filterItemForClient(data, this.clientOptions[client.sessionId].filter)) {\n client.send('+', [roomId, data]);\n }\n });\n\n } else {\n const previousData = this.rooms[roomIndex];\n\n // replace room listing data\n this.rooms[roomIndex] = data;\n\n clients.forEach((client) => {\n const hadData = this.filterItemForClient(previousData, this.clientOptions[client.sessionId].filter);\n const hasData = this.filterItemForClient(data, this.clientOptions[client.sessionId].filter);\n\n if (hadData && !hasData) {\n client.send('-', roomId);\n\n } else if (hasData) {\n client.send('+', [roomId, data]);\n }\n });\n }\n });\n\n this.rooms = await matchMaker.query({ private: false, unlisted: false });\n\n this.onMessage('filter', (client: Client, filter: FilterInput) => {\n this.clientOptions[client.sessionId].filter = filter;\n client.send('rooms', this.filterItemsForClient(this.clientOptions[client.sessionId]));\n });\n }\n\n public onJoin(client: Client, options: LobbyOptions) {\n this.clientOptions[client.sessionId] = options || {};\n client.send('rooms', this.filterItemsForClient(this.clientOptions[client.sessionId]));\n }\n\n public onLeave(client: Client) {\n delete this.clientOptions[client.sessionId];\n }\n\n public onDispose() {\n if (this.unsubscribeLobby) {\n this.unsubscribeLobby();\n }\n }\n\n protected filterItemsForClient(options: LobbyOptions) {\n const filter = options.filter;\n\n return (filter)\n ? this.rooms.filter((room) => this.filterItemForClient(room, filter))\n : this.rooms;\n }\n\n protected filterItemForClient(room: IRoomCache, filter?: LobbyOptions['filter']) {\n if (!filter) {\n return true;\n }\n\n let isAllowed = true;\n\n if (filter.name !== room.name) {\n isAllowed = false;\n }\n\n if (filter.metadata) {\n for (const field in filter.metadata) {\n if (room.metadata[field] !== filter.metadata[field]) {\n isAllowed = false;\n break;\n }\n }\n }\n\n return isAllowed;\n }\n\n}\n"],
|
|
5
|
+
"mappings": ";;;;;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AACA,iBAA4B;AAE5B,mBAA+B;AAC/B,kBAAqB;AAkBd,MAAM,kBAAkB,iBAAK;AAAA,EAA7B;AAAA;AACL,SAAO,QAAsB,CAAC;AAG9B,SAAO,gBAAuD,CAAC;AAAA;AAAA,EAE/D,MAAa,SAAS,SAAc;AAElC,SAAK,QAAQ,WAAW;AAExB,SAAK,mBAAmB,UAAM,6BAAe,CAAC,QAAQ,SAAS;AAC7D,YAAM,YAAY,KAAK,MAAM,UAAU,CAAC,SAAS,KAAK,WAAW,MAAM;AACvE,YAAM,UAAU,KAAK,QAAQ,OAAO,CAAC,WAAW,KAAK,cAAc,OAAO,UAAU;AAEpF,UAAI,CAAC,MAAM;AAET,YAAI,cAAc,IAAI;AACpB,gBAAM,eAAe,KAAK,MAAM;AAEhC,eAAK,MAAM,OAAO,WAAW,CAAC;AAE9B,kBAAQ,QAAQ,CAAC,WAAW;AAC1B,gBAAI,KAAK,oBAAoB,cAAc,KAAK,cAAc,OAAO,WAAW,MAAM,GAAG;AACvF,qBAAO,KAAK,KAAK,MAAM;AAAA,YACzB;AAAA,UACF,CAAC;AAAA,QACH;AAAA,MAEF,WAAW,cAAc,IAAI;AAE3B,aAAK,MAAM,KAAK,IAAI;AAEpB,gBAAQ,QAAQ,CAAC,WAAW;AAC1B,cAAI,KAAK,oBAAoB,MAAM,KAAK,cAAc,OAAO,WAAW,MAAM,GAAG;AAC/E,mBAAO,KAAK,KAAK,CAAC,QAAQ,IAAI,CAAC;AAAA,UACjC;AAAA,QACF,CAAC;AAAA,MAEH,OAAO;AACL,cAAM,eAAe,KAAK,MAAM;AAGhC,aAAK,MAAM,aAAa;AAExB,gBAAQ,QAAQ,CAAC,WAAW;AAC1B,gBAAM,UAAU,KAAK,oBAAoB,cAAc,KAAK,cAAc,OAAO,WAAW,MAAM;AAClG,gBAAM,UAAU,KAAK,oBAAoB,MAAM,KAAK,cAAc,OAAO,WAAW,MAAM;AAE1F,cAAI,WAAW,CAAC,SAAS;AACvB,mBAAO,KAAK,KAAK,MAAM;AAAA,UAEzB,WAAW,SAAS;AAClB,mBAAO,KAAK,KAAK,CAAC,QAAQ,IAAI,CAAC;AAAA,UACjC;AAAA,QACF,CAAC;AAAA,MACH;AAAA,IACF,CAAC;AAED,SAAK,QAAQ,MAAM,WAAW,MAAM,EAAE,SAAS,OAAO,UAAU,MAAM,CAAC;AAEvE,SAAK,UAAU,UAAU,CAAC,QAAgB,WAAwB;AAChE,WAAK,cAAc,OAAO,WAAW,SAAS;AAC9C,aAAO,KAAK,SAAS,KAAK,qBAAqB,KAAK,cAAc,OAAO,UAAU,CAAC;AAAA,IACtF,CAAC;AAAA,EACH;AAAA,EAEO,OAAO,QAAgB,SAAuB;AACnD,SAAK,cAAc,OAAO,aAAa,WAAW,CAAC;AACnD,WAAO,KAAK,SAAS,KAAK,qBAAqB,KAAK,cAAc,OAAO,UAAU,CAAC;AAAA,EACtF;AAAA,EAEO,QAAQ,QAAgB;AAC7B,WAAO,KAAK,cAAc,OAAO;AAAA,EACnC;AAAA,EAEO,YAAY;AACjB,QAAI,KAAK,kBAAkB;AACzB,WAAK,iBAAiB;AAAA,IACxB;AAAA,EACF;AAAA,EAEU,qBAAqB,SAAuB;AACpD,UAAM,SAAS,QAAQ;AAEvB,WAAQ,SACJ,KAAK,MAAM,OAAO,CAAC,SAAS,KAAK,oBAAoB,MAAM,MAAM,CAAC,IAClE,KAAK;AAAA,EACX;AAAA,EAEU,oBAAoB,MAAkB,QAAiC;AAC/E,QAAI,CAAC,QAAQ;AACX,aAAO;AAAA,IACT;AAEA,QAAI,YAAY;AAEhB,QAAI,OAAO,SAAS,KAAK,MAAM;AAC7B,kBAAY;AAAA,IACd;AAEA,QAAI,OAAO,UAAU;AACnB,iBAAW,SAAS,OAAO,UAAU;AACnC,YAAI,KAAK,SAAS,WAAW,OAAO,SAAS,QAAQ;AACnD,sBAAY;AACZ;AAAA,QACF;AAAA,MACF;AAAA,IACF;AAEA,WAAO;AAAA,EACT;AAEF;",
|
|
6
6
|
"names": []
|
|
7
7
|
}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../../src/rooms/LobbyRoom.ts"],
|
|
4
|
-
"sourcesContent": ["\nimport * as matchMaker from '../MatchMaker';\nimport {
|
|
5
|
-
"mappings": "AACA,YAAY,gBAAgB;AAE5B,SAAS,sBAAsB;AAC/B,SAAS,YAAY;AAkBd,MAAM,kBAAkB,KAAK;AAAA,EAA7B;AAAA;AACL,SAAO,
|
|
4
|
+
"sourcesContent": ["\nimport * as matchMaker from '../MatchMaker';\nimport { IRoomCache } from '../matchmaker/driver/local/LocalDriver';\nimport { subscribeLobby } from '../matchmaker/Lobby';\nimport { Room } from '../Room';\nimport { Client } from '../Transport';\n\n// TODO: use Schema state & filters on version 1.0.0\n\n// class DummyLobbyState extends Schema { // tslint:disable-line\n// @type(\"number\") public _: number;\n// }\n\nexport interface FilterInput {\n name?: string;\n metadata?: any;\n}\n\nexport interface LobbyOptions {\n filter?: FilterInput;\n}\n\nexport class LobbyRoom extends Room { // tslint:disable-line\n public rooms: IRoomCache[] = [];\n public unsubscribeLobby: () => void;\n\n public clientOptions: { [sessionId: string]: LobbyOptions } = {};\n\n public async onCreate(options: any) {\n // prevent LobbyRoom to notify itself\n this.listing.unlisted = true;\n\n this.unsubscribeLobby = await subscribeLobby((roomId, data) => {\n const roomIndex = this.rooms.findIndex((room) => room.roomId === roomId);\n const clients = this.clients.filter((client) => this.clientOptions[client.sessionId]);\n\n if (!data) {\n // remove room listing data\n if (roomIndex !== -1) {\n const previousData = this.rooms[roomIndex];\n\n this.rooms.splice(roomIndex, 1);\n\n clients.forEach((client) => {\n if (this.filterItemForClient(previousData, this.clientOptions[client.sessionId].filter)) {\n client.send('-', roomId);\n }\n });\n }\n\n } else if (roomIndex === -1) {\n // append room listing data\n this.rooms.push(data);\n\n clients.forEach((client) => {\n if (this.filterItemForClient(data, this.clientOptions[client.sessionId].filter)) {\n client.send('+', [roomId, data]);\n }\n });\n\n } else {\n const previousData = this.rooms[roomIndex];\n\n // replace room listing data\n this.rooms[roomIndex] = data;\n\n clients.forEach((client) => {\n const hadData = this.filterItemForClient(previousData, this.clientOptions[client.sessionId].filter);\n const hasData = this.filterItemForClient(data, this.clientOptions[client.sessionId].filter);\n\n if (hadData && !hasData) {\n client.send('-', roomId);\n\n } else if (hasData) {\n client.send('+', [roomId, data]);\n }\n });\n }\n });\n\n this.rooms = await matchMaker.query({ private: false, unlisted: false });\n\n this.onMessage('filter', (client: Client, filter: FilterInput) => {\n this.clientOptions[client.sessionId].filter = filter;\n client.send('rooms', this.filterItemsForClient(this.clientOptions[client.sessionId]));\n });\n }\n\n public onJoin(client: Client, options: LobbyOptions) {\n this.clientOptions[client.sessionId] = options || {};\n client.send('rooms', this.filterItemsForClient(this.clientOptions[client.sessionId]));\n }\n\n public onLeave(client: Client) {\n delete this.clientOptions[client.sessionId];\n }\n\n public onDispose() {\n if (this.unsubscribeLobby) {\n this.unsubscribeLobby();\n }\n }\n\n protected filterItemsForClient(options: LobbyOptions) {\n const filter = options.filter;\n\n return (filter)\n ? this.rooms.filter((room) => this.filterItemForClient(room, filter))\n : this.rooms;\n }\n\n protected filterItemForClient(room: IRoomCache, filter?: LobbyOptions['filter']) {\n if (!filter) {\n return true;\n }\n\n let isAllowed = true;\n\n if (filter.name !== room.name) {\n isAllowed = false;\n }\n\n if (filter.metadata) {\n for (const field in filter.metadata) {\n if (room.metadata[field] !== filter.metadata[field]) {\n isAllowed = false;\n break;\n }\n }\n }\n\n return isAllowed;\n }\n\n}\n"],
|
|
5
|
+
"mappings": "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",
|
|
6
6
|
"names": []
|
|
7
7
|
}
|
|
@@ -1,19 +1,20 @@
|
|
|
1
|
-
/// <reference types="node" />
|
|
2
1
|
import { Serializer } from './Serializer';
|
|
3
|
-
import { Schema } from '@colyseus/schema';
|
|
2
|
+
import { Encoder, Schema, Iterator, StateView } from '@colyseus/schema';
|
|
4
3
|
import { Client } from '../Transport';
|
|
4
|
+
declare const SHARED_VIEW: {};
|
|
5
5
|
export declare class SchemaSerializer<T> implements Serializer<T> {
|
|
6
6
|
id: string;
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
7
|
+
protected encoder: Encoder;
|
|
8
|
+
protected hasFilters: boolean;
|
|
9
|
+
protected handshakeCache: Buffer;
|
|
10
|
+
protected needFullEncode: boolean;
|
|
11
|
+
protected fullEncodeBuffer: Buffer;
|
|
12
|
+
protected fullEncodeCache: Buffer;
|
|
13
|
+
protected sharedOffsetCache: Iterator;
|
|
14
|
+
protected views: Map<StateView | typeof SHARED_VIEW, Buffer>;
|
|
15
15
|
reset(newState: T & Schema): void;
|
|
16
16
|
getFullState(client?: Client): Buffer;
|
|
17
17
|
applyPatches(clients: Client[]): boolean;
|
|
18
18
|
handshake(): Buffer;
|
|
19
19
|
}
|
|
20
|
+
export {};
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../../src/serializer/SchemaSerializer.ts"],
|
|
4
|
-
"sourcesContent": ["import { Serializer } from './Serializer';\n\nimport { Encoder, dumpChanges, Reflection, Schema, Iterator, StateView } from '@colyseus/schema';\nimport { debugPatch } from '../Debug';\nimport { Protocol } from '../Protocol';\nimport { Client, ClientState } from '../Transport';\n\nconst SHARED_VIEW = {};\n\nexport class SchemaSerializer<T> implements Serializer<T> {\n public id = 'schema';\n\n
|
|
5
|
-
"mappings": ";;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAEA,oBAA8E;AAC9E,mBAA2B;AAC3B,sBAAyB;AACzB,uBAAoC;AAEpC,MAAM,cAAc,CAAC;AAEd,MAAM,iBAA6C;AAAA,EAAnD;AACL,SAAO,KAAK;AAGZ,
|
|
4
|
+
"sourcesContent": ["import { Serializer } from './Serializer';\n\nimport { Encoder, dumpChanges, Reflection, Schema, Iterator, StateView } from '@colyseus/schema';\nimport { debugPatch } from '../Debug';\nimport { Protocol } from '../Protocol';\nimport { Client, ClientState } from '../Transport';\n\nconst SHARED_VIEW = {};\n\nexport class SchemaSerializer<T> implements Serializer<T> {\n public id = 'schema';\n\n protected encoder: Encoder;\n protected hasFilters: boolean = false;\n\n protected handshakeCache: Buffer;\n\n // flag to avoid re-encoding full state if no changes were made\n protected needFullEncode: boolean = true;\n\n // TODO: make this optional. allocating a new buffer for each room may not be always necessary.\n protected fullEncodeBuffer: Buffer = Buffer.allocUnsafe(Encoder.BUFFER_SIZE);\n protected fullEncodeCache: Buffer;\n protected sharedOffsetCache: Iterator = { offset: 0 };\n\n protected views: Map<StateView | typeof SHARED_VIEW, Buffer>;\n\n public reset(newState: T & Schema) {\n this.encoder = new Encoder(newState);\n this.hasFilters = this.encoder.context.hasFilters;\n\n // cache ROOM_STATE byte as part of the encoded buffer\n this.fullEncodeBuffer[0] = Protocol.ROOM_STATE;\n\n if (this.hasFilters) {\n this.views = new Map();\n }\n }\n\n public getFullState(client?: Client) {\n if (this.needFullEncode || this.encoder.root.changes.size > 0) {\n this.sharedOffsetCache = { offset: 1 };\n this.fullEncodeCache = this.encoder.encodeAll(this.sharedOffsetCache, this.fullEncodeBuffer);\n this.needFullEncode = false;\n }\n\n if (this.hasFilters && client?.view) {\n return this.encoder.encodeAllView(\n client.view,\n this.sharedOffsetCache.offset,\n { ...this.sharedOffsetCache },\n this.fullEncodeBuffer\n );\n\n } else {\n return this.fullEncodeCache;\n }\n }\n\n public applyPatches(clients: Client[]) {\n let numClients = clients.length;\n this.needFullEncode = (this.encoder.root.changes.size > 0);\n\n if (\n numClients == 0 ||\n (\n !this.needFullEncode &&\n (!this.hasFilters || this.encoder.root.filteredChanges.size === 0)\n )\n ) {\n // skip patching state if:\n // - no clients are connected\n // - no changes were made\n // - no \"filtered changes\" were made when using filters\n return false;\n }\n\n\n // dump changes for patch debugging\n if (debugPatch.enabled) {\n (debugPatch as any).dumpChanges = dumpChanges(this.encoder.state);\n }\n\n // get patch bytes\n const it: Iterator = { offset: 1 };\n this.encoder.sharedBuffer[0] = Protocol.ROOM_STATE_PATCH;\n\n // encode changes once, for all clients\n const encodedChanges = this.encoder.encode(it);\n\n if (!this.hasFilters) {\n while (numClients--) {\n const client = clients[numClients];\n\n //\n // FIXME: avoid this check for each client\n //\n if (client.state !== ClientState.JOINED) {\n continue;\n }\n\n client.raw(encodedChanges);\n }\n\n } else {\n // cache shared offset\n const sharedOffset = it.offset;\n\n // encode state multiple times, for each client\n while (numClients--) {\n const client = clients[numClients];\n\n //\n // FIXME: avoid this check for each client\n //\n if (client.state !== ClientState.JOINED) {\n continue;\n }\n\n const view = client.view || SHARED_VIEW;\n\n let encodedView = this.views.get(view);\n\n // allow to pass the same encoded view for multiple clients\n if (encodedView === undefined) {\n encodedView = (view === SHARED_VIEW)\n ? encodedChanges\n : this.encoder.encodeView(client.view, sharedOffset, it);\n this.views.set(view, encodedView);\n }\n\n client.raw(encodedView);\n }\n\n // clear views\n this.views.clear();\n }\n\n // discard changes after sending\n this.encoder.discardChanges();\n\n // debug patches\n if (debugPatch.enabled) {\n debugPatch(\n '%d bytes sent to %d clients, %j',\n encodedChanges.length,\n clients.length,\n (debugPatch as any).dumpChanges,\n );\n }\n\n return true;\n }\n\n public handshake() {\n /**\n * Cache handshake to avoid encoding it for each client joining\n */\n if (!this.handshakeCache) {\n // TODO: re-use handshake buffer for all rooms\n this.handshakeCache = (this.encoder.state && Reflection.encode(this.encoder.state));\n }\n\n return this.handshakeCache;\n }\n\n}\n"],
|
|
5
|
+
"mappings": "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",
|
|
6
6
|
"names": []
|
|
7
7
|
}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../../src/serializer/SchemaSerializer.ts"],
|
|
4
|
-
"sourcesContent": ["import { Serializer } from './Serializer';\n\nimport { Encoder, dumpChanges, Reflection, Schema, Iterator, StateView } from '@colyseus/schema';\nimport { debugPatch } from '../Debug';\nimport { Protocol } from '../Protocol';\nimport { Client, ClientState } from '../Transport';\n\nconst SHARED_VIEW = {};\n\nexport class SchemaSerializer<T> implements Serializer<T> {\n public id = 'schema';\n\n
|
|
5
|
-
"mappings": "AAEA,SAAS,SAAS,aAAa,kBAA+C;AAC9E,SAAS,kBAAkB;AAC3B,SAAS,gBAAgB;AACzB,SAAiB,mBAAmB;AAEpC,MAAM,cAAc,CAAC;AAEd,MAAM,iBAA6C;AAAA,EAAnD;AACL,SAAO,KAAK;AAGZ,
|
|
4
|
+
"sourcesContent": ["import { Serializer } from './Serializer';\n\nimport { Encoder, dumpChanges, Reflection, Schema, Iterator, StateView } from '@colyseus/schema';\nimport { debugPatch } from '../Debug';\nimport { Protocol } from '../Protocol';\nimport { Client, ClientState } from '../Transport';\n\nconst SHARED_VIEW = {};\n\nexport class SchemaSerializer<T> implements Serializer<T> {\n public id = 'schema';\n\n protected encoder: Encoder;\n protected hasFilters: boolean = false;\n\n protected handshakeCache: Buffer;\n\n // flag to avoid re-encoding full state if no changes were made\n protected needFullEncode: boolean = true;\n\n // TODO: make this optional. allocating a new buffer for each room may not be always necessary.\n protected fullEncodeBuffer: Buffer = Buffer.allocUnsafe(Encoder.BUFFER_SIZE);\n protected fullEncodeCache: Buffer;\n protected sharedOffsetCache: Iterator = { offset: 0 };\n\n protected views: Map<StateView | typeof SHARED_VIEW, Buffer>;\n\n public reset(newState: T & Schema) {\n this.encoder = new Encoder(newState);\n this.hasFilters = this.encoder.context.hasFilters;\n\n // cache ROOM_STATE byte as part of the encoded buffer\n this.fullEncodeBuffer[0] = Protocol.ROOM_STATE;\n\n if (this.hasFilters) {\n this.views = new Map();\n }\n }\n\n public getFullState(client?: Client) {\n if (this.needFullEncode || this.encoder.root.changes.size > 0) {\n this.sharedOffsetCache = { offset: 1 };\n this.fullEncodeCache = this.encoder.encodeAll(this.sharedOffsetCache, this.fullEncodeBuffer);\n this.needFullEncode = false;\n }\n\n if (this.hasFilters && client?.view) {\n return this.encoder.encodeAllView(\n client.view,\n this.sharedOffsetCache.offset,\n { ...this.sharedOffsetCache },\n this.fullEncodeBuffer\n );\n\n } else {\n return this.fullEncodeCache;\n }\n }\n\n public applyPatches(clients: Client[]) {\n let numClients = clients.length;\n this.needFullEncode = (this.encoder.root.changes.size > 0);\n\n if (\n numClients == 0 ||\n (\n !this.needFullEncode &&\n (!this.hasFilters || this.encoder.root.filteredChanges.size === 0)\n )\n ) {\n // skip patching state if:\n // - no clients are connected\n // - no changes were made\n // - no \"filtered changes\" were made when using filters\n return false;\n }\n\n\n // dump changes for patch debugging\n if (debugPatch.enabled) {\n (debugPatch as any).dumpChanges = dumpChanges(this.encoder.state);\n }\n\n // get patch bytes\n const it: Iterator = { offset: 1 };\n this.encoder.sharedBuffer[0] = Protocol.ROOM_STATE_PATCH;\n\n // encode changes once, for all clients\n const encodedChanges = this.encoder.encode(it);\n\n if (!this.hasFilters) {\n while (numClients--) {\n const client = clients[numClients];\n\n //\n // FIXME: avoid this check for each client\n //\n if (client.state !== ClientState.JOINED) {\n continue;\n }\n\n client.raw(encodedChanges);\n }\n\n } else {\n // cache shared offset\n const sharedOffset = it.offset;\n\n // encode state multiple times, for each client\n while (numClients--) {\n const client = clients[numClients];\n\n //\n // FIXME: avoid this check for each client\n //\n if (client.state !== ClientState.JOINED) {\n continue;\n }\n\n const view = client.view || SHARED_VIEW;\n\n let encodedView = this.views.get(view);\n\n // allow to pass the same encoded view for multiple clients\n if (encodedView === undefined) {\n encodedView = (view === SHARED_VIEW)\n ? encodedChanges\n : this.encoder.encodeView(client.view, sharedOffset, it);\n this.views.set(view, encodedView);\n }\n\n client.raw(encodedView);\n }\n\n // clear views\n this.views.clear();\n }\n\n // discard changes after sending\n this.encoder.discardChanges();\n\n // debug patches\n if (debugPatch.enabled) {\n debugPatch(\n '%d bytes sent to %d clients, %j',\n encodedChanges.length,\n clients.length,\n (debugPatch as any).dumpChanges,\n );\n }\n\n return true;\n }\n\n public handshake() {\n /**\n * Cache handshake to avoid encoding it for each client joining\n */\n if (!this.handshakeCache) {\n // TODO: re-use handshake buffer for all rooms\n this.handshakeCache = (this.encoder.state && Reflection.encode(this.encoder.state));\n }\n\n return this.handshakeCache;\n }\n\n}\n"],
|
|
5
|
+
"mappings": "AAEA,SAAS,SAAS,aAAa,kBAA+C;AAC9E,SAAS,kBAAkB;AAC3B,SAAS,gBAAgB;AACzB,SAAiB,mBAAmB;AAEpC,MAAM,cAAc,CAAC;AAEd,MAAM,iBAA6C;AAAA,EAAnD;AACL,SAAO,KAAK;AAGZ,SAAU,aAAsB;AAKhC,SAAU,iBAA0B;AAGpC,SAAU,mBAA2B,OAAO,YAAY,QAAQ,WAAW;AAE3E,SAAU,oBAA8B,EAAE,QAAQ,EAAE;AAAA;AAAA,EAI7C,MAAM,UAAsB;AACjC,SAAK,UAAU,IAAI,QAAQ,QAAQ;AACnC,SAAK,aAAa,KAAK,QAAQ,QAAQ;AAGvC,SAAK,iBAAiB,KAAK,SAAS;AAEpC,QAAI,KAAK,YAAY;AACnB,WAAK,QAAQ,oBAAI,IAAI;AAAA,IACvB;AAAA,EACF;AAAA,EAEO,aAAa,QAAiB;AACnC,QAAI,KAAK,kBAAkB,KAAK,QAAQ,KAAK,QAAQ,OAAO,GAAG;AAC7D,WAAK,oBAAoB,EAAE,QAAQ,EAAE;AACrC,WAAK,kBAAkB,KAAK,QAAQ,UAAU,KAAK,mBAAmB,KAAK,gBAAgB;AAC3F,WAAK,iBAAiB;AAAA,IACxB;AAEA,QAAI,KAAK,cAAc,QAAQ,MAAM;AACnC,aAAO,KAAK,QAAQ;AAAA,QAClB,OAAO;AAAA,QACP,KAAK,kBAAkB;AAAA,QACvB,EAAE,GAAG,KAAK,kBAAkB;AAAA,QAC5B,KAAK;AAAA,MACP;AAAA,IAEF,OAAO;AACL,aAAO,KAAK;AAAA,IACd;AAAA,EACF;AAAA,EAEO,aAAa,SAAmB;AACrC,QAAI,aAAa,QAAQ;AACzB,SAAK,iBAAkB,KAAK,QAAQ,KAAK,QAAQ,OAAO;AAExD,QACE,cAAc,KAEZ,CAAC,KAAK,mBACL,CAAC,KAAK,cAAc,KAAK,QAAQ,KAAK,gBAAgB,SAAS,IAElE;AAKA,aAAO;AAAA,IACT;AAIA,QAAI,WAAW,SAAS;AACtB,MAAC,WAAmB,cAAc,YAAY,KAAK,QAAQ,KAAK;AAAA,IAClE;AAGA,UAAM,KAAe,EAAE,QAAQ,EAAE;AACjC,SAAK,QAAQ,aAAa,KAAK,SAAS;AAGxC,UAAM,iBAAiB,KAAK,QAAQ,OAAO,EAAE;AAE7C,QAAI,CAAC,KAAK,YAAY;AACpB,aAAO,cAAc;AACnB,cAAM,SAAS,QAAQ;AAKvB,YAAI,OAAO,UAAU,YAAY,QAAQ;AACvC;AAAA,QACF;AAEA,eAAO,IAAI,cAAc;AAAA,MAC3B;AAAA,IAEF,OAAO;AAEL,YAAM,eAAe,GAAG;AAGxB,aAAO,cAAc;AACnB,cAAM,SAAS,QAAQ;AAKvB,YAAI,OAAO,UAAU,YAAY,QAAQ;AACvC;AAAA,QACF;AAEA,cAAM,OAAO,OAAO,QAAQ;AAE5B,YAAI,cAAc,KAAK,MAAM,IAAI,IAAI;AAGrC,YAAI,gBAAgB,QAAW;AAC7B,wBAAe,SAAS,cACpB,iBACA,KAAK,QAAQ,WAAW,OAAO,MAAM,cAAc,EAAE;AACzD,eAAK,MAAM,IAAI,MAAM,WAAW;AAAA,QAClC;AAEA,eAAO,IAAI,WAAW;AAAA,MACxB;AAGA,WAAK,MAAM,MAAM;AAAA,IACnB;AAGA,SAAK,QAAQ,eAAe;AAG5B,QAAI,WAAW,SAAS;AACtB;AAAA,QACE;AAAA,QACA,eAAe;AAAA,QACf,QAAQ;AAAA,QACP,WAAmB;AAAA,MACtB;AAAA,IACF;AAEA,WAAO;AAAA,EACT;AAAA,EAEO,YAAY;AAIjB,QAAI,CAAC,KAAK,gBAAgB;AAExB,WAAK,iBAAkB,KAAK,QAAQ,SAAS,WAAW,OAAO,KAAK,QAAQ,KAAK;AAAA,IACnF;AAEA,WAAO,KAAK;AAAA,EACd;AAEF;",
|
|
6
6
|
"names": []
|
|
7
7
|
}
|
package/build/utils/Utils.d.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
/// <reference types="node" />
|
|
2
1
|
import { EventEmitter } from "events";
|
|
3
2
|
export declare const REMOTE_ROOM_SHORT_TIMEOUT: number;
|
|
3
|
+
export declare const MAX_CONCURRENT_CREATE_ROOM_WAIT_TIME: number;
|
|
4
4
|
export declare function generateId(length?: number): any;
|
|
5
5
|
export declare function getBearerToken(authHeader: string): string;
|
|
6
6
|
export declare function registerGracefulShutdown(callback: (err?: Error) => void): void;
|
|
@@ -10,9 +10,11 @@ export declare class Deferred<T = any> {
|
|
|
10
10
|
promise: Promise<T>;
|
|
11
11
|
resolve: Function;
|
|
12
12
|
reject: Function;
|
|
13
|
-
constructor();
|
|
13
|
+
constructor(promise?: Promise<T>);
|
|
14
14
|
then(func: (value: T) => any): any;
|
|
15
15
|
catch(func: (value: any) => any): Promise<any>;
|
|
16
|
+
static reject(reason?: any): Deferred<never>;
|
|
17
|
+
static resolve<T = any>(value?: T): Deferred<T>;
|
|
16
18
|
}
|
|
17
19
|
export declare function merge(a: any, ...objs: any[]): any;
|
|
18
20
|
export declare class HttpServerMock extends EventEmitter {
|