TalAter / UpUp

✈️ Easily create sites that work offline as well as online
https://www.talater.com/upup/
MIT License
4.88k stars 264 forks source link

Allow to update the asset(s) that the SW cached #43

Closed greenido closed 8 years ago

greenido commented 9 years ago

When we updating an asset (e.g. code, img etc') there should be an easy way to communicate it to upup so it could refresh the cached version.

TalAter commented 9 years ago

Great idea. This should be implemented along with #12 (add TTLs to the cache so some assets can be recached automatically once stale) and #29 (allowing the site to ask for the cached assets timestamp).

By the way, do you have a real life use case you're already dealing with for this? Could help plan the implementation in the best way possible.

greenido commented 9 years ago

I don't have a real life use case (at the moment :) But maybe, @jakearchibald could point us here.

jakearchibald commented 9 years ago

I guess you'd want the cache to be updated following any change to the resources. Be it a spelling correcting, and accidental xss vector, a change of branding etc etc.

bergben commented 8 years ago

any news on this? is there an alternative way to do this for now?

vukhanhtruong commented 8 years ago

+1

greenido commented 8 years ago

Ahh :) good reminder... @Tal - Any news?

On Sat, Sep 10, 2016 at 1:46 AM, Vu Khanh Truong notifications@github.com wrote:

+1

— You are receiving this because you authored the thread. Reply to this email directly, view it on GitHub https://github.com/TalAter/UpUp/issues/43#issuecomment-246100306, or mute the thread https://github.com/notifications/unsubscribe-auth/AADwIFGGqmUiGiH5kLZrYUnDPQ_UOoD-ks5qom58gaJpZM4F2UYW .

TalAter commented 8 years ago

OK,

I took some time to think about this issue, and here is how I plan to approach this. Feedback and ideas would be welcome.

First of all, I should say that UpUp behaves a bit differently than the traditional service worker caching pattern. The common approach is to cache on the service worker's install event and clear obsolete caches on the activate event. This approach won't work for UpUp as it only installs a service worker once per UpUp version. The developer using UpUp changes the code on the page, not in the service worker when she is setting content, assets or other settings.

This is why UpUp does the caching in response to a message event posted from the page. It then places the resources it caches in a cache called upup-cache.

The proposed solution:

  1. When UpUp posts a message to the service worker, pass it a hash value generated from the settings object's content-url + content + assets.
  2. Add an option for the developer to pass a cache version name in UpUp's settings object (optional). This will pass to the service worker through the posted message.
  3. Change UpUp's service worker to use a cache named 'upup-cache-'+versionName+cacheHash. When the page code posts a message to the service worker it will pass it this version name and the cache's hash. The service worker will cache.addAll() of the assets and content to this new cache, and then delete all other caches whose name begins with upup-cache.

To summarize:

UpUp will now save the offline content in a new cache every time the developer changes the list of files/content to cache, and/or passes a new version name.

For example:

UpUp.start({
  'cache-version': 1,
  'content-url': 'offline.html',
  'assets': ['/img/logo.png']
});

Both of the following changes would cause a new cache to be used:

// Changing a cache version
UpUp.start({
  'cache-version': 2,
  'content-url': 'offline.html',
  'assets': ['/img/logo.png']
});
// Changing the assets to be cached
UpUp.start({
  'cache-version': 1,
  'content-url': 'offline.html',
  'assets': ['/img/logo.png', '/css/style.css']
});
hash function ``` javascript var hash = function(input) { input = input.toString(); var hash = 0, i, chr, len = input.length; if (len === 0) { return hash; } for (i = 0; i < len; i++) { chr = input.charCodeAt(i); hash = ((hash << 5) - hash) + chr; hash |= 0; } return hash; } console.log(hash(['312', 'saddsa'])); ```
TalAter commented 8 years ago

This change is live now 🎆 !

As of a67c12b7d56a4879f9007ec3bd474a15a92b52cb, files are now saved in a separate cache every time the content of content, content-url or assets changes. Once the new cache is saved, all the older UpUp caches are deleted.

You can also manually force a cache update by adding or changing a cache-version to your settings object.

For example:

UpUp.start({
  'cache-version': 'v2',
  'content-url': '/offline.html',
  'assets': ['/img/logo.png']
});

This is also in the docs.

I still want to solve #12, and then I will release version 1.0.0