feat(service-worker): include CacheQueryOptions options in ngsw-config (#34663)

Previously it was not possible to provide `CacheQueryOptions` ([MDN](https://developer.mozilla.org/en-US/docs/Web/API/Cache)) for querying the Cache.
This commit introduces a new parameter called `cacheQueryOptions` for `DataGroup` and `AssetGroup`.
Currently only `ignoreSearch` is supported as `ignoreVary` and `ignoreMethod` would require using
the complete Request object for matching which is not possible with the current implementation.

Closes #28443

PR Close #34663
This commit is contained in:
Maximilian Koeller
2020-04-29 16:07:34 +02:00
committed by Alex Rickabaugh
parent 49be32c931
commit dc9f4b994e
13 changed files with 198 additions and 23 deletions

View File

@ -60,6 +60,17 @@
}
},
"additionalProperties": false
},
"cacheQueryOptions" : {
"type": "object",
"description": "Provide options that are passed to Cache#match.",
"properties" : {
"ignoreSearch": {
"type": "boolean",
"description": "Whether to ignore the query string in the URL."
}
},
"additionalProperties": false
}
},
"required": [
@ -122,6 +133,17 @@
"maxAge"
],
"additionalProperties": false
},
"cacheQueryOptions" : {
"type": "object",
"description": "Provide options that are passed to Cache#match.",
"properties" : {
"ignoreSearch": {
"type": "boolean",
"description": "Whether to ignore the query string in the URL."
}
},
"additionalProperties": false
}
},
"required": [

View File

@ -69,6 +69,7 @@ export class Generator {
name: group.name,
installMode: group.installMode || 'prefetch',
updateMode: group.updateMode || group.installMode || 'prefetch',
cacheQueryOptions: buildCacheQueryOptions(group.cacheQueryOptions),
urls: matchedFiles.map(url => joinUrls(this.baseHref, url)),
patterns: (group.resources.urls || []).map(url => urlToRegex(url, this.baseHref, true)),
};
@ -84,6 +85,7 @@ export class Generator {
maxSize: group.cacheConfig.maxSize,
maxAge: parseDurationToMs(group.cacheConfig.maxAge),
timeoutMs: group.cacheConfig.timeout && parseDurationToMs(group.cacheConfig.timeout),
cacheQueryOptions: buildCacheQueryOptions(group.cacheQueryOptions),
version: group.version !== undefined ? group.version : 1,
};
});
@ -149,3 +151,8 @@ function withOrderedKeys<T extends {[key: string]: any}>(unorderedObj: T): T {
Object.keys(unorderedObj).sort().forEach(key => orderedObj[key] = unorderedObj[key]);
return orderedObj as T;
}
function buildCacheQueryOptions(inOptions?: Pick<CacheQueryOptions, 'ignoreSearch'>):
CacheQueryOptions|undefined {
return inOptions;
}

View File

@ -39,6 +39,7 @@ export interface AssetGroup {
installMode?: 'prefetch'|'lazy';
updateMode?: 'prefetch'|'lazy';
resources: {files?: Glob[]; urls?: Glob[];};
cacheQueryOptions?: Pick<CacheQueryOptions, 'ignoreSearch'>;
}
/**
@ -55,4 +56,5 @@ export interface DataGroup {
timeout?: Duration;
strategy?: 'freshness' | 'performance';
};
cacheQueryOptions?: Pick<CacheQueryOptions, 'ignoreSearch'>;
}

View File

@ -92,6 +92,7 @@ describe('Generator', () => {
'\\/some\\/url\\?with\\+escaped\\+chars',
'\\/test\\/relative\\/[^/]*\\.txt',
],
cacheQueryOptions: undefined,
}],
dataGroups: [{
name: 'other',
@ -105,6 +106,7 @@ describe('Generator', () => {
maxAge: 259200000,
timeoutMs: 60000,
version: 1,
cacheQueryOptions: undefined,
}],
navigationUrls: [
{positive: true, regex: '^\\/included\\/absolute\\/.*$'},
@ -181,4 +183,76 @@ describe('Generator', () => {
'which is no longer supported. Use \'files\' instead.'));
}
});
it('generates a correct config with cacheQueryOptions', async () => {
const fs = new MockFilesystem({
'/index.html': 'This is a test',
'/main.js': 'This is a JS file',
});
const gen = new Generator(fs, '/');
const config = await gen.process({
index: '/index.html',
assetGroups: [{
name: 'test',
resources: {
files: [
'/**/*.html',
'/**/*.?s',
]
},
cacheQueryOptions: {ignoreSearch: true},
}],
dataGroups: [{
name: 'other',
urls: ['/api/**'],
cacheConfig: {
maxAge: '3d',
maxSize: 100,
strategy: 'performance',
timeout: '1m',
},
cacheQueryOptions: {ignoreSearch: false},
}]
});
expect(config).toEqual({
configVersion: 1,
appData: undefined,
timestamp: 1234567890123,
index: '/index.html',
assetGroups: [{
name: 'test',
installMode: 'prefetch',
updateMode: 'prefetch',
urls: [
'/index.html',
'/main.js',
],
patterns: [],
cacheQueryOptions: {ignoreSearch: true}
}],
dataGroups: [{
name: 'other',
patterns: [
'\\/api\\/.*',
],
strategy: 'performance',
maxSize: 100,
maxAge: 259200000,
timeoutMs: 60000,
version: 1,
cacheQueryOptions: {ignoreSearch: false}
}],
navigationUrls: [
{positive: true, regex: '^\\/.*$'},
{positive: false, regex: '^\\/(?:.+\\/)?[^/]*\\.[^/]*$'},
{positive: false, regex: '^\\/(?:.+\\/)?[^/]*__[^/]*$'},
{positive: false, regex: '^\\/(?:.+\\/)?[^/]*__[^/]*\\/.*$'},
],
hashTable: {
'/index.html': 'a54d88e06612d820bc3be72877c74f257b561b19',
'/main.js': '41347a66676cdc0516934c76d9d13010df420f2c',
},
});
});
});