Skip to content

Commit 1fcc375

Browse files
authored
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>
1 parent d24c5d8 commit 1fcc375

32 files changed

+220
-221
lines changed

knip.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ export default {
99
"src/crypto-api/index.ts",
1010
"src/testing.ts",
1111
"src/matrix.ts",
12+
"src/utils.ts", // not really an entrypoint but we have deprecated `defer` there
1213
"scripts/**",
1314
"spec/**",
1415
// XXX: these look entirely unused

spec/integ/crypto/crypto.spec.ts

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -59,7 +59,7 @@ import {
5959
} from "../../../src/matrix";
6060
import { E2EKeyReceiver } from "../../test-utils/E2EKeyReceiver";
6161
import { type ISyncResponder, SyncResponder } from "../../test-utils/SyncResponder";
62-
import { defer, escapeRegExp } from "../../../src/utils";
62+
import { escapeRegExp } from "../../../src/utils";
6363
import { downloadDeviceToJsDevice } from "../../../src/rust-crypto/device-converter";
6464
import { flushPromises } from "../../test-utils/flushPromises";
6565
import {
@@ -1283,13 +1283,13 @@ describe("crypto", () => {
12831283
const inboundGroupSessionPromise = expectSendRoomKey("@bob:xyz", testOlmAccount);
12841284

12851285
// ... and finally, send the room key. We block the response until `sendRoomMessageDefer` completes.
1286-
const sendRoomMessageDefer = defer<FetchMock.MockResponse>();
1286+
const sendRoomMessageResolvers = Promise.withResolvers<FetchMock.MockResponse>();
12871287
const reqProm = new Promise<IContent>((resolve) => {
12881288
fetchMock.putOnce(
12891289
new RegExp("/send/m.room.encrypted/"),
12901290
async (url: string, opts: RequestInit): Promise<FetchMock.MockResponse> => {
12911291
resolve(JSON.parse(opts.body as string));
1292-
return await sendRoomMessageDefer.promise;
1292+
return await sendRoomMessageResolvers.promise;
12931293
},
12941294
{
12951295
// append to the list of intercepts on this path (since we have some tests that call
@@ -1318,7 +1318,7 @@ describe("crypto", () => {
13181318

13191319
// release the send request
13201320
const resp = { event_id: "$event_id" };
1321-
sendRoomMessageDefer.resolve(resp);
1321+
sendRoomMessageResolvers.resolve(resp);
13221322
expect(await sendProm).toEqual(resp);
13231323

13241324
// still pending at this point

spec/integ/crypto/megolm-backup.spec.ts

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,6 @@ import { advanceTimersUntil, awaitDecryption, syncPromise } from "../../test-uti
3636
import * as testData from "../../test-utils/test-data";
3737
import { type KeyBackupInfo, type KeyBackupSession } from "../../../src/crypto-api/keybackup";
3838
import { flushPromises } from "../../test-utils/flushPromises";
39-
import { defer, type IDeferred } from "../../../src/utils";
4039
import { decodeRecoveryKey, DecryptionFailureCode, CryptoEvent, type CryptoApi } from "../../../src/crypto-api";
4140
import { type KeyBackup } from "../../../src/rust-crypto/backup.ts";
4241

@@ -861,7 +860,7 @@ describe("megolm-keys backup", () => {
861860
expect(await aliceCrypto.getKeyBackupInfo()).toStrictEqual(testData.SIGNED_BACKUP_DATA);
862861

863862
// Delete the backup and we are expecting the key backup to be disabled
864-
const keyBackupStatus = defer<boolean>();
863+
const keyBackupStatus = Promise.withResolvers<boolean>();
865864
aliceClient.once(CryptoEvent.KeyBackupStatus, (enabled) => keyBackupStatus.resolve(enabled));
866865
await aliceCrypto.deleteKeyBackupVersion(testData.SIGNED_BACKUP_DATA.version!);
867866
expect(await keyBackupStatus.promise).toBe(false);
@@ -1158,7 +1157,7 @@ describe("megolm-keys backup", () => {
11581157
// A check backup should happen at some point
11591158
await aliceCrypto.checkKeyBackupAndEnable();
11601159

1161-
const awaitHasQueriedNewBackup: IDeferred<void> = defer<void>();
1160+
const awaitHasQueriedNewBackup: PromiseWithResolvers<void> = Promise.withResolvers<void>();
11621161

11631162
fetchMock.get(
11641163
"express:/_matrix/client/v3/room_keys/keys/:room_id/:session_id",

spec/integ/crypto/verification.spec.ts

Lines changed: 13 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -44,7 +44,7 @@ import {
4444
type Verifier,
4545
VerifierEvent,
4646
} from "../../../src/crypto-api/verification";
47-
import { defer, escapeRegExp } from "../../../src/utils";
47+
import { escapeRegExp } from "../../../src/utils";
4848
import { awaitDecryption, emitPromise, getSyncResponse, syncPromise } from "../../test-utils/test-utils";
4949
import { SyncResponder } from "../../test-utils/SyncResponder";
5050
import {
@@ -1540,10 +1540,10 @@ function expectSendToDeviceMessage(msgtype: string): Promise<{ messages: any }>
15401540
* @returns a map of secret name to promise that will resolve (with the id of the secret request) when the secret is requested.
15411541
*/
15421542
function mockSecretRequestAndGetPromises(): Map<string, Promise<string>> {
1543-
const mskRequestDefer = defer<string>();
1544-
const sskRequestDefer = defer<string>();
1545-
const uskRequestDefer = defer<string>();
1546-
const backupKeyRequestDefer = defer<string>();
1543+
const mskRequestResolvers = Promise.withResolvers<string>();
1544+
const sskRequestResolvers = Promise.withResolvers<string>();
1545+
const uskRequestResolvers = Promise.withResolvers<string>();
1546+
const backupKeyRequestResolvers = Promise.withResolvers<string>();
15471547

15481548
fetchMock.put(
15491549
new RegExp(`/_matrix/client/(r0|v3)/sendToDevice/m.secret.request`),
@@ -1555,13 +1555,13 @@ function mockSecretRequestAndGetPromises(): Map<string, Promise<string>> {
15551555
const name = content.name;
15561556
const requestId = content.request_id;
15571557
if (name == "m.cross_signing.user_signing") {
1558-
uskRequestDefer.resolve(requestId);
1558+
uskRequestResolvers.resolve(requestId);
15591559
} else if (name == "m.cross_signing.master") {
1560-
mskRequestDefer.resolve(requestId);
1560+
mskRequestResolvers.resolve(requestId);
15611561
} else if (name == "m.cross_signing.self_signing") {
1562-
sskRequestDefer.resolve(requestId);
1562+
sskRequestResolvers.resolve(requestId);
15631563
} else if (name == "m.megolm_backup.v1") {
1564-
backupKeyRequestDefer.resolve(requestId);
1564+
backupKeyRequestResolvers.resolve(requestId);
15651565
}
15661566
}
15671567
return {};
@@ -1570,10 +1570,10 @@ function mockSecretRequestAndGetPromises(): Map<string, Promise<string>> {
15701570
);
15711571

15721572
const promiseMap = new Map<string, Promise<string>>();
1573-
promiseMap.set("m.cross_signing.master", mskRequestDefer.promise);
1574-
promiseMap.set("m.cross_signing.self_signing", sskRequestDefer.promise);
1575-
promiseMap.set("m.cross_signing.user_signing", uskRequestDefer.promise);
1576-
promiseMap.set("m.megolm_backup.v1", backupKeyRequestDefer.promise);
1573+
promiseMap.set("m.cross_signing.master", mskRequestResolvers.promise);
1574+
promiseMap.set("m.cross_signing.self_signing", sskRequestResolvers.promise);
1575+
promiseMap.set("m.cross_signing.user_signing", uskRequestResolvers.promise);
1576+
promiseMap.set("m.megolm_backup.v1", backupKeyRequestResolvers.promise);
15771577
return promiseMap;
15781578
}
15791579

spec/integ/matrix-client-methods.spec.ts

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1796,6 +1796,27 @@ describe("MatrixClient", function () {
17961796
expect(client.getUserIdLocalpart()).toBe("alice");
17971797
});
17981798
});
1799+
1800+
describe("setRoomMutePushRule", () => {
1801+
it("should set room push rule to muted", async () => {
1802+
const roomId = "!roomId:server";
1803+
const client = new MatrixClient({
1804+
baseUrl: "http://localhost",
1805+
fetchFn: httpBackend.fetchFn as typeof globalThis.fetch,
1806+
});
1807+
client.pushRules = {
1808+
global: {
1809+
room: [{ rule_id: roomId, actions: [], default: false, enabled: false }],
1810+
},
1811+
};
1812+
1813+
const path = `/pushrules/global/room/${encodeURIComponent(roomId)}`;
1814+
httpBackend.when("DELETE", path).respond(200, {});
1815+
httpBackend.when("PUT", path).respond(200, {});
1816+
client.setRoomMutePushRule("global", roomId, true);
1817+
await httpBackend.flush("");
1818+
});
1819+
});
17991820
});
18001821

18011822
function withThreadId(event: MatrixEvent, newThreadId: string): MatrixEvent {

spec/integ/rendezvous/MSC4108SignInWithQR.spec.ts

Lines changed: 7 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,6 @@ import {
2626
PayloadType,
2727
RendezvousError,
2828
} from "../../../src/rendezvous";
29-
import { defer } from "../../../src/utils";
3029
import {
3130
ClientPrefix,
3231
DEVICE_CODE_SCOPE,
@@ -112,8 +111,8 @@ describe("MSC4108SignInWithQR", () => {
112111
let opponentLogin: MSC4108SignInWithQR;
113112

114113
beforeEach(async () => {
115-
let ourData = defer<string>();
116-
let opponentData = defer<string>();
114+
let ourData = Promise.withResolvers<string>();
115+
let opponentData = Promise.withResolvers<string>();
117116

118117
const ourMockSession = {
119118
send: jest.fn(async (newData) => {
@@ -122,7 +121,7 @@ describe("MSC4108SignInWithQR", () => {
122121
receive: jest.fn(() => {
123122
const prom = opponentData.promise;
124123
prom.then(() => {
125-
opponentData = defer();
124+
opponentData = Promise.withResolvers();
126125
});
127126
return prom;
128127
}),
@@ -141,7 +140,7 @@ describe("MSC4108SignInWithQR", () => {
141140
receive: jest.fn(() => {
142141
const prom = ourData.promise;
143142
prom.then(() => {
144-
ourData = defer();
143+
ourData = Promise.withResolvers();
145144
});
146145
return prom;
147146
}),
@@ -334,11 +333,11 @@ describe("MSC4108SignInWithQR", () => {
334333
// @ts-ignore
335334
await opponentLogin.receive();
336335

337-
const deferred = defer<IMyDevice>();
338-
mocked(client.getDevice).mockReturnValue(deferred.promise);
336+
const deviceResolvers = Promise.withResolvers<IMyDevice>();
337+
mocked(client.getDevice).mockReturnValue(deviceResolvers.promise);
339338

340339
ourLogin.cancel(MSC4108FailureReason.UserCancelled).catch(() => {});
341-
deferred.resolve({} as IMyDevice);
340+
deviceResolvers.resolve({} as IMyDevice);
342341

343342
const secrets = {
344343
cross_signing: { master_key: "mk", user_signing_key: "usk", self_signing_key: "ssk" },

spec/integ/sliding-sync-sdk.spec.ts

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -48,7 +48,6 @@ import { type SyncApiOptions, SyncState } from "../../src/sync";
4848
import { type IStoredClientOpts } from "../../src";
4949
import { logger } from "../../src/logger";
5050
import { emitPromise } from "../test-utils/test-utils";
51-
import { defer } from "../../src/utils";
5251
import { KnownMembership } from "../../src/@types/membership";
5352
import { type SyncCryptoCallbacks } from "../../src/common-crypto/CryptoBackend";
5453

@@ -369,7 +368,7 @@ describe("SlidingSyncSdk", () => {
369368
});
370369

371370
it("can be created with live events", async () => {
372-
const seenLiveEventDeferred = defer<boolean>();
371+
const seenLiveEventDeferred = Promise.withResolvers<boolean>();
373372
const listener = (
374373
ev: MatrixEvent,
375374
room?: Room,

spec/unit/ToDeviceMessageQueue.spec.ts

Lines changed: 9 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,6 @@ import { getMockClientWithEventEmitter } from "../test-utils/client";
55
import { StubStore } from "../../src/store/stub";
66
import { type IndexedToDeviceBatch } from "../../src/models/ToDeviceMessage";
77
import { SyncState } from "../../src/sync";
8-
import { defer } from "../../src/utils";
98

109
describe("onResumedSync", () => {
1110
let batch: IndexedToDeviceBatch | null;
@@ -60,7 +59,7 @@ describe("onResumedSync", () => {
6059
});
6160

6261
it("resends queue after connectivity restored", async () => {
63-
const deferred = defer();
62+
const successResolvers = Promise.withResolvers<void>();
6463

6564
onSendToDeviceFailure = () => {
6665
expect(store.getOldestToDeviceBatch).toHaveBeenCalledTimes(1);
@@ -73,31 +72,31 @@ describe("onResumedSync", () => {
7372
onSendToDeviceSuccess = () => {
7473
expect(store.getOldestToDeviceBatch).toHaveBeenCalledTimes(3);
7574
expect(store.removeToDeviceBatch).toHaveBeenCalled();
76-
deferred.resolve();
75+
successResolvers.resolve();
7776
};
7877

7978
queue.start();
80-
return deferred.promise;
79+
return successResolvers.promise;
8180
});
8281

8382
it("does not resend queue if client sync still catching up", async () => {
84-
const deferred = defer();
83+
const successResolvers = Promise.withResolvers<void>();
8584

8685
onSendToDeviceFailure = () => {
8786
expect(store.getOldestToDeviceBatch).toHaveBeenCalledTimes(1);
8887
expect(store.removeToDeviceBatch).not.toHaveBeenCalled();
8988

9089
resumeSync(SyncState.Catchup, SyncState.Catchup);
9190
expect(store.getOldestToDeviceBatch).toHaveBeenCalledTimes(1);
92-
deferred.resolve();
91+
successResolvers.resolve();
9392
};
9493

9594
queue.start();
96-
return deferred.promise;
95+
return successResolvers.promise;
9796
});
9897

9998
it("does not resend queue if connectivity restored after queue stopped", async () => {
100-
const deferred = defer();
99+
const successResolvers = Promise.withResolvers<void>();
101100

102101
onSendToDeviceFailure = () => {
103102
expect(store.getOldestToDeviceBatch).toHaveBeenCalledTimes(1);
@@ -107,10 +106,10 @@ describe("onResumedSync", () => {
107106

108107
resumeSync(SyncState.Syncing, SyncState.Catchup);
109108
expect(store.getOldestToDeviceBatch).toHaveBeenCalledTimes(1);
110-
deferred.resolve();
109+
successResolvers.resolve();
111110
};
112111

113112
queue.start();
114-
return deferred.promise;
113+
return successResolvers.promise;
115114
});
116115
});

spec/unit/http-api/fetch.spec.ts

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@ import {
2929
Method,
3030
} from "../../../src";
3131
import { emitPromise } from "../../test-utils/test-utils";
32-
import { defer, type QueryDict, sleep } from "../../../src/utils";
32+
import { type QueryDict, sleep } from "../../../src/utils";
3333
import { type Logger } from "../../../src/logger";
3434

3535
describe("FetchHttpApi", () => {
@@ -525,8 +525,8 @@ describe("FetchHttpApi", () => {
525525

526526
it("should not log query parameters", async () => {
527527
jest.useFakeTimers();
528-
const deferred = defer<Response>();
529-
const fetchFn = jest.fn().mockReturnValue(deferred.promise);
528+
const responseResolvers = Promise.withResolvers<Response>();
529+
const fetchFn = jest.fn().mockReturnValue(responseResolvers.promise);
530530
const mockLogger = {
531531
debug: jest.fn(),
532532
} as unknown as Mocked<Logger>;
@@ -538,7 +538,7 @@ describe("FetchHttpApi", () => {
538538
});
539539
const prom = api.requestOtherUrl(Method.Get, "https://server:8448/some/path?query=param#fragment");
540540
jest.advanceTimersByTime(1234);
541-
deferred.resolve({ ok: true, status: 200, text: () => Promise.resolve("RESPONSE") } as Response);
541+
responseResolvers.resolve({ ok: true, status: 200, text: () => Promise.resolve("RESPONSE") } as Response);
542542
await prom;
543543
expect(mockLogger.debug).not.toHaveBeenCalledWith("fragment");
544544
expect(mockLogger.debug).not.toHaveBeenCalledWith("query");
@@ -557,7 +557,7 @@ describe("FetchHttpApi", () => {
557557
});
558558

559559
it("should not make multiple concurrent refresh token requests", async () => {
560-
const deferredTokenRefresh = defer<{ accessToken: string; refreshToken: string }>();
560+
const deferredTokenRefresh = Promise.withResolvers<{ accessToken: string; refreshToken: string }>();
561561
const fetchFn = jest.fn().mockResolvedValue({
562562
ok: false,
563563
status: tokenInactiveError.httpStatus,
@@ -612,7 +612,7 @@ describe("FetchHttpApi", () => {
612612
});
613613

614614
it("should use newly refreshed token if request starts mid-refresh", async () => {
615-
const deferredTokenRefresh = defer<{ accessToken: string; refreshToken: string }>();
615+
const deferredTokenRefresh = Promise.withResolvers<{ accessToken: string; refreshToken: string }>();
616616
const fetchFn = jest.fn().mockResolvedValue({
617617
ok: false,
618618
status: tokenInactiveError.httpStatus,

spec/unit/matrix-client.spec.ts

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -73,7 +73,7 @@ import {
7373
PolicyRecommendation,
7474
PolicyScope,
7575
} from "../../src/models/invites-ignorer";
76-
import { defer, type QueryDict } from "../../src/utils";
76+
import { type QueryDict } from "../../src/utils";
7777
import { type SyncState } from "../../src/sync";
7878
import * as featureUtils from "../../src/feature";
7979
import { StubStore } from "../../src/store/stub";
@@ -1997,8 +1997,8 @@ describe("MatrixClient", function () {
19971997
});
19981998

19991999
it("should cancel an event which is encrypting", async () => {
2000-
const encryptEventDefer = defer();
2001-
mockCrypto.encryptEvent.mockReturnValue(encryptEventDefer.promise);
2000+
const encryptEventResolvers = Promise.withResolvers<void>();
2001+
mockCrypto.encryptEvent.mockReturnValue(encryptEventResolvers.promise);
20022002

20032003
const statusPromise = testUtils.emitPromise(event, "Event.status");
20042004
// @ts-ignore protected method access
@@ -2009,7 +2009,7 @@ describe("MatrixClient", function () {
20092009
assertCancelled();
20102010

20112011
// now let the encryption complete, and check that the message is not sent.
2012-
encryptEventDefer.resolve();
2012+
encryptEventResolvers.resolve();
20132013
await encryptAndSendPromise;
20142014
assertCancelled();
20152015
});

0 commit comments

Comments
 (0)