diff --git a/docs/.vitepress/config.js b/docs/.vitepress/config.ts similarity index 87% rename from docs/.vitepress/config.js rename to docs/.vitepress/config.ts index b6ba157e..d486a4ed 100644 --- a/docs/.vitepress/config.js +++ b/docs/.vitepress/config.ts @@ -1,4 +1,4 @@ -require('esbuild-register') +import type { UserConfig } from 'vitepress' const Guide = [ { @@ -83,6 +83,10 @@ const Frameworks = [ text: 'Svelte', link: '/frameworks/svelte', }, + { + text: 'SvelteKit', + link: '/frameworks/sveltekit', + }, { text: 'SolidJS', link: '/frameworks/solidjs', @@ -114,6 +118,10 @@ const Examples = [ text: 'Svelte', link: '/examples/svelte', }, + { + text: 'SvelteKit', + link: '/examples/sveltekit', + }, { text: 'SolidJS', link: '/examples/solidjs', @@ -147,45 +155,41 @@ const slidebars = [ { text: 'Guide', children: Guide.map((e) => { - e.useLinkText = `${e.text} | Guide` + (e as any).useLinkText = `${e.text} | Guide` return e }), }, { text: 'Frameworks', children: Frameworks.map((e) => { - e.useLinkText = `${e.text} | Frameworks` + (e as any).useLinkText = `${e.text} | Frameworks` return e }), }, { text: 'Examples', children: Examples.map((e) => { - e.useLinkText = `${e.text} | Examples` + (e as any).useLinkText = `${e.text} | Examples` return e }), }, { text: 'Deployment', children: Deployment.map((e) => { - e.useLinkText = `${e.text} | Deployment` + (e as any).useLinkText = `${e.text} | Deployment` return e }), }, { text: 'Workbox', children: Workbox.map((e) => { - e.useLinkText = `${e.text} | Workbox` + (e as any).useLinkText = `${e.text} | Workbox` return e }), }, ] - -/** - * @type {import('vitepress').UserConfig} - */ -const config = { +const config: UserConfig = { title: 'Vite Plugin PWA', description: 'Zero-config PWA Framework-agnostic Plugin for Vite', lang: 'en-US', @@ -195,7 +199,7 @@ const config = { ['link', { rel: 'alternate icon', href: '/favicon.ico', type: 'image/png', sizes: '16x16' }], ['link', { rel: 'mask-icon', href: '/safari-pinned-tab.svg', color: '#ffffff' }], ['meta', { name: 'author', content: 'Anthony Fu' }], - ['meta', { name: 'keywords', content: 'react, pwa, vue, preact, svelte, workbox, solidjs, vite, vite-plugin' }], + ['meta', { name: 'keywords', content: 'react, pwa, vue, vitepress, preact, svelte, sveltekit, workbox, solidjs, vite, vite-plugin' }], ['meta', { property: 'og:title', content: 'Vite Plugin PWA' }], ['meta', { property: 'og:description', content: 'Zero-config PWA Framework-agnostic Plugin for Vite' }], ['meta', { name: 'twitter:card', content: 'summary_large_image' }], @@ -252,4 +256,4 @@ const config = { }, } -module.exports = config +export default config diff --git a/docs/.vitepress/theme/components/ExamplesBehaviors.md b/docs/.vitepress/theme/components/ExamplesBehaviors.md new file mode 100644 index 00000000..ad847517 --- /dev/null +++ b/docs/.vitepress/theme/components/ExamplesBehaviors.md @@ -0,0 +1,17 @@ +- `Prompt for update`: + - Show `Ready to work offline` on first visit and once the `service worker` ready. + - Show `Prompt for update` when new `service worker` available. + +- `Auto update`: + - Show `Ready to work offline` on first visit and once the `service worker` ready. + - When new content available, the service worker will be updated automatically. + +- `Prompt for update` with `Periodic service worker updates`: + - Show `Ready to work offline` on first visit and once the `service worker` ready. + - Show `Prompt for update` when new `service worker` available. + - The example project will register a `Periodic service worker updates` + +- `Auto update` with `Periodic service worker updates`: + - Show `Ready to work offline` on first visit and once the `service worker` ready. + - The example project will register a `Periodic service worker updates` + - When new content available, the service worker will be updated automatically. diff --git a/docs/.vitepress/theme/components/ExamplesGenerateSW.md b/docs/.vitepress/theme/components/ExamplesGenerateSW.md new file mode 100644 index 00000000..1e5a3432 --- /dev/null +++ b/docs/.vitepress/theme/components/ExamplesGenerateSW.md @@ -0,0 +1,3 @@ +`generateSW` has the following behaviors: + + diff --git a/docs/.vitepress/theme/components/ExamplesInjectManifest.md b/docs/.vitepress/theme/components/ExamplesInjectManifest.md new file mode 100644 index 00000000..06becabc --- /dev/null +++ b/docs/.vitepress/theme/components/ExamplesInjectManifest.md @@ -0,0 +1,3 @@ +`injectManifest` has the following behavior: + + diff --git a/docs/.vitepress/theme/composables/navLink.ts b/docs/.vitepress/theme/composables/navLink.ts index 527c69d4..485c0c06 100644 --- a/docs/.vitepress/theme/composables/navLink.ts +++ b/docs/.vitepress/theme/composables/navLink.ts @@ -2,11 +2,9 @@ import { computed, Ref } from 'vue' import { useRoute, withBase } from 'vitepress' import type { DefaultTheme } from '../config' import { isExternal as isExternalCheck } from '../utils' -// import { useUrl } from './url' export function useNavLink(item: Ref) { const route = useRoute() - // const { withBase } = useUrl() const isExternal = isExternalCheck(item.value.link) @@ -24,6 +22,12 @@ export function useNavLink(item: Ref) { = itemPath === '/' ? itemPath === routePath : routePath.startsWith(itemPath) + // fix /frameworks/sveltekit and /frameworks/svelte + if (routePath === '/frameworks/sveltekit' && itemPath === '/frameworks/svelte' && active) + active = false + // fix /examples/sveltekit and /examples/svelte + if (routePath === '/examples/sveltekit' && itemPath === '/examples/svelte' && active) + active = false } return { diff --git a/docs/examples/index.md b/docs/examples/index.md index bc2fdfc9..15561f27 100644 --- a/docs/examples/index.md +++ b/docs/examples/index.md @@ -102,7 +102,7 @@ We provide the following example projects: - + @@ -117,7 +117,7 @@ We provide the following example projects: - + @@ -132,7 +132,22 @@ We provide the following example projects: - + + + + + + + + @@ -147,7 +162,7 @@ We provide the following example projects: - + @@ -162,7 +177,7 @@ We provide the following example projects: - + diff --git a/docs/examples/preact.md b/docs/examples/preact.md index 2015d6cb..63da6c54 100644 --- a/docs/examples/preact.md +++ b/docs/examples/preact.md @@ -8,7 +8,11 @@ The `Preact` example project can be found on `examples/preact-router` package/di The router used on this example project is [preact-router](https://github.com/preactjs/preact-router) . -The `Preact` example has been created using `create-vite` template with `PNPM`: +The `Preact` example has been created using `create-vite` template with `pnpx`: + +
+ pnpx create-vite + ```shell pnpx create-vite + create-vite 2.6.6 @@ -24,7 +28,7 @@ Done. Now run: npm install npm run dev ``` - +
To test `new content available`, you should rerun the corresponding script, and then refresh the page. @@ -37,31 +41,8 @@ If you are running an example with `Periodic SW updates`, you will need to wait ## generateSW -`generateSW` has the following behaviors: -- `Prompt for update`: - - Show `Ready to work offlline` on first visit and once the `service worker` ready. - - Show `Prompt for update` when new `service worker` available. - -- `Auto update`: - - Show `Ready to work offlline` on first visit and once the `service worker` ready. - - When new content available, the service worker will be updated automatically. - -- `Prompt for update` with `Periodic service worker updates`: - - Show `Ready to work offlline` on first visit and once the `service worker` ready. - - Show `Prompt for update` when new `service worker` available. - - The example project will register a `Periodic service worker updates` - -- `Auto update` with `Periodic service worker updates`: - - Show `Ready to work offlline` on first visit and once the `service worker` ready. - - The example project will register a `Periodic service worker updates` - - When new content available, the service worker will be updated automatically. + ## injectManifest -`injectManifest` has the following behavior: -- Custom `TypeScript Service Worker` with offline support. -- Show `Ready to work offlline` on first visit and once the `service worker` ready. -- Show `Prompt for update` when new `service worker` available. - - - + diff --git a/docs/examples/react.md b/docs/examples/react.md index 089048f3..c13c22d1 100644 --- a/docs/examples/react.md +++ b/docs/examples/react.md @@ -8,7 +8,11 @@ The `React` example project can be found on `examples/react-router` package/dire The router used on this example project is [react-router](https://reactrouter.com/) . -The `React` example has been created using `create-vite` template with `PNPM`: +The `React` example has been created using `create-vite` template with `pnpx`: + +
+ pnpx create-vite + ```shell pnpx create-vite + create-vite 2.5.4 @@ -24,6 +28,7 @@ Done. Now run: npm install npm run dev ``` +
To test `new content available`, you should rerun the corresponding script, and then refresh the page. @@ -36,28 +41,8 @@ If you are running an example with `Periodic SW updates`, you will need to wait ## generateSW -`generateSW` has the following behaviors: -- `Prompt for update`: - - Show `Ready to work offlline` on first visit and once the `service worker` ready. - - Show `Prompt for update` when new `service worker` available. - -- `Auto update`: - - Show `Ready to work offlline` on first visit and once the `service worker` ready. - - When new content available, the service worker will be updated automatically. - -- `Prompt for update` with `Periodic service worker updates`: - - Show `Ready to work offlline` on first visit and once the `service worker` ready. - - Show `Prompt for update` when new `service worker` available. - - The example project will register a `Periodic service worker updates` - -- `Auto update` with `Periodic service worker updates`: - - Show `Ready to work offlline` on first visit and once the `service worker` ready. - - The example project will register a `Periodic service worker updates` - - When new content available, the service worker will be updated automatically. + ## injectManifest -`injectManifest` has the following behavior: -- Custom `TypeScript Service Worker` with offline support. -- Show `Ready to work offlline` on first visit and once the `service worker` ready. -- Show `Prompt for update` when new `service worker` available. + diff --git a/docs/examples/solidjs.md b/docs/examples/solidjs.md index 34e3aaa1..30d989e7 100644 --- a/docs/examples/solidjs.md +++ b/docs/examples/solidjs.md @@ -8,11 +8,16 @@ The `SolidJS` example project can be found on `examples/solid-router` package/di The router used on this example project is [solid-app-router](https://github.com/solidjs/solid-app-router) . -The `SolidJS` example has been created using `https://github.com/solidjs/templates` template with `NPX`: +The `SolidJS` example has been created using `https://github.com/solidjs/templates` template with `npx`: + +
+ npx degit solidjs/templates/ts-router solid-router + ```shell npx degit solidjs/templates/ts-router solid-router > cloned solidjs/templates#HEAD to solid-router ``` +
To test `new content available`, you should rerun the corresponding script, and then refresh the page. @@ -25,28 +30,9 @@ If you are running an example with `Periodic SW updates`, you will need to wait ## generateSW -`generateSW` has the following behaviors: -- `Prompt for update`: - - Show `Ready to work offlline` on first visit and once the `service worker` ready. - - Show `Prompt for update` when new `service worker` available. - -- `Auto update`: - - Show `Ready to work offlline` on first visit and once the `service worker` ready. - - When new content available, the service worker will be updated automatically. - -- `Prompt for update` with `Periodic service worker updates`: - - Show `Ready to work offlline` on first visit and once the `service worker` ready. - - Show `Prompt for update` when new `service worker` available. - - The example project will register a `Periodic service worker updates` - -- `Auto update` with `Periodic service worker updates`: - - Show `Ready to work offlline` on first visit and once the `service worker` ready. - - The example project will register a `Periodic service worker updates` - - When new content available, the service worker will be updated automatically. + ## injectManifest -`injectManifest` has the following behavior: -- Custom `TypeScript Service Worker` with offline support. -- Show `Ready to work offlline` on first visit and once the `service worker` ready. -- Show `Prompt for update` when new `service worker` available. + + diff --git a/docs/examples/svelte.md b/docs/examples/svelte.md index 2600d9cd..d63b1a32 100644 --- a/docs/examples/svelte.md +++ b/docs/examples/svelte.md @@ -8,7 +8,11 @@ The `Svelte` example project can be found on `examples/react-routify` package/di The router used on this example project is [@roxi/routify](https://routify.dev/) . -The `Svelte` example has been created using `create-vite` template with `PNPM`: +The `Svelte` example has been created using `create-vite` template with `pnpx`: + +
+ pnpx create-vite + ```shell pnpx create-vite + create-vite 2.5.4 @@ -24,6 +28,7 @@ Done. Now run: npm install npm run dev ``` +
To test `new content available`, you should rerun the corresponding script, and then refresh the page. @@ -36,28 +41,9 @@ If you are running an example with `Periodic SW updates`, you will need to wait ## generateSW -`generateSW` has the following behaviors: -- `Prompt for update`: - - Show `Ready to work offlline` on first visit and once the `service worker` ready. - - Show `Prompt for update` when new `service worker` available. - -- `Auto update`: - - Show `Ready to work offlline` on first visit and once the `service worker` ready. - - When new content available, the service worker will be updated automatically. - -- `Prompt for update` with `Periodic service worker updates`: - - Show `Ready to work offlline` on first visit and once the `service worker` ready. - - Show `Prompt for update` when new `service worker` available. - - The example project will register a `Periodic service worker updates` - -- `Auto update` with `Periodic service worker updates`: - - Show `Ready to work offlline` on first visit and once the `service worker` ready. - - The example project will register a `Periodic service worker updates` - - When new content available, the service worker will be updated automatically. + ## injectManifest -`injectManifest` has the following behavior: -- Custom `TypeScript Service Worker` with offline support. -- Show `Ready to work offlline` on first visit and once the `service worker` ready. -- Show `Prompt for update` when new `service worker` available. + + diff --git a/docs/examples/sveltekit.md b/docs/examples/sveltekit.md new file mode 100644 index 00000000..688b8c2e --- /dev/null +++ b/docs/examples/sveltekit.md @@ -0,0 +1,67 @@ +--- +title: SvelteKit | Examples +--- + +# SvelteKit + +The `SvelteKit` example project can be found on `examples/sveltekit-pwa` package/directory and it is configured with `@sveltejs/adapter-static` adapter. + +The `SvelteKit` example has been created using `svelte@next` template with `pnpm`: + +
+ pnpm create svelte@next sveltekit-pwa + +```shell +pnpm create svelte@next sveltekit-pwa ++ create-svelte 2.0.0-next.89 + +Progress: resolved 5, reused 5, downloaded 0, added 5, done + +create-svelte version 2.0.0-next.89 + +Welcome to SvelteKit! + +This is beta software; expect bugs and missing features. + +Problems? Open an issue on https://github.com/sveltejs/kit/issues if none exists already. + +√ Which Svelte app template? » Skeleton project +√ Use TypeScript? ... No / Yes +√ Add ESLint for code linting? ... No / Yes +√ Add Prettier for code formatting? ... No / Yes + +Your project is ready! +✔ Typescript + Inside Svelte components, use + + + {#if (!dev && browser)} + + {/if} + + +
+ +
+ +{#if ReloadPrompt} + +{/if} +``` +
+ +## SvelteKit Adapters + +The main problem with the current implementation of the service worker module of `SvelteKit` is that you don't have access to the result applied by any adapter you have configured on your application. The service worker module of `SvelteKit` will be called before the adapter logic is applied, and so, inside the service worker module, you don't have access to those resources. Your application will not work when the user is offline, since the pages will not be included on the service worker precache manifest. + +When using `Vite PWA Plugin` with any `SvelteKit Adapter` you need to provide an additional script to rebuild your `pwa` once `SvelteKit` finish building your application, that is, when the adapter configured finish its job. + +The biggest difference between this plugin and the SvelteKit service worker module is that this plugin does not require integration into the application logic - just configuration. You can take a look at [SvelteKit example](https://github.com/antfu/vite-plugin-pwa/tree/main/examples/sveltekit-pwa) to configure the additional scripts on your application, it is quite complex since we use it for multiple behaviors with the same codebase. + +### Workbox manifestTransforms + +We must provide a list of URLs for the service worker to load and precache. We provide these to workbox using the [the `manifestTransforms` option](https://developers.google.com/web/tools/workbox/reference-docs/latest/module-workbox-build#.ManifestTransform) under `workbox` or [`injectManifest`](https://developers.google.com/web/tools/workbox/reference-docs/latest/module-workbox-build#.injectManifest). The [manifest entries](https://developers.google.com/web/tools/workbox/reference-docs/latest/module-workbox-build#.ManifestEntry) provided via this option will contain all the assets specified in the `srcDir` option. + +Since `SvelteKit` outputs an `.html` page for each pre-rendered page, you can use `manifestTransforms` to generate the URL from the prerendered HTML file path. For an example, see the `pwa-configuration.js` module in the next example using `@sveltejs/adapter-static`. + +Pages which are not prerendered or are generated with a unique adapter will need to be handled separately and the `manifestTransforms` logic will need to be modified accordingly. + +### Static Adapter example + +As an example, when using [@sveltejs/adapter-static](https://github.com/sveltejs/kit/tree/master/packages/adapter-static) with `generateSW` strategy and `Prompt for update` behavior, you will need: + +
+1) add pwa.js script + +```js +import { resolveConfig } from 'vite' +import { VitePWA } from 'vite-plugin-pwa'; +import { pwaConfiguration } from './pwa-configuration.js'; +import { copyFileSync } from 'fs'; + +const webmanifestDestinations = [ + './.svelte-kit/output/client/', + './build/', +] + +const swDestinations = [ + './build/', +] + +const buildPwa = async() => { + const config = await resolveConfig({ plugins: [VitePWA({ ...pwaConfiguration })] }, 'build', 'production' ) + // when `vite-plugin-pwa` is present, use it to regenerate SW after rendering + const pwaPlugin = config.plugins.find(i => i.name === 'vite-plugin-pwa')?.api + if (pwaPlugin?.generateSW) { + console.log('Generating PWA...') + await pwaPlugin.generateSW() + webmanifestDestinations.forEach(d => { + copyFileSync('./.svelte-kit/output/client/_app/manifest.webmanifest', `${d}/manifest.webmanifest`) + }) + // don't copy workbox, SvelteKit will copy it + swDestinations.forEach(d => { + copyFileSync('./.svelte-kit/output/client/sw.js', `${d}/sw.js`) + }) + console.log('Generation of PWA complete') + } +} + +buildPwa() +``` +
+ + +
+2) add pwa-configuration.js script + +```js +const pwaConfiguration = { + srcDir: './build', + outDir: './.svelte-kit/output/client', + includeManifestIcons: false, + base: '/', + scope: '/', + manifest: { + short_name: "", + name: "", + scope: "/", + start_url: "/", + display: "standalone", + theme_color: "#ffffff", + background_color: "#ffffff", + icons: [ + { + src: "/pwa-192x192.png", + sizes: "192x192", + type: "image/png" + }, + { + src: "/pwa-512x512.png", + "sizes": "512x512", + "type": "image/png" + }, + { + src: "/pwa-512x512.png", + "sizes": "512x512", + "type": "image/png", + purpose: 'any maskable' + } + ] + }, + workbox: { + // mode: 'development', + navigateFallback: '/', + // vite and SvelteKit are not aligned: pwa plugin will use /\.[a-f0-9]{8}\./ by default: #164 optimize workbox work + dontCacheBustURLsMatching: /-[a-f0-9]{8}\./, + globDirectory: './build/', + globPatterns: ['robots.txt', '**/*.{js,css,html,ico,png,svg,webmanifest}'], + globIgnores: ['**/sw*', '**/workbox-*'], + manifestTransforms: [async(entries) => { + // manifest.webmanifest is added always by pwa plugin, so we remove it. + // EXCLUDE from the sw precache sw and workbox-* + const manifest = entries.filter(({ url }) => + url !== 'manifest.webmanifest' && url !== 'sw.js' && !url.startsWith('workbox-') + ).map((e) => { + let url = e.url; + if (url && url.endsWith('.html')) { + if (url.startsWith('/')) { + url = url.slice(1) + } + if (url === 'index.html') { + e.url = url === 'index.html' ? '/' + } else if (url.endsWith('index.html')) { + e.url = `/${url.substring(0, url.lastIndexOf('/'))}` + } else if (url.endsWith('.html')) { + e.url = `/${url.substring(0, url.length - '.html'.length)}` + } + } + + return e + }); + + return { manifest }; + }] + } +}; + +export { pwaConfiguration }; +``` +
+ +
+3) modify your build script + +```json +"scripts": { + "build": "svelte-kit build && node ./pwa.js" +} +``` +
+ + +
+4) add Vite Plugin PWA to svelte.config.js + +```js +import adapter from '@sveltejs/adapter-static'; +import preprocess from 'svelte-preprocess'; +import { VitePWA } from 'vite-plugin-pwa'; +import { pwaConfiguration } from './pwa-configuration.js' + +/** @type {import('@sveltejs/kit').Config} */ +const config = { + // Consult https://github.com/sveltejs/svelte-preprocess + // for more information about preprocessors + preprocess: preprocess(), + + kit: { + adapter: adapter(), + + // hydrate the
element in src/app.html + target: '#svelte', + vite: { + plugins: [VitePWA(pwaConfiguration)] + } + } +}; + +export default config; +``` +
diff --git a/examples/preact-router/package.json b/examples/preact-router/package.json index 66c56a87..9a2bdf31 100644 --- a/examples/preact-router/package.json +++ b/examples/preact-router/package.json @@ -8,6 +8,9 @@ "start-claims": "npm run run-build-claims && npm run serve", "start-claims-reloadsw": "npm run run-build-reloadsw-claims && npm run serve", "start-sw": "npm run run-build-sw && npm run serve", + "start-sw-reloadsw": "npm run run-build-sw-reloadsw && npm run serve", + "start-sw-claims": "npm run run-build-sw-claims && npm run serve", + "start-sw-claims-reloadsw": "npm run run-build-sw-reloadsw-claims && npm run serve", "dev": "cross-env DEBUG=vite-plugin-pwa:* vite", "build": "rimraf dist && cross-env DEBUG=vite-plugin-pwa:* BASE_URL=/ SOURCE_MAP=true vite build", "run-build": "rimraf dist && cross-env DEBUG=vite-plugin-pwa:* BASE_URL=/ SOURCE_MAP=true vite build", @@ -15,6 +18,9 @@ "run-build-claims": "rimraf dist && cross-env DEBUG=vite-plugin-pwa:* BASE_URL=/ SOURCE_MAP=true CLAIMS=true vite build", "run-build-reloadsw-claims": "rimraf dist && cross-env DEBUG=vite-plugin-pwa:* BASE_URL=/ SOURCE_MAP=true CLAIMS=true RELOAD_SW=true vite build", "run-build-sw": "rimraf dist && cross-env DEBUG=vite-plugin-pwa:* BASE_URL=/ SOURCE_MAP=true SW=true vite build", + "run-build-sw-reloadsw": "cross-env DEBUG=vite-plugin-pwa:* BASE_URL=/ SOURCE_MAP=true RELOAD_SW=true SW=true vite build", + "run-build-sw-claims": "cross-env DEBUG=vite-plugin-pwa:* BASE_URL=/ SOURCE_MAP=true CLAIMS=true SW=true vite build", + "run-build-sw-reloadsw-claims": "cross-env DEBUG=vite-plugin-pwa:* BASE_URL=/ SOURCE_MAP=true CLAIMS=true RELOAD_SW=true SW=true vite build", "serve": "serve dist" }, "dependencies": { @@ -30,6 +36,7 @@ "typescript": "^4.4.4", "vite": "^2.6.14", "vite-plugin-pwa": "workspace:*", + "workbox-core": "^6.4.0", "workbox-precaching": "^6.4.0", "workbox-routing": "^6.4.0", "workbox-window": "^6.4.0" diff --git a/examples/preact-router/src/claims-sw.ts b/examples/preact-router/src/claims-sw.ts new file mode 100644 index 00000000..02152cad --- /dev/null +++ b/examples/preact-router/src/claims-sw.ts @@ -0,0 +1,17 @@ +import { precacheAndRoute, cleanupOutdatedCaches, createHandlerBoundToURL } from 'workbox-precaching' +import { clientsClaim } from 'workbox-core' +import { registerRoute, NavigationRoute } from 'workbox-routing' + +declare let self: ServiceWorkerGlobalScope + +// self.__WB_MANIFEST is default injection point +precacheAndRoute(self.__WB_MANIFEST) + +// clean old assets +cleanupOutdatedCaches() + +// to allow work offline +registerRoute(new NavigationRoute(createHandlerBoundToURL('index.html'))) + +self.skipWaiting() +clientsClaim() diff --git a/examples/preact-router/src/sw.ts b/examples/preact-router/src/prompt-sw.ts similarity index 100% rename from examples/preact-router/src/sw.ts rename to examples/preact-router/src/prompt-sw.ts diff --git a/examples/preact-router/vite.config.ts b/examples/preact-router/vite.config.ts index 47475b19..8b3dcbb6 100644 --- a/examples/preact-router/vite.config.ts +++ b/examples/preact-router/vite.config.ts @@ -33,22 +33,23 @@ const pwaOptions: Partial = { } const replaceOptions = { __DATE__: new Date().toISOString() } +const claims = process.env.CLAIMS === 'true' +const reload = process.env.RELOAD_SW === 'true' if (process.env.SW === 'true') { pwaOptions.srcDir = 'src' - pwaOptions.filename = 'sw.ts' + pwaOptions.filename = claims ? 'claims-sw.ts' : 'prompt-sw.ts' pwaOptions.strategies = 'injectManifest' ;(pwaOptions.manifest as Partial).name = 'PWA Inject Manifest' ;(pwaOptions.manifest as Partial).short_name = 'PWA Inject' } -else { - if (process.env.CLAIMS === 'true') - pwaOptions.registerType = 'autoUpdate' - if (process.env.RELOAD_SW === 'true') { - // @ts-ignore - replaceOptions.__RELOAD_SW__ = 'true' - } +if (claims) + pwaOptions.registerType = 'autoUpdate' + +if (reload) { + // @ts-ignore + replaceOptions.__RELOAD_SW__ = 'true' } // https://vitejs.dev/config/ diff --git a/examples/react-router/package.json b/examples/react-router/package.json index 79a574d4..a4f19821 100644 --- a/examples/react-router/package.json +++ b/examples/react-router/package.json @@ -8,6 +8,9 @@ "start-claims": "npm run run-build-claims && npm run serve", "start-claims-reloadsw": "npm run run-build-reloadsw-claims && npm run serve", "start-sw": "npm run run-build-sw && npm run serve", + "start-sw-reloadsw": "npm run run-build-sw-reloadsw && npm run serve", + "start-sw-claims": "npm run run-build-sw-claims && npm run serve", + "start-sw-claims-reloadsw": "npm run run-build-sw-reloadsw-claims && npm run serve", "dev": "cross-env DEBUG=vite-plugin-pwa:* vite", "build": "cross-env DEBUG=vite-plugin-pwa:* BASE_URL=/ SOURCE_MAP=true vite build", "run-build": "cross-env DEBUG=vite-plugin-pwa:* BASE_URL=/ SOURCE_MAP=true vite build", @@ -15,6 +18,9 @@ "run-build-claims": "cross-env DEBUG=vite-plugin-pwa:* BASE_URL=/ SOURCE_MAP=true CLAIMS=true vite build", "run-build-reloadsw-claims": "cross-env DEBUG=vite-plugin-pwa:* BASE_URL=/ SOURCE_MAP=true CLAIMS=true RELOAD_SW=true vite build", "run-build-sw": "rimraf dist && cross-env DEBUG=vite-plugin-pwa:* BASE_URL=/ SOURCE_MAP=true SW=true vite build", + "run-build-sw-reloadsw": "cross-env DEBUG=vite-plugin-pwa:* BASE_URL=/ SOURCE_MAP=true RELOAD_SW=true SW=true vite build", + "run-build-sw-claims": "cross-env DEBUG=vite-plugin-pwa:* BASE_URL=/ SOURCE_MAP=true CLAIMS=true SW=true vite build", + "run-build-sw-reloadsw-claims": "cross-env DEBUG=vite-plugin-pwa:* BASE_URL=/ SOURCE_MAP=true CLAIMS=true RELOAD_SW=true SW=true vite build", "serve": "serve dist" }, "dependencies": { @@ -37,6 +43,7 @@ "typescript": "^4.4.4", "vite": "^2.6.14", "vite-plugin-pwa": "workspace:*", + "workbox-core": "^6.4.0", "workbox-precaching": "^6.4.0", "workbox-routing": "^6.4.0", "workbox-window": "^6.4.0" diff --git a/examples/react-router/src/claims-sw.ts b/examples/react-router/src/claims-sw.ts new file mode 100644 index 00000000..02152cad --- /dev/null +++ b/examples/react-router/src/claims-sw.ts @@ -0,0 +1,17 @@ +import { precacheAndRoute, cleanupOutdatedCaches, createHandlerBoundToURL } from 'workbox-precaching' +import { clientsClaim } from 'workbox-core' +import { registerRoute, NavigationRoute } from 'workbox-routing' + +declare let self: ServiceWorkerGlobalScope + +// self.__WB_MANIFEST is default injection point +precacheAndRoute(self.__WB_MANIFEST) + +// clean old assets +cleanupOutdatedCaches() + +// to allow work offline +registerRoute(new NavigationRoute(createHandlerBoundToURL('index.html'))) + +self.skipWaiting() +clientsClaim() diff --git a/examples/react-router/src/sw.ts b/examples/react-router/src/prompt-sw.ts similarity index 100% rename from examples/react-router/src/sw.ts rename to examples/react-router/src/prompt-sw.ts diff --git a/examples/react-router/vite.config.ts b/examples/react-router/vite.config.ts index fbd77f92..30a8bf94 100644 --- a/examples/react-router/vite.config.ts +++ b/examples/react-router/vite.config.ts @@ -33,22 +33,23 @@ const pwaOptions: Partial = { } const replaceOptions = { __DATE__: new Date().toISOString() } +const claims = process.env.CLAIMS === 'true' +const reload = process.env.RELOAD_SW === 'true' if (process.env.SW === 'true') { pwaOptions.srcDir = 'src' - pwaOptions.filename = 'sw.ts' + pwaOptions.filename = claims ? 'claims-sw.ts' : 'prompt-sw.ts' pwaOptions.strategies = 'injectManifest' ;(pwaOptions.manifest as Partial).name = 'PWA Inject Manifest' ;(pwaOptions.manifest as Partial).short_name = 'PWA Inject' } -else { - if (process.env.CLAIMS === 'true') - pwaOptions.registerType = 'autoUpdate' - if (process.env.RELOAD_SW === 'true') { - // @ts-ignore - replaceOptions.__RELOAD_SW__ = 'true' - } +if (claims) + pwaOptions.registerType = 'autoUpdate' + +if (reload) { + // @ts-ignore + replaceOptions.__RELOAD_SW__ = 'true' } export default defineConfig({ diff --git a/examples/solid-router/package.json b/examples/solid-router/package.json index af46b0eb..b3c622c5 100644 --- a/examples/solid-router/package.json +++ b/examples/solid-router/package.json @@ -8,6 +8,9 @@ "start-claims": "npm run run-build-claims && npm run serve", "start-claims-reloadsw": "npm run run-build-reloadsw-claims && npm run serve", "start-sw": "npm run run-build-sw && npm run serve", + "start-sw-reloadsw": "npm run run-build-sw-reloadsw && npm run serve", + "start-sw-claims": "npm run run-build-sw-claims && npm run serve", + "start-sw-claims-reloadsw": "npm run run-build-sw-reloadsw-claims && npm run serve", "dev": "cross-env DEBUG=vite-plugin-pwa:* vite", "build": "rimraf dist && cross-env DEBUG=vite-plugin-pwa:* BASE_URL=/ SOURCE_MAP=true vite build", "run-build": "rimraf dist && cross-env DEBUG=vite-plugin-pwa:* BASE_URL=/ SOURCE_MAP=true vite build", @@ -15,6 +18,9 @@ "run-build-claims": "rimraf dist && cross-env DEBUG=vite-plugin-pwa:* BASE_URL=/ SOURCE_MAP=true CLAIMS=true vite build", "run-build-reloadsw-claims": "rimraf dist && cross-env DEBUG=vite-plugin-pwa:* BASE_URL=/ SOURCE_MAP=true CLAIMS=true RELOAD_SW=true vite build", "run-build-sw": "rimraf dist && cross-env DEBUG=vite-plugin-pwa:* BASE_URL=/ SOURCE_MAP=true SW=true vite build", + "run-build-sw-reloadsw": "cross-env DEBUG=vite-plugin-pwa:* BASE_URL=/ SOURCE_MAP=true RELOAD_SW=true SW=true vite build", + "run-build-sw-claims": "cross-env DEBUG=vite-plugin-pwa:* BASE_URL=/ SOURCE_MAP=true CLAIMS=true vite SW=true build", + "run-build-sw-reloadsw-claims": "cross-env DEBUG=vite-plugin-pwa:* BASE_URL=/ SOURCE_MAP=true CLAIMS=true RELOAD_SW=true SW=true vite build", "serve": "serve dist" }, "devDependencies": { @@ -26,6 +32,7 @@ "vite": "^2.6.14", "vite-plugin-pwa": "workspace:*", "vite-plugin-solid": "^2.1.2", + "workbox-core": "^6.4.0", "workbox-precaching": "^6.4.0", "workbox-routing": "^6.4.0", "workbox-window": "^6.4.0" diff --git a/examples/solid-router/src/ReloadPrompt.tsx b/examples/solid-router/src/ReloadPrompt.tsx index 4dfbfc01..957ccd81 100644 --- a/examples/solid-router/src/ReloadPrompt.tsx +++ b/examples/solid-router/src/ReloadPrompt.tsx @@ -40,18 +40,18 @@ const ReloadPrompt: Component = () => {
-
- New content available, click on reload button to update.} - when={offlineReady()} - > - App ready to work offline - -
- - - - +
+ New content available, click on reload button to update.} + when={offlineReady()} + > + App ready to work offline + +
+ + + +
diff --git a/examples/solid-router/src/claims-sw.ts b/examples/solid-router/src/claims-sw.ts new file mode 100644 index 00000000..02152cad --- /dev/null +++ b/examples/solid-router/src/claims-sw.ts @@ -0,0 +1,17 @@ +import { precacheAndRoute, cleanupOutdatedCaches, createHandlerBoundToURL } from 'workbox-precaching' +import { clientsClaim } from 'workbox-core' +import { registerRoute, NavigationRoute } from 'workbox-routing' + +declare let self: ServiceWorkerGlobalScope + +// self.__WB_MANIFEST is default injection point +precacheAndRoute(self.__WB_MANIFEST) + +// clean old assets +cleanupOutdatedCaches() + +// to allow work offline +registerRoute(new NavigationRoute(createHandlerBoundToURL('index.html'))) + +self.skipWaiting() +clientsClaim() diff --git a/examples/solid-router/src/sw.ts b/examples/solid-router/src/prompt-sw.ts similarity index 100% rename from examples/solid-router/src/sw.ts rename to examples/solid-router/src/prompt-sw.ts diff --git a/examples/solid-router/vite.config.ts b/examples/solid-router/vite.config.ts index 22055b3c..728d1cee 100644 --- a/examples/solid-router/vite.config.ts +++ b/examples/solid-router/vite.config.ts @@ -33,22 +33,23 @@ const pwaOptions: Partial = { } const replaceOptions = { __DATE__: new Date().toISOString() } +const claims = process.env.CLAIMS === 'true' +const reload = process.env.RELOAD_SW === 'true' if (process.env.SW === 'true') { pwaOptions.srcDir = 'src' - pwaOptions.filename = 'sw.ts' + pwaOptions.filename = claims ? 'claims-sw.ts' : 'prompt-sw.ts' pwaOptions.strategies = 'injectManifest' ;(pwaOptions.manifest as Partial).name = 'PWA Inject Manifest' ;(pwaOptions.manifest as Partial).short_name = 'PWA Inject' } -else { - if (process.env.CLAIMS === 'true') - pwaOptions.registerType = 'autoUpdate' - if (process.env.RELOAD_SW === 'true') { - // @ts-ignore - replaceOptions.__RELOAD_SW__ = 'true' - } +if (claims) + pwaOptions.registerType = 'autoUpdate' + +if (reload) { + // @ts-ignore + replaceOptions.__RELOAD_SW__ = 'true' } export default defineConfig({ diff --git a/examples/svelte-routify/package.json b/examples/svelte-routify/package.json index a685f066..cb7e5b98 100644 --- a/examples/svelte-routify/package.json +++ b/examples/svelte-routify/package.json @@ -9,6 +9,9 @@ "start-claims": "npm run run-build-claims && npm run serve", "start-claims-reloadsw": "npm run run-build-reloadsw-claims && npm run serve", "start-sw": "npm run run-build-sw && npm run serve", + "start-sw-reloadsw": "npm run run-build-sw-reloadsw && npm run serve", + "start-sw-claims": "npm run run-build-sw-claims && npm run serve", + "start-sw-claims-reloadsw": "npm run run-build-sw-reloadsw-claims && npm run serve", "dev": "cross-env DEBUG=vite-plugin-pwa:* vite", "build": "routify -b && cross-env DEBUG=vite-plugin-pwa:* BASE_URL=/ SOURCE_MAP=true vite build", "run-build": "routify -b && cross-env DEBUG=vite-plugin-pwa:* BASE_URL=/ SOURCE_MAP=true vite build", @@ -16,6 +19,9 @@ "run-build-claims": "routify -b && cross-env DEBUG=vite-plugin-pwa:* BASE_URL=/ SOURCE_MAP=true CLAIMS=true vite build", "run-build-reloadsw-claims": "routify -b && cross-env DEBUG=vite-plugin-pwa:* BASE_URL=/ SOURCE_MAP=true CLAIMS=true RELOAD_SW=true vite build", "run-build-sw": "rimraf dist && cross-env DEBUG=vite-plugin-pwa:* BASE_URL=/ SOURCE_MAP=true SW=true vite build", + "run-build-sw-reloadsw": "cross-env DEBUG=vite-plugin-pwa:* BASE_URL=/ SOURCE_MAP=true RELOAD_SW=true vite build", + "run-build-sw-claims": "cross-env DEBUG=vite-plugin-pwa:* BASE_URL=/ SOURCE_MAP=true CLAIMS=true SW=true vite build", + "run-build-sw-reloadsw-claims": "cross-env DEBUG=vite-plugin-pwa:* BASE_URL=/ SOURCE_MAP=true CLAIMS=true RELOAD_SW=true SW=true vite build", "serve": "serve dist" }, "devDependencies": { @@ -33,6 +39,7 @@ "svelte-preprocess": "^4.9.8", "typescript": "^4.4.4", "vite": "^2.6.14", + "workbox-core": "^6.4.0", "workbox-precaching": "^6.4.0", "workbox-routing": "^6.4.0", "vite-plugin-pwa": "workspace:*" diff --git a/examples/svelte-routify/src/claims-sw.ts b/examples/svelte-routify/src/claims-sw.ts new file mode 100644 index 00000000..02152cad --- /dev/null +++ b/examples/svelte-routify/src/claims-sw.ts @@ -0,0 +1,17 @@ +import { precacheAndRoute, cleanupOutdatedCaches, createHandlerBoundToURL } from 'workbox-precaching' +import { clientsClaim } from 'workbox-core' +import { registerRoute, NavigationRoute } from 'workbox-routing' + +declare let self: ServiceWorkerGlobalScope + +// self.__WB_MANIFEST is default injection point +precacheAndRoute(self.__WB_MANIFEST) + +// clean old assets +cleanupOutdatedCaches() + +// to allow work offline +registerRoute(new NavigationRoute(createHandlerBoundToURL('index.html'))) + +self.skipWaiting() +clientsClaim() diff --git a/examples/svelte-routify/src/lib/ReloadPrompt.svelte b/examples/svelte-routify/src/lib/ReloadPrompt.svelte index efdb408b..55777b35 100644 --- a/examples/svelte-routify/src/lib/ReloadPrompt.svelte +++ b/examples/svelte-routify/src/lib/ReloadPrompt.svelte @@ -65,30 +65,30 @@
{buildDate}
diff --git a/examples/svelte-routify/src/sw.ts b/examples/svelte-routify/src/prompt-sw.ts similarity index 100% rename from examples/svelte-routify/src/sw.ts rename to examples/svelte-routify/src/prompt-sw.ts diff --git a/examples/svelte-routify/vite.config.js b/examples/svelte-routify/vite.config.js index 5c5477bd..0be8cc68 100644 --- a/examples/svelte-routify/vite.config.js +++ b/examples/svelte-routify/vite.config.js @@ -33,22 +33,23 @@ const pwaOptions = { } const replaceOptions = { __DATE__: new Date().toISOString() } +const claims = process.env.CLAIMS === 'true' +const reload = process.env.RELOAD_SW === 'true' if (process.env.SW === 'true') { pwaOptions.srcDir = 'src' - pwaOptions.filename = 'sw.ts' + pwaOptions.filename = claims ? 'claims-sw.ts' : 'prompt-sw.ts' pwaOptions.strategies = 'injectManifest' pwaOptions.manifest.name = 'PWA Inject Manifest' pwaOptions.manifest.short_name = 'PWA Inject' } -else { - if (process.env.CLAIMS === 'true') - pwaOptions.registerType = 'autoUpdate' - if (process.env.RELOAD_SW === 'true') { - // @ts-ignore - replaceOptions.__RELOAD_SW__ = 'true' - } +if (claims) + pwaOptions.registerType = 'autoUpdate' + +if (reload) { + // @ts-ignore + replaceOptions.__RELOAD_SW__ = 'true' } export default defineConfig({ diff --git a/examples/sveltekit-pwa/.eslintrc.cjs b/examples/sveltekit-pwa/.eslintrc.cjs new file mode 100644 index 00000000..6ad4bdd7 --- /dev/null +++ b/examples/sveltekit-pwa/.eslintrc.cjs @@ -0,0 +1,20 @@ +module.exports = { + root: true, + parser: '@typescript-eslint/parser', + extends: ['eslint:recommended', 'plugin:@typescript-eslint/recommended'], + plugins: ['svelte3', '@typescript-eslint'], + ignorePatterns: ['*.cjs'], + overrides: [{ files: ['*.svelte'], processor: 'svelte3/svelte3' }], + settings: { + 'svelte3/typescript': () => require('typescript') + }, + parserOptions: { + sourceType: 'module', + ecmaVersion: 2019 + }, + env: { + browser: true, + es2017: true, + node: true + } +}; diff --git a/examples/sveltekit-pwa/.gitignore b/examples/sveltekit-pwa/.gitignore new file mode 100644 index 00000000..bbde1f50 --- /dev/null +++ b/examples/sveltekit-pwa/.gitignore @@ -0,0 +1,7 @@ +.DS_Store +node_modules +/build +/.svelte-kit +/package +.env +.env.* diff --git a/examples/sveltekit-pwa/README.md b/examples/sveltekit-pwa/README.md new file mode 100644 index 00000000..82510ca0 --- /dev/null +++ b/examples/sveltekit-pwa/README.md @@ -0,0 +1,38 @@ +# create-svelte + +Everything you need to build a Svelte project, powered by [`create-svelte`](https://github.com/sveltejs/kit/tree/master/packages/create-svelte); + +## Creating a project + +If you're seeing this, you've probably already done this step. Congrats! + +```bash +# create a new project in the current directory +npm init svelte@next + +# create a new project in my-app +npm init svelte@next my-app +``` + +> Note: the `@next` is temporary + +## Developing + +Once you've created a project and installed dependencies with `npm install` (or `pnpm install` or `yarn`), start a development server: + +```bash +npm run dev + +# or start the server and open the app in a new browser tab +npm run dev -- --open +``` + +## Building + +Before creating a production version of your app, install an [adapter](https://kit.svelte.dev/docs#adapters) for your target environment. Then: + +```bash +npm run build +``` + +> You can preview the built app with `npm run preview`, regardless of whether you installed an adapter. This should _not_ be used to serve your app in production. diff --git a/examples/sveltekit-pwa/package.json b/examples/sveltekit-pwa/package.json new file mode 100644 index 00000000..ace54907 --- /dev/null +++ b/examples/sveltekit-pwa/package.json @@ -0,0 +1,53 @@ +{ + "name": "example-sveltekit-pwa", + "version": "0.0.0", + "private": true, + "scripts": { + "dev": "svelte-kit dev", + "build": "svelte-kit build", + "package": "svelte-kit package", + "preview": "svelte-kit preview", + "check": "svelte-check --tsconfig ./tsconfig.json", + "check:watch": "svelte-check --tsconfig ./tsconfig.json --watch", + "lint": "eslint --ignore-path .gitignore .", + "start": "npm run run-build && npm run preview", + "start-reloadsw": "npm run run-build-reloadsw && npm run preview", + "start-claims": "npm run run-build-claims && npm run preview", + "start-claims-reloadsw": "npm run run-build-reloadsw-claims && npm run preview", + "start-sw": "npm run run-build-sw && npm run preview", + "start-sw-reloadsw": "npm run run-build-sw-reloadsw && npm run preview", + "start-sw-claims": "npm run run-build-sw-claims && npm run preview", + "start-sw-claims-reloadsw": "npm run run-build-sw-reloadsw-claims && npm run preview", + "run-build": "rimraf .svelte-kit && rimraf build && cross-env DEBUG=vite-plugin-pwa:* BASE_URL=/ SOURCE_MAP=true svelte-kit build && node ./pwa.js --BASE_URL=/ --SOURCE_MAP=true", + "run-build-reloadsw": "rimraf .svelte-kit && rimraf build && cross-env DEBUG=vite-plugin-pwa:* BASE_URL=/ SOURCE_MAP=true RELOAD_SW=true svelte-kit build && node ./pwa.js --BASE_URL=/ --SOURCE_MAP=true --RELOAD_SW=true", + "run-build-claims": "rimraf .svelte-kit && rimraf build && cross-env DEBUG=vite-plugin-pwa:* BASE_URL=/ SOURCE_MAP=true CLAIMS=true svelte-kit build && node ./pwa.js --BASE_URL=/ --SOURCE_MAP=true --CLAIMS=true", + "run-build-reloadsw-claims": "routify -b && cross-env DEBUG=vite-plugin-pwa:* BASE_URL=/ SOURCE_MAP=true CLAIMS=true RELOAD_SW=true svelte-kit build && node ./pwa.js --BASE_URL=/ --SOURCE_MAP=true --CLAIMS=true --RELOAD_SW=true", + "run-build-sw": "rimraf .svelte-kit && rimraf build && cross-env DEBUG=vite-plugin-pwa:* BASE_URL=/ SOURCE_MAP=true SW=true svelte-kit build && node ./pwa.js --BASE_URL=/ --SOURCE_MAP=true --SW=true", + "run-build-sw-reloadsw": "rimraf .svelte-kit && rimraf build && cross-env DEBUG=vite-plugin-pwa:* BASE_URL=/ SOURCE_MAP=true RELOAD_SW=true SW=true svelte-kit build && node ./pwa.js --BASE_URL=/ --SOURCE_MAP=true --RELOAD_SW=true --SW=true", + "run-build-sw-claims": "rimraf .svelte-kit && rimraf build && cross-env DEBUG=vite-plugin-pwa:* BASE_URL=/ SOURCE_MAP=true CLAIMS=true SW=true svelte-kit build && node ./pwa.js --BASE_URL=/ --SOURCE_MAP=true --CLAIMS=true --SW=true", + "run-build-sw-reloadsw-claims": "rimraf .svelte-kit && rimraf build && cross-env DEBUG=vite-plugin-pwa:* BASE_URL=/ SOURCE_MAP=true CLAIMS=true RELOAD_SW=true SW=true svelte-kit build && node ./pwa.js --BASE_URL=/ --SOURCE_MAP=true --CLAIMS=true --RELOAD_SW=true --SW=true" + }, + "devDependencies": { + "@rollup/plugin-replace": "^3.0.0", + "@sveltejs/adapter-static": "next", + "@sveltejs/kit": "next", + "@typescript-eslint/eslint-plugin": "^4.31.1", + "@typescript-eslint/parser": "^4.31.1", + "cross-env": "^7.0.3", + "eslint": "^7.32.0", + "eslint-plugin-svelte3": "^3.2.1", + "https-localhost": "^4.7.0", + "minimist": "^1.2.5", + "rimraf": "^3.0.2", + "svelte": "^3.44.1", + "svelte-check": "^2.2.8", + "svelte-preprocess": "^4.9.8", + "tslib": "^2.3.1", + "typescript": "^4.4.4", + "workbox-core": "^6.4.0", + "workbox-precaching": "^6.4.0", + "workbox-routing": "^6.4.0", + "vite-plugin-pwa": "workspace:*" + }, + "type": "module" +} diff --git a/examples/sveltekit-pwa/pwa-configuration.js b/examples/sveltekit-pwa/pwa-configuration.js new file mode 100644 index 00000000..f150c260 --- /dev/null +++ b/examples/sveltekit-pwa/pwa-configuration.js @@ -0,0 +1,89 @@ +const pwaConfiguration = { + srcDir: './build', + outDir: './.svelte-kit/output/client', + mode: 'development', + includeManifestIcons: false, + scope: '/', + base: '/', + manifest: { + short_name: "PWA Router", + name: "PWA Router", + start_url: "/", + scope: "/", + display: "standalone", + theme_color: "#ffffff", + background_color: "#ffffff", + icons: [ + { + src: '/pwa-192x192.png', + sizes: '192x192', + type: 'image/png', + }, + { + src: '/pwa-512x512.png', + sizes: '512x512', + type: 'image/png', + }, + { + src: '/pwa-512x512.png', + sizes: '512x512', + type: 'image/png', + purpose: 'any maskable', + }, + ] + }, +} + +const claims = process.env.CLAIMS === 'true' +const reload = process.env.RELOAD_SW === 'true' +const sw = process.env.SW === 'true' +const replaceOptions = { + __DATE__: new Date().toISOString(), + __RELOAD_SW__: reload ? 'true' : 'false', +} + +const workboxOrInjectManifestEntry = { + // vite and SvelteKit are not aligned: pwa plugin will use /\.[a-f0-9]{8}\./ by default: #164 optimize workbox work + dontCacheBustURLsMatching: /-[a-f0-9]{8}\./, + globDirectory: './build/', + globPatterns: ['**/*.{js,css,html,ico,png,svg,webmanifest}'], + globIgnores: sw ? (claims ? ['**/claims-sw*'] : ['**/prompt-sw*']) : ['**/sw*', '**/workbox-*'], + // Before generating the service worker, manifestTransforms entry will allow us to transform the resulting precache manifest. See the manifestTransforms docs for mode details. + manifestTransforms: [async(entries) => { + // manifest.webmanifest is added always by pwa plugin, so we remove it. + // EXCLUDE from the sw precache sw and workbox-* + const manifest = entries.filter(({ url }) => + url !== 'manifest.webmanifest' && !url.endsWith('sw.js') && !url.startsWith('workbox-') + ).map((e) => { + let url = e.url + if (url && url.endsWith('.html')) { + if (url.startsWith('/')) + url = url.slice(1) + + e.url = url === 'index.html' ? '/' : `/${url.substring(0, url.lastIndexOf('/'))}` + console.log(`${url} => ${e.url}`) + } + + return e + }) + return { manifest } + }] +} + +if (sw) { + pwaConfiguration.srcDir = 'src' + pwaConfiguration.filename = claims ? 'claims-sw.ts' : 'prompt-sw.ts' + pwaConfiguration.strategies = 'injectManifest' + pwaConfiguration.manifest.name = 'PWA Inject Manifest' + pwaConfiguration.manifest.short_name = 'PWA Inject' + pwaConfiguration.injectManifest = workboxOrInjectManifestEntry +} else { + workboxOrInjectManifestEntry.mode = 'development' + workboxOrInjectManifestEntry.navigateFallback = '/' + pwaConfiguration.workbox = workboxOrInjectManifestEntry +} + +if (claims) + pwaConfiguration.registerType = 'autoUpdate' + +export { pwaConfiguration, replaceOptions } diff --git a/examples/sveltekit-pwa/pwa.js b/examples/sveltekit-pwa/pwa.js new file mode 100644 index 00000000..ff4b347c --- /dev/null +++ b/examples/sveltekit-pwa/pwa.js @@ -0,0 +1,57 @@ +import { resolveConfig } from 'vite' +import replace from '@rollup/plugin-replace' +import { VitePWA } from 'vite-plugin-pwa' +import { copyFileSync } from 'fs' +import minimist from 'minimist' + +const args = minimist(process.argv.slice(2)) + +process.env.CLAIMS = `${args['CLAIMS'] === 'true'}` +process.env.RELOAD_SW = `${args['RELOAD_SW'] === 'true'}` +process.env.SW = `${args['SW'] === 'true'}` + +const webmanifestDestinations = [ + './.svelte-kit/output/client/', + './build/', +] + +const swDestinations = [ + './build/', +] + +const buildPwa = async() => { + const { pwaConfiguration, replaceOptions } = await import('./pwa-configuration.js') + const config = await resolveConfig({ + plugins: [ + VitePWA(pwaConfiguration), + replace(replaceOptions), + ] + }, + 'build', + 'production' + ) + // when `vite-plugin-pwa` is presented, use it to regenerate SW after rendering + const pwaPlugin = config.plugins.find(i => i.name === 'vite-plugin-pwa')?.api + if (pwaPlugin?.generateSW) { + console.log('Generating PWA...') + await pwaPlugin.generateSW() + webmanifestDestinations.forEach(d => { + copyFileSync('./.svelte-kit/output/client/_app/manifest.webmanifest', `${d}/manifest.webmanifest`) + }) + // don't copy workbox, svelte kit will copy it + if (pwaConfiguration.strategies === 'injectManifest') { + const destName = pwaConfiguration.registerType === 'autoUpdate' ? 'claims-sw.js' : 'prompt-sw.js' + const name = `./.svelte-kit/output/client/${destName}` + swDestinations.forEach(d => { + copyFileSync(name, `${d}/${destName}`) + }) + } else { + swDestinations.forEach(d => { + copyFileSync('./.svelte-kit/output/client/sw.js', `${d}/sw.js`) + }) + } + console.log('Generation of PWA complete') + } +} + +buildPwa() diff --git a/examples/sveltekit-pwa/src/app.html b/examples/sveltekit-pwa/src/app.html new file mode 100644 index 00000000..2238847d --- /dev/null +++ b/examples/sveltekit-pwa/src/app.html @@ -0,0 +1,16 @@ + + + + + + + + + + + %svelte.head% + + +
%svelte.body%
+ + diff --git a/examples/sveltekit-pwa/src/claims-sw.ts b/examples/sveltekit-pwa/src/claims-sw.ts new file mode 100644 index 00000000..65d55450 --- /dev/null +++ b/examples/sveltekit-pwa/src/claims-sw.ts @@ -0,0 +1,17 @@ +import { precacheAndRoute, cleanupOutdatedCaches, createHandlerBoundToURL } from 'workbox-precaching' +import { clientsClaim } from 'workbox-core' +import { registerRoute, NavigationRoute } from 'workbox-routing' + +declare let self: ServiceWorkerGlobalScope + +// self.__WB_MANIFEST is default injection point +precacheAndRoute(self.__WB_MANIFEST) + +// clean old assets +cleanupOutdatedCaches() + +// to allow work offline +registerRoute(new NavigationRoute(createHandlerBoundToURL('/'))) + +self.skipWaiting() +clientsClaim() diff --git a/examples/sveltekit-pwa/src/global.d.ts b/examples/sveltekit-pwa/src/global.d.ts new file mode 100644 index 00000000..815c61ad --- /dev/null +++ b/examples/sveltekit-pwa/src/global.d.ts @@ -0,0 +1,4 @@ +/// +/// +/// +/// diff --git a/examples/sveltekit-pwa/src/lib/components/Counter.svelte b/examples/sveltekit-pwa/src/lib/components/Counter.svelte new file mode 100644 index 00000000..e3cefc5f --- /dev/null +++ b/examples/sveltekit-pwa/src/lib/components/Counter.svelte @@ -0,0 +1,34 @@ + + + + + diff --git a/examples/sveltekit-pwa/src/lib/components/Go.svelte b/examples/sveltekit-pwa/src/lib/components/Go.svelte new file mode 100644 index 00000000..ce98478b --- /dev/null +++ b/examples/sveltekit-pwa/src/lib/components/Go.svelte @@ -0,0 +1,52 @@ + + +
+ + +
+ + diff --git a/examples/sveltekit-pwa/src/lib/components/ReloadPrompt.svelte b/examples/sveltekit-pwa/src/lib/components/ReloadPrompt.svelte new file mode 100644 index 00000000..6c907074 --- /dev/null +++ b/examples/sveltekit-pwa/src/lib/components/ReloadPrompt.svelte @@ -0,0 +1,87 @@ + + +{#if toast} + +{/if} + +
{buildDate}
+ + diff --git a/examples/sveltekit-pwa/src/prompt-sw.ts b/examples/sveltekit-pwa/src/prompt-sw.ts new file mode 100644 index 00000000..39a74fcf --- /dev/null +++ b/examples/sveltekit-pwa/src/prompt-sw.ts @@ -0,0 +1,18 @@ +import { precacheAndRoute, cleanupOutdatedCaches, createHandlerBoundToURL } from 'workbox-precaching' +import { registerRoute, NavigationRoute } from 'workbox-routing' + +declare let self: ServiceWorkerGlobalScope + +self.addEventListener('message', (event) => { + if (event.data && event.data.type === 'SKIP_WAITING') + self.skipWaiting() +}) + +// self.__WB_MANIFEST is default injection point +precacheAndRoute(self.__WB_MANIFEST) + +// clean old assets +cleanupOutdatedCaches() + +// to allow work offline +registerRoute(new NavigationRoute(createHandlerBoundToURL('/'))) diff --git a/examples/sveltekit-pwa/src/routes/__layout.svelte b/examples/sveltekit-pwa/src/routes/__layout.svelte new file mode 100644 index 00000000..f5391c6d --- /dev/null +++ b/examples/sveltekit-pwa/src/routes/__layout.svelte @@ -0,0 +1,58 @@ + + + + {#if (!dev && browser)} + + {/if} + + +
+ PWA Logo +

SvelteKit PWA!

+ +
Built at: { date }
+ + + +
+ +{#if ReloadPrompt} + +{/if} + + diff --git a/examples/sveltekit-pwa/src/routes/about.svelte b/examples/sveltekit-pwa/src/routes/about.svelte new file mode 100644 index 00000000..74dc1e48 --- /dev/null +++ b/examples/sveltekit-pwa/src/routes/about.svelte @@ -0,0 +1,8 @@ + + +
/about route, built at: { date }
+
+Go Home diff --git a/examples/sveltekit-pwa/src/routes/hi/[name].svelte b/examples/sveltekit-pwa/src/routes/hi/[name].svelte new file mode 100644 index 00000000..27d68fb7 --- /dev/null +++ b/examples/sveltekit-pwa/src/routes/hi/[name].svelte @@ -0,0 +1,16 @@ + + +
/hi route, built at: { date }
+ +

+ Hi: { name } +

+
+Go Home diff --git a/examples/sveltekit-pwa/src/routes/index.svelte b/examples/sveltekit-pwa/src/routes/index.svelte new file mode 100644 index 00000000..30be4ee0 --- /dev/null +++ b/examples/sveltekit-pwa/src/routes/index.svelte @@ -0,0 +1,10 @@ + + +
+ +
+ +About
diff --git a/examples/sveltekit-pwa/static/favicon.svg b/examples/sveltekit-pwa/static/favicon.svg new file mode 100644 index 00000000..733f4fb4 --- /dev/null +++ b/examples/sveltekit-pwa/static/favicon.svg @@ -0,0 +1,130 @@ + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/examples/sveltekit-pwa/static/pwa-192x192.png b/examples/sveltekit-pwa/static/pwa-192x192.png new file mode 100644 index 00000000..cd3ee45e Binary files /dev/null and b/examples/sveltekit-pwa/static/pwa-192x192.png differ diff --git a/examples/sveltekit-pwa/static/pwa-512x512.png b/examples/sveltekit-pwa/static/pwa-512x512.png new file mode 100644 index 00000000..200cb73a Binary files /dev/null and b/examples/sveltekit-pwa/static/pwa-512x512.png differ diff --git a/examples/sveltekit-pwa/svelte.config.js b/examples/sveltekit-pwa/svelte.config.js new file mode 100644 index 00000000..f1d1aa37 --- /dev/null +++ b/examples/sveltekit-pwa/svelte.config.js @@ -0,0 +1,27 @@ +import adapter from '@sveltejs/adapter-static'; +import preprocess from 'svelte-preprocess'; +import { VitePWA } from 'vite-plugin-pwa'; +import replace from '@rollup/plugin-replace' +import { pwaConfiguration, replaceOptions } from './pwa-configuration.js' + +/** @type {import('@sveltejs/kit').Config} */ +const config = { + // Consult https://github.com/sveltejs/svelte-preprocess + // for more information about preprocessors + preprocess: preprocess(), + + kit: { + adapter: adapter(), + + // hydrate the
element in src/app.html + target: '#svelte', + vite: { + plugins: [ + VitePWA(pwaConfiguration), + replace(replaceOptions) + ] + } + } +}; + +export default config; diff --git a/examples/sveltekit-pwa/tsconfig.json b/examples/sveltekit-pwa/tsconfig.json new file mode 100644 index 00000000..4b9c71f8 --- /dev/null +++ b/examples/sveltekit-pwa/tsconfig.json @@ -0,0 +1,31 @@ +{ + "compilerOptions": { + "moduleResolution": "node", + "module": "es2020", + "lib": ["es2020", "DOM", "WebWorker"], + "target": "es2020", + /** + svelte-preprocess cannot figure out whether you have a value or a type, so tell TypeScript + to enforce using \`import type\` instead of \`import\` for Types. + */ + "importsNotUsedAsValues": "error", + "isolatedModules": true, + "resolveJsonModule": true, + /** + * To have warnings/errors of the Svelte compiler at the correct position, + * enable source maps by default. + */ + "sourceMap": true, + "esModuleInterop": true, + "skipLibCheck": true, + "forceConsistentCasingInFileNames": true, + "baseUrl": ".", + "allowJs": true, + "checkJs": true, + "paths": { + "$lib": ["src/lib"], + "$lib/*": ["src/lib/*"] + } + }, + "include": ["src/**/*.d.ts", "src/**/*.js", "src/**/*.ts", "src/**/*.svelte"] +} diff --git a/examples/vue-router/package.json b/examples/vue-router/package.json index fcd28934..d55307c5 100644 --- a/examples/vue-router/package.json +++ b/examples/vue-router/package.json @@ -8,6 +8,9 @@ "start-claims": "npm run run-build-claims && npm run serve", "start-claims-reloadsw": "npm run run-build-reloadsw-claims && npm run serve", "start-sw": "npm run run-build-sw && npm run serve", + "start-sw-reloadsw": "npm run run-build-sw-reloadsw && npm run serve", + "start-sw-claims": "npm run run-build-sw-claims && npm run serve", + "start-sw-claims-reloadsw": "npm run run-build-sw-reloadsw-claims && npm run serve", "dev": "cross-env DEBUG=vite-plugin-pwa:* vite", "build": "cross-env DEBUG=vite-plugin-pwa:* vite build", "run-build": "cross-env DEBUG=vite-plugin-pwa:* BASE_URL=/ SOURCE_MAP=true vite build", @@ -15,6 +18,9 @@ "run-build-claims": "cross-env DEBUG=vite-plugin-pwa:* BASE_URL=/ SOURCE_MAP=true CLAIMS=true vite build", "run-build-reloadsw-claims": "cross-env DEBUG=vite-plugin-pwa:* BASE_URL=/ SOURCE_MAP=true CLAIMS=true RELOAD_SW=true vite build", "run-build-sw": "rimraf dist && cross-env DEBUG=vite-plugin-pwa:* BASE_URL=/ SOURCE_MAP=true SW=true vite build", + "run-build-sw-reloadsw": "cross-env DEBUG=vite-plugin-pwa:* BASE_URL=/ SOURCE_MAP=true RELOAD_SW=true SW=true vite build", + "run-build-sw-claims": "cross-env DEBUG=vite-plugin-pwa:* BASE_URL=/ SOURCE_MAP=true CLAIMS=true SW=true vite build", + "run-build-sw-reloadsw-claims": "cross-env DEBUG=vite-plugin-pwa:* BASE_URL=/ SOURCE_MAP=true CLAIMS=true RELOAD_SW=true SW=true vite build", "serve": "serve dist" }, "dependencies": { @@ -32,6 +38,7 @@ "typescript": "^4.4.4", "vite": "^2.6.14", "vite-plugin-pwa": "workspace:*", + "workbox-core": "^6.4.0", "workbox-precaching": "^6.4.0", "workbox-routing": "^6.4.0", "workbox-window": "^6.4.0" diff --git a/examples/vue-router/src/claims-sw.ts b/examples/vue-router/src/claims-sw.ts new file mode 100644 index 00000000..02152cad --- /dev/null +++ b/examples/vue-router/src/claims-sw.ts @@ -0,0 +1,17 @@ +import { precacheAndRoute, cleanupOutdatedCaches, createHandlerBoundToURL } from 'workbox-precaching' +import { clientsClaim } from 'workbox-core' +import { registerRoute, NavigationRoute } from 'workbox-routing' + +declare let self: ServiceWorkerGlobalScope + +// self.__WB_MANIFEST is default injection point +precacheAndRoute(self.__WB_MANIFEST) + +// clean old assets +cleanupOutdatedCaches() + +// to allow work offline +registerRoute(new NavigationRoute(createHandlerBoundToURL('index.html'))) + +self.skipWaiting() +clientsClaim() diff --git a/examples/vue-router/src/sw.ts b/examples/vue-router/src/prompt-sw.ts similarity index 100% rename from examples/vue-router/src/sw.ts rename to examples/vue-router/src/prompt-sw.ts diff --git a/examples/vue-router/vite.config.ts b/examples/vue-router/vite.config.ts index c7098bf7..9b72c9f0 100644 --- a/examples/vue-router/vite.config.ts +++ b/examples/vue-router/vite.config.ts @@ -33,22 +33,23 @@ const pwaOptions: Partial = { } const replaceOptions = { __DATE__: new Date().toISOString() } +const claims = process.env.CLAIMS === 'true' +const reload = process.env.RELOAD_SW === 'true' if (process.env.SW === 'true') { pwaOptions.srcDir = 'src' - pwaOptions.filename = 'sw.ts' + pwaOptions.filename = claims ? 'claims-sw.ts' : 'prompt-sw.ts' pwaOptions.strategies = 'injectManifest' ;(pwaOptions.manifest as Partial).name = 'PWA Inject Manifest' ;(pwaOptions.manifest as Partial).short_name = 'PWA Inject' } -else { - if (process.env.CLAIMS === 'true') - pwaOptions.registerType = 'autoUpdate' - if (process.env.RELOAD_SW === 'true') { - // @ts-ignore - replaceOptions.__RELOAD_SW__ = 'true' - } +if (claims) + pwaOptions.registerType = 'autoUpdate' + +if (reload) { + // @ts-ignore + replaceOptions.__RELOAD_SW__ = 'true' } export default defineConfig({ diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index ce268356..2367918b 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -116,6 +116,7 @@ importers: typescript: ^4.4.4 vite: ^2.6.14 vite-plugin-pwa: workspace:* + workbox-core: ^6.4.0 workbox-precaching: ^6.4.0 workbox-routing: ^6.4.0 workbox-window: ^6.4.0 @@ -131,6 +132,7 @@ importers: typescript: 4.4.4 vite: 2.6.14 vite-plugin-pwa: link:../.. + workbox-core: 6.4.0 workbox-precaching: 6.4.0 workbox-routing: 6.4.0 workbox-window: 6.4.0 @@ -154,6 +156,7 @@ importers: typescript: ^4.4.4 vite: ^2.6.14 vite-plugin-pwa: workspace:* + workbox-core: ^6.4.0 workbox-precaching: ^6.4.0 workbox-routing: ^6.4.0 workbox-window: ^6.4.0 @@ -176,6 +179,7 @@ importers: typescript: 4.4.4 vite: 2.6.14 vite-plugin-pwa: link:../.. + workbox-core: 6.4.0 workbox-precaching: 6.4.0 workbox-routing: 6.4.0 workbox-window: 6.4.0 @@ -192,6 +196,7 @@ importers: vite: ^2.6.14 vite-plugin-pwa: workspace:* vite-plugin-solid: ^2.1.2 + workbox-core: ^6.4.0 workbox-precaching: ^6.4.0 workbox-routing: ^6.4.0 workbox-window: ^6.4.0 @@ -207,6 +212,7 @@ importers: vite: 2.6.14 vite-plugin-pwa: link:../.. vite-plugin-solid: 2.1.2 + workbox-core: 6.4.0 workbox-precaching: 6.4.0 workbox-routing: 6.4.0 workbox-window: 6.4.0 @@ -228,6 +234,7 @@ importers: typescript: ^4.4.4 vite: ^2.6.14 vite-plugin-pwa: workspace:* + workbox-core: ^6.4.0 workbox-precaching: ^6.4.0 workbox-routing: ^6.4.0 devDependencies: @@ -246,6 +253,51 @@ importers: typescript: 4.4.4 vite: 2.6.14 vite-plugin-pwa: link:../.. + workbox-core: 6.4.0 + workbox-precaching: 6.4.0 + workbox-routing: 6.4.0 + + examples/sveltekit-pwa: + specifiers: + '@rollup/plugin-replace': ^3.0.0 + '@sveltejs/adapter-static': next + '@sveltejs/kit': next + '@typescript-eslint/eslint-plugin': ^4.31.1 + '@typescript-eslint/parser': ^4.31.1 + cross-env: ^7.0.3 + eslint: ^7.32.0 + eslint-plugin-svelte3: ^3.2.1 + https-localhost: ^4.7.0 + minimist: ^1.2.5 + rimraf: ^3.0.2 + svelte: ^3.44.1 + svelte-check: ^2.2.8 + svelte-preprocess: ^4.9.8 + tslib: ^2.3.1 + typescript: ^4.4.4 + vite-plugin-pwa: workspace:* + workbox-core: ^6.4.0 + workbox-precaching: ^6.4.0 + workbox-routing: ^6.4.0 + devDependencies: + '@rollup/plugin-replace': 3.0.0_rollup@2.60.0 + '@sveltejs/adapter-static': 1.0.0-next.21 + '@sveltejs/kit': 1.0.0-next.201_svelte@3.44.1 + '@typescript-eslint/eslint-plugin': 4.33.0_cc617358c89d3f38c52462f6d809db4c + '@typescript-eslint/parser': 4.33.0_eslint@7.32.0+typescript@4.4.4 + cross-env: 7.0.3 + eslint: 7.32.0 + eslint-plugin-svelte3: 3.2.1_eslint@7.32.0+svelte@3.44.1 + https-localhost: 4.7.0 + minimist: 1.2.5 + rimraf: 3.0.2 + svelte: 3.44.1 + svelte-check: 2.2.8_svelte@3.44.1 + svelte-preprocess: 4.9.8_svelte@3.44.1+typescript@4.4.4 + tslib: 2.3.1 + typescript: 4.4.4 + vite-plugin-pwa: link:../.. + workbox-core: 6.4.0 workbox-precaching: 6.4.0 workbox-routing: 6.4.0 @@ -288,6 +340,7 @@ importers: vite-plugin-pwa: workspace:* vue: ^3.2.21 vue-router: ^4.0.12 + workbox-core: ^6.4.0 workbox-precaching: ^6.4.0 workbox-routing: ^6.4.0 workbox-window: ^6.4.0 @@ -305,6 +358,7 @@ importers: typescript: 4.4.4 vite: 2.6.14 vite-plugin-pwa: link:../.. + workbox-core: 6.4.0 workbox-precaching: 6.4.0 workbox-routing: 6.4.0 workbox-window: 6.4.0 @@ -520,6 +574,12 @@ packages: leven: 3.1.0 dev: false + /@babel/code-frame/7.12.11: + resolution: {integrity: sha512-Zt1yodBx1UcyiePMSkWnU4hPqhwq7hGi2nFL1LeA3EUl+q2LQx16MISgJ0+z7dnmgvP9QtIleuETGOiOH1RcIw==} + dependencies: + '@babel/highlight': 7.16.0 + dev: true + /@babel/code-frame/7.14.5: resolution: {integrity: sha512-9pzDqyc6OLDaqe+zbACgFkb6fKMNG6CObKpnYXChRsvYGyEdc7CA2BaqeOM+vOtCS5ndmJicPJhKAwYRI6UfFw==} engines: {node: '>=6.9.0'} @@ -1967,6 +2027,23 @@ packages: react: 17.0.2 dev: true + /@eslint/eslintrc/0.4.3: + resolution: {integrity: sha512-J6KFFz5QCYUJq3pf0mjEcCJVERbzv71PUIDczuh9JkwGEzced6CO5ADLHB1rbf/+oPBtoPfMYNOpGDzCANlbXw==} + engines: {node: ^10.12.0 || >=12.0.0} + dependencies: + ajv: 6.12.6 + debug: 4.3.2 + espree: 7.3.1 + globals: 13.9.0 + ignore: 4.0.6 + import-fresh: 3.3.0 + js-yaml: 3.14.1 + minimatch: 3.0.4 + strip-json-comments: 3.1.1 + transitivePeerDependencies: + - supports-color + dev: true + /@eslint/eslintrc/1.0.4: resolution: {integrity: sha512-h8Vx6MdxwWI2WM8/zREHMoqdgLNXEL4QX3MWSVMdyNJGvXVOs+6lp+m2hc3FnuMHDc4poxFNI20vCk0OmI4G0Q==} engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} @@ -1992,6 +2069,17 @@ packages: resolution: {integrity: sha512-bprfNmYt1opFUFEtD2XfY/kEsm13bzHQgU80uMjhuK0DJ914IjolT1GytpkdM6tJ4MBvyiJPP+bTtWO+BZ7c7w==} dev: true + /@humanwhocodes/config-array/0.5.0: + resolution: {integrity: sha512-FagtKFz74XrTl7y6HCzQpwDfXP0yhxe9lHLD1UZxjvZIcbyRz8zTFF/yYNfSfzU414eDwZ1SrO0Qvtyf+wFMQg==} + engines: {node: '>=10.10.0'} + dependencies: + '@humanwhocodes/object-schema': 1.2.0 + debug: 4.3.2 + minimatch: 3.0.4 + transitivePeerDependencies: + - supports-color + dev: true + /@humanwhocodes/config-array/0.6.0: resolution: {integrity: sha512-JQlEKbcgEUjBFhLIF4iqM7u/9lwgHRBcpHrmUNCALK0Q3amXN6lxdoXLnF0sm11E9VqTmBALR87IlUg1bZ8A9A==} engines: {node: '>=10.10.0'} @@ -2216,6 +2304,30 @@ packages: string.prototype.matchall: 4.0.6 dev: false + /@sveltejs/adapter-static/1.0.0-next.21: + resolution: {integrity: sha512-B4+QoUVAaANKx+mHntG8SqF45zbj3Ct4Akg/cGauo6COyfKZRhO5OsMa+wPuT2TKJBZC4eEDK0p+p9nyQBkxKQ==} + dev: true + + /@sveltejs/kit/1.0.0-next.201_svelte@3.44.1: + resolution: {integrity: sha512-WcYexOEPWgDWOk0oOteTU5QwWykdIcOFJig+akeHqwE/jVtPURLZFtTNx0ymUWXN4S+dUXf60KF6HEMv74FHpA==} + engines: {node: '>=14.13'} + hasBin: true + peerDependencies: + svelte: ^3.44.0 + dependencies: + '@sveltejs/vite-plugin-svelte': 1.0.0-next.30_svelte@3.44.1+vite@2.6.14 + cheap-watch: 1.0.4 + sade: 1.7.4 + svelte: 3.44.1 + vite: 2.6.14 + transitivePeerDependencies: + - diff-match-patch + - less + - sass + - stylus + - supports-color + dev: true + /@sveltejs/vite-plugin-svelte/1.0.0-next.30_svelte@3.44.1+vite@2.6.14: resolution: {integrity: sha512-YQqdMxjL1VgSFk4/+IY3yLwuRRapPafPiZTiaGEq1psbJYSNYUWx9F1zMm32GMsnogg3zn99mGJOqe3ld3HZSg==} engines: {node: ^14.13.1 || >= 16} @@ -2378,6 +2490,32 @@ packages: resolution: {integrity: sha512-op5P/f6n+9g5X4a+sYONp9EALnNxpoU3oXuB/BjeQv9d+k0bNE4LYSF06K6tXYL4PeCIZVJOi4yMCUCOi2NaqQ==} dev: true + /@typescript-eslint/eslint-plugin/4.33.0_cc617358c89d3f38c52462f6d809db4c: + resolution: {integrity: sha512-aINiAxGVdOl1eJyVjaWn/YcVAq4Gi/Yo35qHGCnqbWVz61g39D0h23veY/MA0rFFGfxK7TySg2uwDeNv+JgVpg==} + engines: {node: ^10.12.0 || >=12.0.0} + peerDependencies: + '@typescript-eslint/parser': ^4.0.0 + eslint: ^5.0.0 || ^6.0.0 || ^7.0.0 + typescript: '*' + peerDependenciesMeta: + typescript: + optional: true + dependencies: + '@typescript-eslint/experimental-utils': 4.33.0_eslint@7.32.0+typescript@4.4.4 + '@typescript-eslint/parser': 4.33.0_eslint@7.32.0+typescript@4.4.4 + '@typescript-eslint/scope-manager': 4.33.0 + debug: 4.3.2 + eslint: 7.32.0 + functional-red-black-tree: 1.0.1 + ignore: 5.1.8 + regexpp: 3.2.0 + semver: 7.3.5 + tsutils: 3.21.0_typescript@4.4.4 + typescript: 4.4.4 + transitivePeerDependencies: + - supports-color + dev: true + /@typescript-eslint/eslint-plugin/5.3.1_4653b7803b7453f5f37717b7e1448517: resolution: {integrity: sha512-cFImaoIr5Ojj358xI/SDhjog57OK2NqlpxwdcgyxDA3bJlZcJq5CPzUXtpD7CxI2Hm6ATU7w5fQnnkVnmwpHqw==} engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} @@ -2429,6 +2567,24 @@ packages: - supports-color dev: true + /@typescript-eslint/experimental-utils/4.33.0_eslint@7.32.0+typescript@4.4.4: + resolution: {integrity: sha512-zeQjOoES5JFjTnAhI5QY7ZviczMzDptls15GFsI6jyUOq0kOf9+WonkhtlIhh0RgHRnqj5gdNxW5j1EvAyYg6Q==} + engines: {node: ^10.12.0 || >=12.0.0} + peerDependencies: + eslint: '*' + dependencies: + '@types/json-schema': 7.0.9 + '@typescript-eslint/scope-manager': 4.33.0 + '@typescript-eslint/types': 4.33.0 + '@typescript-eslint/typescript-estree': 4.33.0_typescript@4.4.4 + eslint: 7.32.0 + eslint-scope: 5.1.1 + eslint-utils: 3.0.0_eslint@7.32.0 + transitivePeerDependencies: + - supports-color + - typescript + dev: true + /@typescript-eslint/experimental-utils/5.3.1_eslint@8.2.0+typescript@4.4.4: resolution: {integrity: sha512-RgFn5asjZ5daUhbK5Sp0peq0SSMytqcrkNfU4pnDma2D8P3ElZ6JbYjY8IMSFfZAJ0f3x3tnO3vXHweYg0g59w==} engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} @@ -2447,6 +2603,26 @@ packages: - typescript dev: true + /@typescript-eslint/parser/4.33.0_eslint@7.32.0+typescript@4.4.4: + resolution: {integrity: sha512-ZohdsbXadjGBSK0/r+d87X0SBmKzOq4/S5nzK6SBgJspFo9/CUDJ7hjayuze+JK7CZQLDMroqytp7pOcFKTxZA==} + engines: {node: ^10.12.0 || >=12.0.0} + peerDependencies: + eslint: ^5.0.0 || ^6.0.0 || ^7.0.0 + typescript: '*' + peerDependenciesMeta: + typescript: + optional: true + dependencies: + '@typescript-eslint/scope-manager': 4.33.0 + '@typescript-eslint/types': 4.33.0 + '@typescript-eslint/typescript-estree': 4.33.0_typescript@4.4.4 + debug: 4.3.2 + eslint: 7.32.0 + typescript: 4.4.4 + transitivePeerDependencies: + - supports-color + dev: true + /@typescript-eslint/parser/5.3.1_eslint@8.2.0+typescript@4.4.4: resolution: {integrity: sha512-TD+ONlx5c+Qhk21x9gsJAMRohWAUMavSOmJgv3JGy9dgPhuBd5Wok0lmMClZDyJNLLZK1JRKiATzCKZNUmoyfw==} engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} @@ -2467,6 +2643,14 @@ packages: - supports-color dev: true + /@typescript-eslint/scope-manager/4.33.0: + resolution: {integrity: sha512-5IfJHpgTsTZuONKbODctL4kKuQje/bzBRkwHE8UOZ4f89Zeddg+EGZs8PD8NcN4LdM3ygHWYB3ukPAYjvl/qbQ==} + engines: {node: ^8.10.0 || ^10.13.0 || >=11.10.1} + dependencies: + '@typescript-eslint/types': 4.33.0 + '@typescript-eslint/visitor-keys': 4.33.0 + dev: true + /@typescript-eslint/scope-manager/5.3.1: resolution: {integrity: sha512-XksFVBgAq0Y9H40BDbuPOTUIp7dn4u8oOuhcgGq7EoDP50eqcafkMVGrypyVGvDYHzjhdUCUwuwVUK4JhkMAMg==} engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} @@ -2475,11 +2659,37 @@ packages: '@typescript-eslint/visitor-keys': 5.3.1 dev: true + /@typescript-eslint/types/4.33.0: + resolution: {integrity: sha512-zKp7CjQzLQImXEpLt2BUw1tvOMPfNoTAfb8l51evhYbOEEzdWyQNmHWWGPR6hwKJDAi+1VXSBmnhL9kyVTTOuQ==} + engines: {node: ^8.10.0 || ^10.13.0 || >=11.10.1} + dev: true + /@typescript-eslint/types/5.3.1: resolution: {integrity: sha512-bG7HeBLolxKHtdHG54Uac750eXuQQPpdJfCYuw4ZI3bZ7+GgKClMWM8jExBtp7NSP4m8PmLRM8+lhzkYnSmSxQ==} engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} dev: true + /@typescript-eslint/typescript-estree/4.33.0_typescript@4.4.4: + resolution: {integrity: sha512-rkWRY1MPFzjwnEVHsxGemDzqqddw2QbTJlICPD9p9I9LfsO8fdmfQPOX3uKfUaGRDFJbfrtm/sXhVXN4E+bzCA==} + engines: {node: ^10.12.0 || >=12.0.0} + peerDependencies: + typescript: '*' + peerDependenciesMeta: + typescript: + optional: true + dependencies: + '@typescript-eslint/types': 4.33.0 + '@typescript-eslint/visitor-keys': 4.33.0 + debug: 4.3.2 + globby: 11.0.4 + is-glob: 4.0.3 + semver: 7.3.5 + tsutils: 3.21.0_typescript@4.4.4 + typescript: 4.4.4 + transitivePeerDependencies: + - supports-color + dev: true + /@typescript-eslint/typescript-estree/5.3.1_typescript@4.4.4: resolution: {integrity: sha512-PwFbh/PKDVo/Wct6N3w+E4rLZxUDgsoII/GrWM2A62ETOzJd4M6s0Mu7w4CWsZraTbaC5UQI+dLeyOIFF1PquQ==} engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} @@ -2501,6 +2711,14 @@ packages: - supports-color dev: true + /@typescript-eslint/visitor-keys/4.33.0: + resolution: {integrity: sha512-uqi/2aSz9g2ftcHWf8uLPJA70rUv6yuMW5Bohw+bwcuzaxQIHaKFZCKGoGXIrc9vkTJ3+0txM73K0Hq3d5wgIg==} + engines: {node: ^8.10.0 || ^10.13.0 || >=11.10.1} + dependencies: + '@typescript-eslint/types': 4.33.0 + eslint-visitor-keys: 2.1.0 + dev: true + /@typescript-eslint/visitor-keys/5.3.1: resolution: {integrity: sha512-3cHUzUuVTuNHx0Gjjt5pEHa87+lzyqOiHXy/Gz+SJOCW1mpw9xQHIIEwnKn+Thph1mgWyZ90nboOcSuZr/jTTQ==} engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} @@ -2744,7 +2962,6 @@ packages: json-schema-traverse: 1.0.0 require-from-string: 2.0.2 uri-js: 4.4.1 - dev: false /algoliasearch/4.10.3: resolution: {integrity: sha512-OLY0AWlPKGLbSaw14ivMB7BT5fPdp8VdzY4L8FtzZnqmLKsyes24cltGlf7/X96ACkYEcT390SReCDt/9SUIRg==} @@ -2803,6 +3020,12 @@ packages: resolution: {integrity: sha512-ZbH3ezXfnT/YE3NdqduIt4lBV+H0ybvA2Qx3K76gIjQvh8gROpDFdDLpx6B1QJtW7zxisCbpTlCLhKqoR8cDBw==} dev: true + /argparse/1.0.10: + resolution: {integrity: sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==} + dependencies: + sprintf-js: 1.0.3 + dev: true + /argparse/2.0.1: resolution: {integrity: sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==} dev: true @@ -2846,6 +3069,11 @@ packages: function-bind: 1.1.1 dev: true + /astral-regex/2.0.0: + resolution: {integrity: sha512-Z7tMw1ytTXt5jqMcOP+OQteU1VuNK9Y02uuJtKQ1Sv69jXQKKg5cibLwGJow8yzZP+eAc18EmLGPal0bp36rvQ==} + engines: {node: '>=8'} + dev: true + /async/0.9.2: resolution: {integrity: sha1-rqdNXmHB+JlhO/ZL2mbUx48v0X0=} dev: false @@ -3074,6 +3302,11 @@ packages: engines: {node: '>=8'} dev: true + /cheap-watch/1.0.4: + resolution: {integrity: sha512-QR/9FrtRL5fjfUJBhAKCdi0lSRQ3rVRRum3GF9wDKp2TJbEIMGhUEr2yU8lORzm9Isdjx7/k9S0DFDx+z5VGtw==} + engines: {node: '>=8'} + dev: true + /chokidar/3.5.2: resolution: {integrity: sha512-ekGhOnNVPgT77r4K/U3GDhu+FQ2S8TnK/s2KbIGXi0SZWuwkZ2QNyfWdZW+TVfn84DpEP7rLeCt2UI6bJ8GwbQ==} engines: {node: '>= 8.10.0'} @@ -3435,6 +3668,10 @@ packages: resolution: {integrity: sha512-NcGkBVXePiuUrPLV8IxP43n1EOtdg+dudVjrfVEUd/bOqpQUFZ2diL5PPYzbgEhZFEltdXV3AcyKwGnEQ5lhMA==} dev: true + /emoji-regex/8.0.0: + resolution: {integrity: sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==} + dev: true + /encodeurl/1.0.2: resolution: {integrity: sha1-rT/0yG7C0CkyL1oCw6mmBslbP1k=} engines: {node: '>= 0.8'} @@ -4014,6 +4251,17 @@ packages: string.prototype.matchall: 4.0.6 dev: true + /eslint-plugin-svelte3/3.2.1_eslint@7.32.0+svelte@3.44.1: + resolution: {integrity: sha512-YoBR9mLoKCjGghJ/gvpnFZKaMEu/VRcuxpSRS8KuozuEo7CdBH7bmBHa6FmMm0i4kJnOyx+PVsaptz96K6H/4Q==} + engines: {node: '>=10'} + peerDependencies: + eslint: '>=6.0.0' + svelte: ^3.2.0 + dependencies: + eslint: 7.32.0 + svelte: 3.44.1 + dev: true + /eslint-plugin-svelte3/3.2.1_eslint@8.2.0+svelte@3.44.1: resolution: {integrity: sha512-YoBR9mLoKCjGghJ/gvpnFZKaMEu/VRcuxpSRS8KuozuEo7CdBH7bmBHa6FmMm0i4kJnOyx+PVsaptz96K6H/4Q==} engines: {node: '>=10'} @@ -4118,6 +4366,16 @@ packages: eslint-visitor-keys: 1.3.0 dev: true + /eslint-utils/3.0.0_eslint@7.32.0: + resolution: {integrity: sha512-uuQC43IGctw68pJA1RgbQS8/NP7rch6Cwd4j3ZBtgo4/8Flj4eGE7ZYSZRN3iq5pVUv6GPdW5Z1RFleo84uLDA==} + engines: {node: ^10.0.0 || ^12.0.0 || >= 14.0.0} + peerDependencies: + eslint: '>=5' + dependencies: + eslint: 7.32.0 + eslint-visitor-keys: 2.1.0 + dev: true + /eslint-utils/3.0.0_eslint@8.2.0: resolution: {integrity: sha512-uuQC43IGctw68pJA1RgbQS8/NP7rch6Cwd4j3ZBtgo4/8Flj4eGE7ZYSZRN3iq5pVUv6GPdW5Z1RFleo84uLDA==} engines: {node: ^10.0.0 || ^12.0.0 || >= 14.0.0} @@ -4143,6 +4401,55 @@ packages: engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} dev: true + /eslint/7.32.0: + resolution: {integrity: sha512-VHZ8gX+EDfz+97jGcgyGCyRia/dPOd6Xh9yPv8Bl1+SoaIwD+a/vlrOmGRUyOYu7MwUhc7CxqeaDZU13S4+EpA==} + engines: {node: ^10.12.0 || >=12.0.0} + hasBin: true + dependencies: + '@babel/code-frame': 7.12.11 + '@eslint/eslintrc': 0.4.3 + '@humanwhocodes/config-array': 0.5.0 + ajv: 6.12.6 + chalk: 4.1.2 + cross-spawn: 7.0.3 + debug: 4.3.2 + doctrine: 3.0.0 + enquirer: 2.3.6 + escape-string-regexp: 4.0.0 + eslint-scope: 5.1.1 + eslint-utils: 2.1.0 + eslint-visitor-keys: 2.1.0 + espree: 7.3.1 + esquery: 1.4.0 + esutils: 2.0.3 + fast-deep-equal: 3.1.3 + file-entry-cache: 6.0.1 + functional-red-black-tree: 1.0.1 + glob-parent: 5.1.2 + globals: 13.9.0 + ignore: 4.0.6 + import-fresh: 3.3.0 + imurmurhash: 0.1.4 + is-glob: 4.0.3 + js-yaml: 3.14.1 + json-stable-stringify-without-jsonify: 1.0.1 + levn: 0.4.1 + lodash.merge: 4.6.2 + minimatch: 3.0.4 + natural-compare: 1.4.0 + optionator: 0.9.1 + progress: 2.0.3 + regexpp: 3.2.0 + semver: 7.3.5 + strip-ansi: 6.0.1 + strip-json-comments: 3.1.1 + table: 6.7.3 + text-table: 0.2.0 + v8-compile-cache: 2.3.0 + transitivePeerDependencies: + - supports-color + dev: true + /eslint/8.2.0: resolution: {integrity: sha512-erw7XmM+CLxTOickrimJ1SiF55jiNlVSp2qqm0NuBWPtHYQCegD5ZMaW0c3i5ytPqL+SSLaCxdvQXFPLJn+ABw==} engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} @@ -4219,6 +4526,15 @@ packages: eslint-visitor-keys: 1.3.0 dev: true + /espree/7.3.1: + resolution: {integrity: sha512-v3JCNCE64umkFpmkFGqzVKsOT0tN1Zr+ueqLZfpV1Ob8e+CEgPWa+OxCoGH3tnhimMKIaBm4m/vaRpJ/krRz2g==} + engines: {node: ^10.12.0 || >=12.0.0} + dependencies: + acorn: 7.4.1 + acorn-jsx: 5.3.1_acorn@7.4.1 + eslint-visitor-keys: 1.3.0 + dev: true + /espree/9.0.0: resolution: {integrity: sha512-r5EQJcYZ2oaGbeR0jR0fFVijGOcwai07/690YRXLINuhmVeRY4UKSAsQPe/0BNuDgwP7Ophoc1PRsr2E3tkbdQ==} engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} @@ -4513,7 +4829,7 @@ packages: resolution: {integrity: sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==} engines: {node: '>= 6'} dependencies: - is-glob: 4.0.1 + is-glob: 4.0.3 /glob-parent/6.0.2: resolution: {integrity: sha512-XxwI8EOhVQgWp6iDL+3b0r86f4d6AX6zSU55HfB4ydCEuXLXc5FcYeOu+nnGftS4TEju/11rt4KJPTMgbfmv4A==} @@ -4860,18 +5176,23 @@ packages: resolution: {integrity: sha1-qIwCU1eR8C7TfHahueqXc8gz+MI=} engines: {node: '>=0.10.0'} + /is-fullwidth-code-point/3.0.0: + resolution: {integrity: sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==} + engines: {node: '>=8'} + dev: true + /is-glob/4.0.1: resolution: {integrity: sha512-5G0tKtBTFImOqDnLB2hG6Bp2qcKEFduo4tZu9MT/H6NQv/ghhy30o55ufafxJ/LdH79LLs2Kfrn85TLKyA7BUg==} engines: {node: '>=0.10.0'} dependencies: is-extglob: 2.1.1 + dev: true /is-glob/4.0.3: resolution: {integrity: sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==} engines: {node: '>=0.10.0'} dependencies: is-extglob: 2.1.1 - dev: true /is-module/1.0.0: resolution: {integrity: sha1-Mlj7afeMFNW4FdZkM2tM/7ZEFZE=} @@ -4982,6 +5303,14 @@ packages: /js-tokens/4.0.0: resolution: {integrity: sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==} + /js-yaml/3.14.1: + resolution: {integrity: sha512-okMH7OXXJ7YrN9Ok3/SXrnu4iX9yOk+25nqX4imS2npuvTYDmo/QEZoqwZkYaIDk3jVvBOTOIEgEhaLOynBS9g==} + hasBin: true + dependencies: + argparse: 1.0.10 + esprima: 4.0.1 + dev: true + /js-yaml/4.1.0: resolution: {integrity: sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==} hasBin: true @@ -5051,7 +5380,6 @@ packages: /json-schema-traverse/1.0.0: resolution: {integrity: sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==} - dev: false /json-schema/0.3.0: resolution: {integrity: sha512-TYfxx36xfl52Rf1LU9HyWSLGPdYLL+SQ8/E/0yVyKG8wCCDaSrhPap0vEdlsZWRaS6tnKKLPGiEJGiREVC8kxQ==} @@ -5196,6 +5524,10 @@ packages: resolution: {integrity: sha1-7dFMgk4sycHgsKG0K7UhBRakJDg=} dev: false + /lodash.truncate/4.4.2: + resolution: {integrity: sha1-WjUNoLERO4N+z//VgSy+WNbq4ZM=} + dev: true + /lodash/4.17.21: resolution: {integrity: sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==} @@ -5944,7 +6276,6 @@ packages: /require-from-string/2.0.2: resolution: {integrity: sha512-Xf0nWe6RseziFMu+Ap9biiUbmplq6S9/p+7w7YXP/JBHhrUDDUhwa+vANyubuqfZWTveU//DYVGsDG7RKL/vEw==} engines: {node: '>=0.10.0'} - dev: false /require-relative/0.8.7: resolution: {integrity: sha1-eZlTn8ngR6N5KPoZb44VY9q9Nt4=} @@ -6164,6 +6495,15 @@ packages: engines: {node: '>=8'} dev: true + /slice-ansi/4.0.0: + resolution: {integrity: sha512-qMCMfhY040cVHT43K9BFygqYbUPFZKHOg7K73mtTWJRb8pyP3fzf4Ixd5SzdEJQ6MRUg/WBnOLxghZtKKurENQ==} + engines: {node: '>=10'} + dependencies: + ansi-styles: 4.3.0 + astral-regex: 2.0.0 + is-fullwidth-code-point: 3.0.0 + dev: true + /solid-app-router/0.1.11_solid-js@1.2.3: resolution: {integrity: sha512-O0Gp2MhsqMJCDFzMNEH1rjpKFIFXO+0pX12AwTDYXQVnGwscbjD0ysAtyvjgXZAcj2udbYEL4uR5IgnJfI3YKw==} peerDependencies: @@ -6278,11 +6618,24 @@ packages: - supports-color dev: true + /sprintf-js/1.0.3: + resolution: {integrity: sha1-BOaSb2YolTVPPdAVIDYzuFcpfiw=} + dev: true + /statuses/1.5.0: resolution: {integrity: sha1-Fhx9rBd2Wf2YEfQ3cfqZOBR4Yow=} engines: {node: '>= 0.6'} dev: true + /string-width/4.2.3: + resolution: {integrity: sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==} + engines: {node: '>=8'} + dependencies: + emoji-regex: 8.0.0 + is-fullwidth-code-point: 3.0.0 + strip-ansi: 6.0.1 + dev: true + /string.prototype.matchall/4.0.6: resolution: {integrity: sha512-6WgDX8HmQqvEd7J+G6VtAahhsQIssiZ8zl7zKh1VDMFyL3hRTJP4FTNA3RbIp2TOQ9AYNDcc7e3fH0Qbup+DBg==} dependencies: @@ -6484,6 +6837,17 @@ packages: resolution: {integrity: sha512-9QNk5KwDF+Bvz+PyObkmSYjI5ksVUYtjW7AU22r2NKcfLJcXp96hkDWU3+XndOsUb+AQ9QhfzfCT2O+CNWT5Tw==} dev: true + /table/6.7.3: + resolution: {integrity: sha512-5DkIxeA7XERBqMwJq0aHZOdMadBx4e6eDoFRuyT5VR82J0Ycg2DwM6GfA/EQAhJ+toRTaS1lIdSQCqgrmhPnlw==} + engines: {node: '>=10.0.0'} + dependencies: + ajv: 8.6.0 + lodash.truncate: 4.4.2 + slice-ansi: 4.0.0 + string-width: 4.2.3 + strip-ansi: 6.0.1 + dev: true + /temp-dir/2.0.0: resolution: {integrity: sha512-aoBAniQmmwtcKp/7BzsH8Cxzv8OL736p7v1ihGb5e9DJ9kTwGWHrQrVB5+lfVDzfGrdRzXch+ig7LHaY1JTOrg==} engines: {node: '>=8'} @@ -6589,6 +6953,10 @@ packages: resolution: {integrity: sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==} dev: true + /tslib/2.3.1: + resolution: {integrity: sha512-77EbyPPpMz+FRFRuAFlWMtmgUWGe9UOG2Z25NqCwiIjRhOf5iKGuzSe5P2w1laq+FkRy4p+PCuVkJSGkzTEKVw==} + dev: true + /tsup/5.7.0_typescript@4.4.4: resolution: {integrity: sha512-Rt83NU4t3e0I2WyubR3doAAl/aijzNYVgWB8cZxem/6MfoutrOFssm6L8eMVIGvPPOYsDDVcAvXLwn+CUgeRAQ==} hasBin: true diff --git a/scripts/run-examples.ts b/scripts/run-examples.ts index 0eac717d..95a0677e 100644 --- a/scripts/run-examples.ts +++ b/scripts/run-examples.ts @@ -21,7 +21,7 @@ type Strategy = { name: string display: string color: Color - behaviors?: Behavior[] + behaviors: Behavior[] } type Framework = { @@ -55,6 +55,7 @@ const STRATEGIES: Strategy[] = [ name: 'injectManifest', display: 'injectManifest', color: blue, + behaviors: BEHAVIORS, }, ] @@ -83,6 +84,12 @@ const FRAMEWORKS: Framework[] = [ dir: 'svelte-routify', strategies: STRATEGIES, }, + { + name: 'sveltekit', + color: blue, + dir: 'sveltekit-pwa', + strategies: STRATEGIES, + }, { name: 'solid', color: yellow, @@ -128,57 +135,50 @@ async function init() { }, { onCancel }, ) - let useBehaviour: Behavior | undefined - let useReloadSW: boolean | undefined - if (useStrategy.behaviors) { - const { behavior }: { behavior: Behavior } = await prompts( + const { behavior: useBehavior }: { behavior: Behavior } = await prompts( + { + type: 'select', + name: 'behavior', + message: 'Select a behavior:', + initial: 0, + choices: useStrategy.behaviors.map((behavior) => { + const behaviorColor = behavior.color + return { + title: behaviorColor(behavior.display), + value: behavior, + } + }), + }, + { onCancel }, + ) + const { reloadSW: useReloadSW }: { reloadSW: boolean } = await prompts( + [ { - type: 'select', - name: 'behavior', - message: 'Select a behavior:', - initial: 0, - choices: useStrategy.behaviors.map((behavior) => { - const behaviorColor = behavior.color - return { - title: behaviorColor(behavior.display), - value: behavior, - } - }), + type: 'toggle', + name: 'reloadSW', + message: 'Enable periodic SW updates?', + initial: false, + active: 'yes', + inactive: 'no', }, - { onCancel }, - ) - useBehaviour = behavior - const { reloadSW } = await prompts( - [ - { - type: 'toggle', - name: 'reloadSW', - message: 'Enable periodic SW updates?', - initial: false, - active: 'yes', - inactive: 'no', - }, - ], - { onCancel }, - ) - useReloadSW = reloadSW - } + ], + { onCancel }, + ) let script = '' - if (useStrategy.name === 'injectManifest') { + if (useStrategy.name === 'injectManifest') script = '-sw' + + switch (useBehavior.name) { + case 'prompt': + break + case 'claims': + default: + script += '-claims' + break } - else { - switch (useBehaviour!.name) { - case 'prompt': - break - case 'claims': - default: - script = '-claims' - break - } - if (useReloadSW === true) - script += '-reloadsw' - } + + if (useReloadSW) + script += '-reloadsw' execSync(`pnpm run start${script}`, { stdio: 'inherit',