Skip to content

Commit 81730ba

Browse files
Add typings for WebChannel (#2385)
1 parent fe11de0 commit 81730ba

File tree

3 files changed

+83
-28
lines changed

3 files changed

+83
-28
lines changed

packages/firestore/src/platform_browser/webchannel_connection.ts

Lines changed: 11 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@ import {
2020
ErrorCode,
2121
EventType,
2222
WebChannel,
23+
WebChannelError,
2324
WebChannelOptions,
2425
XhrIo
2526
} from '@firebase/webchannel-wrapper';
@@ -98,9 +99,7 @@ export class WebChannelConnection implements Connection {
9899
const url = this.makeUrl(rpcName);
99100

100101
return new Promise((resolve: Resolver<Resp>, reject: Rejecter) => {
101-
// XhrIo doesn't have TS typings.
102-
// eslint-disable-next-line @typescript-eslint/no-explicit-any
103-
const xhr: any = new XhrIo();
102+
const xhr = new XhrIo();
104103
xhr.listenOnce(EventType.COMPLETE, () => {
105104
try {
106105
switch (xhr.getLastErrorCode()) {
@@ -125,7 +124,8 @@ export class WebChannelConnection implements Connection {
125124
xhr.getResponseText()
126125
);
127126
if (status > 0) {
128-
const responseError = xhr.getResponseJson().error;
127+
const responseError = (xhr.getResponseJson() as WebChannelError)
128+
.error;
129129
if (
130130
!!responseError &&
131131
!!responseError.status &&
@@ -272,9 +272,7 @@ export class WebChannelConnection implements Connection {
272272

273273
const url = urlParts.join('');
274274
log.debug(LOG_TAG, 'Creating WebChannel: ' + url + ' ' + request);
275-
// Use any because listen isn't defined on it.
276-
// eslint-disable-next-line @typescript-eslint/no-explicit-any
277-
const channel = webchannelTransport.createWebChannel(url, request) as any;
275+
const channel = webchannelTransport.createWebChannel(url, request);
278276

279277
// WebChannel supports sending the first message with the handshake - saving
280278
// a network round trip. However, it will have to call send in the same
@@ -310,14 +308,14 @@ export class WebChannelConnection implements Connection {
310308
// Note that eventually this function could go away if we are confident
311309
// enough the code is exception free.
312310
const unguardedEventListen = <T>(
313-
type: WebChannel.EventType,
311+
type: string,
314312
fn: (param?: T) => void
315313
): void => {
316314
// TODO(dimond): closure typing seems broken because WebChannel does
317315
// not implement goog.events.Listenable
318-
channel.listen(type, (param?: T) => {
316+
channel.listen(type, (param: unknown) => {
319317
try {
320-
fn(param);
318+
fn(param as T);
321319
} catch (e) {
322320
setTimeout(() => {
323321
throw e;
@@ -371,10 +369,10 @@ export class WebChannelConnection implements Connection {
371369
// compatible with the bug we need to check either condition. The latter
372370
// can be removed once the fix has been rolled out.
373371
// Use any because msgData.error is not typed.
374-
// eslint-disable-next-line @typescript-eslint/no-explicit-any
375-
const msgDataAsAny: any = msgData;
372+
const msgDataOrError: WebChannelError | object = msgData;
376373
const error =
377-
msgDataAsAny.error || (msgDataAsAny[0] && msgDataAsAny[0].error);
374+
msgDataOrError.error ||
375+
(msgDataOrError as WebChannelError[])[0]?.error;
378376
if (error) {
379377
log.debug(LOG_TAG, 'WebChannel received error:', error);
380378
// error.status will be a string like 'OK' or 'NOT_FOUND'.

packages/webchannel-wrapper/src/index.d.ts

Lines changed: 72 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -15,23 +15,73 @@
1515
* limitations under the License.
1616
*/
1717

18-
// TODO(mikelehen): Flesh out proper types (or figure out how to generate via
19-
// clutz or something).
20-
export class XhrIo {}
21-
export const ErrorCode: any;
22-
export const EventType: any;
18+
// WARNING: This is not a complete set of types exported by WebChannelWrapper.
19+
// It is merely meant to support the usage patterns of the Firestore SDK.
20+
21+
export var EventType: {
22+
COMPLETE: string;
23+
};
24+
2325
export namespace WebChannel {
24-
export type EventType = any;
25-
export const EventType: any;
26+
export var EventType: {
27+
OPEN: string;
28+
CLOSE: string;
29+
ERROR: string;
30+
MESSAGE: string;
31+
};
32+
}
33+
34+
export var ErrorCode: {
35+
NO_ERROR: number;
36+
HTTP_ERROR: number;
37+
TIMEOUT: number;
38+
};
39+
40+
export interface Headers {
41+
[name: string]: string | number;
42+
}
43+
44+
export interface WebChannelError {
45+
error?: { status: string; message: string };
2646
}
2747

28-
type StringMap = { [key: string]: string };
48+
export class XhrIo {
49+
send(
50+
url: string,
51+
method?: string,
52+
body?: string,
53+
headers?: Headers,
54+
timeoutInterval?: number
55+
): void;
56+
57+
getLastErrorCode(): number;
58+
59+
getLastError(): string;
60+
61+
getStatus(): number;
62+
63+
getResponseText(): string;
64+
65+
getResponseJson(): WebChannelError | object;
66+
67+
listenOnce(type: string, cb: (param: unknown) => void): void;
68+
}
2969

3070
export interface WebChannelOptions {
31-
messageHeaders?: StringMap;
32-
initMessageHeaders?: StringMap;
71+
messageHeaders?: {
72+
// To ensure compatibility with property minifcation tools, keys need to
73+
// be listed explicity.
74+
[k: string]: never;
75+
};
76+
initMessageHeaders?: {
77+
// To ensure compatibility with property minifcation tools, keys need to
78+
// be listed explicity.
79+
[k: string]: never;
80+
};
3381
messageContentType?: string;
34-
messageUrlParams?: StringMap;
82+
messageUrlParams?: {
83+
database?: string;
84+
};
3585
clientProtocolHeaderRequired?: boolean;
3686
concurrentRequestLimit?: number;
3787
supportsCrossDomainXhr?: boolean;
@@ -44,13 +94,22 @@ export interface WebChannelOptions {
4494
fastHandshake?: boolean;
4595
disableRedac?: boolean;
4696
clientProfile?: string;
47-
internalChannelParams?: { [key: string]: boolean | number };
97+
internalChannelParams?: {
98+
forwardChannelRequestTimeoutMs?: number;
99+
};
48100
xmlHttpFactory?: unknown;
49101
requestRefreshThresholds?: { [key: string]: number };
50102
}
51103

104+
export interface WebChannel {
105+
open(): void;
106+
close(): void;
107+
listen(type: string, cb: (param: unknown) => void): void;
108+
send(msg: unknown): void;
109+
}
110+
52111
export interface WebChannelTransport {
53-
createWebChannel(url: string, options: WebChannelOptions): any;
112+
createWebChannel(url: string, options: WebChannelOptions): WebChannel;
54113
}
55114

56115
export function createWebChannelTransport(): WebChannelTransport;

packages/webchannel-wrapper/src/index.js

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -68,8 +68,6 @@ goog.net.XhrIo.prototype['getLastError'] =
6868
goog.net.XhrIo.prototype['getLastErrorCode'] =
6969
goog.net.XhrIo.prototype.getLastErrorCode;
7070
goog.net.XhrIo.prototype['getStatus'] = goog.net.XhrIo.prototype.getStatus;
71-
goog.net.XhrIo.prototype['getStatusText'] =
72-
goog.net.XhrIo.prototype.getStatusText;
7371
goog.net.XhrIo.prototype['getResponseJson'] =
7472
goog.net.XhrIo.prototype.getResponseJson;
7573
goog.net.XhrIo.prototype['getResponseText'] =

0 commit comments

Comments
 (0)