Skip to content

Commit

Permalink
Initial service worker
Browse files Browse the repository at this point in the history
  • Loading branch information
jakearchibald committed Apr 22, 2019
1 parent efd9259 commit 1e0508c
Show file tree
Hide file tree
Showing 8 changed files with 152 additions and 3 deletions.
33 changes: 33 additions & 0 deletions consts-plugin.js
@@ -0,0 +1,33 @@
/**
* Copyright 2019 Google Inc. All Rights Reserved.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
* http://www.apache.org/licenses/LICENSE-2.0
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
export default function constsPlugin(consts) {
return {
name: "consts-plugin",
async resolveId(id) {
if (id !== "consts:") {
return;
}
return id;
},
load(id) {
if (id !== "consts:") {
return;
}
return Object.entries(consts)
.map(
([key, value]) => `export const ${key} = ${JSON.stringify(value)};`
)
.join("");
}
};
}
41 changes: 41 additions & 0 deletions resource-list-plugin.js
@@ -0,0 +1,41 @@
/**
* Copyright 2018 Google Inc. All Rights Reserved.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
* http://www.apache.org/licenses/LICENSE-2.0
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
const resourceListMarker = "___REPLACE_THIS_WITH_RESOURCE_LIST_LATER";

export default function resourceList() {
return {
name: "dependencygraph",
resolveId(id) {
if (id !== "resource-list:") {
return null;
}
return id;
},
load(id) {
if (id !== "resource-list:") {
return null;
}
return `export default ${resourceListMarker};`;
},
generateBundle(_outputOptions, bundle) {
const resourceListJSON = JSON.stringify(Object.keys(bundle));

for (const item of Object.values(bundle)) {
if (!item.code) {
continue;
}
item.code = item.code.replace(resourceListMarker, resourceListJSON);
}
}
};
}
13 changes: 11 additions & 2 deletions rollup.config.js
Expand Up @@ -17,22 +17,27 @@ import { terser } from "rollup-plugin-terser";
import loadz0r from "rollup-plugin-loadz0r";
import dependencyGraph from "./dependency-graph-plugin.js";
import chunkNamePlugin from "./chunk-name-plugin.js";
import resourceListPlugin from "./resource-list-plugin";
import postcss from "rollup-plugin-postcss";
import glsl from "./glsl-plugin.js";
import cssModuleTypes from "./css-module-types.js";
import assetPlugin from "./asset-plugin.js";
import { readFileSync } from "fs";
import constsPlugin from "./consts-plugin.js";

// Delete 'dist'
require("rimraf").sync("dist");

export default {
input: "src/bootstrap.ts",
input: {
bootstrap: "src/bootstrap.ts",
sw: "src/sw/index.ts"
},
output: {
dir: "dist",
format: "amd",
sourcemap: true,
entryFileNames: "[name]-[hash].js",
entryFileNames: "[name].js",
chunkFileNames: "[name]-[hash].js"
},
plugins: [
Expand All @@ -47,6 +52,9 @@ export default {
return name.replace(/-\w/g, val => val.slice(1).toUpperCase());
}
}),
constsPlugin({
version: require("./package.json").version
}),
typescript({
// Make sure we are using our version of TypeScript.
typescript: require("typescript"),
Expand Down Expand Up @@ -87,6 +95,7 @@ export default {
dependencyGraph({
propList: ["facadeModuleId", "fileName", "imports", "code", "isAsset"]
}),
resourceListPlugin(),
terser()
]
};
9 changes: 9 additions & 0 deletions src/missing-types.d.ts
Expand Up @@ -3,6 +3,15 @@ declare module "chunk-name:*" {
export default value;
}

declare module "resource-list:" {
const value: string[];
export default value;
}

declare module "consts:" {
export const version: string;
}

interface Window {
debug?: Promise<typeof import("./services/debug/index.js")>;
}
Expand Down
43 changes: 43 additions & 0 deletions src/sw/index.ts
@@ -0,0 +1,43 @@
import { version } from "consts:";
import resourceList from "resource-list:";
// Give TypeScript the correct global.
declare var self: ServiceWorkerGlobalScope;

const staticCache = `static-${version}`;

self.addEventListener("install", event => {
const toCache = resourceList.filter(item => item !== "sw.js");

event.waitUntil(
(async function() {
const cache = await caches.open(staticCache);
await cache.addAll(toCache);
})()
);
});

self.addEventListener("activate", event => {
event.waitUntil(
(async function() {
const cacheNames = await caches.keys();
for (const cacheName of cacheNames) {
if (cacheName === staticCache) {
continue;
}
await caches.delete(cacheName);
}
})()
);
});

self.addEventListener("fetch", event => {
if (event.request.method !== "GET") {
return;
}
event.respondWith(
(async function() {
const cachedResponse = await caches.match(event.request);
return cachedResponse || fetch(event.request);
})()
);
});
1 change: 1 addition & 0 deletions src/sw/missing-types.d.ts
@@ -0,0 +1 @@
import "../missing-types";
12 changes: 12 additions & 0 deletions src/sw/tsconfig.json
@@ -0,0 +1,12 @@
{
"compilerOptions": {
"experimentalDecorators": true,
"target": "es5",
"downlevelIteration": true,
"module": "esnext",
"strict": true,
"lib": ["esnext", "webworker"],
"moduleResolution": "node",
"baseUrl": "./",
}
}
3 changes: 2 additions & 1 deletion tsconfig.json
Expand Up @@ -11,5 +11,6 @@
"moduleResolution": "node",
"baseUrl": "./",
"types": []
}
},
"exclude": ["src/sw/**/*"]
}

0 comments on commit 1e0508c

Please sign in to comment.