| author | |
| committer | |
| log | 6832e061d3ab21c081e593dc308f5087eacf377d |
| tree | 1d5a07d4463a1df48d1c827a82b9ccdbb992faa6 |
| parent | 8f9a9d4e99fa9e1b759ae0f7a63151deae720585 |
| signature | Commit is signed but in an unrecognized format. |
12 files changed, 153 insertions(+), 40 deletions(-)
deno.jsonc+1-1| ... | @@ -1,6 +1,6 @@ | ... | @@ -1,6 +1,6 @@ |
| 1 | { | 1 | { |
| 2 | "lint": { | 2 | "lint": { |
| 3 | "exclude": ["framework/meta"], // OLD | 3 | "exclude": ["src"], // OLD |
| 4 | "rules": { | 4 | "rules": { |
| 5 | "exclude": [ | 5 | "exclude": [ |
| 6 | "no-explicit-any" // TODO | 6 | "no-explicit-any" // TODO |
framework/assets.ts+1| ... | @@ -97,3 +97,4 @@ import * as fs from "./fs.ts"; | ... | @@ -97,3 +97,4 @@ import * as fs from "./fs.ts"; |
| 97 | import type { Context, Next } from "hono"; | 97 | import type { Context, Next } from "hono"; |
| 98 | import type { StatusCode } from "hono/utils/http-status"; | 98 | import type { StatusCode } from "hono/utils/http-status"; |
| 99 | import type { BuiltAsset, BuiltAssetMap, View } from "./incremental.ts"; | 99 | import type { BuiltAsset, BuiltAssetMap, View } from "./incremental.ts"; |
| 100 | import { Buffer } from "node:buffer"; |
framework/bundle.ts+2-2| ... | @@ -1,5 +1,4 @@ | ... | @@ -1,5 +1,4 @@ |
| 1 | // This file implements client-side bundling, mostly wrapping esbuild. | 1 | // This file implements client-side bundling, mostly wrapping esbuild. |
| 2 | import process from "node:process"; | ||
| 3 | const plugins: esbuild.Plugin[] = [ | 2 | const plugins: esbuild.Plugin[] = [ |
| 4 | // There are currently no plugins needed by 'paperclover.net' | 3 | // There are currently no plugins needed by 'paperclover.net' |
| 5 | ]; | 4 | ]; |
| ... | @@ -80,6 +79,7 @@ export async function bundleClientJavaScript( | ... | @@ -80,6 +79,7 @@ export async function bundleClientJavaScript( |
| 80 | } | 79 | } |
| 81 | } | 80 | } |
| 82 | 81 | ||
| 83 | import * as path from "node:path"; | ||
| 84 | import * as esbuild from "esbuild"; | 82 | import * as esbuild from "esbuild"; |
| 83 | import * as path from "node:path"; | ||
| 84 | import process from "node:process"; | ||
| 85 | import { Incremental } from "./incremental.ts"; | 85 | import { Incremental } from "./incremental.ts"; |
framework/engine/jsx-runtime.ts+1-1| ... | @@ -35,7 +35,7 @@ declare global { | ... | @@ -35,7 +35,7 @@ declare global { |
| 35 | [name: string]: Record<string, unknown>; | 35 | [name: string]: Record<string, unknown>; |
| 36 | } | 36 | } |
| 37 | interface ElementChildrenAttribute { | 37 | interface ElementChildrenAttribute { |
| 38 | children: {}; | 38 | children: unknown; |
| 39 | } | 39 | } |
| 40 | type Element = engine.Node; | 40 | type Element = engine.Node; |
| 41 | type ElementType = keyof IntrinsicElements | engine.Component; | 41 | type ElementType = keyof IntrinsicElements | engine.Component; |
framework/hot.ts+4-2| ... | @@ -157,11 +157,13 @@ function loadMarko(module: NodeJS.Module, filepath: string) { | ... | @@ -157,11 +157,13 @@ function loadMarko(module: NodeJS.Module, filepath: string) { |
| 157 | // bare client import statements to it's own usage. | 157 | // bare client import statements to it's own usage. |
| 158 | if (src.match(/^\s*client\s+import\s+["']/m)) { | 158 | if (src.match(/^\s*client\s+import\s+["']/m)) { |
| 159 | src = src.replace( | 159 | src = src.replace( |
| 160 | /^\s*client\s+import\s+("[^"]+|'[^']+)[^\n]+/m, | 160 | /^\s*client\s+import\s+("[^"]+"|'[^']+')[^\n]+/m, |
| 161 | "<CloverScriptInclude src=$1 />", | 161 | "<CloverScriptInclude src=$1 />", |
| 162 | ) + '\nimport { Script as CloverScriptInclude } from "#sitegen";'; | 162 | ) + '\nimport { Script as CloverScriptInclude } from "#sitegen";\n'; |
| 163 | } | 163 | } |
| 164 | 164 | ||
| 165 | console.log(src); | ||
| 166 | console.log("---"); | ||
| 165 | src = marko.compileSync(src, filepath).code; | 167 | src = marko.compileSync(src, filepath).code; |
| 166 | src = src.replace("marko/debug/html", "#ssr/marko"); | 168 | src = src.replace("marko/debug/html", "#ssr/marko"); |
| 167 | return loadEsbuildCode(module, filepath, src); | 169 | return loadEsbuildCode(module, filepath, src); |
framework/mime.ts+19-18| ... | @@ -1,29 +1,30 @@ | ... | @@ -1,29 +1,30 @@ |
| 1 | const db = new Map( | 1 | const entries = fs.readFileSync( |
| 2 | fs.readFileSync(path.join(import.meta.dirname, "mime.txt"), "utf8") | 2 | path.join(import.meta.dirname, "mime.txt"), |
| 3 | .split("\n").filter(Boolean).map((line) => | 3 | "utf8", |
| 4 | line.split(/\s+/) as [string, string] | 4 | ) |
| 5 | ), | 5 | .split("\n") |
| 6 | ); | 6 | .map((line) => line.trim()) |
| 7 | .filter((line) => line && !line.startsWith("#")) | ||
| 8 | .map((line) => line.split(/\s+/, 2) as [string, string]); | ||
| 9 | const extensions = new Map(entries.filter((x) => x[0].startsWith("."))); | ||
| 10 | const fullNames = new Map(entries.filter((x) => !x[0].startsWith("."))); | ||
| 7 | 11 | ||
| 8 | /** | 12 | /** |
| 9 | * Accepts: | 13 | * Accepts: |
| 10 | * - Full file path | 14 | * - Full file path or basename |
| 11 | * - Extension (with or without dot) | 15 | * - Extension (with or without dot) |
| 12 | */ | 16 | */ |
| 13 | export function contentTypeFor(file: string) { | 17 | export function contentTypeFor(file: string) { |
| 14 | if (file.includes("/") || file.includes("\\")) { | 18 | const slash = file.indexOf("/"); |
| 15 | // Some file names are special cased. | 19 | if (slash !== -1) file = file.slice(slash + 1); |
| 16 | switch (path.basename(file)) { | ||
| 17 | case "rss.xml": | ||
| 18 | return "application/rss+xml"; | ||
| 19 | } | ||
| 20 | |||
| 21 | file = path.extname(file); | ||
| 22 | } | ||
| 23 | const dot = file.indexOf("."); | 20 | const dot = file.indexOf("."); |
| 24 | if (dot === -1) file = "." + file; | 21 | if (dot === -1) file = "." + file; |
| 25 | else if (dot > 0) file = file.slice(dot); | 22 | else if (dot > 0) { |
| 26 | return db.get(file) ?? "application/octet-stream"; | 23 | let entry = fullNames.get(file); |
| 24 | if (entry) return entry; | ||
| 25 | file = file.slice(dot); | ||
| 26 | } | ||
| 27 | return extensions.get(file) ?? "application/octet-stream"; | ||
| 27 | } | 28 | } |
| 28 | 29 | ||
| 29 | import * as fs from "./fs.ts"; | 30 | import * as fs from "./fs.ts"; |
framework/mime.txt created+99| ... | @@ -0,0 +1,99 @@ | ||
| 1 | # media types | ||
| 2 | # https://developer.mozilla.org/en-US/docs/Web/HTTP/Guides/MIME_types | ||
| 3 | .aac audio/x-aac | ||
| 4 | .aif audio/x-aiff | ||
| 5 | .aifc audio/x-aiff | ||
| 6 | .aiff audio/x-aiff | ||
| 7 | .asm text/x-asm | ||
| 8 | .avi video/x-msvideo | ||
| 9 | .bat application/x-msdownload | ||
| 10 | .c text/x-c | ||
| 11 | .chat text/x-clover-chatlog | ||
| 12 | .class application/java-vm | ||
| 13 | .cmd application/x-msdownload | ||
| 14 | .com application/x-msdownload | ||
| 15 | .conf text/plain | ||
| 16 | .cpp text/x-c | ||
| 17 | .css text/css | ||
| 18 | .csv text/csv | ||
| 19 | .cxx text/x-c | ||
| 20 | .def text/plain | ||
| 21 | .diff text/plain | ||
| 22 | .dll application/x-msdownload | ||
| 23 | .dmg application/octet-stream | ||
| 24 | .doc application/msword | ||
| 25 | .docx application/vnd.openxmlformats-officedocument.wordprocessingml.document | ||
| 26 | .epub application/epub+zip | ||
| 27 | .exe application/x-msdownload | ||
| 28 | .flv video/x-flv | ||
| 29 | .fbx application/fbx | ||
| 30 | .gz application/x-gzip | ||
| 31 | .h text/x-c | ||
| 32 | .h264 video/h264 | ||
| 33 | .hh text/x-c | ||
| 34 | .htm text/html;charset=utf-8 | ||
| 35 | .html text/html;charset=utf-8 | ||
| 36 | .ico image/x-icon | ||
| 37 | .ics text/calendar | ||
| 38 | .in text/plain | ||
| 39 | .jar application/java-archive | ||
| 40 | .java text/x-java-source | ||
| 41 | .jpeg image/jpeg | ||
| 42 | .jpg image/jpeg | ||
| 43 | .jpgv video/jpeg | ||
| 44 | .jxl image/jxl | ||
| 45 | .js application/javascript | ||
| 46 | .json application/json | ||
| 47 | .latex application/x-latex | ||
| 48 | .list text/plain | ||
| 49 | .log text/plain | ||
| 50 | .m4a audio/mp4 | ||
| 51 | .man text/troff | ||
| 52 | .mid audio/midi | ||
| 53 | .midi audio/midi | ||
| 54 | .mov video/quicktime | ||
| 55 | .mp3 audio/mpeg | ||
| 56 | .mp4 video/mp4 | ||
| 57 | .msh model/mesh | ||
| 58 | .msi application/x-msdownload | ||
| 59 | .obj application/octet-stream | ||
| 60 | .ogg audio/ogg | ||
| 61 | .otf application/x-font-otf | ||
| 62 | .pdf application/pdf | ||
| 63 | .png image/png | ||
| 64 | .ppt application/vnd.ms-powerpoint | ||
| 65 | .pptx application/vnd.openxmlformats-officedocument.presentationml.presentation | ||
| 66 | .psd image/vnd.adobe.photoshop | ||
| 67 | .py text/x-python | ||
| 68 | .rar application/x-rar-compressed | ||
| 69 | .rss application/rss+xml | ||
| 70 | .rtf application/rtf | ||
| 71 | .rtx text/richtext | ||
| 72 | .s text/x-asm | ||
| 73 | .pem application/x-pem-file" | ||
| 74 | .ser application/java-serialized-object | ||
| 75 | .sh application/x-sh | ||
| 76 | .sig application/pgp-signature | ||
| 77 | .silo model/mesh | ||
| 78 | .svg image/svg+xml | ||
| 79 | .t text/troff | ||
| 80 | .tar application/x-tar | ||
| 81 | .text text/plain | ||
| 82 | .tgz application/x-gzip | ||
| 83 | .tif image/tiff | ||
| 84 | .tiff image/tiff | ||
| 85 | .torrent application/x-bittorrent | ||
| 86 | .ttc application/x-font-ttf | ||
| 87 | .ttf application/x-font-ttf | ||
| 88 | .txt text/plain | ||
| 89 | .urls text/uri-list | ||
| 90 | .v text/x-v | ||
| 91 | .wav audio/x-wav | ||
| 92 | .wmv video/x-ms-wmv | ||
| 93 | .xls application/vnd.ms-excel | ||
| 94 | .xlsx application/vnd.openxmlformats-officedocument.spreadsheetml.sheet | ||
| 95 | .xml application/xml | ||
| 96 | .xps application/vnd.ms-xpsdocument | ||
| 97 | |||
| 98 | # special cased based on file name | ||
| 99 | rss.xml application/rss+xml | ||
framework/queue.ts+5-5| ... | @@ -1,8 +1,3 @@ | ... | @@ -1,8 +1,3 @@ |
| 1 | import { Progress } from "@paperclover/console/Progress"; | ||
| 2 | import { Spinner } from "@paperclover/console/Spinner"; | ||
| 3 | import * as path from "node:path"; | ||
| 4 | import process from "node:process"; | ||
| 5 | |||
| 6 | interface QueueOptions<T, R> { | 1 | interface QueueOptions<T, R> { |
| 7 | name: string; | 2 | name: string; |
| 8 | fn: (item: T, spin: Spinner) => Promise<R>; | 3 | fn: (item: T, spin: Spinner) => Promise<R>; |
| ... | @@ -204,3 +199,8 @@ export class OnceMap<T> { | ... | @@ -204,3 +199,8 @@ export class OnceMap<T> { |
| 204 | return result; | 199 | return result; |
| 205 | } | 200 | } |
| 206 | } | 201 | } |
| 202 | |||
| 203 | import { Progress } from "@paperclover/console/Progress"; | ||
| 204 | import { Spinner } from "@paperclover/console/Spinner"; | ||
| 205 | import * as path from "node:path"; | ||
| 206 | import process from "node:process"; |
package-lock.json+3-3| ... | @@ -1027,9 +1027,9 @@ | ... | @@ -1027,9 +1027,9 @@ |
| 1027 | "license": "ISC" | 1027 | "license": "ISC" |
| 1028 | }, | 1028 | }, |
| 1029 | "node_modules/acorn": { | 1029 | "node_modules/acorn": { |
| 1030 | "version": "8.14.1", | 1030 | "version": "8.15.0", |
| 1031 | "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.14.1.tgz", | 1031 | "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.15.0.tgz", |
| 1032 | "integrity": "sha512-OvQ/2pUDKmgfCg++xsTX1wGxfTaszcHVcTctW4UJB4hibJx2HXxxO5UmVgyjMa+ZDsiaf5wWLXYpRWMmBI0QHg==", | 1032 | "integrity": "sha512-NZyJarBfL7nWwIq+FDL6Zp/yHEhePMNnnJ0y3qfieCrmNvYct8uvtiV41UvlSe6apAfk0fY1FbWx+NwfmpvtTg==", |
| 1033 | "license": "MIT", | 1033 | "license": "MIT", |
| 1034 | "bin": { | 1034 | "bin": { |
| 1035 | "acorn": "bin/acorn" | 1035 | "acorn": "bin/acorn" |
package.json+3-4| ... | @@ -1,5 +1,4 @@ | ... | @@ -1,5 +1,4 @@ |
| 1 | { | 1 | { |
| 2 | "private": true, | ||
| 3 | "type": "module", | 2 | "type": "module", |
| 4 | "dependencies": { | 3 | "dependencies": { |
| 5 | "@hono/node-server": "^1.14.3", | 4 | "@hono/node-server": "^1.14.3", |
| ... | @@ -23,9 +22,9 @@ | ... | @@ -23,9 +22,9 @@ |
| 23 | "#ssr/jsx-runtime": "./framework/engine/jsx-runtime.ts", | 22 | "#ssr/jsx-runtime": "./framework/engine/jsx-runtime.ts", |
| 24 | "#ssr/marko": "./framework/engine/marko-runtime.ts", | 23 | "#ssr/marko": "./framework/engine/marko-runtime.ts", |
| 25 | "#marko/html": { | 24 | "#marko/html": { |
| 26 | "development": "marko/debug/html", | 25 | "types": "marko/html", |
| 27 | "production": "marko/html", | 26 | "production": "marko/production", |
| 28 | "types": "marko/html" | 27 | "node": "marko/debug/html" |
| 29 | }, | 28 | }, |
| 30 | "#hono/platform": { | 29 | "#hono/platform": { |
| 31 | "bun": "hono/bun", | 30 | "bun": "hono/bun", |
repl.js+1-1| ... | @@ -18,7 +18,7 @@ hot.load("node:repl").start({ | ... | @@ -18,7 +18,7 @@ hot.load("node:repl").start({ |
| 18 | .catch((err) => { | 18 | .catch((err) => { |
| 19 | // TODO: improve @paperclover/console's ability to print AggregateError | 19 | // TODO: improve @paperclover/console's ability to print AggregateError |
| 20 | // and errors with extra random properties | 20 | // and errors with extra random properties |
| 21 | console.error(inspect(err)); | 21 | console.error(util.inspect(err)); |
| 22 | }) | 22 | }) |
| 23 | .then((result) => done(null, result)); | 23 | .then((result) => done(null, result)); |
| 24 | }, | 24 | }, |
run.js+14-3| ... | @@ -1,6 +1,5 @@ | ... | @@ -1,6 +1,5 @@ |
| 1 | // This file allows using Node.js in combination with | 1 | // This file allows using Node.js in combination with |
| 2 | // all available plugins. Usage: "node run <script>" | 2 | // all available plugins. Usage: "node run <script>" |
| 3 | import * as path from "node:path"; | ||
| 4 | import * as util from "node:util"; | 3 | import * as util from "node:util"; |
| 5 | import process from "node:process"; | 4 | import process from "node:process"; |
| 6 | 5 | ||
| ... | @@ -47,9 +46,21 @@ if (process.argv[1].startsWith(import.meta.filename.slice(0, -".js".length))) { | ... | @@ -47,9 +46,21 @@ if (process.argv[1].startsWith(import.meta.filename.slice(0, -".js".length))) { |
| 47 | console.error("usage: node run <script> [...args]"); | 46 | console.error("usage: node run <script> [...args]"); |
| 48 | process.exit(1); | 47 | process.exit(1); |
| 49 | } | 48 | } |
| 50 | const file = path.resolve(process.argv[2]); | 49 | let found; |
| 50 | for (const dir of ["./", "./src/", "./framework/"]) { | ||
| 51 | try { | ||
| 52 | found = hot.resolveFrom(import.meta.filename, dir + process.argv[2]); | ||
| 53 | break; | ||
| 54 | } catch (e) { | ||
| 55 | continue; | ||
| 56 | } | ||
| 57 | } | ||
| 58 | if (!found) { | ||
| 59 | console.error("Cannot find script: " + process.argv[2]); | ||
| 60 | process.exit(1); | ||
| 61 | } | ||
| 51 | process.argv = [process.argv[0], ...process.argv.slice(2)]; | 62 | process.argv = [process.argv[0], ...process.argv.slice(2)]; |
| 52 | hot.load(file).main?.(); | 63 | hot.load(found).main?.(); |
| 53 | } | 64 | } |
| 54 | 65 | ||
| 55 | export { hot }; | 66 | export { hot }; |