@signe/room 2.4.0 → 2.4.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.d.ts +16 -4
- package/dist/index.js +63 -14
- package/dist/index.js.map +1 -1
- package/package.json +2 -2
- package/src/mock.ts +52 -12
- package/src/server.ts +1 -1
- package/src/testing.ts +23 -6
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@signe/room",
|
|
3
|
-
"version": "2.4.
|
|
3
|
+
"version": "2.4.2",
|
|
4
4
|
"description": "",
|
|
5
5
|
"main": "./dist/index.js",
|
|
6
6
|
"keywords": [],
|
|
@@ -17,7 +17,7 @@
|
|
|
17
17
|
"dset": "^3.1.3",
|
|
18
18
|
"partysocket": "^1.0.1",
|
|
19
19
|
"zod": "^3.23.8",
|
|
20
|
-
"@signe/sync": "2.4.
|
|
20
|
+
"@signe/sync": "2.4.2"
|
|
21
21
|
},
|
|
22
22
|
"publishConfig": {
|
|
23
23
|
"access": "public"
|
package/src/mock.ts
CHANGED
|
@@ -47,29 +47,62 @@ export class MockPartyClient {
|
|
|
47
47
|
}
|
|
48
48
|
|
|
49
49
|
class MockLobby {
|
|
50
|
-
constructor(public server: Server) {}
|
|
50
|
+
constructor(public server: Server, public lobbyId: string) {}
|
|
51
51
|
|
|
52
|
-
socket() {
|
|
52
|
+
socket(_init?: any) {
|
|
53
53
|
return new MockPartyClient(this.server)
|
|
54
54
|
}
|
|
55
55
|
|
|
56
|
+
async connection(idOrOptions?: string | { id?: string, query?: Record<string, string>, headers?: Record<string, string> }, maybeOptions?: { query?: Record<string, string>, headers?: Record<string, string> }) {
|
|
57
|
+
const id = typeof idOrOptions === 'string' ? idOrOptions : idOrOptions?.id;
|
|
58
|
+
const options = (typeof idOrOptions === 'string' ? maybeOptions : idOrOptions) || {};
|
|
59
|
+
return (this.server.room as any).connection(this.server, id, options as any);
|
|
60
|
+
}
|
|
61
|
+
|
|
56
62
|
fetch(url: string, options: any) {
|
|
57
|
-
|
|
63
|
+
const baseUrl = url.includes('shard') ? '' :( '/parties/main/' + this.lobbyId )
|
|
64
|
+
return request(this.server, baseUrl + url, options)
|
|
58
65
|
}
|
|
59
66
|
}
|
|
60
67
|
|
|
68
|
+
interface MockContextOptions {
|
|
69
|
+
parties?: any;
|
|
70
|
+
partyFn?: (room: MockPartyRoom) => any;
|
|
71
|
+
}
|
|
72
|
+
|
|
61
73
|
class MockContext {
|
|
62
74
|
parties: {
|
|
63
|
-
main:
|
|
75
|
+
main: any
|
|
64
76
|
} = {
|
|
65
77
|
main: new Map()
|
|
66
78
|
}
|
|
67
79
|
|
|
68
|
-
constructor(public room: MockPartyRoom, options:
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
80
|
+
constructor(public room: MockPartyRoom, options: MockContextOptions = {}) {
|
|
81
|
+
const parties = options.parties || {}
|
|
82
|
+
if (options.partyFn) {
|
|
83
|
+
const serverCache = new Map<string, Server>();
|
|
84
|
+
this.parties.main = {
|
|
85
|
+
get: async (lobbyId: string) => {
|
|
86
|
+
if (!serverCache.has(lobbyId)) {
|
|
87
|
+
// Create an isolated IO for the specified lobby without recursive parties
|
|
88
|
+
const io = new MockPartyRoom(lobbyId, { env: this.room.env });
|
|
89
|
+
const server = options.partyFn(io);
|
|
90
|
+
if (typeof server.onStart === 'function') {
|
|
91
|
+
await server.onStart();
|
|
92
|
+
}
|
|
93
|
+
serverCache.set(lobbyId, server);
|
|
94
|
+
}
|
|
95
|
+
const server = serverCache.get(lobbyId)!;
|
|
96
|
+
return new MockLobby(server, lobbyId)
|
|
97
|
+
}
|
|
98
|
+
}
|
|
99
|
+
}
|
|
100
|
+
else {
|
|
101
|
+
for (let lobbyId in parties) {
|
|
102
|
+
const server = parties[lobbyId](room)
|
|
103
|
+
;(this.parties.main as Map<string, any>).set(lobbyId, new MockLobby(server, lobbyId))
|
|
104
|
+
}
|
|
105
|
+
}
|
|
73
106
|
}
|
|
74
107
|
}
|
|
75
108
|
|
|
@@ -82,18 +115,25 @@ class MockPartyRoom {
|
|
|
82
115
|
constructor(public id?: string, options: any = {}) {
|
|
83
116
|
this.id = id || generateShortUUID()
|
|
84
117
|
this.context = new MockContext(this, {
|
|
85
|
-
parties: options.parties
|
|
118
|
+
parties: options.parties,
|
|
119
|
+
partyFn: options.partyFn
|
|
86
120
|
})
|
|
87
121
|
this.env = options.env || {}
|
|
88
122
|
}
|
|
89
123
|
|
|
90
|
-
async connection(server: Server, id?: string) {
|
|
124
|
+
async connection(server: Server, id?: string, opts?: { query?: Record<string, string>, headers?: Record<string, string> }) {
|
|
91
125
|
const socket = new MockPartyClient(server, id);
|
|
92
126
|
const url = new URL('http://localhost')
|
|
127
|
+
if (opts?.query) {
|
|
128
|
+
for (const [key, value] of Object.entries(opts.query)) {
|
|
129
|
+
url.searchParams.set(key, String(value))
|
|
130
|
+
}
|
|
131
|
+
}
|
|
93
132
|
const request = new Request(url.toString(), {
|
|
94
133
|
method: 'GET',
|
|
95
134
|
headers: {
|
|
96
|
-
'Content-Type': 'application/json'
|
|
135
|
+
'Content-Type': 'application/json',
|
|
136
|
+
...(opts?.headers || {})
|
|
97
137
|
}
|
|
98
138
|
})
|
|
99
139
|
await server.onConnect(socket.conn as any, { request } as any);
|
package/src/server.ts
CHANGED
|
@@ -335,7 +335,7 @@ export class Server implements Party.Server {
|
|
|
335
335
|
};
|
|
336
336
|
|
|
337
337
|
try {
|
|
338
|
-
const targetRoomParty = this.room.context.parties.main.get(targetRoomId);
|
|
338
|
+
const targetRoomParty = await this.room.context.parties.main.get(targetRoomId);
|
|
339
339
|
const response = await targetRoomParty.fetch('/session-transfer', {
|
|
340
340
|
method: 'POST',
|
|
341
341
|
body: JSON.stringify(transferData),
|
package/src/testing.ts
CHANGED
|
@@ -30,7 +30,9 @@ import { Shard } from "./shard"
|
|
|
30
30
|
export async function testRoom(Room, options: {
|
|
31
31
|
hibernate?: boolean,
|
|
32
32
|
shard?: boolean,
|
|
33
|
-
env?: Record<string, string
|
|
33
|
+
env?: Record<string, string>,
|
|
34
|
+
parties?: Record<string, (io: any) => any>,
|
|
35
|
+
partyFn?: (io: any) => any
|
|
34
36
|
} = {}) {
|
|
35
37
|
|
|
36
38
|
const createServer = (io: any) => {
|
|
@@ -42,10 +44,14 @@ export async function testRoom(Room, options: {
|
|
|
42
44
|
const isShard = options.shard || false
|
|
43
45
|
const io = new ServerIo(Room.path, isShard ? {
|
|
44
46
|
parties: {
|
|
45
|
-
game: createServer
|
|
47
|
+
game: createServer,
|
|
48
|
+
...(options.parties || {})
|
|
46
49
|
},
|
|
50
|
+
partyFn: options.partyFn,
|
|
47
51
|
env: options.env
|
|
48
52
|
} : {
|
|
53
|
+
parties: options.parties,
|
|
54
|
+
partyFn: options.partyFn,
|
|
49
55
|
env: options.env
|
|
50
56
|
})
|
|
51
57
|
Room.prototype.throttleSync = 0
|
|
@@ -58,11 +64,22 @@ export async function testRoom(Room, options: {
|
|
|
58
64
|
// Add subRoom property to Shard for compatibility with Server
|
|
59
65
|
(shardServer as any).subRoom = null;
|
|
60
66
|
server = shardServer;
|
|
61
|
-
|
|
62
|
-
|
|
67
|
+
// In shard mode, parties.main is a Map of lobbies; ensure their servers are started
|
|
68
|
+
if (io.context.parties.main instanceof Map) {
|
|
69
|
+
for (const lobby of io.context.parties.main.values()) {
|
|
70
|
+
await lobby.server.onStart();
|
|
71
|
+
}
|
|
63
72
|
}
|
|
64
73
|
} else {
|
|
65
74
|
server = await createServer(io as any);
|
|
75
|
+
// If extra parties are provided in non-shard mode, start them too
|
|
76
|
+
if (io.context.parties.main instanceof Map) {
|
|
77
|
+
for (const lobby of io.context.parties.main.values()) {
|
|
78
|
+
if (lobby.server && lobby.server !== server) {
|
|
79
|
+
await lobby.server.onStart();
|
|
80
|
+
}
|
|
81
|
+
}
|
|
82
|
+
}
|
|
66
83
|
}
|
|
67
84
|
|
|
68
85
|
await server.onStart()
|
|
@@ -70,8 +87,8 @@ export async function testRoom(Room, options: {
|
|
|
70
87
|
return {
|
|
71
88
|
server,
|
|
72
89
|
room: (server as any).subRoom,
|
|
73
|
-
createClient: async (id?: string) => {
|
|
74
|
-
const client = await io.connection(server as Server, id)
|
|
90
|
+
createClient: async (id?: string, opts?: { query?: Record<string, string>, headers?: Record<string, string> }) => {
|
|
91
|
+
const client = await io.connection(server as Server, id, opts)
|
|
75
92
|
return client
|
|
76
93
|
}
|
|
77
94
|
}
|