@diffenderfer-games/hub 2.0.0-next.0 → 2.0.0-next.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (154) hide show
  1. package/CHANGELOG.md +36 -0
  2. package/LICENSE +21 -21
  3. package/README.md +206 -139
  4. package/dist/auto.d.ts +6 -6
  5. package/dist/auto.js +2 -2
  6. package/dist/doctor/cli.mjs +62 -25
  7. package/dist/doctor/cli.mjs.map +1 -1
  8. package/dist/index.d.ts +6 -6
  9. package/dist/index.js +2 -2
  10. package/dist/mp.d.ts +3 -3
  11. package/dist/race.d.ts +1 -1
  12. package/dist/rooms.d.ts +3 -3
  13. package/dist/shared/bridge.js +9 -3
  14. package/dist/shared/bridge.js.map +1 -1
  15. package/dist/shared/client-version.gen.js +1 -1
  16. package/dist/shared/daily.d.ts +10 -4
  17. package/dist/shared/daily.d.ts.map +1 -1
  18. package/dist/shared/daily.js +12 -2
  19. package/dist/shared/daily.js.map +1 -1
  20. package/dist/shared/globals.js +8 -3
  21. package/dist/shared/globals.js.map +1 -1
  22. package/dist/shared/index.d.ts +314 -35
  23. package/dist/shared/index.d.ts.map +1 -1
  24. package/dist/shared/input.js +7 -2
  25. package/dist/shared/input.js.map +1 -1
  26. package/dist/shared/latest-state.js +1 -1
  27. package/dist/shared/mp.js +10 -2
  28. package/dist/shared/mp.js.map +1 -1
  29. package/dist/shared/multiplayer-types.d.ts +15 -2
  30. package/dist/shared/multiplayer-types.d.ts.map +1 -1
  31. package/dist/shared/race-types.d.ts +1 -1
  32. package/dist/shared/race.js +1 -1
  33. package/dist/shared/room-types.d.ts +28 -3
  34. package/dist/shared/room-types.d.ts.map +1 -1
  35. package/dist/shared/rooms.d.ts.map +1 -1
  36. package/dist/shared/rooms.js +10 -2
  37. package/dist/shared/rooms.js.map +1 -1
  38. package/dist/shared/runtime-opener.js +1 -1
  39. package/dist/shared/social.d.ts +23 -8
  40. package/dist/shared/social.d.ts.map +1 -1
  41. package/dist/shared/social.js +6 -1
  42. package/dist/shared/social.js.map +1 -1
  43. package/dist/shared/src.js +1588 -388
  44. package/dist/shared/src.js.map +1 -1
  45. package/dist/shared/wire-types.d.ts +6 -2
  46. package/dist/shared/wire-types.d.ts.map +1 -1
  47. package/dist/social.d.ts +5 -5
  48. package/dist/social.js +1 -1
  49. package/package.json +89 -89
  50. package/src/auto.ts +39 -39
  51. package/src/core/connection.ts +394 -299
  52. package/src/core/errors.ts +147 -147
  53. package/src/core/game-data.ts +40 -38
  54. package/src/core/hub-economy.ts +216 -179
  55. package/src/core/hub-progress.ts +202 -205
  56. package/src/core/hub.ts +133 -131
  57. package/src/core/menu-control.ts +61 -61
  58. package/src/core/offline/events.ts +50 -50
  59. package/src/core/offline/favorites.ts +21 -21
  60. package/src/core/offline/hub-kinds/daily-kind.ts +68 -0
  61. package/src/core/offline/hub-kinds/economy-kinds.ts +86 -0
  62. package/src/core/offline/hub-kinds/game-fields.ts +2 -0
  63. package/src/core/offline/hub-kinds/index.ts +35 -0
  64. package/src/core/offline/hub-kinds/legacy-ops.ts +37 -0
  65. package/src/core/offline/hub-kinds/progress-kinds.ts +148 -0
  66. package/src/core/offline/kind-adapters.ts +48 -0
  67. package/src/core/offline/local-inventory.ts +64 -0
  68. package/src/core/offline/local-store.ts +259 -261
  69. package/src/core/offline/offline-api.ts +65 -0
  70. package/src/core/offline/outbox-entry.ts +59 -0
  71. package/src/core/offline/outbox-kinds.ts +78 -0
  72. package/src/core/offline/outbox-merge.ts +39 -0
  73. package/src/core/offline/outbox-replayer.ts +141 -0
  74. package/src/core/offline/outbox-store.ts +85 -0
  75. package/src/core/offline/outbox.ts +232 -0
  76. package/src/core/offline/queue.ts +126 -171
  77. package/src/core/offline/replay-lease.ts +87 -0
  78. package/src/core/offline/replay-policy.ts +52 -0
  79. package/src/core/page.ts +74 -74
  80. package/src/core/rest/endpoint-types.ts +22 -22
  81. package/src/core/rest/rest-client.ts +163 -152
  82. package/src/core/rest/routes.gen.ts +108 -87
  83. package/src/core/storage/json-guards.ts +80 -74
  84. package/src/core/storage/key-value.ts +66 -66
  85. package/src/core/ticket.ts +43 -43
  86. package/src/core/types.ts +134 -134
  87. package/src/core/version/client-version.gen.ts +1 -1
  88. package/src/core/version/hub-version.ts +62 -62
  89. package/src/core/version/semver.ts +97 -97
  90. package/src/daily/daily-system.ts +168 -161
  91. package/src/daily/page-daily.ts +36 -36
  92. package/src/daily/types.ts +68 -67
  93. package/src/daily.ts +10 -10
  94. package/src/doctor/checks.ts +86 -76
  95. package/src/doctor/cli.ts +98 -106
  96. package/src/doctor/hub-version-fetch.ts +43 -0
  97. package/src/doctor/tsconfig.json +12 -12
  98. package/src/globals.ts +115 -110
  99. package/src/index.ts +55 -50
  100. package/src/input/device-state.ts +146 -146
  101. package/src/input/edges.ts +55 -55
  102. package/src/input/gamepad.ts +61 -61
  103. package/src/input/input-events.ts +32 -32
  104. package/src/input/input-registry.ts +171 -164
  105. package/src/input/input-system.ts +393 -393
  106. package/src/input/legacy-controls.ts +64 -64
  107. package/src/input/nav-state.ts +191 -191
  108. package/src/input/navigator.ts +171 -171
  109. package/src/input/on-screen-controls.ts +101 -101
  110. package/src/input/page-control.ts +43 -43
  111. package/src/input/page-input.ts +193 -193
  112. package/src/input/player-remaps.ts +77 -77
  113. package/src/input/source-values.ts +116 -116
  114. package/src/input/spatial.ts +47 -47
  115. package/src/input/types.ts +331 -331
  116. package/src/input/zero-config.ts +177 -177
  117. package/src/input.ts +22 -22
  118. package/src/mp.ts +10 -10
  119. package/src/overlay/controls-panel.ts +163 -163
  120. package/src/overlay/dom.ts +46 -46
  121. package/src/overlay/layout-clusters.ts +162 -162
  122. package/src/overlay/layout-geometry.ts +136 -136
  123. package/src/overlay/layout.ts +203 -203
  124. package/src/overlay/listener-scope.ts +23 -23
  125. package/src/overlay/on-screen-keyboard.ts +137 -137
  126. package/src/overlay/overlay.ts +208 -208
  127. package/src/overlay/styles.ts +9 -9
  128. package/src/overlay/virtual-controls.ts +262 -262
  129. package/src/race.ts +10 -10
  130. package/src/realtime/bridge.ts +126 -121
  131. package/src/realtime/cross-bundle.ts +29 -29
  132. package/src/realtime/fallback-notice.ts +48 -48
  133. package/src/realtime/hub-link.ts +65 -65
  134. package/src/realtime/latest-state.ts +33 -33
  135. package/src/realtime/multiplayer-forwarder.ts +40 -28
  136. package/src/realtime/multiplayer-types.ts +66 -52
  137. package/src/realtime/page-runtime.ts +60 -60
  138. package/src/realtime/race-forwarder.ts +59 -59
  139. package/src/realtime/race-types.ts +132 -132
  140. package/src/realtime/room-types.ts +151 -125
  141. package/src/realtime/rooms-forwarder.ts +91 -79
  142. package/src/realtime/runtime-api.ts +60 -49
  143. package/src/realtime/runtime-opener.ts +61 -61
  144. package/src/realtime/social-forwarder.ts +77 -72
  145. package/src/realtime/social-types.ts +86 -78
  146. package/src/realtime/types.ts +53 -53
  147. package/src/realtime/wire-types.ts +79 -72
  148. package/src/rooms.ts +10 -10
  149. package/src/social.ts +18 -18
  150. package/src/types.ts +13 -13
  151. package/src/uistack/page-stack.ts +45 -45
  152. package/src/uistack/play-suspension.ts +82 -82
  153. package/src/uistack/types.ts +76 -76
  154. package/src/uistack/ui-stack.ts +144 -144
