Initial service implementation
ci / test (push) Successful in 11s

This commit is contained in:
Luna
2026-07-16 20:16:05 +00:00
commit 18d0b333d2
27 changed files with 2953 additions and 0 deletions
+16
View File
@@ -0,0 +1,16 @@
import type { NextFunction, Request, Response } from "express";
export function asyncHandler(handler: (req: Request, res: Response) => Promise<void>) {
return (req: Request, res: Response, next: NextFunction) => {
void handler(req, res).catch(next);
};
}
export function readOptionalString(value: unknown): string | null {
if (typeof value !== "string") {
return null;
}
const trimmed = value.trim();
return trimmed === "" ? null : trimmed;
}
+44
View File
@@ -0,0 +1,44 @@
export class Semaphore {
private current = 0;
private readonly waiting: Array<() => void> = [];
constructor(private readonly limit: number) {}
get active(): number {
return this.current;
}
get queued(): number {
return this.waiting.length;
}
async use<T>(task: () => Promise<T>): Promise<T> {
await this.acquire();
try {
return await task();
} finally {
this.release();
}
}
private async acquire(): Promise<void> {
if (this.current < this.limit) {
this.current += 1;
return;
}
await new Promise<void>((resolve) => {
this.waiting.push(() => {
this.current += 1;
resolve();
});
});
}
private release(): void {
this.current -= 1;
const next = this.waiting.shift();
next?.();
}
}