@playcademy/vite-plugin 1.1.0-beta.2 → 1.1.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 (2) hide show
  1. package/dist/index.js +138 -27
  2. package/package.json +4 -4
package/dist/index.js CHANGED
@@ -23746,7 +23746,7 @@ import path from "node:path";
23746
23746
  // package.json
23747
23747
  var package_default = {
23748
23748
  name: "@playcademy/vite-plugin",
23749
- version: "1.1.0-beta.2",
23749
+ version: "1.1.1-beta.1",
23750
23750
  type: "module",
23751
23751
  exports: {
23752
23752
  ".": {
@@ -25342,7 +25342,7 @@ var package_default2;
25342
25342
  var init_package = __esm(() => {
25343
25343
  package_default2 = {
25344
25344
  name: "@playcademy/sandbox",
25345
- version: "0.5.1-beta.6",
25345
+ version: "0.5.2-beta.1",
25346
25346
  description: "Local development server for Playcademy game development",
25347
25347
  type: "module",
25348
25348
  exports: {
@@ -55859,6 +55859,95 @@ class TimebackCacheManager {
55859
55859
  this.enrollmentCache.cleanup();
55860
55860
  }
55861
55861
  }
55862
+ function computeMasteryPct(masteredUnits, masterableUnits) {
55863
+ if (masterableUnits <= 0) {
55864
+ return 0;
55865
+ }
55866
+ return masteredUnits / masterableUnits;
55867
+ }
55868
+ function clampMasteryPct(masteryPct) {
55869
+ return Math.min(1, Math.max(0, masteryPct));
55870
+ }
55871
+ function createMasteryWriteWarning({
55872
+ currentMasteredUnits,
55873
+ attemptedMasteredUnits,
55874
+ storedMasteredUnits,
55875
+ masterableUnits,
55876
+ effectiveDelta
55877
+ }) {
55878
+ let message;
55879
+ if (attemptedMasteredUnits < 0) {
55880
+ message = `Activity saved. Mastery was capped at the configured minimum: attempted ${attemptedMasteredUnits}/${masterableUnits}, applied ${effectiveDelta} units, stored ${storedMasteredUnits}/${masterableUnits}.`;
55881
+ } else if (storedMasteredUnits > masterableUnits) {
55882
+ message = `Activity saved. Mastery remains above the configured maximum: attempted ${attemptedMasteredUnits}/${masterableUnits}, applied ${effectiveDelta} units, stored ${storedMasteredUnits}/${masterableUnits}.`;
55883
+ } else {
55884
+ message = `Activity saved. Mastery was capped at the configured maximum: attempted ${attemptedMasteredUnits}/${masterableUnits}, applied ${effectiveDelta} units, stored ${storedMasteredUnits}/${masterableUnits}.`;
55885
+ }
55886
+ return {
55887
+ code: MASTERY_WRITE_CAPPED_WARNING_CODE,
55888
+ message,
55889
+ currentMasteredUnits,
55890
+ attemptedMasteredUnits,
55891
+ appliedMasteredUnits: effectiveDelta,
55892
+ storedMasteredUnits,
55893
+ masterableUnits
55894
+ };
55895
+ }
55896
+ function evaluateMasteryBounds({
55897
+ currentMasteredUnits,
55898
+ masterableUnits,
55899
+ masteredUnits = 0,
55900
+ masteredUnitsAbsolute
55901
+ }) {
55902
+ const attemptedMasteredUnits = masteredUnitsAbsolute === undefined ? currentMasteredUnits + masteredUnits : masteredUnitsAbsolute;
55903
+ const base = {
55904
+ currentMasteredUnits,
55905
+ attemptedMasteredUnits,
55906
+ masterableUnits
55907
+ };
55908
+ if (!Number.isFinite(currentMasteredUnits) || !Number.isFinite(masterableUnits) || !Number.isFinite(masteredUnits) || masteredUnitsAbsolute !== undefined && !Number.isFinite(masteredUnitsAbsolute) || !Number.isFinite(attemptedMasteredUnits)) {
55909
+ throw new Error("Mastery bounds evaluation requires finite numeric values.");
55910
+ }
55911
+ if (attemptedMasteredUnits < 0) {
55912
+ const storedMasteredUnits2 = 0;
55913
+ const effectiveDelta2 = storedMasteredUnits2 - currentMasteredUnits;
55914
+ return {
55915
+ ...base,
55916
+ storedMasteredUnits: storedMasteredUnits2,
55917
+ effectiveDelta: effectiveDelta2,
55918
+ writeWarning: createMasteryWriteWarning({
55919
+ currentMasteredUnits,
55920
+ attemptedMasteredUnits,
55921
+ storedMasteredUnits: storedMasteredUnits2,
55922
+ masterableUnits,
55923
+ effectiveDelta: effectiveDelta2
55924
+ })
55925
+ };
55926
+ }
55927
+ if (masterableUnits > 0 && attemptedMasteredUnits > masterableUnits) {
55928
+ const storedMasteredUnits2 = currentMasteredUnits > masterableUnits ? Math.min(currentMasteredUnits, attemptedMasteredUnits) : masterableUnits;
55929
+ const effectiveDelta2 = storedMasteredUnits2 - currentMasteredUnits;
55930
+ return {
55931
+ ...base,
55932
+ storedMasteredUnits: storedMasteredUnits2,
55933
+ effectiveDelta: effectiveDelta2,
55934
+ writeWarning: createMasteryWriteWarning({
55935
+ currentMasteredUnits,
55936
+ attemptedMasteredUnits,
55937
+ storedMasteredUnits: storedMasteredUnits2,
55938
+ masterableUnits,
55939
+ effectiveDelta: effectiveDelta2
55940
+ })
55941
+ };
55942
+ }
55943
+ const storedMasteredUnits = attemptedMasteredUnits;
55944
+ const effectiveDelta = storedMasteredUnits - currentMasteredUnits;
55945
+ return {
55946
+ ...base,
55947
+ storedMasteredUnits,
55948
+ effectiveDelta
55949
+ };
55950
+ }
55862
55951
 
55863
55952
  class MasteryTracker {
55864
55953
  cacheManager;
@@ -55881,7 +55970,8 @@ class MasteryTracker {
55881
55970
  courseId,
55882
55971
  resourceId,
55883
55972
  additionalMasteredUnits: hasAbsolute ? 0 : masteredUnits,
55884
- absoluteMasteredUnits: hasAbsolute ? masteredUnitsAbsolute : undefined
55973
+ absoluteMasteredUnits: hasAbsolute ? masteredUnitsAbsolute : undefined,
55974
+ validateBounds: true
55885
55975
  });
55886
55976
  if (!status) {
55887
55977
  return;
@@ -55891,13 +55981,15 @@ class MasteryTracker {
55891
55981
  pctCompleteApp: status.pctCompleteApp,
55892
55982
  masteryAchieved: !wasComplete && status.isComplete,
55893
55983
  masteryRevoked: wasComplete && !status.isComplete,
55894
- effectiveDelta: status.effectiveDelta
55984
+ effectiveDelta: status.effectiveDelta,
55985
+ ...status.writeWarning ? { writeWarning: status.writeWarning } : {}
55895
55986
  };
55896
55987
  }
55897
55988
  async getStatus(input) {
55898
55989
  const status = await this.calculateStatus({
55899
55990
  ...input,
55900
- additionalMasteredUnits: 0
55991
+ additionalMasteredUnits: 0,
55992
+ validateBounds: false
55901
55993
  });
55902
55994
  if (!status) {
55903
55995
  return;
@@ -55914,7 +56006,8 @@ class MasteryTracker {
55914
56006
  courseId,
55915
56007
  resourceId,
55916
56008
  additionalMasteredUnits,
55917
- absoluteMasteredUnits
56009
+ absoluteMasteredUnits,
56010
+ validateBounds
55918
56011
  }) {
55919
56012
  const masterableUnits = await this.resolveMasterableUnits(resourceId);
55920
56013
  if (!masterableUnits || masterableUnits <= 0) {
@@ -55927,24 +56020,38 @@ class MasteryTracker {
55927
56020
  return;
55928
56021
  }
55929
56022
  const historicalMasteredUnits = this.sumAnalyticsMetric(facts, "masteredUnits");
55930
- let totalMastered;
55931
- let effectiveDelta;
55932
- if (absoluteMasteredUnits !== undefined) {
55933
- totalMastered = Math.max(0, absoluteMasteredUnits);
55934
- effectiveDelta = totalMastered - historicalMasteredUnits;
55935
- } else {
55936
- effectiveDelta = additionalMasteredUnits;
55937
- totalMastered = Math.max(0, historicalMasteredUnits + effectiveDelta);
55938
- }
55939
- const rawPct = totalMastered / masterableUnits * 100;
55940
- const pctCompleteApp = Math.min(100, Math.max(0, Math.round(rawPct)));
56023
+ const bounds = validateBounds ? evaluateMasteryBounds({
56024
+ currentMasteredUnits: historicalMasteredUnits,
56025
+ masterableUnits,
56026
+ masteredUnits: additionalMasteredUnits,
56027
+ masteredUnitsAbsolute: absoluteMasteredUnits
56028
+ }) : {
56029
+ currentMasteredUnits: historicalMasteredUnits,
56030
+ attemptedMasteredUnits: historicalMasteredUnits,
56031
+ storedMasteredUnits: historicalMasteredUnits,
56032
+ masterableUnits,
56033
+ effectiveDelta: 0
56034
+ };
56035
+ if (validateBounds && bounds.writeWarning) {
56036
+ addEvent("timeback.mastery_write_capped", {
56037
+ "app.timeback.current_mastered_units": bounds.currentMasteredUnits,
56038
+ "app.timeback.attempted_mastered_units": bounds.attemptedMasteredUnits,
56039
+ "app.timeback.applied_mastered_units": bounds.effectiveDelta,
56040
+ "app.timeback.stored_mastered_units": bounds.storedMasteredUnits,
56041
+ "app.timeback.masterable_units": bounds.masterableUnits
56042
+ });
56043
+ }
56044
+ const masteredUnits = bounds.storedMasteredUnits;
56045
+ const masteryPct = computeMasteryPct(masteredUnits, masterableUnits);
56046
+ const pctCompleteApp = Math.round(clampMasteryPct(masteryPct) * 100);
55941
56047
  return {
55942
- masteredUnits: totalMastered,
56048
+ masteredUnits,
55943
56049
  masterableUnits,
55944
56050
  pctCompleteApp,
55945
- isComplete: totalMastered >= masterableUnits,
56051
+ isComplete: masteredUnits >= masterableUnits,
55946
56052
  historicalMasteredUnits,
55947
- effectiveDelta
56053
+ effectiveDelta: bounds.effectiveDelta,
56054
+ ...bounds.writeWarning ? { writeWarning: bounds.writeWarning } : {}
55948
56055
  };
55949
56056
  }
55950
56057
  async createCompletionEntry(studentId, courseId, classId, appName) {
@@ -56143,8 +56250,6 @@ class ProgressRecorder {
56143
56250
  xpEarned = 0,
56144
56251
  attemptNumber
56145
56252
  } = progressData;
56146
- const actualLineItemId = await this.resolveAssessmentLineItem(activityId, activityName, progressData.classId, ids);
56147
- const currentAttemptNumber = await this.resolveAttemptNumber(attemptNumber, score, studentId, actualLineItemId);
56148
56253
  let extensions = progressData.extensions;
56149
56254
  const masteryProgress = await this.masteryTracker.checkProgress({
56150
56255
  studentId,
@@ -56158,6 +56263,7 @@ class ProgressRecorder {
56158
56263
  let masteryAchieved = false;
56159
56264
  let scoreStatus = SCORE_STATUS.fullyGraded;
56160
56265
  const inProgress = "false";
56266
+ const warnings = masteryProgress?.writeWarning ? [masteryProgress.writeWarning] : undefined;
56161
56267
  if (masteryProgress) {
56162
56268
  masteryAchieved = masteryProgress.masteryAchieved;
56163
56269
  pctCompleteApp = masteryProgress.pctCompleteApp;
@@ -56169,6 +56275,8 @@ class ProgressRecorder {
56169
56275
  scoreStatus = SCORE_STATUS.fullyGraded;
56170
56276
  }
56171
56277
  }
56278
+ const actualLineItemId = await this.resolveAssessmentLineItem(activityId, activityName, progressData.classId, ids);
56279
+ const currentAttemptNumber = await this.resolveAttemptNumber(attemptNumber, score, studentId, actualLineItemId);
56172
56280
  if (score !== undefined) {
56173
56281
  await this.createGradebookEntry({
56174
56282
  lineItemId: actualLineItemId,
@@ -56227,7 +56335,8 @@ class ProgressRecorder {
56227
56335
  masteredUnitsApplied: effectiveMasteredUnits,
56228
56336
  pctCompleteApp,
56229
56337
  scoreStatus,
56230
- inProgress
56338
+ inProgress,
56339
+ ...warnings ? { warnings } : {}
56231
56340
  };
56232
56341
  }
56233
56342
  async resolveContext(courseId, studentIdentifier, progressData) {
@@ -56958,6 +57067,7 @@ var GRADE_VALUES;
56958
57067
  var TimebackAuthError;
56959
57068
  var UUID_PATTERN;
56960
57069
  var storage;
57070
+ var MASTERY_WRITE_CAPPED_WARNING_CODE = "MASTERY_WRITE_CAPPED";
56961
57071
  var EmailSchema;
56962
57072
  var StudentSourcedIdSchema;
56963
57073
  var StudentIdentifierSchema;
@@ -58627,8 +58737,8 @@ var init_schemas4 = __esm(() => {
58627
58737
  inactiveSeconds: exports_external.number().nonnegative().optional()
58628
58738
  }).optional(),
58629
58739
  xpEarned: exports_external.number(),
58630
- masteredUnits: exports_external.number().optional(),
58631
- masteredUnitsAbsolute: exports_external.number().int().nonnegative().optional(),
58740
+ masteredUnits: exports_external.number().finite().optional(),
58741
+ masteredUnitsAbsolute: exports_external.number().finite().int().optional(),
58632
58742
  extensions: exports_external.record(exports_external.string(), exports_external.unknown()).optional()
58633
58743
  }).refine((data) => !(data.masteredUnits !== undefined && data.masteredUnitsAbsolute !== undefined), {
58634
58744
  message: "Cannot provide both masteredUnits and masteredUnitsAbsolute",
@@ -62736,7 +62846,8 @@ var init_timeback_service = __esm(() => {
62736
62846
  masteredUnits: result.masteredUnitsApplied,
62737
62847
  pctCompleteApp: result.pctCompleteApp,
62738
62848
  scoreStatus: result.scoreStatus,
62739
- inProgress: result.inProgress
62849
+ inProgress: result.inProgress,
62850
+ ...result.warnings ? { warnings: result.warnings } : {}
62740
62851
  };
62741
62852
  }
62742
62853
  async resolveActiveGameCourse({
@@ -125081,7 +125192,7 @@ var init_timeback7 = __esm(() => {
125081
125192
  const seed3 = hashCode(`${e.grade}-${e.subject}`);
125082
125193
  const masterableUnits = 5 + seed3 % 16;
125083
125194
  const masteredUnits = seed3 % (masterableUnits + 1);
125084
- const pctComplete = masterableUnits > 0 ? Math.round(masteredUnits / masterableUnits * 1e4) / 100 : 0;
125195
+ const pctComplete = masterableUnits > 0 ? Math.round(masteredUnits / masterableUnits * 100) : 0;
125085
125196
  return {
125086
125197
  grade: e.grade,
125087
125198
  subject: e.subject,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@playcademy/vite-plugin",
3
- "version": "1.1.0-beta.2",
3
+ "version": "1.1.1-beta.1",
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.25.0-beta.2"
22
+ "playcademy": "0.25.1-beta.1"
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.5.1-beta.6",
29
- "@playcademy/sdk": "0.13.0-beta.2",
28
+ "@playcademy/sandbox": "0.5.2-beta.1",
29
+ "@playcademy/sdk": "0.13.1-beta.1",
30
30
  "@playcademy/types": "0.0.1",
31
31
  "@playcademy/utils": "0.0.1",
32
32
  "@types/archiver": "^6.0.3",