Skip to content

Commit 78daef9

Browse files
chore: types for client
1 parent 3be97b4 commit 78daef9

File tree

12 files changed

+197
-86
lines changed

12 files changed

+197
-86
lines changed

client-src/clients/SockJSClient.js

Lines changed: 9 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,9 @@ import { log } from "../utils/log.js";
33

44
/** @typedef {import("../index").EXPECTED_ANY} EXPECTED_ANY */
55

6+
/**
7+
* @implements {CommunicationClient}
8+
*/
69
export default class SockJSClient {
710
/**
811
* @param {string} url url
@@ -12,13 +15,9 @@ export default class SockJSClient {
1215
this.sock = new SockJS(
1316
url.replace(/^ws:/i, "http:").replace(/^wss:/i, "https:"),
1417
);
15-
this.sock.onerror =
16-
/**
17-
* @param {Error} error error
18-
*/
19-
(error) => {
20-
log.error(error);
21-
};
18+
this.sock.onerror = (error) => {
19+
log.error(error);
20+
};
2221
}
2322

2423
/**
@@ -40,12 +39,8 @@ export default class SockJSClient {
4039
* @param {(...args: EXPECTED_ANY[]) => void} fn function
4140
*/
4241
onMessage(fn) {
43-
this.sock.onmessage =
44-
/**
45-
* @param {Error & { data: string }} err error
46-
*/
47-
(err) => {
48-
fn(err.data);
49-
};
42+
this.sock.onmessage = (err) => {
43+
fn(err.data);
44+
};
5045
}
5146
}

client-src/clients/WebSocketClient.js

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,9 @@ import { log } from "../utils/log.js";
22

33
/** @typedef {import("../index").EXPECTED_ANY} EXPECTED_ANY */
44

