From 5722979894b53805639407f856cea78a56d725f3 Mon Sep 17 00:00:00 2001 From: aahmed98 <43424656+aahmed98@users.noreply.github.com> Date: Sat, 9 Feb 2019 15:26:57 -0500 Subject: Create database.tsx --- database.tsx | 15 +++++++++++++++ 1 file changed, 15 insertions(+) create mode 100644 database.tsx diff --git a/database.tsx b/database.tsx new file mode 100644 index 000000000..9c90326a5 --- /dev/null +++ b/database.tsx @@ -0,0 +1,15 @@ +import { action, configure } from 'mobx'; +import * as mongodb from 'mongodb'; + +export class database { + private MongoClient = mongodb.MongoClient; + private url = 'mongodb://localhost:27017/website'; + + public async update(id: string, field: string, value: string) { + this.MongoClient.connect(this.url, (err, db) => { + let collection = db.collection('documents'); + collection.update({ "id": id }, { $set: { field: value } }); + db.close(); + }); + } +} -- cgit v1.2.3-70-g09d2 From 1eb3d60457d4fc0ae957832c3ab751b54a24cc21 Mon Sep 17 00:00:00 2001 From: ab Date: Sat, 9 Feb 2019 17:28:27 -0500 Subject: database --- database.tsx | 15 ---------- package-lock.json | 82 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ package.json | 2 ++ src/Main.tsx | 3 ++ src/Server.ts | 61 ++++++++++++++++++++++++++++++++++++++++ src/Server.tsx | 61 ---------------------------------------- src/SocketStub.ts | 78 +++++++++++++++++++++++++++++++++++++++++++++++++++ src/SocketStub.tsx | 78 --------------------------------------------------- src/database.ts | 41 +++++++++++++++++++++++++++ webpack.config.js | 5 +++- 10 files changed, 271 insertions(+), 155 deletions(-) delete mode 100644 database.tsx create mode 100644 src/Server.ts delete mode 100644 src/Server.tsx create mode 100644 src/SocketStub.ts delete mode 100644 src/SocketStub.tsx create mode 100644 src/database.ts diff --git a/database.tsx b/database.tsx deleted file mode 100644 index 9c90326a5..000000000 --- a/database.tsx +++ /dev/null @@ -1,15 +0,0 @@ -import { action, configure } from 'mobx'; -import * as mongodb from 'mongodb'; - -export class database { - private MongoClient = mongodb.MongoClient; - private url = 'mongodb://localhost:27017/website'; - - public async update(id: string, field: string, value: string) { - this.MongoClient.connect(this.url, (err, db) => { - let collection = db.collection('documents'); - collection.update({ "id": id }, { $set: { field: value } }); - db.close(); - }); - } -} diff --git a/package-lock.json b/package-lock.json index 9fbe16195..810bf6c8f 100644 --- a/package-lock.json +++ b/package-lock.json @@ -17,6 +17,14 @@ "@fortawesome/fontawesome-common-types": "^0.2.14" } }, + "@types/bson": { + "version": "1.0.11", + "resolved": "https://registry.npmjs.org/@types/bson/-/bson-1.0.11.tgz", + "integrity": "sha512-j+UcCWI+FsbI5/FQP/Kj2CXyplWAz39ktHFkXk84h7dNblKRSoNJs95PZFRd96NQGqsPEPgeclqnznWZr14ZDA==", + "requires": { + "@types/node": "*" + } + }, "@types/chai": { "version": "4.1.7", "resolved": "https://registry.npmjs.org/@types/chai/-/chai-4.1.7.tgz", @@ -37,6 +45,15 @@ "integrity": "sha512-lAVp+Kj54ui/vLUFxsJTMtWvZraZxum3w3Nwkble2dNuV5VnPA+Mi2oGX9XYJAaIvZi3tn3cbjS/qcJXRb6Bww==", "dev": true }, + "@types/mongodb": { + "version": "3.1.19", + "resolved": "https://registry.npmjs.org/@types/mongodb/-/mongodb-3.1.19.tgz", + "integrity": "sha512-H54hQEovAhyLrIZOhPNfGyCCDoTqKsjb8GQBy8nptJqfxrYCp5WVcPJf9v0kfTPR72xOhaz9+WcYxOXWwEg1Vg==", + "requires": { + "@types/bson": "*", + "@types/node": "*" + } + }, "@types/node": { "version": "10.12.21", "resolved": "https://registry.npmjs.org/@types/node/-/node-10.12.21.tgz", @@ -928,6 +945,11 @@ "pako": "~1.0.5" } }, + "bson": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/bson/-/bson-1.1.0.tgz", + "integrity": "sha512-9Aeai9TacfNtWXOYarkFJRW2CWo+dRon+fuLZYJmvLV3+MiUp0bEI6IAZfXEIg7/Pl/7IWlLaDnhzTsD81etQA==" + }, "buffer": { "version": "4.9.1", "resolved": "https://registry.npmjs.org/buffer/-/buffer-4.9.1.tgz", @@ -4172,6 +4194,12 @@ "readable-stream": "^2.0.1" } }, + "memory-pager": { + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/memory-pager/-/memory-pager-1.5.0.tgz", + "integrity": "sha512-ZS4Bp4r/Zoeq6+NLJpP+0Zzm0pR8whtGPf1XExKLJBAczGMnSi3It14OiNCStjQjM6NU1okjQGSxgEZN8eBYKg==", + "optional": true + }, "meow": { "version": "3.7.0", "resolved": "https://registry.npmjs.org/meow/-/meow-3.7.0.tgz", @@ -4425,6 +4453,26 @@ } } }, + "mongodb": { + "version": "3.1.13", + "resolved": "https://registry.npmjs.org/mongodb/-/mongodb-3.1.13.tgz", + "integrity": "sha512-sz2dhvBZQWf3LRNDhbd30KHVzdjZx9IKC0L+kSZ/gzYquCF5zPOgGqRz6sSCqYZtKP2ekB4nfLxhGtzGHnIKxA==", + "requires": { + "mongodb-core": "3.1.11", + "safe-buffer": "^5.1.2" + } + }, + "mongodb-core": { + "version": "3.1.11", + "resolved": "https://registry.npmjs.org/mongodb-core/-/mongodb-core-3.1.11.tgz", + "integrity": "sha512-rD2US2s5qk/ckbiiGFHeu+yKYDXdJ1G87F6CG3YdaZpzdOm5zpoAZd/EKbPmFO6cQZ+XVXBXBJ660sSI0gc6qg==", + "requires": { + "bson": "^1.1.0", + "require_optional": "^1.0.1", + "safe-buffer": "^5.1.2", + "saslprep": "^1.0.0" + } + }, "move-concurrently": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/move-concurrently/-/move-concurrently-1.0.1.tgz", @@ -8692,6 +8740,22 @@ "resolved": "https://registry.npmjs.org/require-main-filename/-/require-main-filename-1.0.1.tgz", "integrity": "sha1-l/cXtp1IeE9fUmpsWqj/3aBVpNE=" }, + "require_optional": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/require_optional/-/require_optional-1.0.1.tgz", + "integrity": "sha512-qhM/y57enGWHAe3v/NcwML6a3/vfESLe/sGM2dII+gEO0BpKRUkWZow/tyloNqJyN6kXSl3RyyM8Ll5D/sJP8g==", + "requires": { + "resolve-from": "^2.0.0", + "semver": "^5.1.0" + }, + "dependencies": { + "resolve-from": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-2.0.0.tgz", + "integrity": "sha1-lICrIOlP+h2egKgEx+oUdhGWa1c=" + } + } + }, "requires-port": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/requires-port/-/requires-port-1.0.0.tgz", @@ -8786,6 +8850,15 @@ "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==" }, + "saslprep": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/saslprep/-/saslprep-1.0.2.tgz", + "integrity": "sha512-4cDsYuAjXssUSjxHKRe4DTZC0agDwsCqcMqtJAQPzC74nJ7LfAJflAtC1Zed5hMzEQKj82d3tuzqdGNRsLJ4Gw==", + "optional": true, + "requires": { + "sparse-bitfield": "^3.0.3" + } + }, "sass-graph": { "version": "2.2.4", "resolved": "https://registry.npmjs.org/sass-graph/-/sass-graph-2.2.4.tgz", @@ -9244,6 +9317,15 @@ "integrity": "sha1-PpNdfd1zYxuXZZlW1VEo6HtQhKM=", "dev": true }, + "sparse-bitfield": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/sparse-bitfield/-/sparse-bitfield-3.0.3.tgz", + "integrity": "sha1-/0rm5oZWBWuks+eSqzM004JzyhE=", + "optional": true, + "requires": { + "memory-pager": "^1.0.2" + } + }, "spdx-correct": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/spdx-correct/-/spdx-correct-3.1.0.tgz", diff --git a/package.json b/package.json index 9afddb8d9..8e79901be 100644 --- a/package.json +++ b/package.json @@ -29,6 +29,7 @@ "dependencies": { "@fortawesome/fontawesome-svg-core": "^1.2.14", "@types/jquery": "^3.3.29", + "@types/mongodb": "^3.1.19", "@types/prosemirror-commands": "^1.0.1", "@types/prosemirror-history": "^1.0.1", "@types/prosemirror-keymap": "^1.0.1", @@ -45,6 +46,7 @@ "mobx": "^5.9.0", "mobx-react": "^5.3.5", "mobx-react-devtools": "^6.0.3", + "mongodb": "^3.1.13", "node-sass": "^4.11.0", "normalize.css": "^8.0.1", "npm": "^6.7.0", diff --git a/src/Main.tsx b/src/Main.tsx index fa6230393..eee8554f3 100644 --- a/src/Main.tsx +++ b/src/Main.tsx @@ -14,6 +14,7 @@ import { ContextMenu } from './views/ContextMenu'; import { DocumentView } from './views/nodes/DocumentView'; import { CompileScript } from './util/Scripting'; import { ImageField } from './fields/ImageField'; +import { database } from './database'; configure({ @@ -40,6 +41,8 @@ document.addEventListener("pointerdown", action(function (e: PointerEvent) { //runInAction(() => { + let db = new database(); + db.update('1', '2', '3'); let doc1 = Documents.TextDocument({ title: "hello" }); let doc2 = doc1.MakeDelegate(); doc2.Set(KS.X, new NumberField(150)); diff --git a/src/Server.ts b/src/Server.ts new file mode 100644 index 000000000..645420771 --- /dev/null +++ b/src/Server.ts @@ -0,0 +1,61 @@ +import { Field, FieldWaiting, FIELD_ID, FIELD_WAITING, FieldValue } from "./fields/Field" +import { Key, KeyStore } from "./fields/Key" +import { ObservableMap, action } from "mobx"; +import { Document } from "./fields/Document" +import { SocketStub } from "./SocketStub"; + +export class Server { + private static ClientFieldsCached: ObservableMap = new ObservableMap(); + + // Retrieves the cached value of the field and sends a request to the server for the real value (if it's not cached). + // Call this is from within a reaction and test whether the return value is FieldWaiting. + // 'hackTimeout' is here temporarily for simplicity when debugging things. + public static GetField(fieldid: FIELD_ID, callback: (field: Field) => void = (f) => { }, hackTimeout: number = -1) { + if (!this.ClientFieldsCached.get(fieldid)) { + this.ClientFieldsCached.set(fieldid, FieldWaiting); + //simulating a server call with a registered callback action + SocketStub.SEND_FIELD_REQUEST(fieldid, + action((field: Field) => callback(Server.cacheField(field))), + hackTimeout); + } else if (this.ClientFieldsCached.get(fieldid) != FieldWaiting) { + callback(this.ClientFieldsCached.get(fieldid) as Field); + } + return this.ClientFieldsCached.get(fieldid); + } + + static times = 0; // hack for testing + public static GetDocumentField(doc: Document, key: Key) { + var hackTimeout: number = key == KeyStore.Data ? (this.times++ == 0 ? 5000 : 1000) : key == KeyStore.X ? 2500 : 500; + + return this.GetField(doc._proxies.get(key), + action((fieldfromserver: Field) => { + doc._proxies.delete(key); + doc.fields.set(key, fieldfromserver); + }) + , hackTimeout); + } + + public static AddDocument(document: Document) { + SocketStub.SEND_ADD_DOCUMENT(document); + } + public static AddDocumentField(doc: Document, key: Key, value: Field) { + SocketStub.SEND_ADD_DOCUMENT_FIELD(doc, key, value); + } + public static DeleteDocumentField(doc: Document, key: Key) { + SocketStub.SEND_DELETE_DOCUMENT_FIELD(doc, key); + } + public static SetFieldValue(field: Field, value: any) { + SocketStub.SEND_SET_FIELD(field, value); + } + + @action + private static cacheField(clientField: Field) { + var cached = this.ClientFieldsCached.get(clientField.Id); + if (!cached || cached == FieldWaiting) { + this.ClientFieldsCached.set(clientField.Id, clientField); + } else { + // probably should overwrite the values within any field that was already here... + } + return this.ClientFieldsCached.get(clientField.Id) as Field; + } +} diff --git a/src/Server.tsx b/src/Server.tsx deleted file mode 100644 index 645420771..000000000 --- a/src/Server.tsx +++ /dev/null @@ -1,61 +0,0 @@ -import { Field, FieldWaiting, FIELD_ID, FIELD_WAITING, FieldValue } from "./fields/Field" -import { Key, KeyStore } from "./fields/Key" -import { ObservableMap, action } from "mobx"; -import { Document } from "./fields/Document" -import { SocketStub } from "./SocketStub"; - -export class Server { - private static ClientFieldsCached: ObservableMap = new ObservableMap(); - - // Retrieves the cached value of the field and sends a request to the server for the real value (if it's not cached). - // Call this is from within a reaction and test whether the return value is FieldWaiting. - // 'hackTimeout' is here temporarily for simplicity when debugging things. - public static GetField(fieldid: FIELD_ID, callback: (field: Field) => void = (f) => { }, hackTimeout: number = -1) { - if (!this.ClientFieldsCached.get(fieldid)) { - this.ClientFieldsCached.set(fieldid, FieldWaiting); - //simulating a server call with a registered callback action - SocketStub.SEND_FIELD_REQUEST(fieldid, - action((field: Field) => callback(Server.cacheField(field))), - hackTimeout); - } else if (this.ClientFieldsCached.get(fieldid) != FieldWaiting) { - callback(this.ClientFieldsCached.get(fieldid) as Field); - } - return this.ClientFieldsCached.get(fieldid); - } - - static times = 0; // hack for testing - public static GetDocumentField(doc: Document, key: Key) { - var hackTimeout: number = key == KeyStore.Data ? (this.times++ == 0 ? 5000 : 1000) : key == KeyStore.X ? 2500 : 500; - - return this.GetField(doc._proxies.get(key), - action((fieldfromserver: Field) => { - doc._proxies.delete(key); - doc.fields.set(key, fieldfromserver); - }) - , hackTimeout); - } - - public static AddDocument(document: Document) { - SocketStub.SEND_ADD_DOCUMENT(document); - } - public static AddDocumentField(doc: Document, key: Key, value: Field) { - SocketStub.SEND_ADD_DOCUMENT_FIELD(doc, key, value); - } - public static DeleteDocumentField(doc: Document, key: Key) { - SocketStub.SEND_DELETE_DOCUMENT_FIELD(doc, key); - } - public static SetFieldValue(field: Field, value: any) { - SocketStub.SEND_SET_FIELD(field, value); - } - - @action - private static cacheField(clientField: Field) { - var cached = this.ClientFieldsCached.get(clientField.Id); - if (!cached || cached == FieldWaiting) { - this.ClientFieldsCached.set(clientField.Id, clientField); - } else { - // probably should overwrite the values within any field that was already here... - } - return this.ClientFieldsCached.get(clientField.Id) as Field; - } -} diff --git a/src/SocketStub.ts b/src/SocketStub.ts new file mode 100644 index 000000000..f9d48c067 --- /dev/null +++ b/src/SocketStub.ts @@ -0,0 +1,78 @@ +import { Field, FIELD_ID } from "./fields/Field" +import { Key, KeyStore } from "./fields/Key" +import { ObservableMap, action } from "mobx"; +import { Document } from "./fields/Document" + +export class SocketStub { + + static FieldStore: ObservableMap = new ObservableMap(); + public static SEND_ADD_DOCUMENT(document: Document) { + + // Send a serialized version of the document to the server + // ...SOCKET(ADD_DOCUMENT, serialied document) + + // server stores each document field in its repository of stored fields + document.fields.forEach((f, key) => this.FieldStore.set((f as Field).Id, f as Field)); + + // server stores stripped down document (w/ only field id proxies) in the field store + this.FieldStore.set(document.Id, new Document(document.Id)); + document.fields.forEach((f, key) => (this.FieldStore.get(document.Id) as Document)._proxies.set(key, (f as Field).Id)); + } + + public static SEND_FIELD_REQUEST(fieldid: FIELD_ID, callback: (field: Field) => void, timeout: number) { + + if (timeout < 0)// this is a hack to make things easier to setup until we have a server... won't be neededa fter that. + callback(this.FieldStore.get(fieldid) as Field); + else { // actual logic here... + + // Send a request for fieldid to the server + // ...SOCKET(RETRIEVE_FIELD, fieldid) + + // server responds (simulated with a timeout) and the callback is invoked + setTimeout(() => + + // when the field data comes back, call the callback() function + callback(this.FieldStore.get(fieldid) as Field), + + + timeout); + } + } + + public static SEND_ADD_DOCUMENT_FIELD(doc: Document, key: Key, value: Field) { + + // Send a serialized version of the field to the server along with the + // associated info of the document id and key where it is used. + + // ...SOCKET(ADD_DOCUMENT_FIELD, document id, key id, serialized field) + + // server updates its document to hold a proxy mapping from key => fieldId + var document = this.FieldStore.get(doc.Id) as Document; + if (document) + document._proxies.set(key, value.Id); + + // server adds the field to its repository of fields + this.FieldStore.set(value.Id, value); + } + + public static SEND_DELETE_DOCUMENT_FIELD(doc: Document, key: Key) { + // Send a request to delete the field stored under the specified key from the document + + // ...SOCKET(DELETE_DOCUMENT_FIELD, document id, key id) + + // Server removes the field id from the document's list of field proxies + var document = this.FieldStore.get(doc.Id) as Document; + if (document) + document._proxies.delete(key); + } + + public static SEND_SET_FIELD(field: Field, value: any) { + // Send a request to set the value of a field + + // ...SOCKET(SET_FIELD, field id, serialized field value) + + // Server updates the value of the field in its fieldstore + if (this.FieldStore.get(field.Id)) + this.FieldStore.get(field.Id)!.TrySetValue(value); + } +} diff --git a/src/SocketStub.tsx b/src/SocketStub.tsx deleted file mode 100644 index f9d48c067..000000000 --- a/src/SocketStub.tsx +++ /dev/null @@ -1,78 +0,0 @@ -import { Field, FIELD_ID } from "./fields/Field" -import { Key, KeyStore } from "./fields/Key" -import { ObservableMap, action } from "mobx"; -import { Document } from "./fields/Document" - -export class SocketStub { - - static FieldStore: ObservableMap = new ObservableMap(); - public static SEND_ADD_DOCUMENT(document: Document) { - - // Send a serialized version of the document to the server - // ...SOCKET(ADD_DOCUMENT, serialied document) - - // server stores each document field in its repository of stored fields - document.fields.forEach((f, key) => this.FieldStore.set((f as Field).Id, f as Field)); - - // server stores stripped down document (w/ only field id proxies) in the field store - this.FieldStore.set(document.Id, new Document(document.Id)); - document.fields.forEach((f, key) => (this.FieldStore.get(document.Id) as Document)._proxies.set(key, (f as Field).Id)); - } - - public static SEND_FIELD_REQUEST(fieldid: FIELD_ID, callback: (field: Field) => void, timeout: number) { - - if (timeout < 0)// this is a hack to make things easier to setup until we have a server... won't be neededa fter that. - callback(this.FieldStore.get(fieldid) as Field); - else { // actual logic here... - - // Send a request for fieldid to the server - // ...SOCKET(RETRIEVE_FIELD, fieldid) - - // server responds (simulated with a timeout) and the callback is invoked - setTimeout(() => - - // when the field data comes back, call the callback() function - callback(this.FieldStore.get(fieldid) as Field), - - - timeout); - } - } - - public static SEND_ADD_DOCUMENT_FIELD(doc: Document, key: Key, value: Field) { - - // Send a serialized version of the field to the server along with the - // associated info of the document id and key where it is used. - - // ...SOCKET(ADD_DOCUMENT_FIELD, document id, key id, serialized field) - - // server updates its document to hold a proxy mapping from key => fieldId - var document = this.FieldStore.get(doc.Id) as Document; - if (document) - document._proxies.set(key, value.Id); - - // server adds the field to its repository of fields - this.FieldStore.set(value.Id, value); - } - - public static SEND_DELETE_DOCUMENT_FIELD(doc: Document, key: Key) { - // Send a request to delete the field stored under the specified key from the document - - // ...SOCKET(DELETE_DOCUMENT_FIELD, document id, key id) - - // Server removes the field id from the document's list of field proxies - var document = this.FieldStore.get(doc.Id) as Document; - if (document) - document._proxies.delete(key); - } - - public static SEND_SET_FIELD(field: Field, value: any) { - // Send a request to set the value of a field - - // ...SOCKET(SET_FIELD, field id, serialized field value) - - // Server updates the value of the field in its fieldstore - if (this.FieldStore.get(field.Id)) - this.FieldStore.get(field.Id)!.TrySetValue(value); - } -} diff --git a/src/database.ts b/src/database.ts new file mode 100644 index 000000000..a822b15bf --- /dev/null +++ b/src/database.ts @@ -0,0 +1,41 @@ +import { action, configure } from 'mobx'; +import * as mongodb from 'mongodb'; + +export class database { + private MongoClient = mongodb.MongoClient; + private url = 'mongodb://localhost:27017/website'; + + public update(id: string, field: string, value: string) { + this.MongoClient.connect(this.url, (err, db) => { + let collection = db.db().collection('documents'); + collection.update({ "id": id }, { $set: { field: value } }); + db.close(); + }); + } + + public delete(id: string) { + this.MongoClient.connect(this.url, (err, db) => { + let collection = db.db().collection('documents'); + collection.remove({ "id": id }); + db.close(); + }); + } + + public insert(kvpairs: JSON) { + this.MongoClient.connect(this.url, (err, db) => { + let collection = db.db().collection('documents'); + collection.insert(kvpairs, () => { }); + db.close(); + }); + } + + public getDocument(id: string) { + var result: Array; + this.MongoClient.connect(this.url, (err, db) => { + let collection = db.db().collection('documents'); + collection.find({ "id": id }).toArray((err, db) => { result = db }); + db.close(); + return result[0]; + }); + } +} diff --git a/webpack.config.js b/webpack.config.js index 1a7c9286e..b5b6720bd 100644 --- a/webpack.config.js +++ b/webpack.config.js @@ -9,7 +9,10 @@ module.exports = { devtool: "source-map", node: { fs: 'empty', - module: 'empty' + module: 'empty', + dns: 'mock', + tls: 'mock', + net: 'mock' }, output: { filename: "./bundle.js", -- cgit v1.2.3-70-g09d2