fix: address coderabbit review feedback

This commit is contained in:
ajnart committed 2026-08-20 15:20:21 +02:00
1 parent 17aef0588f
commit cf624e2f23
10 files changed
+256 -175

No files matched your search

+29 -1
View File
@@ -40,6 +40,7 @@ const MAX_UNCOMPRESSED_ARCHIVE_BYTES = MAX_UNCOMPRESSED_DATABASE_BYTES + 2 * MEB
const MAX_METADATA_BYTES = MEBIBYTE;
const MAX_ENCRYPTION_KEY_BYTES = 1024;
const MAX_ARCHIVE_ENTRIES = 1024;
const UPLOAD_IDLE_TIMEOUT_MS = 60_000;
const RESTART_DELAY_MS = 500;
let restoreInProgress = false;
@@ -73,6 +74,26 @@ const createRequestSizeLimiter = () => {
});
};
const createUploadIdleTimeout = () => {
let timeout: NodeJS.Timeout | undefined;
const stream = new Transform({
transform(chunk: Buffer, _encoding, callback) {
resetTimeout();
callback(null, chunk);
},
});
const resetTimeout = () => {
if (timeout) clearTimeout(timeout);
timeout = setTimeout(() => stream.destroy(new Error("Backup upload timed out")), UPLOAD_IDLE_TIMEOUT_MS);
timeout.unref();
};
resetTimeout();
stream.on("close", () => {
if (timeout) clearTimeout(timeout);
});
return stream;
};
const streamUploadedBackupAsync = async (request: Request, uploadPath: string): Promise<number | null> => {
assertDeclaredRequestSize(request);
if (!request.body) return null;
@@ -128,7 +149,9 @@ const streamUploadedBackupAsync = async (request: Request, uploadPath: string):
const requestStream = Readable.fromWeb(request.body as NodeReadableStream<Uint8Array>);
try {
await pipeline(requestStream, createRequestSizeLimiter(), parser);
await pipeline(requestStream, createUploadIdleTimeout(), createRequestSizeLimiter(), parser, {
signal: request.signal,
});
await uploadWrite;
} catch (error) {
await uploadWrite.catch(() => undefined);
@@ -453,6 +476,11 @@ export async function POST(req: Request) {
return NextResponse.json({ error: message }, { status: 400 });
} finally {
zip.close();
try {
fs.rmSync(uploadPath, { force: true });
} catch {
// The outer restore-directory cleanup retries this path.
}
}
tempDb = new BetterSqlite3(tempPath);
@@ -2,11 +2,24 @@
width: 100%;
max-width: 100%;
min-width: 0;
overflow-x: auto;
overflow-y: visible;
overflow: visible;
}
.viewport[data-board-hydrated="false"] {
.horizontalScroller {
width: 100%;
max-width: 100%;
min-width: 0;
/*
* Horizontal scrolling computes the other overflow axis to auto. Keep the
* board chrome inside that scrollport without changing the sizer's height.
*/
padding-block: var(--board-canvas-overflow-top) var(--board-canvas-overflow-bottom);
margin-block: calc(0px - var(--board-canvas-overflow-top)) calc(0px - var(--board-canvas-overflow-bottom));
overflow-x: auto;
}
.viewport[data-board-hydrated="false"] .horizontalScroller {
overflow: clip;
}
@@ -9,6 +9,8 @@ import classes from "./scaled-board-canvas.module.css";
const BoardCanvasScaleContext = createContext(1);
const MIN_READABLE_CANVAS_SCALE = 0.5;
const CANVAS_OVERFLOW_TOP = 48;
const CANVAS_OVERFLOW_BOTTOM = 8;
export const useBoardCanvasScale = () => useContext(BoardCanvasScaleContext);
@@ -76,18 +78,26 @@ export const ScaledBoardCanvas = ({
data-canvas-initial-width={initialAvailableWidth}
aria-label={label}
>
<Box className={classes.sizer} style={{ width: visualWidth, height: resolvedLogicalHeight * scale }}>
<Box
ref={canvasRef}
className={classes.canvas}
style={{
"--board-canvas-inverse-scale": inverseScale,
"--board-canvas-ui-scale": uiScale,
width: logicalWidth,
zoom: scale,
}}
>
<BoardCanvasScaleContext.Provider value={scale}>{children}</BoardCanvasScaleContext.Provider>
<Box
className={classes.horizontalScroller}
style={{
"--board-canvas-overflow-top": `${CANVAS_OVERFLOW_TOP * Math.max(1, scale)}px`,
"--board-canvas-overflow-bottom": `${CANVAS_OVERFLOW_BOTTOM * Math.max(1, scale)}px`,
}}
>
<Box className={classes.sizer} style={{ width: visualWidth, height: resolvedLogicalHeight * scale }}>
<Box
ref={canvasRef}
className={classes.canvas}
style={{
"--board-canvas-inverse-scale": inverseScale,
"--board-canvas-ui-scale": uiScale,
width: logicalWidth,
zoom: scale,
}}
>
<BoardCanvasScaleContext.Provider value={scale}>{children}</BoardCanvasScaleContext.Provider>
</Box>
</Box>
</Box>
</Box>
@@ -8,7 +8,6 @@
.board-grid-entry {
z-index: 1;
overflow: visible;
touch-action: none;
}
.board-grid-entry:has([data-board-widget-header]):hover,