@mnbroatch/boardgame.io 0.0.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 (296) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +102 -0
  3. package/ai/package.json +7 -0
  4. package/client/package.json +7 -0
  5. package/core/package.json +7 -0
  6. package/debug/package.json +7 -0
  7. package/dist/boardgameio.es.js +14238 -0
  8. package/dist/boardgameio.js +14277 -0
  9. package/dist/boardgameio.min.js +16 -0
  10. package/dist/cjs/Debug-9d141c06.js +9586 -0
  11. package/dist/cjs/ai-e0e8a768.js +377 -0
  12. package/dist/cjs/ai.js +20 -0
  13. package/dist/cjs/client-76dec77b.js +258 -0
  14. package/dist/cjs/client-a22d7500.js +524 -0
  15. package/dist/cjs/client.js +26 -0
  16. package/dist/cjs/core.js +52 -0
  17. package/dist/cjs/debug.js +18 -0
  18. package/dist/cjs/filter-player-view-bb02e2f6.js +89 -0
  19. package/dist/cjs/initialize-267fcd69.js +61 -0
  20. package/dist/cjs/internal.js +25 -0
  21. package/dist/cjs/master-2904879d.js +320 -0
  22. package/dist/cjs/master.js +18 -0
  23. package/dist/cjs/multiplayer.js +23 -0
  24. package/dist/cjs/plugin-random-7425844d.js +229 -0
  25. package/dist/cjs/plugins.js +59 -0
  26. package/dist/cjs/react-native.js +182 -0
  27. package/dist/cjs/react.js +727 -0
  28. package/dist/cjs/reducer-16eec232.js +1203 -0
  29. package/dist/cjs/server.js +4087 -0
  30. package/dist/cjs/socketio-7a0837eb.js +478 -0
  31. package/dist/cjs/testing.js +30 -0
  32. package/dist/cjs/transport-b1874dfa.js +37 -0
  33. package/dist/cjs/turn-order-b2ff8740.js +1136 -0
  34. package/dist/cjs/util-fcfd8fb8.js +140 -0
  35. package/dist/esm/Debug-0141fe2d.js +9577 -0
  36. package/dist/esm/ai-5c06e761.js +371 -0
  37. package/dist/esm/ai.js +8 -0
  38. package/dist/esm/client-2e653027.js +522 -0
  39. package/dist/esm/client-5f57c3f2.js +255 -0
  40. package/dist/esm/client.js +16 -0
  41. package/dist/esm/core.js +40 -0
  42. package/dist/esm/debug.js +10 -0
  43. package/dist/esm/filter-player-view-2c6cc96f.js +87 -0
  44. package/dist/esm/initialize-11d626ca.js +59 -0
  45. package/dist/esm/internal.js +10 -0
  46. package/dist/esm/master-fa8f2e43.js +318 -0
  47. package/dist/esm/master.js +10 -0
  48. package/dist/esm/multiplayer.js +14 -0
  49. package/dist/esm/plugin-random-087f861e.js +226 -0
  50. package/dist/esm/plugins.js +55 -0
  51. package/dist/esm/react-native.js +173 -0
  52. package/dist/esm/react.js +716 -0
  53. package/dist/esm/reducer-c46da7e5.js +1198 -0
  54. package/dist/esm/socketio-c22ffa65.js +455 -0
  55. package/dist/esm/testing.js +26 -0
  56. package/dist/esm/transport-ce07b771.js +35 -0
  57. package/dist/esm/turn-order-376d315e.js +1091 -0
  58. package/dist/esm/util-b6147cef.js +135 -0
  59. package/dist/types/packages/ai.d.ts +5 -0
  60. package/dist/types/packages/client.d.ts +3 -0
  61. package/dist/types/packages/core.d.ts +5 -0
  62. package/dist/types/packages/debug.d.ts +2 -0
  63. package/dist/types/packages/internal.d.ts +8 -0
  64. package/dist/types/packages/master.d.ts +2 -0
  65. package/dist/types/packages/multiplayer.d.ts +3 -0
  66. package/dist/types/packages/plugins.d.ts +3 -0
  67. package/dist/types/packages/react-native.d.ts +2 -0
  68. package/dist/types/packages/react.d.ts +3 -0
  69. package/dist/types/packages/server.d.ts +6 -0
  70. package/dist/types/packages/testing.d.ts +1 -0
  71. package/dist/types/src/ai/ai.d.ts +53 -0
  72. package/dist/types/src/ai/ai.test.d.ts +1 -0
  73. package/dist/types/src/ai/bot.d.ts +40 -0
  74. package/dist/types/src/ai/mcts-bot.d.ts +60 -0
  75. package/dist/types/src/ai/random-bot.d.ts +27 -0
  76. package/dist/types/src/client/client.d.ts +104 -0
  77. package/dist/types/src/client/client.test.d.ts +1 -0
  78. package/dist/types/src/client/debug/tests/debug.test.d.ts +1 -0
  79. package/dist/types/src/client/manager.d.ts +61 -0
  80. package/dist/types/src/client/react.d.ts +75 -0
  81. package/dist/types/src/client/react.ssr.test.d.ts +4 -0
  82. package/dist/types/src/client/react.test.d.ts +1 -0
  83. package/dist/types/src/client/transport/dummy.d.ts +18 -0
  84. package/dist/types/src/client/transport/local.d.ts +59 -0
  85. package/dist/types/src/client/transport/local.test.d.ts +1 -0
  86. package/dist/types/src/client/transport/socketio.d.ts +45 -0
  87. package/dist/types/src/client/transport/socketio.test.d.ts +1 -0
  88. package/dist/types/src/client/transport/transport.d.ts +50 -0
  89. package/dist/types/src/client/transport/transport.test.d.ts +1 -0
  90. package/dist/types/src/core/action-creators.d.ts +144 -0
  91. package/dist/types/src/core/action-types.d.ts +10 -0
  92. package/dist/types/src/core/backwards-compatibility.d.ts +12 -0
  93. package/dist/types/src/core/constants.d.ts +6 -0
  94. package/dist/types/src/core/errors.d.ts +15 -0
  95. package/dist/types/src/core/flow.d.ts +28 -0
  96. package/dist/types/src/core/flow.test.d.ts +1 -0
  97. package/dist/types/src/core/game-methods.d.ts +9 -0
  98. package/dist/types/src/core/game.d.ts +26 -0
  99. package/dist/types/src/core/game.test.d.ts +1 -0
  100. package/dist/types/src/core/initialize.d.ts +9 -0
  101. package/dist/types/src/core/logger.d.ts +2 -0
  102. package/dist/types/src/core/player-view.d.ts +7 -0
  103. package/dist/types/src/core/player-view.test.d.ts +1 -0
  104. package/dist/types/src/core/reducer.d.ts +155 -0
  105. package/dist/types/src/core/reducer.test.d.ts +1 -0
  106. package/dist/types/src/core/turn-order.d.ts +179 -0
  107. package/dist/types/src/core/turn-order.test.d.ts +8 -0
  108. package/dist/types/src/lobby/client.d.ts +194 -0
  109. package/dist/types/src/lobby/client.test.d.ts +1 -0
  110. package/dist/types/src/lobby/connection.d.ts +44 -0
  111. package/dist/types/src/lobby/connection.test.d.ts +1 -0
  112. package/dist/types/src/lobby/create-match-form.d.ts +26 -0
  113. package/dist/types/src/lobby/login-form.d.ts +23 -0
  114. package/dist/types/src/lobby/match-instance.d.ts +31 -0
  115. package/dist/types/src/lobby/react.d.ts +113 -0
  116. package/dist/types/src/lobby/react.ssr.test.d.ts +4 -0
  117. package/dist/types/src/lobby/react.test.d.ts +1 -0
  118. package/dist/types/src/master/filter-player-view.d.ts +96 -0
  119. package/dist/types/src/master/filter-player-view.test.d.ts +1 -0
  120. package/dist/types/src/master/master.d.ts +94 -0
  121. package/dist/types/src/master/master.test.d.ts +1 -0
  122. package/dist/types/src/plugins/events/events.d.ts +54 -0
  123. package/dist/types/src/plugins/events/events.test.d.ts +1 -0
  124. package/dist/types/src/plugins/main.d.ts +75 -0
  125. package/dist/types/src/plugins/main.test.d.ts +1 -0
  126. package/dist/types/src/plugins/plugin-events.d.ts +5 -0
  127. package/dist/types/src/plugins/plugin-immer.d.ts +7 -0
  128. package/dist/types/src/plugins/plugin-immer.test.d.ts +1 -0
  129. package/dist/types/src/plugins/plugin-log.d.ts +14 -0
  130. package/dist/types/src/plugins/plugin-log.test.d.ts +1 -0
  131. package/dist/types/src/plugins/plugin-player.d.ts +29 -0
  132. package/dist/types/src/plugins/plugin-player.test.d.ts +1 -0
  133. package/dist/types/src/plugins/plugin-random.d.ts +4 -0
  134. package/dist/types/src/plugins/plugin-serializable.d.ts +7 -0
  135. package/dist/types/src/plugins/plugin-serializable.test.d.ts +1 -0
  136. package/dist/types/src/plugins/random/random.alea.d.ts +19 -0
  137. package/dist/types/src/plugins/random/random.d.ts +54 -0
  138. package/dist/types/src/plugins/random/random.test.d.ts +1 -0
  139. package/dist/types/src/server/api.d.ts +13 -0
  140. package/dist/types/src/server/api.test.d.ts +1 -0
  141. package/dist/types/src/server/auth.d.ts +38 -0
  142. package/dist/types/src/server/auth.test.d.ts +1 -0
  143. package/dist/types/src/server/cors.d.ts +4 -0
  144. package/dist/types/src/server/cors.test.d.ts +1 -0
  145. package/dist/types/src/server/db/base.d.ts +192 -0
  146. package/dist/types/src/server/db/flatfile.d.ts +44 -0
  147. package/dist/types/src/server/db/flatfile.test.d.ts +1 -0
  148. package/dist/types/src/server/db/index.d.ts +4 -0
  149. package/dist/types/src/server/db/index.test.d.ts +1 -0
  150. package/dist/types/src/server/db/inmemory.d.ts +43 -0
  151. package/dist/types/src/server/db/inmemory.test.d.ts +1 -0
  152. package/dist/types/src/server/db/localstorage.d.ts +7 -0
  153. package/dist/types/src/server/db/localstorage.test.d.ts +1 -0
  154. package/dist/types/src/server/index.d.ts +68 -0
  155. package/dist/types/src/server/index.test.d.ts +1 -0
  156. package/dist/types/src/server/transport/pubsub/generic-pub-sub.d.ts +6 -0
  157. package/dist/types/src/server/transport/pubsub/in-memory-pub-sub.d.ts +7 -0
  158. package/dist/types/src/server/transport/pubsub/in-memory-pub-sub.test.d.ts +1 -0
  159. package/dist/types/src/server/transport/socketio-simultaneous.test.d.ts +1 -0
  160. package/dist/types/src/server/transport/socketio.d.ts +65 -0
  161. package/dist/types/src/server/transport/socketio.test.d.ts +1 -0
  162. package/dist/types/src/server/util.d.ts +35 -0
  163. package/dist/types/src/testing/mock-random.d.ts +15 -0
  164. package/dist/types/src/testing/mock-random.test.d.ts +1 -0
  165. package/dist/types/src/types.d.ts +387 -0
  166. package/internal/package.json +7 -0
  167. package/master/package.json +7 -0
  168. package/multiplayer/package.json +7 -0
  169. package/package.json +211 -0
  170. package/plugins/package.json +7 -0
  171. package/react/package.json +7 -0
  172. package/react-native/package.json +7 -0
  173. package/server/package.json +6 -0
  174. package/src/ai/ai.test.ts +433 -0
  175. package/src/ai/ai.ts +84 -0
  176. package/src/ai/bot.ts +122 -0
  177. package/src/ai/mcts-bot.ts +331 -0
  178. package/src/ai/random-bot.ts +20 -0
  179. package/src/client/client.test.ts +993 -0
  180. package/src/client/client.ts +588 -0
  181. package/src/client/debug/Debug.svelte +239 -0
  182. package/src/client/debug/Menu.svelte +65 -0
  183. package/src/client/debug/ai/AI.svelte +215 -0
  184. package/src/client/debug/ai/Options.svelte +48 -0
  185. package/src/client/debug/info/Info.svelte +22 -0
  186. package/src/client/debug/info/Item.svelte +24 -0
  187. package/src/client/debug/log/Log.svelte +157 -0
  188. package/src/client/debug/log/LogEvent.svelte +149 -0
  189. package/src/client/debug/log/LogMetadata.svelte +7 -0
  190. package/src/client/debug/log/PhaseMarker.svelte +27 -0
  191. package/src/client/debug/log/TurnMarker.svelte +23 -0
  192. package/src/client/debug/main/ClientSwitcher.svelte +59 -0
  193. package/src/client/debug/main/Controls.svelte +58 -0
  194. package/src/client/debug/main/Hotkey.svelte +84 -0
  195. package/src/client/debug/main/InteractiveFunction.svelte +85 -0
  196. package/src/client/debug/main/Main.svelte +121 -0
  197. package/src/client/debug/main/Move.svelte +68 -0
  198. package/src/client/debug/main/PlayerInfo.svelte +70 -0
  199. package/src/client/debug/mcts/Action.svelte +22 -0
  200. package/src/client/debug/mcts/MCTS.svelte +78 -0
  201. package/src/client/debug/mcts/Table.svelte +98 -0
  202. package/src/client/debug/tests/JSONTree.mock.svelte +3 -0
  203. package/src/client/debug/tests/debug.test.ts +183 -0
  204. package/src/client/debug/utils/shortcuts.js +50 -0
  205. package/src/client/debug/utils/shortcuts.test.js +49 -0
  206. package/src/client/manager.ts +177 -0
  207. package/src/client/react-native.js +136 -0
  208. package/src/client/react-native.test.js +229 -0
  209. package/src/client/react.ssr.test.tsx +24 -0
  210. package/src/client/react.test.tsx +213 -0
  211. package/src/client/react.tsx +192 -0
  212. package/src/client/transport/dummy.ts +19 -0
  213. package/src/client/transport/local.test.ts +353 -0
  214. package/src/client/transport/local.ts +230 -0
  215. package/src/client/transport/socketio.test.ts +328 -0
  216. package/src/client/transport/socketio.ts +210 -0
  217. package/src/client/transport/transport.test.ts +27 -0
  218. package/src/client/transport/transport.ts +95 -0
  219. package/src/core/action-creators.ts +159 -0
  220. package/src/core/action-types.ts +18 -0
  221. package/src/core/backwards-compatibility.ts +23 -0
  222. package/src/core/constants.ts +6 -0
  223. package/src/core/errors.ts +35 -0
  224. package/src/core/flow.test.ts +2433 -0
  225. package/src/core/flow.ts +897 -0
  226. package/src/core/game-methods.ts +9 -0
  227. package/src/core/game.test.ts +286 -0
  228. package/src/core/game.ts +114 -0
  229. package/src/core/initialize.ts +77 -0
  230. package/src/core/logger.test.js +90 -0
  231. package/src/core/logger.ts +18 -0
  232. package/src/core/player-view.test.ts +50 -0
  233. package/src/core/player-view.ts +39 -0
  234. package/src/core/reducer.test.ts +991 -0
  235. package/src/core/reducer.ts +532 -0
  236. package/src/core/turn-order.test.ts +1123 -0
  237. package/src/core/turn-order.ts +473 -0
  238. package/src/lobby/client.test.ts +385 -0
  239. package/src/lobby/client.ts +358 -0
  240. package/src/lobby/connection.test.ts +207 -0
  241. package/src/lobby/connection.ts +162 -0
  242. package/src/lobby/create-match-form.tsx +122 -0
  243. package/src/lobby/login-form.tsx +75 -0
  244. package/src/lobby/match-instance.tsx +135 -0
  245. package/src/lobby/react.ssr.test.tsx +22 -0
  246. package/src/lobby/react.test.tsx +594 -0
  247. package/src/lobby/react.tsx +402 -0
  248. package/src/master/filter-player-view.test.ts +381 -0
  249. package/src/master/filter-player-view.ts +102 -0
  250. package/src/master/master.test.ts +1068 -0
  251. package/src/master/master.ts +492 -0
  252. package/src/plugins/events/events.test.ts +108 -0
  253. package/src/plugins/events/events.ts +209 -0
  254. package/src/plugins/main.test.ts +411 -0
  255. package/src/plugins/main.ts +314 -0
  256. package/src/plugins/plugin-events.ts +40 -0
  257. package/src/plugins/plugin-immer.test.ts +86 -0
  258. package/src/plugins/plugin-immer.ts +37 -0
  259. package/src/plugins/plugin-log.test.ts +37 -0
  260. package/src/plugins/plugin-log.ts +40 -0
  261. package/src/plugins/plugin-player.test.ts +172 -0
  262. package/src/plugins/plugin-player.ts +100 -0
  263. package/src/plugins/plugin-random.ts +40 -0
  264. package/src/plugins/plugin-serializable.test.ts +40 -0
  265. package/src/plugins/plugin-serializable.ts +55 -0
  266. package/src/plugins/random/random.alea.ts +109 -0
  267. package/src/plugins/random/random.test.ts +167 -0
  268. package/src/plugins/random/random.ts +198 -0
  269. package/src/server/api.test.ts +1699 -0
  270. package/src/server/api.ts +527 -0
  271. package/src/server/auth.test.ts +275 -0
  272. package/src/server/auth.ts +89 -0
  273. package/src/server/cors.test.ts +121 -0
  274. package/src/server/cors.ts +7 -0
  275. package/src/server/db/base.ts +296 -0
  276. package/src/server/db/flatfile.test.ts +221 -0
  277. package/src/server/db/flatfile.ts +228 -0
  278. package/src/server/db/index.test.ts +8 -0
  279. package/src/server/db/index.ts +12 -0
  280. package/src/server/db/inmemory.test.ts +143 -0
  281. package/src/server/db/inmemory.ts +143 -0
  282. package/src/server/db/localstorage.test.ts +73 -0
  283. package/src/server/db/localstorage.ts +44 -0
  284. package/src/server/index.test.ts +265 -0
  285. package/src/server/index.ts +175 -0
  286. package/src/server/transport/pubsub/generic-pub-sub.ts +11 -0
  287. package/src/server/transport/pubsub/in-memory-pub-sub.test.ts +47 -0
  288. package/src/server/transport/pubsub/in-memory-pub-sub.ts +28 -0
  289. package/src/server/transport/socketio-simultaneous.test.ts +603 -0
  290. package/src/server/transport/socketio.test.ts +303 -0
  291. package/src/server/transport/socketio.ts +279 -0
  292. package/src/server/util.ts +85 -0
  293. package/src/testing/mock-random.test.ts +45 -0
  294. package/src/testing/mock-random.ts +27 -0
  295. package/src/types.ts +511 -0
  296. package/testing/package.json +7 -0
@@ -0,0 +1,213 @@
1
+ /*
2
+ * Copyright 2017 The boardgame.io Authors
3
+ *
4
+ * Use of this source code is governed by a MIT-style
5
+ * license that can be found in the LICENSE file or at
6
+ * https://opensource.org/licenses/MIT.
7
+ */
8
+ /* eslint-disable unicorn/no-array-callback-reference */
9
+
10
+ import React from 'react';
11
+ import type { BoardProps } from './react';
12
+ import { Client } from './react';
13
+ import Enzyme from 'enzyme';
14
+ import Adapter from 'enzyme-adapter-react-16';
15
+ import { Local } from './transport/local';
16
+ import { SocketIO } from './transport/socketio';
17
+
18
+ Enzyme.configure({ adapter: new Adapter() });
19
+
20
+ class TestBoard extends React.Component<
21
+ BoardProps & { doStuff?; extraValue? }
22
+ > {
23
+ render() {
24
+ return <div id="board">Board</div>;
25
+ }
26
+ }
27
+
28
+ test('board is rendered', () => {
29
+ const Board = Client({
30
+ game: {},
31
+ board: TestBoard,
32
+ });
33
+
34
+ const game = Enzyme.mount(<Board />);
35
+ const board = game.find(TestBoard);
36
+
37
+ expect(board.props().isActive).toBe(true);
38
+ expect(board.text()).toBe('Board');
39
+
40
+ game.unmount();
41
+ });
42
+
43
+ test('board props', () => {
44
+ const Board = Client({
45
+ game: {},
46
+ board: TestBoard,
47
+ });
48
+ const board = Enzyme.mount(<Board />).find(TestBoard);
49
+ expect(board.props().isMultiplayer).toEqual(false);
50
+ expect(board.props().isActive).toBe(true);
51
+ });
52
+
53
+ test('can pass extra props to Client', () => {
54
+ const Board = Client({
55
+ game: {},
56
+ board: TestBoard,
57
+ });
58
+ const board = Enzyme.mount(
59
+ <Board doStuff={() => true} extraValue={55} />
60
+ ).find(TestBoard);
61
+ expect(board.props().doStuff()).toBe(true);
62
+ expect(board.props().extraValue).toBe(55);
63
+ });
64
+
65
+ test('debug ui can be turned off', () => {
66
+ const Board = Client({
67
+ game: {},
68
+ board: TestBoard,
69
+ debug: false,
70
+ });
71
+
72
+ const game = Enzyme.mount(<Board />);
73
+ expect(game.find('.debug-ui')).toHaveLength(0);
74
+ });
75
+
76
+ test('custom loading component', () => {
77
+ const Loading = () => <div>custom</div>;
78
+ const Board = Client({
79
+ game: {},
80
+ loading: Loading,
81
+ board: TestBoard,
82
+ multiplayer: SocketIO(),
83
+ });
84
+ const board = Enzyme.mount(<Board />);
85
+ expect(board.html()).toContain('custom');
86
+ });
87
+
88
+ test('can pass empty board', () => {
89
+ const Board = Client({
90
+ game: {},
91
+ });
92
+
93
+ const game = Enzyme.mount(<Board />);
94
+ expect(game).not.toBe(undefined);
95
+ });
96
+
97
+ test('move api', () => {
98
+ const Board = Client({
99
+ game: {
100
+ moves: {
101
+ A: (_, arg) => ({ arg }),
102
+ },
103
+ },
104
+ board: TestBoard,
105
+ });
106
+
107
+ const game = Enzyme.mount(<Board />);
108
+ const board = game.find('TestBoard').instance() as TestBoard;
109
+
110
+ expect(board.props.G).toEqual({});
111
+ board.props.moves.A(42);
112
+ expect(board.props.G).toEqual({ arg: 42 });
113
+ });
114
+
115
+ test('update matchID / playerID', () => {
116
+ let Board = null;
117
+ let game = null;
118
+
119
+ // No multiplayer.
120
+
121
+ Board = Client({
122
+ game: {
123
+ moves: {
124
+ A: (_, arg) => ({ arg }),
125
+ },
126
+ },
127
+ board: TestBoard,
128
+ });
129
+ game = Enzyme.mount(<Board />);
130
+ game.setProps({ matchID: 'a' });
131
+ game.setProps({ playerID: '3' });
132
+ expect(game.instance().transport).toBe(undefined);
133
+
134
+ // Multiplayer.
135
+
136
+ Board = Client({
137
+ game: {
138
+ moves: {
139
+ A: (_, arg) => ({ arg }),
140
+ },
141
+ },
142
+ board: TestBoard,
143
+ multiplayer: Local(),
144
+ });
145
+ game = Enzyme.mount(<Board matchID="a" playerID="1" credentials="foo" />);
146
+ const m = game.instance().client.transport;
147
+ const g = game.instance().client;
148
+
149
+ const spy1 = jest.spyOn(m, 'updateMatchID');
150
+ const spy2 = jest.spyOn(m, 'updatePlayerID');
151
+ const spy3 = jest.spyOn(g, 'updateCredentials');
152
+
153
+ expect(m.matchID).toBe('a');
154
+ expect(m.playerID).toBe('1');
155
+
156
+ game.setProps({ matchID: 'a' });
157
+ game.setProps({ playerID: '1' });
158
+ game.setProps({ credentials: 'foo' });
159
+
160
+ expect(m.matchID).toBe('a');
161
+ expect(m.playerID).toBe('1');
162
+ expect(spy1).not.toHaveBeenCalled();
163
+ expect(spy2).not.toHaveBeenCalled();
164
+ expect(spy3).not.toHaveBeenCalled();
165
+
166
+ game.setProps({ matchID: 'next' });
167
+ game.setProps({ playerID: 'next' });
168
+ game.setProps({ credentials: 'bar' });
169
+
170
+ expect(m.matchID).toBe('next');
171
+ expect(m.playerID).toBe('next');
172
+ expect(spy1).toHaveBeenCalled();
173
+ expect(spy2).toHaveBeenCalled();
174
+ expect(spy3).toHaveBeenCalled();
175
+ });
176
+
177
+ test('local playerView', () => {
178
+ const Board = Client({
179
+ game: {
180
+ setup: () => ({ secret: true }),
181
+ playerView: ({ playerID }) => ({ stripped: playerID }),
182
+ },
183
+ board: TestBoard,
184
+ numPlayers: 2,
185
+ });
186
+
187
+ const game = Enzyme.mount(<Board playerID="1" />);
188
+ const board = game.find('TestBoard').instance() as TestBoard;
189
+ expect(board.props.G).toEqual({ stripped: '1' });
190
+ });
191
+
192
+ test('reset Game', () => {
193
+ const Board = Client({
194
+ game: {
195
+ moves: {
196
+ A: (_, arg) => ({ arg }),
197
+ },
198
+ },
199
+ board: TestBoard,
200
+ });
201
+
202
+ const game = Enzyme.mount(<Board />);
203
+ const board = game.find('TestBoard').instance() as TestBoard;
204
+
205
+ const initial = { G: { ...board.props.G }, ctx: { ...board.props.ctx } };
206
+
207
+ expect(board.props.G).toEqual({});
208
+ board.props.moves.A(42);
209
+ expect(board.props.G).toEqual({ arg: 42 });
210
+ board.props.reset();
211
+ expect(board.props.G).toEqual(initial.G);
212
+ expect(board.props.ctx).toEqual(initial.ctx);
213
+ });
@@ -0,0 +1,192 @@
1
+ /*
2
+ * Copyright 2017 The boardgame.io Authors
3
+ *
4
+ * Use of this source code is governed by a MIT-style
5
+ * license that can be found in the LICENSE file or at
6
+ * https://opensource.org/licenses/MIT.
7
+ */
8
+
9
+ import React from 'react';
10
+ import PropTypes from 'prop-types';
11
+ import { Client as RawClient } from './client';
12
+ import type { ClientOpts, ClientState, _ClientImpl } from './client';
13
+
14
+ type WrappedBoardDelegates = 'matchID' | 'playerID' | 'credentials';
15
+
16
+ export type WrappedBoardProps = Pick<
17
+ ClientOpts,
18
+ WrappedBoardDelegates | 'debug'
19
+ >;
20
+
21
+ type ExposedClientProps<G extends any = any> = Pick<
22
+ _ClientImpl<G>,
23
+ | 'log'
24
+ | 'moves'
25
+ | 'events'
26
+ | 'reset'
27
+ | 'undo'
28
+ | 'redo'
29
+ | 'playerID'
30
+ | 'matchID'
31
+ | 'matchData'
32
+ | 'sendChatMessage'
33
+ | 'chatMessages'
34
+ >;
35
+
36
+ export type BoardProps<G extends any = any> = ClientState<G> &
37
+ Omit<WrappedBoardProps, keyof ExposedClientProps<G>> &
38
+ ExposedClientProps<G> & {
39
+ isMultiplayer: boolean;
40
+ };
41
+
42
+ type ReactClientOpts<
43
+ G extends any = any,
44
+ P extends BoardProps<G> = BoardProps<G>,
45
+ PluginAPIs extends Record<string, unknown> = Record<string, unknown>
46
+ > = Omit<ClientOpts<G, PluginAPIs>, WrappedBoardDelegates> & {
47
+ board?: React.ComponentType<P>;
48
+ loading?: React.ComponentType;
49
+ };
50
+
51
+ /**
52
+ * Client
53
+ *
54
+ * boardgame.io React client.
55
+ *
56
+ * @param {...object} game - The return value of `Game`.
57
+ * @param {...object} numPlayers - The number of players.
58
+ * @param {...object} board - The React component for the game.
59
+ * @param {...object} loading - (optional) The React component for the loading state.
60
+ * @param {...object} multiplayer - Set to a falsy value or a transportFactory, e.g., SocketIO()
61
+ * @param {...object} debug - Enables the Debug UI.
62
+ * @param {...object} enhancer - Optional enhancer to send to the Redux store
63
+ *
64
+ * Returns:
65
+ * A React component that wraps board and provides an
66
+ * API through props for it to interact with the framework
67
+ * and dispatch actions such as MAKE_MOVE, GAME_EVENT, RESET,
68
+ * UNDO and REDO.
69
+ */
70
+ export function Client<
71
+ G extends any = any,
72
+ P extends BoardProps<G> = BoardProps<G>,
73
+ PluginAPIs extends Record<string, unknown> = Record<string, unknown>
74
+ >(opts: ReactClientOpts<G, P, PluginAPIs>) {
75
+ const { game, numPlayers, board, multiplayer, enhancer } = opts;
76
+ let { loading, debug } = opts;
77
+
78
+ // Component that is displayed before the client has synced
79
+ // with the game master.
80
+ if (loading === undefined) {
81
+ const Loading = () => <div className="bgio-loading">connecting...</div>;
82
+ loading = Loading;
83
+ }
84
+
85
+ type AdditionalProps = Omit<P, keyof BoardProps<G>>;
86
+
87
+ /*
88
+ * WrappedBoard
89
+ *
90
+ * The main React component that wraps the passed in
91
+ * board component and adds the API to its props.
92
+ */
93
+ return class WrappedBoard extends React.Component<
94
+ WrappedBoardProps & AdditionalProps
95
+ > {
96
+ client: _ClientImpl<G>;
97
+ unsubscribe?: () => void;
98
+
99
+ static propTypes = {
100
+ // The ID of a game to connect to.
101
+ // Only relevant in multiplayer.
102
+ matchID: PropTypes.string,
103
+ // The ID of the player associated with this client.
104
+ // Only relevant in multiplayer.
105
+ playerID: PropTypes.string,
106
+ // This client's authentication credentials.
107
+ // Only relevant in multiplayer.
108
+ credentials: PropTypes.string,
109
+ // Enable / disable the Debug UI.
110
+ debug: PropTypes.any,
111
+ };
112
+
113
+ static defaultProps = {
114
+ matchID: 'default',
115
+ playerID: null,
116
+ credentials: null,
117
+ debug: true,
118
+ };
119
+
120
+ constructor(props: WrappedBoardProps & AdditionalProps) {
121
+ super(props);
122
+
123
+ if (debug === undefined) {
124
+ debug = props.debug;
125
+ }
126
+
127
+ this.client = RawClient({
128
+ game,
129
+ debug,
130
+ numPlayers,
131
+ multiplayer,
132
+ matchID: props.matchID,
133
+ playerID: props.playerID,
134
+ credentials: props.credentials,
135
+ enhancer,
136
+ });
137
+ }
138
+
139
+ componentDidMount() {
140
+ this.unsubscribe = this.client.subscribe(() => this.forceUpdate());
141
+ this.client.start();
142
+ }
143
+
144
+ componentWillUnmount() {
145
+ this.client.stop();
146
+ this.unsubscribe();
147
+ }
148
+
149
+ componentDidUpdate(prevProps: WrappedBoardProps & AdditionalProps) {
150
+ if (this.props.matchID != prevProps.matchID) {
151
+ this.client.updateMatchID(this.props.matchID);
152
+ }
153
+ if (this.props.playerID != prevProps.playerID) {
154
+ this.client.updatePlayerID(this.props.playerID);
155
+ }
156
+ if (this.props.credentials != prevProps.credentials) {
157
+ this.client.updateCredentials(this.props.credentials);
158
+ }
159
+ }
160
+
161
+ render() {
162
+ const state = this.client.getState();
163
+
164
+ if (state === null) {
165
+ return React.createElement(loading);
166
+ }
167
+
168
+ let _board = null;
169
+
170
+ if (board) {
171
+ _board = React.createElement(board, {
172
+ ...state,
173
+ ...(this.props as P),
174
+ isMultiplayer: !!multiplayer,
175
+ moves: this.client.moves,
176
+ events: this.client.events,
177
+ matchID: this.client.matchID,
178
+ playerID: this.client.playerID,
179
+ reset: this.client.reset,
180
+ undo: this.client.undo,
181
+ redo: this.client.redo,
182
+ log: this.client.log,
183
+ matchData: this.client.matchData,
184
+ sendChatMessage: this.client.sendChatMessage,
185
+ chatMessages: this.client.chatMessages,
186
+ });
187
+ }
188
+
189
+ return <div className="bgio-client">{_board}</div>;
190
+ }
191
+ };
192
+ }
@@ -0,0 +1,19 @@
1
+ import { Transport } from './transport';
2
+ import type { TransportOpts } from './transport';
3
+
4
+ /**
5
+ * This class doesn’t do anything, but simplifies the client class by providing
6
+ * dummy functions to call, so we don’t need to mock them in the client.
7
+ */
8
+ class DummyImpl extends Transport {
9
+ connect() {}
10
+ disconnect() {}
11
+ sendAction() {}
12
+ sendChatMessage() {}
13
+ requestSync() {}
14
+ updateCredentials() {}
15
+ updateMatchID() {}
16
+ updatePlayerID() {}
17
+ }
18
+
19
+ export const DummyTransport = (opts: TransportOpts) => new DummyImpl(opts);