chore: set up prettier & format code
This commit is contained in:
parent
e174121ab3
commit
75b29eddc5
17 changed files with 379 additions and 290 deletions
7
.prettierignore
Normal file
7
.prettierignore
Normal file
|
@ -0,0 +1,7 @@
|
||||||
|
# someday let's think about formatting html
|
||||||
|
**/*.html
|
||||||
|
|
||||||
|
**/*.md
|
||||||
|
**/*.css
|
||||||
|
**/*.yml
|
||||||
|
**/*.yaml
|
324
astro-sw.js
324
astro-sw.js
|
@ -3,12 +3,12 @@
|
||||||
* @author Ayo Ayco <https://ayo.ayco.io>
|
* @author Ayo Ayco <https://ayo.ayco.io>
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import { readFile, writeFile, readdir, unlink } from 'node:fs/promises';
|
import { readFile, writeFile, readdir, unlink } from 'node:fs/promises'
|
||||||
import { fileURLToPath } from 'node:url';
|
import { fileURLToPath } from 'node:url'
|
||||||
import { resolve, dirname, join } from 'node:path';
|
import { resolve, dirname, join } from 'node:path'
|
||||||
import { build } from 'esbuild';
|
import { build } from 'esbuild'
|
||||||
|
|
||||||
const ASTROSW = '@ayco/astro-sw';
|
const ASTROSW = '@ayco/astro-sw'
|
||||||
/**
|
/**
|
||||||
* @typedef {import('astro').AstroIntegration} AstroIntegration
|
* @typedef {import('astro').AstroIntegration} AstroIntegration
|
||||||
* @typedef {import('esbuild').BuildOptions} BuildOptions
|
* @typedef {import('esbuild').BuildOptions} BuildOptions
|
||||||
|
@ -41,36 +41,36 @@ const ASTROSW = '@ayco/astro-sw';
|
||||||
* waitFn: () => void,
|
* waitFn: () => void,
|
||||||
* }
|
* }
|
||||||
* }
|
* }
|
||||||
* }} options
|
* }} options
|
||||||
* @returns {AstroIntegration}
|
* @returns {AstroIntegration}
|
||||||
*/
|
*/
|
||||||
export default function serviceWorker(options) {
|
export default function serviceWorker(options) {
|
||||||
let {
|
let {
|
||||||
assetCachePrefix = ASTROSW,
|
assetCachePrefix = ASTROSW,
|
||||||
assetCacheVersionID = '0',
|
assetCacheVersionID = '0',
|
||||||
path: serviceWorkerPath = undefined,
|
path: serviceWorkerPath = undefined,
|
||||||
customRoutes = [],
|
customRoutes = [],
|
||||||
excludeRoutes = [],
|
excludeRoutes = [],
|
||||||
logAssets = false,
|
logAssets = false,
|
||||||
esbuild = {},
|
esbuild = {},
|
||||||
registrationHooks = {}
|
registrationHooks = {},
|
||||||
} = options || {};
|
} = options || {}
|
||||||
|
|
||||||
const {
|
const {
|
||||||
installing: installingFn = () => { },
|
installing: installingFn = () => {},
|
||||||
waiting: waitingFn = () => { },
|
waiting: waitingFn = () => {},
|
||||||
active: activeFn = () => { },
|
active: activeFn = () => {},
|
||||||
error: errorFn = () => { },
|
error: errorFn = () => {},
|
||||||
unsupported: unsupportedFn = () => { },
|
unsupported: unsupportedFn = () => {},
|
||||||
afterRegistration: afterRegistrationFn = () => { },
|
afterRegistration: afterRegistrationFn = () => {},
|
||||||
} = registrationHooks;
|
} = registrationHooks
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @type {Array<string>}
|
* @type {Array<string>}
|
||||||
*/
|
*/
|
||||||
let assets = [];
|
let assets = []
|
||||||
|
|
||||||
const registrationScript = `const registerSW = async () => {
|
const registrationScript = `const registerSW = async () => {
|
||||||
if ("serviceWorker" in navigator) {
|
if ("serviceWorker" in navigator) {
|
||||||
try {
|
try {
|
||||||
const registration = await navigator.serviceWorker.register("/sw.js", {
|
const registration = await navigator.serviceWorker.register("/sw.js", {
|
||||||
|
@ -95,145 +95,161 @@ export default function serviceWorker(options) {
|
||||||
|
|
||||||
registerSW();`
|
registerSW();`
|
||||||
|
|
||||||
let output = 'static';
|
let output = 'static'
|
||||||
const __dirname = resolve(dirname('.'));
|
const __dirname = resolve(dirname('.'))
|
||||||
|
|
||||||
return {
|
return {
|
||||||
'name': ASTROSW,
|
name: ASTROSW,
|
||||||
'hooks': {
|
hooks: {
|
||||||
'astro:config:setup': async ({ injectScript, config: _config, command, logger }) => {
|
'astro:config:setup': async ({
|
||||||
|
injectScript,
|
||||||
|
config: _config,
|
||||||
|
command,
|
||||||
|
logger,
|
||||||
|
}) => {
|
||||||
|
if (!serviceWorkerPath || serviceWorkerPath === '') {
|
||||||
|
// REQUIRED OPTION IS MISSING
|
||||||
|
logger.error('Missing required path to service worker script')
|
||||||
|
}
|
||||||
|
// const transformedScript=await transform(registrationScript)
|
||||||
|
|
||||||
if (!serviceWorkerPath || serviceWorkerPath === '') {
|
output = _config.output
|
||||||
// REQUIRED OPTION IS MISSING
|
if (command === 'build') {
|
||||||
logger.error('Missing required path to service worker script');
|
injectScript('page', registrationScript)
|
||||||
}
|
}
|
||||||
// const transformedScript=await transform(registrationScript)
|
},
|
||||||
|
'astro:config:done': async ({ injectTypes, logger }) => {
|
||||||
output = _config.output;
|
let injectedTypes = `
|
||||||
if (command === 'build') {
|
|
||||||
injectScript('page', registrationScript);
|
|
||||||
}
|
|
||||||
},
|
|
||||||
'astro:config:done': async ({ injectTypes, logger }) => {
|
|
||||||
let injectedTypes = `
|
|
||||||
declare const __assets: string[];
|
declare const __assets: string[];
|
||||||
declare const __version: string;
|
declare const __version: string;
|
||||||
declare const __prefix: string;`
|
declare const __prefix: string;`
|
||||||
injectTypes({ filename: 'caching.d.ts', content: injectedTypes })
|
injectTypes({ filename: 'caching.d.ts', content: injectedTypes })
|
||||||
},
|
},
|
||||||
'astro:build:ssr': ({ manifest }) => {
|
'astro:build:ssr': ({ manifest }) => {
|
||||||
assets = manifest.assets
|
assets = manifest.assets
|
||||||
},
|
},
|
||||||
'astro:build:done': async ({ dir, routes, pages, logger }) => {
|
'astro:build:done': async ({ dir, routes, pages, logger }) => {
|
||||||
const outfile = fileURLToPath(new URL('./sw.js', dir));
|
const outfile = fileURLToPath(new URL('./sw.js', dir))
|
||||||
const swPath = (serviceWorkerPath && serviceWorkerPath !== '')
|
const swPath =
|
||||||
? join(__dirname, serviceWorkerPath)
|
serviceWorkerPath && serviceWorkerPath !== ''
|
||||||
: undefined;
|
? join(__dirname, serviceWorkerPath)
|
||||||
let originalScript;
|
: undefined
|
||||||
|
let originalScript
|
||||||
|
|
||||||
const _publicFiles = (await readdir(dir, { withFileTypes: true }) ?? [])
|
const _publicFiles = (
|
||||||
.filter(dirent => dirent.isFile())
|
(await readdir(dir, { withFileTypes: true })) ?? []
|
||||||
.map(dirent => `/${dirent.name}`);
|
)
|
||||||
|
.filter((dirent) => dirent.isFile())
|
||||||
|
.map((dirent) => `/${dirent.name}`)
|
||||||
|
|
||||||
const _routes = routes
|
const _routes =
|
||||||
.filter(({ isIndex }) => isIndex)
|
routes
|
||||||
.flatMap(({ pathname }) => pathname === '/' ? pathname : [pathname, `${pathname}/`])
|
.filter(({ isIndex }) => isIndex)
|
||||||
.filter(pathname => pathname !== '')
|
.flatMap(({ pathname }) =>
|
||||||
?? [];
|
pathname === '/' ? pathname : [pathname, `${pathname}/`]
|
||||||
|
)
|
||||||
|
.filter((pathname) => pathname !== '') ?? []
|
||||||
|
|
||||||
const _pages = pages
|
const _pages =
|
||||||
.filter(({ pathname }) => pathname !== '')
|
pages
|
||||||
.map(({ pathname }) => `/${pathname}`)
|
.filter(({ pathname }) => pathname !== '')
|
||||||
?? [];
|
.map(({ pathname }) => `/${pathname}`) ?? []
|
||||||
|
|
||||||
const _pagesWithoutEndSlash = pages
|
const _pagesWithoutEndSlash =
|
||||||
.filter(({ pathname }) => pathname !== '')
|
pages
|
||||||
.map(({ pathname }) => {
|
.filter(({ pathname }) => pathname !== '')
|
||||||
const lastChar = pathname.slice(-1);
|
.map(({ pathname }) => {
|
||||||
const len = pathname.length;
|
const lastChar = pathname.slice(-1)
|
||||||
return lastChar === '/'
|
const len = pathname.length
|
||||||
? `/${pathname.slice(0, len - 1)}`
|
return lastChar === '/'
|
||||||
: `/${pathname}`;
|
? `/${pathname.slice(0, len - 1)}`
|
||||||
})
|
: `/${pathname}`
|
||||||
.filter(pathname => pathname !== '')
|
})
|
||||||
?? [];
|
.filter((pathname) => pathname !== '') ?? []
|
||||||
|
|
||||||
const _excludeRoutes = [
|
const _excludeRoutes = [
|
||||||
...excludeRoutes,
|
...excludeRoutes,
|
||||||
...excludeRoutes.map(route => `${route}/`)
|
...excludeRoutes.map((route) => `${route}/`),
|
||||||
];
|
]
|
||||||
|
|
||||||
assets = [...new Set([
|
assets = [
|
||||||
...assets,
|
...new Set([
|
||||||
..._routes,
|
...assets,
|
||||||
..._pages,
|
..._routes,
|
||||||
..._pagesWithoutEndSlash,
|
..._pages,
|
||||||
...customRoutes,
|
..._pagesWithoutEndSlash,
|
||||||
..._publicFiles
|
...customRoutes,
|
||||||
])].filter(asset => !!asset
|
..._publicFiles,
|
||||||
&& asset !== ''
|
]),
|
||||||
&& !asset.includes('404')
|
].filter(
|
||||||
&& !asset.includes('index.html')
|
(asset) =>
|
||||||
&& !_excludeRoutes.includes(asset)
|
!!asset &&
|
||||||
);
|
asset !== '' &&
|
||||||
|
!asset.includes('404') &&
|
||||||
|
!asset.includes('index.html') &&
|
||||||
|
!_excludeRoutes.includes(asset)
|
||||||
|
)
|
||||||
|
|
||||||
|
if (logAssets) {
|
||||||
|
logger.info(
|
||||||
|
`${assets.length} assets for caching: \n ▶ ${assets.toString().replaceAll(',', '\n ▶ ')}\n`
|
||||||
|
)
|
||||||
|
} else {
|
||||||
|
logger.info(`${assets.length} assets for caching.`)
|
||||||
|
}
|
||||||
|
|
||||||
if (logAssets) {
|
try {
|
||||||
logger.info(`${assets.length} assets for caching: \n ▶ ${assets.toString().replaceAll(',', '\n ▶ ')}\n`);
|
logger.info(`Using service worker in path: ${swPath}`)
|
||||||
} else {
|
originalScript = await readFile(swPath)
|
||||||
logger.info(`${assets.length} assets for caching.`);
|
} catch {
|
||||||
}
|
logger.error(`Service worker script not found! ${swPath}`)
|
||||||
|
if (!swPath) {
|
||||||
try {
|
logger.error(`
|
||||||
logger.info(`Using service worker in path: ${swPath}`);
|
|
||||||
originalScript = await readFile(swPath);
|
|
||||||
} catch {
|
|
||||||
logger.error(`Service worker script not found! ${swPath}`)
|
|
||||||
if (!swPath) {
|
|
||||||
|
|
||||||
logger.error(`
|
|
||||||
|
|
||||||
[${ASTROSW}] ERR: The 'path' option is required!
|
[${ASTROSW}] ERR: The 'path' option is required!
|
||||||
[${ASTROSW}] INFO: Please see service worker options in https://ayco.io/gh/astro-sw#readme
|
[${ASTROSW}] INFO: Please see service worker options in https://ayco.io/gh/astro-sw#readme
|
||||||
`);
|
`)
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
const assetsDeclaration = `const __assets = ${JSON.stringify(assets)};\n`;
|
|
||||||
const versionDeclaration = `const __version = ${JSON.stringify(assetCacheVersionID)};\n`;
|
|
||||||
const prefixDeclaration = `const __prefix = ${JSON.stringify(assetCachePrefix)};\n`;
|
|
||||||
|
|
||||||
const tempFile = `${swPath}.tmp.ts`;
|
|
||||||
|
|
||||||
try {
|
|
||||||
await writeFile(
|
|
||||||
tempFile,
|
|
||||||
assetsDeclaration + versionDeclaration + prefixDeclaration + originalScript,
|
|
||||||
{ flag: 'w+' }
|
|
||||||
);
|
|
||||||
} catch (err) {
|
|
||||||
logger.error(err.toString())
|
|
||||||
}
|
|
||||||
|
|
||||||
try {
|
|
||||||
await build({
|
|
||||||
bundle: true,
|
|
||||||
...esbuild,
|
|
||||||
outfile,
|
|
||||||
platform: 'browser',
|
|
||||||
entryPoints: [tempFile],
|
|
||||||
})
|
|
||||||
} catch (err) {
|
|
||||||
logger.error(err.toString())
|
|
||||||
}
|
|
||||||
|
|
||||||
// remove temp file
|
|
||||||
try {
|
|
||||||
await unlink(tempFile);
|
|
||||||
} catch (err) {
|
|
||||||
logger.error(err.toString())
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
|
||||||
};
|
const assetsDeclaration = `const __assets = ${JSON.stringify(assets)};\n`
|
||||||
|
const versionDeclaration = `const __version = ${JSON.stringify(assetCacheVersionID)};\n`
|
||||||
|
const prefixDeclaration = `const __prefix = ${JSON.stringify(assetCachePrefix)};\n`
|
||||||
|
|
||||||
|
const tempFile = `${swPath}.tmp.ts`
|
||||||
|
|
||||||
|
try {
|
||||||
|
await writeFile(
|
||||||
|
tempFile,
|
||||||
|
assetsDeclaration +
|
||||||
|
versionDeclaration +
|
||||||
|
prefixDeclaration +
|
||||||
|
originalScript,
|
||||||
|
{ flag: 'w+' }
|
||||||
|
)
|
||||||
|
} catch (err) {
|
||||||
|
logger.error(err.toString())
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
await build({
|
||||||
|
bundle: true,
|
||||||
|
...esbuild,
|
||||||
|
outfile,
|
||||||
|
platform: 'browser',
|
||||||
|
entryPoints: [tempFile],
|
||||||
|
})
|
||||||
|
} catch (err) {
|
||||||
|
logger.error(err.toString())
|
||||||
|
}
|
||||||
|
|
||||||
|
// remove temp file
|
||||||
|
try {
|
||||||
|
await unlink(tempFile)
|
||||||
|
} catch (err) {
|
||||||
|
logger.error(err.toString())
|
||||||
|
}
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -1,13 +1,13 @@
|
||||||
// @ts-check
|
// @ts-check
|
||||||
|
|
||||||
import { defineConfig } from "astro/config";
|
import { defineConfig } from 'astro/config'
|
||||||
import node from "@astrojs/node";
|
import node from '@astrojs/node'
|
||||||
import serviceWorker from "./astro-sw.js";
|
import serviceWorker from './astro-sw.js'
|
||||||
|
|
||||||
export default defineConfig({
|
export default defineConfig({
|
||||||
output: "hybrid",
|
output: 'hybrid',
|
||||||
adapter: node({
|
adapter: node({
|
||||||
mode: "middleware"
|
mode: 'middleware',
|
||||||
}),
|
}),
|
||||||
site: 'https://ayo.ayco.io',
|
site: 'https://ayo.ayco.io',
|
||||||
integrations: [
|
integrations: [
|
||||||
|
@ -16,23 +16,21 @@ export default defineConfig({
|
||||||
customRoutes: [
|
customRoutes: [
|
||||||
// '/threads'
|
// '/threads'
|
||||||
],
|
],
|
||||||
excludeRoutes: [
|
excludeRoutes: ['/exclude'],
|
||||||
'/exclude'
|
|
||||||
],
|
|
||||||
logAssets: true,
|
logAssets: true,
|
||||||
esbuild: {
|
esbuild: {
|
||||||
minify: true
|
minify: true,
|
||||||
},
|
},
|
||||||
registrationHooks: {
|
registrationHooks: {
|
||||||
installing: () => console.log('>>> installing...'),
|
installing: () => console.log('>>> installing...'),
|
||||||
waiting: () => console.log('>>> waiting...'),
|
waiting: () => console.log('>>> waiting...'),
|
||||||
active: () => console.log('>>> active...'),
|
active: () => console.log('>>> active...'),
|
||||||
error: (error) => console.error('>>> error', error),
|
error: (error) => console.error('>>> error', error),
|
||||||
'afterRegistration': async () => {
|
afterRegistration: async () => {
|
||||||
const sw = await navigator.serviceWorker.getRegistration();
|
const sw = await navigator.serviceWorker.getRegistration()
|
||||||
console.log('>>> registrered', sw)
|
console.log('>>> registrered', sw)
|
||||||
}
|
},
|
||||||
},
|
},
|
||||||
})
|
}),
|
||||||
]
|
],
|
||||||
});
|
})
|
||||||
|
|
|
@ -2,4 +2,4 @@ export default {
|
||||||
__prefix: false,
|
__prefix: false,
|
||||||
__version: false,
|
__version: false,
|
||||||
__assets: false,
|
__assets: false,
|
||||||
};
|
}
|
||||||
|
|
|
@ -25,7 +25,8 @@
|
||||||
"build": "astro build",
|
"build": "astro build",
|
||||||
"build:preview:static": "astro build && astro preview",
|
"build:preview:static": "astro build && astro preview",
|
||||||
"build:preview": "astro build && node ./server.mjs",
|
"build:preview": "astro build && node ./server.mjs",
|
||||||
"test": "echo \"Error: no test specified\" && exit 1"
|
"test": "echo \"Error: no test specified\" && exit 1",
|
||||||
|
"format": "prettier . --write"
|
||||||
},
|
},
|
||||||
"keywords": [
|
"keywords": [
|
||||||
"withastro",
|
"withastro",
|
||||||
|
@ -38,7 +39,9 @@
|
||||||
"@fastify/middie": "^8.3.1",
|
"@fastify/middie": "^8.3.1",
|
||||||
"@fastify/static": "^7.0.4",
|
"@fastify/static": "^7.0.4",
|
||||||
"astro": "^4.15.2",
|
"astro": "^4.15.2",
|
||||||
"fastify": "^4.28.1"
|
"fastify": "^4.28.1",
|
||||||
|
"prettier": "^3.4.2",
|
||||||
|
"prettier-plugin-astro": "^0.14.1"
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"esbuild": "^0.23.1"
|
"esbuild": "^0.23.1"
|
||||||
|
|
|
@ -27,6 +27,12 @@ importers:
|
||||||
fastify:
|
fastify:
|
||||||
specifier: ^4.28.1
|
specifier: ^4.28.1
|
||||||
version: 4.28.1
|
version: 4.28.1
|
||||||
|
prettier:
|
||||||
|
specifier: ^3.4.2
|
||||||
|
version: 3.4.2
|
||||||
|
prettier-plugin-astro:
|
||||||
|
specifier: ^0.14.1
|
||||||
|
version: 0.14.1
|
||||||
|
|
||||||
packages:
|
packages:
|
||||||
|
|
||||||
|
@ -1668,6 +1674,15 @@ packages:
|
||||||
resolution: {integrity: sha512-gYBeFTZLu055D8Vv3cSPox/0iTPtkzxpLroSYYA7WXgRi31WCJ51Uyl8ZiPeUUjyvs2MBzK+S8v9JVUgHU/Sqw==}
|
resolution: {integrity: sha512-gYBeFTZLu055D8Vv3cSPox/0iTPtkzxpLroSYYA7WXgRi31WCJ51Uyl8ZiPeUUjyvs2MBzK+S8v9JVUgHU/Sqw==}
|
||||||
engines: {node: '>=18.12'}
|
engines: {node: '>=18.12'}
|
||||||
|
|
||||||
|
prettier-plugin-astro@0.14.1:
|
||||||
|
resolution: {integrity: sha512-RiBETaaP9veVstE4vUwSIcdATj6dKmXljouXc/DDNwBSPTp8FRkLGDSGFClKsAFeeg+13SB0Z1JZvbD76bigJw==}
|
||||||
|
engines: {node: ^14.15.0 || >=16.0.0}
|
||||||
|
|
||||||
|
prettier@3.4.2:
|
||||||
|
resolution: {integrity: sha512-e9MewbtFo+Fevyuxn/4rrcDAaq0IYxPGLvObpQjiZBMAzB9IGmzlnG9RZy3FFas+eBMu2vA0CszMeduow5dIuQ==}
|
||||||
|
engines: {node: '>=14'}
|
||||||
|
hasBin: true
|
||||||
|
|
||||||
prismjs@1.29.0:
|
prismjs@1.29.0:
|
||||||
resolution: {integrity: sha512-Kx/1w86q/epKcmte75LNrEoT+lX8pBpavuAbvJWRXar7Hz8jrtF+e3vY751p0R8H9HdArwaCTNDDzHg/ScJK1Q==}
|
resolution: {integrity: sha512-Kx/1w86q/epKcmte75LNrEoT+lX8pBpavuAbvJWRXar7Hz8jrtF+e3vY751p0R8H9HdArwaCTNDDzHg/ScJK1Q==}
|
||||||
engines: {node: '>=6'}
|
engines: {node: '>=6'}
|
||||||
|
@ -1778,6 +1793,9 @@ packages:
|
||||||
run-parallel@1.2.0:
|
run-parallel@1.2.0:
|
||||||
resolution: {integrity: sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA==}
|
resolution: {integrity: sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA==}
|
||||||
|
|
||||||
|
s.color@0.0.15:
|
||||||
|
resolution: {integrity: sha512-AUNrbEUHeKY8XsYr/DYpl+qk5+aM+DChopnWOPEzn8YKzOhv4l2zH6LzZms3tOZP3wwdOyc0RmTciyi46HLIuA==}
|
||||||
|
|
||||||
safe-buffer@5.2.1:
|
safe-buffer@5.2.1:
|
||||||
resolution: {integrity: sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==}
|
resolution: {integrity: sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==}
|
||||||
|
|
||||||
|
@ -1788,6 +1806,9 @@ packages:
|
||||||
resolution: {integrity: sha512-b3rppTKm9T+PsVCBEOUR46GWI7fdOs00VKZ1+9c1EWDaDMvjQc6tUwuFyIprgGgTcWoVHSKrU8H31ZHA2e0RHA==}
|
resolution: {integrity: sha512-b3rppTKm9T+PsVCBEOUR46GWI7fdOs00VKZ1+9c1EWDaDMvjQc6tUwuFyIprgGgTcWoVHSKrU8H31ZHA2e0RHA==}
|
||||||
engines: {node: '>=10'}
|
engines: {node: '>=10'}
|
||||||
|
|
||||||
|
sass-formatter@0.7.9:
|
||||||
|
resolution: {integrity: sha512-CWZ8XiSim+fJVG0cFLStwDvft1VI7uvXdCNJYXhDvowiv+DsbD1nXLiQ4zrE5UBvj5DWZJ93cwN0NX5PMsr1Pw==}
|
||||||
|
|
||||||
section-matter@1.0.0:
|
section-matter@1.0.0:
|
||||||
resolution: {integrity: sha512-vfD3pmTzGpufjScBh50YHKzEu2lxBWhVEHsNGoEXmCmn2hKGfeNLYMzCJpe8cD7gqX7TJluOVpBkAequ6dgMmA==}
|
resolution: {integrity: sha512-vfD3pmTzGpufjScBh50YHKzEu2lxBWhVEHsNGoEXmCmn2hKGfeNLYMzCJpe8cD7gqX7TJluOVpBkAequ6dgMmA==}
|
||||||
engines: {node: '>=4'}
|
engines: {node: '>=4'}
|
||||||
|
@ -1901,6 +1922,9 @@ packages:
|
||||||
resolution: {integrity: sha512-vavAMRXOgBVNF6nyEEmL3DBK19iRpDcoIwW+swQ+CbGiu7lju6t+JklA1MHweoWtadgt4ISVUsXLyDq34ddcwA==}
|
resolution: {integrity: sha512-vavAMRXOgBVNF6nyEEmL3DBK19iRpDcoIwW+swQ+CbGiu7lju6t+JklA1MHweoWtadgt4ISVUsXLyDq34ddcwA==}
|
||||||
engines: {node: '>=4'}
|
engines: {node: '>=4'}
|
||||||
|
|
||||||
|
suf-log@2.5.3:
|
||||||
|
resolution: {integrity: sha512-KvC8OPjzdNOe+xQ4XWJV2whQA0aM1kGVczMQ8+dStAO6KfEB140JEVQ9dE76ONZ0/Ylf67ni4tILPJB41U0eow==}
|
||||||
|
|
||||||
supports-color@5.5.0:
|
supports-color@5.5.0:
|
||||||
resolution: {integrity: sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==}
|
resolution: {integrity: sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==}
|
||||||
engines: {node: '>=4'}
|
engines: {node: '>=4'}
|
||||||
|
@ -3911,6 +3935,14 @@ snapshots:
|
||||||
find-yarn-workspace-root2: 1.2.16
|
find-yarn-workspace-root2: 1.2.16
|
||||||
which-pm: 3.0.0
|
which-pm: 3.0.0
|
||||||
|
|
||||||
|
prettier-plugin-astro@0.14.1:
|
||||||
|
dependencies:
|
||||||
|
'@astrojs/compiler': 2.10.3
|
||||||
|
prettier: 3.4.2
|
||||||
|
sass-formatter: 0.7.9
|
||||||
|
|
||||||
|
prettier@3.4.2: {}
|
||||||
|
|
||||||
prismjs@1.29.0: {}
|
prismjs@1.29.0: {}
|
||||||
|
|
||||||
process-warning@3.0.0: {}
|
process-warning@3.0.0: {}
|
||||||
|
@ -4077,6 +4109,8 @@ snapshots:
|
||||||
dependencies:
|
dependencies:
|
||||||
queue-microtask: 1.2.3
|
queue-microtask: 1.2.3
|
||||||
|
|
||||||
|
s.color@0.0.15: {}
|
||||||
|
|
||||||
safe-buffer@5.2.1: {}
|
safe-buffer@5.2.1: {}
|
||||||
|
|
||||||
safe-regex2@3.1.0:
|
safe-regex2@3.1.0:
|
||||||
|
@ -4085,6 +4119,10 @@ snapshots:
|
||||||
|
|
||||||
safe-stable-stringify@2.5.0: {}
|
safe-stable-stringify@2.5.0: {}
|
||||||
|
|
||||||
|
sass-formatter@0.7.9:
|
||||||
|
dependencies:
|
||||||
|
suf-log: 2.5.3
|
||||||
|
|
||||||
section-matter@1.0.0:
|
section-matter@1.0.0:
|
||||||
dependencies:
|
dependencies:
|
||||||
extend-shallow: 2.0.1
|
extend-shallow: 2.0.1
|
||||||
|
@ -4223,6 +4261,10 @@ snapshots:
|
||||||
|
|
||||||
strip-bom@3.0.0: {}
|
strip-bom@3.0.0: {}
|
||||||
|
|
||||||
|
suf-log@2.5.3:
|
||||||
|
dependencies:
|
||||||
|
s.color: 0.0.15
|
||||||
|
|
||||||
supports-color@5.5.0:
|
supports-color@5.5.0:
|
||||||
dependencies:
|
dependencies:
|
||||||
has-flag: 3.0.0
|
has-flag: 3.0.0
|
||||||
|
|
21
prettier.config.mjs
Normal file
21
prettier.config.mjs
Normal file
|
@ -0,0 +1,21 @@
|
||||||
|
/**
|
||||||
|
* @see https://prettier.io/docs/en/configuration.html
|
||||||
|
* @type {import("prettier").Config}
|
||||||
|
*/
|
||||||
|
const config = {
|
||||||
|
trailingComma: 'es5',
|
||||||
|
tabWidth: 2,
|
||||||
|
semi: false,
|
||||||
|
singleQuote: true,
|
||||||
|
plugins: ['prettier-plugin-astro'],
|
||||||
|
overrides: [
|
||||||
|
{
|
||||||
|
files: '*.astro',
|
||||||
|
options: {
|
||||||
|
parser: 'astro',
|
||||||
|
},
|
||||||
|
},
|
||||||
|
],
|
||||||
|
}
|
||||||
|
|
||||||
|
export default config
|
18
server.mjs
18
server.mjs
|
@ -1,18 +1,18 @@
|
||||||
#!/usr/bin/env node
|
#!/usr/bin/env node
|
||||||
|
|
||||||
import Fastify from 'fastify';
|
import Fastify from 'fastify'
|
||||||
import fastifyMiddie from '@fastify/middie';
|
import fastifyMiddie from '@fastify/middie'
|
||||||
import fastifyStatic from '@fastify/static';
|
import fastifyStatic from '@fastify/static'
|
||||||
import { fileURLToPath } from 'node:url';
|
import { fileURLToPath } from 'node:url'
|
||||||
import { handler as ssrHandler } from './dist/server/entry.mjs';
|
import { handler as ssrHandler } from './dist/server/entry.mjs'
|
||||||
|
|
||||||
const app = Fastify({ logger: true });
|
const app = Fastify({ logger: true })
|
||||||
|
|
||||||
await app
|
await app
|
||||||
.register(fastifyStatic, {
|
.register(fastifyStatic, {
|
||||||
root: fileURLToPath(new URL('./dist/client', import.meta.url)),
|
root: fileURLToPath(new URL('./dist/client', import.meta.url)),
|
||||||
})
|
})
|
||||||
.register(fastifyMiddie);
|
.register(fastifyMiddie)
|
||||||
app.use(ssrHandler);
|
app.use(ssrHandler)
|
||||||
|
|
||||||
app.listen({ port: 4321 });
|
app.listen({ port: 4321 })
|
||||||
|
|
|
@ -1,16 +1,16 @@
|
||||||
import { defineCollection, z } from 'astro:content';
|
import { defineCollection, z } from 'astro:content'
|
||||||
|
|
||||||
const blog = defineCollection({
|
const blog = defineCollection({
|
||||||
type: 'content',
|
type: 'content',
|
||||||
// Type-check frontmatter using a schema
|
// Type-check frontmatter using a schema
|
||||||
schema: z.object({
|
schema: z.object({
|
||||||
title: z.string(),
|
title: z.string(),
|
||||||
description: z.string(),
|
description: z.string(),
|
||||||
// Transform string to Date object
|
// Transform string to Date object
|
||||||
pubDate: z.coerce.date(),
|
pubDate: z.coerce.date(),
|
||||||
updatedDate: z.coerce.date().optional(),
|
updatedDate: z.coerce.date().optional(),
|
||||||
heroImage: z.string().optional(),
|
heroImage: z.string().optional(),
|
||||||
}),
|
}),
|
||||||
});
|
})
|
||||||
|
|
||||||
export const collections = { blog };
|
export const collections = { blog }
|
||||||
|
|
2
src/env.d.ts
vendored
2
src/env.d.ts
vendored
|
@ -1,2 +1,2 @@
|
||||||
/// <reference path="../.astro/types.d.ts" />
|
/// <reference path="../.astro/types.d.ts" />
|
||||||
/// <reference types="astro/client" />
|
/// <reference types="astro/client" />
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
import { log } from "./utils";
|
import { log } from './utils'
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Note: @ayco/astro-sw integration injects variables `__prefix`, `__version`, & `__assets`
|
* Note: @ayco/astro-sw integration injects variables `__prefix`, `__version`, & `__assets`
|
||||||
|
@ -7,88 +7,86 @@ import { log } from "./utils";
|
||||||
*/
|
*/
|
||||||
const cacheName = `${__prefix ?? 'app'}-v${__version ?? '000'}`
|
const cacheName = `${__prefix ?? 'app'}-v${__version ?? '000'}`
|
||||||
const addResourcesToCache = async (resources) => {
|
const addResourcesToCache = async (resources) => {
|
||||||
const cache = await caches.open(cacheName);
|
const cache = await caches.open(cacheName)
|
||||||
console.log('adding resources to cache...', resources)
|
console.log('adding resources to cache...', resources)
|
||||||
await cache.addAll(resources);
|
await cache.addAll(resources)
|
||||||
};
|
}
|
||||||
|
|
||||||
log('test log', {hello: 'world'});
|
log('test log', { hello: 'world' })
|
||||||
|
|
||||||
const putInCache = async (request, response) => {
|
const putInCache = async (request, response) => {
|
||||||
const cache = await caches.open(cacheName);
|
const cache = await caches.open(cacheName)
|
||||||
console.log('adding one response to cache...', request)
|
console.log('adding one response to cache...', request)
|
||||||
await cache.put(request, response);
|
await cache.put(request, response)
|
||||||
};
|
}
|
||||||
|
|
||||||
const cacheFirst = async ({ request, preloadResponsePromise, fallbackUrl }) => {
|
const cacheFirst = async ({ request, preloadResponsePromise, fallbackUrl }) => {
|
||||||
// First try to get the resource from the cache
|
// First try to get the resource from the cache
|
||||||
const responseFromCache = await caches.match(request);
|
const responseFromCache = await caches.match(request)
|
||||||
if (responseFromCache) {
|
if (responseFromCache) {
|
||||||
return responseFromCache;
|
return responseFromCache
|
||||||
}
|
}
|
||||||
|
|
||||||
// Next try to use the preloaded response, if it's there
|
// Next try to use the preloaded response, if it's there
|
||||||
// NOTE: Chrome throws errors regarding preloadResponse, see:
|
// NOTE: Chrome throws errors regarding preloadResponse, see:
|
||||||
// https://bugs.chromium.org/p/chromium/issues/detail?id=1420515
|
// https://bugs.chromium.org/p/chromium/issues/detail?id=1420515
|
||||||
// https://github.com/mdn/dom-examples/issues/145
|
// https://github.com/mdn/dom-examples/issues/145
|
||||||
// To avoid those errors, remove or comment out this block of preloadResponse
|
// To avoid those errors, remove or comment out this block of preloadResponse
|
||||||
// code along with enableNavigationPreload() and the "activate" listener.
|
// code along with enableNavigationPreload() and the "activate" listener.
|
||||||
const preloadResponse = await preloadResponsePromise;
|
const preloadResponse = await preloadResponsePromise
|
||||||
if (preloadResponse) {
|
if (preloadResponse) {
|
||||||
console.info('using preload response', preloadResponse);
|
console.info('using preload response', preloadResponse)
|
||||||
putInCache(request, preloadResponse.clone());
|
putInCache(request, preloadResponse.clone())
|
||||||
return preloadResponse;
|
return preloadResponse
|
||||||
}
|
}
|
||||||
|
|
||||||
// Next try to get the resource from the network
|
// Next try to get the resource from the network
|
||||||
try {
|
try {
|
||||||
const responseFromNetwork = await fetch(request.clone());
|
const responseFromNetwork = await fetch(request.clone())
|
||||||
// response may be used only once
|
// response may be used only once
|
||||||
// we need to save clone to put one copy in cache
|
// we need to save clone to put one copy in cache
|
||||||
// and serve second one
|
// and serve second one
|
||||||
putInCache(request, responseFromNetwork.clone());
|
putInCache(request, responseFromNetwork.clone())
|
||||||
return responseFromNetwork;
|
return responseFromNetwork
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
const fallbackResponse = await caches.match(fallbackUrl);
|
const fallbackResponse = await caches.match(fallbackUrl)
|
||||||
if (fallbackResponse) {
|
if (fallbackResponse) {
|
||||||
return fallbackResponse;
|
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' },
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
};
|
// 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' },
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
const enableNavigationPreload = async () => {
|
const enableNavigationPreload = async () => {
|
||||||
if (self.registration.navigationPreload) {
|
if (self.registration.navigationPreload) {
|
||||||
// Enable navigation preloads!
|
// Enable navigation preloads!
|
||||||
await self.registration.navigationPreload.enable();
|
await self.registration.navigationPreload.enable()
|
||||||
}
|
}
|
||||||
};
|
}
|
||||||
|
|
||||||
self.addEventListener('activate', (event) => {
|
self.addEventListener('activate', (event) => {
|
||||||
console.log('activating...', event)
|
console.log('activating...', event)
|
||||||
event.waitUntil(enableNavigationPreload());
|
event.waitUntil(enableNavigationPreload())
|
||||||
});
|
})
|
||||||
|
|
||||||
self.addEventListener('install', (event) => {
|
self.addEventListener('install', (event) => {
|
||||||
console.log('installing...', event)
|
console.log('installing...', event)
|
||||||
event.waitUntil(
|
event.waitUntil(addResourcesToCache(__assets ?? []))
|
||||||
addResourcesToCache(__assets ?? [])
|
})
|
||||||
);
|
|
||||||
});
|
|
||||||
|
|
||||||
self.addEventListener('fetch', (event) => {
|
self.addEventListener('fetch', (event) => {
|
||||||
console.log('fetch happened', event.request)
|
console.log('fetch happened', event.request)
|
||||||
event.respondWith(
|
event.respondWith(
|
||||||
cacheFirst({
|
cacheFirst({
|
||||||
request: event.request,
|
request: event.request,
|
||||||
preloadResponsePromise: event.preloadResponse,
|
preloadResponsePromise: event.preloadResponse,
|
||||||
fallbackUrl: './',
|
fallbackUrl: './',
|
||||||
})
|
})
|
||||||
);
|
)
|
||||||
});
|
})
|
||||||
|
|
|
@ -1,3 +1,5 @@
|
||||||
---
|
---
|
||||||
|
|
||||||
---
|
---
|
||||||
404
|
|
||||||
|
404
|
||||||
|
|
|
@ -1,17 +1,17 @@
|
||||||
---
|
---
|
||||||
import { type CollectionEntry, getCollection } from 'astro:content';
|
import { type CollectionEntry, getCollection } from 'astro:content'
|
||||||
|
|
||||||
export async function getStaticPaths() {
|
export async function getStaticPaths() {
|
||||||
const posts = await getCollection('blog');
|
const posts = await getCollection('blog')
|
||||||
return posts.map((post) => ({
|
return posts.map((post) => ({
|
||||||
params: { slug: post.slug },
|
params: { slug: post.slug },
|
||||||
props: post,
|
props: post,
|
||||||
}));
|
}))
|
||||||
}
|
}
|
||||||
type Props = CollectionEntry<'blog'>;
|
type Props = CollectionEntry<'blog'>
|
||||||
|
|
||||||
const post = Astro.props;
|
const post = Astro.props
|
||||||
const { Content } = await post.render();
|
const { Content } = await post.render()
|
||||||
---
|
---
|
||||||
|
|
||||||
<Content />
|
<Content />
|
||||||
|
|
|
@ -1,5 +1,7 @@
|
||||||
---
|
---
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
blog index
|
blog index
|
||||||
|
|
||||||
<a href="/blog/building-a-cozy-web">post</a>
|
<a href="/blog/building-a-cozy-web">post</a>
|
||||||
|
|
|
@ -1,4 +1,5 @@
|
||||||
---
|
---
|
||||||
---
|
|
||||||
|
|
||||||
exclude
|
---
|
||||||
|
|
||||||
|
exclude
|
||||||
|
|
|
@ -1,15 +1,14 @@
|
||||||
---
|
---
|
||||||
export const prerender = false
|
export const prerender = false
|
||||||
---
|
---
|
||||||
<!DOCTYPE html>
|
|
||||||
|
<!doctype html>
|
||||||
<html lang="en">
|
<html lang="en">
|
||||||
<head>
|
<head>
|
||||||
<meta charset="UTF-8">
|
<meta charset="UTF-8" />
|
||||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
||||||
<title>Hello</title>
|
<title>Hello</title>
|
||||||
</head>
|
</head>
|
||||||
<body>
|
<body> Hello </body>
|
||||||
Hello
|
|
||||||
</body>
|
|
||||||
</html>
|
</html>
|
||||||
<!-- <Fragment set:html={content} /> -->
|
<!-- <Fragment set:html={content} /> -->
|
||||||
|
|
|
@ -1,3 +1,3 @@
|
||||||
export function log(message: any, ...data) {
|
export function log(message: any, ...data) {
|
||||||
console.log(message, ...data)
|
console.log(message, ...data)
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue