@playcademy/sandbox 0.10.0 → 0.10.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.
Files changed (3) hide show
  1. package/dist/cli.js +36 -28
  2. package/dist/server.js +36 -28
  3. package/package.json +1 -1
package/dist/cli.js CHANGED
@@ -1128,7 +1128,7 @@ var package_default;
1128
1128
  var init_package = __esm(() => {
1129
1129
  package_default = {
1130
1130
  name: "@playcademy/sandbox",
1131
- version: "0.10.0",
1131
+ version: "0.10.1-beta.1",
1132
1132
  description: "Local development server for Playcademy game development",
1133
1133
  type: "module",
1134
1134
  exports: {
@@ -9562,6 +9562,21 @@ function assessmentReviewBankShortage(fulfillment) {
9562
9562
  function assessmentFlowForPurpose(purpose) {
9563
9563
  return purpose === "review" ? "item-submit" : "attempt-submit";
9564
9564
  }
9565
+ function assessmentItemOutcomes(submissions, standardForItem) {
9566
+ return submissions.map((submission) => {
9567
+ const standard = standardForItem(submission.itemIdentifier);
9568
+ if (!standard) {
9569
+ throw new Error(`Missing outcome standard for item ${submission.itemIdentifier}`);
9570
+ }
9571
+ return {
9572
+ itemIdentifier: submission.itemIdentifier,
9573
+ standard: { ...standard },
9574
+ answered: submission.answered,
9575
+ score: { ...submission.score },
9576
+ isCorrect: submission.isCorrect
9577
+ };
9578
+ });
9579
+ }
9565
9580
  function isObject(value) {
9566
9581
  return typeof value === "object" && value !== null;
9567
9582
  }
@@ -10730,7 +10745,7 @@ function completeAssessmentTranscript(input) {
10730
10745
  }
10731
10746
  if (input.terminal) {
10732
10747
  const count = itemSubmissions.length;
10733
- const conventionalComplete = assessmentFlowForPurpose(input.purpose) === "item-submit" ? count > 0 : count === input.itemCount;
10748
+ const conventionalComplete = assessmentFlowForPurpose(input.purpose) === "item-submit" ? count > 0 : count === input.itemCount && (input.purpose !== "mastery" || count > 0);
10734
10749
  const complete = state ? state.status === "ready-to-complete" && count > 0 : conventionalComplete;
10735
10750
  if (!complete) {
10736
10751
  throw new AssessmentTranscriptError("A complete administered transcript is required for submission", count);
@@ -10738,12 +10753,6 @@ function completeAssessmentTranscript(input) {
10738
10753
  }
10739
10754
  return { itemSubmissions, ledger, state };
10740
10755
  }
10741
- function administeredItemIdentifiers(itemSubmissions) {
10742
- return new Set(itemSubmissions.map((submission) => submission.itemIdentifier));
10743
- }
10744
- function itemAdministration(itemSubmissions, itemIdentifier) {
10745
- return itemSubmissions.find((submission) => submission.itemIdentifier === itemIdentifier);
10746
- }
10747
10756
  function selectAssessmentCourseCandidate(candidates, subjectSpecified) {
10748
10757
  if (candidates.length === 0) {
10749
10758
  return { outcome: "none" };
@@ -11570,7 +11579,7 @@ function isReviewFulfillment(value) {
11570
11579
  const shortagesValid = value.shortages.every((shortage) => isRecord(shortage) && isAssessmentStandardRef(shortage.standard) && Number.isInteger(shortage.requested) && Number.isInteger(shortage.selected) && Number.isInteger(shortage.eligible));
11571
11580
  return shortagesValid && (value.status === "complete" && value.shortages.length === 0 || value.status === "partial" && value.shortages.length > 0);
11572
11581
  }
11573
- function isReviewItemOutcome(value) {
11582
+ function isAssessmentItemOutcome(value) {
11574
11583
  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");
11575
11584
  }
11576
11585
  function isAssessmentItemSubmission(value) {
@@ -11661,7 +11670,7 @@ function isCompletionMetadata(value, purpose, routedDiagnostic) {
11661
11670
  if (!isRecord(value) || typeof value.testName !== "string" || value.courseName !== undefined && typeof value.courseName !== "string" || !Number.isInteger(value.correctQuestions) || value.session !== undefined && !isAssessmentSessionTiming(value.session) || value.totalQuestions !== undefined && (!Number.isInteger(value.totalQuestions) || Number(value.totalQuestions) < 0)) {
11662
11671
  return false;
11663
11672
  }
11664
- const itemOutcomesValid = value.itemOutcomes === undefined || purpose === "review" && Array.isArray(value.itemOutcomes) && value.itemOutcomes.every(isReviewItemOutcome);
11673
+ const itemOutcomesValid = value.itemOutcomes === undefined || purpose === "review" && Array.isArray(value.itemOutcomes) && value.itemOutcomes.every(isAssessmentItemOutcome);
11665
11674
  const diagnosticTracksValid = value.diagnosticTracks === undefined || routedDiagnostic && Array.isArray(value.diagnosticTracks) && value.diagnosticTracks.every(isDiagnosticTrackResult);
11666
11675
  return itemOutcomesValid && diagnosticTracksValid && (!routedDiagnostic || value.itemOutcomes === undefined && Array.isArray(value.diagnosticTracks) && value.diagnosticTracks.length > 0);
11667
11676
  }
@@ -100388,6 +100397,17 @@ function buildAssessmentSubmitResult(input) {
100388
100397
  const itemOutcomes = input.metadata.completion?.itemOutcomes;
100389
100398
  return itemOutcomes ? { ...base, purpose: input.metadata.purpose, itemOutcomes } : null;
100390
100399
  }
100400
+ if (input.metadata.purpose === "mastery") {
100401
+ const { itemSubmissions, mastery, completion } = input.metadata;
100402
+ if (itemSubmissions.length === 0 || completion?.totalQuestions !== undefined && itemSubmissions.length !== completion.totalQuestions) {
100403
+ return null;
100404
+ }
100405
+ return {
100406
+ ...base,
100407
+ purpose: "mastery",
100408
+ itemOutcomes: assessmentItemOutcomes(itemSubmissions, () => mastery.standard)
100409
+ };
100410
+ }
100391
100411
  return { ...base, purpose: input.metadata.purpose };
100392
100412
  }
100393
100413
  function assessmentAwardFromResult(result, metadata2) {
@@ -103394,22 +103414,11 @@ async function resumeAssessmentTranscript(input) {
103394
103414
  }
103395
103415
  }
103396
103416
  function assessmentReviewTranscriptOutcomes(input) {
103397
- const resultByItem = new Map(input.itemResults.map((item) => [item.itemIdentifier, item]));
103398
- const administered = administeredItemIdentifiers(input.metadata.itemSubmissions);
103399
- return input.metadata.review.selections.filter((selection) => administered.has(selection.itemIdentifier)).map((selection) => {
103400
- const result = resultByItem.get(selection.itemIdentifier);
103401
- const submission = itemAdministration(input.metadata.itemSubmissions, selection.itemIdentifier);
103402
- if (!result || !submission) {
103403
- throw new Error(`Scoring omitted selected review item ${selection.itemIdentifier}`);
103404
- }
103405
- return {
103406
- itemIdentifier: selection.itemIdentifier,
103407
- standard: selection.standard,
103408
- answered: submission.answered,
103409
- score: result.score,
103410
- isCorrect: result.isCorrect
103411
- };
103412
- });
103417
+ const standards = new Map(input.metadata.review.selections.map((selection) => [
103418
+ selection.itemIdentifier,
103419
+ selection.standard
103420
+ ]));
103421
+ return assessmentItemOutcomes(input.metadata.itemSubmissions, (identifier) => standards.get(identifier));
103413
103422
  }
103414
103423
  function assessmentReviewTranscriptExposures(input) {
103415
103424
  const exposures = [];
@@ -104461,8 +104470,7 @@ var init_timeback_assessment_runtime_service = __esm(async () => {
104461
104470
  }, transcript, true, db2);
104462
104471
  const diagnostic = this.isPlatformRoutedDiagnosticMetadata(graded.metadata) ? summarizeDiagnosticSubmission(graded.metadata, graded.manifest) : null;
104463
104472
  const itemOutcomes = graded.metadata.purpose === "review" ? assessmentReviewTranscriptOutcomes({
104464
- metadata: graded.metadata,
104465
- itemResults: graded.itemResults
104473
+ metadata: graded.metadata
104466
104474
  }) : undefined;
104467
104475
  const courseName = attempt.metadata.courseName ?? "Game Course";
104468
104476
  const timestamp6 = new Date().toISOString();
package/dist/server.js CHANGED
@@ -1127,7 +1127,7 @@ var package_default;
1127
1127
  var init_package = __esm(() => {
1128
1128
  package_default = {
1129
1129
  name: "@playcademy/sandbox",
1130
- version: "0.10.0",
1130
+ version: "0.10.1-beta.1",
1131
1131
  description: "Local development server for Playcademy game development",
1132
1132
  type: "module",
1133
1133
  exports: {
@@ -9561,6 +9561,21 @@ function assessmentReviewBankShortage(fulfillment) {
9561
9561
  function assessmentFlowForPurpose(purpose) {
9562
9562
  return purpose === "review" ? "item-submit" : "attempt-submit";
9563
9563
  }
9564
+ function assessmentItemOutcomes(submissions, standardForItem) {
9565
+ return submissions.map((submission) => {
9566
+ const standard = standardForItem(submission.itemIdentifier);
9567
+ if (!standard) {
9568
+ throw new Error(`Missing outcome standard for item ${submission.itemIdentifier}`);
9569
+ }
9570
+ return {
9571
+ itemIdentifier: submission.itemIdentifier,
9572
+ standard: { ...standard },
9573
+ answered: submission.answered,
9574
+ score: { ...submission.score },
9575
+ isCorrect: submission.isCorrect
9576
+ };
9577
+ });
9578
+ }
9564
9579
  function isObject(value) {
9565
9580
  return typeof value === "object" && value !== null;
9566
9581
  }
@@ -10729,7 +10744,7 @@ function completeAssessmentTranscript(input) {
10729
10744
  }
10730
10745
  if (input.terminal) {
10731
10746
  const count = itemSubmissions.length;
10732
- const conventionalComplete = assessmentFlowForPurpose(input.purpose) === "item-submit" ? count > 0 : count === input.itemCount;
10747
+ const conventionalComplete = assessmentFlowForPurpose(input.purpose) === "item-submit" ? count > 0 : count === input.itemCount && (input.purpose !== "mastery" || count > 0);
10733
10748
  const complete = state ? state.status === "ready-to-complete" && count > 0 : conventionalComplete;
10734
10749
  if (!complete) {
10735
10750
  throw new AssessmentTranscriptError("A complete administered transcript is required for submission", count);
@@ -10737,12 +10752,6 @@ function completeAssessmentTranscript(input) {
10737
10752
  }
10738
10753
  return { itemSubmissions, ledger, state };
10739
10754
  }
10740
- function administeredItemIdentifiers(itemSubmissions) {
10741
- return new Set(itemSubmissions.map((submission) => submission.itemIdentifier));
10742
- }
10743
- function itemAdministration(itemSubmissions, itemIdentifier) {
10744
- return itemSubmissions.find((submission) => submission.itemIdentifier === itemIdentifier);
10745
- }
10746
10755
  function selectAssessmentCourseCandidate(candidates, subjectSpecified) {
10747
10756
  if (candidates.length === 0) {
10748
10757
  return { outcome: "none" };
@@ -11569,7 +11578,7 @@ function isReviewFulfillment(value) {
11569
11578
  const shortagesValid = value.shortages.every((shortage) => isRecord(shortage) && isAssessmentStandardRef(shortage.standard) && Number.isInteger(shortage.requested) && Number.isInteger(shortage.selected) && Number.isInteger(shortage.eligible));
11570
11579
  return shortagesValid && (value.status === "complete" && value.shortages.length === 0 || value.status === "partial" && value.shortages.length > 0);
11571
11580
  }
11572
- function isReviewItemOutcome(value) {
11581
+ function isAssessmentItemOutcome(value) {
11573
11582
  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");
11574
11583
  }
11575
11584
  function isAssessmentItemSubmission(value) {
@@ -11660,7 +11669,7 @@ function isCompletionMetadata(value, purpose, routedDiagnostic) {
11660
11669
  if (!isRecord(value) || typeof value.testName !== "string" || value.courseName !== undefined && typeof value.courseName !== "string" || !Number.isInteger(value.correctQuestions) || value.session !== undefined && !isAssessmentSessionTiming(value.session) || value.totalQuestions !== undefined && (!Number.isInteger(value.totalQuestions) || Number(value.totalQuestions) < 0)) {
11661
11670
  return false;
11662
11671
  }
11663
- const itemOutcomesValid = value.itemOutcomes === undefined || purpose === "review" && Array.isArray(value.itemOutcomes) && value.itemOutcomes.every(isReviewItemOutcome);
11672
+ const itemOutcomesValid = value.itemOutcomes === undefined || purpose === "review" && Array.isArray(value.itemOutcomes) && value.itemOutcomes.every(isAssessmentItemOutcome);
11664
11673
  const diagnosticTracksValid = value.diagnosticTracks === undefined || routedDiagnostic && Array.isArray(value.diagnosticTracks) && value.diagnosticTracks.every(isDiagnosticTrackResult);
11665
11674
  return itemOutcomesValid && diagnosticTracksValid && (!routedDiagnostic || value.itemOutcomes === undefined && Array.isArray(value.diagnosticTracks) && value.diagnosticTracks.length > 0);
11666
11675
  }
@@ -100387,6 +100396,17 @@ function buildAssessmentSubmitResult(input) {
100387
100396
  const itemOutcomes = input.metadata.completion?.itemOutcomes;
100388
100397
  return itemOutcomes ? { ...base, purpose: input.metadata.purpose, itemOutcomes } : null;
100389
100398
  }
100399
+ if (input.metadata.purpose === "mastery") {
100400
+ const { itemSubmissions, mastery, completion } = input.metadata;
100401
+ if (itemSubmissions.length === 0 || completion?.totalQuestions !== undefined && itemSubmissions.length !== completion.totalQuestions) {
100402
+ return null;
100403
+ }
100404
+ return {
100405
+ ...base,
100406
+ purpose: "mastery",
100407
+ itemOutcomes: assessmentItemOutcomes(itemSubmissions, () => mastery.standard)
100408
+ };
100409
+ }
100390
100410
  return { ...base, purpose: input.metadata.purpose };
100391
100411
  }
100392
100412
  function assessmentAwardFromResult(result, metadata2) {
@@ -103393,22 +103413,11 @@ async function resumeAssessmentTranscript(input) {
103393
103413
  }
103394
103414
  }
103395
103415
  function assessmentReviewTranscriptOutcomes(input) {
103396
- const resultByItem = new Map(input.itemResults.map((item) => [item.itemIdentifier, item]));
103397
- const administered = administeredItemIdentifiers(input.metadata.itemSubmissions);
103398
- return input.metadata.review.selections.filter((selection) => administered.has(selection.itemIdentifier)).map((selection) => {
103399
- const result = resultByItem.get(selection.itemIdentifier);
103400
- const submission = itemAdministration(input.metadata.itemSubmissions, selection.itemIdentifier);
103401
- if (!result || !submission) {
103402
- throw new Error(`Scoring omitted selected review item ${selection.itemIdentifier}`);
103403
- }
103404
- return {
103405
- itemIdentifier: selection.itemIdentifier,
103406
- standard: selection.standard,
103407
- answered: submission.answered,
103408
- score: result.score,
103409
- isCorrect: result.isCorrect
103410
- };
103411
- });
103416
+ const standards = new Map(input.metadata.review.selections.map((selection) => [
103417
+ selection.itemIdentifier,
103418
+ selection.standard
103419
+ ]));
103420
+ return assessmentItemOutcomes(input.metadata.itemSubmissions, (identifier) => standards.get(identifier));
103412
103421
  }
103413
103422
  function assessmentReviewTranscriptExposures(input) {
103414
103423
  const exposures = [];
@@ -104460,8 +104469,7 @@ var init_timeback_assessment_runtime_service = __esm(async () => {
104460
104469
  }, transcript, true, db2);
104461
104470
  const diagnostic = this.isPlatformRoutedDiagnosticMetadata(graded.metadata) ? summarizeDiagnosticSubmission(graded.metadata, graded.manifest) : null;
104462
104471
  const itemOutcomes = graded.metadata.purpose === "review" ? assessmentReviewTranscriptOutcomes({
104463
- metadata: graded.metadata,
104464
- itemResults: graded.itemResults
104472
+ metadata: graded.metadata
104465
104473
  }) : undefined;
104466
104474
  const courseName = attempt.metadata.courseName ?? "Game Course";
104467
104475
  const timestamp6 = new Date().toISOString();
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@playcademy/sandbox",
3
- "version": "0.10.0",
3
+ "version": "0.10.1-beta.1",
4
4
  "description": "Local development server for Playcademy game development",
5
5
  "type": "module",
6
6
  "exports": {