package/CHANGELOG.md ADDED
@@ -0,0 +1,36 @@
1
+ # @diffenderfer-games/hub
2
+
3
+ ## 2.0.0-next.2
4
+
5
+ ### Minor Changes
6
+
7
+ - 3944819: `game.labels`: say what kind of game yours is, from a fixed vocabulary (`GAME_LABELS`, with display names in `GAME_LABEL_TITLES`, grouped in `GAME_LABEL_GROUPS`): genre (`cards`, `board`, `puzzle`, `arcade`, `platformer`, `real-time-strategy`, `physics`, `typing`, `word`, `sports`, `racing`), look (`2d`, `3d`), where it plays (`phone`, `controller`, `desktop`) and players (`multiplayer`, `single-player`). The home page filters by them. An unknown label is a `hub-doctor` warning, not an error.
8
+
9
+ New endpoints: `GET /catalog/players` (how many accounts and guests have each game open right now: counts only) and `GET /games/:slug/me/activity` (the signed-in player's plays and minutes in a game). The `lobbyOpen` notification preference now means "tell me when people want to play": an open public lobby or race, or a tournament opening.
10
+ - 937d61e: Explicit offline replay. Writes made offline now go into a typed operation outbox in `localStorage`: each op has a kind whose handler performs it (several dependent calls can be one op), ops replay in order with backoff when the hub is back and after a reload, one tab replays at a time, and the outbox is capped. Saves, stats, scores, the profile, daily completions, inventory grants and house exchanges, and starring a game all queue offline. Games add their own kinds with `hub.offline.define(kind, handler)`, queue them with `hub.offline.enqueue(kind, payload)`, list them with `hub.offline.pending()`, and hear `queued`, `replayed` and `failed` through `hub.offline.on(...)` (and `hub:offline-*` window events). An offline `hub.daily.complete()` resolves `null`, fires `hub:daily-queued`, and replays later. The contract marks the endpoints that may be replayed (`OFFLINE_REPLAY_ENDPOINTS`); each replayed call carries an operation key (`x-hub-op`) and the hub runs it once per key. `SyncConflict.op` is now the dropped outbox op.
11
+ - ed68402: Invite links and resilient online games (batch 2026-10, R13 and R14).
12
+
13
+ - **Invite links:** `hub.mp.inviteLink()` makes (or reuses) a shareable link to the room the player is in; `hub.mp.revokeInviteLink(token)` revokes it. Opening `/<slug>/<lobby>?hub_link=<token>` arrives as an ordinary `join` or `watch` launch with `via: 'link'`. Contract: `POST /mp/links`, `GET /mp/links`, `DELETE /mp/links/:token`, `POST /mp/links/:token/open`, the `InviteLink` shape and the `link_invalid`, `link_room_gone` and `too_many_links` error codes.
14
+ - **Resilient rooms:** the new `room.seat` event (`room.on('seat', …)`: `away` with `graceEndsAt`, `back`, `gone` with `reason`), `room.seats()`, `hub.rooms.reclaim()` (socket op `room.reclaim`), seats' `graceEndsAt`, and `Launch.via` (`'link' | 'rejoin'`). The host role now passes on instead of the room closing with `host_left`: once the host's seat is freed by default, or as soon as the host drops with `hub.rooms.create({ hostMigration: 'drop' })`.
15
+ - The realtime feature version is 3; on an older runtime the new methods reject with `OfflineError` asking for a reload.
16
+ - 5b68831: Tournaments (docs/multiplayer.md §15). `game.multiplayer.tournaments: true` says a game plays 1v1 tournament matches and reports their winner; race games need nothing. A ready match reaches the game as an ordinary `host`/`guest` launch with the new `launch.tournament` (`{ id, title, match, opponent }`); a hub-room game ends it with `room.end({ winnerId })`, an own-server game posts results with `tournament: { id, match }`.
17
+
18
+ New endpoints: `GET /play-online` (lobbies waiting for a player, invites, my tournaments, open ones coming up), `GET|POST /tournaments`, `GET|DELETE /tournaments/:id`, `POST /tournaments/:id/join|leave|start|invites`, `PUT|DELETE /tournaments/:id/follow` and `POST /tournaments/:id/matches/:match/launch`; the `tournament` socket event; the `tournament` notice kind; `GameInfo.tournaments`; `TOURNAMENT_LIMITS`. `hub.social.openPlayOnline()` opens the hub's Play online window (realtime feature version 4).
19
+
20
+ ### Patch Changes
21
+
22
+ - `hub.input.axis(name)` reads a vertical-only axis (`axes: { paddle: { y: ['up', 'down'] } }`); it used to read 0.
23
+ - A save, profile or score meta with an optional field set to `undefined` is stored and sent as the JSON it stands for (the field left out); with the new outbox it was refused as "Malformed offline operation payload" and never reached the hub.
24
+ - Updated dependencies [3944819]
25
+ - Updated dependencies [937d61e]
26
+ - Updated dependencies [ed68402]
27
+ - Updated dependencies [5b68831]
28
+ - @diffenderfer-games/hub-contract@2.0.0-next.2
29
+
30
+ ## 2.0.0-next.1
31
+
32
+ ### Patch Changes
33
+
34
+ - Follow-ups from the Bubble Pop pilot. `hub-doctor` gives up after `--timeout` ms (default 10 s) and fails with `hub unreachable at <url>` instead of hanging. A v1 vendored singleton adopted on the page is now recorded in `window.__DG__` as `{ version: 'v1' }`. The README covers exact pins for prereleases, sharing the page with the host's `/_hub/hub.js`, and testing against the hub.
35
+ - Updated dependencies
36
+ - @diffenderfer-games/hub-contract@2.0.0-next.1
package/LICENSE CHANGED
@@ -1,21 +1,21 @@
1
- MIT License
2
-
3
- Copyright (c) 2026 Philip Diffenderfer
4
-
5
- Permission is hereby granted, free of charge, to any person obtaining a copy
6
- of this software and associated documentation files (the "Software"), to deal
7
- in the Software without restriction, including without limitation the rights
8
- to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
- copies of the Software, and to permit persons to whom the Software is
10
- furnished to do so, subject to the following conditions:
11
-
12
- The above copyright notice and this permission notice shall be included in all
13
- copies or substantial portions of the Software.
14
-
15
- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
- IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
- FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
- AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
- LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
- OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
- SOFTWARE.
1
+ MIT License
2
+
3
+ Copyright (c) 2026 Philip Diffenderfer
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md CHANGED
@@ -1,139 +1,206 @@
1
- # @diffenderfer-games/hub
2
-
3
- The client library for games on [diffenderfer.games](https://diffenderfer.games):
4
- accounts, saves, stats, leaderboards, inventory and trades, daily challenges,
5
- the input system (keyboard, touch and gamepad), and the social, multiplayer,
6
- rooms and race namespaces. It is typed from the hub's wire contract
7
- (`@diffenderfer-games/hub-contract`), ships ES modules with `.d.ts` files, and
8
- carries no zod at runtime.
9
-
10
- ## Install
11
-
12
- ```sh
13
- npm install @diffenderfer-games/hub
14
- ```
15
-
16
- ESM only, for browsers (ES2020: Safari 14+, current Chrome, Edge and Firefox).
17
- Node 20+ for the `hub-doctor` command.
18
-
19
- ## Use
20
-
21
- ```ts
22
- import { hub } from '@diffenderfer-games/hub';
23
-
24
- const { user } = await hub.me();
25
- await hub.ensureGuest(); // a guest account, so progress saves without a sign-in
26
- await hub.putSave('auto', { level: 7, gold: 120 });
27
- await hub.submitScore('highscore', 9001, { title: 'High Score' });
28
- hub.recordPlay();
29
-
30
- hub.input.define({ groups: { play: { inputs: { jump: { keys: [' '], gamepad: { button: 0 } } } } } });
31
- hub.input.enable('play');
32
- hub.daily.define({ play: (challenge) => startLevel(challenge.seed) });
33
- hub.overlay.autoPause({ pause, resume });
34
- ```
35
-
36
- In a game the host serves, the slug and the API base are read from the page.
37
- For anything else, create a client yourself:
38
-
39
- ```ts
40
- import { createHub } from '@diffenderfer-games/hub';
41
-
42
- const demo = createHub({ slug: 'my-game', apiBase: '/_api', offline: 'auto' });
43
- ```
44
-
45
- A game's own JSON is typed by the game: `hub.getSave<MySave>('auto')`,
46
- `hub.putSave<MySave>('auto', save)`, `hub.getProfile<MyProfile>()`.
47
-
48
- ## Entry points
49
-
50
- | Import | What it has |
51
- |---|---|
52
- | `@diffenderfer-games/hub` | `hub`, `createHub`, `Hub`, the errors, every client type, and the input and daily exports |
53
- | `@diffenderfer-games/hub/input` | `getInput`, `InputSystem`, the on-screen control layout, `getUiStack` |
54
- | `@diffenderfer-games/hub/daily` | `getDaily`, `DailySystem` |
55
- | `@diffenderfer-games/hub/race`, `/social`, `/mp`, `/rooms` | one namespace each (`race`, `social` with `presence` and `notify`, `mp`, `rooms`) |
56
- | `@diffenderfer-games/hub/types` | type-only: every contract type (requests, replies, entities, error codes, socket ops and events, the `game.*` manifest) |
57
- | `@diffenderfer-games/hub/auto` | everything above, and it sets `window.HubSDK` (what `/_hub/hub.js` is built from) |
58
-
59
- The namespaces also hang off `hub` (`hub.input`, `hub.daily`, `hub.race`,
60
- `hub.social`, `hub.presence`, `hub.notify`, `hub.mp`, `hub.rooms`,
61
- `hub.overlay`, `hub.menu`), created on first use.
62
-
63
- ## Errors
64
-
65
- Every call rejects with a `HubError` when it fails. `status` is the HTTP
66
- status, or `undefined` when the hub could not be reached (`isOffline`).
67
- `code`, `reason`, `hint` and `retryAfterMs` come from the hub's error body.
68
-
69
- - `ContentRejectedError`: the safety filter refused some text (HTTP 422).
70
- Keep the player's draft and show `hint`.
71
- - `OfflineError`: an action that needs the hub was tried offline.
72
- - `code: 'unsupported_by_hub'`: the hub does not have this call yet (the game
73
- uses a newer client than the deployed hub). Deploy the hub first.
74
-
75
- The analytics calls (`recordPlay`, `heartbeat`, `event`) never throw.
76
-
77
- ## Offline
78
-
79
- With `offline: 'auto'` (the default), reads fall back to a cache in
80
- `localStorage` when the hub can't be reached, and writes (saves, stats,
81
- scores, profile) apply to the cache at once and are queued. The queue replays
82
- in order when the connection returns; `hub.sync()` replays it on demand,
83
- `hub.pending()` counts what waits, and `hub.onStatus(listener)` reports
84
- changes. `hub.prefetchAll()` warms the cache for every game in one request.
85
- `offline: 'always'` never touches the network (develop without a hub);
86
- `offline: 'never'` always throws instead.
87
-
88
- The cache and queue use the same `localStorage` keys as the old vendored
89
- client, so a game that switches to this package keeps its players' queued
90
- progress.
91
-
92
- ## Games without a build step
93
-
94
- Keep `import('/_hub/hub.js')` or `window.HubSDK.hub`: the host serves a
95
- bundle of this package's `./auto` entry, at the version the host was built
96
- with. Install the package as a dev dependency only if you want editor types:
97
-
98
- ```js
99
- /** @type {import('@diffenderfer-games/hub').Hub} */
100
- const hub = window.HubSDK.hub;
101
- ```
102
-
103
- ## Versions
104
-
105
- The client sends its version as `x-hub-client`. `hub.hubVersion()` reads the
106
- hub's `GET /_api/version` (`{ server, contract, supported, deprecated }`) once
107
- per page, and `hub.clientSupport()` says whether this client is `supported`,
108
- `deprecated` or `unsupported` (`unknown` on a hub from before versioning).
109
-
110
- The hub supports the current major and the previous one. Update with
111
- `npm update @diffenderfer-games/hub`.
112
-
113
- ## hub-doctor
114
-
115
- Run it in a game's folder, in CI and before pushing:
116
-
117
- ```sh
118
- npx hub-doctor # checks against https://diffenderfer.games
119
- npx hub-doctor --offline # skip the version check
120
- npx hub-doctor --hub http://localhost:8080 --dir ../my-game --json
121
- ```
122
-
123
- It fails when the installed client is outside the hub's `supported` range or
124
- the `package.json` `game.*` block does not match the manifest schema, and it
125
- warns when the client is deprecated or a vendored `src/hub/` copy (or
126
- `scripts/sync-hub.mjs`) is still around.
127
-
128
- ## Moving from the vendored copy
129
-
130
- 1. `npm install @diffenderfer-games/hub`.
131
- 2. Change `from './hub/hub'` (or `'./hub'`) to `from '@diffenderfer-games/hub'`.
132
- 3. Delete `src/hub/` and `scripts/sync-hub.mjs`.
133
- 4. Add `npx hub-doctor` to the game's CI.
134
-
135
- Every method name is unchanged.
136
-
137
- ## License
138
-
139
- MIT
1
+ # @diffenderfer-games/hub
2
+
3
+ The client library for games on [diffenderfer.games](https://diffenderfer.games):
4
+ accounts, saves, stats, leaderboards, inventory and trades, daily challenges,
5
+ the input system (keyboard, touch and gamepad), and the social, multiplayer,
6
+ rooms and race namespaces. It is typed from the hub's wire contract
7
+ (`@diffenderfer-games/hub-contract`), ships ES modules with `.d.ts` files, and
8
+ carries no zod at runtime.
9
+
10
+ ## Install
11
+
12
+ ```sh
13
+ npm install @diffenderfer-games/hub
14
+ ```
15
+
16
+ **Prereleases: pin the exact version.** While the package is on `2.0.0-next.N`,
17
+ a caret range does not move between prereleases the way you might expect, so
18
+ install with `--save-exact` and bump on purpose:
19
+
20
+ ```sh
21
+ npm install --save-exact @diffenderfer-games/hub@2.0.0-next.1
22
+ ```
23
+
24
+ The `next` dist-tag always names the newest prerelease. `latest` points at the
25
+ same prerelease for now. It moves to `2.0.0` with the first stable release,
26
+ after which ordinary `^2.0.0` ranges are fine.
27
+
28
+ ESM only, for browsers (ES2020: Safari 14+, current Chrome, Edge and Firefox).
29
+ Node 20+ for the `hub-doctor` command.
30
+
31
+ ## Use
32
+
33
+ ```ts
34
+ import { hub } from '@diffenderfer-games/hub';
35
+
36
+ const { user } = await hub.me();
37
+ await hub.ensureGuest(); // a guest account, so progress saves without a sign-in
38
+ await hub.putSave('auto', { level: 7, gold: 120 });
39
+ await hub.submitScore('highscore', 9001, { title: 'High Score' });
40
+ hub.recordPlay();
41
+
42
+ hub.input.define({ groups: { play: { inputs: { jump: { keys: [' '], gamepad: { button: 0 } } } } } });
43
+ hub.input.enable('play');
44
+ hub.daily.define({ play: (challenge) => startLevel(challenge.seed) });
45
+ hub.overlay.autoPause({ pause, resume });
46
+ ```
47
+
48
+ In a game the host serves, the slug and the API base are read from the page.
49
+ For anything else, create a client yourself:
50
+
51
+ ```ts
52
+ import { createHub } from '@diffenderfer-games/hub';
53
+
54
+ const demo = createHub({ slug: 'my-game', apiBase: '/_api', offline: 'auto' });
55
+ ```
56
+
57
+ A game's own JSON is typed by the game: `hub.getSave<MySave>('auto')`,
58
+ `hub.putSave<MySave>('auto', save)`, `hub.getProfile<MyProfile>()`.
59
+
60
+ ## Entry points
61
+
62
+ | Import | What it has |
63
+ |---|---|
64
+ | `@diffenderfer-games/hub` | `hub`, `createHub`, `Hub`, the errors, every client type, and the input and daily exports |
65
+ | `@diffenderfer-games/hub/input` | `getInput`, `InputSystem`, the on-screen control layout, `getUiStack` |
66
+ | `@diffenderfer-games/hub/daily` | `getDaily`, `DailySystem` |
67
+ | `@diffenderfer-games/hub/race`, `/social`, `/mp`, `/rooms` | one namespace each (`race`, `social` with `presence` and `notify`, `mp`, `rooms`) |
68
+ | `@diffenderfer-games/hub/types` | type-only: every contract type (requests, replies, entities, error codes, socket ops and events, the `game.*` manifest) |
69
+ | `@diffenderfer-games/hub/auto` | everything above, and it sets `window.HubSDK` (what `/_hub/hub.js` is built from) |
70
+
71
+ The namespaces also hang off `hub` (`hub.input`, `hub.daily`, `hub.race`,
72
+ `hub.social`, `hub.presence`, `hub.notify`, `hub.mp`, `hub.rooms`,
73
+ `hub.overlay`, `hub.menu`), created on first use.
74
+
75
+ ## Errors
76
+
77
+ Every call rejects with a `HubError` when it fails. `status` is the HTTP
78
+ status, or `undefined` when the hub could not be reached (`isOffline`).
79
+ `code`, `reason`, `hint` and `retryAfterMs` come from the hub's error body.
80
+
81
+ - `ContentRejectedError`: the safety filter refused some text (HTTP 422).
82
+ Keep the player's draft and show `hint`.
83
+ - `OfflineError`: an action that needs the hub was tried offline.
84
+ - `code: 'unsupported_by_hub'`: the hub does not have this call yet (the game
85
+ uses a newer client than the deployed hub). Deploy the hub first.
86
+
87
+ The analytics calls (`recordPlay`, `heartbeat`, `event`) never throw.
88
+
89
+ ## Offline
90
+
91
+ With `offline: 'auto'` (the default), reads fall back to a cache in
92
+ `localStorage` when the hub can't be reached, and writes (saves, stats,
93
+ scores, profile, daily completions, inventory grants and exchanges, stars)
94
+ apply to the cache at once and are queued in an outbox. The outbox replays
95
+ in order when the connection returns (and after a reload), one tab at a
96
+ time, and the hub applies each replayed call once. `hub.sync()` replays it
97
+ on demand, `hub.pending()` counts what waits, and `hub.onStatus(listener)`
98
+ reports changes. `hub.prefetchAll()` warms the cache for every game in one
99
+ request. `offline: 'always'` never touches the network (develop without a
100
+ hub); `offline: 'never'` always throws instead.
101
+
102
+ Queue your own operations, with a handler that may make several dependent
103
+ calls:
104
+
105
+ ```ts
106
+ hub.offline.define<{ score: number }>('my-game.finish', async (run, context) => {
107
+ const { rank } = await context.call('submitScore', { slug: 'my-game', key: 'runs', score: run.score });
108
+ await context.call('updateGameStat', { slug: 'my-game', key: 'best-rank', value: rank ?? 0, mode: 'max' });
109
+ });
110
+ hub.offline.enqueue('my-game.finish', { score: 4200 });
111
+ hub.offline.on('failed', ({ op, error }) => console.warn(op.kind, error));
112
+ ```
113
+
114
+ The full rules (what replays, ordering, retries, the size cap) are in the
115
+ hub docs' "Offline and replay" section. The cache keeps the old vendored
116
+ client's `localStorage` keys, and its queue moves into the outbox, so a game
117
+ that switches to this package keeps its players' queued progress.
118
+
119
+ ## Games without a build step
120
+
121
+ Keep `import('/_hub/hub.js')` or `window.HubSDK.hub`: the host serves a
122
+ bundle of this package's `./auto` entry, at the version the host was built
123
+ with. Install the package as a dev dependency only if you want editor types:
124
+
125
+ ```js
126
+ /** @type {import('@diffenderfer-games/hub').Hub} */
127
+ const hub = window.HubSDK.hub;
128
+ ```
129
+
130
+ ## Sharing the page with the host's `/_hub/hub.js`
131
+
132
+ Every game page also gets the host's menu and social runtime, which use the
133
+ host's own copy of this client (`/_hub/hub.js`, built from the version the host
134
+ was deployed with). Your bundled copy and the host's cooperate. The page-wide
135
+ pieces (the input system, daily challenges, the realtime API) are registered
136
+ once on `window.__DG__`, each with the version that created it:
137
+
138
+ - **Same shape** (the usual case): the first one wins and both copies share
139
+ it, so an older patch version on either side is harmless.
140
+ - **A different shape** (a major change): your game's copy owns input and
141
+ daily; the host's runtime owns realtime. The mismatch is logged once in the
142
+ console with the fix: `npm update @diffenderfer-games/hub`.
143
+ - **A v1 vendored copy** already on the page is shared too, and recorded as
144
+ `{ version: 'v1' }`.
145
+
146
+ The v1 globals (`window.__HUB_INPUT__`, `__HUB_DAILY__`, `__HUB_RT__`) stay as
147
+ aliases. Don't create your own singletons; `hub.input`, `hub.daily` and the
148
+ forwarders always return the shared ones.
149
+
150
+ ## Versions
151
+
152
+ The client sends its version as `x-hub-client`. `hub.hubVersion()` reads the
153
+ hub's `GET /_api/version` (`{ server, contract, supported, deprecated }`) once
154
+ per page, and `hub.clientSupport()` says whether this client is `supported`,
155
+ `deprecated` or `unsupported` (`unknown` on a hub from before versioning).
156
+
157
+ The hub supports the current major and the previous one. Update with
158
+ `npm update @diffenderfer-games/hub`.
159
+
160
+ ## hub-doctor
161
+
162
+ Run it in a game's folder, in CI and before pushing:
163
+
164
+ ```sh
165
+ npx hub-doctor # checks against https://diffenderfer.games
166
+ npx hub-doctor --offline # skip the version check
167
+ npx hub-doctor --timeout 5000 # wait at most 5 s for the hub (default 10 s)
168
+ npx hub-doctor --hub http://localhost:8080 --dir ../my-game --json
169
+ ```
170
+
171
+ An unreachable or slow hub is an error (`hub unreachable at <url> (...)`) and
172
+ exits non-zero, so CI notices. Use `--offline` where CI has no network.
173
+
174
+ It fails when the installed client is outside the hub's `supported` range or
175
+ the `package.json` `game.*` block does not match the manifest schema, and it
176
+ warns when the client is deprecated or a vendored `src/hub/` copy (or
177
+ `scripts/sync-hub.mjs`) is still around.
178
+
179
+ ## Testing your game against the hub
180
+
181
+ The hub's test kit lives in the host repo (`test/helpers/`). Point your
182
+ game's tests at a checkout of it with `DG_HOST`; the default is
183
+ `../diffenderfer-games`. It boots a real hub on a free port for each test
184
+ file:
185
+
186
+ ```sh
187
+ DG_HOST=../diffenderfer-games HUB_IMPL=next npm run test:hub
188
+ ```
189
+
190
+ `HUB_IMPL=next` runs the TypeScript hub and host that production runs. Without
191
+ it, the kit boots the old hub (`src/index.js`), which is kept only as a
192
+ rollback path until it is deleted; test against `next`. The checkout needs
193
+ `npm ci` at its root and in `next/`.
194
+
195
+ ## Moving from the vendored copy
196
+
197
+ 1. `npm install @diffenderfer-games/hub`.
198
+ 2. Change `from './hub/hub'` (or `'./hub'`) to `from '@diffenderfer-games/hub'`.
199
+ 3. Delete `src/hub/` and `scripts/sync-hub.mjs`.
200
+ 4. Add `npx hub-doctor` to the game's CI.
201
+
202
+ Every method name is unchanged.
203
+
204
+ ## License
205
+
206
+ MIT
package/dist/auto.d.ts CHANGED
@@ -1,14 +1,14 @@
1
- import { a as RaceResultPlayer, c as RoomChatLine, d as RoomStateChange, f as SchemaOutput, i as RaceRecordPlayer, l as RoomMessage, m as Snapshot, n as Notice, o as RaceStatusEvent, p as ServerEvents, r as RaceHistory, s as RealtimeErrorShape, t as InviteCreated, u as RoomSeat } from "./shared/wire-types.js";
1
+ import { a as RaceRecordPlayer, c as RealtimeErrorShape, d as RoomSeat, f as RoomSeatChange, g as Snapshot, h as ServerEvents, i as RaceHistory, l as RoomChatLine, m as SchemaOutput, n as InviteLink, o as RaceResultPlayer, p as RoomStateChange, r as Notice, s as RaceStatusEvent, t as InviteCreated, u as RoomMessage } from "./shared/wire-types.js";
2
2
  import { _ as DailyStatus, a as isDailySystem, c as DailyAll, d as DailyCompletionMeta, f as DailyDefinition, g as DailyStartResponse, h as DailyHost, i as getDaily, l as DailyChallenge, m as DailyGameStatus, n as DailyCompletions, o as DAILY_START_EVENT, p as DailyEventDetail, r as DAILY_SINGLETON_API, s as DailySystem, t as DailyCompletion, u as DailyCompleteResponse } from "./shared/daily.js";
