1 import { extractTime
} from "@/utils/timeControl";
2 import { shuffle
} from "@/utils/alea";
4 // TODO: show game structure
6 // { gameId: "", players: [], timeControl: "", clocks: [] }
9 function dbOperation(callback
)
12 let DBOpenRequest
= window
.indexedDB
.open("vchess", 4);
14 DBOpenRequest
.onerror = function(event
) {
15 alert("Database error: " + event
.target
.errorCode
);
18 DBOpenRequest
.onsuccess = function(event
) {
19 db
= DBOpenRequest
.result
;
24 DBOpenRequest
.onupgradeneeded = function(event
) {
25 let db
= event
.target
.result
;
26 db
.onerror = function(event
) {
27 alert("Error while loading database: " + event
.target
.errorCode
);
29 // Create objectStore for vchess->games
30 db
.createObjectStore("games", { keyPath: "gameId" });
34 // Optional callback to get error status
35 function addGame(game
, callback
)
38 let transaction
= db
.transaction(["games"], "readwrite");
41 transaction
.oncomplete = function() {
42 callback({}); //everything's fine
44 transaction
.onerror = function() {
45 callback({errmsg: "addGame failed: " + transaction
.error
});
48 let objectStore
= transaction
.objectStore("games");
49 objectStore
.add(game
);
53 // Clear current live game from localStorage
55 localStorage
.deleteItem("gameInfo");
56 localStorage
.deleteItem("gameState");
62 return Object
.assign({},
63 JSON
.parse(localStorage
.getItem("gameInfo")),
64 JSON
.parse(localStorage
.getItem("gameState")));
67 // Only called internally after a score update
68 function transferToDb()
70 addGame(getCurrent(), (err
) => {
77 export const GameStorage
=
82 // NOTE: when >= 3 players, better use an array + shuffle for mycolor
83 const mycolor
= (Math
.random() < 0.5 ? "w" : "b");
84 // Shuffle players order (white then black then other colors).
85 const players
= shuffle(o
.players
);
86 // Extract times (in [milli]seconds), set clocks, store in localStorage
87 const tc
= extractTime(o
.timeControl
);
89 // game infos: constant
97 timeControl: o
.timeControl
,
98 increment: tc
.increment
,
99 mode: "live", //function for live games only
102 // game state: will be updated
107 clocks: [...Array(o
.players
.length
)].fill(tc
.mainTime
),
108 started: [...Array(o
.players
.length
)].fill(false),
112 localStorage
.setItem("gameInfo", JSON
.stringify(gameInfo
));
113 localStorage
.setItem("gameState", JSON
.stringify(gameState
));
117 // TODO: also option to takeback a move ? Is fen included in move ?
118 // NOTE: for live games only (all on server for corr)
119 update: function(fen
, moves
, clocks
, started
, score
)
121 let gameState
= JSON
.parse(localStorage
.getItem("gameState"));
124 gameState
.moves
= moves
;
126 gameState
.clocks
= clocks
;
129 gameState
.started
= started
;
131 gameState
.score
= score
;
132 localStorage
.setItem("gameState", JSON
.stringify(gameState
));
133 if (!!score
&& score
!= "*")
134 transferToDb(); //game is over
138 // Since DB requests are asynchronous, require a callback using the result
139 // TODO: option for remote retrieval (third arg, or just "gameRef")
140 getLocal: function(callback
, gameId
)
143 dbOperation((db
) => {
144 // TODO: if gameId is provided, limit search to gameId (just .get(gameId). ...)
145 let objectStore
= db
.transaction('games').objectStore('games');
146 objectStore
.openCursor().onsuccess = function(event
) {
147 var cursor
= event
.target
.result
;
148 // if there is still another cursor to go, keep runing this code
151 games
.push(cursor
.value
);
160 // Delete a game in indexedDB
161 remove: function(gameId
, callback
)
163 dbOperation((db
) => {
164 let transaction
= db
.transaction(["games"], "readwrite");
167 transaction
.oncomplete = function() {
168 callback({}); //everything's fine
170 transaction
.onerror = function() {
171 callback({errmsg: "deleteGame failed: " + transaction
.error
});
174 transaction
.objectStore("games").delete(gameId
);
178 // Retrieve any live game from its identifiers (remote or not, running or not)
179 // NOTE: need callback because result might be obtained asynchronously
180 get: function(gameRef
, callback
)
182 const gid
= gameRef
.id
;
183 const rid
= gameRef
.rid
; //may be blank
186 // TODO: send request to server which forward to user sid == rid,
187 // need to listen to "remote game" event in main hall ?
188 return callback({}); //means "the game will arrive later" (TODO...)
191 const gameInfoStr
= localStorage
.getItem("gameInfo");
194 const gameInfo
= JSON
.parse(gameInfoStr
);
195 if (gameInfo
.gameId
== gid
)
197 const gameState
= JSON
.parse(localStorage
.getItem("gameState"));
198 return callback(Object
.assign({}, gameInfo
, gameState
));
202 // Game is local and not running
203 getLocal(callback
, gid
);