Como posso reivindicar um cliente ao inicializar um ServiceWorker para evitar a necessidade de recarregar a página?

Estou tendo problemas para envolver minha cabeçaClients.claim API do ServiceWorker. Pelo que entendi (aqui eaqui) Eu posso ligarclaim() no trabalhador de serviçoativar evento para evitar a necessidade de atualizar a página para inicializar o ServiceWorker. Eu não consigo fazê-lo funcionar e sempre acabo tendo que atualizar. Aqui está o meu código:

Dentro do trabalhador de serviço:

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() {...}
      );
    })
  );
});

O procedimento acima é executado, mas estou tendo que atualizar e encontrei umIllegal invocation erro nos internos do Chrome ServiceWorker. Se eu remover oclients.claim dewaitUntil manipulador e descomente o anterior, não recebo erros, mas ainda preciso atualizar. O depurador mostra:

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":""}

A atualização é acionada assim:

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.");
    }
  }); 

Pergunta, questão:
Como impedir corretamente que a página seja atualizada para ativar o ServiceWorker usandoclaim? Nenhum dos links que encontrei mencionou ter que procurar explicitamentecontroller mas suponho que se um ServiceWorker estiver ativo, ele terá um controlador acessível.

Obrigado por divulgar algumas informações.

EDITAR:
Descobri-lo com a ajuda de baixo. Isso fez funcionar para mim:

// 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();
    })
  );
});

Script de acionamento:

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;
      });
  });

questionAnswers(1)

yourAnswerToTheQuestion