@playcademy/sdk 0.9.1-beta.2 → 0.9.1-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.
package/dist/index.d.ts CHANGED
@@ -1,5 +1,7 @@
1
- import { UserRole, AUTH_PROVIDER_IDS } from '@playcademy/constants';
2
- import * as drizzle_orm_pg_core from 'drizzle-orm/pg-core';
1
+ import * as _playcademy_types from '@playcademy/types';
2
+ import { TimebackGrade, TimebackSubject } from '@playcademy/types/timeback';
3
+ import { TimebackUserRole, UserEnrollment, UserOrganization, UserInfo } from '@playcademy/types/user';
4
+ import { AUTH_PROVIDER_IDS } from '@playcademy/constants';
3
5
 
4
6
  /**
5
7
  * Base error class for Cademy SDK specific errors.
@@ -138,231 +140,17 @@ interface ApiErrorInfo {
138
140
  * @example
139
141
  * ```typescript
140
142
  * try {
141
- * await client.shop.purchase(itemId)
143
+ * await client.scores.submit(100)
142
144
  * } catch (error) {
143
145
  * const info = extractApiErrorInfo(error)
144
146
  * if (info) {
145
- * showToast(`Error: ${info.message}`)
147
+ * console.error(`Error: ${info.message}`)
146
148
  * }
147
149
  * }
148
150
  * ```
149
151
  */
150
152
  declare function extractApiErrorInfo(error: unknown): ApiErrorInfo | null;
151
153
 
152
- /**
153
- * Connection monitoring types
154
- *
155
- * Type definitions for connection state, configuration, and callbacks.
156
- */
157
- /**
158
- * Possible connection states.
159
- *
160
- * - **online**: Connection is stable and healthy
161
- * - **offline**: Complete loss of network connectivity
162
- * - **degraded**: Connection is slow or experiencing intermittent issues
163
- */
164
- type ConnectionState = 'online' | 'offline' | 'degraded';
165
- /**
166
- * Configuration options for ConnectionMonitor.
167
- *
168
- * @see {@link ConnectionMonitor} for usage
169
- */
170
- interface ConnectionMonitorConfig {
171
- /** Base URL for heartbeat pings (e.g., 'https://api.playcademy.com') */
172
- baseUrl: string;
173
- /** How often to send heartbeat pings in milliseconds (default: 10000) */
174
- heartbeatInterval?: number;
175
- /** How long to wait for heartbeat response in milliseconds (default: 5000) */
176
- heartbeatTimeout?: number;
177
- /** Number of consecutive failures before triggering disconnect (default: 2) */
178
- failureThreshold?: number;
179
- /** Enable periodic heartbeat monitoring (default: true) */
180
- enableHeartbeat?: boolean;
181
- /** Enable browser online/offline event listeners (default: true) */
182
- enableOfflineEvents?: boolean;
183
- }
184
- /**
185
- * Callback function signature for connection state changes.
186
- *
187
- * @param state - The new connection state
188
- * @param reason - Human-readable reason for the state change
189
- */
190
- type ConnectionChangeCallback = (state: ConnectionState, reason: string) => void;
191
-
192
- /**
193
- * Connection Monitor
194
- *
195
- * Monitors network connectivity using multiple signals:
196
- * 1. navigator.onLine - Instant offline detection
197
- * 2. Periodic heartbeat - Detects slow/degraded connections
198
- * 3. Request failure tracking - Piggybacks on actual API calls
199
- *
200
- * Designed for school WiFi environments where connections may be
201
- * unstable or degraded without fully disconnecting.
202
- */
203
-
204
- /**
205
- * Monitors network connectivity using multiple signals and notifies callbacks of state changes.
206
- *
207
- * The ConnectionMonitor uses a multi-signal approach to detect connection issues:
208
- *
209
- * 1. **navigator.onLine events** - Instant detection of hard disconnects
210
- * 2. **Heartbeat pings** - Periodic checks to detect slow/degraded connections
211
- * 3. **Request failure tracking** - Piggybacks on actual API calls
212
- *
213
- * This comprehensive approach ensures reliable detection across different network
214
- * failure modes common in school WiFi environments (hard disconnect, slow connection,
215
- * intermittent failures).
216
- *
217
- * @example
218
- * ```typescript
219
- * const monitor = new ConnectionMonitor({
220
- * baseUrl: 'https://api.playcademy.com',
221
- * heartbeatInterval: 10000, // Check every 10s
222
- * failureThreshold: 2 // Trigger after 2 failures
223
- * })
224
- *
225
- * monitor.onChange((state, reason) => {
226
- * console.log(`Connection: ${state} - ${reason}`)
227
- * })
228
- *
229
- * monitor.start()
230
- * ```
231
- *
232
- * @see {@link ConnectionManagerConfig} for configuration options
233
- */
234
- declare class ConnectionMonitor {
235
- private state;
236
- private callbacks;
237
- private heartbeatInterval?;
238
- private consecutiveFailures;
239
- private isMonitoring;
240
- private config;
241
- /**
242
- * Creates a new ConnectionMonitor instance.
243
- *
244
- * The monitor starts in a stopped state. Call `start()` to begin monitoring.
245
- *
246
- * @param config - Configuration options
247
- * @param config.baseUrl - Base URL for heartbeat pings
248
- * @param config.heartbeatInterval - How often to check (default: 10000ms)
249
- * @param config.heartbeatTimeout - Request timeout (default: 5000ms)
250
- * @param config.failureThreshold - Failures before triggering disconnect (default: 2)
251
- * @param config.enableHeartbeat - Enable periodic checks (default: true)
252
- * @param config.enableOfflineEvents - Listen to browser events (default: true)
253
- */
254
- constructor(config: ConnectionMonitorConfig);
255
- /**
256
- * Starts monitoring the connection state.
257
- *
258
- * Sets up event listeners and begins heartbeat checks based on configuration.
259
- * Idempotent - safe to call multiple times.
260
- */
261
- start(): void;
262
- /**
263
- * Stops monitoring the connection state and cleans up resources.
264
- *
265
- * Removes event listeners and clears heartbeat intervals.
266
- * Idempotent - safe to call multiple times.
267
- */
268
- stop(): void;
269
- /**
270
- * Registers a callback to be notified of all connection state changes.
271
- *
272
- * The callback fires for all state transitions: online → offline,
273
- * offline → degraded, degraded → online, etc.
274
- *
275
- * @param callback - Function called with (state, reason) when connection changes
276
- * @returns Cleanup function to unregister the callback
277
- *
278
- * @example
279
- * ```typescript
280
- * const cleanup = monitor.onChange((state, reason) => {
281
- * console.log(`Connection: ${state}`)
282
- * if (state === 'offline') {
283
- * showReconnectingUI()
284
- * }
285
- * })
286
- *
287
- * // Later: cleanup() to unregister
288
- * ```
289
- */
290
- onChange(callback: ConnectionChangeCallback): () => void;
291
- /**
292
- * Gets the current connection state.
293
- *
294
- * @returns The current state ('online', 'offline', or 'degraded')
295
- */
296
- getState(): ConnectionState;
297
- /**
298
- * Manually triggers an immediate connection check.
299
- *
300
- * Forces a heartbeat ping to verify connectivity right now, bypassing
301
- * the normal interval. Useful before critical operations.
302
- *
303
- * @returns Promise resolving to the current connection state after the check
304
- *
305
- * @example
306
- * ```typescript
307
- * const state = await monitor.checkNow()
308
- * if (state !== 'online') {
309
- * alert('Please check your internet connection')
310
- * }
311
- * ```
312
- */
313
- checkNow(): Promise<ConnectionState>;
314
- /**
315
- * Reports a request failure for tracking.
316
- *
317
- * This should be called from your request wrapper whenever an API call fails.
318
- * Only network errors are tracked (TypeError, fetch failures) - HTTP error
319
- * responses (4xx, 5xx) are ignored.
320
- *
321
- * After consecutive failures exceed the threshold, the monitor transitions
322
- * to 'degraded' or 'offline' state.
323
- *
324
- * @param error - The error from the failed request
325
- *
326
- * @example
327
- * ```typescript
328
- * try {
329
- * await fetch('/api/data')
330
- * } catch (error) {
331
- * monitor.reportRequestFailure(error)
332
- * throw error
333
- * }
334
- * ```
335
- */
336
- reportRequestFailure(error: unknown): void;
337
- /**
338
- * Reports a successful request.
339
- *
340
- * This should be called from your request wrapper whenever an API call succeeds.
341
- * Resets the consecutive failure counter and transitions from 'degraded' to
342
- * 'online' if the connection has recovered.
343
- *
344
- * @example
345
- * ```typescript
346
- * try {
347
- * const result = await fetch('/api/data')
348
- * monitor.reportRequestSuccess()
349
- * return result
350
- * } catch (error) {
351
- * monitor.reportRequestFailure(error)
352
- * throw error
353
- * }
354
- * ```
355
- */
356
- reportRequestSuccess(): void;
357
- private _detectInitialState;
358
- private _handleOnline;
359
- private _handleOffline;
360
- private _startHeartbeat;
361
- private _performHeartbeat;
362
- private _handleHeartbeatFailure;
363
- private _setState;
364
- }
365
-
366
154
  /**
367
155
  * OAuth 2.0 implementation for the Playcademy SDK
368
156
  */
