@indiegems/gem-web-sdk 20.1.0 → 21.1.0

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.
Files changed (66) hide show
  1. package/CHANGELOG.md +40 -0
  2. package/README.md +1 -0
  3. package/brand/ticket-hero-128.png +0 -0
  4. package/brand/ticket-hero-256.png +0 -0
  5. package/brand/ticket-hero-384.png +0 -0
  6. package/brand/ticket-hero-512.png +0 -0
  7. package/brand/ticket-hero-768.png +0 -0
  8. package/brand/ticket-icon-20-1.5x.png +0 -0
  9. package/brand/ticket-icon-20-1x.png +0 -0
  10. package/brand/ticket-icon-20-2x.png +0 -0
  11. package/brand/ticket-icon-20-3x.png +0 -0
  12. package/brand/ticket-icon-32-1.5x.png +0 -0
  13. package/brand/ticket-icon-32-1x.png +0 -0
  14. package/brand/ticket-icon-32-2x.png +0 -0
  15. package/brand/ticket-icon-32-3x.png +0 -0
  16. package/brand/ticket-icon-ingame-20-1.5x.png +0 -0
  17. package/brand/ticket-icon-ingame-20-1x.png +0 -0
  18. package/brand/ticket-icon-ingame-20-2x.png +0 -0
  19. package/brand/ticket-icon-ingame-20-3x.png +0 -0
  20. package/brand/ticket-icon-ingame-32-1.5x.png +0 -0
  21. package/brand/ticket-icon-ingame-32-1x.png +0 -0
  22. package/brand/ticket-icon-ingame-32-2x.png +0 -0
  23. package/brand/ticket-icon-ingame-32-3x.png +0 -0
  24. package/brand/ticket-pile-1-128.png +0 -0
  25. package/brand/ticket-pile-1-256.png +0 -0
  26. package/brand/ticket-pile-1-384.png +0 -0
  27. package/brand/ticket-pile-1-512.png +0 -0
  28. package/brand/ticket-pile-1-768.png +0 -0
  29. package/brand/ticket-pile-2-128.png +0 -0
  30. package/brand/ticket-pile-2-256.png +0 -0
  31. package/brand/ticket-pile-2-384.png +0 -0
  32. package/brand/ticket-pile-2-512.png +0 -0
  33. package/brand/ticket-pile-2-768.png +0 -0
  34. package/dist/conformance.d.ts +1 -1
  35. package/dist/dev-tools.d.ts +1 -0
  36. package/dist/function.d.ts +11 -3
  37. package/dist/game.d.ts +79 -12
  38. package/dist/gem-web-sdk.bridge.js +2 -2
  39. package/dist/gem-web-sdk.conformance.js +3 -3
  40. package/dist/gem-web-sdk.dev-tools.js +2 -0
  41. package/dist/gem-web-sdk.esm.js +3 -3
  42. package/dist/gem-web-sdk.function.js +3 -3
  43. package/dist/gem-web-sdk.game.js +3 -3
  44. package/dist/gem-web-sdk.min.js +3 -3
  45. package/dist/gem-web-sdk.sdk.js +3 -3
  46. package/dist/gem-web-sdk.server.js +2 -2
  47. package/dist/index.d.ts +103 -48
  48. package/dist/sdk.d.ts +79 -12
  49. package/docs/analytics.md +12 -0
  50. package/docs/api/api-reference-function.md +14 -2
  51. package/docs/api/api-reference-game.md +357 -21
  52. package/docs/api/api-reference-server.md +1 -1
  53. package/docs/api/reference.json +413 -16
  54. package/docs/arcade-economy.md +2 -2
  55. package/docs/brand-art.md +65 -16
  56. package/docs/changelog.md +40 -0
  57. package/docs/game-economy-tutorial.md +6 -3
  58. package/docs/getting-started.md +122 -30
  59. package/docs/graphics-route.md +188 -0
  60. package/docs/inventory-and-catalogs.md +69 -27
  61. package/docs/manifest.json +23 -18
  62. package/docs/server-bundles.md +3 -3
  63. package/docs/what-a-game-must-do.md +33 -2
  64. package/package.json +5 -1
  65. package/schema/bridge.v1.json +263 -12
  66. package/schema/capabilities.public.json +26 -0
