Skip to content
This repository was archived by the owner on Oct 12, 2021. It is now read-only.

Commit 07676ac

Browse files
committed
feat(worker): an 'external' plugin which supports caching resources that have no build-time hash
1 parent e399a97 commit 07676ac

File tree

6 files changed

+79
-0
lines changed

6 files changed

+79
-0
lines changed
Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,53 @@
1+
import {
2+
FetchInstruction,
3+
Operation,
4+
Plugin,
5+
PluginFactory,
6+
VersionWorker,
7+
VersionWorkerImpl,
8+
cacheFromNetworkOp,
9+
fetchFromCacheInstruction,
10+
} from '@angular/service-worker/worker';
11+
12+
interface UrlConfig {
13+
url: string;
14+
}
15+
16+
interface ExternalManifest {
17+
urls: UrlConfig[];
18+
}
19+
20+
export interface ExternalContentCacheOptions {
21+
manifestKey?: string;
22+
}
23+
24+
export function ExternalContentCache(options?: ExternalContentCacheOptions): PluginFactory<ExternalPlugin> {
25+
const manifestKey = (options && options.manifestKey) || 'external';
26+
return (worker: VersionWorker) => new ExternalPlugin(worker as VersionWorkerImpl, manifestKey);
27+
}
28+
29+
export class ExternalPlugin implements Plugin<ExternalPlugin> {
30+
private cacheKey: string;
31+
32+
constructor(public worker: VersionWorkerImpl, public key: string) {
33+
this.cacheKey = key === 'external' ? key : `external:${key}`;
34+
}
35+
36+
private get externalManifest(): ExternalManifest {
37+
return this.worker.manifest[this.key];
38+
}
39+
40+
setup(operations: Operation[]) {
41+
if (!this.externalManifest || !this.externalManifest.urls) {
42+
return;
43+
}
44+
operations.push(...this
45+
.externalManifest
46+
.urls
47+
.map(url => cacheFromNetworkOp(this.worker, url.url, this.cacheKey)));
48+
}
49+
50+
fetch(req: Request, instructions: FetchInstruction[]): void {
51+
instructions.unshift(fetchFromCacheInstruction(this.worker, req, this.cacheKey));
52+
}
53+
}
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
This is full text.

service-worker/worker/src/test/e2e/harness/client/debug/ngsw-manifest.json

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,5 +3,10 @@
33
"urls": {
44
"/hello.txt": "test"
55
}
6+
},
7+
"external": {
8+
"urls": [
9+
{"url": "http://localhost:8080/full.txt"}
10+
]
611
}
712
}

service-worker/worker/src/test/e2e/spec/sanity.e2e.ts

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,11 @@ const SIMPLE_MANIFEST = {
1414
'/goodbye.txt': 'same',
1515
}
1616
},
17+
external: {
18+
urls: [
19+
{url: 'http://localhost:8080/full.txt'},
20+
],
21+
},
1722
push: {
1823
showNotifications: true
1924
}
@@ -108,6 +113,7 @@ describe('world sanity', () => {
108113
server.addResponse('/ngsw-manifest.json.js', '/* mocked */');
109114
server.addResponse('/ngsw-manifest.json', JSON.stringify(SIMPLE_MANIFEST));
110115
server.addResponse('/hello.txt', 'Hello world!');
116+
server.addResponse('/full.txt', 'Cached initially!');
111117
server.addResponse('/goodbye.txt', 'Goodbye world!');
112118
po.installServiceWorker('/worker-test.js');
113119
po
@@ -125,6 +131,13 @@ describe('world sanity', () => {
125131
.then(result => expect(result).toBe('Hello world!'))
126132
.then(done), 2000);
127133
});
134+
it('and cached /full.txt with full url', done => {
135+
server.addResponse('/full.txt', 'Not cached?');
136+
po
137+
.request('http://localhost:8080/full.txt')
138+
.then(result => expect(result).toBe('Cached initially!'))
139+
.then(done);
140+
});
128141
it('worker responds to ping', done => {
129142
po
130143
.ping()
@@ -159,6 +172,7 @@ describe('world sanity', () => {
159172
server.addResponse('/ngsw-manifest.json', JSON.stringify(UPDATE_MANIFEST));
160173
server.addResponse('/hello.txt', 'Hola mundo!');
161174
server.addResponse('/goodbye.txt', 'Should not be re-fetched.');
175+
server.addResponse('/full.txt', 'Should be reloaded');
162176
po
163177
.checkForUpdate()
164178
.then(updated => expect(updated).toBeTruthy())
@@ -168,6 +182,8 @@ describe('world sanity', () => {
168182
.then(result => expect(result).toBe('Hola mundo!'))
169183
.then(() => po.request('/goodbye.txt'))
170184
.then(result => expect(result).toBe('Goodbye world!'))
185+
.then(() => po.request('http://localhost:8080/full.txt'))
186+
.then(result => expect(result).toBe('Should be reloaded'))
171187
.then(() => done());
172188
});
173189
});

service-worker/worker/src/worker/builds/basic.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,14 @@
11
import {bootstrapServiceWorker} from '../bootstrap';
22
import {StaticContentCache} from '../../plugins/static';
3+
import {ExternalContentCache} from '../../plugins/external';
34
import {RouteRedirection} from '../../plugins/routes';
45
import {Push} from '../../plugins/push';
56

67
bootstrapServiceWorker({
78
manifestUrl: 'ngsw-manifest.json',
89
plugins: [
910
StaticContentCache(),
11+
ExternalContentCache(),
1012
RouteRedirection(),
1113
Push(),
1214
],

service-worker/worker/src/worker/builds/test.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
import {bootstrapServiceWorker} from '../bootstrap';
22
import {StaticContentCache} from '../../plugins/static';
3+
import {ExternalContentCache} from '../../plugins/external';
34
import {RouteRedirection} from '../../plugins/routes';
45
import {Push} from '../../plugins/push';
56
import {Verbosity, HttpHandler} from '../logging';
@@ -8,6 +9,7 @@ bootstrapServiceWorker({
89
manifestUrl: '/ngsw-manifest.json',
910
plugins: [
1011
StaticContentCache(),
12+
ExternalContentCache(),
1113
RouteRedirection(),
1214
Push(),
1315
],

0 commit comments

Comments
 (0)