@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,296 @@
|
|
|
1
|
+
import type { Object } from 'ts-toolbelt';
|
|
2
|
+
import type { State, Server, LogEntry } from '../../types';
|
|
3
|
+
|
|
4
|
+
export enum Type {
|
|
5
|
+
SYNC = 0,
|
|
6
|
+
ASYNC = 1,
|
|
7
|
+
}
|
|
8
|
+
|
|
9
|
+
/**
|
|
10
|
+
* Type guard that checks if a storage implementation is synchronous.
|
|
11
|
+
*/
|
|
12
|
+
export function isSynchronous(storageAPI: Sync | Async): storageAPI is Sync {
|
|
13
|
+
return storageAPI.type() === Type.SYNC;
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
/**
|
|
17
|
+
* Indicates which fields the fetch operation should return.
|
|
18
|
+
*/
|
|
19
|
+
export interface FetchOpts {
|
|
20
|
+
state?: boolean;
|
|
21
|
+
log?: boolean;
|
|
22
|
+
metadata?: boolean;
|
|
23
|
+
initialState?: boolean;
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
/**
|
|
27
|
+
* Data that can be retrieved from a database fetch query
|
|
28
|
+
*/
|
|
29
|
+
export interface FetchFields {
|
|
30
|
+
state: State;
|
|
31
|
+
log: LogEntry[];
|
|
32
|
+
metadata: Server.MatchData;
|
|
33
|
+
initialState: State;
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
/**
|
|
37
|
+
* The result of the fetch operation.
|
|
38
|
+
*/
|
|
39
|
+
export type FetchResult<O extends FetchOpts> = Object.Pick<
|
|
40
|
+
FetchFields,
|
|
41
|
+
Object.SelectKeys<O, true>
|
|
42
|
+
>;
|
|
43
|
+
|
|
44
|
+
/**
|
|
45
|
+
* Options passed when listing matches.
|
|
46
|
+
*/
|
|
47
|
+
export interface ListMatchesOpts {
|
|
48
|
+
gameName?: string;
|
|
49
|
+
where?: {
|
|
50
|
+
isGameover?: boolean;
|
|
51
|
+
updatedBefore?: number;
|
|
52
|
+
updatedAfter?: number;
|
|
53
|
+
};
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
/**
|
|
57
|
+
* @deprecated Use ListMatchesOpts instead
|
|
58
|
+
*/
|
|
59
|
+
export interface ListGamesOpts {
|
|
60
|
+
gameName?: string;
|
|
61
|
+
where?: {
|
|
62
|
+
isGameover?: boolean;
|
|
63
|
+
updatedBefore?: number;
|
|
64
|
+
updatedAfter?: number;
|
|
65
|
+
};
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
/**
|
|
69
|
+
* Options passed when creating a new match.
|
|
70
|
+
*/
|
|
71
|
+
export interface CreateMatchOpts {
|
|
72
|
+
initialState: State;
|
|
73
|
+
metadata: Server.MatchData;
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
/**
|
|
77
|
+
* @deprecated Use CreateMatchOpts instead
|
|
78
|
+
*/
|
|
79
|
+
export interface CreateGameOpts {
|
|
80
|
+
initialState: State;
|
|
81
|
+
metadata: Server.MatchData;
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
export abstract class Async {
|
|
85
|
+
/* istanbul ignore next */
|
|
86
|
+
type() {
|
|
87
|
+
/* istanbul ignore next */
|
|
88
|
+
return Type.ASYNC;
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
/**
|
|
92
|
+
* Connect.
|
|
93
|
+
*/
|
|
94
|
+
abstract connect();
|
|
95
|
+
|
|
96
|
+
/**
|
|
97
|
+
* Create a new match.
|
|
98
|
+
*
|
|
99
|
+
* This might just need to call setState and setMetadata in
|
|
100
|
+
* most implementations.
|
|
101
|
+
*
|
|
102
|
+
* However, it exists as a separate call so that the
|
|
103
|
+
* implementation can provision things differently when
|
|
104
|
+
* a match is created. For example, it might stow away the
|
|
105
|
+
* initial match state in a separate field for easier retrieval.
|
|
106
|
+
*/
|
|
107
|
+
/* istanbul ignore next */
|
|
108
|
+
async createMatch(matchID: string, opts: CreateMatchOpts): Promise<void> {
|
|
109
|
+
if (this.createGame) {
|
|
110
|
+
console.warn(
|
|
111
|
+
'The database connector does not implement a createMatch method.',
|
|
112
|
+
'\nUsing the deprecated createGame method instead.'
|
|
113
|
+
);
|
|
114
|
+
return this.createGame(matchID, opts);
|
|
115
|
+
} else {
|
|
116
|
+
console.error(
|
|
117
|
+
'The database connector does not implement a createMatch method.'
|
|
118
|
+
);
|
|
119
|
+
}
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
/**
|
|
123
|
+
* Create a new game.
|
|
124
|
+
*
|
|
125
|
+
* This might just need to call setState and setMetadata in
|
|
126
|
+
* most implementations.
|
|
127
|
+
*
|
|
128
|
+
* However, it exists as a separate call so that the
|
|
129
|
+
* implementation can provision things differently when
|
|
130
|
+
* a game is created. For example, it might stow away the
|
|
131
|
+
* initial game state in a separate field for easier retrieval.
|
|
132
|
+
*
|
|
133
|
+
* @deprecated Use createMatch instead, if implemented
|
|
134
|
+
*/
|
|
135
|
+
async createGame?(matchID: string, opts: CreateGameOpts): Promise<void>;
|
|
136
|
+
|
|
137
|
+
/**
|
|
138
|
+
* Update the game state.
|
|
139
|
+
*
|
|
140
|
+
* If passed a deltalog array, setState should append its contents to the
|
|
141
|
+
* existing log for this game.
|
|
142
|
+
*/
|
|
143
|
+
abstract setState(
|
|
144
|
+
matchID: string,
|
|
145
|
+
state: State,
|
|
146
|
+
deltalog?: LogEntry[]
|
|
147
|
+
): Promise<void>;
|
|
148
|
+
|
|
149
|
+
/**
|
|
150
|
+
* Update the game metadata.
|
|
151
|
+
*/
|
|
152
|
+
abstract setMetadata(
|
|
153
|
+
matchID: string,
|
|
154
|
+
metadata: Server.MatchData
|
|
155
|
+
): Promise<void>;
|
|
156
|
+
|
|
157
|
+
/**
|
|
158
|
+
* Fetch the game state.
|
|
159
|
+
*/
|
|
160
|
+
abstract fetch<O extends FetchOpts>(
|
|
161
|
+
matchID: string,
|
|
162
|
+
opts: O
|
|
163
|
+
): Promise<FetchResult<O>>;
|
|
164
|
+
|
|
165
|
+
/**
|
|
166
|
+
* Remove the game state.
|
|
167
|
+
*/
|
|
168
|
+
abstract wipe(matchID: string): Promise<void>;
|
|
169
|
+
|
|
170
|
+
/**
|
|
171
|
+
* Return all matches.
|
|
172
|
+
*/
|
|
173
|
+
/* istanbul ignore next */
|
|
174
|
+
async listMatches(opts?: ListMatchesOpts): Promise<string[]> {
|
|
175
|
+
if (this.listGames) {
|
|
176
|
+
console.warn(
|
|
177
|
+
'The database connector does not implement a listMatches method.',
|
|
178
|
+
'\nUsing the deprecated listGames method instead.'
|
|
179
|
+
);
|
|
180
|
+
return this.listGames(opts);
|
|
181
|
+
} else {
|
|
182
|
+
console.error(
|
|
183
|
+
'The database connector does not implement a listMatches method.'
|
|
184
|
+
);
|
|
185
|
+
}
|
|
186
|
+
}
|
|
187
|
+
|
|
188
|
+
/**
|
|
189
|
+
* Return all games.
|
|
190
|
+
*
|
|
191
|
+
* @deprecated Use listMatches instead, if implemented
|
|
192
|
+
*/
|
|
193
|
+
async listGames?(opts?: ListGamesOpts): Promise<string[]>;
|
|
194
|
+
}
|
|
195
|
+
|
|
196
|
+
export abstract class Sync {
|
|
197
|
+
type() {
|
|
198
|
+
return Type.SYNC;
|
|
199
|
+
}
|
|
200
|
+
|
|
201
|
+
/**
|
|
202
|
+
* Connect.
|
|
203
|
+
*/
|
|
204
|
+
connect() {
|
|
205
|
+
return;
|
|
206
|
+
}
|
|
207
|
+
|
|
208
|
+
/**
|
|
209
|
+
* Create a new match.
|
|
210
|
+
*
|
|
211
|
+
* This might just need to call setState and setMetadata in
|
|
212
|
+
* most implementations.
|
|
213
|
+
*
|
|
214
|
+
* However, it exists as a separate call so that the
|
|
215
|
+
* implementation can provision things differently when
|
|
216
|
+
* a match is created. For example, it might stow away the
|
|
217
|
+
* initial match state in a separate field for easier retrieval.
|
|
218
|
+
*/
|
|
219
|
+
/* istanbul ignore next */
|
|
220
|
+
createMatch(matchID: string, opts: CreateMatchOpts): void {
|
|
221
|
+
if (this.createGame) {
|
|
222
|
+
console.warn(
|
|
223
|
+
'The database connector does not implement a createMatch method.',
|
|
224
|
+
'\nUsing the deprecated createGame method instead.'
|
|
225
|
+
);
|
|
226
|
+
return this.createGame(matchID, opts);
|
|
227
|
+
} else {
|
|
228
|
+
console.error(
|
|
229
|
+
'The database connector does not implement a createMatch method.'
|
|
230
|
+
);
|
|
231
|
+
}
|
|
232
|
+
}
|
|
233
|
+
|
|
234
|
+
/**
|
|
235
|
+
* Create a new game.
|
|
236
|
+
*
|
|
237
|
+
* This might just need to call setState and setMetadata in
|
|
238
|
+
* most implementations.
|
|
239
|
+
*
|
|
240
|
+
* However, it exists as a separate call so that the
|
|
241
|
+
* implementation can provision things differently when
|
|
242
|
+
* a game is created. For example, it might stow away the
|
|
243
|
+
* initial game state in a separate field for easier retrieval.
|
|
244
|
+
*
|
|
245
|
+
* @deprecated Use createMatch instead, if implemented
|
|
246
|
+
*/
|
|
247
|
+
createGame?(matchID: string, opts: CreateGameOpts): void;
|
|
248
|
+
|
|
249
|
+
/**
|
|
250
|
+
* Update the match state.
|
|
251
|
+
*
|
|
252
|
+
* If passed a deltalog array, setState should append its contents to the
|
|
253
|
+
* existing log for this match.
|
|
254
|
+
*/
|
|
255
|
+
abstract setState(matchID: string, state: State, deltalog?: LogEntry[]): void;
|
|
256
|
+
|
|
257
|
+
/**
|
|
258
|
+
* Update the match metadata.
|
|
259
|
+
*/
|
|
260
|
+
abstract setMetadata(matchID: string, metadata: Server.MatchData): void;
|
|
261
|
+
|
|
262
|
+
/**
|
|
263
|
+
* Fetch the match state.
|
|
264
|
+
*/
|
|
265
|
+
abstract fetch<O extends FetchOpts>(matchID: string, opts: O): FetchResult<O>;
|
|
266
|
+
|
|
267
|
+
/**
|
|
268
|
+
* Remove the match state.
|
|
269
|
+
*/
|
|
270
|
+
abstract wipe(matchID: string): void;
|
|
271
|
+
|
|
272
|
+
/**
|
|
273
|
+
* Return all matches.
|
|
274
|
+
*/
|
|
275
|
+
/* istanbul ignore next */
|
|
276
|
+
listMatches(opts?: ListMatchesOpts): string[] {
|
|
277
|
+
if (this.listGames) {
|
|
278
|
+
console.warn(
|
|
279
|
+
'The database connector does not implement a listMatches method.',
|
|
280
|
+
'\nUsing the deprecated listGames method instead.'
|
|
281
|
+
);
|
|
282
|
+
return this.listGames(opts);
|
|
283
|
+
} else {
|
|
284
|
+
console.error(
|
|
285
|
+
'The database connector does not implement a listMatches method.'
|
|
286
|
+
);
|
|
287
|
+
}
|
|
288
|
+
}
|
|
289
|
+
|
|
290
|
+
/**
|
|
291
|
+
* Return all games.
|
|
292
|
+
*
|
|
293
|
+
* @deprecated Use listMatches instead, if implemented
|
|
294
|
+
*/
|
|
295
|
+
listGames?(opts?: ListGamesOpts): string[];
|
|
296
|
+
}
|
|
@@ -0,0 +1,221 @@
|
|
|
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 { FlatFile } from './flatfile';
|
|
10
|
+
import type { State, Server, LogEntry } from '../../types';
|
|
11
|
+
|
|
12
|
+
describe('FlatFile', () => {
|
|
13
|
+
let db: FlatFile;
|
|
14
|
+
|
|
15
|
+
beforeAll(async () => {
|
|
16
|
+
db = new FlatFile({ dir: './tmp', logging: false });
|
|
17
|
+
await db.connect();
|
|
18
|
+
});
|
|
19
|
+
|
|
20
|
+
afterEach(async () => {
|
|
21
|
+
await db.clear();
|
|
22
|
+
});
|
|
23
|
+
|
|
24
|
+
test('basic', async () => {
|
|
25
|
+
// Must return undefined when no game exists.
|
|
26
|
+
const result = await db.fetch('matchID', { state: true });
|
|
27
|
+
expect(result.state).toEqual(undefined);
|
|
28
|
+
|
|
29
|
+
// Create game.
|
|
30
|
+
const state: unknown = { a: 1 };
|
|
31
|
+
const metadata: unknown = { metadata: true };
|
|
32
|
+
|
|
33
|
+
await db.createMatch('matchID', {
|
|
34
|
+
initialState: state as State,
|
|
35
|
+
metadata: metadata as Server.MatchData,
|
|
36
|
+
});
|
|
37
|
+
|
|
38
|
+
// Must return created game.
|
|
39
|
+
{
|
|
40
|
+
const result = await db.fetch('matchID', {
|
|
41
|
+
state: true,
|
|
42
|
+
metadata: true,
|
|
43
|
+
initialState: true,
|
|
44
|
+
});
|
|
45
|
+
expect(result.state).toEqual({ a: 1 });
|
|
46
|
+
expect(result.initialState).toEqual(result.state);
|
|
47
|
+
expect(result.metadata).toEqual({ metadata: true });
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
// Must return all keys
|
|
51
|
+
const keys = await db.listMatches();
|
|
52
|
+
expect(keys).toEqual(['matchID']);
|
|
53
|
+
|
|
54
|
+
// Must remove match from DB
|
|
55
|
+
await db.wipe('matchID');
|
|
56
|
+
expect(
|
|
57
|
+
await db.fetch('matchID', { metadata: true, state: true, log: true })
|
|
58
|
+
).toEqual({});
|
|
59
|
+
|
|
60
|
+
// Shall not return error
|
|
61
|
+
await db.wipe('matchID');
|
|
62
|
+
|
|
63
|
+
// Shall create match, then clear DB, then check whether DB is cleared
|
|
64
|
+
await db.setState('game2', state as State);
|
|
65
|
+
await db.clear();
|
|
66
|
+
const keys2 = await db.listMatches();
|
|
67
|
+
expect(keys2).toHaveLength(0);
|
|
68
|
+
});
|
|
69
|
+
|
|
70
|
+
test('log', async () => {
|
|
71
|
+
const logEntry1: LogEntry = {
|
|
72
|
+
_stateID: 0,
|
|
73
|
+
action: {
|
|
74
|
+
type: 'MAKE_MOVE',
|
|
75
|
+
payload: { type: '', playerID: '0', args: [] },
|
|
76
|
+
},
|
|
77
|
+
turn: 0,
|
|
78
|
+
phase: '',
|
|
79
|
+
};
|
|
80
|
+
|
|
81
|
+
const logEntry2: LogEntry = {
|
|
82
|
+
_stateID: 1,
|
|
83
|
+
action: {
|
|
84
|
+
type: 'MAKE_MOVE',
|
|
85
|
+
payload: { type: '', playerID: '0', args: [] },
|
|
86
|
+
},
|
|
87
|
+
turn: 1,
|
|
88
|
+
phase: '',
|
|
89
|
+
};
|
|
90
|
+
|
|
91
|
+
await db.setState('matchID', null, [logEntry1]);
|
|
92
|
+
await db.setState('matchID', null, [logEntry2]);
|
|
93
|
+
|
|
94
|
+
const result = await db.fetch('matchID', { log: true });
|
|
95
|
+
expect(result.log).toEqual([logEntry1, logEntry2]);
|
|
96
|
+
});
|
|
97
|
+
|
|
98
|
+
describe('listMatches', () => {
|
|
99
|
+
beforeEach(async () => {
|
|
100
|
+
const state: unknown = { a: 1 };
|
|
101
|
+
|
|
102
|
+
await db.createMatch('matchID', {
|
|
103
|
+
initialState: state as State,
|
|
104
|
+
metadata: {
|
|
105
|
+
gameName: 'game1',
|
|
106
|
+
updatedAt: new Date(2020, 3).getTime(),
|
|
107
|
+
} as Server.MatchData,
|
|
108
|
+
});
|
|
109
|
+
|
|
110
|
+
await db.createMatch('matchID2', {
|
|
111
|
+
initialState: state as State,
|
|
112
|
+
metadata: {
|
|
113
|
+
gameName: 'game1',
|
|
114
|
+
gameover: 'gameover',
|
|
115
|
+
updatedAt: new Date(2020, 5).getTime(),
|
|
116
|
+
} as Server.MatchData,
|
|
117
|
+
});
|
|
118
|
+
|
|
119
|
+
await db.createMatch('matchID3', {
|
|
120
|
+
initialState: state as State,
|
|
121
|
+
metadata: {
|
|
122
|
+
gameName: 'game2',
|
|
123
|
+
updatedAt: new Date(2020, 4).getTime(),
|
|
124
|
+
} as Server.MatchData,
|
|
125
|
+
});
|
|
126
|
+
});
|
|
127
|
+
|
|
128
|
+
test('filter by gameName', async () => {
|
|
129
|
+
let keys = await db.listMatches();
|
|
130
|
+
expect(keys).toEqual(
|
|
131
|
+
expect.arrayContaining(['matchID', 'matchID2', 'matchID3'])
|
|
132
|
+
);
|
|
133
|
+
|
|
134
|
+
keys = await db.listMatches({ gameName: 'game1' });
|
|
135
|
+
expect(keys).toEqual(expect.arrayContaining(['matchID', 'matchID2']));
|
|
136
|
+
|
|
137
|
+
keys = await db.listMatches({ gameName: 'game2' });
|
|
138
|
+
expect(keys).toEqual(['matchID3']);
|
|
139
|
+
});
|
|
140
|
+
|
|
141
|
+
test('filter by isGameover', async () => {
|
|
142
|
+
let keys = await db.listMatches({});
|
|
143
|
+
|
|
144
|
+
expect(keys).toEqual(
|
|
145
|
+
expect.arrayContaining(['matchID', 'matchID2', 'matchID3'])
|
|
146
|
+
);
|
|
147
|
+
|
|
148
|
+
keys = await db.listMatches({ where: { isGameover: true } });
|
|
149
|
+
expect(keys).toEqual(['matchID2']);
|
|
150
|
+
|
|
151
|
+
keys = await db.listMatches({ where: { isGameover: false } });
|
|
152
|
+
expect(keys).toEqual(expect.arrayContaining(['matchID', 'matchID3']));
|
|
153
|
+
});
|
|
154
|
+
|
|
155
|
+
test('filter by updatedBefore', async () => {
|
|
156
|
+
const timestamp = new Date(2020, 4);
|
|
157
|
+
|
|
158
|
+
let keys = await db.listMatches({});
|
|
159
|
+
expect(keys).toEqual(
|
|
160
|
+
expect.arrayContaining(['matchID', 'matchID2', 'matchID3'])
|
|
161
|
+
);
|
|
162
|
+
|
|
163
|
+
keys = await db.listMatches({
|
|
164
|
+
where: { updatedBefore: timestamp.getTime() },
|
|
165
|
+
});
|
|
166
|
+
expect(keys).toEqual(expect.arrayContaining(['matchID']));
|
|
167
|
+
});
|
|
168
|
+
|
|
169
|
+
test('filter by updatedAfter', async () => {
|
|
170
|
+
const timestamp = new Date(2020, 4);
|
|
171
|
+
|
|
172
|
+
let keys = await db.listMatches({});
|
|
173
|
+
expect(keys).toEqual(
|
|
174
|
+
expect.arrayContaining(['matchID', 'matchID2', 'matchID3'])
|
|
175
|
+
);
|
|
176
|
+
|
|
177
|
+
keys = await db.listMatches({
|
|
178
|
+
where: { updatedAfter: timestamp.getTime() },
|
|
179
|
+
});
|
|
180
|
+
expect(keys).toEqual(['matchID2']);
|
|
181
|
+
});
|
|
182
|
+
|
|
183
|
+
test('filter combined', async () => {
|
|
184
|
+
const timestamp = new Date(2020, 4);
|
|
185
|
+
const timestamp2 = new Date(2020, 2, 15);
|
|
186
|
+
let keys = await db.listMatches({
|
|
187
|
+
gameName: 'chess',
|
|
188
|
+
where: { isGameover: true },
|
|
189
|
+
});
|
|
190
|
+
expect(keys).toEqual([]);
|
|
191
|
+
|
|
192
|
+
keys = await db.listMatches({
|
|
193
|
+
where: { isGameover: true, updatedBefore: timestamp.getTime() },
|
|
194
|
+
});
|
|
195
|
+
expect(keys).toEqual([]);
|
|
196
|
+
|
|
197
|
+
keys = await db.listMatches({
|
|
198
|
+
where: { isGameover: false, updatedBefore: timestamp.getTime() },
|
|
199
|
+
});
|
|
200
|
+
expect(keys).toEqual(['matchID']);
|
|
201
|
+
|
|
202
|
+
keys = await db.listMatches({
|
|
203
|
+
where: { isGameover: true, updatedAfter: timestamp.getTime() },
|
|
204
|
+
});
|
|
205
|
+
expect(keys).toEqual(['matchID2']);
|
|
206
|
+
|
|
207
|
+
keys = await db.listMatches({
|
|
208
|
+
where: { isGameover: false, updatedAfter: timestamp.getTime() },
|
|
209
|
+
});
|
|
210
|
+
expect(keys).toEqual([]);
|
|
211
|
+
|
|
212
|
+
keys = await db.listMatches({
|
|
213
|
+
where: {
|
|
214
|
+
updatedBefore: timestamp.getTime(),
|
|
215
|
+
updatedAfter: timestamp2.getTime(),
|
|
216
|
+
},
|
|
217
|
+
});
|
|
218
|
+
expect(keys).toEqual(['matchID']);
|
|
219
|
+
});
|
|
220
|
+
});
|
|
221
|
+
});
|