# j-ServiceWorker

> Cache SPA assets and an offline fallback with a service worker.

Framework: jcomponent20
Product: jComponent 20 (jcomponent@20)
Language: en
Content-SHA256: db7ce63bfad9ca3799e0164bf5dfdebe02eeade49ceedf536d1bb2e934d2ad6b
Snapshot: c0700e321579725c5cf4f5ace1ad7d2866d1b4f93c24a63c0b41b6b7998e976c
Sources: components@910ed1a86f6e72b4f031d3ad0dc7844f9fc5cb8e
Review: usage-reviewed

The component registers /sw-jcomponent.js and sends it the asset list, cache version and offline fallback from its datasource. Serve the application over HTTPS or localhost, and place the worker at the root URL so it can handle the application pages.

- This component is a little bit special. First of all, you need put the code below into file e.g. `sw-jcomponent.js` and place it to the `public` (e.g. `myproject/public/sw-jcomponent.js`)

```js
var prefix='jc';function hash(s,unsigned){var hash=0,i,char;if(!s.length)return hash;var l=s.length;for(i=0;i<l;i++){char=s.charCodeAt(i);hash=((hash<<5)-hash)+char;hash|=0;}return unsigned?hash>>>0:hash}self.addEventListener('install',()=>{self.skipWaiting()});self.addEventListener('message',function(e){if(e.data.action==='jc-sw'){var data=e.data.data;data.name=prefix+'-'+data.version+'-'+hash(data.assets.toString(),true);addcache(e.data.data)}});self.addEventListener('fetch',function(e){e.respondWith(fetch(e.request).catch(function(){return caches.match(e.request).then(function(response){if(response)return response;if(e.request.mode==='navigate'||(e.request.method==='GET'&&e.request.headers.get('accept').includes('text/html')))return caches.match('jc-offline-fallback')})}))});function addcache(data){caches.open(data.name).then(function(cache){if(data.assets&&data.assets.length)cache.addAll(data.assets);if(data.fallback){fetch(data.fallback,{mode:'no-cors'}).then(function(response){return cache.put('jc-offline-fallback',response)})}}).then(function(){caches.keys().then(function(keys){return Promise.all(keys.map(function(key){if(data.name!==key)return caches.delete(key)}))})})}
```

- The component will communicate with this _service worker_ code.

__Configuration__:

- `expire {String}` expiration data from users storage (default: `1 day`) __we don't recommend changing this__
- `debug {Boolean}` enables `debug` mode. It'll refresh assets every reload (so you don't need to change the version) (default: `false`)
- `datasource {String}` path to data-source (data-source is a object)

__Datasource structure__:

```js
{
	version: '1.00',
	fallback: '/',
	assets: [
		'/js/default.js'
	]
}
```

__Good to know__:
- __PATH__ can be used as dynamic version. It'll refresh assets instantly (without page reloading) e.g. `SET('version', '1.35')`
- After add/remove something from assets, you doesn't need to increase version
- __fallback__ performs offline version of html. e.g. `fallback: '/offline.html'`
- Assets can be everything: fonts, partial pages, css files, javascript files
- __It's work only in Single Page Applications like [this](https://github.com/totaljs/spa) or [this](https://github.com/totaljs/emptyproject-pwa)__

__Usage__:

```html
<ui-component name="serviceworker" path="version" config="datasource:mysource"></ui-component>

<script>
	var version = '1.34';
	var mysource = {
		version: version,
		fallback: '/',
		assets: [
			'/pages/settings.html',
			'/pages/articles.html',
			'/pages/dashboard.html'
		]
	};
</script>
```

Source: [Total.js components](https://github.com/totaljs/components/tree/910ed1a86f6e72b4f031d3ad0dc7844f9fc5cb8e/j-ServiceWorker). Copyright Denis Granec. [MIT license](/knowledge-licenses.json).
