Skip to content

Commit

Permalink
feat(service-worker): support multiple apps in same domain
Browse files Browse the repository at this point in the history
suffixing the baseHref with ngsw:<base-href> string to seperate caches
files app in same domain

Fixes issue angular#21388
  • Loading branch information
sheikalthaf committed Nov 13, 2018
1 parent 5247594 commit e969fc6
Show file tree
Hide file tree
Showing 4 changed files with 26 additions and 7 deletions.
12 changes: 12 additions & 0 deletions packages/service-worker/worker/src/adapter.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@
* from the global scope.
*/
export class Adapter {
ngsw = 'ngsw';
/**
* Wrapper around the `Request` constructor.
*/
Expand Down Expand Up @@ -54,6 +55,17 @@ export class Adapter {
timeout(ms: number): Promise<void> {
return new Promise<void>(resolve => { setTimeout(() => resolve(), ms); });
}

/**
* suffixing the baseHref with `ngsw` string to avoid clash of cache files
* in same domain with multiple apps
*/
setBaseHref(baseHref: string) {
if (baseHref && ['/'].indexOf(baseHref) == -1) {
const str = baseHref.replace(/^\//, '').replace(/\/$/, '').replace(/\//, ':');
this.ngsw += ':' + str;
}
}
}

/**
Expand Down
4 changes: 2 additions & 2 deletions packages/service-worker/worker/src/app-version.ts
Original file line number Diff line number Diff line change
Expand Up @@ -66,7 +66,7 @@ export class AppVersion implements UpdateSource {
this.assetGroups = (manifest.assetGroups || []).map(config => {
// Every asset group has a cache that's prefixed by the manifest hash and the name of the
// group.
const prefix = `ngsw:${this.manifestHash}:assets`;
const prefix = `${adapter.ngsw}:${this.manifestHash}:assets`;
// Check the caching mode, which determines when resources will be fetched/updated.
switch (config.installMode) {
case 'prefetch':
Expand All @@ -83,7 +83,7 @@ export class AppVersion implements UpdateSource {
.map(
config => new DataGroup(
this.scope, this.adapter, config, this.database,
`ngsw:${config.version}:data`));
`${adapter.ngsw}:${config.version}:data`));

// Create `include`/`exclude` RegExps for the `navigationUrls` declared in the manifest.
const includeUrls = manifest.navigationUrls.filter(spec => spec.positive);
Expand Down
6 changes: 3 additions & 3 deletions packages/service-worker/worker/src/db-cache.ts
Original file line number Diff line number Diff line change
Expand Up @@ -23,16 +23,16 @@ export class CacheDatabase implements Database {
if (this.tables.has(name)) {
this.tables.delete(name);
}
return this.scope.caches.delete(`ngsw:db:${name}`);
return this.scope.caches.delete(`${this.adapter.ngsw}:db:${name}`);
}

list(): Promise<string[]> {
return this.scope.caches.keys().then(keys => keys.filter(key => key.startsWith('ngsw:db:')));
return this.scope.caches.keys().then(keys => keys.filter(key => key.startsWith(`${this.adapter.ngsw}:db:`)));
}

open(name: string): Promise<Table> {
if (!this.tables.has(name)) {
const table = this.scope.caches.open(`ngsw:db:${name}`)
const table = this.scope.caches.open(`${this.adapter.ngsw}:db:${name}`)
.then(cache => new CacheTable(name, cache, this.adapter));
this.tables.set(name, table);
}
Expand Down
11 changes: 9 additions & 2 deletions packages/service-worker/worker/src/driver.ts
Original file line number Diff line number Diff line change
Expand Up @@ -109,6 +109,12 @@ export class Driver implements Debuggable, UpdateSource {

constructor(
private scope: ServiceWorkerGlobalScope, private adapter: Adapter, private db: Database) {
/**
* Extract Base Href from scope
* send the baseHref to adapter to suffix with ngsw string
*/
const baseHref = new URL(scope.registration.scope).pathname;
adapter.setBaseHref(baseHref);
// Set up all the event handlers that the SW needs.

// The install event is triggered when the service worker is first installed.
Expand Down Expand Up @@ -694,7 +700,7 @@ export class Driver implements Debuggable, UpdateSource {

private async deleteAllCaches(): Promise<void> {
await(await this.scope.caches.keys())
.filter(key => key.startsWith('ngsw:'))
.filter(key => key.startsWith(`${this.adapter.ngsw}:`))
.reduce(async(previous, key) => {
await Promise.all([
previous,
Expand Down Expand Up @@ -913,8 +919,9 @@ export class Driver implements Debuggable, UpdateSource {
*/
async cleanupOldSwCaches(): Promise<void> {
const cacheNames = await this.scope.caches.keys();
const regex = new RegExp(`^${this.adapter.ngsw}:(?:active|staged|manifest:.+)$`)
const oldSwCacheNames =
cacheNames.filter(name => /^ngsw:(?:active|staged|manifest:.+)$/.test(name));
cacheNames.filter(name => regex.test(name));

await Promise.all(oldSwCacheNames.map(name => this.scope.caches.delete(name)));
}
Expand Down

0 comments on commit e969fc6

Please sign in to comment.