@@ -250,34 +250,23 @@ export class Driver implements Debuggable, UpdateSource {
250250 return ;
251251 }
252252
253- // Initialization is the only event which is sent directly from the SW to itself,
254- // and thus `event.source` is not a Client. Handle it here, before the check
255- // for Client sources.
256- if ( data . action === 'INITIALIZE' ) {
257- // Only initialize if not already initialized (or initializing).
258- if ( this . initialized === null ) {
259- // Initialize the SW.
260- this . initialized = this . initialize ( ) ;
261-
262- // Wait until initialization is properly scheduled, then trigger idle
263- // events to allow it to complete (assuming the SW is idle).
264- event . waitUntil ( ( async ( ) => {
265- await this . initialized ;
266- await this . idle . trigger ( ) ;
267- } ) ( ) ) ;
253+ event . waitUntil ( ( async ( ) => {
254+ // Initialization is the only event which is sent directly from the SW to itself, and thus
255+ // `event.source` is not a `Client`. Handle it here, before the check for `Client` sources.
256+ if ( data . action === 'INITIALIZE' ) {
257+ return this . ensureInitialized ( event ) ;
268258 }
269259
270- return ;
271- }
272-
273- // Only messages from true clients are accepted past this point (this is essentially
274- // a typecast).
275- if ( ! this . adapter . isClient ( event . source ) ) {
276- return ;
277- }
260+ // Only messages from true clients are accepted past this point.
261+ // This is essentially a typecast.
262+ if ( ! this . adapter . isClient ( event . source ) ) {
263+ return ;
264+ }
278265
279- // Handle the message and keep the SW alive until it's handled.
280- event . waitUntil ( this . handleMessage ( data , event . source ) ) ;
266+ // Handle the message and keep the SW alive until it's handled.
267+ await this . ensureInitialized ( event ) ;
268+ await this . handleMessage ( data , event . source ) ;
269+ } ) ( ) ) ;
281270 }
282271
283272 private onPush ( msg : PushEvent ) : void {
@@ -295,6 +284,32 @@ export class Driver implements Debuggable, UpdateSource {
295284 event . waitUntil ( this . handleClick ( event . notification , event . action ) ) ;
296285 }
297286
287+ private async ensureInitialized ( event : ExtendableEvent ) : Promise < void > {
288+ // Since the SW may have just been started, it may or may not have been initialized already.
289+ // `this.initialized` will be `null` if initialization has not yet been attempted, or will be a
290+ // `Promise` which will resolve (successfully or unsuccessfully) if it has.
291+ if ( this . initialized !== null ) {
292+ return this . initialized ;
293+ }
294+
295+ // Initialization has not yet been attempted, so attempt it. This should only ever happen once
296+ // per SW instantiation.
297+ try {
298+ this . initialized = this . initialize ( ) ;
299+ await this . initialized ;
300+ } catch ( error ) {
301+ // If initialization fails, the SW needs to enter a safe state, where it declines to respond
302+ // to network requests.
303+ this . state = DriverReadyState . SAFE_MODE ;
304+ this . stateMessage = `Initialization failed due to error: ${ errorToString ( error ) } ` ;
305+
306+ throw error ;
307+ } finally {
308+ // Regardless if initialization succeeded, background tasks still need to happen.
309+ event . waitUntil ( this . idle . trigger ( ) ) ;
310+ }
311+ }
312+
298313 private async handleMessage ( msg : MsgAny & { action : string } , from : Client ) : Promise < void > {
299314 if ( isMsgCheckForUpdates ( msg ) ) {
300315 const action = ( async ( ) => { await this . checkForUpdate ( ) ; } ) ( ) ;
@@ -383,28 +398,10 @@ export class Driver implements Debuggable, UpdateSource {
383398 }
384399
385400 private async handleFetch ( event : FetchEvent ) : Promise < Response > {
386- // Since the SW may have just been started, it may or may not have been initialized already.
387- // this.initialized will be `null` if initialization has not yet been attempted, or will be a
388- // Promise which will resolve (successfully or unsuccessfully) if it has.
389- if ( this . initialized === null ) {
390- // Initialization has not yet been attempted, so attempt it. This should only ever happen once
391- // per SW instantiation.
392- this . initialized = this . initialize ( ) ;
393- }
394-
395- // If initialization fails, the SW needs to enter a safe state, where it declines to respond to
396- // network requests.
397401 try {
398- // Wait for initialization.
399- await this . initialized ;
400- } catch ( e ) {
401- // Initialization failed. Enter a safe state.
402- this . state = DriverReadyState . SAFE_MODE ;
403- this . stateMessage = `Initialization failed due to error: ${ errorToString ( e ) } ` ;
404-
405- // Even though the driver entered safe mode, background tasks still need to happen.
406- event . waitUntil ( this . idle . trigger ( ) ) ;
407-
402+ // Ensure the SW instance has been initialized.
403+ await this . ensureInitialized ( event ) ;
404+ } catch {
408405 // Since the SW is already committed to responding to the currently active request,
409406 // respond with a network fetch.
410407 return this . safeFetch ( event . request ) ;
0 commit comments