@playcademy/sandbox 0.3.16 → 0.3.17-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 +70 -11
  2. package/dist/server.js +70 -11
  3. package/package.json +1 -1
package/dist/cli.js CHANGED
@@ -1310,7 +1310,7 @@ var package_default;
1310
1310
  var init_package = __esm(() => {
1311
1311
  package_default = {
1312
1312
  name: "@playcademy/sandbox",
1313
- version: "0.3.16",
1313
+ version: "0.3.17-beta.1",
1314
1314
  description: "Local development server for Playcademy game development",
1315
1315
  type: "module",
1316
1316
  exports: {
@@ -30485,6 +30485,27 @@ class TimebackAdminService {
30485
30485
  const rounded = Math.round(value * TimebackAdminService.XP_PRECISION_FACTOR) / TimebackAdminService.XP_PRECISION_FACTOR;
30486
30486
  return Object.is(rounded, -0) ? 0 : rounded;
30487
30487
  }
30488
+ static toAttributionEventTime(date3) {
30489
+ if (!date3) {
30490
+ return;
30491
+ }
30492
+ const match = date3.match(/^(\d{4})-(\d{2})-(\d{2})$/);
30493
+ if (!match) {
30494
+ throw new ValidationError("Date must be in YYYY-MM-DD format");
30495
+ }
30496
+ const [, yearStr, monthStr, dayStr] = match;
30497
+ const year = Number(yearStr);
30498
+ const month = Number(monthStr);
30499
+ const day = Number(dayStr);
30500
+ if (!Number.isInteger(year) || !Number.isInteger(month) || !Number.isInteger(day)) {
30501
+ throw new ValidationError("Date must be in YYYY-MM-DD format");
30502
+ }
30503
+ const eventTime = new Date(Date.UTC(year, month - 1, day, 12, 0, 0));
30504
+ if (eventTime.getUTCFullYear() !== year || eventTime.getUTCMonth() + 1 !== month || eventTime.getUTCDate() !== day) {
30505
+ throw new ValidationError("Date must be a valid calendar date");
30506
+ }
30507
+ return eventTime.toISOString();
30508
+ }
30488
30509
  requireClient() {
30489
30510
  if (!this.deps.timeback) {
30490
30511
  logger16.error("Timeback client not available in context");
@@ -30560,7 +30581,6 @@ class TimebackAdminService {
30560
30581
  masteredUnitsForDay += masteredUnitsFromFact;
30561
30582
  }
30562
30583
  }
30563
- const roundedXpForDay = TimebackAdminService.roundXpToTenths(xpForDay);
30564
30584
  totalXpRaw += xpForDay;
30565
30585
  activeTimeSeconds += activeSecondsForDay;
30566
30586
  masteredUnits += masteredUnitsForDay;
@@ -30569,7 +30589,7 @@ class TimebackAdminService {
30569
30589
  }
30570
30590
  history.push({
30571
30591
  date: date3,
30572
- xpEarned: roundedXpForDay,
30592
+ xpEarned: TimebackAdminService.roundXpToTenths(xpForDay),
30573
30593
  activeTimeSeconds: activeSecondsForDay,
30574
30594
  masteredUnits: masteredUnitsForDay
30575
30595
  });
@@ -30883,6 +30903,7 @@ class TimebackAdminService {
30883
30903
  courseId: data.courseId,
30884
30904
  studentId: data.studentId,
30885
30905
  xpEarned: data.xp,
30906
+ eventTime: TimebackAdminService.toAttributionEventTime(data.date),
30886
30907
  reason: data.reason,
30887
30908
  actor,
30888
30909
  appName,
@@ -30897,6 +30918,7 @@ class TimebackAdminService {
30897
30918
  courseId: data.courseId,
30898
30919
  studentId: data.studentId,
30899
30920
  activeTimeSeconds: data.seconds,
30921
+ eventTime: TimebackAdminService.toAttributionEventTime(data.date),
30900
30922
  reason: data.reason,
30901
30923
  actor,
30902
30924
  appName,
@@ -30911,6 +30933,7 @@ class TimebackAdminService {
30911
30933
  courseId: data.courseId,
30912
30934
  studentId: data.studentId,
30913
30935
  masteredUnits: data.units,
30936
+ eventTime: TimebackAdminService.toAttributionEventTime(data.date),
30914
30937
  reason: data.reason,
30915
30938
  actor,
30916
30939
  appName,
@@ -34838,7 +34861,7 @@ function createCaliperNamespace(client) {
34838
34861
  "@context": CALIPER_CONSTANTS4.context,
34839
34862
  id: `urn:uuid:${crypto.randomUUID()}`,
34840
34863
  type: TIMEBACK_EVENT_TYPES4.timeSpentEvent,
34841
- eventTime: new Date().toISOString(),
34864
+ eventTime: data.eventTime || new Date().toISOString(),
34842
34865
  profile: CALIPER_CONSTANTS4.profile,
34843
34866
  actor: {
34844
34867
  id: urls.user(data.studentId),
@@ -35339,6 +35362,7 @@ class AdminEventRecorder {
35339
35362
  courseId: data.courseId,
35340
35363
  courseName: ctx.courseContext.courseName,
35341
35364
  xpEarned: data.xpEarned,
35365
+ eventTime: data.eventTime,
35342
35366
  subject: ctx.courseContext.subject,
35343
35367
  appName: ctx.appName,
35344
35368
  sensorUrl: ctx.sensorUrl,
@@ -35364,6 +35388,7 @@ class AdminEventRecorder {
35364
35388
  courseId: data.courseId,
35365
35389
  courseName: ctx.courseContext.courseName,
35366
35390
  activeTimeSeconds: data.activeTimeSeconds,
35391
+ eventTime: data.eventTime,
35367
35392
  subject: ctx.courseContext.subject,
35368
35393
  appName: ctx.appName,
35369
35394
  sensorUrl: ctx.sensorUrl,
@@ -35384,6 +35409,7 @@ class AdminEventRecorder {
35384
35409
  courseId: data.courseId,
35385
35410
  courseName: ctx.courseContext.courseName,
35386
35411
  masteredUnits: data.masteredUnits,
35412
+ eventTime: data.eventTime,
35387
35413
  subject: ctx.courseContext.subject,
35388
35414
  appName: ctx.appName,
35389
35415
  sensorUrl: ctx.sensorUrl,
@@ -93379,7 +93405,19 @@ function isTimebackGrade3(value) {
93379
93405
  function isTimebackSubject3(value) {
93380
93406
  return TIMEBACK_SUBJECTS5.includes(value);
93381
93407
  }
93382
- var TIMEBACK_GRADES, TIMEBACK_SUBJECTS5, TimebackGradeSchema, TimebackSubjectSchema, UpdateTimebackXpRequestSchema, EndActivityRequestSchema, PopulateStudentRequestSchema, DerivedPlatformCourseConfigSchema, TimebackBaseConfigSchema, PlatformTimebackSetupRequestSchema, AdminTimebackMutationBaseSchema, GrantTimebackXpRequestSchema, AdjustTimebackTimeRequestSchema, AdjustTimebackMasteryRequestSchema, ToggleCourseCompletionRequestSchema;
93408
+ function isValidAdminAttributionDate(value) {
93409
+ const match3 = value.match(/^(\d{4})-(\d{2})-(\d{2})$/);
93410
+ if (!match3) {
93411
+ return false;
93412
+ }
93413
+ const [, yearStr, monthStr, dayStr] = match3;
93414
+ const year3 = Number(yearStr);
93415
+ const month = Number(monthStr);
93416
+ const day = Number(dayStr);
93417
+ const date4 = new Date(Date.UTC(year3, month - 1, day, 12, 0, 0));
93418
+ return date4.getUTCFullYear() === year3 && date4.getUTCMonth() + 1 === month && date4.getUTCDate() === day;
93419
+ }
93420
+ var TIMEBACK_GRADES, TIMEBACK_SUBJECTS5, TimebackGradeSchema, TimebackSubjectSchema, UpdateTimebackXpRequestSchema, EndActivityRequestSchema, PopulateStudentRequestSchema, DerivedPlatformCourseConfigSchema, TimebackBaseConfigSchema, PlatformTimebackSetupRequestSchema, AdminTimebackMutationBaseSchema, AdminAttributionDateSchema, GrantTimebackXpRequestSchema, AdjustTimebackTimeRequestSchema, AdjustTimebackMasteryRequestSchema, ToggleCourseCompletionRequestSchema;
93383
93421
  var init_schemas11 = __esm(() => {
93384
93422
  init_esm();
93385
93423
  TIMEBACK_GRADES = [-1, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13];
@@ -93489,14 +93527,32 @@ var init_schemas11 = __esm(() => {
93489
93527
  studentId: exports_external.string().min(1),
93490
93528
  reason: exports_external.string().min(1)
93491
93529
  });
93530
+ AdminAttributionDateSchema = exports_external.string().superRefine((value, ctx) => {
93531
+ if (!/^\d{4}-\d{2}-\d{2}$/.test(value)) {
93532
+ ctx.addIssue({
93533
+ code: exports_external.ZodIssueCode.custom,
93534
+ message: "Date must be in YYYY-MM-DD format"
93535
+ });
93536
+ return;
93537
+ }
93538
+ if (!isValidAdminAttributionDate(value)) {
93539
+ ctx.addIssue({
93540
+ code: exports_external.ZodIssueCode.custom,
93541
+ message: "Date must be a valid calendar date"
93542
+ });
93543
+ }
93544
+ });
93492
93545
  GrantTimebackXpRequestSchema = AdminTimebackMutationBaseSchema.extend({
93493
- xp: exports_external.number().min(-100, "Amount must be between -100 and 100").max(100, "Amount must be between -100 and 100").refine((value) => value !== 0, { message: "Amount cannot be 0" })
93546
+ xp: exports_external.number().min(-100, "Amount must be between -100 and 100").max(100, "Amount must be between -100 and 100").refine((value) => value !== 0, { message: "Amount cannot be 0" }),
93547
+ date: AdminAttributionDateSchema.optional()
93494
93548
  });
93495
93549
  AdjustTimebackTimeRequestSchema = AdminTimebackMutationBaseSchema.extend({
93496
- seconds: exports_external.number().refine((value) => value !== 0, { message: "Time amount cannot be 0" })
93550
+ seconds: exports_external.number().refine((value) => value !== 0, { message: "Time amount cannot be 0" }),
93551
+ date: AdminAttributionDateSchema.optional()
93497
93552
  });
93498
93553
  AdjustTimebackMasteryRequestSchema = AdminTimebackMutationBaseSchema.extend({
93499
- units: exports_external.number().refine((value) => value !== 0, { message: "Units cannot be 0" })
93554
+ units: exports_external.number().refine((value) => value !== 0, { message: "Units cannot be 0" }),
93555
+ date: AdminAttributionDateSchema.optional()
93500
93556
  });
93501
93557
  ToggleCourseCompletionRequestSchema = exports_external.object({
93502
93558
  gameId: exports_external.string().uuid(),
@@ -95907,7 +95963,8 @@ var init_timeback_controller = __esm(() => {
95907
95963
  gameId: body2.gameId,
95908
95964
  courseId: body2.courseId,
95909
95965
  studentId: body2.studentId,
95910
- xp: body2.xp
95966
+ xp: body2.xp,
95967
+ date: body2.date
95911
95968
  });
95912
95969
  return ctx.services.timebackAdmin.grantManualXp(body2, ctx.user);
95913
95970
  });
@@ -95918,7 +95975,8 @@ var init_timeback_controller = __esm(() => {
95918
95975
  gameId: body2.gameId,
95919
95976
  courseId: body2.courseId,
95920
95977
  studentId: body2.studentId,
95921
- seconds: body2.seconds
95978
+ seconds: body2.seconds,
95979
+ date: body2.date
95922
95980
  });
95923
95981
  return ctx.services.timebackAdmin.adjustTimeSpent(body2, ctx.user);
95924
95982
  });
@@ -95929,7 +95987,8 @@ var init_timeback_controller = __esm(() => {
95929
95987
  gameId: body2.gameId,
95930
95988
  courseId: body2.courseId,
95931
95989
  studentId: body2.studentId,
95932
- units: body2.units
95990
+ units: body2.units,
95991
+ date: body2.date
95933
95992
  });
95934
95993
  return ctx.services.timebackAdmin.adjustMasteredUnits(body2, ctx.user);
95935
95994
  });
package/dist/server.js CHANGED
@@ -1309,7 +1309,7 @@ var package_default;
1309
1309
  var init_package = __esm(() => {
1310
1310
  package_default = {
1311
1311
  name: "@playcademy/sandbox",
1312
- version: "0.3.16",
1312
+ version: "0.3.17-beta.1",
1313
1313
  description: "Local development server for Playcademy game development",
1314
1314
  type: "module",
1315
1315
  exports: {
@@ -30484,6 +30484,27 @@ class TimebackAdminService {
30484
30484
  const rounded = Math.round(value * TimebackAdminService.XP_PRECISION_FACTOR) / TimebackAdminService.XP_PRECISION_FACTOR;
30485
30485
  return Object.is(rounded, -0) ? 0 : rounded;
30486
30486
  }
30487
+ static toAttributionEventTime(date3) {
30488
+ if (!date3) {
30489
+ return;
30490
+ }
30491
+ const match = date3.match(/^(\d{4})-(\d{2})-(\d{2})$/);
30492
+ if (!match) {
30493
+ throw new ValidationError("Date must be in YYYY-MM-DD format");
30494
+ }
30495
+ const [, yearStr, monthStr, dayStr] = match;
30496
+ const year = Number(yearStr);
30497
+ const month = Number(monthStr);
30498
+ const day = Number(dayStr);
30499
+ if (!Number.isInteger(year) || !Number.isInteger(month) || !Number.isInteger(day)) {
30500
+ throw new ValidationError("Date must be in YYYY-MM-DD format");
30501
+ }
30502
+ const eventTime = new Date(Date.UTC(year, month - 1, day, 12, 0, 0));
30503
+ if (eventTime.getUTCFullYear() !== year || eventTime.getUTCMonth() + 1 !== month || eventTime.getUTCDate() !== day) {
30504
+ throw new ValidationError("Date must be a valid calendar date");
30505
+ }
30506
+ return eventTime.toISOString();
30507
+ }
30487
30508
  requireClient() {
30488
30509
  if (!this.deps.timeback) {
30489
30510
  logger16.error("Timeback client not available in context");
@@ -30559,7 +30580,6 @@ class TimebackAdminService {
30559
30580
  masteredUnitsForDay += masteredUnitsFromFact;
30560
30581
  }
30561
30582
  }
30562
- const roundedXpForDay = TimebackAdminService.roundXpToTenths(xpForDay);
30563
30583
  totalXpRaw += xpForDay;
30564
30584
  activeTimeSeconds += activeSecondsForDay;
30565
30585
  masteredUnits += masteredUnitsForDay;
@@ -30568,7 +30588,7 @@ class TimebackAdminService {
30568
30588
  }
30569
30589
  history.push({
30570
30590
  date: date3,
30571
- xpEarned: roundedXpForDay,
30591
+ xpEarned: TimebackAdminService.roundXpToTenths(xpForDay),
30572
30592
  activeTimeSeconds: activeSecondsForDay,
30573
30593
  masteredUnits: masteredUnitsForDay
30574
30594
  });
@@ -30882,6 +30902,7 @@ class TimebackAdminService {
30882
30902
  courseId: data.courseId,
30883
30903
  studentId: data.studentId,
30884
30904
  xpEarned: data.xp,
30905
+ eventTime: TimebackAdminService.toAttributionEventTime(data.date),
30885
30906
  reason: data.reason,
30886
30907
  actor,
30887
30908
  appName,
@@ -30896,6 +30917,7 @@ class TimebackAdminService {
30896
30917
  courseId: data.courseId,
30897
30918
  studentId: data.studentId,
30898
30919
  activeTimeSeconds: data.seconds,
30920
+ eventTime: TimebackAdminService.toAttributionEventTime(data.date),
30899
30921
  reason: data.reason,
30900
30922
  actor,
30901
30923
  appName,
@@ -30910,6 +30932,7 @@ class TimebackAdminService {
30910
30932
  courseId: data.courseId,
30911
30933
  studentId: data.studentId,
30912
30934
  masteredUnits: data.units,
30935
+ eventTime: TimebackAdminService.toAttributionEventTime(data.date),
30913
30936
  reason: data.reason,
30914
30937
  actor,
30915
30938
  appName,
@@ -34837,7 +34860,7 @@ function createCaliperNamespace(client) {
34837
34860
  "@context": CALIPER_CONSTANTS4.context,
34838
34861
  id: `urn:uuid:${crypto.randomUUID()}`,
34839
34862
  type: TIMEBACK_EVENT_TYPES4.timeSpentEvent,
34840
- eventTime: new Date().toISOString(),
34863
+ eventTime: data.eventTime || new Date().toISOString(),
34841
34864
  profile: CALIPER_CONSTANTS4.profile,
34842
34865
  actor: {
34843
34866
  id: urls.user(data.studentId),
@@ -35338,6 +35361,7 @@ class AdminEventRecorder {
35338
35361
  courseId: data.courseId,
35339
35362
  courseName: ctx.courseContext.courseName,
35340
35363
  xpEarned: data.xpEarned,
35364
+ eventTime: data.eventTime,
35341
35365
  subject: ctx.courseContext.subject,
35342
35366
  appName: ctx.appName,
35343
35367
  sensorUrl: ctx.sensorUrl,
@@ -35363,6 +35387,7 @@ class AdminEventRecorder {
35363
35387
  courseId: data.courseId,
35364
35388
  courseName: ctx.courseContext.courseName,
35365
35389
  activeTimeSeconds: data.activeTimeSeconds,
35390
+ eventTime: data.eventTime,
35366
35391
  subject: ctx.courseContext.subject,
35367
35392
  appName: ctx.appName,
35368
35393
  sensorUrl: ctx.sensorUrl,
@@ -35383,6 +35408,7 @@ class AdminEventRecorder {
35383
35408
  courseId: data.courseId,
35384
35409
  courseName: ctx.courseContext.courseName,
35385
35410
  masteredUnits: data.masteredUnits,
35411
+ eventTime: data.eventTime,
35386
35412
  subject: ctx.courseContext.subject,
35387
35413
  appName: ctx.appName,
35388
35414
  sensorUrl: ctx.sensorUrl,
@@ -93378,7 +93404,19 @@ function isTimebackGrade3(value) {
93378
93404
  function isTimebackSubject3(value) {
93379
93405
  return TIMEBACK_SUBJECTS5.includes(value);
93380
93406
  }
93381
- var TIMEBACK_GRADES, TIMEBACK_SUBJECTS5, TimebackGradeSchema, TimebackSubjectSchema, UpdateTimebackXpRequestSchema, EndActivityRequestSchema, PopulateStudentRequestSchema, DerivedPlatformCourseConfigSchema, TimebackBaseConfigSchema, PlatformTimebackSetupRequestSchema, AdminTimebackMutationBaseSchema, GrantTimebackXpRequestSchema, AdjustTimebackTimeRequestSchema, AdjustTimebackMasteryRequestSchema, ToggleCourseCompletionRequestSchema;
93407
+ function isValidAdminAttributionDate(value) {
93408
+ const match3 = value.match(/^(\d{4})-(\d{2})-(\d{2})$/);
93409
+ if (!match3) {
93410
+ return false;
93411
+ }
93412
+ const [, yearStr, monthStr, dayStr] = match3;
93413
+ const year3 = Number(yearStr);
93414
+ const month = Number(monthStr);
93415
+ const day = Number(dayStr);
93416
+ const date4 = new Date(Date.UTC(year3, month - 1, day, 12, 0, 0));
93417
+ return date4.getUTCFullYear() === year3 && date4.getUTCMonth() + 1 === month && date4.getUTCDate() === day;
93418
+ }
93419
+ var TIMEBACK_GRADES, TIMEBACK_SUBJECTS5, TimebackGradeSchema, TimebackSubjectSchema, UpdateTimebackXpRequestSchema, EndActivityRequestSchema, PopulateStudentRequestSchema, DerivedPlatformCourseConfigSchema, TimebackBaseConfigSchema, PlatformTimebackSetupRequestSchema, AdminTimebackMutationBaseSchema, AdminAttributionDateSchema, GrantTimebackXpRequestSchema, AdjustTimebackTimeRequestSchema, AdjustTimebackMasteryRequestSchema, ToggleCourseCompletionRequestSchema;
93382
93420
  var init_schemas11 = __esm(() => {
93383
93421
  init_esm();
93384
93422
  TIMEBACK_GRADES = [-1, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13];
@@ -93488,14 +93526,32 @@ var init_schemas11 = __esm(() => {
93488
93526
  studentId: exports_external.string().min(1),
93489
93527
  reason: exports_external.string().min(1)
93490
93528
  });
93529
+ AdminAttributionDateSchema = exports_external.string().superRefine((value, ctx) => {
93530
+ if (!/^\d{4}-\d{2}-\d{2}$/.test(value)) {
93531
+ ctx.addIssue({
93532
+ code: exports_external.ZodIssueCode.custom,
93533
+ message: "Date must be in YYYY-MM-DD format"
93534
+ });
93535
+ return;
93536
+ }
93537
+ if (!isValidAdminAttributionDate(value)) {
93538
+ ctx.addIssue({
93539
+ code: exports_external.ZodIssueCode.custom,
93540
+ message: "Date must be a valid calendar date"
93541
+ });
93542
+ }
93543
+ });
93491
93544
  GrantTimebackXpRequestSchema = AdminTimebackMutationBaseSchema.extend({
93492
- xp: exports_external.number().min(-100, "Amount must be between -100 and 100").max(100, "Amount must be between -100 and 100").refine((value) => value !== 0, { message: "Amount cannot be 0" })
93545
+ xp: exports_external.number().min(-100, "Amount must be between -100 and 100").max(100, "Amount must be between -100 and 100").refine((value) => value !== 0, { message: "Amount cannot be 0" }),
93546
+ date: AdminAttributionDateSchema.optional()
93493
93547
  });
93494
93548
  AdjustTimebackTimeRequestSchema = AdminTimebackMutationBaseSchema.extend({
93495
- seconds: exports_external.number().refine((value) => value !== 0, { message: "Time amount cannot be 0" })
93549
+ seconds: exports_external.number().refine((value) => value !== 0, { message: "Time amount cannot be 0" }),
93550
+ date: AdminAttributionDateSchema.optional()
93496
93551
  });
93497
93552
  AdjustTimebackMasteryRequestSchema = AdminTimebackMutationBaseSchema.extend({
93498
- units: exports_external.number().refine((value) => value !== 0, { message: "Units cannot be 0" })
93553
+ units: exports_external.number().refine((value) => value !== 0, { message: "Units cannot be 0" }),
93554
+ date: AdminAttributionDateSchema.optional()
93499
93555
  });
93500
93556
  ToggleCourseCompletionRequestSchema = exports_external.object({
93501
93557
  gameId: exports_external.string().uuid(),
@@ -95906,7 +95962,8 @@ var init_timeback_controller = __esm(() => {
95906
95962
  gameId: body2.gameId,
95907
95963
  courseId: body2.courseId,
95908
95964
  studentId: body2.studentId,
95909
- xp: body2.xp
95965
+ xp: body2.xp,
95966
+ date: body2.date
95910
95967
  });
95911
95968
  return ctx.services.timebackAdmin.grantManualXp(body2, ctx.user);
95912
95969
  });
@@ -95917,7 +95974,8 @@ var init_timeback_controller = __esm(() => {
95917
95974
  gameId: body2.gameId,
95918
95975
  courseId: body2.courseId,
95919
95976
  studentId: body2.studentId,
95920
- seconds: body2.seconds
95977
+ seconds: body2.seconds,
95978
+ date: body2.date
95921
95979
  });
95922
95980
  return ctx.services.timebackAdmin.adjustTimeSpent(body2, ctx.user);
95923
95981
  });
@@ -95928,7 +95986,8 @@ var init_timeback_controller = __esm(() => {
95928
95986
  gameId: body2.gameId,
95929
95987
  courseId: body2.courseId,
95930
95988
  studentId: body2.studentId,
95931
- units: body2.units
95989
+ units: body2.units,
95990
+ date: body2.date
95932
95991
  });
95933
95992
  return ctx.services.timebackAdmin.adjustMasteredUnits(body2, ctx.user);
95934
95993
  });
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@playcademy/sandbox",
3
- "version": "0.3.16",
3
+ "version": "0.3.17-beta.1",
4
4
  "description": "Local development server for Playcademy game development",
5
5
  "type": "module",
6
6
  "exports": {