velocious 1.0.1 → 1.0.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +36 -0
- package/bin/velocious.mjs +8 -0
- package/index.mjs +21 -0
- package/package.json +15 -7
- package/peak_flow.yml +12 -5
- package/spec/cli/commands/db/create-spec.mjs +25 -0
- package/spec/cli/commands/db/migrate-spec.mjs +37 -0
- package/spec/cli/commands/destroy/migration-spec.mjs +15 -0
- package/spec/cli/commands/generate/migration-spec.mjs +18 -0
- package/spec/cli/commands/init-spec.mjs +19 -0
- package/spec/cli/commands/test/test-files-finder-spec.mjs +12 -0
- package/spec/database/connection/drivers/mysql/{query-parser-spec.cjs → query-parser-spec.mjs} +12 -8
- package/spec/database/drivers/mysql/connection-spec.mjs +21 -0
- package/spec/database/record/create-spec.mjs +14 -0
- package/spec/database/record/destroy-spec.mjs +17 -0
- package/spec/database/record/find-spec.mjs +29 -0
- package/spec/database/record/update-spec.mjs +15 -0
- package/spec/dummy/dummy-directory.mjs +11 -0
- package/spec/dummy/index.mjs +63 -0
- package/spec/dummy/src/config/configuration.example.mjs +19 -0
- package/spec/dummy/src/config/configuration.peakflow.mjs +20 -0
- package/spec/dummy/src/{routes.cjs → config/routes.mjs} +3 -2
- package/spec/dummy/src/database/migrations/20230728075328-create-projects.mjs +11 -0
- package/spec/dummy/src/database/migrations/20230728075329-create-tasks.mjs +13 -0
- package/spec/dummy/src/models/task.mjs +4 -0
- package/spec/dummy/src/routes/tasks/controller.mjs +26 -0
- package/spec/http-server/{client-spec.cjs → client-spec.mjs} +7 -10
- package/spec/http-server/{get-spec.cjs → get-spec.mjs} +2 -2
- package/spec/http-server/post-spec.mjs +72 -0
- package/spec/support/jasmine.json +4 -3
- package/src/application.mjs +50 -0
- package/src/cli/base-command.mjs +11 -0
- package/src/cli/commands/db/create.mjs +50 -0
- package/src/cli/commands/db/migrate.mjs +58 -0
- package/src/cli/commands/destroy/migration.mjs +35 -0
- package/src/cli/commands/generate/migration.mjs +36 -0
- package/src/cli/commands/init.mjs +60 -0
- package/src/cli/commands/test/index.mjs +14 -0
- package/src/cli/commands/test/test-files-finder.mjs +99 -0
- package/src/cli/commands/test/test-runner.mjs +19 -0
- package/src/cli/index.mjs +59 -0
- package/src/configuration-resolver.mjs +26 -0
- package/src/configuration.mjs +49 -0
- package/src/{controller.cjs → controller.mjs} +21 -4
- package/src/database/drivers/base.mjs +17 -0
- package/src/database/drivers/index.mjs +5 -0
- package/src/database/drivers/mysql/connect-connection.mjs +12 -0
- package/src/database/drivers/mysql/index.mjs +102 -0
- package/src/database/drivers/mysql/options.mjs +17 -0
- package/src/database/drivers/mysql/query-parser.mjs +25 -0
- package/src/database/drivers/mysql/query.mjs +26 -0
- package/src/database/drivers/mysql/sql/create-database.mjs +4 -0
- package/src/database/drivers/mysql/sql/create-table.mjs +4 -0
- package/src/database/drivers/mysql/sql/delete.mjs +19 -0
- package/src/database/drivers/mysql/sql/insert.mjs +29 -0
- package/src/database/drivers/mysql/sql/update.mjs +31 -0
- package/src/database/drivers/sqlite/options.mjs +17 -0
- package/src/database/drivers/sqlite/query-parser.mjs +25 -0
- package/src/database/drivers/sqlite/sql/create-database.mjs +4 -0
- package/src/database/drivers/sqlite/sql/create-table.mjs +4 -0
- package/src/database/drivers/sqlite/sql/delete.mjs +19 -0
- package/src/database/drivers/sqlite/sql/insert.mjs +29 -0
- package/src/database/drivers/sqlite/sql/update.mjs +31 -0
- package/src/database/drivers/sqlite-expo/index.mjs +100 -0
- package/src/database/drivers/sqlite-expo/query.mjs +9 -0
- package/src/database/handler.mjs +7 -0
- package/src/database/index.mjs +15 -0
- package/src/database/migration/index.mjs +18 -0
- package/src/database/migrator/index.mjs +15 -0
- package/src/database/pool/index.mjs +112 -0
- package/src/database/query/base.mjs +11 -0
- package/src/database/query/create-database-base.mjs +20 -0
- package/src/database/query/create-table-base.mjs +69 -0
- package/src/database/query/delete-base.mjs +9 -0
- package/src/database/query/from-base.mjs +9 -0
- package/src/database/query/from-plain.mjs +10 -0
- package/src/database/query/from-table.mjs +12 -0
- package/src/database/query/index.mjs +144 -0
- package/src/database/query/insert-base.mjs +15 -0
- package/src/database/query/join-base.mjs +9 -0
- package/src/database/query/join-plain.mjs +12 -0
- package/src/database/query/order-base.mjs +9 -0
- package/src/database/query/order-plain.mjs +21 -0
- package/src/database/query/select-base.mjs +9 -0
- package/src/database/query/select-plain.mjs +12 -0
- package/src/database/query/{select-table-and-column.cjs → select-table-and-column.mjs} +4 -4
- package/src/database/query/update-base.mjs +16 -0
- package/src/database/query-parser/{from-parser.cjs → from-parser.mjs} +3 -6
- package/src/database/query-parser/{joins-parser.cjs → joins-parser.mjs} +3 -6
- package/src/database/query-parser/{options.cjs → options.mjs} +13 -2
- package/src/database/query-parser/{select-parser.cjs → select-parser.mjs} +7 -6
- package/src/database/record/index.mjs +187 -0
- package/src/database/record/record-not-found-error.mjs +1 -0
- package/src/database/table-data/index.mjs +83 -0
- package/src/{error-logger.js → error-logger.mjs} +1 -1
- package/src/http-server/client/{index.cjs → index.mjs} +10 -11
- package/src/http-server/client/params-to-object.mjs +68 -0
- package/src/http-server/client/request-buffer/form-data-part.mjs +42 -0
- package/src/http-server/client/request-buffer/header.mjs +7 -0
- package/src/http-server/client/request-buffer/index.mjs +229 -0
- package/src/http-server/client/request-parser.mjs +47 -0
- package/src/http-server/client/{request-runner.cjs → request-runner.mjs} +5 -5
- package/src/http-server/client/request.mjs +15 -0
- package/src/http-server/client/{response.cjs → response.mjs} +1 -1
- package/src/http-server/index.mjs +137 -0
- package/src/http-server/server-client.mjs +47 -0
- package/src/http-server/worker-handler/index.mjs +79 -0
- package/src/http-server/worker-handler/worker-script.mjs +4 -0
- package/src/http-server/worker-handler/worker-thread.mjs +65 -0
- package/src/{logger.cjs → logger.mjs} +2 -2
- package/src/routes/base-route.mjs +34 -0
- package/src/routes/{get-route.cjs → get-route.mjs} +5 -3
- package/src/routes/index.mjs +9 -0
- package/src/routes/{resolver.cjs → resolver.mjs} +17 -9
- package/src/routes/{resource-route.cjs → resource-route.mjs} +9 -5
- package/src/routes/root-route.mjs +6 -0
- package/src/spec/index.mjs +5 -0
- package/src/templates/configuration.mjs +17 -0
- package/src/templates/generate-migration.mjs +11 -0
- package/src/templates/routes.mjs +11 -0
- package/src/utils/file-exists.mjs +13 -0
- package/bin/velocious +0 -14
- package/index.cjs +0 -13
- package/spec/dummy/config/databases.example.json +0 -10
- package/spec/dummy/config/databases.json +0 -0
- package/spec/dummy/config/databases.peakflow.json +0 -11
- package/spec/dummy/index.cjs +0 -40
- package/spec/dummy/src/models/task.cjs +0 -4
- package/spec/dummy/src/routes/tasks/controller.cjs +0 -18
- package/src/application.cjs +0 -36
- package/src/configuration.cjs +0 -14
- package/src/database/connection/drivers/mysql/index.cjs +0 -5
- package/src/database/connection/drivers/mysql/options.cjs +0 -7
- package/src/database/connection/drivers/mysql/query-parser.cjs +0 -26
- package/src/database/connection/index.cjs +0 -2
- package/src/database/handler.cjs +0 -5
- package/src/database/index.cjs +0 -9
- package/src/database/pool/index.cjs +0 -2
- package/src/database/query/from-base.cjs +0 -15
- package/src/database/query/from-plain.cjs +0 -12
- package/src/database/query/from-table.cjs +0 -12
- package/src/database/query/index.cjs +0 -59
- package/src/database/query/join-base.cjs +0 -15
- package/src/database/query/join-plain.cjs +0 -12
- package/src/database/query/select-base.cjs +0 -15
- package/src/database/query/select-plain.cjs +0 -12
- package/src/database/record/index.cjs +0 -5
- package/src/http-server/client/request-parser.cjs +0 -92
- package/src/http-server/client/request.cjs +0 -25
- package/src/http-server/index.cjs +0 -78
- package/src/http-server/worker-handler/index.cjs +0 -78
- package/src/http-server/worker-handler/socket-handler.cjs +0 -35
- package/src/http-server/worker-handler/worker-script.cjs +0 -4
- package/src/http-server/worker-handler/worker-thread.cjs +0 -49
- package/src/routes/base-route.cjs +0 -25
- package/src/routes/index.cjs +0 -9
- package/src/routes/root-route.cjs +0 -4
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
import {digg} from "diggerize"
|
|
2
|
+
import {EventEmitter} from "events"
|
|
3
|
+
import Incorporator from "incorporator"
|
|
4
|
+
import ParamsToObject from "./params-to-object.mjs"
|
|
5
|
+
import RequestBuffer from "./request-buffer/index.mjs"
|
|
6
|
+
|
|
7
|
+
export default class VelociousHttpServerClientRequestParser {
|
|
8
|
+
constructor({configuration}) {
|
|
9
|
+
if (!configuration) throw new Error("No configuration given")
|
|
10
|
+
|
|
11
|
+
this.configuration = configuration
|
|
12
|
+
this.data = []
|
|
13
|
+
this.events = new EventEmitter()
|
|
14
|
+
this.params = {}
|
|
15
|
+
|
|
16
|
+
this.requestBuffer = new RequestBuffer({configuration})
|
|
17
|
+
this.requestBuffer.events.on("completed", this.requestDone)
|
|
18
|
+
this.requestBuffer.events.on("form-data-part", this.onFormDataPart)
|
|
19
|
+
this.requestBuffer.events.on("request-done", this.requestDone)
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
onFormDataPart = (formDataPart) => {
|
|
23
|
+
const unorderedParams = {}
|
|
24
|
+
|
|
25
|
+
unorderedParams[formDataPart.getName()] = formDataPart.getValue()
|
|
26
|
+
|
|
27
|
+
const paramsToObject = new ParamsToObject(unorderedParams)
|
|
28
|
+
const newParams = paramsToObject.toObject()
|
|
29
|
+
const incorporator = new Incorporator({objects: [this.params, newParams]})
|
|
30
|
+
|
|
31
|
+
incorporator.merge()
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
feed = (data) => this.requestBuffer.feed(data)
|
|
35
|
+
getHeader = (name) => this.requestBuffer.getHeader(name)?.value
|
|
36
|
+
getHttpMethod = () => digg(this, "requestBuffer", "httpMethod")
|
|
37
|
+
getHost = () => this.requestBuffer.getHeader("host")?.value
|
|
38
|
+
getPath = () => digg(this, "requestBuffer", "path")
|
|
39
|
+
|
|
40
|
+
requestDone = () => {
|
|
41
|
+
const incorporator = new Incorporator({objects: [this.params, this.requestBuffer.params]})
|
|
42
|
+
|
|
43
|
+
incorporator.merge()
|
|
44
|
+
this.state = "done"
|
|
45
|
+
this.events.emit("done")
|
|
46
|
+
}
|
|
47
|
+
}
|
|
@@ -1,9 +1,9 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
1
|
+
import EventEmitter from "events"
|
|
2
|
+
import logger from "../../logger.mjs"
|
|
3
|
+
import Response from "./response.mjs"
|
|
4
|
+
import RoutesResolver from "../../routes/resolver.mjs"
|
|
5
5
|
|
|
6
|
-
|
|
6
|
+
export default class VelociousHttpServerClientRequestRunner {
|
|
7
7
|
events = new EventEmitter()
|
|
8
8
|
|
|
9
9
|
constructor({configuration, request}) {
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import {digg} from "diggerize"
|
|
2
|
+
import RequestParser from "./request-parser.mjs"
|
|
3
|
+
|
|
4
|
+
export default class VelociousHttpServerClientRequest {
|
|
5
|
+
constructor({configuration}) {
|
|
6
|
+
this.configuration = configuration
|
|
7
|
+
this.requestParser = new RequestParser({configuration})
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
feed = (data) => this.requestParser.feed(data)
|
|
11
|
+
httpMethod = () => this.requestParser.getHttpMethod()
|
|
12
|
+
host = () => this.requestParser.getHost()
|
|
13
|
+
path = () => this.requestParser.getPath()
|
|
14
|
+
params = () => digg(this, "requestParser", "params")
|
|
15
|
+
}
|
|
@@ -0,0 +1,137 @@
|
|
|
1
|
+
import {digg} from "diggerize"
|
|
2
|
+
import logger from "../logger.mjs"
|
|
3
|
+
import Net from "net"
|
|
4
|
+
import ServerClient from "./server-client.mjs"
|
|
5
|
+
import WorkerHandler from "./worker-handler/index.mjs"
|
|
6
|
+
|
|
7
|
+
export default class VelociousHttpServer {
|
|
8
|
+
clientCount = 0
|
|
9
|
+
clients = {}
|
|
10
|
+
workerCount = 0
|
|
11
|
+
workerHandlers = []
|
|
12
|
+
|
|
13
|
+
constructor({configuration, host, maxWorkers, port}) {
|
|
14
|
+
this.configuration = configuration
|
|
15
|
+
this.host = host || "0.0.0.0"
|
|
16
|
+
this.port = port || 3006
|
|
17
|
+
this.maxWorkers = maxWorkers || 16
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
async start() {
|
|
21
|
+
await this._ensureAtLeastOneWorker()
|
|
22
|
+
this.netServer = new Net.Server()
|
|
23
|
+
this.netServer.on("connection", this.onConnection)
|
|
24
|
+
await this._netServerListen()
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
_netServerListen() {
|
|
28
|
+
return new Promise((resolve, reject) => {
|
|
29
|
+
try {
|
|
30
|
+
this.netServer.listen(this.port, this.host, () => {
|
|
31
|
+
logger(this, `Velocious listening on ${this.host}:${this.port}`)
|
|
32
|
+
resolve()
|
|
33
|
+
})
|
|
34
|
+
} catch (error) {
|
|
35
|
+
reject(error)
|
|
36
|
+
}
|
|
37
|
+
})
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
async _ensureAtLeastOneWorker() {
|
|
41
|
+
if (this.workerHandlers.length == 0) {
|
|
42
|
+
await this.spawnWorker()
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
isActive() {
|
|
47
|
+
return this.netServer.listening
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
async stopClients() {
|
|
51
|
+
for (const clientCount in this.clients) {
|
|
52
|
+
const client = this.clients[clientCount]
|
|
53
|
+
|
|
54
|
+
await client.close()
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
stopServer() {
|
|
59
|
+
return new Promise((resolve, reject) => {
|
|
60
|
+
this.netServer.close((error) => {
|
|
61
|
+
if (error) {
|
|
62
|
+
reject(error)
|
|
63
|
+
} else {
|
|
64
|
+
resolve()
|
|
65
|
+
}
|
|
66
|
+
})
|
|
67
|
+
})
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
async stop() {
|
|
71
|
+
await this.stopClients()
|
|
72
|
+
await this.stopServer()
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
onConnection = (socket) => {
|
|
76
|
+
const clientCount = this.clientCount
|
|
77
|
+
|
|
78
|
+
logger(this, `New client ${clientCount}`)
|
|
79
|
+
|
|
80
|
+
this.clientCount++
|
|
81
|
+
|
|
82
|
+
const workerHandler = this.workerHandlerToUse()
|
|
83
|
+
const client = new ServerClient({
|
|
84
|
+
clientCount,
|
|
85
|
+
configuration: this.configuration,
|
|
86
|
+
socket
|
|
87
|
+
})
|
|
88
|
+
|
|
89
|
+
client.events.on("close", this.onClientClose)
|
|
90
|
+
|
|
91
|
+
logger(this, `Gave client ${clientCount} to worker ${workerHandler.workerCount}`)
|
|
92
|
+
|
|
93
|
+
workerHandler.addSocketConnection(client)
|
|
94
|
+
|
|
95
|
+
this.clients[clientCount] = client
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
onClientClose = (client) => {
|
|
99
|
+
const clientCount = digg(client, "clientCount")
|
|
100
|
+
const oldClientsLength = Object.keys(this.clients).length
|
|
101
|
+
|
|
102
|
+
delete this.clients[clientCount]
|
|
103
|
+
|
|
104
|
+
const newClientsLength = Object.keys(this.clients).length
|
|
105
|
+
|
|
106
|
+
if (newClientsLength != (oldClientsLength - 1)) {
|
|
107
|
+
console.error(`Expected client to have been removed but length didn't change from ${oldClientsLength} to ${oldClientsLength - 1}`)
|
|
108
|
+
}
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
async spawnWorker() {
|
|
112
|
+
const workerCount = this.workerCount
|
|
113
|
+
|
|
114
|
+
this.workerCount++
|
|
115
|
+
|
|
116
|
+
const workerHandler = new WorkerHandler({
|
|
117
|
+
configuration: this.configuration,
|
|
118
|
+
workerCount
|
|
119
|
+
})
|
|
120
|
+
|
|
121
|
+
await workerHandler.start()
|
|
122
|
+
this.workerHandlers.push(workerHandler)
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
workerHandlerToUse() {
|
|
126
|
+
logger(this, `Worker handlers length: ${this.workerHandlers.length}`)
|
|
127
|
+
|
|
128
|
+
const randomWorkerNumber = parseInt(Math.random() * this.workerHandlers.length)
|
|
129
|
+
const workerHandler = this.workerHandlers[randomWorkerNumber]
|
|
130
|
+
|
|
131
|
+
if (!workerHandler) {
|
|
132
|
+
throw new Error(`No workerHandler by that number: ${randomWorkerNumber}`)
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
return workerHandler
|
|
136
|
+
}
|
|
137
|
+
}
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
import EventEmitter from "events"
|
|
2
|
+
import logger from "../logger.mjs"
|
|
3
|
+
|
|
4
|
+
export default class ServerClient {
|
|
5
|
+
events = new EventEmitter()
|
|
6
|
+
|
|
7
|
+
constructor({configuration, socket, clientCount}) {
|
|
8
|
+
if (!configuration) throw new Error("No configuration given")
|
|
9
|
+
|
|
10
|
+
this.configuration = configuration
|
|
11
|
+
this.socket = socket
|
|
12
|
+
this.clientCount = clientCount
|
|
13
|
+
|
|
14
|
+
socket.on("end", this.onSocketEnd)
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
listen = () => this.socket.on("data", this.onSocketData)
|
|
18
|
+
|
|
19
|
+
close() {
|
|
20
|
+
return new Promise((resolve, reject) => {
|
|
21
|
+
this.socket.destroy()
|
|
22
|
+
this.events.emit("close", this)
|
|
23
|
+
resolve()
|
|
24
|
+
})
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
onSocketData = (chunk) => {
|
|
28
|
+
logger(this, `Socket ${this.clientCount}: ${chunk}`)
|
|
29
|
+
|
|
30
|
+
this.worker.postMessage({
|
|
31
|
+
command: "clientWrite",
|
|
32
|
+
chunk,
|
|
33
|
+
clientCount: this.clientCount
|
|
34
|
+
})
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
onSocketEnd = () => {
|
|
38
|
+
logger(this, `Socket ${this.clientCount} end`)
|
|
39
|
+
this.events.emit("close", this)
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
send(data) {
|
|
43
|
+
logger(this, "Send", data)
|
|
44
|
+
|
|
45
|
+
this.socket.write(data)
|
|
46
|
+
}
|
|
47
|
+
}
|
|
@@ -0,0 +1,79 @@
|
|
|
1
|
+
import {digg, digs} from "diggerize"
|
|
2
|
+
import {dirname} from "path"
|
|
3
|
+
import {fileURLToPath} from "url"
|
|
4
|
+
import logger from "../../logger.mjs"
|
|
5
|
+
import {Worker} from "worker_threads"
|
|
6
|
+
|
|
7
|
+
export default class VelociousHttpServerWorker {
|
|
8
|
+
constructor({configuration, workerCount}) {
|
|
9
|
+
this.configuration = configuration
|
|
10
|
+
this.clients = {}
|
|
11
|
+
this.workerCount = workerCount
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
async start() {
|
|
15
|
+
return new Promise((resolve) => {
|
|
16
|
+
const {debug, directory} = digs(this.configuration, "debug", "directory")
|
|
17
|
+
const __filename = fileURLToPath(import.meta.url)
|
|
18
|
+
const __dirname = dirname(__filename)
|
|
19
|
+
|
|
20
|
+
this.onStartCallback = resolve
|
|
21
|
+
this.worker = new Worker(`${__dirname}/worker-script.mjs`, {
|
|
22
|
+
workerData: {
|
|
23
|
+
debug,
|
|
24
|
+
directory,
|
|
25
|
+
workerCount: this.workerCount
|
|
26
|
+
}
|
|
27
|
+
})
|
|
28
|
+
this.worker.on("error", this.onWorkerError)
|
|
29
|
+
this.worker.on("exit", this.onWorkerExit)
|
|
30
|
+
this.worker.on("message", this.onWorkerMessage)
|
|
31
|
+
})
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
addSocketConnection(client) {
|
|
35
|
+
const clientCount = digg(client, "clientCount")
|
|
36
|
+
|
|
37
|
+
client.socket.on("end", () => {
|
|
38
|
+
logger(this, `Removing ${clientCount} from clients`)
|
|
39
|
+
delete this.clients[clientCount]
|
|
40
|
+
})
|
|
41
|
+
|
|
42
|
+
client.worker = this.worker
|
|
43
|
+
client.listen()
|
|
44
|
+
|
|
45
|
+
this.clients[clientCount] = client
|
|
46
|
+
this.worker.postMessage({command: "newClient", clientCount})
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
onWorkerError = (error) => {
|
|
50
|
+
throw error // Throws original error with backtrace and everything into the console
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
onWorkerExit = (code) => {
|
|
54
|
+
if (code !== 0) {
|
|
55
|
+
throw new Error(`Client worker stopped with exit code ${code}`)
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
onWorkerMessage = (data) => {
|
|
60
|
+
logger(this, `Worker message`, data)
|
|
61
|
+
|
|
62
|
+
const {command} = digs(data, "command")
|
|
63
|
+
|
|
64
|
+
if (command == "started") {
|
|
65
|
+
this.onStartCallback()
|
|
66
|
+
this.onStartCallback = null
|
|
67
|
+
} else if (command == "clientOutput") {
|
|
68
|
+
logger(this, "CLIENT OUTPUT", data)
|
|
69
|
+
|
|
70
|
+
const {clientCount, output} = digs(data, "clientCount", "output")
|
|
71
|
+
|
|
72
|
+
logger(this, "CLIENT OUTPUT", data)
|
|
73
|
+
|
|
74
|
+
this.clients[clientCount].send(output)
|
|
75
|
+
} else {
|
|
76
|
+
throw new Error(`Unknown command: ${command}`)
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
}
|
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
import Application from "../../application.mjs"
|
|
2
|
+
import Client from "../client/index.mjs"
|
|
3
|
+
import DatabasePool from "../../database/pool/index.mjs"
|
|
4
|
+
import {digg, digs} from "diggerize"
|
|
5
|
+
import errorLogger from "../../error-logger.mjs"
|
|
6
|
+
import logger from "../../logger.mjs"
|
|
7
|
+
|
|
8
|
+
export default class VelociousHttpServerWorkerHandlerWorkerThread {
|
|
9
|
+
constructor({parentPort, workerData}) {
|
|
10
|
+
const {workerCount} = digs(workerData, "workerCount")
|
|
11
|
+
|
|
12
|
+
this.clients = {}
|
|
13
|
+
this.parentPort = parentPort
|
|
14
|
+
this.workerData = workerData
|
|
15
|
+
this.workerCount = workerCount
|
|
16
|
+
|
|
17
|
+
parentPort.on("message", errorLogger(this.onCommand))
|
|
18
|
+
|
|
19
|
+
this.initialize().then(() => {
|
|
20
|
+
this.application.initialize().then(() => {
|
|
21
|
+
logger(this, `Worker ${workerCount} started`)
|
|
22
|
+
parentPort.postMessage({command: "started"})
|
|
23
|
+
})
|
|
24
|
+
})
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
async initialize() {
|
|
28
|
+
const {debug, directory} = digs(this.workerData, "debug", "directory")
|
|
29
|
+
const configurationPath = `${this.workerData.directory}/src/config/configuration.mjs`
|
|
30
|
+
const configurationImport = await import(configurationPath)
|
|
31
|
+
const configuration = configurationImport.default
|
|
32
|
+
|
|
33
|
+
this.application = new Application({configuration, debug, directory})
|
|
34
|
+
|
|
35
|
+
this.configuration = configuration
|
|
36
|
+
this.configuration.setCurrent()
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
onCommand = (data) => {
|
|
40
|
+
logger(this, `Worker ${this.workerCount} received command`, data)
|
|
41
|
+
|
|
42
|
+
const {command} = data
|
|
43
|
+
|
|
44
|
+
if (command == "newClient") {
|
|
45
|
+
const {clientCount} = digs(data, "clientCount")
|
|
46
|
+
const client = new Client({
|
|
47
|
+
clientCount,
|
|
48
|
+
configuration: this.configuration
|
|
49
|
+
})
|
|
50
|
+
|
|
51
|
+
client.events.on("output", (output) => {
|
|
52
|
+
this.parentPort.postMessage({command: "clientOutput", clientCount, output})
|
|
53
|
+
})
|
|
54
|
+
|
|
55
|
+
this.clients[clientCount] = client
|
|
56
|
+
} else if (command == "clientWrite") {
|
|
57
|
+
const {chunk, clientCount} = digs(data, "chunk", "clientCount")
|
|
58
|
+
const client = digg(this.clients, clientCount)
|
|
59
|
+
|
|
60
|
+
client.onWrite(chunk)
|
|
61
|
+
} else {
|
|
62
|
+
throw new Error(`Unknown command: ${command}`)
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
|
|
1
|
+
import {digg} from "diggerize"
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
export default function log(object, ...messages) {
|
|
4
4
|
if (!object.configuration) console.error(`No configuration on ${object.constructor.name}`)
|
|
5
5
|
|
|
6
6
|
if (object.configuration?.debug) {
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
import GetRoute from "./get-route.mjs"
|
|
2
|
+
import ResourceRoute from "./resource-route.mjs"
|
|
3
|
+
|
|
4
|
+
var VelociousBaseRoute
|
|
5
|
+
|
|
6
|
+
export function initBaseRoute() {
|
|
7
|
+
if (VelociousBaseRoute) return
|
|
8
|
+
|
|
9
|
+
VelociousBaseRoute = class VelociousBaseRoute {
|
|
10
|
+
routes = []
|
|
11
|
+
|
|
12
|
+
get(name, args) {
|
|
13
|
+
const route = new GetRoute({name, args})
|
|
14
|
+
|
|
15
|
+
this.routes.push(route)
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
matchWithPath(_path) {
|
|
19
|
+
throw new Error(`No 'matchWithPath' implemented on ${this.constructor.name}`)
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
resources(name, callback) {
|
|
23
|
+
const route = new ResourceRoute({name})
|
|
24
|
+
|
|
25
|
+
this.routes.push(route)
|
|
26
|
+
|
|
27
|
+
if (callback) {
|
|
28
|
+
callback(route)
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
export {VelociousBaseRoute as default}
|
|
@@ -1,7 +1,9 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
1
|
+
import BaseRoute, {initBaseRoute} from "./base-route.mjs"
|
|
2
|
+
import escapeStringRegexp from "escape-string-regexp"
|
|
3
3
|
|
|
4
|
-
|
|
4
|
+
initBaseRoute()
|
|
5
|
+
|
|
6
|
+
export default class VelociousRouteGetRoute extends BaseRoute {
|
|
5
7
|
constructor({name}) {
|
|
6
8
|
super()
|
|
7
9
|
this.name = name
|
|
@@ -1,18 +1,18 @@
|
|
|
1
|
-
|
|
1
|
+
import {digg, digs} from "diggerize"
|
|
2
2
|
|
|
3
|
-
|
|
4
|
-
constructor({configuration, request, response
|
|
3
|
+
export default class VelociousRoutesResolver {
|
|
4
|
+
constructor({configuration, request, response}) {
|
|
5
5
|
if (!configuration) throw new Error("No configuration given")
|
|
6
6
|
if (!request) throw new Error("No request given")
|
|
7
7
|
if (!response) throw new Error("No response given")
|
|
8
8
|
|
|
9
9
|
this.configuration = configuration
|
|
10
|
-
this.params =
|
|
10
|
+
this.params = request.params()
|
|
11
11
|
this.request = request
|
|
12
12
|
this.response = response
|
|
13
13
|
}
|
|
14
14
|
|
|
15
|
-
resolve() {
|
|
15
|
+
async resolve() {
|
|
16
16
|
let currentRoute = digg(this, "configuration", "routes", "rootRoute")
|
|
17
17
|
let currentPath = this.request.path()
|
|
18
18
|
|
|
@@ -21,8 +21,9 @@ module.exports = class VelociousRoutesResolver {
|
|
|
21
21
|
if (!matchResult) throw new Error(`Couldn't match a route with the given path: ${currentPath}`)
|
|
22
22
|
|
|
23
23
|
if (this.params.action && this.params.controller) {
|
|
24
|
-
const controllerPath = `${digg(this, "configuration", "directory")}/src/routes/${digg(this, "params", "controller")}/controller.
|
|
25
|
-
const
|
|
24
|
+
const controllerPath = `${digg(this, "configuration", "directory")}/src/routes/${digg(this, "params", "controller")}/controller.mjs`
|
|
25
|
+
const controllerClassImport = await import(controllerPath)
|
|
26
|
+
const controllerClass = controllerClassImport.default
|
|
26
27
|
const controllerInstance = new controllerClass({
|
|
27
28
|
configuration: this.configuration,
|
|
28
29
|
params: this.params,
|
|
@@ -30,7 +31,13 @@ module.exports = class VelociousRoutesResolver {
|
|
|
30
31
|
response: this.response
|
|
31
32
|
})
|
|
32
33
|
|
|
33
|
-
|
|
34
|
+
if (!(this.params.action in controllerInstance)) {
|
|
35
|
+
throw new Error(`Missing action on controller: ${this.params.controller}#${this.params.action}`)
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
await this.configuration.getDatabasePool().withConnection(async () => {
|
|
39
|
+
await controllerInstance[this.params.action]()
|
|
40
|
+
})
|
|
34
41
|
|
|
35
42
|
return
|
|
36
43
|
}
|
|
@@ -44,7 +51,8 @@ module.exports = class VelociousRoutesResolver {
|
|
|
44
51
|
for (const subRoute of route.routes) {
|
|
45
52
|
const matchResult = subRoute.matchWithPath({
|
|
46
53
|
params: this.params,
|
|
47
|
-
path: pathWithoutSlash
|
|
54
|
+
path: pathWithoutSlash,
|
|
55
|
+
request: this.request
|
|
48
56
|
})
|
|
49
57
|
|
|
50
58
|
if (!matchResult) continue
|
|
@@ -1,14 +1,16 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
1
|
+
import BaseRoute, {initBaseRoute} from "./base-route.mjs"
|
|
2
|
+
import escapeStringRegexp from "escape-string-regexp"
|
|
3
3
|
|
|
4
|
-
|
|
4
|
+
initBaseRoute()
|
|
5
|
+
|
|
6
|
+
export default class VelociousRouteResourceRoute extends BaseRoute {
|
|
5
7
|
constructor({name}) {
|
|
6
8
|
super()
|
|
7
9
|
this.name = name
|
|
8
10
|
this.regExp = new RegExp(`^(${escapeStringRegexp(name)})(.*)$`)
|
|
9
11
|
}
|
|
10
12
|
|
|
11
|
-
matchWithPath({params, path}) {
|
|
13
|
+
matchWithPath({params, path, request}) {
|
|
12
14
|
const match = path.match(this.regExp)
|
|
13
15
|
|
|
14
16
|
if (match) {
|
|
@@ -24,7 +26,9 @@ module.exports = class VelociousRouteResourceRoute extends BaseRoute {
|
|
|
24
26
|
}
|
|
25
27
|
|
|
26
28
|
if (!subRoutesMatchesRestPath) {
|
|
27
|
-
if (
|
|
29
|
+
if (request.httpMethod() == "POST") {
|
|
30
|
+
action = "create"
|
|
31
|
+
} else if (restPath.match(/\/(.+)/)) {
|
|
28
32
|
// TODO: This should change the action to "show" and set the "resource_name_id" in params.
|
|
29
33
|
action = "show"
|
|
30
34
|
}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import {Configuration} from "velocious"
|
|
2
|
+
|
|
3
|
+
const configuration = new Configuration({
|
|
4
|
+
database: {
|
|
5
|
+
default: {
|
|
6
|
+
master: {
|
|
7
|
+
type: "mysql",
|
|
8
|
+
host: "mariadb",
|
|
9
|
+
username: "username",
|
|
10
|
+
password: "password",
|
|
11
|
+
database: "database"
|
|
12
|
+
}
|
|
13
|
+
}
|
|
14
|
+
}
|
|
15
|
+
})
|
|
16
|
+
|
|
17
|
+
export default configuration
|
package/bin/velocious
DELETED
|
@@ -1,14 +0,0 @@
|
|
|
1
|
-
#!/usr/bin/node
|
|
2
|
-
|
|
3
|
-
console.log("Hello", process.argv)
|
|
4
|
-
|
|
5
|
-
const args = process.argv.slice(2)
|
|
6
|
-
|
|
7
|
-
console.log(args)
|
|
8
|
-
|
|
9
|
-
if (args[0] == "g" && args[1] == "migration") {
|
|
10
|
-
const migrationName = args[2]
|
|
11
|
-
const date = new Date()
|
|
12
|
-
|
|
13
|
-
console.log({ migrationName, date })
|
|
14
|
-
}
|