summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorNick Van Doorn <vandoorn.nick@gmail.com>2019-02-09 01:31:39 -0800
committerNick Van Doorn <vandoorn.nick@gmail.com>2019-02-09 01:31:39 -0800
commitcc3c82a0b2816a4e1601d237a130cf7bae953335 (patch)
treedf65babf3a3870de2bc706b43efd815721a83044
parent7aa0d4141516cf03e332d70e374f46f35ea09f76 (diff)
Blah
-rw-r--r--.prettierrc.json4
-rw-r--r--client/jest.config.js6
-rw-r--r--client/package.json6
-rw-r--r--client/readme.md2
-rw-r--r--client/src/config.model.ts5
-rw-r--r--client/src/database-connection.model.ts10
-rw-r--r--client/src/database-connection.test.ts3
-rw-r--r--client/src/database-connection.ts41
-rw-r--r--client/src/index.ts7
-rw-r--r--client/yarn.lock12
-rw-r--r--core/jest.config.js6
-rw-r--r--core/package.json2
-rw-r--r--core/readme.md2
-rw-r--r--core/src/change-handlers.model.ts6
-rw-r--r--core/src/context.model.ts6
-rw-r--r--core/src/database.model.ts14
-rw-r--r--core/src/database.test.ts197
-rw-r--r--core/src/database.ts114
-rw-r--r--core/src/index.ts6
-rw-r--r--lib/database-change.model.ts4
-rw-r--r--lib/error.model.ts10
-rw-r--r--lib/subscription-req.model.ts2
-rw-r--r--lib/util.ts4
-rw-r--r--lib/write-req.model.ts4
-rwxr-xr-xscripts/build.sh10
-rwxr-xr-xscripts/format.sh3
-rwxr-xr-xscripts/release.sh63
-rw-r--r--server/bin/index.ts8
-rw-r--r--server/jest.config.js6
-rw-r--r--server/package.json4
-rw-r--r--server/readme.md2
-rw-r--r--server/src/context.model.ts6
-rw-r--r--server/src/operations.ts60
-rw-r--r--server/src/server.test.ts36
-rw-r--r--server/src/server.ts22
-rw-r--r--server/yarn.lock4
36 files changed, 386 insertions, 311 deletions
diff --git a/.prettierrc.json b/.prettierrc.json
new file mode 100644
index 0000000..b2095be
--- /dev/null
+++ b/.prettierrc.json
@@ -0,0 +1,4 @@
+{
+ "semi": false,
+ "singleQuote": true
+}
diff --git a/client/jest.config.js b/client/jest.config.js
index 3f878c4..758fa13 100644
--- a/client/jest.config.js
+++ b/client/jest.config.js
@@ -1,4 +1,4 @@
module.exports = {
- preset: "ts-jest",
- testEnvironment: "node"
-};
+ preset: 'ts-jest',
+ testEnvironment: 'node'
+}
diff --git a/client/package.json b/client/package.json
index c199e46..b7489f0 100644
--- a/client/package.json
+++ b/client/package.json
@@ -1,6 +1,6 @@
{
"name": "naive-client",
- "version": "2.2.1",
+ "version": "2.3.4",
"description": "A naive NoSQL database client",
"main": "dist/client/src/index.js",
"types": "dist/client/src/index.d.ts",
@@ -18,5 +18,9 @@
"ts-node": "^7.0.1",
"typedoc": "^0.14.2",
"typescript": "^3.2.4"
+ },
+ "dependencies": {
+ "@types/node-fetch": "^2.1.4",
+ "node-fetch": "^2.3.0"
}
}
diff --git a/client/readme.md b/client/readme.md
index 79f4637..92753d4 100644
--- a/client/readme.md
+++ b/client/readme.md
@@ -1,6 +1,6 @@
# naive
-![build status](https://api.travis-ci.org/nvandoorn/naive.svg?branch=master "Build Status")
+![build status](https://api.travis-ci.org/nvandoorn/naive.svg?branch=master 'Build Status')
[Read the docs](https://nvandoorn.github.io/naive/)
diff --git a/client/src/config.model.ts b/client/src/config.model.ts
index 9c3b70a..278f7f7 100644
--- a/client/src/config.model.ts
+++ b/client/src/config.model.ts
@@ -1,5 +1,4 @@
export interface Config {
- wsPort: number;
- httpPort: number;
- url: string;
+ wsPort: number
+ httpUrl: string
}
diff --git a/client/src/database-connection.model.ts b/client/src/database-connection.model.ts
index b89014b..0523e22 100644
--- a/client/src/database-connection.model.ts
+++ b/client/src/database-connection.model.ts
@@ -1,7 +1,7 @@
export interface DatabaseConnection {
- init(): Promise<any>;
- close(): Promise<any>;
- subscribe(path: string, callback: (e: any) => any): Promise<() => any>;
- write(path: string, toWrite: Object): Promise<any>;
- remove(path: string): Promise<any>;
+ init(): Promise<any>
+ close(): Promise<any>
+ subscribe(path: string, callback: (e: any) => any): Promise<() => any>
+ write(path: string, toWrite: Object): Promise<any>
+ remove(path: string): Promise<any>
}
diff --git a/client/src/database-connection.test.ts b/client/src/database-connection.test.ts
new file mode 100644
index 0000000..e6353e8
--- /dev/null
+++ b/client/src/database-connection.test.ts
@@ -0,0 +1,3 @@
+describe('Client module', () => {
+ test('it should work', () => {})
+})
diff --git a/client/src/database-connection.ts b/client/src/database-connection.ts
index d870f71..3cf733c 100644
--- a/client/src/database-connection.ts
+++ b/client/src/database-connection.ts
@@ -1,5 +1,7 @@
-import { Config } from "./config.model";
-import { DatabaseConnection } from "./database-connection.model";
+import { Config } from './config.model'
+import { DatabaseConnection } from './database-connection.model'
+
+const IS_NODE = true
/**
* Client side implementation is implemented using
@@ -7,25 +9,34 @@ import { DatabaseConnection } from "./database-connection.model";
* size
*/
export const dbFactory = (config: Config): DatabaseConnection => {
+ // TODO figure out how to patch
+ // in native fetch instead
+ // when this is running in the browser
+ const send = require('node-fetch')
const write = (path: string, toWrite: Object | null) => {
- const { url, httpPort } = config;
- return fetch(`${url}:${httpPort}/write`, {
- method: "POST",
- body: JSON.stringify({
- path,
- toWrite
- })
- });
- };
+ const { httpUrl } = config
+ const body = JSON.stringify({
+ path,
+ toWrite
+ })
+ return send(`${httpUrl}/write`, {
+ method: 'POST',
+ body,
+ headers: {
+ Accept: 'application/json',
+ 'Content-Type': 'application/json'
+ }
+ })
+ }
return {
async init() {},
async close() {},
async subscribe(path: string, callback: (e: any) => Promise<any>) {
- return () => {};
+ return () => {}
},
write,
async remove(path: string) {
- write(path, null);
+ write(path, null)
}
- };
-};
+ }
+}
diff --git a/client/src/index.ts b/client/src/index.ts
index c16688d..f11e59c 100644
--- a/client/src/index.ts
+++ b/client/src/index.ts
@@ -1,3 +1,4 @@
-export { dbFactory } from "./database-connection";
-export { DatabaseConnection } from "./database-connection.model";
-export { Config } from "./config.model";
+export { dbFactory } from './database-connection'
+export { DatabaseConnection } from './database-connection.model'
+export { Config } from './config.model'
+declare var fetch: any
diff --git a/client/yarn.lock b/client/yarn.lock
index 7bbbb85..97a7de5 100644
--- a/client/yarn.lock
+++ b/client/yarn.lock
@@ -69,6 +69,13 @@
resolved "https://registry.yarnpkg.com/@types/minimatch/-/minimatch-3.0.3.tgz#3dca0e3f33b200fc7d1139c0cd96c1268cadfd9d"
integrity sha512-tHq6qdbT9U1IRSGf14CL0pUlULksvY9OZ+5eEgl1N7t+OA3tGvNpxJCzuKQlsNgCVwbAs670L1vcVQi8j9HjnA==
+"@types/node-fetch@^2.1.4":
+ version "2.1.4"
+ resolved "https://registry.yarnpkg.com/@types/node-fetch/-/node-fetch-2.1.4.tgz#093d1beae11541aef25999d70aa09286fd025b1a"
+ integrity sha512-tR1ekaXUGpmzOcDXWU9BW73YfA2/VW1DF1FH+wlJ82BbCSnWTbdX+JkqWQXWKIGsFPnPsYadbXfNgz28g+ccWg==
+ dependencies:
+ "@types/node" "*"
+
"@types/node@*", "@types/node@^10.12.18":
version "10.12.18"
resolved "https://registry.yarnpkg.com/@types/node/-/node-10.12.18.tgz#1d3ca764718915584fcd9f6344621b7672665c67"
@@ -2475,6 +2482,11 @@ needle@^2.2.1:
iconv-lite "^0.4.4"
sax "^1.2.4"
+node-fetch@^2.3.0:
+ version "2.3.0"
+ resolved "https://registry.yarnpkg.com/node-fetch/-/node-fetch-2.3.0.tgz#1a1d940bbfb916a1d3e0219f037e89e71f8c5fa5"
+ integrity sha512-MOd8pV3fxENbryESLgVIeaGKrdl+uaYhCSSVkjeOb/31/njTpcis5aWfdqgNlHIrKOLRbMnfPINPOML2CIFeXA==
+
node-int64@^0.4.0:
version "0.4.0"
resolved "https://registry.yarnpkg.com/node-int64/-/node-int64-0.4.0.tgz#87a9065cdb355d3182d8f94ce11188b825c68a3b"
diff --git a/core/jest.config.js b/core/jest.config.js
index 3f878c4..758fa13 100644
--- a/core/jest.config.js
+++ b/core/jest.config.js
@@ -1,4 +1,4 @@
module.exports = {
- preset: "ts-jest",
- testEnvironment: "node"
-};
+ preset: 'ts-jest',
+ testEnvironment: 'node'
+}
diff --git a/core/package.json b/core/package.json
index c5c40f7..8d9f6ee 100644
--- a/core/package.json
+++ b/core/package.json
@@ -1,6 +1,6 @@
{
"name": "naive-core",
- "version": "2.2.1",
+ "version": "2.3.4",
"description": "A naive NoSQL database",
"main": "dist/core/src/index.js",
"types": "dist/core/src/index.d.ts",
diff --git a/core/readme.md b/core/readme.md
index 79f4637..92753d4 100644
--- a/core/readme.md
+++ b/core/readme.md
@@ -1,6 +1,6 @@
# naive
-![build status](https://api.travis-ci.org/nvandoorn/naive.svg?branch=master "Build Status")
+![build status](https://api.travis-ci.org/nvandoorn/naive.svg?branch=master 'Build Status')
[Read the docs](https://nvandoorn.github.io/naive/)
diff --git a/core/src/change-handlers.model.ts b/core/src/change-handlers.model.ts
index 0bddecf..0ef499a 100644
--- a/core/src/change-handlers.model.ts
+++ b/core/src/change-handlers.model.ts
@@ -1,6 +1,6 @@
export interface ChangeHandlers {
[handlerKey: string]: {
- path: string;
- callback: (e: any) => Promise<any>;
- };
+ path: string
+ callback: (e: any) => Promise<any>
+ }
}
diff --git a/core/src/context.model.ts b/core/src/context.model.ts
index 193f152..3551fc8 100644
--- a/core/src/context.model.ts
+++ b/core/src/context.model.ts
@@ -6,13 +6,13 @@ export interface Context {
* but it may be handy to pipe it elsewhere
* later
*/
- logger: (e: any) => void;
+ logger: (e: any) => void
/**
* Location of the database cache file (JSON file)
*/
- cachePath: string;
+ cachePath: string
/**
* Maximum database size in megabytes
*/
- maxDbSizeMB: number;
+ maxDbSizeMB: number
}
diff --git a/core/src/database.model.ts b/core/src/database.model.ts
index a0cd3a5..0ceed6e 100644
--- a/core/src/database.model.ts
+++ b/core/src/database.model.ts
@@ -7,7 +7,7 @@ export interface DatabaseInterface {
* but is required for any form
* of non-volatile storage
*/
- init(): Promise<void>;
+ init(): Promise<void>
/**
* Read data from the "node" described by path
@@ -16,12 +16,12 @@ export interface DatabaseInterface {
* null is returned if there is no data
* at path
*/
- read(path: string): Promise<Object>;
+ read(path: string): Promise<Object>
/**
* Subscribe to all data changes at path
*/
- subscribe(path: string, callback: (e: any) => any): () => any;
+ subscribe(path: string, callback: (e: any) => any): () => any
/**
* Write data to the node described by path
@@ -32,20 +32,20 @@ export interface DatabaseInterface {
*
* An exception is thrown if the write fails
*/
- write(path: string, toWrite: Object): Promise<void>;
+ write(path: string, toWrite: Object): Promise<void>
/**
* Remove data at path
*/
- remove(path: string): Promise<void>;
+ remove(path: string): Promise<void>
/**
* Empty the database
*/
- flush(): Promise<void>;
+ flush(): Promise<void>
/**
* String representation (JSON) of the database
*/
- toString(): Object;
+ toString(): Object
}
diff --git a/core/src/database.test.ts b/core/src/database.test.ts
index 7f81308..7b2be8d 100644
--- a/core/src/database.test.ts
+++ b/core/src/database.test.ts
@@ -1,130 +1,131 @@
-import { Database } from "./database";
-import { NaiveErrorCode } from "../../lib/error.model";
+import { Database } from './database'
+import { NaiveErrorCode } from '../../lib/error.model'
-const generateString = (sizeBytes: number) =>
- Array(Math.ceil(sizeBytes)).fill("a");
+const generateString = (sizeBytes: number): string =>
+ Array(Math.ceil(sizeBytes))
+ .fill('a')
+ .join('')
-const maxDbSizeMB = 0.1;
+const maxDbSizeMB = 0.1
-describe("Database module", () => {
- let db: Database;
+describe('Database module', () => {
+ let db: Database
beforeAll(async () => {
db = new Database({
logger: console.log,
maxDbSizeMB,
cachePath: `${__dirname}/db.json`
- });
- await db.init();
- });
+ })
+ await db.init()
+ })
beforeEach(async () => {
- await db.flush();
- });
-
- // Next 2 tests simply look
- // for expections on operations that
- // should be harmless
- test("it should write data", () => {
- return db.write("/hello/world", {
- formula: "hello world"
- });
- });
-
- test("it should read data", () => {
- return db.read("/hello/world");
- });
-
- test("it should have a string representation", () => {
- expect(db.toString()).not.toHaveLength(0);
- });
-
- test("it should write and then read data", async () => {
- const path = "/hello/world";
+ await db.flush()
+ })
+
+ // Next 2 tests run simple operations
+ // that should _not_ throw exceptions
+ test('it should write data', () => {
+ return db.write('/hello/world', {
+ formula: 'hello world'
+ })
+ })
+
+ test('it should read data', () => {
+ return db.read('/hello/world')
+ })
+
+ test('it should have a string representation', () => {
+ expect(db.toString()).not.toHaveLength(0)
+ })
+
+ test('it should write and then read data', async () => {
+ const path = '/hello/world'
const toWrite = {
- secret: "stuff"
- };
- await db.write(path, toWrite);
- const s = await db.read(path);
- expect(s).toBe(toWrite);
- });
-
- test("it should write and read data from the root", async () => {
+ secret: 'stuff'
+ }
+ await db.write(path, toWrite)
+ const s = await db.read(path)
+ expect(s).toBe(toWrite)
+ })
+
+ test('it should write and read data from the root', async () => {
const toWrite = {
my: {
big: {
- fun: "data"
+ fun: 'data'
}
}
- };
- await db.write("/", toWrite);
- const s = await db.read("/");
- expect(s).toEqual(toWrite);
- });
-
- test("it should remove data", async () => {
- const path = "/this/is/fun";
+ }
+ await db.write('/', toWrite)
+ const s = await db.read('/')
+ expect(s).toEqual(toWrite)
+ })
+
+ test('it should remove data', async () => {
+ const path = '/this/is/fun'
await db.write(path, {
foxNews: {
- stories: ["AOC", "aoc", "aOC", "aOc"]
+ stories: ['AOC', 'aoc', 'aOC', 'aOc']
}
- });
- await db.remove(path);
- const s = await db.read(path);
- expect(s).toBeNull();
- });
+ })
+ await db.remove(path)
+ const s = await db.read(path)
+ expect(s).toBeNull()
+ })
- test("it should remove data at path & leave other data", async () => {
- const path = "/this/is/fun";
+ test('it should remove data at path & leave other data', async () => {
+ const path = '/this/is/fun'
const buzzFeed = {
- stories: ["hack your dogs brain in 4 easy steps"]
- };
+ stories: ['hack your dogs brain in 4 easy steps']
+ }
await db.write(path, {
foxNews: {
- stories: ["AOC", "aoc", "aOC", "aOc"]
+ stories: ['AOC', 'aoc', 'aOC', 'aOc']
},
buzzFeed
- });
- const appendedPath = `${path}/foxNews`;
- await db.remove(appendedPath);
- const buzzFeedOut = await db.read(`${path}/buzzFeed`);
- const foxOut = await db.read(appendedPath);
- expect(buzzFeedOut).toEqual(buzzFeed);
- expect(foxOut).toBeNull();
- });
-
- test("it should be empty after a flush", async () => {
- await db.write("/hello/world", {
- my: "object"
- });
- await db.flush();
- expect(db.toString()).toHaveLength(2); // empty object
- });
-
- test("it should read null on an empty node", async () => {
- const s = await db.read("/any/path/should/work");
- expect(s).toBeNull();
- });
-
- test("it should not change on read", async () => {
- await db.write("/my/data/lives/here", {
+ })
+ const appendedPath = `${path}/foxNews`
+ await db.remove(appendedPath)
+ const buzzFeedOut = await db.read(`${path}/buzzFeed`)
+ const foxOut = await db.read(appendedPath)
+ expect(buzzFeedOut).toEqual(buzzFeed)
+ expect(foxOut).toBeNull()
+ })
+
+ test('it should be empty after a flush', async () => {
+ await db.write('/hello/world', {
+ my: 'object'
+ })
+ await db.flush()
+ expect(db.toString()).toHaveLength(2) // empty object
+ })
+
+ test('it should read null on an empty node', async () => {
+ const s = await db.read('/any/path/should/work')
+ expect(s).toBeNull()
+ })
+
+ test('it should not change on read', async () => {
+ await db.write('/my/data/lives/here', {
whiteHouseDinner: `America's Finest McDouble's`
- });
- const before = db.toString();
- const s = await db.read("/no/data/here/silly");
- expect(s).toBeNull();
- expect(before).toEqual(db.toString());
- });
-
- test("it should throw an error if max size is exceeded", async () => {
+ })
+ const before = db.toString()
+ const s = await db.read('/no/data/here/silly')
+ expect(s).toBeNull()
+ expect(before).toEqual(db.toString())
+ })
+
+ test('it should throw an error if max size is exceeded', async () => {
try {
- await db.write("/big/data", {
+ await db.write('/big/data', {
bigObj: generateString(maxDbSizeMB * 1024 ** 2)
- });
- throw new Error("Did not throw exception");
+ })
+ throw new Error('Did not throw exception')
} catch (e) {
- expect(e.code).toBe(NaiveErrorCode.OUT_OF_SPACE);
+ expect(e.code).toBe(NaiveErrorCode.OUT_OF_SPACE)
}
- });
-});
+ })
+})
diff --git a/core/src/database.ts b/core/src/database.ts
index 3b19f8e..e4083b1 100644
--- a/core/src/database.ts
+++ b/core/src/database.ts
@@ -1,22 +1,22 @@
-import { writeFile, readFile } from "fs";
-import { promisify } from "util";
+import { writeFile, readFile } from 'fs'
+import { promisify } from 'util'
-import { DatabaseInterface } from "./database.model";
-import { Context } from "./context.model";
-import { NaiveError, NaiveErrorCode as e } from "../../lib/error.model";
-import { ChangeHandlers } from "./change-handlers.model";
+import { DatabaseInterface } from './database.model'
+import { Context } from './context.model'
+import { NaiveError, NaiveErrorCode as e } from '../../lib/error.model'
+import { ChangeHandlers } from './change-handlers.model'
-import { last, getKey } from "../../lib/util";
+import { last, getKey } from '../../lib/util'
/**
* Split path using "/" as a delimiter
*/
-const splitPath = (path: string): string[] => path.split("/").filter(k => k);
+const splitPath = (path: string): string[] => path.split('/').filter(k => k)
/**
* Identify if a path is a root node
*/
-const isRootNode = (path: string): boolean => path === "/" || path === "";
+const isRootNode = (path: string): boolean => path === '/' || path === ''
/**
* Check if path1 matches path2,
@@ -26,19 +26,19 @@ const isRootNode = (path: string): boolean => path === "/" || path === "";
*/
const isChildOrMatch = (child: string, parent: string) => {
// console.log(`child: ${child}, parent ${parent}`);
- if (child === parent || parent === "/") return true;
- const parentTokens = parent.split("/").filter((i: string) => i.length);
- return parentTokens.every((t, i) => child.split("/")[i] === t);
-};
+ if (child === parent || parent === '/') return true
+ const parentTokens = parent.split('/').filter((i: string) => i.length)
+ return parentTokens.every((t, i) => child.split('/')[i] === t)
+}
-const write = promisify(writeFile);
-const read = promisify(readFile);
+const write = promisify(writeFile)
+const read = promisify(readFile)
export const DEFAULT_CTX = {
logger: console.log,
cachePath: `${__dirname}/db.json`,
maxDbSizeMB: 6
-};
+}
/**
* Implementation of NoSQL DB that uses paths and objects.
@@ -54,22 +54,22 @@ export class Database implements DatabaseInterface {
/**
* In memory buffer to read/write data
*/
- private buff: any = {};
+ private buff: any = {}
/**
* An array of callback functions that are alerted
* when the database changes (mostly want to use this
* for some type of pubsub functionality on-top)
*/
- private changeHandlers: ChangeHandlers = {};
+ private changeHandlers: ChangeHandlers = {}
constructor(private ctx: Context = DEFAULT_CTX) {}
async init(): Promise<void> {
try {
- const buff = await read(this.ctx.cachePath);
- this.buff = JSON.parse(buff.toString());
+ const buff = await read(this.ctx.cachePath)
+ this.buff = JSON.parse(buff.toString())
} catch (e) {
- this.ctx.logger("Failed to init database, using empty object");
- this.ctx.logger(e);
+ this.ctx.logger('Failed to init database, using empty object')
+ this.ctx.logger(e)
}
}
@@ -78,57 +78,57 @@ export class Database implements DatabaseInterface {
// (which obviously becomes a bad idea at some point)
async read(path: string): Promise<Object> {
// root node case
- if (isRootNode(path)) return this.buff;
- const pathParts = splitPath(path);
- return this.resolve(pathParts);
+ if (isRootNode(path)) return this.buff
+ const pathParts = splitPath(path)
+ return this.resolve(pathParts)
}
async write(path: string, toWrite: any): Promise<void> {
if (isRootNode(path)) {
- this.buff = toWrite;
+ this.buff = toWrite
} else {
- const pathParts = splitPath(path);
- const writeTo = this.resolve(pathParts, false, 1);
- writeTo[last(pathParts)] = toWrite;
+ const pathParts = splitPath(path)
+ const writeTo = this.resolve(pathParts, false, 1)
+ writeTo[last(pathParts)] = toWrite
}
- await this.serialize();
+ await this.serialize()
// alert everyone of our new change
- await this.runChangeHandlers(path, toWrite);
+ await this.runChangeHandlers(path, toWrite)
}
private async runChangeHandlers(path: string, change: any): Promise<void> {
- const handlers = Object.values(this.changeHandlers);
+ const handlers = Object.values(this.changeHandlers)
for (let handler of handlers) {
if (isChildOrMatch(path, handler.path)) {
- await handler.callback(change);
+ await handler.callback(change)
}
}
}
subscribe(path: string, callback: (e: any) => Promise<any>): () => any {
- const key = getKey("subscriber");
+ const key = getKey('subscriber')
this.changeHandlers[key] = {
path,
callback
- };
- return () => this.unsubscribe(key);
+ }
+ return () => this.unsubscribe(key)
}
private unsubscribe(key: string) {
- delete this.changeHandlers[key];
+ delete this.changeHandlers[key]
}
remove(path: string): Promise<void> {
- return this.write(path, null);
+ return this.write(path, null)
}
async flush(): Promise<void> {
- this.buff = {};
- await this.serialize();
+ this.buff = {}
+ await this.serialize()
}
toString() {
- return JSON.stringify(this.buff);
+ return JSON.stringify(this.buff)
}
/**
@@ -148,41 +148,41 @@ export class Database implements DatabaseInterface {
isRead: boolean = true,
level: number = 0
): any {
- const [firstPart] = pathParts;
- if (isRootNode(firstPart)) return this.buff;
- const n = pathParts.length - level;
+ const [firstPart] = pathParts
+ if (isRootNode(firstPart)) return this.buff
+ const n = pathParts.length - level
// TODO avoid having to pull
// this specific case out
if (n === 0) {
if (!this.buff[firstPart]) {
- this.buff[firstPart] = {};
- return this.buff[firstPart];
+ this.buff[firstPart] = {}
+ return this.buff[firstPart]
}
}
// start at the root of our buffer
- let lastNode = this.buff;
- let node;
+ let lastNode = this.buff
+ let node
for (let i = 0; i < n; i++) {
- const part: string = pathParts[i];
+ const part: string = pathParts[i]
// handle null node
if (!lastNode[part]) {
// if we're reading from the object
// we want to stop as soon
// as we hit a null node
if (isRead) {
- return null;
+ return null
}
// but if we're writing and the node is missing,
// we should make it and continue
else {
- lastNode[part] = {};
+ lastNode[part] = {}
}
}
// traverse to the next node
- node = lastNode[part];
- lastNode = node;
+ node = lastNode[part]
+ lastNode = node
}
- return node;
+ return node
}
/**
@@ -195,12 +195,12 @@ export class Database implements DatabaseInterface {
* Throws OUT_OF_SPACE
*/
private serialize(): Promise<void> {
- if (!this.hasSpace()) throw new NaiveError(e.OUT_OF_SPACE);
- return write(this.ctx.cachePath, this.toString());
+ if (!this.hasSpace()) throw new NaiveError(e.OUT_OF_SPACE)
+ return write(this.ctx.cachePath, this.toString())
}
private hasSpace(): boolean {
// convert from MB to B
- return this.toString().length <= this.ctx.maxDbSizeMB * 1024 ** 2;
+ return this.toString().length <= this.ctx.maxDbSizeMB * 1024 ** 2
}
}
diff --git a/core/src/index.ts b/core/src/index.ts
index 0874475..ff4b500 100644
--- a/core/src/index.ts
+++ b/core/src/index.ts
@@ -1,3 +1,3 @@
-export { Database } from "./database";
-export { Context } from "./context.model";
-export { DatabaseInterface } from "./database.model";
+export { Database } from './database'
+export { Context } from './context.model'
+export { DatabaseInterface } from './database.model'
diff --git a/lib/database-change.model.ts b/lib/database-change.model.ts
index c3a04f5..8e8db39 100644
--- a/lib/database-change.model.ts
+++ b/lib/database-change.model.ts
@@ -1,4 +1,4 @@
export interface DatabaseChange {
- path: string;
- change: Object;
+ path: string
+ change: Object
}
diff --git a/lib/error.model.ts b/lib/error.model.ts
index 5cf9916..c79a2b2 100644
--- a/lib/error.model.ts
+++ b/lib/error.model.ts
@@ -3,20 +3,20 @@ export enum NaiveErrorCode {
OUT_OF_SPACE
}
-const e = NaiveErrorCode;
+const e = NaiveErrorCode
export const lookupMsg = (c: NaiveErrorCode) => {
switch (c) {
case e.OUT_OF_SPACE:
- return `Out of storage space (too big for in memory buffer)`;
+ return `Out of storage space (too big for in memory buffer)`
case e.UNCAUGHT:
default:
- return `Uncaught error. Please add message/code in src/error.model.ts`;
+ return `Uncaught error. Please add message/code in src/error.model.ts`
}
-};
+}
export class NaiveError extends Error {
constructor(public code: NaiveErrorCode) {
- super(lookupMsg(code));
+ super(lookupMsg(code))
}
}
diff --git a/lib/subscription-req.model.ts b/lib/subscription-req.model.ts
index a788767..b6c70fd 100644
--- a/lib/subscription-req.model.ts
+++ b/lib/subscription-req.model.ts
@@ -1,3 +1,3 @@
export interface SubscriptionRequest {
- path: string;
+ path: string
}
diff --git a/lib/util.ts b/lib/util.ts
index 7e7b965..1235792 100644
--- a/lib/util.ts
+++ b/lib/util.ts
@@ -1,10 +1,10 @@
/**
* Get the last item in t
*/
-export const last = <T>(t: T[]): T => t[t.length - 1];
+export const last = <T>(t: T[]): T => t[t.length - 1]
/**
* Generate a random key with a seed
*/
export const getKey = (seed: string) =>
- seed + Date.now() + Math.floor(Math.random() * 1000);
+ seed + Date.now() + Math.floor(Math.random() * 1000)
diff --git a/lib/write-req.model.ts b/lib/write-req.model.ts
index ff2f361..26e2982 100644
--- a/lib/write-req.model.ts
+++ b/lib/write-req.model.ts
@@ -1,4 +1,4 @@
export interface WriteRequest {
- path: string;
- toWrite: Object;
+ path: string
+ toWrite: Object
}
diff --git a/scripts/build.sh b/scripts/build.sh
new file mode 100755
index 0000000..7db02bd
--- /dev/null
+++ b/scripts/build.sh
@@ -0,0 +1,10 @@
+#!/usr/bin/env bash
+
+declare -a arr=("core" "client" "server")
+
+for i in "${arr[@]}"
+do
+ cd $i
+ yarn run build
+ cd ..
+done
diff --git a/scripts/format.sh b/scripts/format.sh
new file mode 100755
index 0000000..5bebb80
--- /dev/null
+++ b/scripts/format.sh
@@ -0,0 +1,3 @@
+#!/usr/bin/env bash
+
+npx prettier --write "**/*.ts"
diff --git a/scripts/release.sh b/scripts/release.sh
index 11e9ac8..d931ec6 100755
--- a/scripts/release.sh
+++ b/scripts/release.sh
@@ -1,20 +1,45 @@
-sed -i.bak s/__REPLACE_VERSION__/$1/g package.json
-yarn test || exit 1
-branchName=$(git symbolic-ref HEAD | sed -e 's,.*/\(.*\),\1,')
-echo $branchName
-# TODO find a better way to exlcude
-# docs from the stash
-git stash push -- src || exit 1
-git checkout master
-yarn run build || exit 1
-# this is a hack required
-# to serve paths that start
-# with '_'
+#!/usr/bin/env bash
+
+declare -a arr=("core" "client" "server")
+
+# TODO re-enable git stuff
+
+# git stash || exit 1
+# git checkout master
+
+rm -rf docs
+mkdir docs
touch docs/.nojekyll
-git add docs package.json
-git commit -m "Update docs for release $1"
-git tag $1
-git push --tags origin master
-git checkout $branchName
-git stash pop
-# sed -i.bak s/$1/__REPLACE_VERSION__/g package.json
+
+branchName=$(git symbolic-ref HEAD | sed -e 's,.*/\(.*\),\1,')
+
+for i in "${arr[@]}"
+do
+ echo "*** Building naive-$i ***"
+ cd $i
+ # update the version in the package file
+ yarn run build || exit 1
+ mv docs ../docs/$i
+ cd ..
+done
+
+for i in "${arr[@]}"
+do
+ echo "*** Testing and publishing naive-$i ***"
+ cd $i
+ # make sure the tests pass
+ yarn test || exit 1
+ # update the version in the package file
+ # for some reason yarn fucks
+ # with the git repo? use npm for now
+ # I guess
+ npm version $1
+ npm publish --access public || exit 1
+ cd ..
+done
+
+# git commit -m "Update for release $1"
+# git tag $1
+# git push --tags origin master
+# git checkout $branchName
+# git stash pop
diff --git a/server/bin/index.ts b/server/bin/index.ts
index fdf1352..fb276c6 100644
--- a/server/bin/index.ts
+++ b/server/bin/index.ts
@@ -1,10 +1,10 @@
-import { runServer } from "../src/server";
-import process from "process";
+import { runServer } from '../src/server'
+import process from 'process'
-const port = +(process.env.PORT || 5000);
+const port = +(process.env.PORT || 5000)
runServer({
httpPort: port,
wsPort: port + 1,
logger: console.log
-});
+})
diff --git a/server/jest.config.js b/server/jest.config.js
index 3f878c4..758fa13 100644
--- a/server/jest.config.js
+++ b/server/jest.config.js
@@ -1,4 +1,4 @@
module.exports = {
- preset: "ts-jest",
- testEnvironment: "node"
-};
+ preset: 'ts-jest',
+ testEnvironment: 'node'
+}
diff --git a/server/package.json b/server/package.json
index 68c6b62..ad3976e 100644
--- a/server/package.json
+++ b/server/package.json
@@ -4,7 +4,7 @@
"description": "A naive NoSQL database server",
"scripts": {
"build": "tsc && typedoc --out docs src",
- "test": "jest src",
+ "test": "jest .!(dist)",
"start": "ts-node bin/index.ts"
},
"bin": {
@@ -22,8 +22,10 @@
"typescript": "^3.2.4"
},
"dependencies": {
+ "@types/body-parser": "^1.17.0",
"@types/express": "^4.16.0",
"@types/ws": "^6.0.1",
+ "body-parser": "^1.18.3",
"express": "^4.16.4",
"ws": "^6.1.2"
}
diff --git a/server/readme.md b/server/readme.md
index 79f4637..92753d4 100644
--- a/server/readme.md
+++ b/server/readme.md
@@ -1,6 +1,6 @@
# naive
-![build status](https://api.travis-ci.org/nvandoorn/naive.svg?branch=master "Build Status")
+![build status](https://api.travis-ci.org/nvandoorn/naive.svg?branch=master 'Build Status')
[Read the docs](https://nvandoorn.github.io/naive/)
diff --git a/server/src/context.model.ts b/server/src/context.model.ts
index d8419d4..cedd675 100644
--- a/server/src/context.model.ts
+++ b/server/src/context.model.ts
@@ -1,5 +1,5 @@
export interface Context {
- httpPort: number;
- wsPort: number;
- logger: (e: any) => any;
+ httpPort: number
+ wsPort: number
+ logger: (e: any) => any
}
diff --git a/server/src/operations.ts b/server/src/operations.ts
index 6802ee7..c0fec8d 100644
--- a/server/src/operations.ts
+++ b/server/src/operations.ts
@@ -1,56 +1,56 @@
-import { Context } from "./context.model";
-import { SubscriptionRequest } from "../../lib/subscription-req.model";
-import { WriteRequest } from "../../lib/write-req.model";
-import { DatabaseChange } from "../../lib/database-change.model";
+import { Context } from './context.model'
+import { SubscriptionRequest } from '../../lib/subscription-req.model'
+import { WriteRequest } from '../../lib/write-req.model'
+import { DatabaseChange } from '../../lib/database-change.model'
-import { DatabaseInterface } from "naive-core";
+import { DatabaseInterface } from 'naive-core'
-import express, { RequestHandler } from "express";
-import bodyParser from "body-parser";
+import express, { RequestHandler } from 'express'
+import bodyParser from 'body-parser'
export const bindOperations = (
ctx: Context,
db: DatabaseInterface,
send: (e: DatabaseChange) => Promise<any>
) => {
- const unsubs: { [key: string]: () => any } = {};
+ const unsubs: { [key: string]: () => any } = {}
const writeHandler: RequestHandler = async (req, res) => {
- const { path, toWrite } = req.body as WriteRequest;
- await db.write(path, toWrite);
- res.status(200).end();
- };
+ const { path, toWrite } = req.body as WriteRequest
+ await db.write(path, toWrite)
+ res.status(200).end()
+ }
const addSubHandler: RequestHandler = async (req, res) => {
- const { path } = req.body as SubscriptionRequest;
+ const { path } = req.body as SubscriptionRequest
// only allow users to subscribe
// to a given path once
// TODO return a better error
if (unsubs[path]) {
- res.status(500).end();
- return;
+ res.status(500).end()
+ return
}
unsubs[path] = db.subscribe(path, async (change: Object) => {
await send({
path,
change
- });
- });
- res.status(200).end();
- };
+ })
+ })
+ res.status(200).end()
+ }
const removeSubHandler: RequestHandler = async (req, res) => {
- const { path } = req.body as SubscriptionRequest;
- const unsub = unsubs[path];
- if (unsub) unsub();
- };
+ const { path } = req.body as SubscriptionRequest
+ const unsub = unsubs[path]
+ if (unsub) unsub()
+ }
- const router = express();
- router.use(bodyParser.json());
- router.post("/write", writeHandler);
+ const router = express()
+ router.use(bodyParser.json())
+ router.post('/write', writeHandler)
router
- .route("/subscribe")
+ .route('/subscribe')
.post(addSubHandler)
- .delete(removeSubHandler);
- router.listen(ctx.httpPort, () => ctx.logger("HTTPS server started"));
-};
+ .delete(removeSubHandler)
+ router.listen(ctx.httpPort, () => ctx.logger('HTTPS server started'))
+}
diff --git a/server/src/server.test.ts b/server/src/server.test.ts
index 2bd2e45..b4a308f 100644
--- a/server/src/server.test.ts
+++ b/server/src/server.test.ts
@@ -1,31 +1,31 @@
-import { runServer } from "./server";
-import process from "process";
+import { runServer } from './server'
+import process from 'process'
// We test the server using the client.
// It would be better to import this
// from a linked npm package,
// but that requires rebuilding each time
// so fuck it for now
-import { dbFactory, DatabaseConnection } from "../../client/src";
+import { dbFactory, DatabaseConnection } from '../../client/src'
-const port = +(process.env.PORT || 5005);
-const httpPort = port;
-const wsPort = port + 1;
+const port = +(process.env.PORT || 5005)
+const httpPort = port
+const wsPort = port + 1
-describe("Server module", async () => {
- let db: DatabaseConnection;
+describe('Server module', async () => {
+ let db: DatabaseConnection
beforeAll(async () => {
await runServer({
httpPort,
wsPort,
logger: console.log
- });
- db = dbFactory({ wsPort, httpUrl: `http://localhost:${httpPort}` });
- await db.init();
- });
- test("it should work", async () => {
- await db.write("/hello/world", {
- my: "data"
- });
- });
-});
+ })
+ db = dbFactory({ wsPort, httpUrl: `http://localhost:${httpPort}` })
+ await db.init()
+ })
+ test('it should work', async () => {
+ await db.write('/hello/world', {
+ my: 'data'
+ })
+ })
+})
diff --git a/server/src/server.ts b/server/src/server.ts
index f80bd2b..459bc69 100644
--- a/server/src/server.ts
+++ b/server/src/server.ts
@@ -1,18 +1,18 @@
-import { Context } from "./context.model";
-import { bindOperations } from "./operations";
-import { DatabaseChange } from "../../lib/database-change.model";
-import WebSocket from "ws";
+import { Context } from './context.model'
+import { bindOperations } from './operations'
+import { DatabaseChange } from '../../lib/database-change.model'
+import WebSocket from 'ws'
-import { Database, Context as CoreContext } from "naive-core";
+import { Database, Context as CoreContext } from 'naive-core'
export const runServer = async (ctx: Context) => {
- const db = new Database();
- await db.init();
- const wss = new WebSocket.Server({ port: ctx.wsPort });
+ 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);
+ client.send(dbChange)
}
- });
-};
+ })
+}
diff --git a/server/yarn.lock b/server/yarn.lock
index 9eb810c..5d36ad8 100644
--- a/server/yarn.lock
+++ b/server/yarn.lock
@@ -18,7 +18,7 @@
esutils "^2.0.2"
js-tokens "^4.0.0"
-"@types/body-parser@*":
+"@types/body-parser@*", "@types/body-parser@^1.17.0":
version "1.17.0"
resolved "https://registry.yarnpkg.com/@types/body-parser/-/body-parser-1.17.0.tgz#9f5c9d9bd04bb54be32d5eb9fc0d8c974e6cf58c"
integrity sha512-a2+YeUjPkztKJu5aIF2yArYFQQp8d51wZ7DavSHjFuY1mqVgidGyzEQ41JIVNy82fXj8yPgy2vJmfIywgESW6w==
@@ -541,7 +541,7 @@ bcrypt-pbkdf@^1.0.0:
dependencies:
tweetnacl "^0.14.3"
-body-parser@1.18.3:
+body-parser@1.18.3, body-parser@^1.18.3:
version "1.18.3"
resolved "https://registry.yarnpkg.com/body-parser/-/body-parser-1.18.3.tgz#5b292198ffdd553b3a0f20ded0592b956955c8b4"
integrity sha1-WykhmP/dVTs6DyDe0FkrlWlVyLQ=