¿Cómo puedo reclamar un cliente al inicializar un ServiceWorker para evitar tener que volver a cargar la página?

Estoy teniendo problemas para entenderClientes reclamo API del ServiceWorker. Por lo que entiendoaquí yaquí) Puedo llamarclaim() en el trabajador de servicioactivar evento para evitar tener que actualizar la página para inicializar el ServiceWorker. Sin embargo, no puedo hacer que funcione y siempre termino teniendo que actualizar. Aquí está mi código:

Dentro del trabajador de servicio:

self.addEventListener('install', function (event) {

  self.skipWaiting();

  event.waitUntil(caches.open(CURRENT_CACHE_DICT.prefetch)
    .then(function(cache) {
      var cachePromises = PREFETCH_URL_LIST.map(function(prefetch_url) {
        var url = new URL(prefetch_url, location.href),
          request = new Request(url, {mode: 'no-cors'});

        return fetch(request).then(function(response) {
          if (response.status >= 400) {
            throw new Error('request for ' + prefetch_url +
              ' failed with status ' + response.statusText);
          }
          return cache.put(prefetch_url, response);
        }).catch(function(error) {
          console.error('Not caching ' + prefetch_url + ' due to ' + error);
        });
      });

      return Promise.all(cachePromises).then(function() {
        console.log('Pre-fetching complete.');
      });
    }).catch(function(error) {
      console.error('Pre-fetching failed:', error);
    })
  );
});

self.addEventListener('activate', function (event) {

  // claim the scope immediately
  // XXX does not work?
  //self.clients.claim();

  event.waitUntil(self.clients.claim()
    .then(caches.keys)
    .then(function(cache_name_list) {
      return Promise.all(
        cache_name_list.map(function() {...}
      );
    })
  );
});

Lo anterior se ejecuta pero estoy terminando teniendo que actualizar y encontré unIllegal invocation error en las partes internas de Chrome ServiceWorker. Si elimino elclients.claim desde elwaitUntil controlador y descomentar el anterior, no obtengo errores, pero todavía tengo que actualizar. El depurador muestra:

Console: {"lineNumber":128,"message":"Pre-fetching complete.","message_level":1,"sourceIdentifier":3,"sourceURL":""}
Console: {"lineNumber":0,"message":"Uncaught (in promise) TypeError: Illegal invocation","message_level":3,"sourceIdentifier":1,"sourceURL":""}

La actualización se activa así:

function waitForInstallation(registration) {
    return new RSVP.Promise(function(resolve, reject) {
        if (registration.installing) {
      registration.installing.addEventListener('statechange', function(e) {
        if (e.target.state == 'installed') {
          resolve();
        } else if (e.target.state == 'redundant') {
          reject(e);
        }
      });
    } else {
      resolve();
    }
  });
}

// refreshing should not be necessary if scope is claimed on activate
function claimScope(installation) {
  return new RSVP.Promise(function (resolve, reject) {
    if (navigator.serviceWorker.controller) {
      resolve();
    } else {
      reject(new Error("Please refresh to initialize serviceworker."));
    }
  });
}

rJS(window)
  .declareMethod('render', function (my_option_dict) {
    var gadget = this;

    if ('serviceWorker' in navigator) {
      return new RSVP.Queue()
        .push(function () {
          return navigator.serviceWorker.register(
            my_option_dict.serviceworker_url,
            {scope: my_option_dict.scope}
          );
        })
        .push(function (registration) {
          return waitForInstallation(registration);
        })
        .push(function (installation) {
          return claimScope(installation);
        })
        .push(null, function (my_error) {
          console.log(my_error);
          throw my_error;
        });
    } else {
      throw new Error("Browser does not support serviceworker.");
    }
  }); 

Pregunta:
¿Cómo evito correctamente que la página tenga que actualizarse para activar el ServiceWorker usandoclaim? Ninguno de los enlaces que encontré mencionó tener que verificar explícitamentecontroller pero supongo que si un ServiceWorker está activo, tendría un controlador accesible.

Gracias por arrojar algo de información.

EDITAR:
Lo descubrí con ayuda de abajo. Esto me hizo funcionar:

// runs while an existing worker runs or nothing controls the page (update here)
self.addEventListener('install', function (event) {

  event.waitUntil(caches.open(CURRENT_CACHE_DICT.dictionary)
    .then(function(cache) {
      var cache_promise_list = DICTIONARY_URL_LIST.map(function(prefetch_url) {...});

      return Promise.all(cache_promise_list).then(function() {
        console.log('Pre-fetching complete.');
      });
    })
    .then(function () {

      // force waiting worker to become active worker (claim)
      self.skipWaiting();

    }).catch(function(error) {
      console.error('Pre-fetching failed:', error);
    })
  );
});

// runs active page, changes here (like deleting old cache) breaks page
self.addEventListener('activate', function (event) {

  event.waitUntil(caches.keys()
    .then(function(cache_name_list) {
      return Promise.all(
        cache_name_list.map(function(cache_name) { ... })  
      );
    })
    .then(function () {
      return self.clients.claim();
    })
  );
});

Secuencia de comandos de activación:

var SW = navigator.serviceWorker;    

function installServiceWorker(my_option_dict) {
  return new RSVP.Queue()
    .push(function () {
      return SW.getRegistration();
    })
    .push(function (is_registered_worker) {

      // XXX What if this isn't mine?
      if (!is_registered_worker) {
        return SW.register(
          my_option_dict.serviceworker_url, {
            "scope": my_option_dict.scope
          }
        );   
      }
      return is_registered_worker;
    });
}

function waitForInstallation(registration) {
  return new RSVP.Promise(function(resolve, reject) {
    if (registration.installing) {
      // If the current registration represents the "installing" service
      // worker, then wait until the installation step completes (during
      // which any defined resources are pre-fetched) to continue.
      registration.installing.addEventListener('statechange', function(e) {
        if (e.target.state == 'installed') {
          resolve(registration);
        } else if (e.target.state == 'redundant') {
          reject(e);
        }
      });
    } else {
      // Otherwise, if this isn't the "installing" service worker, then
      // installation must have beencompleted during a previous visit to this
      // page, and the any resources will already have benn pre-fetched So
      // we can proceed right away.
      resolve(registration);
    }
  });
}

// refreshing should not be necessary if scope is claimed on activate
function claimScope(registration) {
  return new RSVP.Promise(function (resolve, reject) {
    if (registration.active.state === 'activated') {
      resolve();
    } else {
      reject(new Error("Please refresh to initialize serviceworker."));
    }
  });
}

rJS(window)

  .ready(function (my_gadget) {
    my_gadget.property_dict = {};
  })

  .declareMethod('render', function (my_option_dict) {
    var gadget = this;

    if (!SW) {
      throw new Error("Browser does not support serviceworker.");
    }

    return new RSVP.Queue()
      .push(function () {
        return installServiceWorker(my_option_dict),
      })
      .push(function (my_promise) {
        return waitForInstallation(my_promise);
      })
      .push(function (my_installation) {
        return claimScope(my_installation);
      })
      .push(function () {
        return gadget;
      })
      .push(null, function (my_error) {
        console.log(my_error);
        throw my_error;
      });
  });

Respuestas a la pregunta(1)

Su respuesta a la pregunta