@chill-sharp/ui-core 1.1.12 → 1.1.15
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +103 -103
- package/fesm2022/chill-sharp-ui-core.mjs +2446 -2446
- package/fesm2022/chill-sharp-ui-core.mjs.map +1 -1
- package/lib/lib/chill-form.component.d.ts +1 -1
- package/package.json +3 -3
- package/service-worker/chill-sharp-service-worker.js +166 -166
- package/styles/core-theme.scss +1235 -1235
- package/.agents/skills/chillsharp-current-user-preferences/SKILL.md +0 -70
- package/.agents/skills/chillsharp-ui-template/SKILL.md +0 -18
- package/doc/AIAssistedDevelopment/README.md +0 -185
- package/doc/AttachmentModel/README.md +0 -173
- package/doc/AuthenticationModel/README.md +0 -213
- package/doc/AuthenticationModel/how-to-integreate-auth-minimal-api.md +0 -293
- package/doc/ChillSharpClient.md +0 -464
- package/doc/ClientGeneration/README.md +0 -172
- package/doc/ComplianceGuide/README.md +0 -178
- package/doc/Configuration/README.md +0 -94
- package/doc/CurrentUserPreferences.md +0 -114
- package/doc/DateTimePolicy/README.md +0 -154
- package/doc/DateTimeSerialization.md +0 -423
- package/doc/Endpoints.md +0 -260
- package/doc/HowTo/01-simple-blog-sqlite.md +0 -153
- package/doc/HowTo/02-blog-schema-labels.md +0 -140
- package/doc/HowTo/03-authentication.md +0 -218
- package/doc/HowTo/04-blog-posts-one-to-many.md +0 -194
- package/doc/HowTo/05-docker-env-variables.md +0 -274
- package/doc/HowTo/06-chunk-transactions-autocomplete.md +0 -196
- package/doc/Mcp/ChatGPT.md +0 -291
- package/doc/Mcp/README.md +0 -799
- package/doc/MenuGuide/README.md +0 -49
- package/doc/ModelPreparation.md +0 -255
- package/doc/PermissionModel/README.md +0 -277
- package/doc/README.md +0 -228
- package/doc/ReferenceExistence.md +0 -130
- package/doc/RegisterContext.md +0 -217
- package/doc/UiCore/CRUD.md +0 -170
- package/doc/UiCore/README.md +0 -13
- package/doc/ValidationModel/README.md +0 -117
- package/doc/it/AIAssistedDevelopment/README.md +0 -185
- package/doc/it/AttachmentModel/README.md +0 -173
- package/doc/it/AuthenticationModel/README.md +0 -171
- package/doc/it/AuthenticationModel/how-to-integreate-auth-minimal-api.md +0 -292
- package/doc/it/ChillSharpClient.md +0 -464
- package/doc/it/ClientGeneration/README.md +0 -152
- package/doc/it/ComplianceGuide/README.md +0 -178
- package/doc/it/Configuration/README.md +0 -94
- package/doc/it/CurrentUserPreferences.md +0 -114
- package/doc/it/DateTimePolicy/README.md +0 -154
- package/doc/it/DateTimeSerialization.md +0 -423
- package/doc/it/Endpoints.md +0 -260
- package/doc/it/HowTo/01-simple-blog-sqlite.md +0 -152
- package/doc/it/HowTo/02-blog-schema-labels.md +0 -139
- package/doc/it/HowTo/03-authentication.md +0 -221
- package/doc/it/HowTo/04-blog-posts-one-to-many.md +0 -193
- package/doc/it/HowTo/05-docker-env-variables.md +0 -268
- package/doc/it/HowTo/06-chunk-transactions-autocomplete.md +0 -196
- package/doc/it/Mcp/ChatGPT.md +0 -291
- package/doc/it/Mcp/README.md +0 -799
- package/doc/it/MenuGuide/README.md +0 -49
- package/doc/it/ModelPreparation.md +0 -254
- package/doc/it/PermissionModel/README.md +0 -190
- package/doc/it/README.md +0 -172
- package/doc/it/ReferenceExistence.md +0 -130
- package/doc/it/RegisterContext.md +0 -218
- package/doc/it/UiCore/CRUD.md +0 -170
- package/doc/it/UiCore/README.md +0 -13
- package/doc/it/ValidationModel/README.md +0 -117
- package/template-customization/upgrade.ps1.template +0 -342
- package/template-customization/upgrade.sh.template +0 -271
|
@@ -72,7 +72,7 @@ export declare class ChillFormComponent implements OnDestroy {
|
|
|
72
72
|
private autocompleteRequestSequence;
|
|
73
73
|
private pendingAutocompletePromise;
|
|
74
74
|
readonly mode: import("@angular/core").Signal<"entity" | "query">;
|
|
75
|
-
readonly source: import("@angular/core").Signal<
|
|
75
|
+
readonly source: import("@angular/core").Signal<ChillEntity | ChillQuery | null>;
|
|
76
76
|
readonly hasCustomSubmitHandler: import("@angular/core").Signal<boolean>;
|
|
77
77
|
readonly properties: import("@angular/core").Signal<ChillPropertySchema[]>;
|
|
78
78
|
readonly layoutItems: import("@angular/core").Signal<ResolvedFormLayoutItem[]>;
|
package/package.json
CHANGED
|
@@ -5,7 +5,7 @@
|
|
|
5
5
|
"url": "git+https://github.com/e-500/chill-sharp.git",
|
|
6
6
|
"directory": "extra/chill-sharp-ui-core"
|
|
7
7
|
},
|
|
8
|
-
"version": "1.1.
|
|
8
|
+
"version": "1.1.15",
|
|
9
9
|
"description": "Shared Angular UI core for ChillSharp applications.",
|
|
10
10
|
"keywords": [
|
|
11
11
|
"angular",
|
|
@@ -44,8 +44,8 @@
|
|
|
44
44
|
"zone.js": "~0.15.0"
|
|
45
45
|
},
|
|
46
46
|
"dependencies": {
|
|
47
|
-
"@chill-sharp/ng-client": "^1.1.
|
|
48
|
-
"@chill-sharp/ts-client": "^1.1.
|
|
47
|
+
"@chill-sharp/ng-client": "^1.1.15",
|
|
48
|
+
"@chill-sharp/ts-client": "^1.1.15",
|
|
49
49
|
"monaco-editor": "^0.52.2",
|
|
50
50
|
"tslib": "^2.3.0"
|
|
51
51
|
},
|
|
@@ -1,166 +1,166 @@
|
|
|
1
|
-
// Shared worker, loaded by the client-owned public/sw.js through importScripts().
|
|
2
|
-
// Set self.CHILL_SHARP_SW_OPTIONS before importing to customize these defaults.
|
|
3
|
-
const OPTIONS = {
|
|
4
|
-
cachePrefix: 'chill-sharp-ui',
|
|
5
|
-
cacheVersion: 'v2',
|
|
6
|
-
cacheTimeoutMs: 10 * 60 * 1000,
|
|
7
|
-
appShell: ['/', '/index.html'],
|
|
8
|
-
legacyCacheNames: [],
|
|
9
|
-
...self.CHILL_SHARP_SW_OPTIONS
|
|
10
|
-
};
|
|
11
|
-
|
|
12
|
-
const SHELL_CACHE = `${OPTIONS.cachePrefix}-shell-${OPTIONS.cacheVersion}`;
|
|
13
|
-
const METADATA_CACHE = `${OPTIONS.cachePrefix}-metadata-${OPTIONS.cacheVersion}`;
|
|
14
|
-
const CACHED_AT = 'X-ChillSharp-Cached-At';
|
|
15
|
-
const METADATA_READS = new Set(['get-schema', 'get-schema-list', 'get-entity-options']);
|
|
16
|
-
const METADATA_WRITES = new Set(['set-schema', 'set-entity-options']);
|
|
17
|
-
let metadataGeneration = 0;
|
|
18
|
-
let pendingMutation = Promise.resolve();
|
|
19
|
-
let cacheOperations = Promise.resolve();
|
|
20
|
-
|
|
21
|
-
// Order cache writes/deletions so a pre-update fetch cannot refill an invalidated cache.
|
|
22
|
-
function changeMetadataCache(action) {
|
|
23
|
-
const operation = cacheOperations.then(action);
|
|
24
|
-
cacheOperations = operation.catch(() => {});
|
|
25
|
-
return operation;
|
|
26
|
-
}
|
|
27
|
-
|
|
28
|
-
function schemaAction(url) {
|
|
29
|
-
const match = url.pathname.match(/\/chill-schema\/([^/]+)\/?$/i);
|
|
30
|
-
return match ? match[1].toLowerCase() : '';
|
|
31
|
-
}
|
|
32
|
-
|
|
33
|
-
function isSchemaUpdate(url, action) {
|
|
34
|
-
return action === 'get-schema' && [...url.searchParams].some(
|
|
35
|
-
([name, value]) => name.toLowerCase() === 'update' && value.toLowerCase() === 'true'
|
|
36
|
-
);
|
|
37
|
-
}
|
|
38
|
-
|
|
39
|
-
async function freshCachedResponse(cacheName, request) {
|
|
40
|
-
const cache = await caches.open(cacheName);
|
|
41
|
-
const response = await cache.match(request);
|
|
42
|
-
if (!response) return undefined;
|
|
43
|
-
const cachedAt = Number(response.headers.get(CACHED_AT));
|
|
44
|
-
const age = Date.now() - cachedAt;
|
|
45
|
-
if (cachedAt > 0 && age >= 0 && age < OPTIONS.cacheTimeoutMs) return response;
|
|
46
|
-
await cache.delete(request);
|
|
47
|
-
return undefined;
|
|
48
|
-
}
|
|
49
|
-
|
|
50
|
-
async function storeResponse(cacheName, request, response) {
|
|
51
|
-
if (!response.ok || [204, 205, 206].includes(response.status) || response.type === 'opaque' ||
|
|
52
|
-
/\bno-store\b/i.test(response.headers.get('Cache-Control') || '') ||
|
|
53
|
-
(response.headers.get('Vary') || '').split(',').some((name) => name.trim() === '*')) return;
|
|
54
|
-
|
|
55
|
-
const headers = new Headers(response.headers);
|
|
56
|
-
headers.set(CACHED_AT, String(Date.now()));
|
|
57
|
-
// Cache API does not distinguish bearer tokens unless the response varies by them.
|
|
58
|
-
const vary = new Set((headers.get('Vary') || '').split(',').map((v) => v.trim()).filter(Boolean));
|
|
59
|
-
vary.add('Authorization');
|
|
60
|
-
headers.set('Vary', [...vary].join(', '));
|
|
61
|
-
const copy = new Response(await response.clone().blob(), {
|
|
62
|
-
status: response.status, statusText: response.statusText, headers
|
|
63
|
-
});
|
|
64
|
-
await (await caches.open(cacheName)).put(request, copy);
|
|
65
|
-
}
|
|
66
|
-
|
|
67
|
-
function fetchFresh(request) {
|
|
68
|
-
return fetch(new Request(request, { cache: 'no-store' }));
|
|
69
|
-
}
|
|
70
|
-
|
|
71
|
-
async function readMetadata(request) {
|
|
72
|
-
await pendingMutation;
|
|
73
|
-
const generation = metadataGeneration;
|
|
74
|
-
const cached = await changeMetadataCache(() => freshCachedResponse(METADATA_CACHE, request)).catch(() => undefined);
|
|
75
|
-
if (cached && generation === metadataGeneration) return cached;
|
|
76
|
-
const response = await fetchFresh(request);
|
|
77
|
-
await changeMetadataCache(async () => {
|
|
78
|
-
if (generation === metadataGeneration) await storeResponse(METADATA_CACHE, request, response);
|
|
79
|
-
}).catch(() => {}); // Storage quota errors must not discard a successful network response.
|
|
80
|
-
return response;
|
|
81
|
-
}
|
|
82
|
-
|
|
83
|
-
function mutateMetadata(request) {
|
|
84
|
-
metadataGeneration++;
|
|
85
|
-
const operation = pendingMutation.then(async () => {
|
|
86
|
-
await changeMetadataCache(() => caches.delete(METADATA_CACHE));
|
|
87
|
-
try {
|
|
88
|
-
// update=true must reach the server on every click, including repeated updates.
|
|
89
|
-
return await fetchFresh(request);
|
|
90
|
-
} finally {
|
|
91
|
-
// Clear all types/views/cultures and entity options, including schema-list summaries.
|
|
92
|
-
// Normal GETs after the update (also after a reload) must fetch the saved schema.
|
|
93
|
-
await changeMetadataCache(() => caches.delete(METADATA_CACHE));
|
|
94
|
-
}
|
|
95
|
-
});
|
|
96
|
-
pendingMutation = operation.then(() => {}, () => {});
|
|
97
|
-
return operation;
|
|
98
|
-
}
|
|
99
|
-
|
|
100
|
-
self.addEventListener('install', (event) => {
|
|
101
|
-
event.waitUntil((async () => {
|
|
102
|
-
const cache = await caches.open(SHELL_CACHE);
|
|
103
|
-
await cache.addAll(OPTIONS.appShell.map((url) => new Request(new URL(url, self.location.href), { cache: 'reload' })));
|
|
104
|
-
await self.skipWaiting();
|
|
105
|
-
})());
|
|
106
|
-
});
|
|
107
|
-
|
|
108
|
-
self.addEventListener('activate', (event) => {
|
|
109
|
-
event.waitUntil((async () => {
|
|
110
|
-
const current = new Set([SHELL_CACHE, METADATA_CACHE]);
|
|
111
|
-
await Promise.all((await caches.keys())
|
|
112
|
-
.filter((key) => OPTIONS.legacyCacheNames.includes(key) ||
|
|
113
|
-
(key.startsWith(`${OPTIONS.cachePrefix}-`) && !current.has(key)))
|
|
114
|
-
.map((key) => caches.delete(key)));
|
|
115
|
-
await self.clients.claim();
|
|
116
|
-
})());
|
|
117
|
-
});
|
|
118
|
-
|
|
119
|
-
self.addEventListener('fetch', (event) => {
|
|
120
|
-
const request = event.request;
|
|
121
|
-
const url = new URL(request.url);
|
|
122
|
-
const action = schemaAction(url);
|
|
123
|
-
|
|
124
|
-
if ((request.method === 'GET' && isSchemaUpdate(url, action)) ||
|
|
125
|
-
(request.method === 'POST' && METADATA_WRITES.has(action))) {
|
|
126
|
-
const response = mutateMetadata(request);
|
|
127
|
-
event.respondWith(response);
|
|
128
|
-
event.waitUntil(response.then(() => {}, () => {}));
|
|
129
|
-
return;
|
|
130
|
-
}
|
|
131
|
-
|
|
132
|
-
if (request.method !== 'GET') return;
|
|
133
|
-
if (METADATA_READS.has(action)) {
|
|
134
|
-
const response = readMetadata(request);
|
|
135
|
-
event.respondWith(response);
|
|
136
|
-
event.waitUntil(response.then(() => {}, () => {}));
|
|
137
|
-
return;
|
|
138
|
-
}
|
|
139
|
-
|
|
140
|
-
// Only metadata APIs above are cached. Other APIs and runtime settings stay fresh.
|
|
141
|
-
if (action || /\/api(?:\/|$)/i.test(url.pathname) ||
|
|
142
|
-
/\/(?:env|runtime-config|sw)\.js$/i.test(url.pathname)) {
|
|
143
|
-
event.respondWith(fetchFresh(request));
|
|
144
|
-
return;
|
|
145
|
-
}
|
|
146
|
-
|
|
147
|
-
if (url.origin !== self.location.origin || request.headers.has('Authorization')) return;
|
|
148
|
-
if (request.mode === 'navigate') {
|
|
149
|
-
event.respondWith(fetchFresh(request).catch(async () => {
|
|
150
|
-
const shell = await (await caches.open(SHELL_CACHE)).match('/index.html');
|
|
151
|
-
return shell || Response.error();
|
|
152
|
-
}));
|
|
153
|
-
return;
|
|
154
|
-
}
|
|
155
|
-
|
|
156
|
-
if (!['script', 'style', 'image', 'font', 'manifest'].includes(request.destination)) return;
|
|
157
|
-
const response = (async () => {
|
|
158
|
-
const cached = await freshCachedResponse(SHELL_CACHE, request);
|
|
159
|
-
if (cached) return cached;
|
|
160
|
-
const result = await fetchFresh(request);
|
|
161
|
-
await storeResponse(SHELL_CACHE, request, result).catch(() => {});
|
|
162
|
-
return result;
|
|
163
|
-
})();
|
|
164
|
-
event.respondWith(response);
|
|
165
|
-
event.waitUntil(response.then(() => {}, () => {}));
|
|
166
|
-
});
|
|
1
|
+
// Shared worker, loaded by the client-owned public/sw.js through importScripts().
|
|
2
|
+
// Set self.CHILL_SHARP_SW_OPTIONS before importing to customize these defaults.
|
|
3
|
+
const OPTIONS = {
|
|
4
|
+
cachePrefix: 'chill-sharp-ui',
|
|
5
|
+
cacheVersion: 'v2',
|
|
6
|
+
cacheTimeoutMs: 10 * 60 * 1000,
|
|
7
|
+
appShell: ['/', '/index.html'],
|
|
8
|
+
legacyCacheNames: [],
|
|
9
|
+
...self.CHILL_SHARP_SW_OPTIONS
|
|
10
|
+
};
|
|
11
|
+
|
|
12
|
+
const SHELL_CACHE = `${OPTIONS.cachePrefix}-shell-${OPTIONS.cacheVersion}`;
|
|
13
|
+
const METADATA_CACHE = `${OPTIONS.cachePrefix}-metadata-${OPTIONS.cacheVersion}`;
|
|
14
|
+
const CACHED_AT = 'X-ChillSharp-Cached-At';
|
|
15
|
+
const METADATA_READS = new Set(['get-schema', 'get-schema-list', 'get-entity-options']);
|
|
16
|
+
const METADATA_WRITES = new Set(['set-schema', 'set-entity-options']);
|
|
17
|
+
let metadataGeneration = 0;
|
|
18
|
+
let pendingMutation = Promise.resolve();
|
|
19
|
+
let cacheOperations = Promise.resolve();
|
|
20
|
+
|
|
21
|
+
// Order cache writes/deletions so a pre-update fetch cannot refill an invalidated cache.
|
|
22
|
+
function changeMetadataCache(action) {
|
|
23
|
+
const operation = cacheOperations.then(action);
|
|
24
|
+
cacheOperations = operation.catch(() => {});
|
|
25
|
+
return operation;
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
function schemaAction(url) {
|
|
29
|
+
const match = url.pathname.match(/\/chill-schema\/([^/]+)\/?$/i);
|
|
30
|
+
return match ? match[1].toLowerCase() : '';
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
function isSchemaUpdate(url, action) {
|
|
34
|
+
return action === 'get-schema' && [...url.searchParams].some(
|
|
35
|
+
([name, value]) => name.toLowerCase() === 'update' && value.toLowerCase() === 'true'
|
|
36
|
+
);
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
async function freshCachedResponse(cacheName, request) {
|
|
40
|
+
const cache = await caches.open(cacheName);
|
|
41
|
+
const response = await cache.match(request);
|
|
42
|
+
if (!response) return undefined;
|
|
43
|
+
const cachedAt = Number(response.headers.get(CACHED_AT));
|
|
44
|
+
const age = Date.now() - cachedAt;
|
|
45
|
+
if (cachedAt > 0 && age >= 0 && age < OPTIONS.cacheTimeoutMs) return response;
|
|
46
|
+
await cache.delete(request);
|
|
47
|
+
return undefined;
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
async function storeResponse(cacheName, request, response) {
|
|
51
|
+
if (!response.ok || [204, 205, 206].includes(response.status) || response.type === 'opaque' ||
|
|
52
|
+
/\bno-store\b/i.test(response.headers.get('Cache-Control') || '') ||
|
|
53
|
+
(response.headers.get('Vary') || '').split(',').some((name) => name.trim() === '*')) return;
|
|
54
|
+
|
|
55
|
+
const headers = new Headers(response.headers);
|
|
56
|
+
headers.set(CACHED_AT, String(Date.now()));
|
|
57
|
+
// Cache API does not distinguish bearer tokens unless the response varies by them.
|
|
58
|
+
const vary = new Set((headers.get('Vary') || '').split(',').map((v) => v.trim()).filter(Boolean));
|
|
59
|
+
vary.add('Authorization');
|
|
60
|
+
headers.set('Vary', [...vary].join(', '));
|
|
61
|
+
const copy = new Response(await response.clone().blob(), {
|
|
62
|
+
status: response.status, statusText: response.statusText, headers
|
|
63
|
+
});
|
|
64
|
+
await (await caches.open(cacheName)).put(request, copy);
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
function fetchFresh(request) {
|
|
68
|
+
return fetch(new Request(request, { cache: 'no-store' }));
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
async function readMetadata(request) {
|
|
72
|
+
await pendingMutation;
|
|
73
|
+
const generation = metadataGeneration;
|
|
74
|
+
const cached = await changeMetadataCache(() => freshCachedResponse(METADATA_CACHE, request)).catch(() => undefined);
|
|
75
|
+
if (cached && generation === metadataGeneration) return cached;
|
|
76
|
+
const response = await fetchFresh(request);
|
|
77
|
+
await changeMetadataCache(async () => {
|
|
78
|
+
if (generation === metadataGeneration) await storeResponse(METADATA_CACHE, request, response);
|
|
79
|
+
}).catch(() => {}); // Storage quota errors must not discard a successful network response.
|
|
80
|
+
return response;
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
function mutateMetadata(request) {
|
|
84
|
+
metadataGeneration++;
|
|
85
|
+
const operation = pendingMutation.then(async () => {
|
|
86
|
+
await changeMetadataCache(() => caches.delete(METADATA_CACHE));
|
|
87
|
+
try {
|
|
88
|
+
// update=true must reach the server on every click, including repeated updates.
|
|
89
|
+
return await fetchFresh(request);
|
|
90
|
+
} finally {
|
|
91
|
+
// Clear all types/views/cultures and entity options, including schema-list summaries.
|
|
92
|
+
// Normal GETs after the update (also after a reload) must fetch the saved schema.
|
|
93
|
+
await changeMetadataCache(() => caches.delete(METADATA_CACHE));
|
|
94
|
+
}
|
|
95
|
+
});
|
|
96
|
+
pendingMutation = operation.then(() => {}, () => {});
|
|
97
|
+
return operation;
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
self.addEventListener('install', (event) => {
|
|
101
|
+
event.waitUntil((async () => {
|
|
102
|
+
const cache = await caches.open(SHELL_CACHE);
|
|
103
|
+
await cache.addAll(OPTIONS.appShell.map((url) => new Request(new URL(url, self.location.href), { cache: 'reload' })));
|
|
104
|
+
await self.skipWaiting();
|
|
105
|
+
})());
|
|
106
|
+
});
|
|
107
|
+
|
|
108
|
+
self.addEventListener('activate', (event) => {
|
|
109
|
+
event.waitUntil((async () => {
|
|
110
|
+
const current = new Set([SHELL_CACHE, METADATA_CACHE]);
|
|
111
|
+
await Promise.all((await caches.keys())
|
|
112
|
+
.filter((key) => OPTIONS.legacyCacheNames.includes(key) ||
|
|
113
|
+
(key.startsWith(`${OPTIONS.cachePrefix}-`) && !current.has(key)))
|
|
114
|
+
.map((key) => caches.delete(key)));
|
|
115
|
+
await self.clients.claim();
|
|
116
|
+
})());
|
|
117
|
+
});
|
|
118
|
+
|
|
119
|
+
self.addEventListener('fetch', (event) => {
|
|
120
|
+
const request = event.request;
|
|
121
|
+
const url = new URL(request.url);
|
|
122
|
+
const action = schemaAction(url);
|
|
123
|
+
|
|
124
|
+
if ((request.method === 'GET' && isSchemaUpdate(url, action)) ||
|
|
125
|
+
(request.method === 'POST' && METADATA_WRITES.has(action))) {
|
|
126
|
+
const response = mutateMetadata(request);
|
|
127
|
+
event.respondWith(response);
|
|
128
|
+
event.waitUntil(response.then(() => {}, () => {}));
|
|
129
|
+
return;
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
if (request.method !== 'GET') return;
|
|
133
|
+
if (METADATA_READS.has(action)) {
|
|
134
|
+
const response = readMetadata(request);
|
|
135
|
+
event.respondWith(response);
|
|
136
|
+
event.waitUntil(response.then(() => {}, () => {}));
|
|
137
|
+
return;
|
|
138
|
+
}
|
|
139
|
+
|
|
140
|
+
// Only metadata APIs above are cached. Other APIs and runtime settings stay fresh.
|
|
141
|
+
if (action || /\/api(?:\/|$)/i.test(url.pathname) ||
|
|
142
|
+
/\/(?:env|runtime-config|sw)\.js$/i.test(url.pathname)) {
|
|
143
|
+
event.respondWith(fetchFresh(request));
|
|
144
|
+
return;
|
|
145
|
+
}
|
|
146
|
+
|
|
147
|
+
if (url.origin !== self.location.origin || request.headers.has('Authorization')) return;
|
|
148
|
+
if (request.mode === 'navigate') {
|
|
149
|
+
event.respondWith(fetchFresh(request).catch(async () => {
|
|
150
|
+
const shell = await (await caches.open(SHELL_CACHE)).match('/index.html');
|
|
151
|
+
return shell || Response.error();
|
|
152
|
+
}));
|
|
153
|
+
return;
|
|
154
|
+
}
|
|
155
|
+
|
|
156
|
+
if (!['script', 'style', 'image', 'font', 'manifest'].includes(request.destination)) return;
|
|
157
|
+
const response = (async () => {
|
|
158
|
+
const cached = await freshCachedResponse(SHELL_CACHE, request);
|
|
159
|
+
if (cached) return cached;
|
|
160
|
+
const result = await fetchFresh(request);
|
|
161
|
+
await storeResponse(SHELL_CACHE, request, result).catch(() => {});
|
|
162
|
+
return result;
|
|
163
|
+
})();
|
|
164
|
+
event.respondWith(response);
|
|
165
|
+
event.waitUntil(response.then(() => {}, () => {}));
|
|
166
|
+
});
|