@beta-gamer/react-native 0.1.6 → 0.1.9

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/dist/index.d.mts CHANGED
@@ -50,9 +50,10 @@ interface BetaGamerContextValue {
50
50
  interface BetaGamerProviderProps {
51
51
  token: string;
52
52
  serverUrl?: string;
53
+ socketPath?: string;
53
54
  children: React.ReactNode;
54
55
  }
55
- declare function BetaGamerProvider({ token, serverUrl, children }: BetaGamerProviderProps): react_jsx_runtime.JSX.Element;
56
+ declare function BetaGamerProvider({ token, serverUrl, socketPath, children }: BetaGamerProviderProps): react_jsx_runtime.JSX.Element;
56
57
  declare function useBetaGamer(): BetaGamerContextValue;
57
58
 
58
59
  /** Returns the current game state (status, players, winner, etc.) */
package/dist/index.d.ts CHANGED
@@ -50,9 +50,10 @@ interface BetaGamerContextValue {
50
50
  interface BetaGamerProviderProps {
51
51
  token: string;
52
52
  serverUrl?: string;
53
+ socketPath?: string;
53
54
  children: React.ReactNode;
54
55
  }
55
- declare function BetaGamerProvider({ token, serverUrl, children }: BetaGamerProviderProps): react_jsx_runtime.JSX.Element;
56
+ declare function BetaGamerProvider({ token, serverUrl, socketPath, children }: BetaGamerProviderProps): react_jsx_runtime.JSX.Element;
56
57
  declare function useBetaGamer(): BetaGamerContextValue;
57
58
 
58
59
  /** Returns the current game state (status, players, winner, etc.) */
package/dist/index.js CHANGED
@@ -41,6 +41,7 @@ module.exports = __toCommonJS(index_exports);
41
41
 
42
42
  // src/context/BetaGamerProvider.tsx
43
43
  var import_react = require("react");
44
+ var import_react_native = require("react-native");
44
45
  var import_socket = require("socket.io-client");
45
46
  var import_jsx_runtime = require("react/jsx-runtime");
46
47
  function base64Decode(str) {
@@ -87,7 +88,7 @@ function decodeToken(token) {
87
88
  return JSON.parse(base64Decode(parts[1]));
88
89
  }
89
90
  var BetaGamerContext = (0, import_react.createContext)(null);
90
- function BetaGamerProvider({ token, serverUrl = "https://api.beta-gamer.com", children }) {
91
+ function BetaGamerProvider({ token, serverUrl = "https://api.beta-gamer.com", socketPath = "/socket.io", children }) {
91
92
  const session = decodeToken(token);
92
93
  const [socket, setSocket] = (0, import_react.useState)(null);
93
94
  const [gameState, setGameState] = (0, import_react.useState)({
@@ -97,9 +98,21 @@ function BetaGamerProvider({ token, serverUrl = "https://api.beta-gamer.com", ch
97
98
  (0, import_react.useEffect)(() => {
98
99
  const s = (0, import_socket.io)(`${serverUrl}/${session.game}`, {
99
100
  auth: { token },
101
+ path: socketPath,
100
102
  transports: ["websocket", "polling"]
101
103
  });
102
104
  setSocket(s);
105
+ s.on("connect_error", (err) => {
106
+ const msg = err.message?.toLowerCase() ?? "";
107
+ let reason = "Unable to connect to the game server.";
108
+ if (msg.includes("websocket") || msg.includes("transport")) reason = "Connection failed: server does not accept WebSocket connections.";
109
+ else if (msg.includes("timeout")) reason = "Connection timed out. Check your internet connection.";
110
+ else if (msg.includes("unauthorized") || msg.includes("401")) reason = "Connection refused: invalid or expired session token.";
111
+ else if (msg.includes("not found") || msg.includes("404")) reason = "Game server not found. Check your serverUrl.";
112
+ else if (msg.includes("cors")) reason = "Connection blocked by CORS policy.";
113
+ else if (err.message) reason = `Connection error: ${err.message}`;
114
+ import_react_native.Alert.alert("Connection Error", `[Beta Gamer] ${reason}`);
115
+ });
103
116
  s.on("game:state", (state) => {
104
117
  setGameState((prev) => ({ ...prev, ...state }));
105
118
  });
@@ -110,7 +123,7 @@ function BetaGamerProvider({ token, serverUrl = "https://api.beta-gamer.com", ch
110
123
  s.disconnect();
111
124
  setSocket(null);
112
125
  };
113
- }, [token, serverUrl, session.game]);
126
+ }, [token, serverUrl, socketPath, session.game]);
114
127
  return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(BetaGamerContext.Provider, { value: { token, session, socket, gameState, theme: session.theme ?? {} }, children });
115
128
  }
116
129
  function useBetaGamer() {
@@ -134,7 +147,7 @@ function useTheme() {
134
147
  }
135
148
 
136
149
  // src/components/PlayerCard.tsx
137
- var import_react_native = require("react-native");
150
+ var import_react_native2 = require("react-native");
138
151
  var import_jsx_runtime2 = require("react/jsx-runtime");
139
152
  function PlayerCard({ player, style, nameStyle, indicatorStyle }) {
140
153
  const { players } = useSession();
@@ -142,15 +155,15 @@ function PlayerCard({ player, style, nameStyle, indicatorStyle }) {
142
155
  const p = player === "self" ? players[0] : players[1];
143
156
  if (!p) return null;
144
157
  const isActive = currentTurn === p.id;
145
- return /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)(import_react_native.View, { style, accessibilityRole: "text", children: [
146
- /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(import_react_native.Text, { style: nameStyle, children: p.displayName }),
147
- isActive && /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(import_react_native.View, { style: indicatorStyle, accessibilityLabel: "Active turn" })
158
+ return /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)(import_react_native2.View, { style, accessibilityRole: "text", children: [
159
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(import_react_native2.Text, { style: nameStyle, children: p.displayName }),
160
+ isActive && /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(import_react_native2.View, { style: indicatorStyle, accessibilityLabel: "Active turn" })
148
161
  ] });
149
162
  }
150
163
 
151
164
  // src/components/Timer.tsx
152
165
  var import_react2 = require("react");
153
- var import_react_native2 = require("react-native");
166
+ var import_react_native3 = require("react-native");
154
167
  var import_jsx_runtime3 = require("react/jsx-runtime");
155
168
  function Timer({ player, initialSeconds = 600, style, textStyle }) {
156
169
  const socket = useSocket();
@@ -173,7 +186,7 @@ function Timer({ player, initialSeconds = 600, style, textStyle }) {
173
186
  }, [status]);
174
187
  const m = Math.floor(seconds / 60).toString().padStart(2, "0");
175
188
  const s = (seconds % 60).toString().padStart(2, "0");
176
- return /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(import_react_native2.View, { style, children: /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)(import_react_native2.Text, { style: textStyle, children: [
189
+ return /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(import_react_native3.View, { style, children: /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)(import_react_native3.Text, { style: textStyle, children: [
177
190
  m,
178
191
  ":",
179
192
  s
@@ -215,7 +228,7 @@ function ChessBoard({ style }) {
215
228
 
216
229
  // src/components/chess/ChessMoveHistory.tsx
217
230
  var import_react4 = require("react");
218
- var import_react_native3 = require("react-native");
231
+ var import_react_native4 = require("react-native");
219
232
  var import_jsx_runtime6 = require("react/jsx-runtime");
220
233
  function ChessMoveHistory({ style, rowStyle, textStyle }) {
221
234
  const socket = useSocket();
@@ -241,7 +254,7 @@ function ChessMoveHistory({ style, rowStyle, textStyle }) {
241
254
  socket.off("chess:move", handler);
242
255
  };
243
256
  }, [socket]);
244
- return /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(import_react_native3.ScrollView, { style, children: moves.map(({ moveNumber, white, black }) => /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(import_react_native3.View, { style: rowStyle, children: /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)(import_react_native3.Text, { style: textStyle, children: [
257
+ return /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(import_react_native4.ScrollView, { style, children: moves.map(({ moveNumber, white, black }) => /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(import_react_native4.View, { style: rowStyle, children: /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)(import_react_native4.Text, { style: textStyle, children: [
245
258
  moveNumber,
246
259
  ". ",
247
260
  white,
@@ -269,7 +282,7 @@ function TictactoeBoard({ style }) {
269
282
 
270
283
  // src/components/subway-runner/index.tsx
271
284
  var import_react5 = require("react");
272
- var import_react_native4 = require("react-native");
285
+ var import_react_native5 = require("react-native");
273
286
  var import_jsx_runtime10 = require("react/jsx-runtime");
274
287
  function SubwayRunnerGame({ style }) {
275
288
  return /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(GameWebView, { game: "subway-runner", style });
@@ -284,7 +297,7 @@ function SubwayRunnerScore({ style, textStyle }) {
284
297
  socket.off("runner:score");
285
298
  };
286
299
  }, [socket]);
287
- return /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(import_react_native4.View, { style, children: /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(import_react_native4.Text, { style: textStyle, children: score }) });
300
+ return /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(import_react_native5.View, { style, children: /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(import_react_native5.Text, { style: textStyle, children: score }) });
288
301
  }
289
302
  function SubwayRunnerLives({ style, lifeStyle }) {
290
303
  const socket = useSocket();
@@ -296,7 +309,7 @@ function SubwayRunnerLives({ style, lifeStyle }) {
296
309
  socket.off("runner:lives");
297
310
  };
298
311
  }, [socket]);
299
- return /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(import_react_native4.View, { style: [{ flexDirection: "row" }, style], children: Array.from({ length: lives }).map((_, i) => /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(import_react_native4.View, { style: lifeStyle, accessibilityLabel: "life" }, i)) });
312
+ return /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(import_react_native5.View, { style: [{ flexDirection: "row" }, style], children: Array.from({ length: lives }).map((_, i) => /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(import_react_native5.View, { style: lifeStyle, accessibilityLabel: "life" }, i)) });
300
313
  }
301
314
  // Annotate the CommonJS export names for ESM import in node:
302
315
  0 && (module.exports = {
package/dist/index.mjs CHANGED
@@ -1,5 +1,6 @@
1
1
  // src/context/BetaGamerProvider.tsx
2
2
  import { createContext, useContext, useEffect, useState } from "react";
3
+ import { Alert } from "react-native";
3
4
  import { io } from "socket.io-client";
4
5
  import { jsx } from "react/jsx-runtime";
5
6
  function base64Decode(str) {
@@ -46,7 +47,7 @@ function decodeToken(token) {
46
47
  return JSON.parse(base64Decode(parts[1]));
47
48
  }
48
49
  var BetaGamerContext = createContext(null);
49
- function BetaGamerProvider({ token, serverUrl = "https://api.beta-gamer.com", children }) {
50
+ function BetaGamerProvider({ token, serverUrl = "https://api.beta-gamer.com", socketPath = "/socket.io", children }) {
50
51
  const session = decodeToken(token);
51
52
  const [socket, setSocket] = useState(null);
52
53
  const [gameState, setGameState] = useState({
@@ -56,9 +57,21 @@ function BetaGamerProvider({ token, serverUrl = "https://api.beta-gamer.com", ch
56
57
  useEffect(() => {
57
58
  const s = io(`${serverUrl}/${session.game}`, {
58
59
  auth: { token },
60
+ path: socketPath,
59
61
  transports: ["websocket", "polling"]
60
62
  });
61
63
  setSocket(s);
64
+ s.on("connect_error", (err) => {
65
+ const msg = err.message?.toLowerCase() ?? "";
66
+ let reason = "Unable to connect to the game server.";
67
+ if (msg.includes("websocket") || msg.includes("transport")) reason = "Connection failed: server does not accept WebSocket connections.";
68
+ else if (msg.includes("timeout")) reason = "Connection timed out. Check your internet connection.";
69
+ else if (msg.includes("unauthorized") || msg.includes("401")) reason = "Connection refused: invalid or expired session token.";
70
+ else if (msg.includes("not found") || msg.includes("404")) reason = "Game server not found. Check your serverUrl.";
71
+ else if (msg.includes("cors")) reason = "Connection blocked by CORS policy.";
72
+ else if (err.message) reason = `Connection error: ${err.message}`;
73
+ Alert.alert("Connection Error", `[Beta Gamer] ${reason}`);
74
+ });
62
75
  s.on("game:state", (state) => {
63
76
  setGameState((prev) => ({ ...prev, ...state }));
64
77
  });
@@ -69,7 +82,7 @@ function BetaGamerProvider({ token, serverUrl = "https://api.beta-gamer.com", ch
69
82
  s.disconnect();
70
83
  setSocket(null);
71
84
  };
72
- }, [token, serverUrl, session.game]);
85
+ }, [token, serverUrl, socketPath, session.game]);
73
86
  return /* @__PURE__ */ jsx(BetaGamerContext.Provider, { value: { token, session, socket, gameState, theme: session.theme ?? {} }, children });
74
87
  }
75
88
  function useBetaGamer() {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@beta-gamer/react-native",
3
- "version": "0.1.6",
3
+ "version": "0.1.9",
4
4
  "description": "React Native SDK for Beta Gamer GaaS — composable game components",
5
5
  "main": "./dist/index.js",
6
6
  "module": "./dist/index.mjs",