2 // // Static informations:
6 // players: array of sid+id+name,
8 // increment: integer (seconds),
9 // type: string ("live" or "corr")
10 // imported: boolean (optional, default false)
11 // // Game (dynamic) state:
13 // moves: array of Move objects,
14 // clocks: array of integers,
15 // initime: array of integers (when clock start running),
16 // score: string (several options; '*' == running),
19 import { ajax
} from "@/utils/ajax";
20 import { store
} from "@/store";
22 function dbOperation(callback
) {
24 let DBOpenRequest
= window
.indexedDB
.open("vchess", 4);
26 DBOpenRequest
.onerror = function(event
) {
27 alert(store
.state
.tr
["Database error:"] + " " + event
.target
.errorCode
);
30 DBOpenRequest
.onsuccess = function() {
31 db
= DBOpenRequest
.result
;
36 DBOpenRequest
.onupgradeneeded = function(event
) {
37 let db
= event
.target
.result
;
38 db
.onerror = function(event
) {
40 store
.state
.tr
["Error while loading database:"] +
42 event
.target
.errorCode
45 // Create objectStore for vchess->games
46 let objectStore
= db
.createObjectStore("games", { keyPath: "id" });
47 objectStore
.createIndex("score", "score"); //to search by game result
51 export const GameStorage
= {
52 // Optional callback to get error status
53 add: function(game
, callback
) {
55 let transaction
= db
.transaction("games", "readwrite");
57 transaction
.oncomplete = function() {
58 callback({}); //everything's fine
60 transaction
.onerror = function() {
63 store
.state
.tr
["Game retrieval failed:"] + " " + transaction
.error
67 let objectStore
= transaction
.objectStore("games");
68 objectStore
.add(game
);
72 // TODO: also option to takeback a move ?
73 // obj: chat, move, fen, clocks, score[Msg], initime, ...
74 update: function(gameId
, obj
) {
75 if (Number
.isInteger(gameId
) || !isNaN(parseInt(gameId
))) {
76 // corr: only move, fen and score
77 ajax("/games", "PUT", {
80 // Some fields may be undefined:
85 scoreMsg: obj
.scoreMsg
,
86 drawOffer: obj
.drawOffer
93 .transaction("games", "readwrite")
94 .objectStore("games");
95 objectStore
.get(gameId
).onsuccess = function(event
) {
96 const game
= event
.target
.result
;
97 Object
.keys(obj
).forEach(k
=> {
98 if (k
== "move") game
.moves
.push(obj
[k
]);
99 else game
[k
] = obj
[k
];
101 objectStore
.put(game
); //save updated data
107 // Retrieve all local games (running, completed, imported...)
108 getAll: function(callback
) {
110 let objectStore
= db
.transaction("games").objectStore("games");
112 objectStore
.openCursor().onsuccess = function(event
) {
113 let cursor
= event
.target
.result
;
114 // if there is still another cursor to go, keep running this code
116 games
.push(cursor
.value
);
118 } else callback(games
);
123 // Retrieve any game from its identifiers (locally or on server)
124 // NOTE: need callback because result is obtained asynchronously
125 get: function(gameId
, callback
) {
126 // corr games identifiers are integers
127 if (Number
.isInteger(gameId
) || !isNaN(parseInt(gameId
))) {
128 ajax("/games", "GET", { gid: gameId
}, res
=> {
130 game
.moves
.forEach(m
=> {
131 m
.squares
= JSON
.parse(m
.squares
);
138 let objectStore
= db
.transaction("games").objectStore("games");
139 objectStore
.get(gameId
).onsuccess = function(event
) {
140 callback(event
.target
.result
);
146 getCurrent: function(callback
) {
148 let objectStore
= db
.transaction("games").objectStore("games");
149 objectStore
.get("*").onsuccess = function(event
) {
150 callback(event
.target
.result
);
155 // Delete a game in indexedDB
156 remove: function(gameId
, callback
) {
158 let transaction
= db
.transaction(["games"], "readwrite");
160 transaction
.oncomplete = function() {
161 callback({}); //everything's fine
163 transaction
.onerror = function() {
166 store
.state
.tr
["Game removal failed:"] + " " + transaction
.error
170 transaction
.objectStore("games").delete(gameId
);