Created
July 22, 2017 14:23
-
-
Save typoerr/a96e07114b2e368eea25c1fe2e16cd93 to your computer and use it in GitHub Desktop.
worker-utils
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
declare var navigator: Navigator; | |
// navigator.serviceWorker.readyはactivate直前に発火するため、controllerの存在確認には信用できない | |
// そのためcontrollerchangeイベントを待つ必要がある | |
export default function awaitServiceWorker() { | |
return new Promise<ServiceWorker>((resolve) => { | |
const resolved = () => resolve(navigator.serviceWorker.controller!); | |
if (navigator.serviceWorker.controller) { | |
resolved(); | |
} else { | |
navigator.serviceWorker.addEventListener('controllerchange', resolved); | |
} | |
}); | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import Minitter from 'minitter'; | |
export type ResponseMap<T, C> = { | |
[K in keyof T]: MessageRequestEvent<T, C, K> | |
}; | |
export interface Action<T, K extends keyof T> { | |
type: K; | |
payload: T[K]; | |
} | |
type Port = { postMessage: Function }; | |
export class MessageRequestEvent<T, C, K extends keyof T> { | |
type: K; | |
data: T[K]; | |
context: C; | |
private ports: Port[] = []; | |
constructor(action: Action<T, K>, context: C, ports?: Port[] | null) { | |
this.type = action.type; | |
this.data = action.payload; | |
this.context = context; | |
this.ports = ports || []; | |
} | |
res<K2 extends keyof T>(type: K2, payload: T[K2]) { | |
const r = JSON.stringify({ type, payload }); | |
this.ports.forEach(port => port.postMessage(r)); | |
} | |
} | |
export class Messenger<T, C = any> extends Minitter<ResponseMap<T, C>> { } | |
/* | |
# Example | |
--------------------------------------------------- | |
interface Messages { | |
'worker:request:a': string; | |
'worker:resolved:a': number; | |
'worker:error:a': Error | |
} | |
const messenger = new Messenger<Messages>(); | |
self.addEventListener('message', ev => { | |
self.clients.matchAll().then(list => { | |
const action = JSON.parse(ev.data) | |
messenger.emit(action.type, new ResponseEvent(action, {}, list)) | |
}) | |
}) | |
messenger.on('a', e => { | |
return someAsyncFunction(e.data) | |
.then(x => e.response('worker:resolved:a', x)) | |
.catch(err => e.response('worker:error:a', err)) | |
}); | |
*/ |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
export type TypedMessageWorker<T> = (Worker | ServiceWorker) & { | |
request<K extends keyof T>(type: K, payload: T[K]): void; | |
}; | |
export default function enhance<T = any>(worker: Worker | ServiceWorker): TypedMessageWorker<T> { | |
function request<K extends keyof T>(type: K, payload: T[K]) { | |
const action = JSON.stringify({ type, payload }); | |
worker.postMessage(action); | |
} | |
return Object.assign(worker, { request }); | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment