diff --git a/.gitignore b/.gitignore index 7427fa6..9b23667 100644 --- a/.gitignore +++ b/.gitignore @@ -1,2 +1,3 @@ +dist/ node_modules/ public/client.js diff --git a/difftool.sh b/difftool.sh index ae365d8..ad058b7 100755 --- a/difftool.sh +++ b/difftool.sh @@ -32,7 +32,7 @@ if [ ${#ARGS[@]} -lt 3 ]; then fi script_dir="$(cd "$(dirname "$0")" && pwd)" -node_args=("$script_dir/server.js") +node_args=("$script_dir/dist/server.cjs") [ -n "$STATIC" ] && node_args+=("$STATIC") [ -n "$OUTFILE" ] && node_args+=("--out" "$OUTFILE") node_args+=("${ARGS[@]}") diff --git a/package-lock.json b/package-lock.json index b14b5d4..fb8a97f 100644 --- a/package-lock.json +++ b/package-lock.json @@ -7,13 +7,14 @@ "": { "name": "difftool", "version": "0.1.0", + "hasInstallScript": true, "dependencies": { - "@pierre/diffs": "^1.2.7", - "@pierre/trees": "^1.0.0-beta.4", - "express": "^5.1.0" + "@pierre/diffs": "1.2.7", + "express": "5.2.1" }, "devDependencies": { - "esbuild": "^0.28.0" + "@pierre/trees": "1.0.0-beta.4", + "esbuild": "0.28.0" } }, "node_modules/@esbuild/aix-ppc64": { @@ -489,6 +490,7 @@ "version": "1.0.0-beta.4", "resolved": "https://registry.npmjs.org/@pierre/trees/-/trees-1.0.0-beta.4.tgz", "integrity": "sha512-OfT1yk9ne8Te5+GB5zUY8yqE6B8BqjBHQJleH4lu8ltwNpoocZl4vXt1AzlEExpxI/pp+AFX5QG+lR3JjtTEag==", + "dev": true, "license": "apache-2.0", "dependencies": { "preact": "11.0.0-beta.0", @@ -1460,6 +1462,7 @@ "version": "11.0.0-beta.0", "resolved": "https://registry.npmjs.org/preact/-/preact-11.0.0-beta.0.tgz", "integrity": "sha512-IcODoASASYwJ9kxz7+MJeiJhvLriwSb4y4mHIyxdgaRZp6kPUud7xytrk/6GZw8U3y6EFJaRb5wi9SrEK+8+lg==", + "dev": true, "license": "MIT", "funding": { "type": "opencollective", @@ -1470,6 +1473,7 @@ "version": "6.6.5", "resolved": "https://registry.npmjs.org/preact-render-to-string/-/preact-render-to-string-6.6.5.tgz", "integrity": "sha512-O6MHzYNIKYaiSX3bOw0gGZfEbOmlIDtDfWwN1JJdc/T3ihzRT6tGGSEWE088dWrEDGa1u7101q+6fzQnO9XCPA==", + "dev": true, "license": "MIT", "peerDependencies": { "preact": ">=10 || >= 11.0.0-0" diff --git a/package.json b/package.json index 9c73910..e1f021c 100644 --- a/package.json +++ b/package.json @@ -4,15 +4,17 @@ "type": "module", "private": true, "dependencies": { - "@pierre/diffs": "^1.2.7", - "@pierre/trees": "^1.0.0-beta.4", - "express": "^5.1.0" + "@pierre/diffs": "1.2.7", + "express": "5.2.1" }, "scripts": { - "build": "esbuild src/client.js --bundle --outfile=public/client.js --format=esm", + "build:client": "esbuild src/client.js --bundle --outfile=public/client.js --format=esm", + "build:server": "esbuild server.js --bundle --platform=node --target=node20 --outfile=dist/server.cjs --format=cjs && mkdir -p dist/public && cp -r public/. dist/public", + "build": "npm run build:server && npm run build:client", "postinstall": "npm run build" }, "devDependencies": { - "esbuild": "^0.28.0" + "@pierre/trees": "1.0.0-beta.4", + "esbuild": "0.28.0" } } diff --git a/server.js b/server.js index ccfab08..098d499 100644 --- a/server.js +++ b/server.js @@ -7,7 +7,9 @@ import { fileURLToPath } from 'url'; import { parsePatchFiles, DEFAULT_THEMES } from '@pierre/diffs'; import { preloadFileDiff } from '@pierre/diffs/ssr'; -const __dirname = dirname(fileURLToPath(import.meta.url)); +const __dirname = typeof __filename !== 'undefined' + ? dirname(__filename) + : dirname(fileURLToPath(import.meta.url)); // --- arg parsing --- @@ -86,76 +88,75 @@ if (files.length === 0) { process.exit(0); } -// --- SSR diffs --- +// --- SSR diffs + helpers + mode dispatch --- -const ssrOptions = { - theme: DEFAULT_THEMES, - themeType: 'system', - diffStyle: 'unified', - useTokenTransformer: true, -}; +(async () => { + const ssrOptions = { + theme: DEFAULT_THEMES, + themeType: 'system', + diffStyle: 'unified', + useTokenTransformer: true, + }; -const renderedFiles = []; -for (const fileDiff of files) { - try { - const result = await preloadFileDiff({ fileDiff, options: ssrOptions }); - renderedFiles.push({ - name: fileDiff.name || 'unknown', - prerenderedHTML: result.prerenderedHTML, - }); - } catch (err) { - console.warn(`Failed to SSR-render ${fileDiff.name || 'unknown'}: ${err.message}`); - renderedFiles.push({ - name: fileDiff.name || 'unknown', - prerenderedHTML: null, - }); + const renderedFiles = []; + for (const fileDiff of files) { + try { + const result = await preloadFileDiff({ fileDiff, options: ssrOptions }); + renderedFiles.push({ + name: fileDiff.name || 'unknown', + prerenderedHTML: result.prerenderedHTML, + }); + } catch (err) { + console.warn(`Failed to SSR-render ${fileDiff.name || 'unknown'}: ${err.message}`); + renderedFiles.push({ + name: fileDiff.name || 'unknown', + prerenderedHTML: null, + }); + } } -} -// --- helpers --- + const finalPatch = patch; -function escapeHtml(str) { - return str.replace(/&/g, '&').replace(//g, '>').replace(/"/g, '"'); -} + function escapeHtml(str) { + return str.replace(/&/g, '&').replace(//g, '>').replace(/"/g, '"'); + } -function fileId(name) { - return 'DF-' + name.replace(/[^a-zA-Z0-9_-]/g, '_'); -} + function fileId(name) { + return 'DF-' + name.replace(/[^a-zA-Z0-9_-]/g, '_'); + } -// --- HTML template --- + function pageHtml(opts) { + const { mode, sidebarHtml, extraScript } = opts; -function pageHtml(opts) { - const { mode, sidebarHtml, extraScript } = opts; - - const fileSections = renderedFiles.map((f) => { - const escapedName = escapeHtml(f.name); - const id = fileId(f.name); - if (f.prerenderedHTML !== null) { - return ` + const fileSections = renderedFiles.map((f) => { + const escapedName = escapeHtml(f.name); + const id = fileId(f.name); + if (f.prerenderedHTML !== null) { + return `