@wells-nelson/build-tools 1.0.0 → 1.0.2
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 +7 -2
- package/dist/service-worker.d.ts +21 -5
- package/dist/service-worker.js +21 -6
- package/dist/vite.d.ts +13 -2
- package/dist/vite.js +33 -4
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -40,14 +40,19 @@ export default defineConfig(({ mode, command }) => ({
|
|
|
40
40
|
|
|
41
41
|
```ts
|
|
42
42
|
/// <reference types="@sveltejs/kit" />
|
|
43
|
-
import { version } from '$app/env';
|
|
43
|
+
import { dev, version } from '$app/env';
|
|
44
44
|
import { assets, immutable } from '$app/manifest';
|
|
45
45
|
import { self } from '$app/service-worker';
|
|
46
46
|
import { registerAppShellCache } from '@wells-nelson/build-tools/service-worker';
|
|
47
47
|
|
|
48
|
-
registerAppShellCache({ sw: self, version, files: [...immutable, ...assets], cachePrefix: 'my-app' });
|
|
48
|
+
registerAppShellCache({ sw: self, version, dev, files: [...immutable, ...assets], cachePrefix: 'my-app' });
|
|
49
49
|
```
|
|
50
50
|
|
|
51
|
+
Navigations go to the network first, so starting the app online always loads the latest deploy;
|
|
52
|
+
offline they fall back to the cached shell. A new worker skips waiting and takes over open
|
|
53
|
+
pages. `networkOnly` paths are never cached (default: SvelteKit's `_app/version.json`, so
|
|
54
|
+
`updated` from `$app/state` notices new deploys). `dev` caches nothing.
|
|
55
|
+
|
|
51
56
|
## Templates
|
|
52
57
|
|
|
53
58
|
`templates/deploy-pages.yml` (replace `__REPO__`) and `templates/manifest.webmanifest`.
|
package/dist/service-worker.d.ts
CHANGED
|
@@ -1,17 +1,19 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* Offline-first app shell for a SvelteKit service worker. Everything the app needs is precached
|
|
3
|
-
* on install; navigations
|
|
4
|
-
*
|
|
3
|
+
* on install; navigations go to the network first (so starting the app online always
|
|
4
|
+
* loads the latest deploy) and fall back to the cached shell (the app root) offline. A new
|
|
5
|
+
* deploy's worker installs, skips waiting and takes over open pages straight away. Cross-origin
|
|
6
|
+
* requests (Supabase, Google avatars) are left to the network.
|
|
5
7
|
*
|
|
6
8
|
* ```ts
|
|
7
9
|
* // src/service-worker/index.ts
|
|
8
10
|
* /// <reference types="@sveltejs/kit" />
|
|
9
|
-
* import { version } from '$app/env';
|
|
11
|
+
* import { dev, version } from '$app/env';
|
|
10
12
|
* import { assets, immutable } from '$app/manifest';
|
|
11
13
|
* import { self } from '$app/service-worker';
|
|
12
14
|
* import { registerAppShellCache } from '@wells-nelson/build-tools/service-worker';
|
|
13
15
|
*
|
|
14
|
-
* registerAppShellCache({ sw: self, version, files: [...immutable, ...assets], cachePrefix: 'my-app' });
|
|
16
|
+
* registerAppShellCache({ sw: self, version, dev, files: [...immutable, ...assets], cachePrefix: 'my-app' });
|
|
15
17
|
* ```
|
|
16
18
|
*/
|
|
17
19
|
/** The parts of ServiceWorkerGlobalScope this uses (so it type-checks without the WebWorker lib). */
|
|
@@ -35,8 +37,22 @@ export interface AppShellCacheOptions {
|
|
|
35
37
|
}>;
|
|
36
38
|
/** Cache name prefix (default 'app'). */
|
|
37
39
|
cachePrefix?: string;
|
|
40
|
+
/**
|
|
41
|
+
* Development: cache nothing and delete what an earlier worker cached, so every code change
|
|
42
|
+
* loads (a cache-first worker would otherwise keep serving stale dev modules).
|
|
43
|
+
*/
|
|
44
|
+
dev?: boolean;
|
|
45
|
+
/**
|
|
46
|
+
* Paths (relative to the scope) that always go to the network and are never cached. Defaults
|
|
47
|
+
* to SvelteKit's `_app/version.json`, so its update check (`updated` in `$app/state`) sees
|
|
48
|
+
* new deploys instead of the first answer it ever cached.
|
|
49
|
+
*/
|
|
50
|
+
networkOnly?: string[];
|
|
38
51
|
}
|
|
39
|
-
export declare function registerAppShellCache({ sw, version, files, cachePrefix }: AppShellCacheOptions): {
|
|
52
|
+
export declare function registerAppShellCache({ sw, version, files, cachePrefix, dev, networkOnly }: AppShellCacheOptions): {
|
|
53
|
+
cacheName: null;
|
|
54
|
+
precache: never[];
|
|
55
|
+
} | {
|
|
40
56
|
cacheName: string;
|
|
41
57
|
precache: string[];
|
|
42
58
|
};
|
package/dist/service-worker.js
CHANGED
|
@@ -1,24 +1,39 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* Offline-first app shell for a SvelteKit service worker. Everything the app needs is precached
|
|
3
|
-
* on install; navigations
|
|
4
|
-
*
|
|
3
|
+
* on install; navigations go to the network first (so starting the app online always
|
|
4
|
+
* loads the latest deploy) and fall back to the cached shell (the app root) offline. A new
|
|
5
|
+
* deploy's worker installs, skips waiting and takes over open pages straight away. Cross-origin
|
|
6
|
+
* requests (Supabase, Google avatars) are left to the network.
|
|
5
7
|
*
|
|
6
8
|
* ```ts
|
|
7
9
|
* // src/service-worker/index.ts
|
|
8
10
|
* /// <reference types="@sveltejs/kit" />
|
|
9
|
-
* import { version } from '$app/env';
|
|
11
|
+
* import { dev, version } from '$app/env';
|
|
10
12
|
* import { assets, immutable } from '$app/manifest';
|
|
11
13
|
* import { self } from '$app/service-worker';
|
|
12
14
|
* import { registerAppShellCache } from '@wells-nelson/build-tools/service-worker';
|
|
13
15
|
*
|
|
14
|
-
* registerAppShellCache({ sw: self, version, files: [...immutable, ...assets], cachePrefix: 'my-app' });
|
|
16
|
+
* registerAppShellCache({ sw: self, version, dev, files: [...immutable, ...assets], cachePrefix: 'my-app' });
|
|
15
17
|
* ```
|
|
16
18
|
*/
|
|
17
|
-
export function registerAppShellCache({ sw, version, files, cachePrefix = 'app' }) {
|
|
19
|
+
export function registerAppShellCache({ sw, version, files, cachePrefix = 'app', dev = false, networkOnly = ['_app/version.json'] }) {
|
|
18
20
|
const CACHE = `${cachePrefix}-cache-${version}`;
|
|
21
|
+
if (dev) {
|
|
22
|
+
sw.addEventListener('install', (event) => event.waitUntil(sw.skipWaiting()));
|
|
23
|
+
sw.addEventListener('activate', (event) => {
|
|
24
|
+
event.waitUntil((async () => {
|
|
25
|
+
for (const key of await caches.keys())
|
|
26
|
+
if (key.startsWith(`${cachePrefix}-cache-`))
|
|
27
|
+
await caches.delete(key);
|
|
28
|
+
await sw.clients.claim();
|
|
29
|
+
})());
|
|
30
|
+
});
|
|
31
|
+
return { cacheName: null, precache: [] };
|
|
32
|
+
}
|
|
19
33
|
const scope = new URL(sw.registration.scope);
|
|
20
34
|
// The app root serves the SPA shell (index.html on GitHub Pages, the fallback page elsewhere).
|
|
21
35
|
const SHELL = scope.href;
|
|
36
|
+
const NETWORK_ONLY = new Set(networkOnly.map((p) => new URL(p, scope).pathname));
|
|
22
37
|
const PRECACHE = files.map((f) => new URL(typeof f === 'string' ? f : f.path, scope).href).concat(SHELL);
|
|
23
38
|
sw.addEventListener('install', (event) => {
|
|
24
39
|
event.waitUntil((async () => {
|
|
@@ -40,7 +55,7 @@ export function registerAppShellCache({ sw, version, files, cachePrefix = 'app'
|
|
|
40
55
|
if (request.method !== 'GET')
|
|
41
56
|
return;
|
|
42
57
|
const url = new URL(request.url);
|
|
43
|
-
if (url.origin !== scope.origin)
|
|
58
|
+
if (url.origin !== scope.origin || NETWORK_ONLY.has(url.pathname))
|
|
44
59
|
return;
|
|
45
60
|
if (request.mode === 'navigate') {
|
|
46
61
|
event.respondWith((async () => {
|
package/dist/vite.d.ts
CHANGED
|
@@ -16,8 +16,19 @@ export declare function basePath({ mode, env, fallback }: {
|
|
|
16
16
|
* break ("Cannot read properties of undefined (reading 'call')" / a 500 page) until a full reload.
|
|
17
17
|
*/
|
|
18
18
|
export declare const SHARED_OPTIMIZE_DEPS: string[];
|
|
19
|
-
/**
|
|
20
|
-
|
|
19
|
+
/**
|
|
20
|
+
* Entry points of the Wells Nelson packages. They must be pre-bundled at startup too: one
|
|
21
|
+
* imported only by a lazily loaded page (e.g. `interactions/account`) or by the service worker
|
|
22
|
+
* otherwise triggers the same mid-session re-bundle.
|
|
23
|
+
*/
|
|
24
|
+
export declare const WELLS_NELSON_ENTRIES: string[];
|
|
25
|
+
/** The entries that resolve from `root` (an app installs only the packages it uses). */
|
|
26
|
+
export declare function installedEntries(entries: string[], root?: string): string[];
|
|
27
|
+
/**
|
|
28
|
+
* `optimizeDeps` with the shared runtime dependencies, every installed Wells Nelson entry point,
|
|
29
|
+
* and the app's own lazily loaded deps (e.g. a search library).
|
|
30
|
+
*/
|
|
31
|
+
export declare function optimizeDeps(extra?: string[], root?: string): {
|
|
21
32
|
include: string[];
|
|
22
33
|
};
|
|
23
34
|
/**
|
package/dist/vite.js
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { existsSync, readFileSync } from 'node:fs';
|
|
2
|
-
import {
|
|
2
|
+
import { createRequire } from 'node:module';
|
|
3
|
+
import { join, resolve } from 'node:path';
|
|
3
4
|
/**
|
|
4
5
|
* SvelteKit `paths.base` from the BASE_PATH env var: the one place the deploy path is configured.
|
|
5
6
|
* GitHub project pages are served from /<repo-name> (the `fallback`); set BASE_PATH to "/" for
|
|
@@ -23,9 +24,37 @@ export const SHARED_OPTIMIZE_DEPS = [
|
|
|
23
24
|
'rxdb/plugins/replication-supabase',
|
|
24
25
|
'rxdb/plugins/storage-dexie'
|
|
25
26
|
];
|
|
26
|
-
/**
|
|
27
|
-
|
|
28
|
-
|
|
27
|
+
/**
|
|
28
|
+
* Entry points of the Wells Nelson packages. They must be pre-bundled at startup too: one
|
|
29
|
+
* imported only by a lazily loaded page (e.g. `interactions/account`) or by the service worker
|
|
30
|
+
* otherwise triggers the same mid-session re-bundle.
|
|
31
|
+
*/
|
|
32
|
+
export const WELLS_NELSON_ENTRIES = [
|
|
33
|
+
'@wells-nelson/displays',
|
|
34
|
+
'@wells-nelson/interactions',
|
|
35
|
+
'@wells-nelson/interactions/account',
|
|
36
|
+
'@wells-nelson/data-storage',
|
|
37
|
+
'@wells-nelson/build-tools/service-worker'
|
|
38
|
+
];
|
|
39
|
+
/** The entries that resolve from `root` (an app installs only the packages it uses). */
|
|
40
|
+
export function installedEntries(entries, root = process.cwd()) {
|
|
41
|
+
const require = createRequire(join(root, 'package.json'));
|
|
42
|
+
return entries.filter((id) => {
|
|
43
|
+
try {
|
|
44
|
+
require.resolve(id);
|
|
45
|
+
return true;
|
|
46
|
+
}
|
|
47
|
+
catch {
|
|
48
|
+
return false;
|
|
49
|
+
}
|
|
50
|
+
});
|
|
51
|
+
}
|
|
52
|
+
/**
|
|
53
|
+
* `optimizeDeps` with the shared runtime dependencies, every installed Wells Nelson entry point,
|
|
54
|
+
* and the app's own lazily loaded deps (e.g. a search library).
|
|
55
|
+
*/
|
|
56
|
+
export function optimizeDeps(extra = [], root = process.cwd()) {
|
|
57
|
+
return { include: [...extra, ...installedEntries(WELLS_NELSON_ENTRIES, root), ...SHARED_OPTIMIZE_DEPS] };
|
|
29
58
|
}
|
|
30
59
|
/**
|
|
31
60
|
* Serve a git-ignored JSON file (e.g. seed data with real names) as a virtual module to the dev
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@wells-nelson/build-tools",
|
|
3
|
-
"version": "1.0.
|
|
3
|
+
"version": "1.0.2",
|
|
4
4
|
"description": "Build and deployment tooling for Wells Nelson SvelteKit PWAs: postbuild, PWA icon generator, Vite config pieces, service worker, and templates.",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"repository": {
|