@wvdsh/sdk-js 1.3.1 → 1.3.3
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 +10 -3
- package/dist/index.js +46 -46
- package/package.json +2 -2
package/dist/index.d.ts
CHANGED
|
@@ -1139,8 +1139,12 @@ declare class WavedashSDK extends EventTarget {
|
|
|
1139
1139
|
* fetcher wired into `ConvexClient.setAuth` and honors `forceRefresh` so the
|
|
1140
1140
|
* server can invalidate a stale token.
|
|
1141
1141
|
*
|
|
1142
|
+
* Same-origin POST to /auth/refresh on the play domain — the
|
|
1143
|
+
* gameplaySession cookie set by the play server during playKey exchange
|
|
1144
|
+
* authenticates the request, so no cross-origin credentials handling needed.
|
|
1145
|
+
*
|
|
1142
1146
|
* Concurrent callers share a single in-flight fetch to avoid duplicate
|
|
1143
|
-
*
|
|
1147
|
+
* refresh round-trips.
|
|
1144
1148
|
*/
|
|
1145
1149
|
private getAuthToken;
|
|
1146
1150
|
/**
|
|
@@ -1150,8 +1154,11 @@ declare class WavedashSDK extends EventTarget {
|
|
|
1150
1154
|
*/
|
|
1151
1155
|
ensureGameplayJwt(): Promise<string>;
|
|
1152
1156
|
/**
|
|
1153
|
-
* Set up listeners
|
|
1154
|
-
*
|
|
1157
|
+
* Set up listeners that flush the end-of-session request when the iframe
|
|
1158
|
+
* is going away. We listen for three signals:
|
|
1159
|
+
* - `beforeunload` / `pagehide` on our own window: covers tab close, hard
|
|
1160
|
+
* reload, and top-level navigation of the parent.
|
|
1161
|
+
* - `END_SESSION` postMessage from the parent: covers parent SPA navigation
|
|
1155
1162
|
*/
|
|
1156
1163
|
private setupSessionEndListeners;
|
|
1157
1164
|
}
|
package/dist/index.js
CHANGED
|
@@ -3033,18 +3033,13 @@ var WavedashLogger = class {
|
|
|
3033
3033
|
};
|
|
3034
3034
|
|
|
3035
3035
|
// src/utils/parentOrigin.ts
|
|
3036
|
-
|
|
3037
|
-
|
|
3038
|
-
|
|
3039
|
-
|
|
3040
|
-
|
|
3041
|
-
|
|
3042
|
-
return `${window.location.protocol}//${parentDomain}`;
|
|
3043
|
-
}
|
|
3044
|
-
console.error(`Invalid iframe hostname pattern: ${iframeHost}`);
|
|
3045
|
-
return "";
|
|
3036
|
+
var _parentOrigin = "";
|
|
3037
|
+
function setParentOrigin(origin) {
|
|
3038
|
+
_parentOrigin = origin;
|
|
3039
|
+
}
|
|
3040
|
+
function getParentOrigin() {
|
|
3041
|
+
return _parentOrigin;
|
|
3046
3042
|
}
|
|
3047
|
-
var parentOrigin = deriveParentOrigin();
|
|
3048
3043
|
|
|
3049
3044
|
// src/utils/iframeMessenger.ts
|
|
3050
3045
|
var RESPONSE_TIMEOUT_MS = 15e3;
|
|
@@ -3052,7 +3047,7 @@ var IFrameMessenger = class {
|
|
|
3052
3047
|
constructor() {
|
|
3053
3048
|
// Arrow function automatically captures 'this' from the class instance
|
|
3054
3049
|
this.handleMessage = (event) => {
|
|
3055
|
-
if (event.origin !==
|
|
3050
|
+
if (event.origin !== getParentOrigin()) {
|
|
3056
3051
|
if (event.source !== window) {
|
|
3057
3052
|
console.warn(`Ignored message from untrusted origin: ${event.origin}`);
|
|
3058
3053
|
}
|
|
@@ -3097,12 +3092,14 @@ var IFrameMessenger = class {
|
|
|
3097
3092
|
this.listeners.get(type)?.delete(listener);
|
|
3098
3093
|
}
|
|
3099
3094
|
postToParent(requestType, data) {
|
|
3095
|
+
const parentOrigin = getParentOrigin();
|
|
3100
3096
|
if (typeof window === "undefined" || !parentOrigin) return false;
|
|
3101
3097
|
window.parent.postMessage({ type: requestType, ...data }, parentOrigin);
|
|
3102
3098
|
return true;
|
|
3103
3099
|
}
|
|
3104
3100
|
async requestFromParent(requestType, data) {
|
|
3105
3101
|
return new Promise((resolve, reject) => {
|
|
3102
|
+
const parentOrigin = getParentOrigin();
|
|
3106
3103
|
if (typeof window === "undefined" || !parentOrigin) {
|
|
3107
3104
|
reject(new Error("Parent origin not found"));
|
|
3108
3105
|
return;
|
|
@@ -4175,8 +4172,12 @@ var WavedashSDK = class extends EventTarget {
|
|
|
4175
4172
|
* fetcher wired into `ConvexClient.setAuth` and honors `forceRefresh` so the
|
|
4176
4173
|
* server can invalidate a stale token.
|
|
4177
4174
|
*
|
|
4175
|
+
* Same-origin POST to /auth/refresh on the play domain — the
|
|
4176
|
+
* gameplaySession cookie set by the play server during playKey exchange
|
|
4177
|
+
* authenticates the request, so no cross-origin credentials handling needed.
|
|
4178
|
+
*
|
|
4178
4179
|
* Concurrent callers share a single in-flight fetch to avoid duplicate
|
|
4179
|
-
*
|
|
4180
|
+
* refresh round-trips.
|
|
4180
4181
|
*/
|
|
4181
4182
|
getAuthToken(forceRefresh = false) {
|
|
4182
4183
|
if (!forceRefresh && this.gameplayJwt) {
|
|
@@ -4186,14 +4187,12 @@ var WavedashSDK = class extends EventTarget {
|
|
|
4186
4187
|
return this.gameplayJwtPromise;
|
|
4187
4188
|
}
|
|
4188
4189
|
const promise = (async () => {
|
|
4189
|
-
const response = await fetch(
|
|
4190
|
-
|
|
4191
|
-
|
|
4192
|
-
|
|
4193
|
-
}
|
|
4194
|
-
);
|
|
4190
|
+
const response = await fetch("/auth/refresh", {
|
|
4191
|
+
method: "POST",
|
|
4192
|
+
credentials: "same-origin"
|
|
4193
|
+
});
|
|
4195
4194
|
if (!response.ok) {
|
|
4196
|
-
throw new Error(`Failed to
|
|
4195
|
+
throw new Error(`Failed to refresh gameplay token: ${response.status}`);
|
|
4197
4196
|
}
|
|
4198
4197
|
this.gameplayJwt = await response.text();
|
|
4199
4198
|
return this.gameplayJwt;
|
|
@@ -4214,48 +4213,48 @@ var WavedashSDK = class extends EventTarget {
|
|
|
4214
4213
|
return this.getAuthToken();
|
|
4215
4214
|
}
|
|
4216
4215
|
/**
|
|
4217
|
-
* Set up listeners
|
|
4218
|
-
*
|
|
4216
|
+
* Set up listeners that flush the end-of-session request when the iframe
|
|
4217
|
+
* is going away. We listen for three signals:
|
|
4218
|
+
* - `beforeunload` / `pagehide` on our own window: covers tab close, hard
|
|
4219
|
+
* reload, and top-level navigation of the parent.
|
|
4220
|
+
* - `END_SESSION` postMessage from the parent: covers parent SPA navigation
|
|
4219
4221
|
*/
|
|
4220
4222
|
setupSessionEndListeners() {
|
|
4221
4223
|
const endSessionEndpoint = `${this.convexHttpUrl}/gameplay/end-session`;
|
|
4222
|
-
|
|
4223
|
-
(jwt) => fetch(endSessionEndpoint, {
|
|
4224
|
-
method: "POST",
|
|
4225
|
-
headers: {
|
|
4226
|
-
"Content-Type": "application/json",
|
|
4227
|
-
Authorization: `Bearer ${jwt}`
|
|
4228
|
-
},
|
|
4229
|
-
body: JSON.stringify({ _type: "warmup" })
|
|
4230
|
-
})
|
|
4231
|
-
).catch(() => {
|
|
4232
|
-
});
|
|
4233
|
-
const endGameplaySession = (_event) => {
|
|
4224
|
+
const endGameplaySession = () => {
|
|
4234
4225
|
if (this.sessionEndSent) return;
|
|
4226
|
+
if (!this.gameplayJwt) return;
|
|
4235
4227
|
this.sessionEndSent = true;
|
|
4236
4228
|
const pendingData = this.statsManager.getPendingData();
|
|
4237
4229
|
this.lobbyManager.destroy();
|
|
4238
4230
|
this.heartbeatManager.destroy();
|
|
4239
4231
|
this.statsManager.destroy();
|
|
4240
|
-
const
|
|
4232
|
+
const body = {
|
|
4233
|
+
gameplayJwt: this.gameplayJwt
|
|
4234
|
+
};
|
|
4241
4235
|
if (pendingData?.stats?.length) {
|
|
4242
|
-
|
|
4236
|
+
body.stats = pendingData.stats;
|
|
4243
4237
|
}
|
|
4244
4238
|
if (pendingData?.achievements?.length) {
|
|
4245
|
-
|
|
4239
|
+
body.achievements = pendingData.achievements;
|
|
4240
|
+
}
|
|
4241
|
+
const payload = JSON.stringify(body);
|
|
4242
|
+
const beaconSent = navigator?.sendBeacon?.(endSessionEndpoint, payload);
|
|
4243
|
+
if (!beaconSent) {
|
|
4244
|
+
fetch(endSessionEndpoint, {
|
|
4245
|
+
method: "POST",
|
|
4246
|
+
body: payload,
|
|
4247
|
+
keepalive: true
|
|
4248
|
+
}).catch(() => {
|
|
4249
|
+
});
|
|
4246
4250
|
}
|
|
4247
|
-
fetch(endSessionEndpoint, {
|
|
4248
|
-
method: "POST",
|
|
4249
|
-
body: JSON.stringify(sessionEndData),
|
|
4250
|
-
keepalive: true,
|
|
4251
|
-
headers: {
|
|
4252
|
-
"Content-Type": "application/json",
|
|
4253
|
-
Authorization: `Bearer ${this.gameplayJwt}`
|
|
4254
|
-
}
|
|
4255
|
-
});
|
|
4256
4251
|
};
|
|
4257
4252
|
window.addEventListener("beforeunload", endGameplaySession);
|
|
4258
4253
|
window.addEventListener("pagehide", endGameplaySession);
|
|
4254
|
+
iframeMessenger.addEventListener(
|
|
4255
|
+
IFRAME_MESSAGE_TYPE5.END_SESSION,
|
|
4256
|
+
endGameplaySession
|
|
4257
|
+
);
|
|
4259
4258
|
}
|
|
4260
4259
|
};
|
|
4261
4260
|
function setupWavedashSDK() {
|
|
@@ -4278,6 +4277,7 @@ function setupWavedashSDK() {
|
|
|
4278
4277
|
`Wavedash SDK: failed to parse ?${UrlParams.SdkConfig}= as JSON: ${message}`
|
|
4279
4278
|
);
|
|
4280
4279
|
}
|
|
4280
|
+
setParentOrigin(sdkConfig.parentOrigin);
|
|
4281
4281
|
const sdk = new WavedashSDK(sdkConfig);
|
|
4282
4282
|
window.Wavedash = sdk;
|
|
4283
4283
|
window.WavedashJS = sdk;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@wvdsh/sdk-js",
|
|
3
|
-
"version": "1.3.
|
|
3
|
+
"version": "1.3.3",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"description": "Wavedash JavaScript SDK",
|
|
6
6
|
"main": "./dist/client.js",
|
|
@@ -49,7 +49,7 @@
|
|
|
49
49
|
"typescript-eslint": "^8.52.0"
|
|
50
50
|
},
|
|
51
51
|
"dependencies": {
|
|
52
|
-
"@wvdsh/api": "^0.1.
|
|
52
|
+
"@wvdsh/api": "^0.1.10",
|
|
53
53
|
"convex": "^1.34.0",
|
|
54
54
|
"lodash.debounce": "^4.0.8"
|
|
55
55
|
}
|