@diffenderfer-games/hub 2.0.0-next.5 → 2.0.0-next.6

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (170) hide show
  1. package/CHANGELOG.md +54 -19
  2. package/README.md +3 -6
  3. package/dist/auto.d.ts +5 -5
  4. package/dist/auto.js +2 -2
  5. package/dist/avatar-pixi.d.ts +147 -0
  6. package/dist/avatar-pixi.d.ts.map +1 -0
  7. package/dist/avatar-pixi.js +280 -0
  8. package/dist/avatar-pixi.js.map +1 -0
  9. package/dist/avatar-svg.d.ts +4 -0
  10. package/dist/avatar-svg.js +5 -0
  11. package/dist/avatar-three.d.ts +69 -0
  12. package/dist/avatar-three.d.ts.map +1 -0
  13. package/dist/avatar-three.js +49 -0
  14. package/dist/avatar-three.js.map +1 -0
  15. package/dist/avatar.d.ts +7 -0
  16. package/dist/avatar.js +487 -0
  17. package/dist/avatar.js.map +1 -0
  18. package/dist/daily.d.ts +2 -2
  19. package/dist/doctor/cli.mjs +1 -1
  20. package/dist/index.d.ts +5 -5
  21. package/dist/index.js +2 -2
  22. package/dist/input.d.ts +2 -2
  23. package/dist/shared/animator.d.ts +104 -0
  24. package/dist/shared/animator.d.ts.map +1 -0
  25. package/dist/shared/art.js +1804 -0
  26. package/dist/shared/art.js.map +1 -0
  27. package/dist/shared/atlas.d.ts +134 -0
  28. package/dist/shared/atlas.d.ts.map +1 -0
  29. package/dist/shared/avatar.d.ts +117 -0
  30. package/dist/shared/avatar.d.ts.map +1 -0
  31. package/dist/shared/bridge.js +13 -5
  32. package/dist/shared/bridge.js.map +1 -1
  33. package/dist/shared/client-version.gen.js +1 -1
  34. package/dist/shared/daily.d.ts +129 -18
  35. package/dist/shared/daily.d.ts.map +1 -1
  36. package/dist/shared/daily.js +120 -26
  37. package/dist/shared/daily.js.map +1 -1
  38. package/dist/shared/defineProperty.js +39 -0
  39. package/dist/shared/describe.d.ts +32 -0
  40. package/dist/shared/describe.d.ts.map +1 -0
  41. package/dist/shared/describe.js +101 -0
  42. package/dist/shared/describe.js.map +1 -0
  43. package/dist/shared/globals.js +1 -39
  44. package/dist/shared/globals.js.map +1 -1
  45. package/dist/shared/index.d.ts +503 -14
  46. package/dist/shared/index.d.ts.map +1 -1
  47. package/dist/shared/input.d.ts +31 -13
  48. package/dist/shared/input.d.ts.map +1 -1
  49. package/dist/shared/input.js +40 -2
  50. package/dist/shared/input.js.map +1 -1
  51. package/dist/shared/json-guards.js +48 -0
  52. package/dist/shared/json-guards.js.map +1 -0
  53. package/dist/shared/live-canvas.js +62 -0
  54. package/dist/shared/live-canvas.js.map +1 -0
  55. package/dist/shared/mp.js +1 -1
  56. package/dist/shared/overlays.js +800 -0
  57. package/dist/shared/overlays.js.map +1 -0
  58. package/dist/shared/page-stack.js +2 -1
  59. package/dist/shared/page-stack.js.map +1 -1
  60. package/dist/shared/pose-key.js +249 -0
  61. package/dist/shared/pose-key.js.map +1 -0
  62. package/dist/shared/race.js +1 -1
  63. package/dist/shared/rooms.js +1 -1
  64. package/dist/shared/scene.d.ts +90 -0
  65. package/dist/shared/scene.d.ts.map +1 -0
  66. package/dist/shared/social.d.ts +55 -4
  67. package/dist/shared/social.d.ts.map +1 -1
  68. package/dist/shared/src.js +2020 -144
  69. package/dist/shared/src.js.map +1 -1
  70. package/dist/shared/svg-markup.js +1860 -0
  71. package/dist/shared/svg-markup.js.map +1 -0
  72. package/dist/shared/svg.js +27 -0
  73. package/dist/shared/svg.js.map +1 -0
  74. package/dist/shared/types.d.ts +166 -0
  75. package/dist/shared/types.d.ts.map +1 -0
  76. package/dist/social.d.ts +2 -2
  77. package/dist/social.js +2 -2
  78. package/dist/turns.d.ts +39 -0
  79. package/dist/turns.d.ts.map +1 -0
  80. package/dist/turns.js +117 -0
  81. package/dist/turns.js.map +1 -0
  82. package/package.json +33 -3
  83. package/src/avatar/adapters/pixi-avatar.ts +73 -0
  84. package/src/avatar/adapters/pixi-crowd.ts +302 -0
  85. package/src/avatar/adapters/pixi-types.ts +84 -0
  86. package/src/avatar/adapters/three.ts +126 -0
  87. package/src/avatar/animator/animator.ts +285 -0
  88. package/src/avatar/animator/reactions.ts +44 -0
  89. package/src/avatar/animator/schedule.ts +73 -0
  90. package/src/avatar/art/beard.ts +49 -0
  91. package/src/avatar/art/glasses.ts +9 -0
  92. package/src/avatar/art/hair.ts +254 -0
  93. package/src/avatar/art/headwear.ts +75 -0
  94. package/src/avatar/art/index.ts +21 -0
  95. package/src/avatar/art/shape.ts +68 -0
  96. package/src/avatar/art-store.ts +36 -0
  97. package/src/avatar/atlas.ts +236 -0
  98. package/src/avatar/catalog-view.ts +14 -0
  99. package/src/avatar/colour.ts +109 -0
  100. package/src/avatar/describe.ts +76 -0
  101. package/src/avatar/face.ts +187 -0
  102. package/src/avatar/geom.ts +168 -0
  103. package/src/avatar/layout.ts +47 -0
  104. package/src/avatar/look-like.ts +52 -0
  105. package/src/avatar/outputs/bitmap.ts +75 -0
  106. package/src/avatar/outputs/canvas-paint.ts +177 -0
  107. package/src/avatar/outputs/canvas.ts +62 -0
  108. package/src/avatar/outputs/custom-element.ts +140 -0
  109. package/src/avatar/outputs/element.ts +58 -0
  110. package/src/avatar/outputs/live-canvas.ts +57 -0
  111. package/src/avatar/outputs/overlay-svg.ts +22 -0
  112. package/src/avatar/outputs/pose-key.ts +30 -0
  113. package/src/avatar/outputs/svg-markup.ts +113 -0
  114. package/src/avatar/outputs/svg.ts +41 -0
  115. package/src/avatar/overlays.ts +128 -0
  116. package/src/avatar/render/body.ts +116 -0
  117. package/src/avatar/render/colours.ts +81 -0
  118. package/src/avatar/render/compose.ts +258 -0
  119. package/src/avatar/render/context.ts +117 -0
  120. package/src/avatar/render/eyes.ts +78 -0
  121. package/src/avatar/render/eyewear.ts +56 -0
  122. package/src/avatar/render/frame.ts +60 -0
  123. package/src/avatar/render/head.ts +81 -0
  124. package/src/avatar/render/mouth.ts +86 -0
  125. package/src/avatar/render/props.ts +91 -0
  126. package/src/avatar/render/types.ts +84 -0
  127. package/src/avatar/scene.ts +119 -0
  128. package/src/avatar-pixi.ts +20 -0
  129. package/src/avatar-svg.ts +21 -0
  130. package/src/avatar-three.ts +18 -0
  131. package/src/avatar.ts +62 -0
  132. package/src/core/avatar/avatar-cache.ts +95 -0
  133. package/src/core/avatar/avatar-ref.ts +34 -0
  134. package/src/core/avatar/avatar-types.ts +43 -0
  135. package/src/core/avatar/hub-avatar.ts +308 -0
  136. package/src/core/connection.ts +8 -0
  137. package/src/core/errors.ts +7 -1
  138. package/src/core/hub-progress.ts +269 -238
  139. package/src/core/hub.ts +174 -6
  140. package/src/core/offline/hub-kinds/avatar-kind.ts +42 -0
  141. package/src/core/offline/hub-kinds/index.ts +9 -0
  142. package/src/core/offline/hub-kinds/saved-kind.ts +93 -0
  143. package/src/core/page-account.ts +121 -0
  144. package/src/core/rest/routes.gen.ts +31 -1
  145. package/src/core/resume/hub-resume.ts +39 -5
  146. package/src/core/resume/resume-types.ts +2 -2
  147. package/src/core/saved/daily-saves.ts +196 -0
  148. package/src/core/saved/daily-seed.ts +16 -0
  149. package/src/core/saved/hub-saved.ts +221 -0
  150. package/src/core/saved/local-saved.ts +122 -0
  151. package/src/core/saved/saved-list.ts +129 -0
  152. package/src/core/saved/saved-open.ts +104 -0
  153. package/src/core/saved/saved-order.ts +49 -0
  154. package/src/core/saved/saved-types.ts +24 -0
  155. package/src/core/turns/hub-turns.ts +140 -0
  156. package/src/core/turns/turn-game.ts +388 -0
  157. package/src/core/version/client-version.gen.ts +2 -2
  158. package/src/daily/daily-system.ts +112 -13
  159. package/src/daily/page-daily.ts +2 -2
  160. package/src/daily/types.ts +46 -9
  161. package/src/doctor/hub-version-fetch.ts +43 -43
  162. package/src/index.ts +10 -1
  163. package/src/input/input-system.ts +10 -1
  164. package/src/input/navigator.ts +11 -0
  165. package/src/input.ts +1 -0
  166. package/src/overlay/overlay.ts +25 -1
  167. package/src/realtime/runtime-api.ts +14 -3
  168. package/src/social.ts +1 -0
  169. package/src/turns-kit/check-rules.ts +182 -0
  170. package/src/turns.ts +13 -0
