diff --git a/babelrc.test.js b/babelrc.test.js index 7a7def6..23bd800 100644 --- a/babelrc.test.js +++ b/babelrc.test.js @@ -1,18 +1,18 @@ module.exports = { - presets: [['@babel/preset-env', { targets: { node: 'current' } }]], + presets: [["@babel/preset-env", { targets: { node: "current" } }]], plugins: [ - '@babel/plugin-transform-runtime', + "@babel/plugin-transform-runtime", [ - '@babel/plugin-proposal-decorators', + "@babel/plugin-proposal-decorators", { - legacy: true - } + legacy: true, + }, ], [ - '@babel/plugin-proposal-class-properties', + "@babel/plugin-proposal-class-properties", { - loose: true - } - ] - ] -} + loose: true, + }, + ], + ], +}; diff --git a/src/Binary.js b/src/Binary.js index 374c4ec..bf5c7e0 100644 --- a/src/Binary.js +++ b/src/Binary.js @@ -1,7 +1,7 @@ // Not efficient enough... // import { nonenumerable } from 'core-decorators'; -import Types from './Types' +import Types from "./Types"; /** Class allowing `@binary` members */ class Binary { @@ -12,23 +12,23 @@ class Binary { // Class props // Slowers down 4x times... // @nonenumerable - static _size + static _size; /** * Static getter for the class binary size * @return {number} - The class binary size */ - static get binarySize () { - return this._size + static get binarySize() { + return this._size; } // @nonenumerable - static _binaryProps + static _binaryProps; /** * Static getter for the class binary props * @return {array} - The list of binary props */ - static get binaryProps () { - return this._binaryProps + static get binaryProps() { + return this._binaryProps; } /** @@ -40,34 +40,34 @@ class Binary { * @return {array} - The array {@link list} where the objects have been added */ // @nonenumerable - static arrayFactory (binOrDV, length, initialOffset = 0, list = []) { + static arrayFactory(binOrDV, length, initialOffset = 0, list = []) { // Optimize: Generate a single DataView for all elements - const dv = binOrDV instanceof DataView ? binOrDV : new DataView(binOrDV) + const dv = binOrDV instanceof DataView ? binOrDV : new DataView(binOrDV); for (let i = 0; i < length; i++) { - list.push(new this(dv, initialOffset + this._size * i)) + list.push(new this(dv, initialOffset + this._size * i)); } - return list + return list; } // Prototype props // @nonenumerable - _initialOffset + _initialOffset; // @nonenumerable - _bin + _bin; // @nonenumerable - __dv + __dv; /** * Getter of the DataView containing this object's data * @return {DataView} - The DataView */ // @nonenumerable - get _dv () { + get _dv() { this.__dv = this?.__dv ?? - new DataView(this._bin, this._initialOffset, this.constructor._size) - return this.__dv + new DataView(this._bin, this._initialOffset, this.constructor._size); + return this.__dv; } /** @@ -80,10 +80,10 @@ class Binary { this.constructor._binaryProps.reduce( (acc, prop) => ({ ...acc, - [prop]: this[prop] + [prop]: this[prop], }), - {} - ) + {}, + ); /** * Save own initial offset at binary data @@ -91,14 +91,14 @@ class Binary { * @param {number} initialOffset - Buffer offset before this object data start * @param {boolean} isLazy - If true and {@link binOrDv} is not a {DataView}, wait until first acces before Instantiating the __dv */ - constructor (binOrDV, initialOffset = 0, isLazy = true) { - this._initialOffset = initialOffset + constructor(binOrDV, initialOffset = 0, isLazy = true) { + this._initialOffset = initialOffset; if (binOrDV instanceof DataView) { - this.__dv = binOrDV + this.__dv = binOrDV; } else { - this._bin = binOrDV + this._bin = binOrDV; if (!isLazy) { - this._dv // Call getter + this._dv; // Call getter } } } @@ -111,7 +111,7 @@ class Binary { */ // @nonenumerable getByteAt = (offset) => - Types.Uint8.get(this._dv, this._initialOffset + offset) + Types.Uint8.get(this._dv, this._initialOffset + offset); } /* @@ -134,4 +134,4 @@ Object.defineProperty(Binary, "binaryProps", { }); */ -export default Binary +export default Binary; diff --git a/src/BinaryArray.js b/src/BinaryArray.js index 2c33325..b432c34 100644 --- a/src/BinaryArray.js +++ b/src/BinaryArray.js @@ -1,15 +1,15 @@ /** Class for returning array members from {@link Binary} objects */ class BinaryArrayBase { // @member - type + type; // @member - dv + dv; // @member - offset + offset; // @member - length + length; // @member - bytes + bytes; /** * Creates a new customized array @@ -18,12 +18,12 @@ class BinaryArrayBase { * @param {number} offset - The offset of the first member of the array into the buffer * @param {number} length - The length of the array */ - constructor (dv, type, offset, length) { - this.type = type - this.dv = dv - this.offset = offset - this.length = length - this.bytes = length * type.bytes + constructor(dv, type, offset, length) { + this.type = type; + this.dv = dv; + this.offset = offset; + this.length = length; + this.bytes = length * type.bytes; } /** @@ -32,7 +32,7 @@ class BinaryArrayBase { * @return {array} - The new generated array (not bound to original values) * @method */ - map = (fn) => Array.from(this, fn) + map = (fn) => Array.from(this, fn); // reduce = (...args) => Array.prototype.reduce.call([...this], ...args); /** @@ -50,20 +50,20 @@ class BinaryArrayBase { * @yield {any} - Each of this array elements of type {@link Types} * @name iterator */ - * [Symbol.iterator] () { + *[Symbol.iterator]() { // Deconstruct to optimize and ease reading const { length, dv, offset, - type: { get, bytes } - } = this + type: { get, bytes }, + } = this; // Use a new index for each iterator. This makes multiple // iterations over the iterable safe for non-trivial cases, // such as use of break or nested looping over the same iterable. for (let index = 0; index < length; index++) { - yield get(dv, offset + bytes * index) + yield get(dv, offset + bytes * index); } } } @@ -79,23 +79,23 @@ const BinaryArrayHandler = { * @param {string} prop - The property to return (only handled when prop is a string representing a number) * @return {any} - The element at {@link prop} position, or a reflected value from {@link target} */ - get (target, prop) { + get(target, prop) { // Very inefficient way // Need to: // - Override Array internals, but are private // - Override `[]` operator, but it's not possible - if (prop === '0' || (typeof prop === 'string' && Number(prop) > 0)) { + if (prop === "0" || (typeof prop === "string" && Number(prop) > 0)) { // Destructure to optimize const { dv, offset, - type: { get, bytes } - } = target - return get(dv, offset + bytes * Number(prop)) + type: { get, bytes }, + } = target; + return get(dv, offset + bytes * Number(prop)); } // Return original value - return Reflect.get(target, prop) + return Reflect.get(target, prop); }, /** @@ -105,20 +105,20 @@ const BinaryArrayHandler = { * @param {any} value - The value to assign to the {@link prop}'th element * @return {boolean} - If {@link prop} is numericalish, true (as needed for JS setters), else the return value from the {@link target} reflected setter */ - set (target, prop, value) { - if (prop === '0' || (typeof prop === 'string' && Number(prop) > 0)) { + set(target, prop, value) { + if (prop === "0" || (typeof prop === "string" && Number(prop) > 0)) { // Destructure to optimize const { dv, offset, - type: { set, bytes } - } = target - set(dv, offset + bytes * Number(prop), value) - return true + type: { set, bytes }, + } = target; + set(dv, offset + bytes * Number(prop), value); + return true; } - return Reflect.set(target, prop, value) - } -} + return Reflect.set(target, prop, value); + }, +}; // #TODO: BUG: Argument Spread Operator not working // well when packing with webpack @@ -133,8 +133,8 @@ const BinaryArrayHandler = { const BinaryArray = (dv, type, offset, length) => { return new Proxy( new BinaryArrayBase(dv, type, offset, length), - BinaryArrayHandler - ) -} + BinaryArrayHandler, + ); +}; -export default BinaryArray +export default BinaryArray; diff --git a/src/TextEncoder-polyfill.js b/src/TextEncoder-polyfill.js index a8e4ac3..caf3d1e 100644 --- a/src/TextEncoder-polyfill.js +++ b/src/TextEncoder-polyfill.js @@ -1,7 +1,7 @@ // Mock Node missing TextEncoder and TextDecoder APIs from its `util` lib -if (!('TextEncoder' in global)) { - import('util').then((nodeUtil) => { - global.TextEncoder = nodeUtil.TextEncoder - global.TextDecoder = nodeUtil.TextDecoder - }) +if (!("TextEncoder" in global)) { + import("util").then((nodeUtil) => { + global.TextEncoder = nodeUtil.TextEncoder; + global.TextDecoder = nodeUtil.TextDecoder; + }); } diff --git a/src/Types.js b/src/Types.js index e137ef6..1ae2de8 100644 --- a/src/Types.js +++ b/src/Types.js @@ -1,4 +1,4 @@ -import BinaryArray from './BinaryArray' +import BinaryArray from "./BinaryArray"; /** * Types used by the {@link binary} decorator @@ -9,66 +9,66 @@ const Types = { extractor: Float32Array, bytes: 4, get: (dv, offset) => dv.getFloat32(offset), - set: (dv, offset, value) => dv.setFloat32(offset, value) + set: (dv, offset, value) => dv.setFloat32(offset, value), }, Float64: { extractor: Float64Array, bytes: 8, get: (dv, offset) => dv.getFloat64(offset), - set: (dv, offset, value) => dv.setFloat64(offset, value) + set: (dv, offset, value) => dv.setFloat64(offset, value), }, Int8: { extractor: Int8Array, bytes: 1, get: (dv, offset) => dv.getInt8(offset), - set: (dv, offset, value) => dv.setInt8(offset, value) + set: (dv, offset, value) => dv.setInt8(offset, value), }, Int16: { extractor: Int16Array, bytes: 2, get: (dv, offset) => dv.getInt16(offset), - set: (dv, offset, value) => dv.setInt16(offset, value) + set: (dv, offset, value) => dv.setInt16(offset, value), }, Int32: { extractor: Int32Array, bytes: 4, get: (dv, offset) => dv.getInt32(offset), - set: (dv, offset, value) => dv.setInt32(offset, value) + set: (dv, offset, value) => dv.setInt32(offset, value), }, BigInt64: { extractor: BigInt64Array, bytes: 8, get: (dv, offset) => dv.getBigInt64(offset), - set: (dv, offset, value) => dv.setBigInt64(offset, value) + set: (dv, offset, value) => dv.setBigInt64(offset, value), }, Uint8: { extractor: Uint8Array, bytes: 1, get: (dv, offset) => dv.getUint8(offset), - set: (dv, offset, value) => dv.setUint8(offset, value) + set: (dv, offset, value) => dv.setUint8(offset, value), }, /** Not implemented */ Uint8Clamped: { extractor: Uint8ClampedArray, - bytes: 1 + bytes: 1, }, Uint16: { extractor: Uint16Array, bytes: 2, get: (dv, offset) => dv.getUint16(offset), - set: (dv, offset, value) => dv.setUint16(offset, value) + set: (dv, offset, value) => dv.setUint16(offset, value), }, Uint32: { extractor: Uint32Array, bytes: 4, get: (dv, offset) => dv.getUint32(offset), - set: (dv, offset, value) => dv.setUint32(offset, value) + set: (dv, offset, value) => dv.setUint32(offset, value), }, BigUint64: { extractor: BigUint64Array, bytes: 8, get: (dv, offset) => dv.getBigUint64(offset), - set: (dv, offset, value) => dv.setBigUint64(offset, value) + set: (dv, offset, value) => dv.setBigUint64(offset, value), }, /** @@ -85,29 +85,29 @@ const Types = { padding: padding && type.bytes, // Change getter/setter depending on padding ensured // 1-byte sized native types always have padding ensured - ...(padding || ('extractor' in type && type.bytes === 1) + ...(padding || ("extractor" in type && type.bytes === 1) ? { - get (dv, offset) { - return new type.extractor(dv.buffer, offset, length) + get(dv, offset) { + return new type.extractor(dv.buffer, offset, length); + }, + set(dv, offset, values) { + const typed = new type.extractor(dv.buffer, offset, length); + typed.set(values); + return true; }, - set (dv, offset, values) { - const typed = new type.extractor(dv.buffer, offset, length) - typed.set(values) - return true - } } : { - get (dv, offset) { - return BinaryArray(dv, type, offset, length) + get(dv, offset) { + return BinaryArray(dv, type, offset, length); }, - set (dv, offset, values) { + set(dv, offset, values) { values.forEach((value, index) => - type.set(dv, offset + type.bytes * index, value) - ) - return true - } - }) - } + type.set(dv, offset + type.bytes * index, value), + ); + return true; + }, + }), + }; }, /** @@ -119,21 +119,21 @@ const Types = { Struct: (Class) => { return { bytes: Class.binarySize, - get (dv, offset) { - return new Class(dv, offset) + get(dv, offset) { + return new Class(dv, offset); }, - set (dv, offset, values) { + set(dv, offset, values) { // TODO: Test if values is a Binary Object and we can just copy binary data, or nothing, // because binary data, class and offset are the same. - const obj = new Class(dv, offset) + const obj = new Class(dv, offset); for (const prop of Object.keys(values)) { if (Class.binaryProps.includes(prop)) { - obj[prop] = values[prop] + obj[prop] = values[prop]; } } - return true - } - } + return true; + }, + }; }, /** @@ -145,42 +145,42 @@ const Types = { * - @param {boolean} zeroTerminated - True if using the C zero terminated strings (default) * @return {object} - The generated Types.* compliant */ - Text: (length, { encoding = 'utf8', zeroTerminated = true } = {}) => { - const decoder = new TextDecoder(encoding) - const encoder = new TextEncoder() // Only UTF8 available + Text: (length, { encoding = "utf8", zeroTerminated = true } = {}) => { + const decoder = new TextDecoder(encoding); + const encoder = new TextEncoder(); // Only UTF8 available return { bytes: length, - get (dv, offset) { - const arr = new Types.Uint8.extractor(dv.buffer, offset, length) + get(dv, offset) { + const arr = new Types.Uint8.extractor(dv.buffer, offset, length); if (zeroTerminated) { - const firstZero = arr.indexOf(0x00) + const firstZero = arr.indexOf(0x00); if (firstZero === 0) { - return '' + return ""; } else if (firstZero > 0) { const arrSmaller = new Types.Uint8.extractor( dv.buffer, offset, - firstZero - ) - return decoder.decode(arrSmaller) + firstZero, + ); + return decoder.decode(arrSmaller); } } - return decoder.decode(arr) + return decoder.decode(arr); }, - set (dv, offset, value) { - const arr = new Types.Uint8.extractor(dv.buffer, offset, length) - const { read, written } = encoder.encodeInto(value, arr) + set(dv, offset, value) { + const arr = new Types.Uint8.extractor(dv.buffer, offset, length); + const { read, written } = encoder.encodeInto(value, arr); if (zeroTerminated && written < arr.length) { - arr[written] = 0 // append null if room + arr[written] = 0; // append null if room } - return true - } - } - } -} + return true; + }, + }; + }, +}; -export default Types +export default Types; diff --git a/src/decorators.js b/src/decorators.js index aad0b10..925d1f8 100644 --- a/src/decorators.js +++ b/src/decorators.js @@ -1,4 +1,4 @@ -import Types from './Types' +import Types from "./Types"; /** * Class member decorator generator for Binary class property @@ -17,26 +17,26 @@ const binary = ({ bytes, padding = false, get, set }) => { * @method * @name decorator */ - return function decorator (target, name, descriptor) { + return function decorator(target, name, descriptor) { // const deleted = (() => { // const {value, initializer, writable} = descriptor; // return {value, initializer, writable}; // })(); // Add size as static property to Class - target.constructor._size = target.constructor._size ?? 0 - target.constructor._binaryProps = target.constructor._binaryProps ?? [] + target.constructor._size = target.constructor._size ?? 0; + target.constructor._binaryProps = target.constructor._binaryProps ?? []; // Create an initial padding offset if needed - const size = target.constructor._size - const paddingOffset = padding ? padding - (size % padding) : 0 + const size = target.constructor._size; + const paddingOffset = padding ? padding - (size % padding) : 0; // Get this property offset - const offset = target.constructor._size + paddingOffset + const offset = target.constructor._size + paddingOffset; // Add property size to Class size (at static Class property) - target.constructor._size += bytes + paddingOffset - target.constructor._binaryProps.push(name) + target.constructor._size += bytes + paddingOffset; + target.constructor._binaryProps.push(name); /** * Property definition returned from {@link binary}'s returned {@link decorator} @@ -53,8 +53,8 @@ const binary = ({ bytes, padding = false, get, set }) => { * @this Binary instance * @name propertyDescriptorGetter */ - get () { - return get(this._dv, this._initialOffset + offset) + get() { + return get(this._dv, this._initialOffset + offset); }, /** @@ -64,15 +64,15 @@ const binary = ({ bytes, padding = false, get, set }) => { * @this Binary instance * @name propertyDescriptorSetter */ - set (value) { - set(this._dv, this._initialOffset + offset, value) - return true - } - } + set(value) { + set(this._dv, this._initialOffset + offset, value); + return true; + }, + }; - return descriptor - } -} + return descriptor; + }; +}; // Using `withBinary` as class decorator is 4x times faster in // instantiation (if using @nonenumerable), at the cost of losing some @@ -94,9 +94,9 @@ const withBinary = (Class) => { * @callback wrapper * */ const wrapper = (binOrDV, initialOffset = 0, ...args) => { - const target = new Class(...args) - target._dv = binOrDV instanceof DataView ? binOrDV : new DataView(binOrDV) - target._initialOffset = initialOffset + const target = new Class(...args); + target._dv = binOrDV instanceof DataView ? binOrDV : new DataView(binOrDV); + target._initialOffset = initialOffset; /** * Get a single byte (as unsigned integer) from a position @@ -105,7 +105,7 @@ const withBinary = (Class) => { * @this {@link Class} instance */ target.getByteAt = (offset) => - Types.Uint8.get(this._dv, this._initialOffset + offset) + Types.Uint8.get(this._dv, this._initialOffset + offset); // This is desirable, but slowers down instantiation time by 4x times // Note: `defineProperties` is +0,25 slower @@ -125,8 +125,8 @@ const withBinary = (Class) => { value: initialOffset, }); */ - return target - } + return target; + }; /** * Allow getting the class size from outside @@ -135,13 +135,13 @@ const withBinary = (Class) => { * @method * @name binarySize */ - Object.defineProperty(wrapper, 'binarySize', { - get () { - return Class._size + Object.defineProperty(wrapper, "binarySize", { + get() { + return Class._size; }, configurable: false, - enumerable: false - }) + enumerable: false, + }); /** * Allow getting the class binary props from outside @@ -150,13 +150,13 @@ const withBinary = (Class) => { * @method * @name binarySize */ - Object.defineProperty(wrapper, 'binaryProps', { - get () { - return Class._binaryProps + Object.defineProperty(wrapper, "binaryProps", { + get() { + return Class._binaryProps; }, configurable: false, - enumerable: false - }) + enumerable: false, + }); /** * Array creator helper @@ -173,22 +173,22 @@ const withBinary = (Class) => { binOrDV, length, initialOffset = 0, - list = [] + list = [], ) { // Optimize: Generate a single DataView for all elements const dv = binOrDV instanceof DataView ? binOrDV - : new DataView(binOrDV, initialOffset, length * Class._size) + : new DataView(binOrDV, initialOffset, length * Class._size); for (let i = 0; i < length; i++) { - list.push(wrapper(dv, initialOffset + Class._size * i)) + list.push(wrapper(dv, initialOffset + Class._size * i)); } - return list - } + return list; + }; - return wrapper -} + return wrapper; +}; -export { withBinary, binary } +export { withBinary, binary }; diff --git a/src/index.js b/src/index.js index 9d089be..de92211 100644 --- a/src/index.js +++ b/src/index.js @@ -1,7 +1,7 @@ -'use strict' +"use strict"; -import Types from './Types' -import Binary from './Binary' -import { binary, withBinary } from './decorators' +import Types from "./Types"; +import Binary from "./Binary"; +import { binary, withBinary } from "./decorators"; -export { Types, Binary, binary, withBinary } +export { Types, Binary, binary, withBinary };