@eyhn/msgpack-stream
Version:
MessagePack for ECMA-262/JavaScript/TypeScript
1,461 lines (1,424 loc) • 106 kB
JavaScript
(function webpackUniversalModuleDefinition(root, factory) {
if(typeof exports === 'object' && typeof module === 'object')
module.exports = factory();
else if(typeof define === 'function' && define.amd)
define([], factory);
else if(typeof exports === 'object')
exports["MessagePack"] = factory();
else
root["MessagePack"] = factory();
})(this, () => {
return /******/ (() => { // webpackBootstrap
/******/ "use strict";
/******/ // The require scope
/******/ var __webpack_require__ = {};
/******/
/************************************************************************/
/******/ /* webpack/runtime/define property getters */
/******/ (() => {
/******/ // define getter functions for harmony exports
/******/ __webpack_require__.d = (exports, definition) => {
/******/ for(var key in definition) {
/******/ if(__webpack_require__.o(definition, key) && !__webpack_require__.o(exports, key)) {
/******/ Object.defineProperty(exports, key, { enumerable: true, get: definition[key] });
/******/ }
/******/ }
/******/ };
/******/ })();
/******/
/******/ /* webpack/runtime/hasOwnProperty shorthand */
/******/ (() => {
/******/ __webpack_require__.o = (obj, prop) => (Object.prototype.hasOwnProperty.call(obj, prop))
/******/ })();
/******/
/******/ /* webpack/runtime/make namespace object */
/******/ (() => {
/******/ // define __esModule on exports
/******/ __webpack_require__.r = (exports) => {
/******/ if(typeof Symbol !== 'undefined' && Symbol.toStringTag) {
/******/ Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });
/******/ }
/******/ Object.defineProperty(exports, '__esModule', { value: true });
/******/ };
/******/ })();
/******/
/************************************************************************/
var __webpack_exports__ = {};
// ESM COMPAT FLAG
__webpack_require__.r(__webpack_exports__);
// EXPORTS
__webpack_require__.d(__webpack_exports__, {
"DataViewIndexOutOfBoundsError": () => (/* reexport */ DataViewIndexOutOfBoundsError),
"DecodeError": () => (/* reexport */ DecodeError),
"Decoder": () => (/* reexport */ Decoder),
"EXT_TIMESTAMP": () => (/* reexport */ EXT_TIMESTAMP),
"Encoder": () => (/* reexport */ Encoder),
"ExtData": () => (/* reexport */ ExtData),
"ExtensionCodec": () => (/* reexport */ ExtensionCodec),
"decode": () => (/* reexport */ decode),
"decodeArrayStream": () => (/* reexport */ decodeArrayStream),
"decodeAsync": () => (/* reexport */ decodeAsync),
"decodeMulti": () => (/* reexport */ decodeMulti),
"decodeMultiStream": () => (/* reexport */ decodeMultiStream),
"decodeStream": () => (/* reexport */ decodeStream),
"decodeTimestampExtension": () => (/* reexport */ decodeTimestampExtension),
"decodeTimestampToTimeSpec": () => (/* reexport */ decodeTimestampToTimeSpec),
"encode": () => (/* reexport */ encode),
"encodeDateToTimeSpec": () => (/* reexport */ encodeDateToTimeSpec),
"encodeStream": () => (/* reexport */ encodeStream),
"encodeTimeSpecToTimestamp": () => (/* reexport */ encodeTimeSpecToTimestamp),
"encodeTimestampExtension": () => (/* reexport */ encodeTimestampExtension)
});
;// CONCATENATED MODULE: ./src/utils/int.ts
// Integer Utility
const UINT32_MAX = 4294967295;
// DataView extension to handle int64 / uint64,
// where the actual range is 53-bits integer (a.k.a. safe integer)
function setUint64(view, offset, value) {
const high = value / 4294967296;
const low = value; // high bits are truncated by DataView
view.setUint32(offset, high);
view.setUint32(offset + 4, low);
}
function setInt64(view, offset, value) {
const high = Math.floor(value / 4294967296);
const low = value; // high bits are truncated by DataView
view.setUint32(offset, high);
view.setUint32(offset + 4, low);
}
function getInt64(view, offset) {
const high = view.getInt32(offset);
const low = view.getUint32(offset + 4);
return high * 4294967296 + low;
}
function getUint64(view, offset) {
const high = view.getUint32(offset);
const low = view.getUint32(offset + 4);
return high * 4294967296 + low;
}
;// CONCATENATED MODULE: ./src/utils/utf8.ts
var _a, _b, _c;
/* eslint-disable @typescript-eslint/no-unnecessary-condition */
const TEXT_ENCODING_AVAILABLE = (typeof process === "undefined" || ((_a = process === null || process === void 0 ? void 0 : process.env) === null || _a === void 0 ? void 0 : _a["TEXT_ENCODING"]) !== "never") &&
typeof TextEncoder !== "undefined" &&
typeof TextDecoder !== "undefined";
function utf8Count(str) {
const strLength = str.length;
let byteLength = 0;
let pos = 0;
while (pos < strLength) {
let value = str.charCodeAt(pos++);
if ((value & 0xffffff80) === 0) {
// 1-byte
byteLength++;
continue;
}
else if ((value & 0xfffff800) === 0) {
// 2-bytes
byteLength += 2;
}
else {
// handle surrogate pair
if (value >= 0xd800 && value <= 0xdbff) {
// high surrogate
if (pos < strLength) {
const extra = str.charCodeAt(pos);
if ((extra & 0xfc00) === 0xdc00) {
++pos;
value = ((value & 0x3ff) << 10) + (extra & 0x3ff) + 0x10000;
}
}
}
if ((value & 0xffff0000) === 0) {
// 3-byte
byteLength += 3;
}
else {
// 4-byte
byteLength += 4;
}
}
}
return byteLength;
}
function utf8EncodeJs(str, output, outputOffset) {
const strLength = str.length;
let offset = outputOffset;
let pos = 0;
while (pos < strLength) {
let value = str.charCodeAt(pos++);
if ((value & 0xffffff80) === 0) {
// 1-byte
output[offset++] = value;
continue;
}
else if ((value & 0xfffff800) === 0) {
// 2-bytes
output[offset++] = ((value >> 6) & 0x1f) | 0xc0;
}
else {
// handle surrogate pair
if (value >= 0xd800 && value <= 0xdbff) {
// high surrogate
if (pos < strLength) {
const extra = str.charCodeAt(pos);
if ((extra & 0xfc00) === 0xdc00) {
++pos;
value = ((value & 0x3ff) << 10) + (extra & 0x3ff) + 0x10000;
}
}
}
if ((value & 0xffff0000) === 0) {
// 3-byte
output[offset++] = ((value >> 12) & 0x0f) | 0xe0;
output[offset++] = ((value >> 6) & 0x3f) | 0x80;
}
else {
// 4-byte
output[offset++] = ((value >> 18) & 0x07) | 0xf0;
output[offset++] = ((value >> 12) & 0x3f) | 0x80;
output[offset++] = ((value >> 6) & 0x3f) | 0x80;
}
}
output[offset++] = (value & 0x3f) | 0x80;
}
}
const sharedTextEncoder = TEXT_ENCODING_AVAILABLE ? new TextEncoder() : undefined;
const TEXT_ENCODER_THRESHOLD = !TEXT_ENCODING_AVAILABLE
? UINT32_MAX
: typeof process !== "undefined" && ((_b = process === null || process === void 0 ? void 0 : process.env) === null || _b === void 0 ? void 0 : _b["TEXT_ENCODING"]) !== "force"
? 200
: 0;
function utf8EncodeTEencode(str, output, outputOffset) {
output.set(sharedTextEncoder.encode(str), outputOffset);
}
function utf8EncodeTEencodeInto(str, output, outputOffset) {
sharedTextEncoder.encodeInto(str, output.subarray(outputOffset));
}
const utf8EncodeTE = (sharedTextEncoder === null || sharedTextEncoder === void 0 ? void 0 : sharedTextEncoder.encodeInto) ? utf8EncodeTEencodeInto : utf8EncodeTEencode;
const CHUNK_SIZE = 4096;
function utf8DecodeJs(bytes, inputOffset, byteLength) {
let offset = inputOffset;
const end = offset + byteLength;
const units = [];
let result = "";
while (offset < end) {
const byte1 = bytes[offset++];
if ((byte1 & 0x80) === 0) {
// 1 byte
units.push(byte1);
}
else if ((byte1 & 0xe0) === 0xc0) {
// 2 bytes
const byte2 = bytes[offset++] & 0x3f;
units.push(((byte1 & 0x1f) << 6) | byte2);
}
else if ((byte1 & 0xf0) === 0xe0) {
// 3 bytes
const byte2 = bytes[offset++] & 0x3f;
const byte3 = bytes[offset++] & 0x3f;
units.push(((byte1 & 0x1f) << 12) | (byte2 << 6) | byte3);
}
else if ((byte1 & 0xf8) === 0xf0) {
// 4 bytes
const byte2 = bytes[offset++] & 0x3f;
const byte3 = bytes[offset++] & 0x3f;
const byte4 = bytes[offset++] & 0x3f;
let unit = ((byte1 & 0x07) << 0x12) | (byte2 << 0x0c) | (byte3 << 0x06) | byte4;
if (unit > 0xffff) {
unit -= 0x10000;
units.push(((unit >>> 10) & 0x3ff) | 0xd800);
unit = 0xdc00 | (unit & 0x3ff);
}
units.push(unit);
}
else {
units.push(byte1);
}
if (units.length >= CHUNK_SIZE) {
result += String.fromCharCode(...units);
units.length = 0;
}
}
if (units.length > 0) {
result += String.fromCharCode(...units);
}
return result;
}
const sharedTextDecoder = TEXT_ENCODING_AVAILABLE ? new TextDecoder() : null;
const TEXT_DECODER_THRESHOLD = !TEXT_ENCODING_AVAILABLE
? UINT32_MAX
: typeof process !== "undefined" && ((_c = process === null || process === void 0 ? void 0 : process.env) === null || _c === void 0 ? void 0 : _c["TEXT_DECODER"]) !== "force"
? 200
: 0;
function utf8DecodeTD(bytes, inputOffset, byteLength) {
const stringBytes = bytes.subarray(inputOffset, inputOffset + byteLength);
return sharedTextDecoder.decode(stringBytes);
}
;// CONCATENATED MODULE: ./src/ExtData.ts
/**
* ExtData is used to handle Extension Types that are not registered to ExtensionCodec.
*/
class ExtData {
constructor(type, data) {
this.type = type;
this.data = data;
}
}
;// CONCATENATED MODULE: ./src/DecodeError.ts
class DecodeError extends Error {
constructor(message) {
super(message);
// fix the prototype chain in a cross-platform way
const proto = Object.create(DecodeError.prototype);
Object.setPrototypeOf(this, proto);
Object.defineProperty(this, "name", {
configurable: true,
enumerable: false,
value: DecodeError.name,
});
}
}
;// CONCATENATED MODULE: ./src/timestamp.ts
// https://github.com/msgpack/msgpack/blob/master/spec.md#timestamp-extension-type
const EXT_TIMESTAMP = -1;
const TIMESTAMP32_MAX_SEC = 0x100000000 - 1; // 32-bit unsigned int
const TIMESTAMP64_MAX_SEC = 0x400000000 - 1; // 34-bit unsigned int
function encodeTimeSpecToTimestamp({ sec, nsec }) {
if (sec >= 0 && nsec >= 0 && sec <= TIMESTAMP64_MAX_SEC) {
// Here sec >= 0 && nsec >= 0
if (nsec === 0 && sec <= TIMESTAMP32_MAX_SEC) {
// timestamp 32 = { sec32 (unsigned) }
const rv = new Uint8Array(4);
const view = new DataView(rv.buffer);
view.setUint32(0, sec);
return rv;
}
else {
// timestamp 64 = { nsec30 (unsigned), sec34 (unsigned) }
const secHigh = sec / 0x100000000;
const secLow = sec & 0xffffffff;
const rv = new Uint8Array(8);
const view = new DataView(rv.buffer);
// nsec30 | secHigh2
view.setUint32(0, (nsec << 2) | (secHigh & 0x3));
// secLow32
view.setUint32(4, secLow);
return rv;
}
}
else {
// timestamp 96 = { nsec32 (unsigned), sec64 (signed) }
const rv = new Uint8Array(12);
const view = new DataView(rv.buffer);
view.setUint32(0, nsec);
setInt64(view, 4, sec);
return rv;
}
}
function encodeDateToTimeSpec(date) {
const msec = date.getTime();
const sec = Math.floor(msec / 1e3);
const nsec = (msec - sec * 1e3) * 1e6;
// Normalizes { sec, nsec } to ensure nsec is unsigned.
const nsecInSec = Math.floor(nsec / 1e9);
return {
sec: sec + nsecInSec,
nsec: nsec - nsecInSec * 1e9,
};
}
function encodeTimestampExtension(object) {
if (object instanceof Date) {
const timeSpec = encodeDateToTimeSpec(object);
return encodeTimeSpecToTimestamp(timeSpec);
}
else {
return null;
}
}
function decodeTimestampToTimeSpec(data) {
const view = new DataView(data.buffer, data.byteOffset, data.byteLength);
// data may be 32, 64, or 96 bits
switch (data.byteLength) {
case 4: {
// timestamp 32 = { sec32 }
const sec = view.getUint32(0);
const nsec = 0;
return { sec, nsec };
}
case 8: {
// timestamp 64 = { nsec30, sec34 }
const nsec30AndSecHigh2 = view.getUint32(0);
const secLow32 = view.getUint32(4);
const sec = (nsec30AndSecHigh2 & 0x3) * 0x100000000 + secLow32;
const nsec = nsec30AndSecHigh2 >>> 2;
return { sec, nsec };
}
case 12: {
// timestamp 96 = { nsec32 (unsigned), sec64 (signed) }
const sec = getInt64(view, 4);
const nsec = view.getUint32(0);
return { sec, nsec };
}
default:
throw new DecodeError(`Unrecognized data size for timestamp (expected 4, 8, or 12): ${data.length}`);
}
}
function decodeTimestampExtension(data) {
const timeSpec = decodeTimestampToTimeSpec(data);
return new Date(timeSpec.sec * 1e3 + timeSpec.nsec / 1e6);
}
const timestampExtension = {
type: EXT_TIMESTAMP,
encode: encodeTimestampExtension,
decode: decodeTimestampExtension,
};
;// CONCATENATED MODULE: ./src/ExtensionCodec.ts
// ExtensionCodec to handle MessagePack extensions
class ExtensionCodec {
constructor() {
// built-in extensions
this.builtInEncoders = [];
this.builtInDecoders = [];
// custom extensions
this.encoders = [];
this.decoders = [];
this.register(timestampExtension);
}
register({ type, encode, decode, }) {
if (type >= 0) {
// custom extensions
this.encoders[type] = encode;
this.decoders[type] = decode;
}
else {
// built-in extensions
const index = 1 + type;
this.builtInEncoders[index] = encode;
this.builtInDecoders[index] = decode;
}
}
tryToEncode(object, context) {
// built-in extensions
for (let i = 0; i < this.builtInEncoders.length; i++) {
const encodeExt = this.builtInEncoders[i];
if (encodeExt != null) {
const data = encodeExt(object, context);
if (data != null) {
const type = -1 - i;
return new ExtData(type, data);
}
}
}
// custom extensions
for (let i = 0; i < this.encoders.length; i++) {
const encodeExt = this.encoders[i];
if (encodeExt != null) {
const data = encodeExt(object, context);
if (data != null) {
const type = i;
return new ExtData(type, data);
}
}
}
if (object instanceof ExtData) {
// to keep ExtData as is
return object;
}
return null;
}
decode(data, type, context) {
const decodeExt = type < 0 ? this.builtInDecoders[-1 - type] : this.decoders[type];
if (decodeExt) {
return decodeExt(data, type, context);
}
else {
// decode() does not fail, returns ExtData instead.
return new ExtData(type, data);
}
}
}
ExtensionCodec.defaultCodec = new ExtensionCodec();
;// CONCATENATED MODULE: ./src/utils/typedArrays.ts
function ensureUint8Array(buffer) {
if (buffer instanceof Uint8Array) {
return buffer;
}
else if (ArrayBuffer.isView(buffer)) {
return new Uint8Array(buffer.buffer, buffer.byteOffset, buffer.byteLength);
}
else if (buffer instanceof ArrayBuffer) {
return new Uint8Array(buffer);
}
else {
// ArrayLike<number>
return Uint8Array.from(buffer);
}
}
function createDataView(buffer) {
if (buffer instanceof ArrayBuffer) {
return new DataView(buffer);
}
const bufferView = ensureUint8Array(buffer);
return new DataView(bufferView.buffer, bufferView.byteOffset, bufferView.byteLength);
}
;// CONCATENATED MODULE: ./src/Encoder.ts
const DEFAULT_MAX_DEPTH = 100;
const DEFAULT_INITIAL_BUFFER_SIZE = 2048;
class Encoder {
constructor(extensionCodec = ExtensionCodec.defaultCodec, context = undefined, maxDepth = DEFAULT_MAX_DEPTH, initialBufferSize = DEFAULT_INITIAL_BUFFER_SIZE, sortKeys = false, forceFloat32 = false, ignoreUndefined = false, forceIntegerToFloat = false) {
this.extensionCodec = extensionCodec;
this.context = context;
this.maxDepth = maxDepth;
this.initialBufferSize = initialBufferSize;
this.sortKeys = sortKeys;
this.forceFloat32 = forceFloat32;
this.ignoreUndefined = ignoreUndefined;
this.forceIntegerToFloat = forceIntegerToFloat;
this.pos = 0;
this.view = new DataView(new ArrayBuffer(this.initialBufferSize));
this.bytes = new Uint8Array(this.view.buffer);
}
reinitializeState() {
this.pos = 0;
}
/**
* This is almost equivalent to {@link Encoder#encode}, but it returns an reference of the encoder's internal buffer and thus much faster than {@link Encoder#encode}.
*
* @returns Encodes the object and returns a shared reference the encoder's internal buffer.
*/
encodeSharedRef(object) {
this.reinitializeState();
this.doEncode(object, 1);
return this.bytes.subarray(0, this.pos);
}
/**
* @returns Encodes the object and returns a copy of the encoder's internal buffer.
*/
encode(object) {
this.reinitializeState();
this.doEncode(object, 1);
return this.bytes.slice(0, this.pos);
}
doEncode(object, depth) {
if (depth > this.maxDepth) {
throw new Error(`Too deep objects in depth ${depth}`);
}
if (object == null) {
this.encodeNil();
}
else if (typeof object === "boolean") {
this.encodeBoolean(object);
}
else if (typeof object === "number") {
this.encodeNumber(object);
}
else if (typeof object === "string") {
this.encodeString(object);
}
else {
this.encodeObject(object, depth);
}
}
ensureBufferSizeToWrite(sizeToWrite) {
const requiredSize = this.pos + sizeToWrite;
if (this.view.byteLength < requiredSize) {
this.resizeBuffer(requiredSize * 2);
}
}
resizeBuffer(newSize) {
const newBuffer = new ArrayBuffer(newSize);
const newBytes = new Uint8Array(newBuffer);
const newView = new DataView(newBuffer);
newBytes.set(this.bytes);
this.view = newView;
this.bytes = newBytes;
}
encodeNil() {
this.writeU8(0xc0);
}
encodeBoolean(object) {
if (object === false) {
this.writeU8(0xc2);
}
else {
this.writeU8(0xc3);
}
}
encodeNumber(object) {
if (Number.isSafeInteger(object) && !this.forceIntegerToFloat) {
if (object >= 0) {
if (object < 0x80) {
// positive fixint
this.writeU8(object);
}
else if (object < 0x100) {
// uint 8
this.writeU8(0xcc);
this.writeU8(object);
}
else if (object < 0x10000) {
// uint 16
this.writeU8(0xcd);
this.writeU16(object);
}
else if (object < 0x100000000) {
// uint 32
this.writeU8(0xce);
this.writeU32(object);
}
else {
// uint 64
this.writeU8(0xcf);
this.writeU64(object);
}
}
else {
if (object >= -0x20) {
// negative fixint
this.writeU8(0xe0 | (object + 0x20));
}
else if (object >= -0x80) {
// int 8
this.writeU8(0xd0);
this.writeI8(object);
}
else if (object >= -0x8000) {
// int 16
this.writeU8(0xd1);
this.writeI16(object);
}
else if (object >= -0x80000000) {
// int 32
this.writeU8(0xd2);
this.writeI32(object);
}
else {
// int 64
this.writeU8(0xd3);
this.writeI64(object);
}
}
}
else {
// non-integer numbers
if (this.forceFloat32) {
// float 32
this.writeU8(0xca);
this.writeF32(object);
}
else {
// float 64
this.writeU8(0xcb);
this.writeF64(object);
}
}
}
writeStringHeader(byteLength) {
if (byteLength < 32) {
// fixstr
this.writeU8(0xa0 + byteLength);
}
else if (byteLength < 0x100) {
// str 8
this.writeU8(0xd9);
this.writeU8(byteLength);
}
else if (byteLength < 0x10000) {
// str 16
this.writeU8(0xda);
this.writeU16(byteLength);
}
else if (byteLength < 0x100000000) {
// str 32
this.writeU8(0xdb);
this.writeU32(byteLength);
}
else {
throw new Error(`Too long string: ${byteLength} bytes in UTF-8`);
}
}
encodeString(object) {
const maxHeaderSize = 1 + 4;
const strLength = object.length;
if (strLength > TEXT_ENCODER_THRESHOLD) {
const byteLength = utf8Count(object);
this.ensureBufferSizeToWrite(maxHeaderSize + byteLength);
this.writeStringHeader(byteLength);
utf8EncodeTE(object, this.bytes, this.pos);
this.pos += byteLength;
}
else {
const byteLength = utf8Count(object);
this.ensureBufferSizeToWrite(maxHeaderSize + byteLength);
this.writeStringHeader(byteLength);
utf8EncodeJs(object, this.bytes, this.pos);
this.pos += byteLength;
}
}
encodeObject(object, depth) {
// try to encode objects with custom codec first of non-primitives
const ext = this.extensionCodec.tryToEncode(object, this.context);
if (ext != null) {
this.encodeExtension(ext);
}
else if (Array.isArray(object)) {
this.encodeArray(object, depth);
}
else if (ArrayBuffer.isView(object)) {
this.encodeBinary(object);
}
else if (typeof object === "object") {
this.encodeMap(object, depth);
}
else {
// symbol, function and other special object come here unless extensionCodec handles them.
throw new Error(`Unrecognized object: ${Object.prototype.toString.apply(object)}`);
}
}
encodeBinary(object) {
const size = object.byteLength;
if (size < 0x100) {
// bin 8
this.writeU8(0xc4);
this.writeU8(size);
}
else if (size < 0x10000) {
// bin 16
this.writeU8(0xc5);
this.writeU16(size);
}
else if (size < 0x100000000) {
// bin 32
this.writeU8(0xc6);
this.writeU32(size);
}
else {
throw new Error(`Too large binary: ${size}`);
}
const bytes = ensureUint8Array(object);
this.writeU8a(bytes);
}
encodeArray(object, depth) {
const size = object.length;
if (size < 16) {
// fixarray
this.writeU8(0x90 + size);
}
else if (size < 0x10000) {
// array 16
this.writeU8(0xdc);
this.writeU16(size);
}
else if (size < 0x100000000) {
// array 32
this.writeU8(0xdd);
this.writeU32(size);
}
else {
throw new Error(`Too large array: ${size}`);
}
for (const item of object) {
this.doEncode(item, depth + 1);
}
}
countWithoutUndefined(object, keys) {
let count = 0;
for (const key of keys) {
if (object[key] !== undefined) {
count++;
}
}
return count;
}
encodeMap(object, depth) {
const keys = Object.keys(object);
if (this.sortKeys) {
keys.sort();
}
const size = this.ignoreUndefined ? this.countWithoutUndefined(object, keys) : keys.length;
if (size < 16) {
// fixmap
this.writeU8(0x80 + size);
}
else if (size < 0x10000) {
// map 16
this.writeU8(0xde);
this.writeU16(size);
}
else if (size < 0x100000000) {
// map 32
this.writeU8(0xdf);
this.writeU32(size);
}
else {
throw new Error(`Too large map object: ${size}`);
}
for (const key of keys) {
const value = object[key];
if (!(this.ignoreUndefined && value === undefined)) {
this.encodeString(key);
this.doEncode(value, depth + 1);
}
}
}
encodeExtension(ext) {
const size = ext.data.length;
if (size === 1) {
// fixext 1
this.writeU8(0xd4);
}
else if (size === 2) {
// fixext 2
this.writeU8(0xd5);
}
else if (size === 4) {
// fixext 4
this.writeU8(0xd6);
}
else if (size === 8) {
// fixext 8
this.writeU8(0xd7);
}
else if (size === 16) {
// fixext 16
this.writeU8(0xd8);
}
else if (size < 0x100) {
// ext 8
this.writeU8(0xc7);
this.writeU8(size);
}
else if (size < 0x10000) {
// ext 16
this.writeU8(0xc8);
this.writeU16(size);
}
else if (size < 0x100000000) {
// ext 32
this.writeU8(0xc9);
this.writeU32(size);
}
else {
throw new Error(`Too large extension object: ${size}`);
}
this.writeI8(ext.type);
this.writeU8a(ext.data);
}
writeU8(value) {
this.ensureBufferSizeToWrite(1);
this.view.setUint8(this.pos, value);
this.pos++;
}
writeU8a(values) {
const size = values.length;
this.ensureBufferSizeToWrite(size);
this.bytes.set(values, this.pos);
this.pos += size;
}
writeI8(value) {
this.ensureBufferSizeToWrite(1);
this.view.setInt8(this.pos, value);
this.pos++;
}
writeU16(value) {
this.ensureBufferSizeToWrite(2);
this.view.setUint16(this.pos, value);
this.pos += 2;
}
writeI16(value) {
this.ensureBufferSizeToWrite(2);
this.view.setInt16(this.pos, value);
this.pos += 2;
}
writeU32(value) {
this.ensureBufferSizeToWrite(4);
this.view.setUint32(this.pos, value);
this.pos += 4;
}
writeI32(value) {
this.ensureBufferSizeToWrite(4);
this.view.setInt32(this.pos, value);
this.pos += 4;
}
writeF32(value) {
this.ensureBufferSizeToWrite(4);
this.view.setFloat32(this.pos, value);
this.pos += 4;
}
writeF64(value) {
this.ensureBufferSizeToWrite(8);
this.view.setFloat64(this.pos, value);
this.pos += 8;
}
writeU64(value) {
this.ensureBufferSizeToWrite(8);
setUint64(this.view, this.pos, value);
this.pos += 8;
}
writeI64(value) {
this.ensureBufferSizeToWrite(8);
setInt64(this.view, this.pos, value);
this.pos += 8;
}
}
;// CONCATENATED MODULE: ./src/StreamEncoder.ts
const StreamEncoder_DEFAULT_MAX_DEPTH = 100;
const DEFAULT_BUFFER_SIZE = 2048;
class StreamEncoder {
constructor(extensionCodec = ExtensionCodec.defaultCodec, context = undefined, maxDepth = StreamEncoder_DEFAULT_MAX_DEPTH, bufferSize = DEFAULT_BUFFER_SIZE, sortKeys = false, forceFloat32 = false, ignoreUndefined = false, forceIntegerToFloat = false) {
this.extensionCodec = extensionCodec;
this.context = context;
this.maxDepth = maxDepth;
this.bufferSize = bufferSize;
this.sortKeys = sortKeys;
this.forceFloat32 = forceFloat32;
this.ignoreUndefined = ignoreUndefined;
this.forceIntegerToFloat = forceIntegerToFloat;
this.view = new DataView(new ArrayBuffer(2048));
this.bytes = new Uint8Array(this.view.buffer);
}
*encode(object) {
const buffer = new Uint8Array(this.bufferSize);
let pos = 0;
for (let chunk of this.doEncode(object, 1)) {
if (chunk.length >= buffer.length) {
if (pos >= 0) {
yield buffer.slice(0, pos);
}
pos = 0;
yield chunk.slice();
}
else {
while (chunk.length > 0) {
const readSize = Math.min(buffer.length - pos, chunk.length);
const read = chunk.subarray(0, readSize);
buffer.set(read, pos);
pos += read.length;
if (pos === buffer.length) {
yield buffer.slice();
pos = 0;
}
chunk = chunk.subarray(readSize, chunk.length);
}
}
}
if (pos >= 0) {
yield buffer.subarray(0, pos);
}
}
doEncode(object, depth) {
if (depth > this.maxDepth) {
throw new Error(`Too deep objects in depth ${depth}`);
}
if (object == null) {
return this.encodeNil();
}
else if (typeof object === "boolean") {
return this.encodeBoolean(object);
}
else if (typeof object === "number") {
return this.encodeNumber(object);
}
else if (typeof object === "string") {
return this.encodeString(object);
}
else {
return this.encodeObject(object, depth);
}
}
ensureBufferSizeToWrite(sizeToWrite) {
if (this.view.byteLength < sizeToWrite) {
this.resizeBuffer(sizeToWrite * 2);
}
}
resizeBuffer(newSize) {
const newBuffer = new ArrayBuffer(newSize);
const newBytes = new Uint8Array(newBuffer);
const newView = new DataView(newBuffer);
this.view = newView;
this.bytes = newBytes;
}
encodeNil() {
return this.writeU8(0xc0);
}
encodeBoolean(object) {
if (object === false) {
return this.writeU8(0xc2);
}
else {
return this.writeU8(0xc3);
}
}
encodeNumber(object) {
if (Number.isSafeInteger(object) && !this.forceIntegerToFloat) {
if (object >= 0) {
if (object < 0x80) {
// positive fixint
return this.writeU8(object);
}
else if (object < 0x100) {
// uint 8
return this.writeU8U8(0xcc, object);
}
else if (object < 0x10000) {
// uint 16
return this.writeU8U16(0xcd, object);
}
else if (object < 0x100000000) {
// uint 32
return this.writeU8U32(0xce, object);
}
else {
// uint 64
return this.writeU8U64(0xcf, object);
}
}
else {
if (object >= -0x20) {
// negative fixint
return this.writeU8(0xe0 | (object + 0x20));
}
else if (object >= -0x80) {
// int 8
return this.writeU8I8(0xd0, object);
}
else if (object >= -0x8000) {
// int 16
return this.writeU8I16(0xd1, object);
}
else if (object >= -0x80000000) {
// int 32
return this.writeU8I32(0xd2, object);
}
else {
// int 64
return this.writeU8I64(0xd3, object);
}
}
}
else {
// non-integer numbers
if (this.forceFloat32) {
// float 32
return this.writeU8F32(0xca, object);
}
else {
// float 64
return this.writeU8F64(0xcb, object);
}
}
}
buildStringHeader(byteLength) {
if (byteLength < 32) {
// fixstr
return [0xa0 + byteLength];
}
else if (byteLength < 0x100) {
// str 8
return [0xd9, byteLength];
}
else if (byteLength < 0x10000) {
// str 16
const bytes = new DataView(new ArrayBuffer(3));
bytes.setUint8(0, 0xda);
bytes.setUint16(1, byteLength);
return new Uint8Array(bytes.buffer);
}
else if (byteLength < 0x100000000) {
// str 32
const bytes = new DataView(new ArrayBuffer(5));
bytes.setUint8(0, 0xdb);
bytes.setUint32(1, byteLength);
return new Uint8Array(bytes.buffer);
}
else {
throw new Error(`Too long string: ${byteLength} bytes in UTF-8`);
}
}
encodeString(object) {
const maxHeaderSize = 1 + 4;
const strLength = object.length;
if (strLength > TEXT_ENCODER_THRESHOLD) {
const byteLength = utf8Count(object);
this.ensureBufferSizeToWrite(maxHeaderSize + byteLength);
const header = this.buildStringHeader(byteLength);
this.bytes.set(header, 0);
utf8EncodeTE(object, this.bytes, header.length);
return this.writeBuffer(byteLength + header.length);
}
else {
const byteLength = utf8Count(object);
this.ensureBufferSizeToWrite(maxHeaderSize + byteLength);
const header = this.buildStringHeader(byteLength);
this.bytes.set(header, 0);
utf8EncodeJs(object, this.bytes, header.length);
return this.writeBuffer(byteLength + header.length);
}
}
encodeObject(object, depth) {
// try to encode objects with custom codec first of non-primitives
const ext = this.extensionCodec.tryToEncode(object, this.context);
if (ext != null) {
return this.encodeExtension(ext);
}
else if (Array.isArray(object)) {
return this.encodeArray(object, depth);
}
else if (ArrayBuffer.isView(object)) {
return this.encodeBinary(object);
}
else if (typeof object === "object") {
return this.encodeMap(object, depth);
}
else {
// symbol, function and other special object come here unless extensionCodec handles them.
throw new Error(`Unrecognized object: ${Object.prototype.toString.apply(object)}`);
}
}
*encodeBinary(object) {
const size = object.byteLength;
if (size < 0x100) {
// bin 8
yield* this.writeU8U8(0xc4, size);
}
else if (size < 0x10000) {
// bin 16
yield* this.writeU8U16(0xc5, size);
}
else if (size < 0x100000000) {
// bin 32
yield* this.writeU8U32(0xc6, size);
}
else {
throw new Error(`Too large binary: ${size}`);
}
const bytes = ensureUint8Array(object);
yield* this.writeU8a(bytes);
}
*encodeArray(object, depth) {
const size = object.length;
if (size < 16) {
// fixarray
yield* this.writeU8(0x90 + size);
}
else if (size < 0x10000) {
// array 16
yield* this.writeU8U16(0xdc, size);
}
else if (size < 0x100000000) {
// array 32
yield* this.writeU8U32(0xdd, size);
}
else {
throw new Error(`Too large array: ${size}`);
}
for (const item of object) {
yield* this.doEncode(item, depth + 1);
}
}
countWithoutUndefined(object, keys) {
let count = 0;
for (const key of keys) {
if (object[key] !== undefined) {
count++;
}
}
return count;
}
*encodeMap(object, depth) {
const keys = Object.keys(object);
if (this.sortKeys) {
keys.sort();
}
const size = this.ignoreUndefined ? this.countWithoutUndefined(object, keys) : keys.length;
if (size < 16) {
// fixmap
yield* this.writeU8(0x80 + size);
}
else if (size < 0x10000) {
// map 16
yield* this.writeU8U16(0xde, size);
}
else if (size < 0x100000000) {
// map 32
yield* this.writeU8U32(0xdf, size);
}
else {
throw new Error(`Too large map object: ${size}`);
}
for (const key of keys) {
const value = object[key];
if (!(this.ignoreUndefined && value === undefined)) {
yield* this.encodeString(key);
yield* this.doEncode(value, depth + 1);
}
}
}
*encodeExtension(ext) {
const size = ext.data.length;
if (size === 1) {
// fixext 1
yield* this.writeU8(0xd4);
}
else if (size === 2) {
// fixext 2
yield* this.writeU8(0xd5);
}
else if (size === 4) {
// fixext 4
yield* this.writeU8(0xd6);
}
else if (size === 8) {
// fixext 8
yield* this.writeU8(0xd7);
}
else if (size === 16) {
// fixext 16
yield* this.writeU8(0xd8);
}
else if (size < 0x100) {
// ext 8
yield* this.writeU8U8(0xc7, size);
}
else if (size < 0x10000) {
// ext 16
yield* this.writeU8U16(0xc8, size);
}
else if (size < 0x100000000) {
// ext 32
yield* this.writeU8U32(0xc9, size);
}
else {
throw new Error(`Too large extension object: ${size}`);
}
yield* this.writeI8(ext.type);
yield* this.writeU8a(ext.data);
}
writeU8(value) {
this.view.setUint8(0, value);
return this.writeBuffer(1);
}
writeU8a(values) {
const size = values.length;
this.ensureBufferSizeToWrite(size);
this.bytes.set(values, 0);
return this.writeBuffer(size);
}
writeI8(value) {
this.view.setInt8(0, value);
return this.writeBuffer(1);
}
writeU16(value) {
this.view.setUint16(0, value);
return this.writeBuffer(2);
}
writeI16(value) {
this.view.setInt16(0, value);
return this.writeBuffer(2);
}
writeU32(value) {
this.view.setUint32(0, value);
return this.writeBuffer(4);
}
writeI32(value) {
this.view.setInt32(0, value);
return this.writeBuffer(4);
}
writeF32(value) {
this.view.setFloat32(0, value);
return this.writeBuffer(4);
}
writeF64(value) {
this.view.setFloat64(0, value);
return this.writeBuffer(8);
}
writeU64(value) {
setUint64(this.view, 0, value);
return this.writeBuffer(8);
}
writeI64(value) {
setInt64(this.view, 0, value);
return this.writeBuffer(8);
}
writeU8U8(value, value2) {
this.view.setUint8(0, value);
this.view.setUint8(1, value2);
return this.writeBuffer(2);
}
writeU8U16(u8, u16) {
this.view.setUint8(0, u8);
this.view.setUint16(1, u16);
return this.writeBuffer(3);
}
writeU8U32(u8, u32) {
this.view.setUint8(0, u8);
this.view.setUint32(1, u32);
return this.writeBuffer(5);
}
writeU8U64(u8, u64) {
this.view.setUint8(0, u8);
setUint64(this.view, 1, u64);
return this.writeBuffer(9);
}
writeU8I8(value, value2) {
this.view.setUint8(0, value);
this.view.setInt8(1, value2);
return this.writeBuffer(2);
}
writeU8I16(u8, i16) {
this.view.setUint8(0, u8);
this.view.setInt16(1, i16);
return this.writeBuffer(3);
}
writeU8I32(u8, i32) {
this.view.setUint8(0, u8);
this.view.setInt32(1, i32);
return this.writeBuffer(5);
}
writeU8I64(u8, i64) {
this.view.setUint8(0, u8);
setInt64(this.view, 1, i64);
return this.writeBuffer(9);
}
writeU8F32(u8, f32) {
this.view.setUint8(0, u8);
this.view.setFloat32(1, f32);
return this.writeBuffer(5);
}
writeU8F64(u8, f64) {
this.view.setUint8(0, u8);
this.view.setFloat64(1, f64);
return this.writeBuffer(9);
}
*writeBuffer(length) {
yield this.bytes.subarray(0, length);
}
}
;// CONCATENATED MODULE: ./src/encode.ts
const defaultEncodeOptions = {};
/**
* It encodes `value` in the MessagePack format and
* returns a byte buffer.
*
* The returned buffer is a slice of a larger `ArrayBuffer`, so you have to use its `#byteOffset` and `#byteLength` in order to convert it to another typed arrays including NodeJS `Buffer`.
*/
function encode(value, options = defaultEncodeOptions) {
const encoder = new Encoder(options.extensionCodec, options.context, options.maxDepth, options.initialBufferSize, options.sortKeys, options.forceFloat32, options.ignoreUndefined, options.forceIntegerToFloat);
return encoder.encodeSharedRef(value);
}
function encodeStream(value, options = defaultEncodeOptions) {
const encoder = new StreamEncoder(options.extensionCodec, options.context, options.maxDepth, options.streamBufferSize, options.sortKeys, options.forceFloat32, options.ignoreUndefined, options.forceIntegerToFloat);
return encoder.encode(value);
}
;// CONCATENATED MODULE: ./src/utils/prettyByte.ts
function prettyByte(byte) {
return `${byte < 0 ? "-" : ""}0x${Math.abs(byte).toString(16).padStart(2, "0")}`;
}
;// CONCATENATED MODULE: ./src/CachedKeyDecoder.ts
const DEFAULT_MAX_KEY_LENGTH = 16;
const DEFAULT_MAX_LENGTH_PER_KEY = 16;
class CachedKeyDecoder {
constructor(maxKeyLength = DEFAULT_MAX_KEY_LENGTH, maxLengthPerKey = DEFAULT_MAX_LENGTH_PER_KEY) {
this.maxKeyLength = maxKeyLength;
this.maxLengthPerKey = maxLengthPerKey;
this.hit = 0;
this.miss = 0;
// avoid `new Array(N)`, which makes a sparse array,
// because a sparse array is typically slower than a non-sparse array.
this.caches = [];
for (let i = 0; i < this.maxKeyLength; i++) {
this.caches.push([]);
}
}
canBeCached(byteLength) {
return byteLength > 0 && byteLength <= this.maxKeyLength;
}
find(bytes, inputOffset, byteLength) {
const records = this.caches[byteLength - 1];
FIND_CHUNK: for (const record of records) {
const recordBytes = record.bytes;
for (let j = 0; j < byteLength; j++) {
if (recordBytes[j] !== bytes[inputOffset + j]) {
continue FIND_CHUNK;
}
}
return record.str;
}
return null;
}
store(bytes, value) {
const records = this.caches[bytes.length - 1];
const record = { bytes, str: value };
if (records.length >= this.maxLengthPerKey) {
// `records` are full!
// Set `record` to an arbitrary position.
records[(Math.random() * records.length) | 0] = record;
}
else {
records.push(record);
}
}
decode(bytes, inputOffset, byteLength) {
const cachedValue = this.find(bytes, inputOffset, byteLength);
if (cachedValue != null) {
this.hit++;
return cachedValue;
}
this.miss++;
const str = utf8DecodeJs(bytes, inputOffset, byteLength);
// Ensure to copy a slice of bytes because the byte may be NodeJS Buffer and Buffer#slice() returns a reference to its internal ArrayBuffer.
const slicedCopyOfBytes = Uint8Array.prototype.slice.call(bytes, inputOffset, inputOffset + byteLength);
this.store(slicedCopyOfBytes, str);
return str;
}
}
;// CONCATENATED MODULE: ./src/Decoder.ts
var __awaiter = (undefined && undefined.__awaiter) || function (thisArg, _arguments, P, generator) {
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
return new (P || (P = Promise))(function (resolve, reject) {
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
step((generator = generator.apply(thisArg, _arguments || [])).next());
});
};
var __asyncValues = (undefined && undefined.__asyncValues) || function (o) {
if (!Symbol.asyncIterator) throw new TypeError("Symbol.asyncIterator is not defined.");
var m = o[Symbol.asyncIterator], i;
return m ? m.call(o) : (o = typeof __values === "function" ? __values(o) : o[Symbol.iterator](), i = {}, verb("next"), verb("throw"), verb("return"), i[Symbol.asyncIterator] = function () { return this; }, i);
function verb(n) { i[n] = o[n] && function (v) { return new Promise(function (resolve, reject) { v = o[n](v), settle(resolve, reject, v.done, v.value); }); }; }
function settle(resolve, reject, d, v) { Promise.resolve(v).then(function(v) { resolve({ value: v, done: d }); }, reject); }
};
var __await = (undefined && undefined.__await) || function (v) { return this instanceof __await ? (this.v = v, this) : new __await(v); }
var __asyncGenerator = (undefined && undefined.__asyncGenerator) || function (thisArg, _arguments, generator) {
if (!Symbol.asyncIterator) throw new TypeError("Symbol.asyncIterator is not defined.");
var g = generator.apply(thisArg, _arguments || []), i, q = [];
return i = {}, verb("next"), verb("throw"), verb("return"), i[Symbol.asyncIterator] = function () { return this; }, i;
function verb(n) { if (g[n]) i[n] = function (v) { return new Promise(function (a, b) { q.push([n, v, a, b]) > 1 || resume(n, v); }); }; }
function resume(n, v) { try { step(g[n](v)); } catch (e) { settle(q[0][3], e); } }
function step(r) { r.value instanceof __await ? Promise.resolve(r.value.v).then(fulfill, reject) : settle(q[0][2], r); }
function fulfill(value) { resume("next", value); }
function reject(value) { resume("throw", value); }
function settle(f, v) { if (f(v), q.shift(), q.length) resume(q[0][0], q[0][1]); }
};
const STATE_ARRAY = "array";
const STATE_MAP_KEY = "map_key";
const STATE_MAP_VALUE = "map_value";
const isValidMapKeyType = (key) => {
const keyType = typeof key;
return keyType === "string" || keyType === "number";
};
const HEAD_BYTE_REQUIRED = -1;
const EMPTY_VIEW = new DataView(new ArrayBuffer(0));
const EMPTY_BYTES = new Uint8Array(EMPTY_VIEW.buffer);
// IE11: Hack to support IE11.
// IE11: Drop this hack and just use RangeError when IE11 is obsolete.
const DataViewIndexOutOfBoundsError = (() => {
try {
// IE11: The spec says it should throw RangeError,
// IE11: but in IE11 it throws TypeError.
EMPTY_VIEW.getInt8(0);
}
catch (e) {
return e.const