summaryrefslogtreecommitdiff
path: root/app/sw.src.js
blob: 243e4259a8125127c7181459a7da147c8f8f84a0 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
// noinspection JSUnresolvedVariable

let cacheName = 'peh-pluralponies-pwa';
let filesToCache = [["%CacheData%"]];

self.addEventListener('install', function(e) {
    e.waitUntil(
        caches.open(cacheName).then(function(cache) {
            return cache.addAll(filesToCache);
        })
    );
});

self.addEventListener('fetch', function(e) {
    e.respondWith(
        caches.match(e.request).then(function(response) {
            return response || fetch(e.request);
        })
    );
});

self.addEventListener('sync', function(e) {
    if (e.tag === 'data-sync') {
        e.waitUntil(repeatRefresh());
    }
})

self.addEventListener('periodicsync', function(e) {
    if (e.tag === 'data-sync') {
        e.waitUntil(repeatRefresh());
    }
})

function sleep(ms) {
    return new Promise((res, _rej) => {
        setTimeout(res, ms);
    })
}

function repeatRefresh() {
    return new Promise(async (_res, _rej) => {
        await repeatRefreshInternal();
    })
}

async function repeatRefreshInternal() {
    await refresh();
    sleep(300000).then(async () => {
        await repeatRefreshInternal();
    });
}

async function fetchPlus(resource, options = {}) {
    const { timeout = 8000 } = options;

    const controller = new AbortController();
    const id = setTimeout(() => controller.abort(), timeout);
    const response = await fetch(resource, {
        ...options,
        signal: controller.signal
    });
    clearTimeout(id);
    return response;
}

function refresh() {
    return new Promise(async (res, rej) => {
        let valuesToGet = JSON.parse(await localforage.getItem("values-to-get"));

        let keys = Object.keys(valuesToGet);
        let index = 2;
        await getNewValue(res, keys, index, valuesToGet);
    })
}

async function getNewValue(res, keys, index, valuesToGet) {
    if (!keys[0]) {
        await localforage.setItem("refresh", new Date().toISOString());
        console.log("Done refreshing in the background at " + new Date().toISOString())
        res();
        return;
    }

    try {
        await localforage.setItem(keys[0], (await (await fetchPlus(valuesToGet[keys[0]]["url"], { timeout: 3000 })).text()));
        keys.shift();

        if (!keys[0]) {
            await localforage.setItem("refresh", new Date().toISOString());
            console.log("Done refreshing in the background at " + new Date().toISOString())
            res();
            return;
        }

        setTimeout(async () => {
            index++;
            await getNewValue(res, keys, index, valuesToGet);
        }, valuesToGet[keys[0]]["limited"] ? 550 : 0);
    } catch (e) {
        for (let key of Object.keys(valuesToGet)) {
            if (await localforage.getItem(key) === null) {
                throw new Error("App requested key '" + key + "' but it can't be retrieved at the moment");
            }
        }

        await localforage.setItem("refresh", new Date().toISOString());
        console.log("Done refreshing in the background at " + new Date().toISOString())
        res();
    }
}