Merge pull request #4472 from urbit/lf/globbed-sw

interface: adds serviceworker support
This commit is contained in:
matildepark 2021-02-21 22:09:33 -05:00 committed by GitHub
commit ec44fbf269
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
11 changed files with 197 additions and 12 deletions

View File

@ -240,7 +240,12 @@
=/ mime-type=@t (rsh 3 (crip <p.u.data>))
:: Should maybe inspect to see how long cache should hold
::
[[200 ['content-type' mime-type] max-1-da:gen ~] `q.u.data]
=/ headers
:~ content-type+mime-type
max-1-da:gen
'Service-Worker-Allowed'^'/'
==
[[200 headers] `q.u.data]
==
::
++ lowercase

View File

@ -5,7 +5,7 @@
/- glob
/+ default-agent, verb, dbug
|%
++ hash 0v5.pmklm.qttdl.n8bs0.0tnc4.gg633
++ hash 0v1.ua909.ub024.9ed4i.23odb.jgdit
+$ state-0 [%0 hash=@uv glob=(unit (each glob:glob tid=@ta))]
+$ all-states
$% state-0
@ -105,12 +105,15 @@
(cat 3 js-name '.js')
=+ .^(js=@t %cx :(weld home /app/landscape/js/bundle /[js-name]/js))
=+ .^(map=@t %cx :(weld home /app/landscape/js/bundle /[map-name]/map))
=+ .^(sw=@t %cx :(weld home /app/landscape/js/bundle /serviceworker/js))
=+ !<(=js=mime (js-tube !>(js)))
=+ !<(=sw=mime (js-tube !>(sw)))
=+ !<(=map=mime (map-tube !>(map)))
=/ =glob:glob
%- ~(gas by *glob:glob)
:~ /[js-name]/js^js-mime
/[map-name]/map^map-mime
/serviceworker/js^sw-mime
==
=/ =path /(cat 3 'glob-' (scot %uv (sham glob)))/glob
[%pass /make %agent [our.bowl %hood] %poke %drum-put !>([path (jam glob)])]~

View File

@ -24,6 +24,6 @@
<div id="portal-root"></div>
<script src="/~landscape/js/channel.js"></script>
<script src="/~landscape/js/session.js"></script>
<script src="/~landscape/js/bundle/index.ee4aea08fefb9c47dcfd.js"></script>
<script src="/~landscape/js/bundle/index.7c43e500ee99cd786842.js"></script>
</body>
</html>

View File

@ -64,6 +64,12 @@ if(urbitrc.URL) {
return '/index.js'
}
},
'/~landscape/js/serviceworker.js': {
target: 'http://localhost:9000',
pathRewrite: (req, path) => {
return '/serviceworker.js'
}
},
'**': {
changeOrigin: true,
target: urbitrc.URL,
@ -78,7 +84,8 @@ if(urbitrc.URL) {
module.exports = {
mode: 'development',
entry: {
app: './src/index.js'
app: './src/index.js',
serviceworker: './src/serviceworker.js'
},
module: {
rules: [
@ -135,10 +142,13 @@ module.exports = {
],
watch: true,
output: {
filename: 'index.js',
chunkFilename: 'index.js',
filename: (pathData) => {
return pathData.chunk.name === 'app' ? 'index.js' : '[name].js';
},
chunkFilename: '[name].js',
path: path.resolve(__dirname, '../dist'),
publicPath: '/'
publicPath: '/',
globalObject: 'this'
},
optimization: {
minimize: false,

View File

@ -3,11 +3,15 @@ const path = require('path');
const { CleanWebpackPlugin } = require('clean-webpack-plugin');
const MomentLocalesPlugin = require('moment-locales-webpack-plugin');
const webpack = require('webpack');
const { execSync } = require('child_process');
const GIT_DESC = execSync('git describe --always', { encoding: 'utf8' }).trim();
module.exports = {
mode: 'production',
entry: {
app: './src/index.js'
app: './src/index.js',
serviceworker: './src/serviceworker.js'
},
module: {
rules: [
@ -56,20 +60,22 @@ module.exports = {
new CleanWebpackPlugin(),
new webpack.DefinePlugin({
'process.env.LANDSCAPE_STREAM': JSON.stringify(process.env.LANDSCAPE_STREAM),
'process.env.LANDSCAPE_SHORTHASH': JSON.stringify(process.env.LANDSCAPE_SHORTHASH),
'process.env.LANDSCAPE_SHORTHASH': JSON.stringify(GIT_DESC),
'process.env.TUTORIAL_HOST': JSON.stringify('~hastuc-dibtux'),
'process.env.TUTORIAL_GROUP': JSON.stringify('beginner-island'),
'process.env.TUTORIAL_CHAT': JSON.stringify('chat-8401'),
'process.env.TUTORIAL_BOOK': JSON.stringify('notebook-9148'),
'process.env.TUTORIAL_LINKS': JSON.stringify('links-4353'),
}),
})
// new HtmlWebpackPlugin({
// title: 'Hot Module Replacement',
// template: './public/index.html',
// }),
],
output: {
filename: 'index.[contenthash].js',
filename: (pathData) => {
return pathData.chunk.name === 'app' ? 'index.[contenthash].js' : '[name].js';
},
path: path.resolve(__dirname, '../../arvo/app/landscape/js/bundle'),
publicPath: '/'
},

View File

@ -1789,7 +1789,9 @@
}
},
"@urbit/eslint-config": {
"version": "1.0.0"
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/@urbit/eslint-config/-/eslint-config-1.0.0.tgz",
"integrity": "sha512-Xmzb6MvM7KorlPJEq/hURZZ4BHSVy/7CoQXWogsBSTv5MOZnMqwNKw6yt24k2AO/2UpHwjGptimaNLqFfesJbw=="
},
"big-integer": {
"version": "1.6.48",
@ -10432,6 +10434,66 @@
"integrity": "sha512-Hz/mrNwitNRh/HUAtM/VT/5VH+ygD6DV7mYKZAtHOrbs8U7lvPS6xf7EJKMF0uW1KJCl0H701g3ZGus+muE5vQ==",
"dev": true
},
"workbox-cacheable-response": {
"version": "6.0.2",
"resolved": "https://registry.npmjs.org/workbox-cacheable-response/-/workbox-cacheable-response-6.0.2.tgz",
"integrity": "sha512-OrgFiYWkmFXDIbNRYSu+fchcfoZqyJ4yZbdc8WKUjr9v/MghKHfR9u7UI077xBkjno5J3YNpbwx73/no3HkrzA==",
"requires": {
"workbox-core": "^6.0.2"
}
},
"workbox-core": {
"version": "6.0.2",
"resolved": "https://registry.npmjs.org/workbox-core/-/workbox-core-6.0.2.tgz",
"integrity": "sha512-Ksl6qeikGb+BOCILoCUJGxwlEQOeeqdpOnpOr9UDt3NtacPYbfYBmpYpKArw5DFWK+5geBsFqgUUlXThlCYfKQ=="
},
"workbox-expiration": {
"version": "6.0.2",
"resolved": "https://registry.npmjs.org/workbox-expiration/-/workbox-expiration-6.0.2.tgz",
"integrity": "sha512-6+nbR18cklAdI3BPT675ytftXPwnVbXGR8mPWNWTJtl5y2urRYv56ZOJLD7FBFVkZ8EjWiRhNP/A0fkxgdKtWQ==",
"requires": {
"workbox-core": "^6.0.2"
}
},
"workbox-precaching": {
"version": "6.0.2",
"resolved": "https://registry.npmjs.org/workbox-precaching/-/workbox-precaching-6.0.2.tgz",
"integrity": "sha512-sqKWL2emzmGnfJpna+9RjUkUiqQO++AKfwljCbgkHg8wBbVLy/rnui3eelKgAI7D8R31LJFfiZkY/kXmwkjtlQ==",
"requires": {
"workbox-core": "^6.0.2",
"workbox-routing": "^6.0.2",
"workbox-strategies": "^6.0.2"
}
},
"workbox-recipes": {
"version": "6.0.2",
"resolved": "https://registry.npmjs.org/workbox-recipes/-/workbox-recipes-6.0.2.tgz",
"integrity": "sha512-ewZIHO4jYE6bnEeUIYS6joQy3l+MydpOsVr2F6EpE8ps++z1ScbSdLtJU+yu6WuO3lH44HFZLeFxYQqYm50QAA==",
"requires": {
"workbox-cacheable-response": "^6.0.2",
"workbox-core": "^6.0.2",
"workbox-expiration": "^6.0.2",
"workbox-precaching": "^6.0.2",
"workbox-routing": "^6.0.2",
"workbox-strategies": "^6.0.2"
}
},
"workbox-routing": {
"version": "6.0.2",
"resolved": "https://registry.npmjs.org/workbox-routing/-/workbox-routing-6.0.2.tgz",
"integrity": "sha512-iQ9ch3fL1YpztDLfHNURaHQ0ispgPCdzWmZZhtSHUyy/+YkTlIiDVTbOQCIpHIrWlKQiim6X3K2ItIy1FW9+wA==",
"requires": {
"workbox-core": "^6.0.2"
}
},
"workbox-strategies": {
"version": "6.0.2",
"resolved": "https://registry.npmjs.org/workbox-strategies/-/workbox-strategies-6.0.2.tgz",
"integrity": "sha512-HjLnYCVS60U7OKhl5NIq8NAQXrotJQRDakmIONnRlQIlP2If/kAiQSUP3QCHMq4EeXGiF+/CdlR1/bhYBHZzZg==",
"requires": {
"workbox-core": "^6.0.2"
}
},
"worker-farm": {
"version": "1.7.0",
"resolved": "https://registry.npmjs.org/worker-farm/-/worker-farm-1.7.0.tgz",

View File

@ -45,6 +45,10 @@
"styled-system": "^5.1.5",
"suncalc": "^1.8.0",
"urbit-ob": "^5.0.1",
"workbox-core": "^6.0.2",
"workbox-precaching": "^6.0.2",
"workbox-recipes": "^6.0.2",
"workbox-routing": "^6.0.2",
"yup": "^0.29.3",
"zustand": "^3.3.1"
},

View File

@ -1,6 +1,8 @@
import * as React from 'react';
import * as ReactDOM from 'react-dom';
import './register-sw';
import App from './views/App';
ReactDOM.render(<App />, document.getElementById('root'));

View File

@ -0,0 +1,10 @@
if ("serviceWorker" in navigator) {
window.addEventListener("load", () => {
navigator.serviceWorker.register("/~landscape/js/bundle/serviceworker.js", {
scope: "/",
}).then(reg => {
});
});
}

View File

@ -0,0 +1,82 @@
import { registerRoute } from 'workbox-routing';
import {
NetworkFirst,
StaleWhileRevalidate,
CacheFirst,
} from 'workbox-strategies';
// Used for filtering matches based on status code, header, or both
import { CacheableResponsePlugin } from 'workbox-cacheable-response';
// Used to limit entries in cache, remove entries after a certain period of time
import { ExpirationPlugin } from 'workbox-expiration';
// generate a different sw for every build, to bust cache properly
const hash = process.env.LANDSCAPE_SHORTHASH;
self.addEventListener("install", ev => {
self.skipWaiting();
});
self.addEventListener('activate', ev => {
ev.waitUntil(clients.claim());
});
// Cache page navigations (html) with a Network First strategy
registerRoute(
// Check to see if the request is a navigation to a new page
({ request }) => request.mode === 'navigate',
// Use a Network First caching strategy
new NetworkFirst({
// Put all cached files in a cache named 'pages'
cacheName: 'pages',
plugins: [
// Ensure that only requests that result in a 200 status are cached
new CacheableResponsePlugin({
statuses: [200],
}),
],
}),
);
// Cache CSS, JS, and Web Worker requests with a Stale While Revalidate strategy
registerRoute(
// Check to see if the request's destination is style for stylesheets, script for JavaScript, or worker for web worker
({ request }) =>
request.destination === 'style' ||
request.destination === 'script' ||
request.destination === 'worker',
// Use a Stale While Revalidate caching strategy
new StaleWhileRevalidate({
// Put all cached files in a cache named 'assets'
cacheName: 'assets',
plugins: [
// Ensure that only requests that result in a 200 status are cached
new CacheableResponsePlugin({
statuses: [200],
}),
],
}),
);
// Cache images with a Cache First strategy
registerRoute(
// Check to see if the request's destination is style for an image
({ request }) => request.destination === 'image',
// Use a Cache First caching strategy
new CacheFirst({
// Put all cached files in a cache named 'images'
cacheName: 'images',
plugins: [
// Ensure that only requests that result in a 200 status are cached
new CacheableResponsePlugin({
statuses: [200],
}),
// Don't cache more than 50 items, and expire them after 30 days
new ExpirationPlugin({
maxEntries: 50,
maxAgeSeconds: 60 * 60 * 24 * 30, // 30 Days
}),
],
}),
);

View File

@ -111,6 +111,7 @@ return;
if (isImage && remoteContentPolicy.imageShown) {
return this.wrapInLink(
<BaseImage
crossOrigin="anonymous"
flexShrink={0}
src={url}
style={style}