Browse Source

Update Elysia (#9212)

* fix spawn.ts, update bun

* update elysia, refactor /json and /plaintext

* refactor db handlers

* use bun build --compile
Daniil Zotov 1 year ago
parent
commit
b976fe8bcc

BIN
frameworks/TypeScript/elysia/bun.lockb


+ 1 - 1
frameworks/TypeScript/elysia/elysia-postgres.dockerfile

@@ -1,4 +1,4 @@
-FROM oven/bun:1.0
+FROM oven/bun:1.1
 
 
 EXPOSE 8080
 EXPOSE 8080
 
 

+ 1 - 1
frameworks/TypeScript/elysia/elysia-smol-postgres.dockerfile

@@ -1,4 +1,4 @@
-FROM oven/bun:1.0
+FROM oven/bun:1.1
 
 
 EXPOSE 8080
 EXPOSE 8080
 
 

+ 1 - 1
frameworks/TypeScript/elysia/elysia.dockerfile

@@ -1,4 +1,4 @@
-FROM oven/bun:1.0
+FROM oven/bun:1.1
 
 
 EXPOSE 8080
 EXPOSE 8080
 
 

+ 6 - 5
frameworks/TypeScript/elysia/package.json

@@ -3,15 +3,16 @@
   "version": "0.0.1",
   "version": "0.0.1",
   "module": "src/index.js",
   "module": "src/index.js",
   "devDependencies": {
   "devDependencies": {
-    "bun-types": "latest"
+    "bun-types": "^1.1.23",
+    "typescript": "^5.5.4"
   },
   },
   "scripts": {
   "scripts": {
     "dev": "bun run --watch src/index.ts",
     "dev": "bun run --watch src/index.ts",
     "start": "bun run src/index.ts",
     "start": "bun run src/index.ts",
-    "build": "bun build --target=bun --minify src/index.ts --outdir=build"
+    "build": "bun build --compile --minify --outfile server src/index.ts"
   },
   },
   "dependencies": {
   "dependencies": {
-    "elysia": "^0.7.17",
-    "postgres": "^3.4.1"
+    "elysia": "^1.1.6",
+    "postgres": "^3.4.4"
   }
   }
-}
+}

+ 13 - 5
frameworks/TypeScript/elysia/spawn.ts

@@ -1,10 +1,18 @@
-import os from 'node:os';
+const cpus = navigator.hardwareConcurrency;
+const buns = new Array(cpus);
 
 
-// @ts-ignore
-const numCPUs = os.availableParallelism();
-for (let i = 0; i < numCPUs; i++) {
-  Bun.spawn(['bun', 'build/index.js'], {
+for (let i = 0; i < cpus; i++) {
+  buns[i] = Bun.spawn(['./server'], {
     stdio: ['inherit', 'inherit', 'inherit'],
     stdio: ['inherit', 'inherit', 'inherit'],
     env: { ...process.env },
     env: { ...process.env },
   });
   });
 }
 }
+
+function kill() {
+  for (const bun of buns) {
+    bun.kill();
+  }
+}
+
+process.on('SIGINT', kill);
+process.on('exit', kill);

+ 56 - 62
frameworks/TypeScript/elysia/src/db-handlers.ts

@@ -1,83 +1,77 @@
 import Elysia from 'elysia';
 import Elysia from 'elysia';
-import * as postgres from './postgres';
-import { Fortune, World } from './types';
+import * as db from './postgres';
+import { Fortune } from './types';
 
 
-const deps = new Elysia({
-  name: 'deps',
-})
-  .decorate('db', postgres)
-  .decorate('generateRandomNumber', () => Math.ceil(Math.random() * 10000))
-  .decorate('html', (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>`;
-    }
+function rand () {
+  return Math.ceil(Math.random() * 10000)
+}
 
 
-    return `<!DOCTYPE html><html><head><title>Fortunes</title></head><body><table><tr><th>id</th><th>message</th></tr>${html}</table></body></html>`;
-  });
+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>`;
+}
 
 
 const dbHandlers = new Elysia({
 const dbHandlers = new Elysia({
   name: 'db-handlers',
   name: 'db-handlers',
 })
 })
-  .use(deps)
-  .get(
-    '/db',
-    async ({ db, generateRandomNumber }) =>
-      await db.find(generateRandomNumber())
-  )
-  .get(
-    '/fortunes',
-    async ({ db, html }) => {
-      const fortunes = await db.fortunes();
-
-      fortunes.push({
-        id: 0,
-        message: 'Additional fortune added at request time.',
-      });
-
-      fortunes.sort((a, b) => (a.message < b.message ? -1 : 1));
-
-      return html(fortunes);
-    },
-    {
-      afterHandle({ set }) {
-        set.headers['content-type'] = 'text/html; charset=utf-8';
-      },
-    }
-  )
-  .derive(({ query }) => ({
-    numberOfObjects: Math.min(parseInt(query.queries || '1') || 1, 500),
-  }))
-  .get('/queries', async ({ db, generateRandomNumber, numberOfObjects }) => {
-    const worldPromises = new Array<Promise<World>>(numberOfObjects);
-
-    for (let i = 0; i < numberOfObjects; i++) {
-      worldPromises[i] = db.find(generateRandomNumber());
-    }
+  .onAfterHandle(({ set }) => {
+    set.headers['server'] = 'Elysia';
+  })
 
 
-    const worlds = await Promise.all(worldPromises);
+  .get('/db', () => db.find(rand()))
 
 
-    return worlds;
+  .get('/fortunes', async ({ set }) => {
+    const fortunes = await db.fortunes();
+
+    fortunes.push({
+      id: 0,
+      message: 'Additional fortune added at request time.',
+    });
+
+    fortunes.sort((a, b) => (a.message < b.message ? -1 : 1));
+
+    set.headers['content-type'] = 'text/html; charset=utf-8';
+    return renderTemplate(fortunes);
+  })
+
+  .get('/queries', async ({ query }) => {
+    const num = parseQueriesNumber(query.queries)
+    const worldPromises = new Array(num);
+
+    for (let i = 0; i < num; i++) {
+      worldPromises[i] = db.find(rand());
+    }
+
+    return await Promise.all(worldPromises);
   })
   })
-  .get('/updates', async ({ db, generateRandomNumber, numberOfObjects }) => {
-    const worldPromises = new Array<Promise<World>>(numberOfObjects);
 
 
-    for (let i = 0; i < numberOfObjects; i++) {
-      worldPromises[i] = db.find(generateRandomNumber());
+  .get('/updates', async ({ query }) => {
+    const num = parseQueriesNumber(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);
     const worlds = await Promise.all(worldPromises);
 
 
-    for (let i = 0; i < numberOfObjects; i++) {
-      worlds[i].randomNumber = generateRandomNumber();
+    for (let i = 0; i < num; i++) {
+      worlds[i].randomNumber = rand();
     }
     }
 
 
     await db.bulkUpdate(worlds);
     await db.bulkUpdate(worlds);
-
     return worlds;
     return worlds;
   });
   });
 
 

+ 13 - 9
frameworks/TypeScript/elysia/src/index.ts

@@ -3,23 +3,27 @@ import dbHandlers from './db-handlers';
 
 
 const app = new Elysia({
 const app = new Elysia({
   serve: {
   serve: {
-    // @ts-ignore
     reusePort: true,
     reusePort: true,
   },
   },
 })
 })
-  .onAfterHandle(({ set }) => {
+  .get('/plaintext', ({ set }) => {
     set.headers['server'] = 'Elysia';
     set.headers['server'] = 'Elysia';
+    return 'Hello, World!';
   })
   })
-  .decorate('HELLO_WORLD_STR', 'Hello, World!')
-  .get('/plaintext', ({ HELLO_WORLD_STR }) => HELLO_WORLD_STR)
-  .get('/json', ({ HELLO_WORLD_STR }) => ({ message: HELLO_WORLD_STR }));
 
 
-if (process.env.DATABASE) {
+  .get('/json', ({ set }) => {
+    set.headers = {
+      'content-type': 'application/json',
+      'server': 'Elysia',
+    };
+
+    return JSON.stringify({ message: 'Hello, World!' });
+  });
+
+if (Bun.env.DATABASE) {
   app.use(dbHandlers);
   app.use(dbHandlers);
 }
 }
 
 
 app.listen(8080);
 app.listen(8080);
 
 
-console.info(
-  `🦊 Elysia is running at ${app.server?.hostname}:${app.server?.port}`
-);
+console.info(`🦊 Elysia is running at ${app.server!.url}`);

+ 6 - 6
frameworks/TypeScript/elysia/src/postgres.ts

@@ -9,16 +9,16 @@ const sql = postgres({
   max: 1,
   max: 1,
 });
 });
 
 
-export const fortunes = async () =>
-  await sql<Fortune[]>`SELECT id, message FROM fortune`;
+export const fortunes = () =>
+  sql<Fortune[]>`SELECT id, message FROM fortune`;
 
 
-export const find = async (id: number) =>
-  await sql<World[]>`SELECT id, randomNumber FROM world WHERE id = ${id}`.then(
+export const find = (id: number) =>
+  sql<World[]>`SELECT id, randomNumber FROM world WHERE id = ${id}`.then(
     (arr) => arr[0]
     (arr) => arr[0]
   );
   );
 
 
-export const bulkUpdate = async (worlds: World[]) =>
-  await sql`UPDATE world SET randomNumber = (update_data.randomNumber)::int
+export const bulkUpdate = (worlds: World[]) =>
+  sql`UPDATE world SET randomNumber = (update_data.randomNumber)::int
   FROM (VALUES ${sql(
   FROM (VALUES ${sql(
     worlds
     worlds
       .map((world) => [world.id, world.randomNumber])
       .map((world) => [world.id, world.randomNumber])

+ 8 - 8
frameworks/TypeScript/elysia/src/types.ts

@@ -1,9 +1,9 @@
-export type Fortune = {
-  id: number;
-  message: string;
-};
+export interface Fortune {
+  id: number
+  message: string
+}
 
 
-export type World = {
-  id: number;
-  randomNumber: number;
-};
+export interface World {
+  id: number
+  randomNumber: number
+}