@@ -1,11 +1,129 @@
1
- import { s as DailySystem } from "./daily.js";
1
+ import { b as avatar_d_exports } from "./avatar.js";
2
+ import { M as SavedOpened, S as SavedEntry, s as DailySystem, w as SavedListOptions, y as GamePayload } from "./daily.js";
2
3
  import { O as InputSystem, n as getUiStack } from "./input.js";
3
4
  import { o as multiplayerForwarder } from "./mp.js";
4
5
  import { f as raceForwarder } from "./race.js";
5
6
  import { n as roomsForwarder } from "./rooms.js";
6
- import { Q as socialForwarder, X as notifyForwarder, Z as presenceForwarder } from "./social.js";
7
- import { Board, Board as Board$1, ErrorCode, GameInfo, GameLeaderboards, GameRecords, HubVersion, Inventory, Inventory as Inventory$1, Json, Json as Json$1, LeaderboardEntry, Metrics, Metrics as Metrics$1, PublicEndpoints, RejectReason, ResumeSlot, ResumeSummary, SessionUser, SortDir, SortDir as SortDir$1, Stats, Stats as Stats$1 } from "@diffenderfer-games/hub-contract";
7
+ import { Q as OpenDesignerOptions, X as AvatarRef, Y as AvatarChange, Z as DesignerResult, it as socialForwarder, nt as notifyForwarder, rt as presenceForwarder } from "./social.js";
8
+ import { AvatarLook } from "@diffenderfer-games/hub-contract/avatar";
9
+ import { Board, Board as Board$1, CreateTurnGame, ErrorCode, GameInfo, GameLeaderboards, GameRecords, HubVersion, Inventory, Inventory as Inventory$1, Json, Json as Json$1, LeaderboardEntry, Metrics, Metrics as Metrics$1, MyAvatar, OpenTurnGame, OpenTurnGame as OpenTurnGame$1, PublicEndpoints, RejectReason, ResumeSlot, ResumeSummary, SavedCounts, SessionUser, SortDir, SortDir as SortDir$1, Stats, Stats as Stats$1, TurnChatLine, TurnChatLine as TurnChatLine$1, TurnDeadline, TurnDeadline as TurnDeadline$1, TurnGameView, TurnGameView as TurnGameView$1, TurnSummary } from "@diffenderfer-games/hub-contract";
8
10
  import { CallReturn, ClientData } from "@ayepi/core/client";
