@playcademy/sdk 0.16.1-beta.22 → 0.16.1-beta.23
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 +23 -15
- package/dist/index.js +10 -1
- package/dist/internal.d.ts +4 -3
- package/dist/internal.js +10 -1
- package/dist/server/edge.js +1 -1
- package/dist/server.js +1 -1
- package/dist/types.d.ts +1 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -122,21 +122,25 @@ Hosted assessments use the same methods locally and when deployed:
|
|
|
122
122
|
const attempt = await client.timeback.assessments.start({
|
|
123
123
|
activityId: 'math-diagnostic',
|
|
124
124
|
purpose: 'diagnostic',
|
|
125
|
+
diagnosticKey: 'math.grade-5-placement',
|
|
125
126
|
subject: 'Math',
|
|
126
127
|
grade: 5,
|
|
127
128
|
})
|
|
128
129
|
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
[attempt.assessment.items[0].identifier]: { RESPONSE: 'A' },
|
|
133
|
-
},
|
|
134
|
-
})
|
|
130
|
+
if (attempt.flow !== 'platform-routed-item-submit' || !attempt.routing.next) {
|
|
131
|
+
throw new Error('Expected an active routed diagnostic')
|
|
132
|
+
}
|
|
135
133
|
|
|
136
|
-
const
|
|
137
|
-
|
|
134
|
+
const current = attempt.routing.next
|
|
135
|
+
const committed = await client.timeback.assessments.submitItem(attempt.attemptId, {
|
|
136
|
+
expectedResponseVersion: attempt.responseVersion,
|
|
138
137
|
submissionId: crypto.randomUUID(),
|
|
138
|
+
routingNodeKey: current.nodeKey,
|
|
139
|
+
itemIdentifier: current.itemIdentifier,
|
|
140
|
+
responses: { RESPONSE: 'A' },
|
|
139
141
|
})
|
|
142
|
+
|
|
143
|
+
// Repeat with committed.routing.next. When routing is ready, submit() only finalizes.
|
|
140
144
|
```
|
|
141
145
|
|
|
142
146
|
`start()` resumes a compatible unfinished attempt or selects content for a fixed test or standards
|
|
@@ -144,20 +148,24 @@ review. Save payloads merge at both the item and response levels; omitted values
|
|
|
144
148
|
and `null` clears one response. Keep the returned `responseVersion` and send it with the next
|
|
145
149
|
mutation.
|
|
146
150
|
|
|
147
|
-
The returned `flow` is authoritative and is derived from
|
|
151
|
+
The returned `flow` is authoritative and is derived from the selected assessment; callers do not configure
|
|
148
152
|
navigation, feedback, and submission independently:
|
|
149
153
|
|
|
150
|
-
- `attempt-submit` is used for
|
|
151
|
-
|
|
154
|
+
- `attempt-submit` is used for end-of-course and mastery attempts. Responses remain editable
|
|
155
|
+
through `save()` until `submit()` finalizes the whole attempt and returns feedback.
|
|
152
156
|
- `item-submit` is used for review attempts. Submit each administered item with `submitItem()`.
|
|
153
157
|
That operation atomically saves the item's responses, locks them, and returns safe immediate
|
|
154
158
|
feedback. Give each item request its own stable `submissionId` and reuse that ID for an ambiguous
|
|
155
159
|
retry; the returned canonical `itemSubmissions` ledger identifies committed items after retry or
|
|
156
160
|
resume.
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
+
- `platform-routed-item-submit` is used for adaptive diagnostics. Render only
|
|
162
|
+
`routing.next.itemIdentifier`, submit it with `routing.next.nodeKey`, and replace local state with
|
|
163
|
+
the returned canonical routing snapshot. Diagnostic receipts never reveal correctness or score,
|
|
164
|
+
and `submit()` becomes available only after routing reports `ready-to-complete`.
|
|
165
|
+
|
|
166
|
+
The host rejects the wrong mutation for each flow, rejects premature finalization, and enforces
|
|
167
|
+
`expectedResponseVersion` for every mutation. Hosted and local providers execute the same routing
|
|
168
|
+
manifest contract; game code never selects the provider.
|
|
161
169
|
|
|
162
170
|
For local development, import the current ordered catalog before starting the dev host:
|
|
163
171
|
|
package/dist/index.js
CHANGED
|
@@ -3150,6 +3150,12 @@ function createTimebackNamespace(client) {
|
|
|
3150
3150
|
throw new Error("activityId is required");
|
|
3151
3151
|
}
|
|
3152
3152
|
validateAssessmentFilters(input);
|
|
3153
|
+
if (input.purpose === "diagnostic" && !input.diagnosticKey?.trim()) {
|
|
3154
|
+
throw new Error("diagnosticKey is required for diagnostic assessments");
|
|
3155
|
+
}
|
|
3156
|
+
if (input.purpose === "diagnostic" && input.diagnosticKey.trim().length > 200) {
|
|
3157
|
+
throw new Error("diagnosticKey must contain at most 200 characters");
|
|
3158
|
+
}
|
|
3153
3159
|
if (input.purpose === "review") {
|
|
3154
3160
|
if (!Array.isArray(input.standards) || input.standards.length === 0) {
|
|
3155
3161
|
throw new Error("standards must contain at least one standard for review");
|
|
@@ -3232,6 +3238,9 @@ function createTimebackNamespace(client) {
|
|
|
3232
3238
|
if (!input.itemIdentifier?.trim()) {
|
|
3233
3239
|
throw new Error("itemIdentifier is required");
|
|
3234
3240
|
}
|
|
3241
|
+
if (input.routingNodeKey !== undefined && !input.routingNodeKey.trim()) {
|
|
3242
|
+
throw new Error("routingNodeKey must be non-empty when provided");
|
|
3243
|
+
}
|
|
3235
3244
|
return client["requestGameBackend"](`${ASSESSMENTS_ROUTE}/${encodeURIComponent(attemptId)}/submit-item`, "POST", input);
|
|
3236
3245
|
},
|
|
3237
3246
|
submit: async (attemptId, input) => {
|
|
@@ -3670,7 +3679,7 @@ async function request({
|
|
|
3670
3679
|
return rawText && rawText.length > 0 ? rawText : undefined;
|
|
3671
3680
|
}
|
|
3672
3681
|
// src/version.ts
|
|
3673
|
-
var SDK_VERSION = "0.16.1-beta.
|
|
3682
|
+
var SDK_VERSION = "0.16.1-beta.23";
|
|
3674
3683
|
|
|
3675
3684
|
// src/clients/base.ts
|
|
3676
3685
|
class PlaycademyBaseClient {
|
package/dist/internal.d.ts
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { SchemaInfo } from '@playcademy/cloudflare';
|
|
2
2
|
import { GamePermission, AUTH_PROVIDER_IDS } from '@playcademy/constants';
|
|
3
3
|
import { TimebackGrade, TimebackSubject, ELevel, HeartbeatRequest, EndActivityRequest, EndActivityScoreData, EndActivityResponse, TimebackCourseConfig, CourseConfig, OrganizationConfig, ComponentConfig, ResourceConfig, ComponentResourceConfig } from '@playcademy/types/timeback';
|
|
4
|
-
export { AssessmentAttemptSnapshot, AssessmentFlow, AssessmentItemSubmission, AssessmentResponseUpdate, AssessmentResponseValue, AssessmentResponses, AssessmentSaveResult, AssessmentScore, AssessmentStandardRef, AssessmentSubmitResult, ELevel, PlayableAssessment, PlayableAssessmentChoice, PlayableAssessmentGraphic, PlayableAssessmentHotspot, PlayableAssessmentInteraction, PlayableAssessmentItem, PlayableContentNode, SaveAssessmentInput, StartAssessmentInput, SubmitAssessmentInput, SubmitAssessmentItemInput, SubmitAssessmentItemResult } from '@playcademy/types/timeback';
|
|
4
|
+
export { AssessmentAttemptSnapshot, AssessmentFlow, AssessmentItemSubmission, AssessmentResponseUpdate, AssessmentResponseValue, AssessmentResponses, AssessmentSaveResult, AssessmentScore, AssessmentStandardRef, AssessmentSubmitResult, ConventionalAssessmentAttemptSnapshot, ConventionalAssessmentSubmitResult, DiagnosticAssessmentItemReceipt, DiagnosticAssessmentSubmitResult, DiagnosticRoutingSnapshot, DiagnosticRoutingTrackSnapshot, ELevel, PlatformRoutedDiagnosticAttemptSnapshot, PlatformRoutedDiagnosticSelectionContext, PlayableAssessment, PlayableAssessmentChoice, PlayableAssessmentGraphic, PlayableAssessmentHotspot, PlayableAssessmentInteraction, PlayableAssessmentItem, PlayableContentNode, SaveAssessmentInput, StartAssessmentInput, StartDiagnosticAssessmentInput, SubmitAssessmentInput, SubmitAssessmentItemInput, SubmitAssessmentItemResult, SubmitDiagnosticAssessmentItemInput, SubmitDiagnosticAssessmentItemResult } from '@playcademy/types/timeback';
|
|
5
5
|
import * as _playcademy_types from '@playcademy/types';
|
|
6
6
|
import { GameManifest, LocalDayContext } from '@playcademy/types';
|
|
7
7
|
export { AuthenticatedUser, DeveloperStatusEnumType, DeveloperStatusResponse, DeveloperStatusValue, GameCourseMetrics, GameLeaderboardEntry, GameManifest, GameMetricComparisonKind, GameMetricComparisonMetric, GameMetricComparisonRow, GameMetricComparisonRowStatus, GameMetricsProxyResponse, GameMetricsResponse, GameMetricsUnsupportedReason, GamePlatform, GameRunMetrics, GameRunMetricsComparison, GameRunMetricsComparisonStatus, GameRunMetricsComparisonSummary, GameTimebackIntegration, GameType, GameUser, LeaderboardEntry, LeaderboardOptions, LeaderboardTimeframe, LocalDayContext, LocalDaySource, ManifestV1, ManifestV2, ManifestVersions, PopulateStudentResponse, UserEnrollment, UserInfo, UserOrganization, UserRank, UserRankResponse, UserRoleEnumType, UserScore, UserTimebackData } from '@playcademy/types';
|
|
@@ -4021,7 +4021,7 @@ declare class PlaycademyInternalClient extends PlaycademyBaseClient {
|
|
|
4021
4021
|
list: (gameId: string, courseId: string) => Promise<_playcademy_types.AssessmentSummary[]>;
|
|
4022
4022
|
create: (gameId: string, courseId: string, data: {
|
|
4023
4023
|
title: string;
|
|
4024
|
-
purpose: _playcademy_types.AssessmentPurpose
|
|
4024
|
+
purpose: Exclude<_playcademy_types.AssessmentPurpose, 'diagnostic'>;
|
|
4025
4025
|
standard?: _playcademy_types.AssessmentStandardRef;
|
|
4026
4026
|
}) => Promise<_playcademy_types.AssessmentRow>;
|
|
4027
4027
|
attachExisting: (gameId: string, courseId: string, manifest: _playcademy_types.AssessmentAssociationImportManifest) => Promise<_playcademy_types.AssessmentAssociationImportResponse>;
|
|
@@ -4029,6 +4029,7 @@ declare class PlaycademyInternalClient extends PlaycademyBaseClient {
|
|
|
4029
4029
|
title?: string;
|
|
4030
4030
|
purpose?: _playcademy_types.AssessmentPurpose;
|
|
4031
4031
|
standard?: _playcademy_types.AssessmentStandardRef;
|
|
4032
|
+
diagnostic?: _playcademy_types.DiagnosticAssessmentDefinitionInput | null;
|
|
4032
4033
|
status?: _playcademy_types.AssessmentStatus;
|
|
4033
4034
|
}) => Promise<_playcademy_types.AssessmentRow>;
|
|
4034
4035
|
reorder: (gameId: string, courseId: string, purpose: _playcademy_types.AssessmentPurpose, testIdentifiers: string[]) => Promise<{
|
|
@@ -4038,7 +4039,7 @@ declare class PlaycademyInternalClient extends PlaycademyBaseClient {
|
|
|
4038
4039
|
action: 'discarded' | 'archived';
|
|
4039
4040
|
}>;
|
|
4040
4041
|
listTestLibrary: (gameId: string, courseId: string, options?: QtiLibraryQueryOptions) => Promise<_playcademy_types.QtiAssessmentTestListResponse>;
|
|
4041
|
-
copy: (gameId: string, courseId: string, testIdentifier: string, purpose: _playcademy_types.AssessmentPurpose, standard?: _playcademy_types.AssessmentStandardRef) => Promise<_playcademy_types.AssessmentRow>;
|
|
4042
|
+
copy: (gameId: string, courseId: string, testIdentifier: string, purpose: Exclude<_playcademy_types.AssessmentPurpose, 'diagnostic'>, standard?: _playcademy_types.AssessmentStandardRef) => Promise<_playcademy_types.AssessmentRow>;
|
|
4042
4043
|
listQuestions: (gameId: string, courseId: string, testIdentifier: string) => Promise<_playcademy_types.QtiTestQuestionsResponse>;
|
|
4043
4044
|
listQuestionLibrary: (gameId: string, courseId: string, options?: QtiLibraryQueryOptions) => Promise<_playcademy_types.QtiAssessmentItemListResponse>;
|
|
4044
4045
|
createQuestion: (gameId: string, courseId: string, testIdentifier: string, data: _playcademy_types.QtiQuestionCreateInput) => Promise<_playcademy_types.QtiTestQuestionRef>;
|
package/dist/internal.js
CHANGED
|
@@ -3150,6 +3150,12 @@ function createTimebackNamespace(client) {
|
|
|
3150
3150
|
throw new Error("activityId is required");
|
|
3151
3151
|
}
|
|
3152
3152
|
validateAssessmentFilters(input);
|
|
3153
|
+
if (input.purpose === "diagnostic" && !input.diagnosticKey?.trim()) {
|
|
3154
|
+
throw new Error("diagnosticKey is required for diagnostic assessments");
|
|
3155
|
+
}
|
|
3156
|
+
if (input.purpose === "diagnostic" && input.diagnosticKey.trim().length > 200) {
|
|
3157
|
+
throw new Error("diagnosticKey must contain at most 200 characters");
|
|
3158
|
+
}
|
|
3153
3159
|
if (input.purpose === "review") {
|
|
3154
3160
|
if (!Array.isArray(input.standards) || input.standards.length === 0) {
|
|
3155
3161
|
throw new Error("standards must contain at least one standard for review");
|
|
@@ -3232,6 +3238,9 @@ function createTimebackNamespace(client) {
|
|
|
3232
3238
|
if (!input.itemIdentifier?.trim()) {
|
|
3233
3239
|
throw new Error("itemIdentifier is required");
|
|
3234
3240
|
}
|
|
3241
|
+
if (input.routingNodeKey !== undefined && !input.routingNodeKey.trim()) {
|
|
3242
|
+
throw new Error("routingNodeKey must be non-empty when provided");
|
|
3243
|
+
}
|
|
3235
3244
|
return client["requestGameBackend"](`${ASSESSMENTS_ROUTE}/${encodeURIComponent(attemptId)}/submit-item`, "POST", input);
|
|
3236
3245
|
},
|
|
3237
3246
|
submit: async (attemptId, input) => {
|
|
@@ -4549,7 +4558,7 @@ async function request({
|
|
|
4549
4558
|
return rawText && rawText.length > 0 ? rawText : undefined;
|
|
4550
4559
|
}
|
|
4551
4560
|
// src/version.ts
|
|
4552
|
-
var SDK_VERSION = "0.16.1-beta.
|
|
4561
|
+
var SDK_VERSION = "0.16.1-beta.23";
|
|
4553
4562
|
|
|
4554
4563
|
// src/clients/base.ts
|
|
4555
4564
|
class PlaycademyBaseClient {
|
package/dist/server/edge.js
CHANGED
package/dist/server.js
CHANGED
package/dist/types.d.ts
CHANGED
|
@@ -2,7 +2,7 @@ import * as _playcademy_types from '@playcademy/types';
|
|
|
2
2
|
import { GameManifest, LocalDayContext } from '@playcademy/types';
|
|
3
3
|
export { AuthenticatedUser, DeveloperStatusEnumType, DeveloperStatusResponse, DeveloperStatusValue, GameCourseMetrics, GameLeaderboardEntry, GameManifest, GameMetricComparisonKind, GameMetricComparisonMetric, GameMetricComparisonRow, GameMetricComparisonRowStatus, GameMetricsProxyResponse, GameMetricsResponse, GameMetricsUnsupportedReason, GamePlatform, GameRunMetrics, GameRunMetricsComparison, GameRunMetricsComparisonStatus, GameRunMetricsComparisonSummary, GameTimebackIntegration, GameType, GameUser, LeaderboardEntry, LeaderboardOptions, LeaderboardTimeframe, LocalDayContext, LocalDaySource, ManifestV1, ManifestV2, ManifestVersions, PopulateStudentResponse, UserEnrollment, UserInfo, UserOrganization, UserRank, UserRankResponse, UserRoleEnumType, UserScore, UserTimebackData } from '@playcademy/types';
|
|
4
4
|
import { TimebackCourseConfig, CourseConfig, OrganizationConfig, ComponentConfig, ResourceConfig, ComponentResourceConfig, TimebackGrade, TimebackSubject, ELevel, EndActivityRequest, HeartbeatRequest, EndActivityScoreData, EndActivityResponse } from '@playcademy/types/timeback';
|
|
5
|
-
export { AssessmentAttemptSnapshot, AssessmentFlow, AssessmentItemSubmission, AssessmentResponseUpdate, AssessmentResponseValue, AssessmentResponses, AssessmentSaveResult, AssessmentScore, AssessmentStandardRef, AssessmentSubmitResult, ELevel, PlayableAssessment, PlayableAssessmentChoice, PlayableAssessmentGraphic, PlayableAssessmentHotspot, PlayableAssessmentInteraction, PlayableAssessmentItem, PlayableContentNode, SaveAssessmentInput, StartAssessmentInput, SubmitAssessmentInput, SubmitAssessmentItemInput, SubmitAssessmentItemResult } from '@playcademy/types/timeback';
|
|
5
|
+
export { AssessmentAttemptSnapshot, AssessmentFlow, AssessmentItemSubmission, AssessmentResponseUpdate, AssessmentResponseValue, AssessmentResponses, AssessmentSaveResult, AssessmentScore, AssessmentStandardRef, AssessmentSubmitResult, ConventionalAssessmentAttemptSnapshot, ConventionalAssessmentSubmitResult, DiagnosticAssessmentItemReceipt, DiagnosticAssessmentSubmitResult, DiagnosticRoutingSnapshot, DiagnosticRoutingTrackSnapshot, ELevel, PlatformRoutedDiagnosticAttemptSnapshot, PlatformRoutedDiagnosticSelectionContext, PlayableAssessment, PlayableAssessmentChoice, PlayableAssessmentGraphic, PlayableAssessmentHotspot, PlayableAssessmentInteraction, PlayableAssessmentItem, PlayableContentNode, SaveAssessmentInput, StartAssessmentInput, StartDiagnosticAssessmentInput, SubmitAssessmentInput, SubmitAssessmentItemInput, SubmitAssessmentItemResult, SubmitDiagnosticAssessmentItemInput, SubmitDiagnosticAssessmentItemResult } from '@playcademy/types/timeback';
|
|
6
6
|
import { TimebackUserRole, UserEnrollment, UserOrganization, UserInfo } from '@playcademy/types/user';
|
|
7
7
|
import { GamePermission, AUTH_PROVIDER_IDS } from '@playcademy/constants';
|
|
8
8
|
import * as drizzle_orm_pg_core from 'drizzle-orm/pg-core';
|