@playcademy/sdk 0.15.1-beta.8 → 0.16.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/README.md +38 -0
- package/dist/index.d.ts +7 -0
- package/dist/index.js +93 -21
- package/dist/internal.d.ts +1 -0
- package/dist/internal.js +95 -22
- package/dist/server/edge.d.ts +9 -0
- package/dist/server/edge.js +63 -5
- package/dist/server.d.ts +9 -0
- package/dist/server.js +63 -5
- package/dist/types.d.ts +7 -0
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -116,6 +116,44 @@ await client.timeback.startActivity(
|
|
|
116
116
|
)
|
|
117
117
|
```
|
|
118
118
|
|
|
119
|
+
Hosted assessments use the same methods locally and when deployed:
|
|
120
|
+
|
|
121
|
+
```typescript
|
|
122
|
+
const attempt = await client.timeback.assessments.start({
|
|
123
|
+
activityId: 'math-diagnostic',
|
|
124
|
+
purpose: 'diagnostic',
|
|
125
|
+
subject: 'Math',
|
|
126
|
+
grade: 5,
|
|
127
|
+
})
|
|
128
|
+
|
|
129
|
+
const saved = await client.timeback.assessments.save(attempt.attemptId, {
|
|
130
|
+
expectedResponseVersion: attempt.responseVersion,
|
|
131
|
+
responses: {
|
|
132
|
+
[attempt.assessment.items[0].identifier]: { RESPONSE: 'A' },
|
|
133
|
+
},
|
|
134
|
+
})
|
|
135
|
+
|
|
136
|
+
const completed = await client.timeback.assessments.submit(attempt.attemptId, {
|
|
137
|
+
expectedResponseVersion: saved.responseVersion,
|
|
138
|
+
submissionId: crypto.randomUUID(),
|
|
139
|
+
})
|
|
140
|
+
```
|
|
141
|
+
|
|
142
|
+
`start()` resumes an unfinished attempt or selects the next live test. Save payloads are
|
|
143
|
+
question deltas, but each included question replaces its complete response state; use `null` to
|
|
144
|
+
clear an answer. Keep the returned `responseVersion` and send it with the next mutation.
|
|
145
|
+
|
|
146
|
+
For local development, import the current ordered catalog before starting the dev host:
|
|
147
|
+
|
|
148
|
+
```bash
|
|
149
|
+
playcademy timeback assessments import
|
|
150
|
+
playcademy dev
|
|
151
|
+
```
|
|
152
|
+
|
|
153
|
+
The host reads `.playcademy/timeback/assessment-fixtures.json` and keeps local attempts in memory.
|
|
154
|
+
Restarting the dev host resets mutable attempt state. Deployed games use TimeBack automatically;
|
|
155
|
+
game code never selects the provider or reads fixture content.
|
|
156
|
+
|
|
119
157
|
### `client.backend`
|
|
120
158
|
|
|
121
159
|
HTTP client for game-specific backend functions deployed via `playcademy deploy`.
|
package/dist/index.d.ts
CHANGED
|
@@ -1037,6 +1037,13 @@ declare class PlaycademyClient extends PlaycademyBaseClient {
|
|
|
1037
1037
|
* - `endActivity(scoreData)` - Submit activity results to TimeBack
|
|
1038
1038
|
*/
|
|
1039
1039
|
timeback: {
|
|
1040
|
+
assessments: {
|
|
1041
|
+
start: (input: _playcademy_types.StartAssessmentInput) => Promise<_playcademy_types.AssessmentAttemptSnapshot>;
|
|
1042
|
+
latest: (options: _playcademy_types.GetLatestAssessmentOptions) => Promise<_playcademy_types.LatestAssessmentResult | null>;
|
|
1043
|
+
get: (attemptId: string) => Promise<_playcademy_types.AssessmentAttemptSnapshot>;
|
|
1044
|
+
save: (attemptId: string, input: _playcademy_types.SaveAssessmentInput) => Promise<_playcademy_types.AssessmentSaveResult>;
|
|
1045
|
+
submit: (attemptId: string, input: _playcademy_types.SubmitAssessmentInput) => Promise<_playcademy_types.AssessmentSubmitResult>;
|
|
1046
|
+
};
|
|
1040
1047
|
readonly user: TimebackUser;
|
|
1041
1048
|
readonly currentRunId: string | undefined;
|
|
1042
1049
|
startActivity: (metadata: _playcademy_types.ActivityData, options?: StartActivityOptions) => StartActivityResult;
|
package/dist/index.js
CHANGED
|
@@ -1118,25 +1118,6 @@ function createScoresNamespace(client) {
|
|
|
1118
1118
|
}
|
|
1119
1119
|
};
|
|
1120
1120
|
}
|
|
1121
|
-
// src/core/guards.ts
|
|
1122
|
-
var VALID_GRADES = [-1, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13];
|
|
1123
|
-
var VALID_SUBJECTS = [
|
|
1124
|
-
"Reading",
|
|
1125
|
-
"Language",
|
|
1126
|
-
"Vocabulary",
|
|
1127
|
-
"Social Studies",
|
|
1128
|
-
"Writing",
|
|
1129
|
-
"Science",
|
|
1130
|
-
"FastMath",
|
|
1131
|
-
"Math",
|
|
1132
|
-
"None"
|
|
1133
|
-
];
|
|
1134
|
-
function isValidGrade(value) {
|
|
1135
|
-
return typeof value === "number" && Number.isInteger(value) && VALID_GRADES.includes(value);
|
|
1136
|
-
}
|
|
1137
|
-
function isValidSubject(value) {
|
|
1138
|
-
return typeof value === "string" && VALID_SUBJECTS.includes(value);
|
|
1139
|
-
}
|
|
1140
1121
|
// ../constants/src/platform.ts
|
|
1141
1122
|
var PLAYCADEMY_BROWSER_TIME_ZONE_HEADER = "x-playcademy-browser-time-zone";
|
|
1142
1123
|
// ../constants/src/timeback.ts
|
|
@@ -1147,8 +1128,22 @@ var TIMEBACK_ROUTES = {
|
|
|
1147
1128
|
GET_HIGHEST_GRADE_MASTERED: "/integrations/timeback/highest-grade-mastered",
|
|
1148
1129
|
HEARTBEAT: "/integrations/timeback/heartbeat",
|
|
1149
1130
|
ADVANCE_COURSE: "/integrations/timeback/advance-course",
|
|
1150
|
-
UNENROLL_COURSE: "/integrations/timeback/unenroll-course"
|
|
1131
|
+
UNENROLL_COURSE: "/integrations/timeback/unenroll-course",
|
|
1132
|
+
ASSESSMENTS: "/integrations/timeback/assessments"
|
|
1151
1133
|
};
|
|
1134
|
+
var TIMEBACK_GRADES = [-1, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13];
|
|
1135
|
+
var TIMEBACK_SUBJECTS = [
|
|
1136
|
+
"Reading",
|
|
1137
|
+
"Language",
|
|
1138
|
+
"Vocabulary",
|
|
1139
|
+
"Social Studies",
|
|
1140
|
+
"Writing",
|
|
1141
|
+
"Science",
|
|
1142
|
+
"FastMath",
|
|
1143
|
+
"Math",
|
|
1144
|
+
"None"
|
|
1145
|
+
];
|
|
1146
|
+
var ASSESSMENT_PURPOSES = ["end_of_course", "diagnostic"];
|
|
1152
1147
|
var TIMEBACK_GAME_METRIC_DECIMAL_PLACES = {
|
|
1153
1148
|
xp: 1,
|
|
1154
1149
|
mastery: 0,
|
|
@@ -1160,6 +1155,19 @@ var TIMEBACK_GAME_METRIC_COMPARISON_TOLERANCE = {
|
|
|
1160
1155
|
time: 60,
|
|
1161
1156
|
score: 0.5 / 10 ** TIMEBACK_GAME_METRIC_DECIMAL_PLACES.score
|
|
1162
1157
|
};
|
|
1158
|
+
// src/core/guards.ts
|
|
1159
|
+
var VALID_GRADES = TIMEBACK_GRADES;
|
|
1160
|
+
var VALID_SUBJECTS = TIMEBACK_SUBJECTS;
|
|
1161
|
+
function isValidGrade(value) {
|
|
1162
|
+
return typeof value === "number" && Number.isInteger(value) && VALID_GRADES.includes(value);
|
|
1163
|
+
}
|
|
1164
|
+
function isValidSubject(value) {
|
|
1165
|
+
return typeof value === "string" && VALID_SUBJECTS.includes(value);
|
|
1166
|
+
}
|
|
1167
|
+
function isAssessmentPurpose(value) {
|
|
1168
|
+
return typeof value === "string" && ASSESSMENT_PURPOSES.includes(value);
|
|
1169
|
+
}
|
|
1170
|
+
|
|
1163
1171
|
// src/core/cache/ttl-cache.ts
|
|
1164
1172
|
function createTTLCache(options) {
|
|
1165
1173
|
const cache = new Map;
|
|
@@ -2003,9 +2011,73 @@ function createTimebackEngine(client) {
|
|
|
2003
2011
|
// src/namespaces/game/timeback.ts
|
|
2004
2012
|
var VALID_XP_INCLUDE_OPTIONS = ["perCourse", "today"];
|
|
2005
2013
|
var VALID_MASTERY_INCLUDE_OPTIONS = ["perCourse"];
|
|
2014
|
+
var ASSESSMENTS_ROUTE = TIMEBACK_ROUTES.ASSESSMENTS;
|
|
2015
|
+
function validateAssessmentFilters(options) {
|
|
2016
|
+
if (!isAssessmentPurpose(options?.purpose)) {
|
|
2017
|
+
throw new Error("purpose must be end_of_course or diagnostic");
|
|
2018
|
+
}
|
|
2019
|
+
if (options.grade !== undefined && !isValidGrade(options.grade)) {
|
|
2020
|
+
throw new Error(`Invalid grade: ${options.grade}. Valid grades: ${VALID_GRADES.join(", ")}`);
|
|
2021
|
+
}
|
|
2022
|
+
if (options.subject !== undefined && !isValidSubject(options.subject)) {
|
|
2023
|
+
throw new Error(`Invalid subject: ${options.subject}. Valid subjects: ${VALID_SUBJECTS.join(", ")}`);
|
|
2024
|
+
}
|
|
2025
|
+
}
|
|
2006
2026
|
function createTimebackNamespace(client) {
|
|
2007
2027
|
const engine = createTimebackEngine(client);
|
|
2008
2028
|
return {
|
|
2029
|
+
assessments: {
|
|
2030
|
+
start: async (input) => {
|
|
2031
|
+
assertPlatformMode(client, "timeback.assessments.start()");
|
|
2032
|
+
if (!input.activityId?.trim()) {
|
|
2033
|
+
throw new Error("activityId is required");
|
|
2034
|
+
}
|
|
2035
|
+
validateAssessmentFilters(input);
|
|
2036
|
+
return client["requestGameBackend"](`${ASSESSMENTS_ROUTE}/start`, "POST", input);
|
|
2037
|
+
},
|
|
2038
|
+
latest: async (options) => {
|
|
2039
|
+
assertPlatformMode(client, "timeback.assessments.latest()");
|
|
2040
|
+
validateAssessmentFilters(options);
|
|
2041
|
+
const params = new URLSearchParams({ purpose: options.purpose });
|
|
2042
|
+
if (options.subject !== undefined) {
|
|
2043
|
+
params.set("subject", options.subject);
|
|
2044
|
+
}
|
|
2045
|
+
if (options.grade !== undefined) {
|
|
2046
|
+
params.set("grade", String(options.grade));
|
|
2047
|
+
}
|
|
2048
|
+
return client["requestGameBackend"](`${ASSESSMENTS_ROUTE}/latest?${params.toString()}`, "GET");
|
|
2049
|
+
},
|
|
2050
|
+
get: async (attemptId) => {
|
|
2051
|
+
assertPlatformMode(client, "timeback.assessments.get()");
|
|
2052
|
+
if (!attemptId?.trim()) {
|
|
2053
|
+
throw new Error("attemptId is required");
|
|
2054
|
+
}
|
|
2055
|
+
return client["requestGameBackend"](`${ASSESSMENTS_ROUTE}/${encodeURIComponent(attemptId)}`, "GET");
|
|
2056
|
+
},
|
|
2057
|
+
save: async (attemptId, input) => {
|
|
2058
|
+
assertPlatformMode(client, "timeback.assessments.save()");
|
|
2059
|
+
if (!attemptId?.trim()) {
|
|
2060
|
+
throw new Error("attemptId is required");
|
|
2061
|
+
}
|
|
2062
|
+
if (!Number.isInteger(input.expectedResponseVersion) || input.expectedResponseVersion < 0) {
|
|
2063
|
+
throw new Error("expectedResponseVersion must be a non-negative integer");
|
|
2064
|
+
}
|
|
2065
|
+
return client["requestGameBackend"](`${ASSESSMENTS_ROUTE}/${encodeURIComponent(attemptId)}/save`, "POST", input);
|
|
2066
|
+
},
|
|
2067
|
+
submit: async (attemptId, input) => {
|
|
2068
|
+
assertPlatformMode(client, "timeback.assessments.submit()");
|
|
2069
|
+
if (!attemptId?.trim()) {
|
|
2070
|
+
throw new Error("attemptId is required");
|
|
2071
|
+
}
|
|
2072
|
+
if (!Number.isInteger(input.expectedResponseVersion) || input.expectedResponseVersion < 0) {
|
|
2073
|
+
throw new Error("expectedResponseVersion must be a non-negative integer");
|
|
2074
|
+
}
|
|
2075
|
+
if (!input.submissionId?.trim()) {
|
|
2076
|
+
throw new Error("submissionId is required");
|
|
2077
|
+
}
|
|
2078
|
+
return client["requestGameBackend"](`${ASSESSMENTS_ROUTE}/${encodeURIComponent(attemptId)}/submit`, "POST", input);
|
|
2079
|
+
}
|
|
2080
|
+
},
|
|
2009
2081
|
get user() {
|
|
2010
2082
|
assertPlatformMode(client, "timeback.user");
|
|
2011
2083
|
return {
|
|
@@ -2391,7 +2463,7 @@ async function request({
|
|
|
2391
2463
|
return rawText && rawText.length > 0 ? rawText : undefined;
|
|
2392
2464
|
}
|
|
2393
2465
|
// src/version.ts
|
|
2394
|
-
var SDK_VERSION = "0.
|
|
2466
|
+
var SDK_VERSION = "0.16.1-beta.1";
|
|
2395
2467
|
|
|
2396
2468
|
// src/clients/base.ts
|
|
2397
2469
|
class PlaycademyBaseClient {
|
package/dist/internal.d.ts
CHANGED
|
@@ -3483,6 +3483,7 @@ declare class PlaycademyInternalClient extends PlaycademyBaseClient {
|
|
|
3483
3483
|
reactivateCourse: (gameId: string, courseId: string) => Promise<_playcademy_types.GameTimebackIntegration>;
|
|
3484
3484
|
getIntegrationConfig: (gameId: string, courseId: string) => Promise<_playcademy_types.GameTimebackIntegrationConfig>;
|
|
3485
3485
|
getConfig: (gameId: string) => Promise<_playcademy_types.TimebackSetupRequest['config']>;
|
|
3486
|
+
exportAssessmentFixtures: (gameId: string) => Promise<_playcademy_types.AssessmentRuntimeFixtureBundle>;
|
|
3486
3487
|
};
|
|
3487
3488
|
students: {
|
|
3488
3489
|
get: (timebackId: string, options?: TTLCacheConfig) => Promise<PlatformTimebackUserContext>;
|
package/dist/internal.js
CHANGED
|
@@ -1118,25 +1118,6 @@ function createScoresNamespace(client) {
|
|
|
1118
1118
|
}
|
|
1119
1119
|
};
|
|
1120
1120
|
}
|
|
1121
|
-
// src/core/guards.ts
|
|
1122
|
-
var VALID_GRADES = [-1, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13];
|
|
1123
|
-
var VALID_SUBJECTS = [
|
|
1124
|
-
"Reading",
|
|
1125
|
-
"Language",
|
|
1126
|
-
"Vocabulary",
|
|
1127
|
-
"Social Studies",
|
|
1128
|
-
"Writing",
|
|
1129
|
-
"Science",
|
|
1130
|
-
"FastMath",
|
|
1131
|
-
"Math",
|
|
1132
|
-
"None"
|
|
1133
|
-
];
|
|
1134
|
-
function isValidGrade(value) {
|
|
1135
|
-
return typeof value === "number" && Number.isInteger(value) && VALID_GRADES.includes(value);
|
|
1136
|
-
}
|
|
1137
|
-
function isValidSubject(value) {
|
|
1138
|
-
return typeof value === "string" && VALID_SUBJECTS.includes(value);
|
|
1139
|
-
}
|
|
1140
1121
|
// ../constants/src/platform.ts
|
|
1141
1122
|
var PLAYCADEMY_BROWSER_TIME_ZONE_HEADER = "x-playcademy-browser-time-zone";
|
|
1142
1123
|
// ../constants/src/timeback.ts
|
|
@@ -1147,8 +1128,22 @@ var TIMEBACK_ROUTES = {
|
|
|
1147
1128
|
GET_HIGHEST_GRADE_MASTERED: "/integrations/timeback/highest-grade-mastered",
|
|
1148
1129
|
HEARTBEAT: "/integrations/timeback/heartbeat",
|
|
1149
1130
|
ADVANCE_COURSE: "/integrations/timeback/advance-course",
|
|
1150
|
-
UNENROLL_COURSE: "/integrations/timeback/unenroll-course"
|
|
1131
|
+
UNENROLL_COURSE: "/integrations/timeback/unenroll-course",
|
|
1132
|
+
ASSESSMENTS: "/integrations/timeback/assessments"
|
|
1151
1133
|
};
|
|
1134
|
+
var TIMEBACK_GRADES = [-1, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13];
|
|
1135
|
+
var TIMEBACK_SUBJECTS = [
|
|
1136
|
+
"Reading",
|
|
1137
|
+
"Language",
|
|
1138
|
+
"Vocabulary",
|
|
1139
|
+
"Social Studies",
|
|
1140
|
+
"Writing",
|
|
1141
|
+
"Science",
|
|
1142
|
+
"FastMath",
|
|
1143
|
+
"Math",
|
|
1144
|
+
"None"
|
|
1145
|
+
];
|
|
1146
|
+
var ASSESSMENT_PURPOSES = ["end_of_course", "diagnostic"];
|
|
1152
1147
|
var TIMEBACK_GAME_METRIC_DECIMAL_PLACES = {
|
|
1153
1148
|
xp: 1,
|
|
1154
1149
|
mastery: 0,
|
|
@@ -1160,6 +1155,19 @@ var TIMEBACK_GAME_METRIC_COMPARISON_TOLERANCE = {
|
|
|
1160
1155
|
time: 60,
|
|
1161
1156
|
score: 0.5 / 10 ** TIMEBACK_GAME_METRIC_DECIMAL_PLACES.score
|
|
1162
1157
|
};
|
|
1158
|
+
// src/core/guards.ts
|
|
1159
|
+
var VALID_GRADES = TIMEBACK_GRADES;
|
|
1160
|
+
var VALID_SUBJECTS = TIMEBACK_SUBJECTS;
|
|
1161
|
+
function isValidGrade(value) {
|
|
1162
|
+
return typeof value === "number" && Number.isInteger(value) && VALID_GRADES.includes(value);
|
|
1163
|
+
}
|
|
1164
|
+
function isValidSubject(value) {
|
|
1165
|
+
return typeof value === "string" && VALID_SUBJECTS.includes(value);
|
|
1166
|
+
}
|
|
1167
|
+
function isAssessmentPurpose(value) {
|
|
1168
|
+
return typeof value === "string" && ASSESSMENT_PURPOSES.includes(value);
|
|
1169
|
+
}
|
|
1170
|
+
|
|
1163
1171
|
// src/core/cache/ttl-cache.ts
|
|
1164
1172
|
function createTTLCache(options) {
|
|
1165
1173
|
const cache = new Map;
|
|
@@ -2003,9 +2011,73 @@ function createTimebackEngine(client) {
|
|
|
2003
2011
|
// src/namespaces/game/timeback.ts
|
|
2004
2012
|
var VALID_XP_INCLUDE_OPTIONS = ["perCourse", "today"];
|
|
2005
2013
|
var VALID_MASTERY_INCLUDE_OPTIONS = ["perCourse"];
|
|
2014
|
+
var ASSESSMENTS_ROUTE = TIMEBACK_ROUTES.ASSESSMENTS;
|
|
2015
|
+
function validateAssessmentFilters(options) {
|
|
2016
|
+
if (!isAssessmentPurpose(options?.purpose)) {
|
|
2017
|
+
throw new Error("purpose must be end_of_course or diagnostic");
|
|
2018
|
+
}
|
|
2019
|
+
if (options.grade !== undefined && !isValidGrade(options.grade)) {
|
|
2020
|
+
throw new Error(`Invalid grade: ${options.grade}. Valid grades: ${VALID_GRADES.join(", ")}`);
|
|
2021
|
+
}
|
|
2022
|
+
if (options.subject !== undefined && !isValidSubject(options.subject)) {
|
|
2023
|
+
throw new Error(`Invalid subject: ${options.subject}. Valid subjects: ${VALID_SUBJECTS.join(", ")}`);
|
|
2024
|
+
}
|
|
2025
|
+
}
|
|
2006
2026
|
function createTimebackNamespace(client) {
|
|
2007
2027
|
const engine = createTimebackEngine(client);
|
|
2008
2028
|
return {
|
|
2029
|
+
assessments: {
|
|
2030
|
+
start: async (input) => {
|
|
2031
|
+
assertPlatformMode(client, "timeback.assessments.start()");
|
|
2032
|
+
if (!input.activityId?.trim()) {
|
|
2033
|
+
throw new Error("activityId is required");
|
|
2034
|
+
}
|
|
2035
|
+
validateAssessmentFilters(input);
|
|
2036
|
+
return client["requestGameBackend"](`${ASSESSMENTS_ROUTE}/start`, "POST", input);
|
|
2037
|
+
},
|
|
2038
|
+
latest: async (options) => {
|
|
2039
|
+
assertPlatformMode(client, "timeback.assessments.latest()");
|
|
2040
|
+
validateAssessmentFilters(options);
|
|
2041
|
+
const params = new URLSearchParams({ purpose: options.purpose });
|
|
2042
|
+
if (options.subject !== undefined) {
|
|
2043
|
+
params.set("subject", options.subject);
|
|
2044
|
+
}
|
|
2045
|
+
if (options.grade !== undefined) {
|
|
2046
|
+
params.set("grade", String(options.grade));
|
|
2047
|
+
}
|
|
2048
|
+
return client["requestGameBackend"](`${ASSESSMENTS_ROUTE}/latest?${params.toString()}`, "GET");
|
|
2049
|
+
},
|
|
2050
|
+
get: async (attemptId) => {
|
|
2051
|
+
assertPlatformMode(client, "timeback.assessments.get()");
|
|
2052
|
+
if (!attemptId?.trim()) {
|
|
2053
|
+
throw new Error("attemptId is required");
|
|
2054
|
+
}
|
|
2055
|
+
return client["requestGameBackend"](`${ASSESSMENTS_ROUTE}/${encodeURIComponent(attemptId)}`, "GET");
|
|
2056
|
+
},
|
|
2057
|
+
save: async (attemptId, input) => {
|
|
2058
|
+
assertPlatformMode(client, "timeback.assessments.save()");
|
|
2059
|
+
if (!attemptId?.trim()) {
|
|
2060
|
+
throw new Error("attemptId is required");
|
|
2061
|
+
}
|
|
2062
|
+
if (!Number.isInteger(input.expectedResponseVersion) || input.expectedResponseVersion < 0) {
|
|
2063
|
+
throw new Error("expectedResponseVersion must be a non-negative integer");
|
|
2064
|
+
}
|
|
2065
|
+
return client["requestGameBackend"](`${ASSESSMENTS_ROUTE}/${encodeURIComponent(attemptId)}/save`, "POST", input);
|
|
2066
|
+
},
|
|
2067
|
+
submit: async (attemptId, input) => {
|
|
2068
|
+
assertPlatformMode(client, "timeback.assessments.submit()");
|
|
2069
|
+
if (!attemptId?.trim()) {
|
|
2070
|
+
throw new Error("attemptId is required");
|
|
2071
|
+
}
|
|
2072
|
+
if (!Number.isInteger(input.expectedResponseVersion) || input.expectedResponseVersion < 0) {
|
|
2073
|
+
throw new Error("expectedResponseVersion must be a non-negative integer");
|
|
2074
|
+
}
|
|
2075
|
+
if (!input.submissionId?.trim()) {
|
|
2076
|
+
throw new Error("submissionId is required");
|
|
2077
|
+
}
|
|
2078
|
+
return client["requestGameBackend"](`${ASSESSMENTS_ROUTE}/${encodeURIComponent(attemptId)}/submit`, "POST", input);
|
|
2079
|
+
}
|
|
2080
|
+
},
|
|
2009
2081
|
get user() {
|
|
2010
2082
|
assertPlatformMode(client, "timeback.user");
|
|
2011
2083
|
return {
|
|
@@ -2914,7 +2986,8 @@ function createTimebackNamespace2(client) {
|
|
|
2914
2986
|
deactivateCourse: (gameId, courseId) => client["request"](`/timeback/integrations/${gameId}/${courseId}`, "DELETE"),
|
|
2915
2987
|
reactivateCourse: (gameId, courseId) => client["request"](`/timeback/integrations/${gameId}/${courseId}/reactivate`, "POST"),
|
|
2916
2988
|
getIntegrationConfig: (gameId, courseId) => client["request"](`/timeback/integrations/${gameId}/${courseId}`, "GET"),
|
|
2917
|
-
getConfig: (gameId) => client["request"](`/timeback/config/${gameId}`, "GET")
|
|
2989
|
+
getConfig: (gameId) => client["request"](`/timeback/config/${gameId}`, "GET"),
|
|
2990
|
+
exportAssessmentFixtures: (gameId) => client["request"](`/timeback/assessments/fixtures/${gameId}`, "GET")
|
|
2918
2991
|
},
|
|
2919
2992
|
students: {
|
|
2920
2993
|
get: async (timebackId, options) => studentCache.get(timebackId, async () => client["request"](`/timeback/user/${timebackId}`, "GET"), options),
|
|
@@ -3239,7 +3312,7 @@ async function request({
|
|
|
3239
3312
|
return rawText && rawText.length > 0 ? rawText : undefined;
|
|
3240
3313
|
}
|
|
3241
3314
|
// src/version.ts
|
|
3242
|
-
var SDK_VERSION = "0.
|
|
3315
|
+
var SDK_VERSION = "0.16.1-beta.1";
|
|
3243
3316
|
|
|
3244
3317
|
// src/clients/base.ts
|
|
3245
3318
|
class PlaycademyBaseClient {
|
package/dist/server/edge.d.ts
CHANGED
|
@@ -346,6 +346,15 @@ declare class PlaycademyClient {
|
|
|
346
346
|
get config(): PlaycademyServerClientState['config'];
|
|
347
347
|
/** TimeBack integration methods (endActivity) */
|
|
348
348
|
timeback: {
|
|
349
|
+
assessments: {
|
|
350
|
+
start: (studentId: string, input: _playcademy_types.StartAssessmentInput) => Promise<_playcademy_types.AssessmentAttemptSnapshot>;
|
|
351
|
+
latest: (studentId: string, options: _playcademy_types.GetLatestAssessmentOptions) => Promise<_playcademy_types.LatestAssessmentResult | null>;
|
|
352
|
+
get: (studentId: string, attemptId: string) => Promise<_playcademy_types.AssessmentAttemptSnapshot>;
|
|
353
|
+
save: (studentId: string, attemptId: string, input: _playcademy_types.SaveAssessmentInput) => Promise<_playcademy_types.AssessmentSaveResult>;
|
|
354
|
+
submit: (studentId: string, attemptId: string, input: _playcademy_types.SubmitAssessmentInput, context: {
|
|
355
|
+
sensorUrl: string;
|
|
356
|
+
}) => Promise<_playcademy_types.AssessmentSubmitResult>;
|
|
357
|
+
};
|
|
349
358
|
endActivity: (studentId: string, payload: _playcademy_types.EndActivityPayload) => Promise<_playcademy_types.EndActivityResponse>;
|
|
350
359
|
getStudentXp: (studentId: string, options?: {
|
|
351
360
|
grade?: number;
|
package/dist/server/edge.js
CHANGED
|
@@ -9,10 +9,21 @@ var __export = (target, all) => {
|
|
|
9
9
|
});
|
|
10
10
|
};
|
|
11
11
|
var __esm = (fn, res) => () => (fn && (res = fn(fn = 0)), res);
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
var
|
|
12
|
+
// ../constants/src/platform.ts
|
|
13
|
+
var PLAYCADEMY_BROWSER_TIME_ZONE_HEADER = "x-playcademy-browser-time-zone";
|
|
14
|
+
// ../constants/src/timeback.ts
|
|
15
|
+
var TIMEBACK_ROUTES = {
|
|
16
|
+
END_ACTIVITY: "/integrations/timeback/end-activity",
|
|
17
|
+
GET_XP: "/integrations/timeback/xp",
|
|
18
|
+
GET_MASTERY: "/integrations/timeback/mastery",
|
|
19
|
+
GET_HIGHEST_GRADE_MASTERED: "/integrations/timeback/highest-grade-mastered",
|
|
20
|
+
HEARTBEAT: "/integrations/timeback/heartbeat",
|
|
21
|
+
ADVANCE_COURSE: "/integrations/timeback/advance-course",
|
|
22
|
+
UNENROLL_COURSE: "/integrations/timeback/unenroll-course",
|
|
23
|
+
ASSESSMENTS: "/integrations/timeback/assessments"
|
|
24
|
+
};
|
|
25
|
+
var TIMEBACK_GRADES = [-1, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13];
|
|
26
|
+
var TIMEBACK_SUBJECTS = [
|
|
16
27
|
"Reading",
|
|
17
28
|
"Language",
|
|
18
29
|
"Vocabulary",
|
|
@@ -23,12 +34,30 @@ var VALID_SUBJECTS = [
|
|
|
23
34
|
"Math",
|
|
24
35
|
"None"
|
|
25
36
|
];
|
|
37
|
+
var ASSESSMENT_PURPOSES = ["end_of_course", "diagnostic"];
|
|
38
|
+
var TIMEBACK_GAME_METRIC_DECIMAL_PLACES = {
|
|
39
|
+
xp: 1,
|
|
40
|
+
mastery: 0,
|
|
41
|
+
score: 2
|
|
42
|
+
};
|
|
43
|
+
var TIMEBACK_GAME_METRIC_COMPARISON_TOLERANCE = {
|
|
44
|
+
xp: 0.5 / 10 ** TIMEBACK_GAME_METRIC_DECIMAL_PLACES.xp,
|
|
45
|
+
mastery: 0,
|
|
46
|
+
time: 60,
|
|
47
|
+
score: 0.5 / 10 ** TIMEBACK_GAME_METRIC_DECIMAL_PLACES.score
|
|
48
|
+
};
|
|
49
|
+
// src/core/guards.ts
|
|
50
|
+
var VALID_GRADES = TIMEBACK_GRADES;
|
|
51
|
+
var VALID_SUBJECTS = TIMEBACK_SUBJECTS;
|
|
26
52
|
function isValidGrade(value) {
|
|
27
53
|
return typeof value === "number" && Number.isInteger(value) && VALID_GRADES.includes(value);
|
|
28
54
|
}
|
|
29
55
|
function isValidSubject(value) {
|
|
30
56
|
return typeof value === "string" && VALID_SUBJECTS.includes(value);
|
|
31
57
|
}
|
|
58
|
+
function isAssessmentPurpose(value) {
|
|
59
|
+
return typeof value === "string" && ASSESSMENT_PURPOSES.includes(value);
|
|
60
|
+
}
|
|
32
61
|
// src/server/namespaces/timeback.ts
|
|
33
62
|
function createTimebackNamespace(client) {
|
|
34
63
|
function enrichActivityData(data) {
|
|
@@ -38,6 +67,35 @@ function createTimebackNamespace(client) {
|
|
|
38
67
|
};
|
|
39
68
|
}
|
|
40
69
|
return {
|
|
70
|
+
assessments: {
|
|
71
|
+
start: (studentId, input) => client["request"]("/api/timeback/assessments/start", "POST", { ...input, gameId: client.gameId, studentId }),
|
|
72
|
+
latest: (studentId, options) => {
|
|
73
|
+
const params = new URLSearchParams({
|
|
74
|
+
gameId: client.gameId,
|
|
75
|
+
studentId,
|
|
76
|
+
purpose: options.purpose
|
|
77
|
+
});
|
|
78
|
+
if (options.subject !== undefined) {
|
|
79
|
+
params.set("subject", options.subject);
|
|
80
|
+
}
|
|
81
|
+
if (options.grade !== undefined) {
|
|
82
|
+
params.set("grade", String(options.grade));
|
|
83
|
+
}
|
|
84
|
+
return client["request"](`/api/timeback/assessments/latest?${params.toString()}`, "GET");
|
|
85
|
+
},
|
|
86
|
+
get: (studentId, attemptId) => {
|
|
87
|
+
const params = new URLSearchParams({ gameId: client.gameId, studentId });
|
|
88
|
+
return client["request"](`/api/timeback/assessments/${encodeURIComponent(attemptId)}?${params.toString()}`, "GET");
|
|
89
|
+
},
|
|
90
|
+
save: (studentId, attemptId, input) => client["request"](`/api/timeback/assessments/${encodeURIComponent(attemptId)}/save`, "POST", { ...input, gameId: client.gameId, studentId }),
|
|
91
|
+
submit: (studentId, attemptId, input, context) => client["request"](`/api/timeback/assessments/${encodeURIComponent(attemptId)}/submit`, "POST", {
|
|
92
|
+
...input,
|
|
93
|
+
gameId: client.gameId,
|
|
94
|
+
studentId,
|
|
95
|
+
appName: client.config.name,
|
|
96
|
+
sensorUrl: context.sensorUrl
|
|
97
|
+
})
|
|
98
|
+
},
|
|
41
99
|
endActivity: async (studentId, payload) => {
|
|
42
100
|
if (!isValidGrade(payload.activityData.grade)) {
|
|
43
101
|
throw new Error("activityData.grade must be a valid grade level (-1 to 13)");
|
|
@@ -234,7 +292,7 @@ function extractApiErrorInfo(error) {
|
|
|
234
292
|
}
|
|
235
293
|
|
|
236
294
|
// src/version.ts
|
|
237
|
-
var SDK_VERSION = "0.
|
|
295
|
+
var SDK_VERSION = "0.16.1-beta.1";
|
|
238
296
|
|
|
239
297
|
// src/server/request.ts
|
|
240
298
|
async function makeApiRequest(opts) {
|
package/dist/server.d.ts
CHANGED
|
@@ -346,6 +346,15 @@ declare class PlaycademyClient$1 {
|
|
|
346
346
|
get config(): PlaycademyServerClientState['config'];
|
|
347
347
|
/** TimeBack integration methods (endActivity) */
|
|
348
348
|
timeback: {
|
|
349
|
+
assessments: {
|
|
350
|
+
start: (studentId: string, input: _playcademy_types.StartAssessmentInput) => Promise<_playcademy_types.AssessmentAttemptSnapshot>;
|
|
351
|
+
latest: (studentId: string, options: _playcademy_types.GetLatestAssessmentOptions) => Promise<_playcademy_types.LatestAssessmentResult | null>;
|
|
352
|
+
get: (studentId: string, attemptId: string) => Promise<_playcademy_types.AssessmentAttemptSnapshot>;
|
|
353
|
+
save: (studentId: string, attemptId: string, input: _playcademy_types.SaveAssessmentInput) => Promise<_playcademy_types.AssessmentSaveResult>;
|
|
354
|
+
submit: (studentId: string, attemptId: string, input: _playcademy_types.SubmitAssessmentInput, context: {
|
|
355
|
+
sensorUrl: string;
|
|
356
|
+
}) => Promise<_playcademy_types.AssessmentSubmitResult>;
|
|
357
|
+
};
|
|
349
358
|
endActivity: (studentId: string, payload: _playcademy_types.EndActivityPayload) => Promise<_playcademy_types.EndActivityResponse>;
|
|
350
359
|
getStudentXp: (studentId: string, options?: {
|
|
351
360
|
grade?: number;
|
package/dist/server.js
CHANGED
|
@@ -198,10 +198,21 @@ function validateConfig(config) {
|
|
|
198
198
|
var init_config_loader = __esm(() => {
|
|
199
199
|
init_file_loader();
|
|
200
200
|
});
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
var
|
|
201
|
+
// ../constants/src/platform.ts
|
|
202
|
+
var PLAYCADEMY_BROWSER_TIME_ZONE_HEADER = "x-playcademy-browser-time-zone";
|
|
203
|
+
// ../constants/src/timeback.ts
|
|
204
|
+
var TIMEBACK_ROUTES = {
|
|
205
|
+
END_ACTIVITY: "/integrations/timeback/end-activity",
|
|
206
|
+
GET_XP: "/integrations/timeback/xp",
|
|
207
|
+
GET_MASTERY: "/integrations/timeback/mastery",
|
|
208
|
+
GET_HIGHEST_GRADE_MASTERED: "/integrations/timeback/highest-grade-mastered",
|
|
209
|
+
HEARTBEAT: "/integrations/timeback/heartbeat",
|
|
210
|
+
ADVANCE_COURSE: "/integrations/timeback/advance-course",
|
|
211
|
+
UNENROLL_COURSE: "/integrations/timeback/unenroll-course",
|
|
212
|
+
ASSESSMENTS: "/integrations/timeback/assessments"
|
|
213
|
+
};
|
|
214
|
+
var TIMEBACK_GRADES = [-1, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13];
|
|
215
|
+
var TIMEBACK_SUBJECTS = [
|
|
205
216
|
"Reading",
|
|
206
217
|
"Language",
|
|
207
218
|
"Vocabulary",
|
|
@@ -212,12 +223,30 @@ var VALID_SUBJECTS = [
|
|
|
212
223
|
"Math",
|
|
213
224
|
"None"
|
|
214
225
|
];
|
|
226
|
+
var ASSESSMENT_PURPOSES = ["end_of_course", "diagnostic"];
|
|
227
|
+
var TIMEBACK_GAME_METRIC_DECIMAL_PLACES = {
|
|
228
|
+
xp: 1,
|
|
229
|
+
mastery: 0,
|
|
230
|
+
score: 2
|
|
231
|
+
};
|
|
232
|
+
var TIMEBACK_GAME_METRIC_COMPARISON_TOLERANCE = {
|
|
233
|
+
xp: 0.5 / 10 ** TIMEBACK_GAME_METRIC_DECIMAL_PLACES.xp,
|
|
234
|
+
mastery: 0,
|
|
235
|
+
time: 60,
|
|
236
|
+
score: 0.5 / 10 ** TIMEBACK_GAME_METRIC_DECIMAL_PLACES.score
|
|
237
|
+
};
|
|
238
|
+
// src/core/guards.ts
|
|
239
|
+
var VALID_GRADES = TIMEBACK_GRADES;
|
|
240
|
+
var VALID_SUBJECTS = TIMEBACK_SUBJECTS;
|
|
215
241
|
function isValidGrade(value) {
|
|
216
242
|
return typeof value === "number" && Number.isInteger(value) && VALID_GRADES.includes(value);
|
|
217
243
|
}
|
|
218
244
|
function isValidSubject(value) {
|
|
219
245
|
return typeof value === "string" && VALID_SUBJECTS.includes(value);
|
|
220
246
|
}
|
|
247
|
+
function isAssessmentPurpose(value) {
|
|
248
|
+
return typeof value === "string" && ASSESSMENT_PURPOSES.includes(value);
|
|
249
|
+
}
|
|
221
250
|
// src/server/namespaces/timeback.ts
|
|
222
251
|
function createTimebackNamespace(client) {
|
|
223
252
|
function enrichActivityData(data) {
|
|
@@ -227,6 +256,35 @@ function createTimebackNamespace(client) {
|
|
|
227
256
|
};
|
|
228
257
|
}
|
|
229
258
|
return {
|
|
259
|
+
assessments: {
|
|
260
|
+
start: (studentId, input) => client["request"]("/api/timeback/assessments/start", "POST", { ...input, gameId: client.gameId, studentId }),
|
|
261
|
+
latest: (studentId, options) => {
|
|
262
|
+
const params = new URLSearchParams({
|
|
263
|
+
gameId: client.gameId,
|
|
264
|
+
studentId,
|
|
265
|
+
purpose: options.purpose
|
|
266
|
+
});
|
|
267
|
+
if (options.subject !== undefined) {
|
|
268
|
+
params.set("subject", options.subject);
|
|
269
|
+
}
|
|
270
|
+
if (options.grade !== undefined) {
|
|
271
|
+
params.set("grade", String(options.grade));
|
|
272
|
+
}
|
|
273
|
+
return client["request"](`/api/timeback/assessments/latest?${params.toString()}`, "GET");
|
|
274
|
+
},
|
|
275
|
+
get: (studentId, attemptId) => {
|
|
276
|
+
const params = new URLSearchParams({ gameId: client.gameId, studentId });
|
|
277
|
+
return client["request"](`/api/timeback/assessments/${encodeURIComponent(attemptId)}?${params.toString()}`, "GET");
|
|
278
|
+
},
|
|
279
|
+
save: (studentId, attemptId, input) => client["request"](`/api/timeback/assessments/${encodeURIComponent(attemptId)}/save`, "POST", { ...input, gameId: client.gameId, studentId }),
|
|
280
|
+
submit: (studentId, attemptId, input, context) => client["request"](`/api/timeback/assessments/${encodeURIComponent(attemptId)}/submit`, "POST", {
|
|
281
|
+
...input,
|
|
282
|
+
gameId: client.gameId,
|
|
283
|
+
studentId,
|
|
284
|
+
appName: client.config.name,
|
|
285
|
+
sensorUrl: context.sensorUrl
|
|
286
|
+
})
|
|
287
|
+
},
|
|
230
288
|
endActivity: async (studentId, payload) => {
|
|
231
289
|
if (!isValidGrade(payload.activityData.grade)) {
|
|
232
290
|
throw new Error("activityData.grade must be a valid grade level (-1 to 13)");
|
|
@@ -423,7 +481,7 @@ function extractApiErrorInfo(error) {
|
|
|
423
481
|
}
|
|
424
482
|
|
|
425
483
|
// src/version.ts
|
|
426
|
-
var SDK_VERSION = "0.
|
|
484
|
+
var SDK_VERSION = "0.16.1-beta.1";
|
|
427
485
|
|
|
428
486
|
// src/server/request.ts
|
|
429
487
|
async function makeApiRequest(opts) {
|
package/dist/types.d.ts
CHANGED
|
@@ -1465,6 +1465,13 @@ declare class PlaycademyClient extends PlaycademyBaseClient {
|
|
|
1465
1465
|
* - `endActivity(scoreData)` - Submit activity results to TimeBack
|
|
1466
1466
|
*/
|
|
1467
1467
|
timeback: {
|
|
1468
|
+
assessments: {
|
|
1469
|
+
start: (input: _playcademy_types.StartAssessmentInput) => Promise<_playcademy_types.AssessmentAttemptSnapshot>;
|
|
1470
|
+
latest: (options: _playcademy_types.GetLatestAssessmentOptions) => Promise<_playcademy_types.LatestAssessmentResult | null>;
|
|
1471
|
+
get: (attemptId: string) => Promise<_playcademy_types.AssessmentAttemptSnapshot>;
|
|
1472
|
+
save: (attemptId: string, input: _playcademy_types.SaveAssessmentInput) => Promise<_playcademy_types.AssessmentSaveResult>;
|
|
1473
|
+
submit: (attemptId: string, input: _playcademy_types.SubmitAssessmentInput) => Promise<_playcademy_types.AssessmentSubmitResult>;
|
|
1474
|
+
};
|
|
1468
1475
|
readonly user: TimebackUser;
|
|
1469
1476
|
readonly currentRunId: string | undefined;
|
|
1470
1477
|
startActivity: (metadata: _playcademy_types.ActivityData, options?: StartActivityOptions) => StartActivityResult;
|