Introduce Offline Mode (#2082)

This commit is contained in:
Alexander Zinchuk 2022-10-29 15:18:27 +02:00
parent 9ff2fc1ba3
commit decbfd39a1
8 changed files with 66 additions and 16 deletions

View File

@ -2,13 +2,10 @@
cp -R ./public/* ${1:-"dist"} cp -R ./public/* ${1:-"dist"}
cp ./src/lib/rlottie/rlottie-wasm.js ${1:-"dist"}
cp ./src/lib/rlottie/rlottie-wasm.wasm ${1:-"dist"} cp ./src/lib/rlottie/rlottie-wasm.wasm ${1:-"dist"}
cp ./src/lib/webp/webp_wasm.wasm ${1:-"dist"}
cp ./node_modules/opus-recorder/dist/decoderWorker.min.wasm ${1:-"dist"} cp ./node_modules/opus-recorder/dist/decoderWorker.min.wasm ${1:-"dist"}
cp ./src/lib/webp/webp_wasm.js ${1:-"dist"}
cp ./src/lib/webp/webp_wasm.wasm ${1:-"dist"}
cp -R ./node_modules/emoji-data-ios/img-apple-64 ${1:-"dist"} cp -R ./node_modules/emoji-data-ios/img-apple-64 ${1:-"dist"}
cp -R ./node_modules/emoji-data-ios/img-apple-160 ${1:-"dist"} cp -R ./node_modules/emoji-data-ios/img-apple-160 ${1:-"dist"}

31
package-lock.json generated
View File

@ -81,6 +81,7 @@
"replace-in-file": "^6.3.2", "replace-in-file": "^6.3.2",
"sass": "^1.50.0", "sass": "^1.50.0",
"sass-loader": "^12.6.0", "sass-loader": "^12.6.0",
"script-loader": "^0.7.2",
"serve": "^13.0.2", "serve": "^13.0.2",
"style-loader": "^3.3.1", "style-loader": "^3.3.1",
"stylelint": "^14.6.1", "stylelint": "^14.6.1",
@ -14171,6 +14172,12 @@
"node": ">= 0.8" "node": ">= 0.8"
} }
}, },
"node_modules/raw-loader": {
"version": "0.5.1",
"resolved": "https://registry.npmjs.org/raw-loader/-/raw-loader-0.5.1.tgz",
"integrity": "sha512-sf7oGoLuaYAScB4VGr0tzetsYlS8EJH6qnTCfQ/WVEa89hALQ4RQfCKt5xCyPQKPDUbVUAIP1QsxAwfAjlDp7Q==",
"dev": true
},
"node_modules/rc": { "node_modules/rc": {
"version": "1.2.8", "version": "1.2.8",
"resolved": "https://registry.npmjs.org/rc/-/rc-1.2.8.tgz", "resolved": "https://registry.npmjs.org/rc/-/rc-1.2.8.tgz",
@ -15036,6 +15043,15 @@
"integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==", "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==",
"dev": true "dev": true
}, },
"node_modules/script-loader": {
"version": "0.7.2",
"resolved": "https://registry.npmjs.org/script-loader/-/script-loader-0.7.2.tgz",
"integrity": "sha512-UMNLEvgOAQuzK8ji8qIscM3GIrRCWN6MmMXGD4SD5l6cSycgGsCo0tX5xRnfQcoghqct0tjHjcykgI1PyBE2aA==",
"dev": true,
"dependencies": {
"raw-loader": "~0.5.1"
}
},
"node_modules/select-hose": { "node_modules/select-hose": {
"version": "2.0.0", "version": "2.0.0",
"resolved": "https://registry.npmjs.org/select-hose/-/select-hose-2.0.0.tgz", "resolved": "https://registry.npmjs.org/select-hose/-/select-hose-2.0.0.tgz",
@ -28750,6 +28766,12 @@
} }
} }
}, },
"raw-loader": {
"version": "0.5.1",
"resolved": "https://registry.npmjs.org/raw-loader/-/raw-loader-0.5.1.tgz",
"integrity": "sha512-sf7oGoLuaYAScB4VGr0tzetsYlS8EJH6qnTCfQ/WVEa89hALQ4RQfCKt5xCyPQKPDUbVUAIP1QsxAwfAjlDp7Q==",
"dev": true
},
"rc": { "rc": {
"version": "1.2.8", "version": "1.2.8",
"resolved": "https://registry.npmjs.org/rc/-/rc-1.2.8.tgz", "resolved": "https://registry.npmjs.org/rc/-/rc-1.2.8.tgz",
@ -29383,6 +29405,15 @@
} }
} }
}, },
"script-loader": {
"version": "0.7.2",
"resolved": "https://registry.npmjs.org/script-loader/-/script-loader-0.7.2.tgz",
"integrity": "sha512-UMNLEvgOAQuzK8ji8qIscM3GIrRCWN6MmMXGD4SD5l6cSycgGsCo0tX5xRnfQcoghqct0tjHjcykgI1PyBE2aA==",
"dev": true,
"requires": {
"raw-loader": "~0.5.1"
}
},
"select-hose": { "select-hose": {
"version": "2.0.0", "version": "2.0.0",
"resolved": "https://registry.npmjs.org/select-hose/-/select-hose-2.0.0.tgz", "resolved": "https://registry.npmjs.org/select-hose/-/select-hose-2.0.0.tgz",

View File

@ -99,6 +99,7 @@
"replace-in-file": "^6.3.2", "replace-in-file": "^6.3.2",
"sass": "^1.50.0", "sass": "^1.50.0",
"sass-loader": "^12.6.0", "sass-loader": "^12.6.0",
"script-loader": "^0.7.2",
"serve": "^13.0.2", "serve": "^13.0.2",
"style-loader": "^3.3.1", "style-loader": "^3.3.1",
"stylelint": "^14.6.1", "stylelint": "^14.6.1",

View File

@ -2,16 +2,14 @@ import { inflate } from 'pako/dist/pako_inflate';
import createWorkerInterface from '../../util/createWorkerInterface'; import createWorkerInterface from '../../util/createWorkerInterface';
import type { CancellableCallback } from '../../util/WorkerConnector'; import type { CancellableCallback } from '../../util/WorkerConnector';
import 'script-loader!./rlottie-wasm';
declare const Module: any; declare const Module: any;
declare function allocate(...args: any[]): string; declare function allocate(...args: any[]): string;
declare function intArrayFromString(str: String): string; declare function intArrayFromString(str: String): string;
declare const self: WorkerGlobalScope;
self.importScripts('rlottie-wasm.js');
let rLottieApi: Record<string, Function>; let rLottieApi: Record<string, Function>;
const rLottieApiPromise = new Promise<void>((resolve) => { const rLottieApiPromise = new Promise<void>((resolve) => {
Module.onRuntimeInitialized = () => { Module.onRuntimeInitialized = () => {

View File

@ -1,5 +1,5 @@
/* eslint-disable */ /* eslint-disable */
importScripts('webp_wasm.js'); import 'script-loader!./webp_wasm';
Module.onRuntimeInitialized = async () => { Module.onRuntimeInitialized = async () => {
self.postMessage({ type: 'initialized' }); self.postMessage({ type: 'initialized' });

View File

@ -1,13 +1,14 @@
import { DEBUG } from './config'; import { DEBUG } from './config';
import { respondForProgressive } from './serviceWorker/progressive'; import { respondForProgressive } from './serviceWorker/progressive';
import { respondForDownload } from './serviceWorker/download'; import { respondForDownload } from './serviceWorker/download';
import { respondWithCache, clearAssetCache } from './serviceWorker/assetCache'; import { respondWithCache, clearAssetCache, respondWithCacheNetworkFirst } from './serviceWorker/assetCache';
import { handlePush, handleNotificationClick, handleClientMessage } from './serviceWorker/pushNotification'; import { handlePush, handleNotificationClick, handleClientMessage } from './serviceWorker/pushNotification';
import { pause } from './util/schedulers'; import { pause } from './util/schedulers';
declare const self: ServiceWorkerGlobalScope; declare const self: ServiceWorkerGlobalScope;
const ASSET_CACHE_PATTERN = /[\da-f]{20}.*\.(js|css|woff2?|svg|png|jpg|jpeg|tgs|json|wasm)$/; const NETWORK_FIRST_ASSETS = new Set(['/', '/rlottie-wasm.wasm', '/webp_wasm.wasm']);
const RE_CACHE_FIRST_ASSETS = /[\da-f]{20}.*\.(js|css|woff2?|svg|png|jpg|jpeg|tgs|json|wasm)$/;
const ACTIVATE_TIMEOUT = 3000; const ACTIVATE_TIMEOUT = 3000;
self.addEventListener('install', (e) => { self.addEventListener('install', (e) => {
@ -52,9 +53,16 @@ self.addEventListener('fetch', (e: FetchEvent) => {
return true; return true;
} }
if (url.startsWith('http') && url.match(ASSET_CACHE_PATTERN)) { if (url.startsWith('http')) {
e.respondWith(respondWithCache(e)); if (NETWORK_FIRST_ASSETS.has(new URL(url).pathname)) {
return true; e.respondWith(respondWithCacheNetworkFirst(e));
return true;
}
if (url.match(RE_CACHE_FIRST_ASSETS)) {
e.respondWith(respondWithCache(e));
return true;
}
} }
return false; return false;

View File

@ -4,7 +4,21 @@ import { pause } from '../util/schedulers';
declare const self: ServiceWorkerGlobalScope; declare const self: ServiceWorkerGlobalScope;
// An attempt to fix freezing UI on iOS // An attempt to fix freezing UI on iOS
const CACHE_TIMEOUT = 3000; const TIMEOUT = 3000;
export async function respondWithCacheNetworkFirst(e: FetchEvent) {
const remote = await withTimeout(() => fetch(e.request), TIMEOUT);
if (!remote?.ok) {
return respondWithCache(e);
}
const toCache = remote.clone();
self.caches.open(ASSET_CACHE_NAME).then((cache) => {
return cache?.put(e.request, toCache);
});
return remote;
}
export async function respondWithCache(e: FetchEvent) { export async function respondWithCache(e: FetchEvent) {
const cacheResult = await withTimeout(async () => { const cacheResult = await withTimeout(async () => {
@ -12,7 +26,7 @@ export async function respondWithCache(e: FetchEvent) {
const cached = await cache.match(e.request); const cached = await cache.match(e.request);
return { cache, cached }; return { cache, cached };
}, CACHE_TIMEOUT); }, TIMEOUT);
const { cache, cached } = cacheResult || {}; const { cache, cached } = cacheResult || {};

View File

@ -129,6 +129,7 @@ module.exports = (_env, { mode = 'production' }) => {
os: require.resolve('os-browserify/browser'), os: require.resolve('os-browserify/browser'),
buffer: require.resolve('buffer/'), buffer: require.resolve('buffer/'),
fs: false, fs: false,
crypto: false,
}, },
}, },