diff --git a/package.json b/package.json
index 841a43b..f370d54 100644
--- a/package.json
+++ b/package.json
@@ -79,6 +79,7 @@
"redux": "^3.7.1",
"redux-saga": "^0.15.4",
"reselect": "^3.0.1",
+ "semantic-ui-css":"^2.2.10",
"semantic-ui-react": "^0.70.0",
"socket.io-client": "^2.0.3"
},
diff --git a/src/ts/@overflow/app/index.tsx b/src/ts/@overflow/app/index.tsx
index e821529..10e10c4 100644
--- a/src/ts/@overflow/app/index.tsx
+++ b/src/ts/@overflow/app/index.tsx
@@ -4,7 +4,6 @@ import { fork } from 'redux-saga/effects';
import { Provider } from 'react-redux';
import { ConnectedRouter } from 'react-router-redux';
-import MuiThemeProvider from 'material-ui/styles/MuiThemeProvider';
import * as injectTapEventPlugin from 'react-tap-event-plugin';
@@ -20,8 +19,6 @@ injectTapEventPlugin();
function* app(): any {
const appContainer: HTMLElement = yield Platform.getAppContainer('react-placeholder');
-
-
ReactDOM.render(
-
-
- {routes}
-
-
+
+ {routes}
+
,
appContainer,
);
}
sagaMiddleware.run(app);
+
diff --git a/src/ts/@overflow/commons/websocket/WebSocketRPC.ts b/src/ts/@overflow/commons/websocket/WebSocketRPC.ts
new file mode 100644
index 0000000..9c2c83e
--- /dev/null
+++ b/src/ts/@overflow/commons/websocket/WebSocketRPC.ts
@@ -0,0 +1,136 @@
+import {
+ ProtocolNotification,
+ ProtocolRequest,
+ ProtocolResponse,
+} from './protocol';
+
+import {
+ PROTOCOL_NAME as RPCProtocol,
+ RPCRequest,
+ RPCResponse,
+} from './protocol/rpc';
+
+
+export type OnConnectFunc = () => void;
+export type OnDisconnectFunc = () => void;
+export type OnResponseFunc = (response: any) => void;
+
+type ID_TYPE = number;
+
+interface RequestQueue {
+ resolve: (value?: any) => void;
+ reject: (reason?: any) => void;
+}
+
+export default class WebSocketRPC {
+ private url: string;
+ private conn: WebSocket;
+ private isReady: boolean;
+ private requestID: ID_TYPE = 0;
+
+ private onConnectListeners: OnConnectFunc[] = [];
+ private onDisconnectListeners: OnDisconnectFunc[] = [];
+ private onResponseListeners: Map
;
+
+ private requestQueue: Map;
+ /**
+ * name
+ */
+ public constructor(url: string) {
+ this.isReady = false;
+ this.url = url;
+ this.onResponseListeners = new Map();
+ this.requestQueue = new Map();
+
+ this.initialize();
+ }
+
+ public Call(method: string, params: any[]): Promise {
+
+
+ return new Promise((resolve, reject) => {
+ const requestID = this.getRequestID();
+ let request = new ProtocolRequest(RPCProtocol, requestID);
+ let req = new RPCRequest(method, params);
+ request.setBody(req.toJSON());
+ this.conn.send(request.toJSON());
+ this.requestQueue.set(requestID, {resolve: resolve, reject: reject});
+ });
+ }
+
+
+ public OnConnect(cb: OnConnectFunc): void {
+ if (this.isReady) {
+ cb();
+ }
+ this.onConnectListeners.push(cb);
+ }
+
+ public OnDisconnect(cb: OnDisconnectFunc): void {
+ this.onDisconnectListeners.push(cb);
+ }
+
+ private initialize(): void {
+ this.conn = new WebSocket(this.url);
+ this.conn.onopen = (e: Event): any => {
+ this.fireOnConnect();
+ this.isReady = true;
+ return null;
+ };
+
+ this.conn.onclose = (e: CloseEvent): any => {
+ this.fireOnDisconnect();
+ return null;
+ };
+
+ this.conn.onmessage = (e: MessageEvent): any => {
+ let response: ProtocolResponse = JSON.parse(e.data);
+ let res: RPCResponse = JSON.parse(response.getBody());
+ const requestID = response.getID();
+ const error = response.getError();
+ const result = res.getResult();
+
+ if (this.requestQueue.has(requestID)) {
+ let promise = this.requestQueue.get(requestID);
+ this.requestQueue.delete(requestID);
+ if (null != result) {
+ promise.resolve(result);
+ } else if (null != error) {
+ promise.reject(error);
+ } else {
+ console.log('??????');
+ }
+ } else {
+ // perhaps sever side send message
+ }
+
+ this.fireOnMessage(e);
+ };
+
+ }
+
+ private fireOnConnect(): void {
+ for (let i = 0; i < this.onConnectListeners.length; i++) {
+ this.onConnectListeners[i]();
+ }
+ }
+
+ private fireOnDisconnect(): void {
+ for (let i = 0; i < this.onDisconnectListeners.length; i++) {
+ this.onDisconnectListeners[i]();
+ }
+ }
+
+ private fireOnMessage(e: MessageEvent): void {
+
+
+ for (let i = 0; i < this.onDisconnectListeners.length; i++) {
+ this.onDisconnectListeners[i]();
+ }
+ }
+
+ private getRequestID(): number {
+ return ++this.requestID;
+ }
+
+}
diff --git a/src/ts/@overflow/commons/websocket/protocol/ProtocolError.ts b/src/ts/@overflow/commons/websocket/protocol/ProtocolError.ts
new file mode 100644
index 0000000..69568c1
--- /dev/null
+++ b/src/ts/@overflow/commons/websocket/protocol/ProtocolError.ts
@@ -0,0 +1,46 @@
+export const enum ErrorCode {
+ E_PARSE = -32700,
+ E_INVALID_REQ = -32600,
+ E_NO_METHOD = -32601,
+ E_BAD_PARAMS = -32602,
+ E_INTERNAL = -32603,
+ E_SERVER = -32000,
+
+}
+
+export class ProtocolError {
+ private code: ErrorCode;
+ private message: string;
+ private data: any;
+
+ public constructor(code: ErrorCode, message: string, data: any) {
+ this.code = code;
+ this.message = message;
+ this.data = data;
+ }
+
+ /**
+ * getID
+ */
+ public getCode(): ErrorCode {
+ return this.code;
+ }
+
+ /**
+ * getBody
+ */
+ public getMessage(): string {
+ return this.message;
+ }
+
+ /**
+ * getError
+ */
+ public getData(): any {
+ return this.data;
+ }
+
+ public static newError(json: string): ProtocolError {
+ return JSON.parse(json);
+ }
+}
diff --git a/src/ts/@overflow/commons/websocket/protocol/ProtocolHeader.ts b/src/ts/@overflow/commons/websocket/protocol/ProtocolHeader.ts
new file mode 100644
index 0000000..059cd2b
--- /dev/null
+++ b/src/ts/@overflow/commons/websocket/protocol/ProtocolHeader.ts
@@ -0,0 +1,44 @@
+export class ProtocolHeader {
+ private readonly protocol: string;
+ private readonly id: ID;
+ private body: string;
+
+ public constructor(protocol: string, id: ID) {
+ this.protocol = protocol;
+ this.id = id;
+ }
+
+ /**
+ * getProtocol
+ */
+ public getProtocol(): string {
+ return this.protocol;
+ }
+
+ /**
+ * getID
+ */
+ public getID(): ID {
+ return this.id;
+ }
+
+ /**
+ * setID
+ */
+ public setBody(body: string): void {
+ this.body = body;
+ }
+ /**
+ * getID
+ */
+ public getBody(): string {
+ return this.body;
+ }
+
+ /**
+ * toJSON
+ */
+ public toJSON(): string {
+ return JSON.stringify(this);
+ }
+}
diff --git a/src/ts/@overflow/commons/websocket/protocol/ProtocolNotification.ts b/src/ts/@overflow/commons/websocket/protocol/ProtocolNotification.ts
new file mode 100644
index 0000000..619025b
--- /dev/null
+++ b/src/ts/@overflow/commons/websocket/protocol/ProtocolNotification.ts
@@ -0,0 +1,35 @@
+export class ProtocolNotification {
+ private readonly protocol: string;
+ private body: string;
+
+ public constructor(protocol: string) {
+ this.protocol = protocol;
+ }
+
+ /**
+ * getProtocol
+ */
+ public getProtocol(): string {
+ return this.protocol;
+ }
+
+ /**
+ * setBody
+ */
+ public setBody(body: string): void {
+ this.body = body;
+ }
+ /**
+ * getBody
+ */
+ public getBody(): string {
+ return this.body;
+ }
+
+ /**
+ * toJSON
+ */
+ public toJSON(): string {
+ return JSON.stringify(this);
+ }
+}
diff --git a/src/ts/@overflow/commons/websocket/protocol/ProtocolRequest.ts b/src/ts/@overflow/commons/websocket/protocol/ProtocolRequest.ts
new file mode 100644
index 0000000..1339d21
--- /dev/null
+++ b/src/ts/@overflow/commons/websocket/protocol/ProtocolRequest.ts
@@ -0,0 +1,7 @@
+import { ProtocolHeader } from './ProtocolHeader';
+
+export class ProtocolRequest extends ProtocolHeader {
+ public constructor(protocol: string, id: ID) {
+ super(protocol, id);
+ }
+}
diff --git a/src/ts/@overflow/commons/websocket/protocol/ProtocolResponse.ts b/src/ts/@overflow/commons/websocket/protocol/ProtocolResponse.ts
new file mode 100644
index 0000000..551ee5e
--- /dev/null
+++ b/src/ts/@overflow/commons/websocket/protocol/ProtocolResponse.ts
@@ -0,0 +1,23 @@
+import { ProtocolHeader } from './ProtocolHeader';
+import { ProtocolError } from './ProtocolError';
+
+export class ProtocolResponse extends ProtocolHeader {
+ private error: ProtocolError;
+
+ public constructor(protocol: string, id: ID) {
+ super(protocol, id);
+ }
+
+ /**
+ * setError
+ */
+ public setError(error: ProtocolError): void {
+ this.error = error;
+ }
+ /**
+ * getError
+ */
+ public getError(): ProtocolError {
+ return this.error;
+ }
+}
diff --git a/src/ts/@overflow/commons/websocket/protocol/ProtocolSub.ts b/src/ts/@overflow/commons/websocket/protocol/ProtocolSub.ts
new file mode 100644
index 0000000..9149392
--- /dev/null
+++ b/src/ts/@overflow/commons/websocket/protocol/ProtocolSub.ts
@@ -0,0 +1,6 @@
+export abstract class ProtocolSub {
+ /**
+ * toJSON
+ */
+ public abstract toJSON(): string;
+}
diff --git a/src/ts/@overflow/commons/websocket/protocol/index.ts b/src/ts/@overflow/commons/websocket/protocol/index.ts
new file mode 100644
index 0000000..afdd54d
--- /dev/null
+++ b/src/ts/@overflow/commons/websocket/protocol/index.ts
@@ -0,0 +1,6 @@
+export * from './ProtocolError';
+export * from './ProtocolHeader';
+export * from './ProtocolNotification';
+export * from './ProtocolRequest';
+export * from './ProtocolResponse';
+export * from './ProtocolSub';
diff --git a/src/ts/@overflow/commons/websocket/protocol/rpc/RPCRequest.ts b/src/ts/@overflow/commons/websocket/protocol/rpc/RPCRequest.ts
new file mode 100644
index 0000000..72866a2
--- /dev/null
+++ b/src/ts/@overflow/commons/websocket/protocol/rpc/RPCRequest.ts
@@ -0,0 +1,33 @@
+import { ProtocolSub } from '../ProtocolSub';
+
+export class RPCRequest extends ProtocolSub {
+ private readonly method: string;
+ private readonly params: any[];
+
+ public constructor(method: string, params: any[]) {
+ super();
+ this.method = method;
+ this.params = params;
+ }
+
+ /**
+ * getMethod
+ */
+ public getMethod(): string {
+ return this.method;
+ }
+
+ /**
+ * getParams
+ */
+ public getParams(): any[] {
+ return this.params;
+ }
+
+ /**
+ * toJSON
+ */
+ public toJSON(): string {
+ return JSON.stringify(this);
+ }
+}
diff --git a/src/ts/@overflow/commons/websocket/protocol/rpc/RPCResponse.ts b/src/ts/@overflow/commons/websocket/protocol/rpc/RPCResponse.ts
new file mode 100644
index 0000000..af7ebcc
--- /dev/null
+++ b/src/ts/@overflow/commons/websocket/protocol/rpc/RPCResponse.ts
@@ -0,0 +1,24 @@
+import { ProtocolSub } from '../ProtocolSub';
+
+export class RPCResponse extends ProtocolSub {
+ private readonly result: any;
+
+ public constructor(result: any) {
+ super();
+ this.result = result;
+ }
+
+ /**
+ * getResult
+ */
+ public getResult(): any {
+ return this.result;
+ }
+
+ /**
+ * toJSON
+ */
+ public toJSON(): string {
+ return JSON.stringify(this);
+ }
+}
diff --git a/src/ts/@overflow/commons/websocket/protocol/rpc/index.ts b/src/ts/@overflow/commons/websocket/protocol/rpc/index.ts
new file mode 100644
index 0000000..f51d676
--- /dev/null
+++ b/src/ts/@overflow/commons/websocket/protocol/rpc/index.ts
@@ -0,0 +1,5 @@
+export * from './RPCRequest';
+export * from './RPCResponse';
+
+export const PROTOCOL_NAME = 'jsonrpc';
+
diff --git a/src/ts/@overflow/member/api/service/MemberService.ts b/src/ts/@overflow/member/api/service/MemberService.ts
index 0a20dbc..562c509 100644
--- a/src/ts/@overflow/member/api/service/MemberService.ts
+++ b/src/ts/@overflow/member/api/service/MemberService.ts
@@ -1,6 +1,7 @@
import Service from '@overflow/commons/api/Service';
import Member from '../model/Member';
+@ServiceClass
export class MemberService extends Service {
public constructor() {
diff --git a/tsconfig.json b/tsconfig.json
index 1dac4cf..c9017b0 100644
--- a/tsconfig.json
+++ b/tsconfig.json
@@ -1,7 +1,7 @@
{
"compilerOptions": {
"allowSyntheticDefaultImports": true,
- "baseUrl": "src/ts",
+ "baseUrl": ".",
"declaration": true,
"emitDecoratorMetadata": true,
"experimentalDecorators": true,
@@ -11,7 +11,7 @@
"es5",
"es6"
],
- "module": "esnext",
+ "module": "umd",
"moduleResolution": "node",
"newLine": "LF",
"noImplicitAny": false,
@@ -19,6 +19,12 @@
"outDir": "dist/ts/",
"preserveConstEnums": true,
"pretty": true,
+ "paths": {
+ "*": [
+ "./src/ts/*",
+ "./types/*"
+ ]
+ },
"removeComments": true,
"sourceMap": true,
"target": "es5",
@@ -34,6 +40,7 @@
"build",
"config",
"node_modules",
- "public"
+ "public",
+ "types"
]
}