diff --git a/package-lock.json b/package-lock.json index 8d80667f..e2abe904 100644 --- a/package-lock.json +++ b/package-lock.json @@ -63,7 +63,7 @@ "text-encoding": "^0.7.0", "ts-jest": "^28.0.4", "ts-loader": "^9.3.0", - "typescript": "^4.6.4", + "typescript": "^4.7.4", "webpack": "^5.72.0", "webpack-bundle-analyzer": "^4.5.0", "webpack-cli": "^4.9.2", @@ -17670,9 +17670,9 @@ } }, "node_modules/typescript": { - "version": "4.6.4", - "resolved": "https://registry.npmjs.org/typescript/-/typescript-4.6.4.tgz", - "integrity": "sha512-9ia/jWHIEbo49HfjrLGfKbZSuWo9iTMwXO+Ca3pRsSpbsMbc7/IU8NKdCZVRRBafVPGnoJeFL76ZOAA84I9fEg==", + "version": "4.7.4", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-4.7.4.tgz", + "integrity": "sha512-C0WQT0gezHuw6AdY1M2jxUO83Rjf0HP7Sk1DtXj6j1EwkQNZrHAg2XPWlq62oqEhYvONq5pkC2Y9oPljWToLmQ==", "dev": true, "bin": { "tsc": "bin/tsc", @@ -31775,9 +31775,9 @@ } }, "typescript": { - "version": "4.6.4", - "resolved": "https://registry.npmjs.org/typescript/-/typescript-4.6.4.tgz", - "integrity": "sha512-9ia/jWHIEbo49HfjrLGfKbZSuWo9iTMwXO+Ca3pRsSpbsMbc7/IU8NKdCZVRRBafVPGnoJeFL76ZOAA84I9fEg==", + "version": "4.7.4", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-4.7.4.tgz", + "integrity": "sha512-C0WQT0gezHuw6AdY1M2jxUO83Rjf0HP7Sk1DtXj6j1EwkQNZrHAg2XPWlq62oqEhYvONq5pkC2Y9oPljWToLmQ==", "dev": true }, "uglify-js": { diff --git a/package.json b/package.json index 9fb3196b..a7549b4a 100644 --- a/package.json +++ b/package.json @@ -76,7 +76,7 @@ "text-encoding": "^0.7.0", "ts-jest": "^28.0.4", "ts-loader": "^9.3.0", - "typescript": "^4.6.4", + "typescript": "^4.7.4", "webpack": "^5.72.0", "webpack-bundle-analyzer": "^4.5.0", "webpack-cli": "^4.9.2", diff --git a/src/global.d.ts b/src/global.d.ts index 817ce4f1..70a2a119 100644 --- a/src/global.d.ts +++ b/src/global.d.ts @@ -38,7 +38,7 @@ declare global { type FiltersError = 'PINNED_DIALOGS_TOO_MUCH'; 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' | 'SESSION_PASSWORD_NEEDED' | 'CONNECTION_NOT_INITED' | 'ERROR_EMPTY' | 'MTPROTO_CLUSTER_INVALID' | diff --git a/src/lib/mtproto/mtprotoworker.ts b/src/lib/mtproto/mtprotoworker.ts index a7430df2..f3ba26af 100644 --- a/src/lib/mtproto/mtprotoworker.ts +++ b/src/lib/mtproto/mtprotoworker.ts @@ -223,7 +223,7 @@ class ApiManagerProxy extends MTProtoMessagePort { }; iframe.addEventListener('load', onLoad); iframe.addEventListener('error', onLoad); - iframe.src = 'ping/' + (Math.random() * 0xFFFFFFFF); + iframe.src = 'ping/' + (Math.random() * 0xFFFFFFFF | 0); document.body.append(iframe); const timeout = window.setTimeout(onLoad, 1e3); diff --git a/src/lib/mtproto/superMessagePort.ts b/src/lib/mtproto/superMessagePort.ts index db9af8cc..3fa1c605 100644 --- a/src/lib/mtproto/superMessagePort.ts +++ b/src/lib/mtproto/superMessagePort.ts @@ -9,6 +9,7 @@ import ctx from '../../environment/ctx'; import indexOfAndSplice from '../../helpers/array/indexOfAndSplice'; import {IS_WORKER} from '../../helpers/context'; import EventListenerBase from '../../helpers/eventListenerBase'; +import makeError from '../../helpers/makeError'; import {Awaited, WorkerTaskTemplate, WorkerTaskVoidTemplate} from '../../types'; import {logger} from '../logger'; @@ -61,7 +62,12 @@ interface CloseTask extends SuperMessagePortTask { // 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 in Task as type['type']]?: (task: Extract, source: MessageEventSource, event: MessageEvent) => void | Promise }; @@ -133,7 +139,11 @@ export default class SuperMessagePort< this.log = logger('MP' + (logSuffix ? '-' + logSuffix : '')); 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', () => { const task = this.createTask('close', undefined); this.postMessage(undefined, task); @@ -146,8 +156,9 @@ export default class SuperMessagePort< invoke: this.processInvokeTask, ping: this.processPingTask, pong: this.processPongTask, - close: this.processCloseTask - // open: this.processOpenTask + close: this.processCloseTask, + // open: this.processOpenTask, + lock: this.processLockTask }; } @@ -231,7 +242,7 @@ export default class SuperMessagePort< this.onPortDisconnect?.(port as any); - const error = new Error('PORT_DISCONNECTED'); + const error = makeError('PORT_DISCONNECTED'); for(const id in this.awaiting) { const task = this.awaiting[id]; if(task.port === port) { @@ -406,6 +417,12 @@ export default class SuperMessagePort< // 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) => { const id = task.id; const innerTask = task.payload;