@playcademy/sdk 0.1.13 → 0.1.15
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/README.md +38 -1
- package/dist/index.d.ts +1363 -607
- package/dist/index.js +506 -155
- package/dist/server.d.ts +3 -1
- package/dist/types.d.ts +466 -108
- package/package.json +4 -5
package/dist/index.d.ts
CHANGED
|
@@ -1,12 +1,250 @@
|
|
|
1
|
-
import
|
|
1
|
+
import { AUTH_PROVIDER_IDS } from '@playcademy/constants';
|
|
2
2
|
import { InferSelectModel } from 'drizzle-orm';
|
|
3
3
|
import * as drizzle_orm_pg_core from 'drizzle-orm/pg-core';
|
|
4
4
|
import * as drizzle_zod from 'drizzle-zod';
|
|
5
5
|
import { z } from 'zod';
|
|
6
|
+
import * as _playcademy_realtime_server_types from '@playcademy/realtime/server/types';
|
|
6
7
|
import * as _playcademy_timeback_types from '@playcademy/timeback/types';
|
|
7
8
|
import { OrganizationConfig, CourseConfig, ComponentConfig, ResourceConfig, ComponentResourceConfig } from '@playcademy/timeback/types';
|
|
8
9
|
import { SchemaInfo } from '@playcademy/cloudflare';
|
|
9
|
-
|
|
10
|
+
|
|
11
|
+
/**
|
|
12
|
+
* Base error class for Cademy SDK specific errors.
|
|
13
|
+
*/
|
|
14
|
+
declare class PlaycademyError extends Error {
|
|
15
|
+
constructor(message: string);
|
|
16
|
+
}
|
|
17
|
+
declare class ApiError extends Error {
|
|
18
|
+
status: number;
|
|
19
|
+
details: unknown;
|
|
20
|
+
constructor(status: number, message: string, details: unknown);
|
|
21
|
+
}
|
|
22
|
+
/**
|
|
23
|
+
* Extract useful error information from an API error
|
|
24
|
+
* Useful for displaying errors to users in a friendly way
|
|
25
|
+
*/
|
|
26
|
+
interface ApiErrorInfo {
|
|
27
|
+
status: number;
|
|
28
|
+
statusText: string;
|
|
29
|
+
error?: string;
|
|
30
|
+
message?: string;
|
|
31
|
+
details?: unknown;
|
|
32
|
+
}
|
|
33
|
+
declare function extractApiErrorInfo(error: unknown): ApiErrorInfo | null;
|
|
34
|
+
|
|
35
|
+
/**
|
|
36
|
+
* Connection monitoring types
|
|
37
|
+
*
|
|
38
|
+
* Type definitions for connection state, configuration, and callbacks.
|
|
39
|
+
*/
|
|
40
|
+
/**
|
|
41
|
+
* Possible connection states.
|
|
42
|
+
*
|
|
43
|
+
* - **online**: Connection is stable and healthy
|
|
44
|
+
* - **offline**: Complete loss of network connectivity
|
|
45
|
+
* - **degraded**: Connection is slow or experiencing intermittent issues
|
|
46
|
+
*/
|
|
47
|
+
type ConnectionState = 'online' | 'offline' | 'degraded';
|
|
48
|
+
/**
|
|
49
|
+
* Configuration options for ConnectionMonitor.
|
|
50
|
+
*
|
|
51
|
+
* @see {@link ConnectionMonitor} for usage
|
|
52
|
+
*/
|
|
53
|
+
interface ConnectionMonitorConfig {
|
|
54
|
+
/** Base URL for heartbeat pings (e.g., 'https://api.playcademy.com') */
|
|
55
|
+
baseUrl: string;
|
|
56
|
+
/** How often to send heartbeat pings in milliseconds (default: 10000) */
|
|
57
|
+
heartbeatInterval?: number;
|
|
58
|
+
/** How long to wait for heartbeat response in milliseconds (default: 5000) */
|
|
59
|
+
heartbeatTimeout?: number;
|
|
60
|
+
/** Number of consecutive failures before triggering disconnect (default: 2) */
|
|
61
|
+
failureThreshold?: number;
|
|
62
|
+
/** Enable periodic heartbeat monitoring (default: true) */
|
|
63
|
+
enableHeartbeat?: boolean;
|
|
64
|
+
/** Enable browser online/offline event listeners (default: true) */
|
|
65
|
+
enableOfflineEvents?: boolean;
|
|
66
|
+
}
|
|
67
|
+
/**
|
|
68
|
+
* Callback function signature for connection state changes.
|
|
69
|
+
*
|
|
70
|
+
* @param state - The new connection state
|
|
71
|
+
* @param reason - Human-readable reason for the state change
|
|
72
|
+
*/
|
|
73
|
+
type ConnectionChangeCallback = (state: ConnectionState, reason: string) => void;
|
|
74
|
+
|
|
75
|
+
/**
|
|
76
|
+
* Connection Monitor
|
|
77
|
+
*
|
|
78
|
+
* Monitors network connectivity using multiple signals:
|
|
79
|
+
* 1. navigator.onLine - Instant offline detection
|
|
80
|
+
* 2. Periodic heartbeat - Detects slow/degraded connections
|
|
81
|
+
* 3. Request failure tracking - Piggybacks on actual API calls
|
|
82
|
+
*
|
|
83
|
+
* Designed for school WiFi environments where connections may be
|
|
84
|
+
* unstable or degraded without fully disconnecting.
|
|
85
|
+
*/
|
|
86
|
+
|
|
87
|
+
/**
|
|
88
|
+
* Monitors network connectivity using multiple signals and notifies callbacks of state changes.
|
|
89
|
+
*
|
|
90
|
+
* The ConnectionMonitor uses a multi-signal approach to detect connection issues:
|
|
91
|
+
*
|
|
92
|
+
* 1. **navigator.onLine events** - Instant detection of hard disconnects
|
|
93
|
+
* 2. **Heartbeat pings** - Periodic checks to detect slow/degraded connections
|
|
94
|
+
* 3. **Request failure tracking** - Piggybacks on actual API calls
|
|
95
|
+
*
|
|
96
|
+
* This comprehensive approach ensures reliable detection across different network
|
|
97
|
+
* failure modes common in school WiFi environments (hard disconnect, slow connection,
|
|
98
|
+
* intermittent failures).
|
|
99
|
+
*
|
|
100
|
+
* @example
|
|
101
|
+
* ```typescript
|
|
102
|
+
* const monitor = new ConnectionMonitor({
|
|
103
|
+
* baseUrl: 'https://api.playcademy.com',
|
|
104
|
+
* heartbeatInterval: 10000, // Check every 10s
|
|
105
|
+
* failureThreshold: 2 // Trigger after 2 failures
|
|
106
|
+
* })
|
|
107
|
+
*
|
|
108
|
+
* monitor.onChange((state, reason) => {
|
|
109
|
+
* console.log(`Connection: ${state} - ${reason}`)
|
|
110
|
+
* })
|
|
111
|
+
*
|
|
112
|
+
* monitor.start()
|
|
113
|
+
* ```
|
|
114
|
+
*
|
|
115
|
+
* @see {@link ConnectionManagerConfig} for configuration options
|
|
116
|
+
*/
|
|
117
|
+
declare class ConnectionMonitor {
|
|
118
|
+
private state;
|
|
119
|
+
private callbacks;
|
|
120
|
+
private heartbeatInterval?;
|
|
121
|
+
private consecutiveFailures;
|
|
122
|
+
private isMonitoring;
|
|
123
|
+
private config;
|
|
124
|
+
/**
|
|
125
|
+
* Creates a new ConnectionMonitor instance.
|
|
126
|
+
*
|
|
127
|
+
* The monitor starts in a stopped state. Call `start()` to begin monitoring.
|
|
128
|
+
*
|
|
129
|
+
* @param config - Configuration options
|
|
130
|
+
* @param config.baseUrl - Base URL for heartbeat pings
|
|
131
|
+
* @param config.heartbeatInterval - How often to check (default: 10000ms)
|
|
132
|
+
* @param config.heartbeatTimeout - Request timeout (default: 5000ms)
|
|
133
|
+
* @param config.failureThreshold - Failures before triggering disconnect (default: 2)
|
|
134
|
+
* @param config.enableHeartbeat - Enable periodic checks (default: true)
|
|
135
|
+
* @param config.enableOfflineEvents - Listen to browser events (default: true)
|
|
136
|
+
*/
|
|
137
|
+
constructor(config: ConnectionMonitorConfig);
|
|
138
|
+
/**
|
|
139
|
+
* Starts monitoring the connection state.
|
|
140
|
+
*
|
|
141
|
+
* Sets up event listeners and begins heartbeat checks based on configuration.
|
|
142
|
+
* Idempotent - safe to call multiple times.
|
|
143
|
+
*/
|
|
144
|
+
start(): void;
|
|
145
|
+
/**
|
|
146
|
+
* Stops monitoring the connection state and cleans up resources.
|
|
147
|
+
*
|
|
148
|
+
* Removes event listeners and clears heartbeat intervals.
|
|
149
|
+
* Idempotent - safe to call multiple times.
|
|
150
|
+
*/
|
|
151
|
+
stop(): void;
|
|
152
|
+
/**
|
|
153
|
+
* Registers a callback to be notified of all connection state changes.
|
|
154
|
+
*
|
|
155
|
+
* The callback fires for all state transitions: online → offline,
|
|
156
|
+
* offline → degraded, degraded → online, etc.
|
|
157
|
+
*
|
|
158
|
+
* @param callback - Function called with (state, reason) when connection changes
|
|
159
|
+
* @returns Cleanup function to unregister the callback
|
|
160
|
+
*
|
|
161
|
+
* @example
|
|
162
|
+
* ```typescript
|
|
163
|
+
* const cleanup = monitor.onChange((state, reason) => {
|
|
164
|
+
* console.log(`Connection: ${state}`)
|
|
165
|
+
* if (state === 'offline') {
|
|
166
|
+
* showReconnectingUI()
|
|
167
|
+
* }
|
|
168
|
+
* })
|
|
169
|
+
*
|
|
170
|
+
* // Later: cleanup() to unregister
|
|
171
|
+
* ```
|
|
172
|
+
*/
|
|
173
|
+
onChange(callback: ConnectionChangeCallback): () => void;
|
|
174
|
+
/**
|
|
175
|
+
* Gets the current connection state.
|
|
176
|
+
*
|
|
177
|
+
* @returns The current state ('online', 'offline', or 'degraded')
|
|
178
|
+
*/
|
|
179
|
+
getState(): ConnectionState;
|
|
180
|
+
/**
|
|
181
|
+
* Manually triggers an immediate connection check.
|
|
182
|
+
*
|
|
183
|
+
* Forces a heartbeat ping to verify connectivity right now, bypassing
|
|
184
|
+
* the normal interval. Useful before critical operations.
|
|
185
|
+
*
|
|
186
|
+
* @returns Promise resolving to the current connection state after the check
|
|
187
|
+
*
|
|
188
|
+
* @example
|
|
189
|
+
* ```typescript
|
|
190
|
+
* const state = await monitor.checkNow()
|
|
191
|
+
* if (state !== 'online') {
|
|
192
|
+
* alert('Please check your internet connection')
|
|
193
|
+
* }
|
|
194
|
+
* ```
|
|
195
|
+
*/
|
|
196
|
+
checkNow(): Promise<ConnectionState>;
|
|
197
|
+
/**
|
|
198
|
+
* Reports a request failure for tracking.
|
|
199
|
+
*
|
|
200
|
+
* This should be called from your request wrapper whenever an API call fails.
|
|
201
|
+
* Only network errors are tracked (TypeError, fetch failures) - HTTP error
|
|
202
|
+
* responses (4xx, 5xx) are ignored.
|
|
203
|
+
*
|
|
204
|
+
* After consecutive failures exceed the threshold, the monitor transitions
|
|
205
|
+
* to 'degraded' or 'offline' state.
|
|
206
|
+
*
|
|
207
|
+
* @param error - The error from the failed request
|
|
208
|
+
*
|
|
209
|
+
* @example
|
|
210
|
+
* ```typescript
|
|
211
|
+
* try {
|
|
212
|
+
* await fetch('/api/data')
|
|
213
|
+
* } catch (error) {
|
|
214
|
+
* monitor.reportRequestFailure(error)
|
|
215
|
+
* throw error
|
|
216
|
+
* }
|
|
217
|
+
* ```
|
|
218
|
+
*/
|
|
219
|
+
reportRequestFailure(error: unknown): void;
|
|
220
|
+
/**
|
|
221
|
+
* Reports a successful request.
|
|
222
|
+
*
|
|
223
|
+
* This should be called from your request wrapper whenever an API call succeeds.
|
|
224
|
+
* Resets the consecutive failure counter and transitions from 'degraded' to
|
|
225
|
+
* 'online' if the connection has recovered.
|
|
226
|
+
*
|
|
227
|
+
* @example
|
|
228
|
+
* ```typescript
|
|
229
|
+
* try {
|
|
230
|
+
* const result = await fetch('/api/data')
|
|
231
|
+
* monitor.reportRequestSuccess()
|
|
232
|
+
* return result
|
|
233
|
+
* } catch (error) {
|
|
234
|
+
* monitor.reportRequestFailure(error)
|
|
235
|
+
* throw error
|
|
236
|
+
* }
|
|
237
|
+
* ```
|
|
238
|
+
*/
|
|
239
|
+
reportRequestSuccess(): void;
|
|
240
|
+
private _detectInitialState;
|
|
241
|
+
private _handleOnline;
|
|
242
|
+
private _handleOffline;
|
|
243
|
+
private _startHeartbeat;
|
|
244
|
+
private _performHeartbeat;
|
|
245
|
+
private _handleHeartbeatFailure;
|
|
246
|
+
private _setState;
|
|
247
|
+
}
|
|
10
248
|
|
|
11
249
|
declare const users: drizzle_orm_pg_core.PgTableWithColumns<{
|
|
12
250
|
name: "user";
|
|
@@ -225,6 +463,23 @@ type GameMetadata = {
|
|
|
225
463
|
emoji?: string;
|
|
226
464
|
[key: string]: unknown;
|
|
227
465
|
};
|
|
466
|
+
/**
|
|
467
|
+
* DNS validation records for custom hostname
|
|
468
|
+
* Structure for the validationRecords JSON field in game_custom_hostnames table
|
|
469
|
+
*/
|
|
470
|
+
type CustomHostnameValidationRecords = {
|
|
471
|
+
/** TXT record for ownership verification */
|
|
472
|
+
ownership?: {
|
|
473
|
+
name?: string;
|
|
474
|
+
value?: string;
|
|
475
|
+
type?: string;
|
|
476
|
+
};
|
|
477
|
+
/** TXT records for SSL certificate validation */
|
|
478
|
+
ssl?: Array<{
|
|
479
|
+
txt_name?: string;
|
|
480
|
+
txt_value?: string;
|
|
481
|
+
}>;
|
|
482
|
+
};
|
|
228
483
|
declare const games: drizzle_orm_pg_core.PgTableWithColumns<{
|
|
229
484
|
name: "games";
|
|
230
485
|
schema: undefined;
|
|
@@ -337,8 +592,8 @@ declare const games: drizzle_orm_pg_core.PgTableWithColumns<{
|
|
|
337
592
|
identity: undefined;
|
|
338
593
|
generated: undefined;
|
|
339
594
|
}, {}, {}>;
|
|
340
|
-
|
|
341
|
-
name: "
|
|
595
|
+
deploymentUrl: drizzle_orm_pg_core.PgColumn<{
|
|
596
|
+
name: "deployment_url";
|
|
342
597
|
tableName: "games";
|
|
343
598
|
dataType: "string";
|
|
344
599
|
columnType: "PgText";
|
|
@@ -461,13 +716,18 @@ declare const games: drizzle_orm_pg_core.PgTableWithColumns<{
|
|
|
461
716
|
};
|
|
462
717
|
dialect: "pg";
|
|
463
718
|
}>;
|
|
464
|
-
|
|
465
|
-
|
|
719
|
+
/**
|
|
720
|
+
* Custom hostnames table
|
|
721
|
+
*
|
|
722
|
+
* Stores custom domain mappings for games with SSL provisioning via Cloudflare.
|
|
723
|
+
*/
|
|
724
|
+
declare const gameCustomHostnames: drizzle_orm_pg_core.PgTableWithColumns<{
|
|
725
|
+
name: "game_custom_hostnames";
|
|
466
726
|
schema: undefined;
|
|
467
727
|
columns: {
|
|
468
728
|
id: drizzle_orm_pg_core.PgColumn<{
|
|
469
729
|
name: "id";
|
|
470
|
-
tableName: "
|
|
730
|
+
tableName: "game_custom_hostnames";
|
|
471
731
|
dataType: "string";
|
|
472
732
|
columnType: "PgUUID";
|
|
473
733
|
data: string;
|
|
@@ -482,11 +742,11 @@ declare const items: drizzle_orm_pg_core.PgTableWithColumns<{
|
|
|
482
742
|
identity: undefined;
|
|
483
743
|
generated: undefined;
|
|
484
744
|
}, {}, {}>;
|
|
485
|
-
|
|
486
|
-
name: "
|
|
487
|
-
tableName: "
|
|
745
|
+
gameId: drizzle_orm_pg_core.PgColumn<{
|
|
746
|
+
name: "game_id";
|
|
747
|
+
tableName: "game_custom_hostnames";
|
|
488
748
|
dataType: "string";
|
|
489
|
-
columnType: "
|
|
749
|
+
columnType: "PgUUID";
|
|
490
750
|
data: string;
|
|
491
751
|
driverParam: string;
|
|
492
752
|
notNull: true;
|
|
@@ -494,31 +754,31 @@ declare const items: drizzle_orm_pg_core.PgTableWithColumns<{
|
|
|
494
754
|
isPrimaryKey: false;
|
|
495
755
|
isAutoincrement: false;
|
|
496
756
|
hasRuntimeDefault: false;
|
|
497
|
-
enumValues:
|
|
757
|
+
enumValues: undefined;
|
|
498
758
|
baseColumn: never;
|
|
499
759
|
identity: undefined;
|
|
500
760
|
generated: undefined;
|
|
501
761
|
}, {}, {}>;
|
|
502
|
-
|
|
503
|
-
name: "
|
|
504
|
-
tableName: "
|
|
762
|
+
userId: drizzle_orm_pg_core.PgColumn<{
|
|
763
|
+
name: "user_id";
|
|
764
|
+
tableName: "game_custom_hostnames";
|
|
505
765
|
dataType: "string";
|
|
506
|
-
columnType: "
|
|
766
|
+
columnType: "PgText";
|
|
507
767
|
data: string;
|
|
508
768
|
driverParam: string;
|
|
509
|
-
notNull:
|
|
769
|
+
notNull: true;
|
|
510
770
|
hasDefault: false;
|
|
511
771
|
isPrimaryKey: false;
|
|
512
772
|
isAutoincrement: false;
|
|
513
773
|
hasRuntimeDefault: false;
|
|
514
|
-
enumValues:
|
|
774
|
+
enumValues: [string, ...string[]];
|
|
515
775
|
baseColumn: never;
|
|
516
776
|
identity: undefined;
|
|
517
777
|
generated: undefined;
|
|
518
778
|
}, {}, {}>;
|
|
519
|
-
|
|
520
|
-
name: "
|
|
521
|
-
tableName: "
|
|
779
|
+
hostname: drizzle_orm_pg_core.PgColumn<{
|
|
780
|
+
name: "hostname";
|
|
781
|
+
tableName: "game_custom_hostnames";
|
|
522
782
|
dataType: "string";
|
|
523
783
|
columnType: "PgText";
|
|
524
784
|
data: string;
|
|
@@ -533,14 +793,14 @@ declare const items: drizzle_orm_pg_core.PgTableWithColumns<{
|
|
|
533
793
|
identity: undefined;
|
|
534
794
|
generated: undefined;
|
|
535
795
|
}, {}, {}>;
|
|
536
|
-
|
|
537
|
-
name: "
|
|
538
|
-
tableName: "
|
|
796
|
+
cloudflareId: drizzle_orm_pg_core.PgColumn<{
|
|
797
|
+
name: "cloudflare_id";
|
|
798
|
+
tableName: "game_custom_hostnames";
|
|
539
799
|
dataType: "string";
|
|
540
800
|
columnType: "PgText";
|
|
541
801
|
data: string;
|
|
542
802
|
driverParam: string;
|
|
543
|
-
notNull:
|
|
803
|
+
notNull: true;
|
|
544
804
|
hasDefault: false;
|
|
545
805
|
isPrimaryKey: false;
|
|
546
806
|
isAutoincrement: false;
|
|
@@ -550,66 +810,66 @@ declare const items: drizzle_orm_pg_core.PgTableWithColumns<{
|
|
|
550
810
|
identity: undefined;
|
|
551
811
|
generated: undefined;
|
|
552
812
|
}, {}, {}>;
|
|
553
|
-
|
|
554
|
-
name: "
|
|
555
|
-
tableName: "
|
|
813
|
+
environment: drizzle_orm_pg_core.PgColumn<{
|
|
814
|
+
name: "environment";
|
|
815
|
+
tableName: "game_custom_hostnames";
|
|
556
816
|
dataType: "string";
|
|
557
817
|
columnType: "PgEnumColumn";
|
|
558
|
-
data: "
|
|
818
|
+
data: "staging" | "production";
|
|
559
819
|
driverParam: string;
|
|
560
820
|
notNull: true;
|
|
561
821
|
hasDefault: true;
|
|
562
822
|
isPrimaryKey: false;
|
|
563
823
|
isAutoincrement: false;
|
|
564
824
|
hasRuntimeDefault: false;
|
|
565
|
-
enumValues: ["
|
|
825
|
+
enumValues: ["staging", "production"];
|
|
566
826
|
baseColumn: never;
|
|
567
827
|
identity: undefined;
|
|
568
828
|
generated: undefined;
|
|
569
829
|
}, {}, {}>;
|
|
570
|
-
|
|
571
|
-
name: "
|
|
572
|
-
tableName: "
|
|
573
|
-
dataType: "
|
|
574
|
-
columnType: "
|
|
575
|
-
data:
|
|
576
|
-
driverParam:
|
|
830
|
+
status: drizzle_orm_pg_core.PgColumn<{
|
|
831
|
+
name: "status";
|
|
832
|
+
tableName: "game_custom_hostnames";
|
|
833
|
+
dataType: "string";
|
|
834
|
+
columnType: "PgEnumColumn";
|
|
835
|
+
data: "pending" | "pending_validation" | "pending_deployment" | "pending_deletion" | "active" | "blocked" | "deleted";
|
|
836
|
+
driverParam: string;
|
|
577
837
|
notNull: true;
|
|
578
838
|
hasDefault: true;
|
|
579
839
|
isPrimaryKey: false;
|
|
580
840
|
isAutoincrement: false;
|
|
581
841
|
hasRuntimeDefault: false;
|
|
582
|
-
enumValues:
|
|
842
|
+
enumValues: ["pending", "pending_validation", "pending_deployment", "pending_deletion", "active", "blocked", "deleted"];
|
|
583
843
|
baseColumn: never;
|
|
584
844
|
identity: undefined;
|
|
585
845
|
generated: undefined;
|
|
586
846
|
}, {}, {}>;
|
|
587
|
-
|
|
588
|
-
name: "
|
|
589
|
-
tableName: "
|
|
847
|
+
sslStatus: drizzle_orm_pg_core.PgColumn<{
|
|
848
|
+
name: "ssl_status";
|
|
849
|
+
tableName: "game_custom_hostnames";
|
|
590
850
|
dataType: "string";
|
|
591
|
-
columnType: "
|
|
592
|
-
data:
|
|
851
|
+
columnType: "PgEnumColumn";
|
|
852
|
+
data: "pending_validation" | "pending_deployment" | "active" | "deleted" | "initializing" | "pending_issuance";
|
|
593
853
|
driverParam: string;
|
|
594
|
-
notNull:
|
|
595
|
-
hasDefault:
|
|
854
|
+
notNull: true;
|
|
855
|
+
hasDefault: true;
|
|
596
856
|
isPrimaryKey: false;
|
|
597
857
|
isAutoincrement: false;
|
|
598
858
|
hasRuntimeDefault: false;
|
|
599
|
-
enumValues: [
|
|
859
|
+
enumValues: ["initializing", "pending_validation", "pending_issuance", "pending_deployment", "active", "deleted"];
|
|
600
860
|
baseColumn: never;
|
|
601
861
|
identity: undefined;
|
|
602
862
|
generated: undefined;
|
|
603
863
|
}, {}, {}>;
|
|
604
|
-
|
|
605
|
-
name: "
|
|
606
|
-
tableName: "
|
|
864
|
+
validationRecords: drizzle_orm_pg_core.PgColumn<{
|
|
865
|
+
name: "validation_records";
|
|
866
|
+
tableName: "game_custom_hostnames";
|
|
607
867
|
dataType: "json";
|
|
608
868
|
columnType: "PgJsonb";
|
|
609
|
-
data:
|
|
869
|
+
data: CustomHostnameValidationRecords;
|
|
610
870
|
driverParam: unknown;
|
|
611
871
|
notNull: false;
|
|
612
|
-
hasDefault:
|
|
872
|
+
hasDefault: false;
|
|
613
873
|
isPrimaryKey: false;
|
|
614
874
|
isAutoincrement: false;
|
|
615
875
|
hasRuntimeDefault: false;
|
|
@@ -617,10 +877,29 @@ declare const items: drizzle_orm_pg_core.PgTableWithColumns<{
|
|
|
617
877
|
baseColumn: never;
|
|
618
878
|
identity: undefined;
|
|
619
879
|
generated: undefined;
|
|
620
|
-
}, {}, {
|
|
880
|
+
}, {}, {
|
|
881
|
+
$type: CustomHostnameValidationRecords;
|
|
882
|
+
}>;
|
|
621
883
|
createdAt: drizzle_orm_pg_core.PgColumn<{
|
|
622
884
|
name: "created_at";
|
|
623
|
-
tableName: "
|
|
885
|
+
tableName: "game_custom_hostnames";
|
|
886
|
+
dataType: "date";
|
|
887
|
+
columnType: "PgTimestamp";
|
|
888
|
+
data: Date;
|
|
889
|
+
driverParam: string;
|
|
890
|
+
notNull: true;
|
|
891
|
+
hasDefault: true;
|
|
892
|
+
isPrimaryKey: false;
|
|
893
|
+
isAutoincrement: false;
|
|
894
|
+
hasRuntimeDefault: false;
|
|
895
|
+
enumValues: undefined;
|
|
896
|
+
baseColumn: never;
|
|
897
|
+
identity: undefined;
|
|
898
|
+
generated: undefined;
|
|
899
|
+
}, {}, {}>;
|
|
900
|
+
updatedAt: drizzle_orm_pg_core.PgColumn<{
|
|
901
|
+
name: "updated_at";
|
|
902
|
+
tableName: "game_custom_hostnames";
|
|
624
903
|
dataType: "date";
|
|
625
904
|
columnType: "PgTimestamp";
|
|
626
905
|
data: Date;
|
|
@@ -638,13 +917,13 @@ declare const items: drizzle_orm_pg_core.PgTableWithColumns<{
|
|
|
638
917
|
};
|
|
639
918
|
dialect: "pg";
|
|
640
919
|
}>;
|
|
641
|
-
declare const
|
|
642
|
-
name: "
|
|
920
|
+
declare const items: drizzle_orm_pg_core.PgTableWithColumns<{
|
|
921
|
+
name: "items";
|
|
643
922
|
schema: undefined;
|
|
644
923
|
columns: {
|
|
645
924
|
id: drizzle_orm_pg_core.PgColumn<{
|
|
646
925
|
name: "id";
|
|
647
|
-
tableName: "
|
|
926
|
+
tableName: "items";
|
|
648
927
|
dataType: "string";
|
|
649
928
|
columnType: "PgUUID";
|
|
650
929
|
data: string;
|
|
@@ -659,9 +938,9 @@ declare const inventoryItems: drizzle_orm_pg_core.PgTableWithColumns<{
|
|
|
659
938
|
identity: undefined;
|
|
660
939
|
generated: undefined;
|
|
661
940
|
}, {}, {}>;
|
|
662
|
-
|
|
663
|
-
name: "
|
|
664
|
-
tableName: "
|
|
941
|
+
slug: drizzle_orm_pg_core.PgColumn<{
|
|
942
|
+
name: "slug";
|
|
943
|
+
tableName: "items";
|
|
665
944
|
dataType: "string";
|
|
666
945
|
columnType: "PgText";
|
|
667
946
|
data: string;
|
|
@@ -676,14 +955,14 @@ declare const inventoryItems: drizzle_orm_pg_core.PgTableWithColumns<{
|
|
|
676
955
|
identity: undefined;
|
|
677
956
|
generated: undefined;
|
|
678
957
|
}, {}, {}>;
|
|
679
|
-
|
|
680
|
-
name: "
|
|
681
|
-
tableName: "
|
|
958
|
+
gameId: drizzle_orm_pg_core.PgColumn<{
|
|
959
|
+
name: "game_id";
|
|
960
|
+
tableName: "items";
|
|
682
961
|
dataType: "string";
|
|
683
962
|
columnType: "PgUUID";
|
|
684
963
|
data: string;
|
|
685
964
|
driverParam: string;
|
|
686
|
-
notNull:
|
|
965
|
+
notNull: false;
|
|
687
966
|
hasDefault: false;
|
|
688
967
|
isPrimaryKey: false;
|
|
689
968
|
isAutoincrement: false;
|
|
@@ -693,50 +972,227 @@ declare const inventoryItems: drizzle_orm_pg_core.PgTableWithColumns<{
|
|
|
693
972
|
identity: undefined;
|
|
694
973
|
generated: undefined;
|
|
695
974
|
}, {}, {}>;
|
|
696
|
-
|
|
697
|
-
name: "
|
|
698
|
-
tableName: "
|
|
699
|
-
dataType: "
|
|
700
|
-
columnType: "
|
|
701
|
-
data:
|
|
702
|
-
driverParam: string
|
|
975
|
+
displayName: drizzle_orm_pg_core.PgColumn<{
|
|
976
|
+
name: "display_name";
|
|
977
|
+
tableName: "items";
|
|
978
|
+
dataType: "string";
|
|
979
|
+
columnType: "PgText";
|
|
980
|
+
data: string;
|
|
981
|
+
driverParam: string;
|
|
703
982
|
notNull: true;
|
|
704
|
-
hasDefault:
|
|
983
|
+
hasDefault: false;
|
|
705
984
|
isPrimaryKey: false;
|
|
706
985
|
isAutoincrement: false;
|
|
707
986
|
hasRuntimeDefault: false;
|
|
708
|
-
enumValues:
|
|
987
|
+
enumValues: [string, ...string[]];
|
|
709
988
|
baseColumn: never;
|
|
710
989
|
identity: undefined;
|
|
711
990
|
generated: undefined;
|
|
712
991
|
}, {}, {}>;
|
|
713
|
-
|
|
714
|
-
name: "
|
|
715
|
-
tableName: "
|
|
716
|
-
dataType: "
|
|
717
|
-
columnType: "
|
|
718
|
-
data:
|
|
992
|
+
description: drizzle_orm_pg_core.PgColumn<{
|
|
993
|
+
name: "description";
|
|
994
|
+
tableName: "items";
|
|
995
|
+
dataType: "string";
|
|
996
|
+
columnType: "PgText";
|
|
997
|
+
data: string;
|
|
719
998
|
driverParam: string;
|
|
720
999
|
notNull: false;
|
|
721
|
-
hasDefault:
|
|
1000
|
+
hasDefault: false;
|
|
722
1001
|
isPrimaryKey: false;
|
|
723
1002
|
isAutoincrement: false;
|
|
724
1003
|
hasRuntimeDefault: false;
|
|
725
|
-
enumValues:
|
|
1004
|
+
enumValues: [string, ...string[]];
|
|
726
1005
|
baseColumn: never;
|
|
727
1006
|
identity: undefined;
|
|
728
1007
|
generated: undefined;
|
|
729
1008
|
}, {}, {}>;
|
|
730
|
-
|
|
731
|
-
|
|
732
|
-
|
|
733
|
-
|
|
734
|
-
|
|
735
|
-
|
|
736
|
-
|
|
737
|
-
|
|
738
|
-
|
|
739
|
-
|
|
1009
|
+
type: drizzle_orm_pg_core.PgColumn<{
|
|
1010
|
+
name: "type";
|
|
1011
|
+
tableName: "items";
|
|
1012
|
+
dataType: "string";
|
|
1013
|
+
columnType: "PgEnumColumn";
|
|
1014
|
+
data: "currency" | "badge" | "trophy" | "collectible" | "consumable" | "unlock" | "upgrade" | "accessory" | "other";
|
|
1015
|
+
driverParam: string;
|
|
1016
|
+
notNull: true;
|
|
1017
|
+
hasDefault: true;
|
|
1018
|
+
isPrimaryKey: false;
|
|
1019
|
+
isAutoincrement: false;
|
|
1020
|
+
hasRuntimeDefault: false;
|
|
1021
|
+
enumValues: ["currency", "badge", "trophy", "collectible", "consumable", "unlock", "upgrade", "accessory", "other"];
|
|
1022
|
+
baseColumn: never;
|
|
1023
|
+
identity: undefined;
|
|
1024
|
+
generated: undefined;
|
|
1025
|
+
}, {}, {}>;
|
|
1026
|
+
isPlaceable: drizzle_orm_pg_core.PgColumn<{
|
|
1027
|
+
name: "is_placeable";
|
|
1028
|
+
tableName: "items";
|
|
1029
|
+
dataType: "boolean";
|
|
1030
|
+
columnType: "PgBoolean";
|
|
1031
|
+
data: boolean;
|
|
1032
|
+
driverParam: boolean;
|
|
1033
|
+
notNull: true;
|
|
1034
|
+
hasDefault: true;
|
|
1035
|
+
isPrimaryKey: false;
|
|
1036
|
+
isAutoincrement: false;
|
|
1037
|
+
hasRuntimeDefault: false;
|
|
1038
|
+
enumValues: undefined;
|
|
1039
|
+
baseColumn: never;
|
|
1040
|
+
identity: undefined;
|
|
1041
|
+
generated: undefined;
|
|
1042
|
+
}, {}, {}>;
|
|
1043
|
+
imageUrl: drizzle_orm_pg_core.PgColumn<{
|
|
1044
|
+
name: "image_url";
|
|
1045
|
+
tableName: "items";
|
|
1046
|
+
dataType: "string";
|
|
1047
|
+
columnType: "PgText";
|
|
1048
|
+
data: string;
|
|
1049
|
+
driverParam: string;
|
|
1050
|
+
notNull: false;
|
|
1051
|
+
hasDefault: false;
|
|
1052
|
+
isPrimaryKey: false;
|
|
1053
|
+
isAutoincrement: false;
|
|
1054
|
+
hasRuntimeDefault: false;
|
|
1055
|
+
enumValues: [string, ...string[]];
|
|
1056
|
+
baseColumn: never;
|
|
1057
|
+
identity: undefined;
|
|
1058
|
+
generated: undefined;
|
|
1059
|
+
}, {}, {}>;
|
|
1060
|
+
metadata: drizzle_orm_pg_core.PgColumn<{
|
|
1061
|
+
name: "metadata";
|
|
1062
|
+
tableName: "items";
|
|
1063
|
+
dataType: "json";
|
|
1064
|
+
columnType: "PgJsonb";
|
|
1065
|
+
data: unknown;
|
|
1066
|
+
driverParam: unknown;
|
|
1067
|
+
notNull: false;
|
|
1068
|
+
hasDefault: true;
|
|
1069
|
+
isPrimaryKey: false;
|
|
1070
|
+
isAutoincrement: false;
|
|
1071
|
+
hasRuntimeDefault: false;
|
|
1072
|
+
enumValues: undefined;
|
|
1073
|
+
baseColumn: never;
|
|
1074
|
+
identity: undefined;
|
|
1075
|
+
generated: undefined;
|
|
1076
|
+
}, {}, {}>;
|
|
1077
|
+
createdAt: drizzle_orm_pg_core.PgColumn<{
|
|
1078
|
+
name: "created_at";
|
|
1079
|
+
tableName: "items";
|
|
1080
|
+
dataType: "date";
|
|
1081
|
+
columnType: "PgTimestamp";
|
|
1082
|
+
data: Date;
|
|
1083
|
+
driverParam: string;
|
|
1084
|
+
notNull: true;
|
|
1085
|
+
hasDefault: true;
|
|
1086
|
+
isPrimaryKey: false;
|
|
1087
|
+
isAutoincrement: false;
|
|
1088
|
+
hasRuntimeDefault: false;
|
|
1089
|
+
enumValues: undefined;
|
|
1090
|
+
baseColumn: never;
|
|
1091
|
+
identity: undefined;
|
|
1092
|
+
generated: undefined;
|
|
1093
|
+
}, {}, {}>;
|
|
1094
|
+
};
|
|
1095
|
+
dialect: "pg";
|
|
1096
|
+
}>;
|
|
1097
|
+
declare const inventoryItems: drizzle_orm_pg_core.PgTableWithColumns<{
|
|
1098
|
+
name: "inventory_items";
|
|
1099
|
+
schema: undefined;
|
|
1100
|
+
columns: {
|
|
1101
|
+
id: drizzle_orm_pg_core.PgColumn<{
|
|
1102
|
+
name: "id";
|
|
1103
|
+
tableName: "inventory_items";
|
|
1104
|
+
dataType: "string";
|
|
1105
|
+
columnType: "PgUUID";
|
|
1106
|
+
data: string;
|
|
1107
|
+
driverParam: string;
|
|
1108
|
+
notNull: true;
|
|
1109
|
+
hasDefault: true;
|
|
1110
|
+
isPrimaryKey: true;
|
|
1111
|
+
isAutoincrement: false;
|
|
1112
|
+
hasRuntimeDefault: false;
|
|
1113
|
+
enumValues: undefined;
|
|
1114
|
+
baseColumn: never;
|
|
1115
|
+
identity: undefined;
|
|
1116
|
+
generated: undefined;
|
|
1117
|
+
}, {}, {}>;
|
|
1118
|
+
userId: drizzle_orm_pg_core.PgColumn<{
|
|
1119
|
+
name: "user_id";
|
|
1120
|
+
tableName: "inventory_items";
|
|
1121
|
+
dataType: "string";
|
|
1122
|
+
columnType: "PgText";
|
|
1123
|
+
data: string;
|
|
1124
|
+
driverParam: string;
|
|
1125
|
+
notNull: true;
|
|
1126
|
+
hasDefault: false;
|
|
1127
|
+
isPrimaryKey: false;
|
|
1128
|
+
isAutoincrement: false;
|
|
1129
|
+
hasRuntimeDefault: false;
|
|
1130
|
+
enumValues: [string, ...string[]];
|
|
1131
|
+
baseColumn: never;
|
|
1132
|
+
identity: undefined;
|
|
1133
|
+
generated: undefined;
|
|
1134
|
+
}, {}, {}>;
|
|
1135
|
+
itemId: drizzle_orm_pg_core.PgColumn<{
|
|
1136
|
+
name: "item_id";
|
|
1137
|
+
tableName: "inventory_items";
|
|
1138
|
+
dataType: "string";
|
|
1139
|
+
columnType: "PgUUID";
|
|
1140
|
+
data: string;
|
|
1141
|
+
driverParam: string;
|
|
1142
|
+
notNull: true;
|
|
1143
|
+
hasDefault: false;
|
|
1144
|
+
isPrimaryKey: false;
|
|
1145
|
+
isAutoincrement: false;
|
|
1146
|
+
hasRuntimeDefault: false;
|
|
1147
|
+
enumValues: undefined;
|
|
1148
|
+
baseColumn: never;
|
|
1149
|
+
identity: undefined;
|
|
1150
|
+
generated: undefined;
|
|
1151
|
+
}, {}, {}>;
|
|
1152
|
+
quantity: drizzle_orm_pg_core.PgColumn<{
|
|
1153
|
+
name: "quantity";
|
|
1154
|
+
tableName: "inventory_items";
|
|
1155
|
+
dataType: "number";
|
|
1156
|
+
columnType: "PgInteger";
|
|
1157
|
+
data: number;
|
|
1158
|
+
driverParam: string | number;
|
|
1159
|
+
notNull: true;
|
|
1160
|
+
hasDefault: true;
|
|
1161
|
+
isPrimaryKey: false;
|
|
1162
|
+
isAutoincrement: false;
|
|
1163
|
+
hasRuntimeDefault: false;
|
|
1164
|
+
enumValues: undefined;
|
|
1165
|
+
baseColumn: never;
|
|
1166
|
+
identity: undefined;
|
|
1167
|
+
generated: undefined;
|
|
1168
|
+
}, {}, {}>;
|
|
1169
|
+
updatedAt: drizzle_orm_pg_core.PgColumn<{
|
|
1170
|
+
name: "updated_at";
|
|
1171
|
+
tableName: "inventory_items";
|
|
1172
|
+
dataType: "date";
|
|
1173
|
+
columnType: "PgTimestamp";
|
|
1174
|
+
data: Date;
|
|
1175
|
+
driverParam: string;
|
|
1176
|
+
notNull: false;
|
|
1177
|
+
hasDefault: true;
|
|
1178
|
+
isPrimaryKey: false;
|
|
1179
|
+
isAutoincrement: false;
|
|
1180
|
+
hasRuntimeDefault: false;
|
|
1181
|
+
enumValues: undefined;
|
|
1182
|
+
baseColumn: never;
|
|
1183
|
+
identity: undefined;
|
|
1184
|
+
generated: undefined;
|
|
1185
|
+
}, {}, {}>;
|
|
1186
|
+
};
|
|
1187
|
+
dialect: "pg";
|
|
1188
|
+
}>;
|
|
1189
|
+
declare const shopListings: drizzle_orm_pg_core.PgTableWithColumns<{
|
|
1190
|
+
name: "shop_listings";
|
|
1191
|
+
schema: undefined;
|
|
1192
|
+
columns: {
|
|
1193
|
+
id: drizzle_orm_pg_core.PgColumn<{
|
|
1194
|
+
name: "id";
|
|
1195
|
+
tableName: "shop_listings";
|
|
740
1196
|
dataType: "string";
|
|
741
1197
|
columnType: "PgUUID";
|
|
742
1198
|
data: string;
|
|
@@ -1442,7 +1898,7 @@ declare const characterComponents: drizzle_orm_pg_core.PgTableWithColumns<{
|
|
|
1442
1898
|
tableName: "character_components";
|
|
1443
1899
|
dataType: "string";
|
|
1444
1900
|
columnType: "PgEnumColumn";
|
|
1445
|
-
data: "
|
|
1901
|
+
data: "accessory" | "body" | "outfit" | "hairstyle" | "eyes";
|
|
1446
1902
|
driverParam: string;
|
|
1447
1903
|
notNull: true;
|
|
1448
1904
|
hasDefault: false;
|
|
@@ -2292,66 +2748,32 @@ declare const UpsertGameMetadataSchema: z.ZodEffects<z.ZodObject<{
|
|
|
2292
2748
|
mapElementId?: string | null | undefined;
|
|
2293
2749
|
metadata?: Record<string, unknown> | undefined;
|
|
2294
2750
|
}>;
|
|
2751
|
+
/**
|
|
2752
|
+
* Simplified game manifest for Cloudflare Workers deployments
|
|
2753
|
+
*
|
|
2754
|
+
* The manifest is auto-generated by build tools (Godot plugin, Vite plugin, etc.)
|
|
2755
|
+
* and provides minimal metadata about the build.
|
|
2756
|
+
*
|
|
2757
|
+
* Fields:
|
|
2758
|
+
* - version: Manifest schema version (for future migrations)
|
|
2759
|
+
* - platform: Auto-detected by build tool (e.g., 'web', 'godot@4.3', 'unity@2023')
|
|
2760
|
+
* - createdAt: Build timestamp (ISO 8601)
|
|
2761
|
+
*
|
|
2762
|
+
* Note: With unified Cloudflare Workers deployments, the worker handles all routing
|
|
2763
|
+
* internally, so we no longer need bootMode, entryPoint, or styles fields.
|
|
2764
|
+
*/
|
|
2295
2765
|
declare const ManifestV1Schema: z.ZodObject<{
|
|
2296
2766
|
version: z.ZodString;
|
|
2297
|
-
|
|
2298
|
-
entryPoint: z.ZodEffects<z.ZodString, string, string>;
|
|
2299
|
-
/**
|
|
2300
|
-
* An array of relative paths to CSS stylesheets.
|
|
2301
|
-
* Currently, this property is ONLY utilized by the 'module' boot mode
|
|
2302
|
-
* (`apps/cademy/src/lib/loader/boot-module.ts`) to load external
|
|
2303
|
-
* stylesheets into the game's shadow DOM.
|
|
2304
|
-
*
|
|
2305
|
-
* This property is under review for potential deprecation and removal.
|
|
2306
|
-
* The 'module' boot mode itself has not yet seen significant adoption
|
|
2307
|
-
* or clear use-cases, and if support for module loading is removed in
|
|
2308
|
-
* the future, this 'styles' property would become obsolete.
|
|
2309
|
-
*
|
|
2310
|
-
* If module-based games need styling, alternative approaches might involve
|
|
2311
|
-
* bundling CSS within their JavaScript or managing style injection internally.
|
|
2312
|
-
*/
|
|
2313
|
-
styles: z.ZodEffects<z.ZodOptional<z.ZodArray<z.ZodString, "many">>, string[] | undefined, string[] | undefined>;
|
|
2314
|
-
/**
|
|
2315
|
-
* Specifies the game or development platform.
|
|
2316
|
-
* Current values include 'web', 'godot', and 'unity'.
|
|
2317
|
-
* The default in the database is 'web'.
|
|
2318
|
-
*
|
|
2319
|
-
* IMPORTANT: This property is NOT CURRENTLY USED by the core loader
|
|
2320
|
-
* or runtime systems in any functional way. It is present in the manifest
|
|
2321
|
-
* but does not drive any specific behavior in `boot-iframe.ts` or
|
|
2322
|
-
* `boot-module.ts` beyond being a piece of metadata.
|
|
2323
|
-
*
|
|
2324
|
-
* Potential Future Uses (Speculative):
|
|
2325
|
-
* - Analytics: Could be used to gather stats on platform popularity/usage.
|
|
2326
|
-
* - Developer Portal: Might inform UI/UX in the dev portal, e.g., showing
|
|
2327
|
-
* platform-specific guides or settings.
|
|
2328
|
-
* - Loader Optimizations: In the future, the loader could potentially use this
|
|
2329
|
-
* to apply platform-specific loading strategies or workarounds, though this
|
|
2330
|
-
* is unlikely given the current generic boot process.
|
|
2331
|
-
* - Asset Pipeline: Could hint to future asset pipeline tools about expected
|
|
2332
|
-
* project structures or build artifacts for different platforms.
|
|
2333
|
-
*
|
|
2334
|
-
* The field is intentionally kept somewhat generic. If finer-grained
|
|
2335
|
-
* distinctions are ever needed (e.g., specific web frameworks like 'phaser',
|
|
2336
|
-
* 'three'), this schema might need to be revisited or a separate
|
|
2337
|
-
* 'platformVersion' or 'framework' field could be added.
|
|
2338
|
-
*/
|
|
2339
|
-
platform: z.ZodEnum<["web", "godot", "unity"]>;
|
|
2767
|
+
platform: z.ZodString;
|
|
2340
2768
|
createdAt: z.ZodString;
|
|
2341
2769
|
}, "strip", z.ZodTypeAny, {
|
|
2342
2770
|
createdAt: string;
|
|
2343
2771
|
version: string;
|
|
2344
|
-
platform:
|
|
2345
|
-
bootMode: "iframe" | "module";
|
|
2346
|
-
entryPoint: string;
|
|
2347
|
-
styles?: string[] | undefined;
|
|
2772
|
+
platform: string;
|
|
2348
2773
|
}, {
|
|
2349
2774
|
createdAt: string;
|
|
2350
2775
|
version: string;
|
|
2351
|
-
platform:
|
|
2352
|
-
bootMode: "iframe" | "module";
|
|
2353
|
-
entryPoint: string;
|
|
2354
|
-
styles?: string[] | undefined;
|
|
2776
|
+
platform: string;
|
|
2355
2777
|
}>;
|
|
2356
2778
|
declare const InsertItemSchema: drizzle_zod.BuildSchema<"insert", {
|
|
2357
2779
|
id: drizzle_orm_pg_core.PgColumn<{
|
|
@@ -2444,7 +2866,7 @@ declare const InsertItemSchema: drizzle_zod.BuildSchema<"insert", {
|
|
|
2444
2866
|
tableName: "items";
|
|
2445
2867
|
dataType: "string";
|
|
2446
2868
|
columnType: "PgEnumColumn";
|
|
2447
|
-
data: "
|
|
2869
|
+
data: "currency" | "badge" | "trophy" | "collectible" | "consumable" | "unlock" | "upgrade" | "accessory" | "other";
|
|
2448
2870
|
driverParam: string;
|
|
2449
2871
|
notNull: true;
|
|
2450
2872
|
hasDefault: true;
|
|
@@ -2540,21 +2962,21 @@ declare const UpdateItemSchema: z.ZodObject<Omit<{
|
|
|
2540
2962
|
metadata: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodUnknown>>;
|
|
2541
2963
|
createdAt: z.ZodOptional<z.ZodDate>;
|
|
2542
2964
|
}, "id" | "createdAt">, "strip", z.ZodTypeAny, {
|
|
2965
|
+
slug?: string | undefined;
|
|
2543
2966
|
description?: string | null | undefined;
|
|
2544
2967
|
displayName?: string | undefined;
|
|
2545
|
-
slug?: string | undefined;
|
|
2546
2968
|
metadata?: Record<string, unknown> | undefined;
|
|
2547
2969
|
gameId?: string | null | undefined;
|
|
2548
|
-
type?: "
|
|
2970
|
+
type?: "currency" | "badge" | "trophy" | "collectible" | "consumable" | "unlock" | "upgrade" | "accessory" | "other" | undefined;
|
|
2549
2971
|
isPlaceable?: boolean | undefined;
|
|
2550
2972
|
imageUrl?: string | null | undefined;
|
|
2551
2973
|
}, {
|
|
2974
|
+
slug?: string | undefined;
|
|
2552
2975
|
description?: string | null | undefined;
|
|
2553
2976
|
displayName?: string | undefined;
|
|
2554
|
-
slug?: string | undefined;
|
|
2555
2977
|
metadata?: Record<string, unknown> | undefined;
|
|
2556
2978
|
gameId?: string | null | undefined;
|
|
2557
|
-
type?: "
|
|
2979
|
+
type?: "currency" | "badge" | "trophy" | "collectible" | "consumable" | "unlock" | "upgrade" | "accessory" | "other" | undefined;
|
|
2558
2980
|
isPlaceable?: boolean | undefined;
|
|
2559
2981
|
imageUrl?: string | null | undefined;
|
|
2560
2982
|
}>;
|
|
@@ -2600,10 +3022,10 @@ declare const InsertShopListingSchema: z.ZodObject<Omit<{
|
|
|
2600
3022
|
createdAt: z.ZodOptional<z.ZodDate>;
|
|
2601
3023
|
updatedAt: z.ZodOptional<z.ZodNullable<z.ZodDate>>;
|
|
2602
3024
|
}, "id" | "createdAt" | "updatedAt">, "strip", z.ZodTypeAny, {
|
|
3025
|
+
isActive: boolean;
|
|
2603
3026
|
itemId: string;
|
|
2604
3027
|
currencyId: string;
|
|
2605
3028
|
price: number;
|
|
2606
|
-
isActive: boolean;
|
|
2607
3029
|
sellBackPercentage?: number | null | undefined;
|
|
2608
3030
|
stock?: number | null | undefined;
|
|
2609
3031
|
availableFrom?: Date | null | undefined;
|
|
@@ -2612,37 +3034,37 @@ declare const InsertShopListingSchema: z.ZodObject<Omit<{
|
|
|
2612
3034
|
itemId: string;
|
|
2613
3035
|
currencyId: string;
|
|
2614
3036
|
price: number;
|
|
3037
|
+
isActive?: boolean | undefined;
|
|
2615
3038
|
sellBackPercentage?: number | null | undefined;
|
|
2616
3039
|
stock?: number | null | undefined;
|
|
2617
|
-
isActive?: boolean | undefined;
|
|
2618
3040
|
availableFrom?: Date | null | undefined;
|
|
2619
3041
|
availableUntil?: Date | null | undefined;
|
|
2620
3042
|
}>;
|
|
2621
3043
|
declare const UpdateShopListingSchema: z.ZodObject<{
|
|
3044
|
+
isActive: z.ZodOptional<z.ZodDefault<z.ZodBoolean>>;
|
|
2622
3045
|
itemId: z.ZodOptional<z.ZodString>;
|
|
2623
3046
|
currencyId: z.ZodOptional<z.ZodString>;
|
|
2624
3047
|
price: z.ZodOptional<z.ZodNumber>;
|
|
2625
3048
|
sellBackPercentage: z.ZodOptional<z.ZodNullable<z.ZodOptional<z.ZodNumber>>>;
|
|
2626
3049
|
stock: z.ZodOptional<z.ZodNullable<z.ZodOptional<z.ZodNumber>>>;
|
|
2627
|
-
isActive: z.ZodOptional<z.ZodDefault<z.ZodBoolean>>;
|
|
2628
3050
|
availableFrom: z.ZodOptional<z.ZodOptional<z.ZodNullable<z.ZodDate>>>;
|
|
2629
3051
|
availableUntil: z.ZodOptional<z.ZodOptional<z.ZodNullable<z.ZodDate>>>;
|
|
2630
3052
|
}, "strip", z.ZodTypeAny, {
|
|
3053
|
+
isActive?: boolean | undefined;
|
|
2631
3054
|
itemId?: string | undefined;
|
|
2632
3055
|
currencyId?: string | undefined;
|
|
2633
3056
|
price?: number | undefined;
|
|
2634
3057
|
sellBackPercentage?: number | null | undefined;
|
|
2635
3058
|
stock?: number | null | undefined;
|
|
2636
|
-
isActive?: boolean | undefined;
|
|
2637
3059
|
availableFrom?: Date | null | undefined;
|
|
2638
3060
|
availableUntil?: Date | null | undefined;
|
|
2639
3061
|
}, {
|
|
3062
|
+
isActive?: boolean | undefined;
|
|
2640
3063
|
itemId?: string | undefined;
|
|
2641
3064
|
currencyId?: string | undefined;
|
|
2642
3065
|
price?: number | undefined;
|
|
2643
3066
|
sellBackPercentage?: number | null | undefined;
|
|
2644
3067
|
stock?: number | null | undefined;
|
|
2645
|
-
isActive?: boolean | undefined;
|
|
2646
3068
|
availableFrom?: Date | null | undefined;
|
|
2647
3069
|
availableUntil?: Date | null | undefined;
|
|
2648
3070
|
}>;
|
|
@@ -2729,31 +3151,21 @@ type PlayerCharacter = typeof playerCharacters.$inferSelect & {
|
|
|
2729
3151
|
};
|
|
2730
3152
|
type PlayerCharacterAccessory = typeof playerCharacterAccessories.$inferSelect;
|
|
2731
3153
|
type GameRow = typeof games.$inferSelect;
|
|
2732
|
-
type BaseGame = Omit<GameRow, 'gameType' | '
|
|
3154
|
+
type BaseGame = Omit<GameRow, 'gameType' | 'deploymentUrl' | 'externalUrl'>;
|
|
2733
3155
|
type HostedGame = BaseGame & {
|
|
2734
3156
|
gameType: 'hosted';
|
|
2735
|
-
|
|
3157
|
+
deploymentUrl: string;
|
|
2736
3158
|
externalUrl: null;
|
|
2737
3159
|
};
|
|
2738
3160
|
type ExternalGame = BaseGame & {
|
|
2739
3161
|
gameType: 'external';
|
|
2740
|
-
|
|
3162
|
+
deploymentUrl: null;
|
|
2741
3163
|
externalUrl: string;
|
|
2742
3164
|
};
|
|
2743
3165
|
type Game = HostedGame | ExternalGame;
|
|
2744
3166
|
type GameStateData = Record<string, unknown>;
|
|
3167
|
+
type GameCustomHostname = typeof gameCustomHostnames.$inferSelect;
|
|
2745
3168
|
type UpsertGameMetadataInput = z.infer<typeof UpsertGameMetadataSchema>;
|
|
2746
|
-
/**
|
|
2747
|
-
* Response from backend deployment API
|
|
2748
|
-
*/
|
|
2749
|
-
interface BackendDeploymentResponse {
|
|
2750
|
-
/** Unique deployment ID */
|
|
2751
|
-
deploymentId: string;
|
|
2752
|
-
/** Backend API URL */
|
|
2753
|
-
url: string;
|
|
2754
|
-
/** Deployment timestamp */
|
|
2755
|
-
deployedAt: string;
|
|
2756
|
-
}
|
|
2757
3169
|
type Item = typeof items.$inferSelect;
|
|
2758
3170
|
type InventoryItem = typeof inventoryItems.$inferSelect;
|
|
2759
3171
|
type ShopListing = typeof shopListings.$inferSelect;
|
|
@@ -2837,10 +3249,12 @@ type CharacterComponentWithSpriteUrl = CharacterComponent & {
|
|
|
2837
3249
|
type InventoryItemWithItem = Omit<InventoryItem, 'itemId'> & {
|
|
2838
3250
|
item: Item;
|
|
2839
3251
|
};
|
|
2840
|
-
|
|
2841
|
-
|
|
3252
|
+
/**
|
|
3253
|
+
* Game with optional manifest metadata from build tools
|
|
3254
|
+
*/
|
|
3255
|
+
type FetchedGame = (HostedGame | ExternalGame | GameRow) & {
|
|
3256
|
+
manifest?: ManifestV1;
|
|
2842
3257
|
};
|
|
2843
|
-
type FetchedGame = HostedGameWithManifest | GameRow;
|
|
2844
3258
|
/**
|
|
2845
3259
|
* Map-related Composite Types
|
|
2846
3260
|
* Types that combine map, game, and item data for rendering and interaction
|
|
@@ -3114,38 +3528,123 @@ type EndActivityResponse = {
|
|
|
3114
3528
|
};
|
|
3115
3529
|
|
|
3116
3530
|
/**
|
|
3117
|
-
*
|
|
3531
|
+
* OAuth 2.0 implementation for the Playcademy SDK
|
|
3532
|
+
*/
|
|
3533
|
+
|
|
3534
|
+
/**
|
|
3535
|
+
* Parses an OAuth state parameter to extract CSRF token and any encoded data.
|
|
3118
3536
|
*
|
|
3119
|
-
*
|
|
3120
|
-
*
|
|
3537
|
+
* @param state - The OAuth state parameter to parse
|
|
3538
|
+
* @returns Object containing CSRF token and optional decoded data
|
|
3121
3539
|
*/
|
|
3540
|
+
declare function parseOAuthState(state: string): {
|
|
3541
|
+
csrfToken: string;
|
|
3542
|
+
data?: Record<string, string>;
|
|
3543
|
+
};
|
|
3122
3544
|
|
|
3123
3545
|
/**
|
|
3124
|
-
*
|
|
3546
|
+
* Response type for the realtime token API
|
|
3125
3547
|
*/
|
|
3126
|
-
interface
|
|
3127
|
-
|
|
3128
|
-
organization?: Partial<OrganizationConfig>;
|
|
3129
|
-
/** Course configuration (subjects and grades REQUIRED) */
|
|
3130
|
-
course: CourseConfig;
|
|
3131
|
-
/** Component overrides */
|
|
3132
|
-
component?: Partial<ComponentConfig>;
|
|
3133
|
-
/** Resource overrides */
|
|
3134
|
-
resource?: Partial<ResourceConfig>;
|
|
3135
|
-
/** Component-Resource link overrides */
|
|
3136
|
-
componentResource?: Partial<ComponentResourceConfig>;
|
|
3548
|
+
interface RealtimeTokenResponse {
|
|
3549
|
+
token: string;
|
|
3137
3550
|
}
|
|
3551
|
+
|
|
3138
3552
|
/**
|
|
3139
|
-
*
|
|
3553
|
+
* Cache configuration types for runtime customization
|
|
3140
3554
|
*/
|
|
3141
|
-
interface CustomRoutesIntegration {
|
|
3142
|
-
/** Directory for custom API routes (defaults to 'server/api') */
|
|
3143
|
-
directory?: string;
|
|
3144
|
-
}
|
|
3145
3555
|
/**
|
|
3146
|
-
*
|
|
3556
|
+
* Runtime configuration for TTL cache behavior
|
|
3147
3557
|
*/
|
|
3148
|
-
interface
|
|
3558
|
+
interface TTLCacheConfig {
|
|
3559
|
+
/** Time-to-live in milliseconds. Set to 0 to disable caching for this call. */
|
|
3560
|
+
ttl?: number;
|
|
3561
|
+
/** Force refresh, bypassing cache */
|
|
3562
|
+
force?: boolean;
|
|
3563
|
+
/** Skip cache and fetch fresh data (alias for force) */
|
|
3564
|
+
skipCache?: boolean;
|
|
3565
|
+
}
|
|
3566
|
+
/**
|
|
3567
|
+
* Runtime configuration for cooldown cache behavior
|
|
3568
|
+
*/
|
|
3569
|
+
interface CooldownCacheConfig {
|
|
3570
|
+
/** Cooldown period in milliseconds. Set to 0 to disable cooldown for this call. */
|
|
3571
|
+
cooldown?: number;
|
|
3572
|
+
/** Force refresh, bypassing cooldown */
|
|
3573
|
+
force?: boolean;
|
|
3574
|
+
}
|
|
3575
|
+
|
|
3576
|
+
interface CharacterComponentsOptions {
|
|
3577
|
+
/**
|
|
3578
|
+
* Optional level filter for components
|
|
3579
|
+
* When provided, only components available at this level or below are returned
|
|
3580
|
+
*/
|
|
3581
|
+
level?: number;
|
|
3582
|
+
/**
|
|
3583
|
+
* Whether to bypass the cache and force a fresh API request
|
|
3584
|
+
* Default: false (use cache when available)
|
|
3585
|
+
*/
|
|
3586
|
+
skipCache?: boolean;
|
|
3587
|
+
}
|
|
3588
|
+
interface CreateCharacterData {
|
|
3589
|
+
bodyComponentId: string;
|
|
3590
|
+
eyesComponentId: string;
|
|
3591
|
+
hairstyleComponentId: string;
|
|
3592
|
+
outfitComponentId: string;
|
|
3593
|
+
}
|
|
3594
|
+
interface UpdateCharacterData {
|
|
3595
|
+
bodyComponentId?: string;
|
|
3596
|
+
eyesComponentId?: string;
|
|
3597
|
+
hairstyleComponentId?: string;
|
|
3598
|
+
outfitComponentId?: string;
|
|
3599
|
+
}
|
|
3600
|
+
|
|
3601
|
+
interface ScoreSubmission {
|
|
3602
|
+
id: string;
|
|
3603
|
+
score: number;
|
|
3604
|
+
achievedAt: Date;
|
|
3605
|
+
}
|
|
3606
|
+
|
|
3607
|
+
/**
|
|
3608
|
+
* Combined response type for summary method
|
|
3609
|
+
*/
|
|
3610
|
+
type XpSummaryResponse = {
|
|
3611
|
+
today: TodayXpResponse;
|
|
3612
|
+
total: TotalXpResponse;
|
|
3613
|
+
};
|
|
3614
|
+
|
|
3615
|
+
/**
|
|
3616
|
+
* @fileoverview Server SDK Type Definitions
|
|
3617
|
+
*
|
|
3618
|
+
* TypeScript type definitions for the server-side Playcademy SDK.
|
|
3619
|
+
* Includes configuration types, client state, and re-exported TimeBack types.
|
|
3620
|
+
*/
|
|
3621
|
+
|
|
3622
|
+
/**
|
|
3623
|
+
* TimeBack integration configuration for Playcademy config file
|
|
3624
|
+
*/
|
|
3625
|
+
interface TimebackIntegrationConfig {
|
|
3626
|
+
/** Organization overrides */
|
|
3627
|
+
organization?: Partial<OrganizationConfig>;
|
|
3628
|
+
/** Course configuration (subjects and grades REQUIRED) */
|
|
3629
|
+
course: CourseConfig;
|
|
3630
|
+
/** Component overrides */
|
|
3631
|
+
component?: Partial<ComponentConfig>;
|
|
3632
|
+
/** Resource overrides */
|
|
3633
|
+
resource?: Partial<ResourceConfig>;
|
|
3634
|
+
/** Component-Resource link overrides */
|
|
3635
|
+
componentResource?: Partial<ComponentResourceConfig>;
|
|
3636
|
+
}
|
|
3637
|
+
/**
|
|
3638
|
+
* Custom API routes integration
|
|
3639
|
+
*/
|
|
3640
|
+
interface CustomRoutesIntegration {
|
|
3641
|
+
/** Directory for custom API routes (defaults to 'server/api') */
|
|
3642
|
+
directory?: string;
|
|
3643
|
+
}
|
|
3644
|
+
/**
|
|
3645
|
+
* Database integration
|
|
3646
|
+
*/
|
|
3647
|
+
interface DatabaseIntegration {
|
|
3149
3648
|
/** Database directory (defaults to 'db') */
|
|
3150
3649
|
directory?: string;
|
|
3151
3650
|
}
|
|
@@ -3164,6 +3663,8 @@ interface IntegrationsConfig {
|
|
|
3164
3663
|
kv?: boolean;
|
|
3165
3664
|
/** Bucket storage (optional) */
|
|
3166
3665
|
bucket?: boolean;
|
|
3666
|
+
/** Authentication (optional) */
|
|
3667
|
+
auth?: boolean;
|
|
3167
3668
|
}
|
|
3168
3669
|
/**
|
|
3169
3670
|
* Unified Playcademy configuration
|
|
@@ -3218,295 +3719,6 @@ interface BackendDeploymentBundle {
|
|
|
3218
3719
|
secrets?: Record<string, string>;
|
|
3219
3720
|
}
|
|
3220
3721
|
|
|
3221
|
-
type TokenType = 'session' | 'apiKey' | 'gameJwt';
|
|
3222
|
-
interface ClientConfig {
|
|
3223
|
-
baseUrl: string;
|
|
3224
|
-
gameUrl?: string;
|
|
3225
|
-
token?: string;
|
|
3226
|
-
tokenType?: TokenType;
|
|
3227
|
-
gameId?: string;
|
|
3228
|
-
autoStartSession?: boolean;
|
|
3229
|
-
}
|
|
3230
|
-
type AuthProviderType = (typeof AUTH_PROVIDER_IDS)[keyof typeof AUTH_PROVIDER_IDS];
|
|
3231
|
-
interface AuthOptions {
|
|
3232
|
-
/** The identity provider to use for authentication */
|
|
3233
|
-
provider: AuthProviderType;
|
|
3234
|
-
/** The OAuth callback URL where your server handles the callback */
|
|
3235
|
-
callbackUrl: string;
|
|
3236
|
-
/** Authentication mode - auto detects best option based on context */
|
|
3237
|
-
mode?: 'auto' | 'popup' | 'redirect';
|
|
3238
|
-
/** Callback for authentication state changes */
|
|
3239
|
-
onStateChange?: (state: AuthStateUpdate) => void;
|
|
3240
|
-
/** Custom OAuth configuration (for users embedding the SDK outside of the Playcademy platform) */
|
|
3241
|
-
oauth?: {
|
|
3242
|
-
clientId: string;
|
|
3243
|
-
authorizationEndpoint?: string;
|
|
3244
|
-
tokenEndpoint?: string;
|
|
3245
|
-
scope?: string;
|
|
3246
|
-
};
|
|
3247
|
-
/**
|
|
3248
|
-
* Optional custom data to encode in OAuth state parameter.
|
|
3249
|
-
* By default, the SDK automatically includes playcademy_user_id and game_id.
|
|
3250
|
-
* Use this to add additional custom data if needed.
|
|
3251
|
-
*/
|
|
3252
|
-
stateData?: Record<string, string>;
|
|
3253
|
-
}
|
|
3254
|
-
interface AuthStateUpdate {
|
|
3255
|
-
/** Current status of the authentication flow */
|
|
3256
|
-
status: 'opening_popup' | 'exchanging_token' | 'complete' | 'error';
|
|
3257
|
-
/** Human-readable message about the current state */
|
|
3258
|
-
message: string;
|
|
3259
|
-
/** Error details if status is 'error' */
|
|
3260
|
-
error?: Error;
|
|
3261
|
-
}
|
|
3262
|
-
interface AuthResult {
|
|
3263
|
-
/** Whether authentication was successful */
|
|
3264
|
-
success: boolean;
|
|
3265
|
-
/** User information if authentication was successful */
|
|
3266
|
-
user?: UserInfo;
|
|
3267
|
-
/** Error if authentication failed */
|
|
3268
|
-
error?: Error;
|
|
3269
|
-
}
|
|
3270
|
-
/**
|
|
3271
|
-
* Authentication state change event payload.
|
|
3272
|
-
* Used when authentication state changes in the application.
|
|
3273
|
-
*/
|
|
3274
|
-
interface AuthStateChangePayload {
|
|
3275
|
-
/** Whether the user is currently authenticated */
|
|
3276
|
-
authenticated: boolean;
|
|
3277
|
-
/** User information if authenticated, null otherwise */
|
|
3278
|
-
user: UserInfo | null;
|
|
3279
|
-
/** Error information if authentication failed */
|
|
3280
|
-
error: Error | null;
|
|
3281
|
-
}
|
|
3282
|
-
/**
|
|
3283
|
-
* OAuth callback event payload.
|
|
3284
|
-
* Used when OAuth flow completes in popup/new-tab windows.
|
|
3285
|
-
*/
|
|
3286
|
-
interface AuthCallbackPayload {
|
|
3287
|
-
/** OAuth authorization code */
|
|
3288
|
-
code: string;
|
|
3289
|
-
/** OAuth state parameter for CSRF protection */
|
|
3290
|
-
state: string;
|
|
3291
|
-
/** Error message if OAuth flow failed */
|
|
3292
|
-
error: string | null;
|
|
3293
|
-
}
|
|
3294
|
-
/**
|
|
3295
|
-
* Token refresh event payload.
|
|
3296
|
-
* Sent when authentication token is updated.
|
|
3297
|
-
*/
|
|
3298
|
-
interface TokenRefreshPayload {
|
|
3299
|
-
/** New authentication token */
|
|
3300
|
-
token: string;
|
|
3301
|
-
/** Token expiration timestamp */
|
|
3302
|
-
exp: number;
|
|
3303
|
-
}
|
|
3304
|
-
/**
|
|
3305
|
-
* Telemetry event payload.
|
|
3306
|
-
* Performance metrics sent from the game.
|
|
3307
|
-
*/
|
|
3308
|
-
interface TelemetryPayload {
|
|
3309
|
-
/** Frames per second */
|
|
3310
|
-
fps: number;
|
|
3311
|
-
/** Memory usage in MB */
|
|
3312
|
-
mem: number;
|
|
3313
|
-
}
|
|
3314
|
-
/**
|
|
3315
|
-
* Keyboard event payload.
|
|
3316
|
-
* Key events forwarded from the game.
|
|
3317
|
-
*/
|
|
3318
|
-
interface KeyEventPayload {
|
|
3319
|
-
/** Key value (e.g., 'Escape', 'F1') */
|
|
3320
|
-
key: string;
|
|
3321
|
-
/** Key code (optional) */
|
|
3322
|
-
code?: string;
|
|
3323
|
-
/** Event type */
|
|
3324
|
-
type: 'keydown' | 'keyup';
|
|
3325
|
-
}
|
|
3326
|
-
interface ClientEvents {
|
|
3327
|
-
authChange: {
|
|
3328
|
-
token: string | null;
|
|
3329
|
-
};
|
|
3330
|
-
inventoryChange: {
|
|
3331
|
-
itemId: string;
|
|
3332
|
-
delta: number;
|
|
3333
|
-
newTotal: number;
|
|
3334
|
-
};
|
|
3335
|
-
levelUp: {
|
|
3336
|
-
oldLevel: number;
|
|
3337
|
-
newLevel: number;
|
|
3338
|
-
creditsAwarded: number;
|
|
3339
|
-
};
|
|
3340
|
-
xpGained: {
|
|
3341
|
-
amount: number;
|
|
3342
|
-
totalXP: number;
|
|
3343
|
-
leveledUp: boolean;
|
|
3344
|
-
};
|
|
3345
|
-
}
|
|
3346
|
-
type GameContextPayload = {
|
|
3347
|
-
token: string;
|
|
3348
|
-
baseUrl: string;
|
|
3349
|
-
realtimeUrl: string;
|
|
3350
|
-
gameId: string;
|
|
3351
|
-
forwardKeys?: string[];
|
|
3352
|
-
};
|
|
3353
|
-
type LoginResponse = {
|
|
3354
|
-
token: string;
|
|
3355
|
-
};
|
|
3356
|
-
type GameTokenResponse = {
|
|
3357
|
-
token: string;
|
|
3358
|
-
exp: number;
|
|
3359
|
-
};
|
|
3360
|
-
type StartSessionResponse = {
|
|
3361
|
-
sessionId: string;
|
|
3362
|
-
};
|
|
3363
|
-
type InventoryMutationResponse = {
|
|
3364
|
-
newTotal: number;
|
|
3365
|
-
};
|
|
3366
|
-
type DevUploadEvent = {
|
|
3367
|
-
type: 'init';
|
|
3368
|
-
} | {
|
|
3369
|
-
type: 's3Progress';
|
|
3370
|
-
loaded: number;
|
|
3371
|
-
total: number;
|
|
3372
|
-
percent: number;
|
|
3373
|
-
} | {
|
|
3374
|
-
type: 'finalizeStart';
|
|
3375
|
-
} | {
|
|
3376
|
-
type: 'finalizeProgress';
|
|
3377
|
-
percent: number;
|
|
3378
|
-
currentFileLabel?: string;
|
|
3379
|
-
} | {
|
|
3380
|
-
type: 'finalizeStatus';
|
|
3381
|
-
message: string;
|
|
3382
|
-
} | {
|
|
3383
|
-
type: 'close';
|
|
3384
|
-
};
|
|
3385
|
-
type DevUploadHooks = {
|
|
3386
|
-
onEvent?: (e: DevUploadEvent) => void;
|
|
3387
|
-
onClose?: () => void;
|
|
3388
|
-
};
|
|
3389
|
-
/**
|
|
3390
|
-
* Better-auth API key creation response
|
|
3391
|
-
*/
|
|
3392
|
-
interface BetterAuthApiKeyResponse {
|
|
3393
|
-
apiKey: string;
|
|
3394
|
-
key: {
|
|
3395
|
-
id: string;
|
|
3396
|
-
name: string | null;
|
|
3397
|
-
expiresAt: string | null;
|
|
3398
|
-
createdAt: string;
|
|
3399
|
-
};
|
|
3400
|
-
}
|
|
3401
|
-
/**
|
|
3402
|
-
* Better-auth API key list item
|
|
3403
|
-
*/
|
|
3404
|
-
interface BetterAuthApiKey {
|
|
3405
|
-
id: string;
|
|
3406
|
-
name: string | null;
|
|
3407
|
-
start: string;
|
|
3408
|
-
enabled: boolean;
|
|
3409
|
-
expiresAt: string | null;
|
|
3410
|
-
createdAt: string;
|
|
3411
|
-
updatedAt: string;
|
|
3412
|
-
lastRequest: string | null;
|
|
3413
|
-
requestCount: number;
|
|
3414
|
-
}
|
|
3415
|
-
/**
|
|
3416
|
-
* Bucket file metadata
|
|
3417
|
-
*/
|
|
3418
|
-
interface BucketFile {
|
|
3419
|
-
key: string;
|
|
3420
|
-
size: number;
|
|
3421
|
-
uploaded: string;
|
|
3422
|
-
contentType?: string;
|
|
3423
|
-
}
|
|
3424
|
-
|
|
3425
|
-
/**
|
|
3426
|
-
* OAuth 2.0 implementation for the Playcademy SDK
|
|
3427
|
-
*/
|
|
3428
|
-
|
|
3429
|
-
/**
|
|
3430
|
-
* Parses an OAuth state parameter to extract CSRF token and any encoded data.
|
|
3431
|
-
*
|
|
3432
|
-
* @param state - The OAuth state parameter to parse
|
|
3433
|
-
* @returns Object containing CSRF token and optional decoded data
|
|
3434
|
-
*/
|
|
3435
|
-
declare function parseOAuthState(state: string): {
|
|
3436
|
-
csrfToken: string;
|
|
3437
|
-
data?: Record<string, string>;
|
|
3438
|
-
};
|
|
3439
|
-
|
|
3440
|
-
/**
|
|
3441
|
-
* Response type for the realtime token API
|
|
3442
|
-
*/
|
|
3443
|
-
interface RealtimeTokenResponse {
|
|
3444
|
-
token: string;
|
|
3445
|
-
}
|
|
3446
|
-
|
|
3447
|
-
/**
|
|
3448
|
-
* Cache configuration types for runtime customization
|
|
3449
|
-
*/
|
|
3450
|
-
/**
|
|
3451
|
-
* Runtime configuration for TTL cache behavior
|
|
3452
|
-
*/
|
|
3453
|
-
interface TTLCacheConfig {
|
|
3454
|
-
/** Time-to-live in milliseconds. Set to 0 to disable caching for this call. */
|
|
3455
|
-
ttl?: number;
|
|
3456
|
-
/** Force refresh, bypassing cache */
|
|
3457
|
-
force?: boolean;
|
|
3458
|
-
/** Skip cache and fetch fresh data (alias for force) */
|
|
3459
|
-
skipCache?: boolean;
|
|
3460
|
-
}
|
|
3461
|
-
/**
|
|
3462
|
-
* Runtime configuration for cooldown cache behavior
|
|
3463
|
-
*/
|
|
3464
|
-
interface CooldownCacheConfig {
|
|
3465
|
-
/** Cooldown period in milliseconds. Set to 0 to disable cooldown for this call. */
|
|
3466
|
-
cooldown?: number;
|
|
3467
|
-
/** Force refresh, bypassing cooldown */
|
|
3468
|
-
force?: boolean;
|
|
3469
|
-
}
|
|
3470
|
-
|
|
3471
|
-
interface CharacterComponentsOptions {
|
|
3472
|
-
/**
|
|
3473
|
-
* Optional level filter for components
|
|
3474
|
-
* When provided, only components available at this level or below are returned
|
|
3475
|
-
*/
|
|
3476
|
-
level?: number;
|
|
3477
|
-
/**
|
|
3478
|
-
* Whether to bypass the cache and force a fresh API request
|
|
3479
|
-
* Default: false (use cache when available)
|
|
3480
|
-
*/
|
|
3481
|
-
skipCache?: boolean;
|
|
3482
|
-
}
|
|
3483
|
-
interface CreateCharacterData {
|
|
3484
|
-
bodyComponentId: string;
|
|
3485
|
-
eyesComponentId: string;
|
|
3486
|
-
hairstyleComponentId: string;
|
|
3487
|
-
outfitComponentId: string;
|
|
3488
|
-
}
|
|
3489
|
-
interface UpdateCharacterData {
|
|
3490
|
-
bodyComponentId?: string;
|
|
3491
|
-
eyesComponentId?: string;
|
|
3492
|
-
hairstyleComponentId?: string;
|
|
3493
|
-
outfitComponentId?: string;
|
|
3494
|
-
}
|
|
3495
|
-
|
|
3496
|
-
interface ScoreSubmission {
|
|
3497
|
-
id: string;
|
|
3498
|
-
score: number;
|
|
3499
|
-
achievedAt: Date;
|
|
3500
|
-
}
|
|
3501
|
-
|
|
3502
|
-
/**
|
|
3503
|
-
* Combined response type for summary method
|
|
3504
|
-
*/
|
|
3505
|
-
type XpSummaryResponse = {
|
|
3506
|
-
today: TodayXpResponse;
|
|
3507
|
-
total: TotalXpResponse;
|
|
3508
|
-
};
|
|
3509
|
-
|
|
3510
3722
|
interface UserScore {
|
|
3511
3723
|
id: string;
|
|
3512
3724
|
score: number;
|
|
@@ -3544,6 +3756,8 @@ interface UserScore {
|
|
|
3544
3756
|
declare function init(options?: {
|
|
3545
3757
|
baseUrl?: string;
|
|
3546
3758
|
allowedParentOrigins?: string[];
|
|
3759
|
+
onDisconnect?: DisconnectHandler;
|
|
3760
|
+
enableConnectionMonitoring?: boolean;
|
|
3547
3761
|
}): Promise<PlaycademyClient>;
|
|
3548
3762
|
|
|
3549
3763
|
/**
|
|
@@ -3597,6 +3811,7 @@ declare class PlaycademyClient {
|
|
|
3597
3811
|
private internalClientSessionId?;
|
|
3598
3812
|
private authContext?;
|
|
3599
3813
|
private initPayload?;
|
|
3814
|
+
private connectionManager?;
|
|
3600
3815
|
/**
|
|
3601
3816
|
* Creates a new PlaycademyClient instance.
|
|
3602
3817
|
*
|
|
@@ -3643,51 +3858,130 @@ declare class PlaycademyClient {
|
|
|
3643
3858
|
*
|
|
3644
3859
|
* @returns The token type
|
|
3645
3860
|
*/
|
|
3646
|
-
getTokenType(): TokenType;
|
|
3861
|
+
getTokenType(): TokenType;
|
|
3862
|
+
/**
|
|
3863
|
+
* Gets the current authentication token.
|
|
3864
|
+
*
|
|
3865
|
+
* @returns The current token or null if not authenticated
|
|
3866
|
+
*
|
|
3867
|
+
* @example
|
|
3868
|
+
* ```typescript
|
|
3869
|
+
* // Send token to your backend for verification
|
|
3870
|
+
* const token = client.getToken()
|
|
3871
|
+
* const response = await fetch('/api/auth/playcademy', {
|
|
3872
|
+
* method: 'POST',
|
|
3873
|
+
* body: JSON.stringify({ gameToken: token })
|
|
3874
|
+
* })
|
|
3875
|
+
* ```
|
|
3876
|
+
*/
|
|
3877
|
+
getToken(): string | null;
|
|
3878
|
+
/**
|
|
3879
|
+
* Checks if the client has a valid API token for making Playcademy API requests.
|
|
3880
|
+
*
|
|
3881
|
+
* For games (iframe context): Checks if we have a valid token from the parent.
|
|
3882
|
+
* For Cademy (standalone): Checks if we have a token from better-auth.
|
|
3883
|
+
*
|
|
3884
|
+
* Note: This checks for API authentication, not whether a user has linked
|
|
3885
|
+
* their identity via OAuth.
|
|
3886
|
+
*
|
|
3887
|
+
* @returns true if API token exists, false otherwise
|
|
3888
|
+
*
|
|
3889
|
+
* @example
|
|
3890
|
+
* ```typescript
|
|
3891
|
+
* if (client.isAuthenticated()) {
|
|
3892
|
+
* // Can make API calls
|
|
3893
|
+
* const games = await client.games.list()
|
|
3894
|
+
* } else {
|
|
3895
|
+
* console.error('No API token available')
|
|
3896
|
+
* }
|
|
3897
|
+
* ```
|
|
3898
|
+
*/
|
|
3899
|
+
isAuthenticated(): boolean;
|
|
3900
|
+
/**
|
|
3901
|
+
* Registers a callback to be called when authentication state changes.
|
|
3902
|
+
*
|
|
3903
|
+
* @param callback - Function to call when auth state changes
|
|
3904
|
+
*/
|
|
3905
|
+
onAuthChange(callback: (token: string | null) => void): void;
|
|
3906
|
+
/**
|
|
3907
|
+
* Registers a callback to be called when connection issues are detected.
|
|
3908
|
+
*
|
|
3909
|
+
* This is a convenience method that filters connection change events to only
|
|
3910
|
+
* fire when the connection degrades (offline or degraded states). Use this
|
|
3911
|
+
* when you want to handle disconnects without being notified of recoveries.
|
|
3912
|
+
*
|
|
3913
|
+
* For all connection state changes, use `client.on('connectionChange', ...)` instead.
|
|
3914
|
+
*
|
|
3915
|
+
* @param callback - Function to call when connection state changes to offline or degraded
|
|
3916
|
+
* @returns Cleanup function to unregister the callback
|
|
3917
|
+
*
|
|
3918
|
+
* @example
|
|
3919
|
+
* ```typescript
|
|
3920
|
+
* const cleanup = client.onDisconnect(({ state, reason, displayAlert }) => {
|
|
3921
|
+
* console.log(`Connection ${state}: ${reason}`)
|
|
3922
|
+
*
|
|
3923
|
+
* if (state === 'offline') {
|
|
3924
|
+
* // Save state and return to game lobby
|
|
3925
|
+
* displayAlert?.('Connection lost. Your progress has been saved.', { type: 'error' })
|
|
3926
|
+
* saveGameState()
|
|
3927
|
+
* returnToLobby()
|
|
3928
|
+
* } else if (state === 'degraded') {
|
|
3929
|
+
* displayAlert?.('Slow connection detected.', { type: 'warning' })
|
|
3930
|
+
* }
|
|
3931
|
+
* })
|
|
3932
|
+
*
|
|
3933
|
+
* // Later: cleanup() to unregister
|
|
3934
|
+
* ```
|
|
3935
|
+
*
|
|
3936
|
+
* @see {@link DISCONNECT_HANDLING.md} for detailed usage examples
|
|
3937
|
+
* @see {@link ConnectionManager.onDisconnect} for the underlying implementation
|
|
3938
|
+
*/
|
|
3939
|
+
onDisconnect(callback: (context: DisconnectContext) => void | Promise<void>): () => void;
|
|
3647
3940
|
/**
|
|
3648
|
-
* Gets the current
|
|
3941
|
+
* Gets the current connection state.
|
|
3649
3942
|
*
|
|
3650
|
-
*
|
|
3943
|
+
* Returns the last known connection state without triggering a new check.
|
|
3944
|
+
* Use `checkConnection()` to force an immediate verification.
|
|
3945
|
+
*
|
|
3946
|
+
* @returns Current connection state ('online', 'offline', 'degraded') or 'unknown' if monitoring is disabled
|
|
3651
3947
|
*
|
|
3652
3948
|
* @example
|
|
3653
3949
|
* ```typescript
|
|
3654
|
-
*
|
|
3655
|
-
*
|
|
3656
|
-
*
|
|
3657
|
-
*
|
|
3658
|
-
* body: JSON.stringify({ gameToken: token })
|
|
3659
|
-
* })
|
|
3950
|
+
* const state = client.getConnectionState()
|
|
3951
|
+
* if (state === 'offline') {
|
|
3952
|
+
* console.log('No connection available')
|
|
3953
|
+
* }
|
|
3660
3954
|
* ```
|
|
3955
|
+
*
|
|
3956
|
+
* @see {@link checkConnection} to trigger an immediate connection check
|
|
3957
|
+
* @see {@link ConnectionManager.getState} for the underlying implementation
|
|
3661
3958
|
*/
|
|
3662
|
-
|
|
3959
|
+
getConnectionState(): ConnectionState | 'unknown';
|
|
3663
3960
|
/**
|
|
3664
|
-
*
|
|
3665
|
-
*
|
|
3666
|
-
* For games (iframe context): Checks if we have a valid token from the parent.
|
|
3667
|
-
* For Cademy (standalone): Checks if we have a token from better-auth.
|
|
3961
|
+
* Manually triggers a connection check immediately.
|
|
3668
3962
|
*
|
|
3669
|
-
*
|
|
3670
|
-
*
|
|
3963
|
+
* Forces a heartbeat ping to verify connectivity right now, bypassing the normal
|
|
3964
|
+
* interval. Useful when you need to verify connection status before a critical
|
|
3965
|
+
* operation (e.g., saving important game state).
|
|
3671
3966
|
*
|
|
3672
|
-
* @returns
|
|
3967
|
+
* @returns Promise resolving to the current connection state after verification
|
|
3673
3968
|
*
|
|
3674
3969
|
* @example
|
|
3675
3970
|
* ```typescript
|
|
3676
|
-
*
|
|
3677
|
-
*
|
|
3678
|
-
*
|
|
3679
|
-
*
|
|
3680
|
-
*
|
|
3971
|
+
* // Check before critical operation
|
|
3972
|
+
* const state = await client.checkConnection()
|
|
3973
|
+
* if (state !== 'online') {
|
|
3974
|
+
* alert('Please check your internet connection before saving')
|
|
3975
|
+
* return
|
|
3681
3976
|
* }
|
|
3977
|
+
*
|
|
3978
|
+
* await client.games.saveState(importantData)
|
|
3682
3979
|
* ```
|
|
3683
|
-
*/
|
|
3684
|
-
isAuthenticated(): boolean;
|
|
3685
|
-
/**
|
|
3686
|
-
* Registers a callback to be called when authentication state changes.
|
|
3687
3980
|
*
|
|
3688
|
-
* @
|
|
3981
|
+
* @see {@link getConnectionState} to get the last known state without checking
|
|
3982
|
+
* @see {@link ConnectionManager.checkNow} for the underlying implementation
|
|
3689
3983
|
*/
|
|
3690
|
-
|
|
3984
|
+
checkConnection(): Promise<ConnectionState | 'unknown'>;
|
|
3691
3985
|
/**
|
|
3692
3986
|
* Sets the authentication context for the client.
|
|
3693
3987
|
* This is called during initialization to store environment info.
|
|
@@ -3750,6 +4044,11 @@ declare class PlaycademyClient {
|
|
|
3750
4044
|
* Safe to call in any environment - isInIframe handles browser detection.
|
|
3751
4045
|
*/
|
|
3752
4046
|
private _detectAuthContext;
|
|
4047
|
+
/**
|
|
4048
|
+
* Initializes connection monitoring if enabled.
|
|
4049
|
+
* Safe to call in any environment - only runs in browser.
|
|
4050
|
+
*/
|
|
4051
|
+
private _initializeConnectionMonitor;
|
|
3753
4052
|
/**
|
|
3754
4053
|
* Initializes an internal game session for automatic session management.
|
|
3755
4054
|
* Only starts a session if:
|
|
@@ -3873,15 +4172,17 @@ declare class PlaycademyClient {
|
|
|
3873
4172
|
get: () => Promise<DeveloperStatusValue>;
|
|
3874
4173
|
};
|
|
3875
4174
|
games: {
|
|
3876
|
-
deploy: {
|
|
3877
|
-
|
|
3878
|
-
|
|
3879
|
-
|
|
3880
|
-
|
|
3881
|
-
|
|
3882
|
-
|
|
3883
|
-
|
|
3884
|
-
|
|
4175
|
+
deploy: (slug: string, options: {
|
|
4176
|
+
metadata?: UpsertGameMetadataInput;
|
|
4177
|
+
file?: File | Blob | null;
|
|
4178
|
+
backend?: BackendDeploymentBundle;
|
|
4179
|
+
hooks?: DevUploadHooks;
|
|
4180
|
+
}) => Promise<Game>;
|
|
4181
|
+
seed: (slug: string, code: string, environment?: "staging" | "production") => Promise<{
|
|
4182
|
+
success: boolean;
|
|
4183
|
+
deploymentId: string;
|
|
4184
|
+
executedAt: string;
|
|
4185
|
+
}>;
|
|
3885
4186
|
upsert: (slug: string, metadata: UpsertGameMetadataInput) => Promise<Game>;
|
|
3886
4187
|
delete: (gameId: string) => Promise<void>;
|
|
3887
4188
|
secrets: {
|
|
@@ -3907,6 +4208,12 @@ declare class PlaycademyClient {
|
|
|
3907
4208
|
put: (slug: string, key: string, content: Blob | ArrayBuffer | Uint8Array, contentType?: string) => Promise<void>;
|
|
3908
4209
|
delete: (slug: string, key: string) => Promise<void>;
|
|
3909
4210
|
};
|
|
4211
|
+
domains: {
|
|
4212
|
+
add: (slug: string, hostname: string) => Promise<GameCustomHostname>;
|
|
4213
|
+
list: (slug: string) => Promise<GameCustomHostname[]>;
|
|
4214
|
+
status: (slug: string, hostname: string, refresh?: boolean) => Promise<GameCustomHostname>;
|
|
4215
|
+
delete: (slug: string, hostname: string) => Promise<void>;
|
|
4216
|
+
};
|
|
3910
4217
|
};
|
|
3911
4218
|
items: {
|
|
3912
4219
|
create: (gameId: string, slug: string, itemData: Omit<InsertItemInput, "slug" | "gameId">) => Promise<Item>;
|
|
@@ -3943,50 +4250,50 @@ declare class PlaycademyClient {
|
|
|
3943
4250
|
};
|
|
3944
4251
|
items: {
|
|
3945
4252
|
create: (props: InsertItemInput) => Promise<{
|
|
3946
|
-
metadata: unknown;
|
|
3947
|
-
type: "accessory" | "currency" | "badge" | "trophy" | "collectible" | "consumable" | "unlock" | "upgrade" | "other";
|
|
3948
|
-
slug: string;
|
|
3949
4253
|
id: string;
|
|
3950
4254
|
createdAt: Date;
|
|
3951
4255
|
gameId: string | null;
|
|
4256
|
+
slug: string;
|
|
3952
4257
|
displayName: string;
|
|
4258
|
+
metadata: unknown;
|
|
3953
4259
|
description: string | null;
|
|
4260
|
+
type: "accessory" | "currency" | "badge" | "trophy" | "collectible" | "consumable" | "unlock" | "upgrade" | "other";
|
|
3954
4261
|
isPlaceable: boolean;
|
|
3955
4262
|
imageUrl: string | null;
|
|
3956
4263
|
}>;
|
|
3957
4264
|
get: (itemId: string) => Promise<{
|
|
3958
|
-
metadata: unknown;
|
|
3959
|
-
type: "accessory" | "currency" | "badge" | "trophy" | "collectible" | "consumable" | "unlock" | "upgrade" | "other";
|
|
3960
|
-
slug: string;
|
|
3961
4265
|
id: string;
|
|
3962
4266
|
createdAt: Date;
|
|
3963
4267
|
gameId: string | null;
|
|
4268
|
+
slug: string;
|
|
3964
4269
|
displayName: string;
|
|
4270
|
+
metadata: unknown;
|
|
3965
4271
|
description: string | null;
|
|
4272
|
+
type: "accessory" | "currency" | "badge" | "trophy" | "collectible" | "consumable" | "unlock" | "upgrade" | "other";
|
|
3966
4273
|
isPlaceable: boolean;
|
|
3967
4274
|
imageUrl: string | null;
|
|
3968
4275
|
}>;
|
|
3969
4276
|
list: () => Promise<{
|
|
3970
|
-
metadata: unknown;
|
|
3971
|
-
type: "accessory" | "currency" | "badge" | "trophy" | "collectible" | "consumable" | "unlock" | "upgrade" | "other";
|
|
3972
|
-
slug: string;
|
|
3973
4277
|
id: string;
|
|
3974
4278
|
createdAt: Date;
|
|
3975
4279
|
gameId: string | null;
|
|
4280
|
+
slug: string;
|
|
3976
4281
|
displayName: string;
|
|
4282
|
+
metadata: unknown;
|
|
3977
4283
|
description: string | null;
|
|
4284
|
+
type: "accessory" | "currency" | "badge" | "trophy" | "collectible" | "consumable" | "unlock" | "upgrade" | "other";
|
|
3978
4285
|
isPlaceable: boolean;
|
|
3979
4286
|
imageUrl: string | null;
|
|
3980
4287
|
}[]>;
|
|
3981
4288
|
update: (itemId: string, props: UpdateItemInput) => Promise<{
|
|
3982
|
-
metadata: unknown;
|
|
3983
|
-
type: "accessory" | "currency" | "badge" | "trophy" | "collectible" | "consumable" | "unlock" | "upgrade" | "other";
|
|
3984
|
-
slug: string;
|
|
3985
4289
|
id: string;
|
|
3986
4290
|
createdAt: Date;
|
|
3987
4291
|
gameId: string | null;
|
|
4292
|
+
slug: string;
|
|
3988
4293
|
displayName: string;
|
|
4294
|
+
metadata: unknown;
|
|
3989
4295
|
description: string | null;
|
|
4296
|
+
type: "accessory" | "currency" | "badge" | "trophy" | "collectible" | "consumable" | "unlock" | "upgrade" | "other";
|
|
3990
4297
|
isPlaceable: boolean;
|
|
3991
4298
|
imageUrl: string | null;
|
|
3992
4299
|
}>;
|
|
@@ -4121,9 +4428,7 @@ declare class PlaycademyClient {
|
|
|
4121
4428
|
}) => Promise<TodayXpResponse>;
|
|
4122
4429
|
total: () => Promise<TotalXpResponse>;
|
|
4123
4430
|
history: (options?: {
|
|
4124
|
-
startDate
|
|
4125
|
-
/** Auto-initializes a PlaycademyClient with context from the environment */
|
|
4126
|
-
?: string;
|
|
4431
|
+
startDate?: string;
|
|
4127
4432
|
endDate?: string;
|
|
4128
4433
|
}) => Promise<XpHistoryResponse>;
|
|
4129
4434
|
summary: (options?: {
|
|
@@ -4154,86 +4459,517 @@ declare class PlaycademyClient {
|
|
|
4154
4459
|
limit?: number;
|
|
4155
4460
|
}) => Promise<UserScore$1[]>;
|
|
4156
4461
|
};
|
|
4157
|
-
/** Character methods (get, create, update, components) */
|
|
4158
|
-
character: {
|
|
4159
|
-
get: (userId?: string) => Promise<PlayerCharacter | null>;
|
|
4160
|
-
create: (characterData: CreateCharacterData) => Promise<PlayerCharacter>;
|
|
4161
|
-
update: (updates: UpdateCharacterData) => Promise<PlayerCharacter>;
|
|
4162
|
-
components: {
|
|
4163
|
-
list: (options?: CharacterComponentsOptions & TTLCacheConfig) => Promise<CharacterComponentWithSpriteUrl[]>;
|
|
4164
|
-
clearCache: (key?: string) => void;
|
|
4165
|
-
getCacheKeys: () => string[];
|
|
4166
|
-
};
|
|
4167
|
-
accessories: {
|
|
4168
|
-
equip: (slot: string, componentId: string) => Promise<PlayerCharacterAccessory>;
|
|
4169
|
-
remove: (slot: string) => Promise<{
|
|
4170
|
-
success: boolean;
|
|
4171
|
-
}>;
|
|
4172
|
-
list: () => Promise<PlayerCharacterAccessory[]>;
|
|
4173
|
-
};
|
|
4462
|
+
/** Character methods (get, create, update, components) */
|
|
4463
|
+
character: {
|
|
4464
|
+
get: (userId?: string) => Promise<PlayerCharacter | null>;
|
|
4465
|
+
create: (characterData: CreateCharacterData) => Promise<PlayerCharacter>;
|
|
4466
|
+
update: (updates: UpdateCharacterData) => Promise<PlayerCharacter>;
|
|
4467
|
+
components: {
|
|
4468
|
+
list: (options?: CharacterComponentsOptions & TTLCacheConfig) => Promise<CharacterComponentWithSpriteUrl[]>;
|
|
4469
|
+
clearCache: (key?: string) => void;
|
|
4470
|
+
getCacheKeys: () => string[];
|
|
4471
|
+
};
|
|
4472
|
+
accessories: {
|
|
4473
|
+
equip: (slot: string, componentId: string) => Promise<PlayerCharacterAccessory>;
|
|
4474
|
+
remove: (slot: string) => Promise<{
|
|
4475
|
+
success: boolean;
|
|
4476
|
+
}>;
|
|
4477
|
+
list: () => Promise<PlayerCharacterAccessory[]>;
|
|
4478
|
+
};
|
|
4479
|
+
};
|
|
4480
|
+
/** Sprites methods (templates) */
|
|
4481
|
+
sprites: {
|
|
4482
|
+
templates: {
|
|
4483
|
+
get: (slug: string) => Promise<SpriteTemplateData>;
|
|
4484
|
+
};
|
|
4485
|
+
};
|
|
4486
|
+
/** Realtime methods (token) */
|
|
4487
|
+
realtime: {
|
|
4488
|
+
token: {
|
|
4489
|
+
get: () => Promise<RealtimeTokenResponse>;
|
|
4490
|
+
};
|
|
4491
|
+
open(channel?: string, url?: string): Promise<_playcademy_realtime_server_types.RealtimeChannel>;
|
|
4492
|
+
};
|
|
4493
|
+
/** Achievements methods (list, history, progress) */
|
|
4494
|
+
achievements: {
|
|
4495
|
+
list: (options?: TTLCacheConfig) => Promise<AchievementCurrent[]>;
|
|
4496
|
+
history: {
|
|
4497
|
+
list: (queryOptions?: {
|
|
4498
|
+
limit?: number;
|
|
4499
|
+
}, cacheOptions?: TTLCacheConfig) => Promise<AchievementHistoryEntry[]>;
|
|
4500
|
+
};
|
|
4501
|
+
progress: {
|
|
4502
|
+
submit: (achievementId: string) => Promise<AchievementProgressResponse>;
|
|
4503
|
+
};
|
|
4504
|
+
};
|
|
4505
|
+
/** Notifications methods (list, update status, stats) */
|
|
4506
|
+
notifications: {
|
|
4507
|
+
list: (queryOptions?: {
|
|
4508
|
+
status?: NotificationStatus;
|
|
4509
|
+
type?: NotificationType;
|
|
4510
|
+
limit?: number;
|
|
4511
|
+
offset?: number;
|
|
4512
|
+
}, cacheOptions?: TTLCacheConfig) => Promise<Notification[]>;
|
|
4513
|
+
markAsSeen: (notificationId: string) => Promise<Notification>;
|
|
4514
|
+
markAsClicked: (notificationId: string) => Promise<Notification>;
|
|
4515
|
+
dismiss: (notificationId: string) => Promise<Notification>;
|
|
4516
|
+
stats: {
|
|
4517
|
+
get: (queryOptions?: {
|
|
4518
|
+
from?: string;
|
|
4519
|
+
to?: string;
|
|
4520
|
+
}, cacheOptions?: TTLCacheConfig) => Promise<NotificationStats>;
|
|
4521
|
+
};
|
|
4522
|
+
};
|
|
4523
|
+
/** Backend methods for calling custom game API routes */
|
|
4524
|
+
backend: {
|
|
4525
|
+
get<T = unknown>(path: string, headers?: Record<string, string>): Promise<T>;
|
|
4526
|
+
post<T = unknown>(path: string, body?: unknown, headers?: Record<string, string>): Promise<T>;
|
|
4527
|
+
put<T = unknown>(path: string, body?: unknown, headers?: Record<string, string>): Promise<T>;
|
|
4528
|
+
patch<T = unknown>(path: string, body?: unknown, headers?: Record<string, string>): Promise<T>;
|
|
4529
|
+
delete<T = unknown>(path: string, headers?: Record<string, string>): Promise<T>;
|
|
4530
|
+
request<T = unknown>(path: string, method: Method, body?: unknown, headers?: Record<string, string>): Promise<T>;
|
|
4531
|
+
download(path: string, method?: Method, body?: unknown, headers?: Record<string, string>): Promise<Response>;
|
|
4532
|
+
url(pathOrStrings: string | TemplateStringsArray, ...values: unknown[]): string;
|
|
4533
|
+
};
|
|
4534
|
+
/** Auto-initializes a PlaycademyClient with context from the environment */
|
|
4535
|
+
static init: typeof init;
|
|
4536
|
+
/** Authenticates a user with email and password */
|
|
4537
|
+
static login: typeof login;
|
|
4538
|
+
/** Static identity utilities for OAuth operations */
|
|
4539
|
+
static identity: {
|
|
4540
|
+
parseOAuthState: typeof parseOAuthState;
|
|
4541
|
+
};
|
|
4542
|
+
}
|
|
4543
|
+
|
|
4544
|
+
type TokenType = 'session' | 'apiKey' | 'gameJwt';
|
|
4545
|
+
interface ClientConfig {
|
|
4546
|
+
baseUrl: string;
|
|
4547
|
+
gameUrl?: string;
|
|
4548
|
+
token?: string;
|
|
4549
|
+
tokenType?: TokenType;
|
|
4550
|
+
gameId?: string;
|
|
4551
|
+
autoStartSession?: boolean;
|
|
4552
|
+
onDisconnect?: DisconnectHandler;
|
|
4553
|
+
enableConnectionMonitoring?: boolean;
|
|
4554
|
+
}
|
|
4555
|
+
/**
|
|
4556
|
+
* Handler called when connection state changes to offline or degraded.
|
|
4557
|
+
* Games can implement this to handle disconnects gracefully.
|
|
4558
|
+
*/
|
|
4559
|
+
type DisconnectHandler = (context: DisconnectContext) => void | Promise<void>;
|
|
4560
|
+
/**
|
|
4561
|
+
* Context provided to disconnect handlers
|
|
4562
|
+
*/
|
|
4563
|
+
interface DisconnectContext {
|
|
4564
|
+
/** Current connection state */
|
|
4565
|
+
state: 'offline' | 'degraded';
|
|
4566
|
+
/** Reason for the disconnect */
|
|
4567
|
+
reason: string;
|
|
4568
|
+
/** Timestamp when disconnect was detected */
|
|
4569
|
+
timestamp: number;
|
|
4570
|
+
/** Utility to display a platform-level alert */
|
|
4571
|
+
displayAlert: (message: string, options?: {
|
|
4572
|
+
type?: 'info' | 'warning' | 'error';
|
|
4573
|
+
duration?: number;
|
|
4574
|
+
}) => void;
|
|
4575
|
+
}
|
|
4576
|
+
type AuthProviderType = (typeof AUTH_PROVIDER_IDS)[keyof typeof AUTH_PROVIDER_IDS];
|
|
4577
|
+
interface AuthOptions {
|
|
4578
|
+
/** The identity provider to use for authentication */
|
|
4579
|
+
provider: AuthProviderType;
|
|
4580
|
+
/** The OAuth callback URL where your server handles the callback */
|
|
4581
|
+
callbackUrl: string;
|
|
4582
|
+
/** Authentication mode - auto detects best option based on context */
|
|
4583
|
+
mode?: 'auto' | 'popup' | 'redirect';
|
|
4584
|
+
/** Callback for authentication state changes */
|
|
4585
|
+
onStateChange?: (state: AuthStateUpdate) => void;
|
|
4586
|
+
/** Custom OAuth configuration (for users embedding the SDK outside of the Playcademy platform) */
|
|
4587
|
+
oauth?: {
|
|
4588
|
+
clientId: string;
|
|
4589
|
+
authorizationEndpoint?: string;
|
|
4590
|
+
tokenEndpoint?: string;
|
|
4591
|
+
scope?: string;
|
|
4592
|
+
};
|
|
4593
|
+
/**
|
|
4594
|
+
* Optional custom data to encode in OAuth state parameter.
|
|
4595
|
+
* By default, the SDK automatically includes playcademy_user_id and game_id.
|
|
4596
|
+
* Use this to add additional custom data if needed.
|
|
4597
|
+
*/
|
|
4598
|
+
stateData?: Record<string, string>;
|
|
4599
|
+
}
|
|
4600
|
+
interface AuthStateUpdate {
|
|
4601
|
+
/** Current status of the authentication flow */
|
|
4602
|
+
status: 'opening_popup' | 'exchanging_token' | 'complete' | 'error';
|
|
4603
|
+
/** Human-readable message about the current state */
|
|
4604
|
+
message: string;
|
|
4605
|
+
/** Error details if status is 'error' */
|
|
4606
|
+
error?: Error;
|
|
4607
|
+
}
|
|
4608
|
+
interface AuthResult {
|
|
4609
|
+
/** Whether authentication was successful */
|
|
4610
|
+
success: boolean;
|
|
4611
|
+
/** User information if authentication was successful */
|
|
4612
|
+
user?: UserInfo;
|
|
4613
|
+
/** Error if authentication failed */
|
|
4614
|
+
error?: Error;
|
|
4615
|
+
}
|
|
4616
|
+
/**
|
|
4617
|
+
* Authentication state change event payload.
|
|
4618
|
+
* Used when authentication state changes in the application.
|
|
4619
|
+
*/
|
|
4620
|
+
interface AuthStateChangePayload {
|
|
4621
|
+
/** Whether the user is currently authenticated */
|
|
4622
|
+
authenticated: boolean;
|
|
4623
|
+
/** User information if authenticated, null otherwise */
|
|
4624
|
+
user: UserInfo | null;
|
|
4625
|
+
/** Error information if authentication failed */
|
|
4626
|
+
error: Error | null;
|
|
4627
|
+
}
|
|
4628
|
+
/**
|
|
4629
|
+
* OAuth callback event payload.
|
|
4630
|
+
* Used when OAuth flow completes in popup/new-tab windows.
|
|
4631
|
+
*/
|
|
4632
|
+
interface AuthCallbackPayload {
|
|
4633
|
+
/** OAuth authorization code */
|
|
4634
|
+
code: string;
|
|
4635
|
+
/** OAuth state parameter for CSRF protection */
|
|
4636
|
+
state: string;
|
|
4637
|
+
/** Error message if OAuth flow failed */
|
|
4638
|
+
error: string | null;
|
|
4639
|
+
}
|
|
4640
|
+
/**
|
|
4641
|
+
* Token refresh event payload.
|
|
4642
|
+
* Sent when authentication token is updated.
|
|
4643
|
+
*/
|
|
4644
|
+
interface TokenRefreshPayload {
|
|
4645
|
+
/** New authentication token */
|
|
4646
|
+
token: string;
|
|
4647
|
+
/** Token expiration timestamp */
|
|
4648
|
+
exp: number;
|
|
4649
|
+
}
|
|
4650
|
+
/**
|
|
4651
|
+
* Telemetry event payload.
|
|
4652
|
+
* Performance metrics sent from the game.
|
|
4653
|
+
*/
|
|
4654
|
+
interface TelemetryPayload {
|
|
4655
|
+
/** Frames per second */
|
|
4656
|
+
fps: number;
|
|
4657
|
+
/** Memory usage in MB */
|
|
4658
|
+
mem: number;
|
|
4659
|
+
}
|
|
4660
|
+
/**
|
|
4661
|
+
* Keyboard event payload.
|
|
4662
|
+
* Key events forwarded from the game.
|
|
4663
|
+
*/
|
|
4664
|
+
interface KeyEventPayload {
|
|
4665
|
+
/** Key value (e.g., 'Escape', 'F1') */
|
|
4666
|
+
key: string;
|
|
4667
|
+
/** Key code (optional) */
|
|
4668
|
+
code?: string;
|
|
4669
|
+
/** Event type */
|
|
4670
|
+
type: 'keydown' | 'keyup';
|
|
4671
|
+
}
|
|
4672
|
+
interface DisplayAlertPayload {
|
|
4673
|
+
message: string;
|
|
4674
|
+
options?: {
|
|
4675
|
+
type?: 'info' | 'warning' | 'error';
|
|
4676
|
+
duration?: number;
|
|
4677
|
+
};
|
|
4678
|
+
}
|
|
4679
|
+
/**
|
|
4680
|
+
* Display alert payload.
|
|
4681
|
+
* Request from game to show platform-level alert.
|
|
4682
|
+
*/
|
|
4683
|
+
interface DisplayAlertPayload {
|
|
4684
|
+
message: string;
|
|
4685
|
+
options?: {
|
|
4686
|
+
type?: 'info' | 'warning' | 'error';
|
|
4687
|
+
duration?: number;
|
|
4174
4688
|
};
|
|
4175
|
-
|
|
4176
|
-
|
|
4177
|
-
|
|
4178
|
-
|
|
4179
|
-
|
|
4689
|
+
}
|
|
4690
|
+
/**
|
|
4691
|
+
* Connection state payload.
|
|
4692
|
+
* Broadcast from platform to games when connection changes.
|
|
4693
|
+
*/
|
|
4694
|
+
interface ConnectionStatePayload {
|
|
4695
|
+
state: 'online' | 'offline' | 'degraded';
|
|
4696
|
+
reason: string;
|
|
4697
|
+
}
|
|
4698
|
+
interface ClientEvents {
|
|
4699
|
+
authChange: {
|
|
4700
|
+
token: string | null;
|
|
4180
4701
|
};
|
|
4181
|
-
|
|
4182
|
-
|
|
4183
|
-
|
|
4184
|
-
|
|
4185
|
-
};
|
|
4186
|
-
open(channel?: string, url?: string): Promise<_playcademy_realtime_server_types.RealtimeChannel>;
|
|
4702
|
+
inventoryChange: {
|
|
4703
|
+
itemId: string;
|
|
4704
|
+
delta: number;
|
|
4705
|
+
newTotal: number;
|
|
4187
4706
|
};
|
|
4188
|
-
|
|
4189
|
-
|
|
4190
|
-
|
|
4191
|
-
|
|
4192
|
-
list: (queryOptions?: {
|
|
4193
|
-
limit?: number;
|
|
4194
|
-
}, cacheOptions?: TTLCacheConfig) => Promise<AchievementHistoryEntry[]>;
|
|
4195
|
-
};
|
|
4196
|
-
progress: {
|
|
4197
|
-
submit: (achievementId: string) => Promise<AchievementProgressResponse>;
|
|
4198
|
-
};
|
|
4707
|
+
levelUp: {
|
|
4708
|
+
oldLevel: number;
|
|
4709
|
+
newLevel: number;
|
|
4710
|
+
creditsAwarded: number;
|
|
4199
4711
|
};
|
|
4200
|
-
|
|
4201
|
-
|
|
4202
|
-
|
|
4203
|
-
|
|
4204
|
-
type?: NotificationType;
|
|
4205
|
-
limit?: number;
|
|
4206
|
-
offset?: number;
|
|
4207
|
-
}, cacheOptions?: TTLCacheConfig) => Promise<Notification[]>;
|
|
4208
|
-
markAsSeen: (notificationId: string) => Promise<Notification>;
|
|
4209
|
-
markAsClicked: (notificationId: string) => Promise<Notification>;
|
|
4210
|
-
dismiss: (notificationId: string) => Promise<Notification>;
|
|
4211
|
-
stats: {
|
|
4212
|
-
get: (queryOptions?: {
|
|
4213
|
-
from?: string;
|
|
4214
|
-
to?: string;
|
|
4215
|
-
}, cacheOptions?: TTLCacheConfig) => Promise<NotificationStats>;
|
|
4216
|
-
};
|
|
4712
|
+
xpGained: {
|
|
4713
|
+
amount: number;
|
|
4714
|
+
totalXP: number;
|
|
4715
|
+
leveledUp: boolean;
|
|
4217
4716
|
};
|
|
4218
|
-
|
|
4219
|
-
|
|
4220
|
-
|
|
4221
|
-
post<T = unknown>(path: string, body?: unknown, headers?: Record<string, string>): Promise<T>;
|
|
4222
|
-
put<T = unknown>(path: string, body?: unknown, headers?: Record<string, string>): Promise<T>;
|
|
4223
|
-
patch<T = unknown>(path: string, body?: unknown, headers?: Record<string, string>): Promise<T>;
|
|
4224
|
-
delete<T = unknown>(path: string, headers?: Record<string, string>): Promise<T>;
|
|
4225
|
-
request<T = unknown>(path: string, method: Method, body?: unknown, headers?: Record<string, string>): Promise<T>;
|
|
4226
|
-
download(path: string, method?: Method, body?: unknown, headers?: Record<string, string>): Promise<Response>;
|
|
4227
|
-
url(pathOrStrings: string | TemplateStringsArray, ...values: unknown[]): string;
|
|
4717
|
+
connectionChange: {
|
|
4718
|
+
state: 'online' | 'offline' | 'degraded';
|
|
4719
|
+
reason: string;
|
|
4228
4720
|
};
|
|
4229
|
-
|
|
4230
|
-
|
|
4231
|
-
|
|
4232
|
-
|
|
4233
|
-
|
|
4234
|
-
|
|
4235
|
-
|
|
4721
|
+
}
|
|
4722
|
+
type GameContextPayload = {
|
|
4723
|
+
token: string;
|
|
4724
|
+
baseUrl: string;
|
|
4725
|
+
realtimeUrl: string;
|
|
4726
|
+
gameId: string;
|
|
4727
|
+
forwardKeys?: string[];
|
|
4728
|
+
};
|
|
4729
|
+
type LoginResponse = {
|
|
4730
|
+
token: string;
|
|
4731
|
+
};
|
|
4732
|
+
type GameTokenResponse = {
|
|
4733
|
+
token: string;
|
|
4734
|
+
exp: number;
|
|
4735
|
+
};
|
|
4736
|
+
type StartSessionResponse = {
|
|
4737
|
+
sessionId: string;
|
|
4738
|
+
};
|
|
4739
|
+
type InventoryMutationResponse = {
|
|
4740
|
+
newTotal: number;
|
|
4741
|
+
};
|
|
4742
|
+
type DevUploadEvent = {
|
|
4743
|
+
type: 'init';
|
|
4744
|
+
} | {
|
|
4745
|
+
type: 's3Progress';
|
|
4746
|
+
loaded: number;
|
|
4747
|
+
total: number;
|
|
4748
|
+
percent: number;
|
|
4749
|
+
} | {
|
|
4750
|
+
type: 'finalizeStart';
|
|
4751
|
+
} | {
|
|
4752
|
+
type: 'finalizeProgress';
|
|
4753
|
+
percent: number;
|
|
4754
|
+
currentFileLabel?: string;
|
|
4755
|
+
} | {
|
|
4756
|
+
type: 'finalizeStatus';
|
|
4757
|
+
message: string;
|
|
4758
|
+
} | {
|
|
4759
|
+
type: 'close';
|
|
4760
|
+
};
|
|
4761
|
+
type DevUploadHooks = {
|
|
4762
|
+
onEvent?: (e: DevUploadEvent) => void;
|
|
4763
|
+
onClose?: () => void;
|
|
4764
|
+
};
|
|
4765
|
+
/**
|
|
4766
|
+
* Better-auth API key creation response
|
|
4767
|
+
*/
|
|
4768
|
+
interface BetterAuthApiKeyResponse {
|
|
4769
|
+
apiKey: string;
|
|
4770
|
+
key: {
|
|
4771
|
+
id: string;
|
|
4772
|
+
name: string | null;
|
|
4773
|
+
expiresAt: string | null;
|
|
4774
|
+
createdAt: string;
|
|
4775
|
+
};
|
|
4776
|
+
}
|
|
4777
|
+
/**
|
|
4778
|
+
* Better-auth API key list item
|
|
4779
|
+
*/
|
|
4780
|
+
interface BetterAuthApiKey {
|
|
4781
|
+
id: string;
|
|
4782
|
+
name: string | null;
|
|
4783
|
+
start: string;
|
|
4784
|
+
enabled: boolean;
|
|
4785
|
+
expiresAt: string | null;
|
|
4786
|
+
createdAt: string;
|
|
4787
|
+
updatedAt: string;
|
|
4788
|
+
lastRequest: string | null;
|
|
4789
|
+
requestCount: number;
|
|
4790
|
+
}
|
|
4791
|
+
/**
|
|
4792
|
+
* Bucket file metadata
|
|
4793
|
+
*/
|
|
4794
|
+
interface BucketFile {
|
|
4795
|
+
key: string;
|
|
4796
|
+
size: number;
|
|
4797
|
+
uploaded: string;
|
|
4798
|
+
contentType?: string;
|
|
4799
|
+
}
|
|
4800
|
+
|
|
4801
|
+
/**
|
|
4802
|
+
* Connection Manager
|
|
4803
|
+
*
|
|
4804
|
+
* Manages connection monitoring and integrates it with the Playcademy client.
|
|
4805
|
+
* Handles event wiring, state management, and disconnect callbacks.
|
|
4806
|
+
*
|
|
4807
|
+
* In iframe mode, disables local monitoring and listens to platform connection
|
|
4808
|
+
* state broadcasts instead (avoids duplicate heartbeats).
|
|
4809
|
+
*/
|
|
4810
|
+
|
|
4811
|
+
/**
|
|
4812
|
+
* Configuration for the ConnectionManager.
|
|
4813
|
+
*/
|
|
4814
|
+
interface ConnectionManagerConfig {
|
|
4815
|
+
/** Base URL for API requests (used for heartbeat pings) */
|
|
4816
|
+
baseUrl: string;
|
|
4817
|
+
/** Authentication context (iframe vs standalone) for alert routing */
|
|
4818
|
+
authContext?: {
|
|
4819
|
+
isInIframe: boolean;
|
|
4236
4820
|
};
|
|
4821
|
+
/** Handler to call when connection issues are detected */
|
|
4822
|
+
onDisconnect?: DisconnectHandler;
|
|
4823
|
+
/** Callback to emit connection change events to the client */
|
|
4824
|
+
onConnectionChange?: (state: ConnectionState, reason: string) => void;
|
|
4825
|
+
}
|
|
4826
|
+
/**
|
|
4827
|
+
* Manages connection monitoring for the Playcademy client.
|
|
4828
|
+
*
|
|
4829
|
+
* The ConnectionManager serves as an integration layer between the low-level
|
|
4830
|
+
* ConnectionMonitor and the PlaycademyClient. It handles:
|
|
4831
|
+
* - Event wiring and coordination
|
|
4832
|
+
* - Disconnect callbacks with context
|
|
4833
|
+
* - Platform-level alert integration
|
|
4834
|
+
* - Request success/failure tracking
|
|
4835
|
+
*
|
|
4836
|
+
* This class is used internally by PlaycademyClient and typically not
|
|
4837
|
+
* instantiated directly by game developers.
|
|
4838
|
+
*
|
|
4839
|
+
* @see {@link ConnectionMonitor} for the underlying monitoring implementation
|
|
4840
|
+
* @see {@link PlaycademyClient.onDisconnect} for the public API
|
|
4841
|
+
*/
|
|
4842
|
+
declare class ConnectionManager {
|
|
4843
|
+
private monitor?;
|
|
4844
|
+
private authContext?;
|
|
4845
|
+
private disconnectHandler?;
|
|
4846
|
+
private connectionChangeCallback?;
|
|
4847
|
+
private currentState;
|
|
4848
|
+
private additionalDisconnectHandlers;
|
|
4849
|
+
/**
|
|
4850
|
+
* Creates a new ConnectionManager instance.
|
|
4851
|
+
*
|
|
4852
|
+
* @param config - Configuration options for the manager
|
|
4853
|
+
*
|
|
4854
|
+
* @example
|
|
4855
|
+
* ```typescript
|
|
4856
|
+
* const manager = new ConnectionManager({
|
|
4857
|
+
* baseUrl: 'https://api.playcademy.com',
|
|
4858
|
+
* authContext: { isInIframe: false },
|
|
4859
|
+
* onDisconnect: (context) => {
|
|
4860
|
+
* console.log(`Disconnected: ${context.state}`)
|
|
4861
|
+
* },
|
|
4862
|
+
* onConnectionChange: (state, reason) => {
|
|
4863
|
+
* console.log(`Connection changed: ${state}`)
|
|
4864
|
+
* }
|
|
4865
|
+
* })
|
|
4866
|
+
* ```
|
|
4867
|
+
*/
|
|
4868
|
+
constructor(config: ConnectionManagerConfig);
|
|
4869
|
+
/**
|
|
4870
|
+
* Gets the current connection state.
|
|
4871
|
+
*
|
|
4872
|
+
* @returns The current connection state ('online', 'offline', or 'degraded')
|
|
4873
|
+
*
|
|
4874
|
+
* @example
|
|
4875
|
+
* ```typescript
|
|
4876
|
+
* const state = manager.getState()
|
|
4877
|
+
* if (state === 'offline') {
|
|
4878
|
+
* console.log('No connection')
|
|
4879
|
+
* }
|
|
4880
|
+
* ```
|
|
4881
|
+
*/
|
|
4882
|
+
getState(): ConnectionState;
|
|
4883
|
+
/**
|
|
4884
|
+
* Manually triggers a connection check immediately.
|
|
4885
|
+
*
|
|
4886
|
+
* Forces a heartbeat ping to verify the current connection status.
|
|
4887
|
+
* Useful when you need to check connectivity before a critical operation.
|
|
4888
|
+
*
|
|
4889
|
+
* In iframe mode, this returns the last known state from platform.
|
|
4890
|
+
*
|
|
4891
|
+
* @returns Promise resolving to the current connection state
|
|
4892
|
+
*
|
|
4893
|
+
* @example
|
|
4894
|
+
* ```typescript
|
|
4895
|
+
* const state = await manager.checkNow()
|
|
4896
|
+
* if (state === 'online') {
|
|
4897
|
+
* await performCriticalOperation()
|
|
4898
|
+
* }
|
|
4899
|
+
* ```
|
|
4900
|
+
*/
|
|
4901
|
+
checkNow(): Promise<ConnectionState>;
|
|
4902
|
+
/**
|
|
4903
|
+
* Reports a successful API request to the connection monitor.
|
|
4904
|
+
*
|
|
4905
|
+
* This resets the consecutive failure counter and transitions from
|
|
4906
|
+
* 'degraded' to 'online' state if applicable.
|
|
4907
|
+
*
|
|
4908
|
+
* Typically called automatically by the SDK's request wrapper.
|
|
4909
|
+
* No-op in iframe mode (platform handles monitoring).
|
|
4910
|
+
*/
|
|
4911
|
+
reportRequestSuccess(): void;
|
|
4912
|
+
/**
|
|
4913
|
+
* Reports a failed API request to the connection monitor.
|
|
4914
|
+
*
|
|
4915
|
+
* Only network errors are tracked (not 4xx/5xx HTTP responses).
|
|
4916
|
+
* After consecutive failures exceed the threshold, the state transitions
|
|
4917
|
+
* to 'degraded' or 'offline'.
|
|
4918
|
+
*
|
|
4919
|
+
* Typically called automatically by the SDK's request wrapper.
|
|
4920
|
+
* No-op in iframe mode (platform handles monitoring).
|
|
4921
|
+
*
|
|
4922
|
+
* @param error - The error from the failed request
|
|
4923
|
+
*/
|
|
4924
|
+
reportRequestFailure(error: unknown): void;
|
|
4925
|
+
/**
|
|
4926
|
+
* Registers a callback to be called when connection issues are detected.
|
|
4927
|
+
*
|
|
4928
|
+
* The callback only fires for 'offline' and 'degraded' states, not when
|
|
4929
|
+
* recovering to 'online'. This provides a clean API for games to handle
|
|
4930
|
+
* disconnect scenarios without being notified of every state change.
|
|
4931
|
+
*
|
|
4932
|
+
* Works in both iframe and standalone modes transparently.
|
|
4933
|
+
*
|
|
4934
|
+
* @param callback - Function to call when connection degrades
|
|
4935
|
+
* @returns Cleanup function to unregister the callback
|
|
4936
|
+
*
|
|
4937
|
+
* @example
|
|
4938
|
+
* ```typescript
|
|
4939
|
+
* const cleanup = manager.onDisconnect(({ state, reason, displayAlert }) => {
|
|
4940
|
+
* if (state === 'offline') {
|
|
4941
|
+
* displayAlert?.('Connection lost. Saving your progress...', { type: 'error' })
|
|
4942
|
+
* saveGameState()
|
|
4943
|
+
* }
|
|
4944
|
+
* })
|
|
4945
|
+
*
|
|
4946
|
+
* // Later: cleanup() to unregister
|
|
4947
|
+
* ```
|
|
4948
|
+
*/
|
|
4949
|
+
onDisconnect(callback: DisconnectHandler): () => void;
|
|
4950
|
+
/**
|
|
4951
|
+
* Stops connection monitoring and performs cleanup.
|
|
4952
|
+
*
|
|
4953
|
+
* Removes event listeners and clears heartbeat intervals.
|
|
4954
|
+
* Should be called when the client is being destroyed.
|
|
4955
|
+
*/
|
|
4956
|
+
stop(): void;
|
|
4957
|
+
/**
|
|
4958
|
+
* Sets up listener for platform connection state broadcasts (iframe mode only).
|
|
4959
|
+
*/
|
|
4960
|
+
private _setupPlatformListener;
|
|
4961
|
+
/**
|
|
4962
|
+
* Handles connection state changes from the monitor or platform.
|
|
4963
|
+
*
|
|
4964
|
+
* Coordinates between:
|
|
4965
|
+
* 1. Emitting events to the client (for client.on('connectionChange'))
|
|
4966
|
+
* 2. Calling the disconnect handler if configured
|
|
4967
|
+
* 3. Calling any additional handlers registered via onDisconnect()
|
|
4968
|
+
*
|
|
4969
|
+
* @param state - The new connection state
|
|
4970
|
+
* @param reason - Human-readable reason for the state change
|
|
4971
|
+
*/
|
|
4972
|
+
private _handleConnectionChange;
|
|
4237
4973
|
}
|
|
4238
4974
|
|
|
4239
4975
|
/**
|
|
@@ -4317,6 +5053,14 @@ declare enum MessageEvents {
|
|
|
4317
5053
|
* Payload: boolean (true = show overlay, false = hide overlay)
|
|
4318
5054
|
*/
|
|
4319
5055
|
OVERLAY = "PLAYCADEMY_OVERLAY",
|
|
5056
|
+
/**
|
|
5057
|
+
* Broadcasts connection state changes to games.
|
|
5058
|
+
* Sent by platform when network connectivity changes.
|
|
5059
|
+
* Payload:
|
|
5060
|
+
* - `state`: 'online' | 'offline' | 'degraded'
|
|
5061
|
+
* - `reason`: string
|
|
5062
|
+
*/
|
|
5063
|
+
CONNECTION_STATE = "PLAYCADEMY_CONNECTION_STATE",
|
|
4320
5064
|
/**
|
|
4321
5065
|
* Game has finished loading and is ready to receive messages.
|
|
4322
5066
|
* Sent once after game initialization is complete.
|
|
@@ -4346,6 +5090,14 @@ declare enum MessageEvents {
|
|
|
4346
5090
|
* - `type`: 'keydown' | 'keyup'
|
|
4347
5091
|
*/
|
|
4348
5092
|
KEY_EVENT = "PLAYCADEMY_KEY_EVENT",
|
|
5093
|
+
/**
|
|
5094
|
+
* Game requests platform to display an alert.
|
|
5095
|
+
* Sent when connection issues are detected or other important events occur.
|
|
5096
|
+
* Payload:
|
|
5097
|
+
* - `message`: string
|
|
5098
|
+
* - `options`: { type?: 'info' | 'warning' | 'error', duration?: number }
|
|
5099
|
+
*/
|
|
5100
|
+
DISPLAY_ALERT = "PLAYCADEMY_DISPLAY_ALERT",
|
|
4349
5101
|
/**
|
|
4350
5102
|
* Notifies about authentication state changes.
|
|
4351
5103
|
* Can be sent in both directions depending on auth flow.
|
|
@@ -4401,6 +5153,8 @@ type MessageEventMap = {
|
|
|
4401
5153
|
[MessageEvents.FORCE_EXIT]: void;
|
|
4402
5154
|
/** Overlay visibility state (true = show, false = hide) */
|
|
4403
5155
|
[MessageEvents.OVERLAY]: boolean;
|
|
5156
|
+
/** Connection state change from platform */
|
|
5157
|
+
[MessageEvents.CONNECTION_STATE]: ConnectionStatePayload;
|
|
4404
5158
|
/** Ready message has no payload data */
|
|
4405
5159
|
[MessageEvents.READY]: void;
|
|
4406
5160
|
/** Exit message has no payload data */
|
|
@@ -4409,6 +5163,8 @@ type MessageEventMap = {
|
|
|
4409
5163
|
[MessageEvents.TELEMETRY]: TelemetryPayload;
|
|
4410
5164
|
/** Key event data */
|
|
4411
5165
|
[MessageEvents.KEY_EVENT]: KeyEventPayload;
|
|
5166
|
+
/** Display alert request from game */
|
|
5167
|
+
[MessageEvents.DISPLAY_ALERT]: DisplayAlertPayload;
|
|
4412
5168
|
/** Authentication state change notification */
|
|
4413
5169
|
[MessageEvents.AUTH_STATE_CHANGE]: AuthStateChangePayload;
|
|
4414
5170
|
/** OAuth callback data from popup/new-tab windows */
|
|
@@ -4780,5 +5536,5 @@ declare class PlaycademyMessaging {
|
|
|
4780
5536
|
*/
|
|
4781
5537
|
declare const messaging: PlaycademyMessaging;
|
|
4782
5538
|
|
|
4783
|
-
export { MessageEvents, PlaycademyClient, messaging };
|
|
4784
|
-
export type { DevUploadEvent, DevUploadHooks };
|
|
5539
|
+
export { ApiError, ConnectionManager, ConnectionMonitor, MessageEvents, PlaycademyClient, PlaycademyError, extractApiErrorInfo, messaging };
|
|
5540
|
+
export type { ApiErrorInfo, ConnectionMonitorConfig, ConnectionState, ConnectionStatePayload, DevUploadEvent, DevUploadHooks, DisconnectContext, DisconnectHandler, DisplayAlertPayload };
|