Compare commits

..

No commits in common. "c12b9b360a086d5459db35f9c17932060dc0efcc" and "6726cafff4839871be1e489a047127c1d1c3284e" have entirely different histories.

10 changed files with 38 additions and 154 deletions

View File

@ -1,45 +0,0 @@
#!/usr/bin/env zx
import { glob } from 'node:fs/promises';
import os from 'node:os';
import path from 'node:path';
import { chunk } from 'es-toolkit/array';
const dataDir = path.join(import.meta.dirname, '../../../data')
/**
* @type {string[]}
*/
const images = [];
for await (const image of glob('**/*.{jpg,jpeg,png,gif,svg}', {
cwd: dataDir,
})) {
images.push(image)
}
const cpus = os.cpus().length - 1;
const chunkSize = Math.ceil(images.length / cpus);
const chunks = chunk(images, chunkSize);
/**
* @param {string[]} images
*/
async function convertImages(images) {
for await (const image of images) {
const imagePath = path.resolve(dataDir, image)
const webp = imagePath.replace(path.extname(imagePath), '.webp')
const avif = imagePath.replace(path.extname(imagePath), '.avif')
console.log(`Converting ${imagePath} to ${webp}...`);
await $`ffmpeg -i "${imagePath}" -c:v libwebp -lossless 1 "${webp}"`;
console.log(`Converting ${imagePath} to ${avif}...`);
await $`ffmpeg -i "${imagePath}" -c:v libaom-av1 -still-picture 1 -pix_fmt yuv420p10le -crf 0 -strict experimental "${avif}"`;
}
}
await Promise.all(
chunks.map(convertImages)
)

View File

@ -26,18 +26,18 @@ host = '{{ get_env(name="HOST", default="localhost") }}'
enable = true
# Generating a unique request ID and enhancing logging with additional information such as the start and completion of request processing, latency, status code, and other request details.
[server.middlewares.request_id]
[server.middleware.request_id]
enable = true
[server.middlewares.logger]
[server.middleware.logger]
enable = true
# when your code is panicked, the request still returns 500 status code.
[server.middlewares.catch_panic]
[server.middleware.catch_panic]
enable = true
# Timeout for incoming requests middleware. requests that take more time from the configuration will cute and 408 status code will returned.
[server.middlewares.timeout_request]
[server.middleware.timeout_request]
enable = false
# Duration time in milliseconds.
timeout = 5000
@ -53,10 +53,7 @@ timeout = 5000
# - POST
# Set the value of the [`Access-Control-Max-Age`][mdn] header in seconds
# max_age: 3600
[server.middlewares.cors]
enable = true
[server.middlewares.compression]
[server.middleware.cors]
enable = true
# Database Configuration

View File

