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

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 (98) hide show
  1. package/CHANGELOG.md +9 -0
  2. package/LICENSE +21 -21
  3. package/README.md +191 -139
  4. package/dist/doctor/cli.mjs +49 -19
  5. package/dist/doctor/cli.mjs.map +1 -1
  6. package/dist/shared/client-version.gen.js +1 -1
  7. package/dist/shared/daily.js +1 -1
  8. package/dist/shared/globals.js +8 -3
  9. package/dist/shared/globals.js.map +1 -1
  10. package/dist/shared/index.d.ts +1 -1
  11. package/package.json +89 -89
  12. package/src/auto.ts +39 -39
  13. package/src/core/connection.ts +299 -299
  14. package/src/core/errors.ts +147 -147
  15. package/src/core/game-data.ts +38 -38
  16. package/src/core/hub-economy.ts +179 -179
  17. package/src/core/hub-progress.ts +205 -205
  18. package/src/core/hub.ts +131 -131
  19. package/src/core/menu-control.ts +61 -61
  20. package/src/core/offline/events.ts +50 -50
  21. package/src/core/offline/favorites.ts +21 -21
  22. package/src/core/offline/local-store.ts +261 -261
  23. package/src/core/offline/queue.ts +171 -171
  24. package/src/core/page.ts +74 -74
  25. package/src/core/rest/endpoint-types.ts +22 -22
  26. package/src/core/rest/rest-client.ts +152 -152
  27. package/src/core/storage/json-guards.ts +74 -74
  28. package/src/core/storage/key-value.ts +66 -66
  29. package/src/core/ticket.ts +43 -43
  30. package/src/core/types.ts +134 -134
  31. package/src/core/version/client-version.gen.ts +1 -1
  32. package/src/core/version/hub-version.ts +62 -62
  33. package/src/core/version/semver.ts +97 -97
  34. package/src/daily/daily-system.ts +161 -161
  35. package/src/daily/page-daily.ts +36 -36
  36. package/src/daily/types.ts +67 -67
  37. package/src/daily.ts +10 -10
  38. package/src/doctor/checks.ts +78 -76
  39. package/src/doctor/cli.ts +98 -106
  40. package/src/doctor/hub-version-fetch.ts +43 -0
  41. package/src/doctor/tsconfig.json +12 -12
  42. package/src/globals.ts +115 -110
  43. package/src/index.ts +50 -50
  44. package/src/input/device-state.ts +146 -146
  45. package/src/input/edges.ts +55 -55
  46. package/src/input/gamepad.ts +61 -61
  47. package/src/input/input-events.ts +32 -32
  48. package/src/input/input-registry.ts +164 -164
  49. package/src/input/input-system.ts +393 -393
  50. package/src/input/legacy-controls.ts +64 -64
  51. package/src/input/nav-state.ts +191 -191
  52. package/src/input/navigator.ts +171 -171
  53. package/src/input/on-screen-controls.ts +101 -101
  54. package/src/input/page-control.ts +43 -43
  55. package/src/input/page-input.ts +193 -193
  56. package/src/input/player-remaps.ts +77 -77
  57. package/src/input/source-values.ts +116 -116
  58. package/src/input/spatial.ts +47 -47
  59. package/src/input/types.ts +331 -331
  60. package/src/input/zero-config.ts +177 -177
  61. package/src/input.ts +22 -22
  62. package/src/mp.ts +10 -10
  63. package/src/overlay/controls-panel.ts +163 -163
  64. package/src/overlay/dom.ts +46 -46
  65. package/src/overlay/layout-clusters.ts +162 -162
  66. package/src/overlay/layout-geometry.ts +136 -136
  67. package/src/overlay/layout.ts +203 -203
  68. package/src/overlay/listener-scope.ts +23 -23
  69. package/src/overlay/on-screen-keyboard.ts +137 -137
  70. package/src/overlay/overlay.ts +208 -208
  71. package/src/overlay/styles.ts +9 -9
  72. package/src/overlay/virtual-controls.ts +262 -262
  73. package/src/race.ts +10 -10
  74. package/src/realtime/bridge.ts +121 -121
  75. package/src/realtime/cross-bundle.ts +29 -29
  76. package/src/realtime/fallback-notice.ts +48 -48
  77. package/src/realtime/hub-link.ts +65 -65
  78. package/src/realtime/latest-state.ts +33 -33
  79. package/src/realtime/multiplayer-forwarder.ts +28 -28
  80. package/src/realtime/multiplayer-types.ts +52 -52
  81. package/src/realtime/page-runtime.ts +60 -60
  82. package/src/realtime/race-forwarder.ts +59 -59
  83. package/src/realtime/race-types.ts +132 -132
  84. package/src/realtime/room-types.ts +125 -125
  85. package/src/realtime/rooms-forwarder.ts +79 -79
  86. package/src/realtime/runtime-api.ts +49 -49
  87. package/src/realtime/runtime-opener.ts +61 -61
  88. package/src/realtime/social-forwarder.ts +72 -72
  89. package/src/realtime/social-types.ts +78 -78
  90. package/src/realtime/types.ts +53 -53
  91. package/src/realtime/wire-types.ts +72 -72
  92. package/src/rooms.ts +10 -10
  93. package/src/social.ts +18 -18
  94. package/src/types.ts +13 -13
  95. package/src/uistack/page-stack.ts +45 -45
  96. package/src/uistack/play-suspension.ts +82 -82
  97. package/src/uistack/types.ts +76 -76
  98. package/src/uistack/ui-stack.ts +144 -144
