@playcademy/sdk 0.1.13 → 0.1.15

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/types.d.ts CHANGED
@@ -226,6 +226,23 @@ type GameMetadata = {
226
226
  emoji?: string;
227
227
  [key: string]: unknown;
228
228
  };
229
+ /**
230
+ * DNS validation records for custom hostname
231
+ * Structure for the validationRecords JSON field in game_custom_hostnames table
232
+ */
233
+ type CustomHostnameValidationRecords = {
234
+ /** TXT record for ownership verification */
235
+ ownership?: {
236
+ name?: string;
237
+ value?: string;
238
+ type?: string;
239
+ };
240
+ /** TXT records for SSL certificate validation */
241
+ ssl?: Array<{
242
+ txt_name?: string;
243
+ txt_value?: string;
244
+ }>;
245
+ };
229
246
  declare const games: drizzle_orm_pg_core.PgTableWithColumns<{
230
247
  name: "games";
231
248
  schema: undefined;
@@ -338,8 +355,8 @@ declare const games: drizzle_orm_pg_core.PgTableWithColumns<{
338
355
  identity: undefined;
339
356
  generated: undefined;
340
357
  }, {}, {}>;
341
- assetBundleBase: drizzle_orm_pg_core.PgColumn<{
342
- name: "asset_bundle_base";
358
+ deploymentUrl: drizzle_orm_pg_core.PgColumn<{
359
+ name: "deployment_url";
343
360
  tableName: "games";
344
361
  dataType: "string";
345
362
  columnType: "PgText";
@@ -554,6 +571,207 @@ declare const gameSessions: drizzle_orm_pg_core.PgTableWithColumns<{
554
571
  };
555
572
  dialect: "pg";
556
573
  }>;
574
+ /**
575
+ * Custom hostnames table
576
+ *
577
+ * Stores custom domain mappings for games with SSL provisioning via Cloudflare.
578
+ */
579
+ declare const gameCustomHostnames: drizzle_orm_pg_core.PgTableWithColumns<{
580
+ name: "game_custom_hostnames";
581
+ schema: undefined;
582
+ columns: {
583
+ id: drizzle_orm_pg_core.PgColumn<{
584
+ name: "id";
585
+ tableName: "game_custom_hostnames";
586
+ dataType: "string";
587
+ columnType: "PgUUID";
588
+ data: string;
589
+ driverParam: string;
590
+ notNull: true;
591
+ hasDefault: true;
592
+ isPrimaryKey: true;
593
+ isAutoincrement: false;
594
+ hasRuntimeDefault: false;
595
+ enumValues: undefined;
596
+ baseColumn: never;
597
+ identity: undefined;
598
+ generated: undefined;
599
+ }, {}, {}>;
600
+ gameId: drizzle_orm_pg_core.PgColumn<{
601
+ name: "game_id";
602
+ tableName: "game_custom_hostnames";
603
+ dataType: "string";
604
+ columnType: "PgUUID";
605
+ data: string;
606
+ driverParam: string;
607
+ notNull: true;
608
+ hasDefault: false;
609
+ isPrimaryKey: false;
610
+ isAutoincrement: false;
611
+ hasRuntimeDefault: false;
612
+ enumValues: undefined;
613
+ baseColumn: never;
614
+ identity: undefined;
615
+ generated: undefined;
616
+ }, {}, {}>;
617
+ userId: drizzle_orm_pg_core.PgColumn<{
618
+ name: "user_id";
619
+ tableName: "game_custom_hostnames";
620
+ dataType: "string";
621
+ columnType: "PgText";
622
+ data: string;
623
+ driverParam: string;
624
+ notNull: true;
625
+ hasDefault: false;
626
+ isPrimaryKey: false;
627
+ isAutoincrement: false;
628
+ hasRuntimeDefault: false;
629
+ enumValues: [string, ...string[]];
630
+ baseColumn: never;
631
+ identity: undefined;
632
+ generated: undefined;
633
+ }, {}, {}>;
634
+ hostname: drizzle_orm_pg_core.PgColumn<{
635
+ name: "hostname";
636
+ tableName: "game_custom_hostnames";
637
+ dataType: "string";
638
+ columnType: "PgText";
639
+ data: string;
640
+ driverParam: string;
641
+ notNull: true;
642
+ hasDefault: false;
643
+ isPrimaryKey: false;
644
+ isAutoincrement: false;
645
+ hasRuntimeDefault: false;
646
+ enumValues: [string, ...string[]];
647
+ baseColumn: never;
648
+ identity: undefined;
649
+ generated: undefined;
650
+ }, {}, {}>;
651
+ cloudflareId: drizzle_orm_pg_core.PgColumn<{
652
+ name: "cloudflare_id";
653
+ tableName: "game_custom_hostnames";
654
+ dataType: "string";
655
+ columnType: "PgText";
656
+ data: string;
657
+ driverParam: string;
658
+ notNull: true;
659
+ hasDefault: false;
660
+ isPrimaryKey: false;
661
+ isAutoincrement: false;
662
+ hasRuntimeDefault: false;
663
+ enumValues: [string, ...string[]];
664
+ baseColumn: never;
665
+ identity: undefined;
666
+ generated: undefined;
667
+ }, {}, {}>;
668
+ environment: drizzle_orm_pg_core.PgColumn<{
669
+ name: "environment";
670
+ tableName: "game_custom_hostnames";
671
+ dataType: "string";
672
+ columnType: "PgEnumColumn";
673
+ data: "staging" | "production";
674
+ driverParam: string;
675
+ notNull: true;
676
+ hasDefault: true;
677
+ isPrimaryKey: false;
678
+ isAutoincrement: false;
679
+ hasRuntimeDefault: false;
680
+ enumValues: ["staging", "production"];
681
+ baseColumn: never;
682
+ identity: undefined;
683
+ generated: undefined;
684
+ }, {}, {}>;
685
+ status: drizzle_orm_pg_core.PgColumn<{
686
+ name: "status";
687
+ tableName: "game_custom_hostnames";
688
+ dataType: "string";
689
+ columnType: "PgEnumColumn";
690
+ data: "pending" | "pending_validation" | "pending_deployment" | "pending_deletion" | "active" | "blocked" | "deleted";
691
+ driverParam: string;
692
+ notNull: true;
693
+ hasDefault: true;
694
+ isPrimaryKey: false;
695
+ isAutoincrement: false;
696
+ hasRuntimeDefault: false;
697
+ enumValues: ["pending", "pending_validation", "pending_deployment", "pending_deletion", "active", "blocked", "deleted"];
698
+ baseColumn: never;
699
+ identity: undefined;
700
+ generated: undefined;
701
+ }, {}, {}>;
702
+ sslStatus: drizzle_orm_pg_core.PgColumn<{
703
+ name: "ssl_status";
704
+ tableName: "game_custom_hostnames";
705
+ dataType: "string";
706
+ columnType: "PgEnumColumn";
707
+ data: "pending_validation" | "pending_deployment" | "active" | "deleted" | "initializing" | "pending_issuance";
708
+ driverParam: string;
709
+ notNull: true;
710
+ hasDefault: true;
711
+ isPrimaryKey: false;
712
+ isAutoincrement: false;
713
+ hasRuntimeDefault: false;
714
+ enumValues: ["initializing", "pending_validation", "pending_issuance", "pending_deployment", "active", "deleted"];
715
+ baseColumn: never;
716
+ identity: undefined;
717
+ generated: undefined;
718
+ }, {}, {}>;
719
+ validationRecords: drizzle_orm_pg_core.PgColumn<{
720
+ name: "validation_records";
721
+ tableName: "game_custom_hostnames";
722
+ dataType: "json";
723
+ columnType: "PgJsonb";
724
+ data: CustomHostnameValidationRecords;
725
+ driverParam: unknown;
726
+ notNull: false;
727
+ hasDefault: false;
728
+ isPrimaryKey: false;
729
+ isAutoincrement: false;
730
+ hasRuntimeDefault: false;
731
+ enumValues: undefined;
732
+ baseColumn: never;
733
+ identity: undefined;
734
+ generated: undefined;
735
+ }, {}, {
736
+ $type: CustomHostnameValidationRecords;
737
+ }>;
738
+ createdAt: drizzle_orm_pg_core.PgColumn<{
739
+ name: "created_at";
740
+ tableName: "game_custom_hostnames";
741
+ dataType: "date";
742
+ columnType: "PgTimestamp";
743
+ data: Date;
744
+ driverParam: string;
745
+ notNull: true;
746
+ hasDefault: true;
747
+ isPrimaryKey: false;
748
+ isAutoincrement: false;
749
+ hasRuntimeDefault: false;
750
+ enumValues: undefined;
751
+ baseColumn: never;
752
+ identity: undefined;
753
+ generated: undefined;
754
+ }, {}, {}>;
755
+ updatedAt: drizzle_orm_pg_core.PgColumn<{
756
+ name: "updated_at";
757
+ tableName: "game_custom_hostnames";
758
+ dataType: "date";
759
+ columnType: "PgTimestamp";
760
+ data: Date;
761
+ driverParam: string;
762
+ notNull: true;
763
+ hasDefault: true;
764
+ isPrimaryKey: false;
765
+ isAutoincrement: false;
766
+ hasRuntimeDefault: false;
767
+ enumValues: undefined;
768
+ baseColumn: never;
769
+ identity: undefined;
770
+ generated: undefined;
771
+ }, {}, {}>;
772
+ };
773
+ dialect: "pg";
774
+ }>;
557
775
  declare const items: drizzle_orm_pg_core.PgTableWithColumns<{
558
776
  name: "items";
559
777
  schema: undefined;
@@ -648,7 +866,7 @@ declare const items: drizzle_orm_pg_core.PgTableWithColumns<{
648
866
  tableName: "items";
649
867
  dataType: "string";
650
868
  columnType: "PgEnumColumn";
651
- data: "accessory" | "currency" | "badge" | "trophy" | "collectible" | "consumable" | "unlock" | "upgrade" | "other";
869
+ data: "currency" | "badge" | "trophy" | "collectible" | "consumable" | "unlock" | "upgrade" | "accessory" | "other";
652
870
  driverParam: string;
653
871
  notNull: true;
654
872
  hasDefault: true;
@@ -1892,7 +2110,7 @@ declare const characterComponents: drizzle_orm_pg_core.PgTableWithColumns<{
1892
2110
  tableName: "character_components";
1893
2111
  dataType: "string";
1894
2112
  columnType: "PgEnumColumn";
1895
- data: "body" | "outfit" | "hairstyle" | "eyes" | "accessory";
2113
+ data: "accessory" | "body" | "outfit" | "hairstyle" | "eyes";
1896
2114
  driverParam: string;
1897
2115
  notNull: true;
1898
2116
  hasDefault: false;
@@ -2959,66 +3177,32 @@ declare const UpsertGameMetadataSchema: z.ZodEffects<z.ZodObject<{
2959
3177
  mapElementId?: string | null | undefined;
2960
3178
  metadata?: Record<string, unknown> | undefined;
2961
3179
  }>;
3180
+ /**
3181
+ * Simplified game manifest for Cloudflare Workers deployments
3182
+ *
3183
+ * The manifest is auto-generated by build tools (Godot plugin, Vite plugin, etc.)
3184
+ * and provides minimal metadata about the build.
3185
+ *
3186
+ * Fields:
3187
+ * - version: Manifest schema version (for future migrations)
3188
+ * - platform: Auto-detected by build tool (e.g., 'web', 'godot@4.3', 'unity@2023')
3189
+ * - createdAt: Build timestamp (ISO 8601)
3190
+ *
3191
+ * Note: With unified Cloudflare Workers deployments, the worker handles all routing
3192
+ * internally, so we no longer need bootMode, entryPoint, or styles fields.
3193
+ */
2962
3194
  declare const ManifestV1Schema: z.ZodObject<{
2963
3195
  version: z.ZodString;
2964
- bootMode: z.ZodEnum<["iframe", "module"]>;
2965
- entryPoint: z.ZodEffects<z.ZodString, string, string>;
2966
- /**
2967
- * An array of relative paths to CSS stylesheets.
2968
- * Currently, this property is ONLY utilized by the 'module' boot mode
2969
- * (`apps/cademy/src/lib/loader/boot-module.ts`) to load external
2970
- * stylesheets into the game's shadow DOM.
2971
- *
2972
- * This property is under review for potential deprecation and removal.
2973
- * The 'module' boot mode itself has not yet seen significant adoption
2974
- * or clear use-cases, and if support for module loading is removed in
2975
- * the future, this 'styles' property would become obsolete.
2976
- *
2977
- * If module-based games need styling, alternative approaches might involve
2978
- * bundling CSS within their JavaScript or managing style injection internally.
2979
- */
2980
- styles: z.ZodEffects<z.ZodOptional<z.ZodArray<z.ZodString, "many">>, string[] | undefined, string[] | undefined>;
2981
- /**
2982
- * Specifies the game or development platform.
2983
- * Current values include 'web', 'godot', and 'unity'.
2984
- * The default in the database is 'web'.
2985
- *
2986
- * IMPORTANT: This property is NOT CURRENTLY USED by the core loader
2987
- * or runtime systems in any functional way. It is present in the manifest
2988
- * but does not drive any specific behavior in `boot-iframe.ts` or
2989
- * `boot-module.ts` beyond being a piece of metadata.
2990
- *
2991
- * Potential Future Uses (Speculative):
2992
- * - Analytics: Could be used to gather stats on platform popularity/usage.
2993
- * - Developer Portal: Might inform UI/UX in the dev portal, e.g., showing
2994
- * platform-specific guides or settings.
2995
- * - Loader Optimizations: In the future, the loader could potentially use this
2996
- * to apply platform-specific loading strategies or workarounds, though this
2997
- * is unlikely given the current generic boot process.
2998
- * - Asset Pipeline: Could hint to future asset pipeline tools about expected
2999
- * project structures or build artifacts for different platforms.
3000
- *
3001
- * The field is intentionally kept somewhat generic. If finer-grained
3002
- * distinctions are ever needed (e.g., specific web frameworks like 'phaser',
3003
- * 'three'), this schema might need to be revisited or a separate
3004
- * 'platformVersion' or 'framework' field could be added.
3005
- */
3006
- platform: z.ZodEnum<["web", "godot", "unity"]>;
3196
+ platform: z.ZodString;
3007
3197
  createdAt: z.ZodString;
3008
3198
  }, "strip", z.ZodTypeAny, {
3009
3199
  createdAt: string;
3010
3200
  version: string;
3011
- platform: "web" | "godot" | "unity";
3012
- bootMode: "iframe" | "module";
3013
- entryPoint: string;
3014
- styles?: string[] | undefined;
3201
+ platform: string;
3015
3202
  }, {
3016
3203
  createdAt: string;
3017
3204
  version: string;
3018
- platform: "web" | "godot" | "unity";
3019
- bootMode: "iframe" | "module";
3020
- entryPoint: string;
3021
- styles?: string[] | undefined;
3205
+ platform: string;
3022
3206
  }>;
3023
3207
  declare const InsertItemSchema: drizzle_zod.BuildSchema<"insert", {
3024
3208
  id: drizzle_orm_pg_core.PgColumn<{
@@ -3111,7 +3295,7 @@ declare const InsertItemSchema: drizzle_zod.BuildSchema<"insert", {
3111
3295
  tableName: "items";
3112
3296
  dataType: "string";
3113
3297
  columnType: "PgEnumColumn";
3114
- data: "accessory" | "currency" | "badge" | "trophy" | "collectible" | "consumable" | "unlock" | "upgrade" | "other";
3298
+ data: "currency" | "badge" | "trophy" | "collectible" | "consumable" | "unlock" | "upgrade" | "accessory" | "other";
3115
3299
  driverParam: string;
3116
3300
  notNull: true;
3117
3301
  hasDefault: true;
@@ -3207,21 +3391,21 @@ declare const UpdateItemSchema: z.ZodObject<Omit<{
3207
3391
  metadata: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodUnknown>>;
3208
3392
  createdAt: z.ZodOptional<z.ZodDate>;
3209
3393
  }, "id" | "createdAt">, "strip", z.ZodTypeAny, {
3394
+ slug?: string | undefined;
3210
3395
  description?: string | null | undefined;
3211
3396
  displayName?: string | undefined;
3212
- slug?: string | undefined;
3213
3397
  metadata?: Record<string, unknown> | undefined;
3214
3398
  gameId?: string | null | undefined;
3215
- type?: "accessory" | "currency" | "badge" | "trophy" | "collectible" | "consumable" | "unlock" | "upgrade" | "other" | undefined;
3399
+ type?: "currency" | "badge" | "trophy" | "collectible" | "consumable" | "unlock" | "upgrade" | "accessory" | "other" | undefined;
3216
3400
  isPlaceable?: boolean | undefined;
3217
3401
  imageUrl?: string | null | undefined;
3218
3402
  }, {
3403
+ slug?: string | undefined;
3219
3404
  description?: string | null | undefined;
3220
3405
  displayName?: string | undefined;
3221
- slug?: string | undefined;
3222
3406
  metadata?: Record<string, unknown> | undefined;
3223
3407
  gameId?: string | null | undefined;
3224
- type?: "accessory" | "currency" | "badge" | "trophy" | "collectible" | "consumable" | "unlock" | "upgrade" | "other" | undefined;
3408
+ type?: "currency" | "badge" | "trophy" | "collectible" | "consumable" | "unlock" | "upgrade" | "accessory" | "other" | undefined;
3225
3409
  isPlaceable?: boolean | undefined;
3226
3410
  imageUrl?: string | null | undefined;
3227
3411
  }>;
@@ -3267,10 +3451,10 @@ declare const InsertShopListingSchema: z.ZodObject<Omit<{
3267
3451
  createdAt: z.ZodOptional<z.ZodDate>;
3268
3452
  updatedAt: z.ZodOptional<z.ZodNullable<z.ZodDate>>;
3269
3453
  }, "id" | "createdAt" | "updatedAt">, "strip", z.ZodTypeAny, {
3454
+ isActive: boolean;
3270
3455
  itemId: string;
3271
3456
  currencyId: string;
3272
3457
  price: number;
3273
- isActive: boolean;
3274
3458
  sellBackPercentage?: number | null | undefined;
3275
3459
  stock?: number | null | undefined;
3276
3460
  availableFrom?: Date | null | undefined;
@@ -3279,37 +3463,37 @@ declare const InsertShopListingSchema: z.ZodObject<Omit<{
3279
3463
  itemId: string;
3280
3464
  currencyId: string;
3281
3465
  price: number;
3466
+ isActive?: boolean | undefined;
3282
3467
  sellBackPercentage?: number | null | undefined;
3283
3468
  stock?: number | null | undefined;
3284
- isActive?: boolean | undefined;
3285
3469
  availableFrom?: Date | null | undefined;
3286
3470
  availableUntil?: Date | null | undefined;
3287
3471
  }>;
3288
3472
  declare const UpdateShopListingSchema: z.ZodObject<{
3473
+ isActive: z.ZodOptional<z.ZodDefault<z.ZodBoolean>>;
3289
3474
  itemId: z.ZodOptional<z.ZodString>;
3290
3475
  currencyId: z.ZodOptional<z.ZodString>;
3291
3476
  price: z.ZodOptional<z.ZodNumber>;
3292
3477
  sellBackPercentage: z.ZodOptional<z.ZodNullable<z.ZodOptional<z.ZodNumber>>>;
3293
3478
  stock: z.ZodOptional<z.ZodNullable<z.ZodOptional<z.ZodNumber>>>;
3294
- isActive: z.ZodOptional<z.ZodDefault<z.ZodBoolean>>;
3295
3479
  availableFrom: z.ZodOptional<z.ZodOptional<z.ZodNullable<z.ZodDate>>>;
3296
3480
  availableUntil: z.ZodOptional<z.ZodOptional<z.ZodNullable<z.ZodDate>>>;
3297
3481
  }, "strip", z.ZodTypeAny, {
3482
+ isActive?: boolean | undefined;
3298
3483
  itemId?: string | undefined;
3299
3484
  currencyId?: string | undefined;
3300
3485
  price?: number | undefined;
3301
3486
  sellBackPercentage?: number | null | undefined;
3302
3487
  stock?: number | null | undefined;
3303
- isActive?: boolean | undefined;
3304
3488
  availableFrom?: Date | null | undefined;
3305
3489
  availableUntil?: Date | null | undefined;
3306
3490
  }, {
3491
+ isActive?: boolean | undefined;
3307
3492
  itemId?: string | undefined;
3308
3493
  currencyId?: string | undefined;
3309
3494
  price?: number | undefined;
3310
3495
  sellBackPercentage?: number | null | undefined;
3311
3496
  stock?: number | null | undefined;
3312
- isActive?: boolean | undefined;
3313
3497
  availableFrom?: Date | null | undefined;
3314
3498
  availableUntil?: Date | null | undefined;
3315
3499
  }>;
@@ -3397,32 +3581,22 @@ type PlayerCharacter = typeof playerCharacters.$inferSelect & {
3397
3581
  };
3398
3582
  type PlayerCharacterAccessory = typeof playerCharacterAccessories.$inferSelect;
3399
3583
  type GameRow = typeof games.$inferSelect;
3400
- type BaseGame = Omit<GameRow, 'gameType' | 'assetBundleBase' | 'externalUrl'>;
3584
+ type BaseGame = Omit<GameRow, 'gameType' | 'deploymentUrl' | 'externalUrl'>;
3401
3585
  type HostedGame = BaseGame & {
3402
3586
  gameType: 'hosted';
3403
- assetBundleBase: string;
3587
+ deploymentUrl: string;
3404
3588
  externalUrl: null;
3405
3589
  };
3406
3590
  type ExternalGame = BaseGame & {
3407
3591
  gameType: 'external';
3408
- assetBundleBase: null;
3592
+ deploymentUrl: null;
3409
3593
  externalUrl: string;
3410
3594
  };
3411
3595
  type Game = HostedGame | ExternalGame;
3412
3596
  type GameSession = typeof gameSessions.$inferSelect;
3413
3597
  type GameStateData = Record<string, unknown>;
3598
+ type GameCustomHostname = typeof gameCustomHostnames.$inferSelect;
3414
3599
  type UpsertGameMetadataInput = z.infer<typeof UpsertGameMetadataSchema>;
3415
- /**
3416
- * Response from backend deployment API
3417
- */
3418
- interface BackendDeploymentResponse {
3419
- /** Unique deployment ID */
3420
- deploymentId: string;
3421
- /** Backend API URL */
3422
- url: string;
3423
- /** Deployment timestamp */
3424
- deployedAt: string;
3425
- }
3426
3600
  type Item = typeof items.$inferSelect;
3427
3601
  type InventoryItem = typeof inventoryItems.$inferSelect;
3428
3602
  type Currency = typeof currencies.$inferSelect;
@@ -3509,10 +3683,12 @@ type CharacterComponentWithSpriteUrl = CharacterComponent & {
3509
3683
  type InventoryItemWithItem = Omit<InventoryItem, 'itemId'> & {
3510
3684
  item: Item;
3511
3685
  };
3512
- type HostedGameWithManifest = HostedGame & {
3513
- manifest: ManifestV1;
3686
+ /**
3687
+ * Game with optional manifest metadata from build tools
3688
+ */
3689
+ type FetchedGame = (HostedGame | ExternalGame | GameRow) & {
3690
+ manifest?: ManifestV1;
3514
3691
  };
3515
- type FetchedGame = HostedGameWithManifest | GameRow;
3516
3692
  /**
3517
3693
  * Map-related Composite Types
3518
3694
  * Types that combine map, game, and item data for rendering and interaction
@@ -3933,6 +4109,8 @@ interface IntegrationsConfig {
3933
4109
  kv?: boolean;
3934
4110
  /** Bucket storage (optional) */
3935
4111
  bucket?: boolean;
4112
+ /** Authentication (optional) */
4113
+ auth?: boolean;
3936
4114
  }
3937
4115
  /**
3938
4116
  * Unified Playcademy configuration
@@ -4066,6 +4244,20 @@ interface UserScore {
4066
4244
  gameSlug: string;
4067
4245
  }
4068
4246
 
4247
+ /**
4248
+ * Connection monitoring types
4249
+ *
4250
+ * Type definitions for connection state, configuration, and callbacks.
4251
+ */
4252
+ /**
4253
+ * Possible connection states.
4254
+ *
4255
+ * - **online**: Connection is stable and healthy
4256
+ * - **offline**: Complete loss of network connectivity
4257
+ * - **degraded**: Connection is slow or experiencing intermittent issues
4258
+ */
4259
+ type ConnectionState = 'online' | 'offline' | 'degraded';
4260
+
4069
4261
  /**
4070
4262
  * @fileoverview Playcademy Messaging System
4071
4263
  *
@@ -4147,6 +4339,14 @@ declare enum MessageEvents {
4147
4339
  * Payload: boolean (true = show overlay, false = hide overlay)
4148
4340
  */
4149
4341
  OVERLAY = "PLAYCADEMY_OVERLAY",
4342
+ /**
4343
+ * Broadcasts connection state changes to games.
4344
+ * Sent by platform when network connectivity changes.
4345
+ * Payload:
4346
+ * - `state`: 'online' | 'offline' | 'degraded'
4347
+ * - `reason`: string
4348
+ */
4349
+ CONNECTION_STATE = "PLAYCADEMY_CONNECTION_STATE",
4150
4350
  /**
4151
4351
  * Game has finished loading and is ready to receive messages.
4152
4352
  * Sent once after game initialization is complete.
@@ -4176,6 +4376,14 @@ declare enum MessageEvents {
4176
4376
  * - `type`: 'keydown' | 'keyup'
4177
4377
  */
4178
4378
  KEY_EVENT = "PLAYCADEMY_KEY_EVENT",
4379
+ /**
4380
+ * Game requests platform to display an alert.
4381
+ * Sent when connection issues are detected or other important events occur.
4382
+ * Payload:
4383
+ * - `message`: string
4384
+ * - `options`: { type?: 'info' | 'warning' | 'error', duration?: number }
4385
+ */
4386
+ DISPLAY_ALERT = "PLAYCADEMY_DISPLAY_ALERT",
4179
4387
  /**
4180
4388
  * Notifies about authentication state changes.
4181
4389
  * Can be sent in both directions depending on auth flow.
@@ -4223,6 +4431,8 @@ declare enum MessageEvents {
4223
4431
  declare function init(options?: {
4224
4432
  baseUrl?: string;
4225
4433
  allowedParentOrigins?: string[];
4434
+ onDisconnect?: DisconnectHandler;
4435
+ enableConnectionMonitoring?: boolean;
4226
4436
  }): Promise<PlaycademyClient>;
4227
4437
 
4228
4438
  /**
@@ -4276,6 +4486,7 @@ declare class PlaycademyClient {
4276
4486
  private internalClientSessionId?;
4277
4487
  private authContext?;
4278
4488
  private initPayload?;
4489
+ private connectionManager?;
4279
4490
  /**
4280
4491
  * Creates a new PlaycademyClient instance.
4281
4492
  *
@@ -4367,6 +4578,85 @@ declare class PlaycademyClient {
4367
4578
  * @param callback - Function to call when auth state changes
4368
4579
  */
4369
4580
  onAuthChange(callback: (token: string | null) => void): void;
4581
+ /**
4582
+ * Registers a callback to be called when connection issues are detected.
4583
+ *
4584
+ * This is a convenience method that filters connection change events to only
4585
+ * fire when the connection degrades (offline or degraded states). Use this
4586
+ * when you want to handle disconnects without being notified of recoveries.
4587
+ *
4588
+ * For all connection state changes, use `client.on('connectionChange', ...)` instead.
4589
+ *
4590
+ * @param callback - Function to call when connection state changes to offline or degraded
4591
+ * @returns Cleanup function to unregister the callback
4592
+ *
4593
+ * @example
4594
+ * ```typescript
4595
+ * const cleanup = client.onDisconnect(({ state, reason, displayAlert }) => {
4596
+ * console.log(`Connection ${state}: ${reason}`)
4597
+ *
4598
+ * if (state === 'offline') {
4599
+ * // Save state and return to game lobby
4600
+ * displayAlert?.('Connection lost. Your progress has been saved.', { type: 'error' })
4601
+ * saveGameState()
4602
+ * returnToLobby()
4603
+ * } else if (state === 'degraded') {
4604
+ * displayAlert?.('Slow connection detected.', { type: 'warning' })
4605
+ * }
4606
+ * })
4607
+ *
4608
+ * // Later: cleanup() to unregister
4609
+ * ```
4610
+ *
4611
+ * @see {@link DISCONNECT_HANDLING.md} for detailed usage examples
4612
+ * @see {@link ConnectionManager.onDisconnect} for the underlying implementation
4613
+ */
4614
+ onDisconnect(callback: (context: DisconnectContext) => void | Promise<void>): () => void;
4615
+ /**
4616
+ * Gets the current connection state.
4617
+ *
4618
+ * Returns the last known connection state without triggering a new check.
4619
+ * Use `checkConnection()` to force an immediate verification.
4620
+ *
4621
+ * @returns Current connection state ('online', 'offline', 'degraded') or 'unknown' if monitoring is disabled
4622
+ *
4623
+ * @example
4624
+ * ```typescript
4625
+ * const state = client.getConnectionState()
4626
+ * if (state === 'offline') {
4627
+ * console.log('No connection available')
4628
+ * }
4629
+ * ```
4630
+ *
4631
+ * @see {@link checkConnection} to trigger an immediate connection check
4632
+ * @see {@link ConnectionManager.getState} for the underlying implementation
4633
+ */
4634
+ getConnectionState(): ConnectionState | 'unknown';
4635
+ /**
4636
+ * Manually triggers a connection check immediately.
4637
+ *
4638
+ * Forces a heartbeat ping to verify connectivity right now, bypassing the normal
4639
+ * interval. Useful when you need to verify connection status before a critical
4640
+ * operation (e.g., saving important game state).
4641
+ *
4642
+ * @returns Promise resolving to the current connection state after verification
4643
+ *
4644
+ * @example
4645
+ * ```typescript
4646
+ * // Check before critical operation
4647
+ * const state = await client.checkConnection()
4648
+ * if (state !== 'online') {
4649
+ * alert('Please check your internet connection before saving')
4650
+ * return
4651
+ * }
4652
+ *
4653
+ * await client.games.saveState(importantData)
4654
+ * ```
4655
+ *
4656
+ * @see {@link getConnectionState} to get the last known state without checking
4657
+ * @see {@link ConnectionManager.checkNow} for the underlying implementation
4658
+ */
4659
+ checkConnection(): Promise<ConnectionState | 'unknown'>;
4370
4660
  /**
4371
4661
  * Sets the authentication context for the client.
4372
4662
  * This is called during initialization to store environment info.
@@ -4429,6 +4719,11 @@ declare class PlaycademyClient {
4429
4719
  * Safe to call in any environment - isInIframe handles browser detection.
4430
4720
  */
4431
4721
  private _detectAuthContext;
4722
+ /**
4723
+ * Initializes connection monitoring if enabled.
4724
+ * Safe to call in any environment - only runs in browser.
4725
+ */
4726
+ private _initializeConnectionMonitor;
4432
4727
  /**
4433
4728
  * Initializes an internal game session for automatic session management.
4434
4729
  * Only starts a session if:
@@ -4552,15 +4847,17 @@ declare class PlaycademyClient {
4552
4847
  get: () => Promise<DeveloperStatusValue>;
4553
4848
  };
4554
4849
  games: {
4555
- deploy: {
4556
- frontend: (slug: string, metadata: UpsertGameMetadataInput, file: File | Blob | null, hooks?: DevUploadHooks) => Promise<Game>;
4557
- backend: (slug: string, bundle: BackendDeploymentBundle) => Promise<BackendDeploymentResponse>;
4558
- seed: (slug: string, code: string, environment?: "staging" | "production") => Promise<{
4559
- success: boolean;
4560
- deploymentId: string;
4561
- executedAt: string;
4562
- }>;
4563
- };
4850
+ deploy: (slug: string, options: {
4851
+ metadata?: UpsertGameMetadataInput;
4852
+ file?: File | Blob | null;
4853
+ backend?: BackendDeploymentBundle;
4854
+ hooks?: DevUploadHooks;
4855
+ }) => Promise<Game>;
4856
+ seed: (slug: string, code: string, environment?: "staging" | "production") => Promise<{
4857
+ success: boolean;
4858
+ deploymentId: string;
4859
+ executedAt: string;
4860
+ }>;
4564
4861
  upsert: (slug: string, metadata: UpsertGameMetadataInput) => Promise<Game>;
4565
4862
  delete: (gameId: string) => Promise<void>;
4566
4863
  secrets: {
@@ -4586,6 +4883,12 @@ declare class PlaycademyClient {
4586
4883
  put: (slug: string, key: string, content: Blob | ArrayBuffer | Uint8Array, contentType?: string) => Promise<void>;
4587
4884
  delete: (slug: string, key: string) => Promise<void>;
4588
4885
  };
4886
+ domains: {
4887
+ add: (slug: string, hostname: string) => Promise<GameCustomHostname>;
4888
+ list: (slug: string) => Promise<GameCustomHostname[]>;
4889
+ status: (slug: string, hostname: string, refresh?: boolean) => Promise<GameCustomHostname>;
4890
+ delete: (slug: string, hostname: string) => Promise<void>;
4891
+ };
4589
4892
  };
4590
4893
  items: {
4591
4894
  create: (gameId: string, slug: string, itemData: Omit<InsertItemInput, "slug" | "gameId">) => Promise<Item>;
@@ -4622,50 +4925,50 @@ declare class PlaycademyClient {
4622
4925
  };
4623
4926
  items: {
4624
4927
  create: (props: InsertItemInput) => Promise<{
4625
- metadata: unknown;
4626
- type: "accessory" | "currency" | "badge" | "trophy" | "collectible" | "consumable" | "unlock" | "upgrade" | "other";
4627
- slug: string;
4628
4928
  id: string;
4629
4929
  createdAt: Date;
4630
4930
  gameId: string | null;
4931
+ slug: string;
4631
4932
  displayName: string;
4933
+ metadata: unknown;
4632
4934
  description: string | null;
4935
+ type: "accessory" | "currency" | "badge" | "trophy" | "collectible" | "consumable" | "unlock" | "upgrade" | "other";
4633
4936
  isPlaceable: boolean;
4634
4937
  imageUrl: string | null;
4635
4938
  }>;
4636
4939
  get: (itemId: string) => Promise<{
4637
- metadata: unknown;
4638
- type: "accessory" | "currency" | "badge" | "trophy" | "collectible" | "consumable" | "unlock" | "upgrade" | "other";
4639
- slug: string;
4640
4940
  id: string;
4641
4941
  createdAt: Date;
4642
4942
  gameId: string | null;
4943
+ slug: string;
4643
4944
  displayName: string;
4945
+ metadata: unknown;
4644
4946
  description: string | null;
4947
+ type: "accessory" | "currency" | "badge" | "trophy" | "collectible" | "consumable" | "unlock" | "upgrade" | "other";
4645
4948
  isPlaceable: boolean;
4646
4949
  imageUrl: string | null;
4647
4950
  }>;
4648
4951
  list: () => Promise<{
4649
- metadata: unknown;
4650
- type: "accessory" | "currency" | "badge" | "trophy" | "collectible" | "consumable" | "unlock" | "upgrade" | "other";
4651
- slug: string;
4652
4952
  id: string;
4653
4953
  createdAt: Date;
4654
4954
  gameId: string | null;
4955
+ slug: string;
4655
4956
  displayName: string;
4957
+ metadata: unknown;
4656
4958
  description: string | null;
4959
+ type: "accessory" | "currency" | "badge" | "trophy" | "collectible" | "consumable" | "unlock" | "upgrade" | "other";
4657
4960
  isPlaceable: boolean;
4658
4961
  imageUrl: string | null;
4659
4962
  }[]>;
4660
4963
  update: (itemId: string, props: UpdateItemInput) => Promise<{
4661
- metadata: unknown;
4662
- type: "accessory" | "currency" | "badge" | "trophy" | "collectible" | "consumable" | "unlock" | "upgrade" | "other";
4663
- slug: string;
4664
4964
  id: string;
4665
4965
  createdAt: Date;
4666
4966
  gameId: string | null;
4967
+ slug: string;
4667
4968
  displayName: string;
4969
+ metadata: unknown;
4668
4970
  description: string | null;
4971
+ type: "accessory" | "currency" | "badge" | "trophy" | "collectible" | "consumable" | "unlock" | "upgrade" | "other";
4669
4972
  isPlaceable: boolean;
4670
4973
  imageUrl: string | null;
4671
4974
  }>;
@@ -4800,9 +5103,7 @@ declare class PlaycademyClient {
4800
5103
  }) => Promise<TodayXpResponse>;
4801
5104
  total: () => Promise<TotalXpResponse>;
4802
5105
  history: (options?: {
4803
- startDate
4804
- /** Auto-initializes a PlaycademyClient with context from the environment */
4805
- ?: string;
5106
+ startDate?: string;
4806
5107
  endDate?: string;
4807
5108
  }) => Promise<XpHistoryResponse>;
4808
5109
  summary: (options?: {
@@ -4923,14 +5224,41 @@ interface ClientConfig {
4923
5224
  tokenType?: TokenType;
4924
5225
  gameId?: string;
4925
5226
  autoStartSession?: boolean;
5227
+ onDisconnect?: DisconnectHandler;
5228
+ enableConnectionMonitoring?: boolean;
5229
+ }
5230
+ /**
5231
+ * Handler called when connection state changes to offline or degraded.
5232
+ * Games can implement this to handle disconnects gracefully.
5233
+ */
5234
+ type DisconnectHandler = (context: DisconnectContext) => void | Promise<void>;
5235
+ /**
5236
+ * Context provided to disconnect handlers
5237
+ */
5238
+ interface DisconnectContext {
5239
+ /** Current connection state */
5240
+ state: 'offline' | 'degraded';
5241
+ /** Reason for the disconnect */
5242
+ reason: string;
5243
+ /** Timestamp when disconnect was detected */
5244
+ timestamp: number;
5245
+ /** Utility to display a platform-level alert */
5246
+ displayAlert: (message: string, options?: {
5247
+ type?: 'info' | 'warning' | 'error';
5248
+ duration?: number;
5249
+ }) => void;
4926
5250
  }
4927
5251
  interface InitPayload {
5252
+ /** Hub API base URL */
4928
5253
  baseUrl: string;
5254
+ /** Game deployment URL (serves both frontend assets and backend API) */
4929
5255
  gameUrl?: string;
5256
+ /** Short-lived game token */
4930
5257
  token: string;
5258
+ /** Game ID */
4931
5259
  gameId: string;
5260
+ /** Realtime WebSocket URL */
4932
5261
  realtimeUrl?: string;
4933
- cdnBase?: string;
4934
5262
  }
4935
5263
  type AuthProviderType = (typeof AUTH_PROVIDER_IDS)[keyof typeof AUTH_PROVIDER_IDS];
4936
5264
  interface AuthOptions {
@@ -5064,6 +5392,32 @@ interface KeyEventPayload {
5064
5392
  /** Event type */
5065
5393
  type: 'keydown' | 'keyup';
5066
5394
  }
5395
+ interface DisplayAlertPayload {
5396
+ message: string;
5397
+ options?: {
5398
+ type?: 'info' | 'warning' | 'error';
5399
+ duration?: number;
5400
+ };
5401
+ }
5402
+ /**
5403
+ * Display alert payload.
5404
+ * Request from game to show platform-level alert.
5405
+ */
5406
+ interface DisplayAlertPayload {
5407
+ message: string;
5408
+ options?: {
5409
+ type?: 'info' | 'warning' | 'error';
5410
+ duration?: number;
5411
+ };
5412
+ }
5413
+ /**
5414
+ * Connection state payload.
5415
+ * Broadcast from platform to games when connection changes.
5416
+ */
5417
+ interface ConnectionStatePayload {
5418
+ state: 'online' | 'offline' | 'degraded';
5419
+ reason: string;
5420
+ }
5067
5421
  interface ClientEvents {
5068
5422
  authChange: {
5069
5423
  token: string | null;
@@ -5083,6 +5437,10 @@ interface ClientEvents {
5083
5437
  totalXP: number;
5084
5438
  leveledUp: boolean;
5085
5439
  };
5440
+ connectionChange: {
5441
+ state: 'online' | 'offline' | 'degraded';
5442
+ reason: string;
5443
+ };
5086
5444
  }
5087
5445
  type GameContextPayload = {
5088
5446
  token: string;
@@ -5178,4 +5536,4 @@ interface BucketFile {
5178
5536
  }
5179
5537
 
5180
5538
  export { PlaycademyClient };
5181
- export type { Achievement, AchievementCurrent, AchievementProgressResponse, AuthCallbackPayload, AuthOptions, AuthProviderType, AuthResult, AuthServerMessage, AuthStateChangePayload, AuthStateUpdate, AuthenticatedUser, BetterAuthApiKey, BetterAuthApiKeyResponse, BetterAuthSignInResponse, BucketFile, CharacterComponent, CharacterComponentWithSpriteUrl, ClientConfig, ClientEvents, Currency, DevUploadEvent, DevUploadHooks, DeveloperStatusResponse, EventListeners, ExternalGame, Game, GameContextPayload, GameLeaderboardEntry, GameSession, GameStateData, GameTokenResponse, GameUser, HostedGame, HostedGameWithManifest, InitPayload, InventoryItem, InventoryItemWithItem, InventoryMutationResponse, Item, KeyEventPayload, LeaderboardEntry, LevelConfig, LoginResponse, ManifestV1, Map, MapElement, MapElementWithGame, MapObject, MapObjectWithItem, PlaycademyServerClientConfig, PlaycademyServerClientState, PlayerCharacter, ShopCurrency, ShopDisplayItem, ShopViewResponse, SpriteTemplate, SpriteTemplateData, StartSessionResponse, TelemetryPayload, TodayXpResponse, TokenRefreshPayload, TokenType, TotalXpResponse, User, UserInfo, UserLevel, UserLevelWithConfig, UserRank, UserRankResponse, UserRoleEnumType, UserScore$1 as UserScore, XpHistoryResponse };
5539
+ export type { Achievement, AchievementCurrent, AchievementProgressResponse, AuthCallbackPayload, AuthOptions, AuthProviderType, AuthResult, AuthServerMessage, AuthStateChangePayload, AuthStateUpdate, AuthenticatedUser, BetterAuthApiKey, BetterAuthApiKeyResponse, BetterAuthSignInResponse, BucketFile, CharacterComponent, CharacterComponentWithSpriteUrl, ClientConfig, ClientEvents, ConnectionStatePayload, Currency, DevUploadEvent, DevUploadHooks, DeveloperStatusResponse, DisconnectContext, DisconnectHandler, DisplayAlertPayload, EventListeners, ExternalGame, FetchedGame, Game, GameContextPayload, GameLeaderboardEntry, GameSession, GameStateData, GameTokenResponse, GameUser, HostedGame, InitPayload, InventoryItem, InventoryItemWithItem, InventoryMutationResponse, Item, KeyEventPayload, LeaderboardEntry, LevelConfig, LoginResponse, ManifestV1, Map, MapElement, MapElementWithGame, MapObject, MapObjectWithItem, PlaycademyServerClientConfig, PlaycademyServerClientState, PlayerCharacter, ShopCurrency, ShopDisplayItem, ShopViewResponse, SpriteTemplate, SpriteTemplateData, StartSessionResponse, TelemetryPayload, TodayXpResponse, TokenRefreshPayload, TokenType, TotalXpResponse, User, UserInfo, UserLevel, UserLevelWithConfig, UserRank, UserRankResponse, UserRoleEnumType, UserScore$1 as UserScore, XpHistoryResponse };