What are the specific steps to add a SharedWorker
to an @angular/cli >1.2
-generated project. I would like the SharedWorker to be defined in TypeScript (with full/correct type-definitions editor support), to share interfaces with the main project, and to be continuously compiled and tested along with the main project.
I haven't discovered an example or blog post that describes how to modify a cli-generated project to include either a Worker
or a SharedWorker
. However, there are several posts (such as this one) which show how to transform an entire cli-generated project to run it as a web worker. But that's not my use-case.
I want to confine interaction with a Lovefield database to a SharedWorker
that runs in a separate process from the main application.
Though I've experimented a bit attempting to figure this out, I haven't made much progress. Hopefully someone can save me (and future readers) a lot of time.
I got this to work following these steps:
src\app\shared-worker
Create file src\app\shared-worker\shared-worker.d.ts
with the following contents:
SharedWorker definitions
declare module SharedWorker {
interface AbstractWorker extends EventTarget {
onerror: (ev: ErrorEvent) => any;
}
export interface SharedWorker extends AbstractWorker {
port: MessagePort;
onconnect: (messageEvent: MessageEvent) => void;
}
}
declare var SharedWorker: {
prototype: SharedWorker.SharedWorker;
new(stringUrl: string, name?: string): SharedWorker.SharedWorker;
};
// Merely added the onconnect() method to the file provied via:
// npm install --save-dev retyped-sharedworker-tsd-ambient
// Definitions by: Toshiya Nakakura <https://github.com/nakakura>
Create file src\app\shared-worker\shared-worker.ts
with the following demo contents:
Sharedworker source
/// <reference path=".\shared-worker.d.ts" />
(<any>self).onconnect = (connectEvent: MessageEvent) => {
const messagePort: MessagePort = (connectEvent.ports as MessagePort[])[0];
messagePort.onmessage = function (messageEvent: MessageEvent) {
const workerResult: number = messageEvent.data.firstNumber * messageEvent.data.secondNumber;
messagePort.postMessage(workerResult);
};
};
Update src\app\app.component.ts
as follows:
AppComponent
import { Component, OnInit, ChangeDetectorRef } from '@angular/core';
import { Subject } from 'rxjs/Subject';
import { Observable } from 'rxjs/Observable';
@Component({
selector: 'app-root',
template: `
<input type="number" [(ngModel)]="firstNumber" />
<input type="number" [(ngModel)]="secondNumber" />
<hr /><button (click)="postMessageToSharedWorker()">Invoke Shared Worker</button>
<hr /><div>Result: {{result$ | async}}</div>`
})
export class AppComponent implements OnInit {
public firstNumber = 4;
public secondNumber = 8;
private resultSubject = new Subject<number>();
private sharedWorker: SharedWorker.SharedWorker;
public result$: Observable<number>;
public ngOnInit(): void {
this.result$ = this.resultSubject.asObservable();
if ('SharedWorker' in window) {
this.sharedWorker = new SharedWorker('app/shared-worker/shared-worker.js');
this.sharedWorker.port.onmessage = (messageEvent: MessageEvent) => {
this.resultSubject.next(messageEvent.data);
this.changeDetectorRef.detectChanges();
};
}
}
public postMessageToSharedWorker() {
if (!('SharedWorker' in window)) {
return;
}
this.sharedWorker.port.postMessage({ firstNumber: this.firstNumber, secondNumber: this.secondNumber });
}
constructor(private changeDetectorRef: ChangeDetectorRef) { }
}
Add "app/shared-worker/shared-worker.js"
to the apps.assets
node in .angular-cli.json
concurrently
as a dev dependency: npm i -D concurrently
Create package.json
scripts
package.json
"wrk-w": "tsc --noLib --experimentalDecorators --watch node_modules/typescript/lib/lib.es6.d.ts src/app/shared-worker/shared-worker.d.ts src/app/shared-worker/shared-worker.ts",
"dev": "concurrently --kill-others \"npm run wrk-w\" \"npm run start\""
Just install @types/sharedworker and add it to tsconfig.app.json in "types" array option.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With