@playcademy/vite-plugin 1.2.1-beta.14 → 1.2.1-beta.16

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 +179 -80
  2. 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.14",
24318
+ version: "1.2.1-beta.16",
24319
24319
  type: "module",
24320
24320
  exports: {
24321
24321
  ".": {
@@ -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.14",
25924
+ version: "0.7.0",
25925
25925
  description: "Local development server for Playcademy game development",
25926
25926
  type: "module",
25927
25927
  exports: {
@@ -34414,9 +34414,18 @@ function assessmentReviewBankShortage(fulfillment) {
34414
34414
  function assessmentFlowForPurpose(purpose) {
34415
34415
  return purpose === "review" || purpose === "mastery" ? "item-submit" : "attempt-submit";
34416
34416
  }
34417
+ function isObject(value) {
34418
+ return typeof value === "object" && value !== null;
34419
+ }
34417
34420
  function isTimebackGrade(value) {
34418
34421
  return typeof value === "number" && Number.isInteger(value) && GRADE_VALUES.includes(value);
34419
34422
  }
34423
+ function isAssessmentSessionTiming(value) {
34424
+ return isObject(value) && typeof value.runId === "string" && isValidUUID(value.runId) && typeof value.resumeId === "string" && isValidUUID(value.resumeId) && isNonNegativeDuration(value.activeSeconds) && (value.inactiveSeconds === undefined || isNonNegativeDuration(value.inactiveSeconds));
34425
+ }
34426
+ function isNonNegativeDuration(value) {
34427
+ return typeof value === "number" && Number.isFinite(value) && value >= 0;
34428
+ }
34420
34429
  function isAssessmentPurpose(value) {
34421
34430
  return ASSESSMENT_PURPOSES.includes(value);
34422
34431
  }
@@ -35260,7 +35269,7 @@ function isPlaycademyAssessmentResultMetadataV1(value) {
35260
35269
  const selectedTest = metadata2.selectedTest;
35261
35270
  const mastery = metadata2.mastery;
35262
35271
  const review = metadata2.review;
35263
- return metadata2.version === 1 && typeof metadata2.activityId === "string" && isAssessmentPurpose(metadata2.purpose) && typeof metadata2.courseId === "string" && typeof metadata2.integrationId === "string" && typeof metadata2.enrollmentId === "string" && Boolean(selectedTest) && typeof selectedTest?.identifier === "string" && typeof selectedTest.contentRevision === "string" && Number.isInteger(metadata2.attemptNumber) && Number.isInteger(metadata2.responseVersion) && Boolean(metadata2.responses) && typeof metadata2.responses === "object" && Array.isArray(metadata2.itemSubmissions) && metadata2.itemSubmissions.every(isAssessmentItemSubmission) && typeof metadata2.startedAt === "string" && typeof metadata2.updatedAt === "string" && (metadata2.purpose === "mastery" ? isMasteryAttemptMetadata(mastery) : mastery === undefined) && (metadata2.purpose === "review" ? isReviewAttemptMetadata(review) : review === undefined) && (metadata2.submissionId === undefined || typeof metadata2.submissionId === "string") && (metadata2.score === undefined || isAssessmentScore(metadata2.score)) && (metadata2.completion === undefined || isRecord(metadata2.completion) && typeof metadata2.completion.testName === "string" && Number.isInteger(metadata2.completion.correctQuestions) && (metadata2.completion.totalQuestions === undefined || Number.isInteger(metadata2.completion.totalQuestions) && metadata2.completion.totalQuestions >= 0) && (metadata2.completion.itemOutcomes === undefined || metadata2.purpose === "review" && Array.isArray(metadata2.completion.itemOutcomes) && metadata2.completion.itemOutcomes.every(isReviewItemOutcome)));
35272
+ return metadata2.version === 1 && typeof metadata2.activityId === "string" && isAssessmentPurpose(metadata2.purpose) && typeof metadata2.courseId === "string" && typeof metadata2.integrationId === "string" && typeof metadata2.enrollmentId === "string" && Boolean(selectedTest) && typeof selectedTest?.identifier === "string" && typeof selectedTest.contentRevision === "string" && Number.isInteger(metadata2.attemptNumber) && Number.isInteger(metadata2.responseVersion) && Boolean(metadata2.responses) && typeof metadata2.responses === "object" && Array.isArray(metadata2.itemSubmissions) && metadata2.itemSubmissions.every(isAssessmentItemSubmission) && typeof metadata2.startedAt === "string" && typeof metadata2.updatedAt === "string" && (metadata2.purpose === "mastery" ? isMasteryAttemptMetadata(mastery) : mastery === undefined) && (metadata2.purpose === "review" ? isReviewAttemptMetadata(review) : review === undefined) && (metadata2.submissionId === undefined || typeof metadata2.submissionId === "string") && (metadata2.score === undefined || isAssessmentScore(metadata2.score)) && (metadata2.completion === undefined || isRecord(metadata2.completion) && typeof metadata2.completion.testName === "string" && Number.isInteger(metadata2.completion.correctQuestions) && (metadata2.completion.session === undefined || isAssessmentSessionTiming(metadata2.completion.session)) && (metadata2.completion.totalQuestions === undefined || Number.isInteger(metadata2.completion.totalQuestions) && metadata2.completion.totalQuestions >= 0) && (metadata2.completion.itemOutcomes === undefined || metadata2.purpose === "review" && Array.isArray(metadata2.completion.itemOutcomes) && metadata2.completion.itemOutcomes.every(isReviewItemOutcome)));
35264
35273
  }
35265
35274
  function isPlaycademyAssessmentItemResultMetadataV1(value) {
35266
35275
  if (!isRecord(value) || !isRecord(value.responses)) {
@@ -35377,6 +35386,7 @@ var init_assessment_runtime = __esm(() => {
35377
35386
  init_src();
35378
35387
  init_timeback3();
35379
35388
  init_src();
35389
+ init_uuid();
35380
35390
  init_src();
35381
35391
  init_uuid();
35382
35392
  init_src();
@@ -35635,7 +35645,10 @@ var init_assessment_runtime = __esm(() => {
35635
35645
  });
35636
35646
  SubmitAssessmentBodySchema = exports_external.object({
35637
35647
  expectedResponseVersion: exports_external.number().int().nonnegative(),
35638
- submissionId: exports_external.string().trim().min(1)
35648
+ submissionId: exports_external.string().trim().min(1),
35649
+ session: exports_external.custom(isAssessmentSessionTiming, {
35650
+ message: "Session timing needs a UUID runId and resumeId with non-negative active and inactive seconds"
35651
+ }).optional()
35639
35652
  });
35640
35653
  StartRuntimeAssessmentRequestSchema = AssessmentRuntimeIdentitySchema.and(StartAssessmentBodySchema);
35641
35654
  SaveRuntimeAssessmentRequestSchema = AssessmentRuntimeIdentitySchema.extend(SaveAssessmentBodySchema.shape);
@@ -43918,10 +43931,10 @@ var require_util5 = __commonJS2((exports) => {
43918
43931
  return objectToString(re) === "[object RegExp]";
43919
43932
  }
43920
43933
  exports.isRegExp = isRegExp;
43921
- function isObject(arg) {
43934
+ function isObject2(arg) {
43922
43935
  return typeof arg === "object" && arg !== null;
43923
43936
  }
43924
- exports.isObject = isObject;
43937
+ exports.isObject = isObject2;
43925
43938
  function isDate(d) {
43926
43939
  return objectToString(d) === "[object Date]";
43927
43940
  }
@@ -60047,23 +60060,23 @@ var init_game_member_service = __esm(() => {
60047
60060
  init_spans();
60048
60061
  init_errors2();
60049
60062
  });
60050
- function isObject(value) {
60063
+ function isObject2(value) {
60051
60064
  return typeof value === "object" && value !== null;
60052
60065
  }
60053
60066
  function isCourseMetadata(value) {
60054
- return isObject(value);
60067
+ return isObject2(value);
60055
60068
  }
60056
60069
  function isResourceMetadata(value) {
60057
- return isObject(value);
60070
+ return isObject2(value);
60058
60071
  }
60059
60072
  function isPlaycademyResourceMetadata(value) {
60060
- if (!isObject(value)) {
60073
+ if (!isObject2(value)) {
60061
60074
  return false;
60062
60075
  }
60063
60076
  if (!("mastery" in value) || value.mastery === undefined) {
60064
60077
  return true;
60065
60078
  }
60066
- return isObject(value.mastery);
60079
+ return isObject2(value.mastery);
60067
60080
  }
60068
60081
  function isTimebackSubject(value) {
60069
60082
  return typeof value === "string" && SUBJECT_VALUES.includes(value);
@@ -60075,6 +60088,7 @@ var SUBJECT_VALUES;
60075
60088
  var GRADE_VALUES2;
60076
60089
  var init_types2 = __esm(() => {
60077
60090
  init_src();
60091
+ init_uuid();
60078
60092
  SUBJECT_VALUES = TIMEBACK_SUBJECTS;
60079
60093
  GRADE_VALUES2 = TIMEBACK_GRADES;
60080
60094
  });
@@ -64516,7 +64530,7 @@ __export(exports_chunk_wex8rmr0, {
64516
64530
  isString: () => isString,
64517
64531
  isRegExp: () => isRegExp,
64518
64532
  isPrimitive: () => isPrimitive,
64519
- isObject: () => isObject2,
64533
+ isObject: () => isObject3,
64520
64534
  isNumber: () => isNumber,
64521
64535
  isNullOrUndefined: () => isNullOrUndefined,
64522
64536
  isNull: () => isNull2,
@@ -64566,7 +64580,7 @@ function format(f, ...args2) {
64566
64580
  }
64567
64581
  });
64568
64582
  for (var x = args2[i2];i2 < len; x = args2[++i2])
64569
- if (isNull2(x) || !isObject2(x))
64583
+ if (isNull2(x) || !isObject3(x))
64570
64584
  str += " " + x;
64571
64585
  else
64572
64586
  str += " " + inspect(x);
@@ -64774,16 +64788,16 @@ function isUndefined(arg) {
64774
64788
  return arg === undefined;
64775
64789
  }
64776
64790
  function isRegExp(re) {
64777
- return isObject2(re) && objectToString(re) === "[object RegExp]";
64791
+ return isObject3(re) && objectToString(re) === "[object RegExp]";
64778
64792
  }
64779
- function isObject2(arg) {
64793
+ function isObject3(arg) {
64780
64794
  return typeof arg === "object" && arg !== null;
64781
64795
  }
64782
64796
  function isDate(d) {
64783
- return isObject2(d) && objectToString(d) === "[object Date]";
64797
+ return isObject3(d) && objectToString(d) === "[object Date]";
64784
64798
  }
64785
64799
  function isError(e) {
64786
- return isObject2(e) && (objectToString(e) === "[object Error]" || e instanceof Error);
64800
+ return isObject3(e) && (objectToString(e) === "[object Error]" || e instanceof Error);
64787
64801
  }
64788
64802
  function isFunction(arg) {
64789
64803
  return typeof arg === "function";
@@ -64812,7 +64826,7 @@ function inherits(ctor, superCtor) {
64812
64826
  ctor.super_ = superCtor, ctor.prototype = Object.create(superCtor.prototype, { constructor: { value: ctor, enumerable: false, writable: true, configurable: true } });
64813
64827
  }
64814
64828
  function _extend(origin, add) {
64815
- if (!add || !isObject2(add))
64829
+ if (!add || !isObject3(add))
64816
64830
  return origin;
64817
64831
  var keys = Object.keys(add), i2 = keys.length;
64818
64832
  while (i2--)
@@ -66685,7 +66699,7 @@ __export(exports_util, {
66685
66699
  joinValues: () => joinValues,
66686
66700
  issue: () => issue2,
66687
66701
  isPlainObject: () => isPlainObject,
66688
- isObject: () => isObject3,
66702
+ isObject: () => isObject4,
66689
66703
  getSizableOrigin: () => getSizableOrigin,
66690
66704
  getParsedType: () => getParsedType2,
66691
66705
  getLengthableOrigin: () => getLengthableOrigin,
@@ -66821,17 +66835,17 @@ function randomString(length = 10) {
66821
66835
  function esc(str) {
66822
66836
  return JSON.stringify(str);
66823
66837
  }
66824
- function isObject3(data) {
66838
+ function isObject4(data) {
66825
66839
  return typeof data === "object" && data !== null && !Array.isArray(data);
66826
66840
  }
66827
66841
  function isPlainObject(o) {
66828
- if (isObject3(o) === false)
66842
+ if (isObject4(o) === false)
66829
66843
  return false;
66830
66844
  const ctor = o.constructor;
66831
66845
  if (ctor === undefined)
66832
66846
  return true;
66833
66847
  const prot = ctor.prototype;
66834
- if (isObject3(prot) === false)
66848
+ if (isObject4(prot) === false)
66835
66849
  return false;
66836
66850
  if (Object.prototype.hasOwnProperty.call(prot, "isPrototypeOf") === false) {
66837
66851
  return false;
@@ -69064,7 +69078,7 @@ var init_schemas5 = __esm(() => {
69064
69078
  return (payload, ctx) => fn(shape, payload, ctx);
69065
69079
  };
69066
69080
  let fastpass;
69067
- const isObject4 = isObject3;
69081
+ const isObject5 = isObject4;
69068
69082
  const jit = !globalConfig.jitless;
69069
69083
  const allowsEval2 = allowsEval;
69070
69084
  const fastEnabled = jit && allowsEval2.value;
@@ -69073,7 +69087,7 @@ var init_schemas5 = __esm(() => {
69073
69087
  inst._zod.parse = (payload, ctx) => {
69074
69088
  value ?? (value = _normalized.value);
69075
69089
  const input = payload.value;
69076
- if (!isObject4(input)) {
69090
+ if (!isObject5(input)) {
69077
69091
  payload.issues.push({
69078
69092
  expected: "object",
69079
69093
  code: "invalid_type",
@@ -69217,7 +69231,7 @@ var init_schemas5 = __esm(() => {
69217
69231
  });
69218
69232
  inst._zod.parse = (payload, ctx) => {
69219
69233
  const input = payload.value;
69220
- if (!isObject3(input)) {
69234
+ if (!isObject4(input)) {
69221
69235
  payload.issues.push({
69222
69236
  code: "invalid_type",
69223
69237
  expected: "object",
@@ -84447,7 +84461,7 @@ __export(exports_chunk_dd0pbbq3, {
84447
84461
  isString: () => isString2,
84448
84462
  isRegExp: () => isRegExp2,
84449
84463
  isPrimitive: () => isPrimitive2,
84450
- isObject: () => isObject4,
84464
+ isObject: () => isObject5,
84451
84465
  isNumber: () => isNumber2,
84452
84466
  isNullOrUndefined: () => isNullOrUndefined2,
84453
84467
  isNull: () => isNull3,
@@ -84497,7 +84511,7 @@ function format2(f, ...args2) {
84497
84511
  }
84498
84512
  });
84499
84513
  for (var x = args2[i2];i2 < len; x = args2[++i2])
84500
- if (isNull3(x) || !isObject4(x))
84514
+ if (isNull3(x) || !isObject5(x))
84501
84515
  str += " " + x;
84502
84516
  else
84503
84517
  str += " " + inspect2(x);
@@ -84705,16 +84719,16 @@ function isUndefined2(arg) {
84705
84719
  return arg === undefined;
84706
84720
  }
84707
84721
  function isRegExp2(re) {
84708
- return isObject4(re) && objectToString2(re) === "[object RegExp]";
84722
+ return isObject5(re) && objectToString2(re) === "[object RegExp]";
84709
84723
  }
84710
- function isObject4(arg) {
84724
+ function isObject5(arg) {
84711
84725
  return typeof arg === "object" && arg !== null;
84712
84726
  }
84713
84727
  function isDate2(d) {
84714
- return isObject4(d) && objectToString2(d) === "[object Date]";
84728
+ return isObject5(d) && objectToString2(d) === "[object Date]";
84715
84729
  }
84716
84730
  function isError2(e) {
84717
- return isObject4(e) && (objectToString2(e) === "[object Error]" || e instanceof Error);
84731
+ return isObject5(e) && (objectToString2(e) === "[object Error]" || e instanceof Error);
84718
84732
  }
84719
84733
  function isFunction2(arg) {
84720
84734
  return typeof arg === "function";
@@ -84743,7 +84757,7 @@ function inherits2(ctor, superCtor) {
84743
84757
  ctor.super_ = superCtor, ctor.prototype = Object.create(superCtor.prototype, { constructor: { value: ctor, enumerable: false, writable: true, configurable: true } });
84744
84758
  }
84745
84759
  function _extend2(origin, add) {
84746
- if (!add || !isObject4(add))
84760
+ if (!add || !isObject5(add))
84747
84761
  return origin;
84748
84762
  var keys = Object.keys(add), i2 = keys.length;
84749
84763
  while (i2--)
@@ -86582,7 +86596,7 @@ __export(exports_util2, {
86582
86596
  joinValues: () => joinValues2,
86583
86597
  issue: () => issue4,
86584
86598
  isPlainObject: () => isPlainObject2,
86585
- isObject: () => isObject5,
86599
+ isObject: () => isObject6,
86586
86600
  hexToUint8Array: () => hexToUint8Array,
86587
86601
  getSizableOrigin: () => getSizableOrigin2,
86588
86602
  getParsedType: () => getParsedType3,
@@ -86743,11 +86757,11 @@ function esc2(str) {
86743
86757
  function slugify(input) {
86744
86758
  return input.toLowerCase().trim().replace(/[^\w\s-]/g, "").replace(/[\s_-]+/g, "-").replace(/^-+|-+$/g, "");
86745
86759
  }
86746
- function isObject5(data) {
86760
+ function isObject6(data) {
86747
86761
  return typeof data === "object" && data !== null && !Array.isArray(data);
86748
86762
  }
86749
86763
  function isPlainObject2(o) {
86750
- if (isObject5(o) === false)
86764
+ if (isObject6(o) === false)
86751
86765
  return false;
86752
86766
  const ctor = o.constructor;
86753
86767
  if (ctor === undefined)
@@ -86755,7 +86769,7 @@ function isPlainObject2(o) {
86755
86769
  if (typeof ctor !== "function")
86756
86770
  return true;
86757
86771
  const prot = ctor.prototype;
86758
- if (isObject5(prot) === false)
86772
+ if (isObject6(prot) === false)
86759
86773
  return false;
86760
86774
  if (Object.prototype.hasOwnProperty.call(prot, "isPrototypeOf") === false) {
86761
86775
  return false;
@@ -89444,13 +89458,13 @@ var init_schemas7 = __esm(() => {
89444
89458
  }
89445
89459
  return propValues;
89446
89460
  });
89447
- const isObject6 = isObject5;
89461
+ const isObject7 = isObject6;
89448
89462
  const catchall = def.catchall;
89449
89463
  let value;
89450
89464
  inst._zod.parse = (payload, ctx) => {
89451
89465
  value ?? (value = _normalized.value);
89452
89466
  const input = payload.value;
89453
- if (!isObject6(input)) {
89467
+ if (!isObject7(input)) {
89454
89468
  payload.issues.push({
89455
89469
  expected: "object",
89456
89470
  code: "invalid_type",
@@ -89577,7 +89591,7 @@ var init_schemas7 = __esm(() => {
89577
89591
  return (payload, ctx) => fn(shape, payload, ctx);
89578
89592
  };
89579
89593
  let fastpass;
89580
- const isObject6 = isObject5;
89594
+ const isObject7 = isObject6;
89581
89595
  const jit = !globalConfig2.jitless;
89582
89596
  const allowsEval3 = allowsEval2;
89583
89597
  const fastEnabled = jit && allowsEval3.value;
@@ -89586,7 +89600,7 @@ var init_schemas7 = __esm(() => {
89586
89600
  inst._zod.parse = (payload, ctx) => {
89587
89601
  value ?? (value = _normalized.value);
89588
89602
  const input = payload.value;
89589
- if (!isObject6(input)) {
89603
+ if (!isObject7(input)) {
89590
89604
  payload.issues.push({
89591
89605
  expected: "object",
89592
89606
  code: "invalid_type",
@@ -89718,7 +89732,7 @@ var init_schemas7 = __esm(() => {
89718
89732
  });
89719
89733
  inst._zod.parse = (payload, ctx) => {
89720
89734
  const input = payload.value;
89721
- if (!isObject5(input)) {
89735
+ if (!isObject6(input)) {
89722
89736
  payload.issues.push({
89723
89737
  code: "invalid_type",
89724
89738
  expected: "object",
@@ -104005,7 +104019,7 @@ __export(exports_chunk_dd0pbbq32, {
104005
104019
  isString: () => isString3,
104006
104020
  isRegExp: () => isRegExp3,
104007
104021
  isPrimitive: () => isPrimitive3,
104008
- isObject: () => isObject6,
104022
+ isObject: () => isObject7,
104009
104023
  isNumber: () => isNumber3,
104010
104024
  isNullOrUndefined: () => isNullOrUndefined3,
104011
104025
  isNull: () => isNull4,
@@ -104055,7 +104069,7 @@ function format3(f, ...args2) {
104055
104069
  }
104056
104070
  });
104057
104071
  for (var x = args2[i2];i2 < len; x = args2[++i2])
104058
- if (isNull4(x) || !isObject6(x))
104072
+ if (isNull4(x) || !isObject7(x))
104059
104073
  str += " " + x;
104060
104074
  else
104061
104075
  str += " " + inspect3(x);
@@ -104263,16 +104277,16 @@ function isUndefined3(arg) {
104263
104277
  return arg === undefined;
104264
104278
  }
104265
104279
  function isRegExp3(re) {
104266
- return isObject6(re) && objectToString3(re) === "[object RegExp]";
104280
+ return isObject7(re) && objectToString3(re) === "[object RegExp]";
104267
104281
  }
104268
- function isObject6(arg) {
104282
+ function isObject7(arg) {
104269
104283
  return typeof arg === "object" && arg !== null;
104270
104284
  }
104271
104285
  function isDate3(d) {
104272
- return isObject6(d) && objectToString3(d) === "[object Date]";
104286
+ return isObject7(d) && objectToString3(d) === "[object Date]";
104273
104287
  }
104274
104288
  function isError3(e) {
104275
- return isObject6(e) && (objectToString3(e) === "[object Error]" || e instanceof Error);
104289
+ return isObject7(e) && (objectToString3(e) === "[object Error]" || e instanceof Error);
104276
104290
  }
104277
104291
  function isFunction3(arg) {
104278
104292
  return typeof arg === "function";
@@ -104301,7 +104315,7 @@ function inherits3(ctor, superCtor) {
104301
104315
  ctor.super_ = superCtor, ctor.prototype = Object.create(superCtor.prototype, { constructor: { value: ctor, enumerable: false, writable: true, configurable: true } });
104302
104316
  }
104303
104317
  function _extend3(origin, add) {
104304
- if (!add || !isObject6(add))
104318
+ if (!add || !isObject7(add))
104305
104319
  return origin;
104306
104320
  var keys = Object.keys(add), i2 = keys.length;
104307
104321
  while (i2--)
@@ -109099,7 +109113,8 @@ function buildAssessmentCompletionMetadata(input) {
109099
109113
  attemptId: input.attemptId,
109100
109114
  submissionId: input.submissionId,
109101
109115
  testIdentifier: input.testIdentifier,
109102
- assessmentPurpose: input.purpose
109116
+ assessmentPurpose: input.purpose,
109117
+ ...input.resumeId ? { resumeId: input.resumeId } : {}
109103
109118
  }
109104
109119
  };
109105
109120
  }
@@ -109121,11 +109136,13 @@ function buildAssessmentCompletionEvent(input) {
109121
109136
  appName: input.appName,
109122
109137
  sensorUrl: input.sensorUrl,
109123
109138
  eventId: input.eventId,
109139
+ runId: input.attemptId,
109124
109140
  generatedExtensions: metadata2,
109125
109141
  eventExtensions: {
109126
109142
  playcademy: {
109127
109143
  assessmentPurpose: input.purpose,
109128
- attemptId: input.attemptId
109144
+ attemptId: input.attemptId,
109145
+ ...input.resumeId ? { resumeId: input.resumeId } : {}
109129
109146
  }
109130
109147
  }
109131
109148
  };
@@ -109743,17 +109760,17 @@ function createActivityNamespace(core3, deps) {
109743
109760
  completeAssessment: (data) => deps.events.emitActivityEvent(buildAssessmentCompletionEvent(data))
109744
109761
  };
109745
109762
  }
109746
- function isObject7(value) {
109763
+ function isObject8(value) {
109747
109764
  return typeof value === "object" && value !== null;
109748
109765
  }
109749
109766
  function isPlaycademyResourceMetadata2(value) {
109750
- if (!isObject7(value)) {
109767
+ if (!isObject8(value)) {
109751
109768
  return false;
109752
109769
  }
109753
109770
  if (!("mastery" in value) || value.mastery === undefined) {
109754
109771
  return true;
109755
109772
  }
109756
- return isObject7(value.mastery);
109773
+ return isObject8(value.mastery);
109757
109774
  }
109758
109775
  function isTimebackSubject3(value) {
109759
109776
  return typeof value === "string" && SUBJECT_VALUES2.includes(value);
@@ -111046,6 +111063,7 @@ var init_dist5 = __esm(async () => {
111046
111063
  init_src();
111047
111064
  init_spans();
111048
111065
  init_src();
111066
+ init_uuid();
111049
111067
  init_src();
111050
111068
  init_spans();
111051
111069
  init_src9();
@@ -111260,6 +111278,7 @@ function deriveSourcedIds2(courseId) {
111260
111278
  }
111261
111279
  var init_utils6 = __esm(() => {
111262
111280
  init_src();
111281
+ init_uuid();
111263
111282
  });
111264
111283
  async function classifyGameMetricsResponse(response, context2) {
111265
111284
  if (response.status === 404) {
@@ -117256,6 +117275,7 @@ function buildAssessmentResultFinalization(input) {
117256
117275
  testName: input.testName,
117257
117276
  totalQuestions: input.totalQuestions,
117258
117277
  correctQuestions: input.correctQuestions,
117278
+ ...input.session ? { session: input.session } : {},
117259
117279
  ...input.itemOutcomes ? { itemOutcomes: input.itemOutcomes } : {}
117260
117280
  },
117261
117281
  updatedAt: input.timestamp
@@ -117361,7 +117381,7 @@ class TimebackAssessmentRuntimeService {
117361
117381
  const compatibleAttempts = this.attemptsMatchingRequest(attempts, requestFingerprint);
117362
117382
  let decision = this.requireDecision(selectRuntimeAssessment(tests, [...compatibleAttempts.values()].map((entry2) => entry2.selection)), input.purpose);
117363
117383
  if (decision.kind === "resume") {
117364
- return this.resumeSnapshot(decision, attempts);
117384
+ return this.resumeSnapshot(decision, attempts, context2.integration);
117365
117385
  }
117366
117386
  let assessment = await this.loadAssessment(decision.test.qtiTestIdentifier);
117367
117387
  const refreshedListing = await this.listAttempts(attemptScope);
@@ -117369,7 +117389,7 @@ class TimebackAssessmentRuntimeService {
117369
117389
  const refreshedCompatible = this.attemptsMatchingRequest(refreshed, requestFingerprint);
117370
117390
  const refreshedDecision = this.requireDecision(selectRuntimeAssessment(tests, [...refreshedCompatible.values()].map((entry2) => entry2.selection)), input.purpose);
117371
117391
  if (refreshedDecision.kind === "resume") {
117372
- return this.resumeSnapshot(refreshedDecision, refreshed);
117392
+ return this.resumeSnapshot(refreshedDecision, refreshed, context2.integration);
117373
117393
  }
117374
117394
  decision = refreshedDecision;
117375
117395
  if (assessment.identifier !== decision.test.qtiTestIdentifier) {
@@ -117429,7 +117449,7 @@ class TimebackAssessmentRuntimeService {
117429
117449
  grade: context2.integration.grade
117430
117450
  })
117431
117451
  });
117432
- return this.snapshot(result, metadata2, assessment);
117452
+ return this.snapshot(result, metadata2, assessment, context2.integration);
117433
117453
  });
117434
117454
  }
117435
117455
  async startReview({
@@ -117564,12 +117584,12 @@ class TimebackAssessmentRuntimeService {
117564
117584
  existingChildResults: refreshedListing.reviewChildren,
117565
117585
  lookupMissingResults: false
117566
117586
  });
117567
- return this.snapshot(result, metadata2, assessment);
117587
+ return this.snapshot(result, metadata2, assessment, context2.integration);
117568
117588
  });
117569
117589
  }
117570
117590
  async get(params) {
117571
117591
  const attempt = await this.authorizeAttemptRead(params);
117572
- return this.snapshotForResult(attempt.result, attempt.metadata);
117592
+ return this.snapshotForResult(attempt.result, attempt.metadata, attempt.integration);
117573
117593
  }
117574
117594
  async latest({
117575
117595
  gameId,
@@ -117918,6 +117938,9 @@ class TimebackAssessmentRuntimeService {
117918
117938
  if (submissionDisposition === "reject") {
117919
117939
  throw AssessmentRuntimeError.from(assessmentAlreadySubmitted(attempt.result.sourcedId));
117920
117940
  }
117941
+ if (input.session && input.session.runId !== attempt.result.sourcedId) {
117942
+ throw new ValidationError("Assessment session runId must match the attemptId.");
117943
+ }
117921
117944
  this.assertResponseVersion(attempt.metadata, input.expectedResponseVersion);
117922
117945
  if (assessmentFlowForPurpose(attempt.metadata.purpose) === "item-submit") {
117923
117946
  const assessment2 = await this.loadAttemptAssessment(attempt.metadata);
@@ -117946,6 +117969,7 @@ class TimebackAssessmentRuntimeService {
117946
117969
  testName: assessment.title,
117947
117970
  totalQuestions: assessment.items.length,
117948
117971
  correctQuestions,
117972
+ ...input.session ? { session: input.session } : {},
117949
117973
  ...reviewOutcomes ? { itemOutcomes: reviewOutcomes } : {}
117950
117974
  });
117951
117975
  const metadata2 = finalization.metadata;
@@ -117984,7 +118008,10 @@ class TimebackAssessmentRuntimeService {
117984
118008
  };
117985
118009
  });
117986
118010
  if (submission.completion) {
117987
- await this.emitCompletionBestEffort(submission.completion);
118011
+ await Promise.allSettled([
118012
+ this.emitCompletionBestEffort(submission.completion),
118013
+ this.emitSessionBestEffort(submission.completion)
118014
+ ]);
117988
118015
  }
117989
118016
  return submission.response;
117990
118017
  }
@@ -118239,7 +118266,7 @@ class TimebackAssessmentRuntimeService {
118239
118266
  }
118240
118267
  return decision;
118241
118268
  }
118242
- resumeSnapshot(decision, attempts) {
118269
+ resumeSnapshot(decision, attempts, integration) {
118243
118270
  if (decision.additionalResumableAttemptIds.length > 0) {
118244
118271
  addEvent("assessment.multiple_resumable_attempts", {
118245
118272
  "app.assessment.attempt_id": decision.attempt.attemptId,
@@ -118247,7 +118274,7 @@ class TimebackAssessmentRuntimeService {
118247
118274
  });
118248
118275
  }
118249
118276
  const resumed = attempts.get(decision.attempt.attemptId);
118250
- return this.snapshotForResult(resumed.result, resumed.metadata);
118277
+ return this.snapshotForResult(resumed.result, resumed.metadata, integration);
118251
118278
  }
118252
118279
  async resumeReviewSnapshot(decision, attempts, existingChildResults, context2) {
118253
118280
  if (decision.additionalResumableAttemptIds.length > 0) {
@@ -118272,7 +118299,7 @@ class TimebackAssessmentRuntimeService {
118272
118299
  existingChildResults,
118273
118300
  lookupMissingResults: true
118274
118301
  });
118275
- return this.snapshot(resumed.result, resumed.metadata, assessment);
118302
+ return this.snapshot(resumed.result, resumed.metadata, assessment, context2.integration);
118276
118303
  }
118277
118304
  async loadReviewBank(identifier, expectedSourceRevision) {
118278
118305
  if (expectedSourceRevision) {
@@ -118737,17 +118764,19 @@ class TimebackAssessmentRuntimeService {
118737
118764
  unauthorizedAttempt(attemptId) {
118738
118765
  return AssessmentRuntimeError.from(assessmentAttemptUnauthorized(attemptId));
118739
118766
  }
118740
- async snapshotForResult(result, metadata2) {
118741
- return this.snapshot(result, metadata2, await this.loadAttemptAssessment(metadata2));
118767
+ async snapshotForResult(result, metadata2, integration) {
118768
+ return this.snapshot(result, metadata2, await this.loadAttemptAssessment(metadata2), integration);
118742
118769
  }
118743
- snapshot(result, metadata2, assessment) {
118770
+ snapshot(result, metadata2, assessment, integration) {
118744
118771
  const completed = this.isCompleted(result);
118745
118772
  const selection = this.selectionContext(metadata2);
118773
+ const activityData = this.activityData(metadata2, assessment, integration);
118746
118774
  return {
118747
118775
  attemptId: result.sourcedId,
118748
118776
  responseVersion: metadata2.responseVersion,
118749
118777
  status: completed ? "completed" : "in_progress",
118750
118778
  flow: assessmentFlowForPurpose(metadata2.purpose),
118779
+ ...activityData ? { activityData } : {},
118751
118780
  assessment: assessmentPresentationForAttempt(assessment, result.sourcedId),
118752
118781
  responses: metadata2.responses,
118753
118782
  itemSubmissions: metadata2.itemSubmissions,
@@ -118755,6 +118784,30 @@ class TimebackAssessmentRuntimeService {
118755
118784
  selection
118756
118785
  };
118757
118786
  }
118787
+ activityData(metadata2, assessment, integration) {
118788
+ const course = this.trackableCourse(integration, "assessment.activity_tracking_invalid_course_metadata");
118789
+ if (!course) {
118790
+ return;
118791
+ }
118792
+ return {
118793
+ activityId: metadata2.activityId,
118794
+ activityName: assessment.title,
118795
+ ...course,
118796
+ courseId: integration.courseId
118797
+ };
118798
+ }
118799
+ trackableCourse(integration, event, attributes2 = {}) {
118800
+ if (!isTimebackGrade2(integration.grade) || !isTimebackSubject(integration.subject)) {
118801
+ addEvent(event, {
118802
+ ...attributes2,
118803
+ "app.timeback.integration_id": integration.id,
118804
+ "app.timeback.grade": integration.grade,
118805
+ "app.timeback.subject": integration.subject
118806
+ });
118807
+ return null;
118808
+ }
118809
+ return { grade: integration.grade, subject: integration.subject };
118810
+ }
118758
118811
  selectionContext(metadata2) {
118759
118812
  if (metadata2.purpose === "review") {
118760
118813
  return {
@@ -118866,12 +118919,9 @@ class TimebackAssessmentRuntimeService {
118866
118919
  async emitCompletionBestEffort(input) {
118867
118920
  const { attempt } = input;
118868
118921
  const integration = attempt.integration;
118869
- if (!isTimebackGrade2(integration.grade) || !isTimebackSubject(integration.subject)) {
118870
- addEvent("assessment.completion_event_invalid_course_metadata", {
118871
- "app.assessment.attempt_id": attempt.result.sourcedId,
118872
- "app.timeback.grade": integration.grade,
118873
- "app.timeback.subject": integration.subject
118874
- });
118922
+ const session2 = attempt.metadata.completion?.session;
118923
+ const course = this.trackableCourse(integration, "assessment.completion_event_invalid_course_metadata", { "app.assessment.attempt_id": attempt.result.sourcedId });
118924
+ if (!course) {
118875
118925
  return;
118876
118926
  }
118877
118927
  try {
@@ -118893,14 +118943,14 @@ class TimebackAssessmentRuntimeService {
118893
118943
  testName: input.testName,
118894
118944
  courseId: integration.courseId,
118895
118945
  courseName: attempt.enrollment.course.title,
118896
- subject: integration.subject,
118897
- grade: integration.grade,
118946
+ ...course,
118898
118947
  appName: input.game.appName,
118899
118948
  sensorUrl: input.game.sensorUrl,
118900
118949
  attemptNumber: attempt.metadata.attemptNumber,
118901
118950
  totalQuestions: input.totalQuestions,
118902
118951
  correctQuestions: input.correctQuestions,
118903
- eventId
118952
+ eventId,
118953
+ ...session2 ? { resumeId: session2.resumeId } : {}
118904
118954
  };
118905
118955
  await this.requireClient().activity.completeAssessment(event);
118906
118956
  } catch (error88) {
@@ -118911,6 +118961,54 @@ class TimebackAssessmentRuntimeService {
118911
118961
  });
118912
118962
  }
118913
118963
  }
118964
+ async emitSessionBestEffort(input) {
118965
+ const { attempt } = input;
118966
+ const session2 = attempt.metadata.completion?.session;
118967
+ if (!session2 || session2.activeSeconds === 0 && (session2.inactiveSeconds ?? 0) === 0) {
118968
+ return;
118969
+ }
118970
+ const integration = attempt.integration;
118971
+ const course = this.trackableCourse(integration, "assessment.time_spent_event_invalid_course_metadata", { "app.assessment.attempt_id": attempt.result.sourcedId });
118972
+ if (!course) {
118973
+ return;
118974
+ }
118975
+ try {
118976
+ const eventId = `urn:uuid:${await deterministicUUID([
118977
+ "playcademy-assessment-time-spent-event-v1",
118978
+ attempt.result.sourcedId,
118979
+ input.submissionId,
118980
+ session2.resumeId
118981
+ ].join("\x00"))}`;
118982
+ await this.requireClient().activity.session(integration.courseId, input.studentId, {
118983
+ eventId,
118984
+ gameId: input.gameId,
118985
+ activityId: attempt.metadata.activityId,
118986
+ activityName: input.testName,
118987
+ courseId: integration.courseId,
118988
+ courseName: attempt.enrollment.course.title,
118989
+ activeTimeSeconds: session2.activeSeconds,
118990
+ ...session2.inactiveSeconds !== undefined ? { inactiveTimeSeconds: session2.inactiveSeconds } : {},
118991
+ subject: course.subject,
118992
+ appName: input.game.appName,
118993
+ sensorUrl: input.game.sensorUrl,
118994
+ runId: session2.runId,
118995
+ extensions: {
118996
+ playcademy: {
118997
+ resumeId: session2.resumeId,
118998
+ assessmentPurpose: attempt.metadata.purpose,
118999
+ attemptId: attempt.result.sourcedId,
119000
+ submissionId: input.submissionId
119001
+ }
119002
+ }
119003
+ });
119004
+ } catch (error88) {
119005
+ addEvent("assessment.time_spent_event_failed", {
119006
+ "app.assessment.attempt_id": attempt.result.sourcedId,
119007
+ "exception.type": errorType(error88),
119008
+ "app.error.message": errorMessage2(error88)
119009
+ });
119010
+ }
119011
+ }
118914
119012
  }
118915
119013
  var init_timeback_assessment_runtime_service = __esm(async () => {
118916
119014
  init_drizzle_orm();
@@ -146452,7 +146550,7 @@ See: https://github.com/isaacs/node-glob/issues/167`);
146452
146550
  throw new TypeError(FUNC_ERROR_TEXT);
146453
146551
  }
146454
146552
  wait = toNumber2(wait) || 0;
146455
- if (isObject8(options)) {
146553
+ if (isObject9(options)) {
146456
146554
  leading = !!options.leading;
146457
146555
  maxing = "maxWait" in options;
146458
146556
  maxWait = maxing ? nativeMax(toNumber2(options.maxWait) || 0, wait) : maxWait;
@@ -146531,7 +146629,7 @@ See: https://github.com/isaacs/node-glob/issues/167`);
146531
146629
  if (typeof func2 != "function") {
146532
146630
  throw new TypeError(FUNC_ERROR_TEXT);
146533
146631
  }
146534
- if (isObject8(options)) {
146632
+ if (isObject9(options)) {
146535
146633
  leading = "leading" in options ? !!options.leading : leading;
146536
146634
  trailing = "trailing" in options ? !!options.trailing : trailing;
146537
146635
  }
@@ -146541,7 +146639,7 @@ See: https://github.com/isaacs/node-glob/issues/167`);
146541
146639
  trailing
146542
146640
  });
146543
146641
  }
146544
- function isObject8(value) {
146642
+ function isObject9(value) {
146545
146643
  var type = typeof value;
146546
146644
  return !!value && (type == "object" || type == "function");
146547
146645
  }
@@ -146558,9 +146656,9 @@ See: https://github.com/isaacs/node-glob/issues/167`);
146558
146656
  if (isSymbol4(value)) {
146559
146657
  return NAN;
146560
146658
  }
146561
- if (isObject8(value)) {
146659
+ if (isObject9(value)) {
146562
146660
  var other = typeof value.valueOf == "function" ? value.valueOf() : value;
146563
- value = isObject8(other) ? other + "" : other;
146661
+ value = isObject9(other) ? other + "" : other;
146564
146662
  }
146565
146663
  if (typeof value != "string") {
146566
146664
  return value === 0 ? value : +value;
@@ -183545,7 +183643,8 @@ var init_timeback_controller = __esm(() => {
183545
183643
  attemptId,
183546
183644
  input: {
183547
183645
  expectedResponseVersion: body2.expectedResponseVersion,
183548
- submissionId: body2.submissionId
183646
+ submissionId: body2.submissionId,
183647
+ ...body2.session ? { session: body2.session } : {}
183549
183648
  },
183550
183649
  game: {
183551
183650
  appName: body2.appName,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@playcademy/vite-plugin",
3
- "version": "1.2.1-beta.14",
3
+ "version": "1.2.1-beta.16",
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.14"
22
+ "playcademy": "0.28.1-beta.16"
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.14",
29
- "@playcademy/sdk": "0.16.1-beta.14",
28
+ "@playcademy/sandbox": "0.7.0",
29
+ "@playcademy/sdk": "0.16.0",
30
30
  "@playcademy/types": "0.0.1",
31
31
  "@playcademy/utils": "0.0.1",
32
32
  "@types/archiver": "^6.0.3",