@indiegems/gem-web-sdk 23.3.0 → 24.0.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.
package/dist/game.d.ts CHANGED
@@ -912,6 +912,7 @@ declare class OrdersApi {
912
912
  interface GamePass {
913
913
  readonly pass: string;
914
914
  readonly held: boolean;
915
+ readonly daysLeft: number;
915
916
  readonly endsAt: string | null;
916
917
  }
917
918
  type PassesEvent = "changed";
@@ -1147,1458 +1148,1773 @@ declare class TransfersApi {
1147
1148
  cancel(transferId: string, signal?: AbortSignal): Promise<Transfer>;
1148
1149
  private resolve;
1149
1150
  }
1150
- interface GameConfig extends GameConfigSnapshot {
1151
- items: GameConfigSnapshot["items"];
1152
- currencies: GameConfigSnapshot["currencies"];
1153
- catalogs: GameConfigSnapshot["catalogs"];
1154
- loot_tables: GameConfigSnapshot["loot_tables"];
1155
- affix_pools?: GameConfigSnapshot["affix_pools"];
1156
- progressions: GameConfigSnapshot["progressions"];
1157
- game_room_templates: GameConfigSnapshot["game_room_templates"];
1158
- kv: GameConfigSnapshot["kv"];
1159
- run_types?: GameConfigSnapshot["run_types"];
1160
- leaderboards?: GameConfigSnapshot["leaderboards"];
1161
- async_opponent_types?: GameConfigSnapshot["async_opponent_types"];
1162
- analytics_events?: GameConfigSnapshot["analytics_events"];
1163
- analytics_funnels?: GameConfigSnapshot["analytics_funnels"];
1164
- "rewarded_placements"?: SnapshotRewardedPlacement[];
1165
- version: GameConfigSnapshot["version"];
1166
- hash: GameConfigSnapshot["hash"];
1167
- item(idOrSlug: string): SnapshotItem | null;
1168
- currency(idOrSlug: string): SnapshotCurrency | null;
1169
- }
1170
- declare class GemConfigError extends Error {
1171
- readonly reason: "config_unreachable" | "config_too_large" | "config_malformed" | "config_timeout" | "config_channel_unknown";
1172
- constructor(reason: "config_unreachable" | "config_too_large" | "config_malformed" | "config_timeout" | "config_channel_unknown", message: string);
1151
+ declare const PROTOCOL: "gem-web-bridge";
1152
+ type GemErrorCode = "version_mismatch" | "handshake_timeout" | "handshake_duplicate" | "invalid_message" | "rate_limited" | "token_unavailable" | "unsupported" | "unsupported_capability" | "internal";
1153
+ interface GemToken {
1154
+ readonly gem: typeof PROTOCOL;
1155
+ readonly type: "gem.token";
1156
+ readonly token: string;
1157
+ readonly requestId?: string;
1158
+ readonly generation: number;
1159
+ readonly apiBaseUrl?: string;
1160
+ readonly playerId: string;
1161
+ readonly gameId: string;
1162
+ readonly channel: "dev" | "test" | "release";
1163
+ readonly gameVersion?: string;
1164
+ readonly expiresAt: number;
1165
+ readonly chainEndsAt: number;
1166
+ readonly allowDevTools?: boolean;
1173
1167
  }
1174
- interface GameConfigOptions {
1175
- readonly fetch?: typeof globalThis.fetch;
1176
- readonly timeoutMs?: number;
1168
+ interface GemTokenDenied {
1169
+ readonly gem: typeof PROTOCOL;
1170
+ readonly type: "gem.token.denied";
1171
+ readonly requestId: string;
1172
+ readonly retryable: boolean;
1173
+ readonly retryAfterMs?: number;
1174
+ readonly reason: "chain_exhausted" | "unavailable";
1175
+ readonly correlationId: string;
1177
1176
  }
1178
- interface DropRateEntry {
1179
- readonly entryId: string;
1180
- readonly weight: number;
1181
- readonly dropRate: number;
1182
- readonly rarityTier?: string;
1177
+ interface GemPause {
1178
+ readonly gem: typeof PROTOCOL;
1179
+ readonly type: "gem.pause";
1180
+ readonly paused: boolean;
1183
1181
  }
1184
- interface DropRates {
1185
- readonly lootTableId: string;
1186
- readonly name: string;
1187
- readonly rollCount: number;
1188
- readonly allowDuplicateRolls: boolean;
1189
- readonly totalWeight: number;
1190
- readonly entries: readonly DropRateEntry[];
1182
+ interface GemPrefs$1 {
1183
+ readonly gem: typeof PROTOCOL;
1184
+ readonly type: "gem.prefs";
1185
+ readonly reducedMotion: boolean;
1186
+ readonly muted: boolean;
1187
+ readonly showFrameStats?: boolean;
1188
+ readonly music?: boolean;
1189
+ readonly sounds?: boolean;
1190
+ readonly locale: string;
1191
+ readonly recommended?: {
1192
+ volume: number;
1193
+ batterySaver: boolean;
1194
+ keyboardLayout: "wasd" | "arrows";
1195
+ gamepadConfirm: "south" | "east";
1196
+ vibration: boolean;
1197
+ lookSensitivity?: number;
1198
+ gamepadLookSensitivity?: number;
1199
+ invertLookY?: boolean;
1200
+ touchMovement?: string;
1201
+ graphicsQuality?: string;
1202
+ graphicsQualityAuto?: boolean;
1203
+ colorHelp?: boolean;
1204
+ textScale?: number;
1205
+ };
1191
1206
  }
1192
- declare class GameConfigApi {
1193
- private readonly api;
1194
- private readonly channel;
1195
- private readonly options;
1196
- private loaded;
1197
- private inFlight;
1198
- private generation;
1199
- private readonly dropRatesByConfig;
1200
- constructor(api: GameApi, channel: () => string, options?: GameConfigOptions);
1201
- load(): Promise<GameConfig | null>;
1202
- refresh(): void;
1203
- dropRates(lootTableId: string, signal?: AbortSignal): Promise<DropRates>;
1204
- private fetchConfig;
1207
+ interface GemCohorts$1 {
1208
+ readonly gem: typeof PROTOCOL;
1209
+ readonly type: "gem.cohorts";
1210
+ readonly cohorts: {
1211
+ experimentId: string;
1212
+ variantKey: string;
1213
+ }[];
1205
1214
  }
1206
- declare const MAX_PERIODS_BACK = 400;
1207
- type ChallengeWindow = "daily" | "weekly" | "monthly" | "cron" | (string & {});
1208
- interface Challenge {
1209
- readonly id: string;
1210
- readonly slug?: string;
1211
- readonly window: ChallengeWindow;
1212
- readonly periodStartAt: number;
1213
- readonly periodEndsAt: number;
1214
- readonly periodLocalDate?: string;
1215
- readonly boundary: string;
1216
- readonly resetTime: string;
1217
- readonly seed: string;
1218
- readonly data?: string;
1219
- readonly dataHash?: string;
1215
+ interface GemInventoryChanged {
1216
+ readonly gem: typeof PROTOCOL;
1217
+ readonly type: "gem.inventoryChanged";
1220
1218
  }
1221
- interface ListChallengesOptions {
1222
- readonly periodsBack?: number;
1223
- readonly signal?: AbortSignal;
1219
+ interface GemViewport$1 {
1220
+ readonly gem: typeof PROTOCOL;
1221
+ readonly type: "gem.viewport";
1222
+ readonly insets: {
1223
+ top: number;
1224
+ right: number;
1225
+ bottom: number;
1226
+ left: number;
1227
+ };
1228
+ readonly reserved?: {
1229
+ x: number;
1230
+ y: number;
1231
+ width: number;
1232
+ height: number;
1233
+ control?: {
1234
+ x: number;
1235
+ y: number;
1236
+ width: number;
1237
+ height: number;
1238
+ };
1239
+ }[];
1224
1240
  }
1225
- declare class ChallengesApi {
1226
- #private;
1227
- constructor(api: GameApi);
1228
- list(options?: ListChallengesOptions): Promise<Challenge[]>;
1241
+ interface GemDeviceSettings {
1242
+ readonly gem: typeof PROTOCOL;
1243
+ readonly type: "gem.deviceSettings";
1244
+ readonly settings?: unknown;
1229
1245
  }
1230
- interface PlayerBadge {
1231
- readonly itemId: string;
1232
- readonly iconUrl: string;
1246
+ interface GemWillTerminate {
1247
+ readonly gem: typeof PROTOCOL;
1248
+ readonly type: "gem.willTerminate";
1249
+ readonly reason: "grant_expiring" | "session_ended" | "navigating" | "kill_switch";
1250
+ readonly graceMs: number;
1233
1251
  }
1234
- type Avatar3dFamily = "small_human" | "adult_human" | (string & {});
1235
- interface WornAvatar3d {
1236
- readonly family: Avatar3dFamily;
1237
- readonly id: string;
1238
- readonly modelUrl: string;
1239
- readonly iconUrl: string;
1252
+ interface GemRoomEvent {
1253
+ readonly gem: typeof PROTOCOL;
1254
+ readonly type: "gem.roomEvent";
1255
+ readonly event: "updated" | "match_started" | "match_ready" | "match_failed" | "version_stale";
1256
+ readonly roomId: string;
1257
+ readonly matchId?: string;
1258
+ readonly version?: number;
1259
+ readonly reason?: string;
1260
+ readonly platform?: "universal" | "mobile";
1240
1261
  }
1241
- interface PlayerIdentity {
1242
- readonly playerId?: string;
1243
- readonly displayName?: PlayerText;
1244
- readonly discriminator?: string;
1245
- readonly displayTag?: PlayerText;
1246
- readonly avatarIconId?: string;
1247
- readonly avatarIconUrl?: string;
1248
- readonly avatar3dId?: string;
1249
- readonly avatar3dModelUrl?: string;
1250
- readonly avatar3dIconUrl?: string;
1251
- readonly avatars3d?: readonly WornAvatar3d[];
1252
- readonly badges: readonly PlayerBadge[];
1262
+ interface GemSocketState {
1263
+ readonly gem: typeof PROTOCOL;
1264
+ readonly type: "gem.socketState";
1265
+ readonly connected: boolean;
1266
+ readonly reason?: "connecting" | "dropped" | "watchdog" | "terminal";
1253
1267
  }
1254
- declare function mapIdentity(row: unknown): PlayerIdentity;
1255
- declare function platformIconUrl(url: string | undefined): string | undefined;
1256
- interface LeaderboardPeriod {
1257
- readonly id: string;
1258
- readonly localDate?: string;
1259
- readonly startAt?: number;
1260
- readonly endsAt?: number;
1261
- readonly opensAt: number;
1262
- readonly closesAt: number;
1263
- readonly final: boolean;
1268
+ interface GemSeatedEvent {
1269
+ readonly gem: typeof PROTOCOL;
1270
+ readonly type: "gem.seatedEvent";
1271
+ readonly roomId: string;
1264
1272
  }
1265
- interface LeaderboardEntry extends RankedRow, PlayerIdentity {
1266
- readonly rank: number;
1267
- readonly occurredAt: number;
1268
- readonly entityId?: string;
1269
- readonly entityType?: EntityType;
1270
- readonly stats?: Readonly<Record<string, number>>;
1271
- readonly properties?: Readonly<Record<string, unknown>>;
1272
- readonly isViewer?: boolean;
1273
+ interface GemAutoStartFailedEvent {
1274
+ readonly gem: typeof PROTOCOL;
1275
+ readonly type: "gem.autoStartFailedEvent";
1276
+ readonly roomId: string;
1277
+ readonly code: string;
1273
1278
  }
1274
- interface Leaderboard {
1275
- readonly leaderboardType: string;
1276
- readonly runType: string;
1277
- readonly bucket1?: string;
1278
- readonly bucket2?: string;
1279
- readonly entries: readonly LeaderboardEntry[];
1280
- readonly generatedAt: number;
1281
- readonly updateFrequencySeconds?: number;
1282
- readonly period?: LeaderboardPeriod;
1279
+ interface GemTicketEvent {
1280
+ readonly gem: typeof PROTOCOL;
1281
+ readonly type: "gem.ticketEvent";
1282
+ readonly event: "queued" | "matched" | "expired" | "cancelled" | "failed";
1283
+ readonly ticketId: string;
1284
+ readonly partySize?: number;
1285
+ readonly queuedAt?: number;
1286
+ readonly expiresAt?: number;
1287
+ readonly reason?: string;
1288
+ readonly roomId?: string;
1283
1289
  }
1284
- interface RankedRow {
1285
- readonly rank: number;
1286
- readonly occurredAt: number;
1287
- readonly stats?: Readonly<Record<string, number>>;
1288
- readonly properties?: Readonly<Record<string, unknown>>;
1290
+ interface GemSignalEvent {
1291
+ readonly gem: typeof PROTOCOL;
1292
+ readonly type: "gem.signalEvent";
1293
+ readonly event: "hello" | "offer" | "answer" | "ice" | "peerJoined" | "peerLeft" | "migration" | "matchEnded" | "error";
1294
+ readonly matchId: string;
1295
+ readonly data: unknown;
1289
1296
  }
1290
- interface EntityLeaderboardEntry extends RankedRow {
1291
- readonly rank: number;
1292
- readonly stats?: Readonly<Record<string, number>>;
1297
+ interface GemRelayDraining {
1298
+ readonly gem: typeof PROTOCOL;
1299
+ readonly type: "gem.relayDraining";
1300
+ readonly matchId: string;
1301
+ readonly clusterTargetId: string;
1302
+ readonly relayIps: string[];
1303
+ readonly drainingSince: string;
1304
+ readonly deadline: string;
1293
1305
  }
1294
- interface EntityLeaderboard {
1295
- readonly leaderboardType: string;
1296
- readonly runType: string;
1297
- readonly entityType: EntityType;
1298
- readonly entityId: string;
1299
- readonly bucket1?: string;
1300
- readonly bucket2?: string;
1301
- readonly entries: readonly EntityLeaderboardEntry[];
1302
- readonly personalBest: EntityLeaderboardEntry | null;
1303
- readonly totalRuns: number;
1304
- readonly totalRunsExact: boolean;
1305
- readonly generatedAt: number;
1306
- readonly period?: LeaderboardPeriod;
1306
+ interface GemDedicatedEvent {
1307
+ readonly gem: typeof PROTOCOL;
1308
+ readonly type: "gem.dedicatedEvent";
1309
+ readonly event: "answer" | "error" | "matchEnded";
1310
+ readonly matchId: string;
1311
+ readonly sdp?: string;
1312
+ readonly sessionId?: string;
1313
+ readonly code?: string;
1314
+ readonly message?: string;
1315
+ readonly reason?: string;
1307
1316
  }
1308
- interface PeriodOptions {
1309
- readonly periodsBack?: number;
1310
- readonly period?: string;
1311
- readonly playerId?: string;
1317
+ interface GemPartyResult {
1318
+ readonly gem: typeof PROTOCOL;
1319
+ readonly type: "gem.partyResult";
1320
+ readonly requestId: string;
1321
+ readonly partyId?: string;
1312
1322
  }
1313
- interface EntityLeaderboardOptions extends PeriodOptions {
1314
- readonly bucket1?: string;
1315
- readonly bucket2?: string;
1316
- readonly limit?: number;
1317
- readonly signal?: AbortSignal;
1323
+ interface GemClusterTarget {
1324
+ readonly gem: typeof PROTOCOL;
1325
+ readonly type: "gem.clusterTarget";
1326
+ readonly clusterTargetId: string;
1327
+ readonly clusterTargetIds?: string[];
1318
1328
  }
1319
- interface GetLeaderboardOptions extends PeriodOptions {
1320
- readonly bucket1?: string;
1321
- readonly bucket2?: string;
1322
- readonly signal?: AbortSignal;
1329
+ interface GemGraphicsRoutes {
1330
+ readonly gem: typeof PROTOCOL;
1331
+ readonly type: "gem.graphicsRoutes";
1332
+ readonly entries: {
1333
+ gpu: string;
1334
+ route?: string;
1335
+ host?: string;
1336
+ }[];
1323
1337
  }
1324
- declare class LeaderboardsApi {
1325
- #private;
1326
- constructor(api: GameApi);
1327
- get(leaderboardType: string, options?: GetLeaderboardOptions): Promise<Leaderboard>;
1328
- friends(leaderboardType: string, options?: GetLeaderboardOptions): Promise<Leaderboard>;
1329
- mine(leaderboardType: string, options?: EntityLeaderboardOptions): Promise<EntityLeaderboard>;
1330
- character(leaderboardType: string, characterId: string, options?: EntityLeaderboardOptions): Promise<EntityLeaderboard>;
1338
+ interface GemScreenshotDenied {
1339
+ readonly gem: typeof PROTOCOL;
1340
+ readonly type: "gem.screenshot.denied";
1341
+ readonly reason: "not_wired" | "no_source" | "unsupported" | "unreadable" | "tainted" | "too_large" | "busy" | "declined" | "failed";
1342
+ readonly retryable: boolean;
1331
1343
  }
1332
- interface ShowcaseValue {
1333
- readonly playerId: string;
1334
- readonly key: string;
1335
- readonly value: unknown;
1336
- readonly updatedAt: number;
1344
+ interface GemDedicatedOffer {
1345
+ readonly gem: typeof PROTOCOL;
1346
+ readonly type: "gem.dedicatedOffer";
1347
+ readonly matchId: string;
1348
+ readonly sdp: string;
1349
+ readonly intent: "initial" | "ice_restart" | "full_reconnect";
1337
1350
  }
1338
- interface ShowcaseFriendEntry extends PlayerIdentity {
1339
- readonly playerId: string;
1340
- readonly value: unknown;
1341
- readonly isViewer: boolean;
1342
- readonly updatedAt: number;
1351
+ interface GemLocalServer {
1352
+ readonly gem: typeof PROTOCOL;
1353
+ readonly type: "gem.localServer";
1354
+ readonly requestId: string;
1355
+ readonly serverId?: string;
1343
1356
  }
1344
- interface ShowcaseFriends {
1345
- readonly key: string;
1346
- readonly entries: readonly ShowcaseFriendEntry[];
1347
- readonly generatedAt: number;
1357
+ interface GemLocalServerDenied {
1358
+ readonly gem: typeof PROTOCOL;
1359
+ readonly type: "gem.localServer.denied";
1360
+ readonly requestId: string;
1361
+ readonly retryable: boolean;
1362
+ readonly reason: "refused" | "unavailable";
1348
1363
  }
1349
- interface ShowcaseCallOptions {
1350
- readonly signal?: AbortSignal;
1364
+ interface GemMenuSelect {
1365
+ readonly gem: typeof PROTOCOL;
1366
+ readonly type: "gem.menuSelect";
1367
+ readonly entry: "settings" | "item";
1368
+ readonly id?: string;
1351
1369
  }
1352
- declare class ShowcaseApi {
1353
- private readonly api;
1354
- private readonly selfPlayerId;
1355
- constructor(api: GameApi, selfPlayerId: () => Promise<string>);
1356
- friends(key: string, options?: ShowcaseCallOptions): Promise<ShowcaseFriends>;
1357
- of(playerId: string, key: string, options?: ShowcaseCallOptions): Promise<ShowcaseValue | null>;
1358
- set(key: string, value: unknown, options?: ShowcaseCallOptions): Promise<ShowcaseValue>;
1359
- clear(key: string, options?: ShowcaseCallOptions): Promise<void>;
1370
+ interface GemSettingsDeclare {
1371
+ readonly gem: typeof PROTOCOL;
1372
+ readonly type: "gem.settingsDeclare";
1373
+ readonly settings: {
1374
+ id: string;
1375
+ label: string;
1376
+ kind: "toggle" | "slider" | "choice";
1377
+ value: boolean | number | string;
1378
+ quick?: boolean;
1379
+ icon?: string;
1380
+ min?: number;
1381
+ max?: number;
1382
+ step?: number;
1383
+ options?: {
1384
+ id: string;
1385
+ label: string;
1386
+ }[];
1387
+ }[];
1360
1388
  }
1361
- interface Friend extends PlayerIdentity {
1362
- readonly playerId: string;
1389
+ interface GemSettingChange {
1390
+ readonly gem: typeof PROTOCOL;
1391
+ readonly type: "gem.settingChange";
1392
+ readonly id: string;
1393
+ readonly value: boolean | number | string;
1363
1394
  }
1364
- interface FriendsPage {
1365
- readonly friends: readonly Friend[];
1366
- readonly nextCursor?: string;
1395
+ interface GemShareResult {
1396
+ readonly gem: typeof PROTOCOL;
1397
+ readonly type: "gem.shareResult";
1398
+ readonly requestId: string;
1399
+ readonly outcome: "accepted" | "refused";
1400
+ readonly reason?: string;
1401
+ readonly key?: string;
1367
1402
  }
1368
- interface ListFriendsOptions {
1369
- readonly limit?: number;
1370
- readonly cursor?: string;
1371
- readonly signal?: AbortSignal;
1403
+ interface GemPurchaseResult {
1404
+ readonly gem: typeof PROTOCOL;
1405
+ readonly type: "gem.purchaseResult";
1406
+ readonly requestId: string;
1407
+ readonly outcome: "ok" | "declined" | "unavailable";
1408
+ readonly reason?: string;
1409
+ readonly purchaseId?: string;
1372
1410
  }
1373
- interface FriendChallenge {
1374
- readonly id: string;
1375
- readonly from: Friend;
1376
- readonly template: string;
1377
- readonly params: Readonly<Record<string, string | number>>;
1378
- readonly createdAt: number;
1379
- readonly openedAt?: number;
1380
- readonly answeredAt?: number;
1411
+ interface GemPurchaseSettled {
1412
+ readonly gem: typeof PROTOCOL;
1413
+ readonly type: "gem.purchaseSettled";
1414
+ readonly purchaseKind: "item" | "recipe";
1415
+ readonly targetId: string;
1416
+ readonly catalogId?: string;
1417
+ readonly quantity: number;
1418
+ readonly purchaseId?: string;
1381
1419
  }
1382
- interface FriendChallengesPage {
1383
- readonly challenges: readonly FriendChallenge[];
1384
- readonly nextCursor?: string;
1420
+ interface GemDeviceSettingsResult {
1421
+ readonly gem: typeof PROTOCOL;
1422
+ readonly type: "gem.deviceSettings.result";
1423
+ readonly requestId: string;
1424
+ readonly outcome: "stored" | "too_large" | "unavailable";
1385
1425
  }
1386
- interface ListFriendChallengesOptions {
1387
- readonly limit?: number;
1388
- readonly cursor?: string;
1389
- readonly signal?: AbortSignal;
1426
+ interface GemAdResult {
1427
+ readonly gem: typeof PROTOCOL;
1428
+ readonly type: "gem.adResult";
1429
+ readonly requestId: string;
1430
+ readonly outcome: "shown" | "no_ad" | "unavailable";
1390
1431
  }
1391
- interface FriendChallengeRequest {
1392
- readonly playerId: string;
1393
- readonly template: string;
1394
- readonly params?: Readonly<Record<string, string | number>>;
1432
+ interface GemMomentResult {
1433
+ readonly gem: typeof PROTOCOL;
1434
+ readonly type: "gem.momentResult";
1435
+ readonly requestId: string;
1436
+ readonly shown: boolean;
1395
1437
  }
1396
- type FriendChallengeOutcomeKind = "accepted" | "cancelled" | "refused" | "unavailable";
1397
- interface FriendChallengeOutcome {
1398
- readonly outcome: FriendChallengeOutcomeKind;
1438
+ interface GemSignInResult {
1439
+ readonly gem: typeof PROTOCOL;
1440
+ readonly type: "gem.signInResult";
1441
+ readonly requestId: string;
1442
+ readonly outcome: "signed_in" | "declined" | "unavailable";
1399
1443
  }
1400
- type FriendChallengeErrorCode = "unknown_template" | "template_not_on_channel" | "param_invalid" | "param_undeclared" | "recipient_invalid" | (string & {});
1401
- declare class FriendChallengeError extends GemApiError {
1402
- readonly code?: FriendChallengeErrorCode;
1444
+ interface GemFriendChallengeResult {
1445
+ readonly gem: typeof PROTOCOL;
1446
+ readonly type: "gem.friendChallengeResult";
1447
+ readonly requestId: string;
1448
+ readonly outcome: "accepted" | "cancelled" | "refused" | "unavailable" | "rate_limited" | "invalid";
1449
+ readonly code?: string;
1403
1450
  readonly param?: string;
1404
1451
  readonly channel?: string;
1405
1452
  readonly configVersion?: number;
1406
- constructor(source: GemApiError, extra?: {
1407
- readonly param?: string;
1408
- readonly channel?: string;
1409
- readonly configVersion?: number;
1410
- });
1453
+ readonly retryAfterMs?: number;
1454
+ readonly detail?: string;
1411
1455
  }
1412
- interface PlayInviteRequest {
1413
- readonly params?: Readonly<Record<string, string>>;
1456
+ interface GemRequestPlayInvite {
1457
+ readonly gem: typeof PROTOCOL;
1458
+ readonly type: "gem.requestPlayInvite";
1459
+ readonly requestId: string;
1460
+ readonly params?: {
1461
+ key: string;
1462
+ value: string;
1463
+ }[];
1414
1464
  }
1415
- interface FriendsApiDependencies {
1416
- readonly challenge?: (request: FriendChallengeRequest) => Promise<FriendChallengeOutcome>;
1417
- readonly inviteToPlay?: (request?: PlayInviteRequest) => Promise<boolean>;
1418
- readonly setInviteParams?: (params: Readonly<Record<string, string>> | null) => boolean;
1419
- readonly launchedChallengeId?: string;
1465
+ interface GemPlayInviteResult {
1466
+ readonly gem: typeof PROTOCOL;
1467
+ readonly type: "gem.playInviteResult";
1468
+ readonly requestId: string;
1469
+ readonly shown: boolean;
1420
1470
  }
1421
- declare class FriendsApi {
1422
- #private;
1423
- constructor(api: GameApi, dependencies?: FriendsApiDependencies);
1424
- list(options?: ListFriendsOptions): Promise<FriendsPage>;
1425
- challenge(request: FriendChallengeRequest): Promise<FriendChallengeOutcome>;
1426
- inviteToPlay(request?: PlayInviteRequest): Promise<boolean>;
1427
- setInviteParams(params: Readonly<Record<string, string>> | null): boolean;
1428
- inbox(options?: ListFriendChallengesOptions): Promise<FriendChallengesPage>;
1429
- launchedChallenge(options?: {
1430
- readonly signal?: AbortSignal;
1431
- }): Promise<FriendChallenge | null>;
1432
- markAnswered(id: string): Promise<void>;
1471
+ interface GemInviteParams {
1472
+ readonly gem: typeof PROTOCOL;
1473
+ readonly type: "gem.inviteParams";
1474
+ readonly params?: {
1475
+ key: string;
1476
+ value: string;
1477
+ }[];
1433
1478
  }
1434
- type PlatformCurrencyAccess = "read" | "spend";
1435
- interface PlatformCurrency {
1436
- readonly slug: string;
1437
- readonly currencyId: string;
1438
- readonly balance: number;
1439
- readonly access: PlatformCurrencyAccess;
1479
+ interface GemRequestAppLinks {
1480
+ readonly gem: typeof PROTOCOL;
1481
+ readonly type: "gem.requestAppLinks";
1482
+ readonly requestId: string;
1440
1483
  }
1441
- interface PlatformCurrencyReadOptions {
1442
- readonly signal?: AbortSignal;
1484
+ interface GemAppLinksResult {
1485
+ readonly gem: typeof PROTOCOL;
1486
+ readonly type: "gem.appLinksResult";
1487
+ readonly requestId: string;
1488
+ readonly outcome: "ok" | "declined" | "unavailable";
1489
+ readonly reason?: string;
1490
+ readonly arcade?: {
1491
+ store: "app_store" | "google_play";
1492
+ };
1493
+ readonly game?: {
1494
+ store: "app_store" | "google_play";
1495
+ };
1443
1496
  }
1444
- declare class PlatformCurrenciesApi {
1445
- #private;
1446
- constructor(api: GameApi);
1447
- get(options?: PlatformCurrencyReadOptions): Promise<readonly PlatformCurrency[]>;
1497
+ interface GemRequestOpenApp {
1498
+ readonly gem: typeof PROTOCOL;
1499
+ readonly type: "gem.requestOpenApp";
1500
+ readonly requestId: string;
1501
+ readonly target: "arcade" | "game";
1448
1502
  }
1449
- type EarnAllowancePeriod = "day" | "window";
1450
- interface EarnAllowance {
1451
- readonly currencySlug: string;
1452
- readonly currencyId: string;
1453
- readonly limit: number;
1454
- readonly earned: number;
1455
- readonly remaining: number;
1456
- readonly period: EarnAllowancePeriod;
1457
- readonly periodDays: number;
1458
- readonly resetsAt?: number;
1503
+ interface GemOpenAppResult {
1504
+ readonly gem: typeof PROTOCOL;
1505
+ readonly type: "gem.openAppResult";
1506
+ readonly requestId: string;
1507
+ readonly outcome: "ok" | "declined" | "unavailable";
1508
+ readonly reason?: string;
1459
1509
  }
1460
- interface EarnAllowanceReadOptions {
1461
- readonly signal?: AbortSignal;
1510
+ interface GemRequestOpenGame {
1511
+ readonly gem: typeof PROTOCOL;
1512
+ readonly type: "gem.requestOpenGame";
1513
+ readonly requestId: string;
1514
+ readonly ref: string;
1462
1515
  }
1463
- interface EarnAllowanceSignal {
1464
- on(listener: () => void): () => void;
1465
- emit(): void;
1516
+ interface GemOpenGameResult {
1517
+ readonly gem: typeof PROTOCOL;
1518
+ readonly type: "gem.openGameResult";
1519
+ readonly requestId: string;
1520
+ readonly outcome: "ok" | "declined" | "unavailable";
1521
+ readonly reason?: string;
1466
1522
  }
1467
- type EarnAllowanceEvent = "changed";
1468
- declare class PlatformEarnAllowanceApi {
1469
- #private;
1470
- constructor(api: GameApi, signal?: EarnAllowanceSignal, log?: ((line: string) => void) | null);
1471
- get(options?: EarnAllowanceReadOptions): Promise<readonly EarnAllowance[]>;
1472
- on(event: EarnAllowanceEvent, listener: () => void): () => void;
1523
+ interface GemRequestSimilarGames {
1524
+ readonly gem: typeof PROTOCOL;
1525
+ readonly type: "gem.requestSimilarGames";
1526
+ readonly requestId: string;
1527
+ readonly limit?: number;
1528
+ }
1529
+ interface GemSimilarGamesResult {
1530
+ readonly gem: typeof PROTOCOL;
1531
+ readonly type: "gem.similarGamesResult";
1532
+ readonly requestId: string;
1533
+ readonly outcome: "ok" | "declined" | "unavailable";
1534
+ readonly reason?: string;
1535
+ readonly games: {
1536
+ gameId: string;
1537
+ slug?: string;
1538
+ iconUrl: string;
1539
+ capsuleLandscapeUrl: string;
1540
+ capsulePortraitUrl: string;
1541
+ previewVideoUrl?: string;
1542
+ previewPosterUrl?: string;
1543
+ untrusted: {
1544
+ name: string;
1545
+ tagline: string;
1546
+ shortDescription: string;
1547
+ tags: string[];
1548
+ };
1549
+ }[];
1550
+ }
1551
+ interface GemRequestStoreOffers {
1552
+ readonly gem: typeof PROTOCOL;
1553
+ readonly type: "gem.requestStoreOffers";
1554
+ readonly requestId: string;
1555
+ }
1556
+ interface GemStoreOffersResult {
1557
+ readonly gem: typeof PROTOCOL;
1558
+ readonly type: "gem.storeOffersResult";
1559
+ readonly requestId: string;
1560
+ readonly outcome: "ok" | "declined" | "unavailable";
1561
+ readonly reason?: string;
1562
+ readonly offers: {
1563
+ skuId: string;
1564
+ kind: "gem_pack" | "boost" | "pass" | "bundle";
1565
+ name: string;
1566
+ description: string;
1567
+ imageUrl?: string;
1568
+ priceDisplay: string;
1569
+ grant?: {
1570
+ currency: string;
1571
+ amount: number;
1572
+ };
1573
+ pass?: string;
1574
+ earnMultipliers?: {
1575
+ currencySlug: string;
1576
+ multiplierBp: number;
1577
+ }[];
1578
+ }[];
1579
+ }
1580
+ interface GemRequestStorePurchase {
1581
+ readonly gem: typeof PROTOCOL;
1582
+ readonly type: "gem.requestStorePurchase";
1583
+ readonly requestId: string;
1584
+ readonly skuId: string;
1585
+ }
1586
+ interface GemStorePurchaseResult {
1587
+ readonly gem: typeof PROTOCOL;
1588
+ readonly type: "gem.storePurchaseResult";
1589
+ readonly requestId: string;
1590
+ readonly outcome: "ok" | "declined" | "unavailable";
1591
+ readonly reason?: string;
1473
1592
  }
1474
- declare class PlatformApi {
1475
- readonly currencies: PlatformCurrenciesApi;
1476
- readonly earnAllowance: PlatformEarnAllowanceApi;
1477
- constructor(api: GameApi, earnAllowanceSignal?: EarnAllowanceSignal, log?: ((line: string) => void) | null);
1593
+ interface GemStorePurchaseSettled {
1594
+ readonly gem: typeof PROTOCOL;
1595
+ readonly type: "gem.storePurchaseSettled";
1596
+ readonly skuId: string;
1478
1597
  }
1479
- interface ProfileShowcaseEntry {
1480
- readonly key: string;
1481
- readonly visibility: string;
1482
- readonly value: unknown;
1483
- readonly updatedAt: number;
1598
+ interface GemRequestStoreOfferSheet {
1599
+ readonly gem: typeof PROTOCOL;
1600
+ readonly type: "gem.requestStoreOfferSheet";
1601
+ readonly requestId: string;
1602
+ readonly skuId: string;
1484
1603
  }
1485
- interface PlayerProfile extends PlayerIdentity {
1486
- readonly playerId: string;
1487
- readonly showcase: readonly ProfileShowcaseEntry[];
1488
- readonly generatedAt: number;
1604
+ interface GemStoreOfferSheetResult {
1605
+ readonly gem: typeof PROTOCOL;
1606
+ readonly type: "gem.storeOfferSheetResult";
1607
+ readonly requestId: string;
1608
+ readonly outcome: "ok" | "declined" | "unavailable";
1609
+ readonly reason?: string;
1489
1610
  }
1490
- interface ProfileCallOptions {
1491
- readonly signal?: AbortSignal;
1611
+ interface PlayerBoostMultiplier {
1612
+ readonly currencyId: string;
1613
+ readonly currencySlug: string;
1614
+ readonly multiplier: number;
1492
1615
  }
1493
- declare class ProfilesApi {
1494
- #private;
1495
- constructor(api: GameApi);
1496
- of(playerId: string, options?: ProfileCallOptions): Promise<PlayerProfile | null>;
1616
+ interface PlayerBoost {
1617
+ readonly active: boolean;
1618
+ readonly multipliers: readonly PlayerBoostMultiplier[];
1619
+ readonly expiresInDays?: number;
1497
1620
  }
1498
- interface FunctionInvokeOptions {
1499
- readonly signal?: AbortSignal;
1500
- readonly cueId?: string;
1621
+ interface PlayerBadge {
1622
+ readonly itemId: string;
1623
+ readonly iconUrl: string;
1501
1624
  }
1502
- interface FunctionResult {
1503
- readonly bytes: Uint8Array;
1504
- readonly invocationId?: string;
1505
- text(): string;
1506
- json<T = unknown>(): T;
1625
+ type Avatar3dFamily = "small_human" | "adult_human" | (string & {});
1626
+ interface WornAvatar3d {
1627
+ readonly family: Avatar3dFamily;
1628
+ readonly id: string;
1629
+ readonly modelUrl: string;
1630
+ readonly iconUrl: string;
1507
1631
  }
1508
- type FunctionFailure = "trap" | "memory_exceeded" | "cpu_budget_exceeded" | "host_call_limit" | "output_too_large" | "argument_too_large";
1509
- declare class GemFunctionError extends GemApiError {
1510
- readonly invocationId?: string;
1511
- readonly functionMessage?: string;
1512
- readonly failure?: FunctionFailure | (string & {});
1513
- constructor(source: GemApiError, extra: {
1514
- readonly invocationId?: string;
1515
- readonly functionMessage?: string;
1516
- readonly failure?: string;
1517
- });
1518
- get retryable(): boolean;
1632
+ interface PlayerIdentity {
1633
+ readonly playerId?: string;
1634
+ readonly displayName?: PlayerText;
1635
+ readonly discriminator?: string;
1636
+ readonly displayTag?: PlayerText;
1637
+ readonly avatarIconId?: string;
1638
+ readonly avatarIconUrl?: string;
1639
+ readonly avatar3dId?: string;
1640
+ readonly avatar3dModelUrl?: string;
1641
+ readonly avatar3dIconUrl?: string;
1642
+ readonly avatars3d?: readonly WornAvatar3d[];
1643
+ readonly badges: readonly PlayerBadge[];
1519
1644
  }
1520
- declare class FunctionsApi {
1521
- #private;
1522
- constructor(invoke: (body: Uint8Array, options?: {
1523
- signal?: AbortSignal;
1524
- cue_id?: string;
1525
- }) => Promise<BytesResponse>);
1526
- invoke(input: unknown, options?: FunctionInvokeOptions): Promise<FunctionResult>;
1645
+ declare function mapIdentity(row: unknown): PlayerIdentity;
1646
+ declare function platformIconUrl(url: string | undefined): string | undefined;
1647
+ interface RewardCue {
1648
+ currencySlug: string;
1649
+ cueId?: string;
1650
+ expected?: number;
1651
+ origin?: {
1652
+ x: number;
1653
+ y: number;
1654
+ };
1527
1655
  }
1528
- type SessionEndReason = "grant_expiring" | "session_ended" | "navigating" | "kill_switch" | "pagehide";
1529
- type MatchTransport = "dedicated" | "p2p";
1530
- 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";
1531
- declare const PLATFORM_EVENTS: readonly PlatformEventName[];
1532
- type AnalyticsValue = string | number;
1533
- interface AnalyticsRejection {
1534
- readonly index: number;
1535
- readonly code: string;
1656
+ type GemCorner = "top-left" | "top-right" | "bottom-left" | "bottom-right";
1657
+ type RewardPresentation = "arcade" | "game";
1658
+ interface MenuStyle {
1659
+ readonly ground: string;
1660
+ readonly accent: string;
1536
1661
  }
1537
- interface AnalyticsFlushResult {
1538
- readonly accepted: number;
1539
- readonly rejected: readonly AnalyticsRejection[];
1540
- readonly dropped: number;
1541
- readonly duplicate: boolean;
1662
+ type FrameState = "waiting" | "connected" | "refused" | "closed";
1663
+ interface FramePlayer extends PlayerIdentity {
1664
+ readonly displayName: PlayerText;
1665
+ readonly displayHandle: PlayerText;
1666
+ readonly avatarUrl?: string;
1667
+ readonly boost: PlayerBoost;
1542
1668
  }
1543
- interface AnalyticsFlushOptions {
1544
- readonly keepalive?: boolean;
1545
- readonly signal?: AbortSignal;
1669
+ type GemArcadeAsk = Omit<GemRequestAppLinks, "gem"> | Omit<GemRequestOpenApp, "gem"> | Omit<GemRequestOpenGame, "gem"> | Omit<GemRequestSimilarGames, "gem"> | Omit<GemRequestStoreOffers, "gem"> | Omit<GemRequestStorePurchase, "gem"> | Omit<GemRequestStoreOfferSheet, "gem">;
1670
+ type GemFriendsWindowAsk = Omit<GemRequestPlayInvite, "gem"> | Omit<GemInviteParams, "gem">;
1671
+ type GemArcadeAnswer = GemAppLinksResult | GemOpenAppResult | GemOpenGameResult | GemSimilarGamesResult | GemStoreOffersResult | GemStorePurchaseResult | GemStorePurchaseSettled | GemStoreOfferSheetResult;
1672
+ interface FrameCallbacks {
1673
+ onToken?(msg: GemToken): void;
1674
+ onPause?(msg: GemPause): void;
1675
+ onMenuSelect?(msg: GemMenuSelect): void;
1676
+ onSettingChange?(msg: GemSettingChange): void;
1677
+ onPrefs?(msg: GemPrefs$1): void;
1678
+ onCohorts?(msg: GemCohorts$1): void;
1679
+ onEarnAllowanceChanged?(): void;
1680
+ onInventoryChanged?(msg: GemInventoryChanged): void;
1681
+ onViewport?(msg: GemViewport$1): void;
1682
+ onWillTerminate?(msg: GemWillTerminate): void;
1683
+ onDevtools?(action: "open" | "close" | "toggle"): void;
1684
+ onScreenshot?(request: {
1685
+ maxWidth: number;
1686
+ maxHeight: number;
1687
+ }, port: MessagePort, deny: (reason: GemScreenshotDenied["reason"], retryable: boolean) => void): void;
1688
+ onRequestContext?(): void;
1689
+ onTokenDenied?(msg: GemTokenDenied): void;
1690
+ onLocalServer?(msg: GemLocalServer): void;
1691
+ onLocalServerDenied?(msg: GemLocalServerDenied): void;
1692
+ onPlayer?(player: FramePlayer, signInAvailable?: boolean): void;
1693
+ onRoomEvent?(msg: GemRoomEvent): void;
1694
+ onSeatedEvent?(msg: GemSeatedEvent): void;
1695
+ onAutoStartFailedEvent?(msg: GemAutoStartFailedEvent): void;
1696
+ onTicketEvent?(msg: GemTicketEvent): void;
1697
+ onSocketState?(msg: GemSocketState): void;
1698
+ onSignalEvent?(msg: GemSignalEvent): void;
1699
+ onRelayDraining?(msg: GemRelayDraining): void;
1700
+ onDedicatedEvent?(msg: GemDedicatedEvent): void;
1701
+ onClusterTarget?(msg: GemClusterTarget): void;
1702
+ onGraphicsRoutes?(msg: GemGraphicsRoutes): void;
1703
+ onPartyResult?(msg: GemPartyResult): void;
1704
+ onPurchaseResult?(msg: GemPurchaseResult): void;
1705
+ onPurchaseSettled?(msg: GemPurchaseSettled): void;
1706
+ onShareResult?(msg: GemShareResult): void;
1707
+ onDeviceSettings?(msg: GemDeviceSettings): void;
1708
+ onDeviceSettingsResult?(msg: GemDeviceSettingsResult): void;
1709
+ onAdResult?(msg: GemAdResult): void;
1710
+ onMomentResult?(msg: GemMomentResult): void;
1711
+ onSignInResult?(msg: GemSignInResult): void;
1712
+ onFriendChallengeResult?(msg: GemFriendChallengeResult): void;
1713
+ onArcadeAnswer?(msg: GemArcadeAnswer): void;
1714
+ onPlayInviteResult?(msg: GemPlayInviteResult): void;
1715
+ onError?(code: GemErrorCode, message?: string): void;
1716
+ onDropped?(code: GemErrorCode, message?: string): void;
1717
+ onStateChange?(state: FrameState): void;
1718
+ onRefused?(reason: string): void;
1546
1719
  }
1547
- interface AnalyticsOptions {
1548
- readonly enabled?: boolean;
1549
- readonly flushIntervalMs?: number;
1550
- readonly maxQueue?: number;
1720
+ interface FrameOptions extends FrameCallbacks {
1721
+ allowedEmbedders: readonly string[];
1722
+ selfOrigin?: string;
1723
+ expectedSource: unknown;
1724
+ capabilities?: readonly string[];
1725
+ clock?: Clock;
1551
1726
  }
1552
- interface AnalyticsApiOptions {
1553
- readonly environment?: Readonly<Record<string, string>> | (() => Readonly<Record<string, string>>);
1554
- readonly client: () => GemClient;
1555
- readonly clock: Clock;
1556
- readonly gameId: () => string | null;
1557
- readonly playerId: () => string | null;
1558
- readonly awaitPlayerId?: () => Promise<string>;
1559
- readonly declarations?: () => Promise<readonly {
1727
+ declare class GemFrame {
1728
+ private readonly options;
1729
+ private state;
1730
+ private port;
1731
+ private version;
1732
+ private peerCapabilities;
1733
+ private unbidden;
1734
+ private engagedSent;
1735
+ private readyPending;
1736
+ private readySent;
1737
+ private settleWaiters;
1738
+ private readonly clock;
1739
+ private readonly inbound;
1740
+ private readonly outbound;
1741
+ private readonly expectedSource;
1742
+ constructor(options: FrameOptions);
1743
+ get currentState(): FrameState;
1744
+ get parentCapabilities(): readonly string[];
1745
+ parentSupports(capability: string): boolean;
1746
+ get protocolVersion(): number | null;
1747
+ get unbiddenLaunch(): boolean;
1748
+ handleWindowMessage(event: HandshakeEvent): boolean;
1749
+ ready(): void;
1750
+ settled(timeoutMs?: number): Promise<FrameState>;
1751
+ progress(loaded: number, total: number): void;
1752
+ requestToken(requestId: string, reason: "initial" | "expiring" | "rejected"): void;
1753
+ requestLocalServer(requestId: string, gameRoomId: string): boolean;
1754
+ exit(reason?: string): void;
1755
+ openExternal(url: string): void;
1756
+ requestFullscreen(enabled: boolean): void;
1757
+ reportMuted(muted: boolean): boolean;
1758
+ reportEngaged(): boolean;
1759
+ cueReward(cue: RewardCue): boolean;
1760
+ showPortraitBorders(name: string | null): boolean;
1761
+ setWalletVisible(visible: boolean, options?: {
1762
+ only?: readonly string[];
1763
+ }): boolean;
1764
+ setMenu(items?: ReadonlyArray<{
1560
1765
  readonly id: string;
1561
- readonly dimensions?: Readonly<Record<string, unknown>> | null;
1562
- }[] | null | undefined>;
1563
- readonly options?: AnalyticsOptions;
1564
- readonly log?: ((message: string) => void) | null;
1766
+ readonly label: string;
1767
+ }>): boolean;
1768
+ declareSettings(settings: GemSettingsDeclare["settings"]): boolean;
1769
+ setGemCorner(corner: GemCorner): boolean;
1770
+ setRewardPresentation(mode: RewardPresentation): boolean;
1771
+ setMenuStyle(style: MenuStyle | null): boolean;
1772
+ requestShare(params: ReadonlyArray<{
1773
+ readonly key: string;
1774
+ readonly value: string;
1775
+ }>, requestId?: string): boolean;
1776
+ requestAvatarPicker(tab?: "2d" | "3d"): boolean;
1777
+ requestVibrate(pattern: readonly number[]): boolean;
1778
+ reportFrameStats(stats: {
1779
+ fps: number;
1780
+ frameTimeP95Ms: number;
1781
+ counts?: "pageFrames" | "gameDraws";
1782
+ }): boolean;
1783
+ sendGameContext(context: Record<string, unknown>): boolean;
1784
+ signal(signal: string, matchId: string, data: Record<string, unknown>): void;
1785
+ dedicatedOffer(matchId: string, sdp: string, intent: GemDedicatedOffer["intent"]): void;
1786
+ requestParty(requestId: string): boolean;
1787
+ requestPurchase(requestId: string, purchaseKind: "item" | "recipe", targetId: string, currencySlug: string, quantity?: number, catalogId?: string, origin?: "sheet" | "direct_refused"): boolean;
1788
+ requestAvatar3dPurchase(requestId: string, itemId: string, currencySlug: string): boolean;
1789
+ putDeviceSettings(requestId: string, settings: Readonly<Record<string, unknown>>): boolean;
1790
+ requestAd(requestId: string, placement: string, format: "interstitial" | "rewarded"): boolean;
1791
+ signalMoment(requestId: string, kind: string, placement?: string, wall?: boolean): boolean;
1792
+ readyCalled(): boolean;
1793
+ requestSignIn(requestId: string): boolean;
1794
+ requestFriendChallenge(requestId: string, playerId: string, template: string, params?: Readonly<Record<string, string | number>>): boolean;
1795
+ requestArcade(msg: GemArcadeAsk | GemFriendsWindowAsk): boolean;
1796
+ close(): void;
1797
+ private transition;
1798
+ private refuseMalformed;
1799
+ private dropUnknownType;
1800
+ private refuse;
1801
+ private fail;
1802
+ private gated;
1803
+ private send;
1804
+ private receive;
1805
+ private dispatchInbound;
1806
+ private screenshotDenied;
1565
1807
  }
1566
- declare class AnalyticsApi {
1567
- #private;
1568
- constructor(options: AnalyticsApiOptions);
1569
- track(name: string, props?: Readonly<Record<string, AnalyticsValue>>): void;
1570
- setContext(props: Readonly<Record<string, AnalyticsValue>>): void;
1571
- experiment(key: string, count: number): Promise<number>;
1572
- experiment<T extends string>(key: string, options: readonly T[]): Promise<T>;
1573
- get environment(): Readonly<Record<string, string>>;
1574
- flush(options?: AnalyticsFlushOptions): Promise<AnalyticsFlushResult>;
1575
- trackPlatform(name: PlatformEventName, props?: Readonly<Record<string, AnalyticsValue>>): void;
1576
- hold(): void;
1577
- release(): void;
1578
- get held(): boolean;
1579
- startSession(): void;
1580
- endSession(reason: SessionEndReason): void;
1581
- setPaused(paused: boolean): void;
1582
- setHidden(hidden: boolean): void;
1583
- dispose(): void;
1584
- get pending(): number;
1808
+ type ArcadeOutcomeKind = "ok" | "declined" | "unavailable";
1809
+ interface ArcadeOutcome {
1810
+ readonly outcome: ArcadeOutcomeKind;
1811
+ readonly reason?: string;
1585
1812
  }
1586
- interface BootMark {
1813
+ interface ArcadeOffer {
1814
+ readonly skuId: string;
1815
+ readonly kind: ArcadeOfferKind;
1587
1816
  readonly name: string;
1588
- readonly at: number;
1817
+ readonly description: string;
1818
+ readonly imageUrl?: string;
1819
+ readonly priceDisplay: string;
1820
+ readonly grant?: {
1821
+ readonly currency: string;
1822
+ readonly amount: number;
1823
+ };
1824
+ readonly pass?: string;
1825
+ readonly earnMultipliers: readonly ArcadeOfferEarnMultiplier[];
1589
1826
  }
1590
- interface BootTimeline {
1591
- mark(name: string, at?: number): boolean;
1592
- timeline(): string;
1593
- readonly marks: readonly BootMark[];
1827
+ type ArcadeOfferKind = "coin_pack" | "gem_pack" | "boost" | "pass" | "bundle";
1828
+ interface ArcadeOfferEarnMultiplier {
1829
+ readonly currencySlug: string;
1830
+ readonly multiplierBp: number;
1594
1831
  }
1595
- interface BootTimelineOptions {
1596
- readonly now?: () => number;
1832
+ interface ShowPassOutcome extends ArcadeOutcome {
1833
+ readonly held: boolean;
1597
1834
  }
1598
- declare function markOnResolve<T>(boot: BootTimeline, name: string, work: Promise<T>, log?: ((message: string) => void) | null): Promise<T>;
1599
- declare function reportOnResolve(boot: BootTimeline, log?: ((message: string) => void) | null): <T>(work: Promise<T>) => Promise<T>;
1600
- declare function createBootTimeline(options?: BootTimelineOptions): BootTimeline;
1601
- type GemGraphicsRoute = "webgpu" | "webgl";
1602
- interface GemPreferredRoute {
1603
- readonly route: GemGraphicsRoute;
1604
- readonly listed: boolean;
1835
+ interface StoreOffersOutcome extends ArcadeOutcome {
1836
+ readonly offers: readonly ArcadeOffer[];
1605
1837
  }
1606
- interface GemGraphicsRouteEntry {
1607
- readonly gpu: string;
1608
- readonly route?: string;
1609
- readonly host?: string;
1838
+ interface StoreSettlement {
1839
+ readonly skuId: string;
1610
1840
  }
1611
- interface PreferredRouteOptions {
1612
- readonly timeoutMs?: number;
1841
+ interface StoreApi {
1842
+ readonly available: boolean;
1843
+ readonly showOfferAvailable: boolean;
1844
+ offers(): Promise<StoreOffersOutcome>;
1845
+ purchase(skuId: string): Promise<ArcadeOutcome>;
1846
+ showOffer(skuId: string): Promise<ArcadeOutcome>;
1847
+ showPass(slug: string): Promise<ShowPassOutcome>;
1848
+ passOnSale(slug: string): Promise<boolean>;
1849
+ onSettled(listener: (settlement: StoreSettlement) => void): () => void;
1613
1850
  }
1614
- interface GraphicsApi {
1615
- preferredRoute(options?: PreferredRouteOptions): Promise<GemPreferredRoute>;
1851
+ type PlatformGrantSource = {
1852
+ readonly source: "pass";
1853
+ readonly pass: string;
1854
+ readonly amount: number;
1855
+ } | {
1856
+ readonly source: "boost";
1857
+ readonly amount: number;
1858
+ };
1859
+ interface PlatformGrantPreview {
1860
+ readonly currencySlug?: string;
1861
+ readonly currencyId?: string;
1862
+ readonly base: number;
1863
+ readonly total: number;
1864
+ readonly breakdown: readonly PlatformGrantSource[];
1865
+ readonly ifComplete?: true;
1616
1866
  }
1617
- type DevToolsOpener = "game" | "platform";
1618
- interface GemDevTools {
1619
- open(): Promise<boolean>;
1620
- close(): void;
1621
- readonly isOpen: boolean;
1867
+ interface EarningsApi {
1868
+ fromReceipt(change: unknown): Promise<PlatformGrantPreview | null>;
1622
1869
  }
1623
- type ClusterTargetLike = string | null | undefined;
1624
- declare const CLIENT_PLATFORMS: readonly [
1625
- "universal",
1626
- "mobile",
1627
- "web"
1628
- ];
1629
- type ClientPlatform = (typeof CLIENT_PLATFORMS)[number];
1630
- interface ClientVersion {
1631
- readonly platform?: ClientPlatform;
1632
- readonly gameVersion: string;
1633
- readonly engineVersion?: string;
1870
+ type PreviewTarget = {
1871
+ readonly recipe: string;
1872
+ } | {
1873
+ readonly progression: string;
1874
+ readonly add?: number;
1875
+ };
1876
+ type PreviewGrant = {
1877
+ readonly kind: "item";
1878
+ readonly itemId: string;
1879
+ readonly quantity: number;
1880
+ } | {
1881
+ readonly kind: "currency";
1882
+ readonly currencyId: string;
1883
+ readonly amount: number;
1884
+ } | {
1885
+ readonly kind: "roll";
1886
+ readonly lootTableId: string;
1887
+ readonly count: number;
1888
+ };
1889
+ interface UnmetRequirement {
1890
+ readonly index: number;
1891
+ readonly kind: string;
1634
1892
  }
1635
- interface ReadyMatch {
1636
- readonly status: "ready";
1637
- readonly matchId: string;
1638
- readonly protocol: string;
1639
- readonly joinCredential?: string;
1640
- readonly credentialExpiresAt?: number;
1641
- readonly host?: string;
1642
- readonly port?: number;
1893
+ interface BonusPreview {
1894
+ readonly id: string;
1895
+ readonly grants: readonly PreviewGrant[];
1896
+ readonly eligible: boolean | "unknown";
1897
+ readonly unmet: readonly UnmetRequirement[];
1643
1898
  }
1644
- interface StartMatchWaiting {
1645
- readonly attempt: number;
1646
- readonly elapsedMs: number;
1647
- readonly budgetMs: number;
1648
- readonly nextAttemptInMs: number;
1649
- readonly status: number;
1650
- readonly message: string;
1899
+ interface PassUpsell {
1900
+ readonly pass: string;
1901
+ readonly name: string;
1902
+ readonly offer: ArcadeOffer;
1903
+ readonly platformGrants: readonly {
1904
+ readonly currencySlug?: string;
1905
+ readonly currencyId?: string;
1906
+ readonly total: number;
1907
+ readonly extra: number;
1908
+ readonly ifComplete?: true;
1909
+ }[];
1910
+ readonly bonuses: readonly {
1911
+ readonly id: string;
1912
+ readonly grants: readonly PreviewGrant[];
1913
+ }[];
1651
1914
  }
1652
- interface StartMatchRetryOptions {
1653
- readonly budgetMs?: number;
1654
- readonly initialDelayMs?: number;
1655
- readonly maxDelayMs?: number;
1656
- readonly onWaiting?: (waiting: StartMatchWaiting) => void;
1915
+ interface ConfigPreview {
1916
+ readonly grants: readonly PreviewGrant[];
1917
+ readonly platformGrants: readonly PlatformGrantPreview[];
1918
+ readonly bonuses: readonly BonusPreview[];
1919
+ readonly upsells: readonly PassUpsell[];
1920
+ }
1921
+ interface PreviewHoldings {
1922
+ readonly items: ReadonlyMap<string, number> | null;
1923
+ readonly currencies: ReadonlyMap<string, number> | null;
1924
+ readonly progressions: ReadonlyMap<string, {
1925
+ readonly value: number;
1926
+ readonly completed: boolean;
1927
+ }> | null;
1928
+ readonly passes: ReadonlyMap<string, boolean> | null;
1929
+ }
1930
+ interface PreviewBoost {
1931
+ readonly currencyId?: string;
1932
+ readonly currencySlug?: string;
1933
+ readonly multiplierBp: number;
1934
+ }
1935
+ declare class PreviewError extends Error {
1936
+ readonly code: "not_found" | "invalid_argument" | "unsupported";
1937
+ constructor(code: "not_found" | "invalid_argument" | "unsupported", message: string);
1657
1938
  }
1658
- interface ClusterTarget {
1659
- readonly id: string;
1660
- readonly pressure: string;
1939
+ interface GameConfig extends GameConfigSnapshot {
1940
+ items: GameConfigSnapshot["items"];
1941
+ currencies: GameConfigSnapshot["currencies"];
1942
+ catalogs: GameConfigSnapshot["catalogs"];
1943
+ loot_tables: GameConfigSnapshot["loot_tables"];
1944
+ affix_pools?: GameConfigSnapshot["affix_pools"];
1945
+ progressions: GameConfigSnapshot["progressions"];
1946
+ game_room_templates: GameConfigSnapshot["game_room_templates"];
1947
+ kv: GameConfigSnapshot["kv"];
1948
+ run_types?: GameConfigSnapshot["run_types"];
1949
+ leaderboards?: GameConfigSnapshot["leaderboards"];
1950
+ async_opponent_types?: GameConfigSnapshot["async_opponent_types"];
1951
+ analytics_events?: GameConfigSnapshot["analytics_events"];
1952
+ analytics_funnels?: GameConfigSnapshot["analytics_funnels"];
1953
+ "rewarded_placements"?: SnapshotRewardedPlacement[];
1954
+ version: GameConfigSnapshot["version"];
1955
+ hash: GameConfigSnapshot["hash"];
1956
+ item(idOrSlug: string): SnapshotItem | null;
1957
+ currency(idOrSlug: string): SnapshotCurrency | null;
1661
1958
  }
1662
- type DedicatedServerFailure = "timeout" | "aborted" | "allocation_failed" | "no_server_ready" | "start_rate_limited" | "p2p_unavailable" | "unsupported_protocol" | "credential_expired" | "credential_reused" | "join_rate_limited" | "signaling_unavailable" | "signaling_failed" | "offer_refused" | "invalid_sdp" | "media_refused" | "connection_failed" | "join_refused" | "match_ended" | "misconfigured";
1663
- declare class DedicatedServerError extends Error {
1664
- readonly reason: DedicatedServerFailure;
1665
- readonly retryable: boolean;
1666
- readonly platformCode: string | undefined;
1667
- constructor(reason: DedicatedServerFailure, message: string, options?: {
1668
- cause?: unknown;
1669
- platformCode?: string;
1670
- });
1959
+ declare class GemConfigError extends Error {
1960
+ readonly reason: "config_unreachable" | "config_too_large" | "config_malformed" | "config_timeout" | "config_channel_unknown";
1961
+ constructor(reason: "config_unreachable" | "config_too_large" | "config_malformed" | "config_timeout" | "config_channel_unknown", message: string);
1671
1962
  }
1672
- type SignalingIntent = "initial" | "ice_restart" | "full_reconnect";
1673
- interface OfferRequest {
1674
- readonly matchId: string;
1675
- readonly sdp: string;
1676
- readonly intent: SignalingIntent;
1963
+ interface PreviewSources {
1964
+ boost(): readonly PreviewBoost[];
1965
+ holdings(needsInventory: boolean): Promise<PreviewHoldings>;
1966
+ offers(): Promise<readonly ArcadeOffer[]>;
1677
1967
  }
1678
- interface SignalingAnswer {
1679
- readonly sdp: string;
1968
+ interface GameConfigOptions {
1969
+ readonly fetch?: typeof globalThis.fetch;
1970
+ readonly timeoutMs?: number;
1680
1971
  }
1681
- interface SignalingChannel {
1682
- exchange(request: OfferRequest, signal?: AbortSignal): Promise<SignalingAnswer>;
1683
- close(): void;
1972
+ interface DropRateEntry {
1973
+ readonly entryId: string;
1974
+ readonly weight: number;
1975
+ readonly dropRate: number;
1976
+ readonly rarityTier?: string;
1684
1977
  }
1685
- type SdpType$1 = "offer" | "answer" | "pranswer" | "rollback";
1686
- interface SessionDescriptionLike$1 {
1687
- readonly type: SdpType$1;
1688
- readonly sdp?: string;
1978
+ interface DropRates {
1979
+ readonly lootTableId: string;
1980
+ readonly name: string;
1981
+ readonly rollCount: number;
1982
+ readonly allowDuplicateRolls: boolean;
1983
+ readonly totalWeight: number;
1984
+ readonly entries: readonly DropRateEntry[];
1689
1985
  }
1690
- interface DataChannelInitLike$1 {
1691
- readonly ordered?: boolean;
1692
- readonly maxRetransmits?: number;
1986
+ declare class GameConfigApi {
1987
+ private readonly api;
1988
+ private readonly channel;
1989
+ private readonly options;
1990
+ private loaded;
1991
+ private inFlight;
1992
+ private generation;
1993
+ private readonly dropRatesByConfig;
1994
+ constructor(api: GameApi, channel: () => string, options?: GameConfigOptions);
1995
+ load(): Promise<GameConfig | null>;
1996
+ refresh(): void;
1997
+ bindPreview(sources: PreviewSources): void;
1998
+ private previewSources;
1999
+ preview(target: PreviewTarget): Promise<ConfigPreview>;
2000
+ dropRates(lootTableId: string, signal?: AbortSignal): Promise<DropRates>;
2001
+ private fetchConfig;
1693
2002
  }
1694
- interface EventTargetLike$1 {
1695
- addEventListener(type: string, listener: (event: unknown) => void): void;
1696
- removeEventListener(type: string, listener: (event: unknown) => void): void;
2003
+ declare const MAX_PERIODS_BACK = 400;
2004
+ type ChallengeWindow = "daily" | "weekly" | "monthly" | "cron" | (string & {});
2005
+ interface Challenge {
2006
+ readonly id: string;
2007
+ readonly slug?: string;
2008
+ readonly window: ChallengeWindow;
2009
+ readonly periodStartAt: number;
2010
+ readonly periodEndsAt: number;
2011
+ readonly periodLocalDate?: string;
2012
+ readonly boundary: string;
2013
+ readonly resetTime: string;
2014
+ readonly seed: string;
2015
+ readonly data?: string;
2016
+ readonly dataHash?: string;
1697
2017
  }
1698
- interface DataChannelLike$1 extends EventTargetLike$1 {
1699
- readonly readyState: string;
1700
- send(data: string | Uint8Array): void;
1701
- close(): void;
2018
+ interface ListChallengesOptions {
2019
+ readonly periodsBack?: number;
2020
+ readonly signal?: AbortSignal;
2021
+ }
2022
+ declare class ChallengesApi {
2023
+ #private;
2024
+ constructor(api: GameApi);
2025
+ list(options?: ListChallengesOptions): Promise<Challenge[]>;
1702
2026
  }
1703
- interface PeerConnectionLike$1 extends EventTargetLike$1 {
1704
- readonly localDescription: SessionDescriptionLike$1 | null;
1705
- readonly iceGatheringState: string;
1706
- createDataChannel(label: string, init?: DataChannelInitLike$1): DataChannelLike$1;
1707
- createOffer(): Promise<SessionDescriptionLike$1>;
1708
- setLocalDescription(description: SessionDescriptionLike$1): Promise<void>;
1709
- setRemoteDescription(description: SessionDescriptionLike$1): Promise<void>;
1710
- close(): void;
2027
+ interface LeaderboardPeriod {
2028
+ readonly id: string;
2029
+ readonly localDate?: string;
2030
+ readonly startAt?: number;
2031
+ readonly endsAt?: number;
2032
+ readonly opensAt: number;
2033
+ readonly closesAt: number;
2034
+ readonly final: boolean;
1711
2035
  }
1712
- interface JoinWelcome {
1713
- readonly playerId?: string;
1714
- readonly matchId?: string;
1715
- readonly heartbeatIntervalMs?: number;
2036
+ interface LeaderboardEntry extends RankedRow, PlayerIdentity {
2037
+ readonly rank: number;
2038
+ readonly occurredAt: number;
2039
+ readonly entityId?: string;
2040
+ readonly entityType?: EntityType;
2041
+ readonly stats?: Readonly<Record<string, number>>;
2042
+ readonly properties?: Readonly<Record<string, unknown>>;
2043
+ readonly isViewer?: boolean;
1716
2044
  }
1717
- interface JoinExchange {
1718
- readonly welcome: JoinWelcome;
1719
- detach(): void;
2045
+ interface Leaderboard {
2046
+ readonly leaderboardType: string;
2047
+ readonly runType: string;
2048
+ readonly bucket1?: string;
2049
+ readonly bucket2?: string;
2050
+ readonly entries: readonly LeaderboardEntry[];
2051
+ readonly generatedAt: number;
2052
+ readonly updateFrequencySeconds?: number;
2053
+ readonly period?: LeaderboardPeriod;
1720
2054
  }
1721
- interface PresentCredentialOptions {
1722
- readonly channel: DataChannelLike$1;
1723
- readonly credential: string;
1724
- readonly credentialExpiresAt: number;
1725
- readonly clock: Clock;
1726
- readonly ceilingMs?: number;
1727
- readonly wire?: number;
1728
- readonly heartbeat?: boolean;
1729
- readonly onMessage?: (data: unknown) => void;
1730
- readonly signal?: AbortSignal;
2055
+ interface RankedRow {
2056
+ readonly rank: number;
2057
+ readonly occurredAt: number;
2058
+ readonly stats?: Readonly<Record<string, number>>;
2059
+ readonly properties?: Readonly<Record<string, unknown>>;
1731
2060
  }
1732
- declare function presentJoinCredential(options: PresentCredentialOptions): Promise<JoinExchange>;
1733
- type TransportKind = "webtransport" | "webrtc" | "websocket";
1734
- declare const UNRELIABLE_CHANNEL_LABEL = "gem-uu";
1735
- interface SendOptions$1 {
1736
- readonly reliable?: boolean;
1737
- readonly ordered?: boolean;
2061
+ interface EntityLeaderboardEntry extends RankedRow {
2062
+ readonly rank: number;
2063
+ readonly stats?: Readonly<Record<string, number>>;
1738
2064
  }
1739
- interface MessageMeta {
1740
- readonly reliable: boolean;
1741
- readonly ordered: boolean;
2065
+ interface EntityLeaderboard {
2066
+ readonly leaderboardType: string;
2067
+ readonly runType: string;
2068
+ readonly entityType: EntityType;
2069
+ readonly entityId: string;
2070
+ readonly bucket1?: string;
2071
+ readonly bucket2?: string;
2072
+ readonly entries: readonly EntityLeaderboardEntry[];
2073
+ readonly personalBest: EntityLeaderboardEntry | null;
2074
+ readonly totalRuns: number;
2075
+ readonly totalRunsExact: boolean;
2076
+ readonly generatedAt: number;
2077
+ readonly period?: LeaderboardPeriod;
1742
2078
  }
1743
- interface GameServerLink {
1744
- readonly transport: TransportKind;
1745
- send(data: Uint8Array | string, options?: SendOptions$1): void;
1746
- onMessage(handler: (data: Uint8Array | string, meta: MessageMeta) => void): void;
1747
- onClose(handler: (reason?: string) => void): void;
1748
- close(): void;
2079
+ interface PeriodOptions {
2080
+ readonly periodsBack?: number;
2081
+ readonly period?: string;
2082
+ readonly playerId?: string;
1749
2083
  }
1750
- interface TransportAdvert {
1751
- readonly v: number;
1752
- readonly host: string;
1753
- readonly port: number;
1754
- readonly match_id: string;
1755
- readonly webrtc?: boolean;
1756
- readonly webtransport?: {
1757
- readonly url: string;
1758
- readonly cert_sha256_b64: string;
1759
- readonly expires_at?: number;
1760
- readonly named_url?: string;
1761
- };
1762
- readonly websocket?: {
1763
- readonly url: string;
1764
- readonly tls?: boolean;
1765
- };
2084
+ interface EntityLeaderboardOptions extends PeriodOptions {
2085
+ readonly bucket1?: string;
2086
+ readonly bucket2?: string;
2087
+ readonly limit?: number;
2088
+ readonly signal?: AbortSignal;
1766
2089
  }
1767
- declare function readTemplateTransports(value: unknown): readonly TransportKind[] | null;
1768
- declare function readTransportAdvert(settings: unknown, forMatch?: string): TransportAdvert | null;
1769
- declare function webTransportAvailable(): boolean;
1770
- type RoomArgScalar = string | number | boolean;
1771
- type RoomArgValue$1 = RoomArgScalar | readonly RoomArgScalar[];
1772
- type RoomArgs = Readonly<Record<string, RoomArgValue$1>>;
1773
- type RoomArgType = "string" | "int" | "float" | "bool" | (string & {});
1774
- interface RoomArgEntry {
1775
- readonly name: string;
1776
- readonly type: RoomArgType;
1777
- readonly list: boolean;
1778
- readonly required: boolean;
1779
- readonly mutable: boolean;
1780
- readonly fixed?: RoomArgValue$1;
1781
- readonly default?: RoomArgValue$1;
1782
- readonly description?: string;
1783
- readonly allowed?: readonly RoomArgScalar[];
1784
- readonly min?: number;
1785
- readonly max?: number;
1786
- readonly minItems?: number;
1787
- readonly maxItems?: number;
1788
- readonly maxLength?: number;
2090
+ interface GetLeaderboardOptions extends PeriodOptions {
2091
+ readonly bucket1?: string;
2092
+ readonly bucket2?: string;
2093
+ readonly signal?: AbortSignal;
1789
2094
  }
1790
- type RoomStatus = "open" | "in_game" | "closed" | (string & {});
1791
- type PlayWithOutcome = "joined" | "unavailable";
1792
- type MatchConnectionState = "disconnected" | "connecting" | "connected" | "suspended";
1793
- type MatchSessionPhase = "none" | "starting" | "ready" | "connected" | "suspended" | "ended" | (string & {});
1794
- interface MatchSession {
1795
- readonly phase: MatchSessionPhase;
1796
- readonly matchId?: string;
1797
- readonly reason?: string;
1798
- readonly roomReopened?: boolean;
2095
+ declare class LeaderboardsApi {
2096
+ #private;
2097
+ constructor(api: GameApi);
2098
+ get(leaderboardType: string, options?: GetLeaderboardOptions): Promise<Leaderboard>;
2099
+ friends(leaderboardType: string, options?: GetLeaderboardOptions): Promise<Leaderboard>;
2100
+ mine(leaderboardType: string, options?: EntityLeaderboardOptions): Promise<EntityLeaderboard>;
2101
+ character(leaderboardType: string, characterId: string, options?: EntityLeaderboardOptions): Promise<EntityLeaderboard>;
1799
2102
  }
1800
- interface MatchEnded {
1801
- readonly matchId: string;
1802
- readonly reason: string;
1803
- readonly roomReopened: boolean;
2103
+ interface ShowcaseValue {
2104
+ readonly playerId: string;
2105
+ readonly key: string;
2106
+ readonly value: unknown;
2107
+ readonly updatedAt: number;
1804
2108
  }
1805
- interface MatchSuspended {
1806
- readonly matchId: string;
1807
- readonly cause: string;
2109
+ interface ShowcaseFriendEntry extends PlayerIdentity {
2110
+ readonly playerId: string;
2111
+ readonly value: unknown;
2112
+ readonly isViewer: boolean;
2113
+ readonly updatedAt: number;
1808
2114
  }
1809
- interface MatchReconnecting {
1810
- readonly matchId: string;
1811
- readonly attempt: number;
1812
- readonly attempts: number;
1813
- readonly remainingMs: number;
2115
+ interface ShowcaseFriends {
2116
+ readonly key: string;
2117
+ readonly entries: readonly ShowcaseFriendEntry[];
2118
+ readonly generatedAt: number;
1814
2119
  }
1815
- interface MatchReconnected {
1816
- readonly matchId: string;
1817
- readonly attempt: number;
2120
+ interface ShowcaseCallOptions {
2121
+ readonly signal?: AbortSignal;
1818
2122
  }
1819
- interface AutoReconnectOptions {
1820
- readonly budgetMs?: number;
1821
- readonly attempts?: number;
1822
- readonly maxDelayMs?: number;
2123
+ declare class ShowcaseApi {
2124
+ private readonly api;
2125
+ private readonly selfPlayerId;
2126
+ constructor(api: GameApi, selfPlayerId: () => Promise<string>);
2127
+ friends(key: string, options?: ShowcaseCallOptions): Promise<ShowcaseFriends>;
2128
+ of(playerId: string, key: string, options?: ShowcaseCallOptions): Promise<ShowcaseValue | null>;
2129
+ set(key: string, value: unknown, options?: ShowcaseCallOptions): Promise<ShowcaseValue>;
2130
+ clear(key: string, options?: ShowcaseCallOptions): Promise<void>;
1823
2131
  }
1824
- interface RoomMember extends PlayerIdentity {
2132
+ interface Friend extends PlayerIdentity {
1825
2133
  readonly playerId: string;
1826
- readonly isReady: boolean;
1827
- readonly role: string;
1828
- readonly joinedAt: number;
1829
- readonly groupId?: string;
1830
- readonly platform?: string;
1831
2134
  }
1832
- interface Room {
1833
- readonly id: string;
1834
- readonly gameId: string;
1835
- readonly name: string;
1836
- readonly status: RoomStatus;
1837
- readonly hostPlayerId: string;
1838
- readonly maxPlayers: number;
1839
- readonly memberCount: number;
1840
- readonly members: readonly RoomMember[];
1841
- readonly isPublic: boolean;
1842
- readonly joinCode?: string;
1843
- readonly settings?: unknown;
1844
- readonly roomArgs?: RoomArgs;
1845
- readonly roomArgsTemplate?: readonly RoomArgEntry[];
1846
- readonly gameChannel: string;
1847
- readonly region?: string;
1848
- readonly clusterTargetId?: string;
1849
- readonly selfHosted: boolean;
1850
- readonly matchId?: string;
1851
- readonly version: number;
1852
- readonly templateId?: string;
1853
- readonly templateSlug?: string;
1854
- readonly roomType: string;
1855
- readonly transports?: readonly TransportKind[];
1856
- readonly createdAt: number;
1857
- readonly updatedAt: number;
1858
- readonly startedAt?: number;
2135
+ interface FriendsPage {
2136
+ readonly friends: readonly Friend[];
2137
+ readonly nextCursor?: string;
1859
2138
  }
1860
- interface MatchAutoStartFailed {
1861
- readonly roomId: string;
1862
- readonly code: string;
1863
- readonly handled: boolean;
2139
+ interface ListFriendsOptions {
2140
+ readonly limit?: number;
2141
+ readonly cursor?: string;
2142
+ readonly signal?: AbortSignal;
1864
2143
  }
1865
- interface RoomSummary {
1866
- readonly id: string;
1867
- readonly gameId: string;
1868
- readonly name: string;
1869
- readonly status: RoomStatus;
1870
- readonly hostPlayerId: string;
1871
- readonly maxPlayers: number;
1872
- readonly memberCount: number;
1873
- readonly isPublic: boolean;
1874
- readonly gameChannel: string;
1875
- readonly roomType: string;
2144
+ interface FriendChallenge {
2145
+ readonly id: string;
2146
+ readonly from: Friend;
2147
+ readonly template: string;
2148
+ readonly params: Readonly<Record<string, string | number>>;
1876
2149
  readonly createdAt: number;
2150
+ readonly openedAt?: number;
2151
+ readonly answeredAt?: number;
1877
2152
  }
1878
- interface RoomPage {
1879
- readonly rooms: readonly RoomSummary[];
2153
+ interface FriendChallengesPage {
2154
+ readonly challenges: readonly FriendChallenge[];
1880
2155
  readonly nextCursor?: string;
1881
2156
  }
1882
- interface RoomOperationError {
1883
- readonly operation: string;
1884
- readonly code: number;
1885
- readonly reason: string;
1886
- readonly message: string;
1887
- readonly retryable: boolean;
1888
- }
1889
- interface QueueForMatchOptions {
1890
- readonly templateSlugs: readonly string[];
1891
- readonly partyId?: string;
2157
+ interface ListFriendChallengesOptions {
2158
+ readonly limit?: number;
2159
+ readonly cursor?: string;
1892
2160
  readonly signal?: AbortSignal;
1893
2161
  }
1894
- type MatchTicketStatus = "queued" | "matched" | "expired" | "cancelled" | "failed" | "lost" | "unavailable";
1895
- type MatchTicketOutcome = {
1896
- readonly status: "matched";
1897
- readonly room: Room;
1898
- } | {
1899
- readonly status: "expired";
1900
- readonly reason: string;
1901
- } | {
1902
- readonly status: "cancelled";
1903
- readonly reason: string;
1904
- } | {
1905
- readonly status: "failed";
1906
- readonly reason: string;
1907
- } | {
1908
- readonly status: "lost";
1909
- } | {
1910
- readonly status: "unavailable";
1911
- };
1912
- interface MatchTicket {
1913
- readonly id: string;
1914
- readonly status: MatchTicketStatus;
1915
- readonly partySize: number;
1916
- readonly queuedAt: number;
1917
- readonly expiresAt: number;
1918
- readonly outcome: Promise<MatchTicketOutcome>;
1919
- cancel(): Promise<MatchTicketOutcome>;
2162
+ interface FriendChallengeRequest {
2163
+ readonly playerId: string;
2164
+ readonly template: string;
2165
+ readonly params?: Readonly<Record<string, string | number>>;
1920
2166
  }
1921
- interface CreateRoomOptions {
1922
- readonly name: string;
1923
- readonly maxPlayers?: number;
1924
- readonly isPublic?: boolean;
1925
- readonly settings?: unknown;
1926
- readonly region?: string;
1927
- readonly templateId?: string;
1928
- readonly templateSlug?: string;
1929
- readonly partyId?: string;
1930
- readonly roomArgs?: RoomArgs;
1931
- readonly signal?: AbortSignal;
2167
+ type FriendChallengeOutcomeKind = "accepted" | "cancelled" | "refused" | "unavailable";
2168
+ interface FriendChallengeOutcome {
2169
+ readonly outcome: FriendChallengeOutcomeKind;
1932
2170
  }
1933
- interface JoinRoomOptions {
1934
- readonly partyId?: string;
1935
- readonly signal?: AbortSignal;
2171
+ type FriendChallengeErrorCode = "unknown_template" | "template_not_on_channel" | "param_invalid" | "param_undeclared" | "recipient_invalid" | (string & {});
2172
+ declare class FriendChallengeError extends GemApiError {
2173
+ readonly code?: FriendChallengeErrorCode;
2174
+ readonly param?: string;
2175
+ readonly channel?: string;
2176
+ readonly configVersion?: number;
2177
+ constructor(source: GemApiError, extra?: {
2178
+ readonly param?: string;
2179
+ readonly channel?: string;
2180
+ readonly configVersion?: number;
2181
+ });
1936
2182
  }
1937
- interface QuickJoinOptions extends JoinRoomOptions {
1938
- readonly templateSlug?: string;
1939
- readonly templateSlugs?: readonly string[];
1940
- readonly templateId?: string;
1941
- readonly region?: string;
1942
- readonly name?: string;
2183
+ interface PlayInviteRequest {
2184
+ readonly params?: Readonly<Record<string, string>>;
1943
2185
  }
1944
- interface ListRoomsOptions {
1945
- readonly status?: "open" | "in_game";
1946
- readonly templateSlug?: string;
1947
- readonly limit?: number;
1948
- readonly cursor?: string;
1949
- readonly signal?: AbortSignal;
2186
+ interface FriendsApiDependencies {
2187
+ readonly challenge?: (request: FriendChallengeRequest) => Promise<FriendChallengeOutcome>;
2188
+ readonly inviteToPlay?: (request?: PlayInviteRequest) => Promise<boolean>;
2189
+ readonly setInviteParams?: (params: Readonly<Record<string, string>> | null) => boolean;
2190
+ readonly launchedChallengeId?: string;
1950
2191
  }
1951
- interface UpdateRoomOptions {
1952
- readonly name?: string;
1953
- readonly maxPlayers?: number;
1954
- readonly isPublic?: boolean;
1955
- readonly settings?: unknown;
1956
- readonly roomArgs?: RoomArgs;
2192
+ declare class FriendsApi {
2193
+ #private;
2194
+ constructor(api: GameApi, dependencies?: FriendsApiDependencies);
2195
+ list(options?: ListFriendsOptions): Promise<FriendsPage>;
2196
+ challenge(request: FriendChallengeRequest): Promise<FriendChallengeOutcome>;
2197
+ inviteToPlay(request?: PlayInviteRequest): Promise<boolean>;
2198
+ setInviteParams(params: Readonly<Record<string, string>> | null): boolean;
2199
+ inbox(options?: ListFriendChallengesOptions): Promise<FriendChallengesPage>;
2200
+ launchedChallenge(options?: {
2201
+ readonly signal?: AbortSignal;
2202
+ }): Promise<FriendChallenge | null>;
2203
+ markAnswered(id: string): Promise<void>;
2204
+ }
2205
+ type PlatformCurrencyAccess = "read" | "spend";
2206
+ interface PlatformCurrency {
2207
+ readonly slug: string;
2208
+ readonly currencyId: string;
2209
+ readonly balance: number;
2210
+ readonly access: PlatformCurrencyAccess;
2211
+ }
2212
+ interface PlatformCurrencyReadOptions {
1957
2213
  readonly signal?: AbortSignal;
1958
2214
  }
1959
- type PartyTicketStatus = "queued" | "matched" | "expired" | "cancelled" | "failed" | "lost";
1960
- type PartyTicketOutcome = {
1961
- readonly status: "matched";
1962
- } | {
1963
- readonly status: "expired";
1964
- readonly reason: string;
1965
- } | {
1966
- readonly status: "cancelled";
1967
- readonly reason: string;
1968
- } | {
1969
- readonly status: "failed";
1970
- readonly reason: string;
1971
- } | {
1972
- readonly status: "lost";
1973
- };
1974
- interface PartyTicket {
1975
- readonly id: string;
1976
- readonly status: PartyTicketStatus;
1977
- readonly partySize: number;
1978
- readonly queuedAt: number;
1979
- readonly expiresAt: number;
1980
- readonly outcome: Promise<PartyTicketOutcome>;
2215
+ declare class PlatformCurrenciesApi {
2216
+ #private;
2217
+ constructor(api: GameApi);
2218
+ get(options?: PlatformCurrencyReadOptions): Promise<readonly PlatformCurrency[]>;
1981
2219
  }
1982
- interface RelayedTicketEvent {
1983
- readonly event: "queued" | "matched" | "expired" | "cancelled" | "failed";
1984
- readonly ticketId: string;
1985
- readonly partySize?: number;
1986
- readonly queuedAt?: number;
1987
- readonly expiresAt?: number;
1988
- readonly reason?: string;
1989
- readonly roomId?: string;
2220
+ type EarnAllowancePeriod = "day" | "window";
2221
+ interface EarnAllowance {
2222
+ readonly currencySlug: string;
2223
+ readonly currencyId: string;
2224
+ readonly limit: number;
2225
+ readonly earned: number;
2226
+ readonly remaining: number;
2227
+ readonly period: EarnAllowancePeriod;
2228
+ readonly periodDays: number;
2229
+ readonly resetsAt?: number;
1990
2230
  }
1991
- interface RoomEventMap {
1992
- created: [
1993
- Room
1994
- ];
1995
- joined: [
1996
- Room
1997
- ];
1998
- left: [
1999
- ];
2000
- closed: [
2001
- ];
2002
- updated: [
2003
- Room
2004
- ];
2005
- seated: [
2006
- Room
2007
- ];
2008
- partyQueued: [
2009
- PartyTicket
2010
- ];
2011
- listed: [
2012
- RoomPage
2013
- ];
2014
- mineListed: [
2015
- readonly RoomSummary[]
2016
- ];
2017
- memberJoined: [
2018
- string
2019
- ];
2020
- memberLeft: [
2021
- string
2022
- ];
2023
- kicked: [
2024
- ];
2025
- readyChanged: [
2026
- string,
2027
- boolean
2028
- ];
2029
- hostChanged: [
2030
- string
2031
- ];
2032
- matchStartWaiting: [
2033
- StartMatchWaiting
2034
- ];
2035
- matchAutoStartFailed: [
2036
- MatchAutoStartFailed
2037
- ];
2038
- matchAllocationStarted: [
2039
- string
2040
- ];
2041
- matchReady: [
2042
- ReadyMatch
2043
- ];
2044
- matchFailed: [
2045
- string,
2046
- string
2047
- ];
2048
- matchEnded: [
2049
- MatchEnded
2050
- ];
2051
- matchSuspended: [
2052
- MatchSuspended
2053
- ];
2054
- matchReconnecting: [
2055
- MatchReconnecting
2056
- ];
2057
- matchReconnected: [
2058
- MatchReconnected
2059
- ];
2060
- versionUpdateAvailable: [
2061
- ClientPlatform | undefined
2062
- ];
2063
- error: [
2064
- RoomOperationError
2065
- ];
2231
+ interface EarnAllowanceReadOptions {
2232
+ readonly signal?: AbortSignal;
2233
+ }
2234
+ interface EarnAllowanceSignal {
2235
+ on(listener: () => void): () => void;
2236
+ emit(): void;
2237
+ }
2238
+ type EarnAllowanceEvent = "changed";
2239
+ declare class PlatformEarnAllowanceApi {
2240
+ #private;
2241
+ constructor(api: GameApi, signal?: EarnAllowanceSignal, log?: ((line: string) => void) | null);
2242
+ get(options?: EarnAllowanceReadOptions): Promise<readonly EarnAllowance[]>;
2243
+ on(event: EarnAllowanceEvent, listener: () => void): () => void;
2066
2244
  }
2067
- type RoomEventName = keyof RoomEventMap;
2068
- interface MatchEndHint {
2069
- readonly matchId?: string;
2070
- readonly reason?: string;
2245
+ declare class PlatformApi {
2246
+ readonly currencies: PlatformCurrenciesApi;
2247
+ readonly earnAllowance: PlatformEarnAllowanceApi;
2248
+ constructor(api: GameApi, earnAllowanceSignal?: EarnAllowanceSignal, log?: ((line: string) => void) | null);
2071
2249
  }
2072
- interface RelayedRoomEvent {
2073
- readonly event: "updated" | "match_started" | "match_ready" | "match_failed" | "version_stale";
2074
- readonly roomId: string;
2075
- readonly matchId?: string;
2076
- readonly version?: number;
2077
- readonly reason?: string;
2078
- readonly platform?: ClientPlatform;
2250
+ interface ProfileShowcaseEntry {
2251
+ readonly key: string;
2252
+ readonly visibility: string;
2253
+ readonly value: unknown;
2254
+ readonly updatedAt: number;
2079
2255
  }
2080
- interface StartMatchOptions {
2081
- readonly clusterTargetId?: ClusterTargetLike;
2082
- readonly retry?: StartMatchRetryOptions;
2256
+ interface PlayerProfile extends PlayerIdentity {
2257
+ readonly playerId: string;
2258
+ readonly showcase: readonly ProfileShowcaseEntry[];
2259
+ readonly generatedAt: number;
2260
+ }
2261
+ interface ProfileCallOptions {
2083
2262
  readonly signal?: AbortSignal;
2084
2263
  }
2085
- interface AwaitMatchOptions {
2086
- readonly timeoutMs?: number;
2087
- readonly pollIntervalMs?: number;
2264
+ declare class ProfilesApi {
2265
+ #private;
2266
+ constructor(api: GameApi);
2267
+ of(playerId: string, options?: ProfileCallOptions): Promise<PlayerProfile | null>;
2268
+ }
2269
+ interface FunctionInvokeOptions {
2088
2270
  readonly signal?: AbortSignal;
2271
+ readonly cueId?: string;
2089
2272
  }
2090
- interface StartedMatch {
2091
- readonly matchId: string;
2092
- readonly status: string;
2273
+ interface FunctionResult {
2274
+ readonly bytes: Uint8Array;
2275
+ readonly invocationId?: string;
2276
+ text(): string;
2277
+ json<T = unknown>(): T;
2093
2278
  }
2094
- interface RoomManager {
2095
- create(options: CreateRoomOptions): Promise<Room>;
2096
- join(roomId: string, options?: JoinRoomOptions): Promise<Room>;
2097
- joinByCode(code: string, options?: JoinRoomOptions): Promise<Room>;
2098
- quickJoin(options: QuickJoinOptions): Promise<Room>;
2099
- queueForMatch(options: QueueForMatchOptions): Promise<MatchTicket>;
2100
- list(options?: ListRoomsOptions): Promise<RoomPage>;
2101
- myRooms(signal?: AbortSignal): Promise<readonly RoomSummary[]>;
2102
- leave(options?: {
2103
- asGroup?: boolean;
2104
- signal?: AbortSignal;
2105
- keepalive?: boolean;
2106
- }): Promise<void>;
2107
- leaveAll(signal?: AbortSignal): Promise<readonly string[]>;
2108
- close(signal?: AbortSignal): Promise<void>;
2109
- refresh(signal?: AbortSignal): Promise<Room | null>;
2110
- setReady(isReady: boolean, signal?: AbortSignal): Promise<Room>;
2111
- kick(playerId: string, signal?: AbortSignal): Promise<Room>;
2112
- transferHost(playerId: string, signal?: AbortSignal): Promise<Room>;
2113
- update(options: UpdateRoomOptions): Promise<Room>;
2114
- startMatch(options?: StartMatchOptions): Promise<StartedMatch>;
2115
- awaitMatch(options?: AwaitMatchOptions): Promise<ReadyMatch>;
2116
- pollMatchStatus(options?: AwaitMatchOptions): Promise<ReadyMatch>;
2117
- notifyMatchConnected(matchId: string): void;
2118
- notifyMatchDisconnected(cause?: string): Promise<void>;
2119
- reconnectToMatch(options?: AwaitMatchOptions): Promise<ReadyMatch>;
2120
- notifyLeavingMatch(options?: {
2121
- keepalive?: boolean;
2122
- }): Promise<void>;
2123
- readonly gameId: string | null;
2124
- readonly currentRoom: Room | null;
2125
- readonly currentTicket: MatchTicket | null;
2126
- readonly partyTicket: PartyTicket | null;
2127
- readonly currentMatch: ReadyMatch | null;
2128
- readonly matchConnectionState: MatchConnectionState;
2129
- readonly matchSession: MatchSession;
2130
- readonly isInRoom: boolean;
2131
- readonly isHost: boolean;
2132
- readonly members: readonly Room["members"][number][];
2133
- readonly playWith: PlayWithOutcome | null;
2134
- on<K extends RoomEventName>(event: K, listener: (...args: RoomEventMap[K]) => void): () => void;
2135
- off<K extends RoomEventName>(event: K, listener: (...args: RoomEventMap[K]) => void): void;
2136
- once<K extends RoomEventName>(event: K, listener: (...args: RoomEventMap[K]) => void): () => void;
2137
- handleRoomEvent(event: RelayedRoomEvent): void;
2138
- handleSeated(roomId: string): void;
2139
- handleAutoStartFailed(roomId: string, code: string): void;
2140
- handleTicketEvent(event: RelayedTicketEvent): void;
2141
- reconcileSeats(): Promise<void>;
2142
- reconcile(hint?: MatchEndHint): Promise<void>;
2143
- startPolling(intervalMs?: number): void;
2144
- stopPolling(): void;
2145
- settled(): Promise<void>;
2146
- dispose(): void;
2279
+ type FunctionFailure = "trap" | "memory_exceeded" | "cpu_budget_exceeded" | "host_call_limit" | "output_too_large" | "argument_too_large";
2280
+ declare class GemFunctionError extends GemApiError {
2281
+ readonly invocationId?: string;
2282
+ readonly functionMessage?: string;
2283
+ readonly failure?: FunctionFailure | (string & {});
2284
+ constructor(source: GemApiError, extra: {
2285
+ readonly invocationId?: string;
2286
+ readonly functionMessage?: string;
2287
+ readonly failure?: string;
2288
+ });
2289
+ get retryable(): boolean;
2147
2290
  }
2148
- declare const PROTOCOL: "gem-web-bridge";
2149
- type GemErrorCode = "version_mismatch" | "handshake_timeout" | "handshake_duplicate" | "invalid_message" | "rate_limited" | "token_unavailable" | "unsupported" | "unsupported_capability" | "internal";
2150
- interface GemToken {
2151
- readonly gem: typeof PROTOCOL;
2152
- readonly type: "gem.token";
2153
- readonly token: string;
2154
- readonly requestId?: string;
2155
- readonly generation: number;
2156
- readonly apiBaseUrl?: string;
2157
- readonly playerId: string;
2158
- readonly gameId: string;
2159
- readonly channel: "dev" | "test" | "release";
2160
- readonly gameVersion?: string;
2161
- readonly expiresAt: number;
2162
- readonly chainEndsAt: number;
2163
- readonly allowDevTools?: boolean;
2291
+ declare class FunctionsApi {
2292
+ #private;
2293
+ constructor(invoke: (body: Uint8Array, options?: {
2294
+ signal?: AbortSignal;
2295
+ cue_id?: string;
2296
+ }) => Promise<BytesResponse>);
2297
+ invoke(input: unknown, options?: FunctionInvokeOptions): Promise<FunctionResult>;
2164
2298
  }
2165
- interface GemTokenDenied {
2166
- readonly gem: typeof PROTOCOL;
2167
- readonly type: "gem.token.denied";
2168
- readonly requestId: string;
2169
- readonly retryable: boolean;
2170
- readonly retryAfterMs?: number;
2171
- readonly reason: "chain_exhausted" | "unavailable";
2172
- readonly correlationId: string;
2299
+ type SessionEndReason = "grant_expiring" | "session_ended" | "navigating" | "kill_switch" | "pagehide";
2300
+ type MatchTransport = "dedicated" | "p2p";
2301
+ 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";
2302
+ declare const PLATFORM_EVENTS: readonly PlatformEventName[];
2303
+ type AnalyticsValue = string | number;
2304
+ interface AnalyticsRejection {
2305
+ readonly index: number;
2306
+ readonly code: string;
2173
2307
  }
2174
- interface GemPause {
2175
- readonly gem: typeof PROTOCOL;
2176
- readonly type: "gem.pause";
2177
- readonly paused: boolean;
2308
+ interface AnalyticsFlushResult {
2309
+ readonly accepted: number;
2310
+ readonly rejected: readonly AnalyticsRejection[];
2311
+ readonly dropped: number;
2312
+ readonly duplicate: boolean;
2178
2313
  }
2179
- interface GemPrefs$1 {
2180
- readonly gem: typeof PROTOCOL;
2181
- readonly type: "gem.prefs";
2182
- readonly reducedMotion: boolean;
2183
- readonly muted: boolean;
2184
- readonly showFrameStats?: boolean;
2185
- readonly music?: boolean;
2186
- readonly sounds?: boolean;
2187
- readonly locale: string;
2188
- readonly recommended?: {
2189
- volume: number;
2190
- batterySaver: boolean;
2191
- keyboardLayout: "wasd" | "arrows";
2192
- gamepadConfirm: "south" | "east";
2193
- vibration: boolean;
2194
- lookSensitivity?: number;
2195
- gamepadLookSensitivity?: number;
2196
- invertLookY?: boolean;
2197
- touchMovement?: string;
2198
- graphicsQuality?: string;
2199
- graphicsQualityAuto?: boolean;
2200
- colorHelp?: boolean;
2201
- textScale?: number;
2202
- };
2314
+ interface AnalyticsFlushOptions {
2315
+ readonly keepalive?: boolean;
2316
+ readonly signal?: AbortSignal;
2203
2317
  }
2204
- interface GemCohorts$1 {
2205
- readonly gem: typeof PROTOCOL;
2206
- readonly type: "gem.cohorts";
2207
- readonly cohorts: {
2208
- experimentId: string;
2209
- variantKey: string;
2210
- }[];
2318
+ interface AnalyticsOptions {
2319
+ readonly enabled?: boolean;
2320
+ readonly flushIntervalMs?: number;
2321
+ readonly maxQueue?: number;
2211
2322
  }
2212
- interface GemInventoryChanged {
2213
- readonly gem: typeof PROTOCOL;
2214
- readonly type: "gem.inventoryChanged";
2323
+ interface AnalyticsApiOptions {
2324
+ readonly environment?: Readonly<Record<string, string>> | (() => Readonly<Record<string, string>>);
2325
+ readonly client: () => GemClient;
2326
+ readonly clock: Clock;
2327
+ readonly gameId: () => string | null;
2328
+ readonly playerId: () => string | null;
2329
+ readonly awaitPlayerId?: () => Promise<string>;
2330
+ readonly declarations?: () => Promise<readonly {
2331
+ readonly id: string;
2332
+ readonly dimensions?: Readonly<Record<string, unknown>> | null;
2333
+ }[] | null | undefined>;
2334
+ readonly options?: AnalyticsOptions;
2335
+ readonly log?: ((message: string) => void) | null;
2215
2336
  }
2216
- interface GemViewport$1 {
2217
- readonly gem: typeof PROTOCOL;
2218
- readonly type: "gem.viewport";
2219
- readonly insets: {
2220
- top: number;
2221
- right: number;
2222
- bottom: number;
2223
- left: number;
2224
- };
2225
- readonly reserved?: {
2226
- x: number;
2227
- y: number;
2228
- width: number;
2229
- height: number;
2230
- control?: {
2231
- x: number;
2232
- y: number;
2233
- width: number;
2234
- height: number;
2235
- };
2236
- }[];
2337
+ declare class AnalyticsApi {
2338
+ #private;
2339
+ constructor(options: AnalyticsApiOptions);
2340
+ track(name: string, props?: Readonly<Record<string, AnalyticsValue>>): void;
2341
+ setContext(props: Readonly<Record<string, AnalyticsValue>>): void;
2342
+ experiment(key: string, count: number): Promise<number>;
2343
+ experiment<T extends string>(key: string, options: readonly T[]): Promise<T>;
2344
+ get environment(): Readonly<Record<string, string>>;
2345
+ flush(options?: AnalyticsFlushOptions): Promise<AnalyticsFlushResult>;
2346
+ trackPlatform(name: PlatformEventName, props?: Readonly<Record<string, AnalyticsValue>>): void;
2347
+ hold(): void;
2348
+ release(): void;
2349
+ get held(): boolean;
2350
+ startSession(): void;
2351
+ endSession(reason: SessionEndReason): void;
2352
+ setPaused(paused: boolean): void;
2353
+ setHidden(hidden: boolean): void;
2354
+ dispose(): void;
2355
+ get pending(): number;
2237
2356
  }
2238
- interface GemDeviceSettings {
2239
- readonly gem: typeof PROTOCOL;
2240
- readonly type: "gem.deviceSettings";
2241
- readonly settings?: unknown;
2357
+ interface BootMark {
2358
+ readonly name: string;
2359
+ readonly at: number;
2242
2360
  }
2243
- interface GemWillTerminate {
2244
- readonly gem: typeof PROTOCOL;
2245
- readonly type: "gem.willTerminate";
2246
- readonly reason: "grant_expiring" | "session_ended" | "navigating" | "kill_switch";
2247
- readonly graceMs: number;
2361
+ interface BootTimeline {
2362
+ mark(name: string, at?: number): boolean;
2363
+ timeline(): string;
2364
+ readonly marks: readonly BootMark[];
2248
2365
  }
2249
- interface GemRoomEvent {
2250
- readonly gem: typeof PROTOCOL;
2251
- readonly type: "gem.roomEvent";
2252
- readonly event: "updated" | "match_started" | "match_ready" | "match_failed" | "version_stale";
2253
- readonly roomId: string;
2254
- readonly matchId?: string;
2255
- readonly version?: number;
2256
- readonly reason?: string;
2257
- readonly platform?: "universal" | "mobile";
2366
+ interface BootTimelineOptions {
2367
+ readonly now?: () => number;
2258
2368
  }
2259
- interface GemSocketState {
2260
- readonly gem: typeof PROTOCOL;
2261
- readonly type: "gem.socketState";
2262
- readonly connected: boolean;
2263
- readonly reason?: "connecting" | "dropped" | "watchdog" | "terminal";
2369
+ declare function markOnResolve<T>(boot: BootTimeline, name: string, work: Promise<T>, log?: ((message: string) => void) | null): Promise<T>;
2370
+ declare function reportOnResolve(boot: BootTimeline, log?: ((message: string) => void) | null): <T>(work: Promise<T>) => Promise<T>;
2371
+ declare function createBootTimeline(options?: BootTimelineOptions): BootTimeline;
2372
+ type GemGraphicsRoute = "webgpu" | "webgl";
2373
+ interface GemPreferredRoute {
2374
+ readonly route: GemGraphicsRoute;
2375
+ readonly listed: boolean;
2264
2376
  }
2265
- interface GemSeatedEvent {
2266
- readonly gem: typeof PROTOCOL;
2267
- readonly type: "gem.seatedEvent";
2268
- readonly roomId: string;
2377
+ interface GemGraphicsRouteEntry {
2378
+ readonly gpu: string;
2379
+ readonly route?: string;
2380
+ readonly host?: string;
2269
2381
  }
2270
- interface GemAutoStartFailedEvent {
2271
- readonly gem: typeof PROTOCOL;
2272
- readonly type: "gem.autoStartFailedEvent";
2273
- readonly roomId: string;
2274
- readonly code: string;
2382
+ interface PreferredRouteOptions {
2383
+ readonly timeoutMs?: number;
2275
2384
  }
2276
- interface GemTicketEvent {
2277
- readonly gem: typeof PROTOCOL;
2278
- readonly type: "gem.ticketEvent";
2279
- readonly event: "queued" | "matched" | "expired" | "cancelled" | "failed";
2280
- readonly ticketId: string;
2281
- readonly partySize?: number;
2282
- readonly queuedAt?: number;
2283
- readonly expiresAt?: number;
2284
- readonly reason?: string;
2285
- readonly roomId?: string;
2385
+ interface GraphicsApi {
2386
+ preferredRoute(options?: PreferredRouteOptions): Promise<GemPreferredRoute>;
2286
2387
  }
2287
- interface GemSignalEvent {
2288
- readonly gem: typeof PROTOCOL;
2289
- readonly type: "gem.signalEvent";
2290
- readonly event: "hello" | "offer" | "answer" | "ice" | "peerJoined" | "peerLeft" | "migration" | "matchEnded" | "error";
2291
- readonly matchId: string;
2292
- readonly data: unknown;
2388
+ type DevToolsOpener = "game" | "platform";
2389
+ interface GemDevTools {
2390
+ open(): Promise<boolean>;
2391
+ close(): void;
2392
+ readonly isOpen: boolean;
2293
2393
  }
2294
- interface GemRelayDraining {
2295
- readonly gem: typeof PROTOCOL;
2296
- readonly type: "gem.relayDraining";
2297
- readonly matchId: string;
2298
- readonly clusterTargetId: string;
2299
- readonly relayIps: string[];
2300
- readonly drainingSince: string;
2301
- readonly deadline: string;
2394
+ type ClusterTargetLike = string | null | undefined;
2395
+ declare const CLIENT_PLATFORMS: readonly [
2396
+ "universal",
2397
+ "mobile",
2398
+ "web"
2399
+ ];
2400
+ type ClientPlatform = (typeof CLIENT_PLATFORMS)[number];
2401
+ interface ClientVersion {
2402
+ readonly platform?: ClientPlatform;
2403
+ readonly gameVersion: string;
2404
+ readonly engineVersion?: string;
2302
2405
  }
2303
- interface GemDedicatedEvent {
2304
- readonly gem: typeof PROTOCOL;
2305
- readonly type: "gem.dedicatedEvent";
2306
- readonly event: "answer" | "error" | "matchEnded";
2406
+ interface ReadyMatch {
2407
+ readonly status: "ready";
2307
2408
  readonly matchId: string;
2308
- readonly sdp?: string;
2309
- readonly sessionId?: string;
2310
- readonly code?: string;
2311
- readonly message?: string;
2312
- readonly reason?: string;
2409
+ readonly protocol: string;
2410
+ readonly joinCredential?: string;
2411
+ readonly credentialExpiresAt?: number;
2412
+ readonly host?: string;
2413
+ readonly port?: number;
2313
2414
  }
2314
- interface GemPartyResult {
2315
- readonly gem: typeof PROTOCOL;
2316
- readonly type: "gem.partyResult";
2317
- readonly requestId: string;
2318
- readonly partyId?: string;
2415
+ interface StartMatchWaiting {
2416
+ readonly attempt: number;
2417
+ readonly elapsedMs: number;
2418
+ readonly budgetMs: number;
2419
+ readonly nextAttemptInMs: number;
2420
+ readonly status: number;
2421
+ readonly message: string;
2319
2422
  }
2320
- interface GemClusterTarget {
2321
- readonly gem: typeof PROTOCOL;
2322
- readonly type: "gem.clusterTarget";
2323
- readonly clusterTargetId: string;
2324
- readonly clusterTargetIds?: string[];
2423
+ interface StartMatchRetryOptions {
2424
+ readonly budgetMs?: number;
2425
+ readonly initialDelayMs?: number;
2426
+ readonly maxDelayMs?: number;
2427
+ readonly onWaiting?: (waiting: StartMatchWaiting) => void;
2325
2428
  }
2326
- interface GemGraphicsRoutes {
2327
- readonly gem: typeof PROTOCOL;
2328
- readonly type: "gem.graphicsRoutes";
2329
- readonly entries: {
2330
- gpu: string;
2331
- route?: string;
2332
- host?: string;
2333
- }[];
2429
+ interface ClusterTarget {
2430
+ readonly id: string;
2431
+ readonly pressure: string;
2334
2432
  }
2335
- interface GemScreenshotDenied {
2336
- readonly gem: typeof PROTOCOL;
2337
- readonly type: "gem.screenshot.denied";
2338
- readonly reason: "not_wired" | "no_source" | "unsupported" | "unreadable" | "tainted" | "too_large" | "busy" | "declined" | "failed";
2433
+ type DedicatedServerFailure = "timeout" | "aborted" | "allocation_failed" | "no_server_ready" | "start_rate_limited" | "p2p_unavailable" | "unsupported_protocol" | "credential_expired" | "credential_reused" | "join_rate_limited" | "signaling_unavailable" | "signaling_failed" | "offer_refused" | "invalid_sdp" | "media_refused" | "connection_failed" | "join_refused" | "match_ended" | "misconfigured";
2434
+ declare class DedicatedServerError extends Error {
2435
+ readonly reason: DedicatedServerFailure;
2339
2436
  readonly retryable: boolean;
2437
+ readonly platformCode: string | undefined;
2438
+ constructor(reason: DedicatedServerFailure, message: string, options?: {
2439
+ cause?: unknown;
2440
+ platformCode?: string;
2441
+ });
2340
2442
  }
2341
- interface GemDedicatedOffer {
2342
- readonly gem: typeof PROTOCOL;
2343
- readonly type: "gem.dedicatedOffer";
2443
+ type SignalingIntent = "initial" | "ice_restart" | "full_reconnect";
2444
+ interface OfferRequest {
2344
2445
  readonly matchId: string;
2345
2446
  readonly sdp: string;
2346
- readonly intent: "initial" | "ice_restart" | "full_reconnect";
2447
+ readonly intent: SignalingIntent;
2347
2448
  }
2348
- interface GemLocalServer {
2349
- readonly gem: typeof PROTOCOL;
2350
- readonly type: "gem.localServer";
2351
- readonly requestId: string;
2352
- readonly serverId?: string;
2449
+ interface SignalingAnswer {
2450
+ readonly sdp: string;
2353
2451
  }
2354
- interface GemLocalServerDenied {
2355
- readonly gem: typeof PROTOCOL;
2356
- readonly type: "gem.localServer.denied";
2357
- readonly requestId: string;
2358
- readonly retryable: boolean;
2359
- readonly reason: "refused" | "unavailable";
2452
+ interface SignalingChannel {
2453
+ exchange(request: OfferRequest, signal?: AbortSignal): Promise<SignalingAnswer>;
2454
+ close(): void;
2360
2455
  }
2361
- interface GemMenuSelect {
2362
- readonly gem: typeof PROTOCOL;
2363
- readonly type: "gem.menuSelect";
2364
- readonly entry: "settings" | "item";
2365
- readonly id?: string;
2456
+ type SdpType$1 = "offer" | "answer" | "pranswer" | "rollback";
2457
+ interface SessionDescriptionLike$1 {
2458
+ readonly type: SdpType$1;
2459
+ readonly sdp?: string;
2366
2460
  }
2367
- interface GemSettingsDeclare {
2368
- readonly gem: typeof PROTOCOL;
2369
- readonly type: "gem.settingsDeclare";
2370
- readonly settings: {
2371
- id: string;
2372
- label: string;
2373
- kind: "toggle" | "slider" | "choice";
2374
- value: boolean | number | string;
2375
- quick?: boolean;
2376
- icon?: string;
2377
- min?: number;
2378
- max?: number;
2379
- step?: number;
2380
- options?: {
2381
- id: string;
2382
- label: string;
2383
- }[];
2384
- }[];
2461
+ interface DataChannelInitLike$1 {
2462
+ readonly ordered?: boolean;
2463
+ readonly maxRetransmits?: number;
2464
+ }
2465
+ interface EventTargetLike$1 {
2466
+ addEventListener(type: string, listener: (event: unknown) => void): void;
2467
+ removeEventListener(type: string, listener: (event: unknown) => void): void;
2468
+ }
2469
+ interface DataChannelLike$1 extends EventTargetLike$1 {
2470
+ readonly readyState: string;
2471
+ send(data: string | Uint8Array): void;
2472
+ close(): void;
2473
+ }
2474
+ interface PeerConnectionLike$1 extends EventTargetLike$1 {
2475
+ readonly localDescription: SessionDescriptionLike$1 | null;
2476
+ readonly iceGatheringState: string;
2477
+ createDataChannel(label: string, init?: DataChannelInitLike$1): DataChannelLike$1;
2478
+ createOffer(): Promise<SessionDescriptionLike$1>;
2479
+ setLocalDescription(description: SessionDescriptionLike$1): Promise<void>;
2480
+ setRemoteDescription(description: SessionDescriptionLike$1): Promise<void>;
2481
+ close(): void;
2482
+ }
2483
+ interface JoinWelcome {
2484
+ readonly playerId?: string;
2485
+ readonly matchId?: string;
2486
+ readonly heartbeatIntervalMs?: number;
2487
+ }
2488
+ interface JoinExchange {
2489
+ readonly welcome: JoinWelcome;
2490
+ detach(): void;
2491
+ }
2492
+ interface PresentCredentialOptions {
2493
+ readonly channel: DataChannelLike$1;
2494
+ readonly credential: string;
2495
+ readonly credentialExpiresAt: number;
2496
+ readonly clock: Clock;
2497
+ readonly ceilingMs?: number;
2498
+ readonly wire?: number;
2499
+ readonly heartbeat?: boolean;
2500
+ readonly onMessage?: (data: unknown) => void;
2501
+ readonly signal?: AbortSignal;
2502
+ }
2503
+ declare function presentJoinCredential(options: PresentCredentialOptions): Promise<JoinExchange>;
2504
+ type TransportKind = "webtransport" | "webrtc" | "websocket";
2505
+ declare const UNRELIABLE_CHANNEL_LABEL = "gem-uu";
2506
+ interface SendOptions$1 {
2507
+ readonly reliable?: boolean;
2508
+ readonly ordered?: boolean;
2385
2509
  }
2386
- interface GemSettingChange {
2387
- readonly gem: typeof PROTOCOL;
2388
- readonly type: "gem.settingChange";
2389
- readonly id: string;
2390
- readonly value: boolean | number | string;
2510
+ interface MessageMeta {
2511
+ readonly reliable: boolean;
2512
+ readonly ordered: boolean;
2391
2513
  }
2392
- interface GemShareResult {
2393
- readonly gem: typeof PROTOCOL;
2394
- readonly type: "gem.shareResult";
2395
- readonly requestId: string;
2396
- readonly outcome: "accepted" | "refused";
2397
- readonly reason?: string;
2398
- readonly key?: string;
2514
+ interface GameServerLink {
2515
+ readonly transport: TransportKind;
2516
+ send(data: Uint8Array | string, options?: SendOptions$1): void;
2517
+ onMessage(handler: (data: Uint8Array | string, meta: MessageMeta) => void): void;
2518
+ onClose(handler: (reason?: string) => void): void;
2519
+ close(): void;
2399
2520
  }
2400
- interface GemPurchaseResult {
2401
- readonly gem: typeof PROTOCOL;
2402
- readonly type: "gem.purchaseResult";
2403
- readonly requestId: string;
2404
- readonly outcome: "ok" | "declined" | "unavailable";
2521
+ interface TransportAdvert {
2522
+ readonly v: number;
2523
+ readonly host: string;
2524
+ readonly port: number;
2525
+ readonly match_id: string;
2526
+ readonly webrtc?: boolean;
2527
+ readonly webtransport?: {
2528
+ readonly url: string;
2529
+ readonly cert_sha256_b64: string;
2530
+ readonly expires_at?: number;
2531
+ readonly named_url?: string;
2532
+ };
2533
+ readonly websocket?: {
2534
+ readonly url: string;
2535
+ readonly tls?: boolean;
2536
+ };
2537
+ }
2538
+ declare function readTemplateTransports(value: unknown): readonly TransportKind[] | null;
2539
+ declare function readTransportAdvert(settings: unknown, forMatch?: string): TransportAdvert | null;
2540
+ declare function webTransportAvailable(): boolean;
2541
+ type RoomArgScalar = string | number | boolean;
2542
+ type RoomArgValue$1 = RoomArgScalar | readonly RoomArgScalar[];
2543
+ type RoomArgs = Readonly<Record<string, RoomArgValue$1>>;
2544
+ type RoomArgType = "string" | "int" | "float" | "bool" | (string & {});
2545
+ interface RoomArgEntry {
2546
+ readonly name: string;
2547
+ readonly type: RoomArgType;
2548
+ readonly list: boolean;
2549
+ readonly required: boolean;
2550
+ readonly mutable: boolean;
2551
+ readonly fixed?: RoomArgValue$1;
2552
+ readonly default?: RoomArgValue$1;
2553
+ readonly description?: string;
2554
+ readonly allowed?: readonly RoomArgScalar[];
2555
+ readonly min?: number;
2556
+ readonly max?: number;
2557
+ readonly minItems?: number;
2558
+ readonly maxItems?: number;
2559
+ readonly maxLength?: number;
2560
+ }
2561
+ type RoomStatus = "open" | "in_game" | "closed" | (string & {});
2562
+ type PlayWithOutcome = "joined" | "unavailable";
2563
+ type MatchConnectionState = "disconnected" | "connecting" | "connected" | "suspended";
2564
+ type MatchSessionPhase = "none" | "starting" | "ready" | "connected" | "suspended" | "ended" | (string & {});
2565
+ interface MatchSession {
2566
+ readonly phase: MatchSessionPhase;
2567
+ readonly matchId?: string;
2405
2568
  readonly reason?: string;
2406
- readonly purchaseId?: string;
2569
+ readonly roomReopened?: boolean;
2407
2570
  }
2408
- interface GemPurchaseSettled {
2409
- readonly gem: typeof PROTOCOL;
2410
- readonly type: "gem.purchaseSettled";
2411
- readonly purchaseKind: "item" | "recipe";
2412
- readonly targetId: string;
2413
- readonly catalogId?: string;
2414
- readonly quantity: number;
2415
- readonly purchaseId?: string;
2571
+ interface MatchEnded {
2572
+ readonly matchId: string;
2573
+ readonly reason: string;
2574
+ readonly roomReopened: boolean;
2416
2575
  }
2417
- interface GemDeviceSettingsResult {
2418
- readonly gem: typeof PROTOCOL;
2419
- readonly type: "gem.deviceSettings.result";
2420
- readonly requestId: string;
2421
- readonly outcome: "stored" | "too_large" | "unavailable";
2576
+ interface MatchSuspended {
2577
+ readonly matchId: string;
2578
+ readonly cause: string;
2422
2579
  }
2423
- interface GemAdResult {
2424
- readonly gem: typeof PROTOCOL;
2425
- readonly type: "gem.adResult";
2426
- readonly requestId: string;
2427
- readonly outcome: "shown" | "no_ad" | "unavailable";
2580
+ interface MatchReconnecting {
2581
+ readonly matchId: string;
2582
+ readonly attempt: number;
2583
+ readonly attempts: number;
2584
+ readonly remainingMs: number;
2428
2585
  }
2429
- interface GemMomentResult {
2430
- readonly gem: typeof PROTOCOL;
2431
- readonly type: "gem.momentResult";
2432
- readonly requestId: string;
2433
- readonly shown: boolean;
2586
+ interface MatchReconnected {
2587
+ readonly matchId: string;
2588
+ readonly attempt: number;
2434
2589
  }
2435
- interface GemSignInResult {
2436
- readonly gem: typeof PROTOCOL;
2437
- readonly type: "gem.signInResult";
2438
- readonly requestId: string;
2439
- readonly outcome: "signed_in" | "declined" | "unavailable";
2590
+ interface AutoReconnectOptions {
2591
+ readonly budgetMs?: number;
2592
+ readonly attempts?: number;
2593
+ readonly maxDelayMs?: number;
2440
2594
  }
2441
- interface GemFriendChallengeResult {
2442
- readonly gem: typeof PROTOCOL;
2443
- readonly type: "gem.friendChallengeResult";
2444
- readonly requestId: string;
2445
- readonly outcome: "accepted" | "cancelled" | "refused" | "unavailable" | "rate_limited" | "invalid";
2446
- readonly code?: string;
2447
- readonly param?: string;
2448
- readonly channel?: string;
2449
- readonly configVersion?: number;
2450
- readonly retryAfterMs?: number;
2451
- readonly detail?: string;
2595
+ interface RoomMember extends PlayerIdentity {
2596
+ readonly playerId: string;
2597
+ readonly isReady: boolean;
2598
+ readonly role: string;
2599
+ readonly joinedAt: number;
2600
+ readonly groupId?: string;
2601
+ readonly platform?: string;
2452
2602
  }
2453
- interface GemRequestPlayInvite {
2454
- readonly gem: typeof PROTOCOL;
2455
- readonly type: "gem.requestPlayInvite";
2456
- readonly requestId: string;
2457
- readonly params?: {
2458
- key: string;
2459
- value: string;
2460
- }[];
2603
+ interface Room {
2604
+ readonly id: string;
2605
+ readonly gameId: string;
2606
+ readonly name: string;
2607
+ readonly status: RoomStatus;
2608
+ readonly hostPlayerId: string;
2609
+ readonly maxPlayers: number;
2610
+ readonly memberCount: number;
2611
+ readonly members: readonly RoomMember[];
2612
+ readonly isPublic: boolean;
2613
+ readonly joinCode?: string;
2614
+ readonly settings?: unknown;
2615
+ readonly roomArgs?: RoomArgs;
2616
+ readonly roomArgsTemplate?: readonly RoomArgEntry[];
2617
+ readonly gameChannel: string;
2618
+ readonly region?: string;
2619
+ readonly clusterTargetId?: string;
2620
+ readonly selfHosted: boolean;
2621
+ readonly matchId?: string;
2622
+ readonly version: number;
2623
+ readonly templateId?: string;
2624
+ readonly templateSlug?: string;
2625
+ readonly roomType: string;
2626
+ readonly transports?: readonly TransportKind[];
2627
+ readonly createdAt: number;
2628
+ readonly updatedAt: number;
2629
+ readonly startedAt?: number;
2461
2630
  }
2462
- interface GemPlayInviteResult {
2463
- readonly gem: typeof PROTOCOL;
2464
- readonly type: "gem.playInviteResult";
2465
- readonly requestId: string;
2466
- readonly shown: boolean;
2631
+ interface MatchAutoStartFailed {
2632
+ readonly roomId: string;
2633
+ readonly code: string;
2634
+ readonly handled: boolean;
2467
2635
  }
2468
- interface GemInviteParams {
2469
- readonly gem: typeof PROTOCOL;
2470
- readonly type: "gem.inviteParams";
2471
- readonly params?: {
2472
- key: string;
2473
- value: string;
2474
- }[];
2636
+ interface RoomSummary {
2637
+ readonly id: string;
2638
+ readonly gameId: string;
2639
+ readonly name: string;
2640
+ readonly status: RoomStatus;
2641
+ readonly hostPlayerId: string;
2642
+ readonly maxPlayers: number;
2643
+ readonly memberCount: number;
2644
+ readonly isPublic: boolean;
2645
+ readonly gameChannel: string;
2646
+ readonly roomType: string;
2647
+ readonly createdAt: number;
2475
2648
  }
2476
- interface GemRequestAppLinks {
2477
- readonly gem: typeof PROTOCOL;
2478
- readonly type: "gem.requestAppLinks";
2479
- readonly requestId: string;
2649
+ interface RoomPage {
2650
+ readonly rooms: readonly RoomSummary[];
2651
+ readonly nextCursor?: string;
2480
2652
  }
2481
- interface GemAppLinksResult {
2482
- readonly gem: typeof PROTOCOL;
2483
- readonly type: "gem.appLinksResult";
2484
- readonly requestId: string;
2485
- readonly outcome: "ok" | "declined" | "unavailable";
2486
- readonly reason?: string;
2487
- readonly arcade?: {
2488
- store: "app_store" | "google_play";
2489
- };
2490
- readonly game?: {
2491
- store: "app_store" | "google_play";
2492
- };
2653
+ interface RoomOperationError {
2654
+ readonly operation: string;
2655
+ readonly code: number;
2656
+ readonly reason: string;
2657
+ readonly message: string;
2658
+ readonly retryable: boolean;
2493
2659
  }
2494
- interface GemRequestOpenApp {
2495
- readonly gem: typeof PROTOCOL;
2496
- readonly type: "gem.requestOpenApp";
2497
- readonly requestId: string;
2498
- readonly target: "arcade" | "game";
2660
+ interface QueueForMatchOptions {
2661
+ readonly templateSlugs: readonly string[];
2662
+ readonly partyId?: string;
2663
+ readonly signal?: AbortSignal;
2664
+ }
2665
+ type MatchTicketStatus = "queued" | "matched" | "expired" | "cancelled" | "failed" | "lost" | "unavailable";
2666
+ type MatchTicketOutcome = {
2667
+ readonly status: "matched";
2668
+ readonly room: Room;
2669
+ } | {
2670
+ readonly status: "expired";
2671
+ readonly reason: string;
2672
+ } | {
2673
+ readonly status: "cancelled";
2674
+ readonly reason: string;
2675
+ } | {
2676
+ readonly status: "failed";
2677
+ readonly reason: string;
2678
+ } | {
2679
+ readonly status: "lost";
2680
+ } | {
2681
+ readonly status: "unavailable";
2682
+ };
2683
+ interface MatchTicket {
2684
+ readonly id: string;
2685
+ readonly status: MatchTicketStatus;
2686
+ readonly partySize: number;
2687
+ readonly queuedAt: number;
2688
+ readonly expiresAt: number;
2689
+ readonly outcome: Promise<MatchTicketOutcome>;
2690
+ cancel(): Promise<MatchTicketOutcome>;
2499
2691
  }
2500
- interface GemOpenAppResult {
2501
- readonly gem: typeof PROTOCOL;
2502
- readonly type: "gem.openAppResult";
2503
- readonly requestId: string;
2504
- readonly outcome: "ok" | "declined" | "unavailable";
2505
- readonly reason?: string;
2692
+ interface CreateRoomOptions {
2693
+ readonly name: string;
2694
+ readonly maxPlayers?: number;
2695
+ readonly isPublic?: boolean;
2696
+ readonly settings?: unknown;
2697
+ readonly region?: string;
2698
+ readonly templateId?: string;
2699
+ readonly templateSlug?: string;
2700
+ readonly partyId?: string;
2701
+ readonly roomArgs?: RoomArgs;
2702
+ readonly signal?: AbortSignal;
2506
2703
  }
2507
- interface GemRequestOpenGame {
2508
- readonly gem: typeof PROTOCOL;
2509
- readonly type: "gem.requestOpenGame";
2510
- readonly requestId: string;
2511
- readonly ref: string;
2704
+ interface JoinRoomOptions {
2705
+ readonly partyId?: string;
2706
+ readonly signal?: AbortSignal;
2512
2707
  }
2513
- interface GemOpenGameResult {
2514
- readonly gem: typeof PROTOCOL;
2515
- readonly type: "gem.openGameResult";
2516
- readonly requestId: string;
2517
- readonly outcome: "ok" | "declined" | "unavailable";
2518
- readonly reason?: string;
2708
+ interface QuickJoinOptions extends JoinRoomOptions {
2709
+ readonly templateSlug?: string;
2710
+ readonly templateSlugs?: readonly string[];
2711
+ readonly templateId?: string;
2712
+ readonly region?: string;
2713
+ readonly name?: string;
2519
2714
  }
2520
- interface GemRequestSimilarGames {
2521
- readonly gem: typeof PROTOCOL;
2522
- readonly type: "gem.requestSimilarGames";
2523
- readonly requestId: string;
2715
+ interface ListRoomsOptions {
2716
+ readonly status?: "open" | "in_game";
2717
+ readonly templateSlug?: string;
2524
2718
  readonly limit?: number;
2719
+ readonly cursor?: string;
2720
+ readonly signal?: AbortSignal;
2525
2721
  }
2526
- interface GemSimilarGamesResult {
2527
- readonly gem: typeof PROTOCOL;
2528
- readonly type: "gem.similarGamesResult";
2529
- readonly requestId: string;
2530
- readonly outcome: "ok" | "declined" | "unavailable";
2531
- readonly reason?: string;
2532
- readonly games: {
2533
- gameId: string;
2534
- slug?: string;
2535
- iconUrl: string;
2536
- capsuleLandscapeUrl: string;
2537
- capsulePortraitUrl: string;
2538
- previewVideoUrl?: string;
2539
- previewPosterUrl?: string;
2540
- untrusted: {
2541
- name: string;
2542
- tagline: string;
2543
- shortDescription: string;
2544
- tags: string[];
2545
- };
2546
- }[];
2722
+ interface UpdateRoomOptions {
2723
+ readonly name?: string;
2724
+ readonly maxPlayers?: number;
2725
+ readonly isPublic?: boolean;
2726
+ readonly settings?: unknown;
2727
+ readonly roomArgs?: RoomArgs;
2728
+ readonly signal?: AbortSignal;
2547
2729
  }
2548
- interface GemRequestStoreOffers {
2549
- readonly gem: typeof PROTOCOL;
2550
- readonly type: "gem.requestStoreOffers";
2551
- readonly requestId: string;
2730
+ type PartyTicketStatus = "queued" | "matched" | "expired" | "cancelled" | "failed" | "lost";
2731
+ type PartyTicketOutcome = {
2732
+ readonly status: "matched";
2733
+ } | {
2734
+ readonly status: "expired";
2735
+ readonly reason: string;
2736
+ } | {
2737
+ readonly status: "cancelled";
2738
+ readonly reason: string;
2739
+ } | {
2740
+ readonly status: "failed";
2741
+ readonly reason: string;
2742
+ } | {
2743
+ readonly status: "lost";
2744
+ };
2745
+ interface PartyTicket {
2746
+ readonly id: string;
2747
+ readonly status: PartyTicketStatus;
2748
+ readonly partySize: number;
2749
+ readonly queuedAt: number;
2750
+ readonly expiresAt: number;
2751
+ readonly outcome: Promise<PartyTicketOutcome>;
2552
2752
  }
2553
- interface GemStoreOffersResult {
2554
- readonly gem: typeof PROTOCOL;
2555
- readonly type: "gem.storeOffersResult";
2556
- readonly requestId: string;
2557
- readonly outcome: "ok" | "declined" | "unavailable";
2753
+ interface RelayedTicketEvent {
2754
+ readonly event: "queued" | "matched" | "expired" | "cancelled" | "failed";
2755
+ readonly ticketId: string;
2756
+ readonly partySize?: number;
2757
+ readonly queuedAt?: number;
2758
+ readonly expiresAt?: number;
2558
2759
  readonly reason?: string;
2559
- readonly offers: {
2560
- skuId: string;
2561
- kind: "gem_pack" | "boost" | "pass" | "bundle";
2562
- name: string;
2563
- description: string;
2564
- imageUrl?: string;
2565
- priceDisplay: string;
2566
- grant?: {
2567
- currency: string;
2568
- amount: number;
2569
- };
2570
- }[];
2760
+ readonly roomId?: string;
2571
2761
  }
2572
- interface GemRequestStorePurchase {
2573
- readonly gem: typeof PROTOCOL;
2574
- readonly type: "gem.requestStorePurchase";
2575
- readonly requestId: string;
2576
- readonly skuId: string;
2762
+ interface RoomEventMap {
2763
+ created: [
2764
+ Room
2765
+ ];
2766
+ joined: [
2767
+ Room
2768
+ ];
2769
+ left: [
2770
+ ];
2771
+ closed: [
2772
+ ];
2773
+ updated: [
2774
+ Room
2775
+ ];
2776
+ seated: [
2777
+ Room
2778
+ ];
2779
+ partyQueued: [
2780
+ PartyTicket
2781
+ ];
2782
+ listed: [
2783
+ RoomPage
2784
+ ];
2785
+ mineListed: [
2786
+ readonly RoomSummary[]
2787
+ ];
2788
+ memberJoined: [
2789
+ string
2790
+ ];
2791
+ memberLeft: [
2792
+ string
2793
+ ];
2794
+ kicked: [
2795
+ ];
2796
+ readyChanged: [
2797
+ string,
2798
+ boolean
2799
+ ];
2800
+ hostChanged: [
2801
+ string
2802
+ ];
2803
+ matchStartWaiting: [
2804
+ StartMatchWaiting
2805
+ ];
2806
+ matchAutoStartFailed: [
2807
+ MatchAutoStartFailed
2808
+ ];
2809
+ matchAllocationStarted: [
2810
+ string
2811
+ ];
2812
+ matchReady: [
2813
+ ReadyMatch
2814
+ ];
2815
+ matchFailed: [
2816
+ string,
2817
+ string
2818
+ ];
2819
+ matchEnded: [
2820
+ MatchEnded
2821
+ ];
2822
+ matchSuspended: [
2823
+ MatchSuspended
2824
+ ];
2825
+ matchReconnecting: [
2826
+ MatchReconnecting
2827
+ ];
2828
+ matchReconnected: [
2829
+ MatchReconnected
2830
+ ];
2831
+ versionUpdateAvailable: [
2832
+ ClientPlatform | undefined
2833
+ ];
2834
+ error: [
2835
+ RoomOperationError
2836
+ ];
2577
2837
  }
2578
- interface GemStorePurchaseResult {
2579
- readonly gem: typeof PROTOCOL;
2580
- readonly type: "gem.storePurchaseResult";
2581
- readonly requestId: string;
2582
- readonly outcome: "ok" | "declined" | "unavailable";
2838
+ type RoomEventName = keyof RoomEventMap;
2839
+ interface MatchEndHint {
2840
+ readonly matchId?: string;
2583
2841
  readonly reason?: string;
2584
2842
  }
2585
- interface GemStorePurchaseSettled {
2586
- readonly gem: typeof PROTOCOL;
2587
- readonly type: "gem.storePurchaseSettled";
2588
- readonly skuId: string;
2843
+ interface RelayedRoomEvent {
2844
+ readonly event: "updated" | "match_started" | "match_ready" | "match_failed" | "version_stale";
2845
+ readonly roomId: string;
2846
+ readonly matchId?: string;
2847
+ readonly version?: number;
2848
+ readonly reason?: string;
2849
+ readonly platform?: ClientPlatform;
2589
2850
  }
2590
- interface GemRequestStoreOfferSheet {
2591
- readonly gem: typeof PROTOCOL;
2592
- readonly type: "gem.requestStoreOfferSheet";
2593
- readonly requestId: string;
2594
- readonly skuId: string;
2851
+ interface StartMatchOptions {
2852
+ readonly clusterTargetId?: ClusterTargetLike;
2853
+ readonly retry?: StartMatchRetryOptions;
2854
+ readonly signal?: AbortSignal;
2595
2855
  }
2596
- interface GemStoreOfferSheetResult {
2597
- readonly gem: typeof PROTOCOL;
2598
- readonly type: "gem.storeOfferSheetResult";
2599
- readonly requestId: string;
2600
- readonly outcome: "ok" | "declined" | "unavailable";
2601
- readonly reason?: string;
2856
+ interface AwaitMatchOptions {
2857
+ readonly timeoutMs?: number;
2858
+ readonly pollIntervalMs?: number;
2859
+ readonly signal?: AbortSignal;
2860
+ }
2861
+ interface StartedMatch {
2862
+ readonly matchId: string;
2863
+ readonly status: string;
2864
+ }
2865
+ interface RoomManager {
2866
+ create(options: CreateRoomOptions): Promise<Room>;
2867
+ join(roomId: string, options?: JoinRoomOptions): Promise<Room>;
2868
+ joinByCode(code: string, options?: JoinRoomOptions): Promise<Room>;
2869
+ quickJoin(options: QuickJoinOptions): Promise<Room>;
2870
+ queueForMatch(options: QueueForMatchOptions): Promise<MatchTicket>;
2871
+ list(options?: ListRoomsOptions): Promise<RoomPage>;
2872
+ myRooms(signal?: AbortSignal): Promise<readonly RoomSummary[]>;
2873
+ leave(options?: {
2874
+ asGroup?: boolean;
2875
+ signal?: AbortSignal;
2876
+ keepalive?: boolean;
2877
+ }): Promise<void>;
2878
+ leaveAll(signal?: AbortSignal): Promise<readonly string[]>;
2879
+ close(signal?: AbortSignal): Promise<void>;
2880
+ refresh(signal?: AbortSignal): Promise<Room | null>;
2881
+ setReady(isReady: boolean, signal?: AbortSignal): Promise<Room>;
2882
+ kick(playerId: string, signal?: AbortSignal): Promise<Room>;
2883
+ transferHost(playerId: string, signal?: AbortSignal): Promise<Room>;
2884
+ update(options: UpdateRoomOptions): Promise<Room>;
2885
+ startMatch(options?: StartMatchOptions): Promise<StartedMatch>;
2886
+ awaitMatch(options?: AwaitMatchOptions): Promise<ReadyMatch>;
2887
+ pollMatchStatus(options?: AwaitMatchOptions): Promise<ReadyMatch>;
2888
+ notifyMatchConnected(matchId: string): void;
2889
+ notifyMatchDisconnected(cause?: string): Promise<void>;
2890
+ reconnectToMatch(options?: AwaitMatchOptions): Promise<ReadyMatch>;
2891
+ notifyLeavingMatch(options?: {
2892
+ keepalive?: boolean;
2893
+ }): Promise<void>;
2894
+ readonly gameId: string | null;
2895
+ readonly currentRoom: Room | null;
2896
+ readonly currentTicket: MatchTicket | null;
2897
+ readonly partyTicket: PartyTicket | null;
2898
+ readonly currentMatch: ReadyMatch | null;
2899
+ readonly matchConnectionState: MatchConnectionState;
2900
+ readonly matchSession: MatchSession;
2901
+ readonly isInRoom: boolean;
2902
+ readonly isHost: boolean;
2903
+ readonly members: readonly Room["members"][number][];
2904
+ readonly playWith: PlayWithOutcome | null;
2905
+ on<K extends RoomEventName>(event: K, listener: (...args: RoomEventMap[K]) => void): () => void;
2906
+ off<K extends RoomEventName>(event: K, listener: (...args: RoomEventMap[K]) => void): void;
2907
+ once<K extends RoomEventName>(event: K, listener: (...args: RoomEventMap[K]) => void): () => void;
2908
+ handleRoomEvent(event: RelayedRoomEvent): void;
2909
+ handleSeated(roomId: string): void;
2910
+ handleAutoStartFailed(roomId: string, code: string): void;
2911
+ handleTicketEvent(event: RelayedTicketEvent): void;
2912
+ reconcileSeats(): Promise<void>;
2913
+ reconcile(hint?: MatchEndHint): Promise<void>;
2914
+ startPolling(intervalMs?: number): void;
2915
+ stopPolling(): void;
2916
+ settled(): Promise<void>;
2917
+ dispose(): void;
2602
2918
  }
2603
2919
  interface ConnectOptions {
2604
2920
  readonly clusterTargetId?: ClusterTargetLike;
@@ -3017,9 +3333,15 @@ interface GemServerHost extends ServerBundleHost {
3017
3333
  broadcast(data: string | Uint8Array, options?: BroadcastOptions): void;
3018
3334
  kick(playerId: string, reason?: string): void;
3019
3335
  endMatch?(): Promise<"ok" | "already_ended" | "refused" | "failed" | (string & {})>;
3336
+ passes?(playerId: string): Promise<GemServerHostRead>;
3337
+ boost?(playerId: string): Promise<GemServerHostRead>;
3020
3338
  log(message: string): void;
3021
3339
  warn(message: string): void;
3022
3340
  }
3341
+ interface GemServerHostRead {
3342
+ readonly status: number;
3343
+ readonly body: unknown;
3344
+ }
3023
3345
  interface GemServerBundle {
3024
3346
  init?(): void | Promise<void>;
3025
3347
  join?(playerId: string, meta?: {
@@ -3159,177 +3481,6 @@ interface AccountApi {
3159
3481
  onSignInAvailableChange(listener: (available: boolean) => void): () => void;
3160
3482
  requestSignIn(): Promise<SignInOutcome>;
3161
3483
  }
3162
- interface PlayerBoostMultiplier {
3163
- readonly currencyId: string;
3164
- readonly currencySlug: string;
3165
- readonly multiplier: number;
3166
- }
3167
- interface PlayerBoost {
3168
- readonly active: boolean;
3169
- readonly multipliers: readonly PlayerBoostMultiplier[];
3170
- readonly expiresInDays?: number;
3171
- }
3172
- interface RewardCue {
3173
- currencySlug: string;
3174
- cueId?: string;
3175
- expected?: number;
3176
- origin?: {
3177
- x: number;
3178
- y: number;
3179
- };
3180
- }
3181
- type GemCorner = "top-left" | "top-right" | "bottom-left" | "bottom-right";
3182
- type RewardPresentation = "arcade" | "game";
3183
- interface MenuStyle {
3184
- readonly ground: string;
3185
- readonly accent: string;
3186
- }
3187
- type FrameState = "waiting" | "connected" | "refused" | "closed";
3188
- interface FramePlayer extends PlayerIdentity {
3189
- readonly displayName: PlayerText;
3190
- readonly displayHandle: PlayerText;
3191
- readonly avatarUrl?: string;
3192
- readonly boost: PlayerBoost;
3193
- }
3194
- type GemArcadeAsk = Omit<GemRequestAppLinks, "gem"> | Omit<GemRequestOpenApp, "gem"> | Omit<GemRequestOpenGame, "gem"> | Omit<GemRequestSimilarGames, "gem"> | Omit<GemRequestStoreOffers, "gem"> | Omit<GemRequestStorePurchase, "gem"> | Omit<GemRequestStoreOfferSheet, "gem">;
3195
- type GemFriendsWindowAsk = Omit<GemRequestPlayInvite, "gem"> | Omit<GemInviteParams, "gem">;
3196
- type GemArcadeAnswer = GemAppLinksResult | GemOpenAppResult | GemOpenGameResult | GemSimilarGamesResult | GemStoreOffersResult | GemStorePurchaseResult | GemStorePurchaseSettled | GemStoreOfferSheetResult;
3197
- interface FrameCallbacks {
3198
- onToken?(msg: GemToken): void;
3199
- onPause?(msg: GemPause): void;
3200
- onMenuSelect?(msg: GemMenuSelect): void;
3201
- onSettingChange?(msg: GemSettingChange): void;
3202
- onPrefs?(msg: GemPrefs$1): void;
3203
- onCohorts?(msg: GemCohorts$1): void;
3204
- onEarnAllowanceChanged?(): void;
3205
- onInventoryChanged?(msg: GemInventoryChanged): void;
3206
- onViewport?(msg: GemViewport$1): void;
3207
- onWillTerminate?(msg: GemWillTerminate): void;
3208
- onDevtools?(action: "open" | "close" | "toggle"): void;
3209
- onScreenshot?(request: {
3210
- maxWidth: number;
3211
- maxHeight: number;
3212
- }, port: MessagePort, deny: (reason: GemScreenshotDenied["reason"], retryable: boolean) => void): void;
3213
- onRequestContext?(): void;
3214
- onTokenDenied?(msg: GemTokenDenied): void;
3215
- onLocalServer?(msg: GemLocalServer): void;
3216
- onLocalServerDenied?(msg: GemLocalServerDenied): void;
3217
- onPlayer?(player: FramePlayer, signInAvailable?: boolean): void;
3218
- onRoomEvent?(msg: GemRoomEvent): void;
3219
- onSeatedEvent?(msg: GemSeatedEvent): void;
3220
- onAutoStartFailedEvent?(msg: GemAutoStartFailedEvent): void;
3221
- onTicketEvent?(msg: GemTicketEvent): void;
3222
- onSocketState?(msg: GemSocketState): void;
3223
- onSignalEvent?(msg: GemSignalEvent): void;
3224
- onRelayDraining?(msg: GemRelayDraining): void;
3225
- onDedicatedEvent?(msg: GemDedicatedEvent): void;
3226
- onClusterTarget?(msg: GemClusterTarget): void;
3227
- onGraphicsRoutes?(msg: GemGraphicsRoutes): void;
3228
- onPartyResult?(msg: GemPartyResult): void;
3229
- onPurchaseResult?(msg: GemPurchaseResult): void;
3230
- onPurchaseSettled?(msg: GemPurchaseSettled): void;
3231
- onShareResult?(msg: GemShareResult): void;
3232
- onDeviceSettings?(msg: GemDeviceSettings): void;
3233
- onDeviceSettingsResult?(msg: GemDeviceSettingsResult): void;
3234
- onAdResult?(msg: GemAdResult): void;
3235
- onMomentResult?(msg: GemMomentResult): void;
3236
- onSignInResult?(msg: GemSignInResult): void;
3237
- onFriendChallengeResult?(msg: GemFriendChallengeResult): void;
3238
- onArcadeAnswer?(msg: GemArcadeAnswer): void;
3239
- onPlayInviteResult?(msg: GemPlayInviteResult): void;
3240
- onError?(code: GemErrorCode, message?: string): void;
3241
- onDropped?(code: GemErrorCode, message?: string): void;
3242
- onStateChange?(state: FrameState): void;
3243
- onRefused?(reason: string): void;
3244
- }
3245
- interface FrameOptions extends FrameCallbacks {
3246
- allowedEmbedders: readonly string[];
3247
- selfOrigin?: string;
3248
- expectedSource: unknown;
3249
- capabilities?: readonly string[];
3250
- clock?: Clock;
3251
- }
3252
- declare class GemFrame {
3253
- private readonly options;
3254
- private state;
3255
- private port;
3256
- private version;
3257
- private peerCapabilities;
3258
- private unbidden;
3259
- private engagedSent;
3260
- private readyPending;
3261
- private readySent;
3262
- private settleWaiters;
3263
- private readonly clock;
3264
- private readonly inbound;
3265
- private readonly outbound;
3266
- private readonly expectedSource;
3267
- constructor(options: FrameOptions);
3268
- get currentState(): FrameState;
3269
- get parentCapabilities(): readonly string[];
3270
- parentSupports(capability: string): boolean;
3271
- get protocolVersion(): number | null;
3272
- get unbiddenLaunch(): boolean;
3273
- handleWindowMessage(event: HandshakeEvent): boolean;
3274
- ready(): void;
3275
- settled(timeoutMs?: number): Promise<FrameState>;
3276
- progress(loaded: number, total: number): void;
3277
- requestToken(requestId: string, reason: "initial" | "expiring" | "rejected"): void;
3278
- requestLocalServer(requestId: string, gameRoomId: string): boolean;
3279
- exit(reason?: string): void;
3280
- openExternal(url: string): void;
3281
- requestFullscreen(enabled: boolean): void;
3282
- reportMuted(muted: boolean): boolean;
3283
- reportEngaged(): boolean;
3284
- cueReward(cue: RewardCue): boolean;
3285
- showPortraitBorders(name: string | null): boolean;
3286
- setWalletVisible(visible: boolean, options?: {
3287
- only?: readonly string[];
3288
- }): boolean;
3289
- setMenu(items?: ReadonlyArray<{
3290
- readonly id: string;
3291
- readonly label: string;
3292
- }>): boolean;
3293
- declareSettings(settings: GemSettingsDeclare["settings"]): boolean;
3294
- setGemCorner(corner: GemCorner): boolean;
3295
- setRewardPresentation(mode: RewardPresentation): boolean;
3296
- setMenuStyle(style: MenuStyle | null): boolean;
3297
- requestShare(params: ReadonlyArray<{
3298
- readonly key: string;
3299
- readonly value: string;
3300
- }>, requestId?: string): boolean;
3301
- requestAvatarPicker(tab?: "2d" | "3d"): boolean;
3302
- requestVibrate(pattern: readonly number[]): boolean;
3303
- reportFrameStats(stats: {
3304
- fps: number;
3305
- frameTimeP95Ms: number;
3306
- counts?: "pageFrames" | "gameDraws";
3307
- }): boolean;
3308
- sendGameContext(context: Record<string, unknown>): boolean;
3309
- signal(signal: string, matchId: string, data: Record<string, unknown>): void;
3310
- dedicatedOffer(matchId: string, sdp: string, intent: GemDedicatedOffer["intent"]): void;
3311
- requestParty(requestId: string): boolean;
3312
- requestPurchase(requestId: string, purchaseKind: "item" | "recipe", targetId: string, currencySlug: string, quantity?: number, catalogId?: string, origin?: "sheet" | "direct_refused"): boolean;
3313
- requestAvatar3dPurchase(requestId: string, itemId: string, currencySlug: string): boolean;
3314
- putDeviceSettings(requestId: string, settings: Readonly<Record<string, unknown>>): boolean;
3315
- requestAd(requestId: string, placement: string, format: "interstitial" | "rewarded"): boolean;
3316
- signalMoment(requestId: string, kind: string, placement?: string, wall?: boolean): boolean;
3317
- readyCalled(): boolean;
3318
- requestSignIn(requestId: string): boolean;
3319
- requestFriendChallenge(requestId: string, playerId: string, template: string, params?: Readonly<Record<string, string | number>>): boolean;
3320
- requestArcade(msg: GemArcadeAsk | GemFriendsWindowAsk): boolean;
3321
- close(): void;
3322
- private transition;
3323
- private refuseMalformed;
3324
- private dropUnknownType;
3325
- private refuse;
3326
- private fail;
3327
- private gated;
3328
- private send;
3329
- private receive;
3330
- private dispatchInbound;
3331
- private screenshotDenied;
3332
- }
3333
3484
  interface ShareRequest {
3334
3485
  readonly params?: Readonly<Record<string, string>>;
3335
3486
  }
@@ -3342,11 +3493,6 @@ interface ShareApi {
3342
3493
  readonly available: boolean;
3343
3494
  request(request?: ShareRequest): Promise<void>;
3344
3495
  }
3345
- type ArcadeOutcomeKind = "ok" | "declined" | "unavailable";
3346
- interface ArcadeOutcome {
3347
- readonly outcome: ArcadeOutcomeKind;
3348
- readonly reason?: string;
3349
- }
3350
3496
  type AppStore = "app_store" | "google_play";
3351
3497
  interface AppListing {
3352
3498
  readonly store: AppStore;
@@ -3384,32 +3530,6 @@ interface ArcadeApi {
3384
3530
  readonly limit?: number;
3385
3531
  }): Promise<SimilarGamesOutcome>;
3386
3532
  }
3387
- interface ArcadeOffer {
3388
- readonly skuId: string;
3389
- readonly kind: "gem_pack" | "boost" | "pass" | "bundle";
3390
- readonly name: string;
3391
- readonly description: string;
3392
- readonly imageUrl?: string;
3393
- readonly priceDisplay: string;
3394
- readonly grant?: {
3395
- readonly currency: string;
3396
- readonly amount: number;
3397
- };
3398
- }
3399
- interface StoreOffersOutcome extends ArcadeOutcome {
3400
- readonly offers: readonly ArcadeOffer[];
3401
- }
3402
- interface StoreSettlement {
3403
- readonly skuId: string;
3404
- }
3405
- interface StoreApi {
3406
- readonly available: boolean;
3407
- readonly showOfferAvailable: boolean;
3408
- offers(): Promise<StoreOffersOutcome>;
3409
- purchase(skuId: string): Promise<ArcadeOutcome>;
3410
- showOffer(skuId: string): Promise<ArcadeOutcome>;
3411
- onSettled(listener: (settlement: StoreSettlement) => void): () => void;
3412
- }
3413
3533
  type BrandingTheme = "light" | "dark";
3414
3534
  interface BrandingVariant {
3415
3535
  readonly url: string;
@@ -3634,6 +3754,7 @@ interface GemPlayer extends PlayerIdentity {
3634
3754
  readonly displayHandle: PlayerText;
3635
3755
  readonly avatarUrl?: string;
3636
3756
  readonly boost: PlayerBoost;
3757
+ readonly isGuest: boolean;
3637
3758
  }
3638
3759
  interface GemPrefs {
3639
3760
  readonly reducedMotion: boolean;
@@ -3721,6 +3842,7 @@ interface Gem {
3721
3842
  readonly characters: CharactersApi;
3722
3843
  readonly transfers: TransfersApi;
3723
3844
  readonly gameConfig: GameConfigApi;
3845
+ readonly earnings: EarningsApi;
3724
3846
  readonly purchases: PurchaseApi;
3725
3847
  readonly deviceSettings: DeviceSettingsApi;
3726
3848
  readonly graphics: GraphicsApi;
@@ -3788,4 +3910,4 @@ interface ExitAnalytics {
3788
3910
  }
3789
3911
  declare function leaveAndExit(rooms: ExitRooms, bridge: ExitBridge | null, reason?: string, analytics?: ExitAnalytics): Promise<void>;
3790
3912
  declare function createGem(options?: GemOptions): Gem;
3791
- 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, 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 BootMark, type BootTimeline, type BrandingApi, type BrandingAsset, type BrandingAssetOptions, type BrandingCurrency, type BrandingImageOptions, type BrandingList, type BrandingLookup, type BrandingTheme, type BrandingVariant, type Challenge, type ChallengeWindow, ChallengesApi, 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, 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 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, 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 GemMatchServerModule, type GemOptions, type GemPlayer, type GemPreferredRoute, type GemPrefs, type GemRecommendedSettings, type GemReservedArea, GemSaveError, type GemServerBundle, type GemServerFactory, type GemServerHost, type GemServerHostProfile, type GemServerLifecycle, type GemTerminationNotice, GemUnframedError, type GemViewport, type GetLeaderboardOptions, type GraphicsApi, type JoinWelcome, type Leaderboard, type LeaderboardEntry, type LeaderboardPeriod, LeaderboardsApi, type ListChallengesOptions, type ListFriendChallengesOptions, type ListFriendsOptions, MAX_PERIODS_BACK, type MatchConnectOptions, type MatchConnection, type MatchHosting, type MatchHostingMode, 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 PlayInviteRequest, type PlayerBadge, type PlayerBoost, type PlayerBoostMultiplier, type PlayerIdentity, type PlayerProfile, type PlayerScope, PlayerText, type PreferredRouteOptions, type ProfileCallOptions, type 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 RewardCue, type RewardPresentation, type RewardedOption, type RewardedStatus, type SavePage, type SaveRecord, type SendOptions$1 as SendOptions, 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 TransportAdvert, type TransportKind, TransportRefusal, UNRELIABLE_CHANNEL_LABEL, type VibrationApi, type WalletVisibleOptions, type WornAvatar3d, asPlayerText, createBootTimeline, createGem, experimentSelection, leaveAndExit, mapIdentity, markOnResolve, platformIconUrl, presentJoinCredential, readTemplateTransports, readTransportAdvert, reportOnResolve, text, webTransportAvailable };
3913
+ 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, type AnalyticsValue, type AppLinksOutcome, type AppListing, type AppStore, type ArcadeApi, type ArcadeAvailability, type ArcadeOffer, type ArcadeOfferEarnMultiplier, type ArcadeOfferKind, type ArcadeOutcome, type ArcadeOutcomeKind, AuthError, type AuthFailure, type AuthState, type Avatar3dFamily, type Avatar3dOffer, type Avatar3dPrice, type Avatar3dPurchaseRequest, type AvatarRigNode, type AvatarRigs, type Avatars3dApi, type BonusPreview, type BootMark, type BootTimeline, type BrandingApi, type BrandingAsset, type BrandingAssetOptions, type BrandingCurrency, type BrandingImageOptions, type BrandingList, type BrandingLookup, type BrandingTheme, type BrandingVariant, type Challenge, type ChallengeWindow, ChallengesApi, type ConfigPreview, 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 EarningsApi, type EntityLeaderboard, type EntityLeaderboardEntry, type EntityLeaderboardOptions, type 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 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, 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 GemMatchServerModule, type GemOptions, type GemPlayer, type GemPreferredRoute, type GemPrefs, type GemRecommendedSettings, type GemReservedArea, GemSaveError, type GemServerBundle, type GemServerFactory, type GemServerHost, type GemServerHostProfile, type GemServerHostRead, type GemServerLifecycle, type GemTerminationNotice, GemUnframedError, type GemViewport, type GetLeaderboardOptions, type GraphicsApi, type JoinWelcome, type Leaderboard, type LeaderboardEntry, type LeaderboardPeriod, LeaderboardsApi, type ListChallengesOptions, type ListFriendChallengesOptions, type ListFriendsOptions, MAX_PERIODS_BACK, type MatchConnectOptions, type MatchConnection, type MatchHosting, type MatchHostingMode, type MatchServeOptions, type MatchTransport, type MenuStyle, type MessageMeta, type MomentKind, type MomentResult, type MomentSignal, type MomentsApi, type MultiTransportSession, PLATFORM_EVENTS, type PassUpsell, type PassesApi, type PassesEvent, type PeriodOptions, PlatformApi, PlatformCurrenciesApi, type PlatformCurrency, type PlatformCurrencyAccess, type PlatformCurrencyPurchasePayment, type PlatformCurrencyPurchaseRequest, type PlatformCurrencyPurchaseResult, type PlatformCurrencyReadOptions, PlatformEarnAllowanceApi, type PlatformEventName, type PlatformGrantPreview, type PlatformGrantSource, type PlayInviteRequest, type PlayerBadge, type PlayerBoost, type PlayerBoostMultiplier, type PlayerIdentity, type PlayerProfile, type PlayerScope, PlayerText, type PreferredRouteOptions, PreviewError, type PreviewGrant, type PreviewTarget, type ProfileCallOptions, type 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 RewardCue, type RewardPresentation, type RewardedOption, type RewardedStatus, type SavePage, type SaveRecord, type SendOptions$1 as SendOptions, type ServerTokenGrant, type SessionEndReason, type ShareApi, ShareRefusal, type ShareRequest, type ShowPassOutcome, 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 TransportAdvert, type TransportKind, TransportRefusal, UNRELIABLE_CHANNEL_LABEL, type UnmetRequirement, type VibrationApi, type WalletVisibleOptions, type WornAvatar3d, asPlayerText, createBootTimeline, createGem, experimentSelection, leaveAndExit, mapIdentity, markOnResolve, platformIconUrl, presentJoinCredential, readTemplateTransports, readTransportAdvert, reportOnResolve, text, webTransportAvailable };