@playcademy/sdk 0.14.1-beta.2 → 0.15.1-beta.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/dist/index.d.ts +7 -0
- package/dist/index.js +10 -5
- package/dist/internal.d.ts +7 -0
- package/dist/internal.js +10 -5
- package/dist/server/edge.js +2 -1
- package/dist/server.js +2 -1
- package/dist/types.d.ts +7 -0
- package/package.json +1 -1
package/dist/index.d.ts
CHANGED
|
@@ -171,6 +171,7 @@ declare function parseOAuthState(state: string): {
|
|
|
171
171
|
type Method = 'GET' | 'POST' | 'PUT' | 'PATCH' | 'DELETE';
|
|
172
172
|
interface RetryPolicy {
|
|
173
173
|
retryableMethods?: readonly Method[];
|
|
174
|
+
retryDelaysMs?: readonly number[];
|
|
174
175
|
}
|
|
175
176
|
|
|
176
177
|
/**
|
|
@@ -1149,6 +1150,12 @@ interface StartActivityOptions {
|
|
|
1149
1150
|
* Must be a UUID (the backend validates it as such) and unique per
|
|
1150
1151
|
* logical run. If omitted, the SDK generates a new UUID on each call,
|
|
1151
1152
|
* which means every session is treated as its own run.
|
|
1153
|
+
*
|
|
1154
|
+
* The platform records at most one completion per activity per run:
|
|
1155
|
+
* after `endActivity` succeeds for an activity under a given `runId`,
|
|
1156
|
+
* any further `endActivity` for that same activity and `runId` is
|
|
1157
|
+
* skipped as a duplicate (`blockedByDedupeGuard`, zero XP awarded).
|
|
1158
|
+
* Start a new run (new `runId`) for a genuine retake.
|
|
1152
1159
|
*/
|
|
1153
1160
|
runId?: string;
|
|
1154
1161
|
}
|
package/dist/index.js
CHANGED
|
@@ -1248,6 +1248,10 @@ var DEFAULT_HEARTBEAT_INTERVAL_MS = 15000;
|
|
|
1248
1248
|
var DEFAULT_INACTIVITY_TIMEOUT_MS = 10 * 60 * 1000;
|
|
1249
1249
|
var RELAY_INTERVAL_MS = 1000;
|
|
1250
1250
|
var HEARTBEAT_RETRY_POLICY = { retryableMethods: ["POST"] };
|
|
1251
|
+
var END_ACTIVITY_RETRY_POLICY = {
|
|
1252
|
+
retryableMethods: ["POST"],
|
|
1253
|
+
retryDelaysMs: [500, 1500, 5000, 1e4, 20000]
|
|
1254
|
+
};
|
|
1251
1255
|
var USER_ACTIVITY_EVENTS = ["keydown", "pointerdown", "pointermove", "wheel"];
|
|
1252
1256
|
var USER_ACTIVITY_LISTENER_OPTIONS = { capture: true };
|
|
1253
1257
|
function normalizeDelayMs(value, defaultValue, allowZero = true) {
|
|
@@ -1799,7 +1803,7 @@ function createTimebackActivityTracker(client) {
|
|
|
1799
1803
|
extensions: data.extensions
|
|
1800
1804
|
};
|
|
1801
1805
|
try {
|
|
1802
|
-
const response = await client["requestGameBackend"](TIMEBACK_ROUTES.END_ACTIVITY, "POST", request);
|
|
1806
|
+
const response = await client["requestGameBackend"](TIMEBACK_ROUTES.END_ACTIVITY, "POST", request, undefined, { retryPolicy: END_ACTIVITY_RETRY_POLICY });
|
|
1803
1807
|
if (currentActivity === activity) {
|
|
1804
1808
|
currentActivity = null;
|
|
1805
1809
|
}
|
|
@@ -2256,8 +2260,9 @@ function isRetryableStatus(status) {
|
|
|
2256
2260
|
}
|
|
2257
2261
|
async function fetchWithRetry(url, init2) {
|
|
2258
2262
|
const startedAt = Date.now();
|
|
2259
|
-
|
|
2260
|
-
|
|
2263
|
+
const retryDelaysMs = init2.retryPolicy?.retryDelaysMs ?? RETRY_DELAYS_MS;
|
|
2264
|
+
for (let attempt = 0;attempt <= retryDelaysMs.length; attempt++) {
|
|
2265
|
+
const retryDelayMs = retryDelaysMs[attempt];
|
|
2261
2266
|
const retryableMethods = init2.retryPolicy?.retryableMethods ?? ["GET"];
|
|
2262
2267
|
const canRetry = retryDelayMs !== undefined && retryableMethods.includes(init2.method);
|
|
2263
2268
|
try {
|
|
@@ -2277,7 +2282,7 @@ async function fetchWithRetry(url, init2) {
|
|
|
2277
2282
|
}
|
|
2278
2283
|
return {
|
|
2279
2284
|
error: new PlaycademyError("Request failed after exhausting retries"),
|
|
2280
|
-
retryCount:
|
|
2285
|
+
retryCount: retryDelaysMs.length,
|
|
2281
2286
|
durationMs: Date.now() - startedAt
|
|
2282
2287
|
};
|
|
2283
2288
|
}
|
|
@@ -2386,7 +2391,7 @@ async function request({
|
|
|
2386
2391
|
return rawText && rawText.length > 0 ? rawText : undefined;
|
|
2387
2392
|
}
|
|
2388
2393
|
// src/version.ts
|
|
2389
|
-
var SDK_VERSION = "0.
|
|
2394
|
+
var SDK_VERSION = "0.15.1-beta.1";
|
|
2390
2395
|
|
|
2391
2396
|
// src/clients/base.ts
|
|
2392
2397
|
class PlaycademyBaseClient {
|
package/dist/internal.d.ts
CHANGED
|
@@ -14,6 +14,7 @@ import { AUTH_PROVIDER_IDS } from '@playcademy/constants';
|
|
|
14
14
|
type Method = 'GET' | 'POST' | 'PUT' | 'PATCH' | 'DELETE';
|
|
15
15
|
interface RetryPolicy {
|
|
16
16
|
retryableMethods?: readonly Method[];
|
|
17
|
+
retryDelaysMs?: readonly number[];
|
|
17
18
|
}
|
|
18
19
|
|
|
19
20
|
/**
|
|
@@ -1917,6 +1918,12 @@ interface StartActivityOptions {
|
|
|
1917
1918
|
* Must be a UUID (the backend validates it as such) and unique per
|
|
1918
1919
|
* logical run. If omitted, the SDK generates a new UUID on each call,
|
|
1919
1920
|
* which means every session is treated as its own run.
|
|
1921
|
+
*
|
|
1922
|
+
* The platform records at most one completion per activity per run:
|
|
1923
|
+
* after `endActivity` succeeds for an activity under a given `runId`,
|
|
1924
|
+
* any further `endActivity` for that same activity and `runId` is
|
|
1925
|
+
* skipped as a duplicate (`blockedByDedupeGuard`, zero XP awarded).
|
|
1926
|
+
* Start a new run (new `runId`) for a genuine retake.
|
|
1920
1927
|
*/
|
|
1921
1928
|
runId?: string;
|
|
1922
1929
|
}
|
package/dist/internal.js
CHANGED
|
@@ -1248,6 +1248,10 @@ var DEFAULT_HEARTBEAT_INTERVAL_MS = 15000;
|
|
|
1248
1248
|
var DEFAULT_INACTIVITY_TIMEOUT_MS = 10 * 60 * 1000;
|
|
1249
1249
|
var RELAY_INTERVAL_MS = 1000;
|
|
1250
1250
|
var HEARTBEAT_RETRY_POLICY = { retryableMethods: ["POST"] };
|
|
1251
|
+
var END_ACTIVITY_RETRY_POLICY = {
|
|
1252
|
+
retryableMethods: ["POST"],
|
|
1253
|
+
retryDelaysMs: [500, 1500, 5000, 1e4, 20000]
|
|
1254
|
+
};
|
|
1251
1255
|
var USER_ACTIVITY_EVENTS = ["keydown", "pointerdown", "pointermove", "wheel"];
|
|
1252
1256
|
var USER_ACTIVITY_LISTENER_OPTIONS = { capture: true };
|
|
1253
1257
|
function normalizeDelayMs(value, defaultValue, allowZero = true) {
|
|
@@ -1799,7 +1803,7 @@ function createTimebackActivityTracker(client) {
|
|
|
1799
1803
|
extensions: data.extensions
|
|
1800
1804
|
};
|
|
1801
1805
|
try {
|
|
1802
|
-
const response = await client["requestGameBackend"](TIMEBACK_ROUTES.END_ACTIVITY, "POST", request);
|
|
1806
|
+
const response = await client["requestGameBackend"](TIMEBACK_ROUTES.END_ACTIVITY, "POST", request, undefined, { retryPolicy: END_ACTIVITY_RETRY_POLICY });
|
|
1803
1807
|
if (currentActivity === activity) {
|
|
1804
1808
|
currentActivity = null;
|
|
1805
1809
|
}
|
|
@@ -2959,8 +2963,9 @@ function isRetryableStatus(status) {
|
|
|
2959
2963
|
}
|
|
2960
2964
|
async function fetchWithRetry(url, init2) {
|
|
2961
2965
|
const startedAt = Date.now();
|
|
2962
|
-
|
|
2963
|
-
|
|
2966
|
+
const retryDelaysMs = init2.retryPolicy?.retryDelaysMs ?? RETRY_DELAYS_MS;
|
|
2967
|
+
for (let attempt = 0;attempt <= retryDelaysMs.length; attempt++) {
|
|
2968
|
+
const retryDelayMs = retryDelaysMs[attempt];
|
|
2964
2969
|
const retryableMethods = init2.retryPolicy?.retryableMethods ?? ["GET"];
|
|
2965
2970
|
const canRetry = retryDelayMs !== undefined && retryableMethods.includes(init2.method);
|
|
2966
2971
|
try {
|
|
@@ -2980,7 +2985,7 @@ async function fetchWithRetry(url, init2) {
|
|
|
2980
2985
|
}
|
|
2981
2986
|
return {
|
|
2982
2987
|
error: new PlaycademyError("Request failed after exhausting retries"),
|
|
2983
|
-
retryCount:
|
|
2988
|
+
retryCount: retryDelaysMs.length,
|
|
2984
2989
|
durationMs: Date.now() - startedAt
|
|
2985
2990
|
};
|
|
2986
2991
|
}
|
|
@@ -3089,7 +3094,7 @@ async function request({
|
|
|
3089
3094
|
return rawText && rawText.length > 0 ? rawText : undefined;
|
|
3090
3095
|
}
|
|
3091
3096
|
// src/version.ts
|
|
3092
|
-
var SDK_VERSION = "0.
|
|
3097
|
+
var SDK_VERSION = "0.15.1-beta.1";
|
|
3093
3098
|
|
|
3094
3099
|
// src/clients/base.ts
|
|
3095
3100
|
class PlaycademyBaseClient {
|
package/dist/server/edge.js
CHANGED
|
@@ -49,6 +49,7 @@ function createTimebackNamespace(client) {
|
|
|
49
49
|
return client["request"]("/api/timeback/end-activity", "POST", {
|
|
50
50
|
gameId: client.gameId,
|
|
51
51
|
studentId,
|
|
52
|
+
...payload.runId ? { runId: payload.runId } : {},
|
|
52
53
|
activityData: enrichedActivityData,
|
|
53
54
|
scoreData: payload.scoreData,
|
|
54
55
|
timingData: payload.timingData,
|
|
@@ -233,7 +234,7 @@ function extractApiErrorInfo(error) {
|
|
|
233
234
|
}
|
|
234
235
|
|
|
235
236
|
// src/version.ts
|
|
236
|
-
var SDK_VERSION = "0.
|
|
237
|
+
var SDK_VERSION = "0.15.1-beta.1";
|
|
237
238
|
|
|
238
239
|
// src/server/request.ts
|
|
239
240
|
async function makeApiRequest(opts) {
|
package/dist/server.js
CHANGED
|
@@ -238,6 +238,7 @@ function createTimebackNamespace(client) {
|
|
|
238
238
|
return client["request"]("/api/timeback/end-activity", "POST", {
|
|
239
239
|
gameId: client.gameId,
|
|
240
240
|
studentId,
|
|
241
|
+
...payload.runId ? { runId: payload.runId } : {},
|
|
241
242
|
activityData: enrichedActivityData,
|
|
242
243
|
scoreData: payload.scoreData,
|
|
243
244
|
timingData: payload.timingData,
|
|
@@ -422,7 +423,7 @@ function extractApiErrorInfo(error) {
|
|
|
422
423
|
}
|
|
423
424
|
|
|
424
425
|
// src/version.ts
|
|
425
|
-
var SDK_VERSION = "0.
|
|
426
|
+
var SDK_VERSION = "0.15.1-beta.1";
|
|
426
427
|
|
|
427
428
|
// src/server/request.ts
|
|
428
429
|
async function makeApiRequest(opts) {
|
package/dist/types.d.ts
CHANGED
|
@@ -28,6 +28,7 @@ declare function parseOAuthState(state: string): {
|
|
|
28
28
|
type Method = 'GET' | 'POST' | 'PUT' | 'PATCH' | 'DELETE';
|
|
29
29
|
interface RetryPolicy {
|
|
30
30
|
retryableMethods?: readonly Method[];
|
|
31
|
+
retryDelaysMs?: readonly number[];
|
|
31
32
|
}
|
|
32
33
|
|
|
33
34
|
/**
|
|
@@ -1548,6 +1549,12 @@ interface StartActivityOptions {
|
|
|
1548
1549
|
* Must be a UUID (the backend validates it as such) and unique per
|
|
1549
1550
|
* logical run. If omitted, the SDK generates a new UUID on each call,
|
|
1550
1551
|
* which means every session is treated as its own run.
|
|
1552
|
+
*
|
|
1553
|
+
* The platform records at most one completion per activity per run:
|
|
1554
|
+
* after `endActivity` succeeds for an activity under a given `runId`,
|
|
1555
|
+
* any further `endActivity` for that same activity and `runId` is
|
|
1556
|
+
* skipped as a duplicate (`blockedByDedupeGuard`, zero XP awarded).
|
|
1557
|
+
* Start a new run (new `runId`) for a genuine retake.
|
|
1551
1558
|
*/
|
|
1552
1559
|
runId?: string;
|
|
1553
1560
|
}
|