11
+ //#region src/core/page-account.d.ts
12
+ /** The signed-in player as the page heard it. */
13
+ interface PageUser {
14
+ readonly id: number;
15
+ /** Their look code when the source carried it, else `null`. */
16
+ readonly look: string | null;
17
+ }
18
+ /** Where the news came from: an account event, or a socket hello (a time to catch up on what was missed). */
19
+ type AccountSource = 'account' | 'session';
20
+ /** Hears every report of who is signed in. */
21
+ type AccountListener = (user: PageUser | null, source: AccountSource) => void;
22
+ /** The page's account, as last heard. */
23
+ declare class PageAccount {
24
+ /** `undefined` until something said; `null` when signed out. */
25
+ private heard;
26
+ private readonly listeners;
27
+ private isListening;
28
+ constructor();
29
+ /** The signed-in player, `null` when signed out, `undefined` before anything said. */
30
+ get user(): PageUser | null | undefined;
31
+ /** Record who is signed in (this client's own sign-in or sign-out) and tell the listeners. */
32
+ note(user: PageUser | null, source?: AccountSource): void;
33
+ /** Hear every report; returns the unsubscribe function. */
34
+ on(listener: AccountListener): () => void;
35
+ /** Listen to the window events (at once in a page; made before a window existed, on first use). */
36
+ private listen;
37
+ private onEvent;
38
+ }
39
+ //#endregion
40
+ //#region src/core/avatar/avatar-ref.d.ts
41
+ /** Anything that carries a player's look: a seat, a `PlayerLite`, a racer, a ticket user. */
42
+ interface CarriesLook {
43
+ readonly look?: string;
44
+ readonly userId?: number;
45
+ readonly id?: number;
46
+ readonly uid?: number;
47
+ }
48
+ //#endregion
49
+ //#region src/core/avatar/hub-avatar.d.ts
50
+ /** What `hub.avatar` needs from its client. */
51
+ interface AvatarHost {
52
+ /** The signed-in user's id, or `null` (`hub.userId()`). */
53
+ readonly currentUserId: () => number | null;
54
+ /** Hear every report of who is signed in (the page's account). */
55
+ readonly onAccount: (listener: AccountListener) => () => void;
56
+ /** `GET /avatar/me`; rejects when offline. */
57
+ readonly fetchMine: () => Promise<MyAvatar>;
58
+ /** `POST /avatar/batch`. */
59
+ readonly fetchCodes: (ids: readonly number[]) => Promise<Record<string, string>>;
60
+ /** Queue a save of your look (sent now when online, replayed later when not). */
61
+ readonly queueSave: (code: string, savedAt: number) => Promise<void>;
62
+ }
63
+ /** The renderer module `load()` resolves with. */
64
+ type AvatarModule = typeof avatar_d_exports;
65
+ type ChangeListener = (change: AvatarChange) => void;
66
+ /** `hub.avatar`. */
67
+ declare class HubAvatar {
68
+ private readonly host;
69
+ private readonly cache;
70
+ private readonly listeners;
71
+ private pending;
72
+ private flushQueued;
73
+ private detachRuntime;
74
+ /** The account the last report named. */
75
+ private lastUserId;
76
+ /** The code of your look the page was last given (`mine`, `mineSync`, `change`). */
77
+ private mineShown;
78
+ /** Players this page asked about or was handed (re-checked on each socket hello). */
79
+ private readonly seen;
80
+ constructor(host: AvatarHost);
81
+ /**
82
+ * Your look (your default if you never designed one). Works offline from
83
+ * the device cache. Before your account exists (a new guest's is made just
84
+ * after the game starts) it resolves at once with a default look, and
85
+ * `change` brings yours when the account is there.
86
+ */
87
+ mine(): Promise<AvatarRef>;
88
+ /** Your cached look, or your default; `null` only while nobody is signed in. */
89
+ mineSync(): AvatarRef | null;
90
+ /** Any player's look: from the cache, else batched with other requests in the same tick. */
91
+ of(userId: number): Promise<AvatarRef>;
92
+ /** Many players' looks at once. */
93
+ many(userIds: readonly number[]): Promise<Map<number, AvatarRef>>;
94
+ /** The look a payload already carries (a `RoomSeat`, `PlayerLite`, racer or ticket user). No request. */
95
+ from(carrier: CarriesLook): AvatarRef;
96
+ /** A seeded default for bots, previews and local pass-and-play seats: `bot('local:2')`. */
97
+ bot(seed: string | number): AvatarRef;
98
+ /** Save your look (designer code paths; queued offline, latest wins). */
99
+ save(look: AvatarLook): Promise<AvatarRef>;
100
+ /**
101
+ * Hear about look changes (yours, friends', your room's, and yours when
102
+ * your account appears). Returns the unsubscribe function. Wait for this
103
+ * rather than polling `mine()`.
104
+ */
105
+ on(_event: 'change', listener: ChangeListener): () => void;
106
+ /** Open "Make your avatar" over the game; resolves when it closes. */
107
+ openDesigner(options?: OpenDesignerOptions): Promise<DesignerResult>;
108
+ /** Loads the renderer and its art; resolves when rendering is synchronous. */
109
+ load(): Promise<AvatarModule>;
110
+ /** Remember the ref the page was given for your look. */
111
+ private showMine;
112
+ /** Cache your look; `change` fires when it differs from the one the page last had. */
113
+ private noteMine;
114
+ /** Someone said who is signed in: fetch your look when the account is new or its look isn't the cached one. */
115
+ private onAccount;
116
+ private refreshMine;
117
+ /** The socket (re)connected: a change sent while it was down never arrived, so ask again. */
118
+ private recheckSeen;
119
+ private emit;
120
+ private attachRuntime;
121
+ private scheduleFlush;
122
+ private flush;
123
+ /** Players' codes, in batches; offline or failing, the missing ones are left out (they get their default). */
124
+ private fetchCodes;
125
+ }
126
+ //#endregion
9
127
  //#region src/core/storage/key-value.d.ts
10
128
  /**
11
129
  * The string store behind the offline cache and queues: `localStorage` when
@@ -25,10 +143,6 @@ interface KeyValueStore {
25
143
  keys(): string[];
26
144
  }
27
145
  //#endregion
28
- //#region src/core/game-data.d.ts
29
- /** Anything a game may store as JSON: an object (interfaces included), an array, text, a number, a boolean or `null`. */
30
- type GamePayload = object | string | number | boolean | null;
31
- //#endregion
32
146
  //#region src/core/rest/endpoint-types.d.ts
33
147
  /** The name of a public REST endpoint (`getCurrentUser`, `writeSave`, ...). */
34
148
  type EndpointName = keyof PublicEndpoints;
@@ -600,6 +714,43 @@ declare class LocalResumeStore {
600
714
  all(): Map<string, LocalResume>;
601
715
  }
602
716
  //#endregion
