@usions/sdk 2.19.0 → 2.20.1
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/package.json +1 -1
- package/src/browser.js +46 -1
- package/src/modules/core.js +21 -0
- package/src/modules/game-core.js +24 -0
- package/types/index.d.ts +9 -0
package/package.json
CHANGED
package/src/browser.js
CHANGED
|
@@ -69,7 +69,7 @@ var Usion = (function () {
|
|
|
69
69
|
* Core Usion object with init, _post, _request
|
|
70
70
|
*/
|
|
71
71
|
const core = {
|
|
72
|
-
version: '2.
|
|
72
|
+
version: '2.20.1', // injected from package.json at build
|
|
73
73
|
config: {},
|
|
74
74
|
_initialized: false,
|
|
75
75
|
_initCallback: null,
|
|
@@ -190,6 +190,27 @@ var Usion = (function () {
|
|
|
190
190
|
const h = self._backendHandlers[data.event];
|
|
191
191
|
if (h) h(data.data);
|
|
192
192
|
}
|
|
193
|
+
|
|
194
|
+
// Handle a room assigned by the host AFTER launch — the solo→host
|
|
195
|
+
// promotion path. The user opened the game solo from Explore (launch
|
|
196
|
+
// mode 'single'), then shared it; the host created a room and tells us
|
|
197
|
+
// to adopt it so invitees connect to the SAME room and the host starts
|
|
198
|
+
// receiving onPlayerJoined. No-op when there is no game module.
|
|
199
|
+
if (data.type === 'GAME_ROOM_ASSIGNED' && data.roomId && self.game) {
|
|
200
|
+
var _assignedRoom = data.roomId;
|
|
201
|
+
// Reflect the new room in launch config so getLaunchParams().roomId,
|
|
202
|
+
// .mode and game.isMultiplayer() all report multiplayer from here on.
|
|
203
|
+
self.config.roomId = _assignedRoom;
|
|
204
|
+
self.config.mode = 'multiplayer';
|
|
205
|
+
// Let a solo game flip to its multiplayer UI before peers arrive.
|
|
206
|
+
self.game._dispatch('roomAssigned', { roomId: _assignedRoom });
|
|
207
|
+
// Connect + join so the host is actually in the room. Idempotent when
|
|
208
|
+
// already connected/joined; non-fatal on failure (the game can retry).
|
|
209
|
+
Promise.resolve()
|
|
210
|
+
.then(function() { return self.game.connect(); })
|
|
211
|
+
.then(function() { return self.game.join(_assignedRoom); })
|
|
212
|
+
.catch(function() { /* non-fatal */ });
|
|
213
|
+
}
|
|
193
214
|
});
|
|
194
215
|
|
|
195
216
|
// Report the user's first real interaction to the host (see below).
|
|
@@ -4615,6 +4636,7 @@ var Usion = (function () {
|
|
|
4615
4636
|
disconnect: 'disconnect',
|
|
4616
4637
|
reconnect: 'reconnect',
|
|
4617
4638
|
connection_error: 'connectionError',
|
|
4639
|
+
room_assigned: 'roomAssigned',
|
|
4618
4640
|
};
|
|
4619
4641
|
|
|
4620
4642
|
function _normalizeEventName(event) {
|
|
@@ -4760,6 +4782,11 @@ var Usion = (function () {
|
|
|
4760
4782
|
onReconnect: function(callback) { return this._setHandler('reconnect', callback); },
|
|
4761
4783
|
onConnectionError: function(callback) { return this._setHandler('connectionError', callback); },
|
|
4762
4784
|
onPlayerConnection: function(callback) { return this._setHandler('playerConnection', callback); },
|
|
4785
|
+
// Fired when the host assigns this app a room AFTER launch (the user opened
|
|
4786
|
+
// the game solo, then shared it — see GAME_ROOM_ASSIGNED). The SDK has
|
|
4787
|
+
// already updated config.roomId and is connecting+joining; use this to flip
|
|
4788
|
+
// a solo game into its multiplayer/hosting UI. onJoined fires right after.
|
|
4789
|
+
onRoomAssigned: function(callback) { return this._setHandler('roomAssigned', callback); },
|
|
4763
4790
|
|
|
4764
4791
|
/** @private Set the single legacy handler; returns an unsubscribe fn. */
|
|
4765
4792
|
_setHandler: function(name, callback) {
|
|
@@ -4824,6 +4851,24 @@ var Usion = (function () {
|
|
|
4824
4851
|
applyGameMethods(game, Usion);
|
|
4825
4852
|
applyGameNetcode(game, Usion);
|
|
4826
4853
|
|
|
4854
|
+
// Foreground catch-up safety net (generic across every transport).
|
|
4855
|
+
//
|
|
4856
|
+
// When a page/iframe is backgrounded its JS is suspended: timers freeze and
|
|
4857
|
+
// relayed actions can be missed (postMessage to a frozen WebView). A brief
|
|
4858
|
+
// app-switch may also never trip a socket disconnect/reconnect, so the game's
|
|
4859
|
+
// onReconnect handler never fires and it silently misses moves made while it
|
|
4860
|
+
// was away — leaving turn state behind and the table deadlocked. On every
|
|
4861
|
+
// return to visibility, if we're in a room, request a sync so the game
|
|
4862
|
+
// deterministically catches up. Per the action reliability contract, onSync
|
|
4863
|
+
// is deduped by sequence, so an unnecessary resync is a no-op.
|
|
4864
|
+
if (typeof document !== 'undefined' && typeof document.addEventListener === 'function') {
|
|
4865
|
+
document.addEventListener('visibilitychange', function() {
|
|
4866
|
+
if (document.visibilityState !== 'visible') return;
|
|
4867
|
+
if (!game.roomId) return;
|
|
4868
|
+
try { game.requestSync(); } catch (e) { /* non-fatal */ }
|
|
4869
|
+
});
|
|
4870
|
+
}
|
|
4871
|
+
|
|
4827
4872
|
return game;
|
|
4828
4873
|
}
|
|
4829
4874
|
|
package/src/modules/core.js
CHANGED
|
@@ -187,6 +187,27 @@ export const core = {
|
|
|
187
187
|
const h = self._backendHandlers[data.event];
|
|
188
188
|
if (h) h(data.data);
|
|
189
189
|
}
|
|
190
|
+
|
|
191
|
+
// Handle a room assigned by the host AFTER launch — the solo→host
|
|
192
|
+
// promotion path. The user opened the game solo from Explore (launch
|
|
193
|
+
// mode 'single'), then shared it; the host created a room and tells us
|
|
194
|
+
// to adopt it so invitees connect to the SAME room and the host starts
|
|
195
|
+
// receiving onPlayerJoined. No-op when there is no game module.
|
|
196
|
+
if (data.type === 'GAME_ROOM_ASSIGNED' && data.roomId && self.game) {
|
|
197
|
+
var _assignedRoom = data.roomId;
|
|
198
|
+
// Reflect the new room in launch config so getLaunchParams().roomId,
|
|
199
|
+
// .mode and game.isMultiplayer() all report multiplayer from here on.
|
|
200
|
+
self.config.roomId = _assignedRoom;
|
|
201
|
+
self.config.mode = 'multiplayer';
|
|
202
|
+
// Let a solo game flip to its multiplayer UI before peers arrive.
|
|
203
|
+
self.game._dispatch('roomAssigned', { roomId: _assignedRoom });
|
|
204
|
+
// Connect + join so the host is actually in the room. Idempotent when
|
|
205
|
+
// already connected/joined; non-fatal on failure (the game can retry).
|
|
206
|
+
Promise.resolve()
|
|
207
|
+
.then(function() { return self.game.connect(); })
|
|
208
|
+
.then(function() { return self.game.join(_assignedRoom); })
|
|
209
|
+
.catch(function() { /* non-fatal */ });
|
|
210
|
+
}
|
|
190
211
|
});
|
|
191
212
|
|
|
192
213
|
// Report the user's first real interaction to the host (see below).
|
package/src/modules/game-core.js
CHANGED
|
@@ -27,6 +27,7 @@ const _EVENT_ALIASES = {
|
|
|
27
27
|
disconnect: 'disconnect',
|
|
28
28
|
reconnect: 'reconnect',
|
|
29
29
|
connection_error: 'connectionError',
|
|
30
|
+
room_assigned: 'roomAssigned',
|
|
30
31
|
};
|
|
31
32
|
|
|
32
33
|
function _normalizeEventName(event) {
|
|
@@ -172,6 +173,11 @@ export function createGameModule(Usion) {
|
|
|
172
173
|
onReconnect: function(callback) { return this._setHandler('reconnect', callback); },
|
|
173
174
|
onConnectionError: function(callback) { return this._setHandler('connectionError', callback); },
|
|
174
175
|
onPlayerConnection: function(callback) { return this._setHandler('playerConnection', callback); },
|
|
176
|
+
// Fired when the host assigns this app a room AFTER launch (the user opened
|
|
177
|
+
// the game solo, then shared it — see GAME_ROOM_ASSIGNED). The SDK has
|
|
178
|
+
// already updated config.roomId and is connecting+joining; use this to flip
|
|
179
|
+
// a solo game into its multiplayer/hosting UI. onJoined fires right after.
|
|
180
|
+
onRoomAssigned: function(callback) { return this._setHandler('roomAssigned', callback); },
|
|
175
181
|
|
|
176
182
|
/** @private Set the single legacy handler; returns an unsubscribe fn. */
|
|
177
183
|
_setHandler: function(name, callback) {
|
|
@@ -236,5 +242,23 @@ export function createGameModule(Usion) {
|
|
|
236
242
|
applyGameMethods(game, Usion);
|
|
237
243
|
applyGameNetcode(game, Usion);
|
|
238
244
|
|
|
245
|
+
// Foreground catch-up safety net (generic across every transport).
|
|
246
|
+
//
|
|
247
|
+
// When a page/iframe is backgrounded its JS is suspended: timers freeze and
|
|
248
|
+
// relayed actions can be missed (postMessage to a frozen WebView). A brief
|
|
249
|
+
// app-switch may also never trip a socket disconnect/reconnect, so the game's
|
|
250
|
+
// onReconnect handler never fires and it silently misses moves made while it
|
|
251
|
+
// was away — leaving turn state behind and the table deadlocked. On every
|
|
252
|
+
// return to visibility, if we're in a room, request a sync so the game
|
|
253
|
+
// deterministically catches up. Per the action reliability contract, onSync
|
|
254
|
+
// is deduped by sequence, so an unnecessary resync is a no-op.
|
|
255
|
+
if (typeof document !== 'undefined' && typeof document.addEventListener === 'function') {
|
|
256
|
+
document.addEventListener('visibilitychange', function() {
|
|
257
|
+
if (document.visibilityState !== 'visible') return;
|
|
258
|
+
if (!game.roomId) return;
|
|
259
|
+
try { game.requestSync(); } catch (e) { /* non-fatal */ }
|
|
260
|
+
});
|
|
261
|
+
}
|
|
262
|
+
|
|
239
263
|
return game;
|
|
240
264
|
}
|
package/types/index.d.ts
CHANGED
|
@@ -355,6 +355,15 @@ export interface GameModule {
|
|
|
355
355
|
onConnectionError(callback: (error: Error) => void): UnsubscribeFn;
|
|
356
356
|
/** Peer connection lifecycle: connected / reconnecting (grace) / gone. */
|
|
357
357
|
onPlayerConnection(callback: (data: PlayerConnectionData) => void): UnsubscribeFn;
|
|
358
|
+
/**
|
|
359
|
+
* Fired when the host assigns this app a room AFTER launch — the solo→host
|
|
360
|
+
* promotion path. The user opened the game solo (launch mode 'single'), then
|
|
361
|
+
* shared it from the host's top-bar Share button; the host created a room and
|
|
362
|
+
* the SDK has already updated `getLaunchParams().roomId`/`.mode` and is
|
|
363
|
+
* connecting+joining. Use this to flip a solo game into its multiplayer /
|
|
364
|
+
* hosting UI; `onJoined` fires right after the join completes.
|
|
365
|
+
*/
|
|
366
|
+
onRoomAssigned(callback: (data: { roomId: string }) => void): UnsubscribeFn;
|
|
358
367
|
|
|
359
368
|
/**
|
|
360
369
|
* Register an ADDITIONAL event listener. Unlike the onX methods this
|