Change pako to fflate (#6699)
This commit is contained in:
parent
03f163e528
commit
be036138c3
@ -39,7 +39,7 @@ await invoke(new GramJs.help.GetAppConfig())
|
|||||||
|
|
||||||
### Dependencies
|
### Dependencies
|
||||||
* [GramJS](https://github.com/gram-js/gramjs) ([MIT License](https://github.com/gram-js/gramjs/blob/master/LICENSE))
|
* [GramJS](https://github.com/gram-js/gramjs) ([MIT License](https://github.com/gram-js/gramjs/blob/master/LICENSE))
|
||||||
* [pako](https://github.com/nodeca/pako) ([MIT License](https://github.com/nodeca/pako/blob/master/LICENSE))
|
* [fflate](https://github.com/101arrowz/fflate) ([MIT License](https://github.com/101arrowz/fflate/blob/master/LICENSE))
|
||||||
* [cryptography](https://github.com/spalt08/cryptography) ([Apache License 2.0](https://github.com/spalt08/cryptography/blob/master/LICENSE))
|
* [cryptography](https://github.com/spalt08/cryptography) ([Apache License 2.0](https://github.com/spalt08/cryptography/blob/master/LICENSE))
|
||||||
* [emoji-data](https://github.com/iamcal/emoji-data) ([MIT License](https://github.com/iamcal/emoji-data/blob/master/LICENSE))
|
* [emoji-data](https://github.com/iamcal/emoji-data) ([MIT License](https://github.com/iamcal/emoji-data/blob/master/LICENSE))
|
||||||
* [twemoji-parser](https://github.com/twitter/twemoji-parser) ([MIT License](https://github.com/twitter/twemoji-parser/blob/master/LICENSE.md))
|
* [twemoji-parser](https://github.com/twitter/twemoji-parser) ([MIT License](https://github.com/twitter/twemoji-parser/blob/master/LICENSE.md))
|
||||||
|
|||||||
15
package-lock.json
generated
15
package-lock.json
generated
@ -18,12 +18,12 @@
|
|||||||
"@tauri-apps/plugin-updater": "^2.9.0",
|
"@tauri-apps/plugin-updater": "^2.9.0",
|
||||||
"async-mutex": "^0.5.0",
|
"async-mutex": "^0.5.0",
|
||||||
"emoji-data-ios": "git+https://github.com/korenskoy/emoji-data-ios#443f1c9",
|
"emoji-data-ios": "git+https://github.com/korenskoy/emoji-data-ios#443f1c9",
|
||||||
|
"fflate": "^0.8.2",
|
||||||
"idb-keyval": "^6.2.2",
|
"idb-keyval": "^6.2.2",
|
||||||
"lowlight": "^3.3.0",
|
"lowlight": "^3.3.0",
|
||||||
"music-metadata": "^11.11.1",
|
"music-metadata": "^11.11.1",
|
||||||
"opus-recorder": "github:Ajaxy/opus-recorder#116830a",
|
"opus-recorder": "github:Ajaxy/opus-recorder#116830a",
|
||||||
"os-browserify": "^0.3.0",
|
"os-browserify": "^0.3.0",
|
||||||
"pako": "^2.1.0",
|
|
||||||
"path-browserify": "^1.0.1",
|
"path-browserify": "^1.0.1",
|
||||||
"qr-code-styling": "^1.9.2"
|
"qr-code-styling": "^1.9.2"
|
||||||
},
|
},
|
||||||
@ -3213,9 +3213,9 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/@isaacs/brace-expansion": {
|
"node_modules/@isaacs/brace-expansion": {
|
||||||
"version": "5.0.0",
|
"version": "5.0.1",
|
||||||
"resolved": "https://registry.npmjs.org/@isaacs/brace-expansion/-/brace-expansion-5.0.0.tgz",
|
"resolved": "https://registry.npmjs.org/@isaacs/brace-expansion/-/brace-expansion-5.0.1.tgz",
|
||||||
"integrity": "sha512-ZT55BDLV0yv0RBm2czMiZ+SqCGO7AvmOM3G/w2xhVPH+te0aKgFjmBvGlL1dH+ql2tgGO3MVrbb3jCKyvpgnxA==",
|
"integrity": "sha512-WMz71T1JS624nWj2n2fnYAuPovhv7EUhk69R6i9dsVyzxt5eM3bjwvgk9L+APE1TRscGysAVMANkB0jh0LQZrQ==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
@ -11753,6 +11753,12 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/fflate": {
|
||||||
|
"version": "0.8.2",
|
||||||
|
"resolved": "https://registry.npmjs.org/fflate/-/fflate-0.8.2.tgz",
|
||||||
|
"integrity": "sha512-cPJU47OaAoCbg0pBvzsgpTPhmhqI5eJjh/JIu8tPj5q+T7iLvW/JAYUqmE7KOB4R1ZyEhzBaIQpQpardBF5z8A==",
|
||||||
|
"license": "MIT"
|
||||||
|
},
|
||||||
"node_modules/file-entry-cache": {
|
"node_modules/file-entry-cache": {
|
||||||
"version": "8.0.0",
|
"version": "8.0.0",
|
||||||
"resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-8.0.0.tgz",
|
"resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-8.0.0.tgz",
|
||||||
@ -16264,6 +16270,7 @@
|
|||||||
"version": "2.1.0",
|
"version": "2.1.0",
|
||||||
"resolved": "https://registry.npmjs.org/pako/-/pako-2.1.0.tgz",
|
"resolved": "https://registry.npmjs.org/pako/-/pako-2.1.0.tgz",
|
||||||
"integrity": "sha512-w+eufiZ1WuJYgPXbV/PO3NCMEc3xqylkKHzp8bxp1uW4qaSNQUkwmLLEc3kKsfz8lpV1F8Ht3U1Cm+9Srog2ug==",
|
"integrity": "sha512-w+eufiZ1WuJYgPXbV/PO3NCMEc3xqylkKHzp8bxp1uW4qaSNQUkwmLLEc3kKsfz8lpV1F8Ht3U1Cm+9Srog2ug==",
|
||||||
|
"dev": true,
|
||||||
"license": "(MIT AND Zlib)"
|
"license": "(MIT AND Zlib)"
|
||||||
},
|
},
|
||||||
"node_modules/param-case": {
|
"node_modules/param-case": {
|
||||||
|
|||||||
@ -132,12 +132,12 @@
|
|||||||
"@tauri-apps/plugin-updater": "^2.9.0",
|
"@tauri-apps/plugin-updater": "^2.9.0",
|
||||||
"async-mutex": "^0.5.0",
|
"async-mutex": "^0.5.0",
|
||||||
"emoji-data-ios": "git+https://github.com/korenskoy/emoji-data-ios#443f1c9",
|
"emoji-data-ios": "git+https://github.com/korenskoy/emoji-data-ios#443f1c9",
|
||||||
|
"fflate": "^0.8.2",
|
||||||
"idb-keyval": "^6.2.2",
|
"idb-keyval": "^6.2.2",
|
||||||
"lowlight": "^3.3.0",
|
"lowlight": "^3.3.0",
|
||||||
"music-metadata": "^11.11.1",
|
"music-metadata": "^11.11.1",
|
||||||
"opus-recorder": "github:Ajaxy/opus-recorder#116830a",
|
"opus-recorder": "github:Ajaxy/opus-recorder#116830a",
|
||||||
"os-browserify": "^0.3.0",
|
"os-browserify": "^0.3.0",
|
||||||
"pako": "^2.1.0",
|
|
||||||
"path-browserify": "^1.0.1",
|
"path-browserify": "^1.0.1",
|
||||||
"qr-code-styling": "^1.9.2"
|
"qr-code-styling": "^1.9.2"
|
||||||
},
|
},
|
||||||
|
|||||||
@ -13,10 +13,11 @@ function compatTest() {
|
|||||||
var hasBigInt = typeof BigInt !== 'undefined';
|
var hasBigInt = typeof BigInt !== 'undefined';
|
||||||
var hasBroadcastChannel = typeof BroadcastChannel !== 'undefined';
|
var hasBroadcastChannel = typeof BroadcastChannel !== 'undefined';
|
||||||
var hasArrayAt = typeof new Array(0).at !== 'undefined';
|
var hasArrayAt = typeof new Array(0).at !== 'undefined';
|
||||||
|
var hasDecompressionStream = typeof DecompressionStream !== 'undefined';
|
||||||
|
|
||||||
var isCompatible = hasPromise && hasWebSockets && hasWebCrypto && hasObjectFromEntries && hasResizeObserver
|
var isCompatible = hasPromise && hasWebSockets && hasWebCrypto && hasObjectFromEntries && hasResizeObserver
|
||||||
&& hasCssSupports && hasDisplayNames && hasPluralRules && hasNumberFormat && hasWebLocks && hasBigInt && hasBroadcastChannel
|
&& hasCssSupports && hasDisplayNames && hasPluralRules && hasNumberFormat && hasWebLocks && hasBigInt && hasBroadcastChannel
|
||||||
&& hasArrayAt;
|
&& hasArrayAt && hasDecompressionStream;
|
||||||
|
|
||||||
if (isCompatible || (window.localStorage && window.localStorage.getItem('tt-ignore-compat'))) {
|
if (isCompatible || (window.localStorage && window.localStorage.getItem('tt-ignore-compat'))) {
|
||||||
window.isCompatTestPassed = true;
|
window.isCompatTestPassed = true;
|
||||||
@ -38,6 +39,7 @@ function compatTest() {
|
|||||||
console.warn('BigInt', hasBigInt);
|
console.warn('BigInt', hasBigInt);
|
||||||
console.warn('BroadcastChannel', hasBroadcastChannel);
|
console.warn('BroadcastChannel', hasBroadcastChannel);
|
||||||
console.warn('Array.at', hasArrayAt);
|
console.warn('Array.at', hasArrayAt);
|
||||||
|
console.warn('DecompressionStream', hasDecompressionStream);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Hardcoded page because server forbids iframe embedding
|
// Hardcoded page because server forbids iframe embedding
|
||||||
|
|||||||
4
src/@types/global.d.ts
vendored
4
src/@types/global.d.ts
vendored
@ -111,10 +111,6 @@ declare module '*.strings' {
|
|||||||
export default url;
|
export default url;
|
||||||
}
|
}
|
||||||
|
|
||||||
declare module 'pako/dist/pako_inflate' {
|
|
||||||
function inflate(...args: any[]): string;
|
|
||||||
}
|
|
||||||
|
|
||||||
declare module 'opus-recorder' {
|
declare module 'opus-recorder' {
|
||||||
export interface IOpusRecorder extends Omit<MediaRecorder, 'start' | 'ondataavailable'> {
|
export interface IOpusRecorder extends Omit<MediaRecorder, 'start' | 'ondataavailable'> {
|
||||||
// eslint-disable-next-line @typescript-eslint/no-misused-new
|
// eslint-disable-next-line @typescript-eslint/no-misused-new
|
||||||
|
|||||||
@ -104,7 +104,7 @@ export default class MessagePacker {
|
|||||||
this.setReady?.(true);
|
this.setReady?.(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
async getBeacon(state: RequestState) {
|
getBeacon(state: RequestState) {
|
||||||
const buffer = new BinaryWriter(Buffer.alloc(0));
|
const buffer = new BinaryWriter(Buffer.alloc(0));
|
||||||
const size = state.data.length + TLMessage.SIZE_OVERHEAD;
|
const size = state.data.length + TLMessage.SIZE_OVERHEAD;
|
||||||
if (size <= MessageContainer.MAXIMUM_SIZE) {
|
if (size <= MessageContainer.MAXIMUM_SIZE) {
|
||||||
@ -112,7 +112,7 @@ export default class MessagePacker {
|
|||||||
if (state.after) {
|
if (state.after) {
|
||||||
afterId = state.after.msgId;
|
afterId = state.after.msgId;
|
||||||
}
|
}
|
||||||
state.msgId = await this._state.writeDataAsMessage(
|
state.msgId = this._state.writeDataAsMessage(
|
||||||
buffer, state.data, state.request.classType === 'request', afterId,
|
buffer, state.data, state.request.classType === 'request', afterId,
|
||||||
);
|
);
|
||||||
this._log.debug(`Assigned msgId = ${state.msgId.toString()} to ${state.request.className
|
this._log.debug(`Assigned msgId = ${state.msgId.toString()} to ${state.request.className
|
||||||
@ -136,7 +136,7 @@ export default class MessagePacker {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
async get() {
|
get() {
|
||||||
if (!this._queue[this._queue.length - 1]) {
|
if (!this._queue[this._queue.length - 1]) {
|
||||||
this._queue = this._queue.filter(Boolean);
|
this._queue = this._queue.filter(Boolean);
|
||||||
return undefined;
|
return undefined;
|
||||||
@ -164,7 +164,7 @@ export default class MessagePacker {
|
|||||||
if (state.after) {
|
if (state.after) {
|
||||||
afterId = state.after.msgId;
|
afterId = state.after.msgId;
|
||||||
}
|
}
|
||||||
state.msgId = await this._state.writeDataAsMessage(
|
state.msgId = this._state.writeDataAsMessage(
|
||||||
buffer, state.data, state.request.classType === 'request', afterId,
|
buffer, state.data, state.request.classType === 'request', afterId,
|
||||||
);
|
);
|
||||||
this._log.debug(`Assigned msgId = ${state.msgId.toString()} to ${state.request.className
|
this._log.debug(`Assigned msgId = ${state.msgId.toString()} to ${state.request.className
|
||||||
@ -192,7 +192,7 @@ export default class MessagePacker {
|
|||||||
b.writeInt32LE(batch.length, 4);
|
b.writeInt32LE(batch.length, 4);
|
||||||
data = Buffer.concat([b, buffer.getValue()]);
|
data = Buffer.concat([b, buffer.getValue()]);
|
||||||
buffer = new BinaryWriter(Buffer.alloc(0));
|
buffer = new BinaryWriter(Buffer.alloc(0));
|
||||||
const containerId = await this._state.writeDataAsMessage(
|
const containerId = this._state.writeDataAsMessage(
|
||||||
buffer, data, false,
|
buffer, data, false,
|
||||||
);
|
);
|
||||||
for (const s of batch) {
|
for (const s of batch) {
|
||||||
|
|||||||
@ -431,7 +431,7 @@ export default class MTProtoSender {
|
|||||||
throw new Error('Cannot send requests while disconnected');
|
throw new Error('Cannot send requests while disconnected');
|
||||||
}
|
}
|
||||||
const state = new RequestState(request, undefined);
|
const state = new RequestState(request, undefined);
|
||||||
const data = await this._sendQueue.getBeacon(state);
|
const data = this._sendQueue.getBeacon(state);
|
||||||
if (!data) return;
|
if (!data) return;
|
||||||
const encryptedData = await this._state.encryptMessageData(data);
|
const encryptedData = await this._state.encryptMessageData(data);
|
||||||
|
|
||||||
@ -529,7 +529,7 @@ export default class MTProtoSender {
|
|||||||
&& this.getConnection()!.shouldLongPoll) {
|
&& this.getConnection()!.shouldLongPoll) {
|
||||||
await this._sendQueueLongPoll.wait();
|
await this._sendQueueLongPoll.wait();
|
||||||
|
|
||||||
const res = await this._sendQueueLongPoll.get();
|
const res = this._sendQueueLongPoll.get();
|
||||||
|
|
||||||
if (this.isReconnecting || !this._isFallback) {
|
if (this.isReconnecting || !this._isFallback) {
|
||||||
this._longPollLoopHandle = undefined;
|
this._longPollLoopHandle = undefined;
|
||||||
@ -612,7 +612,7 @@ export default class MTProtoSender {
|
|||||||
// If we've had new ACKs appended while waiting for messages to send, add them to queue
|
// If we've had new ACKs appended while waiting for messages to send, add them to queue
|
||||||
appendAcks();
|
appendAcks();
|
||||||
|
|
||||||
const res = await this._sendQueue.get();
|
const res = this._sendQueue.get();
|
||||||
|
|
||||||
this.logWithIndex.debug(`Got ${res?.batch.length} message(s) to send`);
|
this.logWithIndex.debug(`Got ${res?.batch.length} message(s) to send`);
|
||||||
|
|
||||||
|
|||||||
@ -140,17 +140,17 @@ export default class MTProtoState {
|
|||||||
* @param contentRelated
|
* @param contentRelated
|
||||||
* @param afterId
|
* @param afterId
|
||||||
*/
|
*/
|
||||||
async writeDataAsMessage(
|
writeDataAsMessage(
|
||||||
buffer: BinaryWriter, data: Buffer<ArrayBuffer>, contentRelated: boolean, afterId?: bigint,
|
buffer: BinaryWriter, data: Buffer<ArrayBuffer>, contentRelated: boolean, afterId?: bigint,
|
||||||
): Promise<bigint> {
|
): bigint {
|
||||||
const msgId = this._getNewMsgId();
|
const msgId = this._getNewMsgId();
|
||||||
const seqNo = this._getSeqNo(contentRelated);
|
const seqNo = this._getSeqNo(contentRelated);
|
||||||
let body;
|
let body;
|
||||||
if (afterId === undefined) {
|
if (afterId === undefined) {
|
||||||
body = await GZIPPacked.gzipIfSmaller(contentRelated, data);
|
body = GZIPPacked.gzipIfNeeded(contentRelated, data);
|
||||||
} else {
|
} else {
|
||||||
// Invoke query expects a query with a getBytes func
|
// Invoke query expects a query with a getBytes func
|
||||||
body = await GZIPPacked.gzipIfSmaller(contentRelated, new Api.InvokeAfterMsg({
|
body = GZIPPacked.gzipIfNeeded(contentRelated, new Api.InvokeAfterMsg({
|
||||||
msgId: afterId,
|
msgId: afterId,
|
||||||
query: {
|
query: {
|
||||||
getBytes() {
|
getBytes() {
|
||||||
|
|||||||
@ -1,65 +1,55 @@
|
|||||||
import { inflate } from 'pako/dist/pako_inflate';
|
import { gzipSync, gunzipSync } from 'fflate';
|
||||||
|
|
||||||
import type { BinaryReader } from '../../extensions';
|
import type { BinaryReader } from '../../extensions';
|
||||||
|
|
||||||
import { serializeBytes } from '..';
|
import { serializeBytes } from '..';
|
||||||
|
|
||||||
export default class GZIPPacked {
|
export default class GZIPPacked {
|
||||||
static CONSTRUCTOR_ID = 0x3072cfa1;
|
static CONSTRUCTOR_ID = 0x3072cfa1;
|
||||||
|
|
||||||
static classType = 'constructor';
|
static classType = 'constructor';
|
||||||
|
|
||||||
data: Buffer<ArrayBuffer>;
|
data: Buffer<ArrayBuffer>;
|
||||||
|
|
||||||
private CONSTRUCTOR_ID: number;
|
private CONSTRUCTOR_ID: number;
|
||||||
|
|
||||||
private classType: string;
|
private classType: string;
|
||||||
|
|
||||||
constructor(data: Buffer<ArrayBuffer>) {
|
constructor(data: Buffer<ArrayBuffer>) {
|
||||||
this.data = data;
|
this.data = data;
|
||||||
this.CONSTRUCTOR_ID = 0x3072cfa1;
|
this.CONSTRUCTOR_ID = 0x3072cfa1;
|
||||||
this.classType = 'constructor';
|
this.classType = 'constructor';
|
||||||
|
}
|
||||||
|
|
||||||
|
static gzipIfNeeded(contentRelated: boolean, data: Buffer<ArrayBuffer>) {
|
||||||
|
if (contentRelated && data.length > 512) {
|
||||||
|
const gzipped = new GZIPPacked(data).toBytes();
|
||||||
|
if (gzipped.length < data.length) {
|
||||||
|
return gzipped;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
return data;
|
||||||
|
}
|
||||||
|
|
||||||
static async gzipIfSmaller(contentRelated: boolean, data: Buffer<ArrayBuffer>) {
|
static gzip(input: Buffer<ArrayBuffer>) {
|
||||||
if (contentRelated && data.length > 512) {
|
return Buffer.from(gzipSync(input));
|
||||||
const gzipped = await new GZIPPacked(data).toBytes();
|
}
|
||||||
if (gzipped.length < data.length) {
|
|
||||||
return gzipped;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return data;
|
|
||||||
}
|
|
||||||
|
|
||||||
static gzip(input: Buffer<ArrayBuffer>) {
|
static ungzip(input: Buffer) {
|
||||||
return Buffer.from(input);
|
return Buffer.from(gunzipSync(input));
|
||||||
// TODO this usually makes it faster for large requests
|
}
|
||||||
// return Buffer.from(deflate(input, { level: 9, gzip: true }))
|
|
||||||
}
|
|
||||||
|
|
||||||
static ungzip(input: Buffer) {
|
toBytes() {
|
||||||
return Buffer.from(inflate(input));
|
const g = Buffer.alloc(4);
|
||||||
}
|
g.writeUInt32LE(GZIPPacked.CONSTRUCTOR_ID, 0);
|
||||||
|
return Buffer.concat([
|
||||||
|
g,
|
||||||
|
serializeBytes(GZIPPacked.gzip(this.data)),
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
|
||||||
async toBytes() {
|
static async fromReader(reader: BinaryReader) {
|
||||||
const g = Buffer.alloc(4);
|
const data = reader.tgReadBytes();
|
||||||
g.writeUInt32LE(GZIPPacked.CONSTRUCTOR_ID, 0);
|
return new GZIPPacked(GZIPPacked.ungzip(data));
|
||||||
return Buffer.concat([
|
}
|
||||||
g,
|
|
||||||
serializeBytes(await GZIPPacked.gzip(this.data)),
|
|
||||||
]);
|
|
||||||
}
|
|
||||||
|
|
||||||
static read(reader: BinaryReader) {
|
|
||||||
const constructor = reader.readInt(false);
|
|
||||||
if (constructor !== GZIPPacked.CONSTRUCTOR_ID) {
|
|
||||||
throw new Error('not equal');
|
|
||||||
}
|
|
||||||
return GZIPPacked.gzip(reader.tgReadBytes());
|
|
||||||
}
|
|
||||||
|
|
||||||
static async fromReader(reader: BinaryReader) {
|
|
||||||
const data = reader.tgReadBytes();
|
|
||||||
return new GZIPPacked(await GZIPPacked.ungzip(data));
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,5 +1,3 @@
|
|||||||
import { inflate } from 'pako/dist/pako_inflate';
|
|
||||||
|
|
||||||
import type { CancellableCallback } from '../../util/PostMessageConnector';
|
import type { CancellableCallback } from '../../util/PostMessageConnector';
|
||||||
|
|
||||||
import { createWorkerInterface } from '../../util/createPostMessageInterface';
|
import { createWorkerInterface } from '../../util/createPostMessageInterface';
|
||||||
@ -98,8 +96,13 @@ async function extractJson(tgsUrl: string) {
|
|||||||
return response.text();
|
return response.text();
|
||||||
}
|
}
|
||||||
|
|
||||||
const arrayBuffer = await response.arrayBuffer();
|
if (!response.body) {
|
||||||
return inflate(arrayBuffer, { to: 'string' });
|
return '';
|
||||||
|
}
|
||||||
|
|
||||||
|
const decompressionStream = response.body.pipeThrough(new DecompressionStream('gzip'));
|
||||||
|
const result = await new Response(decompressionStream).text();
|
||||||
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
function calcParams(json: string, isLowPriority: boolean, framesCount: number) {
|
function calcParams(json: string, isLowPriority: boolean, framesCount: number) {
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user