+2
-1
| import { Client } from './client'; | ||
| import { Config } from './mux'; | ||
| import { Server } from './server'; | ||
| export { Client, Server }; | ||
| export { Config, Client, Server }; |
+10
-3
| export interface Config { | ||
| acceptBacklog?: number; | ||
| enableKeepAlive?: boolean; | ||
| keepAliveInterval?: number; | ||
| connectionWriteTimeout?: number; | ||
| maxStreamWindowSize?: number; | ||
| logger?: typeof console.log; | ||
| } | ||
| export declare const defaultConfig: { | ||
| acceptBacklog: number; | ||
@@ -7,4 +15,3 @@ enableKeepAlive: boolean; | ||
| maxStreamWindowSize: number; | ||
| logger: typeof console.log; | ||
| } | ||
| export declare const defaultConfig: Config; | ||
| logger: (message?: any, ...optionalParams: any[]) => void; | ||
| }; |
+5
-5
@@ -5,3 +5,3 @@ /// <reference types="node" /> | ||
| import { Header } from './header'; | ||
| import { Config } from './mux'; | ||
| import { Config, defaultConfig } from './mux'; | ||
| export declare class Session extends Transform { | ||
@@ -11,10 +11,10 @@ private localGoaway; | ||
| private nextStreamID; | ||
| private streams; | ||
| private shutdown; | ||
| config: typeof defaultConfig; | ||
| private pings; | ||
| private pingID; | ||
| private pingTimer?; | ||
| private streams; | ||
| private shutdown; | ||
| protected onStream?: (duplex: Duplex) => void; | ||
| private currentHeader?; | ||
| config: Config; | ||
| constructor(client: boolean, config?: Config, onStream?: (duplex: Duplex) => void); | ||
@@ -28,3 +28,3 @@ _transform(chunk: any, encoding: BufferEncoding, cb: TransformCallback): void; | ||
| private goAway; | ||
| open(): Duplex | undefined; | ||
| open(): Duplex; | ||
| private handlePing; | ||
@@ -31,0 +31,0 @@ private ping; |
+15
-46
@@ -10,3 +10,3 @@ "use strict"; | ||
| class Session extends stream_1.Transform { | ||
| constructor(client, config = mux_1.defaultConfig, onStream) { | ||
| constructor(client, config, onStream) { | ||
| super(); | ||
@@ -17,2 +17,5 @@ // localGoAway indicates that we should stop accepting futher connections | ||
| this.remoteGoAway = false; | ||
| // pings is used to track inflight pings | ||
| this.pings = new Map(); | ||
| this.pingID = 0; | ||
| // streams maps a stream id to a stream | ||
@@ -22,5 +25,2 @@ this.streams = new Map(); | ||
| this.shutdown = false; | ||
| // pings is used to track inflight pings | ||
| this.pings = new Map(); | ||
| this.pingID = 0; | ||
| if (client) { | ||
@@ -33,3 +33,3 @@ this.nextStreamID = 1; | ||
| this.onStream = onStream; | ||
| this.config = config; | ||
| this.config = Object.assign(Object.assign({}, mux_1.defaultConfig), config); | ||
| if (this.config.enableKeepAlive) { | ||
@@ -40,7 +40,5 @@ this.keepalive(); | ||
| _transform(chunk, encoding, cb) { | ||
| this.config.logger('session: received', chunk); // .toString("ascii")); | ||
| let packet = Buffer.alloc(chunk.length, chunk); | ||
| if (!this.currentHeader) { | ||
| if (packet.length >= header_1.Header.LENGTH) { | ||
| this.config.logger('H ', packet.toString('hex')); | ||
| this.currentHeader = header_1.Header.parse(packet); | ||
@@ -51,3 +49,2 @@ packet = packet.slice(header_1.Header.LENGTH); | ||
| // header info is incomplete wait for more data | ||
| console.log('header info is incomplete wait for more data'); | ||
| return cb(); | ||
@@ -57,3 +54,2 @@ } | ||
| let expectedLength = this.currentHeader.length; | ||
| this.config.logger('currentHeader', this.currentHeader, this.currentHeader.encode(), 'packet', packet, 'len', packet.length, 'is server', this.nextStreamID % 2 == 0); | ||
| // Verify the version | ||
@@ -71,16 +67,6 @@ if (this.currentHeader.version !== constants_1.VERSION) { | ||
| var fullPacket = packet.slice(0, expectedLength); | ||
| // this.push(currentHeader, fullPacket); | ||
| // this.config.logger("packet", fullPacket.toString()); | ||
| // assert(expectedLength === fullPacket.length); | ||
| // assert(packet.length === rest.length + fullPacket.length); | ||
| this.handleStreamMessage(this.currentHeader, fullPacket, encoding); | ||
| // expectedLength = 0; | ||
| // packet = Buffer.alloc(0); | ||
| this.currentHeader = undefined; | ||
| if (rest.length > 0) { | ||
| // logger.debug("REST: %d", rest.length); | ||
| // this.config.logger("remaining", rest.toString()); | ||
| // return cb(undefined, rest); | ||
| return this._transform(rest, encoding, cb); | ||
| // return plexer._transform(rest, encoding, cb); | ||
| } | ||
@@ -93,7 +79,3 @@ } | ||
| if (packet.length > 0) { | ||
| // logger.debug("REST: %d", rest.length); | ||
| // this.config.logger("remaining", rest.toString()); | ||
| // return cb(undefined, rest); | ||
| return this._transform(packet, encoding, cb); | ||
| // return plexer._transform(rest, encoding, cb); | ||
| } | ||
@@ -133,9 +115,3 @@ break; | ||
| } | ||
| this.config.logger('Pushing', fullPacket.toString(), 'to stream', stream.ID()); | ||
| stream.push(fullPacket, encoding); | ||
| // this.push(fullPacket); | ||
| // old | ||
| // handle accorrding to header | ||
| // get or create stream | ||
| // push packet to stream | ||
| } | ||
@@ -145,3 +121,2 @@ closeStream(streamID) { | ||
| } | ||
| ///////// | ||
| isClosed() { | ||
@@ -166,6 +141,7 @@ return this.shutdown; | ||
| }); | ||
| error ? this.emit('error', error) : console.log('noope'); // this.destroy(); | ||
| if (error) { | ||
| this.emit('error', error); | ||
| } | ||
| this.end(); | ||
| } | ||
| // tood private/public methods | ||
| // incomingStream is used to create a new incoming stream | ||
@@ -178,3 +154,2 @@ incomingStream(streamID) { | ||
| } | ||
| // console.log("stream incomoign", this.streams); | ||
| // Allocate a new stream | ||
@@ -184,3 +159,2 @@ const stream = new stream_2.Stream(this, streamID, constants_1.STREAM_STATES.SYNReceived); | ||
| if (this.streams.has(streamID)) { | ||
| console.log('dupl', streamID); | ||
| this.config.logger('[ERR] yamux: duplicate stream declared'); | ||
@@ -199,3 +173,2 @@ this.emit('error', constants_1.ERRORS.errDuplicateStream); | ||
| } | ||
| // this.config.logger("calling onstream", this.onStream); | ||
| if (this.onStream) { | ||
@@ -212,12 +185,12 @@ this.onStream(stream); | ||
| open() { | ||
| const stream = new stream_2.Stream(this, this.nextStreamID, constants_1.STREAM_STATES.Init); | ||
| this.nextStreamID += 2; | ||
| if (this.isClosed()) { | ||
| this.emit('error', constants_1.ERRORS.errSessionShutdown); | ||
| return; | ||
| return stream; | ||
| } | ||
| if (this.remoteGoAway) { | ||
| this.emit('error', constants_1.ERRORS.errRemoteGoAway); | ||
| return; | ||
| return stream; | ||
| } | ||
| const stream = new stream_2.Stream(this, this.nextStreamID, constants_1.STREAM_STATES.Init); | ||
| this.nextStreamID += 2; | ||
| this.streams.set(stream.ID(), stream); | ||
@@ -230,5 +203,3 @@ stream.sendWindowUpdate(); | ||
| if (hdr.flags === constants_1.FLAGS.SYN) { | ||
| // this.config.logger("[PING] handle ping", hdr, this.nextStreamID, "is server", this.nextStreamID%2==0); | ||
| const responseHdr = new header_1.Header(constants_1.VERSION, constants_1.TYPES.Ping, constants_1.FLAGS.ACK, 0, pingID); | ||
| // this.config.logger("sending back ping acck", responseHdr); | ||
| return this.send(responseHdr); | ||
@@ -238,3 +209,2 @@ } | ||
| const responseTimeout = this.pings.get(pingID); | ||
| // this.config.logger("[PING] handle ping akc", hdr, this.nextStreamID, "is server", this.nextStreamID % 2 == 0, !!responseTimeout, this.pings.size, pingID); | ||
| if (responseTimeout) { | ||
@@ -253,3 +223,2 @@ clearTimeout(responseTimeout); | ||
| const hdr = new header_1.Header(constants_1.VERSION, constants_1.TYPES.Ping, constants_1.FLAGS.SYN, 0, pingID); | ||
| // this.config.logger("[PING] Send ping", hdr); | ||
| // Wait for a response | ||
@@ -267,3 +236,2 @@ const responseTimeout = setTimeout(() => { | ||
| } | ||
| // public accept(): Stream { | ||
| send(header, data) { | ||
@@ -275,4 +243,5 @@ const buffers = [header.encode()]; | ||
| const toSend = Buffer.concat(buffers); | ||
| // this.config.logger("sending", toSend); | ||
| this.push(toSend); | ||
| if (!this.writableEnded) { | ||
| this.push(toSend); | ||
| } | ||
| } | ||
@@ -279,0 +248,0 @@ handleGoAway(hdr) { |
+4
-9
@@ -8,3 +8,2 @@ "use strict"; | ||
| class Stream extends stream_1.Duplex { | ||
| // private encoder: Transform | undefined; | ||
| constructor(session, id, state) { | ||
@@ -40,3 +39,2 @@ super(); | ||
| const sendHdr = new header_1.Header(constants_1.VERSION, constants_1.TYPES.Data, flags, this.id, chunk.length); | ||
| // console.log("next header", sendHdr); | ||
| const buffers = [sendHdr.encode(), chunk]; | ||
@@ -55,6 +53,2 @@ const packet = Buffer.concat(buffers); | ||
| } | ||
| // console.log("pushgin to recvbuf"); | ||
| // let packet = this.recvBuf ? this.recvBuf : Buffer.alloc(0); | ||
| // this.recvBuf = Buffer.concat([packet, chunk]); | ||
| // this.push(this.recvBuf); | ||
| break; | ||
@@ -94,6 +88,7 @@ } | ||
| this.controlHdr = new header_1.Header(constants_1.VERSION, constants_1.TYPES.WindowUpdate, flags, this.id, 0); | ||
| this.session.send(this.controlHdr); | ||
| if (!this.session.isClosed()) { | ||
| this.session.send(this.controlHdr); | ||
| } | ||
| } | ||
| close() { | ||
| console.log('srte close', this.state); | ||
| switch (this.state) { | ||
@@ -136,3 +131,3 @@ // Opened means we need to signal a close | ||
| default: | ||
| console.log('[ERR] yamux: unexpected FIN flag in state %d', this.state); | ||
| this.session.config.logger('[ERR] yamux: unexpected FIN flag in state %d', this.state); | ||
| this.emit('error', constants_1.ERRORS.errUnexpectedFlag); | ||
@@ -139,0 +134,0 @@ return; |
+16
-7
| { | ||
| "name": "yamux-js", | ||
| "version": "0.0.1", | ||
| "main": "src/index.ts", | ||
| "version": "0.0.2", | ||
| "main": "lib/index", | ||
| "license": "MIT", | ||
@@ -23,10 +23,19 @@ "repository": { | ||
| "clean": "rm -rf lib", | ||
| "format": "yarn prettier --write .", | ||
| "format:check": "yarn prettier .", | ||
| "format": "yarn prettier --write src", | ||
| "format:check": "yarn prettier --check src", | ||
| "prepare": "yarn format:check && yarn build", | ||
| "test": "mocha --require ts-node/register --color --recursive --extension ts", | ||
| "test:watch": "yarn test --watch" | ||
| }, | ||
| "publishConfig": { | ||
| "main": "lib/index" | ||
| }, | ||
| "keywords": [ | ||
| "yamux", | ||
| "hashicorp", | ||
| "multiplex", | ||
| "multiplexer", | ||
| "multiplexing", | ||
| "streams", | ||
| "typescript", | ||
| "javascript", | ||
| "interleave" | ||
| ], | ||
| "files": [ | ||
@@ -33,0 +42,0 @@ "lib" |
+15
-0
| # Yamux-js | ||
| [](https://www.npmjs.com/package/yamux-js) | ||
| [](https://github.com/th-ch/yamux-js) | ||
@@ -26,2 +27,16 @@ [](https://github.com/th-ch/yamux-js/blob/master/LICENSE) | ||
| ## Installation | ||
| Install Yamux-js using [`yarn`](https://yarnpkg.com/en/package/jest): | ||
| ```bash | ||
| yarn add yamux-js | ||
| ``` | ||
| Or [`npm`](https://www.npmjs.com/package/yamux-js): | ||
| ```bash | ||
| npm install --save yamux-js | ||
| ``` | ||
| ## Usage | ||
@@ -28,0 +43,0 @@ |
| import {Client} from './client'; | ||
| import {Config} from './mux'; | ||
| import {Server} from './server'; | ||
| export {Config, Client, Server}; |
126
13.51%32591
-5.34%19
-5%681
-4.49%