1
- import { ErrorPayload , HMRPayload , Update } from 'types/hmrPayload'
1
+ import {
2
+ ConnectedPayload ,
3
+ ErrorPayload ,
4
+ FullReloadPayload ,
5
+ HMRPayload ,
6
+ PrunePayload ,
7
+ Update ,
8
+ UpdatePayload
9
+ } from 'types/hmrPayload'
2
10
import { ErrorOverlay , overlayId } from './overlay'
3
11
import './env'
12
+
4
13
// injected by the hmr plugin when served
5
14
declare const __ROOT__ : string
6
15
declare const __BASE__ : string
@@ -46,6 +55,7 @@ async function handleMessage(payload: HMRPayload) {
46
55
setInterval ( ( ) => socket . send ( 'ping' ) , __HMR_TIMEOUT__ )
47
56
break
48
57
case 'update' :
58
+ notifyListeners ( 'vite:beforeUpdate' , payload )
49
59
// if this is the first update and there's already an error overlay, it
50
60
// means the page opened with existing server compile error and the whole
51
61
// module script failed to load (since one of the nested imports is 500).
@@ -84,13 +94,11 @@ async function handleMessage(payload: HMRPayload) {
84
94
} )
85
95
break
86
96
case 'custom' : {
87
- const cbs = customListenersMap . get ( payload . event )
88
- if ( cbs ) {
89
- cbs . forEach ( ( cb ) => cb ( payload . data ) )
90
- }
97
+ notifyListeners ( payload . event as CustomEventName < any > , payload . data )
91
98
break
92
99
}
93
100
case 'full-reload' :
101
+ notifyListeners ( 'vite:beforeFullReload' , payload )
94
102
if ( payload . path && payload . path . endsWith ( '.html' ) ) {
95
103
// if html file is edited, only reload the page if the browser is
96
104
// currently on that page.
@@ -108,6 +116,7 @@ async function handleMessage(payload: HMRPayload) {
108
116
}
109
117
break
110
118
case 'prune' :
119
+ notifyListeners ( 'vite:beforePrune' , payload )
111
120
// After an HMR update, some modules are no longer imported on the page
112
121
// but they may have left behind side effects that need to be cleaned up
113
122
// (.e.g style injections)
@@ -120,6 +129,7 @@ async function handleMessage(payload: HMRPayload) {
120
129
} )
121
130
break
122
131
case 'error' : {
132
+ notifyListeners ( 'vite:error' , payload )
123
133
const err = payload . err
124
134
if ( enableOverlay ) {
125
135
createErrorOverlay ( err )
@@ -137,6 +147,31 @@ async function handleMessage(payload: HMRPayload) {
137
147
}
138
148
}
139
149
150
+ function notifyListeners (
151
+ event : 'vite:beforeUpdate' ,
152
+ payload : UpdatePayload
153
+ ) : void
154
+ function notifyListeners ( event : 'vite:beforePrune' , payload : PrunePayload ) : void
155
+ function notifyListeners (
156
+ event : 'vite:beforeFullReload' ,
157
+ payload : FullReloadPayload
158
+ ) : void
159
+ function notifyListeners ( event : 'vite:error' , payload : ErrorPayload ) : void
160
+ function notifyListeners < T extends string > (
161
+ event : CustomEventName < T > ,
162
+ data : any
163
+ ) : void
164
+ function notifyListeners ( event : string , data : any ) : void {
165
+ const cbs = customListenersMap . get ( event )
166
+ if ( cbs ) {
167
+ cbs . forEach ( ( cb ) => cb ( data ) )
168
+ }
169
+ }
170
+
171
+ // See https://stackoverflow.com/a/63549561.
172
+ type CustomEventName < T extends string > = ( T extends `vite:${T } ` ? never : T ) &
173
+ ( `vite:${T } ` extends T ? never : T )
174
+
140
175
const enableOverlay = __HMR_ENABLE_OVERLAY__
141
176
142
177
function createErrorOverlay ( err : ErrorPayload [ 'err' ] ) {
@@ -333,10 +368,10 @@ const hotModulesMap = new Map<string, HotModule>()
333
368
const disposeMap = new Map < string , ( data : any ) => void | Promise < void > > ( )
334
369
const pruneMap = new Map < string , ( data : any ) => void | Promise < void > > ( )
335
370
const dataMap = new Map < string , any > ( )
336
- const customListenersMap = new Map < string , ( ( customData : any ) => void ) [ ] > ( )
371
+ const customListenersMap = new Map < string , ( ( data : any ) => void ) [ ] > ( )
337
372
const ctxToListenersMap = new Map <
338
373
string ,
339
- Map < string , ( ( customData : any ) => void ) [ ] >
374
+ Map < string , ( ( data : any ) => void ) [ ] >
340
375
> ( )
341
376
342
377
// Just infer the return type for now
@@ -427,7 +462,7 @@ export const createHotContext = (ownerPath: string) => {
427
462
} ,
428
463
429
464
// custom events
430
- on ( event : string , cb : ( ) => void ) {
465
+ on : ( event : string , cb : ( data : any ) => void ) => {
431
466
const addToMap = ( map : Map < string , any [ ] > ) => {
432
467
const existing = map . get ( event ) || [ ]
433
468
existing . push ( cb )
0 commit comments