Compare commits
8 Commits
Author | SHA1 | Date | |
---|---|---|---|
9dc310eb50 | |||
b26bc9096e | |||
56c98f7c23 | |||
6bf07b4e60 | |||
a2ff4abddc | |||
ee37d4b26d | |||
f99335bc47 | |||
445d833b5d |
14
CHANGELOG.md
14
CHANGELOG.md
@ -1,3 +1,17 @@
|
|||||||
|
<a name="5.0.5"></a>
|
||||||
|
## [5.0.5](https://github.com/angular/angular/compare/5.0.4...5.0.5) (2017-12-01)
|
||||||
|
|
||||||
|
|
||||||
|
### Bug Fixes
|
||||||
|
|
||||||
|
* **compiler-cli:** propagate ts.SourceFile moduleName into metadata ([a2ff4ab](https://github.com/angular/angular/commit/a2ff4ab))
|
||||||
|
* **service-worker:** allow disabling SW while still using services ([f99335b](https://github.com/angular/angular/commit/f99335b))
|
||||||
|
* **service-worker:** don't crash if SW not supported ([ee37d4b](https://github.com/angular/angular/commit/ee37d4b))
|
||||||
|
* **service-worker:** send initialization signal from the application ([6bf07b4](https://github.com/angular/angular/commit/6bf07b4))
|
||||||
|
* **service-worker:** use relative path for ngsw.json ([56c98f7](https://github.com/angular/angular/commit/56c98f7))
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
<a name="5.0.4"></a>
|
<a name="5.0.4"></a>
|
||||||
## [5.0.4](https://github.com/angular/angular/compare/5.0.3...5.0.4) (2017-12-01)
|
## [5.0.4](https://github.com/angular/angular/compare/5.0.3...5.0.4) (2017-12-01)
|
||||||
|
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "angular-srcs",
|
"name": "angular-srcs",
|
||||||
"version": "5.0.4",
|
"version": "5.0.5",
|
||||||
"private": true,
|
"private": true,
|
||||||
"branchPattern": "2.0.*",
|
"branchPattern": "2.0.*",
|
||||||
"description": "Angular - a web framework for modern web apps",
|
"description": "Angular - a web framework for modern web apps",
|
||||||
|
@ -551,6 +551,7 @@ export class MetadataCollector {
|
|||||||
__symbolic: 'module',
|
__symbolic: 'module',
|
||||||
version: this.options.version || METADATA_VERSION, metadata
|
version: this.options.version || METADATA_VERSION, metadata
|
||||||
};
|
};
|
||||||
|
if (sourceFile.moduleName) result.importAs = sourceFile.moduleName;
|
||||||
if (exports) result.exports = exports;
|
if (exports) result.exports = exports;
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
@ -112,6 +112,7 @@ function upgradeMetadataWithDtsData(
|
|||||||
newMetadata.metadata[prop] = dtsMetadata.metadata[prop];
|
newMetadata.metadata[prop] = dtsMetadata.metadata[prop];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if (dtsMetadata['importAs']) newMetadata['importAs'] = dtsMetadata['importAs'];
|
||||||
|
|
||||||
// Only copy exports from exports from metadata prior to version 3.
|
// Only copy exports from exports from metadata prior to version 3.
|
||||||
// Starting with version 3 the collector began collecting exports and
|
// Starting with version 3 the collector began collecting exports and
|
||||||
|
@ -45,6 +45,7 @@ describe('Collector', () => {
|
|||||||
're-exports.ts',
|
're-exports.ts',
|
||||||
're-exports-2.ts',
|
're-exports-2.ts',
|
||||||
'export-as.d.ts',
|
'export-as.d.ts',
|
||||||
|
'named-module.d.ts',
|
||||||
'static-field-reference.ts',
|
'static-field-reference.ts',
|
||||||
'static-method.ts',
|
'static-method.ts',
|
||||||
'static-method-call.ts',
|
'static-method-call.ts',
|
||||||
@ -101,6 +102,12 @@ describe('Collector', () => {
|
|||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it('should preserve module names from TypeScript sources', () => {
|
||||||
|
const sourceFile = program.getSourceFile('named-module.d.ts');
|
||||||
|
const metadata = collector.getMetadata(sourceFile);
|
||||||
|
expect(metadata !['importAs']).toEqual('some-named-module');
|
||||||
|
});
|
||||||
|
|
||||||
it('should be able to collect a simple component\'s metadata', () => {
|
it('should be able to collect a simple component\'s metadata', () => {
|
||||||
const sourceFile = program.getSourceFile('app/hero-detail.component.ts');
|
const sourceFile = program.getSourceFile('app/hero-detail.component.ts');
|
||||||
const metadata = collector.getMetadata(sourceFile);
|
const metadata = collector.getMetadata(sourceFile);
|
||||||
@ -1384,6 +1391,10 @@ const FILES: Directory = {
|
|||||||
declare function someFunction(): void;
|
declare function someFunction(): void;
|
||||||
export { someFunction as SomeFunction };
|
export { someFunction as SomeFunction };
|
||||||
`,
|
`,
|
||||||
|
'named-module.d.ts': `
|
||||||
|
/// <amd-module name="some-named-module" />
|
||||||
|
export type SomeType = 'a';
|
||||||
|
`,
|
||||||
'local-symbol-ref.ts': `
|
'local-symbol-ref.ts': `
|
||||||
import {Component, Validators} from 'angular2/core';
|
import {Component, Validators} from 'angular2/core';
|
||||||
|
|
||||||
|
@ -21,6 +21,7 @@ const globals = {
|
|||||||
'rxjs/observable/defer': 'Rx.Observable',
|
'rxjs/observable/defer': 'Rx.Observable',
|
||||||
'rxjs/observable/fromEvent': 'Rx.Observable',
|
'rxjs/observable/fromEvent': 'Rx.Observable',
|
||||||
'rxjs/observable/merge': 'Rx.Observable',
|
'rxjs/observable/merge': 'Rx.Observable',
|
||||||
|
'rxjs/observable/never': 'Rx.Observable',
|
||||||
'rxjs/observable/of': 'Rx.Observable',
|
'rxjs/observable/of': 'Rx.Observable',
|
||||||
'rxjs/observable/throw': 'Rx.Observable',
|
'rxjs/observable/throw': 'Rx.Observable',
|
||||||
|
|
||||||
|
@ -24,7 +24,7 @@ import {switchMap as op_switchMap} from 'rxjs/operator/switchMap';
|
|||||||
import {take as op_take} from 'rxjs/operator/take';
|
import {take as op_take} from 'rxjs/operator/take';
|
||||||
import {toPromise as op_toPromise} from 'rxjs/operator/toPromise';
|
import {toPromise as op_toPromise} from 'rxjs/operator/toPromise';
|
||||||
|
|
||||||
const ERR_SW_NOT_SUPPORTED = 'Service workers are not supported by this browser';
|
export const ERR_SW_NOT_SUPPORTED = 'Service workers are disabled or not supported by this browser';
|
||||||
|
|
||||||
export interface Version {
|
export interface Version {
|
||||||
hash: string;
|
hash: string;
|
||||||
@ -86,9 +86,9 @@ export class NgswCommChannel {
|
|||||||
*/
|
*/
|
||||||
readonly events: Observable<IncomingEvent>;
|
readonly events: Observable<IncomingEvent>;
|
||||||
|
|
||||||
constructor(serviceWorker: ServiceWorkerContainer|undefined) {
|
constructor(private serviceWorker: ServiceWorkerContainer|undefined) {
|
||||||
if (!serviceWorker) {
|
if (!serviceWorker) {
|
||||||
this.worker = this.events = errorObservable(ERR_SW_NOT_SUPPORTED);
|
this.worker = this.events = this.registration = errorObservable(ERR_SW_NOT_SUPPORTED);
|
||||||
} else {
|
} else {
|
||||||
const controllerChangeEvents =
|
const controllerChangeEvents =
|
||||||
<Observable<any>>(obs_fromEvent(serviceWorker, 'controllerchange'));
|
<Observable<any>>(obs_fromEvent(serviceWorker, 'controllerchange'));
|
||||||
@ -176,4 +176,6 @@ export class NgswCommChannel {
|
|||||||
}));
|
}));
|
||||||
return op_toPromise.call(mapErrorAndValue);
|
return op_toPromise.call(mapErrorAndValue);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
get isEnabled(): boolean { return !!this.serviceWorker; }
|
||||||
}
|
}
|
@ -16,14 +16,18 @@ import {NgswCommChannel} from './low_level';
|
|||||||
import {SwPush} from './push';
|
import {SwPush} from './push';
|
||||||
import {SwUpdate} from './update';
|
import {SwUpdate} from './update';
|
||||||
|
|
||||||
|
export abstract class RegistrationOptions {
|
||||||
|
scope?: string;
|
||||||
|
enabled?: boolean;
|
||||||
|
}
|
||||||
|
|
||||||
export const SCRIPT = new InjectionToken<string>('NGSW_REGISTER_SCRIPT');
|
export const SCRIPT = new InjectionToken<string>('NGSW_REGISTER_SCRIPT');
|
||||||
export const OPTS = new InjectionToken<Object>('NGSW_REGISTER_OPTIONS');
|
|
||||||
|
|
||||||
export function ngswAppInitializer(
|
export function ngswAppInitializer(
|
||||||
injector: Injector, script: string, options: RegistrationOptions): Function {
|
injector: Injector, script: string, options: RegistrationOptions): Function {
|
||||||
const initializer = () => {
|
const initializer = () => {
|
||||||
const app = injector.get<ApplicationRef>(ApplicationRef);
|
const app = injector.get<ApplicationRef>(ApplicationRef);
|
||||||
if (!('serviceWorker' in navigator)) {
|
if (!('serviceWorker' in navigator) || options.enabled === false) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
const onStable =
|
const onStable =
|
||||||
@ -31,15 +35,24 @@ export function ngswAppInitializer(
|
|||||||
const isStable = op_take.call(onStable, 1) as Observable<boolean>;
|
const isStable = op_take.call(onStable, 1) as Observable<boolean>;
|
||||||
const whenStable = op_toPromise.call(isStable) as Promise<boolean>;
|
const whenStable = op_toPromise.call(isStable) as Promise<boolean>;
|
||||||
|
|
||||||
|
// Wait for service worker controller changes, and fire an INITIALIZE action when a new SW
|
||||||
|
// becomes active. This allows the SW to initialize itself even if there is no application
|
||||||
|
// traffic.
|
||||||
|
navigator.serviceWorker.addEventListener('controllerchange', () => {
|
||||||
|
if (navigator.serviceWorker.controller !== null) {
|
||||||
|
navigator.serviceWorker.controller.postMessage({action: 'INITIALIZE'});
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
// Don't return the Promise, as that will block the application until the SW is registered, and
|
// Don't return the Promise, as that will block the application until the SW is registered, and
|
||||||
// cause a crash if the SW registration fails.
|
// cause a crash if the SW registration fails.
|
||||||
whenStable.then(() => navigator.serviceWorker.register(script, options));
|
whenStable.then(() => navigator.serviceWorker.register(script, {scope: options.scope}));
|
||||||
};
|
};
|
||||||
return initializer;
|
return initializer;
|
||||||
}
|
}
|
||||||
|
|
||||||
export function ngswCommChannelFactory(): NgswCommChannel {
|
export function ngswCommChannelFactory(opts: RegistrationOptions): NgswCommChannel {
|
||||||
return new NgswCommChannel(navigator.serviceWorker);
|
return new NgswCommChannel(opts.enabled !== false ? navigator.serviceWorker : undefined);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -49,20 +62,27 @@ export function ngswCommChannelFactory(): NgswCommChannel {
|
|||||||
providers: [SwPush, SwUpdate],
|
providers: [SwPush, SwUpdate],
|
||||||
})
|
})
|
||||||
export class ServiceWorkerModule {
|
export class ServiceWorkerModule {
|
||||||
static register(script: string, opts: RegistrationOptions = {}): ModuleWithProviders {
|
/**
|
||||||
|
* Register the given Angular Service Worker script.
|
||||||
|
*
|
||||||
|
* If `enabled` is set to `false` in the given options, the module will behave as if service
|
||||||
|
* workers are not supported by the browser, and the service worker will not be registered.
|
||||||
|
*/
|
||||||
|
static register(script: string, opts: {scope?: string; enabled?: boolean;} = {}):
|
||||||
|
ModuleWithProviders {
|
||||||
return {
|
return {
|
||||||
ngModule: ServiceWorkerModule,
|
ngModule: ServiceWorkerModule,
|
||||||
providers: [
|
providers: [
|
||||||
{provide: SCRIPT, useValue: script},
|
{provide: SCRIPT, useValue: script},
|
||||||
{provide: OPTS, useValue: opts},
|
{provide: RegistrationOptions, useValue: opts},
|
||||||
{provide: NgswCommChannel, useFactory: ngswCommChannelFactory},
|
{provide: NgswCommChannel, useFactory: ngswCommChannelFactory, deps: [RegistrationOptions]},
|
||||||
{
|
{
|
||||||
provide: APP_INITIALIZER,
|
provide: APP_INITIALIZER,
|
||||||
useFactory: ngswAppInitializer,
|
useFactory: ngswAppInitializer,
|
||||||
deps: [Injector, SCRIPT, OPTS],
|
deps: [Injector, SCRIPT, RegistrationOptions],
|
||||||
multi: true,
|
multi: true,
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -9,15 +9,15 @@
|
|||||||
import {Injectable} from '@angular/core';
|
import {Injectable} from '@angular/core';
|
||||||
import {Observable} from 'rxjs/Observable';
|
import {Observable} from 'rxjs/Observable';
|
||||||
import {Subject} from 'rxjs/Subject';
|
import {Subject} from 'rxjs/Subject';
|
||||||
|
|
||||||
import {merge as obs_merge} from 'rxjs/observable/merge';
|
import {merge as obs_merge} from 'rxjs/observable/merge';
|
||||||
|
import {never as obs_never} from 'rxjs/observable/never';
|
||||||
import {map as op_map} from 'rxjs/operator/map';
|
import {map as op_map} from 'rxjs/operator/map';
|
||||||
import {switchMap as op_switchMap} from 'rxjs/operator/switchMap';
|
import {switchMap as op_switchMap} from 'rxjs/operator/switchMap';
|
||||||
import {take as op_take} from 'rxjs/operator/take';
|
import {take as op_take} from 'rxjs/operator/take';
|
||||||
import {toPromise as op_toPromise} from 'rxjs/operator/toPromise';
|
import {toPromise as op_toPromise} from 'rxjs/operator/toPromise';
|
||||||
|
|
||||||
import {NgswCommChannel} from './low_level';
|
import {ERR_SW_NOT_SUPPORTED, NgswCommChannel} from './low_level';
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Subscribe and listen to push notifications from the Service Worker.
|
* Subscribe and listen to push notifications from the Service Worker.
|
||||||
@ -34,6 +34,11 @@ export class SwPush {
|
|||||||
new Subject<PushSubscription|null>();
|
new Subject<PushSubscription|null>();
|
||||||
|
|
||||||
constructor(private sw: NgswCommChannel) {
|
constructor(private sw: NgswCommChannel) {
|
||||||
|
if (!sw.isEnabled) {
|
||||||
|
this.messages = obs_never();
|
||||||
|
this.subscription = obs_never();
|
||||||
|
return;
|
||||||
|
}
|
||||||
this.messages =
|
this.messages =
|
||||||
op_map.call(this.sw.eventsOfType('PUSH'), (message: {data: object}) => message.data);
|
op_map.call(this.sw.eventsOfType('PUSH'), (message: {data: object}) => message.data);
|
||||||
|
|
||||||
@ -46,7 +51,16 @@ export class SwPush {
|
|||||||
this.subscription = obs_merge(workerDrivenSubscriptions, this.subscriptionChanges);
|
this.subscription = obs_merge(workerDrivenSubscriptions, this.subscriptionChanges);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns true if the Service Worker is enabled (supported by the browser and enabled via
|
||||||
|
* ServiceWorkerModule).
|
||||||
|
*/
|
||||||
|
get isEnabled(): boolean { return this.sw.isEnabled; }
|
||||||
|
|
||||||
requestSubscription(options: {serverPublicKey: string}): Promise<PushSubscription> {
|
requestSubscription(options: {serverPublicKey: string}): Promise<PushSubscription> {
|
||||||
|
if (!this.sw.isEnabled) {
|
||||||
|
return Promise.reject(new Error(ERR_SW_NOT_SUPPORTED));
|
||||||
|
}
|
||||||
const pushOptions: PushSubscriptionOptionsInit = {userVisibleOnly: true};
|
const pushOptions: PushSubscriptionOptionsInit = {userVisibleOnly: true};
|
||||||
let key = atob(options.serverPublicKey.replace(/_/g, '/').replace(/-/g, '+'));
|
let key = atob(options.serverPublicKey.replace(/_/g, '/').replace(/-/g, '+'));
|
||||||
let applicationServerKey = new Uint8Array(new ArrayBuffer(key.length));
|
let applicationServerKey = new Uint8Array(new ArrayBuffer(key.length));
|
||||||
@ -64,6 +78,9 @@ export class SwPush {
|
|||||||
}
|
}
|
||||||
|
|
||||||
unsubscribe(): Promise<void> {
|
unsubscribe(): Promise<void> {
|
||||||
|
if (!this.sw.isEnabled) {
|
||||||
|
return Promise.reject(new Error(ERR_SW_NOT_SUPPORTED));
|
||||||
|
}
|
||||||
const unsubscribe = op_switchMap.call(this.subscription, (sub: PushSubscription | null) => {
|
const unsubscribe = op_switchMap.call(this.subscription, (sub: PushSubscription | null) => {
|
||||||
if (sub !== null) {
|
if (sub !== null) {
|
||||||
return sub.unsubscribe().then(success => {
|
return sub.unsubscribe().then(success => {
|
||||||
|
@ -9,9 +9,10 @@
|
|||||||
import {Injectable} from '@angular/core';
|
import {Injectable} from '@angular/core';
|
||||||
import {Observable} from 'rxjs/Observable';
|
import {Observable} from 'rxjs/Observable';
|
||||||
import {defer as obs_defer} from 'rxjs/observable/defer';
|
import {defer as obs_defer} from 'rxjs/observable/defer';
|
||||||
|
import {never as obs_never} from 'rxjs/observable/never';
|
||||||
import {map as op_map} from 'rxjs/operator/map';
|
import {map as op_map} from 'rxjs/operator/map';
|
||||||
|
|
||||||
import {NgswCommChannel, UpdateActivatedEvent, UpdateAvailableEvent} from './low_level';
|
import {ERR_SW_NOT_SUPPORTED, NgswCommChannel, UpdateActivatedEvent, UpdateAvailableEvent} from './low_level';
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -26,16 +27,33 @@ export class SwUpdate {
|
|||||||
readonly activated: Observable<UpdateActivatedEvent>;
|
readonly activated: Observable<UpdateActivatedEvent>;
|
||||||
|
|
||||||
constructor(private sw: NgswCommChannel) {
|
constructor(private sw: NgswCommChannel) {
|
||||||
|
if (!sw.isEnabled) {
|
||||||
|
this.available = obs_never();
|
||||||
|
this.activated = obs_never();
|
||||||
|
return;
|
||||||
|
}
|
||||||
this.available = this.sw.eventsOfType('UPDATE_AVAILABLE');
|
this.available = this.sw.eventsOfType('UPDATE_AVAILABLE');
|
||||||
this.activated = this.sw.eventsOfType('UPDATE_ACTIVATED');
|
this.activated = this.sw.eventsOfType('UPDATE_ACTIVATED');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns true if the Service Worker is enabled (supported by the browser and enabled via
|
||||||
|
* ServiceWorkerModule).
|
||||||
|
*/
|
||||||
|
get isEnabled(): boolean { return this.sw.isEnabled; }
|
||||||
|
|
||||||
checkForUpdate(): Promise<void> {
|
checkForUpdate(): Promise<void> {
|
||||||
|
if (!this.sw.isEnabled) {
|
||||||
|
return Promise.reject(new Error(ERR_SW_NOT_SUPPORTED));
|
||||||
|
}
|
||||||
const statusNonce = this.sw.generateNonce();
|
const statusNonce = this.sw.generateNonce();
|
||||||
return this.sw.postMessageWithStatus('CHECK_FOR_UPDATES', {statusNonce}, statusNonce);
|
return this.sw.postMessageWithStatus('CHECK_FOR_UPDATES', {statusNonce}, statusNonce);
|
||||||
}
|
}
|
||||||
|
|
||||||
activateUpdate(): Promise<void> {
|
activateUpdate(): Promise<void> {
|
||||||
|
if (!this.sw.isEnabled) {
|
||||||
|
return Promise.reject(new Error(ERR_SW_NOT_SUPPORTED));
|
||||||
|
}
|
||||||
const statusNonce = this.sw.generateNonce();
|
const statusNonce = this.sw.generateNonce();
|
||||||
return this.sw.postMessageWithStatus('ACTIVATE_UPDATE', {statusNonce}, statusNonce);
|
return this.sw.postMessageWithStatus('ACTIVATE_UPDATE', {statusNonce}, statusNonce);
|
||||||
}
|
}
|
||||||
|
@ -71,6 +71,24 @@ export function main() {
|
|||||||
});
|
});
|
||||||
expect(() => TestBed.get(SwPush)).not.toThrow();
|
expect(() => TestBed.get(SwPush)).not.toThrow();
|
||||||
});
|
});
|
||||||
|
describe('with no SW', () => {
|
||||||
|
beforeEach(() => { comm = new NgswCommChannel(undefined); });
|
||||||
|
it('can be instantiated', () => { push = new SwPush(comm); });
|
||||||
|
it('does not crash on subscription to observables', () => {
|
||||||
|
push = new SwPush(comm);
|
||||||
|
push.messages.toPromise().catch(err => fail(err));
|
||||||
|
push.subscription.toPromise().catch(err => fail(err));
|
||||||
|
});
|
||||||
|
it('gives an error when registering', done => {
|
||||||
|
push = new SwPush(comm);
|
||||||
|
push.requestSubscription({serverPublicKey: 'test'}).catch(err => { done(); });
|
||||||
|
});
|
||||||
|
it('gives an error when unsubscribing', done => {
|
||||||
|
|
||||||
|
push = new SwPush(comm);
|
||||||
|
push.unsubscribe().catch(err => { done(); });
|
||||||
|
});
|
||||||
|
});
|
||||||
});
|
});
|
||||||
describe('SwUpdate', () => {
|
describe('SwUpdate', () => {
|
||||||
let update: SwUpdate;
|
let update: SwUpdate;
|
||||||
@ -147,6 +165,23 @@ export function main() {
|
|||||||
});
|
});
|
||||||
expect(() => TestBed.get(SwUpdate)).not.toThrow();
|
expect(() => TestBed.get(SwUpdate)).not.toThrow();
|
||||||
});
|
});
|
||||||
|
describe('with no SW', () => {
|
||||||
|
beforeEach(() => { comm = new NgswCommChannel(undefined); });
|
||||||
|
it('can be instantiated', () => { update = new SwUpdate(comm); });
|
||||||
|
it('does not crash on subscription to observables', () => {
|
||||||
|
update = new SwUpdate(comm);
|
||||||
|
update.available.toPromise().catch(err => fail(err));
|
||||||
|
update.activated.toPromise().catch(err => fail(err));
|
||||||
|
});
|
||||||
|
it('gives an error when checking for updates', done => {
|
||||||
|
update = new SwUpdate(comm);
|
||||||
|
update.checkForUpdate().catch(err => { done(); });
|
||||||
|
});
|
||||||
|
it('gives an error when activating updates', done => {
|
||||||
|
update = new SwUpdate(comm);
|
||||||
|
update.activateUpdate().catch(err => { done(); });
|
||||||
|
});
|
||||||
|
});
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
@ -580,8 +580,8 @@ export class Driver implements Debuggable, UpdateSource {
|
|||||||
* Retrieve a copy of the latest manifest from the server.
|
* Retrieve a copy of the latest manifest from the server.
|
||||||
*/
|
*/
|
||||||
private async fetchLatestManifest(): Promise<Manifest> {
|
private async fetchLatestManifest(): Promise<Manifest> {
|
||||||
const res = await this.safeFetch(
|
const res =
|
||||||
this.adapter.newRequest('/ngsw.json?ngsw-cache-bust=' + Math.random()));
|
await this.safeFetch(this.adapter.newRequest('ngsw.json?ngsw-cache-bust=' + Math.random()));
|
||||||
if (!res.ok) {
|
if (!res.ok) {
|
||||||
if (res.status === 404) {
|
if (res.status === 404) {
|
||||||
await this.deleteAllCaches();
|
await this.deleteAllCaches();
|
||||||
|
@ -158,7 +158,7 @@ export function main() {
|
|||||||
expect(await scope.startup(true)).toEqual(true);
|
expect(await scope.startup(true)).toEqual(true);
|
||||||
await scope.resolveSelfMessages();
|
await scope.resolveSelfMessages();
|
||||||
await driver.initialized;
|
await driver.initialized;
|
||||||
server.assertSawRequestFor('/ngsw.json');
|
server.assertSawRequestFor('ngsw.json');
|
||||||
server.assertSawRequestFor('/foo.txt');
|
server.assertSawRequestFor('/foo.txt');
|
||||||
server.assertSawRequestFor('/bar.txt');
|
server.assertSawRequestFor('/bar.txt');
|
||||||
server.assertSawRequestFor('/redirected.txt');
|
server.assertSawRequestFor('/redirected.txt');
|
||||||
@ -170,7 +170,7 @@ export function main() {
|
|||||||
async_it('initializes prefetched content correctly, after a request kicks it off', async() => {
|
async_it('initializes prefetched content correctly, after a request kicks it off', async() => {
|
||||||
expect(await makeRequest(scope, '/foo.txt')).toEqual('this is foo');
|
expect(await makeRequest(scope, '/foo.txt')).toEqual('this is foo');
|
||||||
await driver.initialized;
|
await driver.initialized;
|
||||||
server.assertSawRequestFor('/ngsw.json');
|
server.assertSawRequestFor('ngsw.json');
|
||||||
server.assertSawRequestFor('/foo.txt');
|
server.assertSawRequestFor('/foo.txt');
|
||||||
server.assertSawRequestFor('/bar.txt');
|
server.assertSawRequestFor('/bar.txt');
|
||||||
server.assertSawRequestFor('/redirected.txt');
|
server.assertSawRequestFor('/redirected.txt');
|
||||||
@ -230,7 +230,7 @@ export function main() {
|
|||||||
|
|
||||||
scope.updateServerState(serverUpdate);
|
scope.updateServerState(serverUpdate);
|
||||||
expect(await driver.checkForUpdate()).toEqual(true);
|
expect(await driver.checkForUpdate()).toEqual(true);
|
||||||
serverUpdate.assertSawRequestFor('/ngsw.json');
|
serverUpdate.assertSawRequestFor('ngsw.json');
|
||||||
serverUpdate.assertSawRequestFor('/foo.txt');
|
serverUpdate.assertSawRequestFor('/foo.txt');
|
||||||
serverUpdate.assertSawRequestFor('/redirected.txt');
|
serverUpdate.assertSawRequestFor('/redirected.txt');
|
||||||
serverUpdate.assertNoOtherRequests();
|
serverUpdate.assertNoOtherRequests();
|
||||||
@ -263,7 +263,7 @@ export function main() {
|
|||||||
|
|
||||||
scope.updateServerState(serverUpdate);
|
scope.updateServerState(serverUpdate);
|
||||||
expect(await driver.checkForUpdate()).toEqual(true);
|
expect(await driver.checkForUpdate()).toEqual(true);
|
||||||
serverUpdate.assertSawRequestFor('/ngsw.json');
|
serverUpdate.assertSawRequestFor('ngsw.json');
|
||||||
serverUpdate.assertSawRequestFor('/foo.txt');
|
serverUpdate.assertSawRequestFor('/foo.txt');
|
||||||
serverUpdate.assertSawRequestFor('/redirected.txt');
|
serverUpdate.assertSawRequestFor('/redirected.txt');
|
||||||
serverUpdate.assertNoOtherRequests();
|
serverUpdate.assertNoOtherRequests();
|
||||||
@ -331,7 +331,7 @@ export function main() {
|
|||||||
scope.advance(12000);
|
scope.advance(12000);
|
||||||
await driver.idle.empty;
|
await driver.idle.empty;
|
||||||
|
|
||||||
serverUpdate.assertSawRequestFor('/ngsw.json');
|
serverUpdate.assertSawRequestFor('ngsw.json');
|
||||||
serverUpdate.assertSawRequestFor('/foo.txt');
|
serverUpdate.assertSawRequestFor('/foo.txt');
|
||||||
serverUpdate.assertSawRequestFor('/redirected.txt');
|
serverUpdate.assertSawRequestFor('/redirected.txt');
|
||||||
serverUpdate.assertNoOtherRequests();
|
serverUpdate.assertNoOtherRequests();
|
||||||
|
@ -73,7 +73,7 @@ export class MockServerStateBuilder {
|
|||||||
}
|
}
|
||||||
|
|
||||||
withManifest(manifest: Manifest): MockServerStateBuilder {
|
withManifest(manifest: Manifest): MockServerStateBuilder {
|
||||||
this.resources.set('/ngsw.json', new MockResponse(JSON.stringify(manifest)));
|
this.resources.set('ngsw.json', new MockResponse(JSON.stringify(manifest)));
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,10 +1,14 @@
|
|||||||
/** @experimental */
|
/** @experimental */
|
||||||
export declare class ServiceWorkerModule {
|
export declare class ServiceWorkerModule {
|
||||||
static register(script: string, opts?: RegistrationOptions): ModuleWithProviders;
|
static register(script: string, opts?: {
|
||||||
|
scope?: string;
|
||||||
|
enabled?: boolean;
|
||||||
|
}): ModuleWithProviders;
|
||||||
}
|
}
|
||||||
|
|
||||||
/** @experimental */
|
/** @experimental */
|
||||||
export declare class SwPush {
|
export declare class SwPush {
|
||||||
|
readonly isEnabled: boolean;
|
||||||
readonly messages: Observable<object>;
|
readonly messages: Observable<object>;
|
||||||
readonly subscription: Observable<PushSubscription | null>;
|
readonly subscription: Observable<PushSubscription | null>;
|
||||||
constructor(sw: NgswCommChannel);
|
constructor(sw: NgswCommChannel);
|
||||||
@ -18,6 +22,7 @@ export declare class SwPush {
|
|||||||
export declare class SwUpdate {
|
export declare class SwUpdate {
|
||||||
readonly activated: Observable<UpdateActivatedEvent>;
|
readonly activated: Observable<UpdateActivatedEvent>;
|
||||||
readonly available: Observable<UpdateAvailableEvent>;
|
readonly available: Observable<UpdateAvailableEvent>;
|
||||||
|
readonly isEnabled: boolean;
|
||||||
constructor(sw: NgswCommChannel);
|
constructor(sw: NgswCommChannel);
|
||||||
activateUpdate(): Promise<void>;
|
activateUpdate(): Promise<void>;
|
||||||
checkForUpdate(): Promise<void>;
|
checkForUpdate(): Promise<void>;
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
g{
|
{
|
||||||
"maxLength": 120,
|
"maxLength": 120,
|
||||||
"types": [
|
"types": [
|
||||||
"build",
|
"build",
|
||||||
|
Reference in New Issue
Block a user