Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

TypeScript type definitions for ServiceWorker

I'm writing a service for my angular 2 app using TypeScript. The service makes use of chrome's ServiceWorker to listen for push notifications (see tutorial). The code (javascript) makes use of navigator first to see if serviceWorker is supported, then continues to complete registration etc., i.e.,

if ('serviceWorker' in navigator) {
  console.log('Service Worker is supported');
  navigator.serviceWorker.register('sw.js').then(function() {
    return navigator.serviceWorker.ready;
  }).then(function(reg) {
    console.log('Service Worker is ready :^)', reg);
      // TODO
  }).catch(function(error) {
    console.log('Service Worker error :^(', error);
  });
}

I'd like to implemenet the above using TypeScript. However, the current lib.d.ts used by the TypeScript compiler (see below) appears to have no definitions defined on Navigator for the serviceWorker or its associated methods such as serviceWorker.register (I guess since it's a chrome-specific implementation).

interface Navigator extends Object, NavigatorID, NavigatorOnLine, NavigatorContentUtils, NavigatorStorageUtils, NavigatorGeolocation, MSNavigatorDoNotTrack, MSFileSaver, NavigatorUserMedia {
    readonly appCodeName: string;
    readonly cookieEnabled: boolean;
    readonly language: string;
    readonly maxTouchPoints: number;
    readonly mimeTypes: MimeTypeArray;
    readonly msManipulationViewsEnabled: boolean;
    readonly msMaxTouchPoints: number;
    readonly msPointerEnabled: boolean;
    readonly plugins: PluginArray;
    readonly pointerEnabled: boolean;
    readonly webdriver: boolean;
    getGamepads(): Gamepad[];
    javaEnabled(): boolean;
    msLaunchUri(uri: string, successCallback?: MSLaunchUriCallback, noHandlerCallback?: MSLaunchUriCallback): void;
    requestMediaKeySystemAccess(keySystem: string, supportedConfigurations: MediaKeySystemConfiguration[]): PromiseLike<MediaKeySystemAccess>;
    vibrate(pattern: number | number[]): boolean;
    addEventListener(type: string, listener: EventListenerOrEventListenerObject, useCapture?: boolean): void;
}

The result is that I'm faced with compilation errors since the compiler can't find the associated serviceWorker types. Given I'm new to JavaScript and TypeScript, I'm trying to determine the best way to proceed. I understand the options to be:

  1. Keep the js code and simply ignore the compilation errors (not ideal).
  2. Keep the js code and somehow suppress the type errors during compilation.
  3. Find an existing typescript definitions library that has serviceWorker defined and include that during compilation.
  4. Write my own typescript definition file for navigator or somehow extend the existing lib.d.ts

Sage advice on the best option greatly appreciated.

Update

Attempted to cast to any to remove compilation errors, i.e.,

var nav = <any> navigator;

    if ('serviceWorker' in nav) {
       nav.serviceWorker.register('sw.js')
           .then(function(reg) {
                    console.log('yey!', <any> reg);
           }).catch(function(err) {
                console.log('boo!', <any> err);
    });

but now facing new errors, i.e.,

error TS7006: Parameter 'reg' implicitly has an 'any' type.
error TS7006: Parameter 'error' implicitly has an 'any' type.

Also, tempted to write definitions for the ServiceWorker using these details. However never done it before, so will need some practice!

like image 977
James B Avatar asked Jul 03 '16 17:07

James B


People also ask

Can Serviceworker be TypeScript?

In this example, TypeScript is used to create a service worker with a network first then cache, caching strategy, to support viewing previously visited pages when offline. When there is no network connection available and a previous page version is not cached, the service worker will display an offline page.

What is use of Serviceworker?

Service workers are specialized JavaScript assets that act as proxies between web browsers and web servers. They aim to improve reliability by providing offline access, as well as boost page performance.

Is service worker a thread?

A service worker is a event-driven JavaScript program that runs in a worker thread separate from a document. Once registered, a service worker is installed on the browser and persists indefinitely until evicted or deleted manually (see Eviction below).

What is web Worker and service workers?

Web workers and service workers are two types of workers available to websites. They have some things in common: Both run in a secondary thread, allowing JavaScript code to execute without blocking the main thread and the user interface.


1 Answers

ServiceWorker is not a chrome specific extension.

OP should refer to Jake Archibald's isSERVICEWORKERready? page for a rundown of the current state of ServiceWorker in the popular browsers.

I added the type definitions in tsd.d.ts based on the interface information linked by OP and they seem to be working.

Please note that I referenced IPromise interface from angular.d.ts.

Defined in tsd.d.ts

/// <reference path="angularjs/angular.d.ts" />

interface Navigator {
    serviceWorker: ServiceWorkerContainer;
}

interface ServiceWorkerContainer {
  register(scriptUrl: string, options?: RegistrationOptions): angular.IPromise<ServiceWorkerRegistration>;
}

interface RegistrationOptions {
  scope: string;
}

interface ServiceWorkerRegistration {
  installing?: ServiceWorker;
  waiting?: ServiceWorker;
  active?: ServiceWorker;

  scope: string;

  update(): angular.IPromise<void>;
  unregister(): angular.IPromise<boolean>;
}

interface ServiceWorker {
  scriptUrl: string;
  state: string;

  postMessage(message: any, transfer: Array<any>): void;
}

Referred in home-controller.ts

///<reference path='../../typings/tsd.d.ts' />
...
// dependencies are injected via AngularJS $injector
constructor() {
  var vm = this;
  vm.ctrlName = 'HomeCtrl';
  if ('serviceWorker' in navigator) {
    navigator.serviceWorker.register('/sw.js', { scope: '/' }).then(function(reg) {
      // registration worked
      console.log('Registration succeeded. Scope is ' + reg.scope);
    }).catch(function(error) {
      // registration failed
      console.log('Registration failed with ' + error);
    });
  } else {
    console.warn('serviceWorker not available in navigator.');
  }
}

Building and loading the app in the chrome

enter image description here

logs the following console message:

enter image description here

Hope this helps.

like image 187
Sourav Paul Avatar answered Oct 15 '22 11:10

Sourav Paul