717
+ //#region src/core/saved/local-saved.d.ts
718
+ /** A daily challenge as this device last saw it. */
719
+ interface LocalDaily {
720
+ readonly id: string;
721
+ readonly game: string;
722
+ readonly day: string;
723
+ readonly seed: number;
724
+ /** `active` in progress; `finished` (won) or `discarded`, kept until the hub has it. */
725
+ readonly status: 'active' | 'finished' | 'discarded';
726
+ readonly userId: number | null;
727
+ /** When it last changed here, epoch ms. */
728
+ readonly at: number;
729
+ readonly label: string;
730
+ readonly fraction: number | null;
731
+ readonly title: string | null;
732
+ readonly version: number;
733
+ readonly gameTitle: string;
734
+ /** The state the game last saved, `null` before its first save. */
735
+ readonly state: Json;
736
+ readonly isSynced: boolean;
737
+ }
738
+ /** The device copies of daily challenges. */
739
+ declare class LocalDailyStore {
740
+ private readonly store;
741
+ constructor(store: KeyValueStore);
742
+ /** The copy of `game`'s `day`, or `null`. */
743
+ read(game: string, day: string): LocalDaily | null;
744
+ /** Store a copy; answers whether it stuck (a full storage refuses a large state). */
745
+ write(copy: LocalDaily): boolean;
746
+ /** Forget a copy. */
747
+ remove(game: string, day: string): void;
748
+ /** The hub has the change made at `at` (and calls the instance `id`): mark it synced; a closed copy is forgotten. */
749
+ markSynced(game: string, day: string, at: number, id?: string): void;
750
+ /** Every copy of `userId`'s, any game. */
751
+ all(userId: number | null): LocalDaily[];
752
+ }
753
+ //#endregion
603
754
  //#region src/core/connection.d.ts
604
755
  /** A queued op the hub refused during a sync (or that kept failing): dropped, with the reason. */
