@@ -15,6 +15,8 @@ import * as HMR from "./hmr";
15
15
import { warnOnce } from "../warnOnce" ;
16
16
import { detectPackageManager } from "../cli/detectPackageManager" ;
17
17
import * as HDR from "./hdr" ;
18
+ import type { Result } from "../result" ;
19
+ import { err , ok } from "../result" ;
18
20
19
21
type Origin = {
20
22
scheme : string ;
@@ -59,7 +61,7 @@ export let serve = async (
59
61
manifest ?: Manifest ;
60
62
prevManifest ?: Manifest ;
61
63
appReady ?: Channel . Type < void > ;
62
- hdr ?: Promise < Record < string , string > > ;
64
+ loaderChanges ?: Promise < Result < Record < string , string > > > ;
63
65
prevLoaderHashes ?: Record < string , string > ;
64
66
} = { } ;
65
67
@@ -122,57 +124,70 @@ export let serve = async (
122
124
} ,
123
125
{
124
126
onBuildStart : async ( ctx ) => {
127
+ // stop listening for previous manifest
125
128
state . appReady ?. err ( ) ;
129
+
126
130
clean ( ctx . config ) ;
127
131
websocket . log ( state . prevManifest ? "Rebuilding..." : "Building..." ) ;
128
132
129
- state . hdr = HDR . detectLoaderChanges ( ctx ) ;
133
+ state . loaderChanges = HDR . detectLoaderChanges ( ctx ) . then ( ok , err ) ;
130
134
} ,
131
135
onBuildManifest : ( manifest : Manifest ) => {
132
136
state . manifest = manifest ;
137
+ state . appReady = Channel . create ( ) ;
133
138
} ,
134
139
onBuildFinish : async ( ctx , durationMs , succeeded ) => {
135
140
if ( ! succeeded ) return ;
136
-
137
141
websocket . log (
138
142
( state . prevManifest ? "Rebuilt" : "Built" ) +
139
143
` in ${ prettyMs ( durationMs ) } `
140
144
) ;
141
- state . appReady = Channel . create ( ) ;
142
145
143
- let start = Date . now ( ) ;
144
- console . log ( `Waiting for app server (${ state . manifest ?. version } )` ) ;
145
- if (
146
- options . command &&
147
- ( state . appServer === undefined || options . restart )
148
- ) {
149
- await kill ( state . appServer ) ;
150
- state . appServer = startAppServer ( options . command ) ;
151
- }
152
- let { ok } = await state . appReady . result ;
153
- // result not ok -> new build started before this one finished. do not process outdated manifest
154
- let loaderHashes = await state . hdr ;
155
- if ( ok ) {
146
+ // accumulate new state, but only update state after updates are processed
147
+ let newState : typeof state = { prevManifest : state . manifest } ;
148
+ try {
149
+ console . log ( `Waiting for app server (${ state . manifest ?. version } )` ) ;
150
+ let start = Date . now ( ) ;
151
+ if (
152
+ options . command &&
153
+ ( state . appServer === undefined || options . restart )
154
+ ) {
155
+ await kill ( state . appServer ) ;
156
+ state . appServer = startAppServer ( options . command ) ;
157
+ }
158
+ let appReady = await state . appReady ! . result ;
159
+ if ( ! appReady . ok ) return ;
156
160
console . log ( `App server took ${ prettyMs ( Date . now ( ) - start ) } ` ) ;
157
- if ( state . manifest && loaderHashes && state . prevManifest ) {
161
+
162
+ // HMR + HDR
163
+ let loaderChanges = await state . loaderChanges ! ;
164
+ if ( loaderChanges . ok ) {
165
+ newState . prevLoaderHashes = loaderChanges . value ;
166
+ }
167
+ if ( loaderChanges ?. ok && state . manifest && state . prevManifest ) {
158
168
let updates = HMR . updates (
159
169
ctx . config ,
160
170
state . manifest ,
161
171
state . prevManifest ,
162
- loaderHashes ,
172
+ loaderChanges . value ,
163
173
state . prevLoaderHashes
164
174
) ;
165
175
websocket . hmr ( state . manifest , updates ) ;
166
176
167
177
let hdr = updates . some ( ( u ) => u . revalidate ) ;
168
178
console . log ( "> HMR" + ( hdr ? " + HDR" : "" ) ) ;
169
- } else if ( state . prevManifest !== undefined ) {
179
+ return ;
180
+ }
181
+
182
+ // Live Reload
183
+ if ( state . prevManifest !== undefined ) {
170
184
websocket . reload ( ) ;
171
185
console . log ( "> Live reload" ) ;
172
186
}
187
+ } finally {
188
+ // commit accumulated state
189
+ Object . assign ( state , newState ) ;
173
190
}
174
- state . prevManifest = state . manifest ;
175
- state . prevLoaderHashes = loaderHashes ;
176
191
} ,
177
192
onFileCreated : ( file ) =>
178
193
websocket . log ( `File created: ${ relativePath ( file ) } ` ) ,
0 commit comments