refactor(service-worker): simplify/improve NgswCommChannel
typings (#23138)
PR Close #23138
This commit is contained in:
parent
9e5b0794c5
commit
59d80c471a
@ -33,6 +33,14 @@ export interface UpdateActivatedEvent {
|
|||||||
current: {hash: string, appData?: Object};
|
current: {hash: string, appData?: Object};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* An event emitted when a `PushEvent` is received by the service worker.
|
||||||
|
*/
|
||||||
|
export interface PushEvent {
|
||||||
|
type: 'PUSH';
|
||||||
|
data: any;
|
||||||
|
}
|
||||||
|
|
||||||
export type IncomingEvent = UpdateAvailableEvent | UpdateActivatedEvent;
|
export type IncomingEvent = UpdateAvailableEvent | UpdateActivatedEvent;
|
||||||
|
|
||||||
export interface TypedEvent { type: string; }
|
export interface TypedEvent { type: string; }
|
||||||
@ -72,30 +80,23 @@ export class NgswCommChannel {
|
|||||||
if (!serviceWorker) {
|
if (!serviceWorker) {
|
||||||
this.worker = this.events = this.registration = errorObservable(ERR_SW_NOT_SUPPORTED);
|
this.worker = this.events = this.registration = errorObservable(ERR_SW_NOT_SUPPORTED);
|
||||||
} else {
|
} else {
|
||||||
const controllerChangeEvents =
|
const controllerChangeEvents = fromEvent(serviceWorker, 'controllerchange');
|
||||||
<Observable<any>>(fromEvent(serviceWorker, 'controllerchange'));
|
const controllerChanges = controllerChangeEvents.pipe(map(() => serviceWorker.controller));
|
||||||
const controllerChanges = <Observable<ServiceWorker|null>>(
|
const currentController = defer(() => of (serviceWorker.controller));
|
||||||
controllerChangeEvents.pipe(map(() => serviceWorker.controller)));
|
const controllerWithChanges = concat(currentController, controllerChanges);
|
||||||
|
|
||||||
const currentController =
|
this.worker = controllerWithChanges.pipe(filter<ServiceWorker>(c => !!c));
|
||||||
<Observable<ServiceWorker|null>>(defer(() => of (serviceWorker.controller)));
|
|
||||||
|
|
||||||
const controllerWithChanges =
|
|
||||||
<Observable<ServiceWorker|null>>(concat(currentController, controllerChanges));
|
|
||||||
this.worker = <Observable<ServiceWorker>>(
|
|
||||||
controllerWithChanges.pipe(filter((c: ServiceWorker) => !!c)));
|
|
||||||
|
|
||||||
this.registration = <Observable<ServiceWorkerRegistration>>(
|
this.registration = <Observable<ServiceWorkerRegistration>>(
|
||||||
this.worker.pipe(switchMap(() => serviceWorker.getRegistration())));
|
this.worker.pipe(switchMap(() => serviceWorker.getRegistration())));
|
||||||
|
|
||||||
const rawEvents = fromEvent(serviceWorker, 'message');
|
const rawEvents = fromEvent<MessageEvent>(serviceWorker, 'message');
|
||||||
|
const rawEventPayload = rawEvents.pipe(map(event => event.data));
|
||||||
const rawEventPayload = rawEvents.pipe(map((event: MessageEvent) => event.data));
|
const eventsUnconnected = rawEventPayload.pipe(filter(event => event && event.type));
|
||||||
const eventsUnconnected =
|
|
||||||
(rawEventPayload.pipe(filter((event: Object) => !!event && !!(event as any)['type'])));
|
|
||||||
const events = eventsUnconnected.pipe(publish()) as ConnectableObservable<IncomingEvent>;
|
const events = eventsUnconnected.pipe(publish()) as ConnectableObservable<IncomingEvent>;
|
||||||
this.events = events;
|
|
||||||
events.connect();
|
events.connect();
|
||||||
|
|
||||||
|
this.events = events;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -130,19 +131,16 @@ export class NgswCommChannel {
|
|||||||
/**
|
/**
|
||||||
* @internal
|
* @internal
|
||||||
*/
|
*/
|
||||||
// TODO(i): the typings and casts in this method are wonky, we should revisit it and make the
|
eventsOfType<T extends TypedEvent>(type: T['type']): Observable<T> {
|
||||||
// types flow correctly
|
const filterFn = (event: TypedEvent): event is T => event.type === type;
|
||||||
eventsOfType<T extends TypedEvent>(type: string): Observable<T> {
|
return this.events.pipe(filter(filterFn));
|
||||||
return <Observable<T>>this.events.pipe(filter((event) => { return event.type === type; }));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @internal
|
* @internal
|
||||||
*/
|
*/
|
||||||
// TODO(i): the typings and casts in this method are wonky, we should revisit it and make the
|
nextEventOfType<T extends TypedEvent>(type: T['type']): Observable<T> {
|
||||||
// types flow correctly
|
return this.eventsOfType(type).pipe(take(1));
|
||||||
nextEventOfType<T extends TypedEvent>(type: string): Observable<T> {
|
|
||||||
return <Observable<T>>(this.eventsOfType(type).pipe(take(1)));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -150,14 +148,12 @@ export class NgswCommChannel {
|
|||||||
*/
|
*/
|
||||||
waitForStatus(nonce: number): Promise<void> {
|
waitForStatus(nonce: number): Promise<void> {
|
||||||
return this.eventsOfType<StatusEvent>('STATUS')
|
return this.eventsOfType<StatusEvent>('STATUS')
|
||||||
.pipe(
|
.pipe(filter(event => event.nonce === nonce), take(1), map(event => {
|
||||||
filter((event: StatusEvent) => event.nonce === nonce), take(1),
|
if (event.status) {
|
||||||
map((event: StatusEvent) => {
|
return undefined;
|
||||||
if (event.status) {
|
}
|
||||||
return undefined;
|
throw new Error(event.error !);
|
||||||
}
|
}))
|
||||||
throw new Error(event.error !);
|
|
||||||
}))
|
|
||||||
.toPromise();
|
.toPromise();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -10,7 +10,7 @@ import {Injectable} from '@angular/core';
|
|||||||
import {NEVER, Observable, Subject, merge} from 'rxjs';
|
import {NEVER, Observable, Subject, merge} from 'rxjs';
|
||||||
import {map, switchMap, take} from 'rxjs/operators';
|
import {map, switchMap, take} from 'rxjs/operators';
|
||||||
|
|
||||||
import {ERR_SW_NOT_SUPPORTED, NgswCommChannel} from './low_level';
|
import {ERR_SW_NOT_SUPPORTED, NgswCommChannel, PushEvent} from './low_level';
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -34,7 +34,7 @@ export class SwPush {
|
|||||||
this.subscription = NEVER;
|
this.subscription = NEVER;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
this.messages = this.sw.eventsOfType('PUSH').pipe(map((message: any) => message.data));
|
this.messages = this.sw.eventsOfType<PushEvent>('PUSH').pipe(map(message => message.data));
|
||||||
|
|
||||||
this.pushManager = this.sw.registration.pipe(
|
this.pushManager = this.sw.registration.pipe(
|
||||||
map((registration: ServiceWorkerRegistration) => { return registration.pushManager; }));
|
map((registration: ServiceWorkerRegistration) => { return registration.pushManager; }));
|
||||||
|
Loading…
x
Reference in New Issue
Block a user