mirror of
https://github.com/AtHeartEngineer/uikit.git
synced 2026-01-09 20:58:01 -05:00
93 lines
3.0 KiB
JavaScript
93 lines
3.0 KiB
JavaScript
import { getAssetFromKV } from '@cloudflare/kv-asset-handler'
|
|
import html from './html'
|
|
import React from 'react'
|
|
import ReactDOMServer from 'react-dom/server'
|
|
import Home from '../src/Home'
|
|
import UIContext, { Interface } from 'nanoether/src/contexts/interface'
|
|
|
|
// Enables edge cdn - https://developers.cloudflare.com/workers/learning/how-the-cache-works/
|
|
const DEBUG = false
|
|
const ENABLE_ASSET_CACHE = true
|
|
const ENABLE_SSR_CACHE = false // TODO: cache bust after deployment
|
|
|
|
addEventListener('fetch', (event) => {
|
|
event.respondWith(generateResponse(event))
|
|
})
|
|
|
|
async function generateResponse(event) {
|
|
// is it a request for ssr or a static asset?
|
|
const isSSR = ! /.+\.[a-zA-Z]+$/.test(event.request.url)
|
|
if (!isSSR && ENABLE_ASSET_CACHE) {
|
|
// take a peek in the cache and return if the url is there
|
|
const response = await caches.default.match(event.request.url)
|
|
if (DEBUG) {
|
|
console.log(`Cache hit: ${event.request.url}`)
|
|
}
|
|
if (response) return response
|
|
}
|
|
return isSSR ? ssr(event) : staticAsset(event)
|
|
}
|
|
|
|
async function ssr(event) {
|
|
try {
|
|
const cookie = event.request.headers.get('Cookie')
|
|
const iface = new Interface()
|
|
if (typeof cookie === 'string' && cookie.indexOf('darkmode=true') !== -1) {
|
|
// render in darkmode
|
|
iface.setDarkmode(true)
|
|
}
|
|
const app = ReactDOMServer.renderToString(
|
|
<UIContext.Provider value={iface}>
|
|
<Home />
|
|
</UIContext.Provider>
|
|
)
|
|
// use npm run
|
|
const finalIndex = html
|
|
.replace('<div id="root"></div>', `<div id="root">${app}</div>`)
|
|
const response = new Response(finalIndex)
|
|
response.headers.set('content-type', 'text/html')
|
|
response.headers.set('Cache-Control', 'max-age=604800,s-maxage=604800,public')
|
|
if (ENABLE_SSR_CACHE) {
|
|
// cache the ssr html itself
|
|
event.waitUntil(
|
|
caches.default.put(event.request.url, new Response(finalIndex))
|
|
)
|
|
}
|
|
return response
|
|
} catch (err) {
|
|
return new Response(err.toString(), {
|
|
status: 500,
|
|
})
|
|
}
|
|
}
|
|
|
|
async function staticAsset(event) {
|
|
// https://www.npmjs.com/package/@cloudflare/kv-asset-handler#optional-arguments
|
|
const asset = await getAssetFromKV(event, {
|
|
bypassCache: !ENABLE_ASSET_CACHE,
|
|
})
|
|
let body = asset.body
|
|
if (ENABLE_ASSET_CACHE) {
|
|
// put the asset in the cache
|
|
// split the response stream, give one to the cache
|
|
if (DEBUG) {
|
|
console.log('Stream split')
|
|
}
|
|
const [b1, b2] = asset.body.tee()
|
|
// cause the script to stay alive until this promise resolves
|
|
event.waitUntil(
|
|
caches.default.put(event.request.url, new Response(b1, asset))
|
|
)
|
|
body = b2
|
|
}
|
|
// build response from body
|
|
const response = new Response(body, asset)
|
|
response.headers.set('Referrer-Policy', 'unsafe-url')
|
|
// tell browsers to cache if it's an svg
|
|
// WARN: if we use anything other than svg we need to change this lol
|
|
if (/.+\.svg$/.test(event.request.url)) {
|
|
response.headers.set('Cache-Control', 'max-age=604800,s-maxage=604800,public')
|
|
}
|
|
return response
|
|
}
|