@ -6,7 +6,6 @@ use tracing::instrument;
use super::{builder::AppBuilder, context::AppContextTrait};
use crate::{
app::Environment,
errors::{RecorderError, RecorderResult},
web::{
controller::{self, core::ControllerTrait},
@ -65,10 +64,8 @@ impl App {
let middlewares = default_middleware_stack(context.clone());
for mid in middlewares {
if mid.is_enabled() {
router = mid.apply(router)?;
tracing::info!(name = mid.name(), "+middleware");
}
router = mid.apply(router)?;
tracing::info!(name = mid.name(), "+middleware");
}
let router = router
@ -89,17 +86,13 @@ impl App {
async {
{
let monitor = task.setup_monitor().await?;
if matches!(context.environment(), Environment::Development) {
monitor.run().await?;
} else {
monitor
.run_with_signal(async move {
Self::shutdown_signal().await;
tracing::info!("apalis shutting down...");
Ok(())
})
.await?;
}
monitor
.run_with_signal(async move {
Self::shutdown_signal().await;
tracing::info!("apalis shutting down...");
Ok(())
})
.await?;
}
Ok::<(), RecorderError>(())

View File

@ -1,4 +1,4 @@
use std::{borrow::Cow, fmt};
use std::fmt;
use async_stream::try_stream;
use axum::{body::Body, response::Response};
@ -206,12 +206,6 @@ impl StorageService {
let mime_type = mime_guess::from_path(storage_path.as_ref()).first_or_octet_stream();
let content_type = HeaderValue::from_str(mime_type.as_ref())?;
let etag = metadata.etag().map(Cow::Borrowed).or_else(|| {
let len = metadata.content_length();
let lm = metadata.last_modified()?.timestamp();
Some(Cow::Owned(format!("\"{lm:x}-{len:x}\"")))
});
let last_modified = metadata.last_modified().map(|lm| lm.to_rfc2822());
let response = if let Some(TypedHeader(range)) = range {
let ranges = range
@ -246,7 +240,7 @@ impl StorageService {
};
let body = Body::from_stream(stream);
let mut builder = Response::builder()
Response::builder()
.status(StatusCode::PARTIAL_CONTENT)
.header(
header::CONTENT_TYPE,
@ -254,34 +248,17 @@ impl StorageService {
format!("multipart/byteranges; boundary={boundary}").as_str(),
)
.unwrap(),
);
if let Some(etag) = etag {
builder = builder.header(header::ETAG, etag.to_string());
}
if let Some(last_modified) = last_modified {
builder = builder.header(header::LAST_MODIFIED, last_modified);
}
builder.body(body)?
)
.body(body)?
} else if let Some((r, content_range)) = ranges.pop() {
let reader = self.reader(storage_path.as_ref()).await?;
let stream = reader.into_bytes_stream(r).await?;
let mut builder = Response::builder()
Response::builder()
.status(StatusCode::PARTIAL_CONTENT)
.header(header::CONTENT_TYPE, content_type.clone())
.header(header::CONTENT_RANGE, content_range);
if let Some(etag) = metadata.etag() {
builder = builder.header(header::ETAG, etag);
}
if let Some(last_modified) = last_modified {
builder = builder.header(header::LAST_MODIFIED, last_modified);
}
builder.body(Body::from_stream(stream))?
.header(header::CONTENT_RANGE, content_range)
.body(Body::from_stream(stream))?
} else {
unreachable!("ranges length should be greater than 0")
}
@ -299,19 +276,10 @@ impl StorageService {
let reader = self.reader(storage_path.as_ref()).await?;
let stream = reader.into_bytes_stream(..).await?;
let mut builder = Response::builder()
Response::builder()
.status(StatusCode::OK)
.header(header::CONTENT_TYPE, content_type);
if let Some(etag) = etag {
builder = builder.header(header::ETAG, etag.to_string());
}
if let Some(last_modified) = last_modified {
builder = builder.header(header::LAST_MODIFIED, last_modified);
}
builder.body(Body::from_stream(stream))?
.header(header::CONTENT_TYPE, content_type)
.body(Body::from_stream(stream))?
};
Ok(response)

View File

@ -0,0 +1,6 @@
---
source: apps/recorder/src/web/middleware/request_id.rs
assertion_line: 126
expression: id
---
"foo-barbaz"

View File

@ -77,6 +77,7 @@
"tw-animate-css": "^1.3.4",
"type-fest": "^4.41.0",
"vaul": "^1.1.2",
"es-toolkit": "^1.39.3",
"@tanstack/react-router": "^1.121.2"
},
"devDependencies": {

View File

@ -1,38 +1,9 @@
import { type ComponentProps, useMemo, useState } from "react";
import type { ComponentProps } from "react";
export type ImgProps = Omit<ComponentProps<"img">, "alt"> &
Required<Pick<ComponentProps<"img">, "alt">> & {
optimize?: boolean;
};
const LEGACY_IMAGE_REGEX = /\.(jpg|jpeg|png|gif|svg)$/;
Required<Pick<ComponentProps<"img">, "alt">>;
export const Img = (props: ImgProps) => {
const src = props.src;
const isLegacy = useMemo(() => src?.match(LEGACY_IMAGE_REGEX), [src]);
const [isError, setIsError] = useState(false);
if (!src) {
// biome-ignore lint/nursery/noImgElement: <explanation>
return <img {...props} alt={props.alt} />;
}
return (
<picture {...props}>
{isLegacy && !isError && (
<>
<source
srcSet={src.replace(LEGACY_IMAGE_REGEX, ".webp")}
type="image/webp"
/>
<source
srcSet={src.replace(LEGACY_IMAGE_REGEX, ".avif")}
type="image/avif"
/>
</>
)}
<img {...props} alt={props.alt} onError={() => setIsError(true)} />
</picture>
);
// biome-ignore lint/nursery/noImgElement: <explanation>
return <img {...props} alt={props.alt} />;
};

View File

@ -11,9 +11,6 @@ prepare-dev-testcontainers:
docker pull ghcr.io/dumtruck/konobangu-testing-torrents:latest
docker pull postgres:17-alpine
dev-optimize-images:
npx -y zx apps/recorder/examples/optimize_image.mjs
dev-webui:
pnpm run --filter=webui dev

View File

@ -19,9 +19,6 @@
"engines": {
"node": ">=22"
},
"dependencies": {
"es-toolkit": "^1.39.3"
},
"devDependencies": {
"@biomejs/biome": "1.9.4",
"@types/node": "^24.0.1",

7
pnpm-lock.yaml generated
View File

@ -10,10 +10,6 @@ overrides:
importers:
.:
dependencies:
es-toolkit:
specifier: ^1.39.3
version: 1.39.3
devDependencies:
'@biomejs/biome':
specifier: 1.9.4
@ -213,6 +209,9 @@ importers:
embla-carousel-react:
specifier: ^8.6.0
version: 8.6.0(react@19.1.0)
es-toolkit:
specifier: ^1.39.3
version: 1.39.3
graphiql:
specifier: ^4.1.2
version: 4.1.2(@codemirror/language@6.11.1)(@emotion/is-prop-valid@0.8.8)(@types/node@24.0.1)(@types/react-dom@19.1.6(@types/react@19.1.8))(@types/react@19.1.8)(graphql-ws@6.0.4(graphql@16.11.0)(ws@8.18.2(bufferutil@4.0.9)(utf-8-validate@6.0.5)))(graphql@16.11.0)(react-dom@19.1.0(react@19.1.0))(react@19.1.0)(use-sync-external-store@1.5.0(react@19.1.0))