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

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.
@@ -0,0 +1,12 @@
1
+ /**
2
+ * Virtual module for the dev shell's SDK import
3
+ *
4
+ * The dev shell (shell.html) needs MessageEvents and messaging from
5
+ * @playcademy/sdk. Rather than loading the SDK from a remote CDN via
6
+ * an importmap, we serve a virtual module that re-exports the needed
7
+ * symbols. Vite resolves @playcademy/sdk through normal node resolution,
8
+ * so the shell always uses the locally installed SDK — whether that's a
9
+ * workspace link or an npm-installed version.
10
+ */
11
+ export declare function resolveShellSdkId(id: string): string | undefined;
12
+ export declare function loadShellSdk(id: string): string | undefined;
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.3",
23750
23750
  type: "module",
23751
23751
  exports: {
23752
23752
  ".": {
@@ -23779,6 +23779,7 @@ var package_default = {
23779
23779
  "@types/bun": "1.3.5"
23780
23780
  },
23781
23781
  peerDependencies: {
23782
+ "@playcademy/sdk": ">=0.10.0",
23782
23783
  typescript: "^5",
23783
23784
  vite: "^5 || ^6"
23784
23785
  }
@@ -24339,6 +24340,8 @@ var TIMEBACK_COURSE_DEFAULTS;
24339
24340
  var TIMEBACK_RESOURCE_DEFAULTS;
24340
24341
  var TIMEBACK_COMPONENT_DEFAULTS;
24341
24342
  var TIMEBACK_COMPONENT_RESOURCE_DEFAULTS;
24343
+ var TIMEBACK_GAME_METRIC_DECIMAL_PLACES;
24344
+ var TIMEBACK_GAME_METRIC_COMPARISON_TOLERANCE;
24342
24345
  var init_timeback2 = __esm(() => {
24343
24346
  TIMEBACK_ROUTES = {
24344
24347
  END_ACTIVITY: "/integrations/timeback/end-activity",
@@ -24383,6 +24386,17 @@ var init_timeback2 = __esm(() => {
24383
24386
  sortOrder: 1,
24384
24387
  lessonType: "quiz"
24385
24388
  };
24389
+ TIMEBACK_GAME_METRIC_DECIMAL_PLACES = {
24390
+ xp: 1,
24391
+ mastery: 0,
24392
+ score: 2
24393
+ };
24394
+ TIMEBACK_GAME_METRIC_COMPARISON_TOLERANCE = {
24395
+ xp: 0.5 / 10 ** TIMEBACK_GAME_METRIC_DECIMAL_PLACES.xp,
24396
+ mastery: 0,
24397
+ time: 60,
24398
+ score: 0.5 / 10 ** TIMEBACK_GAME_METRIC_DECIMAL_PLACES.score
24399
+ };
24386
24400
  });
24387
24401
  var WORKER_NAMING;
24388
24402
  var SECRETS_PREFIX = "secrets_";
@@ -25177,7 +25191,7 @@ var package_default2;
25177
25191
  var init_package = __esm(() => {
25178
25192
  package_default2 = {
25179
25193
  name: "@playcademy/sandbox",
25180
- version: "0.4.1-beta.1",
25194
+ version: "0.4.1-beta.3",
25181
25195
  description: "Local development server for Playcademy game development",
25182
25196
  type: "module",
25183
25197
  exports: {
@@ -53873,7 +53887,7 @@ var CourseGoalsSchema;
53873
53887
  var UpdateGameTimebackIntegrationRequestSchema;
53874
53888
  var TimebackActivityDataSchema;
53875
53889
  var EndActivityRequestSchema;
53876
- var GameActivityMetricsSchema;
53890
+ var GameRunMetricsSchema;
53877
53891
  var GameCourseMetricsSchema;
53878
53892
  var GameMetricsResponseSchema;
53879
53893
  var AdvanceCourseRequestSchema;
@@ -53972,22 +53986,22 @@ var init_schemas4 = __esm(() => {
53972
53986
  message: "Cannot provide both masteredUnits and masteredUnitsAbsolute",
53973
53987
  path: ["masteredUnitsAbsolute"]
53974
53988
  });
53975
- GameActivityMetricsSchema = exports_external.object({
53989
+ GameRunMetricsSchema = exports_external.object({
53990
+ runId: exports_external.string().uuid(),
53976
53991
  activityId: exports_external.string().min(1),
53977
53992
  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()
53993
+ totalXp: exports_external.number().nonnegative().optional(),
53994
+ masteredUnits: exports_external.number().int().nonnegative().optional(),
53995
+ activeTimeSeconds: exports_external.number().nonnegative().optional(),
53996
+ score: exports_external.number().min(0).max(100).optional()
53983
53997
  });
53984
53998
  GameCourseMetricsSchema = exports_external.object({
53985
53999
  grade: TimebackGradeSchema,
53986
54000
  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()
54001
+ totalXp: exports_external.number().nonnegative().optional(),
54002
+ masteredUnits: exports_external.number().int().nonnegative().optional(),
54003
+ activeTimeSeconds: exports_external.number().nonnegative().optional(),
54004
+ activities: exports_external.array(GameRunMetricsSchema).optional()
53991
54005
  });
53992
54006
  GameMetricsResponseSchema = exports_external.object({
53993
54007
  studentId: exports_external.string().min(1),
@@ -54257,6 +54271,122 @@ function compareEnrollmentsByRecency(a, b) {
54257
54271
  var init_timeback_admin_util = __esm(() => {
54258
54272
  init_errors();
54259
54273
  });
54274
+ function createMetricRow(definition) {
54275
+ const { gameValue, kind, metric, timebackValue, tolerance } = definition;
54276
+ if (timebackValue === undefined && gameValue === undefined) {
54277
+ return null;
54278
+ }
54279
+ if (gameValue === undefined) {
54280
+ return {
54281
+ metric,
54282
+ kind,
54283
+ status: "not_reported_by_game",
54284
+ ...timebackValue !== undefined ? { timebackValue } : {}
54285
+ };
54286
+ }
54287
+ if (timebackValue === undefined) {
54288
+ return {
54289
+ metric,
54290
+ kind,
54291
+ status: "not_recorded_by_timeback",
54292
+ gameValue
54293
+ };
54294
+ }
54295
+ const delta = gameValue - timebackValue;
54296
+ const isDiscrepant = tolerance === 0 ? delta !== 0 : Math.abs(delta) >= tolerance;
54297
+ return {
54298
+ metric,
54299
+ kind,
54300
+ status: isDiscrepant ? "discrepant" : "matched",
54301
+ timebackValue,
54302
+ gameValue,
54303
+ delta
54304
+ };
54305
+ }
54306
+ function createRunComparison(activity, gameRun) {
54307
+ const runId = activity.runId ?? "";
54308
+ if (!gameRun) {
54309
+ return {
54310
+ runId,
54311
+ status: "not_reported",
54312
+ discrepancyCount: 0,
54313
+ rows: []
54314
+ };
54315
+ }
54316
+ const rows = [
54317
+ createMetricRow({
54318
+ metric: "xp",
54319
+ kind: "number",
54320
+ timebackValue: activity.xpDelta,
54321
+ gameValue: gameRun.totalXp,
54322
+ tolerance: TIMEBACK_GAME_METRIC_COMPARISON_TOLERANCE.xp
54323
+ }),
54324
+ createMetricRow({
54325
+ metric: "mastery",
54326
+ kind: "number",
54327
+ timebackValue: activity.masteredUnitsDelta,
54328
+ gameValue: gameRun.masteredUnits,
54329
+ tolerance: TIMEBACK_GAME_METRIC_COMPARISON_TOLERANCE.mastery
54330
+ }),
54331
+ createMetricRow({
54332
+ metric: "time",
54333
+ kind: "time",
54334
+ timebackValue: activity.timeDeltaSeconds,
54335
+ gameValue: gameRun.activeTimeSeconds,
54336
+ tolerance: TIMEBACK_GAME_METRIC_COMPARISON_TOLERANCE.time
54337
+ }),
54338
+ createMetricRow({
54339
+ metric: "score",
54340
+ kind: "percent",
54341
+ timebackValue: activity.score,
54342
+ gameValue: gameRun.score,
54343
+ tolerance: TIMEBACK_GAME_METRIC_COMPARISON_TOLERANCE.score
54344
+ })
54345
+ ].filter((row) => row !== null);
54346
+ const discrepancyCount = rows.filter((row) => row.status === "discrepant").length;
54347
+ return {
54348
+ runId,
54349
+ status: discrepancyCount > 0 ? "discrepant" : "matched",
54350
+ discrepancyCount,
54351
+ rows
54352
+ };
54353
+ }
54354
+ function summarizeGameRunMetricsComparison(comparison) {
54355
+ return {
54356
+ runId: comparison.runId,
54357
+ status: comparison.status,
54358
+ discrepancyCount: comparison.discrepancyCount,
54359
+ ...comparison.reason ? { reason: comparison.reason } : {}
54360
+ };
54361
+ }
54362
+ function buildGameRunMetricComparisons(activities, course, response) {
54363
+ const activitiesWithRunIds = activities.filter((activity) => typeof activity.runId === "string" && activity.runId.length > 0);
54364
+ const comparisons = new Map;
54365
+ if (activitiesWithRunIds.length === 0) {
54366
+ return comparisons;
54367
+ }
54368
+ if (!response.supported) {
54369
+ for (const activity of activitiesWithRunIds) {
54370
+ comparisons.set(activity.runId, {
54371
+ runId: activity.runId,
54372
+ status: "unavailable",
54373
+ discrepancyCount: 0,
54374
+ reason: response.reason,
54375
+ rows: []
54376
+ });
54377
+ }
54378
+ return comparisons;
54379
+ }
54380
+ const gameCourseMetrics = response.metrics.courses.find((gameCourse) => gameCourse.grade === course.grade && gameCourse.subject === course.subject);
54381
+ const gameRunsById = new Map(gameCourseMetrics?.activities?.map((gameRun) => [gameRun.runId.toLowerCase(), gameRun]));
54382
+ for (const activity of activitiesWithRunIds) {
54383
+ comparisons.set(activity.runId, createRunComparison(activity, gameRunsById.get(activity.runId.toLowerCase())));
54384
+ }
54385
+ return comparisons;
54386
+ }
54387
+ var init_timeback_game_metrics_comparison_util = __esm(() => {
54388
+ init_src();
54389
+ });
54260
54390
  async function upsertMasteryCompletionEntry(params) {
54261
54391
  const { client, courseId, studentId, appName, action } = params;
54262
54392
  const ids = deriveSourcedIds(courseId);
@@ -54643,6 +54773,8 @@ class TimebackAdminService {
54643
54773
  static ANALYTICS_CONCURRENCY = 8;
54644
54774
  static MASTERABLE_UNITS_CONCURRENCY = 4;
54645
54775
  static GAME_METRICS_FETCH_TIMEOUT_MS = 1e4;
54776
+ static GAME_METRICS_LIST_FETCH_TIMEOUT_MS = 3000;
54777
+ static GAME_METRICS_RUN_IDS_PER_REQUEST = 50;
54646
54778
  constructor(deps) {
54647
54779
  this.deps = deps;
54648
54780
  }
@@ -54652,13 +54784,42 @@ class TimebackAdminService {
54652
54784
  }
54653
54785
  return this.deps.config.localGameUrls[slug2] ?? deployedUrl;
54654
54786
  }
54655
- static resolveGameMetricsUrl(baseUrl) {
54787
+ static resolveGameMetricsUrl(baseUrl, runIds) {
54656
54788
  try {
54657
- return new URL("/__playcademy/metrics", baseUrl);
54789
+ const url2 = new URL("/__playcademy/metrics", baseUrl);
54790
+ for (const runId of runIds ?? []) {
54791
+ url2.searchParams.append("runId", runId);
54792
+ }
54793
+ return url2;
54658
54794
  } catch {
54659
54795
  return null;
54660
54796
  }
54661
54797
  }
54798
+ static normalizeRunIds(runIds, limit = Number.POSITIVE_INFINITY) {
54799
+ const normalized = [];
54800
+ const seen = new Set;
54801
+ for (const runId of runIds ?? []) {
54802
+ const value = runId.trim().toLowerCase();
54803
+ if (isValidUUID(value) && !seen.has(value)) {
54804
+ seen.add(value);
54805
+ normalized.push(value);
54806
+ if (normalized.length >= limit) {
54807
+ break;
54808
+ }
54809
+ }
54810
+ }
54811
+ return normalized;
54812
+ }
54813
+ static chunkRunIds(runIds) {
54814
+ const chunks = [];
54815
+ for (let index2 = 0;index2 < runIds.length; index2 += this.GAME_METRICS_RUN_IDS_PER_REQUEST) {
54816
+ chunks.push(runIds.slice(index2, index2 + this.GAME_METRICS_RUN_IDS_PER_REQUEST));
54817
+ }
54818
+ return chunks;
54819
+ }
54820
+ static isAbortError(error) {
54821
+ return error instanceof Error && error.name === "AbortError";
54822
+ }
54662
54823
  static roundXpToTenths(value) {
54663
54824
  const rounded = Math.round(value * TimebackAdminService.XP_PRECISION_FACTOR) / TimebackAdminService.XP_PRECISION_FACTOR;
54664
54825
  return Object.is(rounded, -0) ? 0 : rounded;
@@ -54819,6 +54980,56 @@ class TimebackAdminService {
54819
54980
  const remediationItems = events.map((event) => mapCaliperEventToRemediationActivity(event, relevantCourseIds)).filter((item) => Boolean(item));
54820
54981
  return [...groupedGameplayItems, ...remediationItems].toSorted((a, b) => b.occurredAt.localeCompare(a.occurredAt));
54821
54982
  }
54983
+ async getGameMetricComparisonsForActivities(user, options) {
54984
+ const runIds = TimebackAdminService.normalizeRunIds(options.activities.map((activity) => activity.runId).filter((runId) => Boolean(runId)));
54985
+ if (runIds.length === 0) {
54986
+ return new Map;
54987
+ }
54988
+ const activitiesByRunId = new Map(options.activities.filter((activity) => typeof activity.runId === "string" && activity.runId.length > 0).map((activity) => [activity.runId.toLowerCase(), activity]));
54989
+ const comparisons = new Map;
54990
+ await Promise.all(TimebackAdminService.chunkRunIds(runIds).map(async (chunk) => {
54991
+ const activities = [];
54992
+ for (const runId of chunk) {
54993
+ const activity = activitiesByRunId.get(runId);
54994
+ if (activity) {
54995
+ activities.push(activity);
54996
+ }
54997
+ }
54998
+ if (activities.length === 0) {
54999
+ return;
55000
+ }
55001
+ let response;
55002
+ try {
55003
+ response = await this.getGameMetrics(options.gameId, options.studentId, user, {
55004
+ runIds: chunk,
55005
+ timeoutMs: options.timeoutMs
55006
+ });
55007
+ } catch (error) {
55008
+ response = {
55009
+ supported: false,
55010
+ reason: "fetch_failed",
55011
+ details: error instanceof Error ? error.message : String(error)
55012
+ };
55013
+ }
55014
+ for (const [runId, comparison] of buildGameRunMetricComparisons(activities, options.course, response)) {
55015
+ comparisons.set(runId, comparison);
55016
+ }
55017
+ }));
55018
+ return comparisons;
55019
+ }
55020
+ async attachGameMetricSummariesToActivities(user, options) {
55021
+ const comparisons = await this.getGameMetricComparisonsForActivities(user, options);
55022
+ if (comparisons.size === 0) {
55023
+ return [...options.activities];
55024
+ }
55025
+ return options.activities.map((activity) => {
55026
+ const comparison = activity.runId ? comparisons.get(activity.runId) : undefined;
55027
+ return comparison ? {
55028
+ ...activity,
55029
+ gameMetricsComparison: summarizeGameRunMetricsComparison(comparison)
55030
+ } : activity;
55031
+ });
55032
+ }
54822
55033
  async getStudentEnrollmentsByCourseId(client, studentId, courseIds, options) {
54823
55034
  const enrollments = new Map;
54824
55035
  const allEnrollments = new Map;
@@ -54978,7 +55189,7 @@ class TimebackAdminService {
54978
55189
  });
54979
55190
  return { gameId, courseId, students: deduped };
54980
55191
  }
54981
- async getGameMetrics(gameId, timebackId, user) {
55192
+ async getGameMetrics(gameId, timebackId, user, options) {
54982
55193
  const client = this.requireClient();
54983
55194
  await this.deps.validateGameManagementAccess(user, gameId);
54984
55195
  const [targetUser, integrations, game2, deployment] = await Promise.all([
@@ -55013,7 +55224,8 @@ class TimebackAdminService {
55013
55224
  if (!metricsBaseUrl) {
55014
55225
  return { supported: false, reason: "no_active_deployment" };
55015
55226
  }
55016
- const metricsUrl = TimebackAdminService.resolveGameMetricsUrl(metricsBaseUrl);
55227
+ const runIds = TimebackAdminService.normalizeRunIds(options?.runIds, TimebackAdminService.GAME_METRICS_RUN_IDS_PER_REQUEST);
55228
+ const metricsUrl = TimebackAdminService.resolveGameMetricsUrl(metricsBaseUrl, runIds);
55017
55229
  if (!metricsUrl) {
55018
55230
  return {
55019
55231
  supported: false,
@@ -55023,7 +55235,7 @@ class TimebackAdminService {
55023
55235
  }
55024
55236
  const token = await this.deps.mintPlatformServiceToken(gameId, targetUser.id);
55025
55237
  const controller = new AbortController;
55026
- const timeout = setTimeout(() => controller.abort(), TimebackAdminService.GAME_METRICS_FETCH_TIMEOUT_MS);
55238
+ const timeout = setTimeout(() => controller.abort(), options?.timeoutMs ?? TimebackAdminService.GAME_METRICS_FETCH_TIMEOUT_MS);
55027
55239
  let response;
55028
55240
  try {
55029
55241
  response = await fetch(metricsUrl, {
@@ -55035,10 +55247,19 @@ class TimebackAdminService {
55035
55247
  signal: controller.signal
55036
55248
  });
55037
55249
  } catch (error) {
55250
+ const timedOut = TimebackAdminService.isAbortError(error);
55251
+ let details;
55252
+ if (timedOut) {
55253
+ details = "Game metrics request timed out";
55254
+ } else if (error instanceof Error) {
55255
+ details = error.message;
55256
+ } else {
55257
+ details = String(error);
55258
+ }
55038
55259
  return {
55039
55260
  supported: false,
55040
- reason: "fetch_failed",
55041
- details: error instanceof Error ? error.message : String(error)
55261
+ reason: timedOut ? "timeout" : "fetch_failed",
55262
+ details
55042
55263
  };
55043
55264
  } finally {
55044
55265
  clearTimeout(timeout);
@@ -55142,7 +55363,14 @@ class TimebackAdminService {
55142
55363
  const allActivities = await this.listRecentActivityForStudent(client, studentId, gameSource, relevantCourseIds, fetchLimit);
55143
55364
  const activities = allActivities.slice(safeOffset, safeOffset + safeLimit);
55144
55365
  const hasMore = allActivities.length > safeOffset + safeLimit;
55145
- return { activities, hasMore };
55366
+ const activitiesWithGameMetrics = await this.attachGameMetricSummariesToActivities(user, {
55367
+ gameId,
55368
+ studentId,
55369
+ course: { grade: integration.grade, subject: integration.subject },
55370
+ activities,
55371
+ timeoutMs: TimebackAdminService.GAME_METRICS_LIST_FETCH_TIMEOUT_MS
55372
+ });
55373
+ return { activities: activitiesWithGameMetrics, hasMore };
55146
55374
  }
55147
55375
  async getActivityDetail(user, options) {
55148
55376
  const { gameId, studentId, courseId, activityId, runId } = options;
@@ -55178,7 +55406,22 @@ class TimebackAdminService {
55178
55406
  if (!activity) {
55179
55407
  throw new NotFoundError("Activity", activityId);
55180
55408
  }
55181
- return { activity, rawEvents: matchedEvents };
55409
+ const comparisons = await this.getGameMetricComparisonsForActivities(user, {
55410
+ gameId,
55411
+ studentId,
55412
+ course: { grade: integration.grade, subject: integration.subject },
55413
+ activities: [activity]
55414
+ });
55415
+ const gameMetricsComparison = activity.runId ? comparisons.get(activity.runId) : undefined;
55416
+ const activityWithGameMetrics = gameMetricsComparison ? {
55417
+ ...activity,
55418
+ gameMetricsComparison: summarizeGameRunMetricsComparison(gameMetricsComparison)
55419
+ } : activity;
55420
+ return {
55421
+ activity: activityWithGameMetrics,
55422
+ rawEvents: matchedEvents,
55423
+ ...gameMetricsComparison ? { gameMetricsComparison } : {}
55424
+ };
55182
55425
  }
55183
55426
  async grantManualXp(data, user) {
55184
55427
  const { client, sensorUrl, appName, actor } = await this.resolveAdminMutationContext(data.gameId, data.courseId, user, data.studentId);
@@ -55466,6 +55709,7 @@ var init_timeback_admin_service = __esm(() => {
55466
55709
  init_errors();
55467
55710
  init_timeback_admin_metrics_util();
55468
55711
  init_timeback_admin_util();
55712
+ init_timeback_game_metrics_comparison_util();
55469
55713
  init_timeback_mastery_completion_util();
55470
55714
  init_timeback_util();
55471
55715
  logger17 = log.scope("TimebackAdminService");
@@ -120916,15 +121160,19 @@ var init_timeback_controller = __esm(() => {
120916
121160
  getGameMetrics = requireGameManagementAccess(async (ctx) => {
120917
121161
  const gameId = ctx.params.gameId;
120918
121162
  const timebackId = ctx.params.timebackId;
121163
+ const runIds = [
121164
+ ...new Set(ctx.url.searchParams.getAll("runId").map((runId) => runId.trim().toLowerCase()).filter(isValidUUID))
121165
+ ];
120919
121166
  if (!gameId || !timebackId) {
120920
121167
  throw ApiError.badRequest("Missing gameId or timebackId path parameter");
120921
121168
  }
120922
121169
  logger45.debug("Getting game metrics", {
120923
121170
  requesterId: ctx.user.id,
120924
121171
  gameId,
120925
- timebackId
121172
+ timebackId,
121173
+ runIds
120926
121174
  });
120927
- return ctx.services.timebackAdmin.getGameMetrics(gameId, timebackId, ctx.user);
121175
+ return ctx.services.timebackAdmin.getGameMetrics(gameId, timebackId, ctx.user, { runIds });
120928
121176
  });
120929
121177
  getStudentActivity = requireGameManagementAccess(async (ctx) => {
120930
121178
  const timebackId = ctx.params.timebackId;
@@ -122767,6 +123015,17 @@ var POSTHOG_CONFIG = {
122767
123015
  var TIMEBACK_ORG_SOURCED_ID2 = "PLAYCADEMY";
122768
123016
  var TIMEBACK_ORG_NAME2 = "Playcademy Studios";
122769
123017
  var TIMEBACK_ORG_TYPE2 = "department";
123018
+ var TIMEBACK_GAME_METRIC_DECIMAL_PLACES2 = {
123019
+ xp: 1,
123020
+ mastery: 0,
123021
+ score: 2
123022
+ };
123023
+ var TIMEBACK_GAME_METRIC_COMPARISON_TOLERANCE2 = {
123024
+ xp: 0.5 / 10 ** TIMEBACK_GAME_METRIC_DECIMAL_PLACES2.xp,
123025
+ mastery: 0,
123026
+ time: 60,
123027
+ score: 0.5 / 10 ** TIMEBACK_GAME_METRIC_DECIMAL_PLACES2.score
123028
+ };
122770
123029
  // src/lib/sandbox/timeback.ts
122771
123030
  function detectTimebackOptions() {
122772
123031
  if (process.env.TIMEBACK_LOCAL === "true") {
@@ -122983,6 +123242,8 @@ var TIMEBACK_COURSE_DEFAULTS2;
122983
123242
  var TIMEBACK_RESOURCE_DEFAULTS2;
122984
123243
  var TIMEBACK_COMPONENT_DEFAULTS2;
122985
123244
  var TIMEBACK_COMPONENT_RESOURCE_DEFAULTS2;
123245
+ var TIMEBACK_GAME_METRIC_DECIMAL_PLACES3;
123246
+ var TIMEBACK_GAME_METRIC_COMPARISON_TOLERANCE3;
122986
123247
  var init_timeback7 = __esm8(() => {
122987
123248
  TIMEBACK_ROUTES2 = {
122988
123249
  END_ACTIVITY: "/integrations/timeback/end-activity",
@@ -123027,6 +123288,17 @@ var init_timeback7 = __esm8(() => {
123027
123288
  sortOrder: 1,
123028
123289
  lessonType: "quiz"
123029
123290
  };
123291
+ TIMEBACK_GAME_METRIC_DECIMAL_PLACES3 = {
123292
+ xp: 1,
123293
+ mastery: 0,
123294
+ score: 2
123295
+ };
123296
+ TIMEBACK_GAME_METRIC_COMPARISON_TOLERANCE3 = {
123297
+ xp: 0.5 / 10 ** TIMEBACK_GAME_METRIC_DECIMAL_PLACES3.xp,
123298
+ mastery: 0,
123299
+ time: 60,
123300
+ score: 0.5 / 10 ** TIMEBACK_GAME_METRIC_DECIMAL_PLACES3.score
123301
+ };
123030
123302
  });
123031
123303
  var WORKER_NAMING2;
123032
123304
  var init_cloudflare2 = __esm8(() => {
@@ -123199,14 +123471,6 @@ var shell_default = `<!doctype html>
123199
123471
  <link rel="preconnect" href="https://fonts.gstatic.com" crossorigin />
123200
123472
  <link href="https://fonts.googleapis.com/css2?family=VT323&display=swap" rel="stylesheet" />
123201
123473
  <script type="module" src="/@vite/client"></script>
123202
- <script type="importmap">
123203
- {
123204
- "imports": {
123205
- "@playcademy/sdk": "https://esm.sh/@playcademy/sdk@latest",
123206
- "@playcademy/sdk-fallback": "https://cdn.playcademy.net/sdk/latest/index.js"
123207
- }
123208
- }
123209
- </script>
123210
123474
  <style>
123211
123475
  * {
123212
123476
  margin: 0;
@@ -123252,10 +123516,7 @@ var shell_default = `<!doctype html>
123252
123516
  <iframe id="frame" class="hidden"></iframe>
123253
123517
 
123254
123518
  <script type="module">
123255
- const { MessageEvents, messaging } = await Promise.any([
123256
- import('@playcademy/sdk'),
123257
- import('@playcademy/sdk-fallback'),
123258
- ])
123519
+ const { MessageEvents, messaging } = await import('/@playcademy/shell-sdk')
123259
123520
 
123260
123521
  const CONFIG = {
123261
123522
  sandboxUrl: '{{SANDBOX_URL}}',
@@ -123873,6 +124134,19 @@ async function configureServerHook(server, context) {
123873
124134
  }
123874
124135
  }
123875
124136
 
124137
+ // src/hooks/shell-sdk.ts
124138
+ var SHELL_SDK_ID = "/@playcademy/shell-sdk";
124139
+ function resolveShellSdkId(id) {
124140
+ if (id === SHELL_SDK_ID) {
124141
+ return SHELL_SDK_ID;
124142
+ }
124143
+ }
124144
+ function loadShellSdk(id) {
124145
+ if (id === SHELL_SDK_ID) {
124146
+ return `export { MessageEvents, messaging } from '@playcademy/sdk'`;
124147
+ }
124148
+ }
124149
+
123876
124150
  // src/hooks/transform-index-html.ts
123877
124151
  var SERVER_TIMING_PATCH = '!function(){function p(P){var o=P.prototype.toJSON;if(o){P.prototype.toJSON=function(){var r=o.call(this);delete r.serverTiming;return r}}}if(typeof PerformanceResourceTiming!=="undefined")p(PerformanceResourceTiming);if(typeof PerformanceNavigationTiming!=="undefined")p(PerformanceNavigationTiming)}();';
123878
124152
  var POSTHOG_LOADER = '!function(t,e){var o,n,p,r;e.__SV||(window.posthog=e,e._i=[],e.init=function(i,s,a){function g(t,e){var o=e.split(".");2==o.length&&(t=t[o[0]],e=o[1]),t[e]=function(){t.push([e].concat(Array.prototype.slice.call(arguments,0)))}}(p=t.createElement("script")).type="text/javascript",p.crossOrigin="anonymous",p.async=!0,p.src=s.api_host.replace(".i.posthog.com","-assets.i.posthog.com")+"/static/array.js",(r=t.getElementsByTagName("script")[0]).parentNode.insertBefore(p,r);var u=e;for(void 0!==a?u=e[a]=[]:a="posthog",u.people=u.people||[],u.toString=function(t){var e="posthog";return"posthog"!==a&&(e+="."+a),t||(e+=" (stub)"),e},u.people.toString=function(){return u.toString(1)+".people (stub)"},o="init capture register register_once register_for_session unregister unregister_for_session getFeatureFlag getFeatureFlagPayload isFeatureEnabled reloadFeatureFlags updateEarlyAccessFeatureEnrollment getEarlyAccessFeatures on onFeatureFlags onSessionId getSurveys getActiveMatchingSurveys renderSurvey canRenderSurvey getNextSurveyStep identify setPersonProperties group resetGroups setPersonPropertiesForFlags resetPersonPropertiesForFlags setGroupPropertiesForFlags resetGroupPropertiesForFlags reset get_distinct_id getGroups get_session_id get_session_replay_url alias set_config startSessionRecording stopSessionRecording sessionRecordingStarted captureException loadToolbar get_property getSessionProperty createPersonProfile opt_in_capturing opt_out_capturing has_opted_in_capturing has_opted_out_capturing clear_opt_in_out_capturing debug getPageViewId".split(" "),n=0;n<o.length;n++)g(u,o[n]);e._i.push([i,s,a])},e.__SV=1)}(document,window.posthog||[]);';
@@ -123963,6 +124237,8 @@ function playcademy(options = {}) {
123963
124237
  config: (userConfig) => configHook(userConfig, context),
123964
124238
  configResolved: (resolvedConfig) => configResolvedHook(resolvedConfig, context),
123965
124239
  configureServer: (server) => configureServerHook(server, context),
124240
+ resolveId: (id) => resolveShellSdkId(id),
124241
+ load: (id) => loadShellSdk(id),
123966
124242
  transformIndexHtml: () => transformIndexHtmlHook(context),
123967
124243
  writeBundle: () => writeBundleHook(context),
123968
124244
  closeBundle: () => closeBundleHook(context)
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.3",
4
4
  "type": "module",
5
5
  "exports": {
6
6
  ".": {
@@ -19,20 +19,21 @@
19
19
  "dependencies": {
20
20
  "archiver": "^7.0.1",
21
21
  "picocolors": "^1.1.1",
22
- "playcademy": "0.22.1"
22
+ "playcademy": "0.23.0"
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.4.0",
29
- "@playcademy/sdk": "0.10.0",
28
+ "@playcademy/sandbox": "0.4.1",
29
+ "@playcademy/sdk": "0.11.0",
30
30
  "@playcademy/types": "0.0.1",
31
31
  "@playcademy/utils": "0.0.1",
32
32
  "@types/archiver": "^6.0.3",
33
33
  "@types/bun": "1.3.5"
34
34
  },
35
35
  "peerDependencies": {
36
+ "@playcademy/sdk": ">=0.10.0",
36
37
  "typescript": "^5",
37
38
  "vite": "^5 || ^6"
38
39
  }