@playcademy/sdk 0.5.0 → 0.6.0-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.
- package/dist/index.d.ts +1425 -1308
- package/dist/index.js +118 -12
- package/dist/internal.d.ts +68 -1
- package/dist/internal.js +115 -25
- package/dist/types.d.ts +506 -403
- package/package.json +1 -1
package/dist/types.d.ts
CHANGED
|
@@ -487,6 +487,23 @@ interface UserInfo {
|
|
|
487
487
|
interface DeveloperStatusResponse {
|
|
488
488
|
status: DeveloperStatusEnumType;
|
|
489
489
|
}
|
|
490
|
+
interface DemoProfile {
|
|
491
|
+
displayName: string;
|
|
492
|
+
isDefault: boolean;
|
|
493
|
+
}
|
|
494
|
+
/**
|
|
495
|
+
* Update shape for `client.demo.profile.update(...)`.
|
|
496
|
+
*
|
|
497
|
+
* Kept as a named type so callers typed against it pick up new fields
|
|
498
|
+
* automatically, but `displayName` is the only updatable field today and
|
|
499
|
+
* the server's `DemoProfileSchema` requires it — a no-field payload would
|
|
500
|
+
* 400 at runtime, so we model that at the type level too. When additional
|
|
501
|
+
* fields land, make them required/optional individually based on server
|
|
502
|
+
* validation, rather than blanket-optional.
|
|
503
|
+
*/
|
|
504
|
+
interface DemoProfileUpdate {
|
|
505
|
+
displayName: string;
|
|
506
|
+
}
|
|
490
507
|
/**
|
|
491
508
|
* Authenticated user for API responses.
|
|
492
509
|
* Differs from UserRow: omits timebackId, adds hasTimebackAccount and timeback.
|
|
@@ -893,6 +910,23 @@ declare const users: drizzle_orm_pg_core.PgTableWithColumns<{
|
|
|
893
910
|
identity: undefined;
|
|
894
911
|
generated: undefined;
|
|
895
912
|
}, {}, {}>;
|
|
913
|
+
isAnonymous: drizzle_orm_pg_core.PgColumn<{
|
|
914
|
+
name: "is_anonymous";
|
|
915
|
+
tableName: "user";
|
|
916
|
+
dataType: "boolean";
|
|
917
|
+
columnType: "PgBoolean";
|
|
918
|
+
data: boolean;
|
|
919
|
+
driverParam: boolean;
|
|
920
|
+
notNull: true;
|
|
921
|
+
hasDefault: true;
|
|
922
|
+
isPrimaryKey: false;
|
|
923
|
+
isAutoincrement: false;
|
|
924
|
+
hasRuntimeDefault: false;
|
|
925
|
+
enumValues: undefined;
|
|
926
|
+
baseColumn: never;
|
|
927
|
+
identity: undefined;
|
|
928
|
+
generated: undefined;
|
|
929
|
+
}, {}, {}>;
|
|
896
930
|
timebackId: drizzle_orm_pg_core.PgColumn<{
|
|
897
931
|
name: "timeback_id";
|
|
898
932
|
tableName: "user";
|
|
@@ -4376,6 +4410,197 @@ type SpriteTemplateRow = typeof spriteTemplates.$inferSelect;
|
|
|
4376
4410
|
|
|
4377
4411
|
type NotificationRow = InferSelectModel<typeof notifications>;
|
|
4378
4412
|
|
|
4413
|
+
/**
|
|
4414
|
+
* @fileoverview Server SDK Type Definitions
|
|
4415
|
+
*
|
|
4416
|
+
* TypeScript type definitions for the server-side Playcademy SDK.
|
|
4417
|
+
* Includes configuration types, client state, and re-exported TimeBack types.
|
|
4418
|
+
*/
|
|
4419
|
+
|
|
4420
|
+
/**
|
|
4421
|
+
* Base configuration for TimeBack integration (shared across all courses).
|
|
4422
|
+
* References upstream TimeBack types from @playcademy/timeback.
|
|
4423
|
+
*
|
|
4424
|
+
* All fields are optional and support template variables: {grade}, {subject}, {gameSlug}
|
|
4425
|
+
*/
|
|
4426
|
+
interface TimebackBaseConfig {
|
|
4427
|
+
/** Organization configuration (shared across all courses) */
|
|
4428
|
+
organization?: Partial<OrganizationConfig>;
|
|
4429
|
+
/** Course defaults (can be overridden per-course) */
|
|
4430
|
+
course?: Partial<CourseConfig>;
|
|
4431
|
+
/** Component defaults */
|
|
4432
|
+
component?: Partial<ComponentConfig>;
|
|
4433
|
+
/** Resource defaults */
|
|
4434
|
+
resource?: Partial<ResourceConfig>;
|
|
4435
|
+
/** ComponentResource defaults */
|
|
4436
|
+
componentResource?: Partial<ComponentResourceConfig>;
|
|
4437
|
+
}
|
|
4438
|
+
/**
|
|
4439
|
+
* Extended course configuration that merges TimebackCourseConfig with per-course overrides.
|
|
4440
|
+
* Used in playcademy.config.* to allow per-course customization.
|
|
4441
|
+
*/
|
|
4442
|
+
interface TimebackCourseConfigWithOverrides extends TimebackCourseConfig {
|
|
4443
|
+
title?: string;
|
|
4444
|
+
courseCode?: string;
|
|
4445
|
+
level?: string;
|
|
4446
|
+
metadata?: CourseConfig['metadata'];
|
|
4447
|
+
totalXp?: number | null;
|
|
4448
|
+
masterableUnits?: number | null;
|
|
4449
|
+
}
|
|
4450
|
+
/**
|
|
4451
|
+
* TimeBack integration configuration for Playcademy config file.
|
|
4452
|
+
*
|
|
4453
|
+
* Supports two levels of customization:
|
|
4454
|
+
* 1. `base`: Shared defaults for all courses (organization, course, component, resource, componentResource)
|
|
4455
|
+
* 2. Per-course overrides in the `courses` array (title, courseCode, level, gradingScheme, metadata)
|
|
4456
|
+
*
|
|
4457
|
+
* Template variables ({grade}, {subject}, {gameSlug}) can be used in string fields.
|
|
4458
|
+
*/
|
|
4459
|
+
interface TimebackIntegrationConfig {
|
|
4460
|
+
/** Multi-grade course configuration (array of grade/subject/totalXp with optional per-course overrides) */
|
|
4461
|
+
courses: TimebackCourseConfigWithOverrides[];
|
|
4462
|
+
/** Optional base configuration (shared across all courses, can be overridden per-course) */
|
|
4463
|
+
base?: TimebackBaseConfig;
|
|
4464
|
+
}
|
|
4465
|
+
/**
|
|
4466
|
+
* Custom API routes integration
|
|
4467
|
+
*/
|
|
4468
|
+
interface CustomRoutesIntegration {
|
|
4469
|
+
/** Directory for custom API routes (defaults to 'server/api') */
|
|
4470
|
+
directory?: string;
|
|
4471
|
+
}
|
|
4472
|
+
/**
|
|
4473
|
+
* Database integration
|
|
4474
|
+
*/
|
|
4475
|
+
interface DatabaseIntegration {
|
|
4476
|
+
/** Database directory (defaults to 'db') */
|
|
4477
|
+
directory?: string;
|
|
4478
|
+
/** Schema strategy: 'push' uses drizzle-kit push-style diffing, 'migrate' uses migration files.
|
|
4479
|
+
* When omitted, auto-detects based on presence of a migrations directory with _journal.json. */
|
|
4480
|
+
strategy?: 'push' | 'migrate';
|
|
4481
|
+
}
|
|
4482
|
+
interface QueueConfig {
|
|
4483
|
+
maxBatchSize?: number;
|
|
4484
|
+
maxRetries?: number;
|
|
4485
|
+
maxBatchTimeout?: number;
|
|
4486
|
+
maxConcurrency?: number;
|
|
4487
|
+
retryDelay?: number;
|
|
4488
|
+
deadLetterQueue?: string;
|
|
4489
|
+
}
|
|
4490
|
+
/**
|
|
4491
|
+
* Integrations configuration
|
|
4492
|
+
* All backend features (database, custom routes, external services) are configured here
|
|
4493
|
+
*/
|
|
4494
|
+
interface IntegrationsConfig {
|
|
4495
|
+
/** TimeBack integration (optional) */
|
|
4496
|
+
timeback?: TimebackIntegrationConfig | null;
|
|
4497
|
+
/** Custom API routes (optional) */
|
|
4498
|
+
customRoutes?: CustomRoutesIntegration | boolean;
|
|
4499
|
+
/** Database (optional) */
|
|
4500
|
+
database?: DatabaseIntegration | boolean;
|
|
4501
|
+
/** Key-Value storage (optional) */
|
|
4502
|
+
kv?: boolean;
|
|
4503
|
+
/** Bucket storage (optional) */
|
|
4504
|
+
bucket?: boolean;
|
|
4505
|
+
/** Authentication (optional) */
|
|
4506
|
+
auth?: boolean;
|
|
4507
|
+
/** Queues (optional) */
|
|
4508
|
+
queues?: Record<string, QueueConfig | boolean>;
|
|
4509
|
+
}
|
|
4510
|
+
/**
|
|
4511
|
+
* Unified Playcademy configuration
|
|
4512
|
+
* Used for playcademy.config.{js,json}
|
|
4513
|
+
*/
|
|
4514
|
+
interface PlaycademyConfig {
|
|
4515
|
+
/** Game name */
|
|
4516
|
+
name: string;
|
|
4517
|
+
/** Game description */
|
|
4518
|
+
description?: string;
|
|
4519
|
+
/** Game emoji icon */
|
|
4520
|
+
emoji?: string;
|
|
4521
|
+
/** Build command to run before deployment */
|
|
4522
|
+
buildCommand?: string[];
|
|
4523
|
+
/** Path to build output */
|
|
4524
|
+
buildPath?: string;
|
|
4525
|
+
/** Game type */
|
|
4526
|
+
gameType?: 'hosted' | 'external';
|
|
4527
|
+
/** External URL (for external games) */
|
|
4528
|
+
externalUrl?: string;
|
|
4529
|
+
/** Game platform */
|
|
4530
|
+
platform?: 'web' | 'unity' | 'godot';
|
|
4531
|
+
/** Integrations (database, custom routes, external services) */
|
|
4532
|
+
integrations?: IntegrationsConfig;
|
|
4533
|
+
}
|
|
4534
|
+
|
|
4535
|
+
/**
|
|
4536
|
+
* Configuration options for initializing a PlaycademyClient instance.
|
|
4537
|
+
*
|
|
4538
|
+
* @example
|
|
4539
|
+
* ```typescript
|
|
4540
|
+
* const config: PlaycademyServerClientConfig = {
|
|
4541
|
+
* apiKey: process.env.PLAYCADEMY_API_KEY!,
|
|
4542
|
+
* gameId: 'my-math-game',
|
|
4543
|
+
* configPath: './playcademy.config.js'
|
|
4544
|
+
* }
|
|
4545
|
+
* ```
|
|
4546
|
+
*/
|
|
4547
|
+
interface PlaycademyServerClientConfig {
|
|
4548
|
+
/**
|
|
4549
|
+
* Playcademy API key for server-to-server authentication.
|
|
4550
|
+
* Obtain from the Playcademy developer dashboard.
|
|
4551
|
+
*/
|
|
4552
|
+
apiKey: string;
|
|
4553
|
+
/**
|
|
4554
|
+
* Optional path to playcademy.config.js file.
|
|
4555
|
+
* If not provided, searches current directory and up to 3 parent directories.
|
|
4556
|
+
* Ignored if `config` is provided directly.
|
|
4557
|
+
*
|
|
4558
|
+
* @example './config/playcademy.config.js'
|
|
4559
|
+
*/
|
|
4560
|
+
configPath?: string;
|
|
4561
|
+
/**
|
|
4562
|
+
* Optional config object (for edge environments without filesystem).
|
|
4563
|
+
* If provided, skips filesystem-based config loading.
|
|
4564
|
+
*
|
|
4565
|
+
* @example { name: 'My Game', integrations: { timeback: {...} } }
|
|
4566
|
+
*/
|
|
4567
|
+
config?: PlaycademyConfig;
|
|
4568
|
+
/**
|
|
4569
|
+
* Optional base URL for Playcademy API.
|
|
4570
|
+
* Defaults to environment variables or 'https://hub.playcademy.net'.
|
|
4571
|
+
*
|
|
4572
|
+
* @example 'http://localhost:3000' for local development
|
|
4573
|
+
*/
|
|
4574
|
+
baseUrl?: string;
|
|
4575
|
+
/**
|
|
4576
|
+
* Optional game ID.
|
|
4577
|
+
* If not provided, will attempt to fetch from API using the API token.
|
|
4578
|
+
*
|
|
4579
|
+
* @example 'my-math-game'
|
|
4580
|
+
*/
|
|
4581
|
+
gameId?: string;
|
|
4582
|
+
}
|
|
4583
|
+
/**
|
|
4584
|
+
* Internal state maintained by the PlaycademyClient instance.
|
|
4585
|
+
*
|
|
4586
|
+
* @internal
|
|
4587
|
+
*/
|
|
4588
|
+
interface PlaycademyServerClientState {
|
|
4589
|
+
/** API key for authentication */
|
|
4590
|
+
apiKey: string;
|
|
4591
|
+
/** Base URL for API requests */
|
|
4592
|
+
baseUrl: string;
|
|
4593
|
+
/** Game identifier */
|
|
4594
|
+
gameId: string;
|
|
4595
|
+
/** Loaded game configuration from playcademy.config.js */
|
|
4596
|
+
config: PlaycademyConfig;
|
|
4597
|
+
/**
|
|
4598
|
+
* TimeBack course ID fetched from the Playcademy API.
|
|
4599
|
+
* Used for all TimeBack event recording.
|
|
4600
|
+
*/
|
|
4601
|
+
courseId?: string;
|
|
4602
|
+
}
|
|
4603
|
+
|
|
4379
4604
|
/**
|
|
4380
4605
|
* Connection monitoring types
|
|
4381
4606
|
*
|
|
@@ -4565,218 +4790,29 @@ declare class ConnectionManager {
|
|
|
4565
4790
|
}
|
|
4566
4791
|
|
|
4567
4792
|
/**
|
|
4568
|
-
* @fileoverview
|
|
4793
|
+
* @fileoverview Playcademy Messaging System
|
|
4569
4794
|
*
|
|
4570
|
-
*
|
|
4571
|
-
*
|
|
4572
|
-
|
|
4573
|
-
|
|
4574
|
-
|
|
4575
|
-
*
|
|
4795
|
+
* This file implements a unified messaging system for the Playcademy platform that handles
|
|
4796
|
+
* communication between different contexts:
|
|
4797
|
+
*
|
|
4798
|
+
* 1. **Iframe-to-Parent Communication**: When games run inside iframes (production/development),
|
|
4799
|
+
* they need to communicate with the parent window using postMessage API
|
|
4800
|
+
*
|
|
4801
|
+
* 2. **Local Communication**: When games run in the same context (local development),
|
|
4802
|
+
* they use CustomEvents for internal messaging
|
|
4803
|
+
*
|
|
4804
|
+
* The system automatically detects the runtime environment and chooses the appropriate
|
|
4805
|
+
* transport method, abstracting this complexity from the developer.
|
|
4806
|
+
*
|
|
4807
|
+
* **Architecture Overview**:
|
|
4808
|
+
* - Games run in iframes for security and isolation
|
|
4809
|
+
* - Parent window (Playcademy shell) manages game lifecycle
|
|
4810
|
+
* - Messages flow bidirectionally between parent and iframe
|
|
4811
|
+
* - Local development mode simulates this architecture without iframes
|
|
4576
4812
|
*/
|
|
4577
|
-
interface AuthStrategy {
|
|
4578
|
-
/** Get the token value */
|
|
4579
|
-
getToken(): string | null;
|
|
4580
|
-
/** Get the token type */
|
|
4581
|
-
getType(): TokenType;
|
|
4582
|
-
/** Get authentication headers for a request */
|
|
4583
|
-
getHeaders(): Record<string, string>;
|
|
4584
|
-
}
|
|
4585
4813
|
|
|
4586
4814
|
/**
|
|
4587
|
-
*
|
|
4588
|
-
* Provides authentication, HTTP requests, events, connection monitoring,
|
|
4589
|
-
* and fundamental namespaces used by all clients.
|
|
4590
|
-
*
|
|
4591
|
-
* Extended by PlaycademyClient (game SDK) and PlaycademyInternalClient (platform SDK).
|
|
4592
|
-
*/
|
|
4593
|
-
declare abstract class PlaycademyBaseClient {
|
|
4594
|
-
baseUrl: string;
|
|
4595
|
-
gameUrl?: string;
|
|
4596
|
-
protected authStrategy: AuthStrategy;
|
|
4597
|
-
protected gameId?: string;
|
|
4598
|
-
protected config: Partial<ClientConfig>;
|
|
4599
|
-
protected listeners: EventListeners;
|
|
4600
|
-
protected internalClientSessionId?: string;
|
|
4601
|
-
protected authContext?: {
|
|
4602
|
-
isInIframe: boolean;
|
|
4603
|
-
};
|
|
4604
|
-
protected initPayload?: InitPayload;
|
|
4605
|
-
protected connectionManager?: ConnectionManager;
|
|
4606
|
-
protected launchId?: string;
|
|
4607
|
-
/**
|
|
4608
|
-
* Internal session manager for automatic session lifecycle.
|
|
4609
|
-
* @private
|
|
4610
|
-
* @internal
|
|
4611
|
-
*/
|
|
4612
|
-
protected _sessionManager: {
|
|
4613
|
-
startSession: (gameId: string) => Promise<{
|
|
4614
|
-
sessionId: string;
|
|
4615
|
-
}>;
|
|
4616
|
-
endSession: (sessionId: string, gameId: string) => Promise<void>;
|
|
4617
|
-
};
|
|
4618
|
-
constructor(config?: Partial<ClientConfig>);
|
|
4619
|
-
/**
|
|
4620
|
-
* Gets the effective base URL for API requests.
|
|
4621
|
-
*/
|
|
4622
|
-
getBaseUrl(): string;
|
|
4623
|
-
/**
|
|
4624
|
-
* Gets the effective game backend URL for integration requests.
|
|
4625
|
-
*/
|
|
4626
|
-
protected getGameBackendUrl(): string;
|
|
4627
|
-
/**
|
|
4628
|
-
* Simple ping method for testing connectivity.
|
|
4629
|
-
*/
|
|
4630
|
-
ping(): string;
|
|
4631
|
-
/**
|
|
4632
|
-
* Sets the authentication token for API requests.
|
|
4633
|
-
*/
|
|
4634
|
-
setToken(token: string | null, tokenType?: TokenType): void;
|
|
4635
|
-
setLaunchId(launchId: string | null | undefined): void;
|
|
4636
|
-
/**
|
|
4637
|
-
* Gets the current token type.
|
|
4638
|
-
*/
|
|
4639
|
-
getTokenType(): TokenType;
|
|
4640
|
-
/**
|
|
4641
|
-
* Gets the current authentication token.
|
|
4642
|
-
*/
|
|
4643
|
-
getToken(): string | null;
|
|
4644
|
-
/**
|
|
4645
|
-
* Checks if the client has a valid API token.
|
|
4646
|
-
*/
|
|
4647
|
-
isAuthenticated(): boolean;
|
|
4648
|
-
/**
|
|
4649
|
-
* Registers a callback to be called when authentication state changes.
|
|
4650
|
-
*/
|
|
4651
|
-
onAuthChange(callback: (token: string | null) => void): void;
|
|
4652
|
-
/**
|
|
4653
|
-
* Registers a callback to be called when connection issues are detected.
|
|
4654
|
-
*/
|
|
4655
|
-
onDisconnect(callback: (context: DisconnectContext) => void | Promise<void>): () => void;
|
|
4656
|
-
/**
|
|
4657
|
-
* Gets the current connection state.
|
|
4658
|
-
*/
|
|
4659
|
-
getConnectionState(): ConnectionState | 'unknown';
|
|
4660
|
-
/**
|
|
4661
|
-
* Manually triggers a connection check immediately.
|
|
4662
|
-
*/
|
|
4663
|
-
checkConnection(): Promise<ConnectionState | 'unknown'>;
|
|
4664
|
-
/**
|
|
4665
|
-
* Sets the authentication context for the client.
|
|
4666
|
-
* @internal
|
|
4667
|
-
*/
|
|
4668
|
-
_setAuthContext(context: {
|
|
4669
|
-
isInIframe: boolean;
|
|
4670
|
-
}): void;
|
|
4671
|
-
/**
|
|
4672
|
-
* Registers an event listener for client events.
|
|
4673
|
-
*/
|
|
4674
|
-
on<E extends keyof ClientEvents>(event: E, callback: (payload: ClientEvents[E]) => void): void;
|
|
4675
|
-
/**
|
|
4676
|
-
* Emits an event to all registered listeners.
|
|
4677
|
-
*/
|
|
4678
|
-
protected emit<E extends keyof ClientEvents>(event: E, payload: ClientEvents[E]): void;
|
|
4679
|
-
/**
|
|
4680
|
-
* Makes an authenticated HTTP request to the platform API.
|
|
4681
|
-
*/
|
|
4682
|
-
protected request<T>(path: string, method: Method, options?: {
|
|
4683
|
-
body?: unknown;
|
|
4684
|
-
headers?: Record<string, string>;
|
|
4685
|
-
raw?: boolean;
|
|
4686
|
-
retryPolicy?: RetryPolicy;
|
|
4687
|
-
}): Promise<T>;
|
|
4688
|
-
/**
|
|
4689
|
-
* Makes an authenticated HTTP request to the game's backend Worker.
|
|
4690
|
-
*/
|
|
4691
|
-
protected requestGameBackend<T>(path: string, method: Method, body?: unknown, headers?: Record<string, string>, options?: {
|
|
4692
|
-
raw?: boolean;
|
|
4693
|
-
retryPolicy?: RetryPolicy;
|
|
4694
|
-
}): Promise<T>;
|
|
4695
|
-
/**
|
|
4696
|
-
* Ensures a gameId is available, throwing an error if not.
|
|
4697
|
-
*/
|
|
4698
|
-
protected _ensureGameId(): string;
|
|
4699
|
-
/**
|
|
4700
|
-
* Detects and sets the authentication context (iframe vs standalone).
|
|
4701
|
-
*/
|
|
4702
|
-
private _detectAuthContext;
|
|
4703
|
-
/**
|
|
4704
|
-
* Initializes connection monitoring if enabled.
|
|
4705
|
-
*/
|
|
4706
|
-
private _initializeConnectionMonitor;
|
|
4707
|
-
private _initializeInternalSession;
|
|
4708
|
-
/**
|
|
4709
|
-
* Current user data and inventory management.
|
|
4710
|
-
* - `me()` - Get authenticated user profile
|
|
4711
|
-
* - `inventory.get()` - List user's items
|
|
4712
|
-
* - `inventory.add(slug, qty)` - Award items to user
|
|
4713
|
-
*/
|
|
4714
|
-
users: {
|
|
4715
|
-
me: () => Promise<AuthenticatedUser>;
|
|
4716
|
-
inventory: {
|
|
4717
|
-
get: () => Promise<InventoryItemWithItem[]>;
|
|
4718
|
-
add: (identifier: string, qty: number) => Promise<InventoryMutationResponse>;
|
|
4719
|
-
remove: (identifier: string, qty: number) => Promise<InventoryMutationResponse>;
|
|
4720
|
-
quantity: (identifier: string) => Promise<number>;
|
|
4721
|
-
has: (identifier: string, minQuantity?: number) => Promise<boolean>;
|
|
4722
|
-
};
|
|
4723
|
-
};
|
|
4724
|
-
}
|
|
4725
|
-
|
|
4726
|
-
/**
|
|
4727
|
-
* Options for configuring activity tracking behavior.
|
|
4728
|
-
*/
|
|
4729
|
-
interface StartActivityOptions {
|
|
4730
|
-
/**
|
|
4731
|
-
* How long the tab can stay hidden before the timing window resets on return.
|
|
4732
|
-
* Defaults to 10 minutes. Set to `Infinity` to disable.
|
|
4733
|
-
*/
|
|
4734
|
-
hiddenTimeoutMs?: number;
|
|
4735
|
-
/**
|
|
4736
|
-
* How often to flush periodic heartbeats with accumulated time data.
|
|
4737
|
-
* Defaults to 15 seconds. Set to `Infinity` to disable the interval;
|
|
4738
|
-
* final unload/endActivity flushes still run.
|
|
4739
|
-
*/
|
|
4740
|
-
heartbeatIntervalMs?: number;
|
|
4741
|
-
/**
|
|
4742
|
-
* Stable identifier for this activity run. When provided, it is used on
|
|
4743
|
-
* every heartbeat and on endActivity instead of a freshly-generated UUID.
|
|
4744
|
-
*
|
|
4745
|
-
* Pass the same `runId` across multiple `startActivity()` calls (for
|
|
4746
|
-
* example, after the player closes and reopens a resumable activity) so
|
|
4747
|
-
* downstream systems can correlate related sessions into a single run.
|
|
4748
|
-
*
|
|
4749
|
-
* Must be a UUID (the backend validates it as such) and unique per
|
|
4750
|
-
* logical run. If omitted, the SDK generates a new UUID on each call,
|
|
4751
|
-
* which means every session is treated as its own run.
|
|
4752
|
-
*/
|
|
4753
|
-
runId?: string;
|
|
4754
|
-
}
|
|
4755
|
-
|
|
4756
|
-
/**
|
|
4757
|
-
* @fileoverview Playcademy Messaging System
|
|
4758
|
-
*
|
|
4759
|
-
* This file implements a unified messaging system for the Playcademy platform that handles
|
|
4760
|
-
* communication between different contexts:
|
|
4761
|
-
*
|
|
4762
|
-
* 1. **Iframe-to-Parent Communication**: When games run inside iframes (production/development),
|
|
4763
|
-
* they need to communicate with the parent window using postMessage API
|
|
4764
|
-
*
|
|
4765
|
-
* 2. **Local Communication**: When games run in the same context (local development),
|
|
4766
|
-
* they use CustomEvents for internal messaging
|
|
4767
|
-
*
|
|
4768
|
-
* The system automatically detects the runtime environment and chooses the appropriate
|
|
4769
|
-
* transport method, abstracting this complexity from the developer.
|
|
4770
|
-
*
|
|
4771
|
-
* **Architecture Overview**:
|
|
4772
|
-
* - Games run in iframes for security and isolation
|
|
4773
|
-
* - Parent window (Playcademy shell) manages game lifecycle
|
|
4774
|
-
* - Messages flow bidirectionally between parent and iframe
|
|
4775
|
-
* - Local development mode simulates this architecture without iframes
|
|
4776
|
-
*/
|
|
4777
|
-
|
|
4778
|
-
/**
|
|
4779
|
-
* Enumeration of all message types used in the Playcademy messaging system.
|
|
4815
|
+
* Enumeration of all message types used in the Playcademy messaging system.
|
|
4780
4816
|
*
|
|
4781
4817
|
* **Message Flow Patterns**:
|
|
4782
4818
|
*
|
|
@@ -4879,6 +4915,15 @@ declare enum MessageEvents {
|
|
|
4879
4915
|
* - `options`: `{ type?: 'info' | 'warning' | 'error', duration?: number }`
|
|
4880
4916
|
*/
|
|
4881
4917
|
DISPLAY_ALERT = "PLAYCADEMY_DISPLAY_ALERT",
|
|
4918
|
+
/**
|
|
4919
|
+
* Game signals that demo mode has ended.
|
|
4920
|
+
* Sent when a demo experience reaches its CTA/upgrade boundary.
|
|
4921
|
+
* Payload:
|
|
4922
|
+
* - `score?`: number
|
|
4923
|
+
* - `durationMs?`: number
|
|
4924
|
+
* - `metadata?`: `Record<string, unknown>`
|
|
4925
|
+
*/
|
|
4926
|
+
DEMO_END = "PLAYCADEMY_DEMO_END",
|
|
4882
4927
|
/**
|
|
4883
4928
|
* Notifies about authentication state changes.
|
|
4884
4929
|
* Can be sent in both directions depending on auth flow.
|
|
@@ -4962,7 +5007,197 @@ declare function init<T extends PlaycademyBaseClient = PlaycademyBaseClient>(thi
|
|
|
4962
5007
|
* }
|
|
4963
5008
|
* ```
|
|
4964
5009
|
*/
|
|
4965
|
-
declare function login(baseUrl: string, email: string, password: string): Promise<LoginResponse>;
|
|
5010
|
+
declare function login(baseUrl: string, email: string, password: string): Promise<LoginResponse>;
|
|
5011
|
+
|
|
5012
|
+
/**
|
|
5013
|
+
* @fileoverview Authentication Strategy Pattern
|
|
5014
|
+
*
|
|
5015
|
+
* Provides different authentication strategies for the Playcademy SDK.
|
|
5016
|
+
* Each strategy knows how to add its authentication headers to requests.
|
|
5017
|
+
*/
|
|
5018
|
+
|
|
5019
|
+
/**
|
|
5020
|
+
* Base interface for authentication strategies
|
|
5021
|
+
*/
|
|
5022
|
+
interface AuthStrategy {
|
|
5023
|
+
/** Get the token value */
|
|
5024
|
+
getToken(): string | null;
|
|
5025
|
+
/** Get the token type */
|
|
5026
|
+
getType(): TokenType;
|
|
5027
|
+
/** Get authentication headers for a request */
|
|
5028
|
+
getHeaders(): Record<string, string>;
|
|
5029
|
+
}
|
|
5030
|
+
|
|
5031
|
+
/**
|
|
5032
|
+
* Base Playcademy SDK client with shared infrastructure.
|
|
5033
|
+
* Provides authentication, HTTP requests, events, connection monitoring,
|
|
5034
|
+
* and fundamental namespaces used by all clients.
|
|
5035
|
+
*
|
|
5036
|
+
* Extended by PlaycademyClient (game SDK) and PlaycademyInternalClient (platform SDK).
|
|
5037
|
+
*/
|
|
5038
|
+
declare abstract class PlaycademyBaseClient {
|
|
5039
|
+
baseUrl: string;
|
|
5040
|
+
gameUrl?: string;
|
|
5041
|
+
mode: PlaycademyMode;
|
|
5042
|
+
protected authStrategy: AuthStrategy;
|
|
5043
|
+
protected gameId?: string;
|
|
5044
|
+
protected config: Partial<ClientConfig>;
|
|
5045
|
+
protected listeners: EventListeners;
|
|
5046
|
+
protected internalClientSessionId?: string;
|
|
5047
|
+
protected authContext?: {
|
|
5048
|
+
isInIframe: boolean;
|
|
5049
|
+
};
|
|
5050
|
+
protected initPayload?: InitPayload;
|
|
5051
|
+
protected connectionManager?: ConnectionManager;
|
|
5052
|
+
protected launchId?: string;
|
|
5053
|
+
/**
|
|
5054
|
+
* Internal session manager for automatic session lifecycle.
|
|
5055
|
+
* @private
|
|
5056
|
+
* @internal
|
|
5057
|
+
*/
|
|
5058
|
+
protected _sessionManager: {
|
|
5059
|
+
startSession: (gameId: string) => Promise<{
|
|
5060
|
+
sessionId: string;
|
|
5061
|
+
}>;
|
|
5062
|
+
endSession: (sessionId: string, gameId: string) => Promise<void>;
|
|
5063
|
+
};
|
|
5064
|
+
constructor(config?: Partial<ClientConfig>);
|
|
5065
|
+
/**
|
|
5066
|
+
* Gets the effective base URL for API requests.
|
|
5067
|
+
*/
|
|
5068
|
+
getBaseUrl(): string;
|
|
5069
|
+
/**
|
|
5070
|
+
* Gets the effective game backend URL for integration requests.
|
|
5071
|
+
*/
|
|
5072
|
+
protected getGameBackendUrl(): string;
|
|
5073
|
+
/**
|
|
5074
|
+
* Simple ping method for testing connectivity.
|
|
5075
|
+
*/
|
|
5076
|
+
ping(): string;
|
|
5077
|
+
/**
|
|
5078
|
+
* Sets the authentication token for API requests.
|
|
5079
|
+
*/
|
|
5080
|
+
setToken(token: string | null, tokenType?: TokenType): void;
|
|
5081
|
+
setLaunchId(launchId: string | null | undefined): void;
|
|
5082
|
+
/**
|
|
5083
|
+
* Gets the current token type.
|
|
5084
|
+
*/
|
|
5085
|
+
getTokenType(): TokenType;
|
|
5086
|
+
/**
|
|
5087
|
+
* Gets the current authentication token.
|
|
5088
|
+
*/
|
|
5089
|
+
getToken(): string | null;
|
|
5090
|
+
/**
|
|
5091
|
+
* Checks if the client has a valid API token.
|
|
5092
|
+
*/
|
|
5093
|
+
isAuthenticated(): boolean;
|
|
5094
|
+
/**
|
|
5095
|
+
* Registers a callback to be called when authentication state changes.
|
|
5096
|
+
*/
|
|
5097
|
+
onAuthChange(callback: (token: string | null) => void): void;
|
|
5098
|
+
/**
|
|
5099
|
+
* Registers a callback to be called when connection issues are detected.
|
|
5100
|
+
*/
|
|
5101
|
+
onDisconnect(callback: (context: DisconnectContext) => void | Promise<void>): () => void;
|
|
5102
|
+
/**
|
|
5103
|
+
* Gets the current connection state.
|
|
5104
|
+
*/
|
|
5105
|
+
getConnectionState(): ConnectionState | 'unknown';
|
|
5106
|
+
/**
|
|
5107
|
+
* Manually triggers a connection check immediately.
|
|
5108
|
+
*/
|
|
5109
|
+
checkConnection(): Promise<ConnectionState | 'unknown'>;
|
|
5110
|
+
/**
|
|
5111
|
+
* Sets the authentication context for the client.
|
|
5112
|
+
* @internal
|
|
5113
|
+
*/
|
|
5114
|
+
_setAuthContext(context: {
|
|
5115
|
+
isInIframe: boolean;
|
|
5116
|
+
}): void;
|
|
5117
|
+
/**
|
|
5118
|
+
* Registers an event listener for client events.
|
|
5119
|
+
*/
|
|
5120
|
+
on<E extends keyof ClientEvents>(event: E, callback: (payload: ClientEvents[E]) => void): void;
|
|
5121
|
+
/**
|
|
5122
|
+
* Emits an event to all registered listeners.
|
|
5123
|
+
*/
|
|
5124
|
+
protected emit<E extends keyof ClientEvents>(event: E, payload: ClientEvents[E]): void;
|
|
5125
|
+
/**
|
|
5126
|
+
* Makes an authenticated HTTP request to the platform API.
|
|
5127
|
+
*/
|
|
5128
|
+
protected request<T>(path: string, method: Method, options?: {
|
|
5129
|
+
body?: unknown;
|
|
5130
|
+
headers?: Record<string, string>;
|
|
5131
|
+
raw?: boolean;
|
|
5132
|
+
retryPolicy?: RetryPolicy;
|
|
5133
|
+
}): Promise<T>;
|
|
5134
|
+
/**
|
|
5135
|
+
* Makes an authenticated HTTP request to the game's backend Worker.
|
|
5136
|
+
*/
|
|
5137
|
+
protected requestGameBackend<T>(path: string, method: Method, body?: unknown, headers?: Record<string, string>, options?: {
|
|
5138
|
+
raw?: boolean;
|
|
5139
|
+
retryPolicy?: RetryPolicy;
|
|
5140
|
+
}): Promise<T>;
|
|
5141
|
+
/**
|
|
5142
|
+
* Ensures a gameId is available, throwing an error if not.
|
|
5143
|
+
*/
|
|
5144
|
+
protected _ensureGameId(): string;
|
|
5145
|
+
/**
|
|
5146
|
+
* Detects and sets the authentication context (iframe vs standalone).
|
|
5147
|
+
*/
|
|
5148
|
+
private _detectAuthContext;
|
|
5149
|
+
/**
|
|
5150
|
+
* Initializes connection monitoring if enabled.
|
|
5151
|
+
*/
|
|
5152
|
+
private _initializeConnectionMonitor;
|
|
5153
|
+
private _initializeInternalSession;
|
|
5154
|
+
/**
|
|
5155
|
+
* Current user data and inventory management.
|
|
5156
|
+
* - `me()` - Get authenticated user profile
|
|
5157
|
+
* - `inventory.get()` - List user's items
|
|
5158
|
+
* - `inventory.add(slug, qty)` - Award items to user
|
|
5159
|
+
*/
|
|
5160
|
+
users: {
|
|
5161
|
+
me: () => Promise<AuthenticatedUser>;
|
|
5162
|
+
inventory: {
|
|
5163
|
+
get: () => Promise<InventoryItemWithItem[]>;
|
|
5164
|
+
add: (identifier: string, qty: number) => Promise<InventoryMutationResponse>;
|
|
5165
|
+
remove: (identifier: string, qty: number) => Promise<InventoryMutationResponse>;
|
|
5166
|
+
quantity: (identifier: string) => Promise<number>;
|
|
5167
|
+
has: (identifier: string, minQuantity?: number) => Promise<boolean>;
|
|
5168
|
+
};
|
|
5169
|
+
};
|
|
5170
|
+
}
|
|
5171
|
+
|
|
5172
|
+
/**
|
|
5173
|
+
* Options for configuring activity tracking behavior.
|
|
5174
|
+
*/
|
|
5175
|
+
interface StartActivityOptions {
|
|
5176
|
+
/**
|
|
5177
|
+
* How long the tab can stay hidden before the timing window resets on return.
|
|
5178
|
+
* Defaults to 10 minutes. Set to `Infinity` to disable.
|
|
5179
|
+
*/
|
|
5180
|
+
hiddenTimeoutMs?: number;
|
|
5181
|
+
/**
|
|
5182
|
+
* How often to flush periodic heartbeats with accumulated time data.
|
|
5183
|
+
* Defaults to 15 seconds. Set to `Infinity` to disable the interval;
|
|
5184
|
+
* final unload/endActivity flushes still run.
|
|
5185
|
+
*/
|
|
5186
|
+
heartbeatIntervalMs?: number;
|
|
5187
|
+
/**
|
|
5188
|
+
* Stable identifier for this activity run. When provided, it is used on
|
|
5189
|
+
* every heartbeat and on endActivity instead of a freshly-generated UUID.
|
|
5190
|
+
*
|
|
5191
|
+
* Pass the same `runId` across multiple `startActivity()` calls (for
|
|
5192
|
+
* example, after the player closes and reopens a resumable activity) so
|
|
5193
|
+
* downstream systems can correlate related sessions into a single run.
|
|
5194
|
+
*
|
|
5195
|
+
* Must be a UUID (the backend validates it as such) and unique per
|
|
5196
|
+
* logical run. If omitted, the SDK generates a new UUID on each call,
|
|
5197
|
+
* which means every session is treated as its own run.
|
|
5198
|
+
*/
|
|
5199
|
+
runId?: string;
|
|
5200
|
+
}
|
|
4966
5201
|
|
|
4967
5202
|
/**
|
|
4968
5203
|
* Playcademy SDK client for game developers.
|
|
@@ -5053,10 +5288,31 @@ declare class PlaycademyClient extends PlaycademyBaseClient {
|
|
|
5053
5288
|
};
|
|
5054
5289
|
/**
|
|
5055
5290
|
* Game score submission and leaderboards.
|
|
5056
|
-
* - `submit(
|
|
5291
|
+
* - `submit(score, metadata?)` - Record a game score
|
|
5057
5292
|
*/
|
|
5058
5293
|
scores: {
|
|
5059
|
-
submit: (
|
|
5294
|
+
submit: (score: number, metadata?: Record<string, unknown> | undefined) => Promise<ScoreSubmission>;
|
|
5295
|
+
};
|
|
5296
|
+
/**
|
|
5297
|
+
* Read-only leaderboard access for the current game scope.
|
|
5298
|
+
* - `fetch(options?)` - Fetch leaderboard entries
|
|
5299
|
+
*/
|
|
5300
|
+
leaderboard: {
|
|
5301
|
+
fetch: (options?: LeaderboardOptions | undefined) => Promise<GameLeaderboardEntry[]>;
|
|
5302
|
+
};
|
|
5303
|
+
/**
|
|
5304
|
+
* Demo-mode helpers. Methods throw when called outside `client.mode === 'demo'`,
|
|
5305
|
+
* so callers should gate on the mode before reaching in.
|
|
5306
|
+
* - `profile.get()` - Read the anonymous demo player's profile
|
|
5307
|
+
* - `profile.update(updates)` - Update the demo player's profile (today: the required `displayName`)
|
|
5308
|
+
* - `end(score, options?)` - Signal to the parent shell that the demo has ended
|
|
5309
|
+
*/
|
|
5310
|
+
demo: {
|
|
5311
|
+
profile: {
|
|
5312
|
+
get: () => Promise<DemoProfile>;
|
|
5313
|
+
update: (updates: DemoProfileUpdate) => Promise<DemoProfile>;
|
|
5314
|
+
};
|
|
5315
|
+
end: (score: number, options?: DemoEndOptions | undefined) => void;
|
|
5060
5316
|
};
|
|
5061
5317
|
/**
|
|
5062
5318
|
* Realtime multiplayer authentication.
|
|
@@ -5232,6 +5488,20 @@ interface XpResponse {
|
|
|
5232
5488
|
*/
|
|
5233
5489
|
|
|
5234
5490
|
type TokenType = 'session' | 'apiKey' | 'gameJwt';
|
|
5491
|
+
/**
|
|
5492
|
+
* Runtime mode for a Playcademy game client.
|
|
5493
|
+
*
|
|
5494
|
+
* - `'platform'` — game is embedded in the platform (e.g. the cademy hub)
|
|
5495
|
+
* with a real authenticated user and full access to SDK namespaces.
|
|
5496
|
+
* - `'demo'` — game is embedded in the landing page demo shell with an
|
|
5497
|
+
* anonymous user; platform-only namespaces throw, and `client.demo.*`
|
|
5498
|
+
* is the supported surface for signaling demo lifecycle events and
|
|
5499
|
+
* reading/updating the anonymous profile.
|
|
5500
|
+
* - `'standalone'` — game is running outside any iframe (e.g. `bun run dev`
|
|
5501
|
+
* or direct-deploy preview) with a mock token and no real platform
|
|
5502
|
+
* context. API calls will not succeed; use this to branch UX locally.
|
|
5503
|
+
*/
|
|
5504
|
+
type PlaycademyMode = 'platform' | 'demo' | 'standalone';
|
|
5235
5505
|
interface ClientConfig {
|
|
5236
5506
|
baseUrl: string;
|
|
5237
5507
|
gameUrl?: string;
|
|
@@ -5242,6 +5512,7 @@ interface ClientConfig {
|
|
|
5242
5512
|
autoStartSession?: boolean;
|
|
5243
5513
|
onDisconnect?: DisconnectHandler;
|
|
5244
5514
|
enableConnectionMonitoring?: boolean;
|
|
5515
|
+
mode?: PlaycademyMode;
|
|
5245
5516
|
}
|
|
5246
5517
|
/**
|
|
5247
5518
|
* Handler called when connection state changes to offline or degraded.
|
|
@@ -5277,6 +5548,8 @@ interface InitPayload {
|
|
|
5277
5548
|
realtimeUrl?: string;
|
|
5278
5549
|
/** Timeback context (if user has a Timeback account) */
|
|
5279
5550
|
timeback?: TimebackInitContext;
|
|
5551
|
+
/** Runtime mode for the game client */
|
|
5552
|
+
mode?: PlaycademyMode;
|
|
5280
5553
|
}
|
|
5281
5554
|
/**
|
|
5282
5555
|
* Simplified user data passed to games via InitPayload
|
|
@@ -5305,6 +5578,7 @@ interface GameContextPayload {
|
|
|
5305
5578
|
realtimeUrl: string;
|
|
5306
5579
|
gameId: string;
|
|
5307
5580
|
forwardKeys?: string[];
|
|
5581
|
+
mode?: PlaycademyMode;
|
|
5308
5582
|
}
|
|
5309
5583
|
type EventListeners = {
|
|
5310
5584
|
[E in keyof ClientEvents]?: ((payload: ClientEvents[E]) => void)[];
|
|
@@ -5427,6 +5701,26 @@ interface ConnectionStatePayload {
|
|
|
5427
5701
|
state: 'online' | 'offline' | 'degraded';
|
|
5428
5702
|
reason: string;
|
|
5429
5703
|
}
|
|
5704
|
+
/**
|
|
5705
|
+
* Options for `client.demo.end(score, options?)`.
|
|
5706
|
+
*
|
|
5707
|
+
* All optional. The landing-page demo shell can render a meaningful CTA
|
|
5708
|
+
* from `score` alone, but `durationMs` enables a nicer summary and
|
|
5709
|
+
* `metadata` lets games pass any extra context they want to surface.
|
|
5710
|
+
*/
|
|
5711
|
+
interface DemoEndOptions {
|
|
5712
|
+
durationMs?: number;
|
|
5713
|
+
metadata?: Record<string, unknown>;
|
|
5714
|
+
}
|
|
5715
|
+
/**
|
|
5716
|
+
* Wire payload for the `PLAYCADEMY_DEMO_END` message.
|
|
5717
|
+
*
|
|
5718
|
+
* `score` is required — the demo shell always needs something to display
|
|
5719
|
+
* when the round ends. `durationMs` and `metadata` are optional.
|
|
5720
|
+
*/
|
|
5721
|
+
interface DemoEndPayload extends DemoEndOptions {
|
|
5722
|
+
score: number;
|
|
5723
|
+
}
|
|
5430
5724
|
|
|
5431
5725
|
/**
|
|
5432
5726
|
* SDK-specific API response types
|
|
@@ -5685,196 +5979,5 @@ interface XpSummaryResponse {
|
|
|
5685
5979
|
total: TotalXpResponse;
|
|
5686
5980
|
}
|
|
5687
5981
|
|
|
5688
|
-
/**
|
|
5689
|
-
* @fileoverview Server SDK Type Definitions
|
|
5690
|
-
*
|
|
5691
|
-
* TypeScript type definitions for the server-side Playcademy SDK.
|
|
5692
|
-
* Includes configuration types, client state, and re-exported TimeBack types.
|
|
5693
|
-
*/
|
|
5694
|
-
|
|
5695
|
-
/**
|
|
5696
|
-
* Base configuration for TimeBack integration (shared across all courses).
|
|
5697
|
-
* References upstream TimeBack types from @playcademy/timeback.
|
|
5698
|
-
*
|
|
5699
|
-
* All fields are optional and support template variables: {grade}, {subject}, {gameSlug}
|
|
5700
|
-
*/
|
|
5701
|
-
interface TimebackBaseConfig {
|
|
5702
|
-
/** Organization configuration (shared across all courses) */
|
|
5703
|
-
organization?: Partial<OrganizationConfig>;
|
|
5704
|
-
/** Course defaults (can be overridden per-course) */
|
|
5705
|
-
course?: Partial<CourseConfig>;
|
|
5706
|
-
/** Component defaults */
|
|
5707
|
-
component?: Partial<ComponentConfig>;
|
|
5708
|
-
/** Resource defaults */
|
|
5709
|
-
resource?: Partial<ResourceConfig>;
|
|
5710
|
-
/** ComponentResource defaults */
|
|
5711
|
-
componentResource?: Partial<ComponentResourceConfig>;
|
|
5712
|
-
}
|
|
5713
|
-
/**
|
|
5714
|
-
* Extended course configuration that merges TimebackCourseConfig with per-course overrides.
|
|
5715
|
-
* Used in playcademy.config.* to allow per-course customization.
|
|
5716
|
-
*/
|
|
5717
|
-
interface TimebackCourseConfigWithOverrides extends TimebackCourseConfig {
|
|
5718
|
-
title?: string;
|
|
5719
|
-
courseCode?: string;
|
|
5720
|
-
level?: string;
|
|
5721
|
-
metadata?: CourseConfig['metadata'];
|
|
5722
|
-
totalXp?: number | null;
|
|
5723
|
-
masterableUnits?: number | null;
|
|
5724
|
-
}
|
|
5725
|
-
/**
|
|
5726
|
-
* TimeBack integration configuration for Playcademy config file.
|
|
5727
|
-
*
|
|
5728
|
-
* Supports two levels of customization:
|
|
5729
|
-
* 1. `base`: Shared defaults for all courses (organization, course, component, resource, componentResource)
|
|
5730
|
-
* 2. Per-course overrides in the `courses` array (title, courseCode, level, gradingScheme, metadata)
|
|
5731
|
-
*
|
|
5732
|
-
* Template variables ({grade}, {subject}, {gameSlug}) can be used in string fields.
|
|
5733
|
-
*/
|
|
5734
|
-
interface TimebackIntegrationConfig {
|
|
5735
|
-
/** Multi-grade course configuration (array of grade/subject/totalXp with optional per-course overrides) */
|
|
5736
|
-
courses: TimebackCourseConfigWithOverrides[];
|
|
5737
|
-
/** Optional base configuration (shared across all courses, can be overridden per-course) */
|
|
5738
|
-
base?: TimebackBaseConfig;
|
|
5739
|
-
}
|
|
5740
|
-
/**
|
|
5741
|
-
* Custom API routes integration
|
|
5742
|
-
*/
|
|
5743
|
-
interface CustomRoutesIntegration {
|
|
5744
|
-
/** Directory for custom API routes (defaults to 'server/api') */
|
|
5745
|
-
directory?: string;
|
|
5746
|
-
}
|
|
5747
|
-
/**
|
|
5748
|
-
* Database integration
|
|
5749
|
-
*/
|
|
5750
|
-
interface DatabaseIntegration {
|
|
5751
|
-
/** Database directory (defaults to 'db') */
|
|
5752
|
-
directory?: string;
|
|
5753
|
-
/** Schema strategy: 'push' uses drizzle-kit push-style diffing, 'migrate' uses migration files.
|
|
5754
|
-
* When omitted, auto-detects based on presence of a migrations directory with _journal.json. */
|
|
5755
|
-
strategy?: 'push' | 'migrate';
|
|
5756
|
-
}
|
|
5757
|
-
interface QueueConfig {
|
|
5758
|
-
maxBatchSize?: number;
|
|
5759
|
-
maxRetries?: number;
|
|
5760
|
-
maxBatchTimeout?: number;
|
|
5761
|
-
maxConcurrency?: number;
|
|
5762
|
-
retryDelay?: number;
|
|
5763
|
-
deadLetterQueue?: string;
|
|
5764
|
-
}
|
|
5765
|
-
/**
|
|
5766
|
-
* Integrations configuration
|
|
5767
|
-
* All backend features (database, custom routes, external services) are configured here
|
|
5768
|
-
*/
|
|
5769
|
-
interface IntegrationsConfig {
|
|
5770
|
-
/** TimeBack integration (optional) */
|
|
5771
|
-
timeback?: TimebackIntegrationConfig | null;
|
|
5772
|
-
/** Custom API routes (optional) */
|
|
5773
|
-
customRoutes?: CustomRoutesIntegration | boolean;
|
|
5774
|
-
/** Database (optional) */
|
|
5775
|
-
database?: DatabaseIntegration | boolean;
|
|
5776
|
-
/** Key-Value storage (optional) */
|
|
5777
|
-
kv?: boolean;
|
|
5778
|
-
/** Bucket storage (optional) */
|
|
5779
|
-
bucket?: boolean;
|
|
5780
|
-
/** Authentication (optional) */
|
|
5781
|
-
auth?: boolean;
|
|
5782
|
-
/** Queues (optional) */
|
|
5783
|
-
queues?: Record<string, QueueConfig | boolean>;
|
|
5784
|
-
}
|
|
5785
|
-
/**
|
|
5786
|
-
* Unified Playcademy configuration
|
|
5787
|
-
* Used for playcademy.config.{js,json}
|
|
5788
|
-
*/
|
|
5789
|
-
interface PlaycademyConfig {
|
|
5790
|
-
/** Game name */
|
|
5791
|
-
name: string;
|
|
5792
|
-
/** Game description */
|
|
5793
|
-
description?: string;
|
|
5794
|
-
/** Game emoji icon */
|
|
5795
|
-
emoji?: string;
|
|
5796
|
-
/** Build command to run before deployment */
|
|
5797
|
-
buildCommand?: string[];
|
|
5798
|
-
/** Path to build output */
|
|
5799
|
-
buildPath?: string;
|
|
5800
|
-
/** Game type */
|
|
5801
|
-
gameType?: 'hosted' | 'external';
|
|
5802
|
-
/** External URL (for external games) */
|
|
5803
|
-
externalUrl?: string;
|
|
5804
|
-
/** Game platform */
|
|
5805
|
-
platform?: 'web' | 'unity' | 'godot';
|
|
5806
|
-
/** Integrations (database, custom routes, external services) */
|
|
5807
|
-
integrations?: IntegrationsConfig;
|
|
5808
|
-
}
|
|
5809
|
-
|
|
5810
|
-
/**
|
|
5811
|
-
* Configuration options for initializing a PlaycademyClient instance.
|
|
5812
|
-
*
|
|
5813
|
-
* @example
|
|
5814
|
-
* ```typescript
|
|
5815
|
-
* const config: PlaycademyServerClientConfig = {
|
|
5816
|
-
* apiKey: process.env.PLAYCADEMY_API_KEY!,
|
|
5817
|
-
* gameId: 'my-math-game',
|
|
5818
|
-
* configPath: './playcademy.config.js'
|
|
5819
|
-
* }
|
|
5820
|
-
* ```
|
|
5821
|
-
*/
|
|
5822
|
-
interface PlaycademyServerClientConfig {
|
|
5823
|
-
/**
|
|
5824
|
-
* Playcademy API key for server-to-server authentication.
|
|
5825
|
-
* Obtain from the Playcademy developer dashboard.
|
|
5826
|
-
*/
|
|
5827
|
-
apiKey: string;
|
|
5828
|
-
/**
|
|
5829
|
-
* Optional path to playcademy.config.js file.
|
|
5830
|
-
* If not provided, searches current directory and up to 3 parent directories.
|
|
5831
|
-
* Ignored if `config` is provided directly.
|
|
5832
|
-
*
|
|
5833
|
-
* @example './config/playcademy.config.js'
|
|
5834
|
-
*/
|
|
5835
|
-
configPath?: string;
|
|
5836
|
-
/**
|
|
5837
|
-
* Optional config object (for edge environments without filesystem).
|
|
5838
|
-
* If provided, skips filesystem-based config loading.
|
|
5839
|
-
*
|
|
5840
|
-
* @example { name: 'My Game', integrations: { timeback: {...} } }
|
|
5841
|
-
*/
|
|
5842
|
-
config?: PlaycademyConfig;
|
|
5843
|
-
/**
|
|
5844
|
-
* Optional base URL for Playcademy API.
|
|
5845
|
-
* Defaults to environment variables or 'https://hub.playcademy.net'.
|
|
5846
|
-
*
|
|
5847
|
-
* @example 'http://localhost:3000' for local development
|
|
5848
|
-
*/
|
|
5849
|
-
baseUrl?: string;
|
|
5850
|
-
/**
|
|
5851
|
-
* Optional game ID.
|
|
5852
|
-
* If not provided, will attempt to fetch from API using the API token.
|
|
5853
|
-
*
|
|
5854
|
-
* @example 'my-math-game'
|
|
5855
|
-
*/
|
|
5856
|
-
gameId?: string;
|
|
5857
|
-
}
|
|
5858
|
-
/**
|
|
5859
|
-
* Internal state maintained by the PlaycademyClient instance.
|
|
5860
|
-
*
|
|
5861
|
-
* @internal
|
|
5862
|
-
*/
|
|
5863
|
-
interface PlaycademyServerClientState {
|
|
5864
|
-
/** API key for authentication */
|
|
5865
|
-
apiKey: string;
|
|
5866
|
-
/** Base URL for API requests */
|
|
5867
|
-
baseUrl: string;
|
|
5868
|
-
/** Game identifier */
|
|
5869
|
-
gameId: string;
|
|
5870
|
-
/** Loaded game configuration from playcademy.config.js */
|
|
5871
|
-
config: PlaycademyConfig;
|
|
5872
|
-
/**
|
|
5873
|
-
* TimeBack course ID fetched from the Playcademy API.
|
|
5874
|
-
* Used for all TimeBack event recording.
|
|
5875
|
-
*/
|
|
5876
|
-
courseId?: string;
|
|
5877
|
-
}
|
|
5878
|
-
|
|
5879
5982
|
export { AchievementCompletionType, NotificationStatus, NotificationType, PlaycademyClient };
|
|
5880
|
-
export type { AchievementCurrent, AchievementHistoryEntry, AchievementProgressResponse, AchievementScopeType, AchievementWithStatus, AuthCallbackPayload, AuthOptions, AuthProviderType, AuthResult, AuthServerMessage, AuthStateChangePayload, AuthStateUpdate, AuthenticatedUser, BetterAuthApiKey, BetterAuthApiKeyResponse, BetterAuthSignInResponse, BucketFile, CharacterComponentRow as CharacterComponent, CharacterComponentType, CharacterComponentWithSpriteUrl, CharacterComponentsOptions, ClientConfig, ClientEvents, ConnectionStatePayload, CourseXp, CreateCharacterData, CreateMapObjectData, CurrencyRow as Currency, DevUploadEvent, DevUploadHooks, DeveloperStatusEnumType, DeveloperStatusResponse, DeveloperStatusValue, DisconnectContext, DisconnectHandler, DisplayAlertPayload, EventListeners, ExternalGame, FetchedGame, Game, GameContextPayload, GameCustomHostname, GameInitUser, GameLeaderboardEntry, MapRow as GameMap, GamePlatform, GameRow as GameRecord, GameSessionRow as GameSession, GameTimebackIntegration, GameTokenResponse, GameType, GameUser, GetXpOptions, HostedGame, InitPayload, InsertCurrencyInput, InsertItemInput, InsertShopListingInput, InteractionType, InventoryItemRow as InventoryItem, InventoryItemWithItem, InventoryMutationResponse, ItemRow as Item, ItemType, KVKeyEntry, KVKeyMetadata, KVSeedEntry, KVStatsResponse, KeyEventPayload, LeaderboardEntry, LeaderboardOptions, LeaderboardTimeframe, LevelConfigRow as LevelConfig, LevelProgressResponse, LevelUpCheckResult, LoginResponse, ManifestV1, MapData, MapElementRow as MapElement, MapElementMetadata, MapElementWithGame, MapObjectRow as MapObject, MapObjectWithItem, NotificationRow as Notification, NotificationStats, PlaceableItemMetadata, PlatformTimebackUser, PlatformTimebackUserContext, PlaycademyServerClientConfig, PlaycademyServerClientState, PlayerCharacterRow as PlayerCharacter, PlayerCharacterAccessoryRow as PlayerCharacterAccessory, PlayerCurrency, PlayerInventoryItem, PlayerProfile, PlayerSessionPayload, PopulateStudentResponse, RealtimeTokenResponse, ScoreSubmission, ShopCurrency, ShopDisplayItem, ShopListingRow as ShopListing, ShopViewResponse, SpriteAnimationFrame, SpriteConfigWithDimensions, SpriteTemplateRow as SpriteTemplate, SpriteTemplateData, StartSessionResponse, TelemetryPayload, TimebackEnrollment, TimebackInitContext, TimebackOrganization, TimebackUser, TimebackUserContext, TimebackUserXp, TodayXpResponse, TokenRefreshPayload, TokenType, TotalXpResponse, UpdateCharacterData, UpdateCurrencyInput, UpdateItemInput, UpdateShopListingInput, UpsertGameMetadataInput, UserRow as User, UserEnrollment, UserInfo, UserLevelRow as UserLevel, UserLevelWithConfig, UserOrganization, UserRank, UserRankResponse, UserRoleEnumType, UserScore, UserTimebackData, XPAddResult, XpHistoryResponse, XpResponse, XpSummaryResponse };
|
|
5983
|
+
export type { AchievementCurrent, AchievementHistoryEntry, AchievementProgressResponse, AchievementScopeType, AchievementWithStatus, AuthCallbackPayload, AuthOptions, AuthProviderType, AuthResult, AuthServerMessage, AuthStateChangePayload, AuthStateUpdate, AuthenticatedUser, BetterAuthApiKey, BetterAuthApiKeyResponse, BetterAuthSignInResponse, BucketFile, CharacterComponentRow as CharacterComponent, CharacterComponentType, CharacterComponentWithSpriteUrl, CharacterComponentsOptions, ClientConfig, ClientEvents, ConnectionStatePayload, CourseXp, CreateCharacterData, CreateMapObjectData, CurrencyRow as Currency, DemoEndOptions, DemoEndPayload, DevUploadEvent, DevUploadHooks, DeveloperStatusEnumType, DeveloperStatusResponse, DeveloperStatusValue, DisconnectContext, DisconnectHandler, DisplayAlertPayload, EventListeners, ExternalGame, FetchedGame, Game, GameContextPayload, GameCustomHostname, GameInitUser, GameLeaderboardEntry, MapRow as GameMap, GamePlatform, GameRow as GameRecord, GameSessionRow as GameSession, GameTimebackIntegration, GameTokenResponse, GameType, GameUser, GetXpOptions, HostedGame, InitPayload, InsertCurrencyInput, InsertItemInput, InsertShopListingInput, InteractionType, InventoryItemRow as InventoryItem, InventoryItemWithItem, InventoryMutationResponse, ItemRow as Item, ItemType, KVKeyEntry, KVKeyMetadata, KVSeedEntry, KVStatsResponse, KeyEventPayload, LeaderboardEntry, LeaderboardOptions, LeaderboardTimeframe, LevelConfigRow as LevelConfig, LevelProgressResponse, LevelUpCheckResult, LoginResponse, ManifestV1, MapData, MapElementRow as MapElement, MapElementMetadata, MapElementWithGame, MapObjectRow as MapObject, MapObjectWithItem, NotificationRow as Notification, NotificationStats, PlaceableItemMetadata, PlatformTimebackUser, PlatformTimebackUserContext, PlaycademyMode, PlaycademyServerClientConfig, PlaycademyServerClientState, PlayerCharacterRow as PlayerCharacter, PlayerCharacterAccessoryRow as PlayerCharacterAccessory, PlayerCurrency, PlayerInventoryItem, PlayerProfile, PlayerSessionPayload, PopulateStudentResponse, RealtimeTokenResponse, ScoreSubmission, ShopCurrency, ShopDisplayItem, ShopListingRow as ShopListing, ShopViewResponse, SpriteAnimationFrame, SpriteConfigWithDimensions, SpriteTemplateRow as SpriteTemplate, SpriteTemplateData, StartSessionResponse, TelemetryPayload, TimebackEnrollment, TimebackInitContext, TimebackOrganization, TimebackUser, TimebackUserContext, TimebackUserXp, TodayXpResponse, TokenRefreshPayload, TokenType, TotalXpResponse, UpdateCharacterData, UpdateCurrencyInput, UpdateItemInput, UpdateShopListingInput, UpsertGameMetadataInput, UserRow as User, UserEnrollment, UserInfo, UserLevelRow as UserLevel, UserLevelWithConfig, UserOrganization, UserRank, UserRankResponse, UserRoleEnumType, UserScore, UserTimebackData, XPAddResult, XpHistoryResponse, XpResponse, XpSummaryResponse };
|