sinzmise-cetastories 1.7.0-1717845568710 → 1.7.0-1717846414703

Sign up to get free protection for your applications and to get access to all the features.
Files changed (115) hide show
  1. package/404/index.html +1 -1
  2. package/404.html +1 -1
  3. package/about/index.html +1 -1
  4. package/album/index.html +1 -1
  5. package/archives/2021/12/index.html +1 -1
  6. package/archives/2021/index.html +1 -1
  7. package/archives/2022/12/index.html +1 -1
  8. package/archives/2022/index.html +1 -1
  9. package/archives/2023/01/index.html +1 -1
  10. package/archives/2023/02/index.html +1 -1
  11. package/archives/2023/03/index.html +1 -1
  12. package/archives/2023/04/index.html +1 -1
  13. package/archives/2023/07/index.html +1 -1
  14. package/archives/2023/08/index.html +1 -1
  15. package/archives/2023/09/index.html +1 -1
  16. package/archives/2023/10/index.html +1 -1
  17. package/archives/2023/11/index.html +1 -1
  18. package/archives/2023/12/index.html +1 -1
  19. package/archives/2023/index.html +1 -1
  20. package/archives/2023/page/2/index.html +1 -1
  21. package/archives/2023/page/3/index.html +1 -1
  22. package/archives/2024/01/index.html +1 -1
  23. package/archives/2024/02/index.html +1 -1
  24. package/archives/2024/03/index.html +1 -1
  25. package/archives/2024/04/index.html +1 -1
  26. package/archives/2024/05/index.html +1 -1
  27. package/archives/2024/index.html +1 -1
  28. package/archives/2024/page/2/index.html +1 -1
  29. package/archives/index.html +1 -1
  30. package/archives/page/2/index.html +1 -1
  31. package/archives/page/3/index.html +1 -1
  32. package/archives/page/4/index.html +1 -1
  33. package/article.json +1 -1
  34. package/atom.xml +21 -21
  35. package/baidu_verify_codeva-NA6uDlCuZg.html +1 -1
  36. package/bangumis/index.html +1 -1
  37. package/bbs/index.html +1 -1
  38. package/cacheList.json +1 -1
  39. package/categories/index.html +1 -1
  40. package/categories//344/270/252/344/272/272/345/260/217/350/256/260/index.html +1 -1
  41. package/categories//344/270/252/344/272/272/345/260/217/350/256/260/page/2/index.html +1 -1
  42. package/categories//346/255/214/346/233/262/346/224/266/351/233/206/index.html +1 -1
  43. package/categories//346/270/270/346/210/217/347/233/270/345/205/263/index.html +1 -1
  44. package/categories//347/253/231/347/202/271/346/212/230/350/205/276/index.html +1 -1
  45. package/categories//347/253/231/347/202/271/346/212/230/350/205/276/page/2/index.html +1 -1
  46. package/categories//351/241/271/347/233/256/346/212/230/350/205/276/index.html +1 -1
  47. package/charts/index.html +1 -1
  48. package/comments/index.html +1 -1
  49. package/essay/index.html +1 -1
  50. package/fcircle/index.html +1 -1
  51. package/google8073542809160a67.html +1 -1
  52. package/index.html +1 -1
  53. package/link/index.html +1 -1
  54. package/music/index.html +1 -1
  55. package/package.json +1 -1
  56. package/page/2/index.html +1 -1
  57. package/page/3/index.html +1 -1
  58. package/page/4/index.html +1 -1
  59. package/posts/10021/index.html +1 -1
  60. package/posts/10045/index.html +1 -1
  61. package/posts/10996/index.html +1 -1
  62. package/posts/12779/index.html +1 -1
  63. package/posts/13624/index.html +1 -1
  64. package/posts/15748/index.html +1 -1
  65. package/posts/15842/index.html +1 -1
  66. package/posts/16107/index.html +1 -1
  67. package/posts/18063/index.html +1 -1
  68. package/posts/20412/index.html +1 -1
  69. package/posts/21375/index.html +1 -1
  70. package/posts/22945/index.html +1 -1
  71. package/posts/23021/index.html +1 -1
  72. package/posts/27531/index.html +1 -1
  73. package/posts/27762/index.html +1 -1
  74. package/posts/28536/index.html +1 -1
  75. package/posts/28733/index.html +1 -1
  76. package/posts/29196/index.html +1 -1
  77. package/posts/38917/index.html +1 -1
  78. package/posts/38964/index.html +1 -1
  79. package/posts/42487/index.html +1 -1
  80. package/posts/42580/index.html +1 -1
  81. package/posts/45875/index.html +1 -1
  82. package/posts/48762/index.html +1 -1
  83. package/posts/50710/index.html +1 -1
  84. package/posts/52677/index.html +1 -1
  85. package/posts/53662/index.html +1 -1
  86. package/posts/54386/index.html +1 -1
  87. package/posts/54481/index.html +1 -1
  88. package/posts/54787/index.html +1 -1
  89. package/posts/56467/index.html +1 -1
  90. package/posts/57692/index.html +1 -1
  91. package/posts/58203/index.html +1 -1
  92. package/posts/61417/index.html +1 -1
  93. package/posts/646/index.html +1 -1
  94. package/seas/index.html +1 -1
  95. package/sitemap.xml +4 -4
  96. package/sw-dom.js +1 -73
  97. package/sw.js +1 -586
  98. package/tags/Flash/347/233/270/345/205/263/index.html +1 -1
  99. package/tags/Steam/346/270/270/346/210/217/index.html +1 -1
  100. package/tags/Windows/350/275/257/344/273/266/index.html +1 -1
  101. package/tags/index.html +1 -1
  102. package/tags//344/270/252/344/272/272/345/260/217/350/256/260/index.html +1 -1
  103. package/tags//344/270/252/344/272/272/345/260/217/350/256/260/page/2/index.html +1 -1
  104. package/tags//345/205/266/345/256/203/346/270/270/346/210/217/index.html +1 -1
  105. package/tags//346/202/254/346/265/256/345/256/240/347/211/251-/347/234/213/346/235/277/345/250/230/index.html +1 -1
  106. package/tags//346/255/214/346/233/262/346/224/266/351/233/206/index.html +1 -1
  107. package/tags//346/270/270/346/210/217/347/233/270/345/205/263/index.html +1 -1
  108. package/tags//347/253/231/347/202/271/345/272/225/351/203/250/351/255/224/346/224/271/index.html +1 -1
  109. package/tags//347/253/231/347/202/271/346/212/230/350/205/276/index.html +1 -1
  110. package/tags//347/253/231/347/202/271/346/212/230/350/205/276/page/2/index.html +1 -1
  111. package/tags//350/207/252/345/273/272/351/203/250/347/275/262/index.html +1 -1
  112. package/tags//351/241/265/351/235/242/351/255/224/346/224/271/index.html +1 -1
  113. package/tags//351/241/271/347/233/256/346/212/230/350/205/276/index.html +1 -1
  114. package/update/index.html +1 -1
  115. package/update.json +1 -1
