-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathsw.js
153 lines (104 loc) · 3.6 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
importScripts("/editor/plugins/phaserstudio.idb/sw-libs/localforage.js");
// importScripts("https://cdn.phaser.io/editor/dist/editor/app/plugins/phaserstudio.idb/sw-libs/localforage.js");
const ver = 28;
/** @type {LocalForage} */
const localForage = self.localforage;
/** @type {Map<LocalForageDriver>} */
let databaseMap = new Map();
self.addEventListener("install", e => {
log("Installing service worker v" + ver);
self.skipWaiting();
});
self.addEventListener("activate", (event) => {
event.waitUntil(clients.claim());
});
self.addEventListener("fetch", async (/** @type {FetchEvent} */ event) => {
event.respondWith(makeResponse(event));
});
/**
* @param {FetchEvent} event
*/
async function makeResponse(event) {
const request = event.request
const url = new URL(request.url);
const path = url.pathname;
log("fetch: " + path);
/** @type {string} */
let fileKey;
let dbName = "";
if (path.startsWith("/editor/project/")) {
fileKey = path.substring("/editor/project".length);
} else if (path.startsWith("/editor/external/")) {
fileKey = path.substring("/editor/external".length);
} else if (path.startsWith("/editor/trial-external/")) {
// ["", "editor", "trial-external", dbName, fileKey...]]
const parts = path.split("/");
dbName = parts[3];
fileKey = path.substring(`/editor/trial-external/${dbName}`.length);
log("parts", parts);
log("dbName:", dbName, "file:", fileKey);
}
if (fileKey === "/") {
fileKey = "/index.html";
}
if (fileKey) {
fileKey = decodeURIComponent(fileKey);
log("testing key " + fileKey);
let database = databaseMap.get(dbName);
if (!database) {
database = localForage.createInstance({
storeName: `PhaserEditor-FsDatabase-${dbName}`,
driver: localForage.INDEXEDDB,
name: `Phaser Editor - FileSystem IndexedDB-${dbName}`
});
databaseMap.set(dbName, database);
}
const content = await database.getItem(fileKey);
if (content) {
log("respondWith indexedDB: " + fileKey + " [" + (typeof content) + "]");
const extension = fileKey.split(".").pop();
const contentType = getContentType(extension);
return new Response(content, {
headers: { "Content-Type": contentType }
});
} else {
log("can't find " + fileKey + " in database");
}
}
log("respondWith fetch: " + url);
if (path.startsWith("/editor/external/") || path.startsWith("/editor/trial-external/")) {
return new Response("Not found", {
headers: { "Content-Type": "text/plain" },
status: 404
});
}
return fetch(request);
}
const CONTENT_TYPE_MAP = {
"txt": "text/plain",
"json": "application/json",
"html": "text/html",
"css": "text/css",
"js": "application/javascript",
"jpg": "image/jpeg",
"png": "image/png",
"gif": "image/gif",
"mp4": "video/mp4",
"mp3": "audio/mpeg",
"wav": "audio/wav",
"ogg": "audio/ogg",
"webm": "video/webm",
"woff": "application/font-woff",
"woff2": "font/woff2",
"ttf": "font/ttf",
"otf": "font/otf",
"eot": "application/vnd.ms-fontobject",
"svg": "image/svg+xml"
};
function getContentType(extension) {
// default to binary data if no mapping found
return CONTENT_TYPE_MAP[extension.toLowerCase()] || "application/octet-stream";
}
function log(...args) {
console.log(`SW v${ver}:`, ...args);
}