@playcademy/sdk 0.9.1-beta.1 → 0.9.1-beta.2
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 +5 -2
- package/dist/index.d.ts +364 -359
- package/dist/index.js +12 -2
- package/dist/internal.d.ts +5506 -5454
- package/dist/internal.js +16 -3
- package/dist/types.d.ts +1182 -1177
- package/package.json +1 -1
package/dist/types.d.ts
CHANGED
|
@@ -26,101 +26,374 @@ interface RetryPolicy {
|
|
|
26
26
|
}
|
|
27
27
|
|
|
28
28
|
/**
|
|
29
|
-
*
|
|
29
|
+
* User Types
|
|
30
30
|
*
|
|
31
|
-
*
|
|
31
|
+
* Enums, DTOs and API response types. Database row types are in @playcademy/data/types.
|
|
32
32
|
*
|
|
33
|
-
* @module types/
|
|
34
|
-
*/
|
|
35
|
-
/**
|
|
36
|
-
* Valid TimeBack subject values for course configuration.
|
|
37
|
-
* These are the supported subject values for OneRoster courses.
|
|
38
|
-
*/
|
|
39
|
-
type TimebackSubject = 'Reading' | 'Language' | 'Vocabulary' | 'Social Studies' | 'Writing' | 'Science' | 'FastMath' | 'Math' | 'None';
|
|
40
|
-
/**
|
|
41
|
-
* Grade levels per AE OneRoster GradeEnum.
|
|
42
|
-
* -1 = Pre-K, 0 = Kindergarten, 1-12 = Grades 1-12, 13 = AP
|
|
33
|
+
* @module types/user
|
|
43
34
|
*/
|
|
44
|
-
|
|
35
|
+
|
|
36
|
+
type UserRoleEnumType = UserRole;
|
|
37
|
+
type DeveloperStatusEnumType = 'none' | 'pending' | 'approved';
|
|
38
|
+
type DeveloperStatusValue = DeveloperStatusEnumType;
|
|
39
|
+
type TimebackUserRole = 'administrator' | 'aide' | 'guardian' | 'parent' | 'proctor' | 'relative' | 'student' | 'teacher';
|
|
40
|
+
type TimebackOrgType = 'department' | 'school' | 'district' | 'local' | 'state' | 'national';
|
|
41
|
+
interface UserEnrollment {
|
|
42
|
+
gameId?: string;
|
|
43
|
+
courseId: string;
|
|
44
|
+
enrollmentIds?: {
|
|
45
|
+
active: string;
|
|
46
|
+
inactive?: string[];
|
|
47
|
+
};
|
|
48
|
+
grade: number;
|
|
49
|
+
subject: string;
|
|
50
|
+
orgId?: string;
|
|
51
|
+
}
|
|
52
|
+
interface UserOrganization {
|
|
53
|
+
id: string;
|
|
54
|
+
name: string | null;
|
|
55
|
+
type: TimebackOrgType | string;
|
|
56
|
+
isPrimary: boolean;
|
|
57
|
+
}
|
|
58
|
+
interface TimebackStudentProfile {
|
|
59
|
+
role: TimebackUserRole;
|
|
60
|
+
organizations: UserOrganization[];
|
|
61
|
+
}
|
|
62
|
+
interface UserTimebackData extends TimebackStudentProfile {
|
|
63
|
+
id: string;
|
|
64
|
+
enrollments: UserEnrollment[];
|
|
65
|
+
}
|
|
45
66
|
/**
|
|
46
|
-
*
|
|
47
|
-
* Matches OneRoster subjects, with "None" as a Caliper-specific fallback.
|
|
67
|
+
* OpenID Connect UserInfo claims (NOT a database row).
|
|
48
68
|
*/
|
|
49
|
-
|
|
69
|
+
interface UserInfo {
|
|
70
|
+
sub: string;
|
|
71
|
+
email: string;
|
|
72
|
+
name: string | null;
|
|
73
|
+
email_verified?: boolean;
|
|
74
|
+
given_name?: string;
|
|
75
|
+
family_name?: string;
|
|
76
|
+
issuer?: string;
|
|
77
|
+
lti_roles?: unknown;
|
|
78
|
+
lti_context?: unknown;
|
|
79
|
+
lti_resource_link?: unknown;
|
|
80
|
+
timeback_id?: string;
|
|
81
|
+
}
|
|
82
|
+
interface DeveloperStatusResponse {
|
|
83
|
+
status: DeveloperStatusEnumType;
|
|
84
|
+
}
|
|
85
|
+
interface DemoProfile {
|
|
86
|
+
displayName: string;
|
|
87
|
+
isDefault: boolean;
|
|
88
|
+
}
|
|
50
89
|
/**
|
|
51
|
-
*
|
|
90
|
+
* Update shape for `client.demo.profile.update(...)`.
|
|
91
|
+
*
|
|
92
|
+
* Kept as a named type so callers typed against it pick up new fields
|
|
93
|
+
* automatically, but `displayName` is the only updatable field today and
|
|
94
|
+
* the server's `DemoProfileSchema` requires it — a no-field payload would
|
|
95
|
+
* 400 at runtime, so we model that at the type level too. When additional
|
|
96
|
+
* fields land, make them required/optional individually based on server
|
|
97
|
+
* validation, rather than blanket-optional.
|
|
52
98
|
*/
|
|
53
|
-
|
|
99
|
+
interface DemoProfileUpdate {
|
|
100
|
+
displayName: string;
|
|
101
|
+
}
|
|
54
102
|
/**
|
|
55
|
-
*
|
|
103
|
+
* Authenticated user for API responses.
|
|
104
|
+
* Differs from UserRow: omits timebackId, adds hasTimebackAccount and timeback.
|
|
56
105
|
*/
|
|
57
|
-
|
|
106
|
+
interface AuthenticatedUser {
|
|
107
|
+
id: string;
|
|
108
|
+
email: string;
|
|
109
|
+
emailVerified: boolean;
|
|
110
|
+
name: string | null;
|
|
111
|
+
image: string | null;
|
|
112
|
+
username: string | null;
|
|
113
|
+
role: UserRoleEnumType;
|
|
114
|
+
developerStatus: DeveloperStatusEnumType;
|
|
115
|
+
characterCreated: boolean;
|
|
116
|
+
createdAt: Date;
|
|
117
|
+
updatedAt: Date;
|
|
118
|
+
hasTimebackAccount: boolean;
|
|
119
|
+
timeback?: UserTimebackData;
|
|
120
|
+
}
|
|
121
|
+
interface GameUser {
|
|
122
|
+
id: string;
|
|
123
|
+
name: string | null;
|
|
124
|
+
role: UserRoleEnumType;
|
|
125
|
+
username: string | null;
|
|
126
|
+
email: string | null;
|
|
127
|
+
timeback?: UserTimebackData;
|
|
128
|
+
}
|
|
58
129
|
|
|
59
130
|
/**
|
|
60
|
-
*
|
|
131
|
+
* Game Types
|
|
61
132
|
*
|
|
62
|
-
*
|
|
63
|
-
* Resource, and complete TimeBack setup.
|
|
133
|
+
* Literal types and API DTOs. Database row types are in @playcademy/data/types.
|
|
64
134
|
*
|
|
65
|
-
* @module types/
|
|
135
|
+
* @module types/game
|
|
66
136
|
*/
|
|
67
137
|
|
|
138
|
+
type GameType = 'hosted' | 'external';
|
|
139
|
+
type GamePlatform = 'web' | 'godot' | 'unity' | (string & {});
|
|
68
140
|
/**
|
|
69
|
-
*
|
|
141
|
+
* Game manifest file format (manifest.json).
|
|
142
|
+
* Note: createdAt is a string here because it's parsed from JSON file.
|
|
70
143
|
*/
|
|
71
|
-
interface
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
144
|
+
interface ManifestV1 {
|
|
145
|
+
version: '1';
|
|
146
|
+
platform: string;
|
|
147
|
+
createdAt: string;
|
|
148
|
+
}
|
|
149
|
+
interface ManifestVersions {
|
|
150
|
+
vitePlugin?: string;
|
|
151
|
+
sdk?: string;
|
|
152
|
+
cli?: string;
|
|
153
|
+
vite?: string;
|
|
154
|
+
godotSdk?: string;
|
|
155
|
+
godot?: string;
|
|
156
|
+
}
|
|
157
|
+
interface ManifestV2 {
|
|
158
|
+
version: '2';
|
|
159
|
+
platform: string;
|
|
160
|
+
createdAt: string;
|
|
161
|
+
versions: ManifestVersions;
|
|
162
|
+
}
|
|
163
|
+
type GameManifest = ManifestV1 | ManifestV2;
|
|
164
|
+
interface DomainValidationRecords {
|
|
165
|
+
ownership?: {
|
|
166
|
+
name?: string;
|
|
167
|
+
value?: string;
|
|
168
|
+
type?: string;
|
|
169
|
+
};
|
|
170
|
+
ssl?: {
|
|
171
|
+
txt_name?: string;
|
|
172
|
+
txt_value?: string;
|
|
173
|
+
}[];
|
|
78
174
|
}
|
|
175
|
+
|
|
79
176
|
/**
|
|
80
|
-
*
|
|
177
|
+
* Leaderboard Types
|
|
178
|
+
*
|
|
179
|
+
* @module types/leaderboard
|
|
81
180
|
*/
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
181
|
+
type LeaderboardTimeframe = 'all_time' | 'monthly' | 'weekly' | 'daily';
|
|
182
|
+
interface LeaderboardOptions {
|
|
183
|
+
timeframe?: LeaderboardTimeframe;
|
|
184
|
+
limit?: number;
|
|
185
|
+
offset?: number;
|
|
186
|
+
gameId?: string;
|
|
187
|
+
}
|
|
188
|
+
interface LeaderboardEntry {
|
|
189
|
+
rank: number;
|
|
190
|
+
userId: string;
|
|
191
|
+
username: string;
|
|
192
|
+
userImage?: string | null;
|
|
193
|
+
score: number;
|
|
194
|
+
achievedAt: Date;
|
|
195
|
+
metadata?: Record<string, unknown>;
|
|
196
|
+
gameId?: string;
|
|
197
|
+
gameTitle?: string;
|
|
198
|
+
gameSlug?: string;
|
|
199
|
+
}
|
|
200
|
+
interface UserRank {
|
|
201
|
+
rank: number;
|
|
202
|
+
totalPlayers: number;
|
|
203
|
+
score: number;
|
|
204
|
+
percentile: number;
|
|
205
|
+
}
|
|
206
|
+
interface UserRankResponse {
|
|
207
|
+
rank: number;
|
|
208
|
+
score: number;
|
|
209
|
+
userId: string;
|
|
210
|
+
}
|
|
211
|
+
interface UserScore {
|
|
212
|
+
id: string;
|
|
213
|
+
score: number;
|
|
214
|
+
achievedAt: Date;
|
|
215
|
+
metadata?: Record<string, unknown>;
|
|
216
|
+
gameId: string;
|
|
217
|
+
gameTitle: string;
|
|
218
|
+
gameSlug: string;
|
|
93
219
|
}
|
|
94
220
|
/**
|
|
95
|
-
*
|
|
221
|
+
* Leaderboard entry with required game context.
|
|
222
|
+
* Used when fetching leaderboards for a specific game.
|
|
96
223
|
*/
|
|
97
|
-
interface
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
224
|
+
interface GameLeaderboardEntry {
|
|
225
|
+
rank: number;
|
|
226
|
+
userId: string;
|
|
227
|
+
username: string;
|
|
228
|
+
userImage?: string | null;
|
|
229
|
+
score: number;
|
|
230
|
+
achievedAt: Date;
|
|
231
|
+
metadata?: Record<string, unknown>;
|
|
232
|
+
gameId: string;
|
|
233
|
+
gameTitle: string;
|
|
234
|
+
gameSlug: string;
|
|
108
235
|
}
|
|
236
|
+
|
|
109
237
|
/**
|
|
110
|
-
*
|
|
238
|
+
* Achievement Types
|
|
239
|
+
*
|
|
240
|
+
* @module types/achievement
|
|
111
241
|
*/
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
242
|
+
type AchievementScopeType = 'daily' | 'weekly' | 'monthly' | 'yearly' | 'game' | 'global' | 'map' | 'level' | 'event';
|
|
243
|
+
declare enum AchievementCompletionType {
|
|
244
|
+
TIME_PLAYED_SESSION = "time_played_session",
|
|
245
|
+
INTERACTION = "interaction",
|
|
246
|
+
LEADERBOARD_RANK = "leaderboard_rank",
|
|
247
|
+
FIRST_SCORE = "first_score",
|
|
248
|
+
PERSONAL_BEST = "personal_best"
|
|
249
|
+
}
|
|
250
|
+
interface AchievementCurrent {
|
|
251
|
+
id: string;
|
|
252
|
+
title: string;
|
|
253
|
+
description?: string | null;
|
|
254
|
+
scope: AchievementScopeType;
|
|
255
|
+
rewardCredits: number;
|
|
256
|
+
limit: number;
|
|
257
|
+
completionType: string;
|
|
258
|
+
completionConfig: unknown;
|
|
259
|
+
target: unknown;
|
|
260
|
+
active: boolean;
|
|
261
|
+
createdAt?: Date | null;
|
|
262
|
+
updatedAt?: Date | null;
|
|
263
|
+
status: 'available' | 'completed';
|
|
264
|
+
scopeKey: string;
|
|
265
|
+
windowStart: string;
|
|
266
|
+
windowEnd: string;
|
|
267
|
+
}
|
|
268
|
+
interface AchievementWithStatus {
|
|
269
|
+
id: string;
|
|
270
|
+
title: string;
|
|
271
|
+
description: string | null;
|
|
272
|
+
scope: AchievementScopeType;
|
|
273
|
+
rewardCredits: number;
|
|
274
|
+
limit: number;
|
|
275
|
+
completionType: string;
|
|
276
|
+
completionConfig: unknown;
|
|
277
|
+
target: unknown;
|
|
278
|
+
active: boolean;
|
|
279
|
+
createdAt: Date | null;
|
|
280
|
+
updatedAt: Date | null;
|
|
281
|
+
status: 'available' | 'completed';
|
|
282
|
+
scopeKey: string;
|
|
283
|
+
windowStart?: string;
|
|
284
|
+
windowEnd?: string;
|
|
285
|
+
}
|
|
286
|
+
interface AchievementHistoryEntry {
|
|
287
|
+
achievementId: string;
|
|
288
|
+
title: string;
|
|
289
|
+
rewardCredits: number;
|
|
290
|
+
createdAt: Date;
|
|
291
|
+
scopeKey: string;
|
|
292
|
+
}
|
|
293
|
+
interface AchievementProgressResponse {
|
|
294
|
+
achievementId: string;
|
|
295
|
+
status: 'completed' | 'already_completed';
|
|
296
|
+
rewardCredits: number;
|
|
297
|
+
scopeKey: string;
|
|
298
|
+
createdAt: Date;
|
|
299
|
+
}
|
|
300
|
+
|
|
301
|
+
/**
|
|
302
|
+
* TimeBack Enums & Literal Types
|
|
303
|
+
*
|
|
304
|
+
* Basic type definitions used throughout the TimeBack integration.
|
|
305
|
+
*
|
|
306
|
+
* @module types/timeback/types
|
|
307
|
+
*/
|
|
308
|
+
/**
|
|
309
|
+
* Valid TimeBack subject values for course configuration.
|
|
310
|
+
* These are the supported subject values for OneRoster courses.
|
|
311
|
+
*/
|
|
312
|
+
type TimebackSubject = 'Reading' | 'Language' | 'Vocabulary' | 'Social Studies' | 'Writing' | 'Science' | 'FastMath' | 'Math' | 'None';
|
|
313
|
+
/**
|
|
314
|
+
* Grade levels per AE OneRoster GradeEnum.
|
|
315
|
+
* -1 = Pre-K, 0 = Kindergarten, 1-12 = Grades 1-12, 13 = AP
|
|
316
|
+
*/
|
|
317
|
+
type TimebackGrade = -1 | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13;
|
|
318
|
+
/**
|
|
319
|
+
* Valid Caliper subject values.
|
|
320
|
+
* Matches OneRoster subjects, with "None" as a Caliper-specific fallback.
|
|
321
|
+
*/
|
|
322
|
+
type CaliperSubject = 'Reading' | 'Language' | 'Vocabulary' | 'Social Studies' | 'Writing' | 'Science' | 'FastMath' | 'Math' | 'None';
|
|
323
|
+
/**
|
|
324
|
+
* OneRoster organization types.
|
|
325
|
+
*/
|
|
326
|
+
type OrganizationType = 'department' | 'school' | 'district' | 'local' | 'state' | 'national';
|
|
327
|
+
/**
|
|
328
|
+
* Lesson types for PowerPath integration.
|
|
329
|
+
*/
|
|
330
|
+
type LessonType = 'powerpath-100' | 'quiz' | 'test-out' | 'placement' | 'unit-test' | 'alpha-read-article' | null;
|
|
331
|
+
|
|
332
|
+
/**
|
|
333
|
+
* TimeBack Configuration Types
|
|
334
|
+
*
|
|
335
|
+
* Configuration interfaces for Organization, Course, Component,
|
|
336
|
+
* Resource, and complete TimeBack setup.
|
|
337
|
+
*
|
|
338
|
+
* @module types/timeback/config
|
|
339
|
+
*/
|
|
340
|
+
|
|
341
|
+
/**
|
|
342
|
+
* Organization configuration for TimeBack (user input - optionals allowed)
|
|
343
|
+
*/
|
|
344
|
+
interface OrganizationConfig {
|
|
345
|
+
/** Display name for your organization */
|
|
346
|
+
name?: string;
|
|
347
|
+
/** Organization type */
|
|
348
|
+
type?: OrganizationType;
|
|
349
|
+
/** Unique identifier (defaults to Playcademy's org) */
|
|
350
|
+
identifier?: string;
|
|
351
|
+
}
|
|
352
|
+
/**
|
|
353
|
+
* Course goals for daily student targets
|
|
354
|
+
*/
|
|
355
|
+
interface CourseGoals {
|
|
356
|
+
/** Target XP students should earn per day */
|
|
357
|
+
dailyXp?: number;
|
|
358
|
+
/** Target lessons per day */
|
|
359
|
+
dailyLessons?: number;
|
|
360
|
+
/** Target active minutes per day */
|
|
361
|
+
dailyActiveMinutes?: number;
|
|
362
|
+
/** Target accuracy percentage */
|
|
363
|
+
dailyAccuracy?: number;
|
|
364
|
+
/** Target mastered units per day */
|
|
365
|
+
dailyMasteredUnits?: number;
|
|
366
|
+
}
|
|
367
|
+
/**
|
|
368
|
+
* Course metrics and totals
|
|
369
|
+
*/
|
|
370
|
+
interface CourseMetrics {
|
|
371
|
+
/** Total XP available in the course */
|
|
372
|
+
totalXp?: number;
|
|
373
|
+
/** Total lessons/activities in the course */
|
|
374
|
+
totalLessons?: number;
|
|
375
|
+
/** Total number of grade levels covered by this course */
|
|
376
|
+
totalGrades?: number;
|
|
377
|
+
/** The type of course (e.g. 'optional', 'hole-filling', 'base') */
|
|
378
|
+
courseType?: 'base' | 'hole-filling' | 'optional' | 'Base' | 'Hole-Filling' | 'Optional';
|
|
379
|
+
/** Indicates whether the course is supplemental content */
|
|
380
|
+
isSupplemental?: boolean;
|
|
381
|
+
}
|
|
382
|
+
/**
|
|
383
|
+
* Complete course metadata structure
|
|
384
|
+
*/
|
|
385
|
+
interface CourseMetadata {
|
|
386
|
+
/** Define the type of course and priority for the student */
|
|
387
|
+
courseType?: 'base' | 'hole-filling' | 'optional';
|
|
388
|
+
/** Boolean value to determine if a course is supplemental to a base course */
|
|
389
|
+
isSupplemental?: boolean;
|
|
390
|
+
/** Boolean value to determine if a course is custom to an individual student */
|
|
391
|
+
isCustom?: boolean;
|
|
392
|
+
/** Signals whether a course is in production with students */
|
|
393
|
+
publishStatus?: 'draft' | 'testing' | 'published' | 'deactivated';
|
|
394
|
+
/** Whether this course appears in the TimeBack catalog for teachers and parents */
|
|
395
|
+
timebackVisible?: boolean;
|
|
396
|
+
/** Who to contact when issues reported with questions */
|
|
124
397
|
contactEmail?: string;
|
|
125
398
|
/** Primary app identifier */
|
|
126
399
|
primaryApp?: string;
|
|
@@ -451,726 +724,804 @@ type GameMetricsProxyResponse = {
|
|
|
451
724
|
};
|
|
452
725
|
|
|
453
726
|
/**
|
|
454
|
-
*
|
|
727
|
+
* Inventory & Shop Types
|
|
728
|
+
*
|
|
729
|
+
* Literal types for inventory system. Database row types are in @playcademy/data/types.
|
|
730
|
+
*
|
|
731
|
+
* @module types/inventory
|
|
455
732
|
*/
|
|
456
733
|
/**
|
|
457
|
-
*
|
|
734
|
+
* Item categories available on the platform.
|
|
458
735
|
*/
|
|
459
|
-
|
|
460
|
-
/** Time-to-live in milliseconds. Set to 0 to disable caching for this call. */
|
|
461
|
-
ttl?: number;
|
|
462
|
-
/** Force refresh, bypassing cache */
|
|
463
|
-
force?: boolean;
|
|
464
|
-
/** Skip cache and fetch fresh data (alias for force) */
|
|
465
|
-
skipCache?: boolean;
|
|
466
|
-
}
|
|
736
|
+
type ItemType = 'currency' | 'badge' | 'trophy' | 'collectible' | 'consumable' | 'unlock' | 'upgrade' | 'accessory' | 'other';
|
|
467
737
|
|
|
468
738
|
/**
|
|
469
|
-
*
|
|
739
|
+
* Map & Placement Types
|
|
470
740
|
*
|
|
471
|
-
*
|
|
472
|
-
*
|
|
741
|
+
* Literal types and JSON shapes for maps. Database row types are in @playcademy/data/types.
|
|
742
|
+
*
|
|
743
|
+
* @module types/map
|
|
473
744
|
*/
|
|
474
|
-
|
|
475
745
|
/**
|
|
476
|
-
*
|
|
477
|
-
* References upstream TimeBack types from @playcademy/timeback.
|
|
478
|
-
*
|
|
479
|
-
* All fields are optional and support template variables: {grade}, {subject}, {gameSlug}
|
|
746
|
+
* Allowed map interaction types.
|
|
480
747
|
*/
|
|
481
|
-
|
|
482
|
-
/** Organization configuration (shared across all courses) */
|
|
483
|
-
organization?: Partial<OrganizationConfig>;
|
|
484
|
-
/** Course defaults (can be overridden per-course) */
|
|
485
|
-
course?: Partial<CourseConfig>;
|
|
486
|
-
/** Component defaults */
|
|
487
|
-
component?: Partial<ComponentConfig>;
|
|
488
|
-
/** Resource defaults */
|
|
489
|
-
resource?: Partial<ResourceConfig>;
|
|
490
|
-
/** ComponentResource defaults */
|
|
491
|
-
componentResource?: Partial<ComponentResourceConfig>;
|
|
492
|
-
}
|
|
748
|
+
type InteractionType = 'game_entry' | 'game_registry' | 'info' | 'teleport' | 'door_in' | 'door_out' | 'npc_interaction' | 'quest_trigger';
|
|
493
749
|
/**
|
|
494
|
-
*
|
|
495
|
-
* Used in playcademy.config.* to allow per-course customization.
|
|
750
|
+
* Metadata for interactive map elements.
|
|
496
751
|
*/
|
|
497
|
-
interface
|
|
752
|
+
interface MapElementMetadata {
|
|
753
|
+
description?: string;
|
|
498
754
|
title?: string;
|
|
499
|
-
|
|
500
|
-
|
|
501
|
-
|
|
502
|
-
|
|
503
|
-
|
|
755
|
+
targetMapIdentifier?: string;
|
|
756
|
+
targetSpawnTileX?: number;
|
|
757
|
+
targetSpawnTileY?: number;
|
|
758
|
+
sourceTiledObjects?: Record<string, unknown>[];
|
|
759
|
+
[key: string]: unknown;
|
|
504
760
|
}
|
|
505
761
|
/**
|
|
506
|
-
*
|
|
507
|
-
*
|
|
508
|
-
* Supports two levels of customization:
|
|
509
|
-
* 1. `base`: Shared defaults for all courses (organization, course, component, resource, componentResource)
|
|
510
|
-
* 2. Per-course overrides in the `courses` array (title, courseCode, level, gradingScheme, metadata)
|
|
511
|
-
*
|
|
512
|
-
* Template variables ({grade}, {subject}, {gameSlug}) can be used in string fields.
|
|
762
|
+
* Metadata describing how an item should be placed on the map.
|
|
513
763
|
*/
|
|
514
|
-
interface
|
|
515
|
-
|
|
516
|
-
|
|
517
|
-
|
|
518
|
-
|
|
764
|
+
interface PlaceableItemMetadata {
|
|
765
|
+
tilesWide?: number;
|
|
766
|
+
tilesHigh?: number;
|
|
767
|
+
flippable?: boolean;
|
|
768
|
+
[key: string]: unknown;
|
|
519
769
|
}
|
|
520
770
|
/**
|
|
521
|
-
*
|
|
771
|
+
* Simplified map data for API responses.
|
|
522
772
|
*/
|
|
523
|
-
interface
|
|
524
|
-
|
|
525
|
-
|
|
773
|
+
interface MapData {
|
|
774
|
+
id: string;
|
|
775
|
+
identifier: string;
|
|
776
|
+
displayName: string;
|
|
777
|
+
description?: string | null;
|
|
778
|
+
metadata?: Record<string, unknown> | null;
|
|
526
779
|
}
|
|
527
780
|
/**
|
|
528
|
-
*
|
|
781
|
+
* Input for creating a map object.
|
|
529
782
|
*/
|
|
530
|
-
interface
|
|
531
|
-
|
|
532
|
-
|
|
533
|
-
|
|
534
|
-
|
|
535
|
-
|
|
536
|
-
|
|
537
|
-
|
|
538
|
-
|
|
539
|
-
maxRetries?: number;
|
|
540
|
-
maxBatchTimeout?: number;
|
|
541
|
-
maxConcurrency?: number;
|
|
542
|
-
retryDelay?: number;
|
|
543
|
-
deadLetterQueue?: string;
|
|
783
|
+
interface CreateMapObjectData {
|
|
784
|
+
itemId: string;
|
|
785
|
+
worldX: number;
|
|
786
|
+
worldY: number;
|
|
787
|
+
width?: number;
|
|
788
|
+
height?: number;
|
|
789
|
+
rotation?: number;
|
|
790
|
+
scale?: number;
|
|
791
|
+
metadata?: Record<string, unknown>;
|
|
544
792
|
}
|
|
793
|
+
|
|
545
794
|
/**
|
|
546
|
-
*
|
|
547
|
-
*
|
|
795
|
+
* Character & Avatar Types
|
|
796
|
+
*
|
|
797
|
+
* Literal types for character system. Database row types are in @playcademy/data/types.
|
|
798
|
+
*
|
|
799
|
+
* @module types/character
|
|
548
800
|
*/
|
|
549
|
-
interface IntegrationsConfig {
|
|
550
|
-
/** TimeBack integration (optional) */
|
|
551
|
-
timeback?: TimebackIntegrationConfig | null;
|
|
552
|
-
/** Custom API routes (optional) */
|
|
553
|
-
customRoutes?: CustomRoutesIntegration | boolean;
|
|
554
|
-
/** Database (optional) */
|
|
555
|
-
database?: DatabaseIntegration | boolean;
|
|
556
|
-
/** Key-Value storage (optional) */
|
|
557
|
-
kv?: boolean;
|
|
558
|
-
/** Bucket storage (optional) */
|
|
559
|
-
bucket?: boolean;
|
|
560
|
-
/** Authentication (optional) */
|
|
561
|
-
auth?: boolean;
|
|
562
|
-
/** Queues (optional) */
|
|
563
|
-
queues?: Record<string, QueueConfig | boolean>;
|
|
564
|
-
}
|
|
565
801
|
/**
|
|
566
|
-
*
|
|
567
|
-
* Used for playcademy.config.{js,json}
|
|
802
|
+
* Character component categories.
|
|
568
803
|
*/
|
|
569
|
-
|
|
570
|
-
/** Game name */
|
|
571
|
-
name: string;
|
|
572
|
-
/** Game description */
|
|
573
|
-
description?: string;
|
|
574
|
-
/** Game emoji icon */
|
|
575
|
-
emoji?: string;
|
|
576
|
-
/** Build command to run before deployment */
|
|
577
|
-
buildCommand?: string[];
|
|
578
|
-
/** Path to build output */
|
|
579
|
-
buildPath?: string;
|
|
580
|
-
/** Game type */
|
|
581
|
-
gameType?: 'hosted' | 'external';
|
|
582
|
-
/** External URL (for external games) */
|
|
583
|
-
externalUrl?: string;
|
|
584
|
-
/** Game platform */
|
|
585
|
-
platform?: 'web' | 'unity' | 'godot';
|
|
586
|
-
/** Integrations (database, custom routes, external services) */
|
|
587
|
-
integrations?: IntegrationsConfig;
|
|
588
|
-
}
|
|
804
|
+
type CharacterComponentType = 'body' | 'outfit' | 'hairstyle' | 'eyes' | 'accessory';
|
|
589
805
|
|
|
590
806
|
/**
|
|
591
|
-
*
|
|
807
|
+
* Level & Progression Types
|
|
592
808
|
*
|
|
593
|
-
* @
|
|
594
|
-
*
|
|
595
|
-
*
|
|
596
|
-
* apiKey: process.env.PLAYCADEMY_API_KEY!,
|
|
597
|
-
* gameId: 'my-math-game',
|
|
598
|
-
* configPath: './playcademy.config.js'
|
|
599
|
-
* }
|
|
600
|
-
* ```
|
|
809
|
+
* API response DTOs for level system. Database row types are in @playcademy/data/types.
|
|
810
|
+
*
|
|
811
|
+
* @module types/level
|
|
601
812
|
*/
|
|
602
|
-
|
|
603
|
-
|
|
604
|
-
|
|
605
|
-
|
|
606
|
-
|
|
607
|
-
|
|
608
|
-
|
|
609
|
-
|
|
610
|
-
|
|
611
|
-
* Ignored if `config` is provided directly.
|
|
612
|
-
*
|
|
613
|
-
* @example './config/playcademy.config.js'
|
|
614
|
-
*/
|
|
615
|
-
configPath?: string;
|
|
616
|
-
/**
|
|
617
|
-
* Optional config object (for edge environments without filesystem).
|
|
618
|
-
* If provided, skips filesystem-based config loading.
|
|
619
|
-
*
|
|
620
|
-
* @example { name: 'My Game', integrations: { timeback: {...} } }
|
|
621
|
-
*/
|
|
622
|
-
config?: PlaycademyConfig;
|
|
623
|
-
/**
|
|
624
|
-
* Optional base URL for Playcademy API.
|
|
625
|
-
* Defaults to environment variables or 'https://hub.playcademy.net'.
|
|
626
|
-
*
|
|
627
|
-
* @example 'http://localhost:3000' for local development
|
|
628
|
-
*/
|
|
629
|
-
baseUrl?: string;
|
|
630
|
-
/**
|
|
631
|
-
* Optional game ID.
|
|
632
|
-
* If not provided, will attempt to fetch from API using the API token.
|
|
633
|
-
*
|
|
634
|
-
* @example 'my-math-game'
|
|
635
|
-
*/
|
|
636
|
-
gameId?: string;
|
|
813
|
+
/**
|
|
814
|
+
* Result of adding XP to a user.
|
|
815
|
+
*/
|
|
816
|
+
interface XPAddResult {
|
|
817
|
+
totalXP: number;
|
|
818
|
+
newLevel: number;
|
|
819
|
+
leveledUp: boolean;
|
|
820
|
+
creditsAwarded: number;
|
|
821
|
+
xpToNextLevel: number;
|
|
637
822
|
}
|
|
638
823
|
/**
|
|
639
|
-
*
|
|
640
|
-
*
|
|
641
|
-
* @internal
|
|
824
|
+
* Result of checking whether a level up occurred.
|
|
642
825
|
*/
|
|
643
|
-
interface
|
|
644
|
-
|
|
645
|
-
|
|
646
|
-
|
|
647
|
-
|
|
648
|
-
|
|
649
|
-
|
|
650
|
-
|
|
651
|
-
|
|
652
|
-
|
|
653
|
-
|
|
654
|
-
|
|
655
|
-
|
|
656
|
-
|
|
826
|
+
interface LevelUpCheckResult {
|
|
827
|
+
newLevel: number;
|
|
828
|
+
remainingXp: number;
|
|
829
|
+
leveledUp: boolean;
|
|
830
|
+
creditsAwarded: number;
|
|
831
|
+
xpToNextLevel: number;
|
|
832
|
+
}
|
|
833
|
+
/**
|
|
834
|
+
* Level progress API response.
|
|
835
|
+
*/
|
|
836
|
+
interface LevelProgressResponse {
|
|
837
|
+
level: number;
|
|
838
|
+
currentXp: number;
|
|
839
|
+
xpToNextLevel: number;
|
|
840
|
+
totalXP: number;
|
|
657
841
|
}
|
|
658
842
|
|
|
659
843
|
/**
|
|
660
|
-
*
|
|
661
|
-
*
|
|
662
|
-
* Enums, DTOs and API response types. Database row types are in @playcademy/data/types.
|
|
844
|
+
* Notification Types
|
|
663
845
|
*
|
|
664
|
-
* @module types/
|
|
846
|
+
* @module types/notification
|
|
665
847
|
*/
|
|
666
848
|
|
|
667
|
-
|
|
668
|
-
|
|
669
|
-
|
|
670
|
-
|
|
671
|
-
type TimebackOrgType = 'department' | 'school' | 'district' | 'local' | 'state' | 'national';
|
|
672
|
-
interface UserEnrollment {
|
|
673
|
-
gameId?: string;
|
|
674
|
-
courseId: string;
|
|
675
|
-
enrollmentIds?: {
|
|
676
|
-
active: string;
|
|
677
|
-
inactive?: string[];
|
|
678
|
-
};
|
|
679
|
-
grade: number;
|
|
680
|
-
subject: string;
|
|
681
|
-
orgId?: string;
|
|
682
|
-
}
|
|
683
|
-
interface UserOrganization {
|
|
684
|
-
id: string;
|
|
685
|
-
name: string | null;
|
|
686
|
-
type: TimebackOrgType | string;
|
|
687
|
-
isPrimary: boolean;
|
|
849
|
+
declare enum NotificationType {
|
|
850
|
+
ACHIEVEMENT = "achievement",
|
|
851
|
+
SYSTEM = "system",
|
|
852
|
+
PROMO = "promo"
|
|
688
853
|
}
|
|
689
|
-
|
|
690
|
-
|
|
691
|
-
|
|
854
|
+
declare enum NotificationStatus {
|
|
855
|
+
PENDING = "pending",
|
|
856
|
+
DELIVERED = "delivered",
|
|
857
|
+
SEEN = "seen",
|
|
858
|
+
CLICKED = "clicked",
|
|
859
|
+
DISMISSED = "dismissed",
|
|
860
|
+
EXPIRED = "expired"
|
|
692
861
|
}
|
|
693
|
-
interface
|
|
694
|
-
|
|
695
|
-
|
|
862
|
+
interface NotificationStats {
|
|
863
|
+
total: number;
|
|
864
|
+
delivered: number;
|
|
865
|
+
seen: number;
|
|
866
|
+
clicked: number;
|
|
867
|
+
dismissed: number;
|
|
868
|
+
expired: number;
|
|
869
|
+
clickThroughRate: number;
|
|
696
870
|
}
|
|
871
|
+
|
|
697
872
|
/**
|
|
698
|
-
*
|
|
873
|
+
* Shop Types
|
|
874
|
+
*
|
|
875
|
+
* @module types/shop
|
|
699
876
|
*/
|
|
700
|
-
interface UserInfo {
|
|
701
|
-
sub: string;
|
|
702
|
-
email: string;
|
|
703
|
-
name: string | null;
|
|
704
|
-
email_verified?: boolean;
|
|
705
|
-
given_name?: string;
|
|
706
|
-
family_name?: string;
|
|
707
|
-
issuer?: string;
|
|
708
|
-
lti_roles?: unknown;
|
|
709
|
-
lti_context?: unknown;
|
|
710
|
-
lti_resource_link?: unknown;
|
|
711
|
-
timeback_id?: string;
|
|
712
|
-
}
|
|
713
|
-
interface DeveloperStatusResponse {
|
|
714
|
-
status: DeveloperStatusEnumType;
|
|
715
|
-
}
|
|
716
|
-
interface DemoProfile {
|
|
717
|
-
displayName: string;
|
|
718
|
-
isDefault: boolean;
|
|
719
|
-
}
|
|
720
877
|
/**
|
|
721
|
-
*
|
|
722
|
-
*
|
|
723
|
-
* Kept as a named type so callers typed against it pick up new fields
|
|
724
|
-
* automatically, but `displayName` is the only updatable field today and
|
|
725
|
-
* the server's `DemoProfileSchema` requires it — a no-field payload would
|
|
726
|
-
* 400 at runtime, so we model that at the type level too. When additional
|
|
727
|
-
* fields land, make them required/optional individually based on server
|
|
728
|
-
* validation, rather than blanket-optional.
|
|
878
|
+
* Currency display info for shop UI.
|
|
729
879
|
*/
|
|
730
|
-
interface
|
|
731
|
-
|
|
880
|
+
interface ShopCurrency {
|
|
881
|
+
id: string;
|
|
882
|
+
symbol: string | null;
|
|
883
|
+
isPrimary: boolean;
|
|
884
|
+
displayName?: string | null;
|
|
885
|
+
imageUrl?: string | null;
|
|
732
886
|
}
|
|
733
887
|
/**
|
|
734
|
-
*
|
|
735
|
-
*
|
|
888
|
+
* Shop item for display.
|
|
889
|
+
* Combines Item fields (excluding createdAt) with shop listing data.
|
|
736
890
|
*/
|
|
737
|
-
interface
|
|
891
|
+
interface ShopDisplayItem {
|
|
738
892
|
id: string;
|
|
739
|
-
|
|
740
|
-
|
|
741
|
-
|
|
742
|
-
|
|
743
|
-
|
|
744
|
-
|
|
745
|
-
|
|
746
|
-
|
|
747
|
-
|
|
748
|
-
|
|
749
|
-
|
|
750
|
-
|
|
893
|
+
slug: string;
|
|
894
|
+
gameId?: string | null;
|
|
895
|
+
displayName: string;
|
|
896
|
+
description?: string | null;
|
|
897
|
+
type: string;
|
|
898
|
+
isPlaceable: boolean;
|
|
899
|
+
imageUrl?: string | null;
|
|
900
|
+
metadata?: unknown;
|
|
901
|
+
listingId: string;
|
|
902
|
+
shopPrice: number;
|
|
903
|
+
currencyId: string;
|
|
904
|
+
currencySymbol?: string | null;
|
|
905
|
+
currencyDisplayName?: string | null;
|
|
906
|
+
currencyImageUrl?: string | null;
|
|
907
|
+
stock?: number | null;
|
|
908
|
+
sellBackPercentage?: number | null;
|
|
751
909
|
}
|
|
752
|
-
|
|
753
|
-
|
|
754
|
-
|
|
755
|
-
|
|
756
|
-
|
|
757
|
-
|
|
758
|
-
timeback?: UserTimebackData;
|
|
910
|
+
/**
|
|
911
|
+
* Complete shop view response.
|
|
912
|
+
*/
|
|
913
|
+
interface ShopViewResponse {
|
|
914
|
+
shopItems: ShopDisplayItem[];
|
|
915
|
+
currencies: ShopCurrency[];
|
|
759
916
|
}
|
|
760
917
|
|
|
761
918
|
/**
|
|
762
|
-
*
|
|
919
|
+
* Sprite Types
|
|
763
920
|
*
|
|
764
|
-
*
|
|
921
|
+
* JSON shapes for sprite configuration. Database row types are in @playcademy/data/types.
|
|
765
922
|
*
|
|
766
|
-
* @module types/
|
|
923
|
+
* @module types/sprite
|
|
767
924
|
*/
|
|
768
|
-
|
|
769
|
-
type GameType = 'hosted' | 'external';
|
|
770
|
-
type GamePlatform = 'web' | 'godot' | 'unity' | (string & {});
|
|
771
925
|
/**
|
|
772
|
-
*
|
|
773
|
-
* Note: createdAt is a string here because it's parsed from JSON file.
|
|
926
|
+
* Animation frame configuration.
|
|
774
927
|
*/
|
|
775
|
-
interface
|
|
776
|
-
|
|
777
|
-
|
|
778
|
-
|
|
779
|
-
|
|
780
|
-
interface ManifestVersions {
|
|
781
|
-
vitePlugin?: string;
|
|
782
|
-
sdk?: string;
|
|
783
|
-
cli?: string;
|
|
784
|
-
vite?: string;
|
|
785
|
-
godotSdk?: string;
|
|
786
|
-
godot?: string;
|
|
787
|
-
}
|
|
788
|
-
interface ManifestV2 {
|
|
789
|
-
version: '2';
|
|
790
|
-
platform: string;
|
|
791
|
-
createdAt: string;
|
|
792
|
-
versions: ManifestVersions;
|
|
793
|
-
}
|
|
794
|
-
type GameManifest = ManifestV1 | ManifestV2;
|
|
795
|
-
interface DomainValidationRecords {
|
|
796
|
-
ownership?: {
|
|
797
|
-
name?: string;
|
|
798
|
-
value?: string;
|
|
799
|
-
type?: string;
|
|
800
|
-
};
|
|
801
|
-
ssl?: {
|
|
802
|
-
txt_name?: string;
|
|
803
|
-
txt_value?: string;
|
|
804
|
-
}[];
|
|
928
|
+
interface SpriteAnimationFrame {
|
|
929
|
+
row: number;
|
|
930
|
+
frameStart: number;
|
|
931
|
+
numFrames: number;
|
|
932
|
+
fps: number;
|
|
805
933
|
}
|
|
806
|
-
|
|
807
934
|
/**
|
|
808
|
-
*
|
|
809
|
-
*
|
|
810
|
-
* @module types/leaderboard
|
|
935
|
+
* Sprite template data structure (stored in JSONB).
|
|
811
936
|
*/
|
|
812
|
-
|
|
813
|
-
|
|
814
|
-
|
|
815
|
-
|
|
816
|
-
|
|
817
|
-
|
|
818
|
-
|
|
819
|
-
|
|
820
|
-
|
|
821
|
-
|
|
822
|
-
|
|
823
|
-
|
|
824
|
-
|
|
825
|
-
|
|
826
|
-
|
|
827
|
-
|
|
828
|
-
|
|
829
|
-
|
|
830
|
-
|
|
831
|
-
|
|
832
|
-
rank: number;
|
|
833
|
-
totalPlayers: number;
|
|
834
|
-
score: number;
|
|
835
|
-
percentile: number;
|
|
836
|
-
}
|
|
837
|
-
interface UserRankResponse {
|
|
838
|
-
rank: number;
|
|
839
|
-
score: number;
|
|
840
|
-
userId: string;
|
|
841
|
-
}
|
|
842
|
-
interface UserScore {
|
|
843
|
-
id: string;
|
|
844
|
-
score: number;
|
|
845
|
-
achievedAt: Date;
|
|
846
|
-
metadata?: Record<string, unknown>;
|
|
847
|
-
gameId: string;
|
|
848
|
-
gameTitle: string;
|
|
849
|
-
gameSlug: string;
|
|
937
|
+
interface SpriteTemplateData {
|
|
938
|
+
tileSize: number;
|
|
939
|
+
tileHeight: number;
|
|
940
|
+
columns: number;
|
|
941
|
+
rows: number;
|
|
942
|
+
spacing: number;
|
|
943
|
+
animations: {
|
|
944
|
+
base_right: SpriteAnimationFrame;
|
|
945
|
+
base_up: SpriteAnimationFrame;
|
|
946
|
+
base_left: SpriteAnimationFrame;
|
|
947
|
+
base_down: SpriteAnimationFrame;
|
|
948
|
+
idle_right: SpriteAnimationFrame;
|
|
949
|
+
walk_right: SpriteAnimationFrame;
|
|
950
|
+
idle_up: SpriteAnimationFrame;
|
|
951
|
+
walk_up: SpriteAnimationFrame;
|
|
952
|
+
idle_left: SpriteAnimationFrame;
|
|
953
|
+
walk_left: SpriteAnimationFrame;
|
|
954
|
+
idle_down: SpriteAnimationFrame;
|
|
955
|
+
walk_down: SpriteAnimationFrame;
|
|
956
|
+
};
|
|
850
957
|
}
|
|
851
958
|
/**
|
|
852
|
-
*
|
|
853
|
-
* Used when fetching leaderboards for a specific game.
|
|
959
|
+
* Sprite sheet configuration with precomputed dimensions.
|
|
854
960
|
*/
|
|
855
|
-
interface
|
|
856
|
-
|
|
857
|
-
|
|
858
|
-
|
|
859
|
-
|
|
860
|
-
|
|
861
|
-
|
|
862
|
-
metadata?: Record<string, unknown>;
|
|
863
|
-
gameId: string;
|
|
864
|
-
gameTitle: string;
|
|
865
|
-
gameSlug: string;
|
|
961
|
+
interface SpriteConfigWithDimensions {
|
|
962
|
+
textureUrl: string;
|
|
963
|
+
columns: number;
|
|
964
|
+
rows: number;
|
|
965
|
+
spriteWidth: number;
|
|
966
|
+
spriteHeight: number;
|
|
967
|
+
animations: Record<string, SpriteAnimationFrame>;
|
|
866
968
|
}
|
|
867
969
|
|
|
868
970
|
/**
|
|
869
|
-
*
|
|
971
|
+
* Connection monitoring types
|
|
870
972
|
*
|
|
871
|
-
*
|
|
973
|
+
* Type definitions for connection state, configuration, and callbacks.
|
|
872
974
|
*/
|
|
873
|
-
type AchievementScopeType = 'daily' | 'weekly' | 'monthly' | 'yearly' | 'game' | 'global' | 'map' | 'level' | 'event';
|
|
874
|
-
declare enum AchievementCompletionType {
|
|
875
|
-
TIME_PLAYED_SESSION = "time_played_session",
|
|
876
|
-
INTERACTION = "interaction",
|
|
877
|
-
LEADERBOARD_RANK = "leaderboard_rank",
|
|
878
|
-
FIRST_SCORE = "first_score",
|
|
879
|
-
PERSONAL_BEST = "personal_best"
|
|
880
|
-
}
|
|
881
|
-
interface AchievementCurrent {
|
|
882
|
-
id: string;
|
|
883
|
-
title: string;
|
|
884
|
-
description?: string | null;
|
|
885
|
-
scope: AchievementScopeType;
|
|
886
|
-
rewardCredits: number;
|
|
887
|
-
limit: number;
|
|
888
|
-
completionType: string;
|
|
889
|
-
completionConfig: unknown;
|
|
890
|
-
target: unknown;
|
|
891
|
-
active: boolean;
|
|
892
|
-
createdAt?: Date | null;
|
|
893
|
-
updatedAt?: Date | null;
|
|
894
|
-
status: 'available' | 'completed';
|
|
895
|
-
scopeKey: string;
|
|
896
|
-
windowStart: string;
|
|
897
|
-
windowEnd: string;
|
|
898
|
-
}
|
|
899
|
-
interface AchievementWithStatus {
|
|
900
|
-
id: string;
|
|
901
|
-
title: string;
|
|
902
|
-
description: string | null;
|
|
903
|
-
scope: AchievementScopeType;
|
|
904
|
-
rewardCredits: number;
|
|
905
|
-
limit: number;
|
|
906
|
-
completionType: string;
|
|
907
|
-
completionConfig: unknown;
|
|
908
|
-
target: unknown;
|
|
909
|
-
active: boolean;
|
|
910
|
-
createdAt: Date | null;
|
|
911
|
-
updatedAt: Date | null;
|
|
912
|
-
status: 'available' | 'completed';
|
|
913
|
-
scopeKey: string;
|
|
914
|
-
windowStart?: string;
|
|
915
|
-
windowEnd?: string;
|
|
916
|
-
}
|
|
917
|
-
interface AchievementHistoryEntry {
|
|
918
|
-
achievementId: string;
|
|
919
|
-
title: string;
|
|
920
|
-
rewardCredits: number;
|
|
921
|
-
createdAt: Date;
|
|
922
|
-
scopeKey: string;
|
|
923
|
-
}
|
|
924
|
-
interface AchievementProgressResponse {
|
|
925
|
-
achievementId: string;
|
|
926
|
-
status: 'completed' | 'already_completed';
|
|
927
|
-
rewardCredits: number;
|
|
928
|
-
scopeKey: string;
|
|
929
|
-
createdAt: Date;
|
|
930
|
-
}
|
|
931
|
-
|
|
932
975
|
/**
|
|
933
|
-
*
|
|
934
|
-
*
|
|
935
|
-
* Literal types for inventory system. Database row types are in @playcademy/data/types.
|
|
976
|
+
* Possible connection states.
|
|
936
977
|
*
|
|
937
|
-
*
|
|
938
|
-
|
|
939
|
-
|
|
940
|
-
* Item categories available on the platform.
|
|
978
|
+
* - **online**: Connection is stable and healthy
|
|
979
|
+
* - **offline**: Complete loss of network connectivity
|
|
980
|
+
* - **degraded**: Connection is slow or experiencing intermittent issues
|
|
941
981
|
*/
|
|
942
|
-
type
|
|
982
|
+
type ConnectionState = 'online' | 'offline' | 'degraded';
|
|
943
983
|
|
|
944
984
|
/**
|
|
945
|
-
*
|
|
985
|
+
* Connection Manager
|
|
946
986
|
*
|
|
947
|
-
*
|
|
987
|
+
* Manages connection monitoring and integrates it with the Playcademy client.
|
|
988
|
+
* Handles event wiring, state management, and disconnect callbacks.
|
|
948
989
|
*
|
|
949
|
-
*
|
|
990
|
+
* In iframe mode, disables local monitoring and listens to platform connection
|
|
991
|
+
* state broadcasts instead (avoids duplicate heartbeats).
|
|
950
992
|
*/
|
|
993
|
+
|
|
951
994
|
/**
|
|
952
|
-
*
|
|
995
|
+
* Configuration for the ConnectionManager.
|
|
953
996
|
*/
|
|
954
|
-
|
|
955
|
-
/**
|
|
956
|
-
|
|
957
|
-
*/
|
|
958
|
-
|
|
959
|
-
|
|
960
|
-
|
|
961
|
-
|
|
962
|
-
|
|
963
|
-
|
|
964
|
-
|
|
965
|
-
[key: string]: unknown;
|
|
966
|
-
}
|
|
967
|
-
/**
|
|
968
|
-
* Metadata describing how an item should be placed on the map.
|
|
969
|
-
*/
|
|
970
|
-
interface PlaceableItemMetadata {
|
|
971
|
-
tilesWide?: number;
|
|
972
|
-
tilesHigh?: number;
|
|
973
|
-
flippable?: boolean;
|
|
974
|
-
[key: string]: unknown;
|
|
975
|
-
}
|
|
976
|
-
/**
|
|
977
|
-
* Simplified map data for API responses.
|
|
978
|
-
*/
|
|
979
|
-
interface MapData {
|
|
980
|
-
id: string;
|
|
981
|
-
identifier: string;
|
|
982
|
-
displayName: string;
|
|
983
|
-
description?: string | null;
|
|
984
|
-
metadata?: Record<string, unknown> | null;
|
|
997
|
+
interface ConnectionManagerConfig {
|
|
998
|
+
/** Base URL for API requests (used for heartbeat pings) */
|
|
999
|
+
baseUrl: string;
|
|
1000
|
+
/** Authentication context (iframe vs standalone) for alert routing */
|
|
1001
|
+
authContext?: {
|
|
1002
|
+
isInIframe: boolean;
|
|
1003
|
+
};
|
|
1004
|
+
/** Handler to call when connection issues are detected */
|
|
1005
|
+
onDisconnect?: DisconnectHandler;
|
|
1006
|
+
/** Callback to emit connection change events to the client */
|
|
1007
|
+
onConnectionChange?: (state: ConnectionState, reason: string) => void;
|
|
985
1008
|
}
|
|
986
1009
|
/**
|
|
987
|
-
*
|
|
1010
|
+
* Manages connection monitoring for the Playcademy client.
|
|
1011
|
+
*
|
|
1012
|
+
* The ConnectionManager serves as an integration layer between the low-level
|
|
1013
|
+
* ConnectionMonitor and the PlaycademyClient. It handles:
|
|
1014
|
+
* - Event wiring and coordination
|
|
1015
|
+
* - Disconnect callbacks with context
|
|
1016
|
+
* - Platform-level alert integration
|
|
1017
|
+
* - Request success/failure tracking
|
|
1018
|
+
*
|
|
1019
|
+
* This class is used internally by PlaycademyClient and typically not
|
|
1020
|
+
* instantiated directly by game developers.
|
|
1021
|
+
*
|
|
1022
|
+
* @see {@link ConnectionMonitor} for the underlying monitoring implementation
|
|
1023
|
+
* @see {@link PlaycademyClient.onDisconnect} for the public API
|
|
988
1024
|
*/
|
|
989
|
-
|
|
990
|
-
|
|
991
|
-
|
|
992
|
-
|
|
993
|
-
|
|
994
|
-
|
|
995
|
-
|
|
996
|
-
|
|
997
|
-
|
|
1025
|
+
declare class ConnectionManager {
|
|
1026
|
+
private monitor?;
|
|
1027
|
+
private authContext?;
|
|
1028
|
+
private disconnectHandler?;
|
|
1029
|
+
private connectionChangeCallback?;
|
|
1030
|
+
private currentState;
|
|
1031
|
+
private additionalDisconnectHandlers;
|
|
1032
|
+
/**
|
|
1033
|
+
* Creates a new ConnectionManager instance.
|
|
1034
|
+
*
|
|
1035
|
+
* @param config - Configuration options for the manager
|
|
1036
|
+
*
|
|
1037
|
+
* @example
|
|
1038
|
+
* ```typescript
|
|
1039
|
+
* const manager = new ConnectionManager({
|
|
1040
|
+
* baseUrl: 'https://api.playcademy.com',
|
|
1041
|
+
* authContext: { isInIframe: false },
|
|
1042
|
+
* onDisconnect: (context) => {
|
|
1043
|
+
* console.log(`Disconnected: ${context.state}`)
|
|
1044
|
+
* },
|
|
1045
|
+
* onConnectionChange: (state, reason) => {
|
|
1046
|
+
* console.log(`Connection changed: ${state}`)
|
|
1047
|
+
* }
|
|
1048
|
+
* })
|
|
1049
|
+
* ```
|
|
1050
|
+
*/
|
|
1051
|
+
constructor(config: ConnectionManagerConfig);
|
|
1052
|
+
/**
|
|
1053
|
+
* Gets the current connection state.
|
|
1054
|
+
*
|
|
1055
|
+
* @returns The current connection state ('online', 'offline', or 'degraded')
|
|
1056
|
+
*
|
|
1057
|
+
* @example
|
|
1058
|
+
* ```typescript
|
|
1059
|
+
* const state = manager.getState()
|
|
1060
|
+
* if (state === 'offline') {
|
|
1061
|
+
* console.log('No connection')
|
|
1062
|
+
* }
|
|
1063
|
+
* ```
|
|
1064
|
+
*/
|
|
1065
|
+
getState(): ConnectionState;
|
|
1066
|
+
/**
|
|
1067
|
+
* Manually triggers a connection check immediately.
|
|
1068
|
+
*
|
|
1069
|
+
* Forces a heartbeat ping to verify the current connection status.
|
|
1070
|
+
* Useful when you need to check connectivity before a critical operation.
|
|
1071
|
+
*
|
|
1072
|
+
* In iframe mode, this returns the last known state from platform.
|
|
1073
|
+
*
|
|
1074
|
+
* @returns Promise resolving to the current connection state
|
|
1075
|
+
*
|
|
1076
|
+
* @example
|
|
1077
|
+
* ```typescript
|
|
1078
|
+
* const state = await manager.checkNow()
|
|
1079
|
+
* if (state === 'online') {
|
|
1080
|
+
* await performCriticalOperation()
|
|
1081
|
+
* }
|
|
1082
|
+
* ```
|
|
1083
|
+
*/
|
|
1084
|
+
checkNow(): Promise<ConnectionState>;
|
|
1085
|
+
/**
|
|
1086
|
+
* Reports a successful API request to the connection monitor.
|
|
1087
|
+
*
|
|
1088
|
+
* This resets the consecutive failure counter and transitions from
|
|
1089
|
+
* 'degraded' to 'online' state if applicable.
|
|
1090
|
+
*
|
|
1091
|
+
* Typically called automatically by the SDK's request wrapper.
|
|
1092
|
+
* No-op in iframe mode (platform handles monitoring).
|
|
1093
|
+
*/
|
|
1094
|
+
reportRequestSuccess(): void;
|
|
1095
|
+
/**
|
|
1096
|
+
* Reports a failed API request to the connection monitor.
|
|
1097
|
+
*
|
|
1098
|
+
* Only network errors are tracked (not 4xx/5xx HTTP responses).
|
|
1099
|
+
* After consecutive failures exceed the threshold, the state transitions
|
|
1100
|
+
* to 'degraded' or 'offline'.
|
|
1101
|
+
*
|
|
1102
|
+
* Typically called automatically by the SDK's request wrapper.
|
|
1103
|
+
* No-op in iframe mode (platform handles monitoring).
|
|
1104
|
+
*
|
|
1105
|
+
* @param error - The error from the failed request
|
|
1106
|
+
*/
|
|
1107
|
+
reportRequestFailure(error: unknown): void;
|
|
1108
|
+
/**
|
|
1109
|
+
* Registers a callback to be called when connection issues are detected.
|
|
1110
|
+
*
|
|
1111
|
+
* The callback only fires for 'offline' and 'degraded' states, not when
|
|
1112
|
+
* recovering to 'online'. This provides a clean API for games to handle
|
|
1113
|
+
* disconnect scenarios without being notified of every state change.
|
|
1114
|
+
*
|
|
1115
|
+
* Works in both iframe and standalone modes transparently.
|
|
1116
|
+
*
|
|
1117
|
+
* @param callback - Function to call when connection degrades
|
|
1118
|
+
* @returns Cleanup function to unregister the callback
|
|
1119
|
+
*
|
|
1120
|
+
* @example
|
|
1121
|
+
* ```typescript
|
|
1122
|
+
* const cleanup = manager.onDisconnect(({ state, reason, displayAlert }) => {
|
|
1123
|
+
* if (state === 'offline') {
|
|
1124
|
+
* displayAlert?.('Connection lost. Saving your progress...', { type: 'error' })
|
|
1125
|
+
* saveGameState()
|
|
1126
|
+
* }
|
|
1127
|
+
* })
|
|
1128
|
+
*
|
|
1129
|
+
* // Later: cleanup() to unregister
|
|
1130
|
+
* ```
|
|
1131
|
+
*/
|
|
1132
|
+
onDisconnect(callback: DisconnectHandler): () => void;
|
|
1133
|
+
/**
|
|
1134
|
+
* Stops connection monitoring and performs cleanup.
|
|
1135
|
+
*
|
|
1136
|
+
* Removes event listeners and clears heartbeat intervals.
|
|
1137
|
+
* Should be called when the client is being destroyed.
|
|
1138
|
+
*/
|
|
1139
|
+
stop(): void;
|
|
1140
|
+
/**
|
|
1141
|
+
* Sets up listener for platform connection state broadcasts (iframe mode only).
|
|
1142
|
+
*/
|
|
1143
|
+
private _setupPlatformListener;
|
|
1144
|
+
/**
|
|
1145
|
+
* Handles connection state changes from the monitor or platform.
|
|
1146
|
+
*
|
|
1147
|
+
* Coordinates between:
|
|
1148
|
+
* 1. Emitting events to the client (for client.on('connectionChange'))
|
|
1149
|
+
* 2. Calling the disconnect handler if configured
|
|
1150
|
+
* 3. Calling any additional handlers registered via onDisconnect()
|
|
1151
|
+
*
|
|
1152
|
+
* @param state - The new connection state
|
|
1153
|
+
* @param reason - Human-readable reason for the state change
|
|
1154
|
+
*/
|
|
1155
|
+
private _handleConnectionChange;
|
|
998
1156
|
}
|
|
999
1157
|
|
|
1000
1158
|
/**
|
|
1001
|
-
*
|
|
1159
|
+
* @fileoverview Playcademy Messaging System
|
|
1002
1160
|
*
|
|
1003
|
-
*
|
|
1161
|
+
* This file implements a unified messaging system for the Playcademy platform that handles
|
|
1162
|
+
* communication between different contexts:
|
|
1004
1163
|
*
|
|
1005
|
-
*
|
|
1006
|
-
|
|
1007
|
-
/**
|
|
1008
|
-
* Character component categories.
|
|
1009
|
-
*/
|
|
1010
|
-
type CharacterComponentType = 'body' | 'outfit' | 'hairstyle' | 'eyes' | 'accessory';
|
|
1011
|
-
|
|
1012
|
-
/**
|
|
1013
|
-
* Level & Progression Types
|
|
1164
|
+
* 1. **Iframe-to-Parent Communication**: When games run inside iframes (production/development),
|
|
1165
|
+
* they need to communicate with the parent window using postMessage API
|
|
1014
1166
|
*
|
|
1015
|
-
*
|
|
1167
|
+
* 2. **Local Communication**: When games run in the same context (local development),
|
|
1168
|
+
* they use CustomEvents for internal messaging
|
|
1016
1169
|
*
|
|
1017
|
-
*
|
|
1018
|
-
|
|
1019
|
-
|
|
1020
|
-
*
|
|
1021
|
-
|
|
1022
|
-
|
|
1023
|
-
|
|
1024
|
-
|
|
1025
|
-
leveledUp: boolean;
|
|
1026
|
-
creditsAwarded: number;
|
|
1027
|
-
xpToNextLevel: number;
|
|
1028
|
-
}
|
|
1029
|
-
/**
|
|
1030
|
-
* Result of checking whether a level up occurred.
|
|
1031
|
-
*/
|
|
1032
|
-
interface LevelUpCheckResult {
|
|
1033
|
-
newLevel: number;
|
|
1034
|
-
remainingXp: number;
|
|
1035
|
-
leveledUp: boolean;
|
|
1036
|
-
creditsAwarded: number;
|
|
1037
|
-
xpToNextLevel: number;
|
|
1038
|
-
}
|
|
1039
|
-
/**
|
|
1040
|
-
* Level progress API response.
|
|
1170
|
+
* The system automatically detects the runtime environment and chooses the appropriate
|
|
1171
|
+
* transport method, abstracting this complexity from the developer.
|
|
1172
|
+
*
|
|
1173
|
+
* **Architecture Overview**:
|
|
1174
|
+
* - Games run in iframes for security and isolation
|
|
1175
|
+
* - Parent window (Playcademy shell) manages game lifecycle
|
|
1176
|
+
* - Messages flow bidirectionally between parent and iframe
|
|
1177
|
+
* - Local development mode simulates this architecture without iframes
|
|
1041
1178
|
*/
|
|
1042
|
-
interface LevelProgressResponse {
|
|
1043
|
-
level: number;
|
|
1044
|
-
currentXp: number;
|
|
1045
|
-
xpToNextLevel: number;
|
|
1046
|
-
totalXP: number;
|
|
1047
|
-
}
|
|
1048
1179
|
|
|
1049
1180
|
/**
|
|
1050
|
-
*
|
|
1181
|
+
* Enumeration of all message types used in the Playcademy messaging system.
|
|
1051
1182
|
*
|
|
1052
|
-
*
|
|
1053
|
-
|
|
1054
|
-
|
|
1055
|
-
|
|
1056
|
-
|
|
1057
|
-
|
|
1058
|
-
|
|
1059
|
-
|
|
1060
|
-
|
|
1061
|
-
|
|
1062
|
-
|
|
1063
|
-
|
|
1064
|
-
|
|
1065
|
-
|
|
1066
|
-
|
|
1067
|
-
|
|
1068
|
-
|
|
1069
|
-
|
|
1070
|
-
|
|
1071
|
-
|
|
1072
|
-
|
|
1073
|
-
|
|
1074
|
-
|
|
1075
|
-
|
|
1183
|
+
* **Message Flow Patterns**:
|
|
1184
|
+
*
|
|
1185
|
+
* **Parent → Game (Overworld → Game)**:
|
|
1186
|
+
* - INIT: Provides game with authentication token and configuration
|
|
1187
|
+
* - TOKEN_REFRESH: Updates game's authentication token before expiry
|
|
1188
|
+
* - PAUSE/RESUME: Controls game execution state
|
|
1189
|
+
* - FORCE_EXIT: Immediately terminates the game
|
|
1190
|
+
* - OVERLAY: Shows/hides UI overlays over the game
|
|
1191
|
+
*
|
|
1192
|
+
* **Game → Parent (Game → Overworld)**:
|
|
1193
|
+
* - READY: Game has loaded and is ready to receive messages
|
|
1194
|
+
* - EXIT: Game requests to be closed (user clicked exit, game ended, etc.)
|
|
1195
|
+
* - TELEMETRY: Game reports performance metrics (FPS, memory usage, etc.)
|
|
1196
|
+
*/
|
|
1197
|
+
declare enum MessageEvents {
|
|
1198
|
+
/**
|
|
1199
|
+
* Initializes the game with authentication context and configuration.
|
|
1200
|
+
* Sent immediately after game iframe loads.
|
|
1201
|
+
* Payload:
|
|
1202
|
+
* - `baseUrl`: string
|
|
1203
|
+
* - `token`: string
|
|
1204
|
+
* - `gameId`: string
|
|
1205
|
+
*/
|
|
1206
|
+
INIT = "PLAYCADEMY_INIT",
|
|
1207
|
+
/**
|
|
1208
|
+
* Updates the game's authentication token before it expires.
|
|
1209
|
+
* Sent periodically to maintain valid authentication.
|
|
1210
|
+
* Payload:
|
|
1211
|
+
* - `token`: string
|
|
1212
|
+
* - `exp`: number
|
|
1213
|
+
*/
|
|
1214
|
+
TOKEN_REFRESH = "PLAYCADEMY_TOKEN_REFRESH",
|
|
1215
|
+
/**
|
|
1216
|
+
* Pauses game execution (e.g., when user switches tabs).
|
|
1217
|
+
* Game should pause timers, animations, and user input.
|
|
1218
|
+
* Payload: void
|
|
1219
|
+
*/
|
|
1220
|
+
PAUSE = "PLAYCADEMY_PAUSE",
|
|
1221
|
+
/**
|
|
1222
|
+
* Resumes game execution after being paused.
|
|
1223
|
+
* Game should restore timers, animations, and user input.
|
|
1224
|
+
* Payload: void
|
|
1225
|
+
*/
|
|
1226
|
+
RESUME = "PLAYCADEMY_RESUME",
|
|
1227
|
+
/**
|
|
1228
|
+
* Forces immediate game termination (emergency exit).
|
|
1229
|
+
* Game should clean up resources and exit immediately.
|
|
1230
|
+
* Payload: void
|
|
1231
|
+
*/
|
|
1232
|
+
FORCE_EXIT = "PLAYCADEMY_FORCE_EXIT",
|
|
1233
|
+
/**
|
|
1234
|
+
* Shows or hides UI overlays over the game.
|
|
1235
|
+
* Game may need to pause or adjust rendering accordingly.
|
|
1236
|
+
* Payload: boolean (true = show overlay, false = hide overlay)
|
|
1237
|
+
*/
|
|
1238
|
+
OVERLAY = "PLAYCADEMY_OVERLAY",
|
|
1239
|
+
/**
|
|
1240
|
+
* Broadcasts connection state changes to games.
|
|
1241
|
+
* Sent by platform when network connectivity changes.
|
|
1242
|
+
* Payload:
|
|
1243
|
+
* - `state`: 'online' | 'offline' | 'degraded'
|
|
1244
|
+
* - `reason`: string
|
|
1245
|
+
*/
|
|
1246
|
+
CONNECTION_STATE = "PLAYCADEMY_CONNECTION_STATE",
|
|
1247
|
+
/**
|
|
1248
|
+
* Game has finished loading and is ready to receive messages.
|
|
1249
|
+
* Sent once after game initialization is complete.
|
|
1250
|
+
* Payload: void
|
|
1251
|
+
*/
|
|
1252
|
+
READY = "PLAYCADEMY_READY",
|
|
1253
|
+
/**
|
|
1254
|
+
* Game SDK initialization failed.
|
|
1255
|
+
* Sent when the game iframe fails to complete SDK init (e.g.
|
|
1256
|
+
* origin validation failure, INIT timeout, client creation error).
|
|
1257
|
+
* Payload:
|
|
1258
|
+
* - `reason`: string — human-readable failure description
|
|
1259
|
+
*/
|
|
1260
|
+
INIT_ERROR = "PLAYCADEMY_INIT_ERROR",
|
|
1261
|
+
/**
|
|
1262
|
+
* Game requests to be closed/exited.
|
|
1263
|
+
* Sent when user clicks exit button or game naturally ends.
|
|
1264
|
+
* Payload: void
|
|
1265
|
+
*/
|
|
1266
|
+
EXIT = "PLAYCADEMY_EXIT",
|
|
1267
|
+
/**
|
|
1268
|
+
* Game reports performance telemetry data.
|
|
1269
|
+
* Sent periodically for monitoring and analytics.
|
|
1270
|
+
* Payload:
|
|
1271
|
+
* - `fps`: number
|
|
1272
|
+
* - `mem`: number
|
|
1273
|
+
*/
|
|
1274
|
+
TELEMETRY = "PLAYCADEMY_TELEMETRY",
|
|
1275
|
+
/**
|
|
1276
|
+
* Game reports key events to parent.
|
|
1277
|
+
* Sent when certain keys are pressed within the game iframe.
|
|
1278
|
+
* Payload:
|
|
1279
|
+
* - `key`: string
|
|
1280
|
+
* - `code?`: string
|
|
1281
|
+
* - `type`: 'keydown' | 'keyup'
|
|
1282
|
+
*/
|
|
1283
|
+
KEY_EVENT = "PLAYCADEMY_KEY_EVENT",
|
|
1284
|
+
/**
|
|
1285
|
+
* Game requests platform to display an alert.
|
|
1286
|
+
* Sent when connection issues are detected or other important events occur.
|
|
1287
|
+
* Payload:
|
|
1288
|
+
* - `message`: string
|
|
1289
|
+
* - `options`: `{ type?: 'info' | 'warning' | 'error', duration?: number }`
|
|
1290
|
+
*/
|
|
1291
|
+
DISPLAY_ALERT = "PLAYCADEMY_DISPLAY_ALERT",
|
|
1292
|
+
/**
|
|
1293
|
+
* Game signals that demo mode has ended.
|
|
1294
|
+
* Sent when a demo experience reaches its CTA/upgrade boundary.
|
|
1295
|
+
* Payload:
|
|
1296
|
+
* - `score?`: number
|
|
1297
|
+
* - `durationMs?`: number
|
|
1298
|
+
* - `metadata?`: `Record<string, unknown>`
|
|
1299
|
+
*/
|
|
1300
|
+
DEMO_END = "PLAYCADEMY_DEMO_END",
|
|
1301
|
+
/**
|
|
1302
|
+
* Notifies about authentication state changes.
|
|
1303
|
+
* Can be sent in both directions depending on auth flow.
|
|
1304
|
+
* Payload:
|
|
1305
|
+
* - `authenticated`: boolean
|
|
1306
|
+
* - `user`: UserInfo | null
|
|
1307
|
+
* - `error`: Error | null
|
|
1308
|
+
*/
|
|
1309
|
+
AUTH_STATE_CHANGE = "PLAYCADEMY_AUTH_STATE_CHANGE",
|
|
1310
|
+
/**
|
|
1311
|
+
* OAuth callback data from popup/new-tab windows.
|
|
1312
|
+
* Sent from popup window back to parent after OAuth completes.
|
|
1313
|
+
* Payload:
|
|
1314
|
+
* - `code`: string (OAuth authorization code)
|
|
1315
|
+
* - `state`: string (OAuth state for CSRF protection)
|
|
1316
|
+
* - `error`: string | null (OAuth error if any)
|
|
1317
|
+
*/
|
|
1318
|
+
AUTH_CALLBACK = "PLAYCADEMY_AUTH_CALLBACK"
|
|
1076
1319
|
}
|
|
1077
1320
|
|
|
1078
1321
|
/**
|
|
1079
|
-
*
|
|
1080
|
-
*
|
|
1081
|
-
* @module types/shop
|
|
1322
|
+
* Cache configuration types for runtime customization
|
|
1082
1323
|
*/
|
|
1083
1324
|
/**
|
|
1084
|
-
*
|
|
1325
|
+
* Runtime configuration for TTL cache behavior
|
|
1085
1326
|
*/
|
|
1086
|
-
interface
|
|
1087
|
-
|
|
1088
|
-
|
|
1089
|
-
|
|
1090
|
-
|
|
1091
|
-
|
|
1327
|
+
interface TTLCacheConfig {
|
|
1328
|
+
/** Time-to-live in milliseconds. Set to 0 to disable caching for this call. */
|
|
1329
|
+
ttl?: number;
|
|
1330
|
+
/** Force refresh, bypassing cache */
|
|
1331
|
+
force?: boolean;
|
|
1332
|
+
/** Skip cache and fetch fresh data (alias for force) */
|
|
1333
|
+
skipCache?: boolean;
|
|
1092
1334
|
}
|
|
1335
|
+
|
|
1093
1336
|
/**
|
|
1094
|
-
*
|
|
1095
|
-
*
|
|
1337
|
+
* @fileoverview Server SDK Type Definitions
|
|
1338
|
+
*
|
|
1339
|
+
* TypeScript type definitions for the server-side Playcademy SDK.
|
|
1340
|
+
* Includes configuration types, client state, and re-exported TimeBack types.
|
|
1096
1341
|
*/
|
|
1097
|
-
|
|
1098
|
-
|
|
1099
|
-
|
|
1100
|
-
|
|
1101
|
-
|
|
1102
|
-
|
|
1103
|
-
|
|
1104
|
-
|
|
1105
|
-
|
|
1106
|
-
|
|
1107
|
-
|
|
1108
|
-
|
|
1109
|
-
|
|
1110
|
-
|
|
1111
|
-
|
|
1112
|
-
|
|
1113
|
-
|
|
1114
|
-
|
|
1342
|
+
|
|
1343
|
+
/**
|
|
1344
|
+
* Base configuration for TimeBack integration (shared across all courses).
|
|
1345
|
+
* References upstream TimeBack types from @playcademy/timeback.
|
|
1346
|
+
*
|
|
1347
|
+
* All fields are optional and support template variables: {grade}, {subject}, {gameSlug}
|
|
1348
|
+
*/
|
|
1349
|
+
interface TimebackBaseConfig {
|
|
1350
|
+
/** Organization configuration (shared across all courses) */
|
|
1351
|
+
organization?: Partial<OrganizationConfig>;
|
|
1352
|
+
/** Course defaults (can be overridden per-course) */
|
|
1353
|
+
course?: Partial<CourseConfig>;
|
|
1354
|
+
/** Component defaults */
|
|
1355
|
+
component?: Partial<ComponentConfig>;
|
|
1356
|
+
/** Resource defaults */
|
|
1357
|
+
resource?: Partial<ResourceConfig>;
|
|
1358
|
+
/** ComponentResource defaults */
|
|
1359
|
+
componentResource?: Partial<ComponentResourceConfig>;
|
|
1115
1360
|
}
|
|
1116
1361
|
/**
|
|
1117
|
-
*
|
|
1362
|
+
* Extended course configuration that merges TimebackCourseConfig with per-course overrides.
|
|
1363
|
+
* Used in playcademy.config.* to allow per-course customization.
|
|
1118
1364
|
*/
|
|
1119
|
-
interface
|
|
1120
|
-
|
|
1121
|
-
|
|
1365
|
+
interface TimebackCourseConfigWithOverrides extends TimebackCourseConfig {
|
|
1366
|
+
title?: string;
|
|
1367
|
+
courseCode?: string;
|
|
1368
|
+
level?: string;
|
|
1369
|
+
metadata?: CourseConfig['metadata'];
|
|
1370
|
+
totalXp?: number | null;
|
|
1371
|
+
masterableUnits?: number | null;
|
|
1122
1372
|
}
|
|
1123
|
-
|
|
1124
1373
|
/**
|
|
1125
|
-
*
|
|
1374
|
+
* TimeBack integration configuration for Playcademy config file.
|
|
1126
1375
|
*
|
|
1127
|
-
*
|
|
1376
|
+
* Supports two levels of customization:
|
|
1377
|
+
* 1. `base`: Shared defaults for all courses (organization, course, component, resource, componentResource)
|
|
1378
|
+
* 2. Per-course overrides in the `courses` array (title, courseCode, level, gradingScheme, metadata)
|
|
1128
1379
|
*
|
|
1129
|
-
*
|
|
1130
|
-
*/
|
|
1131
|
-
/**
|
|
1132
|
-
* Animation frame configuration.
|
|
1380
|
+
* Template variables ({grade}, {subject}, {gameSlug}) can be used in string fields.
|
|
1133
1381
|
*/
|
|
1134
|
-
interface
|
|
1135
|
-
|
|
1136
|
-
|
|
1137
|
-
|
|
1138
|
-
|
|
1382
|
+
interface TimebackIntegrationConfig {
|
|
1383
|
+
/** Multi-grade course configuration (array of grade/subject/totalXp with optional per-course overrides) */
|
|
1384
|
+
courses: TimebackCourseConfigWithOverrides[];
|
|
1385
|
+
/** Optional base configuration (shared across all courses, can be overridden per-course) */
|
|
1386
|
+
base?: TimebackBaseConfig;
|
|
1139
1387
|
}
|
|
1140
1388
|
/**
|
|
1141
|
-
*
|
|
1389
|
+
* Custom API routes integration
|
|
1142
1390
|
*/
|
|
1143
|
-
interface
|
|
1144
|
-
|
|
1145
|
-
|
|
1146
|
-
columns: number;
|
|
1147
|
-
rows: number;
|
|
1148
|
-
spacing: number;
|
|
1149
|
-
animations: {
|
|
1150
|
-
base_right: SpriteAnimationFrame;
|
|
1151
|
-
base_up: SpriteAnimationFrame;
|
|
1152
|
-
base_left: SpriteAnimationFrame;
|
|
1153
|
-
base_down: SpriteAnimationFrame;
|
|
1154
|
-
idle_right: SpriteAnimationFrame;
|
|
1155
|
-
walk_right: SpriteAnimationFrame;
|
|
1156
|
-
idle_up: SpriteAnimationFrame;
|
|
1157
|
-
walk_up: SpriteAnimationFrame;
|
|
1158
|
-
idle_left: SpriteAnimationFrame;
|
|
1159
|
-
walk_left: SpriteAnimationFrame;
|
|
1160
|
-
idle_down: SpriteAnimationFrame;
|
|
1161
|
-
walk_down: SpriteAnimationFrame;
|
|
1162
|
-
};
|
|
1391
|
+
interface CustomRoutesIntegration {
|
|
1392
|
+
/** Directory for custom API routes (defaults to 'server/api') */
|
|
1393
|
+
directory?: string;
|
|
1163
1394
|
}
|
|
1164
1395
|
/**
|
|
1165
|
-
*
|
|
1396
|
+
* Database integration
|
|
1166
1397
|
*/
|
|
1167
|
-
interface
|
|
1168
|
-
|
|
1169
|
-
|
|
1170
|
-
|
|
1171
|
-
|
|
1172
|
-
|
|
1173
|
-
|
|
1398
|
+
interface DatabaseIntegration {
|
|
1399
|
+
/** Database directory (defaults to 'db') */
|
|
1400
|
+
directory?: string;
|
|
1401
|
+
/** Schema strategy: 'push' uses drizzle-kit push-style diffing, 'migrate' uses migration files.
|
|
1402
|
+
* When omitted, auto-detects based on presence of a migrations directory with _journal.json. */
|
|
1403
|
+
strategy?: 'push' | 'migrate';
|
|
1404
|
+
}
|
|
1405
|
+
interface QueueConfig {
|
|
1406
|
+
maxBatchSize?: number;
|
|
1407
|
+
maxRetries?: number;
|
|
1408
|
+
maxBatchTimeout?: number;
|
|
1409
|
+
maxConcurrency?: number;
|
|
1410
|
+
retryDelay?: number;
|
|
1411
|
+
deadLetterQueue?: string;
|
|
1412
|
+
}
|
|
1413
|
+
/**
|
|
1414
|
+
* Integrations configuration
|
|
1415
|
+
* All backend features (database, custom routes, external services) are configured here
|
|
1416
|
+
*/
|
|
1417
|
+
interface IntegrationsConfig {
|
|
1418
|
+
/** TimeBack integration (optional) */
|
|
1419
|
+
timeback?: TimebackIntegrationConfig | null;
|
|
1420
|
+
/** Custom API routes (optional) */
|
|
1421
|
+
customRoutes?: CustomRoutesIntegration | boolean;
|
|
1422
|
+
/** Database (optional) */
|
|
1423
|
+
database?: DatabaseIntegration | boolean;
|
|
1424
|
+
/** Key-Value storage (optional) */
|
|
1425
|
+
kv?: boolean;
|
|
1426
|
+
/** Bucket storage (optional) */
|
|
1427
|
+
bucket?: boolean;
|
|
1428
|
+
/** Authentication (optional) */
|
|
1429
|
+
auth?: boolean;
|
|
1430
|
+
/** Queues (optional) */
|
|
1431
|
+
queues?: Record<string, QueueConfig | boolean>;
|
|
1432
|
+
}
|
|
1433
|
+
/**
|
|
1434
|
+
* Unified Playcademy configuration
|
|
1435
|
+
* Used for playcademy.config.{js,json}
|
|
1436
|
+
*/
|
|
1437
|
+
interface PlaycademyConfig {
|
|
1438
|
+
/** Game name */
|
|
1439
|
+
name: string;
|
|
1440
|
+
/** Game description */
|
|
1441
|
+
description?: string;
|
|
1442
|
+
/** Game emoji icon */
|
|
1443
|
+
emoji?: string;
|
|
1444
|
+
/** Build command to run before deployment */
|
|
1445
|
+
buildCommand?: string[];
|
|
1446
|
+
/** Path to build output */
|
|
1447
|
+
buildPath?: string;
|
|
1448
|
+
/** Game type */
|
|
1449
|
+
gameType?: 'hosted' | 'external';
|
|
1450
|
+
/** External URL (for external games) */
|
|
1451
|
+
externalUrl?: string;
|
|
1452
|
+
/** Game platform */
|
|
1453
|
+
platform?: 'web' | 'unity' | 'godot';
|
|
1454
|
+
/** Integrations (database, custom routes, external services) */
|
|
1455
|
+
integrations?: IntegrationsConfig;
|
|
1456
|
+
}
|
|
1457
|
+
|
|
1458
|
+
/**
|
|
1459
|
+
* Configuration options for initializing a PlaycademyClient instance.
|
|
1460
|
+
*
|
|
1461
|
+
* @example
|
|
1462
|
+
* ```typescript
|
|
1463
|
+
* const config: PlaycademyServerClientConfig = {
|
|
1464
|
+
* apiKey: process.env.PLAYCADEMY_API_KEY!,
|
|
1465
|
+
* gameId: 'my-math-game',
|
|
1466
|
+
* configPath: './playcademy.config.js'
|
|
1467
|
+
* }
|
|
1468
|
+
* ```
|
|
1469
|
+
*/
|
|
1470
|
+
interface PlaycademyServerClientConfig {
|
|
1471
|
+
/**
|
|
1472
|
+
* Playcademy API key for server-to-server authentication.
|
|
1473
|
+
* Obtain from the Playcademy developer dashboard.
|
|
1474
|
+
*/
|
|
1475
|
+
apiKey: string;
|
|
1476
|
+
/**
|
|
1477
|
+
* Optional path to playcademy.config.js file.
|
|
1478
|
+
* If not provided, searches current directory and up to 3 parent directories.
|
|
1479
|
+
* Ignored if `config` is provided directly.
|
|
1480
|
+
*
|
|
1481
|
+
* @example './config/playcademy.config.js'
|
|
1482
|
+
*/
|
|
1483
|
+
configPath?: string;
|
|
1484
|
+
/**
|
|
1485
|
+
* Optional config object (for edge environments without filesystem).
|
|
1486
|
+
* If provided, skips filesystem-based config loading.
|
|
1487
|
+
*
|
|
1488
|
+
* @example { name: 'My Game', integrations: { timeback: {...} } }
|
|
1489
|
+
*/
|
|
1490
|
+
config?: PlaycademyConfig;
|
|
1491
|
+
/**
|
|
1492
|
+
* Optional base URL for Playcademy API.
|
|
1493
|
+
* Defaults to environment variables or 'https://hub.playcademy.net'.
|
|
1494
|
+
*
|
|
1495
|
+
* @example 'http://localhost:3000' for local development
|
|
1496
|
+
*/
|
|
1497
|
+
baseUrl?: string;
|
|
1498
|
+
/**
|
|
1499
|
+
* Optional game ID.
|
|
1500
|
+
* If not provided, will attempt to fetch from API using the API token.
|
|
1501
|
+
*
|
|
1502
|
+
* @example 'my-math-game'
|
|
1503
|
+
*/
|
|
1504
|
+
gameId?: string;
|
|
1505
|
+
}
|
|
1506
|
+
/**
|
|
1507
|
+
* Internal state maintained by the PlaycademyClient instance.
|
|
1508
|
+
*
|
|
1509
|
+
* @internal
|
|
1510
|
+
*/
|
|
1511
|
+
interface PlaycademyServerClientState {
|
|
1512
|
+
/** API key for authentication */
|
|
1513
|
+
apiKey: string;
|
|
1514
|
+
/** Base URL for API requests */
|
|
1515
|
+
baseUrl: string;
|
|
1516
|
+
/** Game identifier */
|
|
1517
|
+
gameId: string;
|
|
1518
|
+
/** Loaded game configuration from playcademy.config.js */
|
|
1519
|
+
config: PlaycademyConfig;
|
|
1520
|
+
/**
|
|
1521
|
+
* TimeBack course ID fetched from the Playcademy API.
|
|
1522
|
+
* Used for all TimeBack event recording.
|
|
1523
|
+
*/
|
|
1524
|
+
courseId?: string;
|
|
1174
1525
|
}
|
|
1175
1526
|
|
|
1176
1527
|
declare const users: drizzle_orm_pg_core.PgTableWithColumns<{
|
|
@@ -4683,466 +5034,50 @@ interface PlayerLocation {
|
|
|
4683
5034
|
interface PlayerSessionPayload {
|
|
4684
5035
|
profile: PlayerProfile;
|
|
4685
5036
|
currencies: PlayerCurrency[];
|
|
4686
|
-
inventory: PlayerInventoryItem[];
|
|
4687
|
-
ownedGameIds: Game['id'][];
|
|
4688
|
-
currentLocation?: PlayerLocation;
|
|
4689
|
-
characterCreated?: UserRow['characterCreated'];
|
|
4690
|
-
playerCharacter?: PlayerCharacterRow | null;
|
|
4691
|
-
}
|
|
4692
|
-
/**
|
|
4693
|
-
* Map-related Composite Types
|
|
4694
|
-
* DB row + joined game/item data
|
|
4695
|
-
*/
|
|
4696
|
-
type MapElementWithGame = MapElementRow & {
|
|
4697
|
-
game: {
|
|
4698
|
-
id: string;
|
|
4699
|
-
displayName: string;
|
|
4700
|
-
} | null;
|
|
4701
|
-
};
|
|
4702
|
-
type MapObjectWithItem = MapObjectRow & {
|
|
4703
|
-
item: {
|
|
4704
|
-
id: string;
|
|
4705
|
-
slug: string;
|
|
4706
|
-
displayName: string;
|
|
4707
|
-
description?: string | null;
|
|
4708
|
-
imageUrl?: string | null;
|
|
4709
|
-
isPlaceable: boolean;
|
|
4710
|
-
metadata?: PlaceableItemMetadata | null;
|
|
4711
|
-
};
|
|
4712
|
-
};
|
|
4713
|
-
/**
|
|
4714
|
-
* Game custom hostname with validation records
|
|
4715
|
-
*/
|
|
4716
|
-
type GameCustomHostname = GameCustomHostnameRow & {
|
|
4717
|
-
validationRecords?: DomainValidationRecords;
|
|
4718
|
-
};
|
|
4719
|
-
|
|
4720
|
-
type UserLevelRow = typeof userLevels.$inferSelect;
|
|
4721
|
-
type LevelConfigRow = typeof levelConfigs.$inferSelect;
|
|
4722
|
-
type UserLevelWithConfig = UserLevelRow & {
|
|
4723
|
-
xpToNextLevel: number;
|
|
4724
|
-
nextLevelConfig?: LevelConfigRow;
|
|
4725
|
-
};
|
|
4726
|
-
|
|
4727
|
-
type SpriteTemplateRow = typeof spriteTemplates.$inferSelect;
|
|
4728
|
-
|
|
4729
|
-
type NotificationRow = InferSelectModel<typeof notifications>;
|
|
4730
|
-
|
|
4731
|
-
/**
|
|
4732
|
-
* Connection monitoring types
|
|
4733
|
-
*
|
|
4734
|
-
* Type definitions for connection state, configuration, and callbacks.
|
|
4735
|
-
*/
|
|
4736
|
-
/**
|
|
4737
|
-
* Possible connection states.
|
|
4738
|
-
*
|
|
4739
|
-
* - **online**: Connection is stable and healthy
|
|
4740
|
-
* - **offline**: Complete loss of network connectivity
|
|
4741
|
-
* - **degraded**: Connection is slow or experiencing intermittent issues
|
|
4742
|
-
*/
|
|
4743
|
-
type ConnectionState = 'online' | 'offline' | 'degraded';
|
|
4744
|
-
|
|
4745
|
-
/**
|
|
4746
|
-
* Connection Manager
|
|
4747
|
-
*
|
|
4748
|
-
* Manages connection monitoring and integrates it with the Playcademy client.
|
|
4749
|
-
* Handles event wiring, state management, and disconnect callbacks.
|
|
4750
|
-
*
|
|
4751
|
-
* In iframe mode, disables local monitoring and listens to platform connection
|
|
4752
|
-
* state broadcasts instead (avoids duplicate heartbeats).
|
|
4753
|
-
*/
|
|
4754
|
-
|
|
4755
|
-
/**
|
|
4756
|
-
* Configuration for the ConnectionManager.
|
|
4757
|
-
*/
|
|
4758
|
-
interface ConnectionManagerConfig {
|
|
4759
|
-
/** Base URL for API requests (used for heartbeat pings) */
|
|
4760
|
-
baseUrl: string;
|
|
4761
|
-
/** Authentication context (iframe vs standalone) for alert routing */
|
|
4762
|
-
authContext?: {
|
|
4763
|
-
isInIframe: boolean;
|
|
4764
|
-
};
|
|
4765
|
-
/** Handler to call when connection issues are detected */
|
|
4766
|
-
onDisconnect?: DisconnectHandler;
|
|
4767
|
-
/** Callback to emit connection change events to the client */
|
|
4768
|
-
onConnectionChange?: (state: ConnectionState, reason: string) => void;
|
|
4769
|
-
}
|
|
4770
|
-
/**
|
|
4771
|
-
* Manages connection monitoring for the Playcademy client.
|
|
4772
|
-
*
|
|
4773
|
-
* The ConnectionManager serves as an integration layer between the low-level
|
|
4774
|
-
* ConnectionMonitor and the PlaycademyClient. It handles:
|
|
4775
|
-
* - Event wiring and coordination
|
|
4776
|
-
* - Disconnect callbacks with context
|
|
4777
|
-
* - Platform-level alert integration
|
|
4778
|
-
* - Request success/failure tracking
|
|
4779
|
-
*
|
|
4780
|
-
* This class is used internally by PlaycademyClient and typically not
|
|
4781
|
-
* instantiated directly by game developers.
|
|
4782
|
-
*
|
|
4783
|
-
* @see {@link ConnectionMonitor} for the underlying monitoring implementation
|
|
4784
|
-
* @see {@link PlaycademyClient.onDisconnect} for the public API
|
|
4785
|
-
*/
|
|
4786
|
-
declare class ConnectionManager {
|
|
4787
|
-
private monitor?;
|
|
4788
|
-
private authContext?;
|
|
4789
|
-
private disconnectHandler?;
|
|
4790
|
-
private connectionChangeCallback?;
|
|
4791
|
-
private currentState;
|
|
4792
|
-
private additionalDisconnectHandlers;
|
|
4793
|
-
/**
|
|
4794
|
-
* Creates a new ConnectionManager instance.
|
|
4795
|
-
*
|
|
4796
|
-
* @param config - Configuration options for the manager
|
|
4797
|
-
*
|
|
4798
|
-
* @example
|
|
4799
|
-
* ```typescript
|
|
4800
|
-
* const manager = new ConnectionManager({
|
|
4801
|
-
* baseUrl: 'https://api.playcademy.com',
|
|
4802
|
-
* authContext: { isInIframe: false },
|
|
4803
|
-
* onDisconnect: (context) => {
|
|
4804
|
-
* console.log(`Disconnected: ${context.state}`)
|
|
4805
|
-
* },
|
|
4806
|
-
* onConnectionChange: (state, reason) => {
|
|
4807
|
-
* console.log(`Connection changed: ${state}`)
|
|
4808
|
-
* }
|
|
4809
|
-
* })
|
|
4810
|
-
* ```
|
|
4811
|
-
*/
|
|
4812
|
-
constructor(config: ConnectionManagerConfig);
|
|
4813
|
-
/**
|
|
4814
|
-
* Gets the current connection state.
|
|
4815
|
-
*
|
|
4816
|
-
* @returns The current connection state ('online', 'offline', or 'degraded')
|
|
4817
|
-
*
|
|
4818
|
-
* @example
|
|
4819
|
-
* ```typescript
|
|
4820
|
-
* const state = manager.getState()
|
|
4821
|
-
* if (state === 'offline') {
|
|
4822
|
-
* console.log('No connection')
|
|
4823
|
-
* }
|
|
4824
|
-
* ```
|
|
4825
|
-
*/
|
|
4826
|
-
getState(): ConnectionState;
|
|
4827
|
-
/**
|
|
4828
|
-
* Manually triggers a connection check immediately.
|
|
4829
|
-
*
|
|
4830
|
-
* Forces a heartbeat ping to verify the current connection status.
|
|
4831
|
-
* Useful when you need to check connectivity before a critical operation.
|
|
4832
|
-
*
|
|
4833
|
-
* In iframe mode, this returns the last known state from platform.
|
|
4834
|
-
*
|
|
4835
|
-
* @returns Promise resolving to the current connection state
|
|
4836
|
-
*
|
|
4837
|
-
* @example
|
|
4838
|
-
* ```typescript
|
|
4839
|
-
* const state = await manager.checkNow()
|
|
4840
|
-
* if (state === 'online') {
|
|
4841
|
-
* await performCriticalOperation()
|
|
4842
|
-
* }
|
|
4843
|
-
* ```
|
|
4844
|
-
*/
|
|
4845
|
-
checkNow(): Promise<ConnectionState>;
|
|
4846
|
-
/**
|
|
4847
|
-
* Reports a successful API request to the connection monitor.
|
|
4848
|
-
*
|
|
4849
|
-
* This resets the consecutive failure counter and transitions from
|
|
4850
|
-
* 'degraded' to 'online' state if applicable.
|
|
4851
|
-
*
|
|
4852
|
-
* Typically called automatically by the SDK's request wrapper.
|
|
4853
|
-
* No-op in iframe mode (platform handles monitoring).
|
|
4854
|
-
*/
|
|
4855
|
-
reportRequestSuccess(): void;
|
|
4856
|
-
/**
|
|
4857
|
-
* Reports a failed API request to the connection monitor.
|
|
4858
|
-
*
|
|
4859
|
-
* Only network errors are tracked (not 4xx/5xx HTTP responses).
|
|
4860
|
-
* After consecutive failures exceed the threshold, the state transitions
|
|
4861
|
-
* to 'degraded' or 'offline'.
|
|
4862
|
-
*
|
|
4863
|
-
* Typically called automatically by the SDK's request wrapper.
|
|
4864
|
-
* No-op in iframe mode (platform handles monitoring).
|
|
4865
|
-
*
|
|
4866
|
-
* @param error - The error from the failed request
|
|
4867
|
-
*/
|
|
4868
|
-
reportRequestFailure(error: unknown): void;
|
|
4869
|
-
/**
|
|
4870
|
-
* Registers a callback to be called when connection issues are detected.
|
|
4871
|
-
*
|
|
4872
|
-
* The callback only fires for 'offline' and 'degraded' states, not when
|
|
4873
|
-
* recovering to 'online'. This provides a clean API for games to handle
|
|
4874
|
-
* disconnect scenarios without being notified of every state change.
|
|
4875
|
-
*
|
|
4876
|
-
* Works in both iframe and standalone modes transparently.
|
|
4877
|
-
*
|
|
4878
|
-
* @param callback - Function to call when connection degrades
|
|
4879
|
-
* @returns Cleanup function to unregister the callback
|
|
4880
|
-
*
|
|
4881
|
-
* @example
|
|
4882
|
-
* ```typescript
|
|
4883
|
-
* const cleanup = manager.onDisconnect(({ state, reason, displayAlert }) => {
|
|
4884
|
-
* if (state === 'offline') {
|
|
4885
|
-
* displayAlert?.('Connection lost. Saving your progress...', { type: 'error' })
|
|
4886
|
-
* saveGameState()
|
|
4887
|
-
* }
|
|
4888
|
-
* })
|
|
4889
|
-
*
|
|
4890
|
-
* // Later: cleanup() to unregister
|
|
4891
|
-
* ```
|
|
4892
|
-
*/
|
|
4893
|
-
onDisconnect(callback: DisconnectHandler): () => void;
|
|
4894
|
-
/**
|
|
4895
|
-
* Stops connection monitoring and performs cleanup.
|
|
4896
|
-
*
|
|
4897
|
-
* Removes event listeners and clears heartbeat intervals.
|
|
4898
|
-
* Should be called when the client is being destroyed.
|
|
4899
|
-
*/
|
|
4900
|
-
stop(): void;
|
|
4901
|
-
/**
|
|
4902
|
-
* Sets up listener for platform connection state broadcasts (iframe mode only).
|
|
4903
|
-
*/
|
|
4904
|
-
private _setupPlatformListener;
|
|
4905
|
-
/**
|
|
4906
|
-
* Handles connection state changes from the monitor or platform.
|
|
4907
|
-
*
|
|
4908
|
-
* Coordinates between:
|
|
4909
|
-
* 1. Emitting events to the client (for client.on('connectionChange'))
|
|
4910
|
-
* 2. Calling the disconnect handler if configured
|
|
4911
|
-
* 3. Calling any additional handlers registered via onDisconnect()
|
|
4912
|
-
*
|
|
4913
|
-
* @param state - The new connection state
|
|
4914
|
-
* @param reason - Human-readable reason for the state change
|
|
4915
|
-
*/
|
|
4916
|
-
private _handleConnectionChange;
|
|
4917
|
-
}
|
|
4918
|
-
|
|
4919
|
-
/**
|
|
4920
|
-
* @fileoverview Playcademy Messaging System
|
|
4921
|
-
*
|
|
4922
|
-
* This file implements a unified messaging system for the Playcademy platform that handles
|
|
4923
|
-
* communication between different contexts:
|
|
4924
|
-
*
|
|
4925
|
-
* 1. **Iframe-to-Parent Communication**: When games run inside iframes (production/development),
|
|
4926
|
-
* they need to communicate with the parent window using postMessage API
|
|
4927
|
-
*
|
|
4928
|
-
* 2. **Local Communication**: When games run in the same context (local development),
|
|
4929
|
-
* they use CustomEvents for internal messaging
|
|
4930
|
-
*
|
|
4931
|
-
* The system automatically detects the runtime environment and chooses the appropriate
|
|
4932
|
-
* transport method, abstracting this complexity from the developer.
|
|
4933
|
-
*
|
|
4934
|
-
* **Architecture Overview**:
|
|
4935
|
-
* - Games run in iframes for security and isolation
|
|
4936
|
-
* - Parent window (Playcademy shell) manages game lifecycle
|
|
4937
|
-
* - Messages flow bidirectionally between parent and iframe
|
|
4938
|
-
* - Local development mode simulates this architecture without iframes
|
|
4939
|
-
*/
|
|
4940
|
-
|
|
4941
|
-
/**
|
|
4942
|
-
* Enumeration of all message types used in the Playcademy messaging system.
|
|
4943
|
-
*
|
|
4944
|
-
* **Message Flow Patterns**:
|
|
4945
|
-
*
|
|
4946
|
-
* **Parent → Game (Overworld → Game)**:
|
|
4947
|
-
* - INIT: Provides game with authentication token and configuration
|
|
4948
|
-
* - TOKEN_REFRESH: Updates game's authentication token before expiry
|
|
4949
|
-
* - PAUSE/RESUME: Controls game execution state
|
|
4950
|
-
* - FORCE_EXIT: Immediately terminates the game
|
|
4951
|
-
* - OVERLAY: Shows/hides UI overlays over the game
|
|
4952
|
-
*
|
|
4953
|
-
* **Game → Parent (Game → Overworld)**:
|
|
4954
|
-
* - READY: Game has loaded and is ready to receive messages
|
|
4955
|
-
* - EXIT: Game requests to be closed (user clicked exit, game ended, etc.)
|
|
4956
|
-
* - TELEMETRY: Game reports performance metrics (FPS, memory usage, etc.)
|
|
4957
|
-
*/
|
|
4958
|
-
declare enum MessageEvents {
|
|
4959
|
-
/**
|
|
4960
|
-
* Initializes the game with authentication context and configuration.
|
|
4961
|
-
* Sent immediately after game iframe loads.
|
|
4962
|
-
* Payload:
|
|
4963
|
-
* - `baseUrl`: string
|
|
4964
|
-
* - `token`: string
|
|
4965
|
-
* - `gameId`: string
|
|
4966
|
-
*/
|
|
4967
|
-
INIT = "PLAYCADEMY_INIT",
|
|
4968
|
-
/**
|
|
4969
|
-
* Updates the game's authentication token before it expires.
|
|
4970
|
-
* Sent periodically to maintain valid authentication.
|
|
4971
|
-
* Payload:
|
|
4972
|
-
* - `token`: string
|
|
4973
|
-
* - `exp`: number
|
|
4974
|
-
*/
|
|
4975
|
-
TOKEN_REFRESH = "PLAYCADEMY_TOKEN_REFRESH",
|
|
4976
|
-
/**
|
|
4977
|
-
* Pauses game execution (e.g., when user switches tabs).
|
|
4978
|
-
* Game should pause timers, animations, and user input.
|
|
4979
|
-
* Payload: void
|
|
4980
|
-
*/
|
|
4981
|
-
PAUSE = "PLAYCADEMY_PAUSE",
|
|
4982
|
-
/**
|
|
4983
|
-
* Resumes game execution after being paused.
|
|
4984
|
-
* Game should restore timers, animations, and user input.
|
|
4985
|
-
* Payload: void
|
|
4986
|
-
*/
|
|
4987
|
-
RESUME = "PLAYCADEMY_RESUME",
|
|
4988
|
-
/**
|
|
4989
|
-
* Forces immediate game termination (emergency exit).
|
|
4990
|
-
* Game should clean up resources and exit immediately.
|
|
4991
|
-
* Payload: void
|
|
4992
|
-
*/
|
|
4993
|
-
FORCE_EXIT = "PLAYCADEMY_FORCE_EXIT",
|
|
4994
|
-
/**
|
|
4995
|
-
* Shows or hides UI overlays over the game.
|
|
4996
|
-
* Game may need to pause or adjust rendering accordingly.
|
|
4997
|
-
* Payload: boolean (true = show overlay, false = hide overlay)
|
|
4998
|
-
*/
|
|
4999
|
-
OVERLAY = "PLAYCADEMY_OVERLAY",
|
|
5000
|
-
/**
|
|
5001
|
-
* Broadcasts connection state changes to games.
|
|
5002
|
-
* Sent by platform when network connectivity changes.
|
|
5003
|
-
* Payload:
|
|
5004
|
-
* - `state`: 'online' | 'offline' | 'degraded'
|
|
5005
|
-
* - `reason`: string
|
|
5006
|
-
*/
|
|
5007
|
-
CONNECTION_STATE = "PLAYCADEMY_CONNECTION_STATE",
|
|
5008
|
-
/**
|
|
5009
|
-
* Game has finished loading and is ready to receive messages.
|
|
5010
|
-
* Sent once after game initialization is complete.
|
|
5011
|
-
* Payload: void
|
|
5012
|
-
*/
|
|
5013
|
-
READY = "PLAYCADEMY_READY",
|
|
5014
|
-
/**
|
|
5015
|
-
* Game SDK initialization failed.
|
|
5016
|
-
* Sent when the game iframe fails to complete SDK init (e.g.
|
|
5017
|
-
* origin validation failure, INIT timeout, client creation error).
|
|
5018
|
-
* Payload:
|
|
5019
|
-
* - `reason`: string — human-readable failure description
|
|
5020
|
-
*/
|
|
5021
|
-
INIT_ERROR = "PLAYCADEMY_INIT_ERROR",
|
|
5022
|
-
/**
|
|
5023
|
-
* Game requests to be closed/exited.
|
|
5024
|
-
* Sent when user clicks exit button or game naturally ends.
|
|
5025
|
-
* Payload: void
|
|
5026
|
-
*/
|
|
5027
|
-
EXIT = "PLAYCADEMY_EXIT",
|
|
5028
|
-
/**
|
|
5029
|
-
* Game reports performance telemetry data.
|
|
5030
|
-
* Sent periodically for monitoring and analytics.
|
|
5031
|
-
* Payload:
|
|
5032
|
-
* - `fps`: number
|
|
5033
|
-
* - `mem`: number
|
|
5034
|
-
*/
|
|
5035
|
-
TELEMETRY = "PLAYCADEMY_TELEMETRY",
|
|
5036
|
-
/**
|
|
5037
|
-
* Game reports key events to parent.
|
|
5038
|
-
* Sent when certain keys are pressed within the game iframe.
|
|
5039
|
-
* Payload:
|
|
5040
|
-
* - `key`: string
|
|
5041
|
-
* - `code?`: string
|
|
5042
|
-
* - `type`: 'keydown' | 'keyup'
|
|
5043
|
-
*/
|
|
5044
|
-
KEY_EVENT = "PLAYCADEMY_KEY_EVENT",
|
|
5045
|
-
/**
|
|
5046
|
-
* Game requests platform to display an alert.
|
|
5047
|
-
* Sent when connection issues are detected or other important events occur.
|
|
5048
|
-
* Payload:
|
|
5049
|
-
* - `message`: string
|
|
5050
|
-
* - `options`: `{ type?: 'info' | 'warning' | 'error', duration?: number }`
|
|
5051
|
-
*/
|
|
5052
|
-
DISPLAY_ALERT = "PLAYCADEMY_DISPLAY_ALERT",
|
|
5053
|
-
/**
|
|
5054
|
-
* Game signals that demo mode has ended.
|
|
5055
|
-
* Sent when a demo experience reaches its CTA/upgrade boundary.
|
|
5056
|
-
* Payload:
|
|
5057
|
-
* - `score?`: number
|
|
5058
|
-
* - `durationMs?`: number
|
|
5059
|
-
* - `metadata?`: `Record<string, unknown>`
|
|
5060
|
-
*/
|
|
5061
|
-
DEMO_END = "PLAYCADEMY_DEMO_END",
|
|
5062
|
-
/**
|
|
5063
|
-
* Notifies about authentication state changes.
|
|
5064
|
-
* Can be sent in both directions depending on auth flow.
|
|
5065
|
-
* Payload:
|
|
5066
|
-
* - `authenticated`: boolean
|
|
5067
|
-
* - `user`: UserInfo | null
|
|
5068
|
-
* - `error`: Error | null
|
|
5069
|
-
*/
|
|
5070
|
-
AUTH_STATE_CHANGE = "PLAYCADEMY_AUTH_STATE_CHANGE",
|
|
5071
|
-
/**
|
|
5072
|
-
* OAuth callback data from popup/new-tab windows.
|
|
5073
|
-
* Sent from popup window back to parent after OAuth completes.
|
|
5074
|
-
* Payload:
|
|
5075
|
-
* - `code`: string (OAuth authorization code)
|
|
5076
|
-
* - `state`: string (OAuth state for CSRF protection)
|
|
5077
|
-
* - `error`: string | null (OAuth error if any)
|
|
5078
|
-
*/
|
|
5079
|
-
AUTH_CALLBACK = "PLAYCADEMY_AUTH_CALLBACK"
|
|
5037
|
+
inventory: PlayerInventoryItem[];
|
|
5038
|
+
ownedGameIds: Game['id'][];
|
|
5039
|
+
currentLocation?: PlayerLocation;
|
|
5040
|
+
characterCreated?: UserRow['characterCreated'];
|
|
5041
|
+
playerCharacter?: PlayerCharacterRow | null;
|
|
5080
5042
|
}
|
|
5081
|
-
|
|
5082
5043
|
/**
|
|
5083
|
-
*
|
|
5084
|
-
*
|
|
5085
|
-
*
|
|
5086
|
-
* This is the recommended way to initialize the SDK as it automatically:
|
|
5087
|
-
* - Detects the runtime environment (iframe vs standalone)
|
|
5088
|
-
* - Configures the client with the appropriate context
|
|
5089
|
-
* - Sets up event listeners for token refresh
|
|
5090
|
-
* - Exposes the client for debugging in development mode
|
|
5091
|
-
*
|
|
5092
|
-
* @param options - Optional configuration overrides
|
|
5093
|
-
* @param options.baseUrl - Override the base URL for API requests
|
|
5094
|
-
* @returns Promise resolving to a fully initialized PlaycademyClient
|
|
5095
|
-
* @throws Error if not running in a browser context
|
|
5096
|
-
*
|
|
5097
|
-
* @example
|
|
5098
|
-
* ```typescript
|
|
5099
|
-
* // Default initialization
|
|
5100
|
-
* const client = await PlaycademyClient.init()
|
|
5101
|
-
*
|
|
5102
|
-
* // With custom base URL
|
|
5103
|
-
* const client = await PlaycademyClient.init({ baseUrl: 'https://custom.api.com' })
|
|
5104
|
-
* ```
|
|
5044
|
+
* Map-related Composite Types
|
|
5045
|
+
* DB row + joined game/item data
|
|
5105
5046
|
*/
|
|
5106
|
-
|
|
5107
|
-
|
|
5108
|
-
|
|
5109
|
-
|
|
5110
|
-
|
|
5111
|
-
}
|
|
5112
|
-
|
|
5047
|
+
type MapElementWithGame = MapElementRow & {
|
|
5048
|
+
game: {
|
|
5049
|
+
id: string;
|
|
5050
|
+
displayName: string;
|
|
5051
|
+
} | null;
|
|
5052
|
+
};
|
|
5053
|
+
type MapObjectWithItem = MapObjectRow & {
|
|
5054
|
+
item: {
|
|
5055
|
+
id: string;
|
|
5056
|
+
slug: string;
|
|
5057
|
+
displayName: string;
|
|
5058
|
+
description?: string | null;
|
|
5059
|
+
imageUrl?: string | null;
|
|
5060
|
+
isPlaceable: boolean;
|
|
5061
|
+
metadata?: PlaceableItemMetadata | null;
|
|
5062
|
+
};
|
|
5063
|
+
};
|
|
5113
5064
|
/**
|
|
5114
|
-
*
|
|
5115
|
-
*
|
|
5116
|
-
* This is a standalone authentication method that doesn't require an initialized client.
|
|
5117
|
-
* Use this for login flows before creating a client instance.
|
|
5118
|
-
*
|
|
5119
|
-
* @deprecated Use client.auth.login() instead for better error handling and automatic token management
|
|
5120
|
-
*
|
|
5121
|
-
* @param baseUrl - The base URL of the Playcademy API
|
|
5122
|
-
* @param email - User's email address
|
|
5123
|
-
* @param password - User's password
|
|
5124
|
-
* @returns Promise resolving to authentication response with token
|
|
5125
|
-
* @throws PlaycademyError if authentication fails or network error occurs
|
|
5126
|
-
*
|
|
5127
|
-
* @example
|
|
5128
|
-
* ```typescript
|
|
5129
|
-
* // Preferred approach:
|
|
5130
|
-
* const client = new PlaycademyClient({ baseUrl: '/api' })
|
|
5131
|
-
* const result = await client.auth.login({
|
|
5132
|
-
* email: 'user@example.com',
|
|
5133
|
-
* password: 'password'
|
|
5134
|
-
* })
|
|
5135
|
-
*
|
|
5136
|
-
* // Legacy approach (still works):
|
|
5137
|
-
* try {
|
|
5138
|
-
* const response = await PlaycademyClient.login('/api', 'user@example.com', 'password')
|
|
5139
|
-
* const client = new PlaycademyClient({ token: response.token })
|
|
5140
|
-
* } catch (error) {
|
|
5141
|
-
* console.error('Login failed:', error.message)
|
|
5142
|
-
* }
|
|
5143
|
-
* ```
|
|
5065
|
+
* Game custom hostname with validation records
|
|
5144
5066
|
*/
|
|
5145
|
-
|
|
5067
|
+
type GameCustomHostname = GameCustomHostnameRow & {
|
|
5068
|
+
validationRecords?: DomainValidationRecords;
|
|
5069
|
+
};
|
|
5070
|
+
|
|
5071
|
+
type UserLevelRow = typeof userLevels.$inferSelect;
|
|
5072
|
+
type LevelConfigRow = typeof levelConfigs.$inferSelect;
|
|
5073
|
+
type UserLevelWithConfig = UserLevelRow & {
|
|
5074
|
+
xpToNextLevel: number;
|
|
5075
|
+
nextLevelConfig?: LevelConfigRow;
|
|
5076
|
+
};
|
|
5077
|
+
|
|
5078
|
+
type SpriteTemplateRow = typeof spriteTemplates.$inferSelect;
|
|
5079
|
+
|
|
5080
|
+
type NotificationRow = InferSelectModel<typeof notifications>;
|
|
5146
5081
|
|
|
5147
5082
|
/**
|
|
5148
5083
|
* @fileoverview Authentication Strategy Pattern
|
|
@@ -5316,52 +5251,69 @@ declare abstract class PlaycademyBaseClient {
|
|
|
5316
5251
|
}
|
|
5317
5252
|
|
|
5318
5253
|
/**
|
|
5319
|
-
*
|
|
5254
|
+
* Auto-initializes a PlaycademyClient with context from the environment.
|
|
5255
|
+
* Works in both iframe mode (production/development) and standalone mode (local dev).
|
|
5256
|
+
*
|
|
5257
|
+
* This is the recommended way to initialize the SDK as it automatically:
|
|
5258
|
+
* - Detects the runtime environment (iframe vs standalone)
|
|
5259
|
+
* - Configures the client with the appropriate context
|
|
5260
|
+
* - Sets up event listeners for token refresh
|
|
5261
|
+
* - Exposes the client for debugging in development mode
|
|
5262
|
+
*
|
|
5263
|
+
* @param options - Optional configuration overrides
|
|
5264
|
+
* @param options.baseUrl - Override the base URL for API requests
|
|
5265
|
+
* @returns Promise resolving to a fully initialized PlaycademyClient
|
|
5266
|
+
* @throws Error if not running in a browser context
|
|
5267
|
+
*
|
|
5268
|
+
* @example
|
|
5269
|
+
* ```typescript
|
|
5270
|
+
* // Default initialization
|
|
5271
|
+
* const client = await PlaycademyClient.init()
|
|
5272
|
+
*
|
|
5273
|
+
* // With custom base URL
|
|
5274
|
+
* const client = await PlaycademyClient.init({ baseUrl: 'https://custom.api.com' })
|
|
5275
|
+
* ```
|
|
5320
5276
|
*/
|
|
5321
|
-
|
|
5322
|
-
|
|
5323
|
-
|
|
5324
|
-
|
|
5325
|
-
|
|
5326
|
-
|
|
5327
|
-
|
|
5328
|
-
|
|
5329
|
-
|
|
5330
|
-
|
|
5331
|
-
|
|
5332
|
-
|
|
5333
|
-
|
|
5334
|
-
|
|
5335
|
-
|
|
5336
|
-
|
|
5337
|
-
|
|
5338
|
-
|
|
5339
|
-
|
|
5340
|
-
|
|
5341
|
-
|
|
5342
|
-
|
|
5343
|
-
|
|
5344
|
-
|
|
5345
|
-
|
|
5346
|
-
|
|
5347
|
-
|
|
5348
|
-
|
|
5349
|
-
|
|
5350
|
-
|
|
5351
|
-
|
|
5352
|
-
|
|
5353
|
-
|
|
5354
|
-
|
|
5355
|
-
|
|
5356
|
-
|
|
5357
|
-
|
|
5358
|
-
|
|
5359
|
-
|
|
5360
|
-
|
|
5361
|
-
* which means every session is treated as its own run.
|
|
5362
|
-
*/
|
|
5363
|
-
runId?: string;
|
|
5364
|
-
}
|
|
5277
|
+
declare function init<T extends PlaycademyBaseClient = PlaycademyBaseClient>(this: new (config?: Partial<ClientConfig>) => T, options?: {
|
|
5278
|
+
baseUrl?: string;
|
|
5279
|
+
allowedParentOrigins?: string[];
|
|
5280
|
+
onDisconnect?: DisconnectHandler;
|
|
5281
|
+
enableConnectionMonitoring?: boolean;
|
|
5282
|
+
}): Promise<T>;
|
|
5283
|
+
|
|
5284
|
+
/**
|
|
5285
|
+
* Authenticates a user with email and password.
|
|
5286
|
+
*
|
|
5287
|
+
* This is a standalone authentication method that doesn't require an initialized client.
|
|
5288
|
+
* Use this for login flows before creating a client instance.
|
|
5289
|
+
*
|
|
5290
|
+
* @deprecated Use client.auth.login() instead for better error handling and automatic token management
|
|
5291
|
+
*
|
|
5292
|
+
* @param baseUrl - The base URL of the Playcademy API
|
|
5293
|
+
* @param email - User's email address
|
|
5294
|
+
* @param password - User's password
|
|
5295
|
+
* @returns Promise resolving to authentication response with token
|
|
5296
|
+
* @throws PlaycademyError if authentication fails or network error occurs
|
|
5297
|
+
*
|
|
5298
|
+
* @example
|
|
5299
|
+
* ```typescript
|
|
5300
|
+
* // Preferred approach:
|
|
5301
|
+
* const client = new PlaycademyClient({ baseUrl: '/api' })
|
|
5302
|
+
* const result = await client.auth.login({
|
|
5303
|
+
* email: 'user@example.com',
|
|
5304
|
+
* password: 'password'
|
|
5305
|
+
* })
|
|
5306
|
+
*
|
|
5307
|
+
* // Legacy approach (still works):
|
|
5308
|
+
* try {
|
|
5309
|
+
* const response = await PlaycademyClient.login('/api', 'user@example.com', 'password')
|
|
5310
|
+
* const client = new PlaycademyClient({ token: response.token })
|
|
5311
|
+
* } catch (error) {
|
|
5312
|
+
* console.error('Login failed:', error.message)
|
|
5313
|
+
* }
|
|
5314
|
+
* ```
|
|
5315
|
+
*/
|
|
5316
|
+
declare function login(baseUrl: string, email: string, password: string): Promise<LoginResponse>;
|
|
5365
5317
|
|
|
5366
5318
|
/**
|
|
5367
5319
|
* Playcademy SDK client for game developers.
|
|
@@ -5430,15 +5382,17 @@ declare class PlaycademyClient extends PlaycademyBaseClient {
|
|
|
5430
5382
|
* - `user.fetch()` - Refresh user context from server
|
|
5431
5383
|
*
|
|
5432
5384
|
* Activity tracking:
|
|
5433
|
-
* - `
|
|
5434
|
-
*
|
|
5435
|
-
*
|
|
5385
|
+
* - `currentRunId` - Current activity run ID, or undefined when inactive
|
|
5386
|
+
* - `startActivity(metadata)` - Begin tracking an activity, return its run
|
|
5387
|
+
* ID, and automatically handle hidden-tab and visible-tab inactivity
|
|
5388
|
+
* with configurable paused-heartbeat timeout behavior
|
|
5436
5389
|
* - `pauseActivity()` / `resumeActivity()` - Pause/resume timer
|
|
5437
5390
|
* - `endActivity(scoreData)` - Submit activity results to TimeBack
|
|
5438
5391
|
*/
|
|
5439
5392
|
timeback: {
|
|
5440
5393
|
readonly user: TimebackUser;
|
|
5441
|
-
|
|
5394
|
+
readonly currentRunId: string | undefined;
|
|
5395
|
+
startActivity: (metadata: ActivityData, options?: StartActivityOptions) => StartActivityResult;
|
|
5442
5396
|
pauseActivity: () => void;
|
|
5443
5397
|
resumeActivity: () => void;
|
|
5444
5398
|
endActivity: (data: EndActivityScoreData) => Promise<EndActivityResponse>;
|
|
@@ -5518,6 +5472,57 @@ declare class PlaycademyClient extends PlaycademyBaseClient {
|
|
|
5518
5472
|
};
|
|
5519
5473
|
}
|
|
5520
5474
|
|
|
5475
|
+
/**
|
|
5476
|
+
* Options for configuring activity tracking behavior.
|
|
5477
|
+
*/
|
|
5478
|
+
interface StartActivityOptions {
|
|
5479
|
+
/**
|
|
5480
|
+
* How long heartbeats continue after the activity is automatically paused
|
|
5481
|
+
* because the tab is hidden or the player is inactive while visible.
|
|
5482
|
+
* Defaults to 10 minutes. Set to `Infinity` to keep heartbeats running
|
|
5483
|
+
* indefinitely during automatic pauses. Invalid values fall back to the
|
|
5484
|
+
* 10-minute default.
|
|
5485
|
+
*/
|
|
5486
|
+
pausedHeartbeatTimeoutMs?: number;
|
|
5487
|
+
/**
|
|
5488
|
+
* @deprecated Use `pausedHeartbeatTimeoutMs` instead.
|
|
5489
|
+
*
|
|
5490
|
+
* Backward-compatible alias for callers that still use the old option
|
|
5491
|
+
* name from earlier SDK releases.
|
|
5492
|
+
*/
|
|
5493
|
+
hiddenTimeoutMs?: number;
|
|
5494
|
+
/**
|
|
5495
|
+
* How often to flush periodic heartbeats with accumulated time data.
|
|
5496
|
+
* Defaults to 15 seconds. Set to `Infinity` to disable the interval;
|
|
5497
|
+
* final unload/endActivity flushes still run. Values must be greater than
|
|
5498
|
+
* 0 or `Infinity`; invalid values fall back to the 15-second default.
|
|
5499
|
+
*/
|
|
5500
|
+
heartbeatIntervalMs?: number;
|
|
5501
|
+
/**
|
|
5502
|
+
* How long the tab can remain visible without keyboard or mouse activity
|
|
5503
|
+
* before the activity is marked inactive. Defaults to 10 minutes. Set to
|
|
5504
|
+
* `Infinity` to disable keyboard/mouse inactivity tracking. Invalid values
|
|
5505
|
+
* fall back to the 10-minute default.
|
|
5506
|
+
*/
|
|
5507
|
+
inactivityTimeoutMs?: number;
|
|
5508
|
+
/**
|
|
5509
|
+
* Stable identifier for this activity run. When provided, it is used on
|
|
5510
|
+
* every heartbeat and on endActivity instead of a freshly-generated UUID.
|
|
5511
|
+
*
|
|
5512
|
+
* Pass the same `runId` across multiple `startActivity()` calls (for
|
|
5513
|
+
* example, after the player closes and reopens a resumable activity) so
|
|
5514
|
+
* downstream systems can correlate related sessions into a single run.
|
|
5515
|
+
*
|
|
5516
|
+
* Must be a UUID (the backend validates it as such) and unique per
|
|
5517
|
+
* logical run. If omitted, the SDK generates a new UUID on each call,
|
|
5518
|
+
* which means every session is treated as its own run.
|
|
5519
|
+
*/
|
|
5520
|
+
runId?: string;
|
|
5521
|
+
}
|
|
5522
|
+
interface StartActivityResult {
|
|
5523
|
+
runId: string;
|
|
5524
|
+
}
|
|
5525
|
+
|
|
5521
5526
|
/**
|
|
5522
5527
|
* Type definitions for the game timeback namespace.
|
|
5523
5528
|
*
|
|
@@ -6204,4 +6209,4 @@ interface AssessmentBankStatus {
|
|
|
6204
6209
|
}
|
|
6205
6210
|
|
|
6206
6211
|
export { AchievementCompletionType, NotificationStatus, NotificationType, PlaycademyClient };
|
|
6207
|
-
export type { AchievementCurrent, AchievementHistoryEntry, AchievementProgressResponse, AchievementScopeType, AchievementWithStatus, AssessmentBankStatus, AssessmentRow, AssessmentSummary, AuthCallbackPayload, AuthOptions, AuthProviderType, AuthResult, AuthServerMessage, AuthStateChangePayload, AuthStateUpdate, AuthenticatedUser, BetterAuthApiKey, BetterAuthApiKeyResponse, BetterAuthSignInResponse, BucketFile, CharacterComponentRow as CharacterComponent, CharacterComponentType, CharacterComponentWithSpriteUrl, CharacterComponentsOptions, ClientConfig, ClientEvents, ConnectionStatePayload, CourseXp, CreateCharacterData, CreateMapObjectData, CurrencyRow as Currency, DemoEndOptions, DemoEndPayload, DevUploadEvent, DevUploadHooks, DeveloperStatusEnumType, DeveloperStatusResponse, DeveloperStatusValue, DisconnectContext, DisconnectHandler, DisplayAlertPayload, EventListeners, ExternalGame, FetchedGame, Game, GameActivityMetrics, GameContextPayload, GameCourseMetrics, GameCustomHostname, GameInitUser, GameLeaderboardEntry, GameManifest, MapRow as GameMap, GameMetricsProxyResponse, GameMetricsResponse, GameMetricsUnsupportedReason, GamePlatform, GameRow as GameRecord, GameSessionRow as GameSession, GameTimebackIntegration, GameTokenResponse, GameType, GameUser, GetXpOptions, HostedGame, InitErrorPayload, InitPayload, InsertCurrencyInput, InsertItemInput, InsertShopListingInput, InteractionType, InventoryItemRow as InventoryItem, InventoryItemWithItem, InventoryMutationResponse, ItemRow as Item, ItemType, KVKeyEntry, KVKeyMetadata, KVSeedEntry, KVStatsResponse, KeyEventPayload, LeaderboardEntry, LeaderboardOptions, LeaderboardTimeframe, LevelConfigRow as LevelConfig, LevelProgressResponse, LevelUpCheckResult, LoginResponse, ManifestV1, ManifestV2, ManifestVersions, MapData, MapElementRow as MapElement, MapElementMetadata, MapElementWithGame, MapObjectRow as MapObject, MapObjectWithItem, NotificationRow as Notification, NotificationStats, PlaceableItemMetadata, PlatformTimebackUser, PlatformTimebackUserContext, PlaycademyMode, PlaycademyServerClientConfig, PlaycademyServerClientState, PlayerCharacterRow as PlayerCharacter, PlayerCharacterAccessoryRow as PlayerCharacterAccessory, PlayerCurrency, PlayerInventoryItem, PlayerProfile, PlayerSessionPayload, PopulateStudentResponse, QtiTestQuestionRef, QtiTestQuestionsResponse, RealtimeTokenResponse, ScoreSubmission, ShopCurrency, ShopDisplayItem, ShopListingRow as ShopListing, ShopViewResponse, SpriteAnimationFrame, SpriteConfigWithDimensions, SpriteTemplateRow as SpriteTemplate, SpriteTemplateData, StartSessionResponse, TelemetryPayload, TimebackEnrollment, TimebackInitContext, TimebackOrganization, TimebackUser, TimebackUserContext, TimebackUserRefreshField, TimebackUserRefreshOptions, TimebackUserXp, TodayXpResponse, TokenRefreshPayload, TokenType, TotalXpResponse, UpdateCharacterData, UpdateCurrencyInput, UpdateItemInput, UpdateShopListingInput, UpsertGameMetadataInput, UserRow as User, UserEnrollment, UserInfo, UserLevelRow as UserLevel, UserLevelWithConfig, UserOrganization, UserRank, UserRankResponse, UserRoleEnumType, UserScore, UserTimebackData, XPAddResult, XpHistoryResponse, XpResponse, XpSummaryResponse };
|
|
6212
|
+
export type { AchievementCurrent, AchievementHistoryEntry, AchievementProgressResponse, AchievementScopeType, AchievementWithStatus, AssessmentBankStatus, AssessmentRow, AssessmentSummary, AuthCallbackPayload, AuthOptions, AuthProviderType, AuthResult, AuthServerMessage, AuthStateChangePayload, AuthStateUpdate, AuthenticatedUser, BetterAuthApiKey, BetterAuthApiKeyResponse, BetterAuthSignInResponse, BucketFile, CharacterComponentRow as CharacterComponent, CharacterComponentType, CharacterComponentWithSpriteUrl, CharacterComponentsOptions, ClientConfig, ClientEvents, ConnectionStatePayload, CourseXp, CreateCharacterData, CreateMapObjectData, CurrencyRow as Currency, DemoEndOptions, DemoEndPayload, DevUploadEvent, DevUploadHooks, DeveloperStatusEnumType, DeveloperStatusResponse, DeveloperStatusValue, DisconnectContext, DisconnectHandler, DisplayAlertPayload, EventListeners, ExternalGame, FetchedGame, Game, GameActivityMetrics, GameContextPayload, GameCourseMetrics, GameCustomHostname, GameInitUser, GameLeaderboardEntry, GameManifest, MapRow as GameMap, GameMetricsProxyResponse, GameMetricsResponse, GameMetricsUnsupportedReason, GamePlatform, GameRow as GameRecord, GameSessionRow as GameSession, GameTimebackIntegration, GameTokenResponse, GameType, GameUser, GetXpOptions, HostedGame, InitErrorPayload, InitPayload, InsertCurrencyInput, InsertItemInput, InsertShopListingInput, InteractionType, InventoryItemRow as InventoryItem, InventoryItemWithItem, InventoryMutationResponse, ItemRow as Item, ItemType, KVKeyEntry, KVKeyMetadata, KVSeedEntry, KVStatsResponse, KeyEventPayload, LeaderboardEntry, LeaderboardOptions, LeaderboardTimeframe, LevelConfigRow as LevelConfig, LevelProgressResponse, LevelUpCheckResult, LoginResponse, ManifestV1, ManifestV2, ManifestVersions, MapData, MapElementRow as MapElement, MapElementMetadata, MapElementWithGame, MapObjectRow as MapObject, MapObjectWithItem, NotificationRow as Notification, NotificationStats, PlaceableItemMetadata, PlatformTimebackUser, PlatformTimebackUserContext, PlaycademyMode, PlaycademyServerClientConfig, PlaycademyServerClientState, PlayerCharacterRow as PlayerCharacter, PlayerCharacterAccessoryRow as PlayerCharacterAccessory, PlayerCurrency, PlayerInventoryItem, PlayerProfile, PlayerSessionPayload, PopulateStudentResponse, QtiTestQuestionRef, QtiTestQuestionsResponse, RealtimeTokenResponse, ScoreSubmission, ShopCurrency, ShopDisplayItem, ShopListingRow as ShopListing, ShopViewResponse, SpriteAnimationFrame, SpriteConfigWithDimensions, SpriteTemplateRow as SpriteTemplate, SpriteTemplateData, StartActivityOptions, StartActivityResult, StartSessionResponse, TelemetryPayload, TimebackEnrollment, TimebackInitContext, TimebackOrganization, TimebackUser, TimebackUserContext, TimebackUserRefreshField, TimebackUserRefreshOptions, TimebackUserXp, TodayXpResponse, TokenRefreshPayload, TokenType, TotalXpResponse, UpdateCharacterData, UpdateCurrencyInput, UpdateItemInput, UpdateShopListingInput, UpsertGameMetadataInput, UserRow as User, UserEnrollment, UserInfo, UserLevelRow as UserLevel, UserLevelWithConfig, UserOrganization, UserRank, UserRankResponse, UserRoleEnumType, UserScore, UserTimebackData, XPAddResult, XpHistoryResponse, XpResponse, XpSummaryResponse };
|