diff --git a/deno.jsonc b/deno.jsonc index 34331cd..31b74c1 100644 --- a/deno.jsonc +++ b/deno.jsonc @@ -1,6 +1,6 @@ { "lint": { - "exclude": ["framework/meta"], // OLD + "exclude": ["src"], // OLD "rules": { "exclude": [ "no-explicit-any" // TODO diff --git a/framework/assets.ts b/framework/assets.ts index 5a925f2..109e727 100644 --- a/framework/assets.ts +++ b/framework/assets.ts @@ -97,3 +97,4 @@ import * as fs from "./fs.ts"; import type { Context, Next } from "hono"; import type { StatusCode } from "hono/utils/http-status"; import type { BuiltAsset, BuiltAssetMap, View } from "./incremental.ts"; +import { Buffer } from "node:buffer"; diff --git a/framework/bundle.ts b/framework/bundle.ts index eef613f..865150a 100644 --- a/framework/bundle.ts +++ b/framework/bundle.ts @@ -1,5 +1,4 @@ // This file implements client-side bundling, mostly wrapping esbuild. -import process from "node:process"; const plugins: esbuild.Plugin[] = [ // There are currently no plugins needed by 'paperclover.net' ]; @@ -80,6 +79,7 @@ export async function bundleClientJavaScript( } } -import * as path from "node:path"; import * as esbuild from "esbuild"; +import * as path from "node:path"; +import process from "node:process"; import { Incremental } from "./incremental.ts"; diff --git a/framework/engine/jsx-runtime.ts b/framework/engine/jsx-runtime.ts index 999d500..d0b1385 100644 --- a/framework/engine/jsx-runtime.ts +++ b/framework/engine/jsx-runtime.ts @@ -35,7 +35,7 @@ declare global { [name: string]: Record; } interface ElementChildrenAttribute { - children: {}; + children: unknown; } type Element = engine.Node; type ElementType = keyof IntrinsicElements | engine.Component; diff --git a/framework/hot.ts b/framework/hot.ts index c1969f4..5078e5c 100644 --- a/framework/hot.ts +++ b/framework/hot.ts @@ -157,11 +157,13 @@ function loadMarko(module: NodeJS.Module, filepath: string) { // bare client import statements to it's own usage. if (src.match(/^\s*client\s+import\s+["']/m)) { src = src.replace( - /^\s*client\s+import\s+("[^"]+|'[^']+)[^\n]+/m, + /^\s*client\s+import\s+("[^"]+"|'[^']+')[^\n]+/m, "", - ) + '\nimport { Script as CloverScriptInclude } from "#sitegen";'; + ) + '\nimport { Script as CloverScriptInclude } from "#sitegen";\n'; } + console.log(src); + console.log("---"); src = marko.compileSync(src, filepath).code; src = src.replace("marko/debug/html", "#ssr/marko"); return loadEsbuildCode(module, filepath, src); diff --git a/framework/mime.ts b/framework/mime.ts index b130e81..d71480b 100644 --- a/framework/mime.ts +++ b/framework/mime.ts @@ -1,29 +1,30 @@ -const db = new Map( - fs.readFileSync(path.join(import.meta.dirname, "mime.txt"), "utf8") - .split("\n").filter(Boolean).map((line) => - line.split(/\s+/) as [string, string] - ), -); +const entries = fs.readFileSync( + path.join(import.meta.dirname, "mime.txt"), + "utf8", +) + .split("\n") + .map((line) => line.trim()) + .filter((line) => line && !line.startsWith("#")) + .map((line) => line.split(/\s+/, 2) as [string, string]); +const extensions = new Map(entries.filter((x) => x[0].startsWith("."))); +const fullNames = new Map(entries.filter((x) => !x[0].startsWith("."))); /** * Accepts: - * - Full file path + * - Full file path or basename * - Extension (with or without dot) */ export function contentTypeFor(file: string) { - if (file.includes("/") || file.includes("\\")) { - // Some file names are special cased. - switch (path.basename(file)) { - case "rss.xml": - return "application/rss+xml"; - } - - file = path.extname(file); - } + const slash = file.indexOf("/"); + if (slash !== -1) file = file.slice(slash + 1); const dot = file.indexOf("."); if (dot === -1) file = "." + file; - else if (dot > 0) file = file.slice(dot); - return db.get(file) ?? "application/octet-stream"; + else if (dot > 0) { + let entry = fullNames.get(file); + if (entry) return entry; + file = file.slice(dot); + } + return extensions.get(file) ?? "application/octet-stream"; } import * as fs from "./fs.ts"; diff --git a/framework/mime.txt b/framework/mime.txt new file mode 100644 index 0000000..7cf5993 --- /dev/null +++ b/framework/mime.txt @@ -0,0 +1,99 @@ +# media types +# https://developer.mozilla.org/en-US/docs/Web/HTTP/Guides/MIME_types +.aac audio/x-aac +.aif audio/x-aiff +.aifc audio/x-aiff +.aiff audio/x-aiff +.asm text/x-asm +.avi video/x-msvideo +.bat application/x-msdownload +.c text/x-c +.chat text/x-clover-chatlog +.class application/java-vm +.cmd application/x-msdownload +.com application/x-msdownload +.conf text/plain +.cpp text/x-c +.css text/css +.csv text/csv +.cxx text/x-c +.def text/plain +.diff text/plain +.dll application/x-msdownload +.dmg application/octet-stream +.doc application/msword +.docx application/vnd.openxmlformats-officedocument.wordprocessingml.document +.epub application/epub+zip +.exe application/x-msdownload +.flv video/x-flv +.fbx application/fbx +.gz application/x-gzip +.h text/x-c +.h264 video/h264 +.hh text/x-c +.htm text/html;charset=utf-8 +.html text/html;charset=utf-8 +.ico image/x-icon +.ics text/calendar +.in text/plain +.jar application/java-archive +.java text/x-java-source +.jpeg image/jpeg +.jpg image/jpeg +.jpgv video/jpeg +.jxl image/jxl +.js application/javascript +.json application/json +.latex application/x-latex +.list text/plain +.log text/plain +.m4a audio/mp4 +.man text/troff +.mid audio/midi +.midi audio/midi +.mov video/quicktime +.mp3 audio/mpeg +.mp4 video/mp4 +.msh model/mesh +.msi application/x-msdownload +.obj application/octet-stream +.ogg audio/ogg +.otf application/x-font-otf +.pdf application/pdf +.png image/png +.ppt application/vnd.ms-powerpoint +.pptx application/vnd.openxmlformats-officedocument.presentationml.presentation +.psd image/vnd.adobe.photoshop +.py text/x-python +.rar application/x-rar-compressed +.rss application/rss+xml +.rtf application/rtf +.rtx text/richtext +.s text/x-asm +.pem application/x-pem-file" +.ser application/java-serialized-object +.sh application/x-sh +.sig application/pgp-signature +.silo model/mesh +.svg image/svg+xml +.t text/troff +.tar application/x-tar +.text text/plain +.tgz application/x-gzip +.tif image/tiff +.tiff image/tiff +.torrent application/x-bittorrent +.ttc application/x-font-ttf +.ttf application/x-font-ttf +.txt text/plain +.urls text/uri-list +.v text/x-v +.wav audio/x-wav +.wmv video/x-ms-wmv +.xls application/vnd.ms-excel +.xlsx application/vnd.openxmlformats-officedocument.spreadsheetml.sheet +.xml application/xml +.xps application/vnd.ms-xpsdocument + +# special cased based on file name +rss.xml application/rss+xml diff --git a/framework/queue.ts b/framework/queue.ts index cb8cdbc..532a249 100644 --- a/framework/queue.ts +++ b/framework/queue.ts @@ -1,8 +1,3 @@ -import { Progress } from "@paperclover/console/Progress"; -import { Spinner } from "@paperclover/console/Spinner"; -import * as path from "node:path"; -import process from "node:process"; - interface QueueOptions { name: string; fn: (item: T, spin: Spinner) => Promise; @@ -204,3 +199,8 @@ export class OnceMap { return result; } } + +import { Progress } from "@paperclover/console/Progress"; +import { Spinner } from "@paperclover/console/Spinner"; +import * as path from "node:path"; +import process from "node:process"; diff --git a/package-lock.json b/package-lock.json index 062ef13..805fb03 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1027,9 +1027,9 @@ "license": "ISC" }, "node_modules/acorn": { - "version": "8.14.1", - "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.14.1.tgz", - "integrity": "sha512-OvQ/2pUDKmgfCg++xsTX1wGxfTaszcHVcTctW4UJB4hibJx2HXxxO5UmVgyjMa+ZDsiaf5wWLXYpRWMmBI0QHg==", + "version": "8.15.0", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.15.0.tgz", + "integrity": "sha512-NZyJarBfL7nWwIq+FDL6Zp/yHEhePMNnnJ0y3qfieCrmNvYct8uvtiV41UvlSe6apAfk0fY1FbWx+NwfmpvtTg==", "license": "MIT", "bin": { "acorn": "bin/acorn" diff --git a/package.json b/package.json index a0410ef..a4002aa 100644 --- a/package.json +++ b/package.json @@ -1,5 +1,4 @@ { - "private": true, "type": "module", "dependencies": { "@hono/node-server": "^1.14.3", @@ -23,9 +22,9 @@ "#ssr/jsx-runtime": "./framework/engine/jsx-runtime.ts", "#ssr/marko": "./framework/engine/marko-runtime.ts", "#marko/html": { - "development": "marko/debug/html", - "production": "marko/html", - "types": "marko/html" + "types": "marko/html", + "production": "marko/production", + "node": "marko/debug/html" }, "#hono/platform": { "bun": "hono/bun", diff --git a/repl.js b/repl.js index faa222a..10b4f1e 100644 --- a/repl.js +++ b/repl.js @@ -18,7 +18,7 @@ hot.load("node:repl").start({ .catch((err) => { // TODO: improve @paperclover/console's ability to print AggregateError // and errors with extra random properties - console.error(inspect(err)); + console.error(util.inspect(err)); }) .then((result) => done(null, result)); }, diff --git a/run.js b/run.js index 8794cdb..80abcec 100644 --- a/run.js +++ b/run.js @@ -1,6 +1,5 @@ // This file allows using Node.js in combination with // all available plugins. Usage: "node run