chore: add new demo-static
Some checks are pending
Demo / Explore-CI (push) Waiting to run

This commit is contained in:
ayo 2026-05-15 20:25:36 +02:00
parent c6ba991d12
commit cbe210855e
14 changed files with 266 additions and 0 deletions

View file

@ -0,0 +1,36 @@
// @ts-check
import { defineConfig } from 'astro/config'
import serviceWorker from '@ayco/astro-sw'
// import { deleteOldCaches, staleWhileRevalidate } from '@ayco/astro-sw/presets'
import * as pkg from './package.json'
export default defineConfig({
output: 'static',
site: 'https://ayo.ayco.io',
integrations: [
serviceWorker({
path: './src/sw.ts',
assetCachePrefix: 'AstroSWTest',
assetCacheVersionID: pkg.version,
// presets: [staleWhileRevalidate(), deleteOldCaches()],
exclude: ['/exclude'],
// include: ['/components/web-component.js'],
logAssets: true,
esbuild: {
minify: true,
},
registrationHooks: {
installing: () => console.log('>>> installing...'),
waiting: () => console.log('>>> waiting...'),
active: () => console.log('>>> active...'),
error: (error) => console.error('>>> error', error),
afterRegistration: async () => {
const sw = await navigator.serviceWorker.getRegistration()
console.log('>>> registrered', sw)
},
},
}),
],
})

24
demo-static/package.json Normal file
View file

@ -0,0 +1,24 @@
{
"name": "demo-static",
"private": true,
"version": "1.0.3",
"main": "index.js",
"scripts": {
"start": "astro dev",
"dev": "astro dev",
"build": "astro build",
"build:preview:static": "astro build && astro preview",
"build:preview": "astro build && astro preview"
},
"author": "Ayo Ayco",
"license": "MIT",
"description": "",
"devDependencies": {
"@astrojs/node": "^10.0.4",
"@ayco/astro-sw": "workspace:*",
"@fastify/middie": "^9.3.1",
"@fastify/static": "^9.0.0",
"astro": "^6.1.3",
"fastify": "^5.8.4"
}
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 80 KiB

View file

@ -0,0 +1,14 @@
function register(){
if ('customElements' in window)
window.customElements.define('web-component', WebComponent)
}
class WebComponent extends HTMLElement {
connectedCallback() {
console.log('hello')
}
}
register()
export default WebComponent

Binary file not shown.

After

Width:  |  Height:  |  Size: 15 KiB

View file

@ -0,0 +1 @@
asset

2
demo-static/src/env.d.ts vendored Normal file
View file

@ -0,0 +1,2 @@
/// <reference path="../.astro/types.d.ts" />
/// <reference types="astro/client" />

View file

@ -0,0 +1,5 @@
---
---
404

View file

@ -0,0 +1,17 @@
---
import { type CollectionEntry, getCollection } from 'astro:content'
export async function getStaticPaths() {
const posts = await getCollection('blog')
return posts.map((post) => ({
params: { slug: post.slug },
props: post,
}))
}
type Props = CollectionEntry<'blog'>
const post = Astro.props
const { Content } = await post.render()
---
<Content />

View file

@ -0,0 +1,7 @@
---
---
blog index
<a href="/blog/building-a-cozy-web">post</a>

View file

@ -0,0 +1,5 @@
---
---
exclude

View file

@ -0,0 +1,15 @@
---
// export const prerender = false
---
<!doctype html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Hello</title>
<script type="module" src="components/web-component.js"></script>
</head>
<body> Hello </body><web-component></web-component>
</html>
<!-- <Fragment set:html={content} /> -->

135
demo-static/src/sw.ts Normal file
View file

@ -0,0 +1,135 @@
/**
* Note: @ayco/astro-sw integration injects variables `__prefix`, `__version`, & `__assets`
* -- find usage in `astro.config.mjs` integrations
* @see https://ayco.io/n/@ayco/astro-sw
*/
const cacheName = `${__prefix ?? 'app'}-v${__version ?? '000'}`
const forceLogging = true
/**
* Cleans up old service worker caches by deleting any cache that doesn't match the current cache name.
* This ensures only the current version of the application's cache is retained.
* @async
* @function cleanOldCaches
* @returns {Promise<void>} A promise that resolves when old caches have been deleted
*/
const cleanOldCaches = async () => {
const allowCacheNames = [cacheName]
const allCaches = await caches.keys()
allCaches.forEach((key) => {
if (!allowCacheNames.includes(key)) {
console.info('Deleting old cache', key)
caches
.delete(key)
.then(() => {
console.info('Successfully deleted cache:', key)
})
.catch((error) => {
console.warn('Failed to delete old cache:', key, error)
})
}
})
}
/**
* Adds specified resources to the service worker cache.
* This function is used to cache static assets for offline access.
* @async
* @function addResourcesToCache
* @param {Array<string>} resources - An array of URLs representing the resources to be cached.
* @returns {Promise<void>} A promise that resolves when all resources have been successfully added to the cache.
*/
const addResourcesToCache = async (resources) => {
const cache = await caches.open(cacheName)
console.info('adding resources to cache...', {
force: !!forceLogging,
context: 'ayco-sw',
data: resources,
})
try {
await cache.addAll(resources)
} catch (error) {
console.error(
'failed to add resources to cache; make sure requests exists and that there are no duplicates',
error
)
}
}
/**
* Puts a response in the cache.
* @async
* @function putInCache
* @param {Request} request - The request to be cached.
* @param {Response} response - The response to be cached.
* @returns {Promise<void>} A promise that resolves when the response has been added to the cache.
*/
const putInCache = async (request, response) => {
const cache = await caches.open(cacheName)
if (response.ok) {
console.info('adding one response to cache...', request.url)
cache.put(request, response)
}
}
const networkFirst = async ({ request, fallbackUrl }) => {
const cache = await caches.open(cacheName)
try {
// Try to get the resource from the network for 5 seconds
const responseFromNetwork = await fetch(request.clone())
putInCache(request, responseFromNetwork.clone())
console.info('using network response', responseFromNetwork.url)
return responseFromNetwork
// eslint-disable-next-line @typescript-eslint/no-unused-vars
} catch (error) {
// Try get the resource from the cache
const responseFromCache = await cache.match(request)
if (responseFromCache) {
console.info('using cached response...', responseFromCache.url)
return responseFromCache
}
// If fallback is provided, try to use it, otherwise return error
if (fallbackUrl) {
const fallbackResponse = await cache.match(fallbackUrl)
if (fallbackResponse) {
console.info('using fallback cached response...', fallbackResponse.url)
return fallbackResponse
}
}
// when even the fallback response is not available,
// there is nothing we can do, but we must always
// return a Response object
return new Response('Network error happened', {
status: 408,
headers: { 'Content-Type': 'text/plain' },
})
}
}
// eslint-disable-next-line @typescript-eslint/no-unused-vars
self.addEventListener('activate', (event) => {
console.info('activating service worker...')
cleanOldCaches()
})
self.addEventListener('install', (event) => {
console.info('installing service worker...')
self.skipWaiting() // go straight to activate
event.waitUntil(addResourcesToCache(__assets ?? []))
})
self.addEventListener('fetch', (event) => {
console.info('fetch happened', { data: event })
event.respondWith(
networkFirst({
request: event.request,
fallbackUrl: './',
})
)
})

View file

@ -0,0 +1,5 @@
{
"extends": "astro/tsconfigs/strict",
"include": [".astro/types.d.ts", "**/*"],
"exclude": ["dist"]
}