@@ -22,7 +22,7 @@ class Module {
22
22
this . _isLocked = true
23
23
}
24
24
25
- accept ( callback ?: ( ) => void ) : void {
25
+ accept ( callback ?: Callback ) : void {
26
26
if ( this . _isLocked ) {
27
27
return
28
28
}
@@ -45,69 +45,94 @@ class Module {
45
45
}
46
46
}
47
47
48
- const { location } = window as any
49
- const { protocol, host } = location
50
48
const modules : Map < string , Module > = new Map ( )
51
- const messageQueue : any [ ] = [ ]
52
- const url = ( protocol === 'https:' ? 'wss' : 'ws' ) + '://' + host + '/_hmr'
53
- const socket = new WebSocket ( url )
49
+ const state : {
50
+ socket : WebSocket | null
51
+ messageQueue : string [ ]
52
+ } = {
53
+ socket : null ,
54
+ messageQueue : [ ]
55
+ }
54
56
55
- socket . addEventListener ( 'open' , ( ) => {
56
- messageQueue . forEach ( msg => socket . send ( JSON . stringify ( msg ) ) )
57
- messageQueue . splice ( 0 , messageQueue . length )
58
- console . log ( '[HMR] listening for file changes...' )
59
- } )
57
+ function sendMessage ( msg : any ) {
58
+ const json = JSON . stringify ( msg )
59
+ if ( ! state . socket || state . socket . readyState !== WebSocket . OPEN ) {
60
+ state . messageQueue . push ( json )
61
+ } else {
62
+ state . socket . send ( json )
63
+ }
64
+ }
60
65
61
- socket . addEventListener ( 'close' , ( ) => {
62
- location . reload ( )
63
- } )
66
+ export function connect ( basePath : string ) {
67
+ const { location } = window as any
68
+ const { protocol, host } = location
69
+ const url = ( protocol === 'https:' ? 'wss' : 'ws' ) + '://' + host + basePath . replace ( / \/ + $ / , '' ) + '/_hmr'
70
+ const ws = new WebSocket ( url )
64
71
65
- socket . addEventListener ( 'message' , ( { data } : { data ?: string } ) => {
66
- if ( data ) {
67
- try {
68
- const {
69
- type,
70
- url,
71
- updateUrl,
72
- routePath,
73
- isIndex,
74
- useDeno,
75
- } = JSON . parse ( data )
76
- switch ( type ) {
77
- case 'add' :
78
- events . emit ( 'add-module' , {
79
- url,
80
- routePath,
81
- isIndex,
82
- useDeno,
83
- } )
84
- break
85
- case 'update' :
86
- const mod = modules . get ( url )
87
- if ( mod ) {
88
- mod . applyUpdate ( updateUrl )
89
- }
90
- break
91
- case 'remove' :
92
- if ( modules . has ( url ) ) {
93
- modules . delete ( url )
94
- events . emit ( 'remove-module' , url )
95
- }
96
- break
97
- }
98
- console . log ( `[HMR] ${ type } module '${ url } '` )
99
- } catch ( err ) {
100
- console . warn ( err )
72
+ ws . addEventListener ( 'open' , ( ) => {
73
+ state . socket = ws
74
+ state . messageQueue . splice ( 0 , state . messageQueue . length ) . forEach ( msg => ws . send ( msg ) )
75
+ console . log ( '[HMR] listening for file changes...' )
76
+ } )
77
+
78
+ ws . addEventListener ( 'close' , ( ) => {
79
+ if ( state . socket === null ) {
80
+ // re-connect
81
+ setTimeout ( ( ) => {
82
+ connect ( basePath )
83
+ } , 300 )
84
+ } else {
85
+ state . socket = null
86
+ console . log ( '[HMR] closed.' )
87
+ // reload the page when re-connected
88
+ setInterval ( ( ) => {
89
+ const ws = new WebSocket ( url )
90
+ ws . addEventListener ( 'open' , ( ) => {
91
+ location . reload ( )
92
+ } )
93
+ } , 300 )
101
94
}
102
- }
103
- } )
95
+ } )
104
96
105
- function sendMessage ( msg : any ) {
106
- if ( socket . readyState !== socket . OPEN ) {
107
- messageQueue . push ( msg )
108
- } else {
109
- socket . send ( JSON . stringify ( msg ) )
110
- }
97
+ ws . addEventListener ( 'message' , ( { data } : { data ?: string } ) => {
98
+ if ( data ) {
99
+ try {
100
+ const {
101
+ type,
102
+ url,
103
+ updateUrl,
104
+ routePath,
105
+ isIndex,
106
+ useDeno,
107
+ } = JSON . parse ( data )
108
+ switch ( type ) {
109
+ case 'add' :
110
+ events . emit ( 'add-module' , {
111
+ url,
112
+ routePath,
113
+ isIndex,
114
+ useDeno,
115
+ } )
116
+ break
117
+ case 'update' :
118
+ const mod = modules . get ( url )
119
+ if ( mod ) {
120
+ mod . applyUpdate ( updateUrl )
121
+ }
122
+ break
123
+ case 'remove' :
124
+ if ( modules . has ( url ) ) {
125
+ modules . delete ( url )
126
+ events . emit ( 'remove-module' , url )
127
+ }
128
+ break
129
+ }
130
+ console . log ( `[HMR] ${ type } module '${ url } '` )
131
+ } catch ( err ) {
132
+ console . warn ( err )
133
+ }
134
+ }
135
+ } )
111
136
}
112
137
113
138
export function createHotContext ( url : string ) {
0 commit comments