@playcademy/vite-plugin 1.2.1-beta.4 → 1.2.1-beta.6

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.
@@ -1,5 +1,5 @@
1
1
  /**
2
- * 'm' hotkey - cycle platform/demo/standalone mode
2
+ * 'm' hotkey - cycle platform/demo(/child)/standalone mode
3
3
  */
4
4
  import type { HotkeyOptions } from '../../types';
5
5
  export declare function toggleModeHotkey(options: HotkeyOptions): {
@@ -1,7 +1,8 @@
1
1
  import type { ViteDevServer } from 'vite';
2
- import type { SandboxManager, TimebackPluginContext } from '../types';
2
+ import type { ResolvedDisplayOptions, SandboxManager, TimebackPluginContext } from '../types';
3
3
  export interface ShellOptions {
4
- hideBadge: boolean;
4
+ display: ResolvedDisplayOptions;
5
5
  timeback?: TimebackPluginContext;
6
6
  }
7
+ export declare function generateLoaderHTML(sandboxUrl: string, gameSlug: string, gameId: string, options: ShellOptions, gameUrl?: string): string;
7
8
  export declare function devServerMiddleware(server: ViteDevServer, sandbox: SandboxManager, gameUrl: string | undefined, options: ShellOptions): void;
@@ -1,4 +1,17 @@
1
- import type { PlaycademyMode } from '../types/options';
1
+ import type { PlaycademyMode, PlaycademyParentOptions } from '../types/options';
2
2
  export type ShellMode = Exclude<PlaycademyMode, 'standalone'>;
3
+ /**
4
+ * Validates the `parent` plugin option for child mode. TypeScript users
5
+ * cannot get this wrong, but a plain-JS vite config can pass a hollow
6
+ * object; without this check the failure surfaces as an unrelated
7
+ * TypeError inside the child game, nowhere near the config that caused
8
+ * it.
9
+ */
10
+ export declare function assertChildParentOptions(parent: PlaycademyParentOptions | undefined | null): void;
3
11
  export declare function isShellMode(mode: PlaycademyMode): mode is ShellMode;
4
- export declare function getNextMode(mode: PlaycademyMode): PlaycademyMode;
12
+ /**
13
+ * The `m` hotkey's cycle. `'child'` joins it only when a parent context is
14
+ * configured: cycling a game into child mode with no intent to deliver
15
+ * would boot it into a meaningless state.
16
+ */
17
+ export declare function getNextMode(mode: PlaycademyMode, includeChild: boolean): PlaycademyMode;
@@ -9,7 +9,7 @@
9
9
  import type { ViteDevServer } from 'vite';
10
10
  import type { DashboardAppManager } from '../lib/dashboard-app';
11
11
  import type { GameBackendServerManager, PlatformRoleOverride, SandboxManager, TimebackRoleOverride } from '../types';
12
- import type { PlaycademyMode } from '../types/options';
12
+ import type { PlaycademyMode, PlaycademyParentOptions } from '../types/options';
13
13
  /**
14
14
  * Module-level server references
15
15
  */
@@ -19,6 +19,7 @@ export declare const serverState: {
19
19
  dashboardApp: DashboardAppManager | null;
20
20
  viteServer: ViteDevServer | null;
21
21
  currentMode: PlaycademyMode;
22
+ parentOptions: PlaycademyParentOptions | null;
22
23
  timebackRoleOverride: TimebackRoleOverride | null;
23
24
  platformRoleOverride: PlatformRoleOverride | null;
24
25
  };
@@ -38,6 +39,14 @@ export declare function hasActiveServers(): boolean;
38
39
  * Get current mode
39
40
  */
40
41
  export declare function getCurrentMode(): PlaycademyMode;
42
+ /**
43
+ * Get the parent-game context for child mode (null unless configured)
44
+ */
45
+ export declare function getParentOptions(): PlaycademyParentOptions | null;
46
+ /**
47
+ * Set the parent-game context for child mode
48
+ */
49
+ export declare function setParentOptions(parent: PlaycademyParentOptions | null): void;
41
50
  /**
42
51
  * Set current mode
43
52
  */
@@ -1,6 +1,6 @@
1
1
  /**
2
2
  * Type exports for the Playcademy Vite Plugin
3
3
  */
4
- export type { PlaycademyExportOptions, PlaycademySandboxOptions, PlaycademyDisplayOptions, PlaycademyPluginOptions, PlaycademyTimebackOptions, PlaycademyMode, } from './options';
5
- export type { BannerOptions, GameBackendDevServerOptions, GameBackendServerManager, HotkeyOptions, PlatformModeOptions, PlatformRoleOverride, PlaycademyOutputData, PluginContext, ProjectInfo, ResolvedPluginOptions, SandboxManager, StandaloneModeOptions, TimebackCourseConfig, TimebackPluginContext, TimebackRoleOverride, } from './internal';
4
+ export type { PlaycademyExportOptions, PlaycademySandboxOptions, PlaycademyDisplayOptions, PlaycademyPluginOptions, PlaycademyTimebackOptions, PlaycademyMode, PlaycademyParentOptions, ShellCorner, } from './options';
5
+ export type { BannerOptions, GameBackendDevServerOptions, GameBackendServerManager, HotkeyOptions, PlatformModeOptions, PlatformRoleOverride, PlaycademyOutputData, PluginContext, ProjectInfo, ResolvedDisplayOptions, ResolvedPluginOptions, SandboxManager, StandaloneModeOptions, TimebackCourseConfig, TimebackPluginContext, TimebackRoleOverride, } from './internal';
6
6
  export { TIMEBACK_ROLES, PLATFORM_ROLES } from './internal';
@@ -2,7 +2,16 @@
2
2
  * Internal plugin state and context types
3
3
  */
4
4
  import type { ResolvedConfig } from 'vite';
5
- import type { PlaycademyMode, PlaycademyTimebackOptions } from './options';
5
+ import type { PlaycademyMode, PlaycademyParentOptions, PlaycademyTimebackOptions, ShellCorner } from './options';
6
+ /**
7
+ * Display options with every default applied.
8
+ */
9
+ export interface ResolvedDisplayOptions {
10
+ hideBadge: boolean;
11
+ badgePosition: ShellCorner;
12
+ hideRelayPanel: boolean;
13
+ relayPanelPosition: ShellCorner;
14
+ }
6
15
  /**
7
16
  * TimeBack roles that can be cycled through in dev mode
8
17
  */
@@ -19,6 +28,7 @@ export type PlatformRoleOverride = (typeof PLATFORM_ROLES)[number];
19
28
  export interface ResolvedPluginOptions {
20
29
  configPath?: string;
21
30
  mode: PlaycademyMode;
31
+ parent?: PlaycademyParentOptions;
22
32
  gameBackendPort: number;
23
33
  sandboxPort: number;
24
34
  dashboardAppPort: number;
@@ -32,7 +42,7 @@ export interface ResolvedPluginOptions {
32
42
  seed: boolean;
33
43
  memoryOnly: boolean;
34
44
  databasePath?: string;
35
- hideBadge: boolean;
45
+ display: ResolvedDisplayOptions;
36
46
  timeback?: PlaycademyTimebackOptions | false;
37
47
  }
38
48
  /**
@@ -134,7 +144,7 @@ export interface PlatformModeOptions {
134
144
  seed: boolean;
135
145
  memoryOnly: boolean;
136
146
  databasePath?: string;
137
- hideBadge: boolean;
147
+ display: ResolvedDisplayOptions;
138
148
  gameBackendPort: number;
139
149
  configPath?: string;
140
150
  timeback?: PlaycademyTimebackOptions | false;
@@ -1,17 +1,51 @@
1
1
  /**
2
2
  * Plugin configuration options
3
3
  */
4
+ import type { ParentGameContext, PlaycademyMode as SdkPlaycademyMode } from '@playcademy/sdk/types';
4
5
  /**
5
6
  * Plugin operation mode
6
7
  *
7
8
  * Controls how the Vite plugin operates during development:
8
9
  * - `'platform'`: Full Playcademy platform experience with sandbox server, backend bundling, and shell wrapper (default)
9
10
  * - `'demo'`: Shell-backed development mode that initializes the SDK with `mode: 'demo'`
11
+ * - `'child'`: Shell impersonates a parent game: INIT carries `mode: 'child'` and the
12
+ * `parent` block, and the shell displays what the game relays (requires the `parent` option)
10
13
  * - `'standalone'`: Backend only, no sandbox or shell
11
14
  *
15
+ * The union is the SDK's own `PlaycademyMode`, aliased so the two can
16
+ * never drift: whatever mode the plugin serves lands verbatim in the
17
+ * game's INIT payload.
18
+ *
12
19
  * @default 'platform'
13
20
  */
14
- export type PlaycademyMode = 'platform' | 'demo' | 'standalone';
21
+ export type PlaycademyMode = SdkPlaycademyMode;
22
+ /**
23
+ * Parent-game context the dev shell presents in `mode: 'child'`.
24
+ *
25
+ * In production a child game is launched by a parent game via
26
+ * `client.embed.launch()`; the dev shell plays that parent role locally so a
27
+ * child game can be developed without one. See the parent-child game
28
+ * embedding proposal (`docs/dev/timeback/` in the platform repo).
29
+ *
30
+ * Fields mirror the SDK's `ParentGameContext`, and each is typed from it
31
+ * directly. The block the dev shell actually sends is additionally checked
32
+ * against `ParentGameContext` where it is built (see the server middleware),
33
+ * so it cannot drift from what a real parent game would send.
34
+ */
35
+ export interface PlaycademyParentOptions {
36
+ /**
37
+ * Parent game id stamped into the INIT payload's `parent` block.
38
+ *
39
+ * @default 'dev-parent-game'
40
+ */
41
+ gameId?: ParentGameContext['gameId'];
42
+ /**
43
+ * The `LaunchIntent` delivered to the game as `client.parent.intent`:
44
+ * which lesson to serve (`lessonId`, in the game's own vocabulary),
45
+ * and at which pedagogy stage (`eLevel`, the platform's E1-E4 taxonomy).
46
+ */
47
+ intent: ParentGameContext['intent'];
48
+ }
15
49
  /**
16
50
  * Configuration for developing a game's dashboard app.
17
51
  *
@@ -276,25 +310,43 @@ export interface PlaycademyTimebackOptions {
276
310
  */
277
311
  courses?: Record<string, 'mock' | string | null | false>;
278
312
  }
313
+ /**
314
+ * Screen corner for the dev shell's overlay elements.
315
+ */
316
+ export type ShellCorner = 'top-left' | 'top-right' | 'bottom-left' | 'bottom-right';
279
317
  /**
280
318
  * Configuration options for the development shell wrapper
281
319
  *
282
320
  * The shell provides the platform UI during development, including the
283
- * Playcademy badge and iframe wrapper used by `platform` and `demo` modes.
321
+ * Playcademy badge and iframe wrapper used by shell modes (`platform`,
322
+ * `demo`, and `child`).
284
323
  */
285
324
  export interface PlaycademyDisplayOptions {
286
325
  /**
287
- * Hide the Playcademy badge in the corner during development.
326
+ * Hide the Playcademy badge during development.
288
327
  *
289
328
  * @default false
290
- * @example
291
- * ```ts
292
- * display: {
293
- * hideBadge: true // Hide the badge
294
- * }
295
- * ```
296
329
  */
297
330
  hideBadge?: boolean;
331
+ /**
332
+ * Corner the badge sits in.
333
+ *
334
+ * @default 'top-left'
335
+ */
336
+ badgePosition?: ShellCorner;
337
+ /**
338
+ * Hide the child-mode relay panel (the live view of what the game
339
+ * relays to its parent: timing and the end-activity report).
340
+ *
341
+ * @default false
342
+ */
343
+ hideRelayPanel?: boolean;
344
+ /**
345
+ * Corner the relay panel sits in.
346
+ *
347
+ * @default 'bottom-left'
348
+ */
349
+ relayPanelPosition?: ShellCorner;
298
350
  }
299
351
  /**
300
352
  * Main configuration options for the Playcademy Vite plugin
@@ -345,6 +397,7 @@ export interface PlaycademyPluginOptions {
345
397
  *
346
398
  * - `'platform'`: Full development experience with sandbox server and shell (recommended)
347
399
  * - `'demo'`: Sandbox + shell, but initializes the SDK with `mode: 'demo'`
400
+ * - `'child'`: Sandbox + shell, but the shell plays a parent game (requires `parent`)
348
401
  * - `'standalone'`: Backend bundling only, no platform features
349
402
  *
350
403
  * Most games should use `'platform'` mode; use `'demo'` to exercise
@@ -359,6 +412,20 @@ export interface PlaycademyPluginOptions {
359
412
  * ```
360
413
  */
361
414
  mode?: PlaycademyMode;
415
+ /**
416
+ * Parent-game context for `mode: 'child'`: what the dev shell's INIT
417
+ * carries in its `parent` block. Required when `mode` is `'child'`;
418
+ * also enables `'child'` in the `m` hotkey's mode cycle.
419
+ *
420
+ * @example
421
+ * ```ts
422
+ * {
423
+ * mode: 'child',
424
+ * parent: { intent: { lessonId: 'two-digit-add', eLevel: 'E2' } }
425
+ * }
426
+ * ```
427
+ */
428
+ parent?: PlaycademyParentOptions;
362
429
  /**
363
430
  * Develop a dashboard app instead of a game.
364
431
  *
@@ -458,7 +525,8 @@ export interface PlaycademyPluginOptions {
458
525
  * ```ts
459
526
  * {
460
527
  * display: {
461
- * hideBadge: true
528
+ * hideBadge: true,
529
+ * relayPanelPosition: 'bottom-right'
462
530
  * }
463
531
  * }
464
532
  * ```
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@playcademy/vite-plugin",
3
- "version": "1.2.1-beta.4",
3
+ "version": "1.2.1-beta.6",
4
4
  "type": "module",
5
5
  "exports": {
6
6
  ".": {
@@ -19,21 +19,21 @@
19
19
  "dependencies": {
20
20
  "archiver": "^7.0.1",
21
21
  "picocolors": "^1.1.1",
22
- "playcademy": "0.28.1-beta.4"
22
+ "playcademy": "0.28.1-beta.6"
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.4",
29
- "@playcademy/sdk": "0.16.1-beta.4",
28
+ "@playcademy/sandbox": "0.7.1-beta.6",
29
+ "@playcademy/sdk": "0.16.1-beta.6",
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.12.0",
36
+ "@playcademy/sdk": ">=0.17.0",
37
37
  "typescript": "^5 || ^6",
38
38
  "vite": "^5 || ^6 || ^7 || ^8"
39
39
  }