Browse Source

Use locks api instead of beforeunload

master
Eduard Kuzmenko 2 years ago
parent
commit
03dc3f34b0
  1. 14
      package-lock.json
  2. 2
      package.json
  3. 2
      src/global.d.ts
  4. 2
      src/lib/mtproto/mtprotoworker.ts
  5. 27
      src/lib/mtproto/superMessagePort.ts

14
package-lock.json generated

@ -63,7 +63,7 @@
"text-encoding": "^0.7.0", "text-encoding": "^0.7.0",
"ts-jest": "^28.0.4", "ts-jest": "^28.0.4",
"ts-loader": "^9.3.0", "ts-loader": "^9.3.0",
"typescript": "^4.6.4", "typescript": "^4.7.4",
"webpack": "^5.72.0", "webpack": "^5.72.0",
"webpack-bundle-analyzer": "^4.5.0", "webpack-bundle-analyzer": "^4.5.0",
"webpack-cli": "^4.9.2", "webpack-cli": "^4.9.2",
@ -17670,9 +17670,9 @@
} }
}, },
"node_modules/typescript": { "node_modules/typescript": {
"version": "4.6.4", "version": "4.7.4",
"resolved": "https://registry.npmjs.org/typescript/-/typescript-4.6.4.tgz", "resolved": "https://registry.npmjs.org/typescript/-/typescript-4.7.4.tgz",
"integrity": "sha512-9ia/jWHIEbo49HfjrLGfKbZSuWo9iTMwXO+Ca3pRsSpbsMbc7/IU8NKdCZVRRBafVPGnoJeFL76ZOAA84I9fEg==", "integrity": "sha512-C0WQT0gezHuw6AdY1M2jxUO83Rjf0HP7Sk1DtXj6j1EwkQNZrHAg2XPWlq62oqEhYvONq5pkC2Y9oPljWToLmQ==",
"dev": true, "dev": true,
"bin": { "bin": {
"tsc": "bin/tsc", "tsc": "bin/tsc",
@ -31775,9 +31775,9 @@
} }
}, },
"typescript": { "typescript": {
"version": "4.6.4", "version": "4.7.4",
"resolved": "https://registry.npmjs.org/typescript/-/typescript-4.6.4.tgz", "resolved": "https://registry.npmjs.org/typescript/-/typescript-4.7.4.tgz",
"integrity": "sha512-9ia/jWHIEbo49HfjrLGfKbZSuWo9iTMwXO+Ca3pRsSpbsMbc7/IU8NKdCZVRRBafVPGnoJeFL76ZOAA84I9fEg==", "integrity": "sha512-C0WQT0gezHuw6AdY1M2jxUO83Rjf0HP7Sk1DtXj6j1EwkQNZrHAg2XPWlq62oqEhYvONq5pkC2Y9oPljWToLmQ==",
"dev": true "dev": true
}, },
"uglify-js": { "uglify-js": {

2
package.json

@ -76,7 +76,7 @@
"text-encoding": "^0.7.0", "text-encoding": "^0.7.0",
"ts-jest": "^28.0.4", "ts-jest": "^28.0.4",
"ts-loader": "^9.3.0", "ts-loader": "^9.3.0",
"typescript": "^4.6.4", "typescript": "^4.7.4",
"webpack": "^5.72.0", "webpack": "^5.72.0",
"webpack-bundle-analyzer": "^4.5.0", "webpack-bundle-analyzer": "^4.5.0",
"webpack-cli": "^4.9.2", "webpack-cli": "^4.9.2",

2
src/global.d.ts vendored

@ -38,7 +38,7 @@ declare global {
type FiltersError = 'PINNED_DIALOGS_TOO_MUCH'; type FiltersError = 'PINNED_DIALOGS_TOO_MUCH';
type LocalFileError = ApiFileManagerError | ReferenceError | StorageError; type LocalFileError = ApiFileManagerError | ReferenceError | StorageError;
type LocalErrorType = LocalFileError | NetworkerError | FiltersError | 'UNKNOWN' | 'NO_DOC' | 'MIDDLEWARE'; type LocalErrorType = LocalFileError | NetworkerError | FiltersError | 'UNKNOWN' | 'NO_DOC' | 'MIDDLEWARE' | 'PORT_DISCONNECTED';
type ServerErrorType = 'FILE_REFERENCE_EXPIRED' | 'SESSION_REVOKED' | 'AUTH_KEY_DUPLICATED' | type ServerErrorType = 'FILE_REFERENCE_EXPIRED' | 'SESSION_REVOKED' | 'AUTH_KEY_DUPLICATED' |
'SESSION_PASSWORD_NEEDED' | 'CONNECTION_NOT_INITED' | 'ERROR_EMPTY' | 'MTPROTO_CLUSTER_INVALID' | 'SESSION_PASSWORD_NEEDED' | 'CONNECTION_NOT_INITED' | 'ERROR_EMPTY' | 'MTPROTO_CLUSTER_INVALID' |

2
src/lib/mtproto/mtprotoworker.ts

@ -223,7 +223,7 @@ class ApiManagerProxy extends MTProtoMessagePort {
}; };
iframe.addEventListener('load', onLoad); iframe.addEventListener('load', onLoad);
iframe.addEventListener('error', onLoad); iframe.addEventListener('error', onLoad);
iframe.src = 'ping/' + (Math.random() * 0xFFFFFFFF); iframe.src = 'ping/' + (Math.random() * 0xFFFFFFFF | 0);
document.body.append(iframe); document.body.append(iframe);
const timeout = window.setTimeout(onLoad, 1e3); const timeout = window.setTimeout(onLoad, 1e3);

27
src/lib/mtproto/superMessagePort.ts

@ -9,6 +9,7 @@ import ctx from '../../environment/ctx';
import indexOfAndSplice from '../../helpers/array/indexOfAndSplice'; import indexOfAndSplice from '../../helpers/array/indexOfAndSplice';
import {IS_WORKER} from '../../helpers/context'; import {IS_WORKER} from '../../helpers/context';
import EventListenerBase from '../../helpers/eventListenerBase'; import EventListenerBase from '../../helpers/eventListenerBase';
import makeError from '../../helpers/makeError';
import {Awaited, WorkerTaskTemplate, WorkerTaskVoidTemplate} from '../../types'; import {Awaited, WorkerTaskTemplate, WorkerTaskVoidTemplate} from '../../types';
import {logger} from '../logger'; import {logger} from '../logger';
@ -61,7 +62,12 @@ interface CloseTask extends SuperMessagePortTask {
// type: 'open' // type: 'open'
// } // }
type Task = InvokeTask | ResultTask | AckTask | PingTask | PongTask | BatchTask | CloseTask/* | OpenTask */; interface LockTask extends SuperMessagePortTask {
type: 'lock',
payload: string
}
type Task = InvokeTask | ResultTask | AckTask | PingTask | PongTask | BatchTask | CloseTask/* | OpenTask */ | LockTask;
type TaskMap = { type TaskMap = {
[type in Task as type['type']]?: (task: Extract<Task, type>, source: MessageEventSource, event: MessageEvent<any>) => void | Promise<any> [type in Task as type['type']]?: (task: Extract<Task, type>, source: MessageEventSource, event: MessageEvent<any>) => void | Promise<any>
}; };
@ -133,7 +139,11 @@ export default class SuperMessagePort<
this.log = logger('MP' + (logSuffix ? '-' + logSuffix : '')); this.log = logger('MP' + (logSuffix ? '-' + logSuffix : ''));
this.debug = DEBUG; this.debug = DEBUG;
if(typeof(window) !== 'undefined') { if('locks' in navigator) {
const id = 'lock-' + Date.now() + (Math.random() * 0xFFFF | 0);
navigator.locks.request(id, () => new Promise(() => {}));
this.pushTask(this.createTask('lock', id));
} else if(typeof(window) !== 'undefined') {
window.addEventListener('beforeunload', () => { window.addEventListener('beforeunload', () => {
const task = this.createTask('close', undefined); const task = this.createTask('close', undefined);
this.postMessage(undefined, task); this.postMessage(undefined, task);
@ -146,8 +156,9 @@ export default class SuperMessagePort<
invoke: this.processInvokeTask, invoke: this.processInvokeTask,
ping: this.processPingTask, ping: this.processPingTask,
pong: this.processPongTask, pong: this.processPongTask,
close: this.processCloseTask close: this.processCloseTask,
// open: this.processOpenTask // open: this.processOpenTask,
lock: this.processLockTask
}; };
} }
@ -231,7 +242,7 @@ export default class SuperMessagePort<
this.onPortDisconnect?.(port as any); this.onPortDisconnect?.(port as any);
const error = new Error('PORT_DISCONNECTED'); const error = makeError('PORT_DISCONNECTED');
for(const id in this.awaiting) { for(const id in this.awaiting) {
const task = this.awaiting[id]; const task = this.awaiting[id];
if(task.port === port) { if(task.port === port) {
@ -406,6 +417,12 @@ export default class SuperMessagePort<
// this.onPortConnect?.(source); // this.onPortConnect?.(source);
// }; // };
protected processLockTask = (task: LockTask, source: MessageEventSource, event: MessageEvent) => {
navigator.locks.request(task.payload, () => {
this.processCloseTask(undefined, source, undefined);
});
};
protected processInvokeTask = async(task: InvokeTask, source: MessageEventSource, event: MessageEvent) => { protected processInvokeTask = async(task: InvokeTask, source: MessageEventSource, event: MessageEvent) => {
const id = task.id; const id = task.id;
const innerTask = task.payload; const innerTask = task.payload;

Loading…
Cancel
Save