This commit is contained in:
Morten Olsen
2023-03-28 08:10:46 +02:00
parent 9b1a067d56
commit 7adf03c83f
44 changed files with 1780 additions and 411 deletions

View File

@@ -1,5 +1,5 @@
import { createFile } from "../file";
import ejs from "ejs";
import { createFile } from '../file';
import ejs from 'ejs';
const createEjs = (path: string) => {
const file = createFile({ path });

View File

@@ -1,16 +1,26 @@
import { readFile } from "fs/promises";
import { Observable } from "../../observable";
import { watch } from "fs";
import { readFile } from 'fs/promises';
import { Observable } from '../../observable';
import { watch } from 'fs';
type FileOptions = {
path: string;
};
const createFile = ({ path }: FileOptions) => {
const file = new Observable(async () => readFile(path, "utf-8"));
let watcher: ReturnType<typeof watch> | undefined;
const addWatcher = () => {
if (watcher) {
watcher.close();
}
watcher = watch(path, () => {
file.recreate();
addWatcher();
});
};
watch(path, () => {
file.recreate();
const file = new Observable(async () => {
addWatcher();
return readFile(path, 'utf-8');
});
return file;

View File

@@ -1,28 +1,25 @@
import fastGlob from "fast-glob";
import watchGlob from "glob-watcher";
import { Observable } from "../../observable";
import fastGlob from 'fast-glob';
import watchGlob from 'glob-watcher';
import { Observable } from '../../observable';
import { resolve } from 'path';
type GlobOptions<T> = {
cwd?: string;
cwd: string;
pattern: string;
create?: (path: string) => T;
};
const defaultCreate = (a: any) => a;
const createGlob = <T = string>({
cwd,
pattern,
create = defaultCreate,
}: GlobOptions<T>) => {
const createGlob = <T = string>({ cwd, pattern, create = defaultCreate }: GlobOptions<T>) => {
const glob = new Observable(async () => {
const files = await fastGlob(pattern, { cwd });
return files.map(create);
return files.map((path) => create(resolve(cwd, path)));
});
const watcher = watchGlob(pattern, { cwd });
watcher.on("add", (path) => {
glob.set((current) => Promise.resolve([...(current || []), create(path)]));
watcher.on('add', (path) => {
glob.set((current) => Promise.resolve([...(current || []), create(resolve(cwd, path))]));
return glob;
});

View File

@@ -1,7 +1,7 @@
import { createHash } from "crypto";
import { Asset, Bundler } from "../../bundler";
import { Observable } from "../../observable";
import sharp, { FormatEnum } from "sharp";
import { createHash } from 'crypto';
import { Asset, Bundler } from '../../bundler';
import { Observable } from '../../observable';
import sharp, { FormatEnum } from 'sharp';
type ImageOptions = {
format: keyof FormatEnum;
@@ -13,8 +13,7 @@ type ImageOptions = {
};
const createImage = (options: ImageOptions) => {
let path =
options.name || createHash("sha256").update(options.image).digest("hex");
let path = options.name || createHash('sha256').update(options.image).digest('hex');
if (options.width) {
path += `-w${options.width}`;
}

View File

@@ -1,7 +1,7 @@
import { Asset, Bundler } from "../../bundler";
import { Observable } from "../../observable";
import { createEjs } from "../ejs";
import { latexToPdf } from "./utils";
import { Asset, Bundler } from '../../bundler';
import { Observable } from '../../observable';
import { createEjs } from '../ejs';
import { latexToPdf } from './utils';
type LatexOptions = {
path: string;
@@ -23,7 +23,11 @@ const createLatex = ({ template, data, path, bundler }: LatexOptions) => {
};
return asset;
});
return bundler.register(`${path}.pdf`, pdf);
const url = bundler.register(`${path}.pdf`, pdf);
return {
url,
item: pdf,
};
};
export { createLatex };

View File

@@ -1,5 +1,5 @@
import latex from "node-latex";
import { Readable } from "stream";
import latex from 'node-latex';
import { Readable } from 'stream';
const latexToPdf = (doc: string) =>
new Promise<Buffer>((resolve, reject) => {
@@ -8,14 +8,14 @@ const latexToPdf = (doc: string) =>
input.push(doc);
input.push(null);
const latexStream = latex(input);
latexStream.on("data", (chunk) => {
latexStream.on('data', (chunk) => {
chunks.push(Buffer.from(chunk));
});
latexStream.on("finish", () => {
latexStream.on('finish', () => {
const result = Buffer.concat(chunks);
resolve(result);
});
latexStream.on("error", (err) => {
latexStream.on('error', (err) => {
reject(err);
});
});

View File

@@ -1,10 +1,10 @@
import React, { ComponentType } from "react";
import { renderToStaticMarkup } from "react-dom/server";
import { HelmetProvider, FilledContext } from "react-helmet-async";
import { Asset, Bundler } from "../../bundler";
import { Observable } from "../../observable";
import { ServerStyleSheet } from "styled-components";
import { resolve } from "path";
import React, { ComponentType } from 'react';
import { renderToStaticMarkup } from 'react-dom/server';
import { HelmetProvider, FilledContext } from 'react-helmet-async';
import { Asset, Bundler } from '../../bundler';
import { Observable } from '../../observable';
import { ServerStyleSheet } from 'styled-components';
import { resolve } from 'path';
type PageOptions = {
path: string;
@@ -24,8 +24,8 @@ const createPage = (options: PageOptions) => {
React.createElement(
HelmetProvider,
{ context: helmetContext },
React.createElement(template, props)
)
React.createElement(template, props),
),
);
const bodyHtml = renderToStaticMarkup(body);
const { helmet } = helmetContext;
@@ -40,7 +40,7 @@ const createPage = (options: PageOptions) => {
helmet.script?.toString(),
]
.filter(Boolean)
.join("");
.join('');
const html = `<!DOCTYPE html>
<html lang="en">
<head>
@@ -55,7 +55,7 @@ const createPage = (options: PageOptions) => {
return asset;
});
const path = resolve("/", options.path, "index.html");
const path = resolve('/', options.path, 'index.html');
return options.bundler.register(path, page);
};

View File

@@ -1,27 +1,27 @@
import vm from "vm";
import React, { ComponentType } from "react";
import { nodeResolve } from "@rollup/plugin-node-resolve";
import commonjs from "@rollup/plugin-commonjs";
import json from "@rollup/plugin-json";
import replace from "@rollup/plugin-replace";
import sucrase from "@rollup/plugin-sucrase";
import alias from "@rollup/plugin-alias";
import externalGlobals from "rollup-plugin-external-globals";
import { createScript } from "../script";
import orgStyled from "styled-components";
import * as styledExports from "styled-components";
import ReactHelmetAsync from "react-helmet-async";
import { resolve } from "path";
import vm from 'vm';
import React, { ComponentType } from 'react';
import { nodeResolve } from '@rollup/plugin-node-resolve';
import commonjs from '@rollup/plugin-commonjs';
import json from '@rollup/plugin-json';
import replace from '@rollup/plugin-replace';
import sucrase from '@rollup/plugin-sucrase';
import alias from '@rollup/plugin-alias';
import externalGlobals from 'rollup-plugin-external-globals';
import { createScript } from '../script';
import orgStyled from 'styled-components';
import * as styledExports from 'styled-components';
import ReactHelmetAsync from 'react-helmet-async';
import { resolve } from 'path';
const styled = orgStyled.bind(null);
for (let key of Object.keys(orgStyled)) {
if (key === "default") {
if (key === 'default') {
continue;
}
(styled as any)[key] = (orgStyled as any)[key];
}
for (let key of Object.keys(styledExports)) {
if (key === "default") {
if (key === 'default') {
continue;
}
(styled as any)[key] = (styledExports as any)[key];
@@ -30,34 +30,32 @@ for (let key of Object.keys(styledExports)) {
const createReact = <TProps = any>(path: string) => {
const script = createScript({
path,
format: "cjs",
format: 'cjs',
plugins: [
replace({
preventAssignment: true,
"process.env.NODE_ENV": JSON.stringify("production"),
'process.env.NODE_ENV': JSON.stringify('production'),
}),
alias({
entries: [
{ find: "@", replacement: resolve("content/templates/react") },
],
entries: [{ find: '@', replacement: resolve('content/templates/react') }],
}),
sucrase({
exclude: ["node_modules/**"],
transforms: ["jsx", "typescript"],
exclude: ['node_modules/**'],
transforms: ['jsx', 'typescript'],
}),
nodeResolve({
browser: true,
preferBuiltins: false,
extensions: [".js", ".ts", ".tsx"],
extensions: ['.js', '.ts', '.tsx'],
}),
json(),
commonjs({
include: /node_modules/,
}),
externalGlobals({
react: "React",
"styled-components": "StyledComponents",
"react-helmet-async": "ReactHelmetAsync",
react: 'React',
'styled-components': 'StyledComponents',
'react-helmet-async': 'ReactHelmetAsync',
}),
],
});

View File

@@ -1,5 +1,5 @@
import { Observable } from "../../observable";
import { InputPluginOption, ModuleFormat, watch } from "rollup";
import { Observable } from '../../observable';
import { InputPluginOption, ModuleFormat, watch } from 'rollup';
type ScriptOptions = {
path: string;
@@ -13,7 +13,7 @@ const build = (options: ScriptOptions, update: (code: string) => void) =>
const watcher = watch({
input: options.path,
plugins: options.plugins,
onwarn: () => { },
onwarn: () => {},
output: {
format: options.format,
},
@@ -22,8 +22,8 @@ const build = (options: ScriptOptions, update: (code: string) => void) =>
},
});
watcher.on("event", async (event) => {
if (event.code === "BUNDLE_END") {
watcher.on('event', async (event) => {
if (event.code === 'BUNDLE_END') {
const { output } = await event.result.generate({
format: options.format,
});
@@ -35,7 +35,7 @@ const build = (options: ScriptOptions, update: (code: string) => void) =>
update(code);
}
}
if (event.code === "ERROR") {
if (event.code === 'ERROR') {
reject(event.error);
}
});
@@ -43,7 +43,7 @@ const build = (options: ScriptOptions, update: (code: string) => void) =>
const createScript = (options: ScriptOptions) => {
const script: Observable<string> = new Observable(() =>
build(options, (code) => script.set(() => Promise.resolve(code)))
build(options, (code) => script.set(() => Promise.resolve(code))),
);
return script;