@playcademy/vite-plugin 1.2.1-beta.17 → 1.2.1-beta.19
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.js +100 -70
- package/package.json +4 -4
package/dist/index.js
CHANGED
|
@@ -24315,7 +24315,7 @@ import path2 from "node:path";
|
|
|
24315
24315
|
// package.json
|
|
24316
24316
|
var package_default = {
|
|
24317
24317
|
name: "@playcademy/vite-plugin",
|
|
24318
|
-
version: "1.2.1-beta.
|
|
24318
|
+
version: "1.2.1-beta.19",
|
|
24319
24319
|
type: "module",
|
|
24320
24320
|
exports: {
|
|
24321
24321
|
".": {
|
|
@@ -25076,7 +25076,7 @@ var init_timeback2 = __esm(() => {
|
|
|
25076
25076
|
ASSESSMENT_PURPOSES = ["end_of_course", "diagnostic", "review", "mastery"];
|
|
25077
25077
|
TIMEBACK_ASSESSMENT_REVIEW_REQUEST_LIMITS = {
|
|
25078
25078
|
standards: 20,
|
|
25079
|
-
|
|
25079
|
+
candidateItemsPerStandard: 2,
|
|
25080
25080
|
standardFieldLength: 128
|
|
25081
25081
|
};
|
|
25082
25082
|
TIMEBACK_COURSE_DEFAULTS = {
|
|
@@ -25921,7 +25921,7 @@ var package_default2;
|
|
|
25921
25921
|
var init_package = __esm(() => {
|
|
25922
25922
|
package_default2 = {
|
|
25923
25923
|
name: "@playcademy/sandbox",
|
|
25924
|
-
version: "0.7.1-beta.
|
|
25924
|
+
version: "0.7.1-beta.18",
|
|
25925
25925
|
description: "Local development server for Playcademy game development",
|
|
25926
25926
|
type: "module",
|
|
25927
25927
|
exports: {
|
|
@@ -34412,7 +34412,7 @@ function assessmentReviewBankShortage(fulfillment) {
|
|
|
34412
34412
|
};
|
|
34413
34413
|
}
|
|
34414
34414
|
function assessmentFlowForPurpose(purpose) {
|
|
34415
|
-
return purpose === "review"
|
|
34415
|
+
return purpose === "review" ? "item-submit" : "attempt-submit";
|
|
34416
34416
|
}
|
|
34417
34417
|
function isObject(value) {
|
|
34418
34418
|
return typeof value === "object" && value !== null;
|
|
@@ -34614,6 +34614,12 @@ function interactionResponseValidationMessage(itemIdentifier, interaction, respo
|
|
|
34614
34614
|
function invalidResponse(message) {
|
|
34615
34615
|
return { code: "INVALID_RESPONSE", message };
|
|
34616
34616
|
}
|
|
34617
|
+
function administeredItemIdentifiers(itemSubmissions) {
|
|
34618
|
+
return new Set(itemSubmissions.map((submission) => submission.itemIdentifier));
|
|
34619
|
+
}
|
|
34620
|
+
function itemAdministration(itemSubmissions, itemIdentifier) {
|
|
34621
|
+
return itemSubmissions.find((submission) => submission.itemIdentifier === itemIdentifier);
|
|
34622
|
+
}
|
|
34617
34623
|
function responseValuesEqual(left, right) {
|
|
34618
34624
|
if (left === undefined || right === undefined) {
|
|
34619
34625
|
return left === right;
|
|
@@ -34664,15 +34670,15 @@ function prepareAssessmentItemSubmission(state, input) {
|
|
|
34664
34670
|
failure: assessmentResponseVersionConflict(input.expectedResponseVersion, state.responseVersion)
|
|
34665
34671
|
};
|
|
34666
34672
|
}
|
|
34667
|
-
const
|
|
34668
|
-
const
|
|
34669
|
-
const
|
|
34670
|
-
if (
|
|
34673
|
+
const itemIndex = state.assessment.items.findIndex((item) => item.identifier === input.itemIdentifier);
|
|
34674
|
+
const previousItemIdentifier = state.itemSubmissions.at(-1)?.itemIdentifier;
|
|
34675
|
+
const previousItemIndex = state.assessment.items.findIndex((item) => item.identifier === previousItemIdentifier);
|
|
34676
|
+
if (itemIndex === -1 || itemIndex <= previousItemIndex) {
|
|
34671
34677
|
return {
|
|
34672
34678
|
action: "reject",
|
|
34673
|
-
failure: assessmentFlowViolation("Items must be submitted once and in
|
|
34679
|
+
failure: assessmentFlowViolation("Items must be submitted once and in candidate order.", {
|
|
34674
34680
|
itemIdentifier: input.itemIdentifier,
|
|
34675
|
-
|
|
34681
|
+
previousItemIdentifier: previousItemIdentifier ?? null,
|
|
34676
34682
|
flow
|
|
34677
34683
|
})
|
|
34678
34684
|
};
|
|
@@ -34695,10 +34701,11 @@ function prepareAssessmentItemSubmission(state, input) {
|
|
|
34695
34701
|
answered: Object.keys(responses[input.itemIdentifier] ?? {}).length > 0
|
|
34696
34702
|
};
|
|
34697
34703
|
}
|
|
34698
|
-
function completeAssessmentItemSubmission(state, input, prepared, scoring) {
|
|
34704
|
+
function completeAssessmentItemSubmission(state, input, prepared, scoring, submittedAt) {
|
|
34699
34705
|
const submission = {
|
|
34700
34706
|
submissionId: input.submissionId,
|
|
34701
34707
|
itemIdentifier: input.itemIdentifier,
|
|
34708
|
+
submittedAt,
|
|
34702
34709
|
responseVersion: prepared.responseVersion,
|
|
34703
34710
|
answered: prepared.answered,
|
|
34704
34711
|
score: scoring.score,
|
|
@@ -34712,8 +34719,8 @@ function completeAssessmentItemSubmission(state, input, prepared, scoring) {
|
|
|
34712
34719
|
};
|
|
34713
34720
|
}
|
|
34714
34721
|
function assessmentResponseUpdateFlowFailure(purpose, itemSubmissions, update) {
|
|
34715
|
-
const
|
|
34716
|
-
const committedUpdate = Object.keys(update).find((identifier) =>
|
|
34722
|
+
const administered = administeredItemIdentifiers(itemSubmissions);
|
|
34723
|
+
const committedUpdate = Object.keys(update).find((identifier) => administered.has(identifier));
|
|
34717
34724
|
return committedUpdate ? assessmentFlowViolation("A submitted item response cannot be edited.", {
|
|
34718
34725
|
itemIdentifier: committedUpdate,
|
|
34719
34726
|
flow: assessmentFlowForPurpose(purpose)
|
|
@@ -34721,11 +34728,17 @@ function assessmentResponseUpdateFlowFailure(purpose, itemSubmissions, update) {
|
|
|
34721
34728
|
}
|
|
34722
34729
|
function assessmentCompletionFlowFailure(purpose, itemSubmissions, itemCount) {
|
|
34723
34730
|
const flow = assessmentFlowForPurpose(purpose);
|
|
34724
|
-
|
|
34731
|
+
if (flow !== "item-submit") {
|
|
34732
|
+
return null;
|
|
34733
|
+
}
|
|
34734
|
+
if (itemSubmissions.length > 0 && itemSubmissions.length <= itemCount) {
|
|
34735
|
+
return null;
|
|
34736
|
+
}
|
|
34737
|
+
return assessmentFlowViolation("At least one candidate must be administered before the review can be completed.", {
|
|
34725
34738
|
flow,
|
|
34726
34739
|
submittedItemCount: itemSubmissions.length,
|
|
34727
34740
|
itemCount
|
|
34728
|
-
})
|
|
34741
|
+
});
|
|
34729
34742
|
}
|
|
34730
34743
|
function selectAssessmentCourseCandidate(candidates, subjectSpecified) {
|
|
34731
34744
|
if (candidates.length === 0) {
|
|
@@ -34901,15 +34914,15 @@ function canonicalRequestStandards(standards) {
|
|
|
34901
34914
|
return [...canonical.values()].toSorted((left, right) => compareCodeUnits(assessmentStandardRefKey(left), assessmentStandardRefKey(right)));
|
|
34902
34915
|
}
|
|
34903
34916
|
function normalizeReviewRequest(request) {
|
|
34904
|
-
const
|
|
34905
|
-
if (!Number.isInteger(
|
|
34906
|
-
throw new RangeError(`
|
|
34917
|
+
const candidateItemsPerStandard = request.candidateItemsPerStandard ?? 1;
|
|
34918
|
+
if (!Number.isInteger(candidateItemsPerStandard) || candidateItemsPerStandard <= 0 || candidateItemsPerStandard > TIMEBACK_ASSESSMENT_REVIEW_REQUEST_LIMITS.candidateItemsPerStandard) {
|
|
34919
|
+
throw new RangeError(`candidateItemsPerStandard must be a positive integer at most ${TIMEBACK_ASSESSMENT_REVIEW_REQUEST_LIMITS.candidateItemsPerStandard}`);
|
|
34907
34920
|
}
|
|
34908
34921
|
const standards = canonicalRequestStandards(request.standards);
|
|
34909
34922
|
if (standards.length === 0) {
|
|
34910
34923
|
throw new Error("At least one review standard is required");
|
|
34911
34924
|
}
|
|
34912
|
-
return { standards,
|
|
34925
|
+
return { standards, candidateItemsPerStandard };
|
|
34913
34926
|
}
|
|
34914
34927
|
function reviewRequestFingerprint(request, policy) {
|
|
34915
34928
|
const normalized = normalizeReviewRequest(request);
|
|
@@ -34918,7 +34931,7 @@ function reviewRequestFingerprint(request, policy) {
|
|
|
34918
34931
|
policy: {
|
|
34919
34932
|
version: policy.version
|
|
34920
34933
|
},
|
|
34921
|
-
|
|
34934
|
+
candidateItemsPerStandard: normalized.candidateItemsPerStandard,
|
|
34922
34935
|
standardKeys: normalized.standards.map(assessmentStandardRefKey)
|
|
34923
34936
|
});
|
|
34924
34937
|
}
|
|
@@ -35018,7 +35031,7 @@ function rankedCandidatesByStandard(bank, exposures) {
|
|
|
35018
35031
|
return byStandard;
|
|
35019
35032
|
}
|
|
35020
35033
|
function reviewSlots(request) {
|
|
35021
|
-
return request.standards.flatMap((standard) => Array.from({ length: request.
|
|
35034
|
+
return request.standards.flatMap((standard) => Array.from({ length: request.candidateItemsPerStandard }, () => ({
|
|
35022
35035
|
standard,
|
|
35023
35036
|
standardKey: assessmentStandardRefKey(standard)
|
|
35024
35037
|
})));
|
|
@@ -35122,7 +35135,7 @@ function preferredDistinctMatching(slots, candidatesByStandard) {
|
|
|
35122
35135
|
return new Map(slotItemEdges.filter((candidate) => candidate.edge.capacity === 0).map((candidate) => [candidate.slotIndex, candidate.itemIdentifier]));
|
|
35123
35136
|
}
|
|
35124
35137
|
function fulfillment(request, candidatesByStandard, selections) {
|
|
35125
|
-
const requestedItemCount = request.standards.length * request.
|
|
35138
|
+
const requestedItemCount = request.standards.length * request.candidateItemsPerStandard;
|
|
35126
35139
|
const selectedByStandard = new Map;
|
|
35127
35140
|
for (const selection of selections) {
|
|
35128
35141
|
const key = assessmentStandardRefKey(selection.standard);
|
|
@@ -35131,10 +35144,10 @@ function fulfillment(request, candidatesByStandard, selections) {
|
|
|
35131
35144
|
const shortages = request.standards.flatMap((standard) => {
|
|
35132
35145
|
const key = assessmentStandardRefKey(standard);
|
|
35133
35146
|
const selected = selectedByStandard.get(key) ?? 0;
|
|
35134
|
-
return selected < request.
|
|
35147
|
+
return selected < request.candidateItemsPerStandard ? [
|
|
35135
35148
|
{
|
|
35136
35149
|
standard,
|
|
35137
|
-
requested: request.
|
|
35150
|
+
requested: request.candidateItemsPerStandard,
|
|
35138
35151
|
selected,
|
|
35139
35152
|
eligible: candidatesByStandard.get(key)?.length ?? 0
|
|
35140
35153
|
}
|
|
@@ -35176,9 +35189,9 @@ function projectReviewAssessment(assessment, bank, selections) {
|
|
|
35176
35189
|
throw new Error(`Review bank ${bank.bankRevision} was built from content revision ${bank.sourceContentRevision}, not ${assessment.contentRevision}`);
|
|
35177
35190
|
}
|
|
35178
35191
|
const selectedIdentifiers = new Set(selections.map((selection) => selection.itemIdentifier));
|
|
35179
|
-
const
|
|
35192
|
+
const itemByIdentifier = new Map(assessment.items.map((item) => [item.identifier, item]));
|
|
35180
35193
|
const indexedItems = new Map(bank.items.map((item) => [item.itemIdentifier, item]));
|
|
35181
|
-
const missingIdentifiers = [...selectedIdentifiers].filter((identifier) => !
|
|
35194
|
+
const missingIdentifiers = [...selectedIdentifiers].filter((identifier) => !itemByIdentifier.has(identifier) || !indexedItems.has(identifier));
|
|
35182
35195
|
if (missingIdentifiers.length > 0) {
|
|
35183
35196
|
throw new Error(`Selected review items are absent from the pinned bank: ${missingIdentifiers.join(", ")}`);
|
|
35184
35197
|
}
|
|
@@ -35194,7 +35207,7 @@ function projectReviewAssessment(assessment, bank, selections) {
|
|
|
35194
35207
|
return structuredClone({
|
|
35195
35208
|
...assessment,
|
|
35196
35209
|
contentRevision: bank.bankRevision,
|
|
35197
|
-
items:
|
|
35210
|
+
items: selections.map((selection) => itemByIdentifier.get(selection.itemIdentifier))
|
|
35198
35211
|
});
|
|
35199
35212
|
}
|
|
35200
35213
|
function assessmentItemCorrectness(verdicts) {
|
|
@@ -35253,10 +35266,10 @@ function isReviewItemOutcome(value) {
|
|
|
35253
35266
|
return isRecord(value) && typeof value.itemIdentifier === "string" && value.itemIdentifier.length > 0 && isAssessmentStandardRef(value.standard) && typeof value.answered === "boolean" && isAssessmentScore(value.score) && (value.isCorrect === null || typeof value.isCorrect === "boolean");
|
|
35254
35267
|
}
|
|
35255
35268
|
function isAssessmentItemSubmission(value) {
|
|
35256
|
-
return isRecord(value) && typeof value.submissionId === "string" && value.submissionId.length > 0 && typeof value.itemIdentifier === "string" && value.itemIdentifier.length > 0 && Number.isInteger(value.responseVersion) && typeof value.answered === "boolean" && isAssessmentScore(value.score) && (value.isCorrect === null || typeof value.isCorrect === "boolean");
|
|
35269
|
+
return isRecord(value) && typeof value.submissionId === "string" && value.submissionId.length > 0 && typeof value.itemIdentifier === "string" && value.itemIdentifier.length > 0 && typeof value.submittedAt === "string" && Number.isInteger(value.responseVersion) && typeof value.answered === "boolean" && isAssessmentScore(value.score) && (value.isCorrect === null || typeof value.isCorrect === "boolean");
|
|
35257
35270
|
}
|
|
35258
35271
|
function isReviewAttemptMetadata(value) {
|
|
35259
|
-
return isRecord(value) && typeof value.requestFingerprint === "string" && typeof value.bankRevision === "string" && Array.isArray(value.standards) && value.standards.every(isAssessmentStandardRef) && Number.isInteger(value.
|
|
35272
|
+
return isRecord(value) && typeof value.requestFingerprint === "string" && typeof value.bankRevision === "string" && Array.isArray(value.standards) && value.standards.every(isAssessmentStandardRef) && Number.isInteger(value.candidateItemsPerStandard) && Array.isArray(value.selections) && value.selections.every((selection) => isRecord(selection) && isAssessmentStandardRef(selection.standard) && typeof selection.itemIdentifier === "string") && isReviewFulfillment(value.fulfillment);
|
|
35260
35273
|
}
|
|
35261
35274
|
function isMasteryAttemptMetadata(value) {
|
|
35262
35275
|
return isRecord(value) && typeof value.requestFingerprint === "string" && isAssessmentStandardRef(value.standard);
|
|
@@ -35626,7 +35639,7 @@ var init_assessment_runtime = __esm(() => {
|
|
|
35626
35639
|
StartAssessmentBaseSchema.extend({
|
|
35627
35640
|
purpose: exports_external.literal("review"),
|
|
35628
35641
|
standards: exports_external.array(AssessmentStandardRefSchema).min(1).max(TIMEBACK_ASSESSMENT_REVIEW_REQUEST_LIMITS.standards),
|
|
35629
|
-
|
|
35642
|
+
candidateItemsPerStandard: exports_external.number().int().positive().max(TIMEBACK_ASSESSMENT_REVIEW_REQUEST_LIMITS.candidateItemsPerStandard).optional()
|
|
35630
35643
|
}),
|
|
35631
35644
|
StartAssessmentBaseSchema.extend({
|
|
35632
35645
|
purpose: exports_external.literal("mastery"),
|
|
@@ -116804,6 +116817,10 @@ var init_timeback4 = __esm(() => {
|
|
|
116804
116817
|
init_assessment_runtime2();
|
|
116805
116818
|
});
|
|
116806
116819
|
function buildReviewItemResultMetadata(input) {
|
|
116820
|
+
const administration = itemAdministration(input.metadata.itemSubmissions, input.selection.itemIdentifier);
|
|
116821
|
+
if (!administration) {
|
|
116822
|
+
throw new Error(`Cannot create a review result for unadministered candidate ${input.selection.itemIdentifier}`);
|
|
116823
|
+
}
|
|
116807
116824
|
return {
|
|
116808
116825
|
version: PLAYCADEMY_ASSESSMENT_ITEM_RESULT_METADATA_VERSION,
|
|
116809
116826
|
parentAttemptId: input.parentAttemptId,
|
|
@@ -116813,7 +116830,7 @@ function buildReviewItemResultMetadata(input) {
|
|
|
116813
116830
|
bankRevision: input.metadata.review.bankRevision,
|
|
116814
116831
|
itemIdentifier: input.selection.itemIdentifier,
|
|
116815
116832
|
standard: input.selection.standard,
|
|
116816
|
-
deliveredAt:
|
|
116833
|
+
deliveredAt: administration.submittedAt,
|
|
116817
116834
|
responseVersion: input.responseVersion ?? input.metadata.responseVersion,
|
|
116818
116835
|
responses: input.metadata.responses[input.selection.itemIdentifier] ?? {},
|
|
116819
116836
|
...input.submissionId ? { submissionId: input.submissionId } : {},
|
|
@@ -116868,7 +116885,8 @@ function resolveReviewChildResult(input) {
|
|
|
116868
116885
|
}
|
|
116869
116886
|
const childMetadata = playcademyAssessmentItemResultMetadata(input.childResult.metadata);
|
|
116870
116887
|
const expectedResponses = input.parentMetadata.responses[input.selection.itemIdentifier] ?? {};
|
|
116871
|
-
|
|
116888
|
+
const administration = itemAdministration(input.parentMetadata.itemSubmissions, input.selection.itemIdentifier);
|
|
116889
|
+
if (input.childResult.assessmentLineItem.sourcedId !== input.childLineItemId || input.childResult.student.sourcedId !== input.parentResult.student.sourcedId || !childMetadata || childMetadata.parentAttemptId !== input.parentResult.sourcedId || childMetadata.activityId !== input.parentMetadata.activityId || childMetadata.integrationId !== input.parentMetadata.integrationId || childMetadata.enrollmentId !== input.parentMetadata.enrollmentId || childMetadata.bankRevision !== input.parentMetadata.review.bankRevision || childMetadata.itemIdentifier !== input.selection.itemIdentifier || childMetadata.standard.framework !== input.selection.standard.framework || childMetadata.standard.identifier !== input.selection.standard.identifier || childMetadata.deliveredAt !== administration?.submittedAt || childMetadata.responseVersion > input.parentMetadata.responseVersion || canonicalJson(childMetadata.responses) !== canonicalJson(expectedResponses)) {
|
|
116872
116890
|
return { action: "restore", reason: "incompatible" };
|
|
116873
116891
|
}
|
|
116874
116892
|
return input.childResult.status === "active" ? { action: "reuse", metadata: childMetadata } : { action: "restore", reason: "inactive" };
|
|
@@ -117556,7 +117574,7 @@ class TimebackAssessmentRuntimeService {
|
|
|
117556
117574
|
requestFingerprint,
|
|
117557
117575
|
bankRevision: source.bank.bankRevision,
|
|
117558
117576
|
standards: [...normalizedRequest.standards],
|
|
117559
|
-
|
|
117577
|
+
candidateItemsPerStandard: normalizedRequest.candidateItemsPerStandard,
|
|
117560
117578
|
selections: [...selected.selections],
|
|
117561
117579
|
fulfillment: selected.fulfillment
|
|
117562
117580
|
}
|
|
@@ -117688,9 +117706,6 @@ class TimebackAssessmentRuntimeService {
|
|
|
117688
117706
|
updatedAt: new Date().toISOString()
|
|
117689
117707
|
};
|
|
117690
117708
|
await this.putResultMetadata(attempt.result, metadata2);
|
|
117691
|
-
if (metadata2.purpose === "review") {
|
|
117692
|
-
await this.putReviewChildResponses(attempt.result, metadata2, new Set(Object.keys(input.responses)));
|
|
117693
|
-
}
|
|
117694
117709
|
return {
|
|
117695
117710
|
attemptId: attempt.result.sourcedId,
|
|
117696
117711
|
responseVersion: metadata2.responseVersion,
|
|
@@ -117758,13 +117773,14 @@ class TimebackAssessmentRuntimeService {
|
|
|
117758
117773
|
if (!preview.scoring) {
|
|
117759
117774
|
throw new Error("Prepared item submission is missing its score");
|
|
117760
117775
|
}
|
|
117761
|
-
const
|
|
117776
|
+
const submittedAt = new Date().toISOString();
|
|
117777
|
+
const completed = completeAssessmentItemSubmission(attempt.metadata, input, transition, preview.scoring, submittedAt);
|
|
117762
117778
|
const metadata2 = {
|
|
117763
117779
|
...attempt.metadata,
|
|
117764
117780
|
responses: completed.responses,
|
|
117765
117781
|
responseVersion: completed.responseVersion,
|
|
117766
117782
|
itemSubmissions: completed.itemSubmissions,
|
|
117767
|
-
updatedAt:
|
|
117783
|
+
updatedAt: submittedAt
|
|
117768
117784
|
};
|
|
117769
117785
|
await this.putResultMetadata(attempt.result, metadata2);
|
|
117770
117786
|
return {
|
|
@@ -117869,12 +117885,13 @@ class TimebackAssessmentRuntimeService {
|
|
|
117869
117885
|
async scoreSubmission(attempt) {
|
|
117870
117886
|
const assessment = await this.loadAttemptAssessment(attempt.metadata);
|
|
117871
117887
|
validateAssessmentResponses(assessment, attempt.metadata.responses);
|
|
117872
|
-
const
|
|
117888
|
+
const administeredItems = attempt.metadata.purpose === "review" ? administeredItemIdentifiers(attempt.metadata.itemSubmissions) : undefined;
|
|
117889
|
+
const itemResults = await this.scoreItems(assessment, attempt.metadata.responses, administeredItems);
|
|
117873
117890
|
return {
|
|
117874
117891
|
responseVersion: attempt.metadata.responseVersion,
|
|
117875
117892
|
assessment,
|
|
117876
117893
|
itemResults,
|
|
117877
|
-
score: aggregateAssessmentScore(itemResults.map((result) => result.score.earned),
|
|
117894
|
+
score: aggregateAssessmentScore(itemResults.map((result) => result.score.earned), itemResults.reduce((total, result) => total + result.score.possible, 0)),
|
|
117878
117895
|
correctQuestions: countCorrectQuestions(itemResults.map((result) => result.isCorrect))
|
|
117879
117896
|
};
|
|
117880
117897
|
}
|
|
@@ -117967,7 +117984,7 @@ class TimebackAssessmentRuntimeService {
|
|
|
117967
117984
|
submissionId: input.submissionId,
|
|
117968
117985
|
timestamp: timestamp6,
|
|
117969
117986
|
testName: assessment.title,
|
|
117970
|
-
totalQuestions:
|
|
117987
|
+
totalQuestions: itemResults.length,
|
|
117971
117988
|
correctQuestions,
|
|
117972
117989
|
...input.session ? { session: input.session } : {},
|
|
117973
117990
|
...reviewOutcomes ? { itemOutcomes: reviewOutcomes } : {}
|
|
@@ -117998,7 +118015,7 @@ class TimebackAssessmentRuntimeService {
|
|
|
117998
118015
|
testIdentifier: assessment.identifier,
|
|
117999
118016
|
testName: assessment.title,
|
|
118000
118017
|
score,
|
|
118001
|
-
totalQuestions:
|
|
118018
|
+
totalQuestions: itemResults.length,
|
|
118002
118019
|
correctQuestions,
|
|
118003
118020
|
submissionId: input.submissionId,
|
|
118004
118021
|
gameId: params.gameId,
|
|
@@ -118542,11 +118559,21 @@ class TimebackAssessmentRuntimeService {
|
|
|
118542
118559
|
if (physicalItems.size !== input.metadata.review.selections.length) {
|
|
118543
118560
|
throw new Error("MVP review selection must use each physical item at most once");
|
|
118544
118561
|
}
|
|
118562
|
+
const administeredItems = administeredItemIdentifiers(input.metadata.itemSubmissions);
|
|
118545
118563
|
await runWithConcurrency(input.metadata.review.selections, TimebackAssessmentRuntimeService.SCORING_CONCURRENCY, async (selection) => {
|
|
118546
118564
|
const item = itemByIdentifier.get(selection.itemIdentifier);
|
|
118547
118565
|
if (!item) {
|
|
118548
118566
|
throw new Error(`Review assessment is missing selected item ${selection.itemIdentifier}`);
|
|
118549
118567
|
}
|
|
118568
|
+
if (!administeredItems.has(selection.itemIdentifier)) {
|
|
118569
|
+
await this.ensureReviewQuestionLineItem({
|
|
118570
|
+
parentLineItemId: input.result.assessmentLineItem.sourcedId,
|
|
118571
|
+
integration: input.integration,
|
|
118572
|
+
bank: input.source.bank,
|
|
118573
|
+
item
|
|
118574
|
+
});
|
|
118575
|
+
return;
|
|
118576
|
+
}
|
|
118550
118577
|
const childLineItemId = await reviewQuestionLineItemId(input.result.assessmentLineItem.sourcedId, item.identifier);
|
|
118551
118578
|
const childResultId = await reviewQuestionResultId(input.result.sourcedId, childLineItemId);
|
|
118552
118579
|
const streamedChildResult = input.existingChildResults.get(childResultId);
|
|
@@ -118593,33 +118620,35 @@ class TimebackAssessmentRuntimeService {
|
|
|
118593
118620
|
});
|
|
118594
118621
|
});
|
|
118595
118622
|
}
|
|
118596
|
-
async
|
|
118597
|
-
|
|
118598
|
-
|
|
118599
|
-
|
|
118600
|
-
|
|
118601
|
-
|
|
118602
|
-
|
|
118603
|
-
|
|
118604
|
-
|
|
118605
|
-
|
|
118606
|
-
|
|
118607
|
-
|
|
118608
|
-
|
|
118609
|
-
|
|
118610
|
-
|
|
118611
|
-
|
|
118612
|
-
|
|
118613
|
-
|
|
118614
|
-
|
|
118615
|
-
|
|
118616
|
-
|
|
118617
|
-
|
|
118618
|
-
|
|
118619
|
-
|
|
118623
|
+
async putReviewChildResponse(result, metadata2, itemIdentifier) {
|
|
118624
|
+
const selection = metadata2.review.selections.find((candidate) => candidate.itemIdentifier === itemIdentifier);
|
|
118625
|
+
if (!selection) {
|
|
118626
|
+
return;
|
|
118627
|
+
}
|
|
118628
|
+
try {
|
|
118629
|
+
const childLineItemId = await reviewQuestionLineItemId(result.assessmentLineItem.sourcedId, selection.itemIdentifier);
|
|
118630
|
+
const childResultId = await reviewQuestionResultId(result.sourcedId, childLineItemId);
|
|
118631
|
+
const childMetadata = buildReviewItemResultMetadata({
|
|
118632
|
+
metadata: metadata2,
|
|
118633
|
+
selection,
|
|
118634
|
+
parentAttemptId: result.sourcedId
|
|
118635
|
+
});
|
|
118636
|
+
await this.requireClient().api.oneroster.assessmentResults.upsert(childResultId, buildOpenReviewChildResult({
|
|
118637
|
+
childLineItemId,
|
|
118638
|
+
student: result.student,
|
|
118639
|
+
metadata: childMetadata
|
|
118640
|
+
}));
|
|
118641
|
+
} catch (error88) {
|
|
118642
|
+
addEvent("assessment.review_child_response_projection_failed", {
|
|
118643
|
+
"app.assessment.attempt_id": result.sourcedId,
|
|
118644
|
+
"app.assessment.qti_item_identifier": selection.itemIdentifier,
|
|
118645
|
+
"exception.type": errorType(error88),
|
|
118646
|
+
"app.error.message": errorMessage2(error88)
|
|
118647
|
+
});
|
|
118648
|
+
}
|
|
118620
118649
|
}
|
|
118621
118650
|
async projectReviewItemResponse(params, projection) {
|
|
118622
|
-
await this.
|
|
118651
|
+
await this.putReviewChildResponse(projection.result, projection.metadata, projection.itemIdentifier);
|
|
118623
118652
|
try {
|
|
118624
118653
|
await this.crossAttemptLockBarrier(params.attemptId);
|
|
118625
118654
|
const latest = await this.peekAttempt(params);
|
|
@@ -118698,7 +118727,8 @@ class TimebackAssessmentRuntimeService {
|
|
|
118698
118727
|
}
|
|
118699
118728
|
async finalizeReviewChildResults(input) {
|
|
118700
118729
|
const resultByItem = new Map(input.itemResults.map((itemResult) => [itemResult.itemIdentifier, itemResult]));
|
|
118701
|
-
|
|
118730
|
+
const administeredItems = administeredItemIdentifiers(input.metadata.itemSubmissions);
|
|
118731
|
+
return runWithConcurrency(input.metadata.review.selections.filter((selection) => administeredItems.has(selection.itemIdentifier)), TimebackAssessmentRuntimeService.SCORING_CONCURRENCY, async (selection) => {
|
|
118702
118732
|
const itemResult = resultByItem.get(selection.itemIdentifier);
|
|
118703
118733
|
if (!itemResult) {
|
|
118704
118734
|
throw new Error(`Scoring omitted selected review item ${selection.itemIdentifier}`);
|
|
@@ -118814,7 +118844,7 @@ class TimebackAssessmentRuntimeService {
|
|
|
118814
118844
|
kind: "standards-review",
|
|
118815
118845
|
purpose: metadata2.purpose,
|
|
118816
118846
|
standards: [...metadata2.review.standards],
|
|
118817
|
-
|
|
118847
|
+
candidateItemsPerStandard: metadata2.review.candidateItemsPerStandard,
|
|
118818
118848
|
selections: [...metadata2.review.selections],
|
|
118819
118849
|
fulfillment: metadata2.review.fulfillment
|
|
118820
118850
|
};
|
|
@@ -185960,7 +185990,7 @@ var init_timeback9 = __esm3(() => {
|
|
|
185960
185990
|
ASSESSMENT_PURPOSES2 = ["end_of_course", "diagnostic", "review", "mastery"];
|
|
185961
185991
|
TIMEBACK_ASSESSMENT_REVIEW_REQUEST_LIMITS2 = {
|
|
185962
185992
|
standards: 20,
|
|
185963
|
-
|
|
185993
|
+
candidateItemsPerStandard: 2,
|
|
185964
185994
|
standardFieldLength: 128
|
|
185965
185995
|
};
|
|
185966
185996
|
TIMEBACK_COURSE_DEFAULTS2 = {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@playcademy/vite-plugin",
|
|
3
|
-
"version": "1.2.1-beta.
|
|
3
|
+
"version": "1.2.1-beta.19",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"exports": {
|
|
6
6
|
".": {
|
|
@@ -19,14 +19,14 @@
|
|
|
19
19
|
"dependencies": {
|
|
20
20
|
"archiver": "^7.0.1",
|
|
21
21
|
"picocolors": "^1.1.1",
|
|
22
|
-
"playcademy": "0.28.1-beta.
|
|
22
|
+
"playcademy": "0.28.1-beta.19"
|
|
23
23
|
},
|
|
24
24
|
"devDependencies": {
|
|
25
25
|
"@electric-sql/pglite": "^0.3.16",
|
|
26
26
|
"@inquirer/prompts": "^7.8.6",
|
|
27
27
|
"@playcademy/constants": "0.0.1",
|
|
28
|
-
"@playcademy/sandbox": "0.7.1-beta.
|
|
29
|
-
"@playcademy/sdk": "0.16.1-beta.
|
|
28
|
+
"@playcademy/sandbox": "0.7.1-beta.18",
|
|
29
|
+
"@playcademy/sdk": "0.16.1-beta.18",
|
|
30
30
|
"@playcademy/types": "0.0.1",
|
|
31
31
|
"@playcademy/utils": "0.0.1",
|
|
32
32
|
"@types/archiver": "^6.0.3",
|