-
Notifications
You must be signed in to change notification settings - Fork 0
/
sw.js
172 lines (160 loc) · 5.34 KB
/
sw.js
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
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
const CACHE_NAME = 'telegeamCache';
let cachelist = [];
const cachetime = 24*60*60*1000;
self.CACHE_NAME = 'SWHelperCache';
self.db = {
read: (key, config) => {
if (!config) { config = { type: "text" } }
return new Promise((resolve, reject) => {
caches.open(CACHE_NAME).then(cache => {
cache.match(new Request(`https://LOCALCACHE/${encodeURIComponent(key)}`)).then(function (res) {
if (!res) resolve(null)
res.text().then(text => resolve(text))
}).catch(() => {
resolve(null)
})
})
})
},
write: (key, value) => {
return new Promise((resolve, reject) => {
caches.open(CACHE_NAME).then(function (cache) {
cache.put(new Request(`https://LOCALCACHE/${encodeURIComponent(key)}`), new Response(value));
resolve()
}).catch(() => {
reject()
})
})
}
}
self.addEventListener('install', async function (installEvent) {
self.skipWaiting();
installEvent.waitUntil(
caches.open(CACHE_NAME)
.then(function (cache) {
console.log('Opened cache');
return cache.addAll(cachelist);
})
);
});
self.addEventListener('fetch', async event => {
try {
event.respondWith(handle(event.request))
} catch (msg) {
event.respondWith(handleerr(event.request, msg))
}
});
const handleerr = async (req, msg) => {
return new Response(`<h1>Service Worker 遇到致命错误</h1>
<b>${msg}</b>`, { headers: { "content-type": "text/html; charset=utf-8" } })
}
const lfetch = async (urls, url, init) => {
let controller = new AbortController();
const PauseProgress = async (res) => {
return new Response(await (res).arrayBuffer(), { status: res.status, headers: res.headers });
};
if (!Promise.any) {
Promise.any = function (promises) {
return new Promise((resolve, reject) => {
promises = Array.isArray(promises) ? promises : []
let len = promises.length
let errs = []
if (len === 0) return reject(new AggregateError('All promises were rejected'))
promises.forEach((promise) => {
promise.then(value => {
resolve(value)
}, err => {
len--
errs.push(err)
if (len === 0) {
reject(new AggregateError(errs))
}
})
})
})
}
}
return Promise.any(urls.map(urls => {
init = init || {}
init.signal = controller.signal
return new Promise((resolve, reject) => {
fetch(urls, init)
.then(PauseProgress)
.then(res => {
if (res.status == 200) {
controller.abort();
resolve(res)
} else {
reject(null)
}
})
})
}))
}
let gdt = {
}
const broadcast = (channel, data) => {
let broadcast = new BroadcastChannel(channel);
return broadcast.postMessage({ type: data })
}
const set_newest_version = async (mirror) => {
// 改为最新版本写入数据库
console.log("[LOG] 开始检查更新.");
return lfetch(mirror, mirror[0])
.then(res => res.json())
.then(async res => {
let thisVersion = await db.read("site_version");
console.info("[INFO] 当前版本: "+ thisVersion);
console.info("[INFO] 最新版本: "+res.version);
if (thisVersion != res.version) {
// 版本有更新 向页面展示
broadcast("Site Update", "REFRESH");
}
await db.write('site_version', res.version);
return;
});
}
const handle = async function (req) {
const urlStr = req.url
const urlObj = new URL(urlStr)
const port = urlObj.port
const domain = urlObj.hostname;
const urlPath = urlObj.pathname;
let urls = []
if (req.method == "GET" && (domain == "telegeam.github.io" || domain == "localhost")) {
const fullpath = (path) => {
path = path.split('?')[0].split('#')[0]
if (path.match(/\/$/)) {
path += 'index.html'
}
if (!path.match(/\.[a-zA-Z]+$/)) {
path += '/index.html'
}
return path
}
}
return fetch(req).then(function (res) {
if (!res) { throw 'error' } //1
return caches.open(CACHE_NAME).then(function (cache) {
cache.delete(req);
cache.put(req, res.clone());
return res;
});
}).catch(function (err) {
return caches.match(req).then(function (resp) {
return resp || caches.match(new Request('/offline/')) //2
})
})
}
self.addEventListener('activate', function(event) {
var cacheWhitelist = ['v2'];
event.waitUntil(
caches.keys().then(function(keyList) {
return Promise.all(keyList.map(function(key) {
if (cacheWhitelist.indexOf(key) === -1) {
return caches.delete(key);
}
}));
})
);
});