11/* global __resourceQuery, __webpack_hash__ */
22/// <reference types="webpack/module" />
3+
4+ // @ts -expect-error
35import hotEmitter from "webpack/hot/emitter.js" ;
6+ // @ts -expect-error
47import webpackHotLog from "webpack/hot/log.js" ;
58import { createOverlay , formatProblem } from "./overlay.js" ;
69import { 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 */
4255const 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 */
101124const 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
138162const parsedResourceQuery = parseURL ( __resourceQuery ) ;
139163
164+ /** @typedef {{ ["Hot Module Replacement"]: boolean, ["Live Reloading"]: boolean, Progress: boolean, Overlay: boolean } } Features */
165+
166+ /** @type {Features } */
140167const 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 */
202229const 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+ */
214244const 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 */
631662const createSocketURL = ( parsedURL ) => {
0 commit comments