@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,27 @@
|
|
|
1
|
+
import type { RandomAPI } from '../plugins/random/random';
|
|
2
|
+
import RandomPlugin from '../plugins/plugin-random';
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* Test helper that creates a plugin to override the built-in random API.
|
|
6
|
+
*
|
|
7
|
+
* @param overrides - A map of method names to mock functions.
|
|
8
|
+
*
|
|
9
|
+
* @example
|
|
10
|
+
* const game = {
|
|
11
|
+
* plugins: [
|
|
12
|
+
* MockRandom({ D6: () => 1 }),
|
|
13
|
+
* ],
|
|
14
|
+
* };
|
|
15
|
+
*/
|
|
16
|
+
export const MockRandom = (
|
|
17
|
+
overrides: Partial<Record<keyof RandomAPI, (...args: any[]) => any>> = {}
|
|
18
|
+
): Omit<typeof RandomPlugin, 'flush'> => {
|
|
19
|
+
// Don’t include the original flush method, otherwise when the
|
|
20
|
+
// built-in random plugin flushes, it won’t have access to the
|
|
21
|
+
// state it needs.
|
|
22
|
+
const { flush, ...rest } = RandomPlugin;
|
|
23
|
+
return {
|
|
24
|
+
...rest,
|
|
25
|
+
api: (context) => ({ ...RandomPlugin.api(context), ...overrides }),
|
|
26
|
+
};
|
|
27
|
+
};
|
package/src/types.ts
ADDED
|
@@ -0,0 +1,511 @@
|
|
|
1
|
+
import type { Object } from 'ts-toolbelt';
|
|
2
|
+
import type Koa from 'koa';
|
|
3
|
+
import type { Store as ReduxStore } from 'redux';
|
|
4
|
+
import type * as ActionCreators from './core/action-creators';
|
|
5
|
+
import type { ActionErrorType, UpdateErrorType } from './core/errors';
|
|
6
|
+
import type { Flow } from './core/flow';
|
|
7
|
+
import type { CreateGameReducer } from './core/reducer';
|
|
8
|
+
import type { INVALID_MOVE } from './core/constants';
|
|
9
|
+
import type { GameMethod } from './core/game-methods';
|
|
10
|
+
import type { Auth } from './server/auth';
|
|
11
|
+
import type * as StorageAPI from './server/db/base';
|
|
12
|
+
import type { EventsAPI } from './plugins/plugin-events';
|
|
13
|
+
import type { LogAPI } from './plugins/plugin-log';
|
|
14
|
+
import type { RandomAPI } from './plugins/random/random';
|
|
15
|
+
import type { Operation } from 'rfc6902';
|
|
16
|
+
export type { StorageAPI };
|
|
17
|
+
|
|
18
|
+
export type AnyFn = (...args: any[]) => any;
|
|
19
|
+
|
|
20
|
+
// "Public" state to be communicated to clients.
|
|
21
|
+
export interface State<G extends any = any> {
|
|
22
|
+
G: G;
|
|
23
|
+
ctx: Ctx;
|
|
24
|
+
deltalog?: Array<LogEntry>;
|
|
25
|
+
plugins: {
|
|
26
|
+
[pluginName: string]: PluginState;
|
|
27
|
+
};
|
|
28
|
+
_undo: Array<Undo<G>>;
|
|
29
|
+
_redo: Array<Undo<G>>;
|
|
30
|
+
_stateID: number;
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
export type ErrorType = UpdateErrorType | ActionErrorType;
|
|
34
|
+
|
|
35
|
+
export interface ActionError {
|
|
36
|
+
type: ErrorType;
|
|
37
|
+
// TODO(#723): Figure out if we want to strongly type payloads.
|
|
38
|
+
payload?: any;
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
export interface TransientMetadata {
|
|
42
|
+
error?: ActionError;
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
// TODO(#732): Actually define a schema for the action dispatch results.
|
|
46
|
+
export type ActionResult = any;
|
|
47
|
+
|
|
48
|
+
// "Private" state that may include garbage that should be stripped before
|
|
49
|
+
// being handed back to a client.
|
|
50
|
+
export interface TransientState<G extends any = any> extends State<G> {
|
|
51
|
+
transients?: TransientMetadata;
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
export type PartialGameState = Pick<State, 'G' | 'ctx' | 'plugins'>;
|
|
55
|
+
|
|
56
|
+
export type StageName = string;
|
|
57
|
+
export type PlayerID = string;
|
|
58
|
+
|
|
59
|
+
export type StageArg =
|
|
60
|
+
| StageName
|
|
61
|
+
| {
|
|
62
|
+
stage?: StageName;
|
|
63
|
+
/** @deprecated Use `minMoves` and `maxMoves` instead. */
|
|
64
|
+
moveLimit?: number;
|
|
65
|
+
minMoves?: number;
|
|
66
|
+
maxMoves?: number;
|
|
67
|
+
};
|
|
68
|
+
|
|
69
|
+
export type ActivePlayersArg =
|
|
70
|
+
| PlayerID[]
|
|
71
|
+
| {
|
|
72
|
+
currentPlayer?: StageArg;
|
|
73
|
+
others?: StageArg;
|
|
74
|
+
all?: StageArg;
|
|
75
|
+
value?: Record<PlayerID, StageArg>;
|
|
76
|
+
minMoves?: number;
|
|
77
|
+
maxMoves?: number;
|
|
78
|
+
/** @deprecated Use `minMoves` and `maxMoves` instead. */
|
|
79
|
+
moveLimit?: number;
|
|
80
|
+
revert?: boolean;
|
|
81
|
+
next?: ActivePlayersArg;
|
|
82
|
+
};
|
|
83
|
+
|
|
84
|
+
export interface ActivePlayers {
|
|
85
|
+
[playerID: string]: StageName;
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
export interface Ctx {
|
|
89
|
+
numPlayers: number;
|
|
90
|
+
playOrder: Array<PlayerID>;
|
|
91
|
+
playOrderPos: number;
|
|
92
|
+
activePlayers: null | ActivePlayers;
|
|
93
|
+
currentPlayer: PlayerID;
|
|
94
|
+
numMoves?: number;
|
|
95
|
+
gameover?: any;
|
|
96
|
+
turn: number;
|
|
97
|
+
phase: string;
|
|
98
|
+
_activePlayersMinMoves?: Record<PlayerID, number>;
|
|
99
|
+
_activePlayersMaxMoves?: Record<PlayerID, number>;
|
|
100
|
+
_activePlayersNumMoves?: Record<PlayerID, number>;
|
|
101
|
+
_prevActivePlayers?: Array<{
|
|
102
|
+
activePlayers: null | ActivePlayers;
|
|
103
|
+
_activePlayersMinMoves?: Record<PlayerID, number>;
|
|
104
|
+
_activePlayersMaxMoves?: Record<PlayerID, number>;
|
|
105
|
+
_activePlayersNumMoves?: Record<PlayerID, number>;
|
|
106
|
+
}>;
|
|
107
|
+
_nextActivePlayers?: ActivePlayersArg;
|
|
108
|
+
_random?: {
|
|
109
|
+
seed: string | number;
|
|
110
|
+
};
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
export interface DefaultPluginAPIs {
|
|
114
|
+
events: EventsAPI;
|
|
115
|
+
log: LogAPI;
|
|
116
|
+
random: RandomAPI;
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
export interface PluginState {
|
|
120
|
+
data: any;
|
|
121
|
+
api?: any;
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
export interface LogEntry {
|
|
125
|
+
action:
|
|
126
|
+
| ActionShape.MakeMove
|
|
127
|
+
| ActionShape.GameEvent
|
|
128
|
+
| ActionShape.Undo
|
|
129
|
+
| ActionShape.Redo;
|
|
130
|
+
_stateID: number;
|
|
131
|
+
turn: number;
|
|
132
|
+
phase: string;
|
|
133
|
+
redact?: boolean;
|
|
134
|
+
automatic?: boolean;
|
|
135
|
+
metadata?: any;
|
|
136
|
+
patch?: Operation[];
|
|
137
|
+
}
|
|
138
|
+
|
|
139
|
+
export interface PluginContext<
|
|
140
|
+
API extends any = any,
|
|
141
|
+
Data extends any = any,
|
|
142
|
+
G extends any = any
|
|
143
|
+
> {
|
|
144
|
+
G: G;
|
|
145
|
+
ctx: Ctx;
|
|
146
|
+
game: Game;
|
|
147
|
+
api: API;
|
|
148
|
+
data: Data;
|
|
149
|
+
}
|
|
150
|
+
|
|
151
|
+
export interface Plugin<
|
|
152
|
+
API extends any = any,
|
|
153
|
+
Data extends any = any,
|
|
154
|
+
G extends any = any
|
|
155
|
+
> {
|
|
156
|
+
name: string;
|
|
157
|
+
noClient?: (context: PluginContext<API, Data, G>) => boolean;
|
|
158
|
+
setup?: (setupCtx: { G: G; ctx: Ctx; game: Game<G> }) => Data;
|
|
159
|
+
isInvalid?: (
|
|
160
|
+
context: Omit<PluginContext<API, Data, G>, 'api'>
|
|
161
|
+
) => false | string;
|
|
162
|
+
action?: (data: Data, payload: ActionShape.Plugin['payload']) => Data;
|
|
163
|
+
api?: (context: {
|
|
164
|
+
G: G;
|
|
165
|
+
ctx: Ctx;
|
|
166
|
+
game: Game<G>;
|
|
167
|
+
data: Data;
|
|
168
|
+
playerID?: PlayerID;
|
|
169
|
+
}) => API;
|
|
170
|
+
flush?: (context: PluginContext<API, Data, G>) => Data;
|
|
171
|
+
dangerouslyFlushRawState?: (flushCtx: {
|
|
172
|
+
state: State<G>;
|
|
173
|
+
game: Game<G>;
|
|
174
|
+
api: API;
|
|
175
|
+
data: Data;
|
|
176
|
+
}) => State<G>;
|
|
177
|
+
fnWrap?: (
|
|
178
|
+
moveOrHook: (context: FnContext<G>, ...args: any[]) => any,
|
|
179
|
+
methodType: GameMethod
|
|
180
|
+
) => (context: FnContext<G>, ...args: any[]) => any;
|
|
181
|
+
playerView?: (context: {
|
|
182
|
+
G: G;
|
|
183
|
+
ctx: Ctx;
|
|
184
|
+
game: Game<G>;
|
|
185
|
+
data: Data;
|
|
186
|
+
playerID?: PlayerID | null;
|
|
187
|
+
}) => any;
|
|
188
|
+
}
|
|
189
|
+
|
|
190
|
+
export type FnContext<
|
|
191
|
+
G extends any = any,
|
|
192
|
+
PluginAPIs extends Record<string, unknown> = Record<string, unknown>
|
|
193
|
+
> = PluginAPIs &
|
|
194
|
+
DefaultPluginAPIs & {
|
|
195
|
+
G: G;
|
|
196
|
+
ctx: Ctx;
|
|
197
|
+
};
|
|
198
|
+
|
|
199
|
+
export type MoveFn<
|
|
200
|
+
G extends any = any,
|
|
201
|
+
PluginAPIs extends Record<string, unknown> = Record<string, unknown>
|
|
202
|
+
> = (
|
|
203
|
+
context: FnContext<G, PluginAPIs> & { playerID: PlayerID },
|
|
204
|
+
...args: any[]
|
|
205
|
+
) => void | G | typeof INVALID_MOVE;
|
|
206
|
+
|
|
207
|
+
export interface LongFormMove<
|
|
208
|
+
G extends any = any,
|
|
209
|
+
PluginAPIs extends Record<string, unknown> = Record<string, unknown>
|
|
210
|
+
> {
|
|
211
|
+
move: MoveFn<G, PluginAPIs>;
|
|
212
|
+
redact?: boolean | ((context: { G: G; ctx: Ctx }) => boolean);
|
|
213
|
+
noLimit?: boolean;
|
|
214
|
+
client?: boolean;
|
|
215
|
+
undoable?: boolean | ((context: { G: G; ctx: Ctx }) => boolean);
|
|
216
|
+
ignoreStaleStateID?: boolean;
|
|
217
|
+
}
|
|
218
|
+
|
|
219
|
+
export type Move<
|
|
220
|
+
G extends any = any,
|
|
221
|
+
PluginAPIs extends Record<string, unknown> = Record<string, unknown>
|
|
222
|
+
> = MoveFn<G, PluginAPIs> | LongFormMove<G, PluginAPIs>;
|
|
223
|
+
|
|
224
|
+
export interface MoveMap<
|
|
225
|
+
G extends any = any,
|
|
226
|
+
PluginAPIs extends Record<string, unknown> = Record<string, unknown>
|
|
227
|
+
> {
|
|
228
|
+
[moveName: string]: Move<G, PluginAPIs>;
|
|
229
|
+
}
|
|
230
|
+
|
|
231
|
+
export interface PhaseConfig<
|
|
232
|
+
G extends any = any,
|
|
233
|
+
PluginAPIs extends Record<string, unknown> = Record<string, unknown>
|
|
234
|
+
> {
|
|
235
|
+
start?: boolean;
|
|
236
|
+
next?: ((context: FnContext<G, PluginAPIs>) => string | void) | string;
|
|
237
|
+
onBegin?: (context: FnContext<G, PluginAPIs>) => void | G;
|
|
238
|
+
onEnd?: (context: FnContext<G, PluginAPIs>) => void | G;
|
|
239
|
+
endIf?: (
|
|
240
|
+
context: FnContext<G, PluginAPIs>
|
|
241
|
+
) => boolean | void | { next: string };
|
|
242
|
+
moves?: MoveMap<G, PluginAPIs>;
|
|
243
|
+
turn?: TurnConfig<G, PluginAPIs>;
|
|
244
|
+
wrapped?: {
|
|
245
|
+
endIf?: (state: State<G>) => boolean | void | { next: string };
|
|
246
|
+
onBegin?: (state: State<G>) => void | G;
|
|
247
|
+
onEnd?: (state: State<G>) => void | G;
|
|
248
|
+
next?: (state: State<G>) => string | void;
|
|
249
|
+
};
|
|
250
|
+
}
|
|
251
|
+
|
|
252
|
+
export interface StageConfig<
|
|
253
|
+
G extends any = any,
|
|
254
|
+
PluginAPIs extends Record<string, unknown> = Record<string, unknown>
|
|
255
|
+
> {
|
|
256
|
+
moves?: MoveMap<G, PluginAPIs>;
|
|
257
|
+
next?: string;
|
|
258
|
+
}
|
|
259
|
+
|
|
260
|
+
export interface StageMap<
|
|
261
|
+
G extends any = any,
|
|
262
|
+
PluginAPIs extends Record<string, unknown> = Record<string, unknown>
|
|
263
|
+
> {
|
|
264
|
+
[stageName: string]: StageConfig<G, PluginAPIs>;
|
|
265
|
+
}
|
|
266
|
+
|
|
267
|
+
export interface TurnOrderConfig<
|
|
268
|
+
G extends any = any,
|
|
269
|
+
PluginAPIs extends Record<string, unknown> = Record<string, unknown>
|
|
270
|
+
> {
|
|
271
|
+
first: (context: FnContext<G, PluginAPIs>) => number;
|
|
272
|
+
next: (context: FnContext<G, PluginAPIs>) => number | undefined;
|
|
273
|
+
playOrder?: (context: FnContext<G, PluginAPIs>) => PlayerID[];
|
|
274
|
+
}
|
|
275
|
+
|
|
276
|
+
export interface TurnConfig<
|
|
277
|
+
G extends any = any,
|
|
278
|
+
PluginAPIs extends Record<string, unknown> = Record<string, unknown>
|
|
279
|
+
> {
|
|
280
|
+
activePlayers?: ActivePlayersArg;
|
|
281
|
+
minMoves?: number;
|
|
282
|
+
maxMoves?: number;
|
|
283
|
+
/** @deprecated Use `minMoves` and `maxMoves` instead. */
|
|
284
|
+
moveLimit?: number;
|
|
285
|
+
onBegin?: (context: FnContext<G, PluginAPIs>) => void | G;
|
|
286
|
+
onEnd?: (context: FnContext<G, PluginAPIs>) => void | G;
|
|
287
|
+
endIf?: (
|
|
288
|
+
context: FnContext<G, PluginAPIs>
|
|
289
|
+
) => boolean | void | { next: PlayerID };
|
|
290
|
+
onMove?: (
|
|
291
|
+
context: FnContext<G, PluginAPIs> & { playerID: PlayerID }
|
|
292
|
+
) => void | G;
|
|
293
|
+
stages?: StageMap<G, PluginAPIs>;
|
|
294
|
+
order?: TurnOrderConfig<G, PluginAPIs>;
|
|
295
|
+
wrapped?: {
|
|
296
|
+
endIf?: (state: State<G>) => boolean | void | { next: PlayerID };
|
|
297
|
+
onBegin?: (state: State<G>) => void | G;
|
|
298
|
+
onEnd?: (state: State<G>) => void | G;
|
|
299
|
+
onMove?: (state: State<G> & { playerID: PlayerID }) => void | G;
|
|
300
|
+
};
|
|
301
|
+
}
|
|
302
|
+
|
|
303
|
+
export interface PhaseMap<
|
|
304
|
+
G extends any = any,
|
|
305
|
+
PluginAPIs extends Record<string, unknown> = Record<string, unknown>
|
|
306
|
+
> {
|
|
307
|
+
[phaseName: string]: PhaseConfig<G, PluginAPIs>;
|
|
308
|
+
}
|
|
309
|
+
|
|
310
|
+
export type AiEnumerate = Array<
|
|
311
|
+
| { event: string; args?: any[] }
|
|
312
|
+
| { move: string; args?: any[] }
|
|
313
|
+
| ActionShape.MakeMove
|
|
314
|
+
| ActionShape.GameEvent
|
|
315
|
+
>;
|
|
316
|
+
|
|
317
|
+
export interface Game<
|
|
318
|
+
G extends any = any,
|
|
319
|
+
PluginAPIs extends Record<string, unknown> = Record<string, unknown>,
|
|
320
|
+
SetupData extends any = any
|
|
321
|
+
> {
|
|
322
|
+
name?: string;
|
|
323
|
+
minPlayers?: number;
|
|
324
|
+
maxPlayers?: number;
|
|
325
|
+
deltaState?: boolean;
|
|
326
|
+
disableUndo?: boolean;
|
|
327
|
+
seed?: string | number;
|
|
328
|
+
setup?: (
|
|
329
|
+
context: PluginAPIs & DefaultPluginAPIs & { ctx: Ctx },
|
|
330
|
+
setupData?: SetupData
|
|
331
|
+
) => G;
|
|
332
|
+
validateSetupData?: (
|
|
333
|
+
setupData: SetupData | undefined,
|
|
334
|
+
numPlayers: number
|
|
335
|
+
) => string | undefined;
|
|
336
|
+
moves?: MoveMap<G, PluginAPIs>;
|
|
337
|
+
phases?: PhaseMap<G, PluginAPIs>;
|
|
338
|
+
turn?: TurnConfig<G, PluginAPIs>;
|
|
339
|
+
events?: {
|
|
340
|
+
endGame?: boolean;
|
|
341
|
+
endPhase?: boolean;
|
|
342
|
+
endTurn?: boolean;
|
|
343
|
+
setPhase?: boolean;
|
|
344
|
+
endStage?: boolean;
|
|
345
|
+
setStage?: boolean;
|
|
346
|
+
pass?: boolean;
|
|
347
|
+
setActivePlayers?: boolean;
|
|
348
|
+
};
|
|
349
|
+
endIf?: (context: FnContext<G, PluginAPIs>) => any;
|
|
350
|
+
onEnd?: (context: FnContext<G, PluginAPIs>) => void | G;
|
|
351
|
+
playerView?: (context: { G: G; ctx: Ctx; playerID: PlayerID | null }) => any;
|
|
352
|
+
plugins?: Array<Plugin<any, any, G>>;
|
|
353
|
+
ai?: {
|
|
354
|
+
enumerate: (G: G, ctx: Ctx, playerID: PlayerID) => AiEnumerate;
|
|
355
|
+
};
|
|
356
|
+
processMove?: (
|
|
357
|
+
state: State<G>,
|
|
358
|
+
action: ActionPayload.MakeMove
|
|
359
|
+
) => State<G> | typeof INVALID_MOVE;
|
|
360
|
+
flow?: ReturnType<typeof Flow>;
|
|
361
|
+
}
|
|
362
|
+
|
|
363
|
+
export type Undo<G extends any = any> = {
|
|
364
|
+
G: G;
|
|
365
|
+
ctx: Ctx;
|
|
366
|
+
plugins: {
|
|
367
|
+
[pluginName: string]: PluginState;
|
|
368
|
+
};
|
|
369
|
+
moveType?: string;
|
|
370
|
+
playerID?: PlayerID;
|
|
371
|
+
};
|
|
372
|
+
|
|
373
|
+
export namespace Server {
|
|
374
|
+
export type GenerateCredentials = (
|
|
375
|
+
ctx: Koa.DefaultContext
|
|
376
|
+
) => Promise<string> | string;
|
|
377
|
+
|
|
378
|
+
export type AuthenticateCredentials = (
|
|
379
|
+
credentials: string,
|
|
380
|
+
playerMetadata: PlayerMetadata
|
|
381
|
+
) => Promise<boolean> | boolean;
|
|
382
|
+
|
|
383
|
+
export type PlayerMetadata = {
|
|
384
|
+
id: number;
|
|
385
|
+
name?: string;
|
|
386
|
+
credentials?: string;
|
|
387
|
+
data?: any;
|
|
388
|
+
isConnected?: boolean;
|
|
389
|
+
};
|
|
390
|
+
|
|
391
|
+
export interface MatchData {
|
|
392
|
+
gameName: string;
|
|
393
|
+
players: { [id: number]: PlayerMetadata };
|
|
394
|
+
setupData?: any;
|
|
395
|
+
gameover?: any;
|
|
396
|
+
nextMatchID?: string;
|
|
397
|
+
unlisted?: boolean;
|
|
398
|
+
createdAt: number;
|
|
399
|
+
updatedAt: number;
|
|
400
|
+
}
|
|
401
|
+
|
|
402
|
+
export type AppCtx = Koa.DefaultContext & {
|
|
403
|
+
db: StorageAPI.Async | StorageAPI.Sync;
|
|
404
|
+
auth: Auth;
|
|
405
|
+
};
|
|
406
|
+
|
|
407
|
+
export type App = Koa<Koa.DefaultState, AppCtx>;
|
|
408
|
+
}
|
|
409
|
+
|
|
410
|
+
export namespace LobbyAPI {
|
|
411
|
+
export type GameList = string[];
|
|
412
|
+
type PublicPlayerMetadata = Omit<Server.PlayerMetadata, 'credentials'>;
|
|
413
|
+
export type Match = Omit<Server.MatchData, 'players'> & {
|
|
414
|
+
matchID: string;
|
|
415
|
+
players: PublicPlayerMetadata[];
|
|
416
|
+
};
|
|
417
|
+
export interface MatchList {
|
|
418
|
+
matches: Match[];
|
|
419
|
+
}
|
|
420
|
+
export interface CreatedMatch {
|
|
421
|
+
matchID: string;
|
|
422
|
+
}
|
|
423
|
+
export interface JoinedMatch {
|
|
424
|
+
playerID: string;
|
|
425
|
+
playerCredentials: string;
|
|
426
|
+
}
|
|
427
|
+
export interface NextMatch {
|
|
428
|
+
nextMatchID: string;
|
|
429
|
+
}
|
|
430
|
+
}
|
|
431
|
+
|
|
432
|
+
export type Reducer = ReturnType<typeof CreateGameReducer>;
|
|
433
|
+
export type Store = ReduxStore<State, ActionShape.Any>;
|
|
434
|
+
|
|
435
|
+
export namespace CredentialedActionShape {
|
|
436
|
+
export type MakeMove = ReturnType<typeof ActionCreators.makeMove>;
|
|
437
|
+
export type GameEvent = ReturnType<typeof ActionCreators.gameEvent>;
|
|
438
|
+
export type Plugin = ReturnType<typeof ActionCreators.plugin>;
|
|
439
|
+
export type AutomaticGameEvent = ReturnType<
|
|
440
|
+
typeof ActionCreators.automaticGameEvent
|
|
441
|
+
>;
|
|
442
|
+
export type Undo = ReturnType<typeof ActionCreators.undo>;
|
|
443
|
+
export type Redo = ReturnType<typeof ActionCreators.redo>;
|
|
444
|
+
export type Any =
|
|
445
|
+
| MakeMove
|
|
446
|
+
| GameEvent
|
|
447
|
+
| AutomaticGameEvent
|
|
448
|
+
| Undo
|
|
449
|
+
| Redo
|
|
450
|
+
| Plugin;
|
|
451
|
+
}
|
|
452
|
+
|
|
453
|
+
export namespace ActionShape {
|
|
454
|
+
type StripCredentials<T extends CredentialedActionShape.Any> = Object.P.Omit<
|
|
455
|
+
T,
|
|
456
|
+
['payload', 'credentials']
|
|
457
|
+
>;
|
|
458
|
+
export type MakeMove = StripCredentials<CredentialedActionShape.MakeMove>;
|
|
459
|
+
export type GameEvent = StripCredentials<CredentialedActionShape.GameEvent>;
|
|
460
|
+
export type Plugin = StripCredentials<CredentialedActionShape.Plugin>;
|
|
461
|
+
export type AutomaticGameEvent =
|
|
462
|
+
StripCredentials<CredentialedActionShape.AutomaticGameEvent>;
|
|
463
|
+
export type Sync = ReturnType<typeof ActionCreators.sync>;
|
|
464
|
+
export type Update = ReturnType<typeof ActionCreators.update>;
|
|
465
|
+
export type Patch = ReturnType<typeof ActionCreators.patch>;
|
|
466
|
+
export type Reset = ReturnType<typeof ActionCreators.reset>;
|
|
467
|
+
export type Undo = StripCredentials<CredentialedActionShape.Undo>;
|
|
468
|
+
export type Redo = StripCredentials<CredentialedActionShape.Redo>;
|
|
469
|
+
// Private type used only for internal error processing.
|
|
470
|
+
// Included here to preserve type-checking of reducer inputs.
|
|
471
|
+
export type StripTransients = ReturnType<
|
|
472
|
+
typeof ActionCreators.stripTransients
|
|
473
|
+
>;
|
|
474
|
+
export type Any =
|
|
475
|
+
| MakeMove
|
|
476
|
+
| GameEvent
|
|
477
|
+
| AutomaticGameEvent
|
|
478
|
+
| Sync
|
|
479
|
+
| Update
|
|
480
|
+
| Patch
|
|
481
|
+
| Reset
|
|
482
|
+
| Undo
|
|
483
|
+
| Redo
|
|
484
|
+
| Plugin
|
|
485
|
+
| StripTransients;
|
|
486
|
+
}
|
|
487
|
+
|
|
488
|
+
export namespace ActionPayload {
|
|
489
|
+
type GetPayload<T extends ActionShape.Any> = Object.At<T, 'payload'>;
|
|
490
|
+
export type MakeMove = GetPayload<ActionShape.MakeMove>;
|
|
491
|
+
export type GameEvent = GetPayload<ActionShape.GameEvent>;
|
|
492
|
+
}
|
|
493
|
+
|
|
494
|
+
export type FilteredMetadata = {
|
|
495
|
+
id: number;
|
|
496
|
+
name?: string;
|
|
497
|
+
isConnected?: boolean;
|
|
498
|
+
}[];
|
|
499
|
+
|
|
500
|
+
export interface SyncInfo {
|
|
501
|
+
state: State;
|
|
502
|
+
filteredMetadata: FilteredMetadata;
|
|
503
|
+
initialState: State;
|
|
504
|
+
log: LogEntry[];
|
|
505
|
+
}
|
|
506
|
+
|
|
507
|
+
export interface ChatMessage {
|
|
508
|
+
id: string;
|
|
509
|
+
sender: PlayerID;
|
|
510
|
+
payload: any;
|
|
511
|
+
}
|