@beta-gamer/react-native 0.1.0 → 0.1.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.
- package/README.md +136 -0
- package/dist/index.js +9 -8
- package/package.json +11 -9
package/README.md
ADDED
|
@@ -0,0 +1,136 @@
|
|
|
1
|
+
# @beta-gamer/react-native
|
|
2
|
+
|
|
3
|
+
React Native SDK for [Beta Gamer](https://beta-gamer.com) — embed multiplayer games into your mobile app as composable components. You control the layout, we handle the game logic, matchmaking, and real-time sync.
|
|
4
|
+
|
|
5
|
+
## Installation
|
|
6
|
+
|
|
7
|
+
```bash
|
|
8
|
+
npm install @beta-gamer/react-native react-native-webview
|
|
9
|
+
```
|
|
10
|
+
|
|
11
|
+
Then link the native module:
|
|
12
|
+
|
|
13
|
+
```bash
|
|
14
|
+
# iOS
|
|
15
|
+
cd ios && pod install
|
|
16
|
+
|
|
17
|
+
# Android — no extra steps needed
|
|
18
|
+
```
|
|
19
|
+
|
|
20
|
+
## Requirements
|
|
21
|
+
|
|
22
|
+
- React Native 0.73+
|
|
23
|
+
- `react-native-webview` 13+
|
|
24
|
+
- A Beta Gamer tenant account and API key → [beta-gamer.com](https://beta-gamer.com)
|
|
25
|
+
|
|
26
|
+
## Quick start
|
|
27
|
+
|
|
28
|
+
**1. Create a session from your backend** (never expose your API key on the client)
|
|
29
|
+
|
|
30
|
+
```ts
|
|
31
|
+
const res = await fetch('https://api.beta-gamer.com/v1/sessions', {
|
|
32
|
+
method: 'POST',
|
|
33
|
+
headers: {
|
|
34
|
+
'Authorization': 'Bearer bg_live_xxxx',
|
|
35
|
+
'Content-Type': 'application/json',
|
|
36
|
+
},
|
|
37
|
+
body: JSON.stringify({
|
|
38
|
+
game: 'chess',
|
|
39
|
+
matchType: 'matchmaking',
|
|
40
|
+
players: [{ id: 'user_123', displayName: 'Alex' }],
|
|
41
|
+
}),
|
|
42
|
+
});
|
|
43
|
+
const { sessionToken } = await res.json();
|
|
44
|
+
```
|
|
45
|
+
|
|
46
|
+
**2. Pass the token to your screen and render**
|
|
47
|
+
|
|
48
|
+
```tsx
|
|
49
|
+
import {
|
|
50
|
+
BetaGamerProvider,
|
|
51
|
+
ChessBoard,
|
|
52
|
+
ChessMoveHistory,
|
|
53
|
+
PlayerCard,
|
|
54
|
+
Timer,
|
|
55
|
+
} from '@beta-gamer/react-native';
|
|
56
|
+
import { View, StyleSheet } from 'react-native';
|
|
57
|
+
|
|
58
|
+
export default function GameScreen({ sessionToken }: { sessionToken: string }) {
|
|
59
|
+
return (
|
|
60
|
+
<BetaGamerProvider token={sessionToken}>
|
|
61
|
+
<View style={styles.layout}>
|
|
62
|
+
<PlayerCard player="opponent" style={styles.card} nameStyle={styles.name} />
|
|
63
|
+
<Timer player="opponent" style={styles.timer} textStyle={styles.clock} />
|
|
64
|
+
|
|
65
|
+
<ChessBoard style={styles.board} />
|
|
66
|
+
<ChessMoveHistory style={styles.history} textStyle={styles.move} />
|
|
67
|
+
|
|
68
|
+
<PlayerCard player="self" style={styles.card} nameStyle={styles.name} />
|
|
69
|
+
<Timer player="self" style={styles.timer} textStyle={styles.clock} />
|
|
70
|
+
</View>
|
|
71
|
+
</BetaGamerProvider>
|
|
72
|
+
);
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
const styles = StyleSheet.create({
|
|
76
|
+
layout: { flex: 1, backgroundColor: '#0f0f0f' },
|
|
77
|
+
board: { flex: 1 },
|
|
78
|
+
// ... your styles
|
|
79
|
+
});
|
|
80
|
+
```
|
|
81
|
+
|
|
82
|
+
## Components
|
|
83
|
+
|
|
84
|
+
### Shared (all games)
|
|
85
|
+
|
|
86
|
+
| Component | Props | Description |
|
|
87
|
+
|-----------|-------|-------------|
|
|
88
|
+
| `BetaGamerProvider` | `token`, `serverUrl?` | Wrap your game UI with this. Handles socket connection and theme. |
|
|
89
|
+
| `PlayerCard` | `player`, `style?`, `nameStyle?`, `indicatorStyle?` | Player name + active-turn indicator |
|
|
90
|
+
| `Timer` | `player`, `initialSeconds?`, `style?`, `textStyle?` | Live countdown clock, syncs with server |
|
|
91
|
+
|
|
92
|
+
### Chess
|
|
93
|
+
|
|
94
|
+
| Component | Props | Description |
|
|
95
|
+
|-----------|-------|-------------|
|
|
96
|
+
| `ChessBoard` | `style?` | Interactive chess board (WebView) |
|
|
97
|
+
| `ChessMoveHistory` | `style?`, `textStyle?`, `rowStyle?` | Scrollable move list in algebraic notation |
|
|
98
|
+
|
|
99
|
+
### Other games
|
|
100
|
+
|
|
101
|
+
| Component | Game |
|
|
102
|
+
|-----------|------|
|
|
103
|
+
| `CheckersBoard` | checkers |
|
|
104
|
+
| `Connect4Board` | connect4 |
|
|
105
|
+
| `TictactoeBoard` | tictactoe |
|
|
106
|
+
| `SubwayRunnerGame`, `SubwayRunnerScore`, `SubwayRunnerLives` | subway-runner |
|
|
107
|
+
|
|
108
|
+
## Hooks
|
|
109
|
+
|
|
110
|
+
```tsx
|
|
111
|
+
import { useGameState, useSession, useSocket, useTheme } from '@beta-gamer/react-native';
|
|
112
|
+
|
|
113
|
+
const { status, winner, reason } = useGameState();
|
|
114
|
+
const { game, mode, matchType, players } = useSession();
|
|
115
|
+
const socket = useSocket(); // raw Socket.IO socket for custom events
|
|
116
|
+
const theme = useTheme(); // active theme tokens
|
|
117
|
+
```
|
|
118
|
+
|
|
119
|
+
## Differences from `@beta-gamer/react`
|
|
120
|
+
|
|
121
|
+
| React | React Native |
|
|
122
|
+
|-------|-------------|
|
|
123
|
+
| `className` prop | `style` / `textStyle` / `rowStyle` props |
|
|
124
|
+
| CSS variables for theming | Theme injected via WebView script |
|
|
125
|
+
| `<div>`, `<span>` | `<View>`, `<Text>` |
|
|
126
|
+
| Move history scrolls via CSS | Wrapped in `<ScrollView>` |
|
|
127
|
+
|
|
128
|
+
## Supported games
|
|
129
|
+
|
|
130
|
+
`chess` · `checkers` · `connect4` · `tictactoe` · `subway-runner`
|
|
131
|
+
|
|
132
|
+
## Links
|
|
133
|
+
|
|
134
|
+
- [Documentation](https://beta-gamer.com/docs)
|
|
135
|
+
- [Dashboard](https://beta-gamer.com/dashboard)
|
|
136
|
+
- [React SDK](https://www.npmjs.com/package/@beta-gamer/react)
|
package/dist/index.js
CHANGED
|
@@ -50,28 +50,29 @@ function decodeToken(token) {
|
|
|
50
50
|
var BetaGamerContext = (0, import_react.createContext)(null);
|
|
51
51
|
function BetaGamerProvider({ token, serverUrl = "https://api.beta-gamer.com", children }) {
|
|
52
52
|
const session = decodeToken(token);
|
|
53
|
-
const
|
|
53
|
+
const [socket, setSocket] = (0, import_react.useState)(null);
|
|
54
54
|
const [gameState, setGameState] = (0, import_react.useState)({
|
|
55
55
|
status: "pending",
|
|
56
56
|
players: session.players
|
|
57
57
|
});
|
|
58
58
|
(0, import_react.useEffect)(() => {
|
|
59
|
-
const
|
|
59
|
+
const s = (0, import_socket.io)(`${serverUrl}/${session.game}`, {
|
|
60
60
|
auth: { token },
|
|
61
|
-
transports: ["websocket"]
|
|
61
|
+
transports: ["websocket", "polling"]
|
|
62
62
|
});
|
|
63
|
-
|
|
64
|
-
|
|
63
|
+
s.on("connect", () => setSocket(s));
|
|
64
|
+
s.on("game:state", (state) => {
|
|
65
65
|
setGameState((prev) => ({ ...prev, ...state }));
|
|
66
66
|
});
|
|
67
|
-
|
|
67
|
+
s.on("game:ended", ({ winner, reason }) => {
|
|
68
68
|
setGameState((prev) => ({ ...prev, status: "ended", winner, reason }));
|
|
69
69
|
});
|
|
70
70
|
return () => {
|
|
71
|
-
|
|
71
|
+
s.disconnect();
|
|
72
|
+
setSocket(null);
|
|
72
73
|
};
|
|
73
74
|
}, [token, serverUrl, session.game]);
|
|
74
|
-
return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(BetaGamerContext.Provider, { value: { token, session, socket
|
|
75
|
+
return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(BetaGamerContext.Provider, { value: { token, session, socket, gameState, theme: session.theme ?? {} }, children });
|
|
75
76
|
}
|
|
76
77
|
function useBetaGamer() {
|
|
77
78
|
const ctx = (0, import_react.useContext)(BetaGamerContext);
|
package/package.json
CHANGED
|
@@ -1,31 +1,33 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@beta-gamer/react-native",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.2",
|
|
4
4
|
"description": "React Native SDK for Beta Gamer GaaS — composable game components",
|
|
5
5
|
"main": "./dist/index.js",
|
|
6
6
|
"types": "./dist/index.d.ts",
|
|
7
|
-
"files": [
|
|
7
|
+
"files": [
|
|
8
|
+
"dist"
|
|
9
|
+
],
|
|
8
10
|
"scripts": {
|
|
9
11
|
"build": "tsup src/index.ts --format cjs --dts --external react --external react-native --external react-native-webview",
|
|
10
|
-
"dev":
|
|
12
|
+
"dev": "tsup src/index.ts --format cjs --dts --external react --external react-native --external react-native-webview --watch"
|
|
11
13
|
},
|
|
12
14
|
"peerDependencies": {
|
|
13
|
-
"react":
|
|
14
|
-
"react-native":
|
|
15
|
+
"react": ">=18",
|
|
16
|
+
"react-native": ">=0.73",
|
|
15
17
|
"react-native-webview": ">=13"
|
|
16
18
|
},
|
|
17
19
|
"dependencies": {
|
|
18
20
|
"socket.io-client": "^4.8.1"
|
|
19
21
|
},
|
|
20
22
|
"devDependencies": {
|
|
21
|
-
"@types/react":
|
|
23
|
+
"@types/react": "^19",
|
|
22
24
|
"@types/react-native": "^0.73.0",
|
|
23
|
-
"tsup":
|
|
24
|
-
"typescript":
|
|
25
|
+
"tsup": "^8.0.0",
|
|
26
|
+
"typescript": "^5"
|
|
25
27
|
},
|
|
26
28
|
"repository": {
|
|
27
29
|
"type": "git",
|
|
28
|
-
"url": "https://github.com/acetennyson/beta-gamer"
|
|
30
|
+
"url": "https://github.com/acetennyson/beta-gamer-sdk"
|
|
29
31
|
},
|
|
30
32
|
"license": "MIT"
|
|
31
33
|
}
|