Allow access to msgpack configuration options (#20438)

This commit is contained in:
Helgevold Consulting, LLC 2020-04-14 00:58:03 -04:00 committed by GitHub
parent bf571309e0
commit 70daed535a
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 78 additions and 8 deletions

View File

@ -4,6 +4,8 @@
import { Buffer } from "buffer";
import * as msgpack5 from "msgpack5";
import { MessagePackOptions } from "./MessagePackOptions";
import {
CancelInvocationMessage, CompletionMessage, HubMessage, IHubProtocol, ILogger, InvocationMessage,
LogLevel, MessageHeaders, MessageType, NullLogger, StreamInvocationMessage, StreamItemMessage, TransferFormat,
@ -32,6 +34,21 @@ export class MessagePackHubProtocol implements IHubProtocol {
private readonly voidResult = 2;
private readonly nonVoidResult = 3;
private readonly messagePackOptions?: any;
/**
*
* @param messagePackOptions MessagePack options passed to msgpack5
*/
constructor(messagePackOptions?: MessagePackOptions) {
if (messagePackOptions) {
this.messagePackOptions = {
...messagePackOptions,
compatibilityMode: false,
};
}
}
/** Creates an array of HubMessage objects from the specified serialized representation.
*
* @param {ArrayBuffer | Buffer} input An ArrayBuffer or Buffer containing the serialized representation.
@ -90,7 +107,7 @@ export class MessagePackHubProtocol implements IHubProtocol {
throw new Error("Invalid payload.");
}
const msgpack = msgpack5();
const msgpack = msgpack5(this.messagePackOptions);
const properties = msgpack.decode(Buffer.from(input));
if (properties.length === 0 || !(properties instanceof Array)) {
throw new Error("Invalid payload.");
@ -220,35 +237,35 @@ export class MessagePackHubProtocol implements IHubProtocol {
}
private writeInvocation(invocationMessage: InvocationMessage): ArrayBuffer {
const msgpack = msgpack5();
const msgpack = msgpack5(this.messagePackOptions);
let payload: any;
if (invocationMessage.streamIds) {
payload = msgpack.encode([MessageType.Invocation, invocationMessage.headers || {}, invocationMessage.invocationId || null,
invocationMessage.target, invocationMessage.arguments, invocationMessage.streamIds]);
} else {
payload = msgpack.encode([MessageType.Invocation, invocationMessage.headers || {}, invocationMessage.invocationId || null,
invocationMessage.target, invocationMessage.arguments]);
invocationMessage.target, invocationMessage.arguments]);
}
return BinaryMessageFormat.write(payload.slice());
}
private writeStreamInvocation(streamInvocationMessage: StreamInvocationMessage): ArrayBuffer {
const msgpack = msgpack5();
const msgpack = msgpack5(this.messagePackOptions);
let payload: any;
if (streamInvocationMessage.streamIds) {
payload = msgpack.encode([MessageType.StreamInvocation, streamInvocationMessage.headers || {}, streamInvocationMessage.invocationId,
streamInvocationMessage.target, streamInvocationMessage.arguments, streamInvocationMessage.streamIds]);
} else {
payload = msgpack.encode([MessageType.StreamInvocation, streamInvocationMessage.headers || {}, streamInvocationMessage.invocationId,
streamInvocationMessage.target, streamInvocationMessage.arguments]);
streamInvocationMessage.target, streamInvocationMessage.arguments]);
}
return BinaryMessageFormat.write(payload.slice());
}
private writeStreamItem(streamItemMessage: StreamItemMessage): ArrayBuffer {
const msgpack = msgpack5();
const msgpack = msgpack5(this.messagePackOptions);
const payload = msgpack.encode([MessageType.StreamItem, streamItemMessage.headers || {}, streamItemMessage.invocationId,
streamItemMessage.item]);
@ -256,7 +273,7 @@ export class MessagePackHubProtocol implements IHubProtocol {
}
private writeCompletion(completionMessage: CompletionMessage): ArrayBuffer {
const msgpack = msgpack5();
const msgpack = msgpack5(this.messagePackOptions);
const resultKind = completionMessage.error ? this.errorResult : completionMessage.result ? this.nonVoidResult : this.voidResult;
let payload: any;
@ -276,7 +293,7 @@ export class MessagePackHubProtocol implements IHubProtocol {
}
private writeCancelInvocation(cancelInvocationMessage: CancelInvocationMessage): ArrayBuffer {
const msgpack = msgpack5();
const msgpack = msgpack5(this.messagePackOptions);
const payload = msgpack.encode([MessageType.CancelInvocation, cancelInvocationMessage.headers || {}, cancelInvocationMessage.invocationId]);
return BinaryMessageFormat.write(payload.slice());

View File

@ -0,0 +1,23 @@
// Copyright (c) .NET Foundation. All rights reserved.
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
/**
* MessagePack Options per:
* {@link https://github.com/mcollina/msgpack5#msgpackoptionsobj Msgpack5 Options Object}
*/
export interface MessagePackOptions {
/**
* @name sortKeys Force a determinate key order
*/
sortKeys?: boolean;
/**
* @name disableTimestampEncoding Disable the encoding of Dates into the timestamp extension type
*/
disableTimestampEncoding?: boolean;
/**
* @name forceFloat64 Force floats to be encoded as 64-bit floats
*/
forceFloat64?: boolean;
}

View File

@ -6,3 +6,5 @@
export const VERSION = "0.0.0-DEV_BUILD";
export { MessagePackHubProtocol } from "./MessagePackHubProtocol";
export { MessagePackOptions } from "./MessagePackOptions";

View File

@ -217,4 +217,32 @@ describe("MessagePackHubProtocol", () => {
const buffer = new MessagePackHubProtocol().writeMessage({ type: MessageType.CancelInvocation, invocationId: "abc" });
expect(new Uint8Array(buffer)).toEqual(payload);
});
it("will preserve double precision if forceFloat64 is set", () => {
const invocation = {
arguments: [Number(0.005)],
headers: {},
invocationId: "123",
streamIds: [],
target: "myMethod",
type: MessageType.Invocation,
} as InvocationMessage;
const protocol = new MessagePackHubProtocol({ forceFloat64: true });
const parsedMessages = protocol.parseMessages(protocol.writeMessage(invocation), NullLogger.instance);
expect(parsedMessages[0]).toEqual({
arguments: [0.005],
headers: {},
invocationId: "123",
streamIds: [],
target: "myMethod",
type: 1,
});
});
it("will force compatibilityMode to false", () => {
const options: any = { compatibilityMode: true };
const protocol: any = new MessagePackHubProtocol(options);
expect(protocol.messagePackOptions.compatibilityMode).toBe(false);
});
});