Add assets/js/offline-engine.js

This commit is contained in:
2026-06-16 10:48:27 +02:00
parent 460dd6e72a
commit 3883cc7eec
+195
View File
@@ -0,0 +1,195 @@
import { getDB } from './db.js';
function getStore(storeName, mode = 'readonly') {
const db = getDB();
const tx = db.transaction(storeName, mode);
return tx.objectStore(storeName);
}
export async function saveWords(lang, list, words) {
const store = getStore('words', 'readwrite');
for (const word of words) {
store.put({
key: `${lang}:${list}:${word.id}`,
lang,
list,
...word
});
}
}
export async function getWords(lang, list) {
return new Promise((resolve) => {
const store = getStore('words');
const req = store.getAll();
req.onsuccess = () => {
const result = req.result.filter(
w => w.lang === lang && w.list === list
);
resolve(result);
};
});
}
export async function getNextWord(lang, list) {
const words = await getWords(lang, list);
if (!words.length) {
return null;
}
const today = new Date().toISOString().split('T')[0];
let due = words.filter(word => {
return !word.nextReview ||
word.nextReview <= today;
});
if (!due.length) {
due = words;
}
const random =
Math.floor(Math.random() * due.length);
return due[random];
}
export async function answerWord(word, answer) {
const correct =
word.answer.trim().toLowerCase() ===
answer.trim().toLowerCase();
const store =
getStore('words', 'readwrite');
const updated = { ...word };
if (correct) {
const days =
updated.interval
? updated.interval * 2
: 1;
updated.interval = days;
const d = new Date();
d.setDate(d.getDate() + days);
updated.nextReview =
d.toISOString().split('T')[0];
} else {
updated.interval = 1;
const d = new Date();
d.setDate(d.getDate() + 1);
updated.nextReview =
d.toISOString().split('T')[0];
}
store.put(updated);
await updateSessionStats(correct);
await queueSync({
wordId: word.id,
lang: word.lang,
list: word.list,
correct,
timestamp: Date.now()
});
return {
correct
};
}
async function queueSync(item) {
const store =
getStore('sync_queue', 'readwrite');
store.add(item);
}
export async function updateSessionStats(correct) {
const store =
getStore('session', 'readwrite');
const req =
store.get('stats');
req.onsuccess = () => {
let stats = req.result;
if (!stats) {
stats = {
key: 'stats',
correct: 0,
wrong: 0
};
}
if (correct) {
stats.correct++;
} else {
stats.wrong++;
}
store.put(stats);
};
}
export async function getSessionStats() {
return new Promise(resolve => {
const store =
getStore('session');
const req =
store.get('stats');
req.onsuccess = () => {
resolve(
req.result || {
correct: 0,
wrong: 0
}
);
};
});
}
export async function resetSessionStats() {
const store =
getStore('session', 'readwrite');
store.put({
key: 'stats',
correct: 0,
wrong: 0
});
}