@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.
Files changed (2) hide show
  1. package/package.json +2 -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.2",
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
- if (fetchingSession) return fetchingSession;
109
+ var requestInitVersion = activeInitVersion;
98
110
 
99
- fetchingSession = new Promise(function (resolve, reject) {
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
- fetchingSession = null;
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
- fetchingSession = null;
178
+ cleanupRequest();
147
179
  reject({ code: "NETWORK_ERROR", message: "Network error contacting session endpoint" });
148
180
  };
149
181
 
150
182
  xhr.ontimeout = function () {
151
- fetchingSession = null;
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
- fetchingSession = null;
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
- return fetchingSession;
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
- fetchingSession = null;
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) {