@diffenderfer-games/hub-contract 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 (81) hide show
  1. package/CHANGELOG.md +24 -0
  2. package/LICENSE +21 -21
  3. package/README.md +26 -26
  4. package/dist/index.d.ts +2683 -39
  5. package/dist/index.d.ts.map +1 -1
  6. package/dist/index.js +862 -18
  7. package/dist/index.js.map +1 -1
  8. package/package.json +53 -53
  9. package/src/api/analytics.ts +81 -81
  10. package/src/api/auth.ts +77 -77
  11. package/src/api/catalog-activity.ts +66 -0
  12. package/src/api/catalog.ts +177 -171
  13. package/src/api/daily.ts +122 -122
  14. package/src/api/economy/bundle.ts +69 -69
  15. package/src/api/index.ts +92 -85
  16. package/src/api/leaderboards.ts +151 -151
  17. package/src/api/messages.ts +142 -142
  18. package/src/api/mp/chat.ts +36 -36
  19. package/src/api/mp/invite-links.ts +42 -0
  20. package/src/api/mp/parties.ts +5 -0
  21. package/src/api/mp/races.ts +211 -211
  22. package/src/api/mp/rooms.ts +122 -90
  23. package/src/api/mp/snapshot.ts +17 -17
  24. package/src/api/mp.ts +135 -110
  25. package/src/api/notify.ts +114 -111
  26. package/src/api/offline.ts +45 -0
  27. package/src/api/progress/game-data.ts +189 -189
  28. package/src/api/progress.ts +59 -59
  29. package/src/api/race.ts +47 -47
  30. package/src/api/reports.ts +208 -208
  31. package/src/api/social/config.ts +47 -47
  32. package/src/api/social/endpoints.ts +179 -179
  33. package/src/api/social/people.ts +118 -118
  34. package/src/api/social/presence.ts +95 -95
  35. package/src/api/social.ts +9 -9
  36. package/src/api/tournaments/endpoints.ts +102 -0
  37. package/src/api/tournaments/play-online.ts +71 -0
  38. package/src/api/tournaments/shapes.ts +202 -0
  39. package/src/api/tournaments.ts +7 -0
  40. package/src/api/version.ts +40 -40
  41. package/src/coerce.ts +50 -50
  42. package/src/common.ts +42 -42
  43. package/src/entities.ts +62 -62
  44. package/src/errors/codes/core.ts +10 -10
  45. package/src/errors/codes/multiplayer.ts +56 -43
  46. package/src/errors/codes/play.ts +5 -5
  47. package/src/errors/codes/social.ts +31 -31
  48. package/src/errors/index.ts +88 -88
  49. package/src/index.ts +16 -16
  50. package/src/limits.ts +125 -100
  51. package/src/logic/daily.ts +54 -54
  52. package/src/logic/index.ts +8 -8
  53. package/src/logic/presence.ts +62 -62
  54. package/src/logic/time.ts +81 -81
  55. package/src/manifest/changes.ts +55 -55
  56. package/src/manifest/controls.ts +42 -42
  57. package/src/manifest/fields.ts +89 -89
  58. package/src/manifest/game.ts +139 -132
  59. package/src/manifest/index.ts +13 -12
  60. package/src/manifest/inject.ts +31 -31
  61. package/src/manifest/labels.ts +99 -0
  62. package/src/manifest/leaderboards.ts +29 -29
  63. package/src/manifest/multiplayer.ts +79 -71
  64. package/src/manifest/race.ts +93 -93
  65. package/src/middleware.ts +47 -47
  66. package/src/realtime/define.ts +52 -52
  67. package/src/realtime/envelope.ts +67 -67
  68. package/src/realtime/events/multiplayer.ts +9 -8
  69. package/src/realtime/events/parties.ts +31 -31
  70. package/src/realtime/events/races.ts +27 -27
  71. package/src/realtime/events/rooms.ts +52 -48
  72. package/src/realtime/events/social.ts +81 -81
  73. package/src/realtime/events/tournaments.ts +12 -0
  74. package/src/realtime/index.ts +24 -24
  75. package/src/realtime/ops/empty.ts +8 -8
  76. package/src/realtime/ops/hello.ts +40 -40
  77. package/src/realtime/ops/multiplayer.ts +8 -8
  78. package/src/realtime/ops/parties.ts +13 -13
  79. package/src/realtime/ops/races.ts +99 -99
  80. package/src/realtime/ops/rooms.ts +22 -8
  81. package/src/realtime/ops/social.ts +58 -58
package/CHANGELOG.md ADDED
@@ -0,0 +1,24 @@
1
+ # @diffenderfer-games/hub-contract
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
+ ## 2.0.0-next.1
21
+
22
+ ### Patch Changes
23
+
24
+ - 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.
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,26 +1,26 @@
1
- # @diffenderfer-games/hub-contract
2
-
3
- The public wire contract of the [diffenderfer.games](https://diffenderfer.games)
4
- hub: zod schemas and TypeScript types for the REST endpoints, socket ops and
5
- events, error bodies and the `game.*` manifest that games use.
6
-
7
- It describes only what a browser already sees: the requests and responses of
8
- the hub's public API. It contains no server code.
9
-
10
- ```bash
11
- npm i @diffenderfer-games/hub-contract zod
12
- ```
13
-
14
- ```ts
15
- import { ErrorBody } from '@diffenderfer-games/hub-contract';
16
-
17
- const body = ErrorBody.parse(await res.json());
18
- if (body.code === 'rate_limited') retryLater(body.retryAfterMs);
19
- ```
20
-
21
- `zod` (v4) is an optional peer dependency: you need it to import the schemas.
22
-
23
- ## Compatibility
24
-
25
- Versions follow the public contract: new endpoints, ops, events or optional
26
- fields are minor releases; removing or narrowing anything is a major release.
1
+ # @diffenderfer-games/hub-contract
2
+
3
+ The public wire contract of the [diffenderfer.games](https://diffenderfer.games)
4
+ hub: zod schemas and TypeScript types for the REST endpoints, socket ops and
5
+ events, error bodies and the `game.*` manifest that games use.
6
+
7
+ It describes only what a browser already sees: the requests and responses of
8
+ the hub's public API. It contains no server code.
9
+
10
+ ```bash
11
+ npm i @diffenderfer-games/hub-contract zod
12
+ ```
13
+
14
+ ```ts
15
+ import { ErrorBody } from '@diffenderfer-games/hub-contract';
16
+
17
+ const body = ErrorBody.parse(await res.json());
18
+ if (body.code === 'rate_limited') retryLater(body.retryAfterMs);
19
+ ```
20
+
21
+ `zod` (v4) is an optional peer dependency: you need it to import the schemas.
22
+
23
+ ## Compatibility
24
+
25
+ Versions follow the public contract: new endpoints, ops, events or optional
26
+ fields are minor releases; removing or narrowing anything is a major release.