@@ -1,177 +1,177 @@
1
- /**
2
- * The zero-config fallback for games that never call `hub.input.define()`:
3
- * on the catalog page a gamepad moves a highlight across the game tiles; in
4
- * a game it presses the keys `game.controls` maps its buttons to. Runs each
5
- * frame only while the menu is closed and no game has taken over input.
6
- */
7
- import type { RepeatingEdges } from './edges';
8
- import { anyPadDirections, isAnyPadButtonPressed, isPadButtonPressed, PAD_BUTTON, padDirections } from './gamepad';
9
- import type { Direction } from './gamepad';
10
- import type { LegacyControls } from './legacy-controls';
11
- import { controlMapFor } from './legacy-controls';
12
- import { findNearestInDirection, rectOf } from './spatial';
13
- import { isTypingTarget } from './device-state';
14
-
15
- /** Synthetic keys stay pressed past half deflection. */
16
- const SYNTH_DEADZONE = 0.5;
17
- const FOCUS_CLASS = 'gp-focus';
18
- const FOCUS_STYLE_ID = 'gp-focus-style';
19
- const FOCUS_CSS = '.gp-focus{outline:3px solid #ff5f3b !important;outline-offset:2px;border-radius:4px;}';
20
-
21
- /** `KeyboardEvent.code` → its `key` and legacy `keyCode`. */
22
- const KEY_FOR_CODE = new Map<string, readonly [string, number]>([
23
- ['ArrowUp', ['ArrowUp', 38]], ['ArrowDown', ['ArrowDown', 40]], ['ArrowLeft', ['ArrowLeft', 37]], ['ArrowRight', ['ArrowRight', 39]],
24
- ['Space', [' ', 32]], ['Enter', ['Enter', 13]], ['Escape', ['Escape', 27]], ['Tab', ['Tab', 9]], ['Backspace', ['Backspace', 8]],
25
- ['ShiftLeft', ['Shift', 16]], ['ControlLeft', ['Control', 17]], ['AltLeft', ['Alt', 18]],
26
- ]);
27
- for (let code = 65; code <= 90; code += 1) {
28
- const letter = String.fromCharCode(code);
29
- KEY_FOR_CODE.set(`Key${letter}`, [letter.toLowerCase(), code]);
30
- }
31
- for (let digit = 0; digit <= 9; digit += 1) {
32
- KEY_FOR_CODE.set(`Digit${String(digit)}`, [String(digit), 48 + digit]);
33
- }
34
-
35
- /** What the fallback reads from the input system each frame. */
36
- export interface ZeroConfigFrame {
37
- readonly gamepads: readonly Gamepad[];
38
- readonly slug: string | null;
39
- readonly controls: LegacyControls;
40
- readonly navEdges: RepeatingEdges;
41
- }
42
-
43
- /** Dispatch a synthetic key event (with the legacy `keyCode`/`which` old games read) on the focused element. */
44
- function dispatchKey(type: 'keydown' | 'keyup', code: string): void {
45
- const [key, keyCode] = KEY_FOR_CODE.get(code) ?? [code, 0];
46
- const active = document.activeElement;
47
- const target: EventTarget = active !== null && active !== document.body ? active : document.body;
48
- const event = new KeyboardEvent(type, { key, code, bubbles: true, cancelable: true });
49
- Object.defineProperty(event, 'keyCode', { get: () => keyCode });
50
- Object.defineProperty(event, 'which', { get: () => keyCode });
51
- target.dispatchEvent(event);
52
- }
53
-
54
- /** Add the highlight style to the page once. */
55
- function ensureFocusStyle(): void {
56
- if (document.getElementById(FOCUS_STYLE_ID) !== null) {
57
- return;
58
- }
59
- const style = document.createElement('style');
60
- style.id = FOCUS_STYLE_ID;
61
- style.textContent = FOCUS_CSS;
62
- document.head.appendChild(style);
63
- }
64
-
65
- /** The keys each pad holds down, by pad index. */
66
- const heldCodes = new Map<number, Set<string>>();
67
-
68
- function releaseAllKeys(): void {
69
- for (const [padIndex, codes] of heldCodes) {
70
- for (const code of codes) {
71
- dispatchKey('keyup', code);
72
- }
73
- heldCodes.set(padIndex, new Set());
74
- }
75
- }
76
-
77
- /** In a game: press and release the mapped keys to match each pad. */
78
- function synthesizeKeys(frame: ZeroConfigFrame): void {
79
- if (isTypingTarget(document.activeElement)) {
80
- releaseAllKeys();
81
- return;
82
- }
83
- frame.gamepads.forEach((pad, padIndex) => {
84
- const map = controlMapFor(frame.controls, padIndex);
85
- const directions = padDirections(pad, SYNTH_DEADZONE);
86
- const wanted = new Set<string>();
87
- for (const direction of ['up', 'down', 'left', 'right'] as const) {
88
- if (directions[direction]) {
89
- wanted.add(map[direction]);
90
- }
91
- }
92
- for (const [buttonIndex, code] of map.buttons) {
93
- if (isPadButtonPressed(pad, buttonIndex)) {
94
- wanted.add(code);
95
- }
96
- }
97
- const held = heldCodes.get(padIndex) ?? new Set<string>();
98
- wanted.forEach((code) => {
99
- if (!held.has(code)) {
100
- dispatchKey('keydown', code);
101
- }
102
- });
103
- held.forEach((code) => {
104
- if (!wanted.has(code)) {
105
- dispatchKey('keyup', code);
106
- }
107
- });
108
- heldCodes.set(padIndex, wanted);
109
- });
110
- }
111
-
112
- /** The visible game tiles on the catalog page. */
113
- function visibleTiles(): HTMLElement[] {
114
- return [...document.querySelectorAll<HTMLElement>('.grid .card')].filter((card) => card.offsetParent !== null);
115
- }
116
-
117
- function highlightTile(tiles: readonly HTMLElement[], index: number): void {
118
- tiles.forEach((tile) => {
119
- tile.classList.remove(FOCUS_CLASS);
120
- });
121
- const tile = tiles[index];
122
- tile?.classList.add(FOCUS_CLASS);
123
- tile?.scrollIntoView({ block: 'nearest', inline: 'nearest' });
124
- }
125
-
126
- /** On the catalog page: move the highlight across the tiles; A or Start opens one. */
127
- function navigateCatalog(frame: ZeroConfigFrame): void {
128
- const held = anyPadDirections(frame.gamepads, SYNTH_DEADZONE);
129
- const isAccepting = isAnyPadButtonPressed(frame.gamepads, PAD_BUTTON.A) || isAnyPadButtonPressed(frame.gamepads, PAD_BUTTON.START);
130
- const fired: Record<Direction, boolean> = {
131
- up: frame.navEdges.fires('lu', held.up),
132
- down: frame.navEdges.fires('ld', held.down),
133
- left: frame.navEdges.fires('ll', held.left),
134
- right: frame.navEdges.fires('lr', held.right),
135
- };
136
- const shouldAccept = frame.navEdges.fires('la', isAccepting) && isAccepting;
137
- const tiles = visibleTiles();
138
- if (tiles.length === 0) {
139
- return;
140
- }
141
- const focused = tiles.findIndex((tile) => tile.classList.contains(FOCUS_CLASS));
142
- const focusedTile = tiles[focused];
143
- if (focusedTile === undefined) {
144
- highlightTile(tiles, 0);
145
- return;
146
- }
147
- if (shouldAccept) {
148
- const href = focusedTile.getAttribute('href');
149
- if (href === null) {
150
- focusedTile.click();
151
- } else {
152
- location.href = href;
153
- }
154
- return;
155
- }
156
- const direction = (['up', 'down', 'left', 'right'] as const).find((candidate) => fired[candidate]);
157
- if (direction === undefined) {
158
- return;
159
- }
160
- const next = findNearestInDirection(tiles.map(rectOf), focused, direction);
161
- if (next >= 0) {
162
- highlightTile(tiles, next);
163
- }
164
- }
165
-
166
- /** One frame of the zero-config fallback. */
167
- export function runZeroConfigFrame(frame: ZeroConfigFrame): void {
168
- if (frame.gamepads.length === 0) {
169
- return;
170
- }
171
- ensureFocusStyle();
172
- if (frame.slug === null) {
173
- navigateCatalog(frame);
174
- } else {
175
- synthesizeKeys(frame);
176
- }
177
- }
1
+ /**
2
+ * The zero-config fallback for games that never call `hub.input.define()`:
3
+ * on the catalog page a gamepad moves a highlight across the game tiles; in
4
+ * a game it presses the keys `game.controls` maps its buttons to. Runs each
5
+ * frame only while the menu is closed and no game has taken over input.
6
+ */
7
+ import type { RepeatingEdges } from './edges';
8
+ import { anyPadDirections, isAnyPadButtonPressed, isPadButtonPressed, PAD_BUTTON, padDirections } from './gamepad';
9
+ import type { Direction } from './gamepad';
10
+ import type { LegacyControls } from './legacy-controls';
11
+ import { controlMapFor } from './legacy-controls';
12
+ import { findNearestInDirection, rectOf } from './spatial';
13
+ import { isTypingTarget } from './device-state';
14
+
15
+ /** Synthetic keys stay pressed past half deflection. */
16
+ const SYNTH_DEADZONE = 0.5;
17
+ const FOCUS_CLASS = 'gp-focus';
18
+ const FOCUS_STYLE_ID = 'gp-focus-style';
19
+ const FOCUS_CSS = '.gp-focus{outline:3px solid #ff5f3b !important;outline-offset:2px;border-radius:4px;}';
20
+
21
+ /** `KeyboardEvent.code` → its `key` and legacy `keyCode`. */
22
+ const KEY_FOR_CODE = new Map<string, readonly [string, number]>([
23
+ ['ArrowUp', ['ArrowUp', 38]], ['ArrowDown', ['ArrowDown', 40]], ['ArrowLeft', ['ArrowLeft', 37]], ['ArrowRight', ['ArrowRight', 39]],
24
+ ['Space', [' ', 32]], ['Enter', ['Enter', 13]], ['Escape', ['Escape', 27]], ['Tab', ['Tab', 9]], ['Backspace', ['Backspace', 8]],
25
+ ['ShiftLeft', ['Shift', 16]], ['ControlLeft', ['Control', 17]], ['AltLeft', ['Alt', 18]],
26
+ ]);
27
+ for (let code = 65; code <= 90; code += 1) {
28
+ const letter = String.fromCharCode(code);
29
+ KEY_FOR_CODE.set(`Key${letter}`, [letter.toLowerCase(), code]);
30
+ }
31
+ for (let digit = 0; digit <= 9; digit += 1) {
32
+ KEY_FOR_CODE.set(`Digit${String(digit)}`, [String(digit), 48 + digit]);
33
+ }
34
+
35
+ /** What the fallback reads from the input system each frame. */
36
+ export interface ZeroConfigFrame {
37
+ readonly gamepads: readonly Gamepad[];
38
+ readonly slug: string | null;
39
+ readonly controls: LegacyControls;
40
+ readonly navEdges: RepeatingEdges;
41
+ }
42
+
43
+ /** Dispatch a synthetic key event (with the legacy `keyCode`/`which` old games read) on the focused element. */
44
+ function dispatchKey(type: 'keydown' | 'keyup', code: string): void {
45
+ const [key, keyCode] = KEY_FOR_CODE.get(code) ?? [code, 0];
46
+ const active = document.activeElement;
47
+ const target: EventTarget = active !== null && active !== document.body ? active : document.body;
48
+ const event = new KeyboardEvent(type, { key, code, bubbles: true, cancelable: true });
49
+ Object.defineProperty(event, 'keyCode', { get: () => keyCode });
50
+ Object.defineProperty(event, 'which', { get: () => keyCode });
51
+ target.dispatchEvent(event);
52
+ }
53
+
54
+ /** Add the highlight style to the page once. */
55
+ function ensureFocusStyle(): void {
56
+ if (document.getElementById(FOCUS_STYLE_ID) !== null) {
57
+ return;
58
+ }
59
+ const style = document.createElement('style');
60
+ style.id = FOCUS_STYLE_ID;
61
+ style.textContent = FOCUS_CSS;
62
+ document.head.appendChild(style);
63
+ }
64
+
65
+ /** The keys each pad holds down, by pad index. */
66
+ const heldCodes = new Map<number, Set<string>>();
67
+
68
+ function releaseAllKeys(): void {
69
+ for (const [padIndex, codes] of heldCodes) {
70
+ for (const code of codes) {
71
+ dispatchKey('keyup', code);
72
+ }
73
+ heldCodes.set(padIndex, new Set());
74
+ }
75
+ }
76
+
77
+ /** In a game: press and release the mapped keys to match each pad. */
78
+ function synthesizeKeys(frame: ZeroConfigFrame): void {
79
+ if (isTypingTarget(document.activeElement)) {
80
+ releaseAllKeys();
81
+ return;
82
+ }
83
+ frame.gamepads.forEach((pad, padIndex) => {
84
+ const map = controlMapFor(frame.controls, padIndex);
85
+ const directions = padDirections(pad, SYNTH_DEADZONE);
86
+ const wanted = new Set<string>();
87
+ for (const direction of ['up', 'down', 'left', 'right'] as const) {
88
+ if (directions[direction]) {
89
+ wanted.add(map[direction]);
90
+ }
91
+ }
92
+ for (const [buttonIndex, code] of map.buttons) {
93
+ if (isPadButtonPressed(pad, buttonIndex)) {
94
+ wanted.add(code);
95
+ }
96
+ }
97
+ const held = heldCodes.get(padIndex) ?? new Set<string>();
98
+ wanted.forEach((code) => {
99
+ if (!held.has(code)) {
100
+ dispatchKey('keydown', code);
101
+ }
102
+ });
103
+ held.forEach((code) => {
104
+ if (!wanted.has(code)) {
105
+ dispatchKey('keyup', code);
106
+ }
107
+ });
108
+ heldCodes.set(padIndex, wanted);
109
+ });
110
+ }
111
+
112
+ /** The visible game tiles on the catalog page. */
113
+ function visibleTiles(): HTMLElement[] {
114
+ return [...document.querySelectorAll<HTMLElement>('.grid .card')].filter((card) => card.offsetParent !== null);
115
+ }
116
+
117
+ function highlightTile(tiles: readonly HTMLElement[], index: number): void {
118
+ tiles.forEach((tile) => {
119
+ tile.classList.remove(FOCUS_CLASS);
120
+ });
121
+ const tile = tiles[index];
122
+ tile?.classList.add(FOCUS_CLASS);
123
+ tile?.scrollIntoView({ block: 'nearest', inline: 'nearest' });
124
+ }
125
+
126
+ /** On the catalog page: move the highlight across the tiles; A or Start opens one. */
127
+ function navigateCatalog(frame: ZeroConfigFrame): void {
128
+ const held = anyPadDirections(frame.gamepads, SYNTH_DEADZONE);
129
+ const isAccepting = isAnyPadButtonPressed(frame.gamepads, PAD_BUTTON.A) || isAnyPadButtonPressed(frame.gamepads, PAD_BUTTON.START);
130
+ const fired: Record<Direction, boolean> = {
131
+ up: frame.navEdges.fires('lu', held.up),
132
+ down: frame.navEdges.fires('ld', held.down),
133
+ left: frame.navEdges.fires('ll', held.left),
134
+ right: frame.navEdges.fires('lr', held.right),
135
+ };
136
+ const shouldAccept = frame.navEdges.fires('la', isAccepting) && isAccepting;
137
+ const tiles = visibleTiles();
138
+ if (tiles.length === 0) {
139
+ return;
140
+ }
141
+ const focused = tiles.findIndex((tile) => tile.classList.contains(FOCUS_CLASS));
142
+ const focusedTile = tiles[focused];
143
+ if (focusedTile === undefined) {
144
+ highlightTile(tiles, 0);
145
+ return;
146
+ }
147
+ if (shouldAccept) {
148
+ const href = focusedTile.getAttribute('href');
149
+ if (href === null) {
150
+ focusedTile.click();
151
+ } else {
152
+ location.href = href;
153
+ }
154
+ return;
155
+ }
156
+ const direction = (['up', 'down', 'left', 'right'] as const).find((candidate) => fired[candidate]);
157
+ if (direction === undefined) {
158
+ return;
159
+ }
160
+ const next = findNearestInDirection(tiles.map(rectOf), focused, direction);
161
+ if (next >= 0) {
162
+ highlightTile(tiles, next);
163
+ }
164
+ }
165
+
166
+ /** One frame of the zero-config fallback. */
167
+ export function runZeroConfigFrame(frame: ZeroConfigFrame): void {
168
+ if (frame.gamepads.length === 0) {
169
+ return;
170
+ }
171
+ ensureFocusStyle();
172
+ if (frame.slug === null) {
173
+ navigateCatalog(frame);
174
+ } else {
175
+ synthesizeKeys(frame);
176
+ }
177
+ }
package/src/input.ts CHANGED
@@ -1,22 +1,22 @@
1
- /**
2
- * `@diffenderfer-games/hub/input`: the input system (`hub.input`): the
3
- * page-wide {@link getInput}, the {@link InputSystem} class, the on-screen
4
- * control layout, and the overlay stack behind `hub.overlay`.
5
- *
6
- * @packageDocumentation
7
- */
8
- export { InputSystem } from './input/input-system';
9
- export type { InputSystemOptions } from './input/input-system';
10
- export { getInput, INPUT_SINGLETON_API, isInputSystem, parseInputOverrides } from './input/page-input';
11
- export type { InputOptions } from './input/page-input';
12
- export { isPageInputControl } from './input/page-control';
13
- export type { PageInputControl } from './input/page-control';
14
- export type * from './input/types';
15
- export { Overlay } from './overlay/overlay';
16
- export { layoutControls } from './overlay/layout';
17
- export type { LayoutOptions } from './overlay/layout';
18
- export { boxesTouch, controlSize } from './overlay/layout-geometry';
19
- export type { Insets, LayoutBox, LayoutItem } from './overlay/layout-geometry';
20
- export { getUiStack, isUiStack } from './uistack/page-stack';
21
- export { UI_STACK_VERSION } from './uistack/ui-stack';
22
- export type * from './uistack/types';
1
+ /**
2
+ * `@diffenderfer-games/hub/input`: the input system (`hub.input`): the
3
+ * page-wide {@link getInput}, the {@link InputSystem} class, the on-screen
4
+ * control layout, and the overlay stack behind `hub.overlay`.
5
+ *
6
+ * @packageDocumentation
7
+ */
8
+ export { InputSystem } from './input/input-system';
9
+ export type { InputSystemOptions } from './input/input-system';
10
+ export { getInput, INPUT_SINGLETON_API, isInputSystem, parseInputOverrides } from './input/page-input';
11
+ export type { InputOptions } from './input/page-input';
12
+ export { isPageInputControl } from './input/page-control';
13
+ export type { PageInputControl } from './input/page-control';
14
+ export type * from './input/types';
15
+ export { Overlay } from './overlay/overlay';
16
+ export { layoutControls } from './overlay/layout';
17
+ export type { LayoutOptions } from './overlay/layout';
18
+ export { boxesTouch, controlSize } from './overlay/layout-geometry';
19
+ export type { Insets, LayoutBox, LayoutItem } from './overlay/layout-geometry';
20
+ export { getUiStack, isUiStack } from './uistack/page-stack';
21
+ export { UI_STACK_VERSION } from './uistack/ui-stack';
22
+ export type * from './uistack/types';
package/src/mp.ts CHANGED
@@ -1,10 +1,10 @@
1
- /**
2
- * `@diffenderfer-games/hub/mp`: the multiplayer forwarder (`hub.mp`):
3
- * invites, launches, the leave guard and own-server tickets.
4
- *
5
- * @packageDocumentation
6
- */
7
- export { multiplayerForwarder as mp } from './realtime/multiplayer-forwarder';
8
- export type * from './realtime/multiplayer-types';
9
- export type { InviteCreated } from './realtime/wire-types';
10
- export type { Invite, JoinInfo, Launch, LaunchTicket, Party } from '@diffenderfer-games/hub-contract';
1
+ /**
2
+ * `@diffenderfer-games/hub/mp`: the multiplayer forwarder (`hub.mp`):
3
+ * invites, launches, the leave guard and own-server tickets.
4
+ *
5
+ * @packageDocumentation
6
+ */
7
+ export { multiplayerForwarder as mp } from './realtime/multiplayer-forwarder';
8
+ export type * from './realtime/multiplayer-types';
9
+ export type { InviteCreated } from './realtime/wire-types';
10
+ export type { Invite, JoinInfo, Launch, LaunchTicket, Party } from '@diffenderfer-games/hub-contract';