├── assets
├── robots.txt
├── favicon.ico
├── favicon.png
├── global.css
├── images
│ └── touch-icons
│ │ ├── logo-192.png
│ │ └── logo-800.png
├── manifest.json
├── __app.html
└── 404.svg
├── sandbox.config.json
├── src
├── pages
│ ├── _layout.svelte
│ ├── index.svelte
│ └── _fallback.svelte
├── main.js
├── App.svelte
├── Serviceworker.svelte
└── sw.js
├── .gitignore
├── api
├── vercel-ssr
│ ├── package.json
│ ├── index.js
│ └── build.js
└── netlify
│ ├── package.json
│ ├── ssr.js
│ └── utils
│ └── build.js
├── .nolluprc.js
├── postcss.config.js
├── vercel.json
├── LICENSE
├── netlify.toml
├── tailwind.config.js
├── README.md
├── package.json
└── rollup.config.js
/assets/robots.txt:
--------------------------------------------------------------------------------
1 | # https://www.robotstxt.org/robotstxt.html
2 | User-agent: *
3 |
--------------------------------------------------------------------------------
/sandbox.config.json:
--------------------------------------------------------------------------------
1 | {
2 | "container": {
3 | "port": 5000
4 | }
5 | }
6 |
--------------------------------------------------------------------------------
/src/pages/_layout.svelte:
--------------------------------------------------------------------------------
1 |
2 |
3 |
--------------------------------------------------------------------------------
/assets/favicon.ico:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/lamualfa/routify-tailwind/HEAD/assets/favicon.ico
--------------------------------------------------------------------------------
/assets/favicon.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/lamualfa/routify-tailwind/HEAD/assets/favicon.png
--------------------------------------------------------------------------------
/assets/global.css:
--------------------------------------------------------------------------------
1 |
2 | @import "tailwindcss/base.css";
3 | @import "tailwindcss/components.css";
4 | @import "tailwindcss/utilities.css";
--------------------------------------------------------------------------------
/assets/images/touch-icons/logo-192.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/lamualfa/routify-tailwind/HEAD/assets/images/touch-icons/logo-192.png
--------------------------------------------------------------------------------
/assets/images/touch-icons/logo-800.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/lamualfa/routify-tailwind/HEAD/assets/images/touch-icons/logo-800.png
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | **/node_modules/
2 | /dist/
3 | .DS_Store
4 | **/.history
5 | src/tmp/
6 | .routify
7 | .netlify
8 | assets/build
9 | .vercel
10 |
--------------------------------------------------------------------------------
/api/vercel-ssr/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "scripts": {
3 | "vercel-build": "node ./build.js"
4 | },
5 | "devDependencies": {
6 | "rollup": "^2.28.2"
7 | }
8 | }
--------------------------------------------------------------------------------
/.nolluprc.js:
--------------------------------------------------------------------------------
1 | module.exports = {
2 | hot: true,
3 | contentBase: 'assets',
4 | publicPath: 'build',
5 | historyApiFallback: '__app.html',
6 | port: 5000
7 | }
8 |
--------------------------------------------------------------------------------
/src/main.js:
--------------------------------------------------------------------------------
1 | import HMR from '@roxi/routify/hmr'
2 | import App from './App.svelte';
3 |
4 | const app = HMR(App, { target: document.body }, 'routify-app')
5 |
6 | export default app;
--------------------------------------------------------------------------------
/postcss.config.js:
--------------------------------------------------------------------------------
1 | module.exports = {
2 | plugins: [
3 | require('postcss-import'),
4 | require('tailwindcss'),
5 | require('postcss-preset-env')({ stage: 1 }),
6 | ],
7 | };
8 |
--------------------------------------------------------------------------------
/src/App.svelte:
--------------------------------------------------------------------------------
1 |
5 |
6 |
9 |
10 |
--------------------------------------------------------------------------------
/vercel.json:
--------------------------------------------------------------------------------
1 | {
2 | "version": 2,
3 | "functions": {
4 | "api/vercel-ssr/index.js": {
5 | "includeFiles": "dist/**"
6 | }
7 | },
8 | "routes": [
9 | {
10 | "handle": "filesystem"
11 | },
12 | {
13 | "src": "/.*",
14 | "dest": "/api/vercel-ssr/index.js"
15 | }
16 | ]
17 | }
18 |
--------------------------------------------------------------------------------
/src/pages/index.svelte:
--------------------------------------------------------------------------------
1 |
2 |
Routify + Tailwind CSS template
3 |
4 | Visit
5 | Official Repository
8 | for further information.
9 |
10 |
11 |
--------------------------------------------------------------------------------
/api/netlify/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "ssr",
3 | "version": "1.0.0",
4 | "description": "",
5 | "main": "ssr.js",
6 | "scripts": {
7 | "build": "node utils/build.js",
8 | "test": "echo \"Error: no test specified\" && exit 1"
9 | },
10 | "author": "",
11 | "license": "ISC",
12 | "dependencies": {
13 | "esbuild": "^0.8.8",
14 | "tossr": "^1.3.1"
15 | }
16 | }
17 |
--------------------------------------------------------------------------------
/api/vercel-ssr/index.js:
--------------------------------------------------------------------------------
1 | const fs = require('fs')
2 | const { tossr } = require('tossr')
3 |
4 | const script = fs.readFileSync(require.resolve('../../dist/build/bundle.js'), 'utf8')
5 | const template = fs.readFileSync(require.resolve('../../dist/__app.html'), 'utf8')
6 |
7 | module.exports = async (req, res) => {
8 | const html = await tossr(template, script, req.url, {})
9 | res.send(html + '\n')
10 | }
11 |
12 |
--------------------------------------------------------------------------------
/api/netlify/ssr.js:
--------------------------------------------------------------------------------
1 | const fs = require('fs')
2 | const { tossr } = require('tossr')
3 | const { script, template } = require('./bundle.json')
4 |
5 | exports.handler = async (event, context) => {
6 | const qs = Object.entries(event.queryStringParameters)
7 | .map(([key, value]) => `${key}=${value}`)
8 | .join('&');
9 | const body = await tossr(template, script, `${event.path}?${qs}`);
10 | return { statusCode: 200, body: body + '\n' }
11 | }
12 |
--------------------------------------------------------------------------------
/src/pages/_fallback.svelte:
--------------------------------------------------------------------------------
1 |
4 |
5 |
17 |
18 |
19 |
404
20 |
Page not found.
21 |
22 |
Go back
23 |
24 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | DO WHAT THE FUCK YOU WANT TO PUBLIC LICENSE
2 | Version 2, December 2004
3 |
4 | Copyright (C) 2020 Laode Muhammad Al Fatih
5 |
6 | Everyone is permitted to copy and distribute verbatim or modified
7 | copies of this license document, and changing it is allowed as long
8 | as the name is changed.
9 |
10 | DO WHAT THE FUCK YOU WANT TO PUBLIC LICENSE
11 | TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
12 |
13 | 0. You just DO WHAT THE FUCK YOU WANT TO.
--------------------------------------------------------------------------------
/netlify.toml:
--------------------------------------------------------------------------------
1 |
2 | [build]
3 | publish = "dist"
4 | functions = "api/netlify"
5 | command = "npm run build && cd api/netlify && npm run build"
6 |
7 | # Dev doesn't work yet. Any takers?
8 | # [dev]
9 | # command = "npm run dev:ssr"
10 | # targetPort = 5000
11 | # publish = "assets"
12 | # autoLaunch = true
13 |
14 | [[redirects]]
15 | # SSR and SPA
16 | from = "/*"
17 | to = "/.netlify/functions/ssr"
18 | status = 200
19 |
20 | # SPA only
21 | # from = "/*"
22 | # to = "/__app.html"
23 | # status = 200
--------------------------------------------------------------------------------
/assets/manifest.json:
--------------------------------------------------------------------------------
1 | {
2 | "background_color": "#ffffff",
3 | "theme_color": "#E938C2",
4 | "name": "Routify app",
5 | "short_name": "Routify app",
6 | "start_url": "/",
7 | "display": "standalone",
8 | "icons": [
9 | {
10 | "src": "/images/touch-icons/logo-192.png",
11 | "sizes": "192x192",
12 | "type": "image/png"
13 | },
14 | {
15 | "src": "/images/touch-icons/logo-800.png",
16 | "sizes": "800x800",
17 | "type": "image/png",
18 | "purpose": "maskable any"
19 | }
20 | ]
21 | }
22 |
--------------------------------------------------------------------------------
/src/Serviceworker.svelte:
--------------------------------------------------------------------------------
1 |
20 |
--------------------------------------------------------------------------------
/assets/__app.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 | Routify + TailwindCSS
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
--------------------------------------------------------------------------------
/api/netlify/utils/build.js:
--------------------------------------------------------------------------------
1 | /**
2 | * Creates a JSON and inlines it with esbuild for ssr.js to consume
3 | * {
4 | * data: duh,
5 | * script: inlined main.js
6 | * template: __app.html
7 | * }
8 | */
9 |
10 | const { resolve } = require('path')
11 | const { readFileSync, writeFileSync } = require('fs')
12 | const { build } = require('esbuild')
13 |
14 | const scriptPath = resolve(__dirname, '../../../dist/build/main.js')
15 | const templatePath = resolve(__dirname, '../../../dist/__app.html')
16 | const bundlePath = resolve(__dirname, '../build/bundle.js')
17 |
18 | build({ entryPoints: [scriptPath], outfile: bundlePath, bundle: true }).then(() => {
19 | const bundle = {
20 | date: new Date,
21 | script: readFileSync(bundlePath, 'utf8'),
22 | template: readFileSync(templatePath, 'utf8')
23 | }
24 |
25 | writeFileSync(resolve(__dirname, '../bundle.json'), JSON.stringify(bundle, null, 2))
26 | })
27 |
--------------------------------------------------------------------------------
/tailwind.config.js:
--------------------------------------------------------------------------------
1 | const { tailwindExtractor } = require('tailwindcss/lib/lib/purgeUnusedStyles');
2 |
3 | const svelteClassColonExtractor = (content) => {
4 | return content.match(/(?<=class:)([a-zA-Z0-9_-]+)/gm) || [];
5 | };
6 |
7 | module.exports = {
8 | purge: {
9 | enabled: !process.env.ROLLUP_WATCH,
10 | content: [
11 | './src/**/*.svelte',
12 | './src/**/*.html',
13 | './src/**/*.css',
14 | './index.html',
15 | ],
16 | preserveHtmlElements: true,
17 | options: {
18 | safelist: [/svelte-/],
19 | defaultExtractor: (content) => {
20 | // WARNING: tailwindExtractor is internal tailwind api
21 | // if this breaks after a tailwind update, report to svite repo
22 | return [
23 | ...tailwindExtractor(content),
24 | ...svelteClassColonExtractor(content),
25 | ];
26 | },
27 | keyframes: true,
28 | },
29 | },
30 | theme: {
31 | extend: {},
32 | },
33 | variants: {},
34 | plugins: [],
35 | };
36 |
--------------------------------------------------------------------------------
/api/vercel-ssr/build.js:
--------------------------------------------------------------------------------
1 | const { resolve } = require('path')
2 | const { existsSync } = require('fs')
3 | const { execSync } = require('child_process')
4 | const { rollup } = require('rollup')
5 |
6 | const shouldBuildSpa = process.env.NOW_GITHUB_DEPLOYMENT || process.env.NOW_BUILDER
7 | const script = resolve(__dirname, '../../dist/build/main.js')
8 | const bundlePath = resolve(__dirname, '../../dist/build/bundle.js')
9 |
10 | build()
11 |
12 |
13 | async function build() {
14 | if (shouldBuildSpa)
15 | execSync('npm install && npm run build:app', { cwd: resolve('..', '..'), stdio: 'inherit' })
16 | else
17 | await waitForAppToExist()
18 |
19 | buildSSRBundle()
20 | }
21 |
22 | async function waitForAppToExist() {
23 | while (!existsSync(script)) {
24 | console.log(`checking if "${script}" exists`)
25 | await new Promise(r => setTimeout(r, 2000))
26 | }
27 | console.log(`found "${script}"`)
28 | }
29 |
30 | async function buildSSRBundle() {
31 | const bundle = await rollup({
32 | input: script,
33 | inlineDynamicImports: true,
34 | })
35 | await bundle.write({ format: 'umd', file: bundlePath, name: 'roxi-ssr' })
36 | }
37 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # Use Routify with Tailwind CSS
2 |
3 | Check out demo [Here](https://routify-tailwind.vercel.app/).
4 |
5 | ## Features
6 |
7 | - Purging Styles in Svelte component
8 |
9 | ## Installation
10 |
11 | ```bash
12 | npx degit lamualfa/routify-tailwind folder-name
13 | ```
14 |
15 | The command above will create a new folder with the name `folder-name` which contains Routify + Tailwind CSS template.
16 |
17 | ## Environment Used
18 |
19 | - Routify `2.5.1-next-major`
20 | - Tailwind `2.0.2`
21 | - PostCSS `8.2.1`
22 |
23 | ## Note
24 |
25 | **This template use _Tailwind CSS_ `v2.0.2`.** If you need the latest version, just run the command `yarn add tailwindcss` or `npm install tailwindcss` to update the Tailwind CSS.
26 |
27 | Special thank's to [dominikg/svite](https://github.com/dominikg/svite) for the Tailwind configuration file.
28 |
29 |
30 |
31 | ## Related
32 |
33 | - [routify-ts](https://github.com/lamualfa/routify-ts) - Use Typescript in Routify Project.
34 | - [routify-twind](https://github.com/lamualfa/routify-twind) - Use Twind (_Tailwind CSS in JS version_) in Routify.
35 | - [routify-windi](https://github.com/lamualfa/routify-windi) - Use Windi CSS (_Next generation of Tailwind CSS compiler_) in Routify.
36 | - [routify-carbon](https://github.com/lamualfa/routify-carbon) - Use IBM Carbon Framework in Routify.
37 | - [routify-vite](https://github.com/lamualfa/routify-vite) Use Vite (_Next Generation Frontend Tooling_) in Routify.
38 | - [routify-vite-ts](https://github.com/lamualfa/routify-vite-ts) Use Vite (_Next Generation Frontend Tooling_) & Typescript in Routify.
39 |
40 |
--------------------------------------------------------------------------------
/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "svelte-app",
3 | "version": "1.0.0",
4 | "@comments scripts": {
5 | "dev": "develop with blazing fast rebuilds",
6 | "dev:features": "develop with features like SSR and serviceworker enabled",
7 | "build": "run build scripts below",
8 | "build:app": "build single page application (SPA)",
9 | "build:static": "Generate static pages",
10 | "serve": "serve content in 'dist' folder",
11 | "rollup": "run the rollup bundler",
12 | "nollup": "run the nollup no-bundler",
13 | "routify": "run routify"
14 | },
15 | "scripts": {
16 | "dev": "run-p routify nollup",
17 | "dev:ssr": "run-p routify rollup",
18 | "build": "run-s build:*",
19 | "build:app": "routify -b && rollup -c",
20 | "build:static": "spank",
21 | "serve": "spassr --ssr",
22 | "rollup": "rollup -cw",
23 | "nollup": "nollup -c",
24 | "routify": "routify"
25 | },
26 | "devDependencies": {
27 | "@rollup/plugin-commonjs": "^15.0.0",
28 | "@rollup/plugin-node-resolve": "^10.0.0",
29 | "@roxi/routify": "^2.8.5",
30 | "cross-env": "^7.0.3",
31 | "fs-extra": "^9.0.1",
32 | "nollup": "^0.13.13",
33 | "npm-run-all": "^4.1.5",
34 | "postcss": "^8.2.1",
35 | "postcss-import": "^14.0.0",
36 | "postcss-load-config": "^3.0.0",
37 | "postcss-preset-env": "^6.7.0",
38 | "rollup": "^2.33.1",
39 | "rollup-plugin-hot": "^0.1.1",
40 | "rollup-plugin-inject-process-env": "^1.3.1",
41 | "rollup-plugin-livereload": "^2.0.0",
42 | "rollup-plugin-svelte": "^6.1.0",
43 | "rollup-plugin-svelte-hot": "^0.11.1",
44 | "rollup-plugin-terser": "^7.0.2",
45 | "rollup-plugin-workbox": "^5.2.1",
46 | "spank": "^1.4.0",
47 | "spassr": "^2.1.6",
48 | "svelte": "^3.29.4",
49 | "svelte-preprocess": "^4.5.2",
50 | "tailwindcss": "^2.0.2",
51 | "tossr": "^1.3.1"
52 | },
53 | "routify": {
54 | "extensions": "svelte,html,svx,md"
55 | },
56 | "spassr": {
57 | "assetsDir": [
58 | "dist",
59 | "assets"
60 | ],
61 | "script": "dist/build/main.js",
62 | "ssrOptions": {
63 | "inlineDynamicImports": true
64 | }
65 | },
66 | "spank": {
67 | "blacklist": [
68 | "/example/modal/basic/4"
69 | ]
70 | }
71 | }
72 |
--------------------------------------------------------------------------------
/rollup.config.js:
--------------------------------------------------------------------------------
1 | import svelte from 'rollup-plugin-svelte-hot';
2 | import Hmr from 'rollup-plugin-hot'
3 | import resolve from '@rollup/plugin-node-resolve';
4 | import commonjs from '@rollup/plugin-commonjs';
5 | import livereload from 'rollup-plugin-livereload';
6 | import { terser } from 'rollup-plugin-terser';
7 | import { copySync, removeSync } from 'fs-extra'
8 | import { spassr } from 'spassr'
9 | import getConfig from '@roxi/routify/lib/utils/config'
10 | import autoPreprocess from 'svelte-preprocess'
11 | import { injectManifest } from 'rollup-plugin-workbox'
12 | import injectProcessEnv from 'rollup-plugin-inject-process-env';
13 |
14 |
15 | const { distDir } = getConfig() // use Routify's distDir for SSOT
16 | const assetsDir = 'assets'
17 | const buildDir = `dist/build`
18 | const isNollup = !!process.env.NOLLUP
19 | const production = !process.env.ROLLUP_WATCH;
20 |
21 | // clear previous builds
22 | removeSync(distDir)
23 | removeSync(buildDir)
24 |
25 |
26 | const serve = () => ({
27 | writeBundle: async () => {
28 | const options = {
29 | assetsDir: [assetsDir, distDir],
30 | entrypoint: `${assetsDir}/__app.html`,
31 | script: `${buildDir}/main.js`
32 | }
33 | spassr({ ...options, port: 5000 })
34 | spassr({ ...options, ssr: true, port: 5005, ssrOptions: { inlineDynamicImports: true, dev: true } })
35 | }
36 | })
37 | const copyToDist = () => ({ writeBundle() { copySync(assetsDir, distDir) } })
38 |
39 |
40 | export default {
41 | preserveEntrySignatures: false,
42 | input: [`src/main.js`],
43 | output: {
44 | sourcemap: true,
45 | format: 'esm',
46 | dir: buildDir,
47 | // for performance, disabling filename hashing in development
48 | chunkFileNames: `[name]${(production && '-[hash]') || ''}.js`,
49 | },
50 | plugins: [
51 | svelte({
52 | dev: !production, // run-time checks
53 | // Extract component CSS — better performance
54 | css: (css) => css.write(`bundle.css`),
55 | hot: isNollup,
56 | preprocess: [
57 | autoPreprocess({
58 | postcss: { configFilePath: './postcss.config.js' },
59 | defaults: { style: 'postcss' },
60 | }),
61 | ],
62 | }),
63 |
64 | // resolve matching modules from current working directory
65 | resolve({
66 | browser: true,
67 | dedupe: (importee) => !!importee.match(/svelte(\/|$)/),
68 | }),
69 | commonjs(),
70 |
71 | production && terser(),
72 | !production && !isNollup && serve(),
73 | !production && !isNollup && livereload(distDir), // refresh entire window when code is updated
74 | !production && isNollup && Hmr({ inMemory: true, public: assetsDir }), // refresh only updated code
75 | injectProcessEnv({
76 | NODE_ENV: production ? 'production' : 'development',
77 | }),
78 | injectManifest({
79 | globDirectory: assetsDir,
80 | globPatterns: ['**/*.{js,css,svg}', '__app.html'],
81 | swSrc: `src/sw.js`,
82 | swDest: `dist/serviceworker.js`,
83 | maximumFileSizeToCacheInBytes: 10000000, // 10 MB,
84 | mode: 'production',
85 | }),
86 | production && copyToDist(),
87 | ],
88 | watch: {
89 | clearScreen: false,
90 | buildDelay: 100,
91 | },
92 | };
--------------------------------------------------------------------------------
/assets/404.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/src/sw.js:
--------------------------------------------------------------------------------
1 | // @ts-check
2 |
3 | import { registerRoute, setDefaultHandler, setCatchHandler } from 'workbox-routing';
4 | import { CacheFirst, NetworkFirst, StaleWhileRevalidate } from 'workbox-strategies';
5 | import { skipWaiting, clientsClaim } from 'workbox-core';
6 | import { precacheAndRoute, matchPrecache } from 'workbox-precaching';
7 | import { ExpirationPlugin } from 'workbox-expiration';
8 | import { RoutifyPlugin, freshCacheData } from '@roxi/routify/workbox-plugin'
9 |
10 |
11 |
12 | /**********
13 | * CONFIG *
14 | **********/
15 |
16 | const entrypointUrl = '__app.html' // entrypoint
17 | const fallbackImage = '404.svg'
18 | const files = self.__WB_MANIFEST // files matching globDirectory and globPattern in rollup.config.js
19 |
20 | const externalAssetsConfig = () => ({
21 | cacheName: 'external',
22 | plugins: [
23 | RoutifyPlugin({
24 | validFor: 60 // cache is considered fresh for n seconds.
25 | }),
26 | new ExpirationPlugin({
27 | maxEntries: 50, // last used entries will be purged when we hit this limit
28 | purgeOnQuotaError: true // purge external assets on quota error
29 | })]
30 | })
31 |
32 |
33 |
34 |
35 | /**************
36 | * INITIALIZE *
37 | **************/
38 |
39 | /**
40 | * precache all files
41 | * remember to precache __app.html and 404.svg if caching of all files is disabled
42 | */
43 | precacheAndRoute(files)
44 |
45 | /** precache only fallback files */
46 | // precacheAndRoute(files.filter(file =>
47 | // ['__app.html', '404.svg']
48 | // .includes(file.url)
49 | // ))
50 |
51 | skipWaiting() // auto update service workers across all tabs when new release is available
52 | clientsClaim() // take control of client without having to wait for refresh
53 |
54 | /**
55 | * manually upgrade service worker by sending a SKIP_WAITING message.
56 | * (remember to disable skipWaiting() above)
57 | */
58 | // addEventListener('message', event => { if (event.data && event.data.type === 'SKIP_WAITING') skipWaiting(); });
59 |
60 |
61 |
62 | /**********
63 | * ROUTES *
64 | **********/
65 |
66 | // serve local pages from the SPA entry point (__app.html)
67 | registerRoute(isLocalPage, matchPrecache(entrypointUrl))
68 |
69 | // serve local assets from cache first
70 | registerRoute(isLocalAsset, new CacheFirst())
71 |
72 | // serve external assets from cache if they're fresh
73 | registerRoute(hasFreshCache, new CacheFirst(externalAssetsConfig()))
74 |
75 | // serve external pages and assets
76 | setDefaultHandler(new NetworkFirst(externalAssetsConfig()));
77 |
78 | // serve a fallback for 404s if possible or respond with an error
79 | setCatchHandler(async ({ event }) => {
80 | switch (event.request.destination) {
81 | case 'document':
82 | return await matchPrecache(entrypointUrl)
83 | case 'image':
84 | return await matchPrecache(fallbackImage)
85 | default:
86 | return Response.error();
87 | }
88 | })
89 |
90 |
91 |
92 | /**********
93 | * CONDITIONS *
94 | **********/
95 |
96 | function isLocalAsset({ url, request }) { return url.host === self.location.host && request.destination != 'document' }
97 | function isLocalPage({ url, request }) { return url.host === self.location.host && request.destination === 'document' }
98 | function hasFreshCache(event) { return !!freshCacheData(event) }
99 |
100 | /** Example condition */
101 | function hasWitheringCache(event) {
102 | const cache = freshCacheData(event)
103 | if (cache) {
104 | const { cachedAt, validFor, validLeft, validUntil } = cache
105 | // return true if half the fresh time has passed
106 | return validFor / 2 > validFor - validLeft
107 | }
108 | }
--------------------------------------------------------------------------------