mirror of
https://github.com/morten-olsen/morten-olsen.github.io.git
synced 2026-02-08 01:46:28 +01:00
foo
This commit is contained in:
@@ -23,7 +23,7 @@ const createProfile = ({ cwd, path, bundler }: ProfileOptions) => {
|
||||
...data,
|
||||
imageUrl: createImage({
|
||||
image: imagePath,
|
||||
format: 'webp',
|
||||
format: 'avif',
|
||||
bundler,
|
||||
}),
|
||||
imagePath,
|
||||
|
||||
@@ -1,40 +1,54 @@
|
||||
import express, { Express } from 'express';
|
||||
import { Bundler } from '../bundler';
|
||||
import { extname } from 'path';
|
||||
|
||||
const createServer = (bundler: Bundler): Express => {
|
||||
const app = express();
|
||||
app.use((req, res) => {
|
||||
let path = req.path;
|
||||
const getAsset = (path: string) => {
|
||||
let asset = bundler.get(path);
|
||||
if (!asset) {
|
||||
path = path.endsWith('/') ? path + 'index.html' : path + '/index.html';
|
||||
asset = bundler.get(path);
|
||||
}
|
||||
return asset;
|
||||
};
|
||||
const app = express();
|
||||
app.get('/dev', (req, res) => {
|
||||
res.set({
|
||||
'Cache-Control': 'no-cache',
|
||||
'Content-Type': 'text/event-stream',
|
||||
Connection: 'keep-alive',
|
||||
});
|
||||
res.flushHeaders();
|
||||
const path = req.query.path?.toString();
|
||||
if (!path) {
|
||||
res.status(400).send('Missing path');
|
||||
return;
|
||||
}
|
||||
const asset = getAsset(path);
|
||||
if (!asset) {
|
||||
res.status(404).send('Not found');
|
||||
return;
|
||||
}
|
||||
const reload = () => {
|
||||
res.write('data: reload\n\n');
|
||||
};
|
||||
asset.subscribe(reload);
|
||||
res.on('close', () => {
|
||||
asset.unsubscribe(reload);
|
||||
});
|
||||
res.on('error', () => {
|
||||
asset.unsubscribe(reload);
|
||||
});
|
||||
res.on('finish', () => {
|
||||
asset.unsubscribe(reload);
|
||||
});
|
||||
});
|
||||
app.use((req, res) => {
|
||||
let path = req.path;
|
||||
let asset = getAsset(path);
|
||||
if (asset) {
|
||||
const ext = extname(path);
|
||||
asset.data
|
||||
.then((data) => {
|
||||
if (ext === '.html') {
|
||||
const unsubscribe = asset!.subscribe(async () => {
|
||||
await asset?.data;
|
||||
unsubscribe();
|
||||
res.end('<script>window.location.reload()</script>');
|
||||
});
|
||||
res.on('close', unsubscribe);
|
||||
res.on('finish', unsubscribe);
|
||||
res.on('error', unsubscribe);
|
||||
res.writeHead(200, {
|
||||
'content-type': 'text/html;charset=utf-8',
|
||||
'Cache-Control': 'no-cache, no-store, must-revalidate',
|
||||
Pragma: 'no-cache',
|
||||
Expires: '0',
|
||||
'keep-alive': 'timeout=5, max=100',
|
||||
});
|
||||
res.write(data.content.toString().replace('</html>', ''));
|
||||
} else {
|
||||
res.send(data.content);
|
||||
}
|
||||
res.send(data.content);
|
||||
})
|
||||
.catch((err) => {
|
||||
console.error(err);
|
||||
|
||||
@@ -12,14 +12,27 @@ type GlobOptions<T> = {
|
||||
const defaultCreate = (a: any) => a;
|
||||
|
||||
const createGlob = <T = string>({ cwd, pattern, create = defaultCreate }: GlobOptions<T>) => {
|
||||
const setup = (item: any) => {
|
||||
if (item instanceof Observable) {
|
||||
item.subscribe(() => {
|
||||
glob.recreate();
|
||||
});
|
||||
}
|
||||
};
|
||||
const glob = new Observable(async () => {
|
||||
const files = await fastGlob(pattern, { cwd });
|
||||
return files.map((path) => create(resolve(cwd, path)));
|
||||
return files.map((path) => {
|
||||
const item = create(resolve(cwd, path));
|
||||
setup(item);
|
||||
return item;
|
||||
});
|
||||
});
|
||||
|
||||
const watcher = watchGlob(pattern, { cwd });
|
||||
watcher.on('add', (path) => {
|
||||
glob.set((current) => Promise.resolve([...(current || []), create(resolve(cwd, path))]));
|
||||
const item = create(resolve(cwd, path));
|
||||
glob.set((current) => Promise.resolve([...(current || []), item]));
|
||||
setup(item);
|
||||
|
||||
return glob;
|
||||
});
|
||||
|
||||
9
bin/resources/page/client.ts
Normal file
9
bin/resources/page/client.ts
Normal file
@@ -0,0 +1,9 @@
|
||||
import EventSource from 'eventsource';
|
||||
|
||||
const path = encodeURIComponent(window.location.pathname);
|
||||
const source = new EventSource(`/dev?path=${path}`);
|
||||
source.onmessage = (msg) => {
|
||||
if (msg.data === 'reload') {
|
||||
window.location.reload();
|
||||
}
|
||||
};
|
||||
@@ -5,6 +5,7 @@ import { Asset, Bundler } from '../../bundler';
|
||||
import { Observable } from '../../observable';
|
||||
import { ServerStyleSheet } from 'styled-components';
|
||||
import { resolve } from 'path';
|
||||
import { createScript } from '../script';
|
||||
|
||||
type PageOptions = {
|
||||
path: string;
|
||||
@@ -12,11 +13,28 @@ type PageOptions = {
|
||||
props: Observable<any>;
|
||||
bundler: Bundler;
|
||||
};
|
||||
|
||||
let devClientUrl: string | undefined;
|
||||
|
||||
const createPage = (options: PageOptions) => {
|
||||
const data = Observable.combine({
|
||||
template: options.template,
|
||||
props: options.props,
|
||||
});
|
||||
if (devClientUrl === undefined) {
|
||||
const devClient = createScript({
|
||||
path: resolve(__dirname, 'client.ts'),
|
||||
format: 'iife',
|
||||
});
|
||||
const devClientAsset = devClient.pipe<Asset>(async () => {
|
||||
const script = await devClient.data;
|
||||
return {
|
||||
content: script,
|
||||
};
|
||||
});
|
||||
const devClientBundle = options.bundler.register('/dev-client.js', devClientAsset);
|
||||
devClientUrl = devClientBundle;
|
||||
}
|
||||
const page = data.pipe(async ({ template, props }) => {
|
||||
const sheet = new ServerStyleSheet();
|
||||
const helmetContext: FilledContext = {} as any;
|
||||
@@ -33,6 +51,7 @@ const createPage = (options: PageOptions) => {
|
||||
const css = sheet.getStyleTags();
|
||||
const headHtml = [
|
||||
css,
|
||||
`<script src="${devClientUrl}"></script>`,
|
||||
helmet.title?.toString(),
|
||||
helmet.priority?.toString(),
|
||||
helmet.meta?.toString(),
|
||||
|
||||
9
bin/resources/page/main.md
Normal file
9
bin/resources/page/main.md
Normal file
@@ -0,0 +1,9 @@
|
||||
---
|
||||
company: Sydbank
|
||||
title: IT Hotline
|
||||
from: 2007
|
||||
to: 2009
|
||||
resume: false
|
||||
---
|
||||
|
||||
I work as a part-time supporter of customers (private and business) and staff, on Sydbanks different electronic banking systems. Mostly telephonic bug finding and PC setup.
|
||||
Reference in New Issue
Block a user