Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[#2602] [JSDoc] Add missing documentation for botframework-streaming #2826

Merged
4 changes: 2 additions & 2 deletions .eslintrc.json
Original file line number Diff line number Diff line change
Expand Up @@ -260,7 +260,7 @@
"files": ["libraries/botframework-streaming/src/*.ts", "libraries/botframework-streaming/src/**/*.ts"],
"plugins": ["jsdoc"],
"rules": {
"jsdoc/require-jsdoc": ["warn", {
"jsdoc/require-jsdoc": ["error", {
"require": {
"FunctionDeclaration": true,
"MethodDefinition": true,
Expand Down Expand Up @@ -299,4 +299,4 @@
}],
"@typescript-eslint/no-use-before-define": ["error", { "functions": false, "classes": true }]
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,11 @@ export class PayloadAssembler {
private readonly _byteOrderMark = 0xFEFF;
private readonly _utf: string = 'utf8';

/**
* Initializes a new instance of the `PayloadAssembler` class.
* @param streamManager The `StreamManager` managing the stream being assembled.
* @param params Parameters for a streaming assembler.
*/
public constructor(streamManager: StreamManager, params: IAssemblerParams) {
if(params.header){
this.id = params.header.id;
Expand All @@ -46,6 +51,10 @@ export class PayloadAssembler {
this._onCompleted = params.onCompleted;
}

/**
* Retrieves the assembler's payload as a stream.
* @returns A `SubscribableStream` of the assembler's payload.
*/
public getPayloadStream(): SubscribableStream {
if (!this.stream) {
this.stream = this.createPayloadStream();
Expand All @@ -54,6 +63,12 @@ export class PayloadAssembler {
return this.stream;
}

/**
* The action the assembler executes when new bytes are received on the incoming stream.
* @param header The stream's Header.
* @param stream The incoming stream being assembled.
* @param contentLength The length of the stream, if finite.
*/
public onReceive(header: IHeader, stream: SubscribableStream, contentLength: number): void {
this.end = header.end;

Expand All @@ -66,22 +81,38 @@ export class PayloadAssembler {
}
}

/**
* Closes the assembler.
*/
public close(): void {
this._streamManager.closeStream(this.id);
}

/**
* Creates a new `SubscribableStream` instance.
* @returns The new stream ready for consumption.
*/
private createPayloadStream(): SubscribableStream {
return new SubscribableStream();
}

/**
* @private
*/
private payloadFromJson<T>(json: string): T {
return JSON.parse((json.charCodeAt(0) === this._byteOrderMark) ? json.slice(1) : json) as T;
}

/**
* @private
*/
private stripBOM(input: string): string {
return (input.charCodeAt(0) === this._byteOrderMark) ? input.slice(1) : input;
}

/**
* @private
*/
private async process(stream: SubscribableStream): Promise<void> {
let streamData: Buffer = stream.read(stream.length) as Buffer;
if (!streamData) {
Expand All @@ -97,6 +128,9 @@ export class PayloadAssembler {
}
}

/**
* @private
*/
private async processResponse(streamDataAsString: string): Promise<void> {

let responsePayload: IResponsePayload = this.payloadFromJson(this.stripBOM(streamDataAsString));
Expand All @@ -105,6 +139,9 @@ export class PayloadAssembler {
await this.processStreams(responsePayload, receiveResponse);
}

/**
* @private
*/
private async processRequest(streamDataAsString: string): Promise<void> {

let requestPayload: IRequestPayload = this.payloadFromJson(streamDataAsString);
Expand All @@ -113,6 +150,9 @@ export class PayloadAssembler {
await this.processStreams(requestPayload, receiveRequest);
}

/**
* @private
*/
private async processStreams(responsePayload: any, receiveResponse: any) {
if (responsePayload.streams) {
responsePayload.streams.forEach((responseStream): void => {
Expand Down
31 changes: 31 additions & 0 deletions libraries/botframework-streaming/src/contentStream.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,11 +9,19 @@ import { SubscribableStream } from './subscribableStream';
import { PayloadAssembler } from './assemblers';
import { INodeBuffer } from './interfaces/INodeBuffer';

/**
* A stream of fixed or infinite length containing content to be decoded.
*/
export class ContentStream {
public id: string;
private readonly assembler: PayloadAssembler;
private stream: SubscribableStream;

/**
* Initializes a new instance of the `ContentStream` class.
* @param id The ID assigned to this instance.
* @param assembler The `PayloadAssembler` assigned to this instance.
*/
public constructor(id: string, assembler: PayloadAssembler) {
if (!assembler) {
throw Error('Null Argument Exception');
Expand All @@ -22,14 +30,23 @@ export class ContentStream {
this.assembler = assembler;
}

/**
* Gets the name of the type of the object contained within this `ContentStream`.
*/
public get contentType(): string {
return this.assembler.payloadType;
}

/**
* Gets the length of this `ContentStream`.
*/
public get length(): number {
return this.assembler.contentLength;
}

/**
* Gets the data contained within this `ContentStream`.
*/
public getStream(): SubscribableStream {
if (!this.stream) {
this.stream = this.assembler.getPayloadStream();
Expand All @@ -38,15 +55,26 @@ export class ContentStream {
return this.stream;
}

/**
* Closes the assembler.
*/
public cancel(): void {
this.assembler.close();
}

/**
* Gets the `SubscribableStream` content as a string.
* @returns A string Promise with `SubscribableStream` content.
*/
public async readAsString(): Promise<string> {
const { bufferArray } = await this.readAll();
return (bufferArray || []).map(result => result.toString('utf8')).join('');
}

/**
* Gets the `SubscribableStream` content as a typed JSON object.
* @returns A typed object Promise with `SubscribableStream` content.
*/
public async readAsJson<T>(): Promise<T> {
let stringToParse = await this.readAsString();
try {
Expand All @@ -56,6 +84,9 @@ export class ContentStream {
}
}

/**
* @private
*/
private async readAll(): Promise<Record<string, any>> {
// do a read-all
let allData: INodeBuffer[] = [];
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,17 +9,29 @@ import { IHeader } from '../interfaces/IHeader';
import { PayloadTypes } from '../payloads/payloadTypes';
import { PayloadSender } from '../payloadTransport/payloadSender';

/**
* Streaming cancel disassembler.
*/
export class CancelDisassembler {
private readonly sender: PayloadSender;
private readonly id: string;
private readonly payloadType: PayloadTypes;

/**
* Initializes a new instance of the `CancelDisassembler` class.
* @param sender The `PayloadSender` that this Cancel request will be sent by.
* @param id The ID of the Stream to cancel.
* @param payloadType The type of the Stream that is being cancelled.
*/
public constructor(sender: PayloadSender, id: string, payloadType: PayloadTypes) {
this.sender = sender;
this.id = id;
this.payloadType = payloadType;
}

/**
* Initiates the process of disassembling the request and signals the `PayloadSender` to begin sending.
*/
public disassemble(): void {
const header: IHeader = {payloadType: this.payloadType, payloadLength: 0, id: this.id, end: true};
this.sender.sendPayload(header);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,11 +19,20 @@ export class HttpContentStreamDisassembler extends PayloadDisassembler {
public readonly contentStream: HttpContentStream;
public payloadType: PayloadTypes = PayloadTypes.stream;

/**
* Initializes a new instance of the `HttpContentStreamDisassembler` class.
* @param sender The `PayloadSender` to send the disassembled data to.
* @param contentStream The `HttpContentStream` to be disassembled.
*/
public constructor(sender: PayloadSender, contentStream: HttpContentStream) {
super(sender, contentStream.id);
this.contentStream = contentStream;
}

/**
* Gets the stream this disassembler is operating on.
* @returns An `IStreamWrapper` with a Subscribable Strea.
*/
public async getStream(): Promise<IStreamWrapper> {
let stream: SubscribableStream = this.contentStream.content.getStream();

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,11 +21,20 @@ export abstract class PayloadDisassembler {
private streamLength?: number;
private readonly id: string;

/**
* Initializes a new instance of the `PayloadDisassembler` class.
* @param sender The `PayloadSender` used to send the disassembled payload chunks.
* @param id The ID of this disassembler.
*/
public constructor(sender: PayloadSender, id: string) {
this.sender = sender;
this.id = id;
}

/**
* Serializes the item into the `IStreamWrapper` that exposes the stream and length of the result.
* @param item The item to be serialized.
*/
protected static serialize<T>(item: T): IStreamWrapper {
let stream: SubscribableStream = new SubscribableStream();

Expand All @@ -35,8 +44,15 @@ export abstract class PayloadDisassembler {
return {stream, streamLength: stream.length};
}

/**
* Gets the stream this disassembler is operating on.
* @returns An `IStreamWrapper` with a Subscribable Stream.
*/
public abstract async getStream(): Promise<IStreamWrapper>;

/**
* Begins the process of disassembling a payload and sending the resulting chunks to the `PayloadSender` to dispatch over the transport.
*/
public async disassemble(): Promise<void> {
let { stream, streamLength }: IStreamWrapper = await this.getStream();

Expand All @@ -46,6 +62,9 @@ export abstract class PayloadDisassembler {
return this.send();
}

/**
* Begins the process of disassembling a payload and signals the `PayloadSender`.
*/
private async send(): Promise<void> {
let header: IHeader = {payloadType: this.payloadType, payloadLength: this.streamLength, id: this.id, end: true};
this.sender.sendPayload(header, this.stream);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,11 +19,21 @@ export class RequestDisassembler extends PayloadDisassembler {
public request: StreamingRequest;
public payloadType: PayloadTypes = PayloadTypes.request;

/**
* Initializes a new instance of the `RequestDisassembler` class.
* @param sender The `PayloadSender` to send the disassembled data to.
* @param id The ID of this disassembler.
* @param request The request to be disassembled.
*/
public constructor(sender: PayloadSender, id: string, request?: StreamingRequest) {
super(sender, id);
this.request = request;
}

/**
* Gets the stream this disassembler is operating on.
* @returns An `IStreamWrapper` with a Subscribable Stream.
*/
public async getStream(): Promise<IStreamWrapper> {
let payload: IRequestPayload = {verb: this.request.verb, path: this.request.path, streams: []};
if (this.request.streams) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,11 +19,21 @@ export class ResponseDisassembler extends PayloadDisassembler {
public readonly response: StreamingResponse;
public readonly payloadType: PayloadTypes = PayloadTypes.response;

/**
* Initializes a new instance of the `ResponseDisassembler` class.
* @param sender The `PayloadSender` to send the disassembled data to.
* @param id The ID of this disassembler.
* @param response The response to be disassembled.
*/
public constructor(sender: PayloadSender, id: string, response: StreamingResponse) {
super(sender, id);
this.response = response;
}

/**
* Gets the stream this disassembler is operating on.
* @returns An `IStreamWrapper` with a Subscribable Stream.
*/
public async getStream(): Promise<IStreamWrapper> {
let payload: IResponsePayload = {statusCode: this.response.statusCode, streams: []};
if (this.response.streams) {
Expand Down
19 changes: 19 additions & 0 deletions libraries/botframework-streaming/src/httpContentStream.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,27 +9,46 @@ import { SubscribableStream } from './subscribableStream';
import { generateGuid } from './utilities/protocol-base';
import { IHttpContentHeaders } from './interfaces/IHttpContentHeaders';

/**
* An attachment contained within a StreamingRequest's stream collection,
* which itself contains any form of media item.
*/
export class HttpContentStream {
public readonly id: string;
public readonly content: HttpContent;
public description: { id: string; type: string; length: number; };

/**
* Initializes a new instance of the `HttpContentStream` class.
* @param content The content to assign to the `HttpContentStream`.
*/
public constructor(content: HttpContent) {
this.id = generateGuid();
this.content = content;
this.description = {id: this.id, type: (this.content.headers) ? this.content.headers.type : 'unknown', length: (this.content.headers) ? this.content.headers.contentLength : 0};
}
}

/**
* The HttpContent class that contains a SubscribableStream.
*/
export class HttpContent {
public headers: IHttpContentHeaders;
private readonly stream: SubscribableStream;

/**
* Initializes a new instance of the `HttpContent` class.
* @param headers The Streaming Http content header definition.
* @param stream The stream of buffered data.
*/
public constructor(headers: IHttpContentHeaders, stream: SubscribableStream) {
this.headers = headers;
this.stream = stream;
}

/**
* Gets the data contained within this `HttpContent`.
*/
public getStream(): SubscribableStream {
return this.stream;
}
Expand Down
Loading