Primeira definição de Worker surgiu com o WebWorkers http://www.html5rocks.com/en/tutorials/workers/basics/
Resumindo: scripts rodando em paralelo à pagina
EX: tarefas que exigem alto processamento
// main script
var worker = new Worker('worker.js');
worker.addEventListener('message', function(e) {
console.log('Worker diz: ', e.data);
}, false);
worker.postMessage('Oi, eu sou o Worker!');
// worker.js
self.addEventListener('message', function(e) {
self.postMessage(e.data);
}, false);
A forma de cachear arquivos parecia simples...
http://diveintohtml5.info/offline.html < html manifest="offline.appcache">
CACHE MANIFEST
assets/6/script/mainmin.js
assets/6/style/mainmin.css
assets/6/style/fonts/pro.ttf
assets/6/style/imgs/sprites1.png
https://meu.server.com/data/posts.json
https://meu.server.com/assets/application.css
https://meu.server.com/assets/application.js
https://meu.server.com/assets/image.jpeg
// main script
navigator.serviceWorker.register("/js/sw_cache.js").then(
function ( serviceWorker ) {
console.log("ServiceWorkers instalado com sucesso.");
},
function ( error ) {
console.error("Ops.. não rolou a instalação do ServiceWorkers", error);
});
Cacheando seus assets
// assets/sw_cache.js
self.addEventListener('install', function(event) {
var urlsToPrefetch = [
'https://www.chromium.org/_/rsrc/1302286216006/config/customLogo.gif'
];
event.waitUntil(
caches.open(CURRENT_CACHES['prefetch']).then(function(cache) {
return cache.addAll(urlsToPrefetch.map(function(urlToPrefetch) {
return new Request(urlToPrefetch, {mode: 'no-cors'});
})
).then(function() {
console.log('All resources fetched and cached.');
});
}).catch(function(error) {
console.error('Pre-fetching failed:', error);
})
);
})
Interceptando requests
// assets/service-worker.js
var base = "https://meu.server.com";
var data_url = new URL("/data/posts.json", base) + "";
self.addEventListener("fetch", function(e) {
var url = e.request.url;
console.log(url);
if (url == data_url) {
e.respondWith(
new Response(JSON.stringify({
posts: { /* ... */ }
}), {
headers: { 'Content-Type': 'application/json' },
status: 200
})
);
}
});
Request + Cache
// assets/worker.js
self.version = 2;
var base = "https://meu.server.com"
var data_url = new URL("/data/posts.json", base) + "";
self.addEventListener("fetch",
function ( e ) {
if (e.request.url == data_url) {
e.respondWith(
caches.match( e.request )
.catch( function () {
return e.default;
})
.catch( function () {
return caches.match("/data/posts_fallback.json");
})
);
}
}
);
Ainda muito recente
navigator.serviceWorker.ready.then(function (sw) {
// Returns a Promise
navigator.sync.register(
"my_data_sync",
{
minInterval: 86400 * 1000, // ms, default: heuristic
repeating: true, // default: false
data: '', // default: empty string
description: '', // default: empty string
lang: '', // default: document lang
dir: '' // default: document dir
}
).then(function() { // Success
// No resolved value
// Success, sync is now registered
},
function() { // Failure
// If no SW registration
// User/UA denied permission
// Sync id already registered
});
});
// assets/service-worker.js
self.onsync = function(event) {
var data = JSON.parse(event.data);
if (event.id === "my_data_sync") {
if (data.whatever === "foo") {
// rejection is indication that the UA should try
// later (especially when network is ok)
event.waitUntil(doAsyncStuff());
}
} else {
// Garbage collect unknown syncs (perhaps from older pages).
navigator.sync.unregister(event.id);
}
};
Nem a spec foi definida.
Spec ainda engatinhando
https://github.com/WebBluetoothCG/web-bluetooth http://www.w3.org/community/web-bluetoothlink da palestra: http://bit.ly/service-workers-tdc-sp
meu twitter: @eduardojmatos