You've already forked matrix-js-sdk
mirror of
https://github.com/matrix-org/matrix-js-sdk.git
synced 2025-08-06 12:02:40 +03:00
Deprecate utils function defer
in favour of Promise.withResolvers
(#4829)
* Switch from defer to Promise.withResolvers As supported by the outgoing LTS version (v22) which has 99% support of ES2024 Signed-off-by: Michael Telatynski <7t3chguy@gmail.com> * delint Signed-off-by: Michael Telatynski <7t3chguy@gmail.com> * Deprecate defer instead of killing it Signed-off-by: Michael Telatynski <7t3chguy@gmail.com> * Knip Signed-off-by: Michael Telatynski <7t3chguy@gmail.com> * Iterate based on review Signed-off-by: Michael Telatynski <7t3chguy@gmail.com> * Iterate based on review Signed-off-by: Michael Telatynski <7t3chguy@gmail.com> * Iterate based on review Signed-off-by: Michael Telatynski <7t3chguy@gmail.com> * Improve coverage Signed-off-by: Michael Telatynski <7t3chguy@gmail.com> --------- Signed-off-by: Michael Telatynski <7t3chguy@gmail.com>
This commit is contained in:
committed by
GitHub
parent
d24c5d8b2b
commit
1fcc375dd5
1
knip.ts
1
knip.ts
@@ -9,6 +9,7 @@ export default {
|
|||||||
"src/crypto-api/index.ts",
|
"src/crypto-api/index.ts",
|
||||||
"src/testing.ts",
|
"src/testing.ts",
|
||||||
"src/matrix.ts",
|
"src/matrix.ts",
|
||||||
|
"src/utils.ts", // not really an entrypoint but we have deprecated `defer` there
|
||||||
"scripts/**",
|
"scripts/**",
|
||||||
"spec/**",
|
"spec/**",
|
||||||
// XXX: these look entirely unused
|
// XXX: these look entirely unused
|
||||||
|
@@ -59,7 +59,7 @@ import {
|
|||||||
} from "../../../src/matrix";
|
} from "../../../src/matrix";
|
||||||
import { E2EKeyReceiver } from "../../test-utils/E2EKeyReceiver";
|
import { E2EKeyReceiver } from "../../test-utils/E2EKeyReceiver";
|
||||||
import { type ISyncResponder, SyncResponder } from "../../test-utils/SyncResponder";
|
import { type ISyncResponder, SyncResponder } from "../../test-utils/SyncResponder";
|
||||||
import { defer, escapeRegExp } from "../../../src/utils";
|
import { escapeRegExp } from "../../../src/utils";
|
||||||
import { downloadDeviceToJsDevice } from "../../../src/rust-crypto/device-converter";
|
import { downloadDeviceToJsDevice } from "../../../src/rust-crypto/device-converter";
|
||||||
import { flushPromises } from "../../test-utils/flushPromises";
|
import { flushPromises } from "../../test-utils/flushPromises";
|
||||||
import {
|
import {
|
||||||
@@ -1283,13 +1283,13 @@ describe("crypto", () => {
|
|||||||
const inboundGroupSessionPromise = expectSendRoomKey("@bob:xyz", testOlmAccount);
|
const inboundGroupSessionPromise = expectSendRoomKey("@bob:xyz", testOlmAccount);
|
||||||
|
|
||||||
// ... and finally, send the room key. We block the response until `sendRoomMessageDefer` completes.
|
// ... and finally, send the room key. We block the response until `sendRoomMessageDefer` completes.
|
||||||
const sendRoomMessageDefer = defer<FetchMock.MockResponse>();
|
const sendRoomMessageResolvers = Promise.withResolvers<FetchMock.MockResponse>();
|
||||||
const reqProm = new Promise<IContent>((resolve) => {
|
const reqProm = new Promise<IContent>((resolve) => {
|
||||||
fetchMock.putOnce(
|
fetchMock.putOnce(
|
||||||
new RegExp("/send/m.room.encrypted/"),
|
new RegExp("/send/m.room.encrypted/"),
|
||||||
async (url: string, opts: RequestInit): Promise<FetchMock.MockResponse> => {
|
async (url: string, opts: RequestInit): Promise<FetchMock.MockResponse> => {
|
||||||
resolve(JSON.parse(opts.body as string));
|
resolve(JSON.parse(opts.body as string));
|
||||||
return await sendRoomMessageDefer.promise;
|
return await sendRoomMessageResolvers.promise;
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
// append to the list of intercepts on this path (since we have some tests that call
|
// append to the list of intercepts on this path (since we have some tests that call
|
||||||
@@ -1318,7 +1318,7 @@ describe("crypto", () => {
|
|||||||
|
|
||||||
// release the send request
|
// release the send request
|
||||||
const resp = { event_id: "$event_id" };
|
const resp = { event_id: "$event_id" };
|
||||||
sendRoomMessageDefer.resolve(resp);
|
sendRoomMessageResolvers.resolve(resp);
|
||||||
expect(await sendProm).toEqual(resp);
|
expect(await sendProm).toEqual(resp);
|
||||||
|
|
||||||
// still pending at this point
|
// still pending at this point
|
||||||
|
@@ -36,7 +36,6 @@ import { advanceTimersUntil, awaitDecryption, syncPromise } from "../../test-uti
|
|||||||
import * as testData from "../../test-utils/test-data";
|
import * as testData from "../../test-utils/test-data";
|
||||||
import { type KeyBackupInfo, type KeyBackupSession } from "../../../src/crypto-api/keybackup";
|
import { type KeyBackupInfo, type KeyBackupSession } from "../../../src/crypto-api/keybackup";
|
||||||
import { flushPromises } from "../../test-utils/flushPromises";
|
import { flushPromises } from "../../test-utils/flushPromises";
|
||||||
import { defer, type IDeferred } from "../../../src/utils";
|
|
||||||
import { decodeRecoveryKey, DecryptionFailureCode, CryptoEvent, type CryptoApi } from "../../../src/crypto-api";
|
import { decodeRecoveryKey, DecryptionFailureCode, CryptoEvent, type CryptoApi } from "../../../src/crypto-api";
|
||||||
import { type KeyBackup } from "../../../src/rust-crypto/backup.ts";
|
import { type KeyBackup } from "../../../src/rust-crypto/backup.ts";
|
||||||
|
|
||||||
@@ -861,7 +860,7 @@ describe("megolm-keys backup", () => {
|
|||||||
expect(await aliceCrypto.getKeyBackupInfo()).toStrictEqual(testData.SIGNED_BACKUP_DATA);
|
expect(await aliceCrypto.getKeyBackupInfo()).toStrictEqual(testData.SIGNED_BACKUP_DATA);
|
||||||
|
|
||||||
// Delete the backup and we are expecting the key backup to be disabled
|
// Delete the backup and we are expecting the key backup to be disabled
|
||||||
const keyBackupStatus = defer<boolean>();
|
const keyBackupStatus = Promise.withResolvers<boolean>();
|
||||||
aliceClient.once(CryptoEvent.KeyBackupStatus, (enabled) => keyBackupStatus.resolve(enabled));
|
aliceClient.once(CryptoEvent.KeyBackupStatus, (enabled) => keyBackupStatus.resolve(enabled));
|
||||||
await aliceCrypto.deleteKeyBackupVersion(testData.SIGNED_BACKUP_DATA.version!);
|
await aliceCrypto.deleteKeyBackupVersion(testData.SIGNED_BACKUP_DATA.version!);
|
||||||
expect(await keyBackupStatus.promise).toBe(false);
|
expect(await keyBackupStatus.promise).toBe(false);
|
||||||
@@ -1158,7 +1157,7 @@ describe("megolm-keys backup", () => {
|
|||||||
// A check backup should happen at some point
|
// A check backup should happen at some point
|
||||||
await aliceCrypto.checkKeyBackupAndEnable();
|
await aliceCrypto.checkKeyBackupAndEnable();
|
||||||
|
|
||||||
const awaitHasQueriedNewBackup: IDeferred<void> = defer<void>();
|
const awaitHasQueriedNewBackup: PromiseWithResolvers<void> = Promise.withResolvers<void>();
|
||||||
|
|
||||||
fetchMock.get(
|
fetchMock.get(
|
||||||
"express:/_matrix/client/v3/room_keys/keys/:room_id/:session_id",
|
"express:/_matrix/client/v3/room_keys/keys/:room_id/:session_id",
|
||||||
|
@@ -44,7 +44,7 @@ import {
|
|||||||
type Verifier,
|
type Verifier,
|
||||||
VerifierEvent,
|
VerifierEvent,
|
||||||
} from "../../../src/crypto-api/verification";
|
} from "../../../src/crypto-api/verification";
|
||||||
import { defer, escapeRegExp } from "../../../src/utils";
|
import { escapeRegExp } from "../../../src/utils";
|
||||||
import { awaitDecryption, emitPromise, getSyncResponse, syncPromise } from "../../test-utils/test-utils";
|
import { awaitDecryption, emitPromise, getSyncResponse, syncPromise } from "../../test-utils/test-utils";
|
||||||
import { SyncResponder } from "../../test-utils/SyncResponder";
|
import { SyncResponder } from "../../test-utils/SyncResponder";
|
||||||
import {
|
import {
|
||||||
@@ -1540,10 +1540,10 @@ function expectSendToDeviceMessage(msgtype: string): Promise<{ messages: any }>
|
|||||||
* @returns a map of secret name to promise that will resolve (with the id of the secret request) when the secret is requested.
|
* @returns a map of secret name to promise that will resolve (with the id of the secret request) when the secret is requested.
|
||||||
*/
|
*/
|
||||||
function mockSecretRequestAndGetPromises(): Map<string, Promise<string>> {
|
function mockSecretRequestAndGetPromises(): Map<string, Promise<string>> {
|
||||||
const mskRequestDefer = defer<string>();
|
const mskRequestResolvers = Promise.withResolvers<string>();
|
||||||
const sskRequestDefer = defer<string>();
|
const sskRequestResolvers = Promise.withResolvers<string>();
|
||||||
const uskRequestDefer = defer<string>();
|
const uskRequestResolvers = Promise.withResolvers<string>();
|
||||||
const backupKeyRequestDefer = defer<string>();
|
const backupKeyRequestResolvers = Promise.withResolvers<string>();
|
||||||
|
|
||||||
fetchMock.put(
|
fetchMock.put(
|
||||||
new RegExp(`/_matrix/client/(r0|v3)/sendToDevice/m.secret.request`),
|
new RegExp(`/_matrix/client/(r0|v3)/sendToDevice/m.secret.request`),
|
||||||
@@ -1555,13 +1555,13 @@ function mockSecretRequestAndGetPromises(): Map<string, Promise<string>> {
|
|||||||
const name = content.name;
|
const name = content.name;
|
||||||
const requestId = content.request_id;
|
const requestId = content.request_id;
|
||||||
if (name == "m.cross_signing.user_signing") {
|
if (name == "m.cross_signing.user_signing") {
|
||||||
uskRequestDefer.resolve(requestId);
|
uskRequestResolvers.resolve(requestId);
|
||||||
} else if (name == "m.cross_signing.master") {
|
} else if (name == "m.cross_signing.master") {
|
||||||
mskRequestDefer.resolve(requestId);
|
mskRequestResolvers.resolve(requestId);
|
||||||
} else if (name == "m.cross_signing.self_signing") {
|
} else if (name == "m.cross_signing.self_signing") {
|
||||||
sskRequestDefer.resolve(requestId);
|
sskRequestResolvers.resolve(requestId);
|
||||||
} else if (name == "m.megolm_backup.v1") {
|
} else if (name == "m.megolm_backup.v1") {
|
||||||
backupKeyRequestDefer.resolve(requestId);
|
backupKeyRequestResolvers.resolve(requestId);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return {};
|
return {};
|
||||||
@@ -1570,10 +1570,10 @@ function mockSecretRequestAndGetPromises(): Map<string, Promise<string>> {
|
|||||||
);
|
);
|
||||||
|
|
||||||
const promiseMap = new Map<string, Promise<string>>();
|
const promiseMap = new Map<string, Promise<string>>();
|
||||||
promiseMap.set("m.cross_signing.master", mskRequestDefer.promise);
|
promiseMap.set("m.cross_signing.master", mskRequestResolvers.promise);
|
||||||
promiseMap.set("m.cross_signing.self_signing", sskRequestDefer.promise);
|
promiseMap.set("m.cross_signing.self_signing", sskRequestResolvers.promise);
|
||||||
promiseMap.set("m.cross_signing.user_signing", uskRequestDefer.promise);
|
promiseMap.set("m.cross_signing.user_signing", uskRequestResolvers.promise);
|
||||||
promiseMap.set("m.megolm_backup.v1", backupKeyRequestDefer.promise);
|
promiseMap.set("m.megolm_backup.v1", backupKeyRequestResolvers.promise);
|
||||||
return promiseMap;
|
return promiseMap;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -1796,6 +1796,27 @@ describe("MatrixClient", function () {
|
|||||||
expect(client.getUserIdLocalpart()).toBe("alice");
|
expect(client.getUserIdLocalpart()).toBe("alice");
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
describe("setRoomMutePushRule", () => {
|
||||||
|
it("should set room push rule to muted", async () => {
|
||||||
|
const roomId = "!roomId:server";
|
||||||
|
const client = new MatrixClient({
|
||||||
|
baseUrl: "http://localhost",
|
||||||
|
fetchFn: httpBackend.fetchFn as typeof globalThis.fetch,
|
||||||
|
});
|
||||||
|
client.pushRules = {
|
||||||
|
global: {
|
||||||
|
room: [{ rule_id: roomId, actions: [], default: false, enabled: false }],
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
const path = `/pushrules/global/room/${encodeURIComponent(roomId)}`;
|
||||||
|
httpBackend.when("DELETE", path).respond(200, {});
|
||||||
|
httpBackend.when("PUT", path).respond(200, {});
|
||||||
|
client.setRoomMutePushRule("global", roomId, true);
|
||||||
|
await httpBackend.flush("");
|
||||||
|
});
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
function withThreadId(event: MatrixEvent, newThreadId: string): MatrixEvent {
|
function withThreadId(event: MatrixEvent, newThreadId: string): MatrixEvent {
|
||||||
|
@@ -26,7 +26,6 @@ import {
|
|||||||
PayloadType,
|
PayloadType,
|
||||||
RendezvousError,
|
RendezvousError,
|
||||||
} from "../../../src/rendezvous";
|
} from "../../../src/rendezvous";
|
||||||
import { defer } from "../../../src/utils";
|
|
||||||
import {
|
import {
|
||||||
ClientPrefix,
|
ClientPrefix,
|
||||||
DEVICE_CODE_SCOPE,
|
DEVICE_CODE_SCOPE,
|
||||||
@@ -112,8 +111,8 @@ describe("MSC4108SignInWithQR", () => {
|
|||||||
let opponentLogin: MSC4108SignInWithQR;
|
let opponentLogin: MSC4108SignInWithQR;
|
||||||
|
|
||||||
beforeEach(async () => {
|
beforeEach(async () => {
|
||||||
let ourData = defer<string>();
|
let ourData = Promise.withResolvers<string>();
|
||||||
let opponentData = defer<string>();
|
let opponentData = Promise.withResolvers<string>();
|
||||||
|
|
||||||
const ourMockSession = {
|
const ourMockSession = {
|
||||||
send: jest.fn(async (newData) => {
|
send: jest.fn(async (newData) => {
|
||||||
@@ -122,7 +121,7 @@ describe("MSC4108SignInWithQR", () => {
|
|||||||
receive: jest.fn(() => {
|
receive: jest.fn(() => {
|
||||||
const prom = opponentData.promise;
|
const prom = opponentData.promise;
|
||||||
prom.then(() => {
|
prom.then(() => {
|
||||||
opponentData = defer();
|
opponentData = Promise.withResolvers();
|
||||||
});
|
});
|
||||||
return prom;
|
return prom;
|
||||||
}),
|
}),
|
||||||
@@ -141,7 +140,7 @@ describe("MSC4108SignInWithQR", () => {
|
|||||||
receive: jest.fn(() => {
|
receive: jest.fn(() => {
|
||||||
const prom = ourData.promise;
|
const prom = ourData.promise;
|
||||||
prom.then(() => {
|
prom.then(() => {
|
||||||
ourData = defer();
|
ourData = Promise.withResolvers();
|
||||||
});
|
});
|
||||||
return prom;
|
return prom;
|
||||||
}),
|
}),
|
||||||
@@ -334,11 +333,11 @@ describe("MSC4108SignInWithQR", () => {
|
|||||||
// @ts-ignore
|
// @ts-ignore
|
||||||
await opponentLogin.receive();
|
await opponentLogin.receive();
|
||||||
|
|
||||||
const deferred = defer<IMyDevice>();
|
const deviceResolvers = Promise.withResolvers<IMyDevice>();
|
||||||
mocked(client.getDevice).mockReturnValue(deferred.promise);
|
mocked(client.getDevice).mockReturnValue(deviceResolvers.promise);
|
||||||
|
|
||||||
ourLogin.cancel(MSC4108FailureReason.UserCancelled).catch(() => {});
|
ourLogin.cancel(MSC4108FailureReason.UserCancelled).catch(() => {});
|
||||||
deferred.resolve({} as IMyDevice);
|
deviceResolvers.resolve({} as IMyDevice);
|
||||||
|
|
||||||
const secrets = {
|
const secrets = {
|
||||||
cross_signing: { master_key: "mk", user_signing_key: "usk", self_signing_key: "ssk" },
|
cross_signing: { master_key: "mk", user_signing_key: "usk", self_signing_key: "ssk" },
|
||||||
|
@@ -48,7 +48,6 @@ import { type SyncApiOptions, SyncState } from "../../src/sync";
|
|||||||
import { type IStoredClientOpts } from "../../src";
|
import { type IStoredClientOpts } from "../../src";
|
||||||
import { logger } from "../../src/logger";
|
import { logger } from "../../src/logger";
|
||||||
import { emitPromise } from "../test-utils/test-utils";
|
import { emitPromise } from "../test-utils/test-utils";
|
||||||
import { defer } from "../../src/utils";
|
|
||||||
import { KnownMembership } from "../../src/@types/membership";
|
import { KnownMembership } from "../../src/@types/membership";
|
||||||
import { type SyncCryptoCallbacks } from "../../src/common-crypto/CryptoBackend";
|
import { type SyncCryptoCallbacks } from "../../src/common-crypto/CryptoBackend";
|
||||||
|
|
||||||
@@ -369,7 +368,7 @@ describe("SlidingSyncSdk", () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
it("can be created with live events", async () => {
|
it("can be created with live events", async () => {
|
||||||
const seenLiveEventDeferred = defer<boolean>();
|
const seenLiveEventDeferred = Promise.withResolvers<boolean>();
|
||||||
const listener = (
|
const listener = (
|
||||||
ev: MatrixEvent,
|
ev: MatrixEvent,
|
||||||
room?: Room,
|
room?: Room,
|
||||||
|
@@ -5,7 +5,6 @@ import { getMockClientWithEventEmitter } from "../test-utils/client";
|
|||||||
import { StubStore } from "../../src/store/stub";
|
import { StubStore } from "../../src/store/stub";
|
||||||
import { type IndexedToDeviceBatch } from "../../src/models/ToDeviceMessage";
|
import { type IndexedToDeviceBatch } from "../../src/models/ToDeviceMessage";
|
||||||
import { SyncState } from "../../src/sync";
|
import { SyncState } from "../../src/sync";
|
||||||
import { defer } from "../../src/utils";
|
|
||||||
|
|
||||||
describe("onResumedSync", () => {
|
describe("onResumedSync", () => {
|
||||||
let batch: IndexedToDeviceBatch | null;
|
let batch: IndexedToDeviceBatch | null;
|
||||||
@@ -60,7 +59,7 @@ describe("onResumedSync", () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
it("resends queue after connectivity restored", async () => {
|
it("resends queue after connectivity restored", async () => {
|
||||||
const deferred = defer();
|
const successResolvers = Promise.withResolvers<void>();
|
||||||
|
|
||||||
onSendToDeviceFailure = () => {
|
onSendToDeviceFailure = () => {
|
||||||
expect(store.getOldestToDeviceBatch).toHaveBeenCalledTimes(1);
|
expect(store.getOldestToDeviceBatch).toHaveBeenCalledTimes(1);
|
||||||
@@ -73,15 +72,15 @@ describe("onResumedSync", () => {
|
|||||||
onSendToDeviceSuccess = () => {
|
onSendToDeviceSuccess = () => {
|
||||||
expect(store.getOldestToDeviceBatch).toHaveBeenCalledTimes(3);
|
expect(store.getOldestToDeviceBatch).toHaveBeenCalledTimes(3);
|
||||||
expect(store.removeToDeviceBatch).toHaveBeenCalled();
|
expect(store.removeToDeviceBatch).toHaveBeenCalled();
|
||||||
deferred.resolve();
|
successResolvers.resolve();
|
||||||
};
|
};
|
||||||
|
|
||||||
queue.start();
|
queue.start();
|
||||||
return deferred.promise;
|
return successResolvers.promise;
|
||||||
});
|
});
|
||||||
|
|
||||||
it("does not resend queue if client sync still catching up", async () => {
|
it("does not resend queue if client sync still catching up", async () => {
|
||||||
const deferred = defer();
|
const successResolvers = Promise.withResolvers<void>();
|
||||||
|
|
||||||
onSendToDeviceFailure = () => {
|
onSendToDeviceFailure = () => {
|
||||||
expect(store.getOldestToDeviceBatch).toHaveBeenCalledTimes(1);
|
expect(store.getOldestToDeviceBatch).toHaveBeenCalledTimes(1);
|
||||||
@@ -89,15 +88,15 @@ describe("onResumedSync", () => {
|
|||||||
|
|
||||||
resumeSync(SyncState.Catchup, SyncState.Catchup);
|
resumeSync(SyncState.Catchup, SyncState.Catchup);
|
||||||
expect(store.getOldestToDeviceBatch).toHaveBeenCalledTimes(1);
|
expect(store.getOldestToDeviceBatch).toHaveBeenCalledTimes(1);
|
||||||
deferred.resolve();
|
successResolvers.resolve();
|
||||||
};
|
};
|
||||||
|
|
||||||
queue.start();
|
queue.start();
|
||||||
return deferred.promise;
|
return successResolvers.promise;
|
||||||
});
|
});
|
||||||
|
|
||||||
it("does not resend queue if connectivity restored after queue stopped", async () => {
|
it("does not resend queue if connectivity restored after queue stopped", async () => {
|
||||||
const deferred = defer();
|
const successResolvers = Promise.withResolvers<void>();
|
||||||
|
|
||||||
onSendToDeviceFailure = () => {
|
onSendToDeviceFailure = () => {
|
||||||
expect(store.getOldestToDeviceBatch).toHaveBeenCalledTimes(1);
|
expect(store.getOldestToDeviceBatch).toHaveBeenCalledTimes(1);
|
||||||
@@ -107,10 +106,10 @@ describe("onResumedSync", () => {
|
|||||||
|
|
||||||
resumeSync(SyncState.Syncing, SyncState.Catchup);
|
resumeSync(SyncState.Syncing, SyncState.Catchup);
|
||||||
expect(store.getOldestToDeviceBatch).toHaveBeenCalledTimes(1);
|
expect(store.getOldestToDeviceBatch).toHaveBeenCalledTimes(1);
|
||||||
deferred.resolve();
|
successResolvers.resolve();
|
||||||
};
|
};
|
||||||
|
|
||||||
queue.start();
|
queue.start();
|
||||||
return deferred.promise;
|
return successResolvers.promise;
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
@@ -29,7 +29,7 @@ import {
|
|||||||
Method,
|
Method,
|
||||||
} from "../../../src";
|
} from "../../../src";
|
||||||
import { emitPromise } from "../../test-utils/test-utils";
|
import { emitPromise } from "../../test-utils/test-utils";
|
||||||
import { defer, type QueryDict, sleep } from "../../../src/utils";
|
import { type QueryDict, sleep } from "../../../src/utils";
|
||||||
import { type Logger } from "../../../src/logger";
|
import { type Logger } from "../../../src/logger";
|
||||||
|
|
||||||
describe("FetchHttpApi", () => {
|
describe("FetchHttpApi", () => {
|
||||||
@@ -525,8 +525,8 @@ describe("FetchHttpApi", () => {
|
|||||||
|
|
||||||
it("should not log query parameters", async () => {
|
it("should not log query parameters", async () => {
|
||||||
jest.useFakeTimers();
|
jest.useFakeTimers();
|
||||||
const deferred = defer<Response>();
|
const responseResolvers = Promise.withResolvers<Response>();
|
||||||
const fetchFn = jest.fn().mockReturnValue(deferred.promise);
|
const fetchFn = jest.fn().mockReturnValue(responseResolvers.promise);
|
||||||
const mockLogger = {
|
const mockLogger = {
|
||||||
debug: jest.fn(),
|
debug: jest.fn(),
|
||||||
} as unknown as Mocked<Logger>;
|
} as unknown as Mocked<Logger>;
|
||||||
@@ -538,7 +538,7 @@ describe("FetchHttpApi", () => {
|
|||||||
});
|
});
|
||||||
const prom = api.requestOtherUrl(Method.Get, "https://server:8448/some/path?query=param#fragment");
|
const prom = api.requestOtherUrl(Method.Get, "https://server:8448/some/path?query=param#fragment");
|
||||||
jest.advanceTimersByTime(1234);
|
jest.advanceTimersByTime(1234);
|
||||||
deferred.resolve({ ok: true, status: 200, text: () => Promise.resolve("RESPONSE") } as Response);
|
responseResolvers.resolve({ ok: true, status: 200, text: () => Promise.resolve("RESPONSE") } as Response);
|
||||||
await prom;
|
await prom;
|
||||||
expect(mockLogger.debug).not.toHaveBeenCalledWith("fragment");
|
expect(mockLogger.debug).not.toHaveBeenCalledWith("fragment");
|
||||||
expect(mockLogger.debug).not.toHaveBeenCalledWith("query");
|
expect(mockLogger.debug).not.toHaveBeenCalledWith("query");
|
||||||
@@ -557,7 +557,7 @@ describe("FetchHttpApi", () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
it("should not make multiple concurrent refresh token requests", async () => {
|
it("should not make multiple concurrent refresh token requests", async () => {
|
||||||
const deferredTokenRefresh = defer<{ accessToken: string; refreshToken: string }>();
|
const deferredTokenRefresh = Promise.withResolvers<{ accessToken: string; refreshToken: string }>();
|
||||||
const fetchFn = jest.fn().mockResolvedValue({
|
const fetchFn = jest.fn().mockResolvedValue({
|
||||||
ok: false,
|
ok: false,
|
||||||
status: tokenInactiveError.httpStatus,
|
status: tokenInactiveError.httpStatus,
|
||||||
@@ -612,7 +612,7 @@ describe("FetchHttpApi", () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
it("should use newly refreshed token if request starts mid-refresh", async () => {
|
it("should use newly refreshed token if request starts mid-refresh", async () => {
|
||||||
const deferredTokenRefresh = defer<{ accessToken: string; refreshToken: string }>();
|
const deferredTokenRefresh = Promise.withResolvers<{ accessToken: string; refreshToken: string }>();
|
||||||
const fetchFn = jest.fn().mockResolvedValue({
|
const fetchFn = jest.fn().mockResolvedValue({
|
||||||
ok: false,
|
ok: false,
|
||||||
status: tokenInactiveError.httpStatus,
|
status: tokenInactiveError.httpStatus,
|
||||||
|
@@ -73,7 +73,7 @@ import {
|
|||||||
PolicyRecommendation,
|
PolicyRecommendation,
|
||||||
PolicyScope,
|
PolicyScope,
|
||||||
} from "../../src/models/invites-ignorer";
|
} from "../../src/models/invites-ignorer";
|
||||||
import { defer, type QueryDict } from "../../src/utils";
|
import { type QueryDict } from "../../src/utils";
|
||||||
import { type SyncState } from "../../src/sync";
|
import { type SyncState } from "../../src/sync";
|
||||||
import * as featureUtils from "../../src/feature";
|
import * as featureUtils from "../../src/feature";
|
||||||
import { StubStore } from "../../src/store/stub";
|
import { StubStore } from "../../src/store/stub";
|
||||||
@@ -1997,8 +1997,8 @@ describe("MatrixClient", function () {
|
|||||||
});
|
});
|
||||||
|
|
||||||
it("should cancel an event which is encrypting", async () => {
|
it("should cancel an event which is encrypting", async () => {
|
||||||
const encryptEventDefer = defer();
|
const encryptEventResolvers = Promise.withResolvers<void>();
|
||||||
mockCrypto.encryptEvent.mockReturnValue(encryptEventDefer.promise);
|
mockCrypto.encryptEvent.mockReturnValue(encryptEventResolvers.promise);
|
||||||
|
|
||||||
const statusPromise = testUtils.emitPromise(event, "Event.status");
|
const statusPromise = testUtils.emitPromise(event, "Event.status");
|
||||||
// @ts-ignore protected method access
|
// @ts-ignore protected method access
|
||||||
@@ -2009,7 +2009,7 @@ describe("MatrixClient", function () {
|
|||||||
assertCancelled();
|
assertCancelled();
|
||||||
|
|
||||||
// now let the encryption complete, and check that the message is not sent.
|
// now let the encryption complete, and check that the message is not sent.
|
||||||
encryptEventDefer.resolve();
|
encryptEventResolvers.resolve();
|
||||||
await encryptAndSendPromise;
|
await encryptAndSendPromise;
|
||||||
assertCancelled();
|
assertCancelled();
|
||||||
});
|
});
|
||||||
|
@@ -30,7 +30,6 @@ import {
|
|||||||
import { LegacyMembershipManager } from "../../../src/matrixrtc/LegacyMembershipManager";
|
import { LegacyMembershipManager } from "../../../src/matrixrtc/LegacyMembershipManager";
|
||||||
import { makeMockClient, makeMockRoom, membershipTemplate, mockCallMembership, type MockClient } from "./mocks";
|
import { makeMockClient, makeMockRoom, membershipTemplate, mockCallMembership, type MockClient } from "./mocks";
|
||||||
import { MembershipManager } from "../../../src/matrixrtc/NewMembershipManager";
|
import { MembershipManager } from "../../../src/matrixrtc/NewMembershipManager";
|
||||||
import { defer } from "../../../src/utils";
|
|
||||||
import { logger } from "../../../src/logger.ts";
|
import { logger } from "../../../src/logger.ts";
|
||||||
|
|
||||||
function waitForMockCall(method: MockedFunction<any>, returnVal?: Promise<any>) {
|
function waitForMockCall(method: MockedFunction<any>, returnVal?: Promise<any>) {
|
||||||
@@ -51,7 +50,7 @@ function waitForMockCallOnce(method: MockedFunction<any>, returnVal?: Promise<an
|
|||||||
}
|
}
|
||||||
|
|
||||||
function createAsyncHandle(method: MockedFunction<any>) {
|
function createAsyncHandle(method: MockedFunction<any>) {
|
||||||
const { reject, resolve, promise } = defer();
|
const { reject, resolve, promise } = Promise.withResolvers<void>();
|
||||||
method.mockImplementation(() => promise);
|
method.mockImplementation(() => promise);
|
||||||
return { reject, resolve };
|
return { reject, resolve };
|
||||||
}
|
}
|
||||||
|
@@ -22,7 +22,6 @@ import { ToDeviceKeyTransport } from "../../../src/matrixrtc/ToDeviceKeyTranspor
|
|||||||
import { getMockClientWithEventEmitter } from "../../test-utils/client.ts";
|
import { getMockClientWithEventEmitter } from "../../test-utils/client.ts";
|
||||||
import { type Statistics } from "../../../src/matrixrtc";
|
import { type Statistics } from "../../../src/matrixrtc";
|
||||||
import { KeyTransportEvents } from "../../../src/matrixrtc/IKeyTransport.ts";
|
import { KeyTransportEvents } from "../../../src/matrixrtc/IKeyTransport.ts";
|
||||||
import { defer } from "../../../src/utils.ts";
|
|
||||||
import { type Logger } from "../../../src/logger.ts";
|
import { type Logger } from "../../../src/logger.ts";
|
||||||
|
|
||||||
describe("ToDeviceKeyTransport", () => {
|
describe("ToDeviceKeyTransport", () => {
|
||||||
@@ -108,9 +107,14 @@ describe("ToDeviceKeyTransport", () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
it("should emit when a key is received", async () => {
|
it("should emit when a key is received", async () => {
|
||||||
const deferred = defer<{ userId: string; deviceId: string; keyBase64Encoded: string; index: number }>();
|
const receivedKeyResolvers = Promise.withResolvers<{
|
||||||
|
userId: string;
|
||||||
|
deviceId: string;
|
||||||
|
keyBase64Encoded: string;
|
||||||
|
index: number;
|
||||||
|
}>();
|
||||||
transport.on(KeyTransportEvents.ReceivedKeys, (userId, deviceId, keyBase64Encoded, index, timestamp) => {
|
transport.on(KeyTransportEvents.ReceivedKeys, (userId, deviceId, keyBase64Encoded, index, timestamp) => {
|
||||||
deferred.resolve({ userId, deviceId, keyBase64Encoded, index });
|
receivedKeyResolvers.resolve({ userId, deviceId, keyBase64Encoded, index });
|
||||||
});
|
});
|
||||||
transport.start();
|
transport.start();
|
||||||
|
|
||||||
@@ -136,7 +140,7 @@ describe("ToDeviceKeyTransport", () => {
|
|||||||
}),
|
}),
|
||||||
);
|
);
|
||||||
|
|
||||||
const { userId, deviceId, keyBase64Encoded, index } = await deferred.promise;
|
const { userId, deviceId, keyBase64Encoded, index } = await receivedKeyResolvers.promise;
|
||||||
expect(userId).toBe("@bob:example.org");
|
expect(userId).toBe("@bob:example.org");
|
||||||
expect(deviceId).toBe("BOBDEVICE");
|
expect(deviceId).toBe("BOBDEVICE");
|
||||||
expect(keyBase64Encoded).toBe(testEncoded);
|
expect(keyBase64Encoded).toBe(testEncoded);
|
||||||
|
@@ -25,7 +25,6 @@ import { EventType, RelationType, UNSTABLE_MSC2716_MARKER } from "../../src/@typ
|
|||||||
import { MatrixEvent, MatrixEventEvent } from "../../src/models/event";
|
import { MatrixEvent, MatrixEventEvent } from "../../src/models/event";
|
||||||
import { M_BEACON } from "../../src/@types/beacon";
|
import { M_BEACON } from "../../src/@types/beacon";
|
||||||
import { type MatrixClient } from "../../src/client";
|
import { type MatrixClient } from "../../src/client";
|
||||||
import { defer } from "../../src/utils";
|
|
||||||
import { Room } from "../../src/models/room";
|
import { Room } from "../../src/models/room";
|
||||||
import { KnownMembership } from "../../src/@types/membership";
|
import { KnownMembership } from "../../src/@types/membership";
|
||||||
import { DecryptionFailureCode } from "../../src/crypto-api";
|
import { DecryptionFailureCode } from "../../src/crypto-api";
|
||||||
@@ -1084,8 +1083,8 @@ describe("RoomState", function () {
|
|||||||
timestamp: Date.now() + 1,
|
timestamp: Date.now() + 1,
|
||||||
});
|
});
|
||||||
|
|
||||||
const deferred = defer<void>();
|
const decryptEventResolvers = Promise.withResolvers<void>();
|
||||||
mockClient.decryptEventIfNeeded.mockReturnValue(deferred.promise);
|
mockClient.decryptEventIfNeeded.mockReturnValue(decryptEventResolvers.promise);
|
||||||
|
|
||||||
state.setStateEvents([beacon1, beacon2]);
|
state.setStateEvents([beacon1, beacon2]);
|
||||||
const beacon = state.beacons.get(getBeaconInfoIdentifier(beacon1)) as Beacon;
|
const beacon = state.beacons.get(getBeaconInfoIdentifier(beacon1)) as Beacon;
|
||||||
@@ -1095,7 +1094,7 @@ describe("RoomState", function () {
|
|||||||
// update type after '''decryption'''
|
// update type after '''decryption'''
|
||||||
decryptingRelatedEvent.event.type = M_BEACON.name;
|
decryptingRelatedEvent.event.type = M_BEACON.name;
|
||||||
decryptingRelatedEvent.event.content = locationEvent.event.content;
|
decryptingRelatedEvent.event.content = locationEvent.event.content;
|
||||||
deferred.resolve();
|
decryptEventResolvers.resolve();
|
||||||
await prom;
|
await prom;
|
||||||
|
|
||||||
expect(addLocationsSpy).toHaveBeenCalledWith([decryptingRelatedEvent]);
|
expect(addLocationsSpy).toHaveBeenCalledWith([decryptingRelatedEvent]);
|
||||||
|
@@ -40,7 +40,6 @@ import {
|
|||||||
type UIAuthCallback,
|
type UIAuthCallback,
|
||||||
} from "../../../src";
|
} from "../../../src";
|
||||||
import { OutgoingRequestProcessor } from "../../../src/rust-crypto/OutgoingRequestProcessor";
|
import { OutgoingRequestProcessor } from "../../../src/rust-crypto/OutgoingRequestProcessor";
|
||||||
import { defer } from "../../../src/utils";
|
|
||||||
|
|
||||||
describe("OutgoingRequestProcessor", () => {
|
describe("OutgoingRequestProcessor", () => {
|
||||||
/** the OutgoingRequestProcessor implementation under test */
|
/** the OutgoingRequestProcessor implementation under test */
|
||||||
@@ -285,13 +284,13 @@ describe("OutgoingRequestProcessor", () => {
|
|||||||
new RustSdkCryptoJs.DeviceId("TEST_DEVICE"),
|
new RustSdkCryptoJs.DeviceId("TEST_DEVICE"),
|
||||||
);
|
);
|
||||||
|
|
||||||
const authRequestResultDefer = defer<string>();
|
const authRequestResultResolvers = Promise.withResolvers<string>();
|
||||||
|
|
||||||
const authRequestCalledPromise = new Promise<void>((resolve) => {
|
const authRequestCalledPromise = new Promise<void>((resolve) => {
|
||||||
const mockHttpApi = {
|
const mockHttpApi = {
|
||||||
authedRequest: async () => {
|
authedRequest: async () => {
|
||||||
resolve();
|
resolve();
|
||||||
return await authRequestResultDefer.promise;
|
return await authRequestResultResolvers.promise;
|
||||||
},
|
},
|
||||||
} as unknown as Mocked<MatrixHttpApi<IHttpOpts & { onlyData: true }>>;
|
} as unknown as Mocked<MatrixHttpApi<IHttpOpts & { onlyData: true }>>;
|
||||||
processor = new OutgoingRequestProcessor(olmMachine, mockHttpApi);
|
processor = new OutgoingRequestProcessor(olmMachine, mockHttpApi);
|
||||||
@@ -308,7 +307,7 @@ describe("OutgoingRequestProcessor", () => {
|
|||||||
olmMachine.close();
|
olmMachine.close();
|
||||||
|
|
||||||
// the HTTP request completes...
|
// the HTTP request completes...
|
||||||
authRequestResultDefer.resolve("{}");
|
authRequestResultResolvers.resolve("{}");
|
||||||
|
|
||||||
// ... and `makeOutgoingRequest` resolves satisfactorily
|
// ... and `makeOutgoingRequest` resolves satisfactorily
|
||||||
await result;
|
await result;
|
||||||
|
@@ -20,7 +20,6 @@ import { type OutgoingRequest } from "@matrix-org/matrix-sdk-crypto-wasm";
|
|||||||
|
|
||||||
import { type OutgoingRequestProcessor } from "../../../src/rust-crypto/OutgoingRequestProcessor";
|
import { type OutgoingRequestProcessor } from "../../../src/rust-crypto/OutgoingRequestProcessor";
|
||||||
import { OutgoingRequestsManager } from "../../../src/rust-crypto/OutgoingRequestsManager";
|
import { OutgoingRequestsManager } from "../../../src/rust-crypto/OutgoingRequestsManager";
|
||||||
import { defer, type IDeferred } from "../../../src/utils";
|
|
||||||
import { logger } from "../../../src/logger";
|
import { logger } from "../../../src/logger";
|
||||||
|
|
||||||
describe("OutgoingRequestsManager", () => {
|
describe("OutgoingRequestsManager", () => {
|
||||||
@@ -70,11 +69,11 @@ describe("OutgoingRequestsManager", () => {
|
|||||||
const request2 = new RustSdkCryptoJs.KeysUploadRequest("foo2", "{}");
|
const request2 = new RustSdkCryptoJs.KeysUploadRequest("foo2", "{}");
|
||||||
const request3 = new RustSdkCryptoJs.KeysBackupRequest("foo3", "{}", "1");
|
const request3 = new RustSdkCryptoJs.KeysBackupRequest("foo3", "{}", "1");
|
||||||
|
|
||||||
const firstOutgoingRequestDefer = defer<OutgoingRequest[]>();
|
const firstOutgoingRequestResolvers = Promise.withResolvers<OutgoingRequest[]>();
|
||||||
|
|
||||||
olmMachine.outgoingRequests
|
olmMachine.outgoingRequests
|
||||||
.mockImplementationOnce(async () => {
|
.mockImplementationOnce(async () => {
|
||||||
return firstOutgoingRequestDefer.promise;
|
return firstOutgoingRequestResolvers.promise;
|
||||||
})
|
})
|
||||||
.mockImplementationOnce(async () => {
|
.mockImplementationOnce(async () => {
|
||||||
return [request3];
|
return [request3];
|
||||||
@@ -87,7 +86,7 @@ describe("OutgoingRequestsManager", () => {
|
|||||||
const thirdRequest = manager.doProcessOutgoingRequests();
|
const thirdRequest = manager.doProcessOutgoingRequests();
|
||||||
|
|
||||||
// let the first request complete
|
// let the first request complete
|
||||||
firstOutgoingRequestDefer.resolve([request1, request2]);
|
firstOutgoingRequestResolvers.resolve([request1, request2]);
|
||||||
|
|
||||||
await firstRequest;
|
await firstRequest;
|
||||||
await secondRequest;
|
await secondRequest;
|
||||||
@@ -112,10 +111,10 @@ describe("OutgoingRequestsManager", () => {
|
|||||||
const outgoingRequestCalledPromises: Promise<void>[] = [];
|
const outgoingRequestCalledPromises: Promise<void>[] = [];
|
||||||
|
|
||||||
// deferreds which will provide the results of OlmMachine.outgoingRequests
|
// deferreds which will provide the results of OlmMachine.outgoingRequests
|
||||||
const outgoingRequestResultDeferreds: IDeferred<OutgoingRequest[]>[] = [];
|
const outgoingRequestResultDeferreds: PromiseWithResolvers<OutgoingRequest[]>[] = [];
|
||||||
|
|
||||||
for (let i = 0; i < 3; i++) {
|
for (let i = 0; i < 3; i++) {
|
||||||
const resultDeferred = defer<OutgoingRequest[]>();
|
const resultDeferred = Promise.withResolvers<OutgoingRequest[]>();
|
||||||
const calledPromise = new Promise<void>((resolve) => {
|
const calledPromise = new Promise<void>((resolve) => {
|
||||||
olmMachine.outgoingRequests.mockImplementationOnce(() => {
|
olmMachine.outgoingRequests.mockImplementationOnce(() => {
|
||||||
resolve();
|
resolve();
|
||||||
@@ -187,10 +186,10 @@ describe("OutgoingRequestsManager", () => {
|
|||||||
it("When the manager is stopped after outgoingRequests() call, do not make sever requests", async () => {
|
it("When the manager is stopped after outgoingRequests() call, do not make sever requests", async () => {
|
||||||
const request1 = new RustSdkCryptoJs.KeysQueryRequest("foo", "{}");
|
const request1 = new RustSdkCryptoJs.KeysQueryRequest("foo", "{}");
|
||||||
|
|
||||||
const firstOutgoingRequestDefer = defer<OutgoingRequest[]>();
|
const firstOutgoingRequestResolvers = Promise.withResolvers<OutgoingRequest[]>();
|
||||||
|
|
||||||
olmMachine.outgoingRequests.mockImplementationOnce(async (): Promise<OutgoingRequest[]> => {
|
olmMachine.outgoingRequests.mockImplementationOnce(async (): Promise<OutgoingRequest[]> => {
|
||||||
return firstOutgoingRequestDefer.promise;
|
return firstOutgoingRequestResolvers.promise;
|
||||||
});
|
});
|
||||||
|
|
||||||
const firstRequest = manager.doProcessOutgoingRequests();
|
const firstRequest = manager.doProcessOutgoingRequests();
|
||||||
@@ -199,7 +198,7 @@ describe("OutgoingRequestsManager", () => {
|
|||||||
manager.stop();
|
manager.stop();
|
||||||
|
|
||||||
// let the first request complete
|
// let the first request complete
|
||||||
firstOutgoingRequestDefer.resolve([request1]);
|
firstOutgoingRequestResolvers.resolve([request1]);
|
||||||
|
|
||||||
await firstRequest;
|
await firstRequest;
|
||||||
|
|
||||||
@@ -210,7 +209,7 @@ describe("OutgoingRequestsManager", () => {
|
|||||||
const request1 = new RustSdkCryptoJs.KeysQueryRequest("11", "{}");
|
const request1 = new RustSdkCryptoJs.KeysQueryRequest("11", "{}");
|
||||||
const request2 = new RustSdkCryptoJs.KeysUploadRequest("12", "{}");
|
const request2 = new RustSdkCryptoJs.KeysUploadRequest("12", "{}");
|
||||||
|
|
||||||
const firstRequestDefer = defer<void>();
|
const firstRequestResolvers = Promise.withResolvers<void>();
|
||||||
|
|
||||||
olmMachine.outgoingRequests.mockImplementationOnce(async (): Promise<OutgoingRequest[]> => {
|
olmMachine.outgoingRequests.mockImplementationOnce(async (): Promise<OutgoingRequest[]> => {
|
||||||
return [request1, request2];
|
return [request1, request2];
|
||||||
@@ -219,7 +218,7 @@ describe("OutgoingRequestsManager", () => {
|
|||||||
processor.makeOutgoingRequest
|
processor.makeOutgoingRequest
|
||||||
.mockImplementationOnce(async () => {
|
.mockImplementationOnce(async () => {
|
||||||
manager.stop();
|
manager.stop();
|
||||||
return firstRequestDefer.promise;
|
return firstRequestResolvers.promise;
|
||||||
})
|
})
|
||||||
.mockImplementationOnce(async () => {
|
.mockImplementationOnce(async () => {
|
||||||
return;
|
return;
|
||||||
@@ -227,7 +226,7 @@ describe("OutgoingRequestsManager", () => {
|
|||||||
|
|
||||||
const firstRequest = manager.doProcessOutgoingRequests();
|
const firstRequest = manager.doProcessOutgoingRequests();
|
||||||
|
|
||||||
firstRequestDefer.resolve();
|
firstRequestResolvers.resolve();
|
||||||
|
|
||||||
await firstRequest;
|
await firstRequest;
|
||||||
|
|
||||||
|
@@ -21,7 +21,6 @@ import fetchMock from "fetch-mock-jest";
|
|||||||
|
|
||||||
import { PerSessionKeyBackupDownloader } from "../../../src/rust-crypto/PerSessionKeyBackupDownloader";
|
import { PerSessionKeyBackupDownloader } from "../../../src/rust-crypto/PerSessionKeyBackupDownloader";
|
||||||
import { logger } from "../../../src/logger";
|
import { logger } from "../../../src/logger";
|
||||||
import { defer, type IDeferred } from "../../../src/utils";
|
|
||||||
import {
|
import {
|
||||||
type RustBackupCryptoEventMap,
|
type RustBackupCryptoEventMap,
|
||||||
type RustBackupCryptoEvents,
|
type RustBackupCryptoEvents,
|
||||||
@@ -57,15 +56,15 @@ describe("PerSessionKeyBackupDownloader", () => {
|
|||||||
let mockOlmMachine: Mocked<OlmMachine>;
|
let mockOlmMachine: Mocked<OlmMachine>;
|
||||||
let mockBackupDecryptor: Mocked<BackupDecryptor>;
|
let mockBackupDecryptor: Mocked<BackupDecryptor>;
|
||||||
|
|
||||||
let expectedSession: { [roomId: string]: { [sessionId: string]: IDeferred<void> } };
|
let expectedSession: { [roomId: string]: { [sessionId: string]: PromiseWithResolvers<void> } };
|
||||||
|
|
||||||
function expectSessionImported(roomId: string, sessionId: string) {
|
function expectSessionImported(roomId: string, sessionId: string) {
|
||||||
const deferred = defer<void>();
|
const sessionImportedResolvers = Promise.withResolvers<void>();
|
||||||
if (!expectedSession[roomId]) {
|
if (!expectedSession[roomId]) {
|
||||||
expectedSession[roomId] = {};
|
expectedSession[roomId] = {};
|
||||||
}
|
}
|
||||||
expectedSession[roomId][sessionId] = deferred;
|
expectedSession[roomId][sessionId] = sessionImportedResolvers;
|
||||||
return deferred.promise;
|
return sessionImportedResolvers.promise;
|
||||||
}
|
}
|
||||||
|
|
||||||
function mockClearSession(sessionId: string): Mocked<IMegolmSessionData> {
|
function mockClearSession(sessionId: string): Mocked<IMegolmSessionData> {
|
||||||
@@ -115,9 +114,9 @@ describe("PerSessionKeyBackupDownloader", () => {
|
|||||||
mockRustBackupManager.importBackedUpRoomKeys.mockImplementation(async (keys) => {
|
mockRustBackupManager.importBackedUpRoomKeys.mockImplementation(async (keys) => {
|
||||||
const roomId = keys[0].room_id;
|
const roomId = keys[0].room_id;
|
||||||
const sessionId = keys[0].session_id;
|
const sessionId = keys[0].session_id;
|
||||||
const deferred = expectedSession[roomId] && expectedSession[roomId][sessionId];
|
const sessionImportedResolvers = expectedSession[roomId] && expectedSession[roomId][sessionId];
|
||||||
if (deferred) {
|
if (sessionImportedResolvers) {
|
||||||
deferred.resolve();
|
sessionImportedResolvers.resolve();
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -143,7 +142,7 @@ describe("PerSessionKeyBackupDownloader", () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
it("Should download and import a missing key from backup", async () => {
|
it("Should download and import a missing key from backup", async () => {
|
||||||
const awaitKeyImported = defer<void>();
|
const awaitKeyImported = Promise.withResolvers<void>();
|
||||||
const roomId = "!roomId";
|
const roomId = "!roomId";
|
||||||
const sessionId = "sessionId";
|
const sessionId = "sessionId";
|
||||||
const expectAPICall = new Promise<void>((resolve) => {
|
const expectAPICall = new Promise<void>((resolve) => {
|
||||||
@@ -168,14 +167,14 @@ describe("PerSessionKeyBackupDownloader", () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
it("Should not hammer the backup if the key is requested repeatedly", async () => {
|
it("Should not hammer the backup if the key is requested repeatedly", async () => {
|
||||||
const blockOnServerRequest = defer<void>();
|
const blockOnServerRequest = Promise.withResolvers<void>();
|
||||||
|
|
||||||
fetchMock.get(`express:/_matrix/client/v3/room_keys/keys/!roomId/:session_id`, async (url, request) => {
|
fetchMock.get(`express:/_matrix/client/v3/room_keys/keys/!roomId/:session_id`, async (url, request) => {
|
||||||
await blockOnServerRequest.promise;
|
await blockOnServerRequest.promise;
|
||||||
return [mockCipherKey];
|
return [mockCipherKey];
|
||||||
});
|
});
|
||||||
|
|
||||||
const awaitKey2Imported = defer<void>();
|
const awaitKey2Imported = Promise.withResolvers<void>();
|
||||||
|
|
||||||
mockRustBackupManager.importBackedUpRoomKeys.mockImplementation(async (keys) => {
|
mockRustBackupManager.importBackedUpRoomKeys.mockImplementation(async (keys) => {
|
||||||
if (keys[0].session_id === "sessionId2") {
|
if (keys[0].session_id === "sessionId2") {
|
||||||
@@ -267,8 +266,8 @@ describe("PerSessionKeyBackupDownloader", () => {
|
|||||||
|
|
||||||
it("Should stop properly", async () => {
|
it("Should stop properly", async () => {
|
||||||
// Simulate a call to stop while request is in flight
|
// Simulate a call to stop while request is in flight
|
||||||
const blockOnServerRequest = defer<void>();
|
const blockOnServerRequest = Promise.withResolvers<void>();
|
||||||
const requestRoomKeyCalled = defer<void>();
|
const requestRoomKeyCalled = Promise.withResolvers<void>();
|
||||||
|
|
||||||
// Mock the request to block
|
// Mock the request to block
|
||||||
fetchMock.get(`express:/_matrix/client/v3/room_keys/keys/:roomId/:sessionId`, async (url, request) => {
|
fetchMock.get(`express:/_matrix/client/v3/room_keys/keys/:roomId/:sessionId`, async (url, request) => {
|
||||||
@@ -490,7 +489,7 @@ describe("PerSessionKeyBackupDownloader", () => {
|
|||||||
|
|
||||||
// @ts-ignore access to private function
|
// @ts-ignore access to private function
|
||||||
const keyQuerySpy: SpyInstance = jest.spyOn(downloader, "queryKeyBackup");
|
const keyQuerySpy: SpyInstance = jest.spyOn(downloader, "queryKeyBackup");
|
||||||
const rateDeferred = defer<void>();
|
const rateDeferred = Promise.withResolvers<void>();
|
||||||
|
|
||||||
keyQuerySpy.mockImplementation(
|
keyQuerySpy.mockImplementation(
|
||||||
// @ts-ignore
|
// @ts-ignore
|
||||||
@@ -544,7 +543,7 @@ describe("PerSessionKeyBackupDownloader", () => {
|
|||||||
|
|
||||||
// @ts-ignore
|
// @ts-ignore
|
||||||
const keyQuerySpy: SpyInstance = jest.spyOn(downloader, "queryKeyBackup");
|
const keyQuerySpy: SpyInstance = jest.spyOn(downloader, "queryKeyBackup");
|
||||||
const errorDeferred = defer<void>();
|
const errorDeferred = Promise.withResolvers<void>();
|
||||||
|
|
||||||
keyQuerySpy.mockImplementation(
|
keyQuerySpy.mockImplementation(
|
||||||
// @ts-ignore
|
// @ts-ignore
|
||||||
@@ -588,7 +587,7 @@ describe("PerSessionKeyBackupDownloader", () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
it("On Unknown error on import skip the key and continue", async () => {
|
it("On Unknown error on import skip the key and continue", async () => {
|
||||||
const keyImported = defer<void>();
|
const keyImported = Promise.withResolvers<void>();
|
||||||
mockRustBackupManager.importBackedUpRoomKeys
|
mockRustBackupManager.importBackedUpRoomKeys
|
||||||
.mockImplementationOnce(async () => {
|
.mockImplementationOnce(async () => {
|
||||||
throw new Error("Didn't work");
|
throw new Error("Didn't work");
|
||||||
|
@@ -29,7 +29,6 @@ import { type Mocked } from "jest-mock";
|
|||||||
import { HistoryVisibility, type MatrixEvent, type Room, type RoomMember } from "../../../src";
|
import { HistoryVisibility, type MatrixEvent, type Room, type RoomMember } from "../../../src";
|
||||||
import { RoomEncryptor, toRustHistoryVisibility } from "../../../src/rust-crypto/RoomEncryptor";
|
import { RoomEncryptor, toRustHistoryVisibility } from "../../../src/rust-crypto/RoomEncryptor";
|
||||||
import { type KeyClaimManager } from "../../../src/rust-crypto/KeyClaimManager";
|
import { type KeyClaimManager } from "../../../src/rust-crypto/KeyClaimManager";
|
||||||
import { defer } from "../../../src/utils";
|
|
||||||
import { type OutgoingRequestsManager } from "../../../src/rust-crypto/OutgoingRequestsManager";
|
import { type OutgoingRequestsManager } from "../../../src/rust-crypto/OutgoingRequestsManager";
|
||||||
import { KnownMembership } from "../../../src/@types/membership";
|
import { KnownMembership } from "../../../src/@types/membership";
|
||||||
import {
|
import {
|
||||||
@@ -120,8 +119,8 @@ describe("RoomEncryptor", () => {
|
|||||||
const defaultDevicesIsolationMode = new AllDevicesIsolationMode(false);
|
const defaultDevicesIsolationMode = new AllDevicesIsolationMode(false);
|
||||||
|
|
||||||
it("should ensure that there is only one shareRoomKey at a time", async () => {
|
it("should ensure that there is only one shareRoomKey at a time", async () => {
|
||||||
const deferredShare = defer<void>();
|
const deferredShare = Promise.withResolvers<void>();
|
||||||
const insideOlmShareRoom = defer<void>();
|
const insideOlmShareRoom = Promise.withResolvers<void>();
|
||||||
|
|
||||||
mockOlmMachine.shareRoomKey.mockImplementationOnce(async () => {
|
mockOlmMachine.shareRoomKey.mockImplementationOnce(async () => {
|
||||||
insideOlmShareRoom.resolve();
|
insideOlmShareRoom.resolve();
|
||||||
@@ -149,8 +148,8 @@ describe("RoomEncryptor", () => {
|
|||||||
|
|
||||||
// Regression test for https://github.com/element-hq/element-web/issues/26684
|
// Regression test for https://github.com/element-hq/element-web/issues/26684
|
||||||
it("Should maintain order of encryption requests", async () => {
|
it("Should maintain order of encryption requests", async () => {
|
||||||
const firstTargetMembers = defer<void>();
|
const firstTargetMembers = Promise.withResolvers<void>();
|
||||||
const secondTargetMembers = defer<void>();
|
const secondTargetMembers = Promise.withResolvers<void>();
|
||||||
|
|
||||||
mockOlmMachine.shareRoomKey.mockResolvedValue([]);
|
mockOlmMachine.shareRoomKey.mockResolvedValue([]);
|
||||||
|
|
||||||
|
@@ -68,7 +68,6 @@ import {
|
|||||||
import * as testData from "../../test-utils/test-data";
|
import * as testData from "../../test-utils/test-data";
|
||||||
import { E2EKeyReceiver } from "../../test-utils/E2EKeyReceiver";
|
import { E2EKeyReceiver } from "../../test-utils/E2EKeyReceiver";
|
||||||
import { E2EKeyResponder } from "../../test-utils/E2EKeyResponder";
|
import { E2EKeyResponder } from "../../test-utils/E2EKeyResponder";
|
||||||
import { defer } from "../../../src/utils";
|
|
||||||
import { logger } from "../../../src/logger";
|
import { logger } from "../../../src/logger";
|
||||||
import { OutgoingRequestsManager } from "../../../src/rust-crypto/OutgoingRequestsManager";
|
import { OutgoingRequestsManager } from "../../../src/rust-crypto/OutgoingRequestsManager";
|
||||||
import { ClientEvent, type ClientEventHandlerMap } from "../../../src/client";
|
import { ClientEvent, type ClientEventHandlerMap } from "../../../src/client";
|
||||||
@@ -928,8 +927,8 @@ describe("RustCrypto", () => {
|
|||||||
|
|
||||||
it("should go round the loop again if another sync completes while the first `outgoingRequests` is running", async () => {
|
it("should go round the loop again if another sync completes while the first `outgoingRequests` is running", async () => {
|
||||||
// the first call to `outgoingMessages` will return a promise which blocks for a while
|
// the first call to `outgoingMessages` will return a promise which blocks for a while
|
||||||
const firstOutgoingRequestsDefer = defer<Array<any>>();
|
const firstOutgoingRequestsResolvers = Promise.withResolvers<Array<any>>();
|
||||||
mocked(olmMachine.outgoingRequests).mockReturnValueOnce(firstOutgoingRequestsDefer.promise);
|
mocked(olmMachine.outgoingRequests).mockReturnValueOnce(firstOutgoingRequestsResolvers.promise);
|
||||||
|
|
||||||
// the second will return a KeysQueryRequest.
|
// the second will return a KeysQueryRequest.
|
||||||
const testReq = new KeysQueryRequest("1234", "{}");
|
const testReq = new KeysQueryRequest("1234", "{}");
|
||||||
@@ -946,7 +945,7 @@ describe("RustCrypto", () => {
|
|||||||
|
|
||||||
// the first call now completes, *with an empty result*, which would normally cause us to exit the loop, but
|
// the first call now completes, *with an empty result*, which would normally cause us to exit the loop, but
|
||||||
// we should have a second call queued. It should trigger a call to `makeOutgoingRequest`.
|
// we should have a second call queued. It should trigger a call to `makeOutgoingRequest`.
|
||||||
firstOutgoingRequestsDefer.resolve([]);
|
firstOutgoingRequestsResolvers.resolve([]);
|
||||||
await awaitCallToMakeOutgoingRequest();
|
await awaitCallToMakeOutgoingRequest();
|
||||||
expect(olmMachine.outgoingRequests).toHaveBeenCalledTimes(2);
|
expect(olmMachine.outgoingRequests).toHaveBeenCalledTimes(2);
|
||||||
});
|
});
|
||||||
|
@@ -1,7 +1,6 @@
|
|||||||
// This file had a function whose name is all caps, which displeases eslint
|
// This file had a function whose name is all caps, which displeases eslint
|
||||||
/* eslint new-cap: "off" */
|
/* eslint new-cap: "off" */
|
||||||
|
|
||||||
import { defer, type IDeferred } from "../../src/utils";
|
|
||||||
import { MatrixError } from "../../src/http-api";
|
import { MatrixError } from "../../src/http-api";
|
||||||
import { MatrixScheduler } from "../../src/scheduler";
|
import { MatrixScheduler } from "../../src/scheduler";
|
||||||
import * as utils from "../test-utils/test-utils";
|
import * as utils from "../test-utils/test-utils";
|
||||||
@@ -14,7 +13,7 @@ describe("MatrixScheduler", function () {
|
|||||||
let scheduler: MatrixScheduler<Record<string, boolean>>;
|
let scheduler: MatrixScheduler<Record<string, boolean>>;
|
||||||
let retryFn: ((event: MatrixEvent | null, attempt: number, err: MatrixError) => number) | null;
|
let retryFn: ((event: MatrixEvent | null, attempt: number, err: MatrixError) => number) | null;
|
||||||
let queueFn: ((event: MatrixEvent) => string | null) | null;
|
let queueFn: ((event: MatrixEvent) => string | null) | null;
|
||||||
let deferred: IDeferred<Record<string, boolean>>;
|
let deferred: PromiseWithResolvers<Record<string, boolean>>;
|
||||||
const roomId = "!foo:bar";
|
const roomId = "!foo:bar";
|
||||||
const eventA = utils.mkMessage({
|
const eventA = utils.mkMessage({
|
||||||
user: "@alice:bar",
|
user: "@alice:bar",
|
||||||
@@ -44,7 +43,7 @@ describe("MatrixScheduler", function () {
|
|||||||
);
|
);
|
||||||
retryFn = null;
|
retryFn = null;
|
||||||
queueFn = null;
|
queueFn = null;
|
||||||
deferred = defer();
|
deferred = Promise.withResolvers();
|
||||||
});
|
});
|
||||||
|
|
||||||
it("should process events in a queue in a FIFO manner", async function () {
|
it("should process events in a queue in a FIFO manner", async function () {
|
||||||
@@ -54,8 +53,8 @@ describe("MatrixScheduler", function () {
|
|||||||
queueFn = function () {
|
queueFn = function () {
|
||||||
return "one_big_queue";
|
return "one_big_queue";
|
||||||
};
|
};
|
||||||
const deferA = defer<Record<string, boolean>>();
|
const deferA = Promise.withResolvers<Record<string, boolean>>();
|
||||||
const deferB = defer<Record<string, boolean>>();
|
const deferB = Promise.withResolvers<Record<string, boolean>>();
|
||||||
let yieldedA = false;
|
let yieldedA = false;
|
||||||
scheduler.setProcessFunction(function (event) {
|
scheduler.setProcessFunction(function (event) {
|
||||||
if (yieldedA) {
|
if (yieldedA) {
|
||||||
@@ -79,9 +78,9 @@ describe("MatrixScheduler", function () {
|
|||||||
|
|
||||||
it("should invoke the retryFn on failure and wait the amount of time specified", async function () {
|
it("should invoke the retryFn on failure and wait the amount of time specified", async function () {
|
||||||
const waitTimeMs = 1500;
|
const waitTimeMs = 1500;
|
||||||
const retryDefer = defer();
|
const retryResolvers = Promise.withResolvers<void>();
|
||||||
retryFn = function () {
|
retryFn = function () {
|
||||||
retryDefer.resolve();
|
retryResolvers.resolve();
|
||||||
return waitTimeMs;
|
return waitTimeMs;
|
||||||
};
|
};
|
||||||
queueFn = function () {
|
queueFn = function () {
|
||||||
@@ -109,7 +108,7 @@ describe("MatrixScheduler", function () {
|
|||||||
await Promise.resolve();
|
await Promise.resolve();
|
||||||
expect(procCount).toEqual(1);
|
expect(procCount).toEqual(1);
|
||||||
deferred.reject({});
|
deferred.reject({});
|
||||||
await retryDefer.promise;
|
await retryResolvers.promise;
|
||||||
expect(procCount).toEqual(1);
|
expect(procCount).toEqual(1);
|
||||||
jest.advanceTimersByTime(waitTimeMs);
|
jest.advanceTimersByTime(waitTimeMs);
|
||||||
await Promise.resolve();
|
await Promise.resolve();
|
||||||
@@ -127,8 +126,8 @@ describe("MatrixScheduler", function () {
|
|||||||
return "yep";
|
return "yep";
|
||||||
};
|
};
|
||||||
|
|
||||||
const deferA = defer<Record<string, boolean>>();
|
const deferA = Promise.withResolvers<Record<string, boolean>>();
|
||||||
const deferB = defer<Record<string, boolean>>();
|
const deferB = Promise.withResolvers<Record<string, boolean>>();
|
||||||
let procCount = 0;
|
let procCount = 0;
|
||||||
scheduler.setProcessFunction(function (ev) {
|
scheduler.setProcessFunction(function (ev) {
|
||||||
procCount += 1;
|
procCount += 1;
|
||||||
@@ -180,7 +179,7 @@ describe("MatrixScheduler", function () {
|
|||||||
};
|
};
|
||||||
|
|
||||||
const expectOrder = [eventA.getId(), eventB.getId(), eventD.getId()];
|
const expectOrder = [eventA.getId(), eventB.getId(), eventD.getId()];
|
||||||
const deferA = defer<Record<string, boolean>>();
|
const deferA = Promise.withResolvers<Record<string, boolean>>();
|
||||||
const allExpectedEventsSeenInOrderPromise = new Promise((resolve) => {
|
const allExpectedEventsSeenInOrderPromise = new Promise((resolve) => {
|
||||||
scheduler.setProcessFunction(function (event) {
|
scheduler.setProcessFunction(function (event) {
|
||||||
const id = expectOrder.shift();
|
const id = expectOrder.shift();
|
||||||
|
@@ -30,7 +30,6 @@ import {
|
|||||||
import { secureRandomString } from "../../src/randomstring";
|
import { secureRandomString } from "../../src/randomstring";
|
||||||
import { type SecretInfo } from "../../src/secret-storage.ts";
|
import { type SecretInfo } from "../../src/secret-storage.ts";
|
||||||
import { type AccountDataEvents, ClientEvent, MatrixEvent, TypedEventEmitter } from "../../src";
|
import { type AccountDataEvents, ClientEvent, MatrixEvent, TypedEventEmitter } from "../../src";
|
||||||
import { defer, type IDeferred } from "../../src/utils";
|
|
||||||
|
|
||||||
declare module "../../src/@types/event" {
|
declare module "../../src/@types/event" {
|
||||||
interface SecretStorageAccountDataEvents {
|
interface SecretStorageAccountDataEvents {
|
||||||
@@ -289,10 +288,10 @@ describe("ServerSideSecretStorageImpl", function () {
|
|||||||
describe("setDefaultKeyId", function () {
|
describe("setDefaultKeyId", function () {
|
||||||
let secretStorage: ServerSideSecretStorage;
|
let secretStorage: ServerSideSecretStorage;
|
||||||
let accountDataAdapter: Mocked<AccountDataClient>;
|
let accountDataAdapter: Mocked<AccountDataClient>;
|
||||||
let accountDataPromise: IDeferred<void>;
|
let accountDataPromise: PromiseWithResolvers<void>;
|
||||||
beforeEach(() => {
|
beforeEach(() => {
|
||||||
accountDataAdapter = mockAccountDataClient();
|
accountDataAdapter = mockAccountDataClient();
|
||||||
accountDataPromise = defer();
|
accountDataPromise = Promise.withResolvers();
|
||||||
accountDataAdapter.setAccountData.mockImplementation(() => {
|
accountDataAdapter.setAccountData.mockImplementation(() => {
|
||||||
accountDataPromise.resolve();
|
accountDataPromise.resolve();
|
||||||
return Promise.resolve({});
|
return Promise.resolve({});
|
||||||
|
@@ -18,7 +18,6 @@ import "fake-indexeddb/auto";
|
|||||||
|
|
||||||
import { type LocalIndexedDBStoreBackend } from "../../../src/store/indexeddb-local-backend";
|
import { type LocalIndexedDBStoreBackend } from "../../../src/store/indexeddb-local-backend";
|
||||||
import { IndexedDBStoreWorker } from "../../../src/store/indexeddb-store-worker";
|
import { IndexedDBStoreWorker } from "../../../src/store/indexeddb-store-worker";
|
||||||
import { defer } from "../../../src/utils";
|
|
||||||
|
|
||||||
function setupWorker(worker: IndexedDBStoreWorker): void {
|
function setupWorker(worker: IndexedDBStoreWorker): void {
|
||||||
worker.onMessage({ data: { command: "setupWorker", args: [] } } as any);
|
worker.onMessage({ data: { command: "setupWorker", args: [] } } as any);
|
||||||
@@ -27,16 +26,16 @@ function setupWorker(worker: IndexedDBStoreWorker): void {
|
|||||||
|
|
||||||
describe("IndexedDBStore Worker", () => {
|
describe("IndexedDBStore Worker", () => {
|
||||||
it("should pass 'closed' event via postMessage", async () => {
|
it("should pass 'closed' event via postMessage", async () => {
|
||||||
const deferred = defer<void>();
|
const postMessageSuccessResolvers = Promise.withResolvers<void>();
|
||||||
const postMessage = jest.fn().mockImplementation(({ seq, command }) => {
|
const postMessage = jest.fn().mockImplementation(({ seq, command }) => {
|
||||||
if (seq === 1 && command === "cmd_success") {
|
if (seq === 1 && command === "cmd_success") {
|
||||||
deferred.resolve();
|
postMessageSuccessResolvers.resolve();
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
const worker = new IndexedDBStoreWorker(postMessage);
|
const worker = new IndexedDBStoreWorker(postMessage);
|
||||||
setupWorker(worker);
|
setupWorker(worker);
|
||||||
|
|
||||||
await deferred.promise;
|
await postMessageSuccessResolvers.promise;
|
||||||
|
|
||||||
// @ts-ignore - private field access
|
// @ts-ignore - private field access
|
||||||
(worker.backend as LocalIndexedDBStoreBackend).db!.onclose!({} as Event);
|
(worker.backend as LocalIndexedDBStoreBackend).db!.onclose!({} as Event);
|
||||||
|
@@ -21,7 +21,6 @@ import { IDBFactory } from "fake-indexeddb";
|
|||||||
import { IndexedDBStore, type IStateEventWithRoomId, MemoryStore, User, UserEvent } from "../../../src";
|
import { IndexedDBStore, type IStateEventWithRoomId, MemoryStore, User, UserEvent } from "../../../src";
|
||||||
import { emitPromise } from "../../test-utils/test-utils";
|
import { emitPromise } from "../../test-utils/test-utils";
|
||||||
import { type LocalIndexedDBStoreBackend } from "../../../src/store/indexeddb-local-backend";
|
import { type LocalIndexedDBStoreBackend } from "../../../src/store/indexeddb-local-backend";
|
||||||
import { defer } from "../../../src/utils";
|
|
||||||
|
|
||||||
describe("IndexedDBStore", () => {
|
describe("IndexedDBStore", () => {
|
||||||
afterEach(() => {
|
afterEach(() => {
|
||||||
@@ -80,7 +79,7 @@ describe("IndexedDBStore", () => {
|
|||||||
it("Should load presence events on startup", async () => {
|
it("Should load presence events on startup", async () => {
|
||||||
// 1. Create idb database
|
// 1. Create idb database
|
||||||
const indexedDB = new IDBFactory();
|
const indexedDB = new IDBFactory();
|
||||||
const setupDefer = defer<Event>();
|
const setupResolvers = Promise.withResolvers<Event>();
|
||||||
const req = indexedDB.open("matrix-js-sdk:db3", 1);
|
const req = indexedDB.open("matrix-js-sdk:db3", 1);
|
||||||
let db: IDBDatabase;
|
let db: IDBDatabase;
|
||||||
req.onupgradeneeded = () => {
|
req.onupgradeneeded = () => {
|
||||||
@@ -89,11 +88,11 @@ describe("IndexedDBStore", () => {
|
|||||||
db.createObjectStore("accountData", { keyPath: ["type"] });
|
db.createObjectStore("accountData", { keyPath: ["type"] });
|
||||||
db.createObjectStore("sync", { keyPath: ["clobber"] });
|
db.createObjectStore("sync", { keyPath: ["clobber"] });
|
||||||
};
|
};
|
||||||
req.onsuccess = setupDefer.resolve;
|
req.onsuccess = setupResolvers.resolve;
|
||||||
await setupDefer.promise;
|
await setupResolvers.promise;
|
||||||
|
|
||||||
// 2. Fill in user presence data
|
// 2. Fill in user presence data
|
||||||
const writeDefer = defer<Event>();
|
const writeResolvers = Promise.withResolvers<Event>();
|
||||||
const transaction = db!.transaction(["users"], "readwrite");
|
const transaction = db!.transaction(["users"], "readwrite");
|
||||||
const objectStore = transaction.objectStore("users");
|
const objectStore = transaction.objectStore("users");
|
||||||
const request = objectStore.put({
|
const request = objectStore.put({
|
||||||
@@ -106,8 +105,8 @@ describe("IndexedDBStore", () => {
|
|||||||
type: "m.presence",
|
type: "m.presence",
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
request.onsuccess = writeDefer.resolve;
|
request.onsuccess = writeResolvers.resolve;
|
||||||
await writeDefer.promise;
|
await writeResolvers.promise;
|
||||||
|
|
||||||
// 3. Close database
|
// 3. Close database
|
||||||
req.result.close();
|
req.result.close();
|
||||||
@@ -201,7 +200,7 @@ describe("IndexedDBStore", () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
it("should resolve isNewlyCreated to false if database existed already but needs upgrade", async () => {
|
it("should resolve isNewlyCreated to false if database existed already but needs upgrade", async () => {
|
||||||
const deferred = defer<Event>();
|
const requestSuccessResolvers = Promise.withResolvers<Event>();
|
||||||
// seed db3 to Version 1 so it forces a migration
|
// seed db3 to Version 1 so it forces a migration
|
||||||
const req = indexedDB.open("matrix-js-sdk:db3", 1);
|
const req = indexedDB.open("matrix-js-sdk:db3", 1);
|
||||||
req.onupgradeneeded = () => {
|
req.onupgradeneeded = () => {
|
||||||
@@ -210,8 +209,8 @@ describe("IndexedDBStore", () => {
|
|||||||
db.createObjectStore("accountData", { keyPath: ["type"] });
|
db.createObjectStore("accountData", { keyPath: ["type"] });
|
||||||
db.createObjectStore("sync", { keyPath: ["clobber"] });
|
db.createObjectStore("sync", { keyPath: ["clobber"] });
|
||||||
};
|
};
|
||||||
req.onsuccess = deferred.resolve;
|
req.onsuccess = requestSuccessResolvers.resolve;
|
||||||
await deferred.promise;
|
await requestSuccessResolvers.promise;
|
||||||
req.result.close();
|
req.result.close();
|
||||||
|
|
||||||
const store = new IndexedDBStore({
|
const store = new IndexedDBStore({
|
||||||
@@ -232,20 +231,20 @@ describe("IndexedDBStore", () => {
|
|||||||
});
|
});
|
||||||
await store.startup();
|
await store.startup();
|
||||||
|
|
||||||
const deferred = defer<void>();
|
const storeClosedResolvers = Promise.withResolvers<void>();
|
||||||
store.on("closed", deferred.resolve);
|
store.on("closed", storeClosedResolvers.resolve);
|
||||||
|
|
||||||
// @ts-ignore - private field access
|
// @ts-ignore - private field access
|
||||||
(store.backend as LocalIndexedDBStoreBackend).db!.onclose!({} as Event);
|
(store.backend as LocalIndexedDBStoreBackend).db!.onclose!({} as Event);
|
||||||
await deferred.promise;
|
await storeClosedResolvers.promise;
|
||||||
});
|
});
|
||||||
|
|
||||||
it("should use remote backend if workerFactory passed", async () => {
|
it("should use remote backend if workerFactory passed", async () => {
|
||||||
const deferred = defer<void>();
|
const workerPostMessageResolvers = Promise.withResolvers<void>();
|
||||||
class MockWorker {
|
class MockWorker {
|
||||||
postMessage(data: any) {
|
postMessage(data: any) {
|
||||||
if (data.command === "setupWorker") {
|
if (data.command === "setupWorker") {
|
||||||
deferred.resolve();
|
workerPostMessageResolvers.resolve();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -257,7 +256,7 @@ describe("IndexedDBStore", () => {
|
|||||||
workerFactory: () => new MockWorker() as Worker,
|
workerFactory: () => new MockWorker() as Worker,
|
||||||
});
|
});
|
||||||
store.startup();
|
store.startup();
|
||||||
await deferred.promise;
|
await workerPostMessageResolvers.promise;
|
||||||
});
|
});
|
||||||
|
|
||||||
it("remote worker should pass closed event", async () => {
|
it("remote worker should pass closed event", async () => {
|
||||||
@@ -273,10 +272,10 @@ describe("IndexedDBStore", () => {
|
|||||||
});
|
});
|
||||||
store.startup();
|
store.startup();
|
||||||
|
|
||||||
const deferred = defer<void>();
|
const storeClosedResolvers = Promise.withResolvers<void>();
|
||||||
store.on("closed", deferred.resolve);
|
store.on("closed", storeClosedResolvers.resolve);
|
||||||
(worker as any).onmessage({ data: { command: "closed" } });
|
(worker as any).onmessage({ data: { command: "closed" } });
|
||||||
await deferred.promise;
|
await storeClosedResolvers.promise;
|
||||||
});
|
});
|
||||||
|
|
||||||
it("remote worker should pass command failures", async () => {
|
it("remote worker should pass command failures", async () => {
|
||||||
|
@@ -52,7 +52,7 @@ import {
|
|||||||
type GroupCallEventHandlerEventHandlerMap,
|
type GroupCallEventHandlerEventHandlerMap,
|
||||||
} from "./webrtc/groupCallEventHandler.ts";
|
} from "./webrtc/groupCallEventHandler.ts";
|
||||||
import * as utils from "./utils.ts";
|
import * as utils from "./utils.ts";
|
||||||
import { deepCompare, defer, noUnsafeEventProps, type QueryDict, replaceParam, safeSet, sleep } from "./utils.ts";
|
import { deepCompare, noUnsafeEventProps, type QueryDict, replaceParam, safeSet, sleep } from "./utils.ts";
|
||||||
import { Direction, EventTimeline } from "./models/event-timeline.ts";
|
import { Direction, EventTimeline } from "./models/event-timeline.ts";
|
||||||
import { type IActionsObject, PushProcessor } from "./pushprocessor.ts";
|
import { type IActionsObject, PushProcessor } from "./pushprocessor.ts";
|
||||||
import { AutoDiscovery, type AutoDiscoveryAction } from "./autodiscovery.ts";
|
import { AutoDiscovery, type AutoDiscoveryAction } from "./autodiscovery.ts";
|
||||||
@@ -2191,7 +2191,7 @@ export class MatrixClient extends TypedEventEmitter<EmittedEvents, ClientEventHa
|
|||||||
if (existingData && deepCompare(existingData.event.content, content)) return {};
|
if (existingData && deepCompare(existingData.event.content, content)) return {};
|
||||||
|
|
||||||
// Create a promise which will resolve when the update is received
|
// Create a promise which will resolve when the update is received
|
||||||
const updatedDefer = defer<void>();
|
const updatedResolvers = Promise.withResolvers<void>();
|
||||||
function accountDataListener(event: MatrixEvent): void {
|
function accountDataListener(event: MatrixEvent): void {
|
||||||
// Note that we cannot safely check that the content matches what we expected, because there is a race:
|
// Note that we cannot safely check that the content matches what we expected, because there is a race:
|
||||||
// * We set the new content
|
// * We set the new content
|
||||||
@@ -2203,13 +2203,13 @@ export class MatrixClient extends TypedEventEmitter<EmittedEvents, ClientEventHa
|
|||||||
//
|
//
|
||||||
// Anyway, what we *shouldn't* do is get stuck in a loop. I think the best we can do is check that the event
|
// Anyway, what we *shouldn't* do is get stuck in a loop. I think the best we can do is check that the event
|
||||||
// type matches.
|
// type matches.
|
||||||
if (event.getType() === eventType) updatedDefer.resolve();
|
if (event.getType() === eventType) updatedResolvers.resolve();
|
||||||
}
|
}
|
||||||
this.addListener(ClientEvent.AccountData, accountDataListener);
|
this.addListener(ClientEvent.AccountData, accountDataListener);
|
||||||
|
|
||||||
try {
|
try {
|
||||||
const result = await retryNetworkOperation(5, () => this.setAccountDataRaw(eventType, content));
|
const result = await retryNetworkOperation(5, () => this.setAccountDataRaw(eventType, content));
|
||||||
await updatedDefer.promise;
|
await updatedResolvers.promise;
|
||||||
return result;
|
return result;
|
||||||
} finally {
|
} finally {
|
||||||
this.removeListener(ClientEvent.AccountData, accountDataListener);
|
this.removeListener(ClientEvent.AccountData, accountDataListener);
|
||||||
@@ -5173,24 +5173,24 @@ export class MatrixClient extends TypedEventEmitter<EmittedEvents, ClientEventHa
|
|||||||
} else if (!hasDontNotifyRule) {
|
} else if (!hasDontNotifyRule) {
|
||||||
// Remove the existing one before setting the mute push rule
|
// Remove the existing one before setting the mute push rule
|
||||||
// This is a workaround to SYN-590 (Push rule update fails)
|
// This is a workaround to SYN-590 (Push rule update fails)
|
||||||
const deferred = utils.defer();
|
const doneResolvers = Promise.withResolvers<void>();
|
||||||
this.deletePushRule(scope, PushRuleKind.RoomSpecific, roomPushRule.rule_id)
|
this.deletePushRule(scope, PushRuleKind.RoomSpecific, roomPushRule.rule_id)
|
||||||
.then(() => {
|
.then(() => {
|
||||||
this.addPushRule(scope, PushRuleKind.RoomSpecific, roomId, {
|
this.addPushRule(scope, PushRuleKind.RoomSpecific, roomId, {
|
||||||
actions: [PushRuleActionName.DontNotify],
|
actions: [PushRuleActionName.DontNotify],
|
||||||
})
|
})
|
||||||
.then(() => {
|
.then(() => {
|
||||||
deferred.resolve();
|
doneResolvers.resolve();
|
||||||
})
|
})
|
||||||
.catch((err) => {
|
.catch((err) => {
|
||||||
deferred.reject(err);
|
doneResolvers.reject(err);
|
||||||
});
|
});
|
||||||
})
|
})
|
||||||
.catch((err) => {
|
.catch((err) => {
|
||||||
deferred.reject(err);
|
doneResolvers.reject(err);
|
||||||
});
|
});
|
||||||
|
|
||||||
promise = deferred.promise;
|
promise = doneResolvers.promise;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -24,7 +24,7 @@ import {
|
|||||||
type UploadResponse,
|
type UploadResponse,
|
||||||
} from "./interface.ts";
|
} from "./interface.ts";
|
||||||
import { MediaPrefix } from "./prefix.ts";
|
import { MediaPrefix } from "./prefix.ts";
|
||||||
import { defer, type QueryDict, removeElement } from "../utils.ts";
|
import { type QueryDict, removeElement } from "../utils.ts";
|
||||||
import * as callbacks from "../realtime-callbacks.ts";
|
import * as callbacks from "../realtime-callbacks.ts";
|
||||||
import { Method } from "./method.ts";
|
import { Method } from "./method.ts";
|
||||||
import { ConnectionError } from "./errors.ts";
|
import { ConnectionError } from "./errors.ts";
|
||||||
@@ -65,14 +65,14 @@ export class MatrixHttpApi<O extends IHttpOpts> extends FetchHttpApi<O> {
|
|||||||
total: 0,
|
total: 0,
|
||||||
abortController,
|
abortController,
|
||||||
} as Upload;
|
} as Upload;
|
||||||
const deferred = defer<UploadResponse>();
|
const uploadResolvers = Promise.withResolvers<UploadResponse>();
|
||||||
|
|
||||||
if (globalThis.XMLHttpRequest) {
|
if (globalThis.XMLHttpRequest) {
|
||||||
const xhr = new globalThis.XMLHttpRequest();
|
const xhr = new globalThis.XMLHttpRequest();
|
||||||
|
|
||||||
const timeoutFn = function (): void {
|
const timeoutFn = function (): void {
|
||||||
xhr.abort();
|
xhr.abort();
|
||||||
deferred.reject(new Error("Timeout"));
|
uploadResolvers.reject(new Error("Timeout"));
|
||||||
};
|
};
|
||||||
|
|
||||||
// set an initial timeout of 30s; we'll advance it each time we get a progress notification
|
// set an initial timeout of 30s; we'll advance it each time we get a progress notification
|
||||||
@@ -91,16 +91,16 @@ export class MatrixHttpApi<O extends IHttpOpts> extends FetchHttpApi<O> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (xhr.status >= 400) {
|
if (xhr.status >= 400) {
|
||||||
deferred.reject(parseErrorResponse(xhr, xhr.responseText));
|
uploadResolvers.reject(parseErrorResponse(xhr, xhr.responseText));
|
||||||
} else {
|
} else {
|
||||||
deferred.resolve(JSON.parse(xhr.responseText));
|
uploadResolvers.resolve(JSON.parse(xhr.responseText));
|
||||||
}
|
}
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
if ((<Error>err).name === "AbortError") {
|
if ((<Error>err).name === "AbortError") {
|
||||||
deferred.reject(err);
|
uploadResolvers.reject(err);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
deferred.reject(new ConnectionError("request failed", <Error>err));
|
uploadResolvers.reject(new ConnectionError("request failed", <Error>err));
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@@ -153,16 +153,16 @@ export class MatrixHttpApi<O extends IHttpOpts> extends FetchHttpApi<O> {
|
|||||||
.then((response) => {
|
.then((response) => {
|
||||||
return this.opts.onlyData ? <UploadResponse>response : response.json();
|
return this.opts.onlyData ? <UploadResponse>response : response.json();
|
||||||
})
|
})
|
||||||
.then(deferred.resolve, deferred.reject);
|
.then(uploadResolvers.resolve, uploadResolvers.reject);
|
||||||
}
|
}
|
||||||
|
|
||||||
// remove the upload from the list on completion
|
// remove the upload from the list on completion
|
||||||
upload.promise = deferred.promise.finally(() => {
|
upload.promise = uploadResolvers.promise.finally(() => {
|
||||||
removeElement(this.uploads, (elem) => elem === upload);
|
removeElement(this.uploads, (elem) => elem === upload);
|
||||||
});
|
});
|
||||||
abortController.signal.addEventListener("abort", () => {
|
abortController.signal.addEventListener("abort", () => {
|
||||||
removeElement(this.uploads, (elem) => elem === upload);
|
removeElement(this.uploads, (elem) => elem === upload);
|
||||||
deferred.reject(new DOMException("Aborted", "AbortError"));
|
uploadResolvers.reject(new DOMException("Aborted", "AbortError"));
|
||||||
});
|
});
|
||||||
this.uploads.push(upload);
|
this.uploads.push(upload);
|
||||||
return upload.promise;
|
return upload.promise;
|
||||||
|
@@ -18,7 +18,6 @@ limitations under the License.
|
|||||||
|
|
||||||
import { logger } from "./logger.ts";
|
import { logger } from "./logger.ts";
|
||||||
import { type MatrixClient } from "./client.ts";
|
import { type MatrixClient } from "./client.ts";
|
||||||
import { defer, type IDeferred } from "./utils.ts";
|
|
||||||
import { MatrixError } from "./http-api/index.ts";
|
import { MatrixError } from "./http-api/index.ts";
|
||||||
import { type UserIdentifier } from "./@types/auth.ts";
|
import { type UserIdentifier } from "./@types/auth.ts";
|
||||||
|
|
||||||
@@ -262,7 +261,7 @@ export class InteractiveAuth<T> {
|
|||||||
private data: IAuthData & MatrixError["data"];
|
private data: IAuthData & MatrixError["data"];
|
||||||
private emailSid?: string;
|
private emailSid?: string;
|
||||||
private requestingEmailToken = false;
|
private requestingEmailToken = false;
|
||||||
private attemptAuthDeferred: IDeferred<T> | null = null;
|
private attemptAuthDeferred: PromiseWithResolvers<T> | null = null;
|
||||||
private chosenFlow: UIAFlow | null = null;
|
private chosenFlow: UIAFlow | null = null;
|
||||||
private currentStage: string | null = null;
|
private currentStage: string | null = null;
|
||||||
|
|
||||||
@@ -298,7 +297,7 @@ export class InteractiveAuth<T> {
|
|||||||
public async attemptAuth(): Promise<T> {
|
public async attemptAuth(): Promise<T> {
|
||||||
// This promise will be quite long-lived and will resolve when the
|
// This promise will be quite long-lived and will resolve when the
|
||||||
// request is authenticated and completes successfully.
|
// request is authenticated and completes successfully.
|
||||||
this.attemptAuthDeferred = defer();
|
this.attemptAuthDeferred = Promise.withResolvers();
|
||||||
// pluck the promise out now, as doRequest may clear before we return
|
// pluck the promise out now, as doRequest may clear before we return
|
||||||
const promise = this.attemptAuthDeferred.promise;
|
const promise = this.attemptAuthDeferred.promise;
|
||||||
|
|
||||||
|
@@ -169,7 +169,7 @@ export class MembershipManager
|
|||||||
}
|
}
|
||||||
this.fociPreferred = fociPreferred;
|
this.fociPreferred = fociPreferred;
|
||||||
this.focusActive = focusActive;
|
this.focusActive = focusActive;
|
||||||
this.leavePromiseDefer = undefined;
|
this.leavePromiseResolvers = undefined;
|
||||||
this.activated = true;
|
this.activated = true;
|
||||||
this.oldStatus = this.status;
|
this.oldStatus = this.status;
|
||||||
this.state = MembershipManager.defaultState;
|
this.state = MembershipManager.defaultState;
|
||||||
@@ -188,8 +188,8 @@ export class MembershipManager
|
|||||||
this.emit(MembershipManagerEvent.StatusChanged, this.oldStatus, this.status);
|
this.emit(MembershipManagerEvent.StatusChanged, this.oldStatus, this.status);
|
||||||
}
|
}
|
||||||
if (!this.scheduler.running) {
|
if (!this.scheduler.running) {
|
||||||
this.leavePromiseDefer?.resolve(true);
|
this.leavePromiseResolvers?.resolve(true);
|
||||||
this.leavePromiseDefer = undefined;
|
this.leavePromiseResolvers = undefined;
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
@@ -207,16 +207,16 @@ export class MembershipManager
|
|||||||
|
|
||||||
// We use the promise to track if we already scheduled a leave event
|
// We use the promise to track if we already scheduled a leave event
|
||||||
// So we do not check scheduler.actions/scheduler.insertions
|
// So we do not check scheduler.actions/scheduler.insertions
|
||||||
if (!this.leavePromiseDefer) {
|
if (!this.leavePromiseResolvers) {
|
||||||
// reset scheduled actions so we will not do any new actions.
|
// reset scheduled actions so we will not do any new actions.
|
||||||
this.leavePromiseDefer = defer<boolean>();
|
this.leavePromiseResolvers = defer<boolean>();
|
||||||
this.activated = false;
|
this.activated = false;
|
||||||
this.scheduler.initiateLeave();
|
this.scheduler.initiateLeave();
|
||||||
if (timeout) setTimeout(() => this.leavePromiseDefer?.resolve(false), timeout);
|
if (timeout) setTimeout(() => this.leavePromiseResolvers?.resolve(false), timeout);
|
||||||
}
|
}
|
||||||
return this.leavePromiseDefer.promise;
|
return this.leavePromiseResolvers.promise;
|
||||||
}
|
}
|
||||||
private leavePromiseDefer?: IDeferred<boolean>;
|
private leavePromiseResolvers?: IDeferred<boolean>;
|
||||||
|
|
||||||
public async onRTCSessionMemberUpdate(memberships: CallMembership[]): Promise<void> {
|
public async onRTCSessionMemberUpdate(memberships: CallMembership[]): Promise<void> {
|
||||||
const userId = this.client.getUserId();
|
const userId = this.client.getUserId();
|
||||||
|
@@ -18,7 +18,7 @@ import { type OlmMachine, type OutgoingRequest } from "@matrix-org/matrix-sdk-cr
|
|||||||
|
|
||||||
import { type OutgoingRequestProcessor } from "./OutgoingRequestProcessor.ts";
|
import { type OutgoingRequestProcessor } from "./OutgoingRequestProcessor.ts";
|
||||||
import { type Logger } from "../logger.ts";
|
import { type Logger } from "../logger.ts";
|
||||||
import { defer, type IDeferred, logDuration } from "../utils.ts";
|
import { logDuration } from "../utils.ts";
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* OutgoingRequestsManager: responsible for processing outgoing requests from the OlmMachine.
|
* OutgoingRequestsManager: responsible for processing outgoing requests from the OlmMachine.
|
||||||
@@ -39,7 +39,7 @@ export class OutgoingRequestsManager {
|
|||||||
* will resolve once that next iteration completes. If it is undefined, there have been no new calls
|
* will resolve once that next iteration completes. If it is undefined, there have been no new calls
|
||||||
* to `doProcessOutgoingRequests` since the current iteration started.
|
* to `doProcessOutgoingRequests` since the current iteration started.
|
||||||
*/
|
*/
|
||||||
private nextLoopDeferred?: IDeferred<void>;
|
private nextLoopDeferred?: PromiseWithResolvers<void>;
|
||||||
|
|
||||||
public constructor(
|
public constructor(
|
||||||
private readonly logger: Logger,
|
private readonly logger: Logger,
|
||||||
@@ -74,7 +74,7 @@ export class OutgoingRequestsManager {
|
|||||||
// In order to circumvent the race, we set a flag which tells the loop to go round once again even if the
|
// In order to circumvent the race, we set a flag which tells the loop to go round once again even if the
|
||||||
// queue appears to be empty.
|
// queue appears to be empty.
|
||||||
if (!this.nextLoopDeferred) {
|
if (!this.nextLoopDeferred) {
|
||||||
this.nextLoopDeferred = defer();
|
this.nextLoopDeferred = Promise.withResolvers();
|
||||||
}
|
}
|
||||||
|
|
||||||
// ... and wait for it to complete.
|
// ... and wait for it to complete.
|
||||||
@@ -99,14 +99,14 @@ export class OutgoingRequestsManager {
|
|||||||
this.outgoingRequestLoopRunning = true;
|
this.outgoingRequestLoopRunning = true;
|
||||||
try {
|
try {
|
||||||
while (!this.stopped && this.nextLoopDeferred) {
|
while (!this.stopped && this.nextLoopDeferred) {
|
||||||
const deferred = this.nextLoopDeferred;
|
const loopTickResolvers = this.nextLoopDeferred;
|
||||||
|
|
||||||
// reset `nextLoopDeferred` so that any future calls to `doProcessOutgoingRequests` are queued
|
// reset `nextLoopDeferred` so that any future calls to `doProcessOutgoingRequests` are queued
|
||||||
// for another additional iteration.
|
// for another additional iteration.
|
||||||
this.nextLoopDeferred = undefined;
|
this.nextLoopDeferred = undefined;
|
||||||
|
|
||||||
// make the requests and feed the results back to the `nextLoopDeferred`
|
// make the requests and feed the results back to the `nextLoopDeferred`
|
||||||
await this.processOutgoingRequests().then(deferred.resolve, deferred.reject);
|
await this.processOutgoingRequests().then(loopTickResolvers.resolve, loopTickResolvers.reject);
|
||||||
}
|
}
|
||||||
} finally {
|
} finally {
|
||||||
this.outgoingRequestLoopRunning = false;
|
this.outgoingRequestLoopRunning = false;
|
||||||
|
@@ -34,7 +34,6 @@ import { type OutgoingRequestProcessor } from "./OutgoingRequestProcessor.ts";
|
|||||||
import { TypedReEmitter } from "../ReEmitter.ts";
|
import { TypedReEmitter } from "../ReEmitter.ts";
|
||||||
import { type MatrixEvent } from "../models/event.ts";
|
import { type MatrixEvent } from "../models/event.ts";
|
||||||
import { EventType, MsgType } from "../@types/event.ts";
|
import { EventType, MsgType } from "../@types/event.ts";
|
||||||
import { defer, type IDeferred } from "../utils.ts";
|
|
||||||
import { VerificationMethod } from "../types.ts";
|
import { VerificationMethod } from "../types.ts";
|
||||||
import type { Logger } from "../logger.ts";
|
import type { Logger } from "../logger.ts";
|
||||||
|
|
||||||
@@ -478,7 +477,7 @@ abstract class BaseRustVerifer<InnerType extends RustSdkCryptoJs.Qr | RustSdkCry
|
|||||||
VerifierEventHandlerMap & VerificationRequestEventHandlerMap
|
VerifierEventHandlerMap & VerificationRequestEventHandlerMap
|
||||||
> {
|
> {
|
||||||
/** A deferred which completes when the verification completes (or rejects when it is cancelled/fails) */
|
/** A deferred which completes when the verification completes (or rejects when it is cancelled/fails) */
|
||||||
protected readonly completionDeferred: IDeferred<void>;
|
protected readonly completionDeferred: PromiseWithResolvers<void>;
|
||||||
|
|
||||||
public constructor(
|
public constructor(
|
||||||
protected inner: InnerType,
|
protected inner: InnerType,
|
||||||
@@ -486,7 +485,7 @@ abstract class BaseRustVerifer<InnerType extends RustSdkCryptoJs.Qr | RustSdkCry
|
|||||||
) {
|
) {
|
||||||
super();
|
super();
|
||||||
|
|
||||||
this.completionDeferred = defer();
|
this.completionDeferred = Promise.withResolvers();
|
||||||
|
|
||||||
// As with RustVerificationRequest, we need to avoid a reference cycle.
|
// As with RustVerificationRequest, we need to avoid a reference cycle.
|
||||||
// See the comments in RustVerificationRequest.
|
// See the comments in RustVerificationRequest.
|
||||||
|
@@ -21,7 +21,7 @@ limitations under the License.
|
|||||||
import { logger } from "./logger.ts";
|
import { logger } from "./logger.ts";
|
||||||
import { type MatrixEvent } from "./models/event.ts";
|
import { type MatrixEvent } from "./models/event.ts";
|
||||||
import { EventType } from "./@types/event.ts";
|
import { EventType } from "./@types/event.ts";
|
||||||
import { defer, type IDeferred, removeElement } from "./utils.ts";
|
import { removeElement } from "./utils.ts";
|
||||||
import { calculateRetryBackoff, type MatrixError } from "./http-api/index.ts";
|
import { calculateRetryBackoff, type MatrixError } from "./http-api/index.ts";
|
||||||
import { type ISendEventResponse } from "./@types/requests.ts";
|
import { type ISendEventResponse } from "./@types/requests.ts";
|
||||||
|
|
||||||
@@ -29,7 +29,7 @@ const DEBUG = false; // set true to enable console logging.
|
|||||||
|
|
||||||
interface IQueueEntry<T> {
|
interface IQueueEntry<T> {
|
||||||
event: MatrixEvent;
|
event: MatrixEvent;
|
||||||
defer: IDeferred<T>;
|
resolvers: PromiseWithResolvers<T>;
|
||||||
attempts: number;
|
attempts: number;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -70,7 +70,7 @@ export class MatrixScheduler<T = ISendEventResponse> {
|
|||||||
|
|
||||||
// queueName: [{
|
// queueName: [{
|
||||||
// event: MatrixEvent, // event to send
|
// event: MatrixEvent, // event to send
|
||||||
// defer: Deferred, // defer to resolve/reject at the END of the retries
|
// defer: PromiseWithResolvers, // defer to resolve/reject at the END of the retries
|
||||||
// attempts: Number // number of times we've called processFn
|
// attempts: Number // number of times we've called processFn
|
||||||
// }, ...]
|
// }, ...]
|
||||||
private readonly queues: Record<string, IQueueEntry<T>[]> = {};
|
private readonly queues: Record<string, IQueueEntry<T>[]> = {};
|
||||||
@@ -188,15 +188,15 @@ export class MatrixScheduler<T = ISendEventResponse> {
|
|||||||
if (!this.queues[queueName]) {
|
if (!this.queues[queueName]) {
|
||||||
this.queues[queueName] = [];
|
this.queues[queueName] = [];
|
||||||
}
|
}
|
||||||
const deferred = defer<T>();
|
const eventResolvers = Promise.withResolvers<T>();
|
||||||
this.queues[queueName].push({
|
this.queues[queueName].push({
|
||||||
event: event,
|
event: event,
|
||||||
defer: deferred,
|
resolvers: eventResolvers,
|
||||||
attempts: 0,
|
attempts: 0,
|
||||||
});
|
});
|
||||||
debuglog("Queue algorithm dumped event %s into queue '%s'", event.getId(), queueName);
|
debuglog("Queue algorithm dumped event %s into queue '%s'", event.getId(), queueName);
|
||||||
this.startProcessingQueues();
|
this.startProcessingQueues();
|
||||||
return deferred.promise;
|
return eventResolvers.promise;
|
||||||
}
|
}
|
||||||
|
|
||||||
private startProcessingQueues(): void {
|
private startProcessingQueues(): void {
|
||||||
@@ -239,7 +239,7 @@ export class MatrixScheduler<T = ISendEventResponse> {
|
|||||||
// remove this from the queue
|
// remove this from the queue
|
||||||
this.removeNextEvent(queueName);
|
this.removeNextEvent(queueName);
|
||||||
debuglog("Queue '%s' sent event %s", queueName, obj.event.getId());
|
debuglog("Queue '%s' sent event %s", queueName, obj.event.getId());
|
||||||
obj.defer.resolve(res);
|
obj.resolvers.resolve(res);
|
||||||
// keep processing
|
// keep processing
|
||||||
this.processQueue(queueName);
|
this.processQueue(queueName);
|
||||||
},
|
},
|
||||||
@@ -279,7 +279,7 @@ export class MatrixScheduler<T = ISendEventResponse> {
|
|||||||
logger.info("clearing queue '%s'", queueName);
|
logger.info("clearing queue '%s'", queueName);
|
||||||
let obj: IQueueEntry<T> | undefined;
|
let obj: IQueueEntry<T> | undefined;
|
||||||
while ((obj = this.removeNextEvent(queueName))) {
|
while ((obj = this.removeNextEvent(queueName))) {
|
||||||
obj.defer.reject(err);
|
obj.resolvers.reject(err);
|
||||||
}
|
}
|
||||||
this.disableQueue(queueName);
|
this.disableQueue(queueName);
|
||||||
}
|
}
|
||||||
|
@@ -15,7 +15,6 @@ limitations under the License.
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
import { logger } from "../logger.ts";
|
import { logger } from "../logger.ts";
|
||||||
import { defer, type IDeferred } from "../utils.ts";
|
|
||||||
import { type ISavedSync } from "./index.ts";
|
import { type ISavedSync } from "./index.ts";
|
||||||
import { type IStoredClientOpts } from "../client.ts";
|
import { type IStoredClientOpts } from "../client.ts";
|
||||||
import { type IStateEventWithRoomId, type ISyncResponse } from "../matrix.ts";
|
import { type IStateEventWithRoomId, type ISyncResponse } from "../matrix.ts";
|
||||||
@@ -26,7 +25,7 @@ export class RemoteIndexedDBStoreBackend implements IIndexedDBBackend {
|
|||||||
private worker?: Worker;
|
private worker?: Worker;
|
||||||
private nextSeq = 0;
|
private nextSeq = 0;
|
||||||
// The currently in-flight requests to the actual backend
|
// The currently in-flight requests to the actual backend
|
||||||
private inFlight: Record<number, IDeferred<any>> = {}; // seq: promise
|
private inFlight: Record<number, PromiseWithResolvers<any>> = {}; // seq: promise
|
||||||
// Once we start connecting, we keep the promise and re-use it
|
// Once we start connecting, we keep the promise and re-use it
|
||||||
// if we try to connect again
|
// if we try to connect again
|
||||||
private startPromise?: Promise<void>;
|
private startPromise?: Promise<void>;
|
||||||
@@ -164,7 +163,7 @@ export class RemoteIndexedDBStoreBackend implements IIndexedDBBackend {
|
|||||||
// the promise automatically gets rejected
|
// the promise automatically gets rejected
|
||||||
return Promise.resolve().then(() => {
|
return Promise.resolve().then(() => {
|
||||||
const seq = this.nextSeq++;
|
const seq = this.nextSeq++;
|
||||||
const def = defer<T>();
|
const def = Promise.withResolvers<T>();
|
||||||
|
|
||||||
this.inFlight[seq] = def;
|
this.inFlight[seq] = def;
|
||||||
|
|
||||||
|
38
src/sync.ts
38
src/sync.ts
@@ -28,7 +28,7 @@ import { type Optional } from "matrix-events-sdk";
|
|||||||
import type { SyncCryptoCallbacks } from "./common-crypto/CryptoBackend.ts";
|
import type { SyncCryptoCallbacks } from "./common-crypto/CryptoBackend.ts";
|
||||||
import { User } from "./models/user.ts";
|
import { User } from "./models/user.ts";
|
||||||
import { NotificationCountType, Room, RoomEvent } from "./models/room.ts";
|
import { NotificationCountType, Room, RoomEvent } from "./models/room.ts";
|
||||||
import { deepCopy, defer, type IDeferred, noUnsafeEventProps, promiseMapSeries, unsafeProp } from "./utils.ts";
|
import { deepCopy, noUnsafeEventProps, promiseMapSeries, unsafeProp } from "./utils.ts";
|
||||||
import { Filter } from "./filter.ts";
|
import { Filter } from "./filter.ts";
|
||||||
import { EventTimeline } from "./models/event-timeline.ts";
|
import { EventTimeline } from "./models/event-timeline.ts";
|
||||||
import { logger } from "./logger.ts";
|
import { logger } from "./logger.ts";
|
||||||
@@ -220,7 +220,7 @@ export class SyncApi {
|
|||||||
private catchingUp = false;
|
private catchingUp = false;
|
||||||
private running = false;
|
private running = false;
|
||||||
private keepAliveTimer?: ReturnType<typeof setTimeout>;
|
private keepAliveTimer?: ReturnType<typeof setTimeout>;
|
||||||
private connectionReturnedDefer?: IDeferred<boolean>;
|
private connectionReturnedResolvers?: PromiseWithResolvers<boolean>;
|
||||||
private notifEvents: MatrixEvent[] = []; // accumulator of sync events in the current sync response
|
private notifEvents: MatrixEvent[] = []; // accumulator of sync events in the current sync response
|
||||||
private failedSyncCount = 0; // Number of consecutive failed /sync requests
|
private failedSyncCount = 0; // Number of consecutive failed /sync requests
|
||||||
private storeIsInvalid = false; // flag set if the store needs to be cleared before we can start
|
private storeIsInvalid = false; // flag set if the store needs to be cleared before we can start
|
||||||
@@ -792,7 +792,7 @@ export class SyncApi {
|
|||||||
* @returns True if this resulted in a request being retried.
|
* @returns True if this resulted in a request being retried.
|
||||||
*/
|
*/
|
||||||
public retryImmediately(): boolean {
|
public retryImmediately(): boolean {
|
||||||
if (!this.connectionReturnedDefer) {
|
if (!this.connectionReturnedResolvers) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
this.startKeepAlives(0);
|
this.startKeepAlives(0);
|
||||||
@@ -916,9 +916,9 @@ export class SyncApi {
|
|||||||
|
|
||||||
if (!this.running) {
|
if (!this.running) {
|
||||||
debuglog("Sync no longer running: exiting.");
|
debuglog("Sync no longer running: exiting.");
|
||||||
if (this.connectionReturnedDefer) {
|
if (this.connectionReturnedResolvers) {
|
||||||
this.connectionReturnedDefer.reject();
|
this.connectionReturnedResolvers.reject();
|
||||||
this.connectionReturnedDefer = undefined;
|
this.connectionReturnedResolvers = undefined;
|
||||||
}
|
}
|
||||||
this.updateSyncState(SyncState.Stopped);
|
this.updateSyncState(SyncState.Stopped);
|
||||||
}
|
}
|
||||||
@@ -999,9 +999,9 @@ export class SyncApi {
|
|||||||
private async onSyncError(err: MatrixError): Promise<boolean> {
|
private async onSyncError(err: MatrixError): Promise<boolean> {
|
||||||
if (!this.running) {
|
if (!this.running) {
|
||||||
debuglog("Sync no longer running: exiting");
|
debuglog("Sync no longer running: exiting");
|
||||||
if (this.connectionReturnedDefer) {
|
if (this.connectionReturnedResolvers) {
|
||||||
this.connectionReturnedDefer.reject();
|
this.connectionReturnedResolvers.reject();
|
||||||
this.connectionReturnedDefer = undefined;
|
this.connectionReturnedResolvers = undefined;
|
||||||
}
|
}
|
||||||
this.updateSyncState(SyncState.Stopped);
|
this.updateSyncState(SyncState.Stopped);
|
||||||
return true; // abort
|
return true; // abort
|
||||||
@@ -1551,10 +1551,10 @@ export class SyncApi {
|
|||||||
} else {
|
} else {
|
||||||
this.pokeKeepAlive();
|
this.pokeKeepAlive();
|
||||||
}
|
}
|
||||||
if (!this.connectionReturnedDefer) {
|
if (!this.connectionReturnedResolvers) {
|
||||||
this.connectionReturnedDefer = defer();
|
this.connectionReturnedResolvers = Promise.withResolvers();
|
||||||
}
|
}
|
||||||
return this.connectionReturnedDefer.promise;
|
return this.connectionReturnedResolvers.promise;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -1562,7 +1562,7 @@ export class SyncApi {
|
|||||||
* reachable.
|
* reachable.
|
||||||
*
|
*
|
||||||
* On failure, schedules a call back to itself. On success, resolves
|
* On failure, schedules a call back to itself. On success, resolves
|
||||||
* this.connectionReturnedDefer.
|
* this.connectionReturnedResolvers.
|
||||||
*
|
*
|
||||||
* @param connDidFail - True if a connectivity failure has been detected. Optional.
|
* @param connDidFail - True if a connectivity failure has been detected. Optional.
|
||||||
*/
|
*/
|
||||||
@@ -1571,18 +1571,18 @@ export class SyncApi {
|
|||||||
// we are in a keepAlive, retrying to connect, but the syncronization
|
// we are in a keepAlive, retrying to connect, but the syncronization
|
||||||
// was stopped, so we are stopping the retry.
|
// was stopped, so we are stopping the retry.
|
||||||
clearTimeout(this.keepAliveTimer);
|
clearTimeout(this.keepAliveTimer);
|
||||||
if (this.connectionReturnedDefer) {
|
if (this.connectionReturnedResolvers) {
|
||||||
this.connectionReturnedDefer.reject("SyncApi.stop() was called");
|
this.connectionReturnedResolvers.reject("SyncApi.stop() was called");
|
||||||
this.connectionReturnedDefer = undefined;
|
this.connectionReturnedResolvers = undefined;
|
||||||
}
|
}
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
const success = (): void => {
|
const success = (): void => {
|
||||||
clearTimeout(this.keepAliveTimer);
|
clearTimeout(this.keepAliveTimer);
|
||||||
if (this.connectionReturnedDefer) {
|
if (this.connectionReturnedResolvers) {
|
||||||
this.connectionReturnedDefer.resolve(connDidFail);
|
this.connectionReturnedResolvers.resolve(connDidFail);
|
||||||
this.connectionReturnedDefer = undefined;
|
this.connectionReturnedResolvers = undefined;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
21
src/utils.ts
21
src/utils.ts
@@ -436,23 +436,14 @@ export function isNullOrUndefined(val: any): boolean {
|
|||||||
return val === null || val === undefined;
|
return val === null || val === undefined;
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface IDeferred<T> {
|
export type IDeferred<T> = PromiseWithResolvers<T>;
|
||||||
resolve: (value: T | Promise<T>) => void;
|
|
||||||
reject: (reason?: any) => void;
|
|
||||||
promise: Promise<T>;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Returns a Deferred
|
/**
|
||||||
|
* Creates a deferred promise. This is a promise that can be resolved or rejected.
|
||||||
|
* @deprecated use {@link Promise.withResolvers} instead.
|
||||||
|
*/
|
||||||
export function defer<T = void>(): IDeferred<T> {
|
export function defer<T = void>(): IDeferred<T> {
|
||||||
let resolve!: IDeferred<T>["resolve"];
|
return Promise.withResolvers<T>();
|
||||||
let reject!: IDeferred<T>["reject"];
|
|
||||||
|
|
||||||
const promise = new Promise<T>((_resolve, _reject) => {
|
|
||||||
resolve = _resolve;
|
|
||||||
reject = _reject;
|
|
||||||
});
|
|
||||||
|
|
||||||
return { resolve, reject, promise };
|
|
||||||
}
|
}
|
||||||
|
|
||||||
export async function promiseMapSeries<T>(
|
export async function promiseMapSeries<T>(
|
||||||
|
Reference in New Issue
Block a user