2 // // Static informations:
6 // players: array of sid+id+name,
8 // increment: integer (seconds),
9 // type: string ("live" or "corr")
10 // // Game (dynamic) state:
12 // moves: array of Move objects,
13 // clocks: array of integers,
14 // initime: array of integers (when clock start running),
15 // score: string (several options; '*' == running),
18 import { store
} from "@/store";
20 function dbOperation(callback
) {
22 let DBOpenRequest
= window
.indexedDB
.open("vchess", 4);
24 DBOpenRequest
.onerror = function(event
) {
25 alert(store
.state
.tr
["Database error: stop private browsing, or update your browser"]);
26 callback("error",null);
29 DBOpenRequest
.onsuccess = function() {
30 db
= DBOpenRequest
.result
;
35 DBOpenRequest
.onupgradeneeded = function(event
) {
36 let db
= event
.target
.result
;
37 let objectStore
= db
.createObjectStore("games", { keyPath: "id" });
38 objectStore
.createIndex("score", "score"); //to search by game result
42 export const GameStorage
= {
43 // Optional callback to get error status
44 add: function(game
, callback
) {
45 dbOperation((err
,db
) => {
50 let transaction
= db
.transaction("games", "readwrite");
51 transaction
.oncomplete = function() {
52 callback(); //everything's fine
54 transaction
.onerror = function(err
) {
55 callback(err
); //duplicate key error (most likely)
57 let objectStore
= transaction
.objectStore("games");
58 objectStore
.add(game
);
62 // obj: chat, move, fen, clocks, score[Msg], initime, ...
63 update: function(gameId
, obj
) {
65 dbOperation((err
,db
) => {
67 .transaction("games", "readwrite")
68 .objectStore("games");
69 objectStore
.get(gameId
).onsuccess = function(event
) {
70 // Ignoring error silently: shouldn't happen now. TODO?
71 if (event
.target
.result
) {
72 let game
= event
.target
.result
;
73 // Hidden tabs are delayed, to prevent multi-updates:
74 if (obj
.moveIdx
< game
.moves
.length
) return;
75 Object
.keys(obj
).forEach(k
=> {
76 if (k
== "move") game
.moves
.push(obj
[k
]);
77 else game
[k
] = obj
[k
];
79 objectStore
.put(game
); //save updated data
85 // Retrieve all local games (running, completed, imported...)
86 // light: do not retrieve moves or clocks (TODO: this is the only usage)
87 getAll: function(light
, callback
) {
88 dbOperation((err
,db
) => {
89 let objectStore
= db
.transaction("games").objectStore("games");
91 objectStore
.openCursor().onsuccess = function(event
) {
92 let cursor
= event
.target
.result
;
93 // if there is still another cursor to go, keep running this code
97 g
.movesCount
= g
.moves
.length
;
104 } else callback(games
);
109 // Retrieve any game from its identifiers (locally or on server)
110 // NOTE: need callback because result is obtained asynchronously
111 get: function(gameId
, callback
) {
113 dbOperation((err
,db
) => {
114 let objectStore
= db
.transaction("games").objectStore("games");
115 objectStore
.get(gameId
).onsuccess = function(event
) {
116 if (event
.target
.result
)
117 callback(event
.target
.result
);
122 // Delete a game in indexedDB
123 remove: function(gameId
, callback
) {
124 dbOperation((err
,db
) => {
126 let transaction
= db
.transaction(["games"], "readwrite");
127 transaction
.oncomplete = function() {
128 callback(); //everything's fine
130 transaction
.objectStore("games").delete(gameId
);