authorgravatar for git@paperclover.netclover caruso <git@paperclover.net> 2026-02-02 03:43:13-08:00
committergravatar for git@paperclover.netclover caruso <git@paperclover.net> 2026-02-02 03:50:47-08:00
logc776c2c6068df0f5910424eff3270e312f5f10ce
tree98944a6adaebc145d444a16813fb32f0230f6eee
parentd04d6837a37f36f46b8badbb14eb9f15c30d38b4
signature Signed by SSH key SHA256:xbd+BjjhyBfwk7GVoURf9Yx0gzDerHbvYv7SddNWmAs

feat: various changes during january friends blog

resolves #60

4 files changed, 20 insertions(+), 10 deletions(-)

run.js+8-5
...@@ -17,13 +17,13 @@ process.emit = function (event, error) {...@@ -17,13 +17,13 @@ process.emit = function (event, error) {
1717
18let hot;18let hot;
19try {19try {
20 // required APIs20 // zstd is not supported in node 22
21 await new Promise((resolve) => zlib.zstdCompress(new Uint8Array(), resolve));21 await new Promise((resolve) => zlib.zstdCompress(new Uint8Array(), resolve));
2222
23 // seems to fail in bun23 // seems to fail in bun, run it earlier to catch
24 (await import("source-map-support")).install({ hookRequire: true });24 (await import("source-map-support")).install({ hookRequire: true });
2525
26 // Init hooks26 // init hooks. some runtimes have bugs here. and long term this system should be rebuilt
27 hot = await import("./framework/hot.ts");27 hot = await import("./framework/hot.ts");
28 hot.load("./lib/log.ts");28 hot.load("./lib/log.ts");
29} catch (e) {29} catch (e) {
...@@ -70,9 +70,12 @@ if (process.argv[1].startsWith(import.meta.filename.slice(0, -".js".length))) {...@@ -70,9 +70,12 @@ if (process.argv[1].startsWith(import.meta.filename.slice(0, -".js".length))) {
70 process.exit(1);70 process.exit(1);
71 }71 }
72 let found;72 let found;
73 for (const dir of ["./", "./src/", "./framework/"]) {73 for (const dir of fs.globSync("{lib,{src,framework},{src,lib}/**/bin}")) {
74 try {74 try {
75 found = hot.resolveFrom(import.meta.filename, dir + process.argv[2]);75 found = hot.resolveFrom(
76 import.meta.filename,
77 `./${dir}/${process.argv[2]}`,
78 );
76 break;79 break;
77 } catch (e) {80 } catch (e) {
78 continue;81 continue;
src/bin/download-db.ts+2-2
...@@ -1,6 +1,6 @@...@@ -1,6 +1,6 @@
1export async function main() {1export async function main() {
2 await rsync.spawn({2 await rsync.spawn({
3 cwd: Path.resolve(import.meta.dirname).parent!.toString(),3 cwd: Path.resolve("."),
4 args: [4 args: [
5 "-a",5 "-a",
6 "--progress",6 "--progress",
...@@ -10,7 +10,7 @@ export async function main() {...@@ -10,7 +10,7 @@ export async function main() {
10 progress: progress.start("download file cache"),10 progress: progress.start("download file cache"),
11 });11 });
12 await rsync.spawn({12 await rsync.spawn({
13 cwd: Path.resolve(import.meta.dirname).parent!.toString(),13 cwd: Path.resolve("."),
14 args: [14 args: [
15 "-a",15 "-a",
16 "--progress",16 "--progress",
src/file-viewer/rsync.ts+3-2
...@@ -25,7 +25,7 @@ export interface SpawnOptions {...@@ -25,7 +25,7 @@ export interface SpawnOptions {
25 args: string[];25 args: string[];
26 rsync?: string;26 rsync?: string;
27 progress: progress.Node;27 progress: progress.Node;
28 cwd?: string;28 cwd?: Path;
29}29}
3030
31export async function spawn(options: SpawnOptions) {31export async function spawn(options: SpawnOptions) {
...@@ -33,7 +33,7 @@ export async function spawn(options: SpawnOptions) {...@@ -33,7 +33,7 @@ export async function spawn(options: SpawnOptions) {
33 using node = options.progress;33 using node = options.progress;
34 const proc = child_process.spawn(rsync, [...defaultExtraOptions, ...args], {34 const proc = child_process.spawn(rsync, [...defaultExtraOptions, ...args], {
35 stdio: ["ignore", "pipe", "pipe"],35 stdio: ["ignore", "pipe", "pipe"],
36 cwd,36 cwd: cwd?.toString(),
37 });37 });
38 const parser = new Parse();38 const parser = new Parse();
39 let running = true;39 let running = true;
...@@ -186,3 +186,4 @@ import events from "node:events";...@@ -186,3 +186,4 @@ import events from "node:events";
186import * as progress from "lib/progress.ts";186import * as progress from "lib/progress.ts";
187import { formatSize } from "@/file-viewer/format.ts";187import { formatSize } from "@/file-viewer/format.ts";
188import { UNWRAP } from "lib/assert.ts";188import { UNWRAP } from "lib/assert.ts";
189import { Path } from "#sitegen/path";
src/tags/photo-grid.tsx+7-1
...@@ -12,6 +12,7 @@ export interface PhotoGridProps {...@@ -12,6 +12,7 @@ export interface PhotoGridProps {
12type Item = [img: string, options?: ItemOptions];12type Item = [img: string, options?: ItemOptions];
1313
14interface ItemOptions {14interface ItemOptions {
15 s?: number;
15 w?: number;16 w?: number;
16 h?: number;17 h?: number;
17 align?: keyof typeof alignments;18 align?: keyof typeof alignments;
...@@ -55,9 +56,14 @@ export function PhotoGrid({...@@ -55,9 +56,14 @@ export function PhotoGrid({
55 let y = 0;56 let y = 0;
56 let contents = [];57 let contents = [];
57 for (const item of items) {58 for (const item of items) {
58 const [img, { w = 1, h = 1, align } = {}] = isArray(item) ? item : [item];59 const [
60 img,
61 { w = 1, h = 1, align, s } = {},
62 ] = isArray(item) ? item : [item];
59 if (w > width) throw new Error(`Item ${img} too wide (${w} > ${width})`);63 if (w > width) throw new Error(`Item ${img} too wide (${w} > ${width})`);
6064
65 x += s ?? 0;
66
61 while (anyCollide(x, y, w, h)) {67 while (anyCollide(x, y, w, h)) {
62 x += 1;68 x += 1;
63 if (x > width - w) x = 0, y += 1;69 if (x > width - w) x = 0, y += 1;