GameStorage.getCorrGame ok + add watchers for st.variants
[vchess.git] / client / src / utils / gameStorage.js
CommitLineData
967a2686
BA
1// Game object: {
2// // Static informations:
3// gameId: string
4// vname: string,
5// fenStart: string,
6// players: array of sid+id+name,
7// timeControl: string,
8// increment: integer (seconds),
9// mode: string ("live" or "corr")
10// imported: boolean (optional, default false)
11// // Game (dynamic) state:
12// fen: string,
13// moves: array of Move objects,
14// clocks: array of integers,
809ba2aa 15// initime: array of integers (when clock start running),
967a2686
BA
16// score: string (several options; '*' == running),
17// }
18
fd7aea36
BA
19import { ajax } from "@/utils/ajax";
20
967a2686
BA
21function dbOperation(callback)
22{
23 let db = null;
24 let DBOpenRequest = window.indexedDB.open("vchess", 4);
25
26 DBOpenRequest.onerror = function(event) {
27 alert("Database error: " + event.target.errorCode);
28 };
29
30 DBOpenRequest.onsuccess = function(event) {
31 db = DBOpenRequest.result;
32 callback(db);
33 db.close();
34 };
35
36 DBOpenRequest.onupgradeneeded = function(event) {
37 let db = event.target.result;
38 db.onerror = function(event) {
39 alert("Error while loading database: " + event.target.errorCode);
40 };
41 // Create objectStore for vchess->games
42c15a75
BA
42 let objectStore = db.createObjectStore("games", { keyPath: "gameId" });
43 objectStore.createIndex("score", "score"); //to search by game result
967a2686
BA
44 }
45}
46
47export const GameStorage =
48{
49 // Optional callback to get error status
50 add: function(game, callback)
51 {
52 dbOperation((db) => {
53 let transaction = db.transaction("games", "readwrite");
54 if (callback)
55 {
56 transaction.oncomplete = function() {
57 callback({}); //everything's fine
58 }
59 transaction.onerror = function() {
60 callback({errmsg: "addGame failed: " + transaction.error});
61 };
62 }
63 let objectStore = transaction.objectStore("games");
64 objectStore.add(game);
65 });
66 },
67
68 // TODO: also option to takeback a move ?
69 // NOTE: for live games only (all on server for corr)
809ba2aa 70 update: function(gameId, obj) //colorIdx, nextIdx, move, fen, addTime, score
967a2686
BA
71 {
72 dbOperation((db) => {
73 let objectStore = db.transaction("games", "readwrite").objectStore("games");
74 objectStore.get(gameId).onsuccess = function(event) {
75 const game = event.target.result;
76 if (!!obj.move)
77 {
78 game.moves.push(obj.move);
79 game.fen = obj.fen;
66d03f23 80 game.clocks[obj.colorIdx] += obj.addTime;
809ba2aa 81 game.initime[obj.nextIdx] = Date.now();
967a2686 82 }
967a2686
BA
83 if (!!obj.score)
84 game.score = obj.score;
85 objectStore.put(game); //save updated data
86 }
87 });
88 },
89
fd7aea36
BA
90 // Retrieve all local games (running, completed, imported...)
91 getAll: function(callback)
967a2686
BA
92 {
93 dbOperation((db) => {
94 let objectStore = db.transaction('games').objectStore('games');
fd7aea36
BA
95 let games = [];
96 objectStore.openCursor().onsuccess = function(event) {
97 let cursor = event.target.result;
98 // if there is still another cursor to go, keep running this code
99 if (cursor)
100 {
101 games.push(cursor.value);
102 cursor.continue();
967a2686 103 }
fd7aea36
BA
104 else
105 callback(games);
967a2686 106 }
fd7aea36
BA
107 });
108 },
109
110 // Retrieve any game from its identifiers (locally or on server)
111 // NOTE: need callback because result is obtained asynchronously
112 get: function(gameId, callback)
113 {
114 // corr games identifiers are integers
115 if (Number.isInteger(gameId) || !isNaN(parseInt(gameId)))
116 {
117 ajax("/games", "GET", {gid:gameId}, res => {
118 callback(res.game);
119 });
120 }
121 else //local game
122 {
123 dbOperation((db) => {
124 let objectStore = db.transaction('games').objectStore('games');
967a2686
BA
125 objectStore.get(gameId).onsuccess = function(event) {
126 callback(event.target.result);
127 }
fd7aea36
BA
128 });
129 }
967a2686
BA
130 },
131
42c15a75
BA
132 getCurrent: function(callback)
133 {
134 dbOperation((db) => {
135 let objectStore = db.transaction('games').objectStore('games');
136 objectStore.get("*").onsuccess = function(event) {
137 callback(event.target.result);
138 };
139 });
140 },
141
967a2686
BA
142 // Delete a game in indexedDB
143 remove: function(gameId, callback)
144 {
145 dbOperation((db) => {
146 let transaction = db.transaction(["games"], "readwrite");
147 if (callback)
148 {
149 transaction.oncomplete = function() {
150 callback({}); //everything's fine
151 }
152 transaction.onerror = function() {
153 callback({errmsg: "removeGame failed: " + transaction.error});
154 };
155 }
156 transaction.objectStore("games").delete(gameId);
157 });
158 },
159};