Skip to content

Commit

Permalink
docs(site): regenerate doc
Browse files Browse the repository at this point in the history
  • Loading branch information
kalitine committed Jul 25, 2018
1 parent 36bf93c commit ff65247
Show file tree
Hide file tree
Showing 32 changed files with 1,252 additions and 944 deletions.
58 changes: 31 additions & 27 deletions docs/class/src/WebChannelFacade.js~WebGroup.html

Large diffs are not rendered by default.

34 changes: 29 additions & 5 deletions docs/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -80,16 +80,40 @@ <h2 id="features">Features</h2><ul>
<li>Universal API (works in Chrome/Firefox and NodeJS).</li>
<li>TypeScript declaration files are included.</li>
<li>Simple and familiar API usage.</li>
<li>4 builds (ES5 code):<ul>
<li><code>dist/netflux.cjs.js</code> CommonJS format for NodeJS (see <em>package.json#main</em>).</li>
<li><code>dist/esm/index.node.js</code> ES module format for NodeJS (see <em>package.json#module</em>).</li>
<li><code>dist/esm/index.browser.js</code> ES module format for browsers (see <em>package.json#browser</em>).</li>
<li><code>dist/netflux.umd.js</code> UMD format for browsers.</li>
<li>Multiple bundles for any configuration:<ul>
<li>For NodeJS<ul>
<li><code>dist/netflux.node.es5.cjs.js</code> commonjs format, es5 code (see <em>package.json#main</em>).</li>
<li><code>dist/netflux.node.es5.esm.js</code> ES module format, es5 code (see <em>package.json#module</em>).</li>
</ul>
</li>
<li>For browsers<ul>
<li><code>dist/netflux.browser.es5.umd.js</code> UMD format, es5 code</li>
<li><code>dist/netflux.browser.es5.esm.js</code> ES module format, es5 code (see <em>package.json#browser</em>).</li>
<li><code>dist/netflux.browser.es2015.esm.js</code> ES module format, es2015 code (see <em>package.json#es2015</em>).</li>
<li><code>dist/netflux.browser.esnext.esm.js</code> ES module format, esnext code (see <em>package.json#esnext</em>).</li>
</ul>
</li>
</ul>
</li>
</ul>
<h2 id="install">Install</h2><pre><code class="lang-shell"><code class="source-code prettyprint">npm install netflux</code>
</code></pre>
<p>3 peer dependencies to be installed for some cases:</p>
<ul>
<li><code>rxjs</code> is necessary for both NodeJS and browsers if you want to take advantage of EcmaScript modules, tree-shaking etc. Otherwise for it is already included into <code>dist/netflux.browser.es5.umd.js</code> and <code>dist/netflux.node.es5.cjs.js</code> bundles.</li>
</ul>
<pre><code class="lang-shell"><code class="source-code prettyprint">npm install rxjs</code>
</code></pre>
<ul>
<li><code>uws</code> and <code>text-encoding</code> if you target NodeJS (developing a bot):</li>
</ul>
<pre><code class="lang-shell"><code class="source-code prettyprint">npm install uws text-encoding</code>
</code></pre>
<p><strong>Why peer dependencies?</strong></p>
<ul>
<li>Reduce the installation size by not omitting unused dependencies.</li>
<li>Take advantage of new standards and techniques: EcmaScript modules, bundle tools like Webpack, RollupJS etc.</li>
</ul>
<h2 id="usage">Usage</h2><p>Here is a basic usage example for client and server (checkout the <a href="https://coast-team.github.io/netflux">documenation</a> for more details).</p>
<blockquote>
<p>It is possible to have only clients without any bot server as his is not a mandatory member, but like any other group member.</p>
Expand Down
892 changes: 478 additions & 414 deletions docs/index.json

Large diffs are not rendered by default.

111 changes: 56 additions & 55 deletions docs/jsFromTs/src/Bot.js
Original file line number Diff line number Diff line change
@@ -1,7 +1,9 @@
import { Channel } from './Channel';
import { WebGroupState } from './index.common.doc';
import { log } from './misc/util';
import { webChannelDefaultOptions } from './WebChannel';
import { wcs, WebGroup } from './WebChannelFacade';
import { Route, WebSocketBuilder } from './WebSocketBuilder';
import { WebSocketBuilder } from './WebSocketBuilder';
const urlLib = require('url');
const uws = require('uws');
const botDefaultOptions = {
Expand Down Expand Up @@ -38,7 +40,7 @@ export class Bot {
init() {
this.webSocketServer = new uws.Server({
perMessageDeflate: this.perMessageDeflate,
verifyClient: (info) => this.validateConnection(info),
verifyClient: (info) => this.validateURLQuery(info),
server: this.server,
});
const serverListening = this.server || this.webSocketServer;
Expand All @@ -48,69 +50,68 @@ export class Bot {
this.onError(err);
});
this.webSocketServer.on('connection', (ws) => {
const { route, wcId, senderId, key } = this.readUrl(ws.upgradeReq.url);
switch (route) {
case Route.INTERNAL: {
const wg = this.webGroups.get(wcId);
const wc = wcs.get(wg);
wc.webSocketBuilder.newInternalWebSocket(ws, senderId);
break;
const { type, wcId, senderId, key } = this.readURLQuery(ws.upgradeReq.url);
let webSocketBuilder;
if (type === Channel.WITH_MEMBER) {
const wg = new WebGroup(this.wcOptions);
this.webGroups.set(wcId, wg);
const wc = wcs.get(wg);
if (this.leaveOnceAlone) {
wc.onAlone = () => {
wc.leave();
this.webGroups.delete(wcId);
};
}
case Route.JOIN: {
wc.init(key, wcId);
this.onWebGroup(wg);
webSocketBuilder = wc.webSocketBuilder;
}
else {
const wg = this.webGroups.get(wcId);
const wc = wcs.get(wg);
webSocketBuilder = wc.webSocketBuilder;
}
webSocketBuilder.newWebSocket(ws, senderId, type);
});
}
validateURLQuery(info) {
try {
const { type, wcId, key } = this.readURLQuery(info.req.url);
switch (type) {
case Channel.WITH_INTERNAL:
return this.webGroups.has(wcId);
case Channel.WITH_MEMBER: {
const wg = this.webGroups.get(wcId);
const wc = wcs.get(wg);
wc.webSocketBuilder.newJoinWebSocket(ws);
break;
return !!key && (wg === undefined || wg.state === WebGroupState.LEFT);
}
case Route.INVITE: {
const wg = new WebGroup(this.wcOptions);
this.webGroups.set(wcId, wg);
const wc = wcs.get(wg);
if (this.leaveOnceAlone) {
wc.onAlone = () => {
wc.leave();
this.webGroups.delete(wcId);
};
}
wc.init(key, wcId);
this.onWebGroup(wg);
wc.webSocketBuilder.newInviteWebSocket(ws);
break;
case Channel.WITH_JOINING: {
const wg = this.webGroups.get(wcId);
return !!key && wg !== undefined && wg.key === key && wg.state !== WebGroupState.LEFT;
}
default:
return false;
}
});
}
validateConnection(info) {
const { route, wcId, senderId, key } = this.readUrl(info.req.url);
if (wcId === undefined) {
return false;
}
switch (route) {
case Route.INTERNAL:
return this.webGroups.has(wcId) && !!senderId;
case Route.INVITE: {
const wg = this.webGroups.get(wcId);
return !!key && (wg === undefined || wg.state === WebGroupState.LEFT);
}
case Route.JOIN: {
const wg = this.webGroups.get(wcId);
return !!key && wg !== undefined && wg.key === key && wg.state !== WebGroupState.LEFT;
}
default:
return false;
catch (err) {
log.warn(err.message);
return false;
}
}
readUrl(url) {
const { pathname, query: { senderId, wcId, key }, } = urlLib.parse(url, true);
let lastRoute = pathname;
if (pathname.endsWith('/')) {
lastRoute = pathname.substr(0, pathname.length - 1);
readURLQuery(url) {
const { type, wcId, senderId, key } = urlLib.parse(url, true).query;
if (!type) {
throw new Error('Query parse error: "type" parameter is undefined');
}
if (!wcId) {
throw new Error('Query parse error: "wcId" parameter is undefined');
}
if (!senderId) {
throw new Error('Query parse error: "senderId" parameter is undefined');
}
lastRoute = lastRoute.split('/').pop();
return {
route: lastRoute,
wcId: wcId ? Number(wcId) : undefined,
senderId: senderId ? Number(senderId) : undefined,
type: Number.parseInt(type, 10),
wcId: Number.parseInt(wcId, 10),
senderId: Number.parseInt(senderId, 10),
key,
};
}
Expand Down
100 changes: 64 additions & 36 deletions docs/jsFromTs/src/Channel.js
Original file line number Diff line number Diff line change
@@ -1,12 +1,6 @@
import { isBrowser, log } from './misc/util';
import { channel as proto, Message } from './proto';
import { isBrowser, log, MIN_ID } from './misc/util';
import { channel as proto, Message } from './proto/index';
import { UserMessage } from './service/UserMessage';
export var ChannelType;
(function (ChannelType) {
ChannelType[ChannelType["INTERNAL"] = 0] = "INTERNAL";
ChannelType[ChannelType["INVITED"] = 1] = "INVITED";
ChannelType[ChannelType["JOINING"] = 2] = "JOINING";
})(ChannelType || (ChannelType = {}));
export const MAXIMUM_MISSED_HEARTBEAT = 3;
/**
* Wrapper class for `RTCDataChannel` and `WebSocket`.
Expand All @@ -15,13 +9,12 @@ export class Channel {
/**
* Creates a channel from existing `RTCDataChannel` or `WebSocket`.
*/
constructor(wc, wsOrDc, type, id = 1, rtcPeerConnection) {
log.channel(`New Channel ${ChannelType[type]}: Me: ${wc.myId} with ${id}`);
constructor(wc, wsOrDc, type, id, pc) {
log.channel(`New Channel ${type}: Me: ${wc.myId} with ${id}`);
this.wc = wc;
this.wsOrDc = wsOrDc;
this.type = type;
this.id = id;
this.rtcPeerConnection = rtcPeerConnection;
this.pc = pc;
this.missedHeartbeat = 0;
this.heartbeatMsg = new Uint8Array(0);
this.resolveInit = () => { };
Expand All @@ -30,33 +23,48 @@ export class Channel {
wsOrDc.binaryType = 'arraybuffer';
this.send = this.sendInBrowser;
}
else if (!this.rtcPeerConnection) {
else if (!this.pc) {
this.send = this.sendInNodeOverWebSocket;
}
else {
wsOrDc.binaryType = 'arraybuffer';
this.send = this.sendInNodeOverDataChannel;
}
if (type === ChannelType.INTERNAL) {
if (type === Channel.WITH_INTERNAL) {
this.id = id;
this.heartbeatMsg = this.createHeartbeatMsg();
this.init = Promise.resolve();
this.initHandlers();
}
else {
if (type === ChannelType.INVITED) {
this.id = MIN_ID;
if (type === Channel.WITH_JOINING) {
this.sendInitPing();
}
this.init = new Promise((resolve, reject) => (this.resolveInit = () => {
this.heartbeatMsg = this.createHeartbeatMsg();
resolve();
}));
this.wsOrDc.onmessage = ({ data }) => {
this.handleInitMessage(proto.Message.decode(new Uint8Array(data)));
try {
const msg = proto.Message.decode(new Uint8Array(data));
this.handleInitMessage(msg);
}
catch (err) {
log.warn('Decode inner Channel message error: ', err);
}
};
}
}
static remoteType(type) {
return type === Channel.WITH_INTERNAL
? Channel.WITH_INTERNAL
: type === Channel.WITH_JOINING
? Channel.WITH_MEMBER
: Channel.WITH_JOINING;
}
get url() {
if (!this.rtcPeerConnection) {
if (!this.pc) {
return this.wsOrDc.url;
}
return '';
Expand All @@ -68,8 +76,9 @@ export class Channel {
this.wsOrDc.onmessage = undefined;
this.wsOrDc.onclose = undefined;
this.wsOrDc.onerror = undefined;
if (this.rtcPeerConnection) {
this.rtcPeerConnection.close();
if (this.pc) {
this.pc.oniceconnectionstatechange = () => { };
this.pc.close();
}
else {
this.wsOrDc.close(1000);
Expand Down Expand Up @@ -146,33 +155,49 @@ export class Channel {
initHandlers() {
// Configure handlers
this.wsOrDc.onmessage = ({ data }) => {
const msg = Message.decode(new Uint8Array(data));
// 0: broadcast message
if (msg.recipientId === 0 || msg.recipientId === this.wc.myId) {
// User Message
if (msg.serviceId === UserMessage.SERVICE_ID) {
const userData = this.wc.userMsg.decodeUserMessage(msg.content, msg.senderId);
if (userData) {
this.wc.onMessage(msg.senderId, userData);
try {
const msg = Message.decode(new Uint8Array(data));
// 0: broadcast message or a message to me
if (msg.recipientId === 0 || msg.recipientId === this.wc.myId) {
// User Message
if (msg.serviceId === UserMessage.SERVICE_ID) {
const userData = this.wc.userMsg.decodeUserMessage(msg.content, msg.senderId);
if (userData) {
this.wc.onMessage(msg.senderId, userData);
}
// Heartbeat message
}
else if (msg.serviceId === 0) {
this.missedHeartbeat = 0;
// Service Message
}
else {
this.wc.streamSubject.next(Object.assign({ channel: this }, msg));
}
// Heartbeat message
}
else if (msg.serviceId === 0) {
this.missedHeartbeat = 0;
// Service Message
}
else {
this.wc.streamSubject.next(Object.assign({ channel: this }, msg));
if (msg.recipientId !== this.wc.myId) {
this.wc.topology.forward(msg);
}
}
if (msg.recipientId !== this.wc.myId) {
this.wc.topology.forward(msg);
catch (err) {
log.warn('Decode general Channel message error: ', err);
}
};
this.wsOrDc.onclose = (evt) => {
log.channel(`Connection with ${this.id} has closed`, evt);
if (this.pc) {
this.pc.oniceconnectionstatechange = () => { };
}
this.wc.topology.onChannelClose(this);
};
if (this.pc) {
this.pc.oniceconnectionstatechange = () => {
if (this.pc && this.pc.iceConnectionState === 'failed') {
this.close();
this.wc.topology.onChannelClose(this);
}
};
}
this.wsOrDc.onerror = (evt) => log.channel('Channel error: ', evt);
}
createHeartbeatMsg() {
Expand All @@ -191,3 +216,6 @@ export class Channel {
})).finish());
}
}
Channel.WITH_INTERNAL = 0;
Channel.WITH_JOINING = 1;
Channel.WITH_MEMBER = 2;
Loading

0 comments on commit ff65247

Please sign in to comment.