@unboxy/phaser-sdk 0.2.6 → 0.2.7
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/SDK-GUIDE.md
CHANGED
|
@@ -314,6 +314,7 @@ Rules of thumb:
|
|
|
314
314
|
|
|
315
315
|
## Changelog
|
|
316
316
|
|
|
317
|
+
- **0.2.7** — fixed handshake race on slow-mounting hosts. `PostMessageTransport.connect` now retries `unboxy:hello` every 200 ms until `unboxy:init` arrives (previously one-shot → lost on Android/mobile where React mounted after the iframe first fired hello). Default handshake timeout bumped from 2 s → 5 s.
|
|
317
318
|
- **0.2.6** — redesigned `unboxy.rooms` around two generic primitives: delta-synced KV state (`room.player.set/get/delete`, `room.data.set/get/delete`) + transient relay (`room.send` / `room.on`). Server no longer bakes in game-specific fields like x/y/color/ready or a `move` handler — games define their own shapes via opaque JSON values, same contract as `gameData` / `saves`.
|
|
318
319
|
- **0.2.5** — added `unboxy.rooms` module (server-authoritative multiplayer rooms backed by Colyseus on unboxy-realtime-service). Requires sign-in. Host must advertise `realtime` capability. Colyseus client loaded lazily — single-player games do not pay for the dependency.
|
|
319
320
|
- **0.2.4** — added `unboxy.gameData` module (game-scope key-value store for scoreboards, shared state)
|
package/dist/core/Unboxy.d.ts
CHANGED
|
@@ -4,7 +4,7 @@ import { GameDataModule } from '../gamedata/GameDataModule.js';
|
|
|
4
4
|
import { RealtimeModule } from '../realtime/RealtimeModule.js';
|
|
5
5
|
import type { UnboxyUser } from '../protocol.js';
|
|
6
6
|
export interface UnboxyInitOptions {
|
|
7
|
-
/** Handshake timeout in ms when running inside a host. Default
|
|
7
|
+
/** Handshake timeout in ms when running inside a host. Default 5000. */
|
|
8
8
|
handshakeTimeoutMs?: number;
|
|
9
9
|
/**
|
|
10
10
|
* Game ID used for the localStorage fallback. Ignored when connected to a
|
package/dist/core/Unboxy.js
CHANGED
|
@@ -4,7 +4,7 @@ import { SavesModule } from '../saves/SavesModule.js';
|
|
|
4
4
|
import { GameDataModule } from '../gamedata/GameDataModule.js';
|
|
5
5
|
import { RealtimeModule } from '../realtime/RealtimeModule.js';
|
|
6
6
|
// Kept in sync with package.json on each publish.
|
|
7
|
-
const SDK_VERSION = '0.2.
|
|
7
|
+
const SDK_VERSION = '0.2.7';
|
|
8
8
|
/**
|
|
9
9
|
* Unboxy platform services bound to the current (game, user).
|
|
10
10
|
*
|
|
@@ -50,7 +50,7 @@ export class Unboxy {
|
|
|
50
50
|
* Discord Activity support is designed for but not shipped in this version.
|
|
51
51
|
*/
|
|
52
52
|
static async init(options = {}) {
|
|
53
|
-
const handshakeTimeoutMs = options.handshakeTimeoutMs ??
|
|
53
|
+
const handshakeTimeoutMs = options.handshakeTimeoutMs ?? 5000;
|
|
54
54
|
const standaloneGameId = options.standaloneGameId ?? 'standalone';
|
|
55
55
|
const pm = await PostMessageTransport.connect(handshakeTimeoutMs, SDK_VERSION);
|
|
56
56
|
if (pm)
|
|
@@ -15,9 +15,14 @@ export declare class PostMessageTransport implements Transport {
|
|
|
15
15
|
private constructor();
|
|
16
16
|
/**
|
|
17
17
|
* Perform the handshake. Resolves once parent has replied with `unboxy:init`.
|
|
18
|
-
*
|
|
18
|
+
* Resolves to null if no response within `timeoutMs`.
|
|
19
|
+
*
|
|
20
|
+
* The hello is retried at `helloRetryMs` intervals because the parent's
|
|
21
|
+
* RPC-host message listener may not be mounted yet when the iframe first
|
|
22
|
+
* fires hello — especially on slower mobile devices where React takes
|
|
23
|
+
* longer to boot. One-shot hello was losing the handshake on Android.
|
|
19
24
|
*/
|
|
20
|
-
static connect(timeoutMs?: number, sdkVersion?: string): Promise<PostMessageTransport | null>;
|
|
25
|
+
static connect(timeoutMs?: number, sdkVersion?: string, helloRetryMs?: number): Promise<PostMessageTransport | null>;
|
|
21
26
|
private installResultListener;
|
|
22
27
|
call<T = unknown>(method: string, params?: unknown): Promise<T>;
|
|
23
28
|
}
|
|
@@ -15,35 +15,51 @@ export class PostMessageTransport {
|
|
|
15
15
|
}
|
|
16
16
|
/**
|
|
17
17
|
* Perform the handshake. Resolves once parent has replied with `unboxy:init`.
|
|
18
|
-
*
|
|
18
|
+
* Resolves to null if no response within `timeoutMs`.
|
|
19
|
+
*
|
|
20
|
+
* The hello is retried at `helloRetryMs` intervals because the parent's
|
|
21
|
+
* RPC-host message listener may not be mounted yet when the iframe first
|
|
22
|
+
* fires hello — especially on slower mobile devices where React takes
|
|
23
|
+
* longer to boot. One-shot hello was losing the handshake on Android.
|
|
19
24
|
*/
|
|
20
|
-
static async connect(timeoutMs =
|
|
25
|
+
static async connect(timeoutMs = 5000, sdkVersion = '0.0.0', helloRetryMs = 200) {
|
|
21
26
|
if (typeof window === 'undefined' || window.parent === window)
|
|
22
27
|
return null;
|
|
23
28
|
const transport = new PostMessageTransport(window.parent);
|
|
24
|
-
const
|
|
29
|
+
const hello = {
|
|
30
|
+
type: 'unboxy:hello',
|
|
31
|
+
protocolVersion: PROTOCOL_VERSION,
|
|
32
|
+
sdkVersion,
|
|
33
|
+
};
|
|
34
|
+
const init = await new Promise((resolve) => {
|
|
35
|
+
let settled = false;
|
|
36
|
+
const finish = (value) => {
|
|
37
|
+
if (settled)
|
|
38
|
+
return;
|
|
39
|
+
settled = true;
|
|
40
|
+
window.removeEventListener('message', onMessage);
|
|
41
|
+
clearInterval(helloInterval);
|
|
42
|
+
clearTimeout(timeoutHandle);
|
|
43
|
+
resolve(value);
|
|
44
|
+
};
|
|
25
45
|
const onMessage = (event) => {
|
|
26
46
|
if (event.source !== window.parent)
|
|
27
47
|
return;
|
|
28
48
|
const data = event.data;
|
|
29
49
|
if (!data || data.type !== 'unboxy:init')
|
|
30
50
|
return;
|
|
31
|
-
|
|
32
|
-
resolve(data);
|
|
51
|
+
finish(data);
|
|
33
52
|
};
|
|
34
53
|
window.addEventListener('message', onMessage);
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
54
|
+
// Fire the first hello immediately, then keep retrying until init
|
|
55
|
+
// arrives or timeout fires. Retries are cheap (a postMessage with a
|
|
56
|
+
// small payload); the parent's RPC host replies on first valid hello.
|
|
57
|
+
transport.parent.postMessage(hello, '*');
|
|
58
|
+
const helloInterval = setInterval(() => {
|
|
59
|
+
transport.parent.postMessage(hello, '*');
|
|
60
|
+
}, helloRetryMs);
|
|
61
|
+
const timeoutHandle = setTimeout(() => finish(null), timeoutMs);
|
|
39
62
|
});
|
|
40
|
-
const hello = {
|
|
41
|
-
type: 'unboxy:hello',
|
|
42
|
-
protocolVersion: PROTOCOL_VERSION,
|
|
43
|
-
sdkVersion,
|
|
44
|
-
};
|
|
45
|
-
transport.parent.postMessage(hello, '*');
|
|
46
|
-
const init = await initPromise;
|
|
47
63
|
if (!init)
|
|
48
64
|
return null;
|
|
49
65
|
if (init.protocolVersion !== PROTOCOL_VERSION) {
|