UNPKG

@eyhn/msgpack-stream

Version:

MessagePack for ECMA-262/JavaScript/TypeScript

1,461 lines (1,424 loc) 106 kB
(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