From bf5b5072f882af849ee66d4c5912c3e005e3a2bb Mon Sep 17 00:00:00 2001 From: Yamagishi Kazutoshi Date: Fri, 17 May 2019 02:26:51 +0900 Subject: [PATCH] [workbox-window]: add types (#35522) --- types/workbox-window/Workbox.d.ts | 115 ++++++++++++++++++ types/workbox-window/index.d.ts | 8 ++ types/workbox-window/messageSW.d.ts | 12 ++ types/workbox-window/tsconfig.json | 28 +++++ types/workbox-window/tslint.json | 3 + .../workbox-window/utils/EventTargetShim.d.ts | 18 +++ types/workbox-window/utils/WorkboxEvent.d.ts | 25 ++++ types/workbox-window/workbox-window-tests.ts | 16 +++ 8 files changed, 225 insertions(+) create mode 100644 types/workbox-window/Workbox.d.ts create mode 100644 types/workbox-window/index.d.ts create mode 100644 types/workbox-window/messageSW.d.ts create mode 100644 types/workbox-window/tsconfig.json create mode 100644 types/workbox-window/tslint.json create mode 100644 types/workbox-window/utils/EventTargetShim.d.ts create mode 100644 types/workbox-window/utils/WorkboxEvent.d.ts create mode 100644 types/workbox-window/workbox-window-tests.ts diff --git a/types/workbox-window/Workbox.d.ts b/types/workbox-window/Workbox.d.ts new file mode 100644 index 0000000000..f473715faf --- /dev/null +++ b/types/workbox-window/Workbox.d.ts @@ -0,0 +1,115 @@ +import { EventTargetShim } from './utils/EventTargetShim'; +import { WorkboxEvent } from './utils/WorkboxEvent'; + +interface WorkboxMessageEvent extends WorkboxEvent { + /** + * The `data` property from the original `message` event. + */ + readonly data: any; +} + +interface WorkboxExtendableEvent extends WorkboxEvent { + /** + * The service worker instance. + */ + readonly sw: ServiceWorker; +} + +interface WorkboxUpdatableEvent extends WorkboxExtendableEvent { + /** + * True if a service worker was already + * controlling when this `Workbox` instance called `register()`. + */ + readonly isUpdate?: boolean; +} + +interface WorkboxWaitingEvent extends WorkboxUpdatableEvent { + /** + * True if a service worker with + * a matching `scriptURL` was already waiting when this `Workbox` + * instance called `register()`. + */ + readonly wasWaitingBeforeRegister?: boolean; +} + +interface WokerboxEventMap { + message: WorkboxMessageEvent; + installed: WorkboxEvent; + waiting: WorkboxWaitingEvent; + controlling: WorkboxEvent; + activated: WorkboxEvent; + redundant: WorkboxEvent; + externalinstalled: WorkboxExtendableEvent; + externalwaiting: WorkboxExtendableEvent; + externalactivated: WorkboxExtendableEvent; +} + +declare class Workbox extends EventTargetShim { + /** + * Creates a new Workbox instance with a script URL and service worker + * options. The script URL and options are the same as those used when + * calling `navigator.serviceWorker.register(scriptURL, options)`. See: + * https://developer.mozilla.org/en-US/docs/Web/API/ServiceWorkerContainer/register + */ + constructor(scriptURL: string, registerOptions?: RegistrationOptions); + + /** + * Registers a service worker for this instances script URL and service + * worker options. By default this method delays registration until after + * the window has loaded. + */ + register(): Promise; + + /** + * Resolves to the service worker registered by this instance as soon as it + * is active. If a service worker was already controlling at registration + * time then it will resolve to that if the script URLs (and optionally + * script versions) match, otherwise it will wait until an update is found + * and activates. + */ + readonly active: Promise; + + /** + * Resolves to the service worker registered by this instance as soon as it + * is controlling the page. If a service worker was already controlling at + * registration time then it will resolve to that if the script URLs (and + * optionally script versions) match, otherwise it will wait until an update + * is found and starts controlling the page. + * Note: the first time a service worker is installed it will active but + * not start controlling the page unless `clients.claim()` is called in the + * service worker. + */ + readonly controlling: Promise; + + /** + * Resolves with a reference to a service worker that matches the script URL + * of this instance, as soon as it's available. + * + * If, at registration time, there's already an active or waiting service + * worker with a matching script URL, it will be used (with the waiting + * service worker taking precedence over the active service worker if both + * match, since the waiting service worker would have been registered more + * recently). + * If there's no matching active or waiting service worker at registration + * time then the promise will not resolve until an update is found and starts + * installing, at which point the installing service worker is used. + */ + getSW(): Promise; + + /** + * Sends the passed data object to the service worker registered by this + * instance (via [`getSW()`]{@link module:workbox-window.Workbox#getSW}) and resolves + * with a response (if any). + * + * A response can be set in a message handler in the service worker by + * calling `event.ports[0].postMessage(...)`, which will resolve the promise + * returned by `messageSW()`. If no response is set, the promise will never + * resolve. + */ + messageSW(): Promise; + + addEventListener(type: K, listener: (this: Workbox, ev: WokerboxEventMap[K]) => void): void; + removeEventListener(type: K, listener: (this: Workbox, ev: WokerboxEventMap[K]) => void): void; +} + +export { Workbox }; diff --git a/types/workbox-window/index.d.ts b/types/workbox-window/index.d.ts new file mode 100644 index 0000000000..77b540c9b4 --- /dev/null +++ b/types/workbox-window/index.d.ts @@ -0,0 +1,8 @@ +// Type definitions for workbox-window 4.3 +// Project: https://github.com/GoogleChrome/workbox/tree/master/packages/workbox-window, https://github.com/GoogleChrome/workbox +// Definitions by: Yamagishi Kazutoshi +// Definitions: https://github.com/DefinitelyTyped/DefinitelyTyped +// TypeScript Version: 3.0 + +export { Workbox } from './Workbox'; +export { messageSW } from './messageSW'; diff --git a/types/workbox-window/messageSW.d.ts b/types/workbox-window/messageSW.d.ts new file mode 100644 index 0000000000..2fa4fcb176 --- /dev/null +++ b/types/workbox-window/messageSW.d.ts @@ -0,0 +1,12 @@ +/** + * Sends a data object to a service worker via `postMessage` and resolves with + * a response (if any). + * + * A response can be set in a message handler in the service worker by + * calling `event.ports[0].postMessage(...)`, which will resolve the promise + * returned by `messageSW()`. If no response is set, the promise will not + * resolve. + */ +declare function messageSW(sw: ServiceWorker, data: object): Promise; + +export { messageSW }; diff --git a/types/workbox-window/tsconfig.json b/types/workbox-window/tsconfig.json new file mode 100644 index 0000000000..8c47214a8b --- /dev/null +++ b/types/workbox-window/tsconfig.json @@ -0,0 +1,28 @@ +{ + "compilerOptions": { + "module": "commonjs", + "lib": [ + "es6", + "webworker" + ], + "noImplicitAny": true, + "noImplicitThis": true, + "strictNullChecks": true, + "strictFunctionTypes": true, + "baseUrl": "../", + "typeRoots": [ + "../" + ], + "types": [], + "noEmit": true, + "forceConsistentCasingInFileNames": true + }, + "files": [ + "index.d.ts", + "Workbox.d.ts", + "messageSW.d.ts", + "utils/EventTargetShim.d.ts", + "utils/WorkboxEvent.d.ts", + "workbox-window-tests.ts" + ] +} diff --git a/types/workbox-window/tslint.json b/types/workbox-window/tslint.json new file mode 100644 index 0000000000..f93cf8562a --- /dev/null +++ b/types/workbox-window/tslint.json @@ -0,0 +1,3 @@ +{ + "extends": "dtslint/dt.json" +} diff --git a/types/workbox-window/utils/EventTargetShim.d.ts b/types/workbox-window/utils/EventTargetShim.d.ts new file mode 100644 index 0000000000..ea83cf8a26 --- /dev/null +++ b/types/workbox-window/utils/EventTargetShim.d.ts @@ -0,0 +1,18 @@ +import { WorkboxEvent } from './WorkboxEvent'; + +interface EventListenerShim { + (evt: WorkboxEvent): void; +} + +/** + * A minimal `EventTarget` shim. + * This is necessary because not all browsers support constructable + * `EventTarget`, so using a real `EventTarget` will error. + */ +declare class EventTargetShim { + addEventListener(type: string, listener: EventListenerShim): void; + removeEventListener(type: string, listener: EventListenerShim): void; + dispatchEvent(evt: WorkboxEvent): void; +} + +export { EventTargetShim }; diff --git a/types/workbox-window/utils/WorkboxEvent.d.ts b/types/workbox-window/utils/WorkboxEvent.d.ts new file mode 100644 index 0000000000..c533635b0a --- /dev/null +++ b/types/workbox-window/utils/WorkboxEvent.d.ts @@ -0,0 +1,25 @@ +import { Workbox } from '../Workbox'; + +/** + * A minimal `Event` subclass shim. + * This doesn't *actually* subclass `Event` because not all browsers support + * constructable `EventTarget`, and using a real `Event` will error. + */ +interface WorkboxEvent { + /** + * The original event. + */ + readonly originalEvent: Event; + + /** + * The event type. + */ + readonly type: string; + + /** + * The `Workbox` instance. + */ + readonly target: Workbox; +} + +export { WorkboxEvent }; diff --git a/types/workbox-window/workbox-window-tests.ts b/types/workbox-window/workbox-window-tests.ts new file mode 100644 index 0000000000..0e5735a01b --- /dev/null +++ b/types/workbox-window/workbox-window-tests.ts @@ -0,0 +1,16 @@ +import { Workbox } from 'workbox-window'; + +{ + const wb = new Workbox('/sw.js'); + + wb.addEventListener('message', (event) => { + event.target; // $ExpectType Workbox + event.data; // $ExpectType any + }); + + wb.addEventListener('waiting', (event) => { + event.isUpdate; // $ExpectType boolean | undefined + }); + + wb.register(); // $ExpectType Promise +}