diff options
Diffstat (limited to 'server/src')
-rw-r--r-- | server/src/operations.ts | 25 | ||||
-rw-r--r-- | server/src/server.test.ts | 30 | ||||
-rw-r--r-- | server/src/server.ts | 24 |
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()]) + } } |