feat: create logger; update cached articles on load
This commit is contained in:
parent
ed2364ebe8
commit
4daa099b22
5 changed files with 108 additions and 28 deletions
|
@ -17,7 +17,9 @@ export interface Props {
|
|||
import type { AppConfig } from '../pages/index.astro';
|
||||
import { getPostCard, renderPost } from '../utils/library'
|
||||
import { cozify } from '../utils/sanitizer';
|
||||
import { logError, logInfo } from '../utils/logger.mjs';
|
||||
const cache = await caches.open('cozy-reader');
|
||||
const baseUrl = window.location.origin;
|
||||
let url= new URL(window.location.href);
|
||||
// only cached unencoded url param
|
||||
const urlParam = url.searchParams.get('url')
|
||||
|
@ -26,16 +28,15 @@ export interface Props {
|
|||
}
|
||||
const { skipSave } = deserialize<Props>('preferences');
|
||||
const { routerOutlet } = deserialize<AppConfig>('app-config');
|
||||
const includesAppURL = urlParam?.includes(window.location.origin)
|
||||
const includesAppURL = urlParam?.includes(baseUrl) ?? false;
|
||||
|
||||
try {
|
||||
const responseFromNetwork = await fetch (url);
|
||||
if (responseFromNetwork && !skipSave && !includesAppURL) {
|
||||
console.info('[cozy-reader]: adding one to cache', url.pathname)
|
||||
await cache.put(url, responseFromNetwork);
|
||||
if (url.href.slice(0, url.href.length - 1) !== baseUrl && !skipSave && !includesAppURL) {
|
||||
logInfo('adding one to cache', {context: 'cozy-reader', data: url})
|
||||
await cache.add(url);
|
||||
}
|
||||
} catch(error) {
|
||||
console.error('[cozy-reader]: ', error)
|
||||
logError('ERR', {context: 'cozy-reader', data: error})
|
||||
}
|
||||
|
||||
const cachedRequests = (await cache.keys())
|
||||
|
@ -44,7 +45,7 @@ export interface Props {
|
|||
const urlParam = urlObj.searchParams.get('url');
|
||||
|
||||
return urlObj.search !== ''
|
||||
&& !urlParam?.startsWith(window.location.origin)
|
||||
&& !urlParam?.startsWith(baseUrl)
|
||||
&& urlParam !== ''
|
||||
&& urlParam !== 'null';
|
||||
});
|
||||
|
@ -63,9 +64,19 @@ export interface Props {
|
|||
let responseText;
|
||||
|
||||
const fullResponse = await cache.match(url)
|
||||
|
||||
try {
|
||||
const responseFromNetwork = await fetch(url, {method: 'GET'});
|
||||
if (responseFromNetwork && url.slice(0, url.length - 1) !== baseUrl && !skipSave && !includesAppURL) {
|
||||
logInfo('updating cached', {context: 'cozy-reader', data: url})
|
||||
await cache.put(url, responseFromNetwork);
|
||||
}
|
||||
} catch(error) {
|
||||
logError('failed to update cached', {context: 'cozy-reader', data: {url, error}})
|
||||
}
|
||||
|
||||
fullResponse?.text().then(async data => {
|
||||
responseText = data;
|
||||
const { baseUrl } = deserialize<AppConfig>('app-config');
|
||||
const cleanedResponse = await cozify(responseText, baseUrl)
|
||||
const html = document.createElement('html');
|
||||
html.innerHTML = cleanedResponse;
|
||||
|
@ -82,6 +93,7 @@ export interface Props {
|
|||
e.preventDefault();
|
||||
localStorage.setItem('scrollPosition', window.scrollY.toString());
|
||||
scrollTo(0,0);
|
||||
logInfo('using cached response', {context: 'cozy-reader', data: url})
|
||||
renderPost(cleanedResponse, url, routerOutlet)
|
||||
}
|
||||
const item = document.createElement('li');
|
||||
|
@ -105,8 +117,8 @@ export interface Props {
|
|||
const fullResponse = await cache.match(url)
|
||||
fullResponse?.text().then(async (data) => {
|
||||
const responseText = data;
|
||||
const { baseUrl } = deserialize<AppConfig>('app-config');
|
||||
const cleanedResponse = await cozify(responseText, baseUrl);
|
||||
logInfo('using cached response', {context: 'cozy-reader', data: url})
|
||||
renderPost(cleanedResponse, url, routerOutlet, true);
|
||||
if (isHome) {
|
||||
const scrollPosition = localStorage.getItem('scrollPosition');
|
||||
|
|
|
@ -4,4 +4,4 @@ export const SITE_AUTHOR_MASTODON = 'https://social.ayco.io/@ayo';
|
|||
export const SITE_PROJECT_REPO = 'https://github.com/ayoayco/Cozy';
|
||||
export const SITE_DESCRIPTION = 'The Web is Yours.';
|
||||
|
||||
export const VERSION = 'Purple-Pizza';
|
||||
export const VERSION = 'Purple-Pizza';
|
|
@ -11,7 +11,6 @@ export const prerender = false;
|
|||
|
||||
const appConfig = {
|
||||
routerOutlet: 'router-outlet',
|
||||
baseUrl: Astro.url.origin
|
||||
};
|
||||
export type AppConfig = typeof appConfig;
|
||||
|
||||
|
|
49
src/sw.js
49
src/sw.js
|
@ -4,20 +4,35 @@
|
|||
* @see https://ayco.io/n/@ayco/astro-sw
|
||||
*/
|
||||
const cacheName = `${__prefix ?? 'app'}-v${__version ?? '000'}`
|
||||
// const forceLogging = true;
|
||||
|
||||
/**
|
||||
* TODO: remove this once astro-sw allows importing utils
|
||||
*/
|
||||
function logInfo(message, {context, force, data} = {}) {
|
||||
context = context !== ''
|
||||
? `[${context}]: `
|
||||
: ''
|
||||
|
||||
if (force || isDev) {
|
||||
console.info(`!!! ${context}${message}`, data ?? '');
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
const addResourcesToCache = async (resources) => {
|
||||
const cache = await caches.open(cacheName);
|
||||
console.log('[cozy-sw]: adding resources to cache...', resources)
|
||||
logInfo('adding resources to cache...', { force: forceLogging, context: 'cozy-sw', data: resources })
|
||||
await cache.addAll(resources);
|
||||
};
|
||||
|
||||
const putInCache = async (request, response) => {
|
||||
const cache = await caches.open(cacheName);
|
||||
console.log('[cozy-sw]: adding one response to cache...', request.url)
|
||||
logInfo('adding one response to cache...', { force: forceLogging, context: 'cozy-sw', data: request.url })
|
||||
// if exists, replace
|
||||
|
||||
const keys = await cache.keys();
|
||||
if(keys.includes(request)) {
|
||||
if (keys.includes(request)) {
|
||||
cache.delete(request);
|
||||
}
|
||||
|
||||
|
@ -26,7 +41,7 @@ const putInCache = async (request, response) => {
|
|||
|
||||
|
||||
const cacheAndRevalidate = async ({ request, preloadResponsePromise, fallbackUrl }) => {
|
||||
|
||||
|
||||
const cache = await caches.open(cacheName);
|
||||
|
||||
// Try get the resource from the cache
|
||||
|
@ -35,21 +50,21 @@ const cacheAndRevalidate = async ({ request, preloadResponsePromise, fallbackUrl
|
|||
// get network response for revalidation of stale assets
|
||||
const responseFromNetwork = await fetch(request.clone());
|
||||
if (responseFromNetwork) {
|
||||
console.info('[cozy-sw]: fetched updated assets', responseFromNetwork.url);
|
||||
logInfo('updated cached resource...', { force: forceLogging, context: 'cozy-sw', data: responseFromNetwork.url })
|
||||
putInCache(request, responseFromNetwork.clone());
|
||||
}
|
||||
|
||||
if (responseFromCache) {
|
||||
console.info('[cozy-sw]: using cached response', responseFromCache.url);
|
||||
logInfo('using cached response...', { force: forceLogging, context: 'cozy-sw', data: responseFromCache.url })
|
||||
return responseFromCache;
|
||||
} else{
|
||||
console.info('[cozy-sw]: using network response', responseFromNetwork.url);
|
||||
} else {
|
||||
logInfo('using network response...', { force: forceLogging, context: 'cozy-sw', data: responseFromNetwork.url })
|
||||
return responseFromNetwork;
|
||||
}
|
||||
} catch(error) {
|
||||
console.info('[cozy-sw]: failed to fetch updated assets', request.url);
|
||||
} catch (error) {
|
||||
logInfo('failed to fetch updated resource', { force: forceLogging, context: 'cozy-sw', data: request.url })
|
||||
if (responseFromCache) {
|
||||
console.info('[cozy-sw]: using cached response', responseFromCache.url);
|
||||
logInfo('using cached response', { force: forceLogging, context: 'cozy-sw', data: responseFromCache.url })
|
||||
return responseFromCache;
|
||||
}
|
||||
}
|
||||
|
@ -63,18 +78,18 @@ const cacheAndRevalidate = async ({ request, preloadResponsePromise, fallbackUrl
|
|||
const preloadResponse = await preloadResponsePromise;
|
||||
if (preloadResponse) {
|
||||
putInCache(request, preloadResponse.clone());
|
||||
console.info('[cozy-sw]: using preload response', preloadResponse.url);
|
||||
logInfo('using preload response', { force: forceLogging, context: 'cozy-sw', data: preloadResponse.url })
|
||||
return preloadResponse;
|
||||
}
|
||||
|
||||
try {
|
||||
// Try to get the resource from the network for 5 seconds
|
||||
const responseFromNetwork = await fetch(request.clone(), {signal: AbortSignal.timeout(5000)});
|
||||
const responseFromNetwork = await fetch(request.clone(), { signal: AbortSignal.timeout(5000) });
|
||||
// response may be used only once
|
||||
// we need to save clone to put one copy in cache
|
||||
// and serve second one
|
||||
putInCache(request, responseFromNetwork.clone());
|
||||
console.info('[cozy-sw]: using network response', responseFromNetwork.url);
|
||||
logInfo('using network response', { force: forceLogging, context: 'cozy-sw', data: responseFromNetwork.url })
|
||||
return responseFromNetwork;
|
||||
|
||||
} catch (error) {
|
||||
|
@ -82,7 +97,7 @@ const cacheAndRevalidate = async ({ request, preloadResponsePromise, fallbackUrl
|
|||
// Try the fallback
|
||||
const fallbackResponse = await cache.match(fallbackUrl);
|
||||
if (fallbackResponse) {
|
||||
console.info('[cozy-sw]: using fallback cached response', fallbackResponse.url);
|
||||
logInfo('using fallback cached response...', { force: forceLogging, context: 'cozy-sw', data: fallbackResponse.url })
|
||||
return fallbackResponse;
|
||||
}
|
||||
|
||||
|
@ -104,12 +119,12 @@ const enableNavigationPreload = async () => {
|
|||
};
|
||||
|
||||
self.addEventListener('activate', (event) => {
|
||||
console.log('[cozy-sw]: activating...', event)
|
||||
logInfo('activating service worker...', { force: forceLogging, context: 'cozy-sw' })
|
||||
event.waitUntil(enableNavigationPreload());
|
||||
});
|
||||
|
||||
self.addEventListener('install', (event) => {
|
||||
console.log('[cozy-sw]: installing...', event)
|
||||
logInfo('installing service worker...', { force: forceLogging, context: 'cozy-sw' })
|
||||
event.waitUntil(
|
||||
addResourcesToCache([
|
||||
...(__assets ?? [])
|
||||
|
|
54
src/utils/logger.mjs
Normal file
54
src/utils/logger.mjs
Normal file
|
@ -0,0 +1,54 @@
|
|||
// @ts-check
|
||||
|
||||
const isDev = import.meta.env.DEV;
|
||||
|
||||
/**
|
||||
* @typedef {{
|
||||
* force?: true
|
||||
* context?: string,
|
||||
* data?: any
|
||||
* }} LogOptions
|
||||
*/
|
||||
|
||||
|
||||
/**
|
||||
* @param {string} message
|
||||
* @param {LogOptions} options
|
||||
*/
|
||||
export function logMessage(message, {context, force, data} = {}) {
|
||||
context = context !== ''
|
||||
? `[${context}]: `
|
||||
: ''
|
||||
|
||||
if (force || isDev) {
|
||||
console.log(`!!! ${context}${message}`, data ?? '');
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {string} message
|
||||
* @param {LogOptions} options
|
||||
*/
|
||||
export function logInfo(message, {context, force, data} = {}) {
|
||||
context = context !== ''
|
||||
? `[${context}]: `
|
||||
: ''
|
||||
|
||||
if (force || isDev) {
|
||||
console.info(`!!! ${context}${message}`, data ?? '');
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {string} message
|
||||
* @param {LogOptions} options
|
||||
*/
|
||||
export function logError(message, {context, force, data} = {}) {
|
||||
context = context !== ''
|
||||
? `[${context}]: `
|
||||
: ''
|
||||
|
||||
if (force || isDev) {
|
||||
console.error(`!!! ${context}${message}`, data ?? '');
|
||||
}
|
||||
}
|
Loading…
Reference in a new issue