3
3
  import { $ as VirtualControlType, A as AxisSide, B as InputReading, C as parseInputOverrides, D as isPageInputControl, E as PageInputControl, F as InputConfig, G as NavElement, H as MenuBridge, I as InputDef, J as NavTarget, K as NavElementKind, L as InputEvents, M as EdgeOffsets, N as GamepadMapping, O as Anchor, P as GroupDef, Q as Vector, R as InputHost, S as isInputSystem, T as InputSystemOptions, U as MouseMapping, V as InputSource, W as NavBlurEvent, X as Rect, Y as NavigableDef, Z as TouchMapping, _ as boxesTouch, a as OverlayEdge, b as InputOptions, c as OverlayReason, d as LayoutOptions, et as VirtualDef, f as layoutControls, g as LayoutItem, h as LayoutBox, i as AutoPauseOptions, j as DraggedSpot, k as AxisDef, l as UiStack, m as Insets, n as getUiStack, nt as VirtualOverride, o as OverlayEvent, p as Overlay, q as NavFocusEvent, r as isUiStack, s as OverlayListener, t as UI_STACK_VERSION, tt as VirtualInputs, u as UiStackHandoff, v as controlSize, w as InputSystem, x as getInput, y as INPUT_SINGLETON_API, z as InputOverrides } from "./shared/input.js";
4
- import { a as JoinInfoEvent, i as InviteResult, n as HubMpApi, r as InviteOptions, t as BusyOptions } from "./shared/multiplayer-types.js";
4
+ import { a as InviteResult, i as InviteOptions, n as HubMpApi, o as JoinInfoEvent, r as InviteLinkMethods, t as BusyOptions } from "./shared/multiplayer-types.js";
5
5
  import { o as multiplayerForwarder } from "./shared/mp.js";
6
- import { a as RoomEvents, c as RoomSendOptions, i as RoomCreateOptions, l as RoomState, n as HubRoomsApi, o as RoomListOptions, r as JoinOptions, s as RoomSelf, t as HubRoom, u as RoomStateOptions } from "./shared/room-types.js";
6
+ import { a as RoomEvents, c as RoomSelf, d as RoomStateOptions, i as RoomCreateOptions, l as RoomSendOptions, n as HubRoomsApi, o as RoomListOptions, r as JoinOptions, s as RoomReclaimMethods, t as HubRoom, u as RoomState } from "./shared/room-types.js";
7
7
  import { a as RaceHistoryQuery, c as RaceRuntimeApi, i as RaceEvents, l as RaceStart, n as RaceCreateOptions, o as RaceHistoryViewOptions, r as RaceDefinition, s as RaceHudPlace, t as HubRaceApi } from "./shared/race-types.js";
