Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Binary file modified frameworks/TypeScript/elysia/bun.lockb
Binary file not shown.
7 changes: 4 additions & 3 deletions frameworks/TypeScript/elysia/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,8 @@
"version": "0.0.1",
"module": "src/index.js",
"devDependencies": {
"typescript": "^5.5.4"
"@types/bun": "^1.1.14",
"typescript": "^5.7.2"
},
"scripts": {
"dev": "bun run --watch src/index.ts",
Expand All @@ -12,7 +13,7 @@
"compile": "bun build --compile --minify --target bun --outfile server src/index.ts"
},
"dependencies": {
"elysia": "^1.1.16",
"postgres": "^3.4.4"
"elysia": "^1.2.9",
"postgres": "^3.4.5"
}
}
122 changes: 57 additions & 65 deletions frameworks/TypeScript/elysia/src/db-handlers.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,74 +2,66 @@ import { Elysia, t } from "elysia";
import * as db from "./postgres";
import { Fortune } from "./types";

function rand() {
return Math.ceil(Math.random() * 10000);
export function rand() {
return Math.ceil(Math.random() * 10000);
}

function parseQueriesNumber(q?: string) {
return Math.min(parseInt(q || "1") || 1, 500);
}

function renderTemplate(fortunes: Fortune[]) {
const n = fortunes.length;

let html = "";
for (let i = 0; i < n; i++) {
html += `<tr><td>${fortunes[i].id}</td><td>${Bun.escapeHTML(
fortunes[i].message,
)}</td></tr>`;
}

return `<!DOCTYPE html><html><head><title>Fortunes</title></head><body><table><tr><th>id</th><th>message</th></tr>${html}</table></body></html>`;
// NaN is falsy, fallback to one.
return Math.min(+q! || 1, 500);
}

export const dbHandlers = new Elysia()
.headers({
server: "Elysia",
})
.get("/db", () => db.find(rand()))
.get("/fortunes", async (c) => {
const fortunes = await db.fortunes();

fortunes.push({
id: 0,
message: "Additional fortune added at request time.",
});

fortunes.sort((a, b) => {
if (a.message < b.message) return -1;

return 1;
});

c.set.headers["content-type"] = "text/html; charset=utf-8";

return renderTemplate(fortunes);
})
.get("/queries", (c) => {
const num = parseQueriesNumber(c.query.queries);
const worldPromises = new Array(num);

for (let i = 0; i < num; i++) {
worldPromises[i] = db.find(rand());
}

return Promise.all(worldPromises);
})
.get("/updates", async (c) => {
const num = parseQueriesNumber(c.query.queries);
const worldPromises = new Array(num);

for (let i = 0; i < num; i++) {
worldPromises[i] = db.find(rand());
}

const worlds = await Promise.all(worldPromises);

for (let i = 0; i < num; i++) {
worlds[i].randomNumber = rand();
}

await db.bulkUpdate(worlds);
return worlds;
});
.headers({
server: "Elysia",
})
// ? Mark as async for Promise result to prevent double Elysia's mapResponse execution
.get("/db", async () => db.find(rand()))
.get("/fortunes", async (c) => {
const fortunes = await db.fortunes();

fortunes.push({
id: 0,
message: "Additional fortune added at request time.",
});

fortunes.sort((a, b) => {
if (a.message < b.message) return -1;

return 1;
});

c.set.headers["content-type"] = "text/html; charset=utf-8";

const n = fortunes.length;

let html = "";
for (let i = 0; i < n; i++) {
html += `<tr><td>${fortunes[i].id}</td><td>${Bun.escapeHTML(
fortunes[i].message,
)}</td></tr>`;
}

return `<!DOCTYPE html><html><head><title>Fortunes</title></head><body><table><tr><th>id</th><th>message</th></tr>${html}</table></body></html>`;
})
// ? Mark as async for Promise result to prevent double Elysia's mapResponse execution
.get("/queries", async (c) => {
const num = parseQueriesNumber(c.query.queries);
const worldPromises = new Array(num);

for (let i = 0; i < num; i++) worldPromises[i] = db.find(rand());

return Promise.all(worldPromises);
})
.get("/updates", async (c) => {
const num = parseQueriesNumber(c.query.queries);
const worldPromises = new Array(num);

for (let i = 0; i < num; i++)
worldPromises[i] = db.findThenRand(rand());

const worlds = await Promise.all(worldPromises);

await db.bulkUpdate(worlds);
return worlds;
});
43 changes: 26 additions & 17 deletions frameworks/TypeScript/elysia/src/postgres.ts
Original file line number Diff line number Diff line change
@@ -1,30 +1,39 @@
import postgres from "postgres";
import { Fortune, World } from "./types";
import { rand } from "./db-handlers";
import type { Fortune, World } from "./types";

const sql = postgres({
host: "tfb-database",
user: "benchmarkdbuser",
password: "benchmarkdbpass",
database: "hello_world",
max: 1,
host: "tfb-database",
user: "benchmarkdbuser",
password: "benchmarkdbpass",
database: "hello_world",
max: 1,
});

export const fortunes = () => sql<Fortune[]>`SELECT id, message FROM fortune`;

export const find = (id: number) =>
sql<World[]>`SELECT id, randomNumber FROM world WHERE id = ${id}`.then(
(arr) => arr[0],
);
sql<World[]>`SELECT id, randomNumber FROM world WHERE id = ${id}`.then(
(arr) => arr[0],
);

export const findThenRand = (id: number) =>
sql<World[]>`SELECT id, randomNumber FROM world WHERE id = ${id}`.then(
(arr) => {
arr[0].randomNumber = rand();
return arr[0];
},
);

export const bulkUpdate = (worlds: World[]) => {
worlds = worlds.toSorted((a, b) => a.id - b.id);
worlds = worlds.toSorted((a, b) => a.id - b.id);

const values = new Array(worlds.length);
for (let i = 0; i < worlds.length; i++) {
values[i] = [worlds[i].id, worlds[i].randomNumber];
}
const values = new Array(worlds.length);
for (let i = 0; i < worlds.length; i++) {
values[i] = [worlds[i].id, worlds[i].randomNumber];
}

return sql`UPDATE world SET randomNumber = (update_data.randomNumber)::int
FROM (VALUES ${sql(values)}) AS update_data (id, randomNumber)
WHERE world.id = (update_data.id)::int`;
return sql`UPDATE world SET randomNumber = (update_data.randomNumber)::int
FROM (VALUES ${sql(values)}) AS update_data (id, randomNumber)
WHERE world.id = (update_data.id)::int`;
};
Loading