605
756
  interface SyncConflict {
@@ -634,6 +785,8 @@ declare class HubConnection {
634
785
  protected readonly outbox: Outbox;
635
786
  /** The device copies of every game's resume slot (`hub.resume`). */
636
787
  protected readonly resumeStore: LocalResumeStore;
788
+ /** The device copies of daily challenges in progress (every game's). */
789
+ protected readonly dailyStore: LocalDailyStore;
637
790
  private readonly offlineMode;
638
791
  private isReachable;
639
792
  private runningSync;
@@ -732,6 +885,16 @@ interface ProfileUpdate<TData extends GamePayload = Json> {
732
885
  }
733
886
  /** Accounts, profile, saves, stats and leaderboards. */
734
887
  declare class HubProgress extends HubConnection {
888
+ /** Who the page is signed in as, as the hub's events and this client's sign-ins tell it. */
889
+ protected readonly account: PageAccount;
890
+ /**
891
+ * Your user id, or `null` when nobody is signed in (also before an offline
892
+ * first visit has an account). Synchronous, and it follows the account as
893
+ * the hub changes it (a new guest's account made by the menu, sign-in,
894
+ * sign-out) with no `hub.me()` needed. Compare it with a seat's `userId`
895
+ * to find yours.
896
+ */
897
+ userId(): number | null;
735
898
  /** The current user (or `null`) and the games they have a profile in. */
736
899
  me(): Promise<MeResponse>;
737
900
  /**
@@ -757,6 +920,9 @@ declare class HubProgress extends HubConnection {
757
920
  private signInLocally;
758
921
  /** Remember who the hub signed in, so the cache's notes about the hub's copies are read for the right player. */
759
922
  private signedIn;
923
+ /** The cache and the page (`hub.userId()`, `hub.avatar`) learn who is signed in. */
924
+ private remember;
925
+ private signedOut;
760
926
  /** This game's profile for the current user, or `profile: null`. `TData` is the game's own data type. */
761
927
  getProfile<TData = Json>(): Promise<{
762
928
  profile: Profile<TData> | null;
@@ -996,8 +1162,8 @@ interface ResumeEntry {
996
1162
  /** Saved on this device and not yet sent to the hub (offline, or the tab closed first). */
997
1163
  readonly isLocalOnly: boolean;
998
1164
  }
999
- /** Why a save was ignored: the page is in a race, a daily challenge or an online room. */
1000
- type ResumeBlocker = 'race' | 'daily' | 'room';
1165
+ /** Why a save was ignored: the page is in a race or an online room. (`'daily'` is no longer returned: a save during a daily goes to the day.) */
1166
+ type ResumeBlocker = 'race' | 'daily' | 'room' | 'turns';
1001
1167
  //#endregion
1002
1168
  //#region src/core/resume/hub-resume.d.ts
1003
1169
  /** How long saves must be quiet before the latest is sent, ms. */
@@ -1015,6 +1181,8 @@ interface ResumeHost {
1015
1181
  gameTitle(): string;
1016
1182
  /** Why saving is off right now, or `null`. */
1017
1183
  blocker(): ResumeBlocker | null;
1184
+ /** The page's daily challenge while one is being played (saves go to the day instead of the run), else `null`. */
1185
+ daily?(): DailyRoute | null;
1018
1186
  /** Perform a resume op: at once when online with nothing waiting, else queued. */
1019
1187
  send(payload: ResumePayload): Promise<void>;
1020
1188
  /** This game's run on the hub, or `undefined` when the hub can't be reached. */
@@ -1023,6 +1191,12 @@ interface ResumeHost {
1023
1191
  fetchList(): Promise<ResumeSummary[] | undefined>;
1024
1192
  /** Clear another game's run on the hub (the home page's discard); throws offline. */
1025
1193
  clearOther(slug: string): Promise<void>;
1194
+ /** The run changed here (saved or cleared): `hub.saved` listeners hear it. */
1195
+ onChange?(): void;
1196
+ }
1197
+ /** Where a save goes during a daily challenge (`hub.daily`). */
1198
+ interface DailyRoute {
1199
+ save(input: ResumeSaveInput<GamePayload>): boolean;
1026
1200
  }
1027
1201
  /** `hub.resume`. */
1028
1202
  declare class HubResume {
@@ -1043,14 +1217,17 @@ declare class HubResume {
1043
1217
  /**
1044
1218
  * Save the run (the latest save wins). Stored on the device at once; sent
1045
1219
  * after {@link RESUME_DEBOUNCE_MS} of quiet, or when the page is hidden.
1046
- * Returns `false` (and saves nothing) in a race, a daily challenge or an
1047
- * online room. Throws a `HubError` 413 over 512 KB, 400 without a label.
1220
+ * Returns `false` (and saves nothing) in a race or an online room; during
1221
+ * a daily challenge the save goes to the day (`hub.daily.save`). Throws a
1222
+ * `HubError` 413 over 512 KB, 400 without a label.
1048
1223
  */
1049
1224
  save<TState extends GamePayload>(run: ResumeSaveInput<TState>): boolean;
1050
1225
  /** Send a waiting save now (the page does this itself when hidden or closed). */
1051
1226
  flush(): Promise<void>;
1052
1227
  /** Clear the run: call it when the run ends (won, lost or quit). Works offline. */
1053
1228
  clear(): Promise<void>;
1229
+ /** Delete the game's saved run (never the day being played). */
1230
+ private clearRun;
1054
1231
  /** The saved run with its progress and time, or `null`. The newer of the device's copy and the hub's wins. */
1055
1232
  get<TState = GamePayload>(options?: ResumeLoadOptions): Promise<ResumeRun<TState> | null>;
1056
1233
  /** The saved state, or `null` (see {@link get} for the version rule). */
@@ -1067,6 +1244,282 @@ declare class HubResume {
1067
1244
  private listenToPage;
1068
1245
  }
1069
1246
  //#endregion
1247
+ //#region src/core/saved/saved-list.d.ts
1248
+ /** What the device holds, for one player. */
1249
+ interface DeviceCopies {
1250
+ /** Run copies by slug (`hub.resume`). */
1251
+ readonly runs: ReadonlyMap<string, LocalResume>;
1252
+ /** Daily copies (`hub.daily`), any game. */
1253
+ readonly dailies: readonly LocalDaily[];
1254
+ }
1255
+ //#endregion
1256
+ //#region src/core/saved/hub-saved.d.ts
1257
+ /** How long changes must be quiet before `on('change')` listeners hear the new list, ms. */
1258
+ declare const SAVED_CHANGE_QUIET_MS = 300;
1259
+ /** What `hub.saved` needs from its client. */
1260
+ interface SavedHost {
1261
+ /** This game's slug; `null` on the home page. */
1262
+ readonly slug: string | null;
1263
+ /** The hub's list (one game, or all), or `undefined` when it can't be reached. */
1264
+ fetchList(game: string | null): Promise<readonly SavedEntry[] | undefined>;
1265
+ /** What this device holds for the signed-in player. */
1266
+ deviceCopies(): DeviceCopies;
1267
+ /** Discard a daily or run (works offline where it can). */
1268
+ discard(entry: SavedEntry): Promise<void>;
1269
+ /** Go to a URL (`location.assign`). */
1270
+ navigate(url: string): void;
1271
+ }
1272
+ /** A change listener: this game's games in progress. */
1273
+ type SavedChangeListener = (games: SavedEntry[]) => void;
1274
+ /** An `onOpen` handler: switch to this instance without a reload. */
1275
+ type SavedOpenHandler = (instance: SavedEntry) => void | Promise<void>;
1276
+ /** The detail of {@link SAVED_OPEN_EVENT}. */
1277
+ interface SavedOpenDetail {
1278
+ readonly entry: SavedEntry;
1279
+ }
1280
+ /** `hub.saved`. */
1281
+ declare class HubSaved {
1282
+ private readonly host;
1283
+ /** Each handler with the kinds it takes (every kind when `undefined`). */
1284
+ private readonly openHandlers;
1285
+ private readonly changeListeners;
1286
+ private isListeningForOpen;
1287
+ private isListeningForChange;
1288
+ private changeTimer;
1289
+ constructor(host: SavedHost);
1290
+ /**
1291
+ * The instance this page was opened for (`?hub_open=<id>&hub_kind=<kind>`,
1292
+ * taken out of the address bar), or `null`. Synchronous: read it before
1293
+ * routing or drawing a title screen.
1294
+ */
1295
+ get opened(): SavedOpened | null;
1296
+ /** This game's games in progress: online games waiting on the player first, then the newest. Works offline. */
1297
+ list(options?: SavedListOptions): Promise<SavedEntry[]>;
1298
+ /** Every game's games in progress (the home page and the menu). Online, plus this device's copies. */
1299
+ listAll(): Promise<SavedEntry[]>;
1300
+ /** The badge counts across every game. */
1301
+ counts(): Promise<SavedCounts>;
1302
+ /**
1303
+ * Switch to an instance of THIS game when the player picks it from the
1304
+ * hub menu, without a reload. Without a handler the page reloads with
1305
+ * `?hub_open=<id>`. With `{ kinds }` the handler takes only those kinds;
1306
+ * the others still reload the page (with `?hub_resume=1` or `?daily=` for
1307
+ * a saved run or a daily). Returns a function that removes the handler.
1308
+ */
1309
+ onOpen(handler: SavedOpenHandler, options?: SavedListOptions): () => void;
1310
+ /** Open an instance: in this game through `onOpen` (or a reload), in another game by going there. */
1311
+ open(id: string): Promise<void>;
1312
+ /** Open an entry already in hand (the hub's lists). */
1313
+ openEntry(entry: SavedEntry): void;
1314
+ /**
1315
+ * Discard a daily challenge or a saved run (the caller asks first; the
1316
+ * hub's own lists ask for themselves). Online games are left with
1317
+ * `hub.turns`, never discarded.
1318
+ */
1319
+ discard(id: string): Promise<void>;
1320
+ /** Hear when this game's list changes; returns a function that stops listening. */
1321
+ on(_eventName: 'change', listener: SavedChangeListener): () => void;
1322
+ /** Something of this game's changed (a save here, an event from the hub): tell the listeners, once per quiet spell. */
1323
+ changed(): void;
1324
+ private listenForOpen;
1325
+ private listenForChange;
1326
+ }
1327
+ //#endregion
1328
+ //#region src/core/turns/turn-game.d.ts
1329
+ /** The window event the social runtime fires for each `ev:turn`. */
1330
+ declare const TURN_EVENT = "hub:turn";
1331
+ /** The runtime's live connection (re)opened: anything sent while it was down is fetched again. */
1332
+ declare const TURN_RESYNC_EVENT = "hub:turn-resync";
1333
+ /** The window event the social runtime fires for each `ev:turn.chat`. */
1334
+ declare const TURN_CHAT_EVENT = "hub:turn-chat";
1335
+ /** How often a page without the live runtime looks for moves, ms. */
1336
+ declare const TURN_POLL_MS = 20000;
1337
+ /** A game's end: the winning seats, and optionally places and scores by seat. */
1338
+ type TurnOutcome = NonNullable<TurnGameView['outcome']>;
1339
+ /** One move as this seat saw it. */
1340
+ interface TurnMoveEvent<View, Ev> {
1341
+ readonly seq: number;
1342
+ readonly seat: number;
1343
+ /** The view after the move (for a replayed move, the view now). */
1344
+ readonly view: View;
1345
+ readonly events: readonly Ev[];
1346
+ }
1347
+ /** What a game's listeners hear. */
1348
+ interface TurnGameEvents<View, Ev> {
1349
+ move: TurnMoveEvent<View, Ev>;
1350
+ turn: TurnSummary;
1351
+ ended: {
1352
+ readonly outcome: TurnOutcome | null;
1353
+ readonly view: View;
1354
+ };
1355
+ chat: TurnChatLine;
1356
+ }
1357
+ /** What a game needs from its client: the REST calls, by name. */
1358
+ interface TurnGameHost {
1359
+ get(id: string): Promise<TurnGameView>;
1360
+ start(id: string): Promise<TurnGameView>;
1361
+ move(id: string, seq: number, move: Json): Promise<{
1362
+ game: TurnGameView;
1363
+ events: Json[];
1364
+ }>;
1365
+ history(id: string, since: number): Promise<{
1366
+ seq: number;
1367
+ seat: number;
1368
+ events: Json[];
1369
+ }[]>;
1370
+ leave(id: string): Promise<void>;
1371
+ nudge(id: string): Promise<void>;
1372
+ setNotify(id: string, mode: 'on' | 'off'): Promise<void>;
1373
+ rematch(id: string): Promise<TurnGameView>;
1374
+ invite(id: string, userIds: readonly number[]): Promise<TurnGameView>;
1375
+ share(id: string, share: {
1376
+ readonly link?: boolean;
1377
+ readonly public?: boolean;
1378
+ }): Promise<TurnGameView>;
1379
+ autoPlay(id: string): Promise<TurnGameView>;
1380
+ chat(id: string, send: {
1381
+ readonly text?: string;
1382
+ readonly quick?: string;
1383
+ }): Promise<TurnChatLine>;
1384
+ /** The page has a game open (saves of a run are off while it does). */
1385
+ opened(game: object): void;
1386
+ closed(game: object): void;
1387
+ /** Whether the live runtime is on the page (else the game polls). */
1388
+ isLive(): boolean;
1389
+ }
1390
+ type Listener<Payload> = (payload: Payload) => void;
1391
+ /** One online game. `View`, `Move` and `Ev` (its events) are the game's own JSON types from its rules. */
1392
+ declare class TurnGame<View = GamePayload, Move extends GamePayload = GamePayload, Ev = GamePayload> {
1393
+ readonly id: string;
1394
+ private state;
1395
+ private readonly host;
1396
+ private readonly listeners;
1397
+ private readonly stopListening;
1398
+ private isClosed;
1399
+ private catchingUp;
1400
+ /** The move count this page's own move in flight will make (its live echo is not another player's move). */
1401
+ private ownSeq;
1402
+ constructor(host: TurnGameHost, initial: TurnGameView);
1403
+ /** Whose move it is, the seats and the deadline. */
1404
+ get summary(): TurnSummary;
1405
+ /** This seat's view, from the game's rules (`null` before the game starts). */
1406
+ get view(): View;
1407
+ /** This player's seat, or `null` (they left). */
1408
+ get mySeat(): number | null;
1409
+ /** The end, once the game is over. */
1410
+ get outcome(): TurnOutcome | null;
1411
+ /** The last chat lines, oldest first. */
1412
+ get chat(): readonly TurnChatLine[];
1413
+ /** `on`: friends may type (moderated); `quick`: quick-chat and emotes only; `off`. */
1414
+ get chatMode(): TurnGameView['chatMode'];
1415
+ /** The link others can take a seat with (the creator's, while seats are open), else `null`. */
1416
+ get link(): string | null;
1417
+ /** Creator: start the game (empty seats go to the computer when the game allows). */
1418
+ start(): Promise<void>;
1419
+ /**
1420
+ * Make a move. Rejects with a `HubError`: 403 `not_your_turn`, 409
1421
+ * `stale` (the game moved on: the view is refreshed first), 422 `illegal`
1422
+ * with the rules' own code in `rule`.
1423
+ */
1424
+ move(move: Move): Promise<{
1425
+ seq: number;
1426
+ view: View;
1427
+ events: Ev[];
1428
+ }>;
1429
+ /** The moves after `sinceSeq`, with their events as this seat may see them ("what happened while you were away"). */
1430
+ history(sinceSeq: number): Promise<{
1431
+ seq: number;
1432
+ seat: number;
1433
+ events: Ev[];
1434
+ }[]>;
1435
+ /** Leave: the computer plays the seat (or, without bots, the others win). The player can't come back. */
1436
+ leave(): Promise<void>;
1437
+ /** Remind whoever must move (once a day). */
1438
+ nudge(): Promise<void>;
1439
+ /** This game's "your turn" alerts. */
1440
+ setNotify(mode: 'on' | 'off'): Promise<void>;
1441
+ /** A finished game: a new one with the same friends (they get an invite). */
1442
+ rematch(): Promise<TurnGame<View, Move, Ev>>;
1443
+ /** Creator, before the start: add an invite link (`link: true`, then read `link`) or list the open seats for anyone (`public`). */
1444
+ share(share: {
1445
+ readonly link?: boolean;
1446
+ readonly public?: boolean;
1447
+ }): Promise<void>;
1448
+ /** Invite friends to free seats (before the start). */
1449
+ invite(userIds: readonly number[]): Promise<void>;
1450
+ /** The turn's deadline passed (or its player is suspended): let the computer play it. */
1451
+ letComputerPlay(): Promise<void>;
1452
+ /** Say something: `{ text }` between friends (moderated), `{ quick }` (a quick-chat phrase id) with anyone. */
1453
+ say(send: {
1454
+ readonly text?: string;
1455
+ readonly quick?: string;
1456
+ }): Promise<TurnChatLine>;
1457
+ /** Fetch the game again, and replay moves missed since the last one this page saw. */
1458
+ refresh(): Promise<void>;
1459
+ /** Hear moves, turn changes, the end and chat; returns a function that stops listening. */
1460
+ on<K extends keyof TurnGameEvents<View, Ev>>(eventName: K, listener: Listener<TurnGameEvents<View, Ev>[K]>): () => void;
1461
+ /** Stop live updates for this page (the game itself goes on). */
1462
+ close(): void;
1463
+ /** Take a fresh answer from the hub; fire `turn` and `ended` when they changed. */
1464
+ private update;
1465
+ private emit;
1466
+ /** A live `hub:turn` for this game: a move (or a missed run of them), or another change. */
1467
+ private onLive;
1468
+ /** Replay what was missed (one catch-up at a time). */
1469
+ private catchUp;
1470
+ private listen;
1471
+ }
1472
+ //#endregion
1473
+ //#region src/core/turns/hub-turns.d.ts
1474
+ /** The query parameter an invite link carries (`/<slug>/?hub_turn_link=<key>`); the client strips it. */
1475
+ declare const TURN_LINK_PARAM = "hub_turn_link";
1476
+ /** How to make a game. */
1477
+ interface TurnCreateOptions {
1478
+ readonly mode?: string;
1479
+ /** The game's own setup choices (at most 2 KB of JSON). */
1480
+ readonly options?: GamePayload;
1481
+ /** Friends to invite (their seats are held). */
1482
+ readonly invite?: readonly number[];
1483
+ /** Make a link others can take a seat with (`game.link`). */
1484
+ readonly link?: boolean;
1485
+ /** List the open seats in Play online for anyone to take. */
1486
+ readonly public?: boolean;
1487
+ /** Seats in all (within `game.turns.players`). */
1488
+ readonly seats?: number;
1489
+ /** Let the computer fill seats nobody took (default true, when the game has bots). */
1490
+ readonly bots?: boolean;
1491
+ /** How long a turn may wait before the others may let the computer play it (default none). */
1492
+ readonly deadline?: TurnDeadline;
1493
+ /** Start by itself once every seat is taken (the creator needn't come back). */
1494
+ readonly autoStart?: boolean;
1495
+ }
1496
+ /** What `hub.turns` needs from its client. */
1497
+ interface TurnsHost extends TurnGameHost {
1498
+ readonly slug: string | null;
1499
+ create(body: CreateTurnGame): ReturnType<TurnGameHost['get']>;
1500
+ join(id: string): ReturnType<TurnGameHost['get']>;
1501
+ joinByLink(key: string): ReturnType<TurnGameHost['get']>;
1502
+ listOpen(game: string | null): Promise<OpenTurnGame[]>;
1503
+ list(): Promise<SavedEntry[]>;
1504
+ }
1505
+ /** `hub.turns`. */
1506
+ declare class HubTurns {
1507
+ private readonly host;
1508
+ constructor(host: TurnsHost);
1509
+ /** The invite link key this page was opened with (`?hub_turn_link=`), taken out of the address bar; `null` when none. Synchronous. */
1510
+ get link(): string | null;
1511
+ /** Make a game in this page's game (its lobby): the player takes the first seat. */
1512
+ create<View = GamePayload, Move extends GamePayload = GamePayload, Event = GamePayload>(options?: TurnCreateOptions): Promise<TurnGame<View, Move, Event>>;
1513
+ /** Take a seat: by the game's id (an invite, an open seat) or by an invite link's key. */
1514
+ join<View = GamePayload, Move extends GamePayload = GamePayload, Event = GamePayload>(idOrLinkKey: string): Promise<TurnGame<View, Move, Event>>;
1515
+ /** Open a game the player sits in (from `hub.saved.opened`, the Continue list, an invite). */
1516
+ open<View = GamePayload, Move extends GamePayload = GamePayload, Event = GamePayload>(id: string): Promise<TurnGame<View, Move, Event>>;
1517
+ /** This game's online games the player sits in (the same rows as `hub.saved.list({ kinds: ['turns'] })`). */
1518
+ list(): Promise<SavedEntry[]>;
1519
+ /** Open-seat games of this game anyone may join (none across a block). */
1520
+ openLobbies(): Promise<OpenTurnGame[]>;
1521
+ }
1522
+ //#endregion
1070
1523
  //#region src/core/version/hub-version.d.ts
1071
1524
  /** How a hub regards a client version. */
1072
1525
  type ClientSupport =
@@ -1085,6 +1538,12 @@ declare class Hub extends HubEconomy {
1085
1538
  /** This client's package version (sent as `x-hub-client`). */
1086
1539
  readonly clientVersion: string;
1087
1540
  private resumeApi;
1541
+ private avatarApi;
1542
+ private savedApi;
1543
+ private dailySavesApi;
1544
+ private turnsApi;
1545
+ /** The online games open on this page (a run isn't saved while one is). */
1546
+ private readonly openTurnGames;
1088
1547
  /**
1089
1548
  * The hub's version and the client versions it supports (`GET /_api/version`),
1090
1549
  * read once per page. `null` for a hub from before versioning.
@@ -1126,9 +1585,35 @@ declare class Hub extends HubEconomy {
1126
1585
  * pick it up again (docs: "Resume saved games"). Needs `game.resumable: true`.
1127
1586
  */
1128
1587
  get resume(): HubResume;
1588
+ /**
1589
+ * Players' avatars: `hub.avatar.mine()`, `of(userId)`, `from(seat)`,
1590
+ * `bot(seed)`, `on('change')`, `openDesigner()` and `load()` for the renderer
1591
+ * (docs: "Avatars"). No art or renderer until `load()`.
1592
+ */
1593
+ get avatar(): HubAvatar;
1594
+ /**
1595
+ * Every game the player has in progress, of every kind: `hub.saved.list()`
1596
+ * for this game's "Continue" list, `opened` and `onOpen` to open the one
1597
+ * the player picked (docs: "Saved games").
1598
+ */
1599
+ get saved(): HubSaved;
1600
+ /**
1601
+ * Online games played over minutes or days, run by the hub from the
1602
+ * game's rules module (`game.turns`): `hub.turns.create`, `join`, `open`
1603
+ * (docs/multiplayer.md "Turn games").
1604
+ */
1605
+ get turns(): HubTurns;
1606
+ /** What `hub.turns` needs from this client: its REST calls. */
1607
+ private turnsHost;
1608
+ /** What `hub.saved` needs from this client. */
1609
+ private savedHost;
1610
+ /** Discard a daily or run: this game's run through `hub.resume` (works offline), others on the hub. */
1611
+ private discardSaved;
1129
1612
  /** What `hub.resume` needs from this client. */
1130
1613
  private resumeHost;
1131
- /** What the daily system needs from this client: its REST calls and window events. */
1614
+ /** This game's daily saves (device copies and their sends). */
1615
+ private dailySaves;
1616
+ /** What the daily system needs from this client: its REST calls, the device copies and window events. */
1132
1617
  private dailyHost;
1133
1618
  }
1134
1619
  /** A ready-to-use client, with the slug and API base detected from the page. */
@@ -1168,6 +1653,8 @@ interface HubErrorDetails {
1168
1653
  readonly retryAfterMs?: number | undefined;
1169
1654
  /** When a suspension or mute ends (epoch ms). */
1170
1655
  readonly until?: number | undefined;
1656
+ /** An online game's rules refused a move (`illegal`): the rules' own short code. */
1657
+ readonly rule?: string | undefined;
1171
1658
  }
1172
1659
  /**
1173
1660
  * Thrown by every hub call that fails. `status` is the HTTP status when the
@@ -1188,6 +1675,8 @@ declare class HubError extends Error {
1188
1675
  readonly retryAfterMs: number | undefined;
1189
1676
  /** When a suspension or mute ends (epoch ms). */
1190
1677
  readonly until: number | undefined;
1678
+ /** An online game's rules refused a move (`code` is `illegal`): the rules' own short code, such as `cell_taken`. */
1679
+ readonly rule: string | undefined;
1191
1680
  /** An error with a player-safe `message`, the HTTP `status` (if any) and the body's extras. */
1192
1681
  constructor(message: string, status?: number, details?: HubErrorDetails);
1193
1682
  /** `true` when the failure was a network or transport error, not an HTTP status. */
@@ -1210,7 +1699,7 @@ declare class ContentRejectedError extends HubError {
1210
1699
  //#endregion
1211
1700
  //#region src/core/version/client-version.gen.d.ts
1212
1701
  /** This client's package version, sent as `x-hub-client` on REST calls and `client` in `hello`. */
1213
- declare const HUB_CLIENT_VERSION = "2.0.0-next.5";
1702
+ declare const HUB_CLIENT_VERSION = "2.0.0-next.6";
1214
1703
  //#endregion
1215
- export { GameInfo$1 as $, StatResult as A, OUTBOX_MAX_ENTRIES as B, GrantBundle as C, EndpointName as Ct, TradeNoteOptions as D, TradeListOptions as E, OfflineEventDetails as F, ProfilePatch as G, OfflineKindDefinition as H, OfflineEventName as I, QueuedScoreOptions as J, QueueOp as K, OfflineListener as L, SyncResult as M, OfflineApi as N, AuthResponse as O, OUTBOX_FULL_CODE as P, GameAnalytics as Q, OfflineOp as R, HubMenuControl as S, EndpointFields as St, TradeId as T, GamePayload as Tt, ReplayContext as U, OfflineHandler as V, CLIENT_VERSION_HEADER as W, Board$1 as X, BufferedEvent as Y, BoardWithTop as Z, ResumeEntry as _, SortDir$1 as _t, HubErrorDetails as a, Inventory$1 as at, ResumeRun as b, SubmitScoreResult as bt, UNSUPPORTED_BY_HUB as c, LeaderboardEntry as ct, hub as d, Metrics$1 as dt, GameLeaderboards as et, ClientSupport as f, Profile as ft, ResumeBlocker as g, SnapshotResponse as gt, RESUME_MAX_STATE_BYTES as h, SaveMeta as ht, HubErrorCode as i, HubStatus as it, SyncConflict as j, ProfileUpdate as k, Hub as l, LeaderboardResult as lt, RESUME_DEBOUNCE_MS as m, Save as mt, ContentRejectedError as n, GlobalAnalytics as nt, OfflineError as o, InventorySnapshot as ot, HubResume as p, ProfileSummary as pt, QueueOpInput as q, HubError as r, HubOptions as rt, SAVE_UNKNOWN_CODE as s, Json$1 as st, HUB_CLIENT_VERSION as t, GameRecords as tt, createHub as u, MeResponse as ut, ResumeLoadOptions as v, Stats$1 as vt, TradeBundle as w, EndpointReply as wt, ResumeSaveInput as x, User as xt, ResumeProgress as y, SubmitScoreOptions as yt, OUTBOX_MAX_CHARS as z };
1704
+ export { OfflineApi as $, SavedChangeListener as A, MeResponse as At, ResumeRun as B, SubmitScoreResult as Bt, TURN_RESYNC_EVENT as C, HubOptions as Ct, TurnOutcome as D, Json$1 as Dt, TurnMoveEvent as E, InventorySnapshot as Et, RESUME_MAX_STATE_BYTES as F, SaveMeta as Ft, TradeId as G, AvatarHost as Gt, HubMenuControl as H, EndpointFields as Ht, ResumeBlocker as I, SnapshotResponse as It, AuthResponse as J, CarriesLook as Jt, TradeListOptions as K, AvatarModule as Kt, ResumeEntry as L, SortDir$1 as Lt, SavedOpenHandler as M, Profile as Mt, HubResume as N, ProfileSummary as Nt, HubSaved as O, LeaderboardEntry as Ot, RESUME_DEBOUNCE_MS as P, Save as Pt, SyncResult as Q, ResumeLoadOptions as R, Stats$1 as Rt, TURN_POLL_MS as S, GlobalAnalytics as St, TurnGameEvents as T, Inventory$1 as Tt, GrantBundle as U, EndpointName as Ut, ResumeSaveInput as V, User as Vt, TradeBundle as W, EndpointReply as Wt, StatResult as X, ProfileUpdate as Y, SyncConflict as Z, HubTurns as _, BoardWithTop as _t, HUB_CLIENT_VERSION as a, OUTBOX_MAX_CHARS as at, TURN_CHAT_EVENT as b, GameLeaderboards as bt, HubErrorCode as c, OfflineKindDefinition as ct, SAVE_UNKNOWN_CODE as d, ProfilePatch as dt, OUTBOX_FULL_CODE as et, UNSUPPORTED_BY_HUB as f, QueueOp as ft, ClientSupport as g, Board$1 as gt, hub as h, BufferedEvent as ht, TurnGameView$1 as i, OfflineOp as it, SavedOpenDetail as j, Metrics$1 as jt, SAVED_CHANGE_QUIET_MS as k, LeaderboardResult as kt, HubErrorDetails as l, ReplayContext as lt, createHub as m, QueuedScoreOptions as mt, TurnChatLine$1 as n, OfflineEventName as nt, ContentRejectedError as o, OUTBOX_MAX_ENTRIES as ot, Hub as p, QueueOpInput as pt, TradeNoteOptions as q, HubAvatar as qt, TurnDeadline$1 as r, OfflineListener as rt, HubError as s, OfflineHandler as st, OpenTurnGame$1 as t, OfflineEventDetails as tt, OfflineError as u, CLIENT_VERSION_HEADER as ut, TURN_LINK_PARAM as v, GameAnalytics as vt, TurnGame as w, HubStatus as wt, TURN_EVENT as x, GameRecords as xt, TurnCreateOptions as y, GameInfo$1 as yt, ResumeProgress as z, SubmitScoreOptions as zt };
1216
1705
  //# sourceMappingURL=index.d.ts.map