@nanotoolkit/game-sdk 0.1.9 → 0.1.11
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/Lib/Bridge/GameBridge.js +29 -5
- package/index.d.ts +2 -0
- package/package.json +1 -1
package/Lib/Bridge/GameBridge.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { parseWireJSON, stringifyWireJSON } from './WireJSON.js';
|
|
2
2
|
import { GameState } from './GameState.js';
|
|
3
3
|
|
|
4
|
-
export const SDK_VERSION = '0.1.
|
|
4
|
+
export const SDK_VERSION = '0.1.11';
|
|
5
5
|
|
|
6
6
|
const REQUEST_TIMEOUT_MS = 10000;
|
|
7
7
|
|
|
@@ -123,6 +123,7 @@ export function ready(bundleId, onInit) {
|
|
|
123
123
|
});
|
|
124
124
|
subscribe('game:ping', (msg) => send({ type: 'game:pong', echo: msg.ts }));
|
|
125
125
|
ensureBackListener();
|
|
126
|
+
ensureExitListener();
|
|
126
127
|
ensureStateListeners();
|
|
127
128
|
subscribe('game:init', (msg) => {
|
|
128
129
|
if (initState) return;
|
|
@@ -132,7 +133,7 @@ export function ready(bundleId, onInit) {
|
|
|
132
133
|
settleInit(publicInit(msg));
|
|
133
134
|
for (const run of initWaiters.splice(0)) run();
|
|
134
135
|
});
|
|
135
|
-
send({ type: 'game:ready', game: bundleId, sdk: SDK_VERSION });
|
|
136
|
+
send({ type: 'game:ready', game: bundleId, sdk: SDK_VERSION, exitLifecycle: 1 });
|
|
136
137
|
}
|
|
137
138
|
if (typeof onInit === 'function') initPromise.then(onInit);
|
|
138
139
|
return initPromise;
|
|
@@ -155,6 +156,22 @@ export function serverNow() {
|
|
|
155
156
|
}
|
|
156
157
|
|
|
157
158
|
const backHandlers = new Set();
|
|
159
|
+
const exitHandlers = new Set();
|
|
160
|
+
|
|
161
|
+
function ensureExitListener() {
|
|
162
|
+
if (ensureExitListener.done) return;
|
|
163
|
+
ensureExitListener.done = true;
|
|
164
|
+
let lastSequence = null;
|
|
165
|
+
subscribe('game:will_exit', (msg) => {
|
|
166
|
+
if (msg.seq !== lastSequence) {
|
|
167
|
+
lastSequence = msg.seq;
|
|
168
|
+
for (const handler of [...exitHandlers]) {
|
|
169
|
+
try { handler(); } catch (error) { console.error('[game-sdk] handler error', error); }
|
|
170
|
+
}
|
|
171
|
+
}
|
|
172
|
+
send({ type: 'game:exit_ready', seq: msg.seq });
|
|
173
|
+
});
|
|
174
|
+
}
|
|
158
175
|
|
|
159
176
|
function ensureBackListener() {
|
|
160
177
|
if (ensureBackListener.done) return;
|
|
@@ -205,6 +222,11 @@ function emitLocal(event, payload) {
|
|
|
205
222
|
|
|
206
223
|
export function on(event, handler) {
|
|
207
224
|
if (typeof handler !== 'function') throw new TypeError('invalid handler');
|
|
225
|
+
if (event === 'willExit') {
|
|
226
|
+
ensureExitListener();
|
|
227
|
+
exitHandlers.add(handler);
|
|
228
|
+
return () => exitHandlers.delete(handler);
|
|
229
|
+
}
|
|
208
230
|
if (event === 'back') {
|
|
209
231
|
ensureBackListener();
|
|
210
232
|
backHandlers.add(handler);
|
|
@@ -225,7 +247,7 @@ export function on(event, handler) {
|
|
|
225
247
|
const spec = EVENTS[event];
|
|
226
248
|
if (!spec)
|
|
227
249
|
throw new TypeError(
|
|
228
|
-
`invalid event: ${event} / ${[...Object.keys(EVENTS), 'back', ...Object.keys(localHandlers)].join(
|
|
250
|
+
`invalid event: ${event} / ${[...Object.keys(EVENTS), 'back', 'willExit', ...Object.keys(localHandlers)].join(
|
|
229
251
|
' / ',
|
|
230
252
|
)}`,
|
|
231
253
|
);
|
|
@@ -409,6 +431,7 @@ function ensureStateListeners() {
|
|
|
409
431
|
const directory = roomDirectory ?? lastEntry;
|
|
410
432
|
if (!directory || msg.rooms?.gameId !== directory.gameId || !Array.isArray(msg.rooms.rooms)) return;
|
|
411
433
|
const known = new Map((directory.rooms ?? []).map((room) => [room.id, room]));
|
|
434
|
+
const updates = new Map(msg.rooms.rooms.map((room) => [room.id, room]));
|
|
412
435
|
if (msg.rooms.rooms.some((room) => !known.has(room.id))) {
|
|
413
436
|
getGameRooms().catch(() => {});
|
|
414
437
|
return;
|
|
@@ -417,9 +440,10 @@ function ensureStateListeners() {
|
|
|
417
440
|
...directory,
|
|
418
441
|
...msg.rooms,
|
|
419
442
|
topic: roomDirectory?.topic ?? lastEntry?.roomsTopic ?? 'game:' + directory.gameId,
|
|
420
|
-
rooms:
|
|
421
|
-
...known.get(room.id),
|
|
443
|
+
rooms: (directory.rooms ?? []).filter((room) => updates.has(room.id)).map((room) => ({
|
|
422
444
|
...room,
|
|
445
|
+
onlineCount: updates.get(room.id).onlineCount,
|
|
446
|
+
targetTime: updates.get(room.id).targetTime,
|
|
423
447
|
})),
|
|
424
448
|
};
|
|
425
449
|
if (lastEntry?.gameId === roomDirectory.gameId) lastEntry.rooms = roomDirectory.rooms;
|
package/index.d.ts
CHANGED
|
@@ -83,6 +83,7 @@ export interface GameRoom {
|
|
|
83
83
|
id: number;
|
|
84
84
|
gameId: number;
|
|
85
85
|
roomName: string;
|
|
86
|
+
roomIcon: string | null;
|
|
86
87
|
position: number;
|
|
87
88
|
onlineCount: number;
|
|
88
89
|
targetTime: number;
|
|
@@ -294,6 +295,7 @@ export function watchIssues(): () => void;
|
|
|
294
295
|
export interface EventPayloads {
|
|
295
296
|
pause: undefined;
|
|
296
297
|
resume: undefined;
|
|
298
|
+
willExit: undefined;
|
|
297
299
|
theme: { dark: boolean };
|
|
298
300
|
lang: { lang: string };
|
|
299
301
|
|