yamux-js
Advanced tools
Comparing version 0.0.1 to 0.0.2
import { Client } from './client'; | ||
import { Config } from './mux'; | ||
import { Server } from './server'; | ||
export { Client, Server }; | ||
export { Config, Client, Server }; |
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,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; |
@@ -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) { |
@@ -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; |
{ | ||
"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" |
# Yamux-js | ||
[![npm version](https://badge.fury.io/js/yamux-js.svg)](https://www.npmjs.com/package/yamux-js) | ||
[![Build status](https://img.shields.io/github/workflow/status/th-ch/yamux-js/Node.js%20CI)](https://github.com/th-ch/yamux-js) | ||
@@ -26,2 +27,16 @@ [![GitHub license](https://img.shields.io/github/license/th-ch/yamux-js.svg)](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 @@ |
126
32591
19
681