@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.
- package/LICENSE +21 -0
- package/README.md +102 -0
- package/ai/package.json +7 -0
- package/client/package.json +7 -0
- package/core/package.json +7 -0
- package/debug/package.json +7 -0
- package/dist/boardgameio.es.js +14238 -0
- package/dist/boardgameio.js +14277 -0
- package/dist/boardgameio.min.js +16 -0
- package/dist/cjs/Debug-9d141c06.js +9586 -0
- package/dist/cjs/ai-e0e8a768.js +377 -0
- package/dist/cjs/ai.js +20 -0
- package/dist/cjs/client-76dec77b.js +258 -0
- package/dist/cjs/client-a22d7500.js +524 -0
- package/dist/cjs/client.js +26 -0
- package/dist/cjs/core.js +52 -0
- package/dist/cjs/debug.js +18 -0
- package/dist/cjs/filter-player-view-bb02e2f6.js +89 -0
- package/dist/cjs/initialize-267fcd69.js +61 -0
- package/dist/cjs/internal.js +25 -0
- package/dist/cjs/master-2904879d.js +320 -0
- package/dist/cjs/master.js +18 -0
- package/dist/cjs/multiplayer.js +23 -0
- package/dist/cjs/plugin-random-7425844d.js +229 -0
- package/dist/cjs/plugins.js +59 -0
- package/dist/cjs/react-native.js +182 -0
- package/dist/cjs/react.js +727 -0
- package/dist/cjs/reducer-16eec232.js +1203 -0
- package/dist/cjs/server.js +4087 -0
- package/dist/cjs/socketio-7a0837eb.js +478 -0
- package/dist/cjs/testing.js +30 -0
- package/dist/cjs/transport-b1874dfa.js +37 -0
- package/dist/cjs/turn-order-b2ff8740.js +1136 -0
- package/dist/cjs/util-fcfd8fb8.js +140 -0
- package/dist/esm/Debug-0141fe2d.js +9577 -0
- package/dist/esm/ai-5c06e761.js +371 -0
- package/dist/esm/ai.js +8 -0
- package/dist/esm/client-2e653027.js +522 -0
- package/dist/esm/client-5f57c3f2.js +255 -0
- package/dist/esm/client.js +16 -0
- package/dist/esm/core.js +40 -0
- package/dist/esm/debug.js +10 -0
- package/dist/esm/filter-player-view-2c6cc96f.js +87 -0
- package/dist/esm/initialize-11d626ca.js +59 -0
- package/dist/esm/internal.js +10 -0
- package/dist/esm/master-fa8f2e43.js +318 -0
- package/dist/esm/master.js +10 -0
- package/dist/esm/multiplayer.js +14 -0
- package/dist/esm/plugin-random-087f861e.js +226 -0
- package/dist/esm/plugins.js +55 -0
- package/dist/esm/react-native.js +173 -0
- package/dist/esm/react.js +716 -0
- package/dist/esm/reducer-c46da7e5.js +1198 -0
- package/dist/esm/socketio-c22ffa65.js +455 -0
- package/dist/esm/testing.js +26 -0
- package/dist/esm/transport-ce07b771.js +35 -0
- package/dist/esm/turn-order-376d315e.js +1091 -0
- package/dist/esm/util-b6147cef.js +135 -0
- package/dist/types/packages/ai.d.ts +5 -0
- package/dist/types/packages/client.d.ts +3 -0
- package/dist/types/packages/core.d.ts +5 -0
- package/dist/types/packages/debug.d.ts +2 -0
- package/dist/types/packages/internal.d.ts +8 -0
- package/dist/types/packages/master.d.ts +2 -0
- package/dist/types/packages/multiplayer.d.ts +3 -0
- package/dist/types/packages/plugins.d.ts +3 -0
- package/dist/types/packages/react-native.d.ts +2 -0
- package/dist/types/packages/react.d.ts +3 -0
- package/dist/types/packages/server.d.ts +6 -0
- package/dist/types/packages/testing.d.ts +1 -0
- package/dist/types/src/ai/ai.d.ts +53 -0
- package/dist/types/src/ai/ai.test.d.ts +1 -0
- package/dist/types/src/ai/bot.d.ts +40 -0
- package/dist/types/src/ai/mcts-bot.d.ts +60 -0
- package/dist/types/src/ai/random-bot.d.ts +27 -0
- package/dist/types/src/client/client.d.ts +104 -0
- package/dist/types/src/client/client.test.d.ts +1 -0
- package/dist/types/src/client/debug/tests/debug.test.d.ts +1 -0
- package/dist/types/src/client/manager.d.ts +61 -0
- package/dist/types/src/client/react.d.ts +75 -0
- package/dist/types/src/client/react.ssr.test.d.ts +4 -0
- package/dist/types/src/client/react.test.d.ts +1 -0
- package/dist/types/src/client/transport/dummy.d.ts +18 -0
- package/dist/types/src/client/transport/local.d.ts +59 -0
- package/dist/types/src/client/transport/local.test.d.ts +1 -0
- package/dist/types/src/client/transport/socketio.d.ts +45 -0
- package/dist/types/src/client/transport/socketio.test.d.ts +1 -0
- package/dist/types/src/client/transport/transport.d.ts +50 -0
- package/dist/types/src/client/transport/transport.test.d.ts +1 -0
- package/dist/types/src/core/action-creators.d.ts +144 -0
- package/dist/types/src/core/action-types.d.ts +10 -0
- package/dist/types/src/core/backwards-compatibility.d.ts +12 -0
- package/dist/types/src/core/constants.d.ts +6 -0
- package/dist/types/src/core/errors.d.ts +15 -0
- package/dist/types/src/core/flow.d.ts +28 -0
- package/dist/types/src/core/flow.test.d.ts +1 -0
- package/dist/types/src/core/game-methods.d.ts +9 -0
- package/dist/types/src/core/game.d.ts +26 -0
- package/dist/types/src/core/game.test.d.ts +1 -0
- package/dist/types/src/core/initialize.d.ts +9 -0
- package/dist/types/src/core/logger.d.ts +2 -0
- package/dist/types/src/core/player-view.d.ts +7 -0
- package/dist/types/src/core/player-view.test.d.ts +1 -0
- package/dist/types/src/core/reducer.d.ts +155 -0
- package/dist/types/src/core/reducer.test.d.ts +1 -0
- package/dist/types/src/core/turn-order.d.ts +179 -0
- package/dist/types/src/core/turn-order.test.d.ts +8 -0
- package/dist/types/src/lobby/client.d.ts +194 -0
- package/dist/types/src/lobby/client.test.d.ts +1 -0
- package/dist/types/src/lobby/connection.d.ts +44 -0
- package/dist/types/src/lobby/connection.test.d.ts +1 -0
- package/dist/types/src/lobby/create-match-form.d.ts +26 -0
- package/dist/types/src/lobby/login-form.d.ts +23 -0
- package/dist/types/src/lobby/match-instance.d.ts +31 -0
- package/dist/types/src/lobby/react.d.ts +113 -0
- package/dist/types/src/lobby/react.ssr.test.d.ts +4 -0
- package/dist/types/src/lobby/react.test.d.ts +1 -0
- package/dist/types/src/master/filter-player-view.d.ts +96 -0
- package/dist/types/src/master/filter-player-view.test.d.ts +1 -0
- package/dist/types/src/master/master.d.ts +94 -0
- package/dist/types/src/master/master.test.d.ts +1 -0
- package/dist/types/src/plugins/events/events.d.ts +54 -0
- package/dist/types/src/plugins/events/events.test.d.ts +1 -0
- package/dist/types/src/plugins/main.d.ts +75 -0
- package/dist/types/src/plugins/main.test.d.ts +1 -0
- package/dist/types/src/plugins/plugin-events.d.ts +5 -0
- package/dist/types/src/plugins/plugin-immer.d.ts +7 -0
- package/dist/types/src/plugins/plugin-immer.test.d.ts +1 -0
- package/dist/types/src/plugins/plugin-log.d.ts +14 -0
- package/dist/types/src/plugins/plugin-log.test.d.ts +1 -0
- package/dist/types/src/plugins/plugin-player.d.ts +29 -0
- package/dist/types/src/plugins/plugin-player.test.d.ts +1 -0
- package/dist/types/src/plugins/plugin-random.d.ts +4 -0
- package/dist/types/src/plugins/plugin-serializable.d.ts +7 -0
- package/dist/types/src/plugins/plugin-serializable.test.d.ts +1 -0
- package/dist/types/src/plugins/random/random.alea.d.ts +19 -0
- package/dist/types/src/plugins/random/random.d.ts +54 -0
- package/dist/types/src/plugins/random/random.test.d.ts +1 -0
- package/dist/types/src/server/api.d.ts +13 -0
- package/dist/types/src/server/api.test.d.ts +1 -0
- package/dist/types/src/server/auth.d.ts +38 -0
- package/dist/types/src/server/auth.test.d.ts +1 -0
- package/dist/types/src/server/cors.d.ts +4 -0
- package/dist/types/src/server/cors.test.d.ts +1 -0
- package/dist/types/src/server/db/base.d.ts +192 -0
- package/dist/types/src/server/db/flatfile.d.ts +44 -0
- package/dist/types/src/server/db/flatfile.test.d.ts +1 -0
- package/dist/types/src/server/db/index.d.ts +4 -0
- package/dist/types/src/server/db/index.test.d.ts +1 -0
- package/dist/types/src/server/db/inmemory.d.ts +43 -0
- package/dist/types/src/server/db/inmemory.test.d.ts +1 -0
- package/dist/types/src/server/db/localstorage.d.ts +7 -0
- package/dist/types/src/server/db/localstorage.test.d.ts +1 -0
- package/dist/types/src/server/index.d.ts +68 -0
- package/dist/types/src/server/index.test.d.ts +1 -0
- package/dist/types/src/server/transport/pubsub/generic-pub-sub.d.ts +6 -0
- package/dist/types/src/server/transport/pubsub/in-memory-pub-sub.d.ts +7 -0
- package/dist/types/src/server/transport/pubsub/in-memory-pub-sub.test.d.ts +1 -0
- package/dist/types/src/server/transport/socketio-simultaneous.test.d.ts +1 -0
- package/dist/types/src/server/transport/socketio.d.ts +65 -0
- package/dist/types/src/server/transport/socketio.test.d.ts +1 -0
- package/dist/types/src/server/util.d.ts +35 -0
- package/dist/types/src/testing/mock-random.d.ts +15 -0
- package/dist/types/src/testing/mock-random.test.d.ts +1 -0
- package/dist/types/src/types.d.ts +387 -0
- package/internal/package.json +7 -0
- package/master/package.json +7 -0
- package/multiplayer/package.json +7 -0
- package/package.json +211 -0
- package/plugins/package.json +7 -0
- package/react/package.json +7 -0
- package/react-native/package.json +7 -0
- package/server/package.json +6 -0
- package/src/ai/ai.test.ts +433 -0
- package/src/ai/ai.ts +84 -0
- package/src/ai/bot.ts +122 -0
- package/src/ai/mcts-bot.ts +331 -0
- package/src/ai/random-bot.ts +20 -0
- package/src/client/client.test.ts +993 -0
- package/src/client/client.ts +588 -0
- package/src/client/debug/Debug.svelte +239 -0
- package/src/client/debug/Menu.svelte +65 -0
- package/src/client/debug/ai/AI.svelte +215 -0
- package/src/client/debug/ai/Options.svelte +48 -0
- package/src/client/debug/info/Info.svelte +22 -0
- package/src/client/debug/info/Item.svelte +24 -0
- package/src/client/debug/log/Log.svelte +157 -0
- package/src/client/debug/log/LogEvent.svelte +149 -0
- package/src/client/debug/log/LogMetadata.svelte +7 -0
- package/src/client/debug/log/PhaseMarker.svelte +27 -0
- package/src/client/debug/log/TurnMarker.svelte +23 -0
- package/src/client/debug/main/ClientSwitcher.svelte +59 -0
- package/src/client/debug/main/Controls.svelte +58 -0
- package/src/client/debug/main/Hotkey.svelte +84 -0
- package/src/client/debug/main/InteractiveFunction.svelte +85 -0
- package/src/client/debug/main/Main.svelte +121 -0
- package/src/client/debug/main/Move.svelte +68 -0
- package/src/client/debug/main/PlayerInfo.svelte +70 -0
- package/src/client/debug/mcts/Action.svelte +22 -0
- package/src/client/debug/mcts/MCTS.svelte +78 -0
- package/src/client/debug/mcts/Table.svelte +98 -0
- package/src/client/debug/tests/JSONTree.mock.svelte +3 -0
- package/src/client/debug/tests/debug.test.ts +183 -0
- package/src/client/debug/utils/shortcuts.js +50 -0
- package/src/client/debug/utils/shortcuts.test.js +49 -0
- package/src/client/manager.ts +177 -0
- package/src/client/react-native.js +136 -0
- package/src/client/react-native.test.js +229 -0
- package/src/client/react.ssr.test.tsx +24 -0
- package/src/client/react.test.tsx +213 -0
- package/src/client/react.tsx +192 -0
- package/src/client/transport/dummy.ts +19 -0
- package/src/client/transport/local.test.ts +353 -0
- package/src/client/transport/local.ts +230 -0
- package/src/client/transport/socketio.test.ts +328 -0
- package/src/client/transport/socketio.ts +210 -0
- package/src/client/transport/transport.test.ts +27 -0
- package/src/client/transport/transport.ts +95 -0
- package/src/core/action-creators.ts +159 -0
- package/src/core/action-types.ts +18 -0
- package/src/core/backwards-compatibility.ts +23 -0
- package/src/core/constants.ts +6 -0
- package/src/core/errors.ts +35 -0
- package/src/core/flow.test.ts +2433 -0
- package/src/core/flow.ts +897 -0
- package/src/core/game-methods.ts +9 -0
- package/src/core/game.test.ts +286 -0
- package/src/core/game.ts +114 -0
- package/src/core/initialize.ts +77 -0
- package/src/core/logger.test.js +90 -0
- package/src/core/logger.ts +18 -0
- package/src/core/player-view.test.ts +50 -0
- package/src/core/player-view.ts +39 -0
- package/src/core/reducer.test.ts +991 -0
- package/src/core/reducer.ts +532 -0
- package/src/core/turn-order.test.ts +1123 -0
- package/src/core/turn-order.ts +473 -0
- package/src/lobby/client.test.ts +385 -0
- package/src/lobby/client.ts +358 -0
- package/src/lobby/connection.test.ts +207 -0
- package/src/lobby/connection.ts +162 -0
- package/src/lobby/create-match-form.tsx +122 -0
- package/src/lobby/login-form.tsx +75 -0
- package/src/lobby/match-instance.tsx +135 -0
- package/src/lobby/react.ssr.test.tsx +22 -0
- package/src/lobby/react.test.tsx +594 -0
- package/src/lobby/react.tsx +402 -0
- package/src/master/filter-player-view.test.ts +381 -0
- package/src/master/filter-player-view.ts +102 -0
- package/src/master/master.test.ts +1068 -0
- package/src/master/master.ts +492 -0
- package/src/plugins/events/events.test.ts +108 -0
- package/src/plugins/events/events.ts +209 -0
- package/src/plugins/main.test.ts +411 -0
- package/src/plugins/main.ts +314 -0
- package/src/plugins/plugin-events.ts +40 -0
- package/src/plugins/plugin-immer.test.ts +86 -0
- package/src/plugins/plugin-immer.ts +37 -0
- package/src/plugins/plugin-log.test.ts +37 -0
- package/src/plugins/plugin-log.ts +40 -0
- package/src/plugins/plugin-player.test.ts +172 -0
- package/src/plugins/plugin-player.ts +100 -0
- package/src/plugins/plugin-random.ts +40 -0
- package/src/plugins/plugin-serializable.test.ts +40 -0
- package/src/plugins/plugin-serializable.ts +55 -0
- package/src/plugins/random/random.alea.ts +109 -0
- package/src/plugins/random/random.test.ts +167 -0
- package/src/plugins/random/random.ts +198 -0
- package/src/server/api.test.ts +1699 -0
- package/src/server/api.ts +527 -0
- package/src/server/auth.test.ts +275 -0
- package/src/server/auth.ts +89 -0
- package/src/server/cors.test.ts +121 -0
- package/src/server/cors.ts +7 -0
- package/src/server/db/base.ts +296 -0
- package/src/server/db/flatfile.test.ts +221 -0
- package/src/server/db/flatfile.ts +228 -0
- package/src/server/db/index.test.ts +8 -0
- package/src/server/db/index.ts +12 -0
- package/src/server/db/inmemory.test.ts +143 -0
- package/src/server/db/inmemory.ts +143 -0
- package/src/server/db/localstorage.test.ts +73 -0
- package/src/server/db/localstorage.ts +44 -0
- package/src/server/index.test.ts +265 -0
- package/src/server/index.ts +175 -0
- package/src/server/transport/pubsub/generic-pub-sub.ts +11 -0
- package/src/server/transport/pubsub/in-memory-pub-sub.test.ts +47 -0
- package/src/server/transport/pubsub/in-memory-pub-sub.ts +28 -0
- package/src/server/transport/socketio-simultaneous.test.ts +603 -0
- package/src/server/transport/socketio.test.ts +303 -0
- package/src/server/transport/socketio.ts +279 -0
- package/src/server/util.ts +85 -0
- package/src/testing/mock-random.test.ts +45 -0
- package/src/testing/mock-random.ts +27 -0
- package/src/types.ts +511 -0
- package/testing/package.json +7 -0
|
@@ -0,0 +1,524 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
var nonSecure = require('nanoid/non-secure');
|
|
4
|
+
var Debug = require('./Debug-9d141c06.js');
|
|
5
|
+
var redux = require('redux');
|
|
6
|
+
var turnOrder = require('./turn-order-b2ff8740.js');
|
|
7
|
+
var reducer = require('./reducer-16eec232.js');
|
|
8
|
+
var initialize = require('./initialize-267fcd69.js');
|
|
9
|
+
var transport = require('./transport-b1874dfa.js');
|
|
10
|
+
|
|
11
|
+
/**
|
|
12
|
+
* This class doesn’t do anything, but simplifies the client class by providing
|
|
13
|
+
* dummy functions to call, so we don’t need to mock them in the client.
|
|
14
|
+
*/
|
|
15
|
+
class DummyImpl extends transport.Transport {
|
|
16
|
+
connect() { }
|
|
17
|
+
disconnect() { }
|
|
18
|
+
sendAction() { }
|
|
19
|
+
sendChatMessage() { }
|
|
20
|
+
requestSync() { }
|
|
21
|
+
updateCredentials() { }
|
|
22
|
+
updateMatchID() { }
|
|
23
|
+
updatePlayerID() { }
|
|
24
|
+
}
|
|
25
|
+
const DummyTransport = (opts) => new DummyImpl(opts);
|
|
26
|
+
|
|
27
|
+
/**
|
|
28
|
+
* Class to manage boardgame.io clients and limit debug panel rendering.
|
|
29
|
+
*/
|
|
30
|
+
class ClientManager {
|
|
31
|
+
constructor() {
|
|
32
|
+
this.debugPanel = null;
|
|
33
|
+
this.currentClient = null;
|
|
34
|
+
this.clients = new Map();
|
|
35
|
+
this.subscribers = new Map();
|
|
36
|
+
}
|
|
37
|
+
/**
|
|
38
|
+
* Register a client with the client manager.
|
|
39
|
+
*/
|
|
40
|
+
register(client) {
|
|
41
|
+
// Add client to clients map.
|
|
42
|
+
this.clients.set(client, client);
|
|
43
|
+
// Mount debug for this client (no-op if another debug is already mounted).
|
|
44
|
+
this.mountDebug(client);
|
|
45
|
+
this.notifySubscribers();
|
|
46
|
+
}
|
|
47
|
+
/**
|
|
48
|
+
* Unregister a client from the client manager.
|
|
49
|
+
*/
|
|
50
|
+
unregister(client) {
|
|
51
|
+
// Remove client from clients map.
|
|
52
|
+
this.clients.delete(client);
|
|
53
|
+
if (this.currentClient === client) {
|
|
54
|
+
// If the removed client owned the debug panel, unmount it.
|
|
55
|
+
this.unmountDebug();
|
|
56
|
+
// Mount debug panel for next available client.
|
|
57
|
+
for (const [client] of this.clients) {
|
|
58
|
+
if (this.debugPanel)
|
|
59
|
+
break;
|
|
60
|
+
this.mountDebug(client);
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
this.notifySubscribers();
|
|
64
|
+
}
|
|
65
|
+
/**
|
|
66
|
+
* Subscribe to the client manager state.
|
|
67
|
+
* Calls the passed callback each time the current client changes or a client
|
|
68
|
+
* registers/unregisters.
|
|
69
|
+
* Returns a function to unsubscribe from the state updates.
|
|
70
|
+
*/
|
|
71
|
+
subscribe(callback) {
|
|
72
|
+
const id = Symbol();
|
|
73
|
+
this.subscribers.set(id, callback);
|
|
74
|
+
callback(this.getState());
|
|
75
|
+
return () => {
|
|
76
|
+
this.subscribers.delete(id);
|
|
77
|
+
};
|
|
78
|
+
}
|
|
79
|
+
/**
|
|
80
|
+
* Switch to a client with a matching playerID.
|
|
81
|
+
*/
|
|
82
|
+
switchPlayerID(playerID) {
|
|
83
|
+
// For multiplayer clients, try switching control to a different client
|
|
84
|
+
// that is using the same transport layer.
|
|
85
|
+
if (this.currentClient.multiplayer) {
|
|
86
|
+
for (const [client] of this.clients) {
|
|
87
|
+
if (client.playerID === playerID &&
|
|
88
|
+
client.debugOpt !== false &&
|
|
89
|
+
client.multiplayer === this.currentClient.multiplayer) {
|
|
90
|
+
this.switchToClient(client);
|
|
91
|
+
return;
|
|
92
|
+
}
|
|
93
|
+
}
|
|
94
|
+
}
|
|
95
|
+
// If no client matches, update the playerID for the current client.
|
|
96
|
+
this.currentClient.updatePlayerID(playerID);
|
|
97
|
+
this.notifySubscribers();
|
|
98
|
+
}
|
|
99
|
+
/**
|
|
100
|
+
* Set the passed client as the active client for debugging.
|
|
101
|
+
*/
|
|
102
|
+
switchToClient(client) {
|
|
103
|
+
if (client === this.currentClient)
|
|
104
|
+
return;
|
|
105
|
+
this.unmountDebug();
|
|
106
|
+
this.mountDebug(client);
|
|
107
|
+
this.notifySubscribers();
|
|
108
|
+
}
|
|
109
|
+
/**
|
|
110
|
+
* Notify all subscribers of changes to the client manager state.
|
|
111
|
+
*/
|
|
112
|
+
notifySubscribers() {
|
|
113
|
+
const arg = this.getState();
|
|
114
|
+
this.subscribers.forEach((cb) => {
|
|
115
|
+
cb(arg);
|
|
116
|
+
});
|
|
117
|
+
}
|
|
118
|
+
/**
|
|
119
|
+
* Get the client manager state.
|
|
120
|
+
*/
|
|
121
|
+
getState() {
|
|
122
|
+
return {
|
|
123
|
+
client: this.currentClient,
|
|
124
|
+
debuggableClients: this.getDebuggableClients(),
|
|
125
|
+
};
|
|
126
|
+
}
|
|
127
|
+
/**
|
|
128
|
+
* Get an array of the registered clients that haven’t disabled the debug panel.
|
|
129
|
+
*/
|
|
130
|
+
getDebuggableClients() {
|
|
131
|
+
return [...this.clients.values()].filter((client) => client.debugOpt !== false);
|
|
132
|
+
}
|
|
133
|
+
/**
|
|
134
|
+
* Mount the debug panel using the passed client.
|
|
135
|
+
*/
|
|
136
|
+
mountDebug(client) {
|
|
137
|
+
if (client.debugOpt === false ||
|
|
138
|
+
this.debugPanel !== null ||
|
|
139
|
+
typeof document === 'undefined') {
|
|
140
|
+
return;
|
|
141
|
+
}
|
|
142
|
+
let DebugImpl;
|
|
143
|
+
let target = document.body;
|
|
144
|
+
if (process.env.NODE_ENV !== 'production') {
|
|
145
|
+
DebugImpl = Debug.Debug;
|
|
146
|
+
}
|
|
147
|
+
if (client.debugOpt && client.debugOpt !== true) {
|
|
148
|
+
DebugImpl = client.debugOpt.impl || DebugImpl;
|
|
149
|
+
target = client.debugOpt.target || target;
|
|
150
|
+
}
|
|
151
|
+
if (DebugImpl) {
|
|
152
|
+
this.currentClient = client;
|
|
153
|
+
this.debugPanel = new DebugImpl({
|
|
154
|
+
target,
|
|
155
|
+
props: { clientManager: this },
|
|
156
|
+
});
|
|
157
|
+
}
|
|
158
|
+
}
|
|
159
|
+
/**
|
|
160
|
+
* Unmount the debug panel.
|
|
161
|
+
*/
|
|
162
|
+
unmountDebug() {
|
|
163
|
+
this.debugPanel.$destroy();
|
|
164
|
+
this.debugPanel = null;
|
|
165
|
+
this.currentClient = null;
|
|
166
|
+
}
|
|
167
|
+
}
|
|
168
|
+
|
|
169
|
+
/*
|
|
170
|
+
* Copyright 2017 The boardgame.io Authors
|
|
171
|
+
*
|
|
172
|
+
* Use of this source code is governed by a MIT-style
|
|
173
|
+
* license that can be found in the LICENSE file or at
|
|
174
|
+
* https://opensource.org/licenses/MIT.
|
|
175
|
+
*/
|
|
176
|
+
/**
|
|
177
|
+
* Global client manager instance that all clients register with.
|
|
178
|
+
*/
|
|
179
|
+
const GlobalClientManager = new ClientManager();
|
|
180
|
+
/**
|
|
181
|
+
* Standardise the passed playerID, using currentPlayer if appropriate.
|
|
182
|
+
*/
|
|
183
|
+
function assumedPlayerID(playerID, store, multiplayer) {
|
|
184
|
+
// In singleplayer mode, if the client does not have a playerID
|
|
185
|
+
// associated with it, we attach the currentPlayer as playerID.
|
|
186
|
+
if (!multiplayer && (playerID === null || playerID === undefined)) {
|
|
187
|
+
const state = store.getState();
|
|
188
|
+
playerID = state.ctx.currentPlayer;
|
|
189
|
+
}
|
|
190
|
+
return playerID;
|
|
191
|
+
}
|
|
192
|
+
/**
|
|
193
|
+
* createDispatchers
|
|
194
|
+
*
|
|
195
|
+
* Create action dispatcher wrappers with bound playerID and credentials
|
|
196
|
+
*/
|
|
197
|
+
function createDispatchers(storeActionType, innerActionNames, store, playerID, credentials, multiplayer) {
|
|
198
|
+
const dispatchers = {};
|
|
199
|
+
for (const name of innerActionNames) {
|
|
200
|
+
dispatchers[name] = (...args) => {
|
|
201
|
+
const action = turnOrder.ActionCreators[storeActionType](name, args, assumedPlayerID(playerID, store, multiplayer), credentials);
|
|
202
|
+
store.dispatch(action);
|
|
203
|
+
};
|
|
204
|
+
}
|
|
205
|
+
return dispatchers;
|
|
206
|
+
}
|
|
207
|
+
// Creates a set of dispatchers to make moves.
|
|
208
|
+
const createMoveDispatchers = createDispatchers.bind(null, 'makeMove');
|
|
209
|
+
// Creates a set of dispatchers to dispatch game flow events.
|
|
210
|
+
const createEventDispatchers = createDispatchers.bind(null, 'gameEvent');
|
|
211
|
+
// Creates a set of dispatchers to dispatch actions to plugins.
|
|
212
|
+
const createPluginDispatchers = createDispatchers.bind(null, 'plugin');
|
|
213
|
+
/**
|
|
214
|
+
* Implementation of Client (see below).
|
|
215
|
+
*/
|
|
216
|
+
class _ClientImpl {
|
|
217
|
+
constructor({ game, debug, numPlayers, multiplayer, matchID: matchID, playerID, credentials, enhancer, }) {
|
|
218
|
+
this.game = reducer.ProcessGameConfig(game);
|
|
219
|
+
this.playerID = playerID;
|
|
220
|
+
this.matchID = matchID || 'default';
|
|
221
|
+
this.credentials = credentials;
|
|
222
|
+
this.multiplayer = multiplayer;
|
|
223
|
+
this.debugOpt = debug;
|
|
224
|
+
this.manager = GlobalClientManager;
|
|
225
|
+
this.gameStateOverride = null;
|
|
226
|
+
this.subscribers = {};
|
|
227
|
+
this._running = false;
|
|
228
|
+
this.reducer = reducer.CreateGameReducer({
|
|
229
|
+
game: this.game,
|
|
230
|
+
isClient: multiplayer !== undefined,
|
|
231
|
+
});
|
|
232
|
+
this.initialState = null;
|
|
233
|
+
if (!multiplayer) {
|
|
234
|
+
this.initialState = initialize.InitializeGame({ game: this.game, numPlayers });
|
|
235
|
+
}
|
|
236
|
+
this.reset = () => {
|
|
237
|
+
this.store.dispatch(turnOrder.reset(this.initialState));
|
|
238
|
+
};
|
|
239
|
+
this.undo = () => {
|
|
240
|
+
const undo = turnOrder.undo(assumedPlayerID(this.playerID, this.store, this.multiplayer), this.credentials);
|
|
241
|
+
this.store.dispatch(undo);
|
|
242
|
+
};
|
|
243
|
+
this.redo = () => {
|
|
244
|
+
const redo = turnOrder.redo(assumedPlayerID(this.playerID, this.store, this.multiplayer), this.credentials);
|
|
245
|
+
this.store.dispatch(redo);
|
|
246
|
+
};
|
|
247
|
+
this.log = [];
|
|
248
|
+
/**
|
|
249
|
+
* Middleware that manages the log object.
|
|
250
|
+
* Reducers generate deltalogs, which are log events
|
|
251
|
+
* that are the result of application of a single action.
|
|
252
|
+
* The master may also send back a deltalog or the entire
|
|
253
|
+
* log depending on the type of request.
|
|
254
|
+
* The middleware below takes care of all these cases while
|
|
255
|
+
* managing the log object.
|
|
256
|
+
*/
|
|
257
|
+
const LogMiddleware = (store) => (next) => (action) => {
|
|
258
|
+
const result = next(action);
|
|
259
|
+
const state = store.getState();
|
|
260
|
+
switch (action.type) {
|
|
261
|
+
case turnOrder.MAKE_MOVE:
|
|
262
|
+
case turnOrder.GAME_EVENT:
|
|
263
|
+
case turnOrder.UNDO:
|
|
264
|
+
case turnOrder.REDO: {
|
|
265
|
+
const deltalog = state.deltalog;
|
|
266
|
+
this.log = [...this.log, ...deltalog];
|
|
267
|
+
break;
|
|
268
|
+
}
|
|
269
|
+
case turnOrder.RESET: {
|
|
270
|
+
this.log = [];
|
|
271
|
+
break;
|
|
272
|
+
}
|
|
273
|
+
case turnOrder.PATCH:
|
|
274
|
+
case turnOrder.UPDATE: {
|
|
275
|
+
let id = -1;
|
|
276
|
+
if (this.log.length > 0) {
|
|
277
|
+
id = this.log[this.log.length - 1]._stateID;
|
|
278
|
+
}
|
|
279
|
+
let deltalog = action.deltalog || [];
|
|
280
|
+
// Filter out actions that are already present
|
|
281
|
+
// in the current log. This may occur when the
|
|
282
|
+
// client adds an entry to the log followed by
|
|
283
|
+
// the update from the master here.
|
|
284
|
+
deltalog = deltalog.filter((l) => l._stateID > id);
|
|
285
|
+
this.log = [...this.log, ...deltalog];
|
|
286
|
+
break;
|
|
287
|
+
}
|
|
288
|
+
case turnOrder.SYNC: {
|
|
289
|
+
this.initialState = action.initialState;
|
|
290
|
+
this.log = action.log || [];
|
|
291
|
+
break;
|
|
292
|
+
}
|
|
293
|
+
}
|
|
294
|
+
return result;
|
|
295
|
+
};
|
|
296
|
+
/**
|
|
297
|
+
* Middleware that intercepts actions and sends them to the master,
|
|
298
|
+
* which keeps the authoritative version of the state.
|
|
299
|
+
*/
|
|
300
|
+
const TransportMiddleware = (store) => (next) => (action) => {
|
|
301
|
+
const baseState = store.getState();
|
|
302
|
+
const result = next(action);
|
|
303
|
+
if (!('clientOnly' in action) &&
|
|
304
|
+
action.type !== turnOrder.STRIP_TRANSIENTS) {
|
|
305
|
+
this.transport.sendAction(baseState, action);
|
|
306
|
+
}
|
|
307
|
+
return result;
|
|
308
|
+
};
|
|
309
|
+
/**
|
|
310
|
+
* Middleware that intercepts actions and invokes the subscription callback.
|
|
311
|
+
*/
|
|
312
|
+
const SubscriptionMiddleware = () => (next) => (action) => {
|
|
313
|
+
const result = next(action);
|
|
314
|
+
this.notifySubscribers();
|
|
315
|
+
return result;
|
|
316
|
+
};
|
|
317
|
+
const middleware = redux.applyMiddleware(reducer.TransientHandlingMiddleware, SubscriptionMiddleware, TransportMiddleware, LogMiddleware);
|
|
318
|
+
enhancer =
|
|
319
|
+
enhancer !== undefined ? redux.compose(middleware, enhancer) : middleware;
|
|
320
|
+
this.store = redux.createStore(this.reducer, this.initialState, enhancer);
|
|
321
|
+
if (!multiplayer)
|
|
322
|
+
multiplayer = DummyTransport;
|
|
323
|
+
this.transport = multiplayer({
|
|
324
|
+
transportDataCallback: (data) => this.receiveTransportData(data),
|
|
325
|
+
gameKey: game,
|
|
326
|
+
game: this.game,
|
|
327
|
+
matchID,
|
|
328
|
+
playerID,
|
|
329
|
+
credentials,
|
|
330
|
+
gameName: this.game.name,
|
|
331
|
+
numPlayers,
|
|
332
|
+
});
|
|
333
|
+
this.createDispatchers();
|
|
334
|
+
this.chatMessages = [];
|
|
335
|
+
this.sendChatMessage = (payload) => {
|
|
336
|
+
this.transport.sendChatMessage(this.matchID, {
|
|
337
|
+
id: nonSecure.nanoid(7),
|
|
338
|
+
sender: this.playerID,
|
|
339
|
+
payload: payload,
|
|
340
|
+
});
|
|
341
|
+
};
|
|
342
|
+
}
|
|
343
|
+
/** Handle incoming match data from a multiplayer transport. */
|
|
344
|
+
receiveMatchData(matchData) {
|
|
345
|
+
this.matchData = matchData;
|
|
346
|
+
this.notifySubscribers();
|
|
347
|
+
}
|
|
348
|
+
/** Handle an incoming chat message from a multiplayer transport. */
|
|
349
|
+
receiveChatMessage(message) {
|
|
350
|
+
this.chatMessages = [...this.chatMessages, message];
|
|
351
|
+
this.notifySubscribers();
|
|
352
|
+
}
|
|
353
|
+
/** Handle all incoming updates from a multiplayer transport. */
|
|
354
|
+
receiveTransportData(data) {
|
|
355
|
+
const [matchID] = data.args;
|
|
356
|
+
if (matchID !== this.matchID)
|
|
357
|
+
return;
|
|
358
|
+
switch (data.type) {
|
|
359
|
+
case 'sync': {
|
|
360
|
+
const [, syncInfo] = data.args;
|
|
361
|
+
const action = turnOrder.sync(syncInfo);
|
|
362
|
+
this.receiveMatchData(syncInfo.filteredMetadata);
|
|
363
|
+
this.store.dispatch(action);
|
|
364
|
+
break;
|
|
365
|
+
}
|
|
366
|
+
case 'update': {
|
|
367
|
+
const [, state, deltalog] = data.args;
|
|
368
|
+
const currentState = this.store.getState();
|
|
369
|
+
if (state._stateID >= currentState._stateID) {
|
|
370
|
+
const action = turnOrder.update(state, deltalog);
|
|
371
|
+
this.store.dispatch(action);
|
|
372
|
+
}
|
|
373
|
+
break;
|
|
374
|
+
}
|
|
375
|
+
case 'patch': {
|
|
376
|
+
const [, prevStateID, stateID, patch, deltalog] = data.args;
|
|
377
|
+
const currentStateID = this.store.getState()._stateID;
|
|
378
|
+
if (prevStateID !== currentStateID)
|
|
379
|
+
break;
|
|
380
|
+
const action = turnOrder.patch(prevStateID, stateID, patch, deltalog);
|
|
381
|
+
this.store.dispatch(action);
|
|
382
|
+
// Emit sync if patch apply failed.
|
|
383
|
+
if (this.store.getState()._stateID === currentStateID) {
|
|
384
|
+
this.transport.requestSync();
|
|
385
|
+
}
|
|
386
|
+
break;
|
|
387
|
+
}
|
|
388
|
+
case 'matchData': {
|
|
389
|
+
const [, matchData] = data.args;
|
|
390
|
+
this.receiveMatchData(matchData);
|
|
391
|
+
break;
|
|
392
|
+
}
|
|
393
|
+
case 'chat': {
|
|
394
|
+
const [, chatMessage] = data.args;
|
|
395
|
+
this.receiveChatMessage(chatMessage);
|
|
396
|
+
break;
|
|
397
|
+
}
|
|
398
|
+
}
|
|
399
|
+
}
|
|
400
|
+
notifySubscribers() {
|
|
401
|
+
Object.values(this.subscribers).forEach((fn) => fn(this.getState()));
|
|
402
|
+
}
|
|
403
|
+
overrideGameState(state) {
|
|
404
|
+
this.gameStateOverride = state;
|
|
405
|
+
this.notifySubscribers();
|
|
406
|
+
}
|
|
407
|
+
start() {
|
|
408
|
+
this.transport.connect();
|
|
409
|
+
this._running = true;
|
|
410
|
+
this.manager.register(this);
|
|
411
|
+
}
|
|
412
|
+
stop() {
|
|
413
|
+
this.transport.disconnect();
|
|
414
|
+
this._running = false;
|
|
415
|
+
this.manager.unregister(this);
|
|
416
|
+
}
|
|
417
|
+
subscribe(fn) {
|
|
418
|
+
const id = Object.keys(this.subscribers).length;
|
|
419
|
+
this.subscribers[id] = fn;
|
|
420
|
+
this.transport.subscribeToConnectionStatus(() => this.notifySubscribers());
|
|
421
|
+
if (this._running || !this.multiplayer) {
|
|
422
|
+
fn(this.getState());
|
|
423
|
+
}
|
|
424
|
+
// Return a handle that allows the caller to unsubscribe.
|
|
425
|
+
return () => {
|
|
426
|
+
delete this.subscribers[id];
|
|
427
|
+
};
|
|
428
|
+
}
|
|
429
|
+
getInitialState() {
|
|
430
|
+
return this.initialState;
|
|
431
|
+
}
|
|
432
|
+
getState() {
|
|
433
|
+
let state = this.store.getState();
|
|
434
|
+
if (this.gameStateOverride !== null) {
|
|
435
|
+
state = this.gameStateOverride;
|
|
436
|
+
}
|
|
437
|
+
// This is the state before a sync with the game master.
|
|
438
|
+
if (state === null) {
|
|
439
|
+
return state;
|
|
440
|
+
}
|
|
441
|
+
// isActive.
|
|
442
|
+
let isActive = true;
|
|
443
|
+
const isPlayerActive = this.game.flow.isPlayerActive(state.G, state.ctx, this.playerID);
|
|
444
|
+
if (this.multiplayer && !isPlayerActive) {
|
|
445
|
+
isActive = false;
|
|
446
|
+
}
|
|
447
|
+
if (!this.multiplayer &&
|
|
448
|
+
this.playerID !== null &&
|
|
449
|
+
this.playerID !== undefined &&
|
|
450
|
+
!isPlayerActive) {
|
|
451
|
+
isActive = false;
|
|
452
|
+
}
|
|
453
|
+
if (state.ctx.gameover !== undefined) {
|
|
454
|
+
isActive = false;
|
|
455
|
+
}
|
|
456
|
+
// Secrets are normally stripped on the server,
|
|
457
|
+
// but we also strip them here so that game developers
|
|
458
|
+
// can see their effects while prototyping.
|
|
459
|
+
// Do not strip again if this is a multiplayer game
|
|
460
|
+
// since the server has already stripped secret info. (issue #818)
|
|
461
|
+
if (!this.multiplayer) {
|
|
462
|
+
state = {
|
|
463
|
+
...state,
|
|
464
|
+
G: this.game.playerView({
|
|
465
|
+
G: state.G,
|
|
466
|
+
ctx: state.ctx,
|
|
467
|
+
playerID: this.playerID,
|
|
468
|
+
}),
|
|
469
|
+
plugins: turnOrder.PlayerView(state, this),
|
|
470
|
+
};
|
|
471
|
+
}
|
|
472
|
+
// Combine into return value.
|
|
473
|
+
return {
|
|
474
|
+
...state,
|
|
475
|
+
log: this.log,
|
|
476
|
+
isActive,
|
|
477
|
+
isConnected: this.transport.isConnected,
|
|
478
|
+
};
|
|
479
|
+
}
|
|
480
|
+
createDispatchers() {
|
|
481
|
+
this.moves = createMoveDispatchers(this.game.moveNames, this.store, this.playerID, this.credentials, this.multiplayer);
|
|
482
|
+
this.events = createEventDispatchers(this.game.flow.enabledEventNames, this.store, this.playerID, this.credentials, this.multiplayer);
|
|
483
|
+
this.plugins = createPluginDispatchers(this.game.pluginNames, this.store, this.playerID, this.credentials, this.multiplayer);
|
|
484
|
+
}
|
|
485
|
+
updatePlayerID(playerID) {
|
|
486
|
+
this.playerID = playerID;
|
|
487
|
+
this.createDispatchers();
|
|
488
|
+
this.transport.updatePlayerID(playerID);
|
|
489
|
+
this.notifySubscribers();
|
|
490
|
+
}
|
|
491
|
+
updateMatchID(matchID) {
|
|
492
|
+
this.matchID = matchID;
|
|
493
|
+
this.createDispatchers();
|
|
494
|
+
this.transport.updateMatchID(matchID);
|
|
495
|
+
this.notifySubscribers();
|
|
496
|
+
}
|
|
497
|
+
updateCredentials(credentials) {
|
|
498
|
+
this.credentials = credentials;
|
|
499
|
+
this.createDispatchers();
|
|
500
|
+
this.transport.updateCredentials(credentials);
|
|
501
|
+
this.notifySubscribers();
|
|
502
|
+
}
|
|
503
|
+
}
|
|
504
|
+
/**
|
|
505
|
+
* Client
|
|
506
|
+
*
|
|
507
|
+
* boardgame.io JS client.
|
|
508
|
+
*
|
|
509
|
+
* @param {...object} game - The return value of `Game`.
|
|
510
|
+
* @param {...object} numPlayers - The number of players.
|
|
511
|
+
* @param {...object} multiplayer - Set to a falsy value or a transportFactory, e.g., SocketIO()
|
|
512
|
+
* @param {...object} matchID - The matchID that you want to connect to.
|
|
513
|
+
* @param {...object} playerID - The playerID associated with this client.
|
|
514
|
+
* @param {...string} credentials - The authentication credentials associated with this client.
|
|
515
|
+
*
|
|
516
|
+
* Returns:
|
|
517
|
+
* A JS object that provides an API to interact with the
|
|
518
|
+
* game by dispatching moves and events.
|
|
519
|
+
*/
|
|
520
|
+
function Client(opts) {
|
|
521
|
+
return new _ClientImpl(opts);
|
|
522
|
+
}
|
|
523
|
+
|
|
524
|
+
exports.Client = Client;
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
Object.defineProperty(exports, '__esModule', { value: true });
|
|
4
|
+
|
|
5
|
+
var client = require('./client-a22d7500.js');
|
|
6
|
+
var client$1 = require('./client-76dec77b.js');
|
|
7
|
+
require('nanoid/non-secure');
|
|
8
|
+
require('./Debug-9d141c06.js');
|
|
9
|
+
require('./turn-order-b2ff8740.js');
|
|
10
|
+
require('immer');
|
|
11
|
+
require('./plugin-random-7425844d.js');
|
|
12
|
+
require('lodash.isplainobject');
|
|
13
|
+
require('flatted');
|
|
14
|
+
require('./reducer-16eec232.js');
|
|
15
|
+
require('rfc6902');
|
|
16
|
+
require('./ai-e0e8a768.js');
|
|
17
|
+
require('setimmediate');
|
|
18
|
+
require('redux');
|
|
19
|
+
require('./initialize-267fcd69.js');
|
|
20
|
+
require('./transport-b1874dfa.js');
|
|
21
|
+
|
|
22
|
+
|
|
23
|
+
|
|
24
|
+
exports.Client = client.Client;
|
|
25
|
+
exports.LobbyClient = client$1.LobbyClient;
|
|
26
|
+
exports.LobbyClientError = client$1.LobbyClientError;
|
package/dist/cjs/core.js
ADDED
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
Object.defineProperty(exports, '__esModule', { value: true });
|
|
4
|
+
|
|
5
|
+
var turnOrder = require('./turn-order-b2ff8740.js');
|
|
6
|
+
require('immer');
|
|
7
|
+
require('./plugin-random-7425844d.js');
|
|
8
|
+
require('lodash.isplainobject');
|
|
9
|
+
|
|
10
|
+
/*
|
|
11
|
+
* Copyright 2018 The boardgame.io Authors
|
|
12
|
+
*
|
|
13
|
+
* Use of this source code is governed by a MIT-style
|
|
14
|
+
* license that can be found in the LICENSE file or at
|
|
15
|
+
* https://opensource.org/licenses/MIT.
|
|
16
|
+
*/
|
|
17
|
+
/**
|
|
18
|
+
* PlayerView reducers.
|
|
19
|
+
*/
|
|
20
|
+
const PlayerView = {
|
|
21
|
+
/**
|
|
22
|
+
* STRIP_SECRETS
|
|
23
|
+
*
|
|
24
|
+
* Reducer which removes a key named `secret` and
|
|
25
|
+
* removes all the keys in `players`, except for the one
|
|
26
|
+
* corresponding to the current playerID.
|
|
27
|
+
*/
|
|
28
|
+
STRIP_SECRETS: ({ G, playerID }) => {
|
|
29
|
+
const r = { ...G };
|
|
30
|
+
if (r.secret !== undefined) {
|
|
31
|
+
delete r.secret;
|
|
32
|
+
}
|
|
33
|
+
if (r.players) {
|
|
34
|
+
r.players = playerID
|
|
35
|
+
? {
|
|
36
|
+
[playerID]: r.players[playerID],
|
|
37
|
+
}
|
|
38
|
+
: {};
|
|
39
|
+
}
|
|
40
|
+
return r;
|
|
41
|
+
},
|
|
42
|
+
};
|
|
43
|
+
|
|
44
|
+
exports.ActivePlayers = turnOrder.ActivePlayers;
|
|
45
|
+
Object.defineProperty(exports, 'GameMethod', {
|
|
46
|
+
enumerable: true,
|
|
47
|
+
get: function () { return turnOrder.GameMethod; }
|
|
48
|
+
});
|
|
49
|
+
exports.INVALID_MOVE = turnOrder.INVALID_MOVE;
|
|
50
|
+
exports.Stage = turnOrder.Stage;
|
|
51
|
+
exports.TurnOrder = turnOrder.TurnOrder;
|
|
52
|
+
exports.PlayerView = PlayerView;
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
Object.defineProperty(exports, '__esModule', { value: true });
|
|
4
|
+
|
|
5
|
+
var Debug = require('./Debug-9d141c06.js');
|
|
6
|
+
require('./turn-order-b2ff8740.js');
|
|
7
|
+
require('immer');
|
|
8
|
+
require('./plugin-random-7425844d.js');
|
|
9
|
+
require('lodash.isplainobject');
|
|
10
|
+
require('flatted');
|
|
11
|
+
require('./reducer-16eec232.js');
|
|
12
|
+
require('rfc6902');
|
|
13
|
+
require('./ai-e0e8a768.js');
|
|
14
|
+
require('setimmediate');
|
|
15
|
+
|
|
16
|
+
|
|
17
|
+
|
|
18
|
+
exports.Debug = Debug.Debug;
|