package/sw-dom.js CHANGED
@@ -1,73 +1 @@
1
- document.addEventListener('DOMContentLoaded', () => {
2
- if (!navigator.serviceWorker?.controller) return
3
- /** 发送信息到 sw */
4
- const postMessage2SW = type => navigator.serviceWorker.controller.postMessage(type)
5
- const pjaxUpdate = url => {
6
- const type = url.endsWith('js') ? 'script' : 'link'
7
- const name = type === 'link' ? 'href' : 'src'
8
- for (let item of document.getElementsByTagName(type)) {
9
- const itUrl = item[name]
10
- if (url.length > itUrl ? url.endsWith(itUrl) : itUrl.endsWith(url)) {
11
- const newEle = document.createElement(type)
12
- const content = item.text || item.textContent || item.innerHTML || ''
13
- // noinspection JSUnresolvedReference
14
- Array.from(item.attributes).forEach(attr => newEle.setAttribute(attr.name, attr.value))
15
- newEle.appendChild(document.createTextNode(content))
16
- item.parentNode.replaceChildren(newEle, item)
17
- return true
18
- }
19
- }
20
- }
21
- const SESSION_KEY = 'updated'
22
- // noinspection JSFileReferences
23
- const onSuccess = () => {
24
- caches.match('https://id.v3/').then(function(response) {
25
- if (response) {
26
- // 如果找到了匹配的缓存响应
27
- response.json().then(function(data) {
28
- var snackbarBg =
29
- document.documentElement.getAttribute('data-theme') === 'light' ?
30
- GLOBAL_CONFIG.Snackbar.bgLight :
31
- GLOBAL_CONFIG.Snackbar.bgDark
32
- var snackbarPos = GLOBAL_CONFIG.Snackbar.position
33
- Snackbar.show({
34
- text: `已刷新缓存,更新为${GLOBAL_CONFIG.uiversion}版本最新内容`,
35
- backgroundColor: snackbarBg,
36
- duration: 30000,
37
- pos: snackbarPos,
38
- actionText: '查看更新日志',
39
- actionTextColor: '#fff',
40
- onActionClick: function(e) {
41
- location.assign("/update/");
42
- },
43
- })
44
- });
45
- } else {
46
- console.info('未找到匹配的缓存响应');
47
- }
48
- }).catch(function(error) {
49
- console.error('缓存匹配出错:', error);
50
- });
51
- };
52
- if (sessionStorage.getItem(SESSION_KEY)) {
53
- onSuccess()
54
- sessionStorage.removeItem(SESSION_KEY)
55
- } else postMessage2SW('update')
56
- navigator.serviceWorker.addEventListener('message', event => {
57
- const data = event.data
58
- sessionStorage.setItem(SESSION_KEY, data.type)
59
- const list = data.list?.filter(url => /\.(js|css)$/.test(url))
60
- if (list) {
61
- // noinspection JSUnresolvedReference
62
- if (window.Pjax?.isSupported?.())
63
- list.forEach(pjaxUpdate)
64
- location.reload()
65
- } else {
66
- const newVersion = data.new, oldVersion = data.old
67
- if (oldVersion && (newVersion.global !== oldVersion.global || newVersion.local !== oldVersion.local)) {
68
- onSuccess()
69
- }
70
- sessionStorage.removeItem(SESSION_KEY)
71
- }
72
- })
73
- })
1
+ document.addEventListener("DOMContentLoaded",(()=>{if(!navigator.serviceWorker?.controller)return;const e=e=>{const t=e.endsWith("js")?"script":"link",o="link"===t?"href":"src";for(let n of document.getElementsByTagName(t)){const r=n[o];if(e.length>r?e.endsWith(r):r.endsWith(e)){const e=document.createElement(t),o=n.text||n.textContent||n.innerHTML||"";return Array.from(n.attributes).forEach((t=>e.setAttribute(t.name,t.value))),e.appendChild(document.createTextNode(o)),n.parentNode.replaceChildren(e,n),!0}}},t="updated",o=()=>{caches.match("https://id.v3/").then((function(e){e?e.json().then((function(e){var t="light"===document.documentElement.getAttribute("data-theme")?GLOBAL_CONFIG.Snackbar.bgLight:GLOBAL_CONFIG.Snackbar.bgDark,o=GLOBAL_CONFIG.Snackbar.position;Snackbar.show({text:`已刷新缓存,更新为${GLOBAL_CONFIG.uiversion}版本最新内容`,backgroundColor:t,duration:3e4,pos:o,actionText:"查看更新日志",actionTextColor:"#fff",onActionClick:function(e){location.assign("/update/")}})})):console.info("未找到匹配的缓存响应")})).catch((function(e){console.error("缓存匹配出错:",e)}))};var n;sessionStorage.getItem(t)?(o(),sessionStorage.removeItem(t)):(n="update",navigator.serviceWorker.controller.postMessage(n)),navigator.serviceWorker.addEventListener("message",(n=>{const r=n.data;sessionStorage.setItem(t,r.type);const a=r.list?.filter((e=>/\.(js|css)$/.test(e)));if(a)window.Pjax?.isSupported?.()&&a.forEach(e),location.reload();else{const e=r.new,n=r.old;!n||e.global===n.global&&e.local===n.local||o(),sessionStorage.removeItem(t)}}))}));
package/sw.js CHANGED
@@ -1,586 +1 @@
1
- // noinspection JSIgnoredPromiseFromCall
2
-
3
- (() => {
4
- /** 缓存库名称 */
5
- const CACHE_NAME = 'StoriHouseCache'
6
- /** 控制信息存储地址(必须以`/`结尾) */
7
- const CTRL_PATH = 'https://id.v3/'
8
-
9
- const ejectDomain = 'blog.sinzmise.top'
10
- const ejectMirror = ['https://registry.npmmirror.com/sinzmise-cetastories/latest']
11
-
12
-
13
- /**
14
- * 读取本地版本号
15
- * @return {Promise<BrowserVersion|undefined>}
16
- */
17
- const readVersion = () => caches.match(CTRL_PATH).then(response => response?.json())
18
- /**
19
- * 写入版本号
20
- * @param version {BrowserVersion}
21
- * @return {Promise<void>}
22
- */
23
- const writeVersion = version => caches.open(CACHE_NAME)
24
- .then(cache => cache.put(CTRL_PATH, new Response(JSON.stringify(version))))
25
-
26
- self.addEventListener('install', () => {
27
- self.skipWaiting()
28
- const escape = 0
29
- if (escape) {
30
- readVersion().then(async oldVersion => {
31
- // noinspection JSIncompatibleTypesComparison
32
- if (oldVersion && oldVersion.escape !== escape) {
33
- const list = await caches.open(CACHE_NAME)
34
- .then(cache => cache.keys())
35
- .then(keys => keys?.map(it => it.url))
36
- await caches.delete(CACHE_NAME)
37
- const info = await updateJson()
38
- info.type = 'escape'
39
- info.list = list
40
- // noinspection JSUnresolvedReference
41
- const clientList = await clients.matchAll()
42
- clientList.forEach(client => client.postMessage(info))
43
- }
44
- })
45
- }
46
- })
47
-
48
- // sw 激活后立即对所有页面生效,而非等待刷新
49
- // noinspection JSUnresolvedReference
50
- self.addEventListener('activate', event => event.waitUntil(clients.claim()))
51
-
52
- /**
53
- * 基础 fetch
54
- * @param request {Request|string}
55
- * @param banCache {boolean} 是否禁用缓存
56
- * @param cors {boolean} 是否启用 cors
57
- * @param optional {RequestInit?} 额外的配置项
58
- * @return {Promise<Response>}
59
- */
60
- const baseFetcher = (request, banCache, cors, optional) => {
61
- if (!optional) optional = {}
62
- optional.cache = banCache ? 'no-store' : 'default'
63
- if (cors) {
64
- optional.mode = 'cors'
65
- optional.credentials = 'same-origin'
66
- }
67
- return fetch(request, optional)
68
- }
69
-
70
- /**
71
- * 添加 cors 配置请求指定资源
72
- * @param request {Request}
73
- * @param optional {RequestInit?} 额外的配置项
74
- * @return {Promise<Response>}
75
- */
76
- const fetchWithCache = (request, optional) =>
77
- baseFetcher(request, false, isCors(request), optional)
78
-
79
- // noinspection JSUnusedLocalSymbols
80
- /**
81
- * 添加 cors 配置请求指定资源
82
- * @param request {Request}
83
- * @param banCache {boolean} 是否禁用 HTTP 缓存
84
- * @param optional {RequestInit?} 额外的配置项
85
- * @return {Promise<Response>}
86
- */
87
- const fetchWithCors = (request, banCache, optional) =>
88
- baseFetcher(request, banCache, true, optional)
89
-
90
- /**
91
- * 判断指定 url 击中了哪一种缓存,都没有击中则返回 null
92
- * @param url {URL}
93
- */
94
- const findCache = url => {
95
- if (url.hostname === 'localhost') return
96
- for (let key in cacheRules) {
97
- const value = cacheRules[key]
98
- if (value.match(url)) return value
99
- }
100
- }
101
-
102
- // noinspection JSFileReferences
103
- let skipRequest = request => request.url.startsWith('https://i0.hdslb.com')
104
- let cacheRules = {
105
- simple: {
106
- clean: true,
107
- search: false,
108
- match: url => {
109
- const allowedHost = ejectDomain;
110
- const allowedPaths = ["/404.html", "/css/index.css"];
111
- return url.host === allowedHost && allowedPaths.includes(url.pathname);
112
- }}
113
- ,
114
- cdn: {
115
- clean: true,
116
- match: url =>
117
- [
118
- "unpkg.com",
119
- "cdn.cbd.int",
120
- "lf26-cdn-tos.bytecdntp.com",
121
- "lf6-cdn-tos.bytecdntp.com",
122
- "lf3-cdn-tos.bytecdntp.com",
123
- "lf9-cdn-tos.bytecdntp.com",
124
- "npm.onmicrosoft.cn",
125
- "cdn.staticfile.org",
126
- "npm.elemecdn.com",
127
- ].includes(url.host) && url.pathname.match(/\.(js|css|woff2|woff|ttf|cur)$/)}
128
- }
129
-
130
- let getSpareUrls = srcUrl => {
131
- if (srcUrl.startsWith("https://npm.elemecdn.com")) {
132
- return {
133
- timeout: 3000,
134
- list: [srcUrl, `https://cdn.cbd.int/${new URL(srcUrl).pathname}`],
135
- };
136
- }
137
- }
138
- let selfdb = () => {
139
- self.db = { //全局定义db,只要read和write,看不懂可以略过
140
- read: (key, config) => {
141
- if (!config) { config = { type: "text" } }
142
- return new Promise((resolve, reject) => {
143
- caches.open(CACHE_NAME).then(cache => {
144
- cache.match(new Request(`https://LOCALCACHE/${encodeURIComponent(key)}`)).then(function (res) {
145
- if (!res) resolve(null)
146
- res.text().then(text => resolve(text))
147
- }).catch(() => {
148
- resolve(null)
149
- })
150
- })
151
- })
152
- },
153
- write: (key, value) => {
154
- return new Promise((resolve, reject) => {
155
- caches.open(CACHE_NAME).then(function (cache) {
156
- cache.put(new Request(`https://LOCALCACHE/${encodeURIComponent(key)}`), new Response(value));
157
- resolve()
158
- }).catch(() => {
159
- reject()
160
- })
161
- })
162
- }
163
- }
164
- }
165
- let lfetch = async (urls, url) => {
166
- let controller = new AbortController();
167
- const PauseProgress = async (res) => {
168
- return new Response(await (res).arrayBuffer(), { status: res.status, headers: res.headers });
169
- };
170
- if (!Promise.any) {
171
- Promise.any = function (promises) {
172
- return new Promise((resolve, reject) => {
173
- promises = Array.isArray(promises) ? promises : []
174
- let len = promises.length
175
- let errs = []
176
- if (len === 0) return reject(new AggregateError('All promises were rejected'))
177
- promises.forEach((promise) => {
178
- promise.then(value => {
179
- resolve(value)
180
- }, err => {
181
- len--
182
- errs.push(err)
183
- if (len === 0) {
184
- reject(new AggregateError(errs))
185
- }
186
- })
187
- })
188
- })
189
- }
190
- }
191
- return Promise.any(urls.map(urls => {
192
- return new Promise((resolve, reject) => {
193
- fetch(urls, {
194
- signal: controller.signal
195
- })
196
- .then(PauseProgress)
197
- .then(res => {
198
- if (res.status == 200) {
199
- controller.abort();
200
- resolve(res)
201
- } else {
202
- reject(res)
203
- }
204
- })
205
- })
206
- }))
207
- }
208
- let fullpath = (path) => {
209
- path = path.split('?')[0].split('#')[0]
210
- if (path.match(/\/$/)) {
211
- path += 'index'
212
- }
213
- if (!path.match(/\.[a-zA-Z]+$/)) {
214
- path += '.html'
215
- }
216
- return path
217
- }
218
- let generate_blog_urls = () => {
219
- const npmmirror = [
220
- // `https://unpkg.zhimg.com/${packagename}@${blogversion}`,
221
- // `https://npm.elemecdn.com/${packagename}@${blogversion}`,
222
- // `https://cdn1.tianli0.top/npm/${packagename}@${blogversion}`,
223
- // `https://cdn.afdelivr.top/npm/${packagename}@${blogversion}`,
224
- `https://registry.npmmirror.com/${packagename}/${blogversion}/files`
225
- ]
226
- for (var i in npmmirror) {
227
- npmmirror[i] += path
228
- }
229
- return npmmirror
230
- }
231
- let get_newest_version = async (ejectMirror) => {
232
- return lfetch(ejectMirror, ejectMirror[0])
233
- .then(res => res.json())
234
- .then(res.version)
235
- }
236
- let set_newest_version = async (ejectMirror) => {
237
- return lfetch(ejectMirror, ejectMirror[0])
238
- .then(res => res.json()) //JSON Parse
239
- .then(async res => {
240
- await db.write('blog_version', res.version) //写入
241
- return;
242
- })
243
- }
244
- let set_newest_time = () => {
245
- setInterval(async() => {
246
- await set_newest_version(mirror) //定时更新,一分钟一次
247
- }, 60*1000);
248
-
249
- setTimeout(async() => {
250
- await set_newest_version(mirror)//打开五秒后更新,避免堵塞
251
- },5000)
252
- function getFileType(fileName) {
253
- suffix=fileName.split('.')[fileName.split('.').length-1]
254
- if(suffix=="html"||suffix=="htm") {
255
- return 'text/html';
256
- }
257
- if(suffix=="js") {
258
- return 'text/javascript';
259
- }
260
- if(suffix=="css") {
261
- return 'text/css';
262
- }
263
- if(suffix=="jpg"||suffix=="jpeg") {
264
- return 'image/jpeg';
265
- }
266
- if(suffix=="ico") {
267
- return 'image/x-icon';
268
- }
269
- if(suffix=="png") {
270
- return 'image/png';
271
- }
272
- return 'text/plain';
273
- }
274
- }
275
- let handle = async(req)=> {
276
- const urlStr = req.url
277
- const urlObj = new URL(urlStr);
278
- const urlPath = urlObj.pathname;
279
- const domain = urlObj.hostname;
280
- //从这里开始
281
- lxs=[]
282
- if(domain === "blog.sinzmise.top"){//这里写你需要拦截的域名
283
- var l=lfetch(generate_blog_urls('sinzmise-cetastories',await db.read('blog_version') || 'latest',fullpath(urlPath)))
284
- return l
285
- .then(res=>res.arrayBuffer())
286
- .then(buffer=>new Response(buffer,{headers:{"Content-Type":`${getFileType(fullpath(urlPath).split("/")[fullpath(urlPath).split("/").length-1].split("\\")[fullpath(urlPath).split("/")[fullpath(urlPath).split("/").length-1].split("\\").length-1])};charset=utf-8`}}));//重新定义header
287
- }
288
- else{
289
- return fetch(req);
290
- }
291
- }
292
- let isCors = () => false
293
- let isMemoryQueue = () => false
294
- const fetchFile = (request, banCache, urls = null) => {
295
- if (!urls) {
296
- urls = getSpareUrls(request.url)
297
- if (!urls) return fetchWithCors(request, banCache)
298
- }
299
- const list = urls.list
300
- const controllers = new Array(list.length)
301
- // noinspection JSCheckFunctionSignatures
302
- const startFetch = index => fetchWithCors(
303
- new Request(list[index], request),
304
- banCache,
305
- {signal: (controllers[index] = new AbortController()).signal}
306
- ).then(response => checkResponse(response) ? {r: response, i: index} : Promise.reject())
307
- return new Promise((resolve, reject) => {
308
- let flag = true
309
- const startAll = () => {
310
- flag = false
311
- Promise.any([
312
- first,
313
- ...Array.from({
314
- length: list.length - 1
315
- }, (_, index) => index + 1).map(index => startFetch(index))
316
- ]).then(res => {
317
- for (let i = 0; i !== list.length; ++i) {
318
- if (i !== res.i)
319
- controllers[i].abort()
320
- }
321
- resolve(res.r)
322
- }).catch(() => reject(`请求 ${request.url} 失败`))
323
- }
324
- const id = setTimeout(startAll, urls.timeout)
325
- const first = startFetch(0)
326
- .then(res => {
327
- if (flag) {
328
- clearTimeout(id)
329
- resolve(res.r)
330
- }
331
- }).catch(() => {
332
- if (flag) {
333
- clearTimeout(id)
334
- startAll()
335
- }
336
- return Promise.reject()
337
- })
338
- })
339
- }
340
-
341
- // 检查请求是否成功
342
- // noinspection JSUnusedLocalSymbols
343
- const checkResponse = response => response.ok || [301, 302, 307, 308].includes(response.status)
344
-
345
- /**
346
- * 删除指定缓存
347
- * @param list 要删除的缓存列表
348
- * @return {Promise<string[]>} 删除的缓存的URL列表
349
- */
350
- const deleteCache = list => caches.open(CACHE_NAME).then(cache => cache.keys()
351
- .then(keys => Promise.all(
352
- keys.map(async it => {
353
- const url = it.url
354
- if (url !== CTRL_PATH && list.match(url)) {
355
- // [debug delete]
356
- // noinspection ES6MissingAwait,JSCheckFunctionSignatures
357
- cache.delete(it)
358
- return url
359
- }
360
- return null
361
- })
362
- )).then(list => list.filter(it => it))
363
- )
364
-
365
- /**
366
- * 缓存列表
367
- * @type {Map<string, function(any)[]>}
368
- */
369
- const cacheMap = new Map()
370
-
371
- self.addEventListener('fetch', event => {
372
- let request = event.request
373
- let url = new URL(request.url)
374
- // [blockRequest call]
375
- if (request.method !== 'GET' || !request.url.startsWith('http')) return
376
- // [modifyRequest call]
377
- if (skipRequest(request)) return;
378
- let cacheKey = url.hostname + url.pathname + url.search
379
- let cache
380
- if (isMemoryQueue(request)) {
381
- cache = cacheMap.get(cacheKey)
382
- if (cache) {
383
- return event.respondWith(
384
- new Promise((resolve, reject) => {
385
- cacheMap.get(cacheKey).push(arg => arg.body ? resolve(arg) : reject(arg))
386
- })
387
- )
388
- }
389
- cacheMap.set(cacheKey, cache = [])
390
- }
391
- /** 处理拉取 */
392
- const handleFetch = promise => {
393
- event.respondWith(
394
- cache ? promise.then(response => {
395
- for (let item of cache) {
396
- item(response.clone())
397
- }
398
- }).catch(err => {
399
- for (let item of cache) {
400
- item(err)
401
- }
402
- }).then(() => {
403
- cacheMap.delete(cacheKey)
404
- return promise
405
- }) : promise
406
- )
407
- }
408
- const cacheRule = findCache(url)
409
- if (cacheRule) {
410
- let key = `https://${url.host}${url.pathname}`
411
- if (key.endsWith('/index.html')) key = key.substring(0, key.length - 10)
412
- if (cacheRule.search) key += url.search
413
- handleFetch(
414
- caches.match(key).then(
415
- cache => cache ?? fetchFile(request, true)
416
- .then(response => {
417
- if (checkResponse(response)) {
418
- const clone = response.clone()
419
- caches.open(CACHE_NAME).then(it => it.put(key, clone))
420
- // [debug put]
421
- }
422
- return response
423
- })
424
- )
425
- )
426
- } else {
427
- const urls = getSpareUrls(request.url)
428
- if (urls) handleFetch(fetchFile(request, false, urls))
429
- // [modifyRequest else-if]
430
- else handleFetch(fetchWithCache(request).catch(err => new Response(err, {status: 499})))
431
- }
432
- })
433
-
434
- self.addEventListener('message', event => {
435
- // [debug message]
436
- if (event.data === 'update')
437
- updateJson().then(info => {
438
- info.type = 'update'
439
- event.source.postMessage(info)
440
- })
441
- })
442
-
443
- /**
444
- * 根据JSON删除缓存
445
- * @returns {Promise<UpdateInfo>}
446
- */
447
- const updateJson = async () => {
448
- /**
449
- * 解析elements,并把结果输出到list中
450
- * @return boolean 是否刷新全站缓存
451
- */
452
- const parseChange = (list, elements, ver) => {
453
- for (let element of elements) {
454
- const {version, change} = element
455
- if (version === ver) return false
456
- if (change) {
457
- for (let it of change)
458
- list.push(new CacheChangeExpression(it))
459
- }
460
- }
461
- // 跨版本幅度过大,直接清理全站
462
- return true
463
- }
464
- /**
465
- * 解析字符串
466
- * @return {Promise<{
467
- * list?: VersionList,
468
- * new: BrowserVersion,
469
- * old: BrowserVersion
470
- * }>}
471
- */
472
- const parseJson = json => readVersion().then(oldVersion => {
473
- const {info, global} = json
474
- /** @type {BrowserVersion} */
475
- const newVersion = {global, local: info[0].version, escape: oldVersion?.escape ?? 0}
476
- // 新用户和刚进行过逃逸操作的用户不进行更新操作
477
- if (!oldVersion) {
478
- // noinspection JSValidateTypes
479
- newVersion.escape = 0
480
- writeVersion(newVersion)
481
- return {new: newVersion, old: oldVersion}
482
- }
483
- let list = new VersionList()
484
- let refresh = parseChange(list, info, oldVersion.local)
485
- writeVersion(newVersion)
486
- // [debug escape]
487
- // 如果需要清理全站
488
- if (refresh) {
489
- if (global !== oldVersion.global) list.force = true
490
- else list.refresh = true
491
- }
492
- return {list, new: newVersion, old: oldVersion}
493
- })
494
- const response = await fetchFile(new Request('/update.json'), false)
495
- if (!checkResponse(response))
496
- throw `加载 update.json 时遇到异常,状态码:${response.status}`
497
- const json = await response.json()
498
- const result = await parseJson(json)
499
- if (result.list) {
500
- const list = await deleteCache(result.list)
501
- result.list = list?.length ? list : null
502
- }
503
- // noinspection JSValidateTypes
504
- return result
505
- }
506
-
507
- /**
508
- * 版本列表
509
- * @constructor
510
- */
511
- function VersionList() {
512
-
513
- const list = []
514
-
515
- /**
516
- * 推送一个表达式
517
- * @param element {CacheChangeExpression} 要推送的表达式
518
- */
519
- this.push = element => {
520
- list.push(element)
521
- }
522
-
523
- /**
524
- * 判断指定 URL 是否和某一条规则匹配
525
- * @param url {string} URL
526
- * @return {boolean}
527
- */
528
- this.match = url => {
529
- if (this.force) return true
530
- // noinspection JSValidateTypes
531
- url = new URL(url)
532
- if (this.refresh) {
533
- // noinspection JSCheckFunctionSignatures
534
- return findCache(url).clean
535
- }
536
- else {
537
- for (let it of list) {
538
- if (it.match(url)) return true
539
- }
540
- }
541
- return false
542
- }
543
-
544
- }
545
-
546
- // noinspection SpellCheckingInspection
547
- /**
548
- * 缓存更新匹配规则表达式
549
- * @param json 格式{"flag": ..., "value": ...}
550
- * @see https://kmar.top/posts/bcfe8408/#23bb4130
551
- * @constructor
552
- */
553
- function CacheChangeExpression(json) {
554
- /**
555
- * 遍历所有value
556
- * @param action {function(string): boolean} 接受value并返回bool的函数
557
- * @return {boolean} 如果value只有一个则返回`action(value)`,否则返回所有运算的或运算(带短路)
558
- */
559
- const forEachValues = action => {
560
- const value = json.value
561
- if (Array.isArray(value)) {
562
- for (let it of value) {
563
- if (action(it)) return true
564
- }
565
- return false
566
- } else return action(value)
567
- }
568
- const getMatch = () => {
569
- switch (json['flag']) {
570
- case 'html':
571
- return url => url.pathname.match(/(\/|\.html)$/)
572
- case 'end':
573
- return url => forEachValues(value => url.href.endsWith(value))
574
- case 'begin':
575
- return url => forEachValues(value => url.pathname.startsWith(value))
576
- case 'str':
577
- return url => forEachValues(value => url.href.includes(value))
578
- case 'reg':
579
- // noinspection JSCheckFunctionSignatures
580
- return url => forEachValues(value => url.href.match(new RegExp(value, 'i')))
581
- default: throw `未知表达式:${JSON.stringify(json)}`
582
- }
583
- }
584
- this.match = getMatch()
585
- }
586
- })()
1
+ (()=>{const t="StoriHouseCache",e="https://id.v3/",n=()=>caches.match(e).then((t=>t?.json())),s=n=>caches.open(t).then((t=>t.put(e,new Response(JSON.stringify(n)))));self.addEventListener("install",(()=>{self.skipWaiting()})),self.addEventListener("activate",(t=>t.waitUntil(clients.claim())));const r=(t,e,n,s)=>(s||(s={}),s.cache=e?"no-store":"default",n&&(s.mode="cors",s.credentials="same-origin"),fetch(t,s)),c=(t,e,n)=>r(t,e,!0,n),a=t=>{if("localhost"!==t.hostname)for(let e in o){const n=o[e];if(n.match(t))return n}};let o={simple:{clean:!0,search:!1,match:t=>"blog.sinzmise.top"===t.host&&["/404.html","/css/index.css"].includes(t.pathname)},cdn:{clean:!0,match:t=>["unpkg.com","cdn.cbd.int","lf26-cdn-tos.bytecdntp.com","lf6-cdn-tos.bytecdntp.com","lf3-cdn-tos.bytecdntp.com","lf9-cdn-tos.bytecdntp.com","npm.onmicrosoft.cn","cdn.staticfile.org","npm.elemecdn.com"].includes(t.host)&&t.pathname.match(/\.(js|css|woff2|woff|ttf|cur)$/)}},i=t=>{if(t.startsWith("https://npm.elemecdn.com"))return{timeout:3e3,list:[t,`https://cdn.cbd.int/${new URL(t).pathname}`]}},l=()=>!1;const h=(t,e,n=null)=>{if(!n&&!(n=i(t.url)))return c(t,e);const s=n.list,r=new Array(s.length),a=n=>c(new Request(s[n],t),e,{signal:(r[n]=new AbortController).signal}).then((t=>u(t)?{r:t,i:n}:Promise.reject()));return new Promise(((e,c)=>{let o=!0;const i=()=>{o=!1,Promise.any([h,...Array.from({length:s.length-1},((t,e)=>e+1)).map((t=>a(t)))]).then((t=>{for(let e=0;e!==s.length;++e)e!==t.i&&r[e].abort();e(t.r)})).catch((()=>c(`请求 ${t.url} 失败`)))},l=setTimeout(i,n.timeout),h=a(0).then((t=>{o&&(clearTimeout(l),e(t.r))})).catch((()=>(o&&(clearTimeout(l),i()),Promise.reject())))}))},u=t=>t.ok||[301,302,307,308].includes(t.status),f=new Map;self.addEventListener("fetch",(e=>{let n=e.request,s=new URL(n.url);if("GET"!==n.method||!n.url.startsWith("http"))return;if((t=>t.url.startsWith("https://i0.hdslb.com"))(n))return;let c,o=s.hostname+s.pathname+s.search;const m=t=>{e.respondWith(c?t.then((t=>{for(let e of c)e(t.clone())})).catch((t=>{for(let e of c)e(t)})).then((()=>(f.delete(o),t))):t)},d=a(s);if(d){let e=`https://${s.host}${s.pathname}`;e.endsWith("/index.html")&&(e=e.substring(0,e.length-10)),d.search&&(e+=s.search),m(caches.match(e).then((s=>s??h(n,!0).then((n=>{if(u(n)){const s=n.clone();caches.open(t).then((t=>t.put(e,s)))}return n})))))}else{const t=i(n.url);m(t?h(n,!1,t):((t,e)=>r(t,!1,l(t),e))(n).catch((t=>new Response(t,{status:499}))))}})),self.addEventListener("message",(t=>{"update"===t.data&&m().then((e=>{e.type="update",t.source.postMessage(e)}))}));const m=async()=>{const r=await h(new Request("/update.json"),!1);if(!u(r))throw`加载 update.json 时遇到异常,状态码:${r.status}`;const c=await r.json(),a=await(t=>n().then((e=>{const{info:n,global:r}=t,c={global:r,local:n[0].version,escape:e?.escape??0};if(!e)return c.escape=0,s(c),{new:c,old:e};let a=new d,o=((t,e,n)=>{for(let s of e){const{version:e,change:r}=s;if(e===n)return!1;if(r)for(let e of r)t.push(new p(e))}return!0})(a,n,e.local);return s(c),o&&(r!==e.global?a.force=!0:a.refresh=!0),{list:a,new:c,old:e}})))(c);if(a.list){const n=await(n=>caches.open(t).then((t=>t.keys().then((s=>Promise.all(s.map((async s=>{const r=s.url;return r!==e&&n.match(r)?(t.delete(s),r):null}))))).then((t=>t.filter((t=>t)))))))(a.list);a.list=n?.length?n:null}return a};function d(){const t=[];this.push=e=>{t.push(e)},this.match=e=>{if(this.force)return!0;if(e=new URL(e),this.refresh)return a(e).clean;for(let n of t)if(n.match(e))return!0;return!1}}function p(t){const e=e=>{const n=t.value;if(Array.isArray(n)){for(let t of n)if(e(t))return!0;return!1}return e(n)};this.match=(()=>{switch(t.flag){case"html":return t=>t.pathname.match(/(\/|\.html)$/);case"end":return t=>e((e=>t.href.endsWith(e)));case"begin":return t=>e((e=>t.pathname.startsWith(e)));case"str":return t=>e((e=>t.href.includes(e)));case"reg":return t=>e((e=>t.href.match(new RegExp(e,"i"))));default:throw`未知表达式:${JSON.stringify(t)}`}})()}})();