@beta-gamer/react-native 0.1.0 → 0.1.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 (3) hide show
  1. package/README.md +136 -0
  2. package/dist/index.js +9 -8
  3. 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 socketRef = (0, import_react.useRef)(null);
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 socket = (0, import_socket.io)(`${serverUrl}/${session.game}`, {
59
+ const s = (0, import_socket.io)(`${serverUrl}/${session.game}`, {
60
60
  auth: { token },
61
- transports: ["websocket"]
61
+ transports: ["websocket", "polling"]
62
62
  });
63
- socketRef.current = socket;
64
- socket.on("game:state", (state) => {
63
+ s.on("connect", () => setSocket(s));
64
+ s.on("game:state", (state) => {
65
65
  setGameState((prev) => ({ ...prev, ...state }));
66
66
  });
67
- socket.on("game:ended", ({ winner, reason }) => {
67
+ s.on("game:ended", ({ winner, reason }) => {
68
68
  setGameState((prev) => ({ ...prev, status: "ended", winner, reason }));
69
69
  });
70
70
  return () => {
71
- socket.disconnect();
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: socketRef.current, gameState, theme: session.theme ?? {} }, children });
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.0",
3
+ "version": "0.1.1",
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": ["dist"],
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": "tsup src/index.ts --format cjs --dts --external react --external react-native --external react-native-webview --watch"
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": ">=18",
14
- "react-native": ">=0.73",
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": "^19",
23
+ "@types/react": "^19",
22
24
  "@types/react-native": "^0.73.0",
23
- "tsup": "^8.0.0",
24
- "typescript": "^5"
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
  }