package/dist/index.d.ts CHANGED
@@ -32,6 +32,7 @@ declare const PARENT_TO_FRAME: readonly [
32
32
  "gem.dedicatedEvent",
33
33
  "gem.partyResult",
34
34
  "gem.clusterTarget",
35
+ "gem.graphicsRoutes",
35
36
  "gem.devtools",
36
37
  "gem.screenshot",
37
38
  "gem.requestContext",
@@ -39,8 +40,10 @@ declare const PARENT_TO_FRAME: readonly [
39
40
  "gem.localServer.denied",
40
41
  "gem.menuSelect",
41
42
  "gem.settingChange",
43
+ "gem.shareResult",
42
44
  "gem.error",
43
45
  "gem.purchaseResult",
46
+ "gem.purchaseSettled",
44
47
  "gem.deviceSettings.result",
45
48
  "gem.adResult",
46
49
  "gem.momentResult",
@@ -99,7 +102,7 @@ declare const FRAME_TO_PARENT: readonly [
99
102
  "gem.requestStorePurchase",
100
103
  "gem.requestStoreOfferSheet"
101
104
  ];
102
- type GemCapability = "ads" | "signIn" | "purchases" | "avatar3dPurchases" | "friendChallenges" | "devtools" | "screenshot" | "feedbackContext" | "rooms" | "p2p" | "dedicated" | "clusterTarget" | "parties" | "autoStartFailure" | "ticketEvents" | "partySeating" | "socketState" | "audioState" | "rewardCue" | "frameStats" | "portraitBorders" | "engagement" | "viewport" | "reservedAreas" | "audioChannels" | "walletDisplay" | "localHost" | "cohorts" | "earnAllowance" | "deviceSettings" | "asyncOpponents" | "share" | "avatarPicker" | "vibration" | "gameMenu" | "controls" | "gemCorner" | "gameSettings" | "moments" | "appLinks" | "openGame" | "store" | "storeOfferSheet" | "menuStyle" | "p2pRelayDrain";
105
+ type GemCapability = "ads" | "signIn" | "purchases" | "purchaseSettled" | "avatar3dPurchases" | "friendChallenges" | "devtools" | "screenshot" | "feedbackContext" | "rooms" | "p2p" | "dedicated" | "clusterTarget" | "graphicsRoutes" | "parties" | "autoStartFailure" | "ticketEvents" | "partySeating" | "socketState" | "audioState" | "rewardCue" | "frameStats" | "portraitBorders" | "engagement" | "viewport" | "reservedAreas" | "audioChannels" | "walletDisplay" | "localHost" | "cohorts" | "earnAllowance" | "deviceSettings" | "asyncOpponents" | "share" | "shareResult" | "shareRemap" | "avatarPicker" | "vibration" | "gameMenu" | "controls" | "gemCorner" | "gameSettings" | "moments" | "appLinks" | "openGame" | "store" | "storeOfferSheet" | "menuStyle" | "p2pRelayDrain";
103
106
  declare const CAPABILITY_GATES: Readonly<Record<string, string>>;
104
107
  declare const CAPABILITY_NAMESPACE_GATES: ReadonlyArray<readonly [
105
108
  string,
@@ -335,6 +338,15 @@ interface GemClusterTarget {
335
338
  readonly clusterTargetId: string;
336
339
  readonly clusterTargetIds?: string[];
337
340
  }
341
+ interface GemGraphicsRoutes {
342
+ readonly gem: typeof PROTOCOL;
343
+ readonly type: "gem.graphicsRoutes";
344
+ readonly entries: {
345
+ gpu: string;
346
+ route?: string;
347
+ host?: string;
348
+ }[];
349
+ }
338
350
  interface GemDevtools {
339
351
  readonly gem: typeof PROTOCOL;
340
352
  readonly type: "gem.devtools";
@@ -520,11 +532,20 @@ interface GemSettingChange {
520
532
  interface GemRequestShare {
521
533
  readonly gem: typeof PROTOCOL;
522
534
  readonly type: "gem.requestShare";
535
+ readonly requestId?: string;
523
536
  readonly params: {
524
537
  key: string;
525
538
  value: string;
526
539
  }[];
527
540
  }
541
+ interface GemShareResult {
542
+ readonly gem: typeof PROTOCOL;
543
+ readonly type: "gem.shareResult";
544
+ readonly requestId: string;
545
+ readonly outcome: "accepted" | "refused";
546
+ readonly reason?: string;
547
+ readonly key?: string;
548
+ }
528
549
  interface GemRequestAvatarPicker {
529
550
  readonly gem: typeof PROTOCOL;
530
551
  readonly type: "gem.requestAvatarPicker";
@@ -562,6 +583,7 @@ interface GemRequestPurchase {
562
583
  readonly currencySlug: string;
563
584
  readonly quantity?: number;
564
585
  readonly catalogId?: string;
586
+ readonly origin?: "sheet" | "direct_refused";
565
587
  }
566
588
  interface GemRequestAvatar3dPurchase {
567
589
  readonly gem: typeof PROTOCOL;
@@ -578,6 +600,15 @@ interface GemPurchaseResult {
578
600
  readonly reason?: string;
579
601
  readonly purchaseId?: string;
580
602
  }
603
+ interface GemPurchaseSettled {
604
+ readonly gem: typeof PROTOCOL;
605
+ readonly type: "gem.purchaseSettled";
606
+ readonly purchaseKind: "item" | "recipe";
607
+ readonly targetId: string;
608
+ readonly catalogId?: string;
609
+ readonly quantity: number;
610
+ readonly purchaseId?: string;
611
+ }
581
612
  interface GemDeviceSettingsPut {
582
613
  readonly gem: typeof PROTOCOL;
583
614
  readonly type: "gem.deviceSettings.put";
@@ -775,7 +806,7 @@ interface GemStoreOfferSheetResult {
775
806
  readonly outcome: "ok" | "declined" | "unavailable";
776
807
  readonly reason?: string;
777
808
  }
778
- type ParentMessage = GemHandshake | GemToken | GemTokenDenied | GemPlayer | GemPause | GemPrefs | GemCohorts | GemEarnAllowanceChanged | GemViewport | GemDeviceSettings | GemWillTerminate | GemRoomEvent | GemSocketState | GemSeatedEvent | GemAutoStartFailedEvent | GemTicketEvent | GemSignalEvent | GemRelayDraining | GemDedicatedEvent | GemPartyResult | GemClusterTarget | GemDevtools | GemScreenshot | GemRequestContext | GemLocalServer | GemLocalServerDenied | GemMenuSelect | GemSettingChange | GemError | GemPurchaseResult | GemDeviceSettingsResult | GemAdResult | GemMomentResult | GemSignInResult | GemFriendChallengeResult | GemAppLinksResult | GemOpenAppResult | GemOpenGameResult | GemSimilarGamesResult | GemStoreOffersResult | GemStorePurchaseResult | GemStorePurchaseSettled | GemStoreOfferSheetResult;
809
+ type ParentMessage = GemHandshake | GemToken | GemTokenDenied | GemPlayer | GemPause | GemPrefs | GemCohorts | GemEarnAllowanceChanged | GemViewport | GemDeviceSettings | GemWillTerminate | GemRoomEvent | GemSocketState | GemSeatedEvent | GemAutoStartFailedEvent | GemTicketEvent | GemSignalEvent | GemRelayDraining | GemDedicatedEvent | GemPartyResult | GemClusterTarget | GemGraphicsRoutes | GemDevtools | GemScreenshot | GemRequestContext | GemLocalServer | GemLocalServerDenied | GemMenuSelect | GemSettingChange | GemShareResult | GemError | GemPurchaseResult | GemPurchaseSettled | GemDeviceSettingsResult | GemAdResult | GemMomentResult | GemSignInResult | GemFriendChallengeResult | GemAppLinksResult | GemOpenAppResult | GemOpenGameResult | GemSimilarGamesResult | GemStoreOffersResult | GemStorePurchaseResult | GemStorePurchaseSettled | GemStoreOfferSheetResult;
779
810
  type FrameMessage = GemHandshakeAccept | GemScreenshotDenied | GemGameContext | GemSignal | GemDedicatedOffer | GemPartyRequest | GemReady | GemEngaged | GemProgress | GemRequestToken | GemRequestLocalServer | GemExit | GemOpenExternal | GemRequestFullscreen | GemAudioState | GemRewardCue | GemWalletDisplay | GemControlsDeclare | GemMenu | GemGemCorner | GemMenuStyle | GemSettingsDeclare | GemRequestShare | GemRequestAvatarPicker | GemVibrate | GemFrameStats | GemPortraitBorders | GemError | GemRequestPurchase | GemRequestAvatar3dPurchase | GemDeviceSettingsPut | GemRequestAd | GemSignalMoment | GemRequestSignIn | GemRequestFriendChallenge | GemRequestAppLinks | GemRequestOpenApp | GemRequestOpenGame | GemRequestSimilarGames | GemRequestStoreOffers | GemRequestStorePurchase | GemRequestStoreOfferSheet;
780
811
  type GemMessage = ParentMessage | FrameMessage;
781
812
  type Rejection = string | null;
@@ -803,6 +834,7 @@ declare const validateGemRelayDraining: (raw: unknown) => Rejection;
803
834
  declare const validateGemDedicatedEvent: (raw: unknown) => Rejection;
804
835
  declare const validateGemPartyResult: (raw: unknown) => Rejection;
805
836
  declare const validateGemClusterTarget: (raw: unknown) => Rejection;
837
+ declare const validateGemGraphicsRoutes: (raw: unknown) => Rejection;
806
838
  declare const validateGemDevtools: (raw: unknown) => Rejection;
807
839
  declare const validateGemScreenshot: (raw: unknown) => Rejection;
808
840
  declare const validateGemScreenshotDenied: (raw: unknown) => Rejection;
@@ -832,6 +864,7 @@ declare const validateGemMenuStyle: (raw: unknown) => Rejection;
832
864
  declare const validateGemSettingsDeclare: (raw: unknown) => Rejection;
833
865
  declare const validateGemSettingChange: (raw: unknown) => Rejection;
834
866
  declare const validateGemRequestShare: (raw: unknown) => Rejection;
867
+ declare const validateGemShareResult: (raw: unknown) => Rejection;
835
868
  declare const validateGemRequestAvatarPicker: (raw: unknown) => Rejection;
836
869
  declare const validateGemVibrate: (raw: unknown) => Rejection;
837
870
  declare const validateGemFrameStats: (raw: unknown) => Rejection;
@@ -840,6 +873,7 @@ declare const validateGemError: (raw: unknown) => Rejection;
840
873
  declare const validateGemRequestPurchase: (raw: unknown) => Rejection;
841
874
  declare const validateGemRequestAvatar3dPurchase: (raw: unknown) => Rejection;
842
875
  declare const validateGemPurchaseResult: (raw: unknown) => Rejection;
876
+ declare const validateGemPurchaseSettled: (raw: unknown) => Rejection;
843
877
  declare const validateGemDeviceSettingsPut: (raw: unknown) => Rejection;
844
878
  declare const validateGemDeviceSettingsResult: (raw: unknown) => Rejection;
845
879
  declare const validateGemRequestAd: (raw: unknown) => Rejection;
@@ -866,49 +900,6 @@ declare const validateGemStorePurchaseSettled: (raw: unknown) => Rejection;
866
900
  declare const validateGemRequestStoreOfferSheet: (raw: unknown) => Rejection;
867
901
  declare const validateGemStoreOfferSheetResult: (raw: unknown) => Rejection;
868
902
  declare const VALIDATORS: Readonly<Record<string, (raw: unknown) => Rejection>>;
869
- type PurchaseRefusalCode = "unknown_currency" | "currency_not_in_game_payable" | "not_purchasable" | "no_price_in_currency" | "busy" | "cancelled" | "insufficient_funds" | "price_mismatch" | "config_version_stale" | "platform_currency_unavailable" | "not_available" | "recipe_locked" | "already_owned" | "recipe_on_cooldown" | "recipe_max_uses_exceeded" | "item_max_stack_exceeded" | "recipe_costs_unmet" | "quantity_invalid" | "error";
870
- interface OfferRefusal {
871
- readonly reason: string;
872
- }
873
- declare function buildDedicatedOfferFrame(matchId: string, gameId: string, data: unknown): {
874
- frame: Record<string, unknown>;
875
- } | OfferRefusal;
876
- declare const INBOUND_EVENTS: Readonly<Record<string, string>>;
877
- interface RelayedDedicatedEvent {
878
- readonly event: string;
879
- readonly matchId: string;
880
- readonly sdp?: string;
881
- readonly sessionId?: string;
882
- readonly code?: string;
883
- readonly message?: string;
884
- readonly reason?: string;
885
- }
886
- declare function projectDedicatedEvent(raw: unknown, gameId: string, knowsMatch: (matchId: string) => boolean): RelayedDedicatedEvent | null;
887
- declare const MAX_SOCKET_FRAME_BYTES = 16384;
888
- declare const MAX_SIGNALS_PER_SECOND = 24;
889
- interface SignalRefusal {
890
- readonly reason: string;
891
- }
892
- declare function buildSocketFrame(signal: string, matchId: string, gameId: string, data: unknown): {
893
- frame: Record<string, unknown>;
894
- } | SignalRefusal;
895
- interface RelayedSignal {
896
- readonly event: string;
897
- readonly matchId: string;
898
- readonly data: Record<string, unknown>;
899
- }
900
- declare function projectSignal(raw: unknown, gameId: string, knowsMatch: (matchId: string) => boolean): RelayedSignal | null;
901
- interface PartyEventRelay {
902
- readonly event: string;
903
- readonly partyId: string;
904
- readonly version?: number;
905
- readonly gameRoomId?: string;
906
- readonly gameId?: string;
907
- readonly inviterPlayerId?: string;
908
- readonly inviterDisplayTag?: string;
909
- readonly partyName?: string;
910
- }
911
- declare function projectPartyEvent(raw: unknown): PartyEventRelay | null;
912
903
  type PortMessageHandler = {
913
904
  handle(event: {
914
905
  data: unknown;
@@ -951,6 +942,55 @@ declare function negotiateVersion(ours: {
951
942
  min: number;
952
943
  max: number;
953
944
  }): number | null;
945
+ interface GemGraphicsRouteEntry {
946
+ readonly gpu: string;
947
+ readonly route?: string;
948
+ readonly host?: string;
949
+ }
950
+ declare const BUILT_IN_GRAPHICS_ROUTES: readonly GemGraphicsRouteEntry[];
951
+ type PurchaseRefusalCode = "unknown_currency" | "currency_not_in_game_payable" | "not_purchasable" | "no_price_in_currency" | "busy" | "cancelled" | "insufficient_funds" | "price_mismatch" | "config_version_stale" | "platform_currency_unavailable" | "not_available" | "recipe_locked" | "already_owned" | "guest_upgrade_required" | "recipe_on_cooldown" | "recipe_max_uses_exceeded" | "item_max_stack_exceeded" | "recipe_costs_unmet" | "quantity_invalid" | "error";
952
+ interface OfferRefusal {
953
+ readonly reason: string;
954
+ }
955
+ declare function buildDedicatedOfferFrame(matchId: string, gameId: string, data: unknown): {
956
+ frame: Record<string, unknown>;
957
+ } | OfferRefusal;
958
+ declare const INBOUND_EVENTS: Readonly<Record<string, string>>;
959
+ interface RelayedDedicatedEvent {
960
+ readonly event: string;
961
+ readonly matchId: string;
962
+ readonly sdp?: string;
963
+ readonly sessionId?: string;
964
+ readonly code?: string;
965
+ readonly message?: string;
966
+ readonly reason?: string;
967
+ }
968
+ declare function projectDedicatedEvent(raw: unknown, gameId: string, knowsMatch: (matchId: string) => boolean): RelayedDedicatedEvent | null;
969
+ declare const MAX_SOCKET_FRAME_BYTES = 16384;
970
+ declare const MAX_SIGNALS_PER_SECOND = 24;
971
+ interface SignalRefusal {
972
+ readonly reason: string;
973
+ }
974
+ declare function buildSocketFrame(signal: string, matchId: string, gameId: string, data: unknown): {
975
+ frame: Record<string, unknown>;
976
+ } | SignalRefusal;
977
+ interface RelayedSignal {
978
+ readonly event: string;
979
+ readonly matchId: string;
980
+ readonly data: Record<string, unknown>;
981
+ }
982
+ declare function projectSignal(raw: unknown, gameId: string, knowsMatch: (matchId: string) => boolean): RelayedSignal | null;
983
+ interface PartyEventRelay {
984
+ readonly event: string;
985
+ readonly partyId: string;
986
+ readonly version?: number;
987
+ readonly gameRoomId?: string;
988
+ readonly gameId?: string;
989
+ readonly inviterPlayerId?: string;
990
+ readonly inviterDisplayTag?: string;
991
+ readonly partyName?: string;
992
+ }
993
+ declare function projectPartyEvent(raw: unknown): PartyEventRelay | null;
954
994
  interface TokenGrant {
955
995
  readonly token: string;
956
996
  readonly expiresAt: number;
@@ -1156,6 +1196,13 @@ declare class GemHost {
1156
1196
  private rememberAsked;
1157
1197
  answerPartyRequest(requestId: string, partyId?: string): boolean;
1158
1198
  answerPurchase(requestId: string, outcome: "ok" | "declined" | "unavailable", purchaseId?: string, reason?: PurchaseRefusalCode): boolean;
1199
+ sendPurchaseSettled(settlement: {
1200
+ purchaseKind: "item" | "recipe";
1201
+ targetId: string;
1202
+ catalogId?: string;
1203
+ quantity: number;
1204
+ purchaseId?: string;
1205
+ }): boolean;
1159
1206
  answerDeviceSettingsPut(requestId: string, outcome: "stored" | "too_large" | "unavailable"): boolean;
1160
1207
  sendDeviceSettings(settings?: Readonly<Record<string, unknown>>): boolean;
1161
1208
  sendMenuSelect(choice: "settings" | {
@@ -1178,6 +1225,10 @@ declare class GemHost {
1178
1225
  readonly arcade?: "app_store" | "google_play";
1179
1226
  readonly game?: "app_store" | "google_play";
1180
1227
  }): boolean;
1228
+ answerShare(requestId: string, outcome: "accepted" | "refused", refusal?: {
1229
+ readonly reason?: string;
1230
+ readonly key?: string;
1231
+ }): boolean;
1181
1232
  answerOpenApp(requestId: string, outcome: ArcadeOutcomeKind, reason?: string): boolean;
1182
1233
  answerOpenGame(requestId: string, outcome: ArcadeOutcomeKind, reason?: string): boolean;
1183
1234
  answerSimilarGames(requestId: string, outcome: ArcadeOutcomeKind, games?: readonly GemGameCard[], reason?: string): boolean;
@@ -1189,6 +1240,7 @@ declare class GemHost {
1189
1240
  grantLocalServer(grant: LocalServerGrant): boolean;
1190
1241
  denyLocalServer(denial: LocalServerDenial): boolean;
1191
1242
  sendClusterTarget(clusterTargets: string | readonly string[]): boolean;
1243
+ sendGraphicsRoutes(entries: readonly GemGraphicsRouteEntry[]): boolean;
1192
1244
  sendPlayer(player: SendPlayerInput): void;
1193
1245
  private chainExpired;
1194
1246
  private localCorrelationId;
@@ -1381,8 +1433,11 @@ interface FrameCallbacks {
1381
1433
  onRelayDraining?(msg: GemRelayDraining): void;
1382
1434
  onDedicatedEvent?(msg: GemDedicatedEvent): void;
1383
1435
  onClusterTarget?(msg: GemClusterTarget): void;
1436
+ onGraphicsRoutes?(msg: GemGraphicsRoutes): void;
1384
1437
  onPartyResult?(msg: GemPartyResult): void;
1385
1438
  onPurchaseResult?(msg: GemPurchaseResult): void;
1439
+ onPurchaseSettled?(msg: GemPurchaseSettled): void;
1440
+ onShareResult?(msg: GemShareResult): void;
1386
1441
  onDeviceSettings?(msg: GemDeviceSettings): void;
1387
1442
  onDeviceSettingsResult?(msg: GemDeviceSettingsResult): void;
1388
1443
  onAdResult?(msg: GemAdResult): void;
@@ -1449,7 +1504,7 @@ declare class GemFrame {
1449
1504
  requestShare(params: ReadonlyArray<{
1450
1505
  readonly key: string;
1451
1506
  readonly value: string;
1452
- }>): boolean;
1507
+ }>, requestId?: string): boolean;
1453
1508
  requestAvatarPicker(tab?: "2d" | "3d"): boolean;
1454
1509
  requestVibrate(pattern: readonly number[]): boolean;
1455
1510
  reportFrameStats(stats: {
@@ -1461,7 +1516,7 @@ declare class GemFrame {
1461
1516
  signal(signal: string, matchId: string, data: Record<string, unknown>): void;
1462
1517
  dedicatedOffer(matchId: string, sdp: string, intent: GemDedicatedOffer["intent"]): void;
1463
1518
  requestParty(requestId: string): boolean;
1464
- requestPurchase(requestId: string, purchaseKind: "item" | "recipe", targetId: string, currencySlug: string, quantity?: number, catalogId?: string): boolean;
1519
+ requestPurchase(requestId: string, purchaseKind: "item" | "recipe", targetId: string, currencySlug: string, quantity?: number, catalogId?: string, origin?: "sheet" | "direct_refused"): boolean;
1465
1520
  requestAvatar3dPurchase(requestId: string, itemId: string, currencySlug: string): boolean;
1466
1521
  putDeviceSettings(requestId: string, settings: Readonly<Record<string, unknown>>): boolean;
1467
1522
  requestAd(requestId: string, placement: string, format: "interstitial" | "rewarded"): boolean;
@@ -2765,4 +2820,4 @@ interface P2pMatchApi {
2765
2820
  session(matchId: string): P2pSession | null;
2766
2821
  }
2767
2822
  declare function createP2pApi(options: P2pApiOptions): P2pMatchApi;
2768
- export { type ArcadeOutcomeKind, type AutoReconnectOptions, type AwaitMatchOptions, CAPABILITY_GATES, CAPABILITY_NAMESPACE_GATES, CHANNELS, CHANNEL_KINDS, type ChannelKind, type ClientPlatform, ClientTelemetry, type ClientTelemetryOptions, type ClientVersion, type Clock, type ClusterTarget, type ClusterTargetBridge, type ClusterTargetLike, type ClusterTargetListResolver, type ClusterTargetRefresher, type ClusterTargetResolver, type ClusterTargetSource, type ClusterTargetSourceOptions, type ConnectOptions, type CreateRoomOptions, INBOUND_EVENTS as DEDICATED_INBOUND_EVENTS, DEFAULT_WELCOME_CEILING_MS, DEVICE_SETTINGS_MAX_BYTES, type DataChannelLike$1 as DataChannelLike, type DedicatedServerApi, type DedicatedServerApiOptions, DedicatedServerError, type DedicatedServerFailure, type DedicatedServerSession, type DedicatedSignalTransport, DedicatedSignalingHub, type DedicatedSignalingOptions, type EstablishOptions, FRAME_TO_PARENT, type FailedMatch, type FrameCallbacks, type FrameMessage, type FrameOptions, type FrameState, type GemAdResult, type GemAppLinksResult, type GemArcadeOffer, type GemAudioState, type GemAutoStartFailedEvent, type GemCapability, type GemClusterTarget, type GemCohorts, type GemControlsDeclare, type GemDedicatedEvent, type GemDedicatedOffer, type GemDeviceSettings, type GemDeviceSettingsPut, type GemDeviceSettingsResult, type GemDevtools, type GemEarnAllowanceChanged, type GemEngaged, type GemError, type GemErrorCode, type GemExit, GemFrame, type GemFrameStats, type GemFriendChallengeResult, type GemGameCard, type GemGameContext, type GemGemCorner, type GemHandshake, type GemHandshakeAccept, GemHost, type GemLocalServer, type GemLocalServerDenied, type GemMenu, type GemMenuSelect, type GemMenuStyle, type GemMessage, type GemMomentResult, type GemOpenAppResult, type GemOpenExternal, type GemOpenGameResult, type GemPartyRequest, type GemPartyResult, type GemPause, type GemPlayer, type GemPortraitBorders, type GemPrefs, type GemProgress, type GemPurchaseResult, type GemReady, type GemRelayDraining, type GemRequestAd, type GemRequestAppLinks, type GemRequestAvatar3dPurchase, type GemRequestAvatarPicker, type GemRequestContext, type GemRequestFriendChallenge, type GemRequestFullscreen, type GemRequestLocalServer, type GemRequestOpenApp, type GemRequestOpenGame, type GemRequestPurchase, type GemRequestShare, type GemRequestSignIn, type GemRequestSimilarGames, type GemRequestStoreOfferSheet, type GemRequestStoreOffers, type GemRequestStorePurchase, type GemRequestToken, type GemRewardCue, type GemRoomEvent, type GemScreenshot, type GemScreenshotDenied, type GemSeatedEvent, type GemSettingChange, type GemSettingsDeclare, type GemSignInResult, type GemSignal, type GemSignalEvent, type GemSignalMoment, type GemSimilarGamesResult, type GemSocketState, type GemStoreOfferSheetResult, type GemStoreOffersResult, type GemStorePurchaseResult, type GemStorePurchaseSettled, type GemTicketEvent, type GemToken, type GemTokenDenied, type GemVibrate, type GemViewport, type GemWalletDisplay, type GemWillTerminate, HANDSHAKE_TIMEOUT_MS, type HandshakeEvent, type HostCallbacks, HostMigration, type HostOptions, type HostState, type JoinCredential, type JoinExchange, type JoinRoomOptions, type JoinWelcome, type KeySource, type ListRoomsOptions, MALFORMED_INBOUND_KEY, MAX_ARRAY_LENGTH, MAX_CLUSTER_TARGETS, MAX_MESSAGE_BYTES, MAX_MESSAGE_DEPTH, MAX_MESSAGE_NODES, MAX_SIGNALS_PER_SECOND, MAX_SOCKET_FRAME_BYTES, MIGRATION_TIMEOUT_MS, type MatchAutoStartFailed, type MatchConnectionState, type MatchEnded, type MatchOutcome, type MatchOutcomeWaitOptions, type MatchReconnected, type MatchReconnecting, type MatchSession, type MatchSessionPhase, type MatchSuspended, type MatchTicket, type MatchTicketOutcome, type MatchTicketStatus, type MigrationState, type OfferRefusal, type OfferRequest, P2pApi, type P2pConnectOptions, P2pError, type P2pEventMap, type P2pEventName, type P2pFailure, type P2pMatchApi, type P2pPeer, P2pSession, PARENT_TO_FRAME, PROTOCOL, type ParentMessage, type PartyBridge, type PartyEventRelay, type PartyResolver, type PartyResolverOptions, type PartyTicket, type PartyTicketOutcome, type PartyTicketStatus, type PeerConnectionLike$1 as PeerConnectionLike, type PlayWithOutcome, PlayerText, type PortLike, type PortMessageHandler, type PresentCredentialOptions, type PurchaseRefusalCode, type QueueForMatchOptions, type QuickJoinOptions, RATE_LIMITS, RateLimiter, type ReadyMatch, type Rejection, type RelayedDedicatedEvent, type RelayedRoomEvent, type RelayedSignal, type RelayedTicketEvent, type ResolvedClientVersion, type Room, type RoomArgEntry, type RoomArgScalar, type RoomArgType, type RoomArgValue, type RoomArgs, RoomEmitter, type RoomEventMap, type RoomEventName, type RoomManager, type RoomManagerOptions, type RoomMember, type RoomOperationError, type RoomPage, type RoomStatus, type RoomSummary, RoomsApi, type RoomsApiOptions, SUPPORTED_VERSIONS, type SdpType$1 as SdpType, type SendPlayerInput, type SessionDescriptionLike$1 as SessionDescriptionLike, type SignalTransport, type SignalingAnswer, type SignalingChannel, SignalingClient, type SignalingIntent, type StartMatchOptions, type StartedMatch$1 as StartedMatch, TELEMETRY_EVENTS, TRANSPORT_LABELS, type TelemetrySample, type TokenDenial, type TokenGrant, type TransportLabel, type TurnLease, type UpdateRoomOptions, VALIDATORS, type VerifiedCredential, WEBRTC_DEDICATED, WEBRTC_P2P, WEB_ENGINE_VERSION, WEB_PROTOCOL_VERSION, type WindowLike, asPlayerText, awaitMatchOutcome, browserPeerConnection, buildDedicatedOfferFrame, buildSocketFrame, capabilityFor, createClusterTargetSource, createDedicatedServerApi, createKeySource, createP2pApi, createPartyResolver, createRoomManager, deviceSettingsByteLength, establishDataChannel, fingerprintOf, fingerprintsMatch, generateCertificate, isOrigin, listClusterTargets, memberFromWire, negotiateVersion, normaliseClusterTarget, normaliseClusterTargets, normaliseFingerprint, originsEqual, presentJoinCredential, projectDedicatedEvent, projectPartyEvent, projectSignal, roomArgValuesFromWire, roomArgsTemplateFromWire, roomFromWire, startMatch, summaryFromWire, systemClock, text, unavailableSignaling, validateGemAdResult, validateGemAppLinksResult, validateGemAudioState, validateGemAutoStartFailedEvent, validateGemClusterTarget, validateGemCohorts, validateGemControlsDeclare, validateGemDedicatedEvent, validateGemDedicatedOffer, validateGemDeviceSettings, validateGemDeviceSettingsPut, validateGemDeviceSettingsResult, validateGemDevtools, validateGemEarnAllowanceChanged, validateGemEngaged, validateGemError, validateGemExit, validateGemFrameStats, validateGemFriendChallengeResult, validateGemGameContext, validateGemGemCorner, validateGemHandshake, validateGemHandshakeAccept, validateGemLocalServer, validateGemLocalServerDenied, validateGemMenu, validateGemMenuSelect, validateGemMenuStyle, validateGemMomentResult, validateGemOpenAppResult, validateGemOpenExternal, validateGemOpenGameResult, validateGemPartyRequest, validateGemPartyResult, validateGemPause, validateGemPlayer, validateGemPortraitBorders, validateGemPrefs, validateGemProgress, validateGemPurchaseResult, validateGemReady, validateGemRelayDraining, validateGemRequestAd, validateGemRequestAppLinks, validateGemRequestAvatar3dPurchase, validateGemRequestAvatarPicker, validateGemRequestContext, validateGemRequestFriendChallenge, validateGemRequestFullscreen, validateGemRequestLocalServer, validateGemRequestOpenApp, validateGemRequestOpenGame, validateGemRequestPurchase, validateGemRequestShare, validateGemRequestSignIn, validateGemRequestSimilarGames, validateGemRequestStoreOfferSheet, validateGemRequestStoreOffers, validateGemRequestStorePurchase, validateGemRequestToken, validateGemRewardCue, validateGemRoomEvent, validateGemScreenshot, validateGemScreenshotDenied, validateGemSeatedEvent, validateGemSettingChange, validateGemSettingsDeclare, validateGemSignInResult, validateGemSignal, validateGemSignalEvent, validateGemSignalMoment, validateGemSimilarGamesResult, validateGemSocketState, validateGemStoreOfferSheetResult, validateGemStoreOffersResult, validateGemStorePurchaseResult, validateGemStorePurchaseSettled, validateGemTicketEvent, validateGemToken, validateGemTokenDenied, validateGemVibrate, validateGemViewport, validateGemWalletDisplay, validateGemWillTerminate, validateSize, verifyCredential };
2823
+ export { type ArcadeOutcomeKind, type AutoReconnectOptions, type AwaitMatchOptions, BUILT_IN_GRAPHICS_ROUTES, CAPABILITY_GATES, CAPABILITY_NAMESPACE_GATES, CHANNELS, CHANNEL_KINDS, type ChannelKind, type ClientPlatform, ClientTelemetry, type ClientTelemetryOptions, type ClientVersion, type Clock, type ClusterTarget, type ClusterTargetBridge, type ClusterTargetLike, type ClusterTargetListResolver, type ClusterTargetRefresher, type ClusterTargetResolver, type ClusterTargetSource, type ClusterTargetSourceOptions, type ConnectOptions, type CreateRoomOptions, INBOUND_EVENTS as DEDICATED_INBOUND_EVENTS, DEFAULT_WELCOME_CEILING_MS, DEVICE_SETTINGS_MAX_BYTES, type DataChannelLike$1 as DataChannelLike, type DedicatedServerApi, type DedicatedServerApiOptions, DedicatedServerError, type DedicatedServerFailure, type DedicatedServerSession, type DedicatedSignalTransport, DedicatedSignalingHub, type DedicatedSignalingOptions, type EstablishOptions, FRAME_TO_PARENT, type FailedMatch, type FrameCallbacks, type FrameMessage, type FrameOptions, type FrameState, type GemAdResult, type GemAppLinksResult, type GemArcadeOffer, type GemAudioState, type GemAutoStartFailedEvent, type GemCapability, type GemClusterTarget, type GemCohorts, type GemControlsDeclare, type GemDedicatedEvent, type GemDedicatedOffer, type GemDeviceSettings, type GemDeviceSettingsPut, type GemDeviceSettingsResult, type GemDevtools, type GemEarnAllowanceChanged, type GemEngaged, type GemError, type GemErrorCode, type GemExit, GemFrame, type GemFrameStats, type GemFriendChallengeResult, type GemGameCard, type GemGameContext, type GemGemCorner, type GemGraphicsRouteEntry, type GemGraphicsRoutes, type GemHandshake, type GemHandshakeAccept, GemHost, type GemLocalServer, type GemLocalServerDenied, type GemMenu, type GemMenuSelect, type GemMenuStyle, type GemMessage, type GemMomentResult, type GemOpenAppResult, type GemOpenExternal, type GemOpenGameResult, type GemPartyRequest, type GemPartyResult, type GemPause, type GemPlayer, type GemPortraitBorders, type GemPrefs, type GemProgress, type GemPurchaseResult, type GemPurchaseSettled, type GemReady, type GemRelayDraining, type GemRequestAd, type GemRequestAppLinks, type GemRequestAvatar3dPurchase, type GemRequestAvatarPicker, type GemRequestContext, type GemRequestFriendChallenge, type GemRequestFullscreen, type GemRequestLocalServer, type GemRequestOpenApp, type GemRequestOpenGame, type GemRequestPurchase, type GemRequestShare, type GemRequestSignIn, type GemRequestSimilarGames, type GemRequestStoreOfferSheet, type GemRequestStoreOffers, type GemRequestStorePurchase, type GemRequestToken, type GemRewardCue, type GemRoomEvent, type GemScreenshot, type GemScreenshotDenied, type GemSeatedEvent, type GemSettingChange, type GemSettingsDeclare, type GemShareResult, type GemSignInResult, type GemSignal, type GemSignalEvent, type GemSignalMoment, type GemSimilarGamesResult, type GemSocketState, type GemStoreOfferSheetResult, type GemStoreOffersResult, type GemStorePurchaseResult, type GemStorePurchaseSettled, type GemTicketEvent, type GemToken, type GemTokenDenied, type GemVibrate, type GemViewport, type GemWalletDisplay, type GemWillTerminate, HANDSHAKE_TIMEOUT_MS, type HandshakeEvent, type HostCallbacks, HostMigration, type HostOptions, type HostState, type JoinCredential, type JoinExchange, type JoinRoomOptions, type JoinWelcome, type KeySource, type ListRoomsOptions, MALFORMED_INBOUND_KEY, MAX_ARRAY_LENGTH, MAX_CLUSTER_TARGETS, MAX_MESSAGE_BYTES, MAX_MESSAGE_DEPTH, MAX_MESSAGE_NODES, MAX_SIGNALS_PER_SECOND, MAX_SOCKET_FRAME_BYTES, MIGRATION_TIMEOUT_MS, type MatchAutoStartFailed, type MatchConnectionState, type MatchEnded, type MatchOutcome, type MatchOutcomeWaitOptions, type MatchReconnected, type MatchReconnecting, type MatchSession, type MatchSessionPhase, type MatchSuspended, type MatchTicket, type MatchTicketOutcome, type MatchTicketStatus, type MigrationState, type OfferRefusal, type OfferRequest, P2pApi, type P2pConnectOptions, P2pError, type P2pEventMap, type P2pEventName, type P2pFailure, type P2pMatchApi, type P2pPeer, P2pSession, PARENT_TO_FRAME, PROTOCOL, type ParentMessage, type PartyBridge, type PartyEventRelay, type PartyResolver, type PartyResolverOptions, type PartyTicket, type PartyTicketOutcome, type PartyTicketStatus, type PeerConnectionLike$1 as PeerConnectionLike, type PlayWithOutcome, PlayerText, type PortLike, type PortMessageHandler, type PresentCredentialOptions, type PurchaseRefusalCode, type QueueForMatchOptions, type QuickJoinOptions, RATE_LIMITS, RateLimiter, type ReadyMatch, type Rejection, type RelayedDedicatedEvent, type RelayedRoomEvent, type RelayedSignal, type RelayedTicketEvent, type ResolvedClientVersion, type Room, type RoomArgEntry, type RoomArgScalar, type RoomArgType, type RoomArgValue, type RoomArgs, RoomEmitter, type RoomEventMap, type RoomEventName, type RoomManager, type RoomManagerOptions, type RoomMember, type RoomOperationError, type RoomPage, type RoomStatus, type RoomSummary, RoomsApi, type RoomsApiOptions, SUPPORTED_VERSIONS, type SdpType$1 as SdpType, type SendPlayerInput, type SessionDescriptionLike$1 as SessionDescriptionLike, type SignalTransport, type SignalingAnswer, type SignalingChannel, SignalingClient, type SignalingIntent, type StartMatchOptions, type StartedMatch$1 as StartedMatch, TELEMETRY_EVENTS, TRANSPORT_LABELS, type TelemetrySample, type TokenDenial, type TokenGrant, type TransportLabel, type TurnLease, type UpdateRoomOptions, VALIDATORS, type VerifiedCredential, WEBRTC_DEDICATED, WEBRTC_P2P, WEB_ENGINE_VERSION, WEB_PROTOCOL_VERSION, type WindowLike, asPlayerText, awaitMatchOutcome, browserPeerConnection, buildDedicatedOfferFrame, buildSocketFrame, capabilityFor, createClusterTargetSource, createDedicatedServerApi, createKeySource, createP2pApi, createPartyResolver, createRoomManager, deviceSettingsByteLength, establishDataChannel, fingerprintOf, fingerprintsMatch, generateCertificate, isOrigin, listClusterTargets, memberFromWire, negotiateVersion, normaliseClusterTarget, normaliseClusterTargets, normaliseFingerprint, originsEqual, presentJoinCredential, projectDedicatedEvent, projectPartyEvent, projectSignal, roomArgValuesFromWire, roomArgsTemplateFromWire, roomFromWire, startMatch, summaryFromWire, systemClock, text, unavailableSignaling, validateGemAdResult, validateGemAppLinksResult, validateGemAudioState, validateGemAutoStartFailedEvent, validateGemClusterTarget, validateGemCohorts, validateGemControlsDeclare, validateGemDedicatedEvent, validateGemDedicatedOffer, validateGemDeviceSettings, validateGemDeviceSettingsPut, validateGemDeviceSettingsResult, validateGemDevtools, validateGemEarnAllowanceChanged, validateGemEngaged, validateGemError, validateGemExit, validateGemFrameStats, validateGemFriendChallengeResult, validateGemGameContext, validateGemGemCorner, validateGemGraphicsRoutes, validateGemHandshake, validateGemHandshakeAccept, validateGemLocalServer, validateGemLocalServerDenied, validateGemMenu, validateGemMenuSelect, validateGemMenuStyle, validateGemMomentResult, validateGemOpenAppResult, validateGemOpenExternal, validateGemOpenGameResult, validateGemPartyRequest, validateGemPartyResult, validateGemPause, validateGemPlayer, validateGemPortraitBorders, validateGemPrefs, validateGemProgress, validateGemPurchaseResult, validateGemPurchaseSettled, validateGemReady, validateGemRelayDraining, validateGemRequestAd, validateGemRequestAppLinks, validateGemRequestAvatar3dPurchase, validateGemRequestAvatarPicker, validateGemRequestContext, validateGemRequestFriendChallenge, validateGemRequestFullscreen, validateGemRequestLocalServer, validateGemRequestOpenApp, validateGemRequestOpenGame, validateGemRequestPurchase, validateGemRequestShare, validateGemRequestSignIn, validateGemRequestSimilarGames, validateGemRequestStoreOfferSheet, validateGemRequestStoreOffers, validateGemRequestStorePurchase, validateGemRequestToken, validateGemRewardCue, validateGemRoomEvent, validateGemScreenshot, validateGemScreenshotDenied, validateGemSeatedEvent, validateGemSettingChange, validateGemSettingsDeclare, validateGemShareResult, validateGemSignInResult, validateGemSignal, validateGemSignalEvent, validateGemSignalMoment, validateGemSimilarGamesResult, validateGemSocketState, validateGemStoreOfferSheetResult, validateGemStoreOffersResult, validateGemStorePurchaseResult, validateGemStorePurchaseSettled, validateGemTicketEvent, validateGemToken, validateGemTokenDenied, validateGemVibrate, validateGemViewport, validateGemWalletDisplay, validateGemWillTerminate, validateSize, verifyCredential };
package/dist/sdk.d.ts CHANGED
@@ -631,6 +631,19 @@ type TrackDefinition = {
631
631
  "requires_item_id"?: string | null;
632
632
  "track_id": string;
633
633
  };
634
+ type PurchaseRefusalCode = "unknown_currency" | "currency_not_in_game_payable" | "not_purchasable" | "no_price_in_currency" | "busy" | "cancelled" | "insufficient_funds" | "price_mismatch" | "config_version_stale" | "platform_currency_unavailable" | "not_available" | "recipe_locked" | "already_owned" | "guest_upgrade_required" | "recipe_on_cooldown" | "recipe_max_uses_exceeded" | "item_max_stack_exceeded" | "recipe_costs_unmet" | "quantity_invalid" | "error";
635
+ declare class PurchaseRefusal extends RangeError {
636
+ readonly code: Extract<PurchaseRefusalCode, "unknown_currency" | "not_purchasable" | "no_price_in_currency" | "quantity_invalid">;
637
+ readonly retryable: false;
638
+ constructor(code: Extract<PurchaseRefusalCode, "unknown_currency" | "not_purchasable" | "no_price_in_currency" | "quantity_invalid">, message: string);
639
+ }
640
+ interface RefusedPurchase {
641
+ readonly kind: "item" | "recipe";
642
+ readonly targetId: string;
643
+ readonly catalogId?: string;
644
+ readonly currencySlug: string;
645
+ readonly quantity: number;
646
+ }
634
647
  type CacheParam = string | number | boolean | undefined;
635
648
  declare class EntityReadCache {
636
649
  private readonly clock;
@@ -870,7 +883,8 @@ declare class MutationsApi {
870
883
  private readonly api;
871
884
  private readonly entity;
872
885
  private readonly cache;
873
- constructor(api: GameApi$1, entity: EntityRef, cache: EntityReadCache);
886
+ private readonly handOffRefused?;
887
+ constructor(api: GameApi$1, entity: EntityRef, cache: EntityReadCache, handOffRefused?: ((refused: RefusedPurchase) => void) | undefined);
874
888
  create(operations: readonly InventoryOperation[], options?: OrderOptions): Promise<OrderResult>;
875
889
  createMany(orders: ReadonlyArray<readonly InventoryOperation[]>, options?: OrderOptions): Promise<unknown>;
876
890
  recipeAvailability(catalogId: string, recipeId: string, signal?: AbortSignal): Promise<RecipeAvailability>;
@@ -1511,7 +1525,7 @@ declare class FunctionsApi {
1511
1525
  }
1512
1526
  type SessionEndReason = "grant_expiring" | "session_ended" | "navigating" | "kill_switch" | "pagehide";
1513
1527
  type MatchTransport = "dedicated" | "p2p";
1514
- type PlatformEventName = "gem_session_start" | "gem_session_end" | "gem_pause" | "gem_resume" | "gem_boot_ready" | "gem_match_started" | "gem_match_ended" | "gem_auth_lost";
1528
+ type PlatformEventName = "gem_session_start" | "gem_session_end" | "gem_pause" | "gem_resume" | "gem_boot_ready" | "gem_match_started" | "gem_match_ended" | "gem_auth_lost" | "gem_graphics_context_lost";
1515
1529
  declare const PLATFORM_EVENTS: readonly PlatformEventName[];
1516
1530
  type AnalyticsValue = string | number;
1517
1531
  interface AnalyticsRejection$1 {
@@ -1582,6 +1596,22 @@ interface BootTimelineOptions {
1582
1596
  declare function markOnResolve<T>(boot: BootTimeline, name: string, work: Promise<T>, log?: ((message: string) => void) | null): Promise<T>;
1583
1597
  declare function reportOnResolve(boot: BootTimeline, log?: ((message: string) => void) | null): <T>(work: Promise<T>) => Promise<T>;
1584
1598
  declare function createBootTimeline(options?: BootTimelineOptions): BootTimeline;
1599
+ type GemGraphicsRoute = "webgpu" | "webgl";
1600
+ interface GemPreferredRoute {
1601
+ readonly route: GemGraphicsRoute;
1602
+ readonly listed: boolean;
1603
+ }
1604
+ interface GemGraphicsRouteEntry {
1605
+ readonly gpu: string;
1606
+ readonly route?: string;
1607
+ readonly host?: string;
1608
+ }
1609
+ interface PreferredRouteOptions {
1610
+ readonly timeoutMs?: number;
1611
+ }
1612
+ interface GraphicsApi {
1613
+ preferredRoute(options?: PreferredRouteOptions): Promise<GemPreferredRoute>;
1614
+ }
1585
1615
  type DevToolsOpener = "game" | "platform";
1586
1616
  interface GemDevTools {
1587
1617
  open(): Promise<boolean>;
@@ -2286,6 +2316,15 @@ interface GemClusterTarget {
2286
2316
  readonly clusterTargetId: string;
2287
2317
  readonly clusterTargetIds?: string[];
2288
2318
  }
2319
+ interface GemGraphicsRoutes {
2320
+ readonly gem: typeof PROTOCOL;
2321
+ readonly type: "gem.graphicsRoutes";
2322
+ readonly entries: {
2323
+ gpu: string;
2324
+ route?: string;
2325
+ host?: string;
2326
+ }[];
2327
+ }
2289
2328
  interface GemScreenshotDenied {
2290
2329
  readonly gem: typeof PROTOCOL;
2291
2330
  readonly type: "gem.screenshot.denied";
@@ -2343,6 +2382,14 @@ interface GemSettingChange {
2343
2382
  readonly id: string;
2344
2383
  readonly value: boolean | number | string;
2345
2384
  }
2385
+ interface GemShareResult {
2386
+ readonly gem: typeof PROTOCOL;
2387
+ readonly type: "gem.shareResult";
2388
+ readonly requestId: string;
2389
+ readonly outcome: "accepted" | "refused";
2390
+ readonly reason?: string;
2391
+ readonly key?: string;
2392
+ }
2346
2393
  interface GemPurchaseResult {
2347
2394
  readonly gem: typeof PROTOCOL;
2348
2395
  readonly type: "gem.purchaseResult";
@@ -2351,6 +2398,15 @@ interface GemPurchaseResult {
2351
2398
  readonly reason?: string;
2352
2399
  readonly purchaseId?: string;
2353
2400
  }
2401
+ interface GemPurchaseSettled {
2402
+ readonly gem: typeof PROTOCOL;
2403
+ readonly type: "gem.purchaseSettled";
2404
+ readonly purchaseKind: "item" | "recipe";
2405
+ readonly targetId: string;
2406
+ readonly catalogId?: string;
2407
+ readonly quantity: number;
2408
+ readonly purchaseId?: string;
2409
+ }
2354
2410
  interface GemDeviceSettingsResult {
2355
2411
  readonly gem: typeof PROTOCOL;
2356
2412
  readonly type: "gem.deviceSettings.result";
@@ -4660,12 +4716,6 @@ interface GemMatchApi {
4660
4716
  serve(server: GemMatchServerModule, options?: MatchServeOptions): Promise<MatchHosting>;
4661
4717
  connect(options?: MatchConnectOptions): Promise<MatchConnection>;
4662
4718
  }
4663
- type PurchaseRefusalCode = "unknown_currency" | "currency_not_in_game_payable" | "not_purchasable" | "no_price_in_currency" | "busy" | "cancelled" | "insufficient_funds" | "price_mismatch" | "config_version_stale" | "platform_currency_unavailable" | "not_available" | "recipe_locked" | "already_owned" | "recipe_on_cooldown" | "recipe_max_uses_exceeded" | "item_max_stack_exceeded" | "recipe_costs_unmet" | "quantity_invalid" | "error";
4664
- declare class PurchaseRefusal extends RangeError {
4665
- readonly code: Extract<PurchaseRefusalCode, "unknown_currency" | "not_purchasable" | "no_price_in_currency" | "quantity_invalid">;
4666
- readonly retryable: false;
4667
- constructor(code: Extract<PurchaseRefusalCode, "unknown_currency" | "not_purchasable" | "no_price_in_currency" | "quantity_invalid">, message: string);
4668
- }
4669
4719
  interface PurchaseRequest {
4670
4720
  kind: "item" | "recipe";
4671
4721
  targetId: string;
@@ -4682,6 +4732,14 @@ type PurchaseOutcome = {
4682
4732
  };
4683
4733
  interface PurchaseApi {
4684
4734
  request(req: PurchaseRequest): Promise<PurchaseOutcome>;
4735
+ onSettled(listener: (settlement: PurchaseSettlement) => void): () => void;
4736
+ }
4737
+ interface PurchaseSettlement {
4738
+ readonly kind: "item" | "recipe";
4739
+ readonly targetId: string;
4740
+ readonly catalogId?: string;
4741
+ readonly quantity: number;
4742
+ readonly purchaseId: string;
4685
4743
  }
4686
4744
  interface Avatar3dPurchaseRequest {
4687
4745
  itemId: string;
@@ -4776,8 +4834,11 @@ interface FrameCallbacks {
4776
4834
  onRelayDraining?(msg: GemRelayDraining): void;
4777
4835
  onDedicatedEvent?(msg: GemDedicatedEvent): void;
4778
4836
  onClusterTarget?(msg: GemClusterTarget): void;
4837
+ onGraphicsRoutes?(msg: GemGraphicsRoutes): void;
4779
4838
  onPartyResult?(msg: GemPartyResult): void;
4780
4839
  onPurchaseResult?(msg: GemPurchaseResult): void;
4840
+ onPurchaseSettled?(msg: GemPurchaseSettled): void;
4841
+ onShareResult?(msg: GemShareResult): void;
4781
4842
  onDeviceSettings?(msg: GemDeviceSettings): void;
4782
4843
  onDeviceSettingsResult?(msg: GemDeviceSettingsResult): void;
4783
4844
  onAdResult?(msg: GemAdResult): void;
@@ -4844,7 +4905,7 @@ declare class GemFrame {
4844
4905
  requestShare(params: ReadonlyArray<{
4845
4906
  readonly key: string;
4846
4907
  readonly value: string;
4847
- }>): boolean;
4908
+ }>, requestId?: string): boolean;
4848
4909
  requestAvatarPicker(tab?: "2d" | "3d"): boolean;
4849
4910
  requestVibrate(pattern: readonly number[]): boolean;
4850
4911
  reportFrameStats(stats: {
@@ -4856,7 +4917,7 @@ declare class GemFrame {
4856
4917
  signal(signal: string, matchId: string, data: Record<string, unknown>): void;
4857
4918
  dedicatedOffer(matchId: string, sdp: string, intent: GemDedicatedOffer["intent"]): void;
4858
4919
  requestParty(requestId: string): boolean;
4859
- requestPurchase(requestId: string, purchaseKind: "item" | "recipe", targetId: string, currencySlug: string, quantity?: number, catalogId?: string): boolean;
4920
+ requestPurchase(requestId: string, purchaseKind: "item" | "recipe", targetId: string, currencySlug: string, quantity?: number, catalogId?: string, origin?: "sheet" | "direct_refused"): boolean;
4860
4921
  requestAvatar3dPurchase(requestId: string, itemId: string, currencySlug: string): boolean;
4861
4922
  putDeviceSettings(requestId: string, settings: Readonly<Record<string, unknown>>): boolean;
4862
4923
  requestAd(requestId: string, placement: string, format: "interstitial" | "rewarded"): boolean;
@@ -4880,9 +4941,14 @@ declare class GemFrame {
4880
4941
  interface ShareRequest {
4881
4942
  readonly params?: Readonly<Record<string, string>>;
4882
4943
  }
4944
+ declare class ShareRefusal extends Error {
4945
+ readonly reason: string;
4946
+ readonly key?: string;
4947
+ constructor(reason: string, key?: string);
4948
+ }
4883
4949
  interface ShareApi {
4884
4950
  readonly available: boolean;
4885
- request(request?: ShareRequest): void;
4951
+ request(request?: ShareRequest): Promise<void>;
4886
4952
  }
4887
4953
  type ArcadeOutcomeKind = "ok" | "declined" | "unavailable";
4888
4954
  interface ArcadeOutcome {
@@ -5256,6 +5322,7 @@ interface Gem {
5256
5322
  readonly gameConfig: GameConfigApi;
5257
5323
  readonly purchases: PurchaseApi;
5258
5324
  readonly deviceSettings: DeviceSettingsApi;
5325
+ readonly graphics: GraphicsApi;
5259
5326
  readonly moments: MomentsApi;
5260
5327
  readonly ads: AdsApi;
5261
5328
  readonly account: AccountApi;
@@ -5318,4 +5385,4 @@ interface ExitAnalytics {
5318
5385
  }
5319
5386
  declare function leaveAndExit(rooms: ExitRooms, bridge: ExitBridge | null, reason?: string, analytics?: ExitAnalytics): Promise<void>;
5320
5387
  declare function createGem(options?: GemOptions): Gem;
5321
- export { ARCADE_EMBEDDERS, AVATAR_RIGS, type AccountApi, type AdFormat, type AdOutcome, type AdOutcomeKind, type AdRequest, type AdsApi, AnalyticsApi, type AnalyticsFlushOptions, type AnalyticsFlushResult, type AnalyticsOptions, type AnalyticsRejection$1 as AnalyticsRejection, type AnalyticsValue, type AppLinksOutcome, type AppListing, type AppStore, type ArcadeApi, type ArcadeAvailability, type ArcadeOffer, type ArcadeOutcome, type ArcadeOutcomeKind, AuthError, type AuthFailure, type AuthState, type Avatar3dFamily, type Avatar3dOffer, type Avatar3dPrice, type Avatar3dPurchaseRequest, type AvatarRigNode, type AvatarRigs, type Avatars3dApi, type Base64String, type BootMark, type BootTimeline, type BrandingApi, type BrandingAsset, type BrandingAssetOptions, type BrandingCurrency, type BrandingImageOptions, type BrandingList, type BrandingLookup, type BrandingTheme, type BrandingVariant, type BroadcastOptions, type BytesResponse, CONDITIONAL_HEADERS, type Challenge, type ChallengeWindow, ChallengesApi, type ClientOptions, type Clock, type ConditionalRequestHeaders, type ConfiguredPurchasePayment, type ConfiguredPurchaseRequest, type ConfiguredPurchaseResult, type ControlsApi, DEVICE_SETTINGS_MAX_BYTES, DedicatedServerError, type DedicatedServerFailure, type DedicatedServerSession, type DevToolsOpener, type DeviceSettings, type DeviceSettingsApi, type DeviceSettingsPutOutcome, type DirectPurchaseRequest, type DirectPurchaseResult, type EarnAllowance, type EarnAllowanceEvent, type EarnAllowancePeriod, type EarnAllowanceReadOptions, type EntityLeaderboard, type EntityLeaderboardEntry, type EntityLeaderboardOptions, type EntityType$1 as EntityType, type ExitAnalytics, type ExitBridge, type ExitRooms, type FrameState, type Friend, type FriendChallenge, FriendChallengeError, type FriendChallengeErrorCode, type FriendChallengeOutcome, type FriendChallengeOutcomeKind, type FriendChallengeRequest, type FriendChallengesPage, FriendsApi, type FriendsPage, type FunctionFailure, type FunctionInvokeOptions, type FunctionResult, FunctionsApi, type GameApi, type GameCard, type GameConfig, type GameMenu, type GameMenuItem, type GamePass, type GameServerLink, type GameSettingsApi, type Gem, GemApiError, type GemAudioChannels, GemClient, type GemCohort, type GemCohorts, GemConfigError, type GemControlBox, type GemCorner, type GemDevTools, type GemErrorReason, GemFrame, GemFunctionError, type GemGameChoiceSetting, type GemGameSetting, type GemGameSettingBase, type GemGameSettingChange, type GemGameSettingIcon, type GemGameSettingOption, type GemGameSettingValue, type GemGameSliderSetting, type GemGameToggleSetting, type GemGraphicsQuality, type GemIdentity, type GemInsets, type GemLook, type GemLookBase, type GemLookDelta, type GemLookOptions, type GemLookSpeed, type GemMatchApi, type GemMatchServer, type GemMatchServerModule, type GemOptions, type GemPlayer, type GemPrefs, type GemRecommendedSettings, type GemReservedArea, GemSaveError, type GemServer, type GemServerBundle, type GemServerFactory, type GemServerHost, type GemServerHostProfile, type GemServerIdentity, type GemServerLifecycle, type GemServerOptions, type GemServerProfile, type GemTerminationNotice, GemUnframedError, type GemViewport, type GetLeaderboardOptions, type HostTokenSource, type HostTokenSourceOptions, type JoinWelcome, type Leaderboard, type LeaderboardEntry, type LeaderboardPeriod, LeaderboardsApi, type ListChallengesOptions, type ListFriendChallengesOptions, type ListFriendsOptions, MAX_PERIODS_BACK, type MatchBackfillState, type MatchConnectOptions, type MatchConnection, type MatchHosting, type MatchHostingMode, type MatchPlayerReport, type MatchPlayerReportResult, type MatchServeOptions, type MatchTransport, type MenuStyle, type MessageMeta, type MomentKind, type MomentResult, type MomentSignal, type MomentsApi, type MultiTransportSession, PLATFORM_EVENTS, type PassesApi, type PassesEvent, type PeriodOptions, PlatformApi, PlatformCurrenciesApi, type PlatformCurrency, type PlatformCurrencyAccess, type PlatformCurrencyPurchasePayment, type PlatformCurrencyPurchaseRequest, type PlatformCurrencyPurchaseResult, type PlatformCurrencyReadOptions, PlatformEarnAllowanceApi, type PlatformEventName, type PlayerBadge$1 as PlayerBadge, type PlayerBoost, type PlayerBoostMultiplier, type PlayerIdentity, type PlayerProfile, type PlayerScope, PlayerText, type ProfileCallOptions, type ProfileShowcaseEntry$1 as ProfileShowcaseEntry, ProfilesApi, type PurchaseApi, type PurchaseOptions, type PurchaseOutcome, PurchaseRefusal, type PurchaseRefusalCode, type PurchaseRequest, type PutBytesOptions, type PutSaveOptions, type RankedRow, type RecipeAvailability, type RecipeLock, type RequestOptions, type RewardCue, type RewardedStatus, type RoomArgValue, type SavePage, type SaveRecord, type SendOptions$1 as SendOptions, type ServerApi, type ServerBundleHost, type ServerTokenGrant, type SessionEndReason, type ShareApi, type ShareRequest, ShowcaseApi, type ShowcaseCallOptions, type ShowcaseFriendEntry, type ShowcaseFriends, type ShowcaseValue, type SignInOutcome, type SignInOutcomeKind, type SimilarGamesOutcome, type SnapshotCurrency, type SnapshotItem, type StoreApi, type StoreOffersOutcome, type StoreSettlement, type TokenGrant, type Transport, type TransportAdvert, type TransportKind, TransportRefusal, type TransportRequest, type TransportResponse, UNRELIABLE_CHANNEL_LABEL, type VersionedGetOptions, type VersionedResponse, type VibrationApi, type WalletVisibleOptions, type WornAvatar3d$1 as WornAvatar3d, asPlayerText, createBootTimeline, createGem, createGemServer, createHostTokenSource, createMatchServer, defineServer, experimentSelection, leaveAndExit, mapIdentity, markOnResolve, platformIconUrl, presentJoinCredential, readTemplateTransports, readTransportAdvert, reportOnResolve, systemClock, text, toBase64, webTransportAvailable };
5388
+ export { ARCADE_EMBEDDERS, AVATAR_RIGS, type AccountApi, type AdFormat, type AdOutcome, type AdOutcomeKind, type AdRequest, type AdsApi, AnalyticsApi, type AnalyticsFlushOptions, type AnalyticsFlushResult, type AnalyticsOptions, type AnalyticsRejection$1 as AnalyticsRejection, type AnalyticsValue, type AppLinksOutcome, type AppListing, type AppStore, type ArcadeApi, type ArcadeAvailability, type ArcadeOffer, type ArcadeOutcome, type ArcadeOutcomeKind, AuthError, type AuthFailure, type AuthState, type Avatar3dFamily, type Avatar3dOffer, type Avatar3dPrice, type Avatar3dPurchaseRequest, type AvatarRigNode, type AvatarRigs, type Avatars3dApi, type Base64String, type BootMark, type BootTimeline, type BrandingApi, type BrandingAsset, type BrandingAssetOptions, type BrandingCurrency, type BrandingImageOptions, type BrandingList, type BrandingLookup, type BrandingTheme, type BrandingVariant, type BroadcastOptions, type BytesResponse, CONDITIONAL_HEADERS, type Challenge, type ChallengeWindow, ChallengesApi, type ClientOptions, type Clock, type ConditionalRequestHeaders, type ConfiguredPurchasePayment, type ConfiguredPurchaseRequest, type ConfiguredPurchaseResult, type ControlsApi, DEVICE_SETTINGS_MAX_BYTES, DedicatedServerError, type DedicatedServerFailure, type DedicatedServerSession, type DevToolsOpener, type DeviceSettings, type DeviceSettingsApi, type DeviceSettingsPutOutcome, type DirectPurchaseRequest, type DirectPurchaseResult, type EarnAllowance, type EarnAllowanceEvent, type EarnAllowancePeriod, type EarnAllowanceReadOptions, type EntityLeaderboard, type EntityLeaderboardEntry, type EntityLeaderboardOptions, type EntityType$1 as EntityType, type ExitAnalytics, type ExitBridge, type ExitRooms, type FrameState, type Friend, type FriendChallenge, FriendChallengeError, type FriendChallengeErrorCode, type FriendChallengeOutcome, type FriendChallengeOutcomeKind, type FriendChallengeRequest, type FriendChallengesPage, FriendsApi, type FriendsPage, type FunctionFailure, type FunctionInvokeOptions, type FunctionResult, FunctionsApi, type GameApi, type GameCard, type GameConfig, type GameMenu, type GameMenuItem, type GamePass, type GameServerLink, type GameSettingsApi, type Gem, GemApiError, type GemAudioChannels, GemClient, type GemCohort, type GemCohorts, GemConfigError, type GemControlBox, type GemCorner, type GemDevTools, type GemErrorReason, GemFrame, GemFunctionError, type GemGameChoiceSetting, type GemGameSetting, type GemGameSettingBase, type GemGameSettingChange, type GemGameSettingIcon, type GemGameSettingOption, type GemGameSettingValue, type GemGameSliderSetting, type GemGameToggleSetting, type GemGraphicsQuality, type GemGraphicsRoute, type GemGraphicsRouteEntry, type GemIdentity, type GemInsets, type GemLook, type GemLookBase, type GemLookDelta, type GemLookOptions, type GemLookSpeed, type GemMatchApi, type GemMatchServer, type GemMatchServerModule, type GemOptions, type GemPlayer, type GemPreferredRoute, type GemPrefs, type GemRecommendedSettings, type GemReservedArea, GemSaveError, type GemServer, type GemServerBundle, type GemServerFactory, type GemServerHost, type GemServerHostProfile, type GemServerIdentity, type GemServerLifecycle, type GemServerOptions, type GemServerProfile, type GemTerminationNotice, GemUnframedError, type GemViewport, type GetLeaderboardOptions, type GraphicsApi, type HostTokenSource, type HostTokenSourceOptions, type JoinWelcome, type Leaderboard, type LeaderboardEntry, type LeaderboardPeriod, LeaderboardsApi, type ListChallengesOptions, type ListFriendChallengesOptions, type ListFriendsOptions, MAX_PERIODS_BACK, type MatchBackfillState, type MatchConnectOptions, type MatchConnection, type MatchHosting, type MatchHostingMode, type MatchPlayerReport, type MatchPlayerReportResult, type MatchServeOptions, type MatchTransport, type MenuStyle, type MessageMeta, type MomentKind, type MomentResult, type MomentSignal, type MomentsApi, type MultiTransportSession, PLATFORM_EVENTS, type PassesApi, type PassesEvent, type PeriodOptions, PlatformApi, PlatformCurrenciesApi, type PlatformCurrency, type PlatformCurrencyAccess, type PlatformCurrencyPurchasePayment, type PlatformCurrencyPurchaseRequest, type PlatformCurrencyPurchaseResult, type PlatformCurrencyReadOptions, PlatformEarnAllowanceApi, type PlatformEventName, type PlayerBadge$1 as PlayerBadge, type PlayerBoost, type PlayerBoostMultiplier, type PlayerIdentity, type PlayerProfile, type PlayerScope, PlayerText, type PreferredRouteOptions, type ProfileCallOptions, type ProfileShowcaseEntry$1 as ProfileShowcaseEntry, ProfilesApi, type PurchaseApi, type PurchaseOptions, type PurchaseOutcome, PurchaseRefusal, type PurchaseRefusalCode, type PurchaseRequest, type PurchaseSettlement, type PutBytesOptions, type PutSaveOptions, type RankedRow, type RecipeAvailability, type RecipeLock, type RequestOptions, type RewardCue, type RewardedStatus, type RoomArgValue, type SavePage, type SaveRecord, type SendOptions$1 as SendOptions, type ServerApi, type ServerBundleHost, type ServerTokenGrant, type SessionEndReason, type ShareApi, ShareRefusal, type ShareRequest, ShowcaseApi, type ShowcaseCallOptions, type ShowcaseFriendEntry, type ShowcaseFriends, type ShowcaseValue, type SignInOutcome, type SignInOutcomeKind, type SimilarGamesOutcome, type SnapshotCurrency, type SnapshotItem, type StoreApi, type StoreOffersOutcome, type StoreSettlement, type TokenGrant, type Transport, type TransportAdvert, type TransportKind, TransportRefusal, type TransportRequest, type TransportResponse, UNRELIABLE_CHANNEL_LABEL, type VersionedGetOptions, type VersionedResponse, type VibrationApi, type WalletVisibleOptions, type WornAvatar3d$1 as WornAvatar3d, asPlayerText, createBootTimeline, createGem, createGemServer, createHostTokenSource, createMatchServer, defineServer, experimentSelection, leaveAndExit, mapIdentity, markOnResolve, platformIconUrl, presentJoinCredential, readTemplateTransports, readTransportAdvert, reportOnResolve, systemClock, text, toBase64, webTransportAvailable };
package/docs/analytics.md CHANGED
@@ -131,10 +131,22 @@ and a game that declares no events at all still gets them:
131
131
  | `gem_boot_ready` | — | `boot_ms` |
132
132
  | `gem_match_started` / `gem_match_ended` | `transport` (`dedicated`, `p2p`) | — |
133
133
  | `gem_auth_lost` | — | — |
134
+ | `gem_graphics_context_lost` | `gpu`, `host`, `route` | `context_ms`, `hidden`, `nth_loss` |
134
135
 
135
136
  `reason` on a session end is one of `grant_expiring`, `session_ended`, `navigating`,
136
137
  `kill_switch` or `pagehide`.
137
138
 
139
+ `gem_graphics_context_lost` is the browser taking one of your WebGL contexts away, or a WebGPU
140
+ device your game made (then `route` is `webgpu`) — on a phone usually a GPU driver fault rather
141
+ than your code. A WebGPU device your game destroys itself is not counted. `gpu` is the GPU family (`powervr_d_series`,
142
+ `powervr_other`, `adreno`, `mali`, `xclipse`, `apple`, `nvidia`, `amd`, `intel`, `software`,
143
+ `other`, `unknown`), `route` is how the browser drives it (`angle_gles`, `angle_vulkan`,
144
+ `angle_d3d11`, `angle_d3d9`, `angle_metal`, `angle_opengl`, `angle_other`, `native_gl`, `webgpu`,
145
+ `unknown`) and `host` is `android_webview` (the Arcade app) or `other`. `hidden` is 1 when the page
146
+ was hidden at the time, which is a phone reclaiming a backgrounded game's memory rather than a
147
+ crash in front of the player. It is sent whether or not your game recovers from the loss, at most
148
+ five times a page.
149
+
138
150
  **The `gem_` prefix is reserved.** Your config cannot declare an id beginning with it and
139
151
  `gem.analytics.track` refuses one rather than sending it, so pick another name.
140
152
 
@@ -1,6 +1,6 @@
1
1
  # The function surface — API reference
2
2
 
3
- Generated from `@indiegems/gem-web-sdk/function` v20.1.0, the version of the package this file ships in. Every symbol below carries an explicit anchor, its `anchor` in `reference.json` beside this file.
3
+ Generated from `@indiegems/gem-web-sdk/function` v21.1.0, the version of the package this file ships in. Every symbol below carries an explicit anchor, its `anchor` in `reference.json` beside this file.
4
4
 
5
5
  `@indiegems/gem-web-sdk/function` exports exactly the symbols on this page and nothing else.
6
6
 
@@ -470,7 +470,7 @@ the reading a funnel should treat as approximate.
470
470
  ## PlatformEventName
471
471
 
472
472
  ```ts
473
- type PlatformEventName = "gem_session_start" | "gem_session_end" | "gem_pause" | "gem_resume" | "gem_boot_ready" | "gem_match_started" | "gem_match_ended" | "gem_auth_lost"
473
+ type PlatformEventName = "gem_session_start" | "gem_session_end" | "gem_pause" | "gem_resume" | "gem_boot_ready" | "gem_match_started" | "gem_match_ended" | "gem_auth_lost" | "gem_graphics_context_lost"
474
474
  ```
475
475
 
476
476
  Every event the SDK emits by itself.
@@ -488,6 +488,12 @@ config names them as steps.
488
488
  | `gem_boot_ready` | — | `boot_ms` |
489
489
  | `gem_match_started` / `gem_match_ended` | `transport` (`MatchTransport`) | — |
490
490
  | `gem_auth_lost` | — | — |
491
+ | `gem_graphics_context_lost` | `gpu`, `host`, `route` | `context_ms`, `hidden`, `nth_loss` |
492
+
493
+ `gem_graphics_context_lost` is the browser taking a WebGL context away, or a
494
+ WebGPU device (`route` is then `webgpu`) — usually a GPU driver fault, sized
495
+ per device across every game (`analytics/graphics.ts` lists the dimension
496
+ values).
491
497
 
492
498
  <a id="gemerrorreason"></a>
493
499
 
@@ -3060,6 +3066,12 @@ platform's own refusals arrive as a `GemApiError` whose `code` is its wire
3060
3066
  code — `insufficient_funds`, `recipe_locked`, `price_mismatch`, … Never
3061
3067
  draw a top-up or payment screen of your own for either.
3062
3068
 
3069
+ `guest_upgrade_required` means the player is a guest, and the platform
3070
+ lets only an account spend. TREAT IT LIKE A DECLINE AND DRAW NOTHING: the
3071
+ SDK has already handed the attempt to the arcade, which offers the player
3072
+ an account over your game. The call rejects at once rather than waiting
3073
+ for them; if they make one and buy, `PurchaseApi.onSettled` hears it.
3074
+
3063
3075
  | Parameter | Type |
3064
3076
  | --- | --- |
3065
3077
  | `request` | `ConfiguredPurchaseRequest` |