@playcademy/vite-plugin 0.3.3-beta.1 → 0.3.3-beta.2

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 +295 -24
  2. package/package.json +1 -1
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: "0.3.3-beta.1",
23749
+ version: "0.3.3-beta.2",
23750
23750
  type: "module",
23751
23751
  exports: {
23752
23752
  ".": {
@@ -24339,6 +24339,8 @@ var TIMEBACK_COURSE_DEFAULTS;
24339
24339
  var TIMEBACK_RESOURCE_DEFAULTS;
24340
24340
  var TIMEBACK_COMPONENT_DEFAULTS;
24341
24341
  var TIMEBACK_COMPONENT_RESOURCE_DEFAULTS;
24342
+ var TIMEBACK_GAME_METRIC_DECIMAL_PLACES;
24343
+ var TIMEBACK_GAME_METRIC_COMPARISON_TOLERANCE;
24342
24344
  var init_timeback2 = __esm(() => {
24343
24345
  TIMEBACK_ROUTES = {
24344
24346
  END_ACTIVITY: "/integrations/timeback/end-activity",
@@ -24383,6 +24385,17 @@ var init_timeback2 = __esm(() => {
24383
24385
  sortOrder: 1,
24384
24386
  lessonType: "quiz"
24385
24387
  };
24388
+ TIMEBACK_GAME_METRIC_DECIMAL_PLACES = {
24389
+ xp: 1,
24390
+ mastery: 0,
24391
+ score: 2
24392
+ };
24393
+ TIMEBACK_GAME_METRIC_COMPARISON_TOLERANCE = {
24394
+ xp: 0.5 / 10 ** TIMEBACK_GAME_METRIC_DECIMAL_PLACES.xp,
24395
+ mastery: 0,
24396
+ time: 60,
24397
+ score: 0.5 / 10 ** TIMEBACK_GAME_METRIC_DECIMAL_PLACES.score
24398
+ };
24386
24399
  });
24387
24400
  var WORKER_NAMING;
24388
24401
  var SECRETS_PREFIX = "secrets_";
@@ -25177,7 +25190,7 @@ var package_default2;
25177
25190
  var init_package = __esm(() => {
25178
25191
  package_default2 = {
25179
25192
  name: "@playcademy/sandbox",
25180
- version: "0.4.1-beta.1",
25193
+ version: "0.4.1-beta.2",
25181
25194
  description: "Local development server for Playcademy game development",
25182
25195
  type: "module",
25183
25196
  exports: {
@@ -53873,7 +53886,7 @@ var CourseGoalsSchema;
53873
53886
  var UpdateGameTimebackIntegrationRequestSchema;
53874
53887
  var TimebackActivityDataSchema;
53875
53888
  var EndActivityRequestSchema;
53876
- var GameActivityMetricsSchema;
53889
+ var GameRunMetricsSchema;
53877
53890
  var GameCourseMetricsSchema;
53878
53891
  var GameMetricsResponseSchema;
53879
53892
  var AdvanceCourseRequestSchema;
@@ -53972,22 +53985,22 @@ var init_schemas4 = __esm(() => {
53972
53985
  message: "Cannot provide both masteredUnits and masteredUnitsAbsolute",
53973
53986
  path: ["masteredUnitsAbsolute"]
53974
53987
  });
53975
- GameActivityMetricsSchema = exports_external.object({
53988
+ GameRunMetricsSchema = exports_external.object({
53989
+ runId: exports_external.string().uuid(),
53976
53990
  activityId: exports_external.string().min(1),
53977
53991
  activityName: exports_external.string().optional(),
53978
- totalXp: exports_external.number().nonnegative(),
53979
- masteredUnits: exports_external.number().int().nonnegative(),
53980
- activeTimeSeconds: exports_external.number().nonnegative(),
53981
- completionCount: exports_external.number().int().nonnegative(),
53982
- lastCompletedAt: exports_external.string().datetime().optional()
53992
+ totalXp: exports_external.number().nonnegative().optional(),
53993
+ masteredUnits: exports_external.number().int().nonnegative().optional(),
53994
+ activeTimeSeconds: exports_external.number().nonnegative().optional(),
53995
+ score: exports_external.number().min(0).max(100).optional()
53983
53996
  });
53984
53997
  GameCourseMetricsSchema = exports_external.object({
53985
53998
  grade: TimebackGradeSchema,
53986
53999
  subject: TimebackSubjectSchema,
53987
- totalXp: exports_external.number().nonnegative(),
53988
- masteredUnits: exports_external.number().int().nonnegative(),
53989
- activeTimeSeconds: exports_external.number().nonnegative(),
53990
- activities: exports_external.array(GameActivityMetricsSchema).optional()
54000
+ totalXp: exports_external.number().nonnegative().optional(),
54001
+ masteredUnits: exports_external.number().int().nonnegative().optional(),
54002
+ activeTimeSeconds: exports_external.number().nonnegative().optional(),
54003
+ activities: exports_external.array(GameRunMetricsSchema).optional()
53991
54004
  });
53992
54005
  GameMetricsResponseSchema = exports_external.object({
53993
54006
  studentId: exports_external.string().min(1),
@@ -54257,6 +54270,122 @@ function compareEnrollmentsByRecency(a, b) {
54257
54270
  var init_timeback_admin_util = __esm(() => {
54258
54271
  init_errors();
54259
54272
  });
54273
+ function createMetricRow(definition) {
54274
+ const { gameValue, kind, metric, timebackValue, tolerance } = definition;
54275
+ if (timebackValue === undefined && gameValue === undefined) {
54276
+ return null;
54277
+ }
54278
+ if (gameValue === undefined) {
54279
+ return {
54280
+ metric,
54281
+ kind,
54282
+ status: "not_reported_by_game",
54283
+ ...timebackValue !== undefined ? { timebackValue } : {}
54284
+ };
54285
+ }
54286
+ if (timebackValue === undefined) {
54287
+ return {
54288
+ metric,
54289
+ kind,
54290
+ status: "not_recorded_by_timeback",
54291
+ gameValue
54292
+ };
54293
+ }
54294
+ const delta = gameValue - timebackValue;
54295
+ const isDiscrepant = tolerance === 0 ? delta !== 0 : Math.abs(delta) >= tolerance;
54296
+ return {
54297
+ metric,
54298
+ kind,
54299
+ status: isDiscrepant ? "discrepant" : "matched",
54300
+ timebackValue,
54301
+ gameValue,
54302
+ delta
54303
+ };
54304
+ }
54305
+ function createRunComparison(activity, gameRun) {
54306
+ const runId = activity.runId ?? "";
54307
+ if (!gameRun) {
54308
+ return {
54309
+ runId,
54310
+ status: "not_reported",
54311
+ discrepancyCount: 0,
54312
+ rows: []
54313
+ };
54314
+ }
54315
+ const rows = [
54316
+ createMetricRow({
54317
+ metric: "xp",
54318
+ kind: "number",
54319
+ timebackValue: activity.xpDelta,
54320
+ gameValue: gameRun.totalXp,
54321
+ tolerance: TIMEBACK_GAME_METRIC_COMPARISON_TOLERANCE.xp
54322
+ }),
54323
+ createMetricRow({
54324
+ metric: "mastery",
54325
+ kind: "number",
54326
+ timebackValue: activity.masteredUnitsDelta,
54327
+ gameValue: gameRun.masteredUnits,
54328
+ tolerance: TIMEBACK_GAME_METRIC_COMPARISON_TOLERANCE.mastery
54329
+ }),
54330
+ createMetricRow({
54331
+ metric: "time",
54332
+ kind: "time",
54333
+ timebackValue: activity.timeDeltaSeconds,
54334
+ gameValue: gameRun.activeTimeSeconds,
54335
+ tolerance: TIMEBACK_GAME_METRIC_COMPARISON_TOLERANCE.time
54336
+ }),
54337
+ createMetricRow({
54338
+ metric: "score",
54339
+ kind: "percent",
54340
+ timebackValue: activity.score,
54341
+ gameValue: gameRun.score,
54342
+ tolerance: TIMEBACK_GAME_METRIC_COMPARISON_TOLERANCE.score
54343
+ })
54344
+ ].filter((row) => row !== null);
54345
+ const discrepancyCount = rows.filter((row) => row.status === "discrepant").length;
54346
+ return {
54347
+ runId,
54348
+ status: discrepancyCount > 0 ? "discrepant" : "matched",
54349
+ discrepancyCount,
54350
+ rows
54351
+ };
54352
+ }
54353
+ function summarizeGameRunMetricsComparison(comparison) {
54354
+ return {
54355
+ runId: comparison.runId,
54356
+ status: comparison.status,
54357
+ discrepancyCount: comparison.discrepancyCount,
54358
+ ...comparison.reason ? { reason: comparison.reason } : {}
54359
+ };
54360
+ }
54361
+ function buildGameRunMetricComparisons(activities, course, response) {
54362
+ const activitiesWithRunIds = activities.filter((activity) => typeof activity.runId === "string" && activity.runId.length > 0);
54363
+ const comparisons = new Map;
54364
+ if (activitiesWithRunIds.length === 0) {
54365
+ return comparisons;
54366
+ }
54367
+ if (!response.supported) {
54368
+ for (const activity of activitiesWithRunIds) {
54369
+ comparisons.set(activity.runId, {
54370
+ runId: activity.runId,
54371
+ status: "unavailable",
54372
+ discrepancyCount: 0,
54373
+ reason: response.reason,
54374
+ rows: []
54375
+ });
54376
+ }
54377
+ return comparisons;
54378
+ }
54379
+ const gameCourseMetrics = response.metrics.courses.find((gameCourse) => gameCourse.grade === course.grade && gameCourse.subject === course.subject);
54380
+ const gameRunsById = new Map(gameCourseMetrics?.activities?.map((gameRun) => [gameRun.runId.toLowerCase(), gameRun]));
54381
+ for (const activity of activitiesWithRunIds) {
54382
+ comparisons.set(activity.runId, createRunComparison(activity, gameRunsById.get(activity.runId.toLowerCase())));
54383
+ }
54384
+ return comparisons;
54385
+ }
54386
+ var init_timeback_game_metrics_comparison_util = __esm(() => {
54387
+ init_src();
54388
+ });
54260
54389
  async function upsertMasteryCompletionEntry(params) {
54261
54390
  const { client, courseId, studentId, appName, action } = params;
54262
54391
  const ids = deriveSourcedIds(courseId);
@@ -54643,6 +54772,8 @@ class TimebackAdminService {
54643
54772
  static ANALYTICS_CONCURRENCY = 8;
54644
54773
  static MASTERABLE_UNITS_CONCURRENCY = 4;
54645
54774
  static GAME_METRICS_FETCH_TIMEOUT_MS = 1e4;
54775
+ static GAME_METRICS_LIST_FETCH_TIMEOUT_MS = 3000;
54776
+ static GAME_METRICS_RUN_IDS_PER_REQUEST = 50;
54646
54777
  constructor(deps) {
54647
54778
  this.deps = deps;
54648
54779
  }
@@ -54652,13 +54783,42 @@ class TimebackAdminService {
54652
54783
  }
54653
54784
  return this.deps.config.localGameUrls[slug2] ?? deployedUrl;
54654
54785
  }
54655
- static resolveGameMetricsUrl(baseUrl) {
54786
+ static resolveGameMetricsUrl(baseUrl, runIds) {
54656
54787
  try {
54657
- return new URL("/__playcademy/metrics", baseUrl);
54788
+ const url2 = new URL("/__playcademy/metrics", baseUrl);
54789
+ for (const runId of runIds ?? []) {
54790
+ url2.searchParams.append("runId", runId);
54791
+ }
54792
+ return url2;
54658
54793
  } catch {
54659
54794
  return null;
54660
54795
  }
54661
54796
  }
54797
+ static normalizeRunIds(runIds, limit = Number.POSITIVE_INFINITY) {
54798
+ const normalized = [];
54799
+ const seen = new Set;
54800
+ for (const runId of runIds ?? []) {
54801
+ const value = runId.trim().toLowerCase();
54802
+ if (isValidUUID(value) && !seen.has(value)) {
54803
+ seen.add(value);
54804
+ normalized.push(value);
54805
+ if (normalized.length >= limit) {
54806
+ break;
54807
+ }
54808
+ }
54809
+ }
54810
+ return normalized;
54811
+ }
54812
+ static chunkRunIds(runIds) {
54813
+ const chunks = [];
54814
+ for (let index2 = 0;index2 < runIds.length; index2 += this.GAME_METRICS_RUN_IDS_PER_REQUEST) {
54815
+ chunks.push(runIds.slice(index2, index2 + this.GAME_METRICS_RUN_IDS_PER_REQUEST));
54816
+ }
54817
+ return chunks;
54818
+ }
54819
+ static isAbortError(error) {
54820
+ return error instanceof Error && error.name === "AbortError";
54821
+ }
54662
54822
  static roundXpToTenths(value) {
54663
54823
  const rounded = Math.round(value * TimebackAdminService.XP_PRECISION_FACTOR) / TimebackAdminService.XP_PRECISION_FACTOR;
54664
54824
  return Object.is(rounded, -0) ? 0 : rounded;
@@ -54819,6 +54979,56 @@ class TimebackAdminService {
54819
54979
  const remediationItems = events.map((event) => mapCaliperEventToRemediationActivity(event, relevantCourseIds)).filter((item) => Boolean(item));
54820
54980
  return [...groupedGameplayItems, ...remediationItems].toSorted((a, b) => b.occurredAt.localeCompare(a.occurredAt));
54821
54981
  }
54982
+ async getGameMetricComparisonsForActivities(user, options) {
54983
+ const runIds = TimebackAdminService.normalizeRunIds(options.activities.map((activity) => activity.runId).filter((runId) => Boolean(runId)));
54984
+ if (runIds.length === 0) {
54985
+ return new Map;
54986
+ }
54987
+ const activitiesByRunId = new Map(options.activities.filter((activity) => typeof activity.runId === "string" && activity.runId.length > 0).map((activity) => [activity.runId.toLowerCase(), activity]));
54988
+ const comparisons = new Map;
54989
+ await Promise.all(TimebackAdminService.chunkRunIds(runIds).map(async (chunk) => {
54990
+ const activities = [];
54991
+ for (const runId of chunk) {
54992
+ const activity = activitiesByRunId.get(runId);
54993
+ if (activity) {
54994
+ activities.push(activity);
54995
+ }
54996
+ }
54997
+ if (activities.length === 0) {
54998
+ return;
54999
+ }
55000
+ let response;
55001
+ try {
55002
+ response = await this.getGameMetrics(options.gameId, options.studentId, user, {
55003
+ runIds: chunk,
55004
+ timeoutMs: options.timeoutMs
55005
+ });
55006
+ } catch (error) {
55007
+ response = {
55008
+ supported: false,
55009
+ reason: "fetch_failed",
55010
+ details: error instanceof Error ? error.message : String(error)
55011
+ };
55012
+ }
55013
+ for (const [runId, comparison] of buildGameRunMetricComparisons(activities, options.course, response)) {
55014
+ comparisons.set(runId, comparison);
55015
+ }
55016
+ }));
55017
+ return comparisons;
55018
+ }
55019
+ async attachGameMetricSummariesToActivities(user, options) {
55020
+ const comparisons = await this.getGameMetricComparisonsForActivities(user, options);
55021
+ if (comparisons.size === 0) {
55022
+ return [...options.activities];
55023
+ }
55024
+ return options.activities.map((activity) => {
55025
+ const comparison = activity.runId ? comparisons.get(activity.runId) : undefined;
55026
+ return comparison ? {
55027
+ ...activity,
55028
+ gameMetricsComparison: summarizeGameRunMetricsComparison(comparison)
55029
+ } : activity;
55030
+ });
55031
+ }
54822
55032
  async getStudentEnrollmentsByCourseId(client, studentId, courseIds, options) {
54823
55033
  const enrollments = new Map;
54824
55034
  const allEnrollments = new Map;
@@ -54978,7 +55188,7 @@ class TimebackAdminService {
54978
55188
  });
54979
55189
  return { gameId, courseId, students: deduped };
54980
55190
  }
54981
- async getGameMetrics(gameId, timebackId, user) {
55191
+ async getGameMetrics(gameId, timebackId, user, options) {
54982
55192
  const client = this.requireClient();
54983
55193
  await this.deps.validateGameManagementAccess(user, gameId);
54984
55194
  const [targetUser, integrations, game2, deployment] = await Promise.all([
@@ -55013,7 +55223,8 @@ class TimebackAdminService {
55013
55223
  if (!metricsBaseUrl) {
55014
55224
  return { supported: false, reason: "no_active_deployment" };
55015
55225
  }
55016
- const metricsUrl = TimebackAdminService.resolveGameMetricsUrl(metricsBaseUrl);
55226
+ const runIds = TimebackAdminService.normalizeRunIds(options?.runIds, TimebackAdminService.GAME_METRICS_RUN_IDS_PER_REQUEST);
55227
+ const metricsUrl = TimebackAdminService.resolveGameMetricsUrl(metricsBaseUrl, runIds);
55017
55228
  if (!metricsUrl) {
55018
55229
  return {
55019
55230
  supported: false,
@@ -55023,7 +55234,7 @@ class TimebackAdminService {
55023
55234
  }
55024
55235
  const token = await this.deps.mintPlatformServiceToken(gameId, targetUser.id);
55025
55236
  const controller = new AbortController;
55026
- const timeout = setTimeout(() => controller.abort(), TimebackAdminService.GAME_METRICS_FETCH_TIMEOUT_MS);
55237
+ const timeout = setTimeout(() => controller.abort(), options?.timeoutMs ?? TimebackAdminService.GAME_METRICS_FETCH_TIMEOUT_MS);
55027
55238
  let response;
55028
55239
  try {
55029
55240
  response = await fetch(metricsUrl, {
@@ -55035,10 +55246,19 @@ class TimebackAdminService {
55035
55246
  signal: controller.signal
55036
55247
  });
55037
55248
  } catch (error) {
55249
+ const timedOut = TimebackAdminService.isAbortError(error);
55250
+ let details;
55251
+ if (timedOut) {
55252
+ details = "Game metrics request timed out";
55253
+ } else if (error instanceof Error) {
55254
+ details = error.message;
55255
+ } else {
55256
+ details = String(error);
55257
+ }
55038
55258
  return {
55039
55259
  supported: false,
55040
- reason: "fetch_failed",
55041
- details: error instanceof Error ? error.message : String(error)
55260
+ reason: timedOut ? "timeout" : "fetch_failed",
55261
+ details
55042
55262
  };
55043
55263
  } finally {
55044
55264
  clearTimeout(timeout);
@@ -55142,7 +55362,14 @@ class TimebackAdminService {
55142
55362
  const allActivities = await this.listRecentActivityForStudent(client, studentId, gameSource, relevantCourseIds, fetchLimit);
55143
55363
  const activities = allActivities.slice(safeOffset, safeOffset + safeLimit);
55144
55364
  const hasMore = allActivities.length > safeOffset + safeLimit;
55145
- return { activities, hasMore };
55365
+ const activitiesWithGameMetrics = await this.attachGameMetricSummariesToActivities(user, {
55366
+ gameId,
55367
+ studentId,
55368
+ course: { grade: integration.grade, subject: integration.subject },
55369
+ activities,
55370
+ timeoutMs: TimebackAdminService.GAME_METRICS_LIST_FETCH_TIMEOUT_MS
55371
+ });
55372
+ return { activities: activitiesWithGameMetrics, hasMore };
55146
55373
  }
55147
55374
  async getActivityDetail(user, options) {
55148
55375
  const { gameId, studentId, courseId, activityId, runId } = options;
@@ -55178,7 +55405,22 @@ class TimebackAdminService {
55178
55405
  if (!activity) {
55179
55406
  throw new NotFoundError("Activity", activityId);
55180
55407
  }
55181
- return { activity, rawEvents: matchedEvents };
55408
+ const comparisons = await this.getGameMetricComparisonsForActivities(user, {
55409
+ gameId,
55410
+ studentId,
55411
+ course: { grade: integration.grade, subject: integration.subject },
55412
+ activities: [activity]
55413
+ });
55414
+ const gameMetricsComparison = activity.runId ? comparisons.get(activity.runId) : undefined;
55415
+ const activityWithGameMetrics = gameMetricsComparison ? {
55416
+ ...activity,
55417
+ gameMetricsComparison: summarizeGameRunMetricsComparison(gameMetricsComparison)
55418
+ } : activity;
55419
+ return {
55420
+ activity: activityWithGameMetrics,
55421
+ rawEvents: matchedEvents,
55422
+ ...gameMetricsComparison ? { gameMetricsComparison } : {}
55423
+ };
55182
55424
  }
55183
55425
  async grantManualXp(data, user) {
55184
55426
  const { client, sensorUrl, appName, actor } = await this.resolveAdminMutationContext(data.gameId, data.courseId, user, data.studentId);
@@ -55466,6 +55708,7 @@ var init_timeback_admin_service = __esm(() => {
55466
55708
  init_errors();
55467
55709
  init_timeback_admin_metrics_util();
55468
55710
  init_timeback_admin_util();
55711
+ init_timeback_game_metrics_comparison_util();
55469
55712
  init_timeback_mastery_completion_util();
55470
55713
  init_timeback_util();
55471
55714
  logger17 = log.scope("TimebackAdminService");
@@ -120916,15 +121159,19 @@ var init_timeback_controller = __esm(() => {
120916
121159
  getGameMetrics = requireGameManagementAccess(async (ctx) => {
120917
121160
  const gameId = ctx.params.gameId;
120918
121161
  const timebackId = ctx.params.timebackId;
121162
+ const runIds = [
121163
+ ...new Set(ctx.url.searchParams.getAll("runId").map((runId) => runId.trim().toLowerCase()).filter(isValidUUID))
121164
+ ];
120919
121165
  if (!gameId || !timebackId) {
120920
121166
  throw ApiError.badRequest("Missing gameId or timebackId path parameter");
120921
121167
  }
120922
121168
  logger45.debug("Getting game metrics", {
120923
121169
  requesterId: ctx.user.id,
120924
121170
  gameId,
120925
- timebackId
121171
+ timebackId,
121172
+ runIds
120926
121173
  });
120927
- return ctx.services.timebackAdmin.getGameMetrics(gameId, timebackId, ctx.user);
121174
+ return ctx.services.timebackAdmin.getGameMetrics(gameId, timebackId, ctx.user, { runIds });
120928
121175
  });
120929
121176
  getStudentActivity = requireGameManagementAccess(async (ctx) => {
120930
121177
  const timebackId = ctx.params.timebackId;
@@ -122767,6 +123014,17 @@ var POSTHOG_CONFIG = {
122767
123014
  var TIMEBACK_ORG_SOURCED_ID2 = "PLAYCADEMY";
122768
123015
  var TIMEBACK_ORG_NAME2 = "Playcademy Studios";
122769
123016
  var TIMEBACK_ORG_TYPE2 = "department";
123017
+ var TIMEBACK_GAME_METRIC_DECIMAL_PLACES2 = {
123018
+ xp: 1,
123019
+ mastery: 0,
123020
+ score: 2
123021
+ };
123022
+ var TIMEBACK_GAME_METRIC_COMPARISON_TOLERANCE2 = {
123023
+ xp: 0.5 / 10 ** TIMEBACK_GAME_METRIC_DECIMAL_PLACES2.xp,
123024
+ mastery: 0,
123025
+ time: 60,
123026
+ score: 0.5 / 10 ** TIMEBACK_GAME_METRIC_DECIMAL_PLACES2.score
123027
+ };
122770
123028
  // src/lib/sandbox/timeback.ts
122771
123029
  function detectTimebackOptions() {
122772
123030
  if (process.env.TIMEBACK_LOCAL === "true") {
@@ -122983,6 +123241,8 @@ var TIMEBACK_COURSE_DEFAULTS2;
122983
123241
  var TIMEBACK_RESOURCE_DEFAULTS2;
122984
123242
  var TIMEBACK_COMPONENT_DEFAULTS2;
122985
123243
  var TIMEBACK_COMPONENT_RESOURCE_DEFAULTS2;
123244
+ var TIMEBACK_GAME_METRIC_DECIMAL_PLACES3;
123245
+ var TIMEBACK_GAME_METRIC_COMPARISON_TOLERANCE3;
122986
123246
  var init_timeback7 = __esm8(() => {
122987
123247
  TIMEBACK_ROUTES2 = {
122988
123248
  END_ACTIVITY: "/integrations/timeback/end-activity",
@@ -123027,6 +123287,17 @@ var init_timeback7 = __esm8(() => {
123027
123287
  sortOrder: 1,
123028
123288
  lessonType: "quiz"
123029
123289
  };
123290
+ TIMEBACK_GAME_METRIC_DECIMAL_PLACES3 = {
123291
+ xp: 1,
123292
+ mastery: 0,
123293
+ score: 2
123294
+ };
123295
+ TIMEBACK_GAME_METRIC_COMPARISON_TOLERANCE3 = {
123296
+ xp: 0.5 / 10 ** TIMEBACK_GAME_METRIC_DECIMAL_PLACES3.xp,
123297
+ mastery: 0,
123298
+ time: 60,
123299
+ score: 0.5 / 10 ** TIMEBACK_GAME_METRIC_DECIMAL_PLACES3.score
123300
+ };
123030
123301
  });
123031
123302
  var WORKER_NAMING2;
123032
123303
  var init_cloudflare2 = __esm8(() => {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@playcademy/vite-plugin",
3
- "version": "0.3.3-beta.1",
3
+ "version": "0.3.3-beta.2",
4
4
  "type": "module",
5
5
  "exports": {
6
6
  ".": {