diff --git a/package-lock.json b/package-lock.json index 1a5352ac..1bdc5d2f 100644 --- a/package-lock.json +++ b/package-lock.json @@ -5,6 +5,7 @@ "requires": true, "packages": { "": { + "name": "discord-server-opensource", "version": "1.0.0", "license": "ISC", "dependencies": { @@ -12,12 +13,15 @@ "@types/node-fetch": "^2.5.7", "express": "^4.17.1", "express-cache-middleware": "^1.0.1", + "faker": "^5.1.0", "lambert-db": "^1.0.3", + "lambert-server": "^1.0.3", "missing-native-js-functions": "^1.0.8", "node-fetch": "^2.6.1", "rethinkdb-ts": "^2.4.5" }, "devDependencies": { + "@types/faker": "^5.1.5", "@types/node": "^14.14.10", "typescript": "^4.1.2" } @@ -68,6 +72,12 @@ "@types/range-parser": "*" } }, + "node_modules/@types/faker": { + "version": "5.1.5", + "resolved": "https://registry.npmjs.org/@types/faker/-/faker-5.1.5.tgz", + "integrity": "sha512-2uEQFb7bsx68rqD4F8q95wZq6LTLOyexjv6BnvJogCO4jStkyc6IDEkODPQcWfovI6g6M3uPQ2/uD/oedJKkNw==", + "dev": true + }, "node_modules/@types/mime": { "version": "2.0.3", "resolved": "https://registry.npmjs.org/@types/mime/-/mime-2.0.3.tgz", @@ -498,6 +508,14 @@ "node": ">= 0.10.0" } }, + "node_modules/express-async-errors": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/express-async-errors/-/express-async-errors-3.1.1.tgz", + "integrity": "sha512-h6aK1da4tpqWSbyCa3FxB/V6Ehd4EEB15zyQq9qe75OZBp0krinNKuH4rAY+S/U/2I36vdLAUFSjQJ+TFmODng==", + "peerDependencies": { + "express": "^4.16.2" + } + }, "node_modules/express-cache-middleware": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/express-cache-middleware/-/express-cache-middleware-1.0.1.tgz", @@ -514,6 +532,11 @@ "resolved": "git+ssh://git@github.com/tprobinson/express-mung.git#64ebd60cc4b5814ac05ea640dfd230c8df6f3527", "license": "MIT" }, + "node_modules/faker": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/faker/-/faker-5.1.0.tgz", + "integrity": "sha512-RrWKFSSA/aNLP0g3o2WW1Zez7/MnMr7xkiZmoCfAGZmdkDQZ6l2KtuXHN5XjdvpRjDl8+3vf+Rrtl06Z352+Mw==" + }, "node_modules/fd-slicer": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/fd-slicer/-/fd-slicer-1.1.0.tgz", @@ -766,6 +789,16 @@ "mongoose": "^5.11.8" } }, + "node_modules/lambert-server": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/lambert-server/-/lambert-server-1.0.3.tgz", + "integrity": "sha512-nPYnj+Rrzwa8JY7NW4vaEJYZFJ3QMTxNIVUOb2RZP/mwrTzuNhsSe0p/qRx1FS+oAO7lx4T+PWoJeKtdQaDeUg==", + "dependencies": { + "express": "^4.17.1", + "express-async-errors": "^3.1.1", + "missing-native-js-functions": "^1.0.9" + } + }, "node_modules/locate-path": { "version": "5.0.0", "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-5.0.0.tgz", @@ -903,9 +936,9 @@ } }, "node_modules/missing-native-js-functions": { - "version": "1.0.8", - "resolved": "https://registry.npmjs.org/missing-native-js-functions/-/missing-native-js-functions-1.0.8.tgz", - "integrity": "sha512-nz3elX9mm8d0Pk/dLwqj148mCP3Al6hufbWhKQ9GHxo8xAVFA3+Q1NzcBkbVeu4gBrlsk7Rd6nTuxNiX47+pXA==" + "version": "1.0.9", + "resolved": "https://registry.npmjs.org/missing-native-js-functions/-/missing-native-js-functions-1.0.9.tgz", + "integrity": "sha512-1xaJlMy7hZ27uwbgXr8bPmcVw5JZMPxdzRBGYKBD9QEaNiWiVsBmauBBrThSvV50iCb+x6yGGqAYihKahSitcA==" }, "node_modules/mkdirp": { "version": "1.0.4", @@ -1732,6 +1765,12 @@ "@types/range-parser": "*" } }, + "@types/faker": { + "version": "5.1.5", + "resolved": "https://registry.npmjs.org/@types/faker/-/faker-5.1.5.tgz", + "integrity": "sha512-2uEQFb7bsx68rqD4F8q95wZq6LTLOyexjv6BnvJogCO4jStkyc6IDEkODPQcWfovI6g6M3uPQ2/uD/oedJKkNw==", + "dev": true + }, "@types/mime": { "version": "2.0.3", "resolved": "https://registry.npmjs.org/@types/mime/-/mime-2.0.3.tgz", @@ -2071,6 +2110,12 @@ "vary": "~1.1.2" } }, + "express-async-errors": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/express-async-errors/-/express-async-errors-3.1.1.tgz", + "integrity": "sha512-h6aK1da4tpqWSbyCa3FxB/V6Ehd4EEB15zyQq9qe75OZBp0krinNKuH4rAY+S/U/2I36vdLAUFSjQJ+TFmODng==", + "requires": {} + }, "express-cache-middleware": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/express-cache-middleware/-/express-cache-middleware-1.0.1.tgz", @@ -2083,6 +2128,11 @@ "version": "git+ssh://git@github.com/tprobinson/express-mung.git#64ebd60cc4b5814ac05ea640dfd230c8df6f3527", "from": "express-mung@git+https://github.com/tprobinson/express-mung.git#sendFork" }, + "faker": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/faker/-/faker-5.1.0.tgz", + "integrity": "sha512-RrWKFSSA/aNLP0g3o2WW1Zez7/MnMr7xkiZmoCfAGZmdkDQZ6l2KtuXHN5XjdvpRjDl8+3vf+Rrtl06Z352+Mw==" + }, "fd-slicer": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/fd-slicer/-/fd-slicer-1.1.0.tgz", @@ -2270,6 +2320,16 @@ "mongoose": "^5.11.8" } }, + "lambert-server": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/lambert-server/-/lambert-server-1.0.3.tgz", + "integrity": "sha512-nPYnj+Rrzwa8JY7NW4vaEJYZFJ3QMTxNIVUOb2RZP/mwrTzuNhsSe0p/qRx1FS+oAO7lx4T+PWoJeKtdQaDeUg==", + "requires": { + "express": "^4.17.1", + "express-async-errors": "^3.1.1", + "missing-native-js-functions": "^1.0.9" + } + }, "locate-path": { "version": "5.0.0", "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-5.0.0.tgz", @@ -2370,9 +2430,9 @@ } }, "missing-native-js-functions": { - "version": "1.0.8", - "resolved": "https://registry.npmjs.org/missing-native-js-functions/-/missing-native-js-functions-1.0.8.tgz", - "integrity": "sha512-nz3elX9mm8d0Pk/dLwqj148mCP3Al6hufbWhKQ9GHxo8xAVFA3+Q1NzcBkbVeu4gBrlsk7Rd6nTuxNiX47+pXA==" + "version": "1.0.9", + "resolved": "https://registry.npmjs.org/missing-native-js-functions/-/missing-native-js-functions-1.0.9.tgz", + "integrity": "sha512-1xaJlMy7hZ27uwbgXr8bPmcVw5JZMPxdzRBGYKBD9QEaNiWiVsBmauBBrThSvV50iCb+x6yGGqAYihKahSitcA==" }, "mkdirp": { "version": "1.0.4", diff --git a/package.json b/package.json index ab7e5414..ba744d28 100644 --- a/package.json +++ b/package.json @@ -22,12 +22,15 @@ "@types/node-fetch": "^2.5.7", "express": "^4.17.1", "express-cache-middleware": "^1.0.1", + "faker": "^5.1.0", "lambert-db": "^1.0.3", + "lambert-server": "^1.0.3", "missing-native-js-functions": "^1.0.8", "node-fetch": "^2.6.1", "rethinkdb-ts": "^2.4.5" }, "devDependencies": { + "@types/faker": "^5.1.5", "@types/node": "^14.14.10", "typescript": "^4.1.2" } diff --git a/src/Server.ts b/src/Server.ts index 92c73a35..39b1fa56 100644 --- a/src/Server.ts +++ b/src/Server.ts @@ -2,27 +2,26 @@ import express, { Application, Router } from "express"; import { traverseDirectory } from "./Utils"; import { Server as HTTPServer } from "http"; import fs from "fs/promises"; +import { Server, ServerOptions } from "lambert-server"; -export type ServerOptions = { - port: number; -}; +export interface DiscordServerOptions extends ServerOptions {} -export class Server { - private app: Application; - private http: HTTPServer; - private options: ServerOptions; - private routes: Router[]; - private initalized: Promise; +declare global { + namespace Express { + interface Request { + server: DiscordServer; + } + } +} - constructor(opts: ServerOptions = { port: 8080 }) { - this.options = opts; +export class DiscordServer extends Server { + public options: DiscordServerOptions; - this.app = express(); - - this.initalized = this.init(); + constructor(opts?: DiscordServerOptions) { + super(opts); } - async init() { + async start() { // recursively loads files in routes/ this.routes = await this.registerRoutes(__dirname + "/routes/"); // const indexHTML = await (await fetch("https://discord.com/app")).buffer(); @@ -33,39 +32,6 @@ export class Server { res.set("content-type", "text/html"); res.send(indexHTML); }); - } - - async start() { - await this.initalized; - await new Promise((res) => this.app.listen(this.options.port, () => res())); - console.log(`[Server] started on ${this.options.port}`); - } - - async registerRoutes(root: string) { - return await traverseDirectory({ dirname: root, recursive: true }, this.registerRoute.bind(this, root)); - } - - registerRoute(root: string, file: string): any { - if (root.endsWith("/") || root.endsWith("\\")) root = root.slice(0, -1); // removes slash at the end of the root dir - let path = file.replace(root, ""); // remove root from path and - path = path.split(".").slice(0, -1).join("."); // trancate .js/.ts file extension of path - if (path.endsWith("/index")) path = path.slice(0, -6); // delete index from path - - try { - var router = require(file); - if (router.router) router = router.router; - if (router.default) router = router.default; - if (!router || router?.prototype?.constructor?.name !== "router") - throw `File doesn't export any default router`; - this.app.use(path, router); - console.log(`[Server] Route ${path} registerd`); - return router; - } catch (error) { - console.error(new Error(`[Server] Failed to register route ${path}: ${error}`)); - } - } - - async stop() { - return new Promise((res) => this.http.close(() => res())); + return super.start(); } } diff --git a/src/index.ts b/src/index.ts index 8765d6dc..2f8aa185 100644 --- a/src/index.ts +++ b/src/index.ts @@ -1,4 +1,4 @@ -import { Server } from "./Server"; +import { DiscordServer } from "./Server"; -const server = new Server(); +const server = new DiscordServer(); server.start().catch(console.error); diff --git a/src/models/Guild.ts.disabled b/src/models/Guild.ts.disabled new file mode 100644 index 00000000..5cffa9b8 --- /dev/null +++ b/src/models/Guild.ts.disabled @@ -0,0 +1,59 @@ +import { Snowflake } from "./Snowflake"; + +export interface Guild { + afkChannel?: Snowflake; + afkTimeout: number; + onlineCount: number; + available: boolean; + banner: string | null; + channels: GuildChannelManager; + readonly createdTimestamp: number; + defaultMessageNotifications: DefaultMessageNotifications | number; + deleted: boolean; + description: string | null; + discoverySplash: string | null; + embedChannel: GuildChannel | null; + embedChannelID: Snowflake | null; + embedEnabled: boolean; + emojis: GuildEmojiManager; + explicitContentFilter: ExplicitContentFilterLevel; + features: GuildFeatures[]; + icon: string | null; + id: Snowflake; + joinedTimestamp: number; + large: boolean; + maximumMembers: number | null; + maximumPresences: number | null; + memberCount: number; + members: GuildMemberManager; + mfaLevel: number; + name: string; + readonly nameAcronym: string; + readonly owner: Snowflake | null; + ownerID: Snowflake; + readonly partnered: boolean; + preferredLocale: string; + premiumSubscriptionCount: number | null; + premiumTier: PremiumTier; + presences: PresenceManager; + readonly publicUpdatesChannel: TextChannel | null; + publicUpdatesChannelID: Snowflake | null; + region: string; + roles: RoleManager; + readonly rulesChannel: TextChannel | null; + rulesChannelID: Snowflake | null; + readonly shard: WebSocketShard; + shardID: number; + splash: string | null; + readonly systemChannel: TextChannel | null; + systemChannelFlags: Readonly; + systemChannelID: Snowflake | null; + vanityURLCode: string | null; + vanityURLUses: number | null; + verificationLevel: VerificationLevel; + readonly verified: boolean; + readonly voiceStates: VoiceStateManager; + readonly widgetChannel: TextChannel | null; + widgetChannelID: Snowflake | null; + widgetEnabled: boolean | null; +} diff --git a/src/models/Snowflake.ts b/src/models/Snowflake.ts new file mode 100644 index 00000000..02e6df3a --- /dev/null +++ b/src/models/Snowflake.ts @@ -0,0 +1 @@ +export type Snowflake = string; diff --git a/src/models/database.ts b/src/models/database.ts new file mode 100644 index 00000000..e69de29b diff --git a/src/routes/api/v8/channel/#CHANNELID/index.ts b/src/routes/api/v8/channel/#CHANNELID/index.ts new file mode 100644 index 00000000..e69de29b diff --git a/src/routes/api/v8/guilds/index.ts b/src/routes/api/v8/guilds/index.ts new file mode 100644 index 00000000..e69de29b diff --git a/src/test.ts b/src/test.ts deleted file mode 100644 index 8dc237d9..00000000 --- a/src/test.ts +++ /dev/null @@ -1,10 +0,0 @@ -import { r } from "rethinkdb-ts"; - -async function main() { - await r.connectPool(); - - const result = await r.db("test").tableCreate("authors").run(); - console.log(result); -} - -main(); diff --git a/src/test/db_benchmark.ts b/src/test/db_benchmark.ts new file mode 100644 index 00000000..74623e06 --- /dev/null +++ b/src/test/db_benchmark.ts @@ -0,0 +1,55 @@ +// @ts-nocheck +import { r } from "rethinkdb-ts"; +import faker from "faker"; +import cluster from "cluster"; +import { performance } from "perf_hooks"; + +console.log("starting"); + +if (cluster.isMaster) { + for (var i = 0; i < 1; i++) { + cluster.fork(); + } + console.log("all nodes started"); +} + +if (cluster.isWorker) { + const inserts = []; + + for (let i = 0; i < 100; i++) { + inserts.push({ + color: faker.commerce.color(), + department: faker.commerce.department(), + price: faker.commerce.price(), + product: faker.commerce.product(), + productAdjective: faker.commerce.productAdjective(), + productName: faker.commerce.productName(), + productMaterial: faker.commerce.productMaterial(), + productDescription: faker.commerce.productDescription(), + }); + } + + async function main(connection) { + const start = performance.now(); + await r + .db("test") + .table("test") + .nth(Math.floor(Math.random() * 300000)) + .run(connection); + const end = performance.now(); + // console.log(end - start); + + // await main(connection); + setTimeout(main.bind(null, connection)); + } + + (async () => { + const threads = 30; + + for (var i = 0; i < threads; i++) { + setTimeout(async () => { + main(await r.connect({ port: 28015, host: "192.168.178.122" })); + }); + } + })(); +}