8
8
  import { f as raceForwarder } from "./shared/race.js";
9
9
  import { n as roomsForwarder } from "./shared/rooms.js";
10
- import { $ as HubNotifyApi, A as RacerState, B as SuggestionStatus, C as RaceRecord, D as RaceStats, E as RaceState, F as ReportReason, G as REALTIME_READY_EVENT, H as isRealtimeApi, I as RoomInfo, J as RealtimeHubLink, K as REALTIME_SINGLETON_API, L as SocialConfig, M as Relation, N as ReportInput, O as Racer, P as ReportKind, Q as socialForwarder, R as SocialMe, S as RaceParams, T as RaceStatValue, U as REALTIME_FAILED_EVENT, V as findRealtimeApi, W as REALTIME_FEATURE_VERSION, X as notifyForwarder, Y as linkRealtimeToHub, Z as presenceForwarder, _ as PlayerLite, a as ErrorBody, at as SocialEvents, b as PresenceKind, c as JoinInfo, d as Message, et as HubPresenceApi, f as MessagesPage, g as PlayerCard, h as Party, i as Counts, it as SocialCounts, j as RecentPlayer, k as RacerResult, l as Launch, m as NotifyPrefs, n as ChatMode, nt as OpenInviteOptions, o as FriendEntry, p as NotifyChange, q as RealtimeApi, r as Conversation, rt as PlayerRef, s as Invite, t as Audience, tt as HubSocialApi, u as LaunchTicket, v as Presence, w as RaceResult, x as RaceOutcome, y as PresenceInput, z as Suggestion } from "./shared/social.js";
11
- import { $ as SubmitScoreResult, A as BoardWithTop, B as Json, C as CLIENT_VERSION_HEADER, D as QueuedScoreOptions, E as QueueOpInput, F as GlobalAnalytics, G as Profile, H as LeaderboardResult, I as HubOptions, J as SaveMeta, K as ProfileSummary, L as HubStatus, M as GameInfo, N as GameLeaderboards, O as BufferedEvent, P as GameRecords, Q as SubmitScoreOptions, R as Inventory, S as SyncResult, T as QueueOp, U as MeResponse, V as LeaderboardEntry, W as Metrics, X as SortDir, Y as SnapshotResponse, Z as Stats, _ as TradeNoteOptions, a as HubErrorDetails, b as StatResult, c as Hub, d as ClientSupport, et as User, f as HubMenuControl, g as TradeListOptions, h as TradeId, i as HubErrorCode, it as GamePayload, j as GameAnalytics, k as Board, l as createHub, m as TradeBundle, n as ContentRejectedError, nt as EndpointName, o as OfflineError, p as GrantBundle, q as Save, r as HubError, rt as EndpointReply, s as UNSUPPORTED_BY_HUB, t as HUB_CLIENT_VERSION, tt as EndpointFields, u as hub, v as AuthResponse, w as ProfilePatch, x as SyncConflict, y as ProfileUpdate, z as InventorySnapshot } from "./shared/index.js";
10
+ import { $ as HubNotifyApi, A as RacerState, B as SuggestionStatus, C as RaceRecord, D as RaceStats, E as RaceState, F as ReportReason, G as REALTIME_READY_EVENT, H as isRealtimeApi, I as RoomInfo, J as RealtimeHubLink, K as REALTIME_SINGLETON_API, L as SocialConfig, M as Relation, N as ReportInput, O as Racer, P as ReportKind, Q as socialForwarder, R as SocialMe, S as RaceParams, T as RaceStatValue, U as REALTIME_FAILED_EVENT, V as findRealtimeApi, W as REALTIME_FEATURE_VERSION, X as notifyForwarder, Y as linkRealtimeToHub, Z as presenceForwarder, _ as PlayerLite, a as ErrorBody, at as SocialCounts, b as PresenceKind, c as JoinInfo, d as Message, et as HubPresenceApi, f as MessagesPage, g as PlayerCard, h as Party, i as Counts, it as PlayerRef, j as RecentPlayer, k as RacerResult, l as Launch, m as NotifyPrefs, n as ChatMode, nt as OpenInviteOptions, o as FriendEntry, ot as SocialEvents, p as NotifyChange, q as RealtimeApi, r as Conversation, rt as PlayOnlineMethods, s as Invite, t as Audience, tt as HubSocialApi, u as LaunchTicket, v as Presence, w as RaceResult, x as RaceOutcome, y as PresenceInput, z as Suggestion } from "./shared/social.js";
11
+ import { $ as LeaderboardResult, A as OUTBOX_MAX_ENTRIES, B as Board, C as OfflineApi, D as OfflineListener, E as OfflineEventName, F as ProfilePatch, G as GameRecords, H as GameAnalytics, I as QueueOp, J as HubStatus, K as GlobalAnalytics, L as QueueOpInput, M as OfflineKindDefinition, N as ReplayContext, O as OfflineOp, P as CLIENT_VERSION_HEADER, Q as LeaderboardEntry, R as QueuedScoreOptions, S as SyncResult, T as OfflineEventDetails, U as GameInfo, V as BoardWithTop, W as GameLeaderboards, X as InventorySnapshot, Y as Inventory, Z as Json, _ as TradeNoteOptions, a as HubErrorDetails, at as SaveMeta, b as StatResult, c as Hub, ct as Stats, d as ClientSupport, dt as User, et as MeResponse, f as HubMenuControl, ft as EndpointFields, g as TradeListOptions, h as TradeId, ht as GamePayload, i as HubErrorCode, it as Save, j as OfflineHandler, k as OUTBOX_MAX_CHARS, l as createHub, lt as SubmitScoreOptions, m as TradeBundle, mt as EndpointReply, n as ContentRejectedError, nt as Profile, o as OfflineError, ot as SnapshotResponse, p as GrantBundle, pt as EndpointName, q as HubOptions, r as HubError, rt as ProfileSummary, s as UNSUPPORTED_BY_HUB, st as SortDir, t as HUB_CLIENT_VERSION, tt as Metrics, u as hub, ut as SubmitScoreResult, v as AuthResponse, w as OUTBOX_FULL_CODE, x as SyncConflict, y as ProfileUpdate, z as BufferedEvent } from "./shared/index.js";
12
12
  //#region src/auto.d.ts
13
13
  /** What `window.HubSDK` holds. */
14
14
  export interface HubSdkGlobal {
@@ -32,5 +32,5 @@ declare global {
32
32
  }
33
33
  }
34
34
  //#endregion
35
- export { type Anchor, type Audience, type AuthResponse, type AutoPauseOptions, type AxisDef, type AxisSide, type Board, type BoardWithTop, type BufferedEvent, type BusyOptions, CLIENT_VERSION_HEADER, type ChatMode, type ClientSupport, ContentRejectedError, type Conversation, type Counts, DAILY_SINGLETON_API, DAILY_START_EVENT, type DailyAll, type DailyChallenge, type DailyCompleteResponse, type DailyCompletion, type DailyCompletionMeta, type DailyCompletions, type DailyDefinition, type DailyEventDetail, type DailyGameStatus, type DailyHost, type DailyStartResponse, type DailyStatus, DailySystem, type DraggedSpot, type EdgeOffsets, type EndpointFields, type EndpointName, type EndpointReply, type ErrorBody, type FriendEntry, type GameAnalytics, type GameInfo, type GameLeaderboards, type GamePayload, type GameRecords, type GamepadMapping, type GlobalAnalytics, type GrantBundle, type GroupDef, HUB_CLIENT_VERSION, Hub, HubError, type HubErrorCode, type HubErrorDetails, type HubMenuControl, type HubMpApi, type HubNotifyApi, type HubOptions, type HubPresenceApi, type HubRaceApi, type HubRoom, type HubRoomsApi, type HubSocialApi, type HubStatus, INPUT_SINGLETON_API, type InputConfig, type InputDef, type InputEvents, type InputHost, type InputOptions, type InputOverrides, type InputReading, type InputSource, InputSystem, type InputSystemOptions, type Insets, type Inventory, type InventorySnapshot, type Invite, type InviteCreated, type InviteOptions, type InviteResult, type JoinInfo, type JoinInfoEvent, type JoinOptions, type Json, type Launch, type LaunchTicket, type LayoutBox, type LayoutItem, type LayoutOptions, type LeaderboardEntry, type LeaderboardResult, type MeResponse, type MenuBridge, type Message, type MessagesPage, type Metrics, type MouseMapping, type NavBlurEvent, type NavElement, type NavElementKind, type NavFocusEvent, type NavTarget, type NavigableDef, type Notice, type NotifyChange, type NotifyPrefs, OfflineError, type OpenInviteOptions, Overlay, type OverlayEdge, type OverlayEvent, type OverlayListener, type OverlayReason, type PageInputControl, type Party, type PlayerCard, type PlayerLite, type PlayerRef, type Presence, type PresenceInput, type PresenceKind, type Profile, type ProfilePatch, type ProfileSummary, type ProfileUpdate, type QueueOp, type QueueOpInput, type QueuedScoreOptions, type REALTIME_FAILED_EVENT, type REALTIME_FEATURE_VERSION, type REALTIME_READY_EVENT, type REALTIME_SINGLETON_API, type RaceCreateOptions, type RaceDefinition, type RaceEvents, type RaceHistory, type RaceHistoryQuery, type RaceHistoryViewOptions, type RaceHudPlace, type RaceOutcome, type RaceParams, type RaceRecord, type RaceRecordPlayer, type RaceResult, type RaceResultPlayer, type RaceRuntimeApi, type RaceStart, type RaceStatValue, type RaceState, type RaceStats, type RaceStatusEvent, type Racer, type RacerResult, type RacerState, type RealtimeApi, type RealtimeErrorShape, type RealtimeHubLink, type RecentPlayer, type Rect, type Relation, type ReportInput, type ReportKind, type ReportReason, type RoomChatLine, type RoomCreateOptions, type RoomEvents, type RoomInfo, type RoomListOptions, type RoomMessage, type RoomSeat, type RoomSelf, type RoomSendOptions, type RoomState, type RoomStateChange, type RoomStateOptions, type Save, type SaveMeta, type SchemaOutput, type ServerEvents, type Snapshot, type SnapshotResponse, type SocialConfig, type SocialCounts, type SocialEvents, type SocialMe, type SortDir, type StatResult, type Stats, type SubmitScoreOptions, type SubmitScoreResult, type Suggestion, type SuggestionStatus, type SyncConflict, type SyncResult, type TouchMapping, type TradeBundle, type TradeId, type TradeListOptions, type TradeNoteOptions, UI_STACK_VERSION, UNSUPPORTED_BY_HUB, type UiStack, type UiStackHandoff, type User, type Vector, type VirtualControlType, type VirtualDef, type VirtualInputs, type VirtualOverride, boxesTouch, controlSize, createHub, type findRealtimeApi, getDaily, getInput, getUiStack, hub, isDailySystem, isInputSystem, isPageInputControl, type isRealtimeApi, isUiStack, layoutControls, type linkRealtimeToHub, type multiplayerForwarder as mp, type notifyForwarder as notify, parseInputOverrides, type presenceForwarder as presence, type raceForwarder as race, type roomsForwarder as rooms, type socialForwarder as social };
35
+ export { type Anchor, type Audience, type AuthResponse, type AutoPauseOptions, type AxisDef, type AxisSide, type Board, type BoardWithTop, type BufferedEvent, type BusyOptions, CLIENT_VERSION_HEADER, type ChatMode, type ClientSupport, ContentRejectedError, type Conversation, type Counts, DAILY_SINGLETON_API, DAILY_START_EVENT, type DailyAll, type DailyChallenge, type DailyCompleteResponse, type DailyCompletion, type DailyCompletionMeta, type DailyCompletions, type DailyDefinition, type DailyEventDetail, type DailyGameStatus, type DailyHost, type DailyStartResponse, type DailyStatus, DailySystem, type DraggedSpot, type EdgeOffsets, type EndpointFields, type EndpointName, type EndpointReply, type ErrorBody, type FriendEntry, type GameAnalytics, type GameInfo, type GameLeaderboards, type GamePayload, type GameRecords, type GamepadMapping, type GlobalAnalytics, type GrantBundle, type GroupDef, HUB_CLIENT_VERSION, Hub, HubError, type HubErrorCode, type HubErrorDetails, type HubMenuControl, type HubMpApi, type HubNotifyApi, type HubOptions, type HubPresenceApi, type HubRaceApi, type HubRoom, type HubRoomsApi, type HubSocialApi, type HubStatus, INPUT_SINGLETON_API, type InputConfig, type InputDef, type InputEvents, type InputHost, type InputOptions, type InputOverrides, type InputReading, type InputSource, InputSystem, type InputSystemOptions, type Insets, type Inventory, type InventorySnapshot, type Invite, type InviteCreated, type InviteLink, type InviteLinkMethods, type InviteOptions, type InviteResult, type JoinInfo, type JoinInfoEvent, type JoinOptions, type Json, type Launch, type LaunchTicket, type LayoutBox, type LayoutItem, type LayoutOptions, type LeaderboardEntry, type LeaderboardResult, type MeResponse, type MenuBridge, type Message, type MessagesPage, type Metrics, type MouseMapping, type NavBlurEvent, type NavElement, type NavElementKind, type NavFocusEvent, type NavTarget, type NavigableDef, type Notice, type NotifyChange, type NotifyPrefs, OUTBOX_FULL_CODE, OUTBOX_MAX_CHARS, OUTBOX_MAX_ENTRIES, OfflineApi, OfflineError, type OfflineEventDetails, type OfflineEventName, type OfflineHandler, type OfflineKindDefinition, type OfflineListener, type OfflineOp, type OpenInviteOptions, Overlay, type OverlayEdge, type OverlayEvent, type OverlayListener, type OverlayReason, type PageInputControl, type Party, type PlayOnlineMethods, type PlayerCard, type PlayerLite, type PlayerRef, type Presence, type PresenceInput, type PresenceKind, type Profile, type ProfilePatch, type ProfileSummary, type ProfileUpdate, type QueueOp, type QueueOpInput, type QueuedScoreOptions, type REALTIME_FAILED_EVENT, type REALTIME_FEATURE_VERSION, type REALTIME_READY_EVENT, type REALTIME_SINGLETON_API, type RaceCreateOptions, type RaceDefinition, type RaceEvents, type RaceHistory, type RaceHistoryQuery, type RaceHistoryViewOptions, type RaceHudPlace, type RaceOutcome, type RaceParams, type RaceRecord, type RaceRecordPlayer, type RaceResult, type RaceResultPlayer, type RaceRuntimeApi, type RaceStart, type RaceStatValue, type RaceState, type RaceStats, type RaceStatusEvent, type Racer, type RacerResult, type RacerState, type RealtimeApi, type RealtimeErrorShape, type RealtimeHubLink, type RecentPlayer, type Rect, type Relation, type ReplayContext, type ReportInput, type ReportKind, type ReportReason, type RoomChatLine, type RoomCreateOptions, type RoomEvents, type RoomInfo, type RoomListOptions, type RoomMessage, type RoomReclaimMethods, type RoomSeat, type RoomSeatChange, type RoomSelf, type RoomSendOptions, type RoomState, type RoomStateChange, type RoomStateOptions, type Save, type SaveMeta, type SchemaOutput, type ServerEvents, type Snapshot, type SnapshotResponse, type SocialConfig, type SocialCounts, type SocialEvents, type SocialMe, type SortDir, type StatResult, type Stats, type SubmitScoreOptions, type SubmitScoreResult, type Suggestion, type SuggestionStatus, type SyncConflict, type SyncResult, type TouchMapping, type TradeBundle, type TradeId, type TradeListOptions, type TradeNoteOptions, UI_STACK_VERSION, UNSUPPORTED_BY_HUB, type UiStack, type UiStackHandoff, type User, type Vector, type VirtualControlType, type VirtualDef, type VirtualInputs, type VirtualOverride, boxesTouch, controlSize, createHub, type findRealtimeApi, getDaily, getInput, getUiStack, hub, isDailySystem, isInputSystem, isPageInputControl, type isRealtimeApi, isUiStack, layoutControls, type linkRealtimeToHub, type multiplayerForwarder as mp, type notifyForwarder as notify, parseInputOverrides, type presenceForwarder as presence, type raceForwarder as race, type roomsForwarder as rooms, type socialForwarder as social };
36
36
  //# sourceMappingURL=auto.d.ts.map
package/dist/auto.js CHANGED
@@ -2,7 +2,7 @@ import { a as DailySystem, i as DAILY_START_EVENT, n as getDaily, r as isDailySy
2
2
  import { t as HUB_CLIENT_VERSION } from "./shared/client-version.gen.js";
3
3
  import { a as isPageInputControl, c as layoutControls, i as parseInputOverrides, l as boxesTouch, n as getInput, o as InputSystem, r as isInputSystem, s as Overlay, t as INPUT_SINGLETON_API, u as controlSize } from "./shared/input.js";
4
4
  import { n as isUiStack, r as UI_STACK_VERSION, t as getUiStack } from "./shared/page-stack.js";
5
- import { a as ContentRejectedError, c as UNSUPPORTED_BY_HUB, i as CLIENT_VERSION_HEADER, n as createHub, o as HubError, r as hub, s as OfflineError, t as Hub } from "./shared/src.js";
5
+ import { a as OUTBOX_FULL_CODE, c as OfflineApi, d as OfflineError, f as UNSUPPORTED_BY_HUB, i as CLIENT_VERSION_HEADER, l as ContentRejectedError, n as createHub, o as OUTBOX_MAX_CHARS, r as hub, s as OUTBOX_MAX_ENTRIES, t as Hub, u as HubError } from "./shared/src.js";
6
6
  //#region src/auto.ts
7
7
  /**
8
8
  * `@diffenderfer-games/hub/auto`: everything the main entry exports, plus a
@@ -22,6 +22,6 @@ if (typeof window !== "undefined") window.HubSDK = {
22
22
  ContentRejectedError
23
23
  };
24
24
  //#endregion
25
- export { CLIENT_VERSION_HEADER, ContentRejectedError, DAILY_SINGLETON_API, DAILY_START_EVENT, DailySystem, HUB_CLIENT_VERSION, Hub, HubError, INPUT_SINGLETON_API, InputSystem, OfflineError, Overlay, UI_STACK_VERSION, UNSUPPORTED_BY_HUB, boxesTouch, controlSize, createHub, getDaily, getInput, getUiStack, hub, isDailySystem, isInputSystem, isPageInputControl, isUiStack, layoutControls, parseInputOverrides };
25
+ export { CLIENT_VERSION_HEADER, ContentRejectedError, DAILY_SINGLETON_API, DAILY_START_EVENT, DailySystem, HUB_CLIENT_VERSION, Hub, HubError, INPUT_SINGLETON_API, InputSystem, OUTBOX_FULL_CODE, OUTBOX_MAX_CHARS, OUTBOX_MAX_ENTRIES, OfflineApi, OfflineError, Overlay, UI_STACK_VERSION, UNSUPPORTED_BY_HUB, boxesTouch, controlSize, createHub, getDaily, getInput, getUiStack, hub, isDailySystem, isInputSystem, isPageInputControl, isUiStack, layoutControls, parseInputOverrides };
26
26
 
27
27
  //# sourceMappingURL=auto.js.map