@rehers/rehers-roleplay-sdk 2.5.2 → 2.5.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/package.json +2 -2
- package/roleplay-sdk.js +52 -9
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@rehers/rehers-roleplay-sdk",
|
|
3
|
-
"version": "2.5.
|
|
3
|
+
"version": "2.5.3",
|
|
4
4
|
"description": "Seamless Roleplay SDK — embed roleplay call sessions via a modal + iframe",
|
|
5
5
|
"main": "roleplay-sdk.js",
|
|
6
6
|
"types": "index.d.ts",
|
|
@@ -32,6 +32,6 @@
|
|
|
32
32
|
"license": "UNLICENSED",
|
|
33
33
|
"repository": {
|
|
34
34
|
"type": "git",
|
|
35
|
-
"url": "https://github.com/rehers/seamless-frontend-independent"
|
|
35
|
+
"url": "git+https://github.com/rehers/seamless-frontend-independent.git"
|
|
36
36
|
}
|
|
37
37
|
}
|
package/roleplay-sdk.js
CHANGED
|
@@ -28,6 +28,8 @@
|
|
|
28
28
|
var sessionExpiresAt = 0; // epoch ms
|
|
29
29
|
var refreshTimer = null;
|
|
30
30
|
var fetchingSession = null; // single-flight Promise
|
|
31
|
+
var activeSessionXhr = null;
|
|
32
|
+
var activeInitVersion = 0;
|
|
31
33
|
|
|
32
34
|
var initCallbacks = { onReady: null, onError: null };
|
|
33
35
|
var initCalled = false;
|
|
@@ -93,24 +95,54 @@
|
|
|
93
95
|
|
|
94
96
|
// ── Session management ────────────────────────────────────────────
|
|
95
97
|
|
|
98
|
+
function clearSessionRequest() {
|
|
99
|
+
if (activeSessionXhr) {
|
|
100
|
+
try {
|
|
101
|
+
activeSessionXhr.abort();
|
|
102
|
+
} catch (_) {}
|
|
103
|
+
activeSessionXhr = null;
|
|
104
|
+
}
|
|
105
|
+
fetchingSession = null;
|
|
106
|
+
}
|
|
107
|
+
|
|
96
108
|
function fetchSession() {
|
|
97
|
-
|
|
109
|
+
var requestInitVersion = activeInitVersion;
|
|
98
110
|
|
|
99
|
-
fetchingSession
|
|
111
|
+
if (fetchingSession && fetchingSession.initVersion === requestInitVersion) {
|
|
112
|
+
return fetchingSession.promise;
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
var requestPromise = new Promise(function (resolve, reject) {
|
|
100
116
|
var url = getApiOrigin() + "/api/sdk/session";
|
|
101
117
|
var body = userToken
|
|
102
118
|
? { userToken: userToken }
|
|
103
119
|
: { userId: userId, userEmail: userEmail, userRole: userRole };
|
|
104
120
|
|
|
105
121
|
var xhr = new XMLHttpRequest();
|
|
122
|
+
activeSessionXhr = xhr;
|
|
106
123
|
xhr.open("POST", url, true);
|
|
107
124
|
xhr.setRequestHeader("Content-Type", "application/json");
|
|
108
125
|
xhr.setRequestHeader("X-Publishable-Key", publishableKey);
|
|
109
126
|
xhr.withCredentials = false;
|
|
110
127
|
xhr.timeout = SESSION_TIMEOUT_MS;
|
|
111
128
|
|
|
129
|
+
function cleanupRequest() {
|
|
130
|
+
if (activeSessionXhr === xhr) {
|
|
131
|
+
activeSessionXhr = null;
|
|
132
|
+
}
|
|
133
|
+
if (fetchingSession && fetchingSession.promise === requestPromise) {
|
|
134
|
+
fetchingSession = null;
|
|
135
|
+
}
|
|
136
|
+
}
|
|
137
|
+
|
|
112
138
|
xhr.onload = function () {
|
|
113
|
-
|
|
139
|
+
cleanupRequest();
|
|
140
|
+
|
|
141
|
+
if (requestInitVersion !== activeInitVersion) {
|
|
142
|
+
reject({ code: "ABORTED", message: "Stale session response ignored" });
|
|
143
|
+
return;
|
|
144
|
+
}
|
|
145
|
+
|
|
114
146
|
var data;
|
|
115
147
|
try {
|
|
116
148
|
data = JSON.parse(xhr.responseText);
|
|
@@ -143,24 +175,29 @@
|
|
|
143
175
|
};
|
|
144
176
|
|
|
145
177
|
xhr.onerror = function () {
|
|
146
|
-
|
|
178
|
+
cleanupRequest();
|
|
147
179
|
reject({ code: "NETWORK_ERROR", message: "Network error contacting session endpoint" });
|
|
148
180
|
};
|
|
149
181
|
|
|
150
182
|
xhr.ontimeout = function () {
|
|
151
|
-
|
|
183
|
+
cleanupRequest();
|
|
152
184
|
reject({ code: "TIMEOUT", message: "Session request timed out after " + SESSION_TIMEOUT_MS + "ms" });
|
|
153
185
|
};
|
|
154
186
|
|
|
155
187
|
xhr.onabort = function () {
|
|
156
|
-
|
|
188
|
+
cleanupRequest();
|
|
157
189
|
reject({ code: "ABORTED", message: "Session request was aborted" });
|
|
158
190
|
};
|
|
159
191
|
|
|
160
192
|
xhr.send(JSON.stringify(body));
|
|
161
193
|
});
|
|
162
194
|
|
|
163
|
-
|
|
195
|
+
fetchingSession = {
|
|
196
|
+
initVersion: requestInitVersion,
|
|
197
|
+
promise: requestPromise,
|
|
198
|
+
};
|
|
199
|
+
|
|
200
|
+
return requestPromise;
|
|
164
201
|
}
|
|
165
202
|
|
|
166
203
|
function getSessionToken() {
|
|
@@ -407,6 +444,7 @@
|
|
|
407
444
|
*/
|
|
408
445
|
init: function (opts) {
|
|
409
446
|
try {
|
|
447
|
+
var initVersion = activeInitVersion + 1;
|
|
410
448
|
var hasUserToken = !!(opts && opts.userToken && String(opts.userToken).trim());
|
|
411
449
|
var hasLegacyIdentity = !!(opts && opts.userId && opts.userEmail);
|
|
412
450
|
|
|
@@ -427,7 +465,8 @@
|
|
|
427
465
|
clearTimeout(refreshTimer);
|
|
428
466
|
refreshTimer = null;
|
|
429
467
|
}
|
|
430
|
-
|
|
468
|
+
activeInitVersion = initVersion;
|
|
469
|
+
clearSessionRequest();
|
|
431
470
|
sessionToken = null;
|
|
432
471
|
sessionExpiresAt = 0;
|
|
433
472
|
paymentLink = null;
|
|
@@ -445,6 +484,7 @@
|
|
|
445
484
|
// Fetch session immediately
|
|
446
485
|
fetchSession()
|
|
447
486
|
.then(function (result) {
|
|
487
|
+
if (initVersion !== activeInitVersion) return;
|
|
448
488
|
if (result.trialMode && !paymentLink) {
|
|
449
489
|
// User not found and no payment link from server — still call onReady
|
|
450
490
|
// The open() will show an error state in the iframe
|
|
@@ -452,6 +492,8 @@
|
|
|
452
492
|
if (initCallbacks.onReady) initCallbacks.onReady();
|
|
453
493
|
})
|
|
454
494
|
.catch(function (err) {
|
|
495
|
+
if (initVersion !== activeInitVersion) return;
|
|
496
|
+
if (err && err.code === "ABORTED") return;
|
|
455
497
|
if (initCallbacks.onError) {
|
|
456
498
|
initCallbacks.onError({ code: err.code || "INIT_ERROR", message: err.message || "Initialization failed" });
|
|
457
499
|
}
|
|
@@ -753,10 +795,12 @@
|
|
|
753
795
|
*/
|
|
754
796
|
destroy: function () {
|
|
755
797
|
try {
|
|
798
|
+
activeInitVersion++;
|
|
756
799
|
if (refreshTimer) {
|
|
757
800
|
clearTimeout(refreshTimer);
|
|
758
801
|
refreshTimer = null;
|
|
759
802
|
}
|
|
803
|
+
clearSessionRequest();
|
|
760
804
|
teardownDialog();
|
|
761
805
|
teardownMount();
|
|
762
806
|
publishableKey = null;
|
|
@@ -767,7 +811,6 @@
|
|
|
767
811
|
paymentLink = null;
|
|
768
812
|
sessionToken = null;
|
|
769
813
|
sessionExpiresAt = 0;
|
|
770
|
-
fetchingSession = null;
|
|
771
814
|
initCallbacks = { onReady: null, onError: null };
|
|
772
815
|
initCalled = false;
|
|
773
816
|
} catch (e) {
|