@@ -384,239 +172,6 @@ interface RetryPolicy {
384
172
  retryableMethods?: readonly Method[];
385
173
  }
386
174
 
387
- /**
388
- * User Types
389
- *
390
- * Enums, DTOs and API response types. Database row types are in @playcademy/data/types.
391
- *
392
- * @module types/user
393
- */
394
-
395
- type UserRoleEnumType = UserRole;
396
- type DeveloperStatusEnumType = 'none' | 'pending' | 'approved';
397
- type TimebackUserRole = 'administrator' | 'aide' | 'guardian' | 'parent' | 'proctor' | 'relative' | 'student' | 'teacher';
398
- type TimebackOrgType = 'department' | 'school' | 'district' | 'local' | 'state' | 'national';
399
- interface UserEnrollment {
400
- gameId?: string;
401
- courseId: string;
402
- enrollmentIds?: {
403
- active: string;
404
- inactive?: string[];
405
- };
406
- grade: number;
407
- subject: string;
408
- orgId?: string;
409
- }
410
- interface UserOrganization {
411
- id: string;
412
- name: string | null;
413
- type: TimebackOrgType | string;
414
- isPrimary: boolean;
415
- }
416
- interface TimebackStudentProfile {
417
- role: TimebackUserRole;
418
- organizations: UserOrganization[];
419
- }
420
- interface UserTimebackData extends TimebackStudentProfile {
421
- id: string;
422
- enrollments: UserEnrollment[];
423
- }
424
- /**
425
- * OpenID Connect UserInfo claims (NOT a database row).
426
- */
427
- interface UserInfo {
428
- sub: string;
429
- email: string;
430
- name: string | null;
431
- email_verified?: boolean;
432
- given_name?: string;
433
- family_name?: string;
434
- issuer?: string;
435
- lti_roles?: unknown;
436
- lti_context?: unknown;
437
- lti_resource_link?: unknown;
438
- timeback_id?: string;
439
- }
440
- interface DemoProfile {
441
- displayName: string;
442
- isDefault: boolean;
443
- }
444
- /**
445
- * Update shape for `client.demo.profile.update(...)`.
446
- *
447
- * Kept as a named type so callers typed against it pick up new fields
448
- * automatically, but `displayName` is the only updatable field today and
449
- * the server's `DemoProfileSchema` requires it — a no-field payload would
450
- * 400 at runtime, so we model that at the type level too. When additional
451
- * fields land, make them required/optional individually based on server
452
- * validation, rather than blanket-optional.
453
- */
454
- interface DemoProfileUpdate {
455
- displayName: string;
456
- }
457
- /**
458
- * Authenticated user for API responses.
459
- * Differs from UserRow: omits timebackId, adds hasTimebackAccount and timeback.
460
- */
461
- interface AuthenticatedUser {
462
- id: string;
463
- email: string;
464
- emailVerified: boolean;
465
- name: string | null;
466
- image: string | null;
467
- username: string | null;
468
- role: UserRoleEnumType;
469
- developerStatus: DeveloperStatusEnumType;
470
- characterCreated: boolean;
471
- createdAt: Date;
472
- updatedAt: Date;
473
- hasTimebackAccount: boolean;
474
- timeback?: UserTimebackData;
475
- }
476
-
477
- /**
478
- * Leaderboard Types
479
- *
480
- * @module types/leaderboard
481
- */
482
- type LeaderboardTimeframe = 'all_time' | 'monthly' | 'weekly' | 'daily';
483
- interface LeaderboardOptions {
484
- timeframe?: LeaderboardTimeframe;
485
- limit?: number;
486
- offset?: number;
487
- gameId?: string;
488
- }
489
- /**
490
- * Leaderboard entry with required game context.
491
- * Used when fetching leaderboards for a specific game.
492
- */
493
- interface GameLeaderboardEntry {
494
- rank: number;
495
- userId: string;
496
- username: string;
497
- userImage?: string | null;
498
- score: number;
499
- achievedAt: Date;
500
- metadata?: Record<string, unknown>;
501
- gameId: string;
502
- gameTitle: string;
503
- gameSlug: string;
504
- }
505
-
506
- /**
507
- * TimeBack Enums & Literal Types
508
- *
509
- * Basic type definitions used throughout the TimeBack integration.
510
- *
511
- * @module types/timeback/types
512
- */
513
- /**
514
- * Valid TimeBack subject values for course configuration.
515
- * These are the supported subject values for OneRoster courses.
516
- */
517
- type TimebackSubject = 'Reading' | 'Language' | 'Vocabulary' | 'Social Studies' | 'Writing' | 'Science' | 'FastMath' | 'Math' | 'None';
518
- /**
519
- * Grade levels per AE OneRoster GradeEnum.
520
- * -1 = Pre-K, 0 = Kindergarten, 1-12 = Grades 1-12, 13 = AP
521
- */
522
- type TimebackGrade = -1 | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13;
523
- /**
524
- * Valid Caliper subject values.
525
- * Matches OneRoster subjects, with "None" as a Caliper-specific fallback.
526
- */
527
- type CaliperSubject = 'Reading' | 'Language' | 'Vocabulary' | 'Social Studies' | 'Writing' | 'Science' | 'FastMath' | 'Math' | 'None';
528
-
529
- /**
530
- * TimeBack Client SDK DTOs
531
- *
532
- * Data transfer objects for the TimeBack client SDK including
533
- * progress tracking, session management, and activity completion.
534
- *
535
- * Note: TimebackClientConfig lives in @playcademy/timeback as it's
536
- * SDK configuration, not a DTO.
537
- *
538
- * @module types/timeback/client
539
- */
540
-
541
- /**
542
- * Known extensions for TimeBack Activity Metrics Collection
543
- */
544
- interface TimebackActivityExtensions {
545
- /** Percentage complete (0-100) for the app course */
546
- pctCompleteApp?: number;
547
- /** Allow other arbitrary extensions */
548
- [key: string]: unknown;
549
- }
550
- /**
551
- * Activity data for ending an activity
552
- */
553
- interface ActivityData {
554
- /** Unique activity identifier (required) */
555
- activityId: string;
556
- /** Grade level for this activity (required for multi-grade course routing) */
557
- grade: number;
558
- /** Subject area (required for multi-grade course routing) */
559
- subject: CaliperSubject;
560
- /** Activity display name (optional) */
561
- activityName?: string;
562
- /** Course identifier (auto-filled from config if not provided) */
563
- courseId?: string;
564
- /** Course display name (auto-filled from config if not provided) */
565
- courseName?: string;
566
- /** Student email address (optional) */
567
- studentEmail?: string;
568
- /** Application name for Caliper events (defaults to 'Game') */
569
- appName?: string;
570
- /** Sensor URL for Caliper events (defaults to baseUrl) */
571
- sensorUrl?: string;
572
- }
573
- /**
574
- * Score data with optional XP override for ending an activity
575
- */
576
- interface EndActivityScoreData {
577
- /** Number of questions answered correctly */
578
- correctQuestions: number;
579
- /** Total number of questions */
580
- totalQuestions: number;
581
- /** Optional XP override - bypasses automatic XP calculation */
582
- xpAwarded?: number;
583
- /** Number of learning units mastered */
584
- masteredUnits?: number;
585
- /** Optional arbitrary extensions to include in the Caliper event */
586
- extensions?: TimebackActivityExtensions;
587
- }
588
-
589
- /**
590
- * TimeBack API Request/Response Types
591
- *
592
- * Types for TimeBack API endpoints including XP tracking,
593
- * setup, verification, and activity completion.
594
- *
595
- * @module types/timeback/api
596
- */
597
-
598
- type TimebackPromotionStatus = 'promoted' | 'no-next-course' | 'already-promoted' | 'not-enrolled' | 'not-mastered';
599
- interface TimebackPromotionResult {
600
- status: TimebackPromotionStatus;
601
- currentCourseId: string;
602
- nextCourseId?: string;
603
- masteredUnits?: number;
604
- masterableUnits?: number;
605
- }
606
- interface EndActivityResponse {
607
- status: 'ok';
608
- courseId: string;
609
- xpAwarded: number;
610
- masteredUnits?: number;
611
- pctCompleteApp?: number;
612
- scoreStatus?: string;
613
- inProgress?: string;
614
- }
615
- interface AdvanceCourseResponse {
616
- status: 'ok';
617
- promotion: TimebackPromotionResult;
618
- }
619
-
620
175
  /**
621
176
  * Cache configuration types for runtime customization
622
177
  */
@@ -632,282 +187,6 @@ interface TTLCacheConfig {
632
187
  skipCache?: boolean;
633
188
  }
634
189
 
635
- declare const items: drizzle_orm_pg_core.PgTableWithColumns<{
636
- name: "items";
637
- schema: undefined;
638
- columns: {
639
- id: drizzle_orm_pg_core.PgColumn<{
640
- name: "id";
641
- tableName: "items";
642
- dataType: "string";
643
- columnType: "PgUUID";
644
- data: string;
645
- driverParam: string;
646
- notNull: true;
647
- hasDefault: true;
648
- isPrimaryKey: true;
649
- isAutoincrement: false;
650
- hasRuntimeDefault: false;
651
- enumValues: undefined;
652
- baseColumn: never;
653
- identity: undefined;
654
- generated: undefined;
655
- }, {}, {}>;
656
- slug: drizzle_orm_pg_core.PgColumn<{
657
- name: "slug";
658
- tableName: "items";
659
- dataType: "string";
660
- columnType: "PgText";
661
- data: string;
662
- driverParam: string;
663
- notNull: true;
664
- hasDefault: false;
665
- isPrimaryKey: false;
666
- isAutoincrement: false;
667
- hasRuntimeDefault: false;
668
- enumValues: [string, ...string[]];
669
- baseColumn: never;
670
- identity: undefined;
671
- generated: undefined;
672
- }, {}, {}>;
673
- gameId: drizzle_orm_pg_core.PgColumn<{
674
- name: "game_id";
675
- tableName: "items";
676
- dataType: "string";
677
- columnType: "PgUUID";
678
- data: string;
679
- driverParam: string;
680
- notNull: false;
681
- hasDefault: false;
682
- isPrimaryKey: false;
683
- isAutoincrement: false;
684
- hasRuntimeDefault: false;
685
- enumValues: undefined;
686
- baseColumn: never;
687
- identity: undefined;
688
- generated: undefined;
689
- }, {}, {}>;
690
- displayName: drizzle_orm_pg_core.PgColumn<{
691
- name: "display_name";
692
- tableName: "items";
693
- dataType: "string";
694
- columnType: "PgText";
695
- data: string;
696
- driverParam: string;
697
- notNull: true;
698
- hasDefault: false;
699
- isPrimaryKey: false;
700
- isAutoincrement: false;
701
- hasRuntimeDefault: false;
702
- enumValues: [string, ...string[]];
703
- baseColumn: never;
704
- identity: undefined;
705
- generated: undefined;
706
- }, {}, {}>;
707
- description: drizzle_orm_pg_core.PgColumn<{
708
- name: "description";
709
- tableName: "items";
710
- dataType: "string";
711
- columnType: "PgText";
712
- data: string;
713
- driverParam: string;
714
- notNull: false;
715
- hasDefault: false;
716
- isPrimaryKey: false;
717
- isAutoincrement: false;
718
- hasRuntimeDefault: false;
719
- enumValues: [string, ...string[]];
720
- baseColumn: never;
721
- identity: undefined;
722
- generated: undefined;
723
- }, {}, {}>;
724
- type: drizzle_orm_pg_core.PgColumn<{
725
- name: "type";
726
- tableName: "items";
727
- dataType: "string";
728
- columnType: "PgEnumColumn";
729
- data: "accessory" | "badge" | "collectible" | "consumable" | "currency" | "other" | "trophy" | "unlock" | "upgrade";
730
- driverParam: string;
731
- notNull: true;
732
- hasDefault: true;
733
- isPrimaryKey: false;
734
- isAutoincrement: false;
735
- hasRuntimeDefault: false;
736
- enumValues: ["currency", "badge", "trophy", "collectible", "consumable", "unlock", "upgrade", "accessory", "other"];
737
- baseColumn: never;
738
- identity: undefined;
739
- generated: undefined;
740
- }, {}, {}>;
741
- isPlaceable: drizzle_orm_pg_core.PgColumn<{
742
- name: "is_placeable";
743
- tableName: "items";
744
- dataType: "boolean";
745
- columnType: "PgBoolean";
746
- data: boolean;
747
- driverParam: boolean;
748
- notNull: true;
749
- hasDefault: true;
750
- isPrimaryKey: false;
751
- isAutoincrement: false;
752
- hasRuntimeDefault: false;
753
- enumValues: undefined;
754
- baseColumn: never;
755
- identity: undefined;
756
- generated: undefined;
757
- }, {}, {}>;
758
- imageUrl: drizzle_orm_pg_core.PgColumn<{
759
- name: "image_url";
760
- tableName: "items";
761
- dataType: "string";
762
- columnType: "PgText";
763
- data: string;
764
- driverParam: string;
765
- notNull: false;
766
- hasDefault: false;
767
- isPrimaryKey: false;
768
- isAutoincrement: false;
769
- hasRuntimeDefault: false;
770
- enumValues: [string, ...string[]];
771
- baseColumn: never;
772
- identity: undefined;
773
- generated: undefined;
774
- }, {}, {}>;
775
- metadata: drizzle_orm_pg_core.PgColumn<{
776
- name: "metadata";
777
- tableName: "items";
778
- dataType: "json";
779
- columnType: "PgJsonb";
780
- data: unknown;
781
- driverParam: unknown;
782
- notNull: false;
783
- hasDefault: true;
784
- isPrimaryKey: false;
785
- isAutoincrement: false;
786
- hasRuntimeDefault: false;
787
- enumValues: undefined;
788
- baseColumn: never;
789
- identity: undefined;
790
- generated: undefined;
791
- }, {}, {}>;
792
- createdAt: drizzle_orm_pg_core.PgColumn<{
793
- name: "created_at";
794
- tableName: "items";
795
- dataType: "date";
796
- columnType: "PgTimestamp";
797
- data: Date;
798
- driverParam: string;
799
- notNull: true;
800
- hasDefault: true;
801
- isPrimaryKey: false;
802
- isAutoincrement: false;
803
- hasRuntimeDefault: false;
804
- enumValues: undefined;
805
- baseColumn: never;
806
- identity: undefined;
807
- generated: undefined;
808
- }, {}, {}>;
809
- };
810
- dialect: 'pg';
811
- }>;
812
- declare const inventoryItems: drizzle_orm_pg_core.PgTableWithColumns<{
813
- name: "inventory_items";
814
- schema: undefined;
815
- columns: {
816
- id: drizzle_orm_pg_core.PgColumn<{
817
- name: "id";
818
- tableName: "inventory_items";
819
- dataType: "string";
820
- columnType: "PgUUID";
821
- data: string;
822
- driverParam: string;
823
- notNull: true;
824
- hasDefault: true;
825
- isPrimaryKey: true;
826
- isAutoincrement: false;
827
- hasRuntimeDefault: false;
828
- enumValues: undefined;
829
- baseColumn: never;
830
- identity: undefined;
831
- generated: undefined;
832
- }, {}, {}>;
833
- userId: drizzle_orm_pg_core.PgColumn<{
834
- name: "user_id";
835
- tableName: "inventory_items";
836
- dataType: "string";
837
- columnType: "PgText";
838
- data: string;
839
- driverParam: string;
840
- notNull: true;
841
- hasDefault: false;
842
- isPrimaryKey: false;
843
- isAutoincrement: false;
844
- hasRuntimeDefault: false;
845
- enumValues: [string, ...string[]];
846
- baseColumn: never;
847
- identity: undefined;
848
- generated: undefined;
849
- }, {}, {}>;
850
- itemId: drizzle_orm_pg_core.PgColumn<{
851
- name: "item_id";
852
- tableName: "inventory_items";
853
- dataType: "string";
854
- columnType: "PgUUID";
855
- data: string;
856
- driverParam: string;
857
- notNull: true;
858
- hasDefault: false;
859
- isPrimaryKey: false;
860
- isAutoincrement: false;
861
- hasRuntimeDefault: false;
862
- enumValues: undefined;
863
- baseColumn: never;
864
- identity: undefined;
865
- generated: undefined;
866
- }, {}, {}>;
867
- quantity: drizzle_orm_pg_core.PgColumn<{
868
- name: "quantity";
869
- tableName: "inventory_items";
870
- dataType: "number";
871
- columnType: "PgInteger";
872
- data: number;
873
- driverParam: string | number;
874
- notNull: true;
875
- hasDefault: true;
876
- isPrimaryKey: false;
877
- isAutoincrement: false;
878
- hasRuntimeDefault: false;
879
- enumValues: undefined;
880
- baseColumn: never;
881
- identity: undefined;
882
- generated: undefined;
883
- }, {}, {}>;
884
- updatedAt: drizzle_orm_pg_core.PgColumn<{
885
- name: "updated_at";
886
- tableName: "inventory_items";
887
- dataType: "date";
888
- columnType: "PgTimestamp";
889
- data: Date;
890
- driverParam: string;
891
- notNull: false;
892
- hasDefault: true;
893
- isPrimaryKey: false;
894
- isAutoincrement: false;
895
- hasRuntimeDefault: false;
896
- enumValues: undefined;
897
- baseColumn: never;
898
- identity: undefined;
899
- generated: undefined;
900
- }, {}, {}>;
901
- };
902
- dialect: 'pg';
903
- }>;
904
-
905
- type ItemRow = typeof items.$inferSelect;
906
- type InventoryItemRow = typeof inventoryItems.$inferSelect;
907
- type InventoryItemWithItem = InventoryItemRow & {
908
- item: ItemRow;
909
- };
910
-
911
190
  /**
912
191
  * @fileoverview Authentication Strategy Pattern
913
192
  *
@@ -929,7 +208,7 @@ interface AuthStrategy {
929
208
 
930
209
  /**
931
210
  * Base Playcademy SDK client with shared infrastructure.
932
- * Provides authentication, HTTP requests, events, connection monitoring,
211
+ * Provides authentication, HTTP requests, events,
933
212
  * and fundamental namespaces used by all clients.
934
213
  *
935
214
  * Extended by PlaycademyClient (game SDK) and PlaycademyInternalClient (platform SDK).
@@ -942,24 +221,11 @@ declare abstract class PlaycademyBaseClient {
942
221
  protected gameId?: string;
943
222
  protected config: Partial<ClientConfig>;
944
223
  protected listeners: EventListeners;
945
- protected internalClientSessionId?: string;
946
224
  protected authContext?: {
947
225
  isInIframe: boolean;
948
226
  };
949
227
  protected initPayload?: InitPayload;
950
- protected connectionManager?: ConnectionManager;
951
228
  protected launchId?: string;
952
- /**
953
- * Internal session manager for automatic session lifecycle.
954
- * @private
955
- * @internal
956
- */
957
- protected _sessionManager: {
958
- startSession: (gameId: string) => Promise<{
959
- sessionId: string;
960
- }>;
961
- endSession: (sessionId: string, gameId: string) => Promise<void>;
962
- };
963
229
  constructor(config?: Partial<ClientConfig>);
964
230
  /**
965
231
  * Gets the effective base URL for API requests.
@@ -994,18 +260,6 @@ declare abstract class PlaycademyBaseClient {
994
260
  * Registers a callback to be called when authentication state changes.
995
261
  */
996
262
  onAuthChange(callback: (token: string | null) => void): void;
997
- /**
998
- * Registers a callback to be called when connection issues are detected.
999
- */
1000
- onDisconnect(callback: (context: DisconnectContext) => void | Promise<void>): () => void;
1001
- /**
1002
- * Gets the current connection state.
1003
- */
1004
- getConnectionState(): ConnectionState | 'unknown';
1005
- /**
1006
- * Manually triggers a connection check immediately.
1007
- */
1008
- checkConnection(): Promise<ConnectionState | 'unknown'>;
1009
263
  /**
1010
264
  * Sets the authentication context for the client.
1011
265
  * @internal
@@ -1057,25 +311,11 @@ declare abstract class PlaycademyBaseClient {
1057
311
  */
1058
312
  private _detectAuthContext;
1059
313
  /**
1060
- * Initializes connection monitoring if enabled.
1061
- */
1062
- private _initializeConnectionMonitor;
1063
- private _initializeInternalSession;
1064
- /**
1065
- * Current user data and inventory management.
314
+ * Current user data.
1066
315
  * - `me()` - Get authenticated user profile
1067
- * - `inventory.get()` - List user's items
1068
- * - `inventory.add(slug, qty)` - Award items to user
1069
316
  */
1070
317
  users: {
1071
- me: () => Promise<AuthenticatedUser>;
1072
- inventory: {
1073
- get: () => Promise<InventoryItemWithItem[]>;
1074
- add: (identifier: string, qty: number) => Promise<InventoryMutationResponse>;
1075
- remove: (identifier: string, qty: number) => Promise<InventoryMutationResponse>;
1076
- quantity: (identifier: string) => Promise<number>;
1077
- has: (identifier: string, minQuantity?: number) => Promise<boolean>;
1078
- };
318
+ me: () => Promise<_playcademy_types.AuthenticatedUser>;
1079
319
  };
1080
320
  }
1081
321
 
@@ -1106,8 +346,6 @@ declare abstract class PlaycademyBaseClient {
1106
346
  declare function init<T extends PlaycademyBaseClient = PlaycademyBaseClient>(this: new (config?: Partial<ClientConfig>) => T, options?: {
1107
347
  baseUrl?: string;
1108
348
  allowedParentOrigins?: string[];
1109
- onDisconnect?: DisconnectHandler;
1110
- enableConnectionMonitoring?: boolean;
1111
349
  }): Promise<T>;
1112
350
 
1113
351
  /**
@@ -1225,14 +463,6 @@ declare enum MessageEvents {
1225
463
  * Payload: boolean (true = show overlay, false = hide overlay)
1226
464
  */
1227
465
  OVERLAY = "PLAYCADEMY_OVERLAY",
1228
- /**
1229
- * Broadcasts connection state changes to games.
1230
- * Sent by platform when network connectivity changes.
1231
- * Payload:
1232
- * - `state`: 'online' | 'offline' | 'degraded'
1233
- * - `reason`: string
1234
- */
1235
- CONNECTION_STATE = "PLAYCADEMY_CONNECTION_STATE",
1236
466
  /**
1237
467
  * Game has finished loading and is ready to receive messages.
1238
468
  * Sent once after game initialization is complete.
@@ -1270,14 +500,6 @@ declare enum MessageEvents {
1270
500
  * - `type`: 'keydown' | 'keyup'
1271
501
  */
1272
502
  KEY_EVENT = "PLAYCADEMY_KEY_EVENT",
1273
- /**
1274
- * Game requests platform to display an alert.
1275
- * Sent when connection issues are detected or other important events occur.
1276
- * Payload:
1277
- * - `message`: string
1278
- * - `options`: `{ type?: 'info' | 'warning' | 'error', duration?: number }`
1279
- */
1280
- DISPLAY_ALERT = "PLAYCADEMY_DISPLAY_ALERT",
1281
503
  /**
1282
504
  * Game signals that demo mode has ended.
1283
505
  * Sent when a demo experience reaches its CTA/upgrade boundary.
@@ -1342,8 +564,6 @@ interface MessageEventMap {
1342
564
  [MessageEvents.FORCE_EXIT]: void;
1343
565
  /** Overlay visibility state (true = show, false = hide) */
1344
566
  [MessageEvents.OVERLAY]: boolean;
1345
- /** Connection state change from platform */
1346
- [MessageEvents.CONNECTION_STATE]: ConnectionStatePayload;
1347
567
  /** Ready message has no payload data */
1348
568
  [MessageEvents.READY]: void;
1349
569
  /** SDK init error data */
@@ -1354,8 +574,6 @@ interface MessageEventMap {
1354
574
  [MessageEvents.TELEMETRY]: TelemetryPayload;
1355
575
  /** Key event data */
1356
576
  [MessageEvents.KEY_EVENT]: KeyEventPayload;
1357
- /** Display alert request from game */
1358
- [MessageEvents.DISPLAY_ALERT]: DisplayAlertPayload;
1359
577
  /** Demo end signal from game */
1360
578
  [MessageEvents.DEMO_END]: DemoEndPayload;
1361
579
  /** Authentication state change notification */
@@ -1755,7 +973,7 @@ declare class PlaycademyClient extends PlaycademyBaseClient {
1755
973
  getGameToken: (gameId: string, options?: {
1756
974
  apply?: boolean;
1757
975
  }) => Promise<GameTokenResponse>;
1758
- exit: () => Promise<void>;
976
+ exit: () => void;
1759
977
  onInit: (handler: (context: GameContextPayload) => void) => void;
1760
978
  onTokenRefresh: (handler: (data: {
1761
979
  token: string;
@@ -1806,23 +1024,13 @@ declare class PlaycademyClient extends PlaycademyBaseClient {
1806
1024
  timeback: {
1807
1025
  readonly user: TimebackUser;
1808
1026
  readonly currentRunId: string | undefined;
1809
- startActivity: (metadata: ActivityData, options?: StartActivityOptions) => StartActivityResult;
1027
+ startActivity: (metadata: _playcademy_types.ActivityData, options?: StartActivityOptions) => StartActivityResult;
1810
1028
  pauseActivity: () => void;
1811
1029
  resumeActivity: () => void;
1812
- endActivity: (data: EndActivityScoreData) => Promise<EndActivityResponse>;
1030
+ endActivity: (data: _playcademy_types.EndActivityScoreData) => Promise<_playcademy_types.EndActivityResponse>;
1813
1031
  advanceCourse: (options?: {
1814
- subject?: TimebackSubject;
1815
- }) => Promise<AdvanceCourseResponse>;
1816
- };
1817
- /**
1818
- * Playcademy Credits (platform currency) management.
1819
- * - `get()` - Get user's credit balance
1820
- * - `add(amount)` - Award credits to user
1821
- */
1822
- credits: {
1823
- balance: () => Promise<number>;
1824
- add: (amount: number) => Promise<number>;
1825
- spend: (amount: number) => Promise<number>;
1032
+ subject?: _playcademy_types.TimebackSubject;
1033
+ }) => Promise<_playcademy_types.AdvanceCourseResponse>;
1826
1034
  };
1827
1035
  /**
1828
1036
  * Game score submission and leaderboards.
@@ -1836,7 +1044,7 @@ declare class PlaycademyClient extends PlaycademyBaseClient {
1836
1044
  * - `fetch(options?)` - Fetch leaderboard entries
1837
1045
  */
1838
1046
  leaderboard: {
1839
- fetch: (options?: LeaderboardOptions) => Promise<GameLeaderboardEntry[]>;
1047
+ fetch: (options?: _playcademy_types.LeaderboardOptions) => Promise<_playcademy_types.GameLeaderboardEntry[]>;
1840
1048
  };
1841
1049
  /**
1842
1050
  * Demo-mode helpers. Methods throw when called outside `client.mode === 'demo'`,
@@ -1847,20 +1055,11 @@ declare class PlaycademyClient extends PlaycademyBaseClient {
1847
1055
  */
1848
1056
  demo: {
1849
1057
  profile: {
1850
- get: () => Promise<DemoProfile>;
1851
- update: (updates: DemoProfileUpdate) => Promise<DemoProfile>;
1058
+ get: () => Promise<_playcademy_types.DemoProfile>;
1059
+ update: (updates: _playcademy_types.DemoProfileUpdate) => Promise<_playcademy_types.DemoProfile>;
1852
1060
  };
1853
1061
  end: (score: number, options?: DemoEndOptions) => void;
1854
1062
  };
1855
- /**
1856
- * Realtime multiplayer authentication.
1857
- * - `getToken()` - Get token for WebSocket/realtime connections
1858
- */
1859
- realtime: {
1860
- token: {
1861
- get: () => Promise<RealtimeTokenResponse>;
1862
- };
1863
- };
1864
1063
  /**
1865
1064
  * Make requests to your game's custom backend API routes.
1866
1065
  * - `get(path)`, `post(path, body)`, `put()`, `delete()` - HTTP methods
@@ -2113,32 +1312,8 @@ interface ClientConfig {
2113
1312
  tokenType?: TokenType;
2114
1313
  gameId?: string;
2115
1314
  launchId?: string;
2116
- autoStartSession?: boolean;
2117
- onDisconnect?: DisconnectHandler;
2118
- enableConnectionMonitoring?: boolean;
2119
1315
  mode?: PlaycademyMode;
2120
1316
  }
2121
- /**
2122
- * Handler called when connection state changes to offline or degraded.
2123
- * Games can implement this to handle disconnects gracefully.
2124
- */
2125
- type DisconnectHandler = (context: DisconnectContext) => void | Promise<void>;
2126
- /**
2127
- * Context provided to disconnect handlers
2128
- */
2129
- interface DisconnectContext {
2130
- /** Current connection state */
2131
- state: 'offline' | 'degraded';
2132
- /** Reason for the disconnect */
2133
- reason: string;
2134
- /** Timestamp when disconnect was detected */
2135
- timestamp: number;
2136
- /** Utility to display a platform-level alert */
2137
- displayAlert: (message: string, options?: {
2138
- type?: 'info' | 'warning' | 'error';
2139
- duration?: number;
2140
- }) => void;
2141
- }
2142
1317
  interface InitPayload {
2143
1318
  /** Hub API base URL */
2144
1319
  baseUrl: string;
@@ -2148,8 +1323,6 @@ interface InitPayload {
2148
1323
  token: string;
2149
1324
  /** Game ID */
2150
1325
  gameId: string;
2151
- /** Realtime WebSocket URL */
2152
- realtimeUrl?: string;
2153
1326
  /** Timeback context (if user has a Timeback account) */
2154
1327
  timeback?: TimebackInitContext;
2155
1328
  /** Runtime mode for the game client */
@@ -2158,7 +1331,6 @@ interface InitPayload {
2158
1331
  interface GameContextPayload {
2159
1332
  token: string;
2160
1333
  baseUrl: string;
2161
- realtimeUrl: string;
2162
1334
  gameId: string;
2163
1335
  forwardKeys?: string[];
2164
1336
  mode?: PlaycademyMode;
@@ -2170,38 +1342,12 @@ interface ClientEvents {
2170
1342
  authChange: {
2171
1343
  token: string | null;
2172
1344
  };
2173
- inventoryChange: {
2174
- itemId: string;
2175
- delta: number;
2176
- newTotal: number;
2177
- };
2178
- levelUp: {
2179
- oldLevel: number;
2180
- newLevel: number;
2181
- creditsAwarded: number;
2182
- };
2183
- xpGained: {
2184
- amount: number;
2185
- totalXP: number;
2186
- leveledUp: boolean;
2187
- };
2188
- connectionChange: {
2189
- state: 'online' | 'offline' | 'degraded';
2190
- reason: string;
2191
- };
2192
1345
  }
2193
1346
 
2194
1347
  /**
2195
1348
  * Event and message payload types for SDK messaging system
2196
1349
  */
2197
1350
 
2198
- interface DisplayAlertPayload {
2199
- message: string;
2200
- options?: {
2201
- type?: 'info' | 'warning' | 'error';
2202
- duration?: number;
2203
- };
2204
- }
2205
1351
  /**
2206
1352
  * Authentication state change event payload.
2207
1353
  * Used when authentication state changes in the application.
@@ -2258,14 +1404,6 @@ interface KeyEventPayload {
2258
1404
  /** Event type */
2259
1405
  type: 'keydown' | 'keyup';
2260
1406
  }
2261
- /**
2262
- * Connection state payload.
2263
- * Broadcast from platform to games when connection changes.
2264
- */
2265
- interface ConnectionStatePayload {
2266
- state: 'online' | 'offline' | 'degraded';
2267
- reason: string;
2268
- }
2269
1407
  /**
2270
1408
  * Init error payload.
2271
1409
  * Sent from game iframe to parent when SDK initialization fails
@@ -2306,19 +1444,6 @@ interface GameTokenResponse {
2306
1444
  exp: number;
2307
1445
  baseUrl?: string;
2308
1446
  }
2309
- interface InventoryMutationResponse {
2310
- newTotal: number;
2311
- }
2312
-
2313
- /**
2314
- * Realtime namespace types
2315
- */
2316
- /**
2317
- * Response type for the realtime token API
2318
- */
2319
- interface RealtimeTokenResponse {
2320
- token: string;
2321
- }
2322
1447
 
2323
1448
  /**
2324
1449
  * Scores namespace types
@@ -2400,179 +1525,5 @@ interface DevUploadHooks {
2400
1525
  onClose?: () => void;
2401
1526
  }
2402
1527
 
2403
- /**
2404
- * Connection Manager
2405
- *
2406
- * Manages connection monitoring and integrates it with the Playcademy client.
2407
- * Handles event wiring, state management, and disconnect callbacks.
2408
- *
2409
- * In iframe mode, disables local monitoring and listens to platform connection
2410
- * state broadcasts instead (avoids duplicate heartbeats).
2411
- */
2412
-
2413
- /**
2414
- * Configuration for the ConnectionManager.
2415
- */
2416
- interface ConnectionManagerConfig {
2417
- /** Base URL for API requests (used for heartbeat pings) */
2418
- baseUrl: string;
2419
- /** Authentication context (iframe vs standalone) for alert routing */
2420
- authContext?: {
2421
- isInIframe: boolean;
2422
- };
2423
- /** Handler to call when connection issues are detected */
2424
- onDisconnect?: DisconnectHandler;
2425
- /** Callback to emit connection change events to the client */
2426
- onConnectionChange?: (state: ConnectionState, reason: string) => void;
2427
- }
2428
- /**
2429
- * Manages connection monitoring for the Playcademy client.
2430
- *
2431
- * The ConnectionManager serves as an integration layer between the low-level
2432
- * ConnectionMonitor and the PlaycademyClient. It handles:
2433
- * - Event wiring and coordination
2434
- * - Disconnect callbacks with context
2435
- * - Platform-level alert integration
2436
- * - Request success/failure tracking
2437
- *
2438
- * This class is used internally by PlaycademyClient and typically not
2439
- * instantiated directly by game developers.
2440
- *
2441
- * @see {@link ConnectionMonitor} for the underlying monitoring implementation
2442
- * @see {@link PlaycademyClient.onDisconnect} for the public API
2443
- */
2444
- declare class ConnectionManager {
2445
- private monitor?;
2446
- private authContext?;
2447
- private disconnectHandler?;
2448
- private connectionChangeCallback?;
2449
- private currentState;
2450
- private additionalDisconnectHandlers;
2451
- /**
2452
- * Creates a new ConnectionManager instance.
2453
- *
2454
- * @param config - Configuration options for the manager
2455
- *
2456
- * @example
2457
- * ```typescript
2458
- * const manager = new ConnectionManager({
2459
- * baseUrl: 'https://api.playcademy.com',
2460
- * authContext: { isInIframe: false },
2461
- * onDisconnect: (context) => {
2462
- * console.log(`Disconnected: ${context.state}`)
2463
- * },
2464
- * onConnectionChange: (state, reason) => {
2465
- * console.log(`Connection changed: ${state}`)
2466
- * }
2467
- * })
2468
- * ```
2469
- */
2470
- constructor(config: ConnectionManagerConfig);
2471
- /**
2472
- * Gets the current connection state.
2473
- *
2474
- * @returns The current connection state ('online', 'offline', or 'degraded')
2475
- *
2476
- * @example
2477
- * ```typescript
2478
- * const state = manager.getState()
2479
- * if (state === 'offline') {
2480
- * console.log('No connection')
2481
- * }
2482
- * ```
2483
- */
2484
- getState(): ConnectionState;
2485
- /**
2486
- * Manually triggers a connection check immediately.
2487
- *
2488
- * Forces a heartbeat ping to verify the current connection status.
2489
- * Useful when you need to check connectivity before a critical operation.
2490
- *
2491
- * In iframe mode, this returns the last known state from platform.
2492
- *
2493
- * @returns Promise resolving to the current connection state
2494
- *
2495
- * @example
2496
- * ```typescript
2497
- * const state = await manager.checkNow()
2498
- * if (state === 'online') {
2499
- * await performCriticalOperation()
2500
- * }
2501
- * ```
2502
- */
2503
- checkNow(): Promise<ConnectionState>;
2504
- /**
2505
- * Reports a successful API request to the connection monitor.
2506
- *
2507
- * This resets the consecutive failure counter and transitions from
2508
- * 'degraded' to 'online' state if applicable.
2509
- *
2510
- * Typically called automatically by the SDK's request wrapper.
2511
- * No-op in iframe mode (platform handles monitoring).
2512
- */
2513
- reportRequestSuccess(): void;
2514
- /**
2515
- * Reports a failed API request to the connection monitor.
2516
- *
2517
- * Only network errors are tracked (not 4xx/5xx HTTP responses).
2518
- * After consecutive failures exceed the threshold, the state transitions
2519
- * to 'degraded' or 'offline'.
2520
- *
2521
- * Typically called automatically by the SDK's request wrapper.
2522
- * No-op in iframe mode (platform handles monitoring).
2523
- *
2524
- * @param error - The error from the failed request
2525
- */
2526
- reportRequestFailure(error: unknown): void;
2527
- /**
2528
- * Registers a callback to be called when connection issues are detected.
2529
- *
2530
- * The callback only fires for 'offline' and 'degraded' states, not when
2531
- * recovering to 'online'. This provides a clean API for games to handle
2532
- * disconnect scenarios without being notified of every state change.
2533
- *
2534
- * Works in both iframe and standalone modes transparently.
2535
- *
2536
- * @param callback - Function to call when connection degrades
2537
- * @returns Cleanup function to unregister the callback
2538
- *
2539
- * @example
2540
- * ```typescript
2541
- * const cleanup = manager.onDisconnect(({ state, reason, displayAlert }) => {
2542
- * if (state === 'offline') {
2543
- * displayAlert?.('Connection lost. Saving your progress...', { type: 'error' })
2544
- * saveGameState()
2545
- * }
2546
- * })
2547
- *
2548
- * // Later: cleanup() to unregister
2549
- * ```
2550
- */
2551
- onDisconnect(callback: DisconnectHandler): () => void;
2552
- /**
2553
- * Stops connection monitoring and performs cleanup.
2554
- *
2555
- * Removes event listeners and clears heartbeat intervals.
2556
- * Should be called when the client is being destroyed.
2557
- */
2558
- stop(): void;
2559
- /**
2560
- * Sets up listener for platform connection state broadcasts (iframe mode only).
2561
- */
2562
- private _setupPlatformListener;
2563
- /**
2564
- * Handles connection state changes from the monitor or platform.
2565
- *
2566
- * Coordinates between:
2567
- * 1. Emitting events to the client (for client.on('connectionChange'))
2568
- * 2. Calling the disconnect handler if configured
2569
- * 3. Calling any additional handlers registered via onDisconnect()
2570
- *
2571
- * @param state - The new connection state
2572
- * @param reason - Human-readable reason for the state change
2573
- */
2574
- private _handleConnectionChange;
2575
- }
2576
-
2577
- export { ApiError, ConnectionManager, ConnectionMonitor, MessageEvents, PlaycademyClient, PlaycademyError, extractApiErrorInfo, messaging };
2578
- export type { ApiErrorCode, ApiErrorInfo, ConnectionMonitorConfig, ConnectionState, ConnectionStatePayload, DevUploadEvent, DevUploadHooks, DisconnectContext, DisconnectHandler, DisplayAlertPayload, ErrorResponseBody, PlaycademyMode };
1528
+ export { ApiError, MessageEvents, PlaycademyClient, PlaycademyError, extractApiErrorInfo, messaging };
1529
+ export type { ApiErrorCode, ApiErrorInfo, DevUploadEvent, DevUploadHooks, ErrorResponseBody, PlaycademyMode };