summaryrefslogtreecommitdiff
path: root/server/src
diff options
context:
space:
mode:
Diffstat (limited to 'server/src')
-rw-r--r--server/src/operations.ts25
-rw-r--r--server/src/server.test.ts30
-rw-r--r--server/src/server.ts24
3 files changed, 69 insertions, 10 deletions
diff --git a/server/src/operations.ts b/server/src/operations.ts
index c0fec8d..7484b33 100644
--- a/server/src/operations.ts
+++ b/server/src/operations.ts
@@ -3,6 +3,8 @@ import { SubscriptionRequest } from '../../lib/subscription-req.model'
import { WriteRequest } from '../../lib/write-req.model'
import { DatabaseChange } from '../../lib/database-change.model'
+import { decodePath } from '../../lib/path'
+
import { DatabaseInterface } from 'naive-core'
import express, { RequestHandler } from 'express'
@@ -13,6 +15,8 @@ export const bindOperations = (
db: DatabaseInterface,
send: (e: DatabaseChange) => Promise<any>
) => {
+ // these methods should be tracked using a better
+ // data structure
const unsubs: { [key: string]: () => any } = {}
const writeHandler: RequestHandler = async (req, res) => {
@@ -21,6 +25,17 @@ export const bindOperations = (
res.status(200).end()
}
+ const readHandler: RequestHandler = async (req, res) => {
+ const { path: encodedPath } = req.params as WriteRequest
+ const path = decodePath(encodedPath)
+ try {
+ const payload = await db.read(path)
+ res.json(payload)
+ } catch (err) {
+ res.status(500).end()
+ }
+ }
+
const addSubHandler: RequestHandler = async (req, res) => {
const { path } = req.body as SubscriptionRequest
// only allow users to subscribe
@@ -47,10 +62,18 @@ export const bindOperations = (
const router = express()
router.use(bodyParser.json())
+ router.get('/read/:path', readHandler)
router.post('/write', writeHandler)
router
.route('/subscribe')
.post(addSubHandler)
.delete(removeSubHandler)
- router.listen(ctx.httpPort, () => ctx.logger('HTTPS server started'))
+ const instance = router.listen(ctx.httpPort, () =>
+ ctx.logger('HTTPS server started')
+ )
+
+ return () =>
+ new Promise((resolve, reject) => {
+ instance.close(resolve)
+ })
}
diff --git a/server/src/server.test.ts b/server/src/server.test.ts
index b4a308f..2d0efca 100644
--- a/server/src/server.test.ts
+++ b/server/src/server.test.ts
@@ -11,21 +11,43 @@ import { dbFactory, DatabaseConnection } from '../../client/src'
const port = +(process.env.PORT || 5005)
const httpPort = port
const wsPort = port + 1
+const localHost = 'http://localhost:'
describe('Server module', async () => {
let db: DatabaseConnection
+ let cleanup: () => Promise<void>
beforeAll(async () => {
- await runServer({
+ cleanup = await runServer({
httpPort,
wsPort,
logger: console.log
})
- db = dbFactory({ wsPort, httpUrl: `http://localhost:${httpPort}` })
+ db = dbFactory({
+ wsUrl: `${localHost}${wsPort}`,
+ httpUrl: `${localHost}${httpPort}`
+ })
await db.init()
})
- test('it should work', async () => {
- await db.write('/hello/world', {
+ afterAll(async () => {
+ if (cleanup) {
+ await cleanup()
+ }
+ })
+ test('it should leave input data unchaged', async () => {
+ const path = '/hello/world'
+ const fixture = {
my: 'data'
+ }
+ await db.write(path, fixture)
+ const r = await db.read(path)
+ expect(r).toMatchObject(fixture)
+ })
+ test('it should get data in realtime', () => {
+ return new Promise(async (resolve, reject) => {
+ db.subscribe('/hello/world', (data: any) => {
+ resolve()
+ })
+ await db.write('/hello/world', { data: 5 })
})
})
})
diff --git a/server/src/server.ts b/server/src/server.ts
index 459bc69..67306ba 100644
--- a/server/src/server.ts
+++ b/server/src/server.ts
@@ -5,14 +5,28 @@ import WebSocket from 'ws'
import { Database, Context as CoreContext } from 'naive-core'
-export const runServer = async (ctx: Context) => {
+type CleanupRoutine = () => Promise<void>
+
+export const runServer = async (ctx: Context): Promise<CleanupRoutine> => {
const db = new Database()
await db.init()
const wss = new WebSocket.Server({ port: ctx.wsPort })
- bindOperations(ctx, db, async (dbChange: DatabaseChange) => {
- for (let client of wss.clients) {
- client.send(dbChange)
+ const socketCleanup = () =>
+ new Promise((resolve, reject) => {
+ wss.close(resolve)
+ })
+
+ const operationCleanup = await bindOperations(
+ ctx,
+ db,
+ async (dbChange: DatabaseChange) => {
+ for (let client of wss.clients) {
+ client.send(JSON.stringify(dbChange))
+ }
}
- })
+ )
+ return async () => {
+ Promise.all([operationCleanup(), socketCleanup()])
+ }
}