Browse Source

Moved MTProto from web worker to service worker

master
morethanwords 4 years ago
parent
commit
dad42da803
  1. 94
      package-lock.json
  2. 2
      package.json
  3. 89
      src/lib/mtproto/mtproto.service.ts
  4. 61
      src/lib/mtproto/mtprotoworker.ts
  5. 33
      src/lib/storage.ts
  6. 2
      src/pages/pageIm.ts
  7. 4
      tsconfig.json
  8. 6
      webpack.common.js

94
package-lock.json generated

@ -3026,6 +3026,12 @@
"integrity": "sha512-SDSGgXT3LRCH6qMWk8OHT1vLSVNuHNvCpKCx2/TYtQMbMGGgxJC9fspwSkQjqzRagrWnCrxuLL3jMNXLXHHvSw==", "integrity": "sha512-SDSGgXT3LRCH6qMWk8OHT1vLSVNuHNvCpKCx2/TYtQMbMGGgxJC9fspwSkQjqzRagrWnCrxuLL3jMNXLXHHvSw==",
"dev": true "dev": true
}, },
"@types/anymatch": {
"version": "1.3.1",
"resolved": "https://registry.npmjs.org/@types/anymatch/-/anymatch-1.3.1.tgz",
"integrity": "sha512-/+CRPXpBDpo2RK9C68N3b2cOvO0Cf5B9aPijHsoDQTHivnGSObdOF2BRQOYjojWTDy6nQvMjmqRXIxH55VjxxA==",
"dev": true
},
"@types/asn1js": { "@types/asn1js": {
"version": "0.0.1", "version": "0.0.1",
"resolved": "https://registry.npmjs.org/@types/asn1js/-/asn1js-0.0.1.tgz", "resolved": "https://registry.npmjs.org/@types/asn1js/-/asn1js-0.0.1.tgz",
@ -3186,12 +3192,91 @@
"integrity": "sha512-1HcDas8SEj4z1Wc696tH56G8OlRaH/sqZOynNNB+HF0WOeXPaxTtbYzJY2oEfiUxjSKjhCKr+MvR7dCHcEelug==", "integrity": "sha512-1HcDas8SEj4z1Wc696tH56G8OlRaH/sqZOynNNB+HF0WOeXPaxTtbYzJY2oEfiUxjSKjhCKr+MvR7dCHcEelug==",
"dev": true "dev": true
}, },
"@types/serviceworker-webpack-plugin": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/@types/serviceworker-webpack-plugin/-/serviceworker-webpack-plugin-1.0.1.tgz",
"integrity": "sha512-NBLpxauF9s0dG+g3KFRo7iQwEuSa9E9Sn+SG/4SxECVOIG/0JBIK3Qc4b+81vH3/1dXJqMfm1JFh8vVsgp5/Dw==",
"dev": true,
"requires": {
"@types/webpack": "*"
}
},
"@types/source-list-map": {
"version": "0.1.2",
"resolved": "https://registry.npmjs.org/@types/source-list-map/-/source-list-map-0.1.2.tgz",
"integrity": "sha512-K5K+yml8LTo9bWJI/rECfIPrGgxdpeNbj+d53lwN4QjW1MCwlkhUms+gtdzigTeUyBr09+u8BwOIY3MXvHdcsA==",
"dev": true
},
"@types/stack-utils": { "@types/stack-utils": {
"version": "1.0.1", "version": "1.0.1",
"resolved": "https://registry.npmjs.org/@types/stack-utils/-/stack-utils-1.0.1.tgz", "resolved": "https://registry.npmjs.org/@types/stack-utils/-/stack-utils-1.0.1.tgz",
"integrity": "sha512-l42BggppR6zLmpfU6fq9HEa2oGPEI8yrSPL3GITjfRInppYFahObbIQOQK3UGxEnyQpltZLaPe75046NOZQikw==", "integrity": "sha512-l42BggppR6zLmpfU6fq9HEa2oGPEI8yrSPL3GITjfRInppYFahObbIQOQK3UGxEnyQpltZLaPe75046NOZQikw==",
"dev": true "dev": true
}, },
"@types/tapable": {
"version": "1.0.6",
"resolved": "https://registry.npmjs.org/@types/tapable/-/tapable-1.0.6.tgz",
"integrity": "sha512-W+bw9ds02rAQaMvaLYxAbJ6cvguW/iJXNT6lTssS1ps6QdrMKttqEAMEG/b5CR8TZl3/L7/lH0ZV5nNR1LXikA==",
"dev": true
},
"@types/uglify-js": {
"version": "3.9.3",
"resolved": "https://registry.npmjs.org/@types/uglify-js/-/uglify-js-3.9.3.tgz",
"integrity": "sha512-KswB5C7Kwduwjj04Ykz+AjvPcfgv/37Za24O2EDzYNbwyzOo8+ydtvzUfZ5UMguiVu29Gx44l1A6VsPPcmYu9w==",
"dev": true,
"requires": {
"source-map": "^0.6.1"
},
"dependencies": {
"source-map": {
"version": "0.6.1",
"resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz",
"integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==",
"dev": true
}
}
},
"@types/webpack": {
"version": "4.41.21",
"resolved": "https://registry.npmjs.org/@types/webpack/-/webpack-4.41.21.tgz",
"integrity": "sha512-2j9WVnNrr/8PLAB5csW44xzQSJwS26aOnICsP3pSGCEdsu6KYtfQ6QJsVUKHWRnm1bL7HziJsfh5fHqth87yKA==",
"dev": true,
"requires": {
"@types/anymatch": "*",
"@types/node": "*",
"@types/tapable": "*",
"@types/uglify-js": "*",
"@types/webpack-sources": "*",
"source-map": "^0.6.0"
},
"dependencies": {
"source-map": {
"version": "0.6.1",
"resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz",
"integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==",
"dev": true
}
}
},
"@types/webpack-sources": {
"version": "1.4.2",
"resolved": "https://registry.npmjs.org/@types/webpack-sources/-/webpack-sources-1.4.2.tgz",
"integrity": "sha512-77T++JyKow4BQB/m9O96n9d/UUHWLQHlcqXb9Vsf4F1+wKNrrlWNFPDLKNT92RJnCSL6CieTc+NDXtCVZswdTw==",
"dev": true,
"requires": {
"@types/node": "*",
"@types/source-list-map": "*",
"source-map": "^0.7.3"
},
"dependencies": {
"source-map": {
"version": "0.7.3",
"resolved": "https://registry.npmjs.org/source-map/-/source-map-0.7.3.tgz",
"integrity": "sha512-CkCj6giN3S+n9qrYiBTX5gystlENnRW5jZeNLHpe6aue+SrHcG5VYwujhW9s4dY31mEGsxBDrHR6oI69fTXsaQ==",
"dev": true
}
}
},
"@types/yargs": { "@types/yargs": {
"version": "13.0.5", "version": "13.0.5",
"resolved": "https://registry.npmjs.org/@types/yargs/-/yargs-13.0.5.tgz", "resolved": "https://registry.npmjs.org/@types/yargs/-/yargs-13.0.5.tgz",
@ -16064,6 +16149,15 @@
"send": "0.17.1" "send": "0.17.1"
} }
}, },
"serviceworker-webpack-plugin": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/serviceworker-webpack-plugin/-/serviceworker-webpack-plugin-1.0.1.tgz",
"integrity": "sha512-VgDEkZ3pA0HajsRaWtl5w6bLxAXx0Y+4dm7YeTcIxVmvC9YXvstex38HOBDuYETeDS5fUlBy/47gC0QYBrG0nw==",
"dev": true,
"requires": {
"minimatch": "^3.0.4"
}
},
"set-blocking": { "set-blocking": {
"version": "2.0.0", "version": "2.0.0",
"resolved": "https://registry.npmjs.org/set-blocking/-/set-blocking-2.0.0.tgz", "resolved": "https://registry.npmjs.org/set-blocking/-/set-blocking-2.0.0.tgz",

2
package.json

@ -30,6 +30,7 @@
"@types/chrome": "0.0.91", "@types/chrome": "0.0.91",
"@types/jest": "^24.9.1", "@types/jest": "^24.9.1",
"@types/puppeteer": "^3.0.1", "@types/puppeteer": "^3.0.1",
"@types/serviceworker-webpack-plugin": "^1.0.1",
"aes-js": "^3.1.2", "aes-js": "^3.1.2",
"autoprefixer": "^9.8.0", "autoprefixer": "^9.8.0",
"babel-jest": "^24.9.0", "babel-jest": "^24.9.0",
@ -61,6 +62,7 @@
"qr-code-styling": "^1.0.1", "qr-code-styling": "^1.0.1",
"resolve-url-loader": "^3.1.1", "resolve-url-loader": "^3.1.1",
"sass-loader": "^8.0.2", "sass-loader": "^8.0.2",
"serviceworker-webpack-plugin": "^1.0.1",
"streamsaver": "^2.0.4", "streamsaver": "^2.0.4",
"style-loader": "^1.2.1", "style-loader": "^1.2.1",
"terser-webpack-plugin": "^3.0.2", "terser-webpack-plugin": "^3.0.2",

89
src/lib/mtproto/mtproto.worker.js → src/lib/mtproto/mtproto.service.ts

@ -7,8 +7,7 @@ import AppStorage from '../storage';
import cryptoWorker from "../crypto/cryptoworker"; import cryptoWorker from "../crypto/cryptoworker";
import networkerFactory from "./networkerFactory"; import networkerFactory from "./networkerFactory";
//const ctx: Worker = self as any; const ctx = self as any as ServiceWorkerGlobalScope;
const ctx = self;
//console.error('INCLUDE !!!', new Error().stack); //console.error('INCLUDE !!!', new Error().stack);
@ -25,8 +24,8 @@ const ctx = self;
* let the calling scope pass in the global scope object. * let the calling scope pass in the global scope object.
* @returns {boolean} * @returns {boolean}
*/ */
var _isSafari = null; var _isSafari: boolean = null;
function isSafari(scope) { function isSafari(scope: any) {
if(_isSafari == null) { if(_isSafari == null) {
var userAgent = scope.navigator ? scope.navigator.userAgent : null; var userAgent = scope.navigator ? scope.navigator.userAgent : null;
_isSafari = !!scope.safari || _isSafari = !!scope.safari ||
@ -35,11 +34,11 @@ function isSafari(scope) {
return _isSafari; return _isSafari;
} }
function isObject(object) { function isObject(object: any) {
return typeof(object) === 'object' && object !== null; return typeof(object) === 'object' && object !== null;
} }
function fillTransfer(transfer, obj) { function fillTransfer(transfer: any, obj: any) {
if(!obj) return; if(!obj) return;
if(obj instanceof ArrayBuffer) { if(obj instanceof ArrayBuffer) {
@ -57,10 +56,14 @@ function fillTransfer(transfer, obj) {
} }
} }
function reply() { /**
* Respond to request
*/
function respond(client: Client | ServiceWorker | MessagePort, ...args: any[]) {
// отключил для всего потому что не успел пофиксить transfer detached // отключил для всего потому что не успел пофиксить transfer detached
//if(isSafari(self)/* || true */) { //if(isSafari(self)/* || true */) {
ctx.postMessage(...arguments); // @ts-ignore
client.postMessage(...args);
/* } else { /* } else {
var transfer = new Set(); var transfer = new Set();
fillTransfer(transfer, arguments); fillTransfer(transfer, arguments);
@ -72,12 +75,24 @@ function reply() {
} }
networkerFactory.setUpdatesProcessor((obj, bool) => { networkerFactory.setUpdatesProcessor((obj, bool) => {
//console.log('updatesss');
//ctx.postMessage({update: {obj, bool}}); //ctx.postMessage({update: {obj, bool}});
reply({update: {obj, bool}}); //respond({update: {obj, bool}});
ctx.clients.matchAll({ includeUncontrolled: false, type: 'window' }).then((listeners) => {
if(!listeners.length) {
//console.trace('no listeners?', self, listeners);
return;
}
listeners[0].postMessage({update: {obj, bool}});
});
}); });
ctx.onmessage = function(e) { ctx.addEventListener('message', async(e) => {
var taskID = e.data.taskID; const taskID = e.data.taskID;
console.log('[SW] Got message:', taskID, e, e.data);
if(e.data.useLs) { if(e.data.useLs) {
AppStorage.finishTask(e.data.taskID, e.data.args); AppStorage.finishTask(e.data.taskID, e.data.args);
@ -87,36 +102,52 @@ ctx.onmessage = function(e) {
switch(e.data.task) { switch(e.data.task) {
case 'computeSRP': case 'computeSRP':
case 'gzipUncompress': case 'gzipUncompress':
// @ts-ignore
return cryptoWorker[e.data.task].apply(cryptoWorker, e.data.args).then(result => { return cryptoWorker[e.data.task].apply(cryptoWorker, e.data.args).then(result => {
//ctx.postMessage({taskID: taskID, result: result}); respond(e.source, {taskID: taskID, result: result});
reply({taskID: taskID, result: result});
}); });
default: { default: {
try { try {
// @ts-ignore
let result = apiManager[e.data.task].apply(apiManager, e.data.args); let result = apiManager[e.data.task].apply(apiManager, e.data.args);
if(result instanceof Promise) { if(result instanceof Promise) {
result.then(result => { result = await result;
//console.log(e.data.task + ' result:', result, taskID);
reply({taskID: taskID, result: result});
//ctx.postMessage({taskID: taskID, result: result});
}).catch(err => {
//console.error(e.data.task + ' err:', err, taskID);
//ctx.postMessage({taskID: taskID, error: err});
reply({taskID: taskID, error: err});
});
} else {
//ctx.postMessage({taskID: taskID, result: result});
reply({taskID: taskID, result: result});
} }
respond(e.source, {taskID: taskID, result: result});
} catch(err) { } catch(err) {
reply({taskID: taskID, error: err}); respond(e.source, {taskID: taskID, error: err});
//ctx.postMessage({taskID: taskID, error: err});
} }
//throw new Error('Unknown task: ' + e.data.task); //throw new Error('Unknown task: ' + e.data.task);
} }
} }
} });
ctx.postMessage('ready'); /**
* Service Worker Installation
*/
ctx.addEventListener('install', (event: ExtendableEvent) => {
//console.log('service worker is installing');
/* initCache();
event.waitUntil(
initNetwork(),
); */
event.waitUntil(ctx.skipWaiting()); // Activate worker immediately
});
/**
* Service Worker Activation
*/
ctx.addEventListener('activate', (event) => {
//console.log('service worker activating', ctx);
/* if (!ctx.cache) initCache();
if (!ctx.network) initNetwork(); */
event.waitUntil(ctx.clients.claim());
});

61
src/lib/mtproto/mtprotoworker.ts

@ -1,6 +1,7 @@
import {dT, isObject, $rootScope} from '../utils'; import {dT, isObject, $rootScope} from '../utils';
import AppStorage from '../storage'; import AppStorage from '../storage';
import CryptoWorkerMethods from '../crypto/crypto_methods'; import CryptoWorkerMethods from '../crypto/crypto_methods';
import runtime from 'serviceworker-webpack-plugin/lib/runtime';
type Task = { type Task = {
taskID: number, taskID: number,
@ -8,8 +9,15 @@ type Task = {
args: any[] args: any[]
}; };
/* let pending: any[] = [];
function resendPending() {
if(navigator.serviceWorker.controller) {
for(let i = 0; i < pending.length; i++) navigator.serviceWorker.controller.postMessage(pending[i]);
pending = [];
}
} */
class ApiManagerProxy extends CryptoWorkerMethods { class ApiManagerProxy extends CryptoWorkerMethods {
private webWorker: Worker | boolean = false;
private taskID = 0; private taskID = 0;
private awaiting: { private awaiting: {
[id: number]: { [id: number]: {
@ -27,8 +35,49 @@ class ApiManagerProxy extends CryptoWorkerMethods {
super(); super();
console.log(dT(), 'ApiManagerProxy constructor'); console.log(dT(), 'ApiManagerProxy constructor');
if(window.Worker) { /**
import('./mtproto.worker.js').then((worker: any) => { * Service worker
*/
runtime.register({ scope: '/' });
navigator.serviceWorker.ready.then((registration) => {
console.info(dT(), 'ApiManagerProxy set SW');
this.releasePending();
});
navigator.serviceWorker.oncontrollerchange = () => {
console.error('oncontrollerchange');
this.releasePending();
navigator.serviceWorker.controller.addEventListener('error', (e) => {
console.error('controller error:', e);
});
};
/**
* Message resolver
*/
navigator.serviceWorker.addEventListener('message', (e) => {
if(!isObject(e.data)) {
return;
}
if(e.data.useLs) {
// @ts-ignore
AppStorage[e.data.task](...e.data.args).then(res => {
navigator.serviceWorker.controller.postMessage({useLs: true, taskID: e.data.taskID, args: res});
});
} else if(e.data.update) {
if(this.updatesProcessor) {
this.updatesProcessor(e.data.update.obj, e.data.update.bool);
}
} else {
this.finalizeTask(e.data.taskID, e.data.result, e.data.error);
}
});
/* if(window.Worker) {
import('./mtproto_service.js').then((worker: any) => {
var tmpWorker = new worker.default(); var tmpWorker = new worker.default();
tmpWorker.onmessage = (e: any) => { tmpWorker.onmessage = (e: any) => {
if(!this.webWorker) { if(!this.webWorker) {
@ -60,7 +109,7 @@ class ApiManagerProxy extends CryptoWorkerMethods {
this.webWorker = false; this.webWorker = false;
}; };
}); });
} } */
} }
private finalizeTask(taskID: number, result: any, error: any) { private finalizeTask(taskID: number, result: any, error: any) {
@ -93,9 +142,9 @@ class ApiManagerProxy extends CryptoWorkerMethods {
} }
private releasePending() { private releasePending() {
if(this.webWorker) { if(navigator.serviceWorker.controller) {
this.pending.forEach(pending => { this.pending.forEach(pending => {
(this.webWorker as Worker).postMessage(pending); navigator.serviceWorker.controller.postMessage(pending);
}); });
this.pending.length = 0; this.pending.length = 0;

33
src/lib/storage.ts

@ -142,6 +142,8 @@ class AppStorage {
private isWebWorker: boolean; private isWebWorker: boolean;
private taskID = 0; private taskID = 0;
private tasks: {[taskID: number]: (result: any) => void} = {}; private tasks: {[taskID: number]: (result: any) => void} = {};
//private log = (...args: any[]) => console.log('[SW LS]', ...args);
private log = (...args: any[]) => {};
constructor() { constructor() {
if(Modes.test) { if(Modes.test) {
@ -149,7 +151,8 @@ class AppStorage {
} }
// @ts-ignore // @ts-ignore
this.isWebWorker = typeof WorkerGlobalScope !== 'undefined' && self instanceof WorkerGlobalScope; //this.isWebWorker = typeof WorkerGlobalScope !== 'undefined' && self instanceof WorkerGlobalScope;
this.isWebWorker = typeof ServiceWorkerGlobalScope !== 'undefined' && self instanceof ServiceWorkerGlobalScope;
} }
public setPrefix(newPrefix: string) { public setPrefix(newPrefix: string) {
@ -161,6 +164,13 @@ class AppStorage {
} }
public finishTask(taskID: number, result: any) { public finishTask(taskID: number, result: any) {
this.log('finishTask:', taskID, result, Object.keys(this.tasks));
if(!this.tasks.hasOwnProperty(taskID)) {
this.log('no such task:', taskID, result);
return;
}
this.tasks[taskID](result); this.tasks[taskID](result);
delete this.tasks[taskID]; delete this.tasks[taskID];
} }
@ -168,10 +178,25 @@ class AppStorage {
private proxy<T>(methodName: string, ..._args: any[]) { private proxy<T>(methodName: string, ..._args: any[]) {
return new Promise<T>((resolve, reject) => { return new Promise<T>((resolve, reject) => {
if(this.isWebWorker) { if(this.isWebWorker) {
this.tasks[this.taskID] = resolve; const taskID = this.taskID++;
this.tasks[taskID] = resolve;
(self as any as ServiceWorkerGlobalScope)
.clients
.matchAll({ includeUncontrolled: false, type: 'window' })
.then((listeners) => {
if(!listeners.length) {
//console.trace('no listeners?', self, listeners);
return;
}
this.log('will proxy', {useLs: true, task: methodName, taskID, args: _args});
listeners[0].postMessage({useLs: true, task: methodName, taskID, args: _args});
});
// @ts-ignore // @ts-ignore
self.postMessage({useLs: true, task: methodName, taskID: this.taskID, args: _args}); //self.postMessage({useLs: true, task: methodName, taskID: this.taskID, args: _args});
this.taskID++;
} else { } else {
let args = Array.prototype.slice.call(_args); let args = Array.prototype.slice.call(_args);
args.push((result: T) => { args.push((result: T) => {

2
src/pages/pageIm.ts

@ -29,7 +29,7 @@ let onFirstMount = () => {
//(Array.from(document.getElementsByClassName('rp')) as HTMLElement[]).forEach(el => ripple(el)); //(Array.from(document.getElementsByClassName('rp')) as HTMLElement[]).forEach(el => ripple(el));
Array.from(document.getElementsByClassName('btn-menu-toggle')).forEach((el) => { Array.from(document.getElementsByClassName('btn-menu-toggle')).forEach((el) => {
el.addEventListener('click', (e) => { (el as HTMLElement).addEventListener('click', (e) => {
//console.log('click pageIm'); //console.log('click pageIm');
if(!el.classList.contains('btn-menu-toggle')) return false; if(!el.classList.contains('btn-menu-toggle')) return false;

4
tsconfig.json

@ -5,7 +5,7 @@
//"target": "es5", /* Specify ECMAScript target version: 'ES3' (default), 'ES5', 'ES2015', 'ES2016', 'ES2017', 'ES2018', 'ES2019' or 'ESNEXT'. */ //"target": "es5", /* Specify ECMAScript target version: 'ES3' (default), 'ES5', 'ES2015', 'ES2016', 'ES2017', 'ES2018', 'ES2019' or 'ESNEXT'. */
"target": "es2016", /* Specify ECMAScript target version: 'ES3' (default), 'ES5', 'ES2015', 'ES2016', 'ES2017', 'ES2018', 'ES2019' or 'ESNEXT'. */ "target": "es2016", /* Specify ECMAScript target version: 'ES3' (default), 'ES5', 'ES2015', 'ES2016', 'ES2017', 'ES2018', 'ES2019' or 'ESNEXT'. */
"module": "commonjs", /* Specify module code generation: 'none', 'commonjs', 'amd', 'system', 'umd', 'es2015', or 'ESNext'. */ "module": "commonjs", /* Specify module code generation: 'none', 'commonjs', 'amd', 'system', 'umd', 'es2015', or 'ESNext'. */
"lib": ["es2016", "dom", "ES2018.Promise"], /* Specify library files to be included in the compilation. */ "lib": ["es2016", "dom", "ES2018.Promise", "webworker"], /* Specify library files to be included in the compilation. */
"allowJs": true, /* Allow javascript files to be compiled. */ "allowJs": true, /* Allow javascript files to be compiled. */
// "checkJs": true, /* Report errors in .js files. */ // "checkJs": true, /* Report errors in .js files. */
// "jsx": "preserve", /* Specify JSX code generation: 'preserve', 'react-native', or 'react'. */ // "jsx": "preserve", /* Specify JSX code generation: 'preserve', 'react-native', or 'react'. */
@ -40,7 +40,7 @@
// "noFallthroughCasesInSwitch": true, /* Report errors for fallthrough cases in switch statement. */ // "noFallthroughCasesInSwitch": true, /* Report errors for fallthrough cases in switch statement. */
/* Module Resolution Options */ /* Module Resolution Options */
// "moduleResolution": "node", /* Specify module resolution strategy: 'node' (Node.js) or 'classic' (TypeScript pre-1.6). */ "moduleResolution": "node", /* Specify module resolution strategy: 'node' (Node.js) or 'classic' (TypeScript pre-1.6). */
// "baseUrl": "./", /* Base directory to resolve non-absolute module names. */ // "baseUrl": "./", /* Base directory to resolve non-absolute module names. */
// "paths": {}, /* A series of entries which re-map imports to lookup locations relative to the 'baseUrl'. */ // "paths": {}, /* A series of entries which re-map imports to lookup locations relative to the 'baseUrl'. */
// "rootDirs": [], /* List of root folders whose combined content represents the structure of the project at runtime. */ // "rootDirs": [], /* List of root folders whose combined content represents the structure of the project at runtime. */

6
webpack.common.js

@ -3,6 +3,7 @@ const HtmlWebpackPlugin = require('html-webpack-plugin');
const MediaQueryPlugin = require('media-query-plugin'); const MediaQueryPlugin = require('media-query-plugin');
const MiniCssExtractPlugin = require('mini-css-extract-plugin'); const MiniCssExtractPlugin = require('mini-css-extract-plugin');
const postcssPresetEnv = require('postcss-preset-env'); const postcssPresetEnv = require('postcss-preset-env');
const ServiceWorkerWebpackPlugin = require('serviceworker-webpack-plugin');
const fs = require('fs'); const fs = require('fs');
const allowedIPs = ['195.66.140.39', '192.168.31.144', '127.0.0.1', '192.168.31.1', '192.168.31.192', '176.100.18.181']; const allowedIPs = ['195.66.140.39', '192.168.31.144', '127.0.0.1', '192.168.31.1', '192.168.31.192', '176.100.18.181'];
@ -165,6 +166,11 @@ module.exports = {
sockHost: useLocal ? undefined : 'tweb.enko.club', sockHost: useLocal ? undefined : 'tweb.enko.club',
}, },
plugins: [ plugins: [
new ServiceWorkerWebpackPlugin({
entry: path.join(__dirname, 'src/lib/mtproto/mtproto.service.ts'),
filename: 'sw.js',
excludes: ['**/*'],
}),
new HtmlWebpackPlugin({ new HtmlWebpackPlugin({
filename: `index.html`, filename: `index.html`,
//template: 'public/index_template.html', //template: 'public/index_template.html',

Loading…
Cancel
Save