5+
/**
6+
* @implements {CommunicationClient}
7+
*/
58
export default class WebSocketClient {
69
/**
710
* @param {string} url url to connect

client-src/globals.d.ts

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
declare interface CommunicationClient {
2+
onOpen(fn: (...args: any[]) => void): void;
3+
onClose(fn: (...args: any[]) => void): void;
4+
onMessage(fn: (...args: any[]) => void): void;
5+
}
6+
7+
declare interface CommunicationClientConstructor {
8+
new (url: string): CommunicationClient; // Defines a constructor that takes a string and returns a GreeterInstance
9+
}
10+
11+
declare const __webpack_dev_server_client__:
12+
| CommunicationClientConstructor
13+
| { default: CommunicationClientConstructor }
14+
| undefined;
15+
16+
declare module "ansi-html-community" {
17+
function ansiHtmlCommunity(str: string): string;
18+
19+
namespace ansiHtmlCommunity {
20+
function setColors(colors: Record<string, string | string[]>): void;
21+
}
22+
23+
export = ansiHtmlCommunity;
24+
}

client-src/index.js

Lines changed: 49 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,9 @@
11
/* global __resourceQuery, __webpack_hash__ */
22
/// <reference types="webpack/module" />
3+
4+
// @ts-expect-error
35
import hotEmitter from "webpack/hot/emitter.js";
6+
// @ts-expect-error
47
import webpackHotLog from "webpack/hot/log.js";
58
import { createOverlay, formatProblem } from "./overlay.js";
69
import { defineProgressElement, isProgressSupported } from "./progress.js";
@@ -11,21 +14,31 @@ import sendMessage from "./utils/sendMessage.js";
1114
// eslint-disable-next-line jsdoc/no-restricted-syntax
1215
/** @typedef {any} EXPECTED_ANY */
1316

17+
/**
18+
* @typedef {object} RawOverlayOptions
19+
* @property {string=} warnings warnings
20+
* @property {string=} errors errors
21+
* @property {string=} runtimeErrors runtime errors
22+
* @property {string=} trustedTypesPolicyName trusted types policy name
23+
*/
24+
1425
/**
1526
* @typedef {object} OverlayOptions
16-
* @property {(boolean | (error: Error) => boolean)=} warnings warnings
17-
* @property {(boolean | (error: Error) => boolean)=} errors errors
18-
* @property {(boolean | (error: Error) => boolean)=} runtimeErrors runtime errors
27+
* @property {(boolean | ((error: Error) => boolean))=} warnings warnings
28+
* @property {(boolean | ((error: Error) => boolean))=} errors errors
29+
* @property {(boolean | ((error: Error) => boolean))=} runtimeErrors runtime errors
1930
* @property {string=} trustedTypesPolicyName trusted types policy name
2031
*/
2132

33+
/** @typedef {false | true | "none" | "error" | "warn" | "info" | "log" | "verbose"} LogLevel */
34+
2235
/**
2336
* @typedef {object} Options
2437
* @property {boolean} hot true when hot enabled, otherwise false
2538
* @property {boolean} liveReload true when live reload enabled, otherwise false
2639
* @property {boolean} progress true when need to show progress, otherwise false
2740
* @property {boolean | OverlayOptions} overlay overlay options
28-
* @property {string=} logging logging level
41+
* @property {LogLevel=} logging logging level
2942
* @property {number=} reconnect count of allowed reconnection
3043
*/
3144

@@ -37,21 +50,28 @@ import sendMessage from "./utils/sendMessage.js";
3750
*/
3851

3952
/**
40-
* @param {boolean | { warnings?: boolean | string, errors?: boolean | string, runtimeErrors?: boolean | string }} overlayOptions overlay options
53+
* @param {boolean | RawOverlayOptions | OverlayOptions} overlayOptions overlay options
4154
*/
4255
const decodeOverlayOptions = (overlayOptions) => {
4356
if (typeof overlayOptions === "object") {
44-
for (const property of ["warnings", "errors", "runtimeErrors"]) {
57+
for (const property_ of ["warnings", "errors", "runtimeErrors"]) {
58+
const property =
59+
/** @type {keyof Omit<RawOverlayOptions, "trustedTypesPolicyName">} */
60+
(property_);
61+
4562
if (typeof overlayOptions[property] === "string") {
4663
const overlayFilterFunctionString = decodeURIComponent(
4764
overlayOptions[property],
4865
);
4966

50-
// eslint-disable-next-line no-new-func
51-
overlayOptions[property] = new Function(
52-
"message",
53-
`var callback = ${overlayFilterFunctionString}
67+
/** @type {OverlayOptions} */
68+
(overlayOptions)[property] = /** @type {(error: Error) => boolean} */ (
69+
// eslint-disable-next-line no-new-func
70+
new Function(
71+
"message",
72+
`var callback = ${overlayFilterFunctionString}
5473
return callback(message)`,
74+
)
5575
);
5676
}
5777
}
@@ -73,7 +93,7 @@ const getCurrentScriptSource = () => {
7393
// `document.currentScript` is the most accurate way to find the current script,
7494
// but is not supported in all browsers.
7595
if (document.currentScript) {
76-
return document.currentScript.getAttribute("src");
96+
return /** @type {string} */ (document.currentScript.getAttribute("src"));
7797
}
7898

7999
// Fallback to getting all scripts running in the document.
@@ -94,12 +114,15 @@ const getCurrentScriptSource = () => {
94114
throw new Error("[webpack-dev-server] Failed to get current script source.");
95115
};
96116

117+
/** @typedef {{ hot?: string, ["live-reload"]?: string, progress?: string, reconnect?: string, logging?: LogLevel, overlay?: string, fromCurrentScript?: boolean }} AdditionalParsedURL */
118+
/** @typedef {Partial<URL> & AdditionalParsedURL} ParsedURL */
119+
97120
/**
98121
* @param {string} resourceQuery resource query
99-
* @returns {{ [key: string]: string | boolean }} parsed URL
122+
* @returns {ParsedURL} parsed URL
100123
*/
101124
const parseURL = (resourceQuery) => {
102-
/** @type {{ [key: string]: string }} */
125+
/** @type {ParsedURL} */
103126
let result = {};
104127

105128
if (typeof resourceQuery === "string" && resourceQuery !== "") {
@@ -108,7 +131,8 @@ const parseURL = (resourceQuery) => {
108131
for (let i = 0; i < searchParams.length; i++) {
109132
const pair = searchParams[i].split("=");
110133

111-
result[pair[0]] = decodeURIComponent(pair[1]);
134+
/** @type {EXPECTED_ANY} */
135+
(result)[pair[0]] = decodeURIComponent(pair[1]);
112136
}
113137
} else {
114138
// Else, get the url from the <script> this file was called with.
@@ -137,6 +161,9 @@ const parseURL = (resourceQuery) => {
137161

138162
const parsedResourceQuery = parseURL(__resourceQuery);
139163

164+
/** @typedef {{ ["Hot Module Replacement"]: boolean, ["Live Reloading"]: boolean, Progress: boolean, Overlay: boolean }} Features */
165+
166+
/** @type {Features} */
140167
const enabledFeatures = {
141168
"Hot Module Replacement": false,
142169
"Live Reloading": false,
@@ -197,7 +224,7 @@ if (typeof parsedResourceQuery.reconnect !== "undefined") {
197224
}
198225

199226
/**
200-
* @param {string} level level
227+
* @param {false | true | "none" | "error" | "warn" | "info" | "log" | "verbose"} level level
201228
*/
202229
const setAllLogLevel = (level) => {
203230
// This is needed because the HMR logger operate separately from dev server logger
@@ -211,6 +238,9 @@ if (options.logging) {
211238
setAllLogLevel(options.logging);
212239
}
213240

241+
/**
242+
* @param {Features} features features
243+
*/
214244
const logEnabledFeatures = (features) => {
215245
const listEnabledFeatures = Object.keys(features);
216246
if (!features || listEnabledFeatures.length === 0) {
@@ -221,7 +251,7 @@ const logEnabledFeatures = (features) => {
221251

222252
// Server started: Hot Module Replacement enabled, Live Reloading enabled, Overlay disabled.
223253
for (let i = 0; i < listEnabledFeatures.length; i++) {
224-
const key = listEnabledFeatures[i];
254+
const key = /** @type {keyof Features} */ (listEnabledFeatures[i]);
225255
logString += ` ${key} ${features[key] ? "enabled" : "disabled"},`;
226256
}
227257
// replace last comma with a period
@@ -297,6 +327,7 @@ const reloadApp = ({ hot, liveReload }, currentStatus) => {
297327
}
298328
// allow refreshing the page only if liveReload isn't disabled
299329
else if (liveReload && allowToLiveReload) {
330+
/** @type {Window} */
300331
let rootWindow = self;
301332

302333
// use parent window for reload (in case we're in an iframe with no valid src)
@@ -400,7 +431,7 @@ const onSocketMessage = {
400431
options.progress = value;
401432
},
402433
/**
403-
* @param {{ pluginName?: string, percent: number, msg: string }} data date with progress
434+
* @param {{ pluginName?: string, percent: string, msg: string }} data date with progress
404435
*/
405436
"progress-update": function progressUpdate(data) {
406437
if (options.progress) {
@@ -625,7 +656,7 @@ const formatURL = (objURL) => {
625656
};
626657

627658
/**
628-
* @param {URL & { fromCurrentScript?: boolean }} parsedURL parsed URL
659+
* @param {ParsedURL} parsedURL parsed URL
629660
* @returns {string} socket URL
630661
*/
631662
const createSocketURL = (parsedURL) => {

client-src/modules/logger/index.js

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1 +1,2 @@
1+
// @ts-expect-error
12
export { default } from "webpack/lib/logging/runtime.js";

0 commit comments

Comments
 (0)