diff --git a/package.json b/package.json index 9e2a9b1..a343054 100644 --- a/package.json +++ b/package.json @@ -63,6 +63,7 @@ }, "dependencies": { "@jsonjoy.com/base64": "^1.1.1", + "@jsonjoy.com/util": "^1.0.0", "hyperdyperid": "^1.2.0", "thingies": "^1.20.0" }, diff --git a/src/__bench__/bench.bson.encoding.ts b/src/__bench__/bench.bson.encoding.ts index 2c41af4..703d777 100644 --- a/src/__bench__/bench.bson.encoding.ts +++ b/src/__bench__/bench.bson.encoding.ts @@ -2,9 +2,9 @@ import {runBenchmark, IBenchmark} from '../__bench__/runBenchmark'; import {BsonEncoder} from '../bson/BsonEncoder'; -import {Writer} from '../util/buffers/Writer'; +import {Writer} from '@jsonjoy.com/util/lib/buffers/Writer'; import {payloads as payloads_} from '../__bench__/payloads'; -import {deepEqual} from '../json-equal/deepEqual'; +import {deepEqual} from '@jsonjoy.com/util/lib/json-equal/deepEqual'; import {BSON, EJSON} from 'bson'; const payloads = payloads_.map((p) => ({...p, data: {data: p.data}})); diff --git a/src/__bench__/bench.cbor-dag.encoding.ts b/src/__bench__/bench.cbor-dag.encoding.ts index a37427e..76d75cb 100644 --- a/src/__bench__/bench.cbor-dag.encoding.ts +++ b/src/__bench__/bench.cbor-dag.encoding.ts @@ -5,7 +5,7 @@ import {CborEncoderDag} from '../cbor/CborEncoderDag'; import {CborEncoder} from '../cbor/CborEncoder'; import {CborDecoder} from '../cbor/CborDecoder'; import {payloads} from '../__bench__/payloads'; -import {deepEqual} from '../json-equal/deepEqual'; +import {deepEqual} from '@jsonjoy.com/util/lib/json-equal/deepEqual'; const benchmark: IBenchmark = { name: 'Encoding', diff --git a/src/__bench__/bench.cbor.decoding.ts b/src/__bench__/bench.cbor.decoding.ts index 830b9b8..2b3348a 100644 --- a/src/__bench__/bench.cbor.decoding.ts +++ b/src/__bench__/bench.cbor.decoding.ts @@ -4,7 +4,7 @@ import {runBenchmark, IBenchmark} from '../__bench__/runBenchmark'; import {CborEncoder} from '../cbor/CborEncoder'; import {CborDecoderBase} from '../cbor/CborDecoderBase'; import {payloads} from '../__bench__/payloads'; -import {deepEqual} from '../json-equal/deepEqual'; +import {deepEqual} from '@jsonjoy.com/util/lib/json-equal/deepEqual'; const encoder = new CborEncoder(); diff --git a/src/__bench__/bench.cbor.encoding.ts b/src/__bench__/bench.cbor.encoding.ts index a11c472..3c7cbe9 100644 --- a/src/__bench__/bench.cbor.encoding.ts +++ b/src/__bench__/bench.cbor.encoding.ts @@ -4,7 +4,7 @@ import {runBenchmark, IBenchmark} from '../__bench__/runBenchmark'; import {CborEncoder} from '../cbor/CborEncoder'; import {CborEncoderFast} from '../cbor/CborEncoderFast'; import {CborDecoder} from '../cbor/CborDecoder'; -import {deepEqual} from '../json-equal/deepEqual'; +import {deepEqual} from '@jsonjoy.com/util/lib/json-equal/deepEqual'; import {payloads} from '../__bench__/payloads'; const benchmark: IBenchmark = { diff --git a/src/__bench__/bench.encoders.ts b/src/__bench__/bench.encoders.ts index cf593cc..7e28d3d 100644 --- a/src/__bench__/bench.encoders.ts +++ b/src/__bench__/bench.encoders.ts @@ -10,8 +10,8 @@ import {UbjsonEncoder} from '../ubjson/UbjsonEncoder'; import {IonEncoderFast} from '../ion/IonEncoderFast'; import {CborDecoder} from '../cbor/CborDecoder'; import {payloads} from '../__bench__/payloads'; -import {deepEqual} from '../json-equal/deepEqual'; -import {Writer} from '../util/buffers/Writer'; +import {deepEqual} from '@jsonjoy.com/util/lib/json-equal/deepEqual'; +import {Writer} from '@jsonjoy.com/util/lib/buffers/Writer'; const benchmark: IBenchmark = { name: 'Encoding', diff --git a/src/__bench__/bench.encoding.ts b/src/__bench__/bench.encoding.ts index c0d7785..0fb8271 100644 --- a/src/__bench__/bench.encoding.ts +++ b/src/__bench__/bench.encoding.ts @@ -5,7 +5,7 @@ import {JsonEncoder} from '../json/JsonEncoder'; import {UbjsonEncoder} from '../ubjson/UbjsonEncoder'; import {CborEncoderFast} from '../cbor/CborEncoderFast'; import {CborEncoder} from '../cbor/CborEncoder'; -import {Writer} from '../util/buffers/Writer'; +import {Writer} from '@jsonjoy.com/util/lib/buffers/Writer'; import {payloads} from '../__bench__/payloads'; import {MsgPackEncoderFast} from '../msgpack'; diff --git a/src/__bench__/bench.ion.encoding.ts b/src/__bench__/bench.ion.encoding.ts index d4c438f..9d37846 100644 --- a/src/__bench__/bench.ion.encoding.ts +++ b/src/__bench__/bench.ion.encoding.ts @@ -2,10 +2,10 @@ import {runBenchmark, IBenchmark} from '../__bench__/runBenchmark'; import {IonEncoderFast} from '../ion/IonEncoderFast'; -import {Writer} from '../util/buffers/Writer'; +import {Writer} from '@jsonjoy.com/util/lib/buffers/Writer'; import {payloads} from '../__bench__/payloads'; import {load, makeBinaryWriter, dom} from 'ion-js'; -import {deepEqual} from '../json-equal/deepEqual'; +import {deepEqual} from '@jsonjoy.com/util/lib/json-equal/deepEqual'; const benchmark: IBenchmark = { name: 'Encoding', diff --git a/src/__bench__/bench.json.decoding.ts b/src/__bench__/bench.json.decoding.ts index 6e92fcb..0f4e9cf 100644 --- a/src/__bench__/bench.json.decoding.ts +++ b/src/__bench__/bench.json.decoding.ts @@ -3,7 +3,7 @@ import {runBenchmark, IBenchmark} from '../__bench__/runBenchmark'; import {JsonDecoder} from '../json/JsonDecoder'; import {payloads} from '../__bench__/payloads'; -import {deepEqual} from '../json-equal/deepEqual'; +import {deepEqual} from '@jsonjoy.com/util/lib/json-equal/deepEqual'; const encodedPayloads = payloads.map((payload) => { return { diff --git a/src/__bench__/bench.json.encoding.ts b/src/__bench__/bench.json.encoding.ts index 0844472..c4bd09a 100644 --- a/src/__bench__/bench.json.encoding.ts +++ b/src/__bench__/bench.json.encoding.ts @@ -2,9 +2,9 @@ import {runBenchmark, IBenchmark} from '../__bench__/runBenchmark'; import {JsonEncoder} from '../json/JsonEncoder'; -import {Writer} from '../util/buffers/Writer'; +import {Writer} from '@jsonjoy.com/util/lib/buffers/Writer'; import {payloads} from '../__bench__/payloads'; -import {deepEqual} from '../json-equal/deepEqual'; +import {deepEqual} from '@jsonjoy.com/util/lib/json-equal/deepEqual'; const safeStringify = require('fast-safe-stringify'); const benchmark: IBenchmark = { diff --git a/src/__bench__/bench.msgpack.decoding.ts b/src/__bench__/bench.msgpack.decoding.ts index 323228f..88a1b0b 100644 --- a/src/__bench__/bench.msgpack.decoding.ts +++ b/src/__bench__/bench.msgpack.decoding.ts @@ -5,7 +5,7 @@ import {MsgPackEncoderFast} from '../msgpack/MsgPackEncoderFast'; import {MsgPackDecoderFast} from '../msgpack/MsgPackDecoderFast'; import {MsgPackDecoder} from '../msgpack/MsgPackDecoder'; import {payloads} from '../__bench__/payloads'; -import {deepEqual} from '../json-equal/deepEqual'; +import {deepEqual} from '@jsonjoy.com/util/lib/json-equal/deepEqual'; const encoder = new MsgPackEncoderFast(); diff --git a/src/__bench__/bench.msgpack.encoding.ts b/src/__bench__/bench.msgpack.encoding.ts index 00d8776..60855d7 100644 --- a/src/__bench__/bench.msgpack.encoding.ts +++ b/src/__bench__/bench.msgpack.encoding.ts @@ -5,7 +5,7 @@ import {MsgPackEncoder} from '../msgpack/MsgPackEncoder'; import {MsgPackEncoderFast} from '../msgpack/MsgPackEncoderFast'; import {CborDecoder} from '../cbor/CborDecoder'; import {payloads} from '../__bench__/payloads'; -import {deepEqual} from '../json-equal/deepEqual'; +import {deepEqual} from '@jsonjoy.com/util/lib/json-equal/deepEqual'; const benchmark: IBenchmark = { name: 'MessagePack Encoding', diff --git a/src/__bench__/bench.slice.ts b/src/__bench__/bench.slice.ts index 6cc3902..a886492 100644 --- a/src/__bench__/bench.slice.ts +++ b/src/__bench__/bench.slice.ts @@ -4,7 +4,7 @@ import {runBenchmark, IBenchmark} from '../__bench__/runBenchmark'; import {CborEncoder} from '../cbor/CborEncoder'; import {CborDecoder} from '../cbor/CborDecoder'; import {payloads} from '../__bench__/payloads'; -import {deepEqual} from '../json-equal/deepEqual'; +import {deepEqual} from '@jsonjoy.com/util/lib/json-equal/deepEqual'; const encoder = new CborEncoder(); diff --git a/src/__bench__/bench.ubjson.decoding.ts b/src/__bench__/bench.ubjson.decoding.ts index 1893dd9..275e8a3 100644 --- a/src/__bench__/bench.ubjson.decoding.ts +++ b/src/__bench__/bench.ubjson.decoding.ts @@ -3,9 +3,9 @@ import {runBenchmark, IBenchmark} from '../__bench__/runBenchmark'; import {UbjsonEncoder} from '../ubjson/UbjsonEncoder'; import {UbjsonDecoder} from '../ubjson/UbjsonDecoder'; -import {Writer} from '../util/buffers/Writer'; +import {Writer} from '@jsonjoy.com/util/lib/buffers/Writer'; import {payloads} from '../__bench__/payloads'; -import {deepEqual} from '../json-equal/deepEqual'; +import {deepEqual} from '@jsonjoy.com/util/lib/json-equal/deepEqual'; const encoder = new UbjsonEncoder(new Writer()); const encodedPayloads = payloads.map((payload) => { diff --git a/src/__bench__/bench.ubjson.encoding.ts b/src/__bench__/bench.ubjson.encoding.ts index 45c6a6a..92d4337 100644 --- a/src/__bench__/bench.ubjson.encoding.ts +++ b/src/__bench__/bench.ubjson.encoding.ts @@ -2,7 +2,7 @@ import {runBenchmark, IBenchmark} from '../__bench__/runBenchmark'; import {UbjsonEncoder} from '../ubjson/UbjsonEncoder'; -import {Writer} from '../util/buffers/Writer'; +import {Writer} from '@jsonjoy.com/util/lib/buffers/Writer'; import {payloads} from '../__bench__/payloads'; const benchmark: IBenchmark = { diff --git a/src/__bench__/bench.writer-size.ts b/src/__bench__/bench.writer-size.ts index 1d41c9d..b543fd5 100644 --- a/src/__bench__/bench.writer-size.ts +++ b/src/__bench__/bench.writer-size.ts @@ -4,8 +4,8 @@ import {runBenchmark, IBenchmark} from '../__bench__/runBenchmark'; import {CborEncoder} from '../cbor/CborEncoder'; import {CborDecoder} from '../cbor/CborDecoder'; import {payloads} from '../__bench__/payloads'; -import {deepEqual} from '../json-equal/deepEqual'; -import {Writer} from '../util/buffers/Writer'; +import {deepEqual} from '@jsonjoy.com/util/lib/json-equal/deepEqual'; +import {Writer} from '@jsonjoy.com/util/lib/buffers/Writer'; const benchmark: IBenchmark = { name: 'Encoding', diff --git a/src/__bench__/profiler/time.ts b/src/__bench__/profiler/time.ts index 5d26700..dce8e27 100644 --- a/src/__bench__/profiler/time.ts +++ b/src/__bench__/profiler/time.ts @@ -1,7 +1,7 @@ /* tslint:disable no-console */ import {MsgPackEncoderFast} from '../../msgpack/MsgPackEncoderFast'; -import {Writer} from '../../util/buffers/Writer'; +import {Writer} from '@jsonjoy.com/util/lib/buffers/Writer'; const json = [1234]; diff --git a/src/__demos__/json.ts b/src/__demos__/json.ts index 4d83347..2129a62 100644 --- a/src/__demos__/json.ts +++ b/src/__demos__/json.ts @@ -8,7 +8,7 @@ import {JsonEncoder} from '../json/JsonEncoder'; import {JsonDecoder} from '../json/JsonDecoder'; -import {Writer} from '../util/buffers/Writer'; +import {Writer} from '@jsonjoy.com/util/lib/buffers/Writer'; const encoder = new JsonEncoder(new Writer()); const decoder = new JsonDecoder(); diff --git a/src/__demos__/ubjson.ts b/src/__demos__/ubjson.ts index ccc70fe..1b870f6 100644 --- a/src/__demos__/ubjson.ts +++ b/src/__demos__/ubjson.ts @@ -8,7 +8,7 @@ import {UbjsonEncoder} from '../ubjson/UbjsonEncoder'; import {UbjsonDecoder} from '../ubjson/UbjsonDecoder'; -import {Writer} from '../util/buffers/Writer'; +import {Writer} from '@jsonjoy.com/util/lib/buffers/Writer'; const encoder = new UbjsonEncoder(new Writer()); const decoder = new UbjsonDecoder(); diff --git a/src/bencode/BencodeDecoder.ts b/src/bencode/BencodeDecoder.ts index 704cdd1..6c309e7 100644 --- a/src/bencode/BencodeDecoder.ts +++ b/src/bencode/BencodeDecoder.ts @@ -1,4 +1,4 @@ -import {Reader} from '../util/buffers/Reader'; +import {Reader} from '@jsonjoy.com/util/lib/buffers/Reader'; import type {BinaryJsonDecoder, PackValue} from '../types'; export class BencodeDecoder implements BinaryJsonDecoder { diff --git a/src/bencode/BencodeEncoder.ts b/src/bencode/BencodeEncoder.ts index e7ca67d..ba21381 100644 --- a/src/bencode/BencodeEncoder.ts +++ b/src/bencode/BencodeEncoder.ts @@ -1,6 +1,6 @@ -import {utf8Size} from '../util/strings/utf8'; -import {sort} from '../util/sort/insertion'; -import type {IWriter, IWriterGrowable} from '../util/buffers'; +import {utf8Size} from '@jsonjoy.com/util/lib/strings/utf8'; +import {sort} from '@jsonjoy.com/util/lib/sort/insertion'; +import type {IWriter, IWriterGrowable} from '@jsonjoy.com/util/lib/buffers'; import type {BinaryJsonEncoder} from '../types'; export class BencodeEncoder implements BinaryJsonEncoder { diff --git a/src/bencode/__tests__/BencodeDecoder.spec.ts b/src/bencode/__tests__/BencodeDecoder.spec.ts index d19d088..39aa978 100644 --- a/src/bencode/__tests__/BencodeDecoder.spec.ts +++ b/src/bencode/__tests__/BencodeDecoder.spec.ts @@ -1,7 +1,7 @@ -import {Writer} from '../../util/buffers/Writer'; +import {Writer} from '@jsonjoy.com/util/lib/buffers/Writer'; +import {utf8} from '@jsonjoy.com/util/lib/buffers/strings'; import {BencodeEncoder} from '../BencodeEncoder'; import {BencodeDecoder} from '../BencodeDecoder'; -import {utf8} from '../../util/buffers/strings'; const decoder = new BencodeDecoder(); diff --git a/src/bencode/__tests__/BencodeEncoder.spec.ts b/src/bencode/__tests__/BencodeEncoder.spec.ts index 20e33ba..1225be0 100644 --- a/src/bencode/__tests__/BencodeEncoder.spec.ts +++ b/src/bencode/__tests__/BencodeEncoder.spec.ts @@ -1,6 +1,5 @@ -import {utf8} from '../../util/buffers/strings'; -import {Writer} from '../../util/buffers/Writer'; -import {PackValue} from '../../types'; +import {utf8} from '@jsonjoy.com/util/lib/buffers/strings'; +import {Writer} from '@jsonjoy.com/util/lib/buffers/Writer'; import {BencodeEncoder} from '../BencodeEncoder'; const writer = new Writer(32); diff --git a/src/bencode/__tests__/automated.spec.ts b/src/bencode/__tests__/automated.spec.ts index 3692fbe..12eee24 100644 --- a/src/bencode/__tests__/automated.spec.ts +++ b/src/bencode/__tests__/automated.spec.ts @@ -1,7 +1,7 @@ -import {Writer} from '../../util/buffers/Writer'; +import {Writer} from '@jsonjoy.com/util/lib/buffers/Writer'; import {BencodeEncoder} from '../BencodeEncoder'; import {BencodeDecoder} from '../BencodeDecoder'; -import {utf8} from '../../util/buffers/strings'; +import {utf8} from '@jsonjoy.com/util/lib/buffers/strings'; const writer = new Writer(8); const encoder = new BencodeEncoder(writer); diff --git a/src/bson/BsonEncoder.ts b/src/bson/BsonEncoder.ts index 98b9e1b..fa39c0f 100644 --- a/src/bson/BsonEncoder.ts +++ b/src/bson/BsonEncoder.ts @@ -11,7 +11,7 @@ import { BsonObjectId, BsonTimestamp, } from './values'; -import type {IWriter, IWriterGrowable} from '../util/buffers'; +import type {IWriter, IWriterGrowable} from '@jsonjoy.com/util/lib/buffers'; import type {BinaryJsonEncoder} from '../types'; export class BsonEncoder implements BinaryJsonEncoder { diff --git a/src/bson/__tests__/BsonEncoder-values.spec.ts b/src/bson/__tests__/BsonEncoder-values.spec.ts index add4fc7..1e0289e 100644 --- a/src/bson/__tests__/BsonEncoder-values.spec.ts +++ b/src/bson/__tests__/BsonEncoder-values.spec.ts @@ -1,5 +1,5 @@ import {BSON, Decimal128, MinKey, MaxKey} from 'bson'; -import {Writer} from '../../util/buffers/Writer'; +import {Writer} from '@jsonjoy.com/util/lib/buffers/Writer'; import {BsonEncoder} from '../BsonEncoder'; import { BsonBinary, diff --git a/src/bson/__tests__/BsonEncoder.spec.ts b/src/bson/__tests__/BsonEncoder.spec.ts index f3d6abf..fc8a56d 100644 --- a/src/bson/__tests__/BsonEncoder.spec.ts +++ b/src/bson/__tests__/BsonEncoder.spec.ts @@ -1,5 +1,5 @@ import {BSON} from 'bson'; -import {Writer} from '../../util/buffers/Writer'; +import {Writer} from '@jsonjoy.com/util/lib/buffers/Writer'; import {BsonEncoder} from '../BsonEncoder'; const writer = new Writer(8); diff --git a/src/bson/__tests__/codec.spec.ts b/src/bson/__tests__/codec.spec.ts index 783a5f6..7a65e92 100644 --- a/src/bson/__tests__/codec.spec.ts +++ b/src/bson/__tests__/codec.spec.ts @@ -1,7 +1,7 @@ import {BSON} from 'bson'; import {documents} from '../../__tests__/json-documents'; import {BsonEncoder} from '../BsonEncoder'; -import {Writer} from '../../util/buffers/Writer'; +import {Writer} from '@jsonjoy.com/util/lib/buffers/Writer'; const run = (encoder: BsonEncoder) => { describe('JSON documents', () => { diff --git a/src/cbor/CborDecoder.ts b/src/cbor/CborDecoder.ts index b149974..951cf24 100644 --- a/src/cbor/CborDecoder.ts +++ b/src/cbor/CborDecoder.ts @@ -2,7 +2,7 @@ import {CONST, ERROR, MAJOR} from './constants'; import {CborDecoderBase} from './CborDecoderBase'; import {JsonPackValue} from '../JsonPackValue'; import type {Path} from '../json-pointer'; -import type {IReader, IReaderResettable} from '../util/buffers'; +import type {IReader, IReaderResettable} from '@jsonjoy.com/util/lib/buffers'; export class CborDecoder< R extends IReader & IReaderResettable = IReader & IReaderResettable, diff --git a/src/cbor/CborDecoderBase.ts b/src/cbor/CborDecoderBase.ts index fc725de..4ed7a67 100644 --- a/src/cbor/CborDecoderBase.ts +++ b/src/cbor/CborDecoderBase.ts @@ -1,11 +1,11 @@ import {CONST, ERROR, MAJOR} from './constants'; -import {decodeF16} from '../util/buffers/f16'; +import {decodeF16} from '@jsonjoy.com/util/lib/buffers/f16'; import {JsonPackExtension} from '../JsonPackExtension'; import {JsonPackValue} from '../JsonPackValue'; -import {Reader} from '../util/buffers/Reader'; -import sharedCachedUtf8Decoder from '../util/buffers/utf8/sharedCachedUtf8Decoder'; -import type {CachedUtf8Decoder} from '../util/buffers/utf8/CachedUtf8Decoder'; -import type {IReader, IReaderResettable} from '../util/buffers'; +import {Reader} from '@jsonjoy.com/util/lib/buffers/Reader'; +import sharedCachedUtf8Decoder from '@jsonjoy.com/util/lib/buffers/utf8/sharedCachedUtf8Decoder'; +import type {CachedUtf8Decoder} from '@jsonjoy.com/util/lib/buffers/utf8/CachedUtf8Decoder'; +import type {IReader, IReaderResettable} from '@jsonjoy.com/util/lib/buffers'; import type {BinaryJsonDecoder, PackValue} from '../types'; export class CborDecoderBase diff --git a/src/cbor/CborEncoder.ts b/src/cbor/CborEncoder.ts index aea5c92..706f0ee 100644 --- a/src/cbor/CborEncoder.ts +++ b/src/cbor/CborEncoder.ts @@ -1,8 +1,8 @@ -import {isFloat32} from '../util/buffers/isFloat32'; +import {isFloat32} from '@jsonjoy.com/util/lib/buffers/isFloat32'; import {JsonPackExtension} from '../JsonPackExtension'; import {CborEncoderFast} from './CborEncoderFast'; -import type {IWriter, IWriterGrowable} from '../util/buffers'; import {JsonPackValue} from '../JsonPackValue'; +import type {IWriter, IWriterGrowable} from '@jsonjoy.com/util/lib/buffers'; export class CborEncoder extends CborEncoderFast { /** diff --git a/src/cbor/CborEncoderFast.ts b/src/cbor/CborEncoderFast.ts index 69a20cc..e819011 100644 --- a/src/cbor/CborEncoderFast.ts +++ b/src/cbor/CborEncoderFast.ts @@ -1,8 +1,8 @@ -import {Writer} from '../util/buffers/Writer'; +import {Writer} from '@jsonjoy.com/util/lib/buffers/Writer'; import {CONST, MAJOR_OVERLAY} from './constants'; -import type {IWriter, IWriterGrowable} from '../util/buffers'; +import type {IWriter, IWriterGrowable} from '@jsonjoy.com/util/lib/buffers'; import type {BinaryJsonEncoder, StreamingBinaryJsonEncoder, TlvBinaryJsonEncoder} from '../types'; -import type {Slice} from '../util/buffers/Slice'; +import type {Slice} from '@jsonjoy.com/util/lib/buffers/Slice'; const isSafeInteger = Number.isSafeInteger; diff --git a/src/cbor/CborEncoderStable.ts b/src/cbor/CborEncoderStable.ts index 02d7796..8fe9647 100644 --- a/src/cbor/CborEncoderStable.ts +++ b/src/cbor/CborEncoderStable.ts @@ -1,7 +1,7 @@ import {CborEncoder} from './CborEncoder'; -import {sort} from '../util/sort/insertion2'; +import {sort} from '@jsonjoy.com/util/lib/sort/insertion2'; import {MAJOR_OVERLAY} from './constants'; -import {objKeyCmp} from '../util/objKeyCmp'; +import {objKeyCmp} from '@jsonjoy.com/util/lib/objKeyCmp'; const strHeaderLength = (strSize: number): 1 | 2 | 3 | 5 => { if (strSize <= 23) return 1; diff --git a/src/cbor/__tests__/CborDecoderDag.spec.ts b/src/cbor/__tests__/CborDecoderDag.spec.ts index e61e929..cbc539b 100644 --- a/src/cbor/__tests__/CborDecoderDag.spec.ts +++ b/src/cbor/__tests__/CborDecoderDag.spec.ts @@ -1,4 +1,4 @@ -import {Writer} from '../../util/buffers/Writer'; +import {Writer} from '@jsonjoy.com/util/lib/buffers/Writer'; import {CborEncoderStable} from '../CborEncoderStable'; import {CborDecoderDag} from '../CborDecoderDag'; import {JsonPackExtension} from '../../JsonPackExtension'; diff --git a/src/cbor/__tests__/CborEncoder.spec.ts b/src/cbor/__tests__/CborEncoder.spec.ts index 67fb4cf..ee9ef4c 100644 --- a/src/cbor/__tests__/CborEncoder.spec.ts +++ b/src/cbor/__tests__/CborEncoder.spec.ts @@ -1,4 +1,4 @@ -import {Writer} from '../../util/buffers/Writer'; +import {Writer} from '@jsonjoy.com/util/lib/buffers/Writer'; import {JsonPackValue} from '../../JsonPackValue'; import {CborEncoder} from '../CborEncoder'; import {decode} from 'cbor'; diff --git a/src/cbor/__tests__/CborEncoderDag.spec.ts b/src/cbor/__tests__/CborEncoderDag.spec.ts index 59bbf0c..83842e5 100644 --- a/src/cbor/__tests__/CborEncoderDag.spec.ts +++ b/src/cbor/__tests__/CborEncoderDag.spec.ts @@ -1,4 +1,4 @@ -import {Writer} from '../../util/buffers/Writer'; +import {Writer} from '@jsonjoy.com/util/lib/buffers/Writer'; import {CborEncoderDag} from '../CborEncoderDag'; import {CborDecoder} from '../CborDecoder'; import {JsonPackExtension} from '../../JsonPackExtension'; diff --git a/src/cbor/__tests__/CborEncoderStable.spec.ts b/src/cbor/__tests__/CborEncoderStable.spec.ts index 600e0c3..2f526c3 100644 --- a/src/cbor/__tests__/CborEncoderStable.spec.ts +++ b/src/cbor/__tests__/CborEncoderStable.spec.ts @@ -1,4 +1,4 @@ -import {Writer} from '../../util/buffers/Writer'; +import {Writer} from '@jsonjoy.com/util/lib/buffers/Writer'; import {CborEncoderStable} from '../CborEncoderStable'; import {encode} from 'cborg'; diff --git a/src/cbor/__tests__/fuzzing.spec.ts b/src/cbor/__tests__/fuzzing.spec.ts index 387c9cd..9994f4f 100644 --- a/src/cbor/__tests__/fuzzing.spec.ts +++ b/src/cbor/__tests__/fuzzing.spec.ts @@ -1,4 +1,4 @@ -import {RandomJson} from '../../json-random'; +import {RandomJson} from '@jsonjoy.com/util/lib/json-random'; import {CborEncoderFast} from '../CborEncoderFast'; import {CborEncoder} from '../CborEncoder'; import {CborEncoderStable} from '../CborEncoderStable'; diff --git a/src/cbor/__tests__/shallow-read.genShallowRead.spec.ts b/src/cbor/__tests__/shallow-read.genShallowRead.spec.ts index d966d2a..544a35e 100644 --- a/src/cbor/__tests__/shallow-read.genShallowRead.spec.ts +++ b/src/cbor/__tests__/shallow-read.genShallowRead.spec.ts @@ -2,7 +2,7 @@ import {genShallowReader} from '../../msgpack/shallow-read'; import {CborEncoder} from '../CborEncoder'; import {CborDecoder} from '../CborDecoder'; import {Path} from '../../json-pointer'; -import {Writer} from '../../util/buffers/Writer'; +import {Writer} from '@jsonjoy.com/util/lib/buffers/Writer'; const assetShallowRead = (doc: unknown, path: Path): void => { const writer = new Writer(1); diff --git a/src/codecs/Codecs.ts b/src/codecs/Codecs.ts index 7b71b6a..fe2e0dd 100644 --- a/src/codecs/Codecs.ts +++ b/src/codecs/Codecs.ts @@ -1,4 +1,4 @@ -import {Writer} from '../util/buffers/Writer'; +import {Writer} from '@jsonjoy.com/util/lib/buffers/Writer'; import {CborJsonValueCodec} from './cbor'; import {JsonJsonValueCodec} from './json'; import {MsgPackJsonValueCodec} from './msgpack'; diff --git a/src/codecs/cbor.ts b/src/codecs/cbor.ts index 29fd39c..1b4d373 100644 --- a/src/codecs/cbor.ts +++ b/src/codecs/cbor.ts @@ -1,7 +1,7 @@ import {CborDecoder} from '../cbor/CborDecoder'; import {CborEncoder} from '../cbor/CborEncoder'; import {EncodingFormat} from '../constants'; -import type {Writer} from '../util/buffers/Writer'; +import type {Writer} from '@jsonjoy.com/util/lib/buffers/Writer'; import type {JsonValueCodec} from './types'; export class CborJsonValueCodec implements JsonValueCodec { diff --git a/src/codecs/json.ts b/src/codecs/json.ts index 48a14b4..0484d54 100644 --- a/src/codecs/json.ts +++ b/src/codecs/json.ts @@ -1,7 +1,7 @@ import {EncodingFormat} from '../constants'; import {JsonEncoder} from '../json/JsonEncoder'; import {JsonDecoder} from '../json/JsonDecoder'; -import type {Writer} from '../util/buffers/Writer'; +import type {Writer} from '@jsonjoy.com/util/lib/buffers/Writer'; import type {JsonValueCodec} from './types'; export class JsonJsonValueCodec implements JsonValueCodec { diff --git a/src/codecs/msgpack.ts b/src/codecs/msgpack.ts index 2910e79..ac8450f 100644 --- a/src/codecs/msgpack.ts +++ b/src/codecs/msgpack.ts @@ -1,7 +1,7 @@ import {EncodingFormat} from '../constants'; import {MsgPackEncoder} from '../msgpack'; import {MsgPackDecoder} from '../msgpack/MsgPackDecoder'; -import type {Writer} from '../util/buffers/Writer'; +import type {Writer} from '@jsonjoy.com/util/lib/buffers/Writer'; import type {JsonValueCodec} from './types'; export class MsgPackJsonValueCodec implements JsonValueCodec { diff --git a/src/ion/IonEncoderFast.ts b/src/ion/IonEncoderFast.ts index d79d1bc..b737481 100644 --- a/src/ion/IonEncoderFast.ts +++ b/src/ion/IonEncoderFast.ts @@ -1,5 +1,5 @@ -import type {IWriter, IWriterGrowable} from '../util/buffers'; -import {Writer} from '../util/buffers/Writer'; +import type {IWriter, IWriterGrowable} from '@jsonjoy.com/util/lib/buffers'; +import {Writer} from '@jsonjoy.com/util/lib/buffers/Writer'; import { AnnotationAstNode, ArrAstNode, diff --git a/src/ion/ast.ts b/src/ion/ast.ts index e85781a..dc50468 100644 --- a/src/ion/ast.ts +++ b/src/ion/ast.ts @@ -1,4 +1,4 @@ -import {utf8Size} from '../util/strings/utf8'; +import {utf8Size} from '@jsonjoy.com/util/lib/strings/utf8'; import {Import} from './Import'; export interface AstNode { diff --git a/src/json-binary/codec.ts b/src/json-binary/codec.ts index d766ad5..e717cfa 100644 --- a/src/json-binary/codec.ts +++ b/src/json-binary/codec.ts @@ -1,7 +1,7 @@ import {JsonPackExtension, JsonPackValue} from '../msgpack'; import {fromBase64} from '@jsonjoy.com/base64/lib/fromBase64'; import {toBase64} from '@jsonjoy.com/base64/lib/toBase64'; -import {isUint8Array} from '../util/buffers/isUint8Array'; +import {isUint8Array} from '@jsonjoy.com/util/lib/buffers/isUint8Array'; import {binUriStart, msgPackExtStart, msgPackUriStart} from './constants'; import {binary_string} from './types'; diff --git a/src/json-binary/types.ts b/src/json-binary/types.ts index 9fe7e80..b9a8406 100644 --- a/src/json-binary/types.ts +++ b/src/json-binary/types.ts @@ -1,6 +1,6 @@ import type {MsgPack} from '../msgpack'; import type {CborUint8Array} from '../cbor/types'; -import type {Brand} from '../util/types'; +import type {Brand} from '@jsonjoy.com/util/lib/types'; export type base64_string = Brand; export type binary_string = Brand< diff --git a/src/json-brand/README.md b/src/json-brand/README.md deleted file mode 100644 index 7f4c63b..0000000 --- a/src/json-brand/README.md +++ /dev/null @@ -1,12 +0,0 @@ -# json-brand - -TypeScript branded type for a JSON string. - -```ts -import {JSON, json} from 'json-pack/lib/json-brand'; - -const str = '{"hello": "world"}' as json<{hello: string}>; - -JSON.parse(str).hello; // OK -JSON.parse(str).foo; // Error: ... -``` diff --git a/src/json-brand/global.d.ts b/src/json-brand/global.d.ts deleted file mode 100644 index b9a6ec2..0000000 --- a/src/json-brand/global.d.ts +++ /dev/null @@ -1,7 +0,0 @@ -declare global { - interface JSON { - parse(text: json, reviver?: (key: any, value: any) => any): T; - stringify(value: T, replacer?: (key: string, value: any) => any, space?: string | number): json; - stringify(value: T, replacer?: (number | string)[] | null, space?: string | number): json; - } -} diff --git a/src/json-brand/index.d.ts b/src/json-brand/index.d.ts deleted file mode 100644 index a6c51e2..0000000 --- a/src/json-brand/index.d.ts +++ /dev/null @@ -1,10 +0,0 @@ -export type json = string & {__JSON__: T}; -export type json_string = json; - -export interface JSON { - parse(text: json, reviver?: (key: any, value: any) => any): T; - stringify(value: T, replacer?: (key: string, value: any) => any, space?: string | number): json; - stringify(value: T, replacer?: (number | string)[] | null, space?: string | number): json; -} - -export const JSON: JSON; diff --git a/src/json-brand/index.ts b/src/json-brand/index.ts deleted file mode 100644 index 2a85af0..0000000 --- a/src/json-brand/index.ts +++ /dev/null @@ -1,5 +0,0 @@ -import * as type from './types'; - -export const JSON = (typeof global !== 'undefined' ? global.JSON : window.JSON) as unknown as type.JSON; - -export type {json, json_string} from './types'; diff --git a/src/json-brand/types.ts b/src/json-brand/types.ts deleted file mode 100644 index b3735b1..0000000 --- a/src/json-brand/types.ts +++ /dev/null @@ -1,9 +0,0 @@ -export type json = json_string; - -export type json_string = string & {__BRAND__: 'JSON_STRING'; __TYPE__: T}; - -export interface JSON { - parse(text: json, reviver?: (key: any, value: any) => any): T; - stringify(value: T, replacer?: (key: string, value: any) => any, space?: string | number): json; - stringify(value: T, replacer?: (number | string)[] | null, space?: string | number): json; -} diff --git a/src/json-equal/$$deepEqual/__tests__/deepEqual.fuzzing.spec.ts b/src/json-equal/$$deepEqual/__tests__/deepEqual.fuzzing.spec.ts deleted file mode 100644 index c089cb8..0000000 --- a/src/json-equal/$$deepEqual/__tests__/deepEqual.fuzzing.spec.ts +++ /dev/null @@ -1,22 +0,0 @@ -import {$$deepEqual} from '..'; -import {RandomJson} from '../../../json-random/RandomJson'; - -const deepEqual = (a: unknown, b: unknown) => { - const js = $$deepEqual(a); - const fn = eval(js); // tslint:disable-line - return fn(b); -}; - -for (let i = 0; i < 100; i++) { - const json1 = RandomJson.generate(); - const json2 = JSON.parse(JSON.stringify(json1)); - - test('iteration ' + (i + 1), () => { - const res1 = deepEqual(json1, json1); - const res2 = deepEqual(json1, json2); - const res3 = deepEqual(json2, json1); - expect(res1).toBe(true); - expect(res2).toBe(true); - expect(res3).toBe(true); - }); -} diff --git a/src/json-equal/$$deepEqual/__tests__/deepEqual.spec.ts b/src/json-equal/$$deepEqual/__tests__/deepEqual.spec.ts deleted file mode 100644 index 4f40619..0000000 --- a/src/json-equal/$$deepEqual/__tests__/deepEqual.spec.ts +++ /dev/null @@ -1,10 +0,0 @@ -import {$$deepEqual} from '..'; -import {runDeepEqualTestSuite} from '../../deepEqual/__tests__/runDeepEqualTestSuite'; - -const deepEqual = (a: unknown, b: unknown) => { - const js = $$deepEqual(a); - const fn = eval(js); // tslint:disable-line - return fn(b); -}; - -runDeepEqualTestSuite(deepEqual); diff --git a/src/json-equal/$$deepEqual/__tests__/deepEqualCodegen.spec.ts b/src/json-equal/$$deepEqual/__tests__/deepEqualCodegen.spec.ts deleted file mode 100644 index ce48b47..0000000 --- a/src/json-equal/$$deepEqual/__tests__/deepEqualCodegen.spec.ts +++ /dev/null @@ -1,55 +0,0 @@ -import {$$deepEqual} from '..'; - -test('generates a deep equal comparator', () => { - const js = $$deepEqual([1, true, false, 'sdf', {foo: 123, null: null}, [null, true, 'asdf'], 3, {}]); - const deepEqual = eval(js); // tslint:disable-line - - const res1 = deepEqual([1, true, false, 'sdf', {foo: 123, null: null}, [null, true, 'asdf'], 3, {}]); - const res2 = deepEqual([2, true, false, 'sdf', {foo: 123, null: null}, [null, true, 'asdf'], 3, {}]); - const res3 = deepEqual([1, true, false, 'sdf', {foox: 123, null: null}, [null, true, 'asdf'], 3, {}]); - const res4 = deepEqual([1, true, false, 'sdf', {foo: 123, null: null}, [null, true, 'asdf'], 3, {a: 1}]); - - expect(res1).toBe(true); - expect(res2).toBe(false); - expect(res3).toBe(false); - expect(res4).toBe(false); -}); - -test('generates a deep equal comparator for primitives', () => { - /* tslint:disable */ - const equal1 = eval($$deepEqual('asdf')); - const equal2 = eval($$deepEqual(123)); - const equal3 = eval($$deepEqual(true)); - const equal4 = eval($$deepEqual(null)); - const equal5 = eval($$deepEqual(false)); - const equal6 = eval($$deepEqual(4.4)); - /* tslint:enable */ - - expect(equal1('asdf')).toBe(true); - expect(equal1('asdf2')).toBe(false); - - expect(equal2(123)).toBe(true); - expect(equal2(1234)).toBe(false); - - expect(equal3(true)).toBe(true); - expect(equal3(false)).toBe(false); - expect(equal3(null)).toBe(false); - - expect(equal4(true)).toBe(false); - expect(equal4(false)).toBe(false); - expect(equal4(null)).toBe(true); - - expect(equal5(true)).toBe(false); - expect(equal5(false)).toBe(true); - expect(equal5(null)).toBe(false); - - expect(equal6(4.4)).toBe(true); - expect(equal6(4)).toBe(false); -}); - -test('undefined is not an empty object', () => { - const js = $$deepEqual(undefined); - const deepEqual = eval(js); // tslint:disable-line - const res = deepEqual({}); - expect(res).toBe(false); -}); diff --git a/src/json-equal/$$deepEqual/index.ts b/src/json-equal/$$deepEqual/index.ts deleted file mode 100644 index 5b98253..0000000 --- a/src/json-equal/$$deepEqual/index.ts +++ /dev/null @@ -1 +0,0 @@ -export * from './v1'; diff --git a/src/json-equal/$$deepEqual/v1.ts b/src/json-equal/$$deepEqual/v1.ts deleted file mode 100644 index 87a2c34..0000000 --- a/src/json-equal/$$deepEqual/v1.ts +++ /dev/null @@ -1,62 +0,0 @@ -import {JavaScript} from '../../util/codegen'; - -const codegenValue = (doc: unknown, code: string[], r: number): number => { - let rr = r; - const type = typeof doc; - const isPrimitive = doc === null || type === 'boolean' || type === 'string' || type === 'number'; - - // Primitives - if (isPrimitive) { - if (doc === Infinity) { - code.push(`if(r${r} !== Infinity)return false;`); - } else if (doc === -Infinity) { - code.push(`if(r${r} !== -Infinity)return false;`); - } else { - code.push(`if(r${r} !== ${JSON.stringify(doc)})return false;`); - } - return rr; - } - - // Arrays - if (Array.isArray(doc)) { - code.push(`if(!Array.isArray(r${r}) || r${r}.length !== ${doc.length})return false;`); - for (let i = 0; i < doc.length; i++) { - rr++; - code.push(`var r${rr}=r${r}[${i}];`); - rr = codegenValue(doc[i], code, rr); - } - return rr; - } - - // Objects - if (type === 'object' && doc) { - const obj = doc as Record; - const keys = Object.keys(obj); - code.push( - `if(!r${r} || typeof r${r} !== "object" || Array.isArray(r${r}) || Object.keys(r${r}).length !== ${keys.length})return false;`, - ); - for (const key of keys) { - rr++; - code.push(`var r${rr}=r${r}[${JSON.stringify(key)}];`); - rr = codegenValue(obj[key], code, rr); - } - } - - // Undefined - if (doc === undefined) { - code.push(`if(r${r} !== undefined)return false;`); - return rr; - } - - return rr; -}; - -export const $$deepEqual = (a: unknown): JavaScript<(b: unknown) => boolean> => { - const code: string[] = []; - codegenValue(a, code, 0); - - const fn = ['(function(r0){', ...code, 'return true;', '})']; - - // return fn.join('\n') as JavaScript<(b: unknown) => boolean>; - return fn.join('') as JavaScript<(b: unknown) => boolean>; -}; diff --git a/src/json-equal/README.md b/src/json-equal/README.md deleted file mode 100644 index b4993fb..0000000 --- a/src/json-equal/README.md +++ /dev/null @@ -1,49 +0,0 @@ -# json-equal - -This library contains the fastest JSON deep comparison algorithms. - -- `deepEqual` — deep comparison of JSON objects. Faster than `fast-deep-equal` and - `fast-equals` packages. -- `$$deepEqual` — if the comparison JSON object is known in advance, this function - can pre-compile a javascript function for comparison, which is about an order of magnitude - faster than `deepEqual`. - - -## Reference - - -### `deepEqual` - -```ts -import {deepEqual} from 'lib/json-equal/deepEqual'; - -deepEqual(a, b); // true/false -``` - - -### `$$deepEqual` - -```ts -import {$$deepEqual} from 'lib/json-equal/$$deepEqual'; - -const js = $$deepEqual(a); -const fn = eval(js); - -fn(b); // true/false -``` - - -## Benchmarks - -``` -node benchmarks/json-equal/bench.deepEqual.js -json-equal (v1) x 873,303 ops/sec ±0.34% (96 runs sampled), 1145 ns/op -json-equal (v2) x 664,673 ops/sec ±0.44% (97 runs sampled), 1504 ns/op -json-equal (v3) x 710,572 ops/sec ±0.15% (100 runs sampled), 1407 ns/op -fast-deep-equal x 620,740 ops/sec ±0.34% (101 runs sampled), 1611 ns/op -fast-equals x 812,390 ops/sec ±0.11% (101 runs sampled), 1231 ns/op -lodash.isEqual x 182,440 ops/sec ±0.18% (98 runs sampled), 5481 ns/op -json-equal/deepEqualCodegen x 6,161,316 ops/sec ±0.30% (101 runs sampled), 162 ns/op -json-equal/deepEqualCodegen (with codegen) x 47,583 ops/sec ±0.11% (100 runs sampled), 21016 ns/op -Fastest is json-equal/deepEqualCodegen -``` diff --git a/src/json-equal/__bench__/bench.deepEqual.ts b/src/json-equal/__bench__/bench.deepEqual.ts deleted file mode 100644 index 6430e6f..0000000 --- a/src/json-equal/__bench__/bench.deepEqual.ts +++ /dev/null @@ -1,65 +0,0 @@ -/* tslint:disable no-console */ - -import * as Benchmark from 'benchmark'; -import {deepEqual as deepEqualV1} from '../deepEqual/v1'; -import {deepEqual as deepEqualV2} from '../deepEqual/v2'; -import {deepEqual as deepEqualV3} from '../deepEqual/v3'; -import {deepEqual as deepEqualV4} from '../deepEqual/v3'; -import {$$deepEqual} from '../$$deepEqual'; -const fastDeepEqual = require('fast-deep-equal/es6'); -const fastEquals = require('fast-equals').deepEqual; -const lodashIsEqual = require('lodash').isEqual; - -const json1 = { - foo: 'bar', - ff: 123, - gg: [4, 3, 'f'], -}; -const json2 = { - foo: 'bar', - ff: 123, - gg: [4, 3, 'f.'], -}; - -// tslint:disable-next-line no-eval eval ban -const equalGenerated1 = eval($$deepEqual(json1)); - -const suite = new Benchmark.Suite(); - -suite - .add(`json-equal (v1)`, () => { - deepEqualV1(json1, json2); - }) - .add(`json-equal (v2)`, () => { - deepEqualV2(json1, json2); - }) - .add(`json-equal (v3)`, () => { - deepEqualV3(json1, json2); - }) - .add(`json-equal (v4)`, () => { - deepEqualV4(json1, json2); - }) - .add(`fast-deep-equal`, () => { - fastDeepEqual(json1, json2); - }) - .add(`fast-equals`, () => { - fastEquals(json1, json2); - }) - .add(`lodash.isEqual`, () => { - lodashIsEqual(json1, json2); - }) - .add(`json-equal/$$deepEqual`, () => { - equalGenerated1(json2); - }) - .add(`json-equal/$$deepEqual (with codegen)`, () => { - // tslint:disable-next-line no-eval eval ban - const equalGenerated1 = eval($$deepEqual(json1)); - equalGenerated1(json2); - }) - .on('cycle', (event: any) => { - console.log(String(event.target) + `, ${Math.round(1000000000 / event.target.hz)} ns/op`); - }) - .on('complete', () => { - console.log('Fastest is ' + suite.filter('fastest').map('name')); - }) - .run(); diff --git a/src/json-equal/deepEqual/__tests__/deepEqual.fuzzing.spec.ts b/src/json-equal/deepEqual/__tests__/deepEqual.fuzzing.spec.ts deleted file mode 100644 index 6d570d8..0000000 --- a/src/json-equal/deepEqual/__tests__/deepEqual.fuzzing.spec.ts +++ /dev/null @@ -1,16 +0,0 @@ -import {deepEqual} from '../../deepEqual'; -import {RandomJson} from '../../../json-random/RandomJson'; - -for (let i = 0; i < 100; i++) { - const json1 = RandomJson.generate(); - const json2 = JSON.parse(JSON.stringify(json1)); - - test('iteration ' + (i + 1), () => { - const res1 = deepEqual(json1, json1); - const res2 = deepEqual(json1, json2); - const res3 = deepEqual(json2, json1); - expect(res1).toBe(true); - expect(res2).toBe(true); - expect(res3).toBe(true); - }); -} diff --git a/src/json-equal/deepEqual/__tests__/deepEqual.spec.ts b/src/json-equal/deepEqual/__tests__/deepEqual.spec.ts deleted file mode 100644 index 4f15b99..0000000 --- a/src/json-equal/deepEqual/__tests__/deepEqual.spec.ts +++ /dev/null @@ -1,4 +0,0 @@ -import {deepEqual} from '../../deepEqual'; -import {runDeepEqualTestSuite} from './runDeepEqualTestSuite'; - -runDeepEqualTestSuite(deepEqual); diff --git a/src/json-equal/deepEqual/__tests__/runDeepEqualTestSuite.ts b/src/json-equal/deepEqual/__tests__/runDeepEqualTestSuite.ts deleted file mode 100644 index e79a11f..0000000 --- a/src/json-equal/deepEqual/__tests__/runDeepEqualTestSuite.ts +++ /dev/null @@ -1,16 +0,0 @@ -import {tests} from './tests'; - -export const runDeepEqualTestSuite = (deepEqual: (a: unknown, b: unknown) => boolean) => { - for (const s of tests) { - describe(s.description, () => { - for (const t of s.tests) { - test(t.description, () => { - const res1 = deepEqual(t.value1, t.value2); - const res2 = deepEqual(t.value1, t.value2); - expect(res1).toBe(t.equal); - expect(res2).toBe(t.equal); - }); - } - }); - } -}; diff --git a/src/json-equal/deepEqual/__tests__/tests.ts b/src/json-equal/deepEqual/__tests__/tests.ts deleted file mode 100644 index 5db01fe..0000000 --- a/src/json-equal/deepEqual/__tests__/tests.ts +++ /dev/null @@ -1,289 +0,0 @@ -interface Test { - description: string; - value1: unknown; - value2: unknown; - equal: boolean; -} - -interface Suite { - description: string; - tests: Test[]; -} - -export const tests: Suite[] = [ - { - description: 'scalars', - tests: [ - { - description: 'equal numbers', - value1: 1, - value2: 1, - equal: true, - }, - { - description: 'not equal numbers', - value1: 1, - value2: 2, - equal: false, - }, - { - description: 'number and array are not equal', - value1: 1, - value2: [], - equal: false, - }, - { - description: '0 and null are not equal', - value1: 0, - value2: null, - equal: false, - }, - { - description: 'equal strings', - value1: 'a', - value2: 'a', - equal: true, - }, - { - description: 'not equal strings', - value1: 'a', - value2: 'b', - equal: false, - }, - { - description: 'empty string and null are not equal', - value1: '', - value2: null, - equal: false, - }, - { - description: 'null is equal to null', - value1: null, - value2: null, - equal: true, - }, - { - description: 'equal booleans (true)', - value1: true, - value2: true, - equal: true, - }, - { - description: 'equal booleans (false)', - value1: false, - value2: false, - equal: true, - }, - { - description: 'not equal booleans', - value1: true, - value2: false, - equal: false, - }, - { - description: '1 and true are not equal', - value1: 1, - value2: true, - equal: false, - }, - { - description: '0 and false are not equal', - value1: 0, - value2: false, - equal: false, - }, - { - description: '0 and -0 are equal', - value1: 0, - value2: -0, - equal: true, - }, - { - description: 'Infinity and Infinity are equal', - value1: Infinity, - value2: Infinity, - equal: true, - }, - { - description: 'Infinity and -Infinity are not equal', - value1: Infinity, - value2: -Infinity, - equal: false, - }, - ], - }, - - { - description: 'objects', - tests: [ - { - description: 'empty objects are equal', - value1: {}, - value2: {}, - equal: true, - }, - { - description: 'equal objects (same properties "order")', - value1: {a: 1, b: '2'}, - value2: {a: 1, b: '2'}, - equal: true, - }, - { - description: 'equal objects (different properties "order")', - value1: {a: 1, b: '2'}, - value2: {b: '2', a: 1}, - equal: true, - }, - { - description: 'not equal objects (extra property)', - value1: {a: 1, b: '2'}, - value2: {a: 1, b: '2', c: []}, - equal: false, - }, - { - description: 'not equal objects (different property values)', - value1: {a: 1, b: '2', c: 3}, - value2: {a: 1, b: '2', c: 4}, - equal: false, - }, - { - description: 'not equal objects (different properties)', - value1: {a: 1, b: '2', c: 3}, - value2: {a: 1, b: '2', d: 3}, - equal: false, - }, - { - description: 'equal objects (same sub-properties)', - value1: {a: [{b: 'c'}]}, - value2: {a: [{b: 'c'}]}, - equal: true, - }, - { - description: 'not equal objects (different sub-property value)', - value1: {a: [{b: 'c'}]}, - value2: {a: [{b: 'd'}]}, - equal: false, - }, - { - description: 'not equal objects (different sub-property)', - value1: {a: [{b: 'c'}]}, - value2: {a: [{c: 'c'}]}, - equal: false, - }, - { - description: 'empty array and empty object are not equal', - value1: {}, - value2: [], - equal: false, - }, - { - description: 'nulls are equal', - value1: null, - value2: null, - equal: true, - }, - { - description: 'null and undefined are not equal', - value1: null, - value2: undefined, - equal: false, - }, - { - description: 'null and empty object are not equal', - value1: null, - value2: {}, - equal: false, - }, - { - description: 'undefined and empty object are not equal', - value1: undefined, - value2: {}, - equal: false, - }, - ], - }, - - { - description: 'arrays', - tests: [ - { - description: 'two empty arrays are equal', - value1: [], - value2: [], - equal: true, - }, - { - description: 'equal arrays', - value1: [1, 2, 3], - value2: [1, 2, 3], - equal: true, - }, - { - description: 'not equal arrays (different item)', - value1: [1, 2, 3], - value2: [1, 2, 4], - equal: false, - }, - { - description: 'not equal arrays (different length)', - value1: [1, 2, 3], - value2: [1, 2], - equal: false, - }, - { - description: 'equal arrays of objects', - value1: [{a: 'a'}, {b: 'b'}], - value2: [{a: 'a'}, {b: 'b'}], - equal: true, - }, - { - description: 'not equal arrays of objects', - value1: [{a: 'a'}, {b: 'b'}], - value2: [{a: 'a'}, {b: 'c'}], - equal: false, - }, - { - description: 'pseudo array and equivalent array are not equal', - value1: {'0': 0, '1': 1, length: 2}, - value2: [0, 1], - equal: false, - }, - ], - }, - - { - description: 'sample objects', - tests: [ - { - description: 'big object', - value1: { - prop1: 'value1', - prop2: 'value2', - prop3: 'value3', - prop4: { - subProp1: 'sub value1', - subProp2: { - subSubProp1: 'sub sub value1', - subSubProp2: [1, 2, {prop2: 1, prop: 2}, 4, 5], - }, - }, - prop5: 1000, - }, - value2: { - prop5: 1000, - prop3: 'value3', - prop1: 'value1', - prop2: 'value2', - prop4: { - subProp2: { - subSubProp1: 'sub sub value1', - subSubProp2: [1, 2, {prop2: 1, prop: 2}, 4, 5], - }, - subProp1: 'sub value1', - }, - }, - equal: true, - }, - ], - }, -]; diff --git a/src/json-equal/deepEqual/index.ts b/src/json-equal/deepEqual/index.ts deleted file mode 100644 index 5b98253..0000000 --- a/src/json-equal/deepEqual/index.ts +++ /dev/null @@ -1 +0,0 @@ -export * from './v1'; diff --git a/src/json-equal/deepEqual/v1.ts b/src/json-equal/deepEqual/v1.ts deleted file mode 100644 index ec7b604..0000000 --- a/src/json-equal/deepEqual/v1.ts +++ /dev/null @@ -1,28 +0,0 @@ -export const deepEqual = (a: unknown, b: unknown): boolean => { - // Primitives - if (a === b) return true; - - if (a && b && typeof a === 'object' && typeof b === 'object') { - // Arrays - if (a.constructor !== b.constructor) return false; - let length, i, keys; - if (Array.isArray(a)) { - length = a.length; - if (length !== (b as Array).length) return false; - for (i = length; i-- !== 0; ) if (!deepEqual(a[i], (b as Array)[i])) return false; - return true; - } - - // Objects - keys = Object.keys(a); - length = keys.length; - if (length !== Object.keys(b).length) return false; - for (i = length; i-- !== 0; ) { - const key = keys[i]; - if (!deepEqual((a as Record)[key], (b as Record)[key])) return false; - } - return true; - } - - return false; -}; diff --git a/src/json-equal/deepEqual/v2.ts b/src/json-equal/deepEqual/v2.ts deleted file mode 100644 index 1a5da79..0000000 --- a/src/json-equal/deepEqual/v2.ts +++ /dev/null @@ -1,29 +0,0 @@ -export const deepEqual = (a: unknown, b: unknown): boolean => { - // Primitives - if (a === b) return true; - - if (a && b && typeof a === 'object' && typeof b === 'object') { - // Arrays - if (a.constructor !== b.constructor) return false; - let length, i, keys; - if (Array.isArray(a)) { - length = a.length; - if (length !== (b as Array).length) return false; - for (i = length; i-- !== 0; ) if (!deepEqual(a[i], (b as Array)[i])) return false; - return true; - } - - // Objects - keys = Object.keys(a); - length = keys.length; - if (length !== Object.keys(b).length) return false; - for (i = length; i-- !== 0; ) if ((b as Record)[keys[i]] === undefined) return false; - for (i = length; i-- !== 0; ) { - const key = keys[i]; - if (!deepEqual((a as Record)[key], (b as Record)[key])) return false; - } - return true; - } - - return false; -}; diff --git a/src/json-equal/deepEqual/v3.ts b/src/json-equal/deepEqual/v3.ts deleted file mode 100644 index 46684e7..0000000 --- a/src/json-equal/deepEqual/v3.ts +++ /dev/null @@ -1,29 +0,0 @@ -export const deepEqual = (a: unknown, b: unknown): boolean => { - // Primitives - if (a === b) return true; - - if (a && b && typeof a === 'object' && typeof b === 'object') { - // Arrays - if (a.constructor !== b.constructor) return false; - let length, i, keys; - if (Array.isArray(a)) { - length = a.length; - if (length !== (b as Array).length) return false; - for (i = length; i-- !== 0; ) if (!deepEqual(a[i], (b as Array)[i])) return false; - return true; - } - - // Objects - keys = Object.keys(a); - length = keys.length; - if (length !== Object.keys(b).length) return false; - for (i = length; i-- !== 0; ) if (!Object.prototype.hasOwnProperty.call(b, keys[i])) return false; - for (i = length; i-- !== 0; ) { - const key = keys[i]; - if (!deepEqual((a as Record)[key], (b as Record)[key])) return false; - } - return true; - } - - return false; -}; diff --git a/src/json-equal/deepEqual/v4.ts b/src/json-equal/deepEqual/v4.ts deleted file mode 100644 index a115da1..0000000 --- a/src/json-equal/deepEqual/v4.ts +++ /dev/null @@ -1,29 +0,0 @@ -export const deepEqual = (a: unknown, b: unknown): boolean => { - // Primitives - if (a === b) return true; - - if (a && b && typeof a === 'object' && typeof b === 'object') { - // Arrays - if (a.constructor !== b.constructor) return false; - let length, i, keys; - if (a.constructor === Array) { - // V4: Array.isArray(a) - length = (a as unknown[]).length; - if (length !== (b as Array).length) return false; - for (i = length; i-- !== 0; ) if (!deepEqual(a[i], (b as Array)[i])) return false; - return true; - } - - // Objects - keys = Object.keys(a); - length = keys.length; - if (length !== Object.keys(b).length) return false; - for (i = length; i-- !== 0; ) { - const key = keys[i]; - if (!deepEqual((a as Record)[key], (b as Record)[key])) return false; - } - return true; - } - - return false; -}; diff --git a/src/json-random/README.md b/src/json-random/README.md deleted file mode 100644 index bfd407b..0000000 --- a/src/json-random/README.md +++ /dev/null @@ -1,142 +0,0 @@ -# json-random - -The `json-random` library lets you generate random JSON values. - - -## Usage - -Generate a random JSON object. - -```ts -import {RandomJson} from 'json-pack/lib/json-random'; - -const json1 = RandomJson.generate(); -console.log(json1); -// { -// '38': "'@9_nO'Mr2kNsk", -// ']Io': 'ek_(3hS_voW|4', -// O55y3: 381613794.8379983, -// 'nWiO8W2hkQ(': false, -// 'r,5^0K!?c': true, -// '믊㶋搀焟㰏䶨⃷쎨躡': 124288683.18213326, -// 'G;l{VueC(#\\': 90848872.89389054, -// '%dP|': 172689822.92919666, -// 'Z``>?7.(0': '鿞虠制�紉蓊澡඾嘍皽퀌࠻ꏙ۽', -// '9#zw;1Grn=95Csj|': { -// '4r::`32,': 606175517.8053282, -// '#vp': 833875564.9460341, -// ']bSg2%Pnh>': 916851127.8107322, -// ',a}I,XOTJo}sxp6': true, -// '?D[f': 218903673.91954625 -// }, -// yM: ',b7`wZ m9u', -// 'f3G!vM-': 856162337.7339423 -// } -``` - -You can provide options ot the `.generate()` function. For example, -you can decrease the node count in the JSON to five, using the `nodeCount` -option: - -```ts -const json2 = RandomJson.generate({ - nodeCount: 5, -}); -console.log(json2); -// { -// '?)DClmRrUZAg8z>8': [ null, 596640662.4073832, 82241937.12592442 ], -// '}geJx8\\u_s': 27895 -// } -``` - -You can set the root node of your JSON value to be an array, using -the `rootNode` option: - -```ts -const json3 = RandomJson.generate({ - nodeCount: 5, - rootNode: 'array', -}); -console.log(json3); -// [ -// 421841709.15660113, -// 641343038.74181, -// { 'SQ6QQ': 'Q{Zi', -// 'GPo/.@': 623441950.4015203, -// 'uvUNV+a0Vj': [] -// } - -const json8 = RandomJson.genArray(); -console.log(json8); -// [ 'BYTvAq+k', [], [ '&XT93Y', '{LN\\!P5SQ}0>&rZ%' ], null ] -``` - - -## Demo - -See demo [here](../demo/json-random.ts). Run it with: - -``` -npx ts-node src/demo/json-random.ts -``` diff --git a/src/json-random/RandomJson.ts b/src/json-random/RandomJson.ts deleted file mode 100644 index 78edd3a..0000000 --- a/src/json-random/RandomJson.ts +++ /dev/null @@ -1,321 +0,0 @@ -import type {JsonValue} from '../types'; - -/** @ignore */ -export type NodeType = 'null' | 'boolean' | 'number' | 'string' | 'binary' | 'array' | 'object'; - -export interface NodeOdds { - null: number; - boolean: number; - number: number; - string: number; - binary: number; - array: number; - object: number; -} - -export interface RandomJsonOptions { - rootNode: 'object' | 'array' | undefined; - nodeCount: number; - odds: NodeOdds; -} - -const defaultOpts: RandomJsonOptions = { - rootNode: 'object', - nodeCount: 32, - odds: { - null: 1, - boolean: 2, - number: 10, - string: 8, - binary: 0, - array: 2, - object: 2, - }, -}; - -type ContainerNode = unknown[] | object; - -const ascii = (): string => { - return String.fromCharCode(Math.floor(32 + Math.random() * (126 - 32))); -}; - -const alphabet = [ - 'a', - 'b', - 'c', - 'd', - 'e', - 'f', - 'g', - 'h', - 'i', - 'j', - 'k', - 'l', - 'm', - 'n', - 'o', - 'p', - 'q', - 'r', - 's', - 't', - 'u', - 'v', - 'w', - 'x', - 'y', - 'z', - 'A', - 'B', - 'C', - 'D', - 'E', - 'F', - 'G', - 'H', - 'I', - 'J', - 'K', - 'L', - 'M', - 'N', - 'O', - 'P', - 'Q', - 'R', - 'S', - 'T', - 'U', - 'V', - 'W', - 'X', - 'Y', - 'Z', - '0', - '1', - '2', - '3', - '4', - '5', - '6', - '7', - '8', - '9', - '-', - '_', - '.', - ',', - ';', - '!', - '@', - '#', - '$', - '%', - '^', - '&', - '*', - '\\', - '/', - '(', - ')', - '+', - '=', - '\n', - '👍', - '🏻', - '😛', - 'ä', - 'ö', - 'ü', - 'ß', - 'а', - 'б', - 'в', - 'г', - '诶', - '必', - '西', -]; -const utf16 = (): string => { - return alphabet[Math.floor(Math.random() * alphabet.length)]; -}; - -/** - * Create a random JSON value. - * - * ```ts - * RandomJson.generate() - * ``` - */ -export class RandomJson { - public static generate(opts?: Partial): JsonValue { - const rnd = new RandomJson(opts); - return rnd.create(); - } - - public static genBoolean(): boolean { - return Math.random() > 0.5; - } - - public static genNumber(): number { - const num = - Math.random() > 0.2 - ? Math.random() * 1e9 - : Math.random() < 0.2 - ? Math.round(0xff * (2 * Math.random() - 1)) - : Math.random() < 0.2 - ? Math.round(0xffff * (2 * Math.random() - 1)) - : Math.round(Number.MAX_SAFE_INTEGER * (2 * Math.random() - 1)); - if (num === -0) return 0; - return num; - } - - public static genString(length = Math.ceil(Math.random() * 16)): string { - let str: string = ''; - if (Math.random() < 0.1) for (let i = 0; i < length; i++) str += utf16(); - else for (let i = 0; i < length; i++) str += ascii(); - if (str.length !== length) return ascii().repeat(length); - return str; - } - - public static genBinary(length = Math.ceil(Math.random() * 16)): Uint8Array { - const buf = new Uint8Array(length); - for (let i = 0; i < length; i++) buf[i] = Math.floor(Math.random() * 256); - return buf; - } - - public static genArray(options: Partial> = {odds: defaultOpts.odds}): unknown[] { - return RandomJson.generate({ - nodeCount: 6, - ...options, - rootNode: 'array', - }) as unknown[]; - } - - public static genObject(options: Partial> = {odds: defaultOpts.odds}): object { - return RandomJson.generate({ - nodeCount: 6, - ...options, - rootNode: 'object', - }) as object; - } - - /** @ignore */ - public opts: RandomJsonOptions; - /** @ignore */ - private totalOdds: number; - /** @ignore */ - private oddTotals: NodeOdds; - /** @ignore */ - public root: JsonValue; - /** @ignore */ - private containers: ContainerNode[] = []; - - /** - * @ignore - */ - public constructor(opts: Partial = {}) { - this.opts = {...defaultOpts, ...opts}; - this.oddTotals = {} as any; - this.oddTotals.null = this.opts.odds.null; - this.oddTotals.boolean = this.oddTotals.null + this.opts.odds.boolean; - this.oddTotals.number = this.oddTotals.boolean + this.opts.odds.number; - this.oddTotals.string = this.oddTotals.number + this.opts.odds.string; - this.oddTotals.binary = this.oddTotals.string + this.opts.odds.binary; - this.oddTotals.array = this.oddTotals.string + this.opts.odds.array; - this.oddTotals.object = this.oddTotals.array + this.opts.odds.object; - this.totalOdds = - this.opts.odds.null + - this.opts.odds.boolean + - this.opts.odds.number + - this.opts.odds.string + - this.opts.odds.binary + - this.opts.odds.array + - this.opts.odds.object; - this.root = - this.opts.rootNode === 'object' - ? {} - : this.opts.rootNode === 'array' - ? [] - : this.pickContainerType() === 'object' - ? {} - : []; - this.containers.push(this.root); - } - - /** - * @ignore - */ - public create(): JsonValue { - for (let i = 0; i < this.opts.nodeCount; i++) this.addNode(); - return this.root; - } - - /** - * @ignore - */ - public addNode(): void { - const container = this.pickContainer(); - const newNodeType = this.pickNodeType(); - const node = this.generate(newNodeType); - if (node && typeof node === 'object') this.containers.push(node as any); - if (Array.isArray(container)) { - const index = Math.floor(Math.random() * (container.length + 1)); - container.splice(index, 0, node); - } else { - const key = RandomJson.genString(); - (container as any)[key] = node; - } - } - - /** - * @ignore - */ - protected generate(type: NodeType): unknown { - switch (type) { - case 'null': - return null; - case 'boolean': - return RandomJson.genBoolean(); - case 'number': - return RandomJson.genNumber(); - case 'string': - return RandomJson.genString(); - case 'binary': - return RandomJson.genBinary(); - case 'array': - return []; - case 'object': - return {}; - } - } - - /** @ignore */ - public pickNodeType(): NodeType { - const odd = Math.random() * this.totalOdds; - if (odd <= this.oddTotals.null) return 'null'; - if (odd <= this.oddTotals.boolean) return 'boolean'; - if (odd <= this.oddTotals.number) return 'number'; - if (odd <= this.oddTotals.string) return 'string'; - if (odd <= this.oddTotals.binary) return 'binary'; - if (odd <= this.oddTotals.array) return 'array'; - return 'object'; - } - - /** - * @ignore - */ - protected pickContainerType(): 'array' | 'object' { - const sum = this.opts.odds.array + this.opts.odds.object; - if (Math.random() < this.opts.odds.array / sum) return 'array'; - return 'object'; - } - - /** - * @ignore - */ - protected pickContainer(): ContainerNode { - return this.containers[Math.floor(Math.random() * this.containers.length)]; - } -} diff --git a/src/json-random/__demos__/json-random.ts b/src/json-random/__demos__/json-random.ts deleted file mode 100644 index 81ce30f..0000000 --- a/src/json-random/__demos__/json-random.ts +++ /dev/null @@ -1,107 +0,0 @@ -/** - * Run with: - * - * npx ts-node src/json-random/__demos__/json-random.ts - */ - -import {RandomJson} from '../../json-random'; - -const json1 = RandomJson.generate(); -console.log(json1); // tslint:disable-line no-console -// { -// '38': "'@9_nO'Mr2kNsk", -// ']Io': 'ek_(3hS_voW|4', -// O55y3: 381613794.8379983, -// 'nWiO8W2hkQ(': false, -// 'r,5^0K!?c': true, -// '믊㶋搀焟㰏䶨⃷쎨躡': 124288683.18213326, -// 'G;l{VueC(#\\': 90848872.89389054, -// '%dP|': 172689822.92919666, -// 'Z``>?7.(0': '鿞虠制�紉蓊澡඾嘍皽퀌࠻ꏙ۽', -// '9#zw;1Grn=95Csj|': { -// '4r::`32,': 606175517.8053282, -// '#vp': 833875564.9460341, -// ']bSg2%Pnh>': 916851127.8107322, -// ',a}I,XOTJo}sxp6': true, -// '?D[f': 218903673.91954625 -// }, -// yM: ',b7`wZ m9u', -// 'f3G!vM-': 856162337.7339423 -// } - -const json2 = RandomJson.generate({ - nodeCount: 5, -}); -console.log(json2); // tslint:disable-line no-console -// { -// '?)DClmRrUZAg8z>8': [ null, 596640662.4073832, 82241937.12592442 ], -// '}geJx8\\u_s': 27895 -// } - -const json3 = RandomJson.generate({ - nodeCount: 5, - rootNode: 'array', -}); -console.log(json3); // tslint:disable-line no-console -// [ -// 421841709.15660113, -// 641343038.74181, -// { 'SQ6QQ': 'Q{Zi', -// 'GPo/.@': 623441950.4015203, -// 'uvUNV+a0Vj': [] -// } - -const json8 = RandomJson.genArray(); -console.log(json8); // tslint:disable-line no-console -// [ 'BYTvAq+k', [], [ '&XT93Y', '{LN\\!P5SQ}0>&rZ%' ], null ] diff --git a/src/json-random/__tests__/RandomJson.spec.ts b/src/json-random/__tests__/RandomJson.spec.ts deleted file mode 100644 index fd13f23..0000000 --- a/src/json-random/__tests__/RandomJson.spec.ts +++ /dev/null @@ -1,122 +0,0 @@ -import {RandomJson} from '../RandomJson'; - -test('generates random JSON', () => { - const mathRandom = Math.random; - let i = 0.0; - Math.random = () => { - i += 0.0379; - if (i >= 1) i -= 1; - return i; - }; - const rj = new RandomJson(); - const json = rj.create(); - const str = JSON.stringify(json); - expect(str.length > 5).toBe(true); - expect(JSON.parse(str)).toEqual(json); - expect(json).toMatchInlineSnapshot(` - { - ""%),047;>BEILPTW": [ - "]\`dgknrvy}", - "aehlpswz #", - "knruy|"&)-04", - "vy}#&*-148;?CF", - 378700000.0000067, - 399200000.0000046, - 483700000.0000056, - 568200000.0000067, - 422500000.00000507, - 466300000.0000035, - 588700000.0000046, - "imptw{ $'+/2", - [ - "bfimqtx{!$(", - "jnquy|"%),03", - "hlosvz}#'*.1", - "jnqux|!%),03", - "lpswz $'+.25", - "adhkosvz}#", - {}, - ], - ], - "58<": false, - "6:=": false, - "8;?": false, - "AEHLO": 244800000.0000021, - "DHLOSV": 279600000.0000062, - "FJNQUX": -3601078262045373, - "GKNRUY": -3494793310839458, - "ORVY]\`d": 387700000.000001, - "PTW[_bfi": 405100000.00000304, - "UY\\\`cgjn": 454799999.99999994, - "i": "\\_cfjmqtx|", - } - `); - Math.random = mathRandom; -}); - -test('can enforce root node to be object', () => { - const rj = new RandomJson({rootNode: 'object'}); - const json = rj.create(); - expect(!!json).toBe(true); - expect(typeof json).toBe('object'); - expect(Array.isArray(json)).toBe(false); -}); - -test('can enforce root node to be array', () => { - const json = RandomJson.generate({rootNode: 'array'}); - expect(Array.isArray(json)).toBe(true); -}); - -describe('exact root type', () => { - describe('.genString()', () => { - test('can generate a string', () => { - const json = RandomJson.genString(); - expect(typeof json).toBe('string'); - }); - }); - - describe('.genNumber()', () => { - test('can generate a number', () => { - const json = RandomJson.genNumber(); - expect(typeof json).toBe('number'); - }); - }); - - describe('.genBoolean()', () => { - test('can generate a boolean', () => { - const json = RandomJson.genBoolean(); - expect(typeof json).toBe('boolean'); - }); - }); - - describe('.genArray()', () => { - test('can generate a array', () => { - const json = RandomJson.genArray(); - expect(json instanceof Array).toBe(true); - }); - }); - - describe('.genObject()', () => { - test('can generate a object', () => { - const json = RandomJson.genObject(); - expect(typeof json).toBe('object'); - expect(!!json).toBe(true); - }); - }); -}); - -test('emoji strings can be converted to UTF-8', () => { - for (let i = 0; i < 100; i++) { - const str = '👍🏻😛' + '👍🏻😛'; - const test = Buffer.from(str).toString('utf8'); - expect(test).toBe(str); - } -}); - -test('random strings can be converted to UTF-8', () => { - for (let i = 0; i < 1000; i++) { - const str = RandomJson.genString(10); - const test = Buffer.from(str).toString('utf8'); - expect(test).toBe(str); - } -}); diff --git a/src/json-random/index.ts b/src/json-random/index.ts deleted file mode 100644 index 553584b..0000000 --- a/src/json-random/index.ts +++ /dev/null @@ -1 +0,0 @@ -export * from './RandomJson'; diff --git a/src/json/JsonDecoder.ts b/src/json/JsonDecoder.ts index 8f9805e..1b990b4 100644 --- a/src/json/JsonDecoder.ts +++ b/src/json/JsonDecoder.ts @@ -1,5 +1,5 @@ -import {decodeUtf8} from '../util/buffers/utf8/decodeUtf8'; -import {Reader} from '../util/buffers/Reader'; +import {decodeUtf8} from '@jsonjoy.com/util/lib/buffers/utf8/decodeUtf8'; +import {Reader} from '@jsonjoy.com/util/lib/buffers/Reader'; import {fromBase64Bin} from '@jsonjoy.com/base64/lib/fromBase64Bin'; import {findEndingQuote} from './util'; import type {BinaryJsonDecoder, PackValue} from '../types'; diff --git a/src/json/JsonEncoder.ts b/src/json/JsonEncoder.ts index a360c6d..db15716 100644 --- a/src/json/JsonEncoder.ts +++ b/src/json/JsonEncoder.ts @@ -1,5 +1,5 @@ import {toBase64Bin} from '@jsonjoy.com/base64/lib/toBase64Bin'; -import type {IWriter, IWriterGrowable} from '../util/buffers'; +import type {IWriter, IWriterGrowable} from '@jsonjoy.com/util/lib/buffers'; import type {BinaryJsonEncoder, StreamingBinaryJsonEncoder} from '../types'; export class JsonEncoder implements BinaryJsonEncoder, StreamingBinaryJsonEncoder { diff --git a/src/json/JsonEncoderStable.ts b/src/json/JsonEncoderStable.ts index 6b074e7..c1bb381 100644 --- a/src/json/JsonEncoderStable.ts +++ b/src/json/JsonEncoderStable.ts @@ -1,6 +1,6 @@ import {JsonEncoder} from './JsonEncoder'; -import {sort} from '../util/sort/insertion2'; -import {objKeyCmp} from '../util/objKeyCmp'; +import {sort} from '@jsonjoy.com/util/lib/sort/insertion2'; +import {objKeyCmp} from '@jsonjoy.com/util/lib/objKeyCmp'; export class JsonEncoderStable extends JsonEncoder { public writeObj(obj: Record): void { diff --git a/src/json/__tests__/JsonDecoder.spec.ts b/src/json/__tests__/JsonDecoder.spec.ts index cb83a00..29307eb 100644 --- a/src/json/__tests__/JsonDecoder.spec.ts +++ b/src/json/__tests__/JsonDecoder.spec.ts @@ -1,4 +1,4 @@ -import {Writer} from '../../util/buffers/Writer'; +import {Writer} from '@jsonjoy.com/util/lib/buffers/Writer'; import {JsonDecoder} from '../JsonDecoder'; import {JsonEncoder} from '../JsonEncoder'; diff --git a/src/json/__tests__/JsonDecoderDag.spec.ts b/src/json/__tests__/JsonDecoderDag.spec.ts index 016ef7b..8f0ec89 100644 --- a/src/json/__tests__/JsonDecoderDag.spec.ts +++ b/src/json/__tests__/JsonDecoderDag.spec.ts @@ -1,5 +1,5 @@ -import {Writer} from '../../util/buffers/Writer'; -import {utf8} from '../../util/buffers/strings'; +import {Writer} from '@jsonjoy.com/util/lib/buffers/Writer'; +import {utf8} from '@jsonjoy.com/util/lib/buffers/strings'; import {JsonEncoderDag} from '../JsonEncoderDag'; import {JsonDecoderDag} from '../JsonDecoderDag'; diff --git a/src/json/__tests__/JsonEncoder.spec.ts b/src/json/__tests__/JsonEncoder.spec.ts index cfa6373..d95d6f2 100644 --- a/src/json/__tests__/JsonEncoder.spec.ts +++ b/src/json/__tests__/JsonEncoder.spec.ts @@ -1,4 +1,4 @@ -import {Writer} from '../../util/buffers/Writer'; +import {Writer} from '@jsonjoy.com/util/lib/buffers/Writer'; import {JsonValue} from '../../types'; import {JsonEncoder} from '../JsonEncoder'; diff --git a/src/json/__tests__/JsonEncoderDag.spec.ts b/src/json/__tests__/JsonEncoderDag.spec.ts index ee8112c..ccd7aab 100644 --- a/src/json/__tests__/JsonEncoderDag.spec.ts +++ b/src/json/__tests__/JsonEncoderDag.spec.ts @@ -1,5 +1,5 @@ -import {Writer} from '../../util/buffers/Writer'; -import {utf8} from '../../util/buffers/strings'; +import {Writer} from '@jsonjoy.com/util/lib/buffers/Writer'; +import {utf8} from '@jsonjoy.com/util/lib/buffers/strings'; import {JsonEncoderDag} from '../JsonEncoderDag'; const writer = new Writer(16); diff --git a/src/json/__tests__/automated.spec.ts b/src/json/__tests__/automated.spec.ts index 1ef6044..a32a3fc 100644 --- a/src/json/__tests__/automated.spec.ts +++ b/src/json/__tests__/automated.spec.ts @@ -1,4 +1,4 @@ -import {Writer} from '../../util/buffers/Writer'; +import {Writer} from '@jsonjoy.com/util/lib/buffers/Writer'; import {JsonValue} from '../../types'; import {JsonEncoder} from '../JsonEncoder'; import {JsonEncoderStable} from '../JsonEncoderStable'; diff --git a/src/json/__tests__/fuzzer.spec.ts b/src/json/__tests__/fuzzer.spec.ts index 0c7ed66..cb444e2 100644 --- a/src/json/__tests__/fuzzer.spec.ts +++ b/src/json/__tests__/fuzzer.spec.ts @@ -1,5 +1,5 @@ -import {RandomJson} from '../../json-random'; -import {Writer} from '../../util/buffers/Writer'; +import {RandomJson} from '@jsonjoy.com/util/lib/json-random'; +import {Writer} from '@jsonjoy.com/util/lib/buffers/Writer'; import {JsonValue} from '../../types'; import {JsonDecoder} from '../JsonDecoder'; import {JsonEncoder} from '../JsonEncoder'; @@ -29,6 +29,6 @@ const assertEncoder = (value: JsonValue) => { test('fuzzing', () => { for (let i = 0; i < 1000; i++) { const json = RandomJson.generate(); - assertEncoder(json); + assertEncoder(json as any); } }, 50000); diff --git a/src/json/__tests__/memory-leaks.spec.ts b/src/json/__tests__/memory-leaks.spec.ts index ade1885..d020de7 100644 --- a/src/json/__tests__/memory-leaks.spec.ts +++ b/src/json/__tests__/memory-leaks.spec.ts @@ -1,4 +1,4 @@ -import {Writer} from '../../util/buffers/Writer'; +import {Writer} from '@jsonjoy.com/util/lib/buffers/Writer'; import {JsonValue} from '../../types'; import {JsonEncoder} from '../JsonEncoder'; import {parse} from '../../json-binary'; diff --git a/src/msgpack/MsgPackDecoder.ts b/src/msgpack/MsgPackDecoder.ts index d5a6938..d9475db 100644 --- a/src/msgpack/MsgPackDecoder.ts +++ b/src/msgpack/MsgPackDecoder.ts @@ -1,7 +1,7 @@ import {JsonPackValue} from '.'; import {MsgPackDecoderFast} from './MsgPackDecoderFast'; import type {Path} from '../json-pointer'; -import type {Reader} from '../util/buffers/Reader'; +import type {Reader} from '@jsonjoy.com/util/lib/buffers/Reader'; /** * @category Decoder diff --git a/src/msgpack/MsgPackDecoderFast.ts b/src/msgpack/MsgPackDecoderFast.ts index f4b0019..bb777c0 100644 --- a/src/msgpack/MsgPackDecoderFast.ts +++ b/src/msgpack/MsgPackDecoderFast.ts @@ -1,9 +1,9 @@ import {JsonPackExtension} from '../JsonPackExtension'; -import {Reader} from '../util/buffers/Reader'; +import {Reader} from '@jsonjoy.com/util/lib/buffers/Reader'; import {ERROR} from '../cbor/constants'; -import sharedCachedUtf8Decoder from '../util/buffers/utf8/sharedCachedUtf8Decoder'; +import sharedCachedUtf8Decoder from '@jsonjoy.com/util/lib/buffers/utf8/sharedCachedUtf8Decoder'; import type {BinaryJsonDecoder, PackValue} from '../types'; -import type {CachedUtf8Decoder} from '../util/buffers/utf8/CachedUtf8Decoder'; +import type {CachedUtf8Decoder} from '@jsonjoy.com/util/lib/buffers/utf8/CachedUtf8Decoder'; /** * @category Decoder diff --git a/src/msgpack/MsgPackEncoder.ts b/src/msgpack/MsgPackEncoder.ts index c0a0952..300ee80 100644 --- a/src/msgpack/MsgPackEncoder.ts +++ b/src/msgpack/MsgPackEncoder.ts @@ -1,9 +1,9 @@ import {MsgPackEncoderFast} from './MsgPackEncoderFast'; -import {isUint8Array} from '../util/buffers/isUint8Array'; +import {isUint8Array} from '@jsonjoy.com/util/lib/buffers/isUint8Array'; import {JsonPackExtension} from '../JsonPackExtension'; import {JsonPackValue} from '../JsonPackValue'; -import type {IWriter, IWriterGrowable} from '../util/buffers'; import {MSGPACK} from './constants'; +import type {IWriter, IWriterGrowable} from '@jsonjoy.com/util/lib/buffers'; /** * @category Encoder diff --git a/src/msgpack/MsgPackEncoderFast.ts b/src/msgpack/MsgPackEncoderFast.ts index 425885e..b24214f 100644 --- a/src/msgpack/MsgPackEncoderFast.ts +++ b/src/msgpack/MsgPackEncoderFast.ts @@ -1,5 +1,5 @@ -import {IWriter, IWriterGrowable} from '../util/buffers'; -import {Writer} from '../util/buffers/Writer'; +import {IWriter, IWriterGrowable} from '@jsonjoy.com/util/lib/buffers'; +import {Writer} from '@jsonjoy.com/util/lib/buffers/Writer'; import {JsonPackExtension} from '../JsonPackExtension'; import {BinaryJsonEncoder, TlvBinaryJsonEncoder} from '../types'; import {IMessagePackEncoder} from './types'; diff --git a/src/msgpack/MsgPackEncoderStable.ts b/src/msgpack/MsgPackEncoderStable.ts index a8e0bfb..43ebd3e 100644 --- a/src/msgpack/MsgPackEncoderStable.ts +++ b/src/msgpack/MsgPackEncoderStable.ts @@ -1,4 +1,4 @@ -import {sort} from '../util/sort/insertion'; +import {sort} from '@jsonjoy.com/util/lib/sort/insertion'; import {MsgPackEncoderFast} from './MsgPackEncoderFast'; /** diff --git a/src/msgpack/MsgPackToJsonConverter.ts b/src/msgpack/MsgPackToJsonConverter.ts index 9be7dc1..0cc399e 100644 --- a/src/msgpack/MsgPackToJsonConverter.ts +++ b/src/msgpack/MsgPackToJsonConverter.ts @@ -1,5 +1,5 @@ -import {json_string} from '../json-brand'; -import {asString} from '../util/strings/asString'; +import {json_string} from '@jsonjoy.com/util/lib/json-brand'; +import {asString} from '@jsonjoy.com/util/lib/strings/asString'; import {toDataUri} from '../util/buffers/toDataUri'; /** diff --git a/src/msgpack/__tests__/MsgPackDecoderFast.spec.ts b/src/msgpack/__tests__/MsgPackDecoderFast.spec.ts index 2aff214..57de13a 100644 --- a/src/msgpack/__tests__/MsgPackDecoderFast.spec.ts +++ b/src/msgpack/__tests__/MsgPackDecoderFast.spec.ts @@ -1,4 +1,4 @@ -import {NullObject} from '../../util/NullObject'; +import {NullObject} from '@jsonjoy.com/util/lib/NullObject'; import {MsgPackDecoderFast} from '../MsgPackDecoderFast'; import {MsgPackEncoderFast} from '../MsgPackEncoderFast'; diff --git a/src/msgpack/__tests__/fuzzing.spec.ts b/src/msgpack/__tests__/fuzzing.spec.ts index 0e0f4ce..b9c38a6 100644 --- a/src/msgpack/__tests__/fuzzing.spec.ts +++ b/src/msgpack/__tests__/fuzzing.spec.ts @@ -1,5 +1,5 @@ import {encode} from '@msgpack/msgpack'; -import {RandomJson} from '../../json-random'; +import {RandomJson} from '@jsonjoy.com/util/lib/json-random'; import {MsgPackEncoderFast} from '../MsgPackEncoderFast'; import {MsgPackDecoderFast} from '../MsgPackDecoderFast'; diff --git a/src/msgpack/shallow-read.ts b/src/msgpack/shallow-read.ts index 3e164f5..0a76fab 100644 --- a/src/msgpack/shallow-read.ts +++ b/src/msgpack/shallow-read.ts @@ -1,5 +1,5 @@ import {Path} from '../json-pointer'; -import {Codegen} from '../util/codegen/Codegen'; +import {Codegen} from '@jsonjoy.com/util/lib/codegen/Codegen'; import type {MsgPackDecoder} from './MsgPackDecoder'; type Decoder = Pick; diff --git a/src/msgpack/types.ts b/src/msgpack/types.ts index 6a71aa3..48d6330 100644 --- a/src/msgpack/types.ts +++ b/src/msgpack/types.ts @@ -1,4 +1,4 @@ -import type {IWriter, IWriterGrowable} from '../util/buffers'; +import type {IWriter, IWriterGrowable} from '@jsonjoy.com/util/lib/buffers'; export type MsgPack = Uint8Array & {__BRAND__: 'msgpack'; __TYPE__: T}; diff --git a/src/resp/RespDecoder.ts b/src/resp/RespDecoder.ts index 9a50754..8c7340f 100644 --- a/src/resp/RespDecoder.ts +++ b/src/resp/RespDecoder.ts @@ -1,9 +1,9 @@ -import {Reader} from '../util/buffers/Reader'; +import {Reader} from '@jsonjoy.com/util/lib/buffers/Reader'; import {RESP} from './constants'; import {RespAttributes, RespPush} from './extensions'; -import type {IReader, IReaderResettable} from '../util/buffers'; +import type {IReader, IReaderResettable} from '@jsonjoy.com/util/lib/buffers'; import type {BinaryJsonDecoder, PackValue} from '../types'; -import {isUtf8} from '../util/buffers/utf8/isUtf8'; +import {isUtf8} from '@jsonjoy.com/util/lib/buffers/utf8/isUtf8'; export class RespDecoder implements BinaryJsonDecoder diff --git a/src/resp/RespEncoder.ts b/src/resp/RespEncoder.ts index 46eb6c6..0ec8474 100644 --- a/src/resp/RespEncoder.ts +++ b/src/resp/RespEncoder.ts @@ -1,11 +1,11 @@ -import {Writer} from '../util/buffers/Writer'; +import {Writer} from '@jsonjoy.com/util/lib/buffers/Writer'; +import {utf8Size} from '@jsonjoy.com/util/lib/strings/utf8'; import {RESP} from './constants'; -import {utf8Size} from '../util/strings/utf8'; import {RespAttributes, RespPush, RespVerbatimString} from './extensions'; import {JsonPackExtension} from '../JsonPackExtension'; -import type {IWriter, IWriterGrowable} from '../util/buffers'; +import type {IWriter, IWriterGrowable} from '@jsonjoy.com/util/lib/buffers'; import type {BinaryJsonEncoder, StreamingBinaryJsonEncoder, TlvBinaryJsonEncoder} from '../types'; -import type {Slice} from '../util/buffers/Slice'; +import type {Slice} from '@jsonjoy.com/util/lib/buffers/Slice'; const REG_RN = /[\r\n]/; const isSafeInteger = Number.isSafeInteger; diff --git a/src/resp/RespEncoderLegacy.ts b/src/resp/RespEncoderLegacy.ts index ca03f48..a2f1465 100644 --- a/src/resp/RespEncoderLegacy.ts +++ b/src/resp/RespEncoderLegacy.ts @@ -2,7 +2,7 @@ import {RESP} from './constants'; import {RespAttributes, RespPush, RespVerbatimString} from './extensions'; import {JsonPackExtension} from '../JsonPackExtension'; import {RespEncoder} from './RespEncoder'; -import type {IWriter, IWriterGrowable} from '../util/buffers'; +import type {IWriter, IWriterGrowable} from '@jsonjoy.com/util/lib/buffers'; const REG_RN = /[\r\n]/; const isSafeInteger = Number.isSafeInteger; diff --git a/src/resp/RespStreamingDecoder.ts b/src/resp/RespStreamingDecoder.ts index a40e7fa..7fe6e91 100644 --- a/src/resp/RespStreamingDecoder.ts +++ b/src/resp/RespStreamingDecoder.ts @@ -1,4 +1,4 @@ -import {StreamingReader} from '../util/buffers/StreamingReader'; +import {StreamingReader} from '@jsonjoy.com/util/lib/buffers/StreamingReader'; import {RespDecoder} from './RespDecoder'; /** diff --git a/src/resp/__tests__/RespDecoder.spec.ts b/src/resp/__tests__/RespDecoder.spec.ts index b74b6eb..9078aa5 100644 --- a/src/resp/__tests__/RespDecoder.spec.ts +++ b/src/resp/__tests__/RespDecoder.spec.ts @@ -1,9 +1,9 @@ import {RespEncoder} from '../RespEncoder'; import {RespDecoder} from '../RespDecoder'; -import {bufferToUint8Array} from '../../util/buffers/bufferToUint8Array'; +import {bufferToUint8Array} from '@jsonjoy.com/util/lib/buffers/bufferToUint8Array'; import {RespAttributes, RespPush} from '../extensions'; -import {Writer} from '../../util/buffers/Writer'; -import {utf8} from '../../util/buffers/strings'; +import {Writer} from '@jsonjoy.com/util/lib/buffers/Writer'; +import {utf8} from '@jsonjoy.com/util/lib/buffers/strings'; const decode = (encoded: string | Uint8Array): unknown => { const decoder = new RespDecoder(); diff --git a/src/resp/__tests__/RespEncoder.spec.ts b/src/resp/__tests__/RespEncoder.spec.ts index 2c9b2c0..712a8ba 100644 --- a/src/resp/__tests__/RespEncoder.spec.ts +++ b/src/resp/__tests__/RespEncoder.spec.ts @@ -1,4 +1,4 @@ -import {bufferToUint8Array} from '../../util/buffers/bufferToUint8Array'; +import {bufferToUint8Array} from '@jsonjoy.com/util/lib/buffers/bufferToUint8Array'; import {RespEncoder} from '../RespEncoder'; import {RespVerbatimString} from '../extensions'; const Parser = require('redis-parser'); diff --git a/src/resp/__tests__/RespStreamingDecoder.spec.ts b/src/resp/__tests__/RespStreamingDecoder.spec.ts index 8fa4ba6..f232df1 100644 --- a/src/resp/__tests__/RespStreamingDecoder.spec.ts +++ b/src/resp/__tests__/RespStreamingDecoder.spec.ts @@ -1,8 +1,8 @@ import {RespStreamingDecoder} from '../RespStreamingDecoder'; import {RespEncoder} from '../RespEncoder'; -import {concatList} from '../../util/buffers/concat'; +import {concatList} from '@jsonjoy.com/util/lib/buffers/concat'; import {documents} from '../../__tests__/json-documents'; -import {utf8} from '../../util/buffers/strings'; +import {utf8} from '@jsonjoy.com/util/lib/buffers/strings'; const encoder = new RespEncoder(); diff --git a/src/resp/__tests__/fuzzing.spec.ts b/src/resp/__tests__/fuzzing.spec.ts index 3dd5729..ccd133b 100644 --- a/src/resp/__tests__/fuzzing.spec.ts +++ b/src/resp/__tests__/fuzzing.spec.ts @@ -1,4 +1,4 @@ -import {RandomJson} from '../../json-random'; +import {RandomJson} from '@jsonjoy.com/util/lib/json-random'; import {RespEncoder} from '../RespEncoder'; import {RespDecoder} from '../RespDecoder'; diff --git a/src/types.ts b/src/types.ts index 14daf88..5e0b034 100644 --- a/src/types.ts +++ b/src/types.ts @@ -1,4 +1,4 @@ -import type {IReader, IReaderResettable, IWriter, IWriterGrowable} from './util/buffers'; +import type {IReader, IReaderResettable, IWriter, IWriterGrowable} from '@jsonjoy.com/util/lib/buffers'; import type {JsonPackExtension} from './JsonPackExtension'; import type {JsonPackValue} from './JsonPackValue'; diff --git a/src/ubjson/UbjsonDecoder.ts b/src/ubjson/UbjsonDecoder.ts index dc87478..ecf4845 100644 --- a/src/ubjson/UbjsonDecoder.ts +++ b/src/ubjson/UbjsonDecoder.ts @@ -1,4 +1,4 @@ -import {Reader} from '../util/buffers/Reader'; +import {Reader} from '@jsonjoy.com/util/lib/buffers/Reader'; import {JsonPackExtension} from '../JsonPackExtension'; import {ERROR} from '../cbor/constants'; import type {BinaryJsonDecoder, PackValue} from '../types'; diff --git a/src/ubjson/UbjsonEncoder.ts b/src/ubjson/UbjsonEncoder.ts index b3cb719..58d72cb 100644 --- a/src/ubjson/UbjsonEncoder.ts +++ b/src/ubjson/UbjsonEncoder.ts @@ -1,4 +1,4 @@ -import type {IWriter, IWriterGrowable} from '../util/buffers'; +import type {IWriter, IWriterGrowable} from '@jsonjoy.com/util/lib/buffers'; import type {BinaryJsonEncoder, StreamingBinaryJsonEncoder} from '../types'; export class UbjsonEncoder implements BinaryJsonEncoder, StreamingBinaryJsonEncoder { diff --git a/src/ubjson/__tests__/UbjsonDecoder.spec.ts b/src/ubjson/__tests__/UbjsonDecoder.spec.ts index de541c0..bf42fab 100644 --- a/src/ubjson/__tests__/UbjsonDecoder.spec.ts +++ b/src/ubjson/__tests__/UbjsonDecoder.spec.ts @@ -1,9 +1,9 @@ import {encode} from '@shelacek/ubjson'; -import {Writer} from '../../util/buffers/Writer'; +import {Writer} from '@jsonjoy.com/util/lib/buffers/Writer'; import {PackValue} from '../../types'; import {UbjsonEncoder} from '../UbjsonEncoder'; import {UbjsonDecoder} from '../UbjsonDecoder'; -import {NullObject} from '../../util/NullObject'; +import {NullObject} from '@jsonjoy.com/util/lib/NullObject'; const encoder = new UbjsonEncoder(new Writer(8)); const decoder = new UbjsonDecoder(); diff --git a/src/ubjson/__tests__/UbjsonEncoder.spec.ts b/src/ubjson/__tests__/UbjsonEncoder.spec.ts index 0f53cc1..f0ca702 100644 --- a/src/ubjson/__tests__/UbjsonEncoder.spec.ts +++ b/src/ubjson/__tests__/UbjsonEncoder.spec.ts @@ -1,5 +1,5 @@ import {decode} from '@shelacek/ubjson'; -import {Writer} from '../../util/buffers/Writer'; +import {Writer} from '@jsonjoy.com/util/lib/buffers/Writer'; import {PackValue} from '../../types'; import {UbjsonEncoder} from '../UbjsonEncoder'; diff --git a/src/ubjson/__tests__/automated.spec.ts b/src/ubjson/__tests__/automated.spec.ts index 15e2529..bd99a9a 100644 --- a/src/ubjson/__tests__/automated.spec.ts +++ b/src/ubjson/__tests__/automated.spec.ts @@ -1,4 +1,4 @@ -import {Writer} from '../../util/buffers/Writer'; +import {Writer} from '@jsonjoy.com/util/lib/buffers/Writer'; import {JsonValue} from '../../types'; import {UbjsonEncoder} from '../UbjsonEncoder'; import {UbjsonDecoder} from '../UbjsonDecoder'; diff --git a/src/ubjson/__tests__/fuzzer.spec.ts b/src/ubjson/__tests__/fuzzer.spec.ts index 641edee..9206a54 100644 --- a/src/ubjson/__tests__/fuzzer.spec.ts +++ b/src/ubjson/__tests__/fuzzer.spec.ts @@ -1,5 +1,5 @@ -import {RandomJson} from '../../json-random'; -import {Writer} from '../../util/buffers/Writer'; +import {RandomJson} from '@jsonjoy.com/util/lib/json-random'; +import {Writer} from '@jsonjoy.com/util/lib/buffers/Writer'; import {JsonValue} from '../../types'; import {UbjsonEncoder} from '../UbjsonEncoder'; import {UbjsonDecoder} from '../UbjsonDecoder'; @@ -29,7 +29,7 @@ const assertEncoder = (value: JsonValue) => { test('fuzzing', () => { for (let i = 0; i < 1000; i++) { const json = RandomJson.generate(); - assertEncoder(json); + assertEncoder(json as any); } }, 50000); diff --git a/src/util/Fuzzer.ts b/src/util/Fuzzer.ts deleted file mode 100644 index 694149b..0000000 --- a/src/util/Fuzzer.ts +++ /dev/null @@ -1,66 +0,0 @@ -import {randomBytes} from 'crypto'; - -function xoshiro128ss(a: number, b: number, c: number, d: number) { - return () => { - const t = b << 9; - let r = b * 5; - r = ((r << 7) | (r >>> 25)) * 9; - c ^= a; - d ^= b; - b ^= c; - a ^= d; - c ^= t; - d = (d << 11) | (d >>> 21); - return (r >>> 0) / 4294967296; - }; -} - -export class Fuzzer { - public static randomInt(min: number, max: number): number { - return Math.floor(Math.random() * (max - min + 1)) + min; - } - - public static randomInt2([min, max]: [min: number, max: number]): number { - return Math.floor(Math.random() * (max - min + 1)) + min; - } - - /** @deprecated */ - public static pick(elements: T[]): T { - return elements[Math.floor(Math.random() * elements.length)]; - } - - /** @deprecated */ - public static repeat(times: number, callback: () => T): T[] { - const result: T[] = []; - for (let i = 0; i < times; i++) result.push(callback()); - return result; - } - - public readonly seed: Buffer; - public readonly random: () => number; - - constructor(seed?: Buffer) { - this.seed = seed = seed || randomBytes(4 * 4); - let i = 0; - const a = (seed[i++] << 24) | (seed[i++] << 16) | (seed[i++] << 8) | seed[i++]; - const b = (seed[i++] << 24) | (seed[i++] << 16) | (seed[i++] << 8) | seed[i++]; - const c = (seed[i++] << 24) | (seed[i++] << 16) | (seed[i++] << 8) | seed[i++]; - const d = (seed[i++] << 24) | (seed[i++] << 16) | (seed[i++] << 8) | seed[i++]; - this.random = xoshiro128ss(a, b, c, d); - Math.random = this.random; - } - - public readonly randomInt = (min: number, max: number): number => { - return Math.floor(Math.random() * (max - min + 1)) + min; - }; - - public readonly pick = (elements: T[]): T => { - return elements[Math.floor(Math.random() * elements.length)]; - }; - - public readonly repeat = (times: number, callback: () => T): T[] => { - const result: T[] = []; - for (let i = 0; i < times; i++) result.push(callback()); - return result; - }; -} diff --git a/src/util/NullObject.ts b/src/util/NullObject.ts deleted file mode 100644 index 707a2f0..0000000 --- a/src/util/NullObject.ts +++ /dev/null @@ -1,2 +0,0 @@ -export const NullObject = function NullObject() {} as any as new () => Record; -NullObject.prototype = Object.create(null); diff --git a/src/util/buffers/Reader.ts b/src/util/buffers/Reader.ts deleted file mode 100644 index 160e9cd..0000000 --- a/src/util/buffers/Reader.ts +++ /dev/null @@ -1,105 +0,0 @@ -import {decodeUtf8} from './utf8/decodeUtf8'; -import type {IReader, IReaderResettable} from './types'; - -export class Reader implements IReader, IReaderResettable { - public uint8 = new Uint8Array([]); - public view = new DataView(this.uint8.buffer); - public x = 0; - - public reset(uint8: Uint8Array): void { - this.x = 0; - this.uint8 = uint8; - this.view = new DataView(uint8.buffer, uint8.byteOffset, uint8.length); - } - - public peak(): number { - return this.view.getUint8(this.x); - } - - public skip(length: number): void { - this.x += length; - } - - public buf(size: number): Uint8Array { - const end = this.x + size; - const bin = this.uint8.subarray(this.x, end); - this.x = end; - return bin; - } - - public u8(): number { - return this.uint8[this.x++]; - // return this.view.getUint8(this.x++); - } - - public i8(): number { - return this.view.getInt8(this.x++); - } - - public u16(): number { - // const num = this.view.getUint16(this.x); - // this.x += 2; - // return num; - let x = this.x; - const num = (this.uint8[x++] << 8) + this.uint8[x++]; - this.x = x; - return num; - } - - public i16(): number { - const num = this.view.getInt16(this.x); - this.x += 2; - return num; - } - - public u32(): number { - const num = this.view.getUint32(this.x); - this.x += 4; - return num; - } - - public i32(): number { - const num = this.view.getInt32(this.x); - this.x += 4; - return num; - } - - public u64(): bigint { - const num = this.view.getBigUint64(this.x); - this.x += 8; - return num; - } - - public i64(): bigint { - const num = this.view.getBigInt64(this.x); - this.x += 8; - return num; - } - - public f32(): number { - const pos = this.x; - this.x += 4; - return this.view.getFloat32(pos); - } - - public f64(): number { - const pos = this.x; - this.x += 8; - return this.view.getFloat64(pos); - } - - public utf8(size: number): string { - const start = this.x; - this.x += size; - return decodeUtf8(this.uint8, start, size); - } - - public ascii(length: number): string { - const uint8 = this.uint8; - let str = ''; - const end = this.x + length; - for (let i = this.x; i < end; i++) str += String.fromCharCode(uint8[i]); - this.x = end; - return str; - } -} diff --git a/src/util/buffers/Slice.ts b/src/util/buffers/Slice.ts deleted file mode 100644 index c0287b8..0000000 --- a/src/util/buffers/Slice.ts +++ /dev/null @@ -1,12 +0,0 @@ -export class Slice { - constructor( - public readonly uint8: Uint8Array, - public readonly view: DataView, - public readonly start: number, - public readonly end: number, - ) {} - - public subarray(): Uint8Array { - return this.uint8.subarray(this.start, this.end); - } -} diff --git a/src/util/buffers/StreamingOctetReader.ts b/src/util/buffers/StreamingOctetReader.ts deleted file mode 100644 index b254a75..0000000 --- a/src/util/buffers/StreamingOctetReader.ts +++ /dev/null @@ -1,175 +0,0 @@ -const fromCharCode = String.fromCharCode; - -export class StreamingOctetReader { - protected readonly chunks: Uint8Array[] = []; - - /** Total size of all chunks. */ - protected chunkSize: number = 0; - - protected x: number = 0; - - public size(): number { - return this.chunkSize - this.x; - } - - public push(chunk: Uint8Array): void { - this.chunks.push(chunk); - this.chunkSize += chunk.length; - } - - protected assertSize(size: number): void { - if (size > this.size()) throw new RangeError('OUT_OF_BOUNDS'); - } - - public u8(): number { - this.assertSize(1); - const chunk = this.chunks[0]!; - let x = this.x; - const octet = chunk[x++]; - if (x === chunk.length) { - this.chunks.shift(); - this.chunkSize -= chunk.length; - x = 0; - } - this.x = x; - return octet; - } - - public u32(): number { - const octet0 = this.u8(); - const octet1 = this.u8(); - const octet2 = this.u8(); - const octet3 = this.u8(); - return (octet0 * 0x1000000 + (octet1 << 16) + (octet2 << 8)) | octet3; - } - - public copy(size: number, dst: Uint8Array, pos: number): void { - if (!size) return; - this.assertSize(size); - const chunk0 = this.chunks[0]!; - const size0 = Math.min(chunk0.length - this.x, size); - dst.set(chunk0.subarray(this.x, this.x + size0), pos); - size -= size0; - if (size <= 0) { - this.skipUnsafe(size0); - return; - } - let chunkIndex = 1; - while (size > 0) { - const chunk1 = this.chunks[chunkIndex]!; - const size1 = Math.min(chunk1.length, size); - dst.set(chunk1.subarray(0, size1), pos + size0); - size -= size1; - chunkIndex++; - } - this.skipUnsafe(size); - } - - public copyXor( - size: number, - dst: Uint8Array, - pos: number, - mask: [number, number, number, number], - maskIndex: number, - ): void { - if (!size) return; - this.assertSize(size); - const chunk0 = this.chunks[0]!; - let x = this.x; - const size0 = Math.min(chunk0.length - x, size); - const end = x + size0; - for (; x < end; ) dst[pos++] = chunk0[x++] ^ mask[maskIndex++ % 4]; - size -= size0; - if (size <= 0) { - this.skipUnsafe(size0); - return; - } - let chunkIndex = 1; - while (size > 0) { - const chunk1 = this.chunks[chunkIndex++]!; - const size1 = Math.min(chunk1.length, size); - for (let x = 0; x < size1; ) dst[pos++] = chunk1[x++] ^ mask[maskIndex++ % 4]; - size -= size1; - } - this.skipUnsafe(size); - } - - public buf(size: number): Uint8Array { - this.assertSize(size); - const buf = new Uint8Array(size); - this.copy(size, buf, 0); - return buf; - } - - public bufXor(size: number, mask: [number, number, number, number], maskIndex: number): Uint8Array { - this.assertSize(size); - const buf = new Uint8Array(size); - this.copyXor(size, buf, 0, mask, maskIndex); - return buf; - } - - public skipUnsafe(n: number): void { - if (!n) return; - const chunk = this.chunks[0]!; - const chunkLength = chunk.length; - const remaining = chunkLength - this.x; - if (remaining > n) { - this.x = this.x + n; - return; - } - this.x = 0; - this.chunks.shift(); - this.chunkSize -= chunkLength; - n -= remaining; - this.skipUnsafe(n); - } - - public skip(n: number): void { - this.assertSize(n); - this.skipUnsafe(n); - } - - public peak(): number { - this.assertSize(1); - return this.chunks[0]![this.x]; - } - - public utf8(length: number, mask: [number, number, number, number], maskIndex: number): string { - this.assertSize(length); - let i = 0; - const points: number[] = []; - while (i < length) { - let code = this.u8() ^ mask[maskIndex++ % 4]; - i++; - if ((code & 0x80) !== 0) { - const octet2 = (this.u8() ^ mask[maskIndex++ % 4]) & 0x3f; - i++; - if ((code & 0xe0) === 0xc0) { - code = ((code & 0x1f) << 6) | octet2; - } else { - const octet3 = (this.u8() ^ mask[maskIndex++ % 4]) & 0x3f; - i++; - if ((code & 0xf0) === 0xe0) { - code = ((code & 0x1f) << 12) | (octet2 << 6) | octet3; - } else { - if ((code & 0xf8) === 0xf0) { - const octet4 = (this.u8() ^ mask[maskIndex++ % 4]) & 0x3f; - i++; - let unit = ((code & 0x07) << 0x12) | (octet2 << 0x0c) | (octet3 << 0x06) | octet4; - if (unit > 0xffff) { - unit -= 0x10000; - const unit0 = ((unit >>> 10) & 0x3ff) | 0xd800; - code = 0xdc00 | (unit & 0x3ff); - points.push(unit0); - } else { - code = unit; - } - } - } - } - } - points.push(code); - } - return fromCharCode.apply(String, points); - } -} diff --git a/src/util/buffers/StreamingReader.ts b/src/util/buffers/StreamingReader.ts deleted file mode 100644 index 1695b73..0000000 --- a/src/util/buffers/StreamingReader.ts +++ /dev/null @@ -1,179 +0,0 @@ -import {Writer} from './Writer'; -import {decodeUtf8} from './utf8/decodeUtf8'; -import type {IReader, IReaderResettable} from './types'; - -export class StreamingReader implements IReader, IReaderResettable { - protected readonly writer: Writer; - - /** - * Offset from the start of the buffer (x0 in Writer). - */ - protected dx = 0; - - constructor(allocSize: number = 16 * 1024) { - this.writer = new Writer(allocSize); - } - - /** - * Returns the number of bytes remaining in the buffer. - */ - public size(): number { - return this.writer.x - this.x; - } - - /** - * Assert that there is enough data in the buffer to read `size` bytes. - * - * @param size Number of bytes to read. - */ - protected assertSize(size: number): void { - if (size > this.size()) throw new RangeError('OUT_OF_BOUNDS'); - } - - /** - * Add a chunk of data to be decoded. The chunk is copied into the - * internal buffer, so you can reuse the chunk after calling this method; or - * this chunk can be neutered by the caller. - * - * @param uint8 `Uint8Array` chunk of data to be decoded. - */ - public push(uint8: Uint8Array): void { - this.writer.buf(uint8, uint8.length); - } - - /** - * Mark the current position as consumed. This will free up memory - * for reuse. - */ - public consume(): void { - this.writer.x0 += this.dx; - this.dx = 0; - } - - // ------------------------------------------------------------------ IReader - - public get uint8(): Uint8Array { - return this.writer.uint8; - } - - public get view(): DataView { - return this.writer.view; - } - - public get x(): number { - return this.writer.x0 + this.dx; - } - - public set x(x: number) { - this.dx = x - this.writer.x0; - } - - public peak(): number { - this.assertSize(1); - return this.view.getUint8(this.x); - } - - public skip(length: number): void { - this.assertSize(length); - this.x += length; - } - - public buf(size: number): Uint8Array { - this.assertSize(size); - const end = this.x + size; - const bin = this.uint8.subarray(this.x, end); - this.x = end; - return bin; - } - - public u8(): number { - this.assertSize(1); - return this.view.getUint8(this.x++); - } - - public i8(): number { - this.assertSize(1); - return this.view.getInt8(this.x++); - } - - public u16(): number { - this.assertSize(2); - const num = this.view.getUint16(this.x); - this.x += 2; - return num; - } - - public i16(): number { - this.assertSize(2); - const num = this.view.getInt16(this.x); - this.x += 2; - return num; - } - - public u32(): number { - this.assertSize(4); - const num = this.view.getUint32(this.x); - this.x += 4; - return num; - } - - public i32(): number { - this.assertSize(4); - const num = this.view.getInt32(this.x); - this.x += 4; - return num; - } - - public u64(): bigint { - this.assertSize(8); - const num = this.view.getBigUint64(this.x); - this.x += 8; - return num; - } - - public i64(): bigint { - this.assertSize(8); - const num = this.view.getBigInt64(this.x); - this.x += 8; - return num; - } - - public f32(): number { - this.assertSize(4); - const pos = this.x; - this.x += 4; - return this.view.getFloat32(pos); - } - - public f64(): number { - this.assertSize(8); - const pos = this.x; - this.x += 8; - return this.view.getFloat64(pos); - } - - public utf8(size: number): string { - this.assertSize(size); - const start = this.x; - this.x += size; - return decodeUtf8(this.uint8, start, size); - } - - public ascii(length: number): string { - this.assertSize(length); - const uint8 = this.uint8; - let str = ''; - const end = this.x + length; - for (let i = this.x; i < end; i++) str += String.fromCharCode(uint8[i]); - this.x = end; - return str; - } - - // -------------------------------------------------------- IReaderResettable - - public reset(uint8: Uint8Array): void { - this.dx = 0; - this.writer.reset(); - this.push(uint8); - } -} diff --git a/src/util/buffers/Uint8ArrayCut.ts b/src/util/buffers/Uint8ArrayCut.ts deleted file mode 100644 index b57bfd6..0000000 --- a/src/util/buffers/Uint8ArrayCut.ts +++ /dev/null @@ -1,7 +0,0 @@ -export class Uint8ArrayCut { - constructor( - public readonly uint8: Uint8Array, - public readonly start: number, - public readonly size: number, - ) {} -} diff --git a/src/util/buffers/Writer.ts b/src/util/buffers/Writer.ts deleted file mode 100644 index 8b96de2..0000000 --- a/src/util/buffers/Writer.ts +++ /dev/null @@ -1,269 +0,0 @@ -import {Slice} from './Slice'; -import {IWriterGrowable, IWriter} from './types'; - -const EMPTY_UINT8 = new Uint8Array([]); -const EMPTY_VIEW = new DataView(EMPTY_UINT8.buffer); - -const hasBuffer = typeof Buffer === 'function'; -const utf8Write = hasBuffer - ? (Buffer.prototype.utf8Write as (this: Uint8Array, str: string, pos: number, maxLength: number) => number) - : null; -const from = hasBuffer ? Buffer.from : null; -const textEncoder = typeof TextEncoder !== 'undefined' ? new TextEncoder() : null; - -/** - * Encoder class provides an efficient way to encode binary data. It grows the - * internal memory buffer automatically as more space is required. It is useful - * in cases when it is not known in advance the size of memory needed. - */ -export class Writer implements IWriter, IWriterGrowable { - /** @ignore */ - public uint8: Uint8Array; - /** @ignore */ - public view: DataView = EMPTY_VIEW; - /** @ignore */ - public x0: number = 0; - /** @ignore */ - public x: number = 0; - protected size: number; - - /** - * @param allocSize Number of bytes to allocate at a time when buffer ends. - */ - constructor(public allocSize: number = 64 * 1024) { - this.uint8 = new Uint8Array(allocSize); - this.size = allocSize; - this.view = new DataView(this.uint8.buffer); - } - - /** @ignore */ - protected grow(size: number) { - const x0 = this.x0; - const x = this.x; - const oldUint8 = this.uint8; - const newUint8 = new Uint8Array(size); - const view = new DataView(newUint8.buffer); - const activeSlice = oldUint8.subarray(x0, x); - newUint8.set(activeSlice, 0); - this.x = x - x0; - this.x0 = 0; - this.uint8 = newUint8; - this.size = size; - this.view = view; - } - - /** - * Make sure the internal buffer has enough space to write the specified number - * of bytes, otherwise resize the internal buffer to accommodate for more size. - * - * @param capacity Number of bytes. - */ - public ensureCapacity(capacity: number) { - const byteLength = this.size; - const remaining = byteLength - this.x; - if (remaining < capacity) { - const total = byteLength - this.x0; - const required = capacity - remaining; - const totalRequired = total + required; - this.grow(totalRequired <= this.allocSize ? this.allocSize : totalRequired * 2); - } - } - - /** @todo Consider renaming to "skip"? */ - public move(capacity: number) { - this.ensureCapacity(capacity); - this.x += capacity; - } - - public reset() { - this.x0 = this.x; - } - - /** - * Allocates a new {@link ArrayBuffer}, useful when the underlying - * {@link ArrayBuffer} cannot be shared between threads. - * - * @param size Size of memory to allocate. - */ - public newBuffer(size: number) { - const uint8 = (this.uint8 = new Uint8Array(size)); - this.size = size; - this.view = new DataView(uint8.buffer); - this.x = this.x0 = 0; - } - - /** - * @returns Encoded memory buffer contents. - */ - public flush(): Uint8Array { - const result = this.uint8.subarray(this.x0, this.x); - this.x0 = this.x; - return result; - } - - public flushSlice(): Slice { - const slice = new Slice(this.uint8, this.view, this.x0, this.x); - this.x0 = this.x; - return slice; - } - - public u8(char: number) { - this.ensureCapacity(1); - this.uint8[this.x++] = char; - } - - public u16(word: number) { - this.ensureCapacity(2); - this.view.setUint16(this.x, word); - this.x += 2; - } - - public u32(dword: number) { - this.ensureCapacity(4); - this.view.setUint32(this.x, dword); - this.x += 4; - } - - public i32(dword: number) { - this.ensureCapacity(4); - this.view.setInt32(this.x, dword); - this.x += 4; - } - - public u64(qword: number | bigint) { - this.ensureCapacity(8); - this.view.setBigUint64(this.x, BigInt(qword)); - this.x += 8; - } - - public f64(float: number) { - this.ensureCapacity(8); - this.view.setFloat64(this.x, float); - this.x += 8; - } - - public u8u16(u8: number, u16: number) { - this.ensureCapacity(3); - let x = this.x; - this.uint8[x++] = u8; - this.uint8[x++] = u16 >>> 8; - this.uint8[x++] = u16 & 0xff; - this.x = x; - } - - public u8u32(u8: number, u32: number) { - this.ensureCapacity(5); - let x = this.x; - this.uint8[x++] = u8; - this.view.setUint32(x, u32); - this.x = x + 4; - } - - public u8u64(u8: number, u64: number | bigint) { - this.ensureCapacity(9); - let x = this.x; - this.uint8[x++] = u8; - this.view.setBigUint64(x, BigInt(u64)); - this.x = x + 8; - } - - public u8f32(u8: number, f32: number) { - this.ensureCapacity(5); - let x = this.x; - this.uint8[x++] = u8; - this.view.setFloat32(x, f32); - this.x = x + 4; - } - - public u8f64(u8: number, f64: number) { - this.ensureCapacity(9); - let x = this.x; - this.uint8[x++] = u8; - this.view.setFloat64(x, f64); - this.x = x + 8; - } - - public buf(buf: Uint8Array, length: number): void { - this.ensureCapacity(length); - const x = this.x; - this.uint8.set(buf, x); - this.x = x + length; - } - - /** - * Encodes string as UTF-8. You need to call .ensureCapacity(str.length * 4) - * before calling - * - * @param str String to encode as UTF-8. - * @returns The number of bytes written - */ - public utf8(str: string): number { - const maxLength = str.length * 4; - if (maxLength < 168) return this.utf8Native(str); - if (utf8Write) { - const writeLength = utf8Write.call(this.uint8, str, this.x, maxLength); - this.x += writeLength; - return writeLength; - } else if (from) { - const uint8 = this.uint8; - const offset = uint8.byteOffset + this.x; - const buf = from(uint8.buffer).subarray(offset, offset + maxLength); - const writeLength = buf.write(str, 0, maxLength, 'utf8'); - this.x += writeLength; - return writeLength; - } else if (maxLength > 1024 && textEncoder) { - const writeLength = textEncoder!.encodeInto(str, this.uint8.subarray(this.x, this.x + maxLength)).written!; - this.x += writeLength; - return writeLength; - } - return this.utf8Native(str); - } - - public utf8Native(str: string): number { - const length = str.length; - const uint8 = this.uint8; - let offset = this.x; - let pos = 0; - while (pos < length) { - let value = str.charCodeAt(pos++); - if ((value & 0xffffff80) === 0) { - uint8[offset++] = value; - continue; - } else if ((value & 0xfffff800) === 0) { - uint8[offset++] = ((value >> 6) & 0x1f) | 0xc0; - } else { - if (value >= 0xd800 && value <= 0xdbff) { - if (pos < length) { - const extra = str.charCodeAt(pos); - if ((extra & 0xfc00) === 0xdc00) { - pos++; - value = ((value & 0x3ff) << 10) + (extra & 0x3ff) + 0x10000; - } - } - } - if ((value & 0xffff0000) === 0) { - uint8[offset++] = ((value >> 12) & 0x0f) | 0xe0; - uint8[offset++] = ((value >> 6) & 0x3f) | 0x80; - } else { - uint8[offset++] = ((value >> 18) & 0x07) | 0xf0; - uint8[offset++] = ((value >> 12) & 0x3f) | 0x80; - uint8[offset++] = ((value >> 6) & 0x3f) | 0x80; - } - } - uint8[offset++] = (value & 0x3f) | 0x80; - } - const writeLength = offset - this.x; - this.x = offset; - return writeLength; - } - - public ascii(str: string): void { - const length = str.length; - this.ensureCapacity(length); - const uint8 = this.uint8; - let x = this.x; - let pos = 0; - while (pos < length) uint8[x++] = str.charCodeAt(pos++); - this.x = x; - } -} diff --git a/src/util/buffers/__bench__/bench.decodeUtf8.ts b/src/util/buffers/__bench__/bench.decodeUtf8.ts deleted file mode 100644 index 1255b2a..0000000 --- a/src/util/buffers/__bench__/bench.decodeUtf8.ts +++ /dev/null @@ -1,108 +0,0 @@ -// yarn build && npx ts-node src/util/buffers/__bench__/bench.decodeUtf8.ts - -import {runBenchmark} from '../../../__bench__/runBenchmark'; - -const prepare = (str: string) => { - const buf = Buffer.from(str); - const arr = new Uint8Array(buf.length); - for (let i = 0; i < buf.length; i++) arr[i] = buf[i]; - return arr; -}; - -const runner = (v: number, name: string) => ({ - name: `${name} (v${v})`, - setup: () => { - const decode = require('../../../../es2020/util/buffers/utf8/decodeUtf8/v' + v).default; - return (data: any) => decode(data, 0, data.length); - }, -}); - -const benchmark = { - name: 'decodeUtf8', - warmup: 1000, - payloads: [ - // { - // name: (buf) => `Single character, ${buf.length} bytes`, - // data: prepare('a'), - // test: () => 'a', - // }, - // { - // name: (buf) => `"Hello", ${buf.length} bytes`, - // data: prepare('Hello'), - // test: () => 'Hello', - // }, - // { - // name: (buf) => `Short text with emoji, ${buf.length} bytes`, - // data: prepare('Hi, Mike 👋!'), - // test: () => 'Hi, Mike 👋!', - // }, - { - name: (buf: any) => `Repeating characters, ${buf.length} bytes`, - data: prepare('a'.repeat(2)), - test: () => 'a'.repeat(2), - }, - { - name: (buf: any) => `Repeating characters, ${buf.length} bytes`, - data: prepare('a'.repeat(4)), - test: () => 'a'.repeat(4), - }, - { - name: (buf: any) => `Repeating characters, ${buf.length} bytes`, - data: prepare('a'.repeat(8)), - test: () => 'a'.repeat(8), - }, - { - name: (buf: any) => `Repeating characters, ${buf.length} bytes`, - data: prepare('abcd'.repeat(3)), - test: () => 'abcd'.repeat(3), - }, - { - name: (buf: any) => `Repeating characters, ${buf.length} bytes`, - data: prepare('abcd'.repeat(4)), - test: () => 'abcd'.repeat(4), - }, - { - name: (buf: any) => `Repeating characters, ${buf.length} bytes`, - data: prepare('abcd'.repeat(8)), - test: () => 'abcd'.repeat(8), - }, - { - name: (buf: any) => `Repeating characters, ${buf.length} bytes`, - data: prepare('abcd'.repeat(16)), - test: () => 'abcd'.repeat(16), - }, - { - name: (buf: any) => `Repeating characters, ${buf.length} bytes`, - data: prepare('abcd'.repeat(32)), - test: () => 'abcd'.repeat(32), - }, - { - name: (buf: any) => `Repeating characters, ${buf.length} bytes`, - data: prepare('abcd'.repeat(64)), - test: () => 'abcd'.repeat(64), - }, - { - name: (buf: any) => `Repeating characters, ${buf.length} bytes`, - data: prepare('abcd'.repeat(128)), - test: () => 'abcd'.repeat(128), - }, - ], - runners: [ - // runner(1, 'JS with buffering in array'), - // runner(2, 'Buffer.prototype.utf8Slice'), - // runner(3, 'Buffer.from(arr).slice'), - // runner(4, 'Buffer.from(arr).subarray'), - // runner(5, 'JS with string concatenation'), - // runner(6, 'TextDecoder'), - // runner(7, 'JS with buffering in array, no flushing'), - // runner(8, 'JS with buffering in array, small buffer'), - // runner(9, 'JS with buffering in array, variable reuse'), - // runner(10, 'JS with string concatenation, variable reuse'), - runner(19, 'json-pack-napi'), - runner(11, 'utf8Slice'), - // runner(12, 'from(arr).subarray'), - // runner(13, 'composition'), - ], -}; - -runBenchmark(benchmark); diff --git a/src/util/buffers/__tests__/StreamingReader.spec.ts b/src/util/buffers/__tests__/StreamingReader.spec.ts deleted file mode 100644 index 420dbfa..0000000 --- a/src/util/buffers/__tests__/StreamingReader.spec.ts +++ /dev/null @@ -1,57 +0,0 @@ -import {StreamingReader} from '../StreamingReader'; - -test('can push and read', () => { - const reader = new StreamingReader(4); - reader.push(new Uint8Array([1, 2, 3])); - expect(reader.u8()).toBe(1); - reader.push(new Uint8Array([4, 5, 6])); - expect(reader.u8()).toBe(2); - expect(reader.u8()).toBe(3); - expect(reader.u8()).toBe(4); - expect(reader.u8()).toBe(5); - expect(reader.u8()).toBe(6); -}); - -test('throws RangeError when reading out of bounds', () => { - const reader = new StreamingReader(2); - reader.push(new Uint8Array([1, 2, 3])); - reader.u16(); - reader.u8(); - expect(() => reader.u8()).toThrow(RangeError); -}); - -test('throws RangeError when reading out of bounds - 2', () => { - const reader = new StreamingReader(); - reader.push(new Uint8Array([1, 2, 3])); - reader.u16(); - expect(() => reader.u16()).toThrow(RangeError); -}); - -test('throws RangeError when reading out of bounds - 3', () => { - const reader = new StreamingReader(4); - reader.push(new Uint8Array([1, 2, 3])); - reader.u16(); - reader.push(new Uint8Array([4, 5])); - expect(() => reader.u32()).toThrow(RangeError); -}); - -test('size shrinks as data is read', () => { - const reader = new StreamingReader(4); - expect(reader.size()).toBe(0); - reader.push(new Uint8Array([1, 2, 3])); - expect(reader.size()).toBe(3); - expect(reader.u8()).toBe(1); - expect(reader.size()).toBe(2); - reader.push(new Uint8Array([4, 5, 6])); - expect(reader.size()).toBe(5); - expect(reader.u8()).toBe(2); - expect(reader.size()).toBe(4); - expect(reader.u8()).toBe(3); - expect(reader.size()).toBe(3); - expect(reader.u8()).toBe(4); - expect(reader.size()).toBe(2); - expect(reader.u8()).toBe(5); - expect(reader.size()).toBe(1); - expect(reader.u8()).toBe(6); - expect(reader.size()).toBe(0); -}); diff --git a/src/util/buffers/__tests__/isFloat32.spec.ts b/src/util/buffers/__tests__/isFloat32.spec.ts deleted file mode 100644 index 34a2104..0000000 --- a/src/util/buffers/__tests__/isFloat32.spec.ts +++ /dev/null @@ -1,9 +0,0 @@ -import {isFloat32} from '../isFloat32'; - -test('returns true for a float32', () => { - expect(isFloat32(1.5)).toBe(true); -}); - -test('returns true for a float64', () => { - expect(isFloat32(1.1)).toBe(false); -}); diff --git a/src/util/buffers/b.ts b/src/util/buffers/b.ts deleted file mode 100644 index 003f912..0000000 --- a/src/util/buffers/b.ts +++ /dev/null @@ -1 +0,0 @@ -export const b = (...args: number[]) => new Uint8Array(args); diff --git a/src/util/buffers/bufferToUint8Array.ts b/src/util/buffers/bufferToUint8Array.ts deleted file mode 100644 index 63598b6..0000000 --- a/src/util/buffers/bufferToUint8Array.ts +++ /dev/null @@ -1 +0,0 @@ -export const bufferToUint8Array = (buf: Buffer): Uint8Array => new Uint8Array(buf.buffer, buf.byteOffset, buf.length); diff --git a/src/util/buffers/cmpUint8Array.ts b/src/util/buffers/cmpUint8Array.ts deleted file mode 100644 index 694c027..0000000 --- a/src/util/buffers/cmpUint8Array.ts +++ /dev/null @@ -1,6 +0,0 @@ -export const cmpUint8Array = (a: Uint8Array, b: Uint8Array): boolean => { - const length = a.length; - if (length !== b.length) return false; - for (let i = 0; i < length; i++) if (a[i] !== b[i]) return false; - return true; -}; diff --git a/src/util/buffers/cmpUint8Array2.ts b/src/util/buffers/cmpUint8Array2.ts deleted file mode 100644 index 344ec1e..0000000 --- a/src/util/buffers/cmpUint8Array2.ts +++ /dev/null @@ -1,18 +0,0 @@ -/** - * Compares two `Uint8Arrays` byte-by-byte. Returns a negative number if `a` is - * less than `b`, a positive number if `a` is greater than `b`, or 0 if `a` is - * equal to `b`. - * - * @returns A negative number if a is less than b, a positive number if a is - * greater than b, or 0 if a is equal to b. - */ -export const cmpUint8Array2 = (a: Uint8Array, b: Uint8Array): number => { - const len1 = a.length; - const len2 = b.length; - const len = Math.min(len1, len2); - for (let i = 0; i < len; i++) { - const diffChar = a[i] - b[i]; - if (diffChar !== 0) return diffChar; - } - return len1 - len2; -}; diff --git a/src/util/buffers/cmpUint8Array3.ts b/src/util/buffers/cmpUint8Array3.ts deleted file mode 100644 index 950c358..0000000 --- a/src/util/buffers/cmpUint8Array3.ts +++ /dev/null @@ -1,19 +0,0 @@ -/** - * Compares two `Uint8Arrays`, first by length, then by each byte. Returns a - * negative number if `a` is less than `b`, a positive number if `a` is greater - * than `b`, or 0 if `a` is equal to `b`. - * - * @returns A negative number if a is less than b, a positive number if a is - * greater than b, or 0 if a is equal to b. - */ -export const cmpUint8Array3 = (a: Uint8Array, b: Uint8Array): number => { - const len1 = a.length; - const len2 = b.length; - const diff = len1 - len2; - if (diff !== 0) return diff; - for (let i = 0; i < len1; i++) { - const diff = a[i] - b[i]; - if (diff !== 0) return diff; - } - return 0; -}; diff --git a/src/util/buffers/concat.ts b/src/util/buffers/concat.ts deleted file mode 100644 index 205bad1..0000000 --- a/src/util/buffers/concat.ts +++ /dev/null @@ -1,31 +0,0 @@ -export const concat = (a: Uint8Array, b: Uint8Array): Uint8Array => { - const res = new Uint8Array(a.length + b.length); - res.set(a); - res.set(b, a.length); - return res; -}; - -export const concatList = (list: Uint8Array[]): Uint8Array => { - const length = list.length; - let size = 0, - offset = 0; - for (let i = 0; i < length; i++) size += list[i].length; - const res = new Uint8Array(size); - for (let i = 0; i < length; i++) { - const item = list[i]; - res.set(item, offset); - offset += item.length; - } - return res; -}; - -export const listToUint8 = (list: Uint8Array[]): Uint8Array => { - switch (list.length) { - case 0: - return new Uint8Array(0); - case 1: - return list[0]; - default: - return concatList(list); - } -}; diff --git a/src/util/buffers/copy.ts b/src/util/buffers/copy.ts deleted file mode 100644 index d779133..0000000 --- a/src/util/buffers/copy.ts +++ /dev/null @@ -1,5 +0,0 @@ -export const copy = (arr: T): T => { - const dupe = new Uint8Array(arr.length) as T; - dupe.set(arr); - return dupe; -}; diff --git a/src/util/buffers/f16.ts b/src/util/buffers/f16.ts deleted file mode 100644 index 51a4150..0000000 --- a/src/util/buffers/f16.ts +++ /dev/null @@ -1,16 +0,0 @@ -const pow = Math.pow; - -export const decodeF16 = (binary: number): number => { - const exponent = (binary & 0x7c00) >> 10; - const fraction = binary & 0x03ff; - return ( - (binary >> 15 ? -1 : 1) * - (exponent - ? exponent === 0x1f - ? fraction - ? NaN - : Infinity - : pow(2, exponent - 15) * (1 + fraction / 0x400) - : 6.103515625e-5 * (fraction / 0x400)) - ); -}; diff --git a/src/util/buffers/index.ts b/src/util/buffers/index.ts deleted file mode 100644 index fcb073f..0000000 --- a/src/util/buffers/index.ts +++ /dev/null @@ -1 +0,0 @@ -export * from './types'; diff --git a/src/util/buffers/isArrayBuffer.ts b/src/util/buffers/isArrayBuffer.ts deleted file mode 100644 index 998e906..0000000 --- a/src/util/buffers/isArrayBuffer.ts +++ /dev/null @@ -1,3 +0,0 @@ -export const isArrayBuffer = (value: unknown): value is ArrayBuffer => { - return value instanceof ArrayBuffer || toString.call(value) === '[object ArrayBuffer]'; -}; diff --git a/src/util/buffers/isFloat32.ts b/src/util/buffers/isFloat32.ts deleted file mode 100644 index 26e3823..0000000 --- a/src/util/buffers/isFloat32.ts +++ /dev/null @@ -1,6 +0,0 @@ -const view = new DataView(new ArrayBuffer(4)); - -export const isFloat32 = (n: number): boolean => { - view.setFloat32(0, n); - return n === view.getFloat32(0); -}; diff --git a/src/util/buffers/isUint8Array.ts b/src/util/buffers/isUint8Array.ts deleted file mode 100644 index b86a8b0..0000000 --- a/src/util/buffers/isUint8Array.ts +++ /dev/null @@ -1,4 +0,0 @@ -export const isUint8Array = - typeof Buffer === 'function' - ? (x: unknown): x is Uint8Array => x instanceof Uint8Array || Buffer.isBuffer(x) - : (x: unknown): x is Uint8Array => x instanceof Uint8Array; diff --git a/src/util/buffers/printOctets.ts b/src/util/buffers/printOctets.ts deleted file mode 100644 index 9e5c01f..0000000 --- a/src/util/buffers/printOctets.ts +++ /dev/null @@ -1,14 +0,0 @@ -export const printOctets = (octets: Uint8Array, max: number = 16): string => { - let str = ''; - if (!octets.length) return str; - if (octets[0] < 16) str += '0'; - str += octets[0].toString(16); - for (let i = 1; i < octets.length && i < max; i++) { - const n = octets[i]; - str += ' '; - if (n < 16) str += '0'; - str += n.toString(16); - } - if (octets.length > max) str += `… (${octets.length - max} more)`; - return str; -}; diff --git a/src/util/buffers/strings.ts b/src/util/buffers/strings.ts deleted file mode 100644 index f4ac5b7..0000000 --- a/src/util/buffers/strings.ts +++ /dev/null @@ -1,16 +0,0 @@ -import {bufferToUint8Array} from './bufferToUint8Array'; - -export const ascii = (txt: TemplateStringsArray | string | [string]): Uint8Array => { - if (typeof txt === 'string') return ascii([txt]); - [txt] = txt; - const len = txt.length; - const res = new Uint8Array(len); - for (let i = 0; i < len; i++) res[i] = txt.charCodeAt(i); - return res; -}; - -export const utf8 = (txt: TemplateStringsArray | [string] | string): Uint8Array => { - if (typeof txt === 'string') return utf8([txt]); - [txt] = txt; - return bufferToUint8Array(Buffer.from(txt, 'utf8')); -}; diff --git a/src/util/buffers/toBuf.ts b/src/util/buffers/toBuf.ts deleted file mode 100644 index 576f8a5..0000000 --- a/src/util/buffers/toBuf.ts +++ /dev/null @@ -1,8 +0,0 @@ -import {encode} from './utf8/encode'; - -export const toBuf = (str: string): Uint8Array => { - const maxLength = str.length * 4; - const arr = new Uint8Array(maxLength); - const strBufferLength = encode(arr, str, 0, maxLength); - return arr.slice(0, strBufferLength); -}; diff --git a/src/util/buffers/toUint8Array.ts b/src/util/buffers/toUint8Array.ts deleted file mode 100644 index 8e2c916..0000000 --- a/src/util/buffers/toUint8Array.ts +++ /dev/null @@ -1,10 +0,0 @@ -export const toUint8Array = (data: unknown): Uint8Array => { - if (data instanceof Uint8Array) return data; - if (data instanceof ArrayBuffer) return new Uint8Array(data); - if (Array.isArray(data)) return new Uint8Array(data); - if (typeof Buffer === 'function') { - if (Buffer.isBuffer(data)) return data; - return Buffer.from(data as any); - } - throw new Error('UINT8ARRAY_INCOMPATIBLE'); -}; diff --git a/src/util/buffers/types.ts b/src/util/buffers/types.ts deleted file mode 100644 index ae29727..0000000 --- a/src/util/buffers/types.ts +++ /dev/null @@ -1,126 +0,0 @@ -import type {Slice} from './Slice'; - -export interface IWriter { - /** - * Uint8Array view of the current memory buffer. - */ - uint8: Uint8Array; - - /** - * DataView view of the current memory buffer. - */ - view: DataView; - - /** - * Position where last flush happened. - */ - x0: number; - - /** - * Current position in the internal buffer. - */ - x: number; - - u8(char: number): void; - u16(word: number): void; - u32(dword: number): void; - i32(dword: number): void; - u64(qword: number | bigint): void; - u8u16(u8: number, u16: number): void; - u8u32(u8: number, u32: number): void; - u8u64(u8: number, u64: number | bigint): void; - u8f32(u8: number, f64: number): void; - u8f64(u8: number, f64: number): void; - f64(dword: number): void; - - /** - * Write contents of a buffer. - * - * @param buf Buffer to copy from. - * @param length Number of octets to copy. - */ - buf(buf: Uint8Array, length: number): void; - - /** - * Write string as UTF-8. You need to call .ensureCapacity(str.length * 4) - * before calling - * - * @param str JavaScript string to encode as UTF-8 byte sequence. - */ - utf8(str: string): number; - - ascii(str: string): void; -} - -export interface IWriterGrowable { - /** @deprecated */ - reset(): void; - - /** - * Calling this method might reset the internal buffer. So, your references - * (such as `x`, `uint8`, `view`) to the internal buffer might become invalid. - * - * @param capacity How many octets to ensure are available after `x`. - */ - ensureCapacity(capacity: number): void; - move(length: number): void; - flush(): Uint8Array; - flushSlice(): Slice; - newBuffer(size: number): void; -} - -export interface IReaderBase { - /** Get current byte value without advancing the cursor. */ - peak(): number; - - /** Advance the cursor given number of octets. */ - skip(length: number): void; - - /** - * Create a new Uint8Array view of provided length starting at - * the current cursor position. - */ - buf(size: number): Uint8Array; - - u8(): number; - i8(): number; - u16(): number; - i16(): number; - u32(): number; - u64(): bigint; - i64(): bigint; - i32(): number; - f32(): number; - f64(): number; - - /** - * Decode a UTF-8 string. - * - * @param size Length of the string. - */ - utf8(size: number): string; - - ascii(length: number): string; -} - -export interface IReader extends IReaderBase { - /** - * Uint8Array view of the current memory buffer. - */ - uint8: Uint8Array; - - /** - * DataView view of the current memory buffer. - */ - view: DataView; - - /** - * Cursor in the current memory buffer. - */ - x: number; -} - -export interface IReaderResettable { - /** Set a new underlying buffer and reset cursor position to 0. */ - reset(uint8: Uint8Array): void; -} diff --git a/src/util/buffers/utf8/CachedUtf8Decoder.ts b/src/util/buffers/utf8/CachedUtf8Decoder.ts deleted file mode 100644 index 01dd36f..0000000 --- a/src/util/buffers/utf8/CachedUtf8Decoder.ts +++ /dev/null @@ -1,54 +0,0 @@ -import decodeUtf8 from './decodeUtf8/v10'; -import {randomU32} from 'hyperdyperid/lib/randomU32'; - -class CacheItem { - constructor( - public readonly bytes: Uint8Array, - public readonly value: string, - ) {} -} - -const enum CONST { - MAX_CACHED_STR_LEN = 31, - MAX_RECORDS_PER_SIZE = 16, -} - -export class CachedUtf8Decoder { - private readonly caches: CacheItem[][]; - - constructor() { - this.caches = []; - for (let i = 0; i < CONST.MAX_CACHED_STR_LEN; i++) this.caches.push([]); - } - - private get(bytes: Uint8Array, offset: number, size: number): string | null { - const records = this.caches[size - 1]!; - const len = records.length; - FIND_CHUNK: for (let i = 0; i < len; i++) { - const record = records[i]; - const recordBytes = record.bytes; - for (let j = 0; j < size; j++) if (recordBytes[j] !== bytes[offset + j]) continue FIND_CHUNK; - return record.value; - } - return null; - } - - private store(bytes: Uint8Array, value: string): void { - const records = this.caches[bytes.length - 1]!; - const record = new CacheItem(bytes, value); - const length = records.length; - if (length >= CONST.MAX_RECORDS_PER_SIZE) records[randomU32(0, CONST.MAX_RECORDS_PER_SIZE - 1)] = record; - else records.push(record); - } - - public decode(bytes: Uint8Array, offset: number, size: number): string { - if (!size) return ''; - const cachedValue = this.get(bytes, offset, size); - if (cachedValue !== null) return cachedValue; - const value = decodeUtf8(bytes, offset, size); - // 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 copy = Uint8Array.prototype.slice.call(bytes, offset, offset + size); - this.store(copy, value); - return value; - } -} diff --git a/src/util/buffers/utf8/__tests__/encode.spec.ts b/src/util/buffers/utf8/__tests__/encode.spec.ts deleted file mode 100644 index 5aeea13..0000000 --- a/src/util/buffers/utf8/__tests__/encode.spec.ts +++ /dev/null @@ -1,23 +0,0 @@ -import {RandomJson} from '../../../../json-random'; -import {encodeUtf8Write, encodeFrom, encodeNative, encodeTe, encode, EncodeString} from '../encode'; - -describe('can encode JavaScript string as UTF-8 string', () => { - const runEncodingTest = (name: string, encode: EncodeString) => { - test(name, () => { - const arr = new Uint8Array(50); - for (let i = 0; i < 1000; i++) { - const str = RandomJson.genString(10); - const len = encode(arr, str, str.length, str.length * 4); - const slice = arr.subarray(10, 10 + len); - const decoded = Buffer.from(slice).toString(); - expect(decoded).toBe(str); - } - }); - }; - - runEncodingTest('encodeUtf8Write', encodeUtf8Write); - runEncodingTest('encodeFrom', encodeFrom); - runEncodingTest('encodeNative', encodeNative); - runEncodingTest('encodeTe', encodeTe); - runEncodingTest('encode', encode); -}); diff --git a/src/util/buffers/utf8/__tests__/isUtf8.spec.ts b/src/util/buffers/utf8/__tests__/isUtf8.spec.ts deleted file mode 100644 index 6ea5aea..0000000 --- a/src/util/buffers/utf8/__tests__/isUtf8.spec.ts +++ /dev/null @@ -1,54 +0,0 @@ -import {isUtf8} from '../isUtf8'; - -describe('returns true for valid UTF8', () => { - const strings = [ - '', - 'hello', - 'hello world', - 'emoji: 🤔', - 'russian: Привет', - 'chinese: 你好', - 'japanese: こんにちは', - 'korean: 안녕하세요', - 'arabic: مرحبا', - 'hebrew: שלום', - 'greek: γεια σας', - 'bulgarian: Здравейте', - 'hindi: नमस्ते', - 'thai: สวัสดี', - 'special chars: !@#$%^&*()_+{}|:"<>?`-=[]\\;\',./', - ]; - for (const str of strings) { - test(str, () => { - const buf = Buffer.from(str); - expect(isUtf8(buf, 0, buf.length)).toBe(true); - }); - } -}); - -describe('returns false for non-UTF8 sequences', () => { - const strings: [name: string, Uint8Array][] = [ - ['two octets', Buffer.from([0xc3, 0x28])], - ['three octets', Buffer.from([0xe2, 0x82, 0x28])], - ['four octets', Buffer.from([0xf0, 0x90, 0x82, 0x28])], - ['five octets', Buffer.from([0xf8, 0x88, 0x82, 0x82, 0x28])], - ['six octets', Buffer.from([0xfc, 0x84, 0x82, 0x82, 0x82, 0x28])], - ]; - for (const [name, str] of strings) { - test(name, () => { - expect(isUtf8(str, 0, str.length)).toBe(false); - }); - } -}); - -describe('returns true for valid non-UTF8 sequences in the middle of buffer', () => { - const strings: [name: string, str: Uint8Array, from: number, length: number][] = [ - ['mid char valid', Buffer.from([0xc3, 0x28, 64, 0xc3, 0x28]), 2, 1], - ]; - for (const [name, str, from, length] of strings) { - test(name, () => { - expect(isUtf8(str, from, length)).toBe(true); - expect(isUtf8(str, 0, from + length)).toBe(false); - }); - } -}); diff --git a/src/util/buffers/utf8/decodeAscii.ts b/src/util/buffers/utf8/decodeAscii.ts deleted file mode 100644 index cb84c50..0000000 --- a/src/util/buffers/utf8/decodeAscii.ts +++ /dev/null @@ -1,167 +0,0 @@ -const fromCharCode = String.fromCharCode; - -/** This code was borrowed form cbor-x under the MIT license. */ - -// MIT License - -// Copyright (c) 2020 Kris Zyp - -// Permission is hereby granted, free of charge, to any person obtaining a copy -// of this software and associated documentation files (the "Software"), to deal -// in the Software without restriction, including without limitation the rights -// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -// copies of the Software, and to permit persons to whom the Software is -// furnished to do so, subject to the following conditions: - -// The above copyright notice and this permission notice shall be included in all -// copies or substantial portions of the Software. - -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -// SOFTWARE. - -export const decodeAscii = (src: Uint8Array, position: number, length: number): string | undefined => { - const bytes = []; - for (let i = 0; i < length; i++) { - const byte = src[position++]; - if (byte & 0x80) return; - bytes.push(byte); - } - return fromCharCode.apply(String, bytes); -}; - -export const decodeAsciiMax15 = (src: Uint8Array, position: number, length: number): string | undefined => { - if (length < 4) { - if (length < 2) { - if (length === 0) return ''; - else { - const a = src[position++]; - if ((a & 0x80) > 1) { - position -= 1; - return; - } - return fromCharCode(a); - } - } else { - const a = src[position++]; - const b = src[position++]; - if ((a & 0x80) > 0 || (b & 0x80) > 0) { - position -= 2; - return; - } - if (length < 3) return fromCharCode(a, b); - const c = src[position++]; - if ((c & 0x80) > 0) { - position -= 3; - return; - } - return fromCharCode(a, b, c); - } - } else { - const a = src[position++]; - const b = src[position++]; - const c = src[position++]; - const d = src[position++]; - if ((a & 0x80) > 0 || (b & 0x80) > 0 || (c & 0x80) > 0 || (d & 0x80) > 0) { - position -= 4; - return; - } - if (length < 6) { - if (length === 4) return fromCharCode(a, b, c, d); - else { - const e = src[position++]; - if ((e & 0x80) > 0) { - position -= 5; - return; - } - return fromCharCode(a, b, c, d, e); - } - } else if (length < 8) { - const e = src[position++]; - const f = src[position++]; - if ((e & 0x80) > 0 || (f & 0x80) > 0) { - position -= 6; - return; - } - if (length < 7) return fromCharCode(a, b, c, d, e, f); - const g = src[position++]; - if ((g & 0x80) > 0) { - position -= 7; - return; - } - return fromCharCode(a, b, c, d, e, f, g); - } else { - const e = src[position++]; - const f = src[position++]; - const g = src[position++]; - const h = src[position++]; - if ((e & 0x80) > 0 || (f & 0x80) > 0 || (g & 0x80) > 0 || (h & 0x80) > 0) { - position -= 8; - return; - } - if (length < 10) { - if (length === 8) return fromCharCode(a, b, c, d, e, f, g, h); - else { - const i = src[position++]; - if ((i & 0x80) > 0) { - position -= 9; - return; - } - return fromCharCode(a, b, c, d, e, f, g, h, i); - } - } else if (length < 12) { - const i = src[position++]; - const j = src[position++]; - if ((i & 0x80) > 0 || (j & 0x80) > 0) { - position -= 10; - return; - } - if (length < 11) return fromCharCode(a, b, c, d, e, f, g, h, i, j); - const k = src[position++]; - if ((k & 0x80) > 0) { - position -= 11; - return; - } - return fromCharCode(a, b, c, d, e, f, g, h, i, j, k); - } else { - const i = src[position++]; - const j = src[position++]; - const k = src[position++]; - const l = src[position++]; - if ((i & 0x80) > 0 || (j & 0x80) > 0 || (k & 0x80) > 0 || (l & 0x80) > 0) { - position -= 12; - return; - } - if (length < 14) { - if (length === 12) return fromCharCode(a, b, c, d, e, f, g, h, i, j, k, l); - else { - const m = src[position++]; - if ((m & 0x80) > 0) { - position -= 13; - return; - } - return fromCharCode(a, b, c, d, e, f, g, h, i, j, k, l, m); - } - } else { - const m = src[position++]; - const n = src[position++]; - if ((m & 0x80) > 0 || (n & 0x80) > 0) { - position -= 14; - return; - } - if (length < 15) return fromCharCode(a, b, c, d, e, f, g, h, i, j, k, l, m, n); - const o = src[position++]; - if ((o & 0x80) > 0) { - position -= 15; - return; - } - return fromCharCode(a, b, c, d, e, f, g, h, i, j, k, l, m, n, o); - } - } - } - } -}; diff --git a/src/util/buffers/utf8/decodeUtf8/README.md b/src/util/buffers/utf8/decodeUtf8/README.md deleted file mode 100644 index dbdea0c..0000000 --- a/src/util/buffers/utf8/decodeUtf8/README.md +++ /dev/null @@ -1,96 +0,0 @@ -# `decodeUtf8` - -Decodes UTF-8 text from `Uint8Array` buffer to JavaScript string (UTF-16). - -- `Buffer.from(arr).subarray` (v4) is always faster than `Buffer.from(arr).slice` (v3). -- `Buffer.prototype.utf8Slice` (v2) is always faster than `Buffer.from(arr).subarray` (v4). - - But `Buffer.prototype.utf8Slice` (v2) is Node's internal implementation detail, so we need - to be able to fall back to `Buffer.from(arr).subarray` (v4). -- "JS with string concatenation" (v5) is fastest for tiny strings. -- "JS with buffering in array" (v1) is fastest for medium sized strings. -- `TextDecoder` (v6) is slower than any `Buffer` methods. - - However, `Buffer` is not available on the browser (and possibly other environments). So, - for long strings would be beneficial to use `TextDecoder` (v6). -- (v10) seems to be faster than (v5). -- (v9) seems to be the fastest out of the buffering approaches. - - -Benchmarks: - -``` -node benchmarks/util/buffers/bench.decodeUtf8.js -============================================================================= Benchmark: decodeUtf8 -Warming up each runner 1000x -------------------------------------------------------------------------- Single character, 1 bytes -👍 JS with buffering in array (v1) x 45,587,314 ops/sec ±0.35% (91 runs sampled) -👍 Buffer.prototype.utf8Slice (v2) x 9,669,294 ops/sec ±0.08% (95 runs sampled) -👍 Buffer.from(arr).slice (v3) x 6,522,838 ops/sec ±0.18% (93 runs sampled) -👍 Buffer.from(arr).subarray (v4) x 7,004,453 ops/sec ±0.17% (99 runs sampled) -👍 JS with string concatenation (v5) x 157,127,790 ops/sec ±0.08% (98 runs sampled) -👍 TextDecoder (v6) x 1,405,754 ops/sec ±1.57% (84 runs sampled) -Fastest is 👍 JS with string concatenation (v5) ----------------------------------------------------------------------------------- "Hello", 5 bytes -👍 JS with buffering in array (v1) x 26,293,330 ops/sec ±0.17% (98 runs sampled) -👍 Buffer.prototype.utf8Slice (v2) x 9,595,299 ops/sec ±0.13% (97 runs sampled) -👍 Buffer.from(arr).slice (v3) x 6,597,346 ops/sec ±0.27% (90 runs sampled) -👍 Buffer.from(arr).subarray (v4) x 6,913,974 ops/sec ±0.17% (98 runs sampled) -👍 JS with string concatenation (v5) x 33,109,095 ops/sec ±0.17% (100 runs sampled) -👍 TextDecoder (v6) x 1,393,950 ops/sec ±1.31% (87 runs sampled) -Fastest is 👍 JS with string concatenation (v5) -------------------------------------------------------------------- Short text with emoji, 14 bytes -👍 JS with buffering in array (v1) x 13,746,402 ops/sec ±0.61% (94 runs sampled) -👍 Buffer.prototype.utf8Slice (v2) x 8,573,654 ops/sec ±0.13% (99 runs sampled) -👍 Buffer.from(arr).slice (v3) x 6,003,418 ops/sec ±0.42% (97 runs sampled) -👍 Buffer.from(arr).subarray (v4) x 6,163,374 ops/sec ±0.35% (99 runs sampled) -👍 JS with string concatenation (v5) x 7,468,848 ops/sec ±0.26% (99 runs sampled) -👍 TextDecoder (v6) x 1,358,357 ops/sec ±1.32% (72 runs sampled) -Fastest is 👍 JS with buffering in array (v1) ---------------------------------------------------------------------- Repeating characters, 8 bytes -👍 JS with buffering in array (v1) x 18,606,797 ops/sec ±0.37% (99 runs sampled) -👍 Buffer.prototype.utf8Slice (v2) x 9,210,861 ops/sec ±0.26% (99 runs sampled) -👍 Buffer.from(arr).slice (v3) x 6,398,227 ops/sec ±0.23% (96 runs sampled) -👍 Buffer.from(arr).subarray (v4) x 6,820,514 ops/sec ±0.22% (99 runs sampled) -👍 JS with string concatenation (v5) x 17,943,107 ops/sec ±0.35% (94 runs sampled) -👍 TextDecoder (v6) x 1,448,300 ops/sec ±1.36% (75 runs sampled) -Fastest is 👍 JS with buffering in array (v1) --------------------------------------------------------------------- Repeating characters, 16 bytes -🤞 JS with buffering in array (v1) x 12,181,356 ops/sec ±0.26% (100 runs sampled) -🤞 Buffer.prototype.utf8Slice (v2) x 9,254,890 ops/sec ±0.25% (97 runs sampled) -🤞 Buffer.from(arr).slice (v3) x 6,407,754 ops/sec ±0.20% (99 runs sampled) -🤞 Buffer.from(arr).subarray (v4) x 6,738,914 ops/sec ±0.25% (98 runs sampled) -🤞 JS with string concatenation (v5) x 9,530,473 ops/sec ±0.21% (101 runs sampled) -🤞 TextDecoder (v6) x 1,456,139 ops/sec ±1.28% (77 runs sampled) -Fastest is 🤞 JS with buffering in array (v1) --------------------------------------------------------------------- Repeating characters, 32 bytes -🤞 JS with buffering in array (v1) x 6,327,652 ops/sec ±0.24% (100 runs sampled) -🤞 Buffer.prototype.utf8Slice (v2) x 8,958,249 ops/sec ±0.22% (99 runs sampled) -🤞 Buffer.from(arr).slice (v3) x 6,217,455 ops/sec ±0.23% (98 runs sampled) -🤞 Buffer.from(arr).subarray (v4) x 6,500,127 ops/sec ±0.18% (101 runs sampled) -🤞 JS with string concatenation (v5) x 5,647,992 ops/sec ±0.14% (99 runs sampled) -🤞 TextDecoder (v6) x 1,452,152 ops/sec ±1.26% (79 runs sampled) -Fastest is 🤞 Buffer.prototype.utf8Slice (v2) --------------------------------------------------------------------- Repeating characters, 64 bytes -🤞 JS with buffering in array (v1) x 3,141,539 ops/sec ±0.23% (99 runs sampled) -🤞 Buffer.prototype.utf8Slice (v2) x 8,898,315 ops/sec ±0.21% (99 runs sampled) -🤞 Buffer.from(arr).slice (v3) x 5,947,900 ops/sec ±0.24% (99 runs sampled) -🤞 Buffer.from(arr).subarray (v4) x 6,380,096 ops/sec ±0.17% (102 runs sampled) -🤞 JS with string concatenation (v5) x 3,027,083 ops/sec ±0.15% (96 runs sampled) -🤞 TextDecoder (v6) x 1,387,153 ops/sec ±0.86% (85 runs sampled) -Fastest is 🤞 Buffer.prototype.utf8Slice (v2) -------------------------------------------------------------------- Repeating characters, 128 bytes -🤞 JS with buffering in array (v1) x 1,525,792 ops/sec ±0.18% (98 runs sampled) -🤞 Buffer.prototype.utf8Slice (v2) x 8,600,267 ops/sec ±0.17% (98 runs sampled) -🤞 Buffer.from(arr).slice (v3) x 5,676,294 ops/sec ±0.16% (98 runs sampled) -🤞 Buffer.from(arr).subarray (v4) x 6,014,855 ops/sec ±0.23% (100 runs sampled) -🤞 JS with string concatenation (v5) x 1,612,844 ops/sec ±0.10% (100 runs sampled) -🤞 TextDecoder (v6) x 1,304,084 ops/sec ±1.14% (86 runs sampled) -Fastest is 🤞 Buffer.prototype.utf8Slice (v2) -------------------------------------------------------------------- Repeating characters, 256 bytes -🤞 JS with buffering in array (v1) x 673,037 ops/sec ±0.08% (98 runs sampled) -🤞 Buffer.prototype.utf8Slice (v2) x 7,934,918 ops/sec ±0.26% (99 runs sampled) -🤞 Buffer.from(arr).slice (v3) x 4,803,526 ops/sec ±0.25% (98 runs sampled) -🤞 Buffer.from(arr).subarray (v4) x 5,007,603 ops/sec ±0.27% (94 runs sampled) -🤞 JS with string concatenation (v5) x 816,504 ops/sec ±0.19% (101 runs sampled) -🤞 TextDecoder (v6) x 1,123,970 ops/sec ±0.90% (92 runs sampled) -Fastest is 🤞 Buffer.prototype.utf8Slice (v2) -``` diff --git a/src/util/buffers/utf8/decodeUtf8/__tests__/decodeUtf8.spec.ts b/src/util/buffers/utf8/decodeUtf8/__tests__/decodeUtf8.spec.ts deleted file mode 100644 index 2a74db7..0000000 --- a/src/util/buffers/utf8/decodeUtf8/__tests__/decodeUtf8.spec.ts +++ /dev/null @@ -1,120 +0,0 @@ -import v1 from '../v1'; -import v2 from '../v2'; -import v3 from '../v3'; -import v4 from '../v4'; -import v5 from '../v5'; -import v6 from '../v6'; -import v7 from '../v7'; -import v8 from '../v8'; -import v9 from '../v9'; -import v10 from '../v10'; -import v11 from '../v11'; -import v12 from '../v12'; -import v13 from '../v13'; -import v14 from '../v14'; -import v15 from '../v15'; -import v16 from '../v16'; -import v17 from '../v17'; -import v18 from '../v18'; -import v19 from '../v19'; - -type Decoder = (buf: Uint8Array, start: number, length: number) => string; - -const runTests = (name: string, decodeUtf8: Decoder) => { - describe(name, () => { - test('can decode basic string', () => { - const arr = new ArrayBuffer(8); - const buf = new Uint8Array(arr); - buf[0] = 1; - buf[1] = 0x61; - buf[2] = 0x62; - buf[3] = 0x63; - buf[4] = 0x64; - buf[5] = 0x65; - buf[6] = 0x66; - buf[7] = 1; - const uint8 = buf.subarray(1, 7); - const str = decodeUtf8(uint8, 1, 2); - expect(str).toBe('bc'); - }); - - test('can decode emoji', () => { - const arr = new ArrayBuffer(8); - const buf = new Uint8Array(arr); - buf[0] = 1; - buf[1] = 0x61; - buf[2] = 0xf0; - buf[3] = 0x9f; - buf[4] = 0x98; - buf[5] = 0x80; - buf[6] = 0x62; - buf[7] = 1; - const uint8 = buf.subarray(1, 7); - const str = decodeUtf8(uint8, 1, 4); - expect(str).toBe('😀'); - }); - - test('can decode a long string', () => { - const str = 'a'.repeat(33333); - const buf = Buffer.from(str); - const arr = new Uint8Array(buf.length); - for (let i = 0; i < arr.length; i++) arr[i] = buf[i]; - const str2 = decodeUtf8(arr, 0, arr.length); - expect(str2).toBe(str); - }); - - test('can decode real-world sentence', () => { - const str = '💯 RëactQuill v2 ReactQuill 2 is here, baby! And it brings a füll port to TypeScript and React 16+.'; - const buf = Buffer.from(str); - const arr = new Uint8Array(buf.length); - for (let i = 0; i < arr.length; i++) arr[i] = buf[i]; - const str2 = decodeUtf8(arr, 0, arr.length); - expect(str2).toBe(str); - }); - - test('can decode various types of characters', () => { - const alphabet = [ - // 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', - // 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', - // 'u', 'v', 'w', 'x', 'y', 'z', - // 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', - // 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', - // 'U', 'V', 'W', 'X', 'Y', 'Z', - // '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', - // '-', '_', '.', ',', ';', '!', '@', '#', '$', '%', - // '^', '&', '*', '\\', '/', '(', ')', '+', '=', '\n', - // '👍', '🏻', '😛', 'ä', 'ö', 'ü', 'ß', 'а', 'б', 'в', - 'г', - '诶', - '必', - '西', - ]; - const str = alphabet.join(''); - const buf = Buffer.from(str); - const arr = new Uint8Array(buf.length); - for (let i = 0; i < arr.length; i++) arr[i] = buf[i]; - const str2 = decodeUtf8(arr, 0, arr.length); - expect(str2).toBe(str); - }); - }); -}; - -runTests('v1', v1); -runTests('v2', v2); -runTests('v3', v3); -runTests('v4', v4); -runTests('v5', v5); -runTests('v6', v6); -runTests('v7', v7); -runTests('v8', v8); -runTests('v9', v9); -runTests('v10', v10); -runTests('v11', v11); -runTests('v12', v12); -runTests('v13', v13); -runTests('v14', v14); -runTests('v15', v15); -runTests('v16', v16); -runTests('v17', v17); -runTests('v18', v18); -runTests('v19', v19); diff --git a/src/util/buffers/utf8/decodeUtf8/index.ts b/src/util/buffers/utf8/decodeUtf8/index.ts deleted file mode 100644 index 7e93498..0000000 --- a/src/util/buffers/utf8/decodeUtf8/index.ts +++ /dev/null @@ -1,3 +0,0 @@ -import decodeUtf8 from './v16'; - -export {decodeUtf8}; diff --git a/src/util/buffers/utf8/decodeUtf8/v1.ts b/src/util/buffers/utf8/decodeUtf8/v1.ts deleted file mode 100644 index d912302..0000000 --- a/src/util/buffers/utf8/decodeUtf8/v1.ts +++ /dev/null @@ -1,38 +0,0 @@ -export default (buf: Uint8Array, start: number, length: number): string => { - let offset = start; - const end = offset + length; - const units: Array = []; - let result = ''; - while (offset < end) { - const byte1 = buf[offset++]!; - if ((byte1 & 0x80) === 0) { - units.push(byte1); - } else if ((byte1 & 0xe0) === 0xc0) { - const byte2 = buf[offset++]! & 0x3f; - units.push(((byte1 & 0x1f) << 6) | byte2); - } else if ((byte1 & 0xf0) === 0xe0) { - const byte2 = buf[offset++]! & 0x3f; - const byte3 = buf[offset++]! & 0x3f; - units.push(((byte1 & 0x1f) << 12) | (byte2 << 6) | byte3); - } else if ((byte1 & 0xf8) === 0xf0) { - const byte2 = buf[offset++]! & 0x3f; - const byte3 = buf[offset++]! & 0x3f; - const byte4 = buf[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 >= 1000) { - result += String.fromCharCode(...units); - units.length = 0; - } - } - if (units.length > 0) result += String.fromCharCode(...units); - return result; -}; diff --git a/src/util/buffers/utf8/decodeUtf8/v10.ts b/src/util/buffers/utf8/decodeUtf8/v10.ts deleted file mode 100644 index ebf8b03..0000000 --- a/src/util/buffers/utf8/decodeUtf8/v10.ts +++ /dev/null @@ -1,39 +0,0 @@ -const fromCharCode = String.fromCharCode; - -export default (buf: Uint8Array, start: number, length: number): string => { - let offset = start; - const end = offset + length; - let str = ''; - while (offset < end) { - const octet1 = buf[offset++]!; - if ((octet1 & 0x80) === 0) { - str += fromCharCode(octet1); - continue; - } - const octet2 = buf[offset++]! & 0x3f; - if ((octet1 & 0xe0) === 0xc0) { - str += fromCharCode(((octet1 & 0x1f) << 6) | octet2); - continue; - } - const octet3 = buf[offset++]! & 0x3f; - if ((octet1 & 0xf0) === 0xe0) { - str += fromCharCode(((octet1 & 0x1f) << 12) | (octet2 << 6) | octet3); - continue; - } - if ((octet1 & 0xf8) === 0xf0) { - const octet4 = buf[offset++]! & 0x3f; - let unit = ((octet1 & 0x07) << 0x12) | (octet2 << 0x0c) | (octet3 << 0x06) | octet4; - if (unit > 0xffff) { - unit -= 0x10000; - const unit0 = ((unit >>> 10) & 0x3ff) | 0xd800; - unit = 0xdc00 | (unit & 0x3ff); - str += fromCharCode(unit0, unit); - } else { - str += fromCharCode(unit); - } - } else { - str += fromCharCode(octet1); - } - } - return str; -}; diff --git a/src/util/buffers/utf8/decodeUtf8/v11.ts b/src/util/buffers/utf8/decodeUtf8/v11.ts deleted file mode 100644 index f3beea7..0000000 --- a/src/util/buffers/utf8/decodeUtf8/v11.ts +++ /dev/null @@ -1,2 +0,0 @@ -const utf8Slice = Buffer.prototype.utf8Slice; -export default (buf: Uint8Array, start: number, length: number): string => utf8Slice.call(buf, start, start + length); diff --git a/src/util/buffers/utf8/decodeUtf8/v12.ts b/src/util/buffers/utf8/decodeUtf8/v12.ts deleted file mode 100644 index 4a31f6d..0000000 --- a/src/util/buffers/utf8/decodeUtf8/v12.ts +++ /dev/null @@ -1,5 +0,0 @@ -const from = Buffer.from; -export default (arr: Uint8Array, start: number, length: number): string => - from(arr) - .subarray(start, start + length) - .toString(); diff --git a/src/util/buffers/utf8/decodeUtf8/v13.ts b/src/util/buffers/utf8/decodeUtf8/v13.ts deleted file mode 100644 index de26b1d..0000000 --- a/src/util/buffers/utf8/decodeUtf8/v13.ts +++ /dev/null @@ -1,27 +0,0 @@ -import v10 from './v10'; - -let decode = v10; - -const hasBuffer = typeof Buffer !== 'undefined'; -const utf8Slice = hasBuffer ? Buffer.prototype.utf8Slice : null; - -if (utf8Slice) { - decode = (buf: Uint8Array, start: number, length: number): string => - length <= 10 ? v10(buf, start, length) : utf8Slice.call(buf, start, start + length); -} else { - const from = hasBuffer ? Buffer.from : null; - if (from) { - decode = (buf: Uint8Array, start: number, length: number): string => - length < 30 - ? v10(buf, start, length) - : from(buf) - .subarray(start, start + length) - .toString(); - } else if (typeof TextDecoder !== 'undefined') { - const decoder = new TextDecoder(); - decode = (buf: Uint8Array, start: number, length: number): string => - length < 150 ? v10(buf, start, length) : decoder.decode(buf.subarray(start, start + length)); - } -} - -export default decode; diff --git a/src/util/buffers/utf8/decodeUtf8/v14.ts b/src/util/buffers/utf8/decodeUtf8/v14.ts deleted file mode 100644 index d9062ad..0000000 --- a/src/util/buffers/utf8/decodeUtf8/v14.ts +++ /dev/null @@ -1,8 +0,0 @@ -import v10 from './v10'; - -const hasBuffer = typeof Buffer !== 'undefined'; -const utf8Slice = hasBuffer ? Buffer.prototype.utf8Slice : null; - -export default utf8Slice - ? (buf: Uint8Array, start: number, length: number): string => utf8Slice.call(buf, start, start + length) - : v10; diff --git a/src/util/buffers/utf8/decodeUtf8/v15.ts b/src/util/buffers/utf8/decodeUtf8/v15.ts deleted file mode 100644 index b5557c0..0000000 --- a/src/util/buffers/utf8/decodeUtf8/v15.ts +++ /dev/null @@ -1,16 +0,0 @@ -import v10 from './v10'; - -const hasBuffer = typeof Buffer !== 'undefined'; -const utf8Slice = hasBuffer ? Buffer.prototype.utf8Slice : null; -const from = hasBuffer ? Buffer.from : null; - -export default (buf: Uint8Array, start: number, length: number): string => { - const end = start + length; - return length > 8 - ? utf8Slice - ? utf8Slice.call(buf, start, end) - : from - ? from(buf).subarray(start, end).toString('utf8') - : v10(buf, start, length) - : v10(buf, start, length); -}; diff --git a/src/util/buffers/utf8/decodeUtf8/v16.ts b/src/util/buffers/utf8/decodeUtf8/v16.ts deleted file mode 100644 index c95f699..0000000 --- a/src/util/buffers/utf8/decodeUtf8/v16.ts +++ /dev/null @@ -1,29 +0,0 @@ -import {decodeAscii, decodeAsciiMax15} from '../decodeAscii'; -import v18 from './v18'; - -type Decoder = (buf: Uint8Array, start: number, length: number) => string; - -const hasBuffer = typeof Buffer !== 'undefined'; -const utf8Slice = hasBuffer ? Buffer.prototype.utf8Slice : null; -const from = hasBuffer ? Buffer.from : null; - -const shortDecoder: Decoder = (buf, start, length) => decodeAsciiMax15(buf, start, length) ?? v18(buf, start, length); - -const midDecoder: Decoder = (buf, start, length) => decodeAscii(buf, start, length) ?? v18(buf, start, length); - -const longDecoder: Decoder = utf8Slice - ? (buf, start, length) => utf8Slice.call(buf, start, start + length) - : from - ? (buf, start, length) => - from(buf) - .subarray(start, start + length) - .toString('utf8') - : v18; - -const decoder: Decoder = (buf, start, length): string => { - if (length < 16) return shortDecoder(buf, start, length); - if (length < 32) return midDecoder(buf, start, length); - return longDecoder(buf, start, length); -}; - -export default decoder; diff --git a/src/util/buffers/utf8/decodeUtf8/v17.ts b/src/util/buffers/utf8/decodeUtf8/v17.ts deleted file mode 100644 index 604ac7e..0000000 --- a/src/util/buffers/utf8/decodeUtf8/v17.ts +++ /dev/null @@ -1,37 +0,0 @@ -const fromCharCode = String.fromCharCode; - -export default (buf: Uint8Array, start: number, length: number): string => { - let offset = start; - const end = offset + length; - let str = ''; - while (offset < end) { - let code = buf[offset++]!; - if ((code & 0x80) !== 0) { - const octet2 = buf[offset++]! & 0x3f; - if ((code & 0xe0) === 0xc0) { - code = ((code & 0x1f) << 6) | octet2; - } else { - const octet3 = buf[offset++]! & 0x3f; - if ((code & 0xf0) === 0xe0) { - code = ((code & 0x1f) << 12) | (octet2 << 6) | octet3; - } else { - if ((code & 0xf8) === 0xf0) { - const octet4 = buf[offset++]! & 0x3f; - let unit = ((code & 0x07) << 0x12) | (octet2 << 0x0c) | (octet3 << 0x06) | octet4; - if (unit > 0xffff) { - unit -= 0x10000; - const unit0 = ((unit >>> 10) & 0x3ff) | 0xd800; - unit = 0xdc00 | (unit & 0x3ff); - str += fromCharCode(unit0); - code = unit; - } else { - code = unit; - } - } - } - } - } - str += fromCharCode(code); - } - return str; -}; diff --git a/src/util/buffers/utf8/decodeUtf8/v18.ts b/src/util/buffers/utf8/decodeUtf8/v18.ts deleted file mode 100644 index e1b518e..0000000 --- a/src/util/buffers/utf8/decodeUtf8/v18.ts +++ /dev/null @@ -1,36 +0,0 @@ -const fromCharCode = String.fromCharCode; - -export default (buf: Uint8Array, start: number, length: number): string => { - let offset = start; - const end = offset + length; - const points: number[] = []; - while (offset < end) { - let code = buf[offset++]!; - if ((code & 0x80) !== 0) { - const octet2 = buf[offset++]! & 0x3f; - if ((code & 0xe0) === 0xc0) { - code = ((code & 0x1f) << 6) | octet2; - } else { - const octet3 = buf[offset++]! & 0x3f; - if ((code & 0xf0) === 0xe0) { - code = ((code & 0x1f) << 12) | (octet2 << 6) | octet3; - } else { - if ((code & 0xf8) === 0xf0) { - const octet4 = buf[offset++]! & 0x3f; - let unit = ((code & 0x07) << 0x12) | (octet2 << 0x0c) | (octet3 << 0x06) | octet4; - if (unit > 0xffff) { - unit -= 0x10000; - const unit0 = ((unit >>> 10) & 0x3ff) | 0xd800; - code = 0xdc00 | (unit & 0x3ff); - points.push(unit0); - } else { - code = unit; - } - } - } - } - } - points.push(code); - } - return fromCharCode.apply(String, points); -}; diff --git a/src/util/buffers/utf8/decodeUtf8/v19.ts b/src/util/buffers/utf8/decodeUtf8/v19.ts deleted file mode 100644 index 2bbc39d..0000000 --- a/src/util/buffers/utf8/decodeUtf8/v19.ts +++ /dev/null @@ -1,3 +0,0 @@ -const {readUtf8} = require('json-pack-napi'); - -export default readUtf8; diff --git a/src/util/buffers/utf8/decodeUtf8/v2.ts b/src/util/buffers/utf8/decodeUtf8/v2.ts deleted file mode 100644 index c661240..0000000 --- a/src/util/buffers/utf8/decodeUtf8/v2.ts +++ /dev/null @@ -1,2 +0,0 @@ -export default (buf: Uint8Array, start: number, length: number): string => - Buffer.prototype.utf8Slice.call(buf, start, start + length); diff --git a/src/util/buffers/utf8/decodeUtf8/v3.ts b/src/util/buffers/utf8/decodeUtf8/v3.ts deleted file mode 100644 index fb8adea..0000000 --- a/src/util/buffers/utf8/decodeUtf8/v3.ts +++ /dev/null @@ -1,4 +0,0 @@ -export default (arr: Uint8Array, start: number, length: number): string => - Buffer.from(arr) - .slice(start, start + length) - .toString(); diff --git a/src/util/buffers/utf8/decodeUtf8/v4.ts b/src/util/buffers/utf8/decodeUtf8/v4.ts deleted file mode 100644 index 23b2678..0000000 --- a/src/util/buffers/utf8/decodeUtf8/v4.ts +++ /dev/null @@ -1,4 +0,0 @@ -export default (arr: Uint8Array, start: number, length: number): string => - Buffer.from(arr) - .subarray(start, start + length) - .toString(); diff --git a/src/util/buffers/utf8/decodeUtf8/v5.ts b/src/util/buffers/utf8/decodeUtf8/v5.ts deleted file mode 100644 index c00b6ca..0000000 --- a/src/util/buffers/utf8/decodeUtf8/v5.ts +++ /dev/null @@ -1,30 +0,0 @@ -export default (uint8: Uint8Array, start: number, length: number): string => { - const end = start + length; - let x = start; - let str = ''; - while (x < end) { - const b1 = uint8[x++]!; - if ((b1 & 0x80) === 0) { - str += String.fromCharCode(b1); - continue; - } else if ((b1 & 0xe0) === 0xc0) { - str += String.fromCharCode(((b1 & 0x1f) << 6) | (uint8[x++]! & 0x3f)); - } else if ((b1 & 0xf0) === 0xe0) { - str += String.fromCharCode(((b1 & 0x1f) << 12) | ((uint8[x++]! & 0x3f) << 6) | (uint8[x++]! & 0x3f)); - } else if ((b1 & 0xf8) === 0xf0) { - const b2 = uint8[x++]! & 0x3f; - const b3 = uint8[x++]! & 0x3f; - const b4 = uint8[x++]! & 0x3f; - let code = ((b1 & 0x07) << 0x12) | (b2 << 0x0c) | (b3 << 0x06) | b4; - if (code > 0xffff) { - code -= 0x10000; - str += String.fromCharCode(((code >>> 10) & 0x3ff) | 0xd800); - code = 0xdc00 | (code & 0x3ff); - } - str += String.fromCharCode(code); - } else { - str += String.fromCharCode(b1); - } - } - return str; -}; diff --git a/src/util/buffers/utf8/decodeUtf8/v6.ts b/src/util/buffers/utf8/decodeUtf8/v6.ts deleted file mode 100644 index 88acf9b..0000000 --- a/src/util/buffers/utf8/decodeUtf8/v6.ts +++ /dev/null @@ -1,6 +0,0 @@ -const sharedTextDecoder = new TextDecoder(); - -export default (uint8: Uint8Array, start: number, length: number): string => { - const stringBytes = uint8.subarray(start, start + length); - return sharedTextDecoder.decode(stringBytes); -}; diff --git a/src/util/buffers/utf8/decodeUtf8/v7.ts b/src/util/buffers/utf8/decodeUtf8/v7.ts deleted file mode 100644 index 32ff0da..0000000 --- a/src/util/buffers/utf8/decodeUtf8/v7.ts +++ /dev/null @@ -1,32 +0,0 @@ -export default (buf: Uint8Array, start: number, length: number): string => { - let offset = start; - const end = offset + length; - const codes: Array = []; - while (offset < end) { - const octet1 = buf[offset++]!; - if ((octet1 & 0x80) === 0) { - codes.push(octet1); - } else if ((octet1 & 0xe0) === 0xc0) { - const octet2 = buf[offset++]! & 0x3f; - codes.push(((octet1 & 0x1f) << 6) | octet2); - } else if ((octet1 & 0xf0) === 0xe0) { - const octet2 = buf[offset++]! & 0x3f; - const octet3 = buf[offset++]! & 0x3f; - codes.push(((octet1 & 0x1f) << 12) | (octet2 << 6) | octet3); - } else if ((octet1 & 0xf8) === 0xf0) { - const octet2 = buf[offset++]! & 0x3f; - const octet3 = buf[offset++]! & 0x3f; - const octet4 = buf[offset++]! & 0x3f; - let unit = ((octet1 & 0x07) << 0x12) | (octet2 << 0x0c) | (octet3 << 0x06) | octet4; - if (unit > 0xffff) { - unit -= 0x10000; - codes.push(((unit >>> 10) & 0x3ff) | 0xd800); - unit = 0xdc00 | (unit & 0x3ff); - } - codes.push(unit); - } else { - codes.push(octet1); - } - } - return String.fromCharCode(...codes); -}; diff --git a/src/util/buffers/utf8/decodeUtf8/v8.ts b/src/util/buffers/utf8/decodeUtf8/v8.ts deleted file mode 100644 index 28b77f6..0000000 --- a/src/util/buffers/utf8/decodeUtf8/v8.ts +++ /dev/null @@ -1,39 +0,0 @@ -// String.fromCharCode(...units) flushing happens more often. -export default (buf: Uint8Array, start: number, length: number): string => { - let offset = start; - const end = offset + length; - const units: Array = []; - let result = ''; - while (offset < end) { - const byte1 = buf[offset++]!; - if ((byte1 & 0x80) === 0) { - units.push(byte1); - } else if ((byte1 & 0xe0) === 0xc0) { - const byte2 = buf[offset++]! & 0x3f; - units.push(((byte1 & 0x1f) << 6) | byte2); - } else if ((byte1 & 0xf0) === 0xe0) { - const byte2 = buf[offset++]! & 0x3f; - const byte3 = buf[offset++]! & 0x3f; - units.push(((byte1 & 0x1f) << 12) | (byte2 << 6) | byte3); - } else if ((byte1 & 0xf8) === 0xf0) { - const byte2 = buf[offset++]! & 0x3f; - const byte3 = buf[offset++]! & 0x3f; - const byte4 = buf[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 >= 8) { - result += String.fromCharCode(...units); - units.length = 0; - } - } - if (units.length > 0) result += String.fromCharCode(...units); - return result; -}; diff --git a/src/util/buffers/utf8/decodeUtf8/v9.ts b/src/util/buffers/utf8/decodeUtf8/v9.ts deleted file mode 100644 index 975c03e..0000000 --- a/src/util/buffers/utf8/decodeUtf8/v9.ts +++ /dev/null @@ -1,35 +0,0 @@ -export default (buf: Uint8Array, start: number, length: number): string => { - let offset = start; - const end = offset + length; - const codes: Array = []; - while (offset < end) { - const octet1 = buf[offset++]!; - if ((octet1 & 0x80) === 0) { - codes.push(octet1); - continue; - } - const octet2 = buf[offset++]! & 0x3f; - if ((octet1 & 0xe0) === 0xc0) { - codes.push(((octet1 & 0x1f) << 6) | octet2); - continue; - } - const octet3 = buf[offset++]! & 0x3f; - if ((octet1 & 0xf0) === 0xe0) { - codes.push(((octet1 & 0x1f) << 12) | (octet2 << 6) | octet3); - continue; - } - if ((octet1 & 0xf8) === 0xf0) { - const octet4 = buf[offset++]! & 0x3f; - let unit = ((octet1 & 0x07) << 0x12) | (octet2 << 0x0c) | (octet3 << 0x06) | octet4; - if (unit > 0xffff) { - unit -= 0x10000; - codes.push(((unit >>> 10) & 0x3ff) | 0xd800); - unit = 0xdc00 | (unit & 0x3ff); - } - codes.push(unit); - } else { - codes.push(octet1); - } - } - return String.fromCharCode(...codes); -}; diff --git a/src/util/buffers/utf8/encode.ts b/src/util/buffers/utf8/encode.ts deleted file mode 100644 index dedb236..0000000 --- a/src/util/buffers/utf8/encode.ts +++ /dev/null @@ -1,58 +0,0 @@ -const hasBuffer = typeof Buffer !== undefined; -const utf8Write = hasBuffer - ? (Buffer.prototype.utf8Write as (this: Uint8Array, str: string, pos: number, maxLength: number) => number) - : null; -const from = hasBuffer ? Buffer.from : null; - -export type EncodeString = (arr: Uint8Array, str: string, pos: number, maxLength: number) => number; - -export const encodeUtf8Write: EncodeString = (arr: Uint8Array, str: string, pos: number, maxLength: number): number => - utf8Write!.call(arr, str, pos, maxLength); - -export const encodeFrom: EncodeString = (arr: Uint8Array, str: string, pos: number, maxLength: number): number => { - const offset = arr.byteOffset + pos; - const buf = from!(arr.buffer).subarray(offset, offset + maxLength); - return buf.write(str, 0, maxLength, 'utf8'); -}; - -export const encodeNative: EncodeString = (arr: Uint8Array, str: string, pos: number, maxLength: number): number => { - const length = str.length; - const start = pos; - let curr = 0; - while (curr < length) { - let value = str.charCodeAt(curr++); - if ((value & 0xffffff80) === 0) { - arr[pos++] = value; - continue; - } else if ((value & 0xfffff800) === 0) { - arr[pos++] = ((value >> 6) & 0x1f) | 0xc0; - } else { - if (value >= 0xd800 && value <= 0xdbff) { - if (curr < length) { - const extra = str.charCodeAt(curr); - if ((extra & 0xfc00) === 0xdc00) { - curr++; - value = ((value & 0x3ff) << 10) + (extra & 0x3ff) + 0x10000; - } - } - } - if ((value & 0xffff0000) === 0) { - arr[pos++] = ((value >> 12) & 0x0f) | 0xe0; - arr[pos++] = ((value >> 6) & 0x3f) | 0x80; - } else { - arr[pos++] = ((value >> 18) & 0x07) | 0xf0; - arr[pos++] = ((value >> 12) & 0x3f) | 0x80; - arr[pos++] = ((value >> 6) & 0x3f) | 0x80; - } - } - arr[pos++] = (value & 0x3f) | 0x80; - } - return pos - start; -}; - -const textEncoder = typeof TextEncoder !== 'undefined' ? new TextEncoder() : null; - -export const encodeTe: EncodeString = (arr: Uint8Array, str: string, pos: number, maxLength: number): number => - textEncoder!.encodeInto(str, arr.subarray(pos, pos + maxLength)).written!; - -export const encode = utf8Write ? encodeUtf8Write : from ? encodeFrom : encodeNative; diff --git a/src/util/buffers/utf8/isUtf8.ts b/src/util/buffers/utf8/isUtf8.ts deleted file mode 100644 index 5b846f0..0000000 --- a/src/util/buffers/utf8/isUtf8.ts +++ /dev/null @@ -1,45 +0,0 @@ -/** - * Validates that the given data is valid UTF-8 text. - * @param buf Data to check. - * @returns True if the data is valid UTF-8. - */ -export const isUtf8 = (buf: Uint8Array, from: number, length: number): boolean => { - const to = from + length; - while (from < to) { - const c = buf[from]; - if (c <= 0x7f) { - from++; - continue; - } - if (c >= 0xc2 && c <= 0xdf) { - if (buf[from + 1] >> 6 === 2) { - from += 2; - continue; - } else return false; - } - const c1 = buf[from + 1]; - if ( - ((c === 0xe0 && c1 >= 0xa0 && c1 <= 0xbf) || (c === 0xed && c1 >= 0x80 && c1 <= 0x9f)) && - buf[from + 2] >> 6 === 2 - ) { - from += 3; - continue; - } - if (((c >= 0xe1 && c <= 0xec) || (c >= 0xee && c <= 0xef)) && c1 >> 6 === 2 && buf[from + 2] >> 6 === 2) { - from += 3; - continue; - } - if ( - ((c === 0xf0 && c1 >= 0x90 && c1 <= 0xbf) || - (c >= 0xf1 && c <= 0xf3 && c1 >> 6 === 2) || - (c === 0xf4 && c1 >= 0x80 && c1 <= 0x8f)) && - buf[from + 2] >> 6 === 2 && - buf[from + 3] >> 6 === 2 - ) { - from += 4; - continue; - } - return false; - } - return true; -}; diff --git a/src/util/buffers/utf8/sharedCachedUtf8Decoder.ts b/src/util/buffers/utf8/sharedCachedUtf8Decoder.ts deleted file mode 100644 index 86b2d4a..0000000 --- a/src/util/buffers/utf8/sharedCachedUtf8Decoder.ts +++ /dev/null @@ -1,3 +0,0 @@ -import {CachedUtf8Decoder} from './CachedUtf8Decoder'; - -export default new CachedUtf8Decoder(); diff --git a/src/util/codegen/Codegen.ts b/src/util/codegen/Codegen.ts deleted file mode 100644 index ab929b1..0000000 --- a/src/util/codegen/Codegen.ts +++ /dev/null @@ -1,296 +0,0 @@ -import {compileClosure} from '.'; -import type {JavaScriptLinked} from './types'; - -/** - * Inline JavaScript statements that are executed in main function body. - */ -export class CodegenStepExecJs { - constructor(public readonly js: string) {} -} - -/** - * A step can be `CodegenStepExecJs` or some application specific step, which - * will later will need to be converted to `CodegenStepExecJs`. - */ -type JsonSerializerStep = CodegenStepExecJs | unknown; - -/** - * Configuration options for {@link Codegen} instances. - */ -export interface CodegenOptions> { - /** - * Inline JavaScript string that represents the arguments that will be passed - * to the main function body. Defaults to "r0", i.e. the first register. - */ - args?: string[]; - - /** - * Name of the generated function. - */ - name?: string; - - /** - * Inline JavaScript statements, that execute at the beginning of the main - * function body. - */ - prologue?: string; - - /** - * Inline JavaScript statements, that execute at the end of the main - * function body. - */ - epilogue?: string | (() => string); - - /** - * Converts all steps to `CodegenStepExecJs`. - */ - processSteps?: (steps: JsonSerializerStep[]) => CodegenStepExecJs[]; - - /** - * Predefined list of dependencies that can be linked on demand. Dependency is - * linked with the name of the property and is linked only once. - */ - linkable?: Linkable; -} - -export type CodegenGenerateOptions = Pick; - -/** - * A helper class which helps with building JavaScript code for a single - * function. It keeps track of external dependencies, internally generated - * constants, and execution steps, which at the end are all converted to - * to an executable JavaScript function. - * - * The final output is a JavaScript function enclosed in a closure: - * - * ```js - * (function(d1, d2, d3) { - * var c1 = something; - * var c2 = something; - * var c3 = something; - * return function(r0) { - * var r1 = something; - * var r2 = something; - * var r3 = something; - * return something; - * } - * }) - * ``` - * - * Where `d*` are the external dependencies, `c*` are the internal constants, - * and `r*` are the local immutable infinite registers. - */ -export class Codegen< - Fn extends (...deps: any[]) => any = (...deps: unknown[]) => unknown, - Linkable = Record, -> { - /** @ignore */ - protected steps: JsonSerializerStep[] = []; - - /** @ignore */ - public options: Required>; - - constructor(opts: CodegenOptions) { - this.options = { - args: ['r0'], - name: '', - prologue: '', - epilogue: '', - processSteps: (steps) => steps.filter((step) => step instanceof CodegenStepExecJs) as CodegenStepExecJs[], - linkable: {} as Linkable, - ...opts, - }; - this.registerCounter = this.options.args.length; - } - - /** - * Add one or more JavaScript statements to the main function body. - */ - public js(js: string): void { - this.steps.push(new CodegenStepExecJs(js)); - } - - public var(expression?: string): string { - const r = this.getRegister(); - if (expression) this.js('var ' + r + ' = ' + expression + ';'); - else this.js('var ' + r + ';'); - return r; - } - - public if(condition: string, then: () => void, otherwise?: () => void): void { - this.js('if (' + condition + ') {'); - then(); - if (otherwise) { - this.js('} else {'); - otherwise(); - } - this.js('}'); - } - - public switch( - expression: string, - cases: [match: string | number | boolean | null, block: () => void, noBreak?: boolean][], - def?: () => void, - ): void { - this.js('switch (' + expression + ') {'); - for (const [match, block, noBreak] of cases) { - this.js('case ' + match + ': {'); - block(); - if (!noBreak) this.js('break;'); - this.js('}'); - } - if (def) { - this.js('default: {'); - def(); - this.js('}'); - } - this.js('}'); - } - - public return(expression: string): void { - this.js('return ' + expression + ';'); - } - - /** - * Add any application specific execution step. Steps of `unknown` type - * later need to converted to `CodegenStepExecJs` steps in the `.processStep` - * callback. - * - * @param step A step in function execution logic. - */ - public step(step: unknown): void { - this.steps.push(step); - } - - protected registerCounter: number; - - /** - * Codegen uses the idea of infinite registers. It starts with `0` and - * increments it by one for each new register. Best practice is to use - * a new register for each new variable and keep them immutable. - * - * Usage: - * - * ```js - * const r = codegen.getRegister(); - * codegen.js(`const ${r} = 1;`); - * ``` - * - * @returns a unique identifier for a variable. - */ - public getRegister(): string { - return `r${this.registerCounter++}`; - } - public r(): string { - return this.getRegister(); - } - - /** @ignore */ - protected dependencies: unknown[] = []; - protected dependencyNames: string[] = []; - - /** - * Allows to wire up dependencies to the generated code. - * - * @param dep Any JavaScript dependency, could be a function, an object, - * or anything else. - * @param name Optional name of the dependency. If not provided, a unique - * name will be generated, which starts with `d` and a counter - * appended. - * @returns Returns the dependency name, a code symbol which can be used as - * variable name. - */ - public linkDependency(dep: unknown, name: string = 'd' + this.dependencies.length): string { - this.dependencies.push(dep); - this.dependencyNames.push(name); - return name; - } - - /** - * Sames as {@link Codegen#linkDependency}, but allows to wire up multiple - * dependencies at once. - */ - public linkDependencies(deps: unknown[]): string[] { - return deps.map((dep) => this.linkDependency(dep)); - } - - protected linked: {[key: string]: 1} = {}; - - /** - * Link a dependency from the pre-defined `options.linkable` object. This method - * can be called many times with the same dependency name, the dependency will - * be linked only once. - * - * @param name Linkable dependency name. - */ - public link(name: keyof Linkable): void { - if (this.linked[name as string]) return; - this.linked[name as string] = 1; - this.linkDependency(this.options.linkable[name], name as string); - } - - /** @ignore */ - protected constants: string[] = []; - protected constantNames: string[] = []; - - /** - * Allows to encode any code or value in the closure of the generated - * function. - * - * @param constant Any JavaScript value in string form. - * @param name Optional name of the constant. If not provided, a unique - * name will be generated, which starts with `c` and a counter - * appended. - * @returns Returns the constant name, a code symbol which can be used as - * variable name. - */ - public addConstant(constant: string, name: string = 'c' + this.constants.length): string { - this.constants.push(constant); - this.constantNames.push(name); - return name; - } - - /** - * Sames as {@link Codegen#addConstant}, but allows to create multiple - * constants at once. - */ - public addConstants(constants: string[]): string[] { - return constants.map((constant) => this.addConstant(constant)); - } - - /** - * Returns generated JavaScript code with the dependency list. - * - * ```js - * const code = codegen.generate(); - * const fn = eval(code.js)(...code.deps); - * const result = fn(...args); - * ``` - */ - public generate(opts: CodegenGenerateOptions = {}): JavaScriptLinked { - const {name, args, prologue, epilogue} = {...this.options, ...opts}; - const steps = this.options.processSteps(this.steps); - const js = `(function(${this.dependencyNames.join(', ')}) { -${this.constants.map((constant, index) => `var ${this.constantNames[index]} = (${constant});`).join('\n')} -return ${name ? `function ${name}` : 'function'}(${args.join(',')}){ -${prologue} -${steps.map((step) => (step as CodegenStepExecJs).js).join('\n')} -${typeof epilogue === 'function' ? epilogue() : epilogue || ''} -}})`; - // console.log(js); - return { - deps: this.dependencies, - js: js as JavaScriptLinked['js'], - }; - } - - /** - * Compiles the generated JavaScript code into a function. - * - * @returns JavaScript function ready for execution. - */ - public compile(opts?: CodegenGenerateOptions): Fn { - const closure = this.generate(opts); - return compileClosure(closure); - } -} diff --git a/src/util/codegen/README.md b/src/util/codegen/README.md deleted file mode 100644 index 5a3951e..0000000 --- a/src/util/codegen/README.md +++ /dev/null @@ -1,17 +0,0 @@ -# util/codegen - -This folder contains utilities for generating code. It is sometimes possible to -generate an optimized function that will execute significantly faster given -a "schema", or "template", of execution. - -Some examples: - -- Deep equality comparison function: if we know one object in advance we can - generate an optimized function which accepts a single object. It is - implemented in `json-equal` library. -- JSON Patch execution: if we know the JSON Patch in advance, we can generate - an optimized function which applies the JSON patch in the most efficient way. - It is implemented in `json-patch` library. -- Given a `json-type` schema of a JSON object, it is possible to generate - optimized functions for validation and serialization of objects according to - that schema. diff --git a/src/util/codegen/__tests__/Codegen.spec.ts b/src/util/codegen/__tests__/Codegen.spec.ts deleted file mode 100644 index 4183da6..0000000 --- a/src/util/codegen/__tests__/Codegen.spec.ts +++ /dev/null @@ -1,31 +0,0 @@ -import {CodegenStepExecJs} from '..'; -import {Codegen} from '../Codegen'; - -test('can generate a simple function', () => { - const codegen = new Codegen({ - name: 'foobar', - args: ['a', 'b'], - prologue: 'var res = 0;', - epilogue: 'return res;', - processSteps: (steps) => { - return steps.map((step) => { - if (typeof step === 'number') { - return new CodegenStepExecJs(`a += ${step};`); - } else return step; - }) as CodegenStepExecJs[]; - }, - }); - codegen.step(4); - const [c1, c2] = codegen.addConstants(['1', '2']); - codegen.js(`b += ${c1} + ${c2};`); - const byTwo = (num: number) => 2 * num; - codegen.linkDependency(byTwo, 'byTwo'); - codegen.js(`res += byTwo(a) + byTwo(b);`); - const code = codegen.generate(); - const fn = codegen.compile(); - // console.log(code.js); - expect(code.deps).toStrictEqual([byTwo]); - expect(typeof code.js).toBe('string'); - expect(fn(1, 2)).toBe(20); - expect(fn.name).toBe('foobar'); -}); diff --git a/src/util/codegen/compile.ts b/src/util/codegen/compile.ts deleted file mode 100644 index a1c0bbb..0000000 --- a/src/util/codegen/compile.ts +++ /dev/null @@ -1,7 +0,0 @@ -import {JavaScriptLinked} from '.'; -import {JavaScript} from './types'; - -// tslint:disable-next-line -export const compile = (js: JavaScript): T => eval(js); - -export const compileClosure = (fn: JavaScriptLinked): T => compile(fn.js)(...fn.deps); diff --git a/src/util/codegen/dynamicFunction.ts b/src/util/codegen/dynamicFunction.ts deleted file mode 100644 index 38a622a..0000000 --- a/src/util/codegen/dynamicFunction.ts +++ /dev/null @@ -1,16 +0,0 @@ -/** - * Wraps a function into a proxy function with the same signature, but which can - * be re-implemented by the user at runtime. - * - * @param implementation Initial implementation. - * @returns Proxy function and implementation setter. - */ -export const dynamicFunction = any>( - implementation: F, -): [fn: F, set: (fn: F) => void] => { - const proxy = ((...args) => implementation(...args)) as F; - const set = (f: F) => { - implementation = f; - }; - return [proxy, set]; -}; diff --git a/src/util/codegen/index.ts b/src/util/codegen/index.ts deleted file mode 100644 index 3a96aef..0000000 --- a/src/util/codegen/index.ts +++ /dev/null @@ -1,3 +0,0 @@ -export * from './types'; -export * from './compile'; -export * from './Codegen'; diff --git a/src/util/codegen/switch.ts b/src/util/codegen/switch.ts deleted file mode 100644 index 3c98a12..0000000 --- a/src/util/codegen/switch.ts +++ /dev/null @@ -1,15 +0,0 @@ -import {dynamicFunction} from './dynamicFunction'; - -/** - * Switcher for code generation. It first executes "evaluation" function - * 3 times, and then generates optimized code. - */ -export const createSwitch = any>(fn: F, codegen: () => F): F => { - let counter = 0; - const [proxy, set] = dynamicFunction((...args) => { - if (counter > 2) set(codegen()); - counter++; - return fn(...args); - }); - return proxy as F; -}; diff --git a/src/util/codegen/types.ts b/src/util/codegen/types.ts deleted file mode 100644 index b9bcd8a..0000000 --- a/src/util/codegen/types.ts +++ /dev/null @@ -1,38 +0,0 @@ -import type {Brand} from '../types'; - -/** - * Represents a string which contains JavaScript code, which can be - * executed by the `eval` function. - * - * ```ts - * const code: JavaScript<() => {}> = `() => {}`; - * const fn = eval(code); // () => {} - * ``` - */ -export type JavaScript = Brand; - -/** - * Represents a string which contains JavaScript code, which is enclosed - * in a JavaScript closure function. The dependencies can be "linked" to - * the JavaScript code, by executing the outer closure function with the - * list of dependencies as arguments. - * - * ```ts - * const multBy: JavaScriptClosure<(x: number) => number, [by: number]> = - * 'function(by) { return function (x) { return x * by }}'; - * - * const multBy3 = eval(multBy)(3); - * - * multBy3(5); // 15 - * ``` - */ -export type JavaScriptClosure = JavaScript<(...deps: D) => Js>; - -/** - * Represents a {@link JavaScriptClosure} with a fixed list of dependencies, - * that can be linked to the JavaScript code-generated closure. - */ -export interface JavaScriptLinked { - deps: Dependencies; - js: JavaScriptClosure; -} diff --git a/src/util/codegen/util/JsExpression.ts b/src/util/codegen/util/JsExpression.ts deleted file mode 100644 index 7ddbd4e..0000000 --- a/src/util/codegen/util/JsExpression.ts +++ /dev/null @@ -1,41 +0,0 @@ -/** - * JsExpression monad allows to write JS expression as strings which depend on each - * other and tracks whether an expression was used or not. - * - * ```ts - * const expr = new JsExpression(() => 'r0'); - * const subExpr = expr.chain((expr) => `${expr}["key"]`); - * - * expr.wasUsed; // false - * subExpr.use(); // r0["key"] - * expr.wasUsed; // true - * subExpr.wasUsed; // true - * ``` - */ -export class JsExpression { - private _wasUsed: boolean = false; - private _expression?: string; - private _listeners: ((expr: string) => void)[] = []; - - constructor(private expression: () => string) {} - - public get wasUsed(): boolean { - return this._wasUsed; - } - - public use(): string { - if (this._wasUsed) return this._expression!; - this._wasUsed = true; - const expression = (this._expression = this.expression()); - for (const listener of this._listeners) listener(expression); - return expression; - } - - public chain(use: (expr: string) => string): JsExpression { - return new JsExpression(() => use(this.use())); - } - - public addListener(listener: (expr: string) => void): void { - this._listeners.push(listener); - } -} diff --git a/src/util/codegen/util/helpers.ts b/src/util/codegen/util/helpers.ts deleted file mode 100644 index 8558b29..0000000 --- a/src/util/codegen/util/helpers.ts +++ /dev/null @@ -1,6 +0,0 @@ -export const emitStringMatch = (expression: string, offset: string, match: string) => { - const conditions: string[] = []; - for (let i = 0; i < match.length; i++) - conditions.push(`${match.charCodeAt(i)} === ${expression}.charCodeAt(${offset} + ${i})`); - return conditions.join(' && '); -}; diff --git a/src/util/codegen/util/normalizeAccessor.ts b/src/util/codegen/util/normalizeAccessor.ts deleted file mode 100644 index 8bfa283..0000000 --- a/src/util/codegen/util/normalizeAccessor.ts +++ /dev/null @@ -1,7 +0,0 @@ -export const normalizeAccessor = (accessor: string): string => { - if (/^[a-z_][a-z_0-9]*$/i.test(accessor)) { - return '.' + accessor; - } else { - return `[${JSON.stringify(accessor)}]`; - } -}; diff --git a/src/util/hasOwnProperty.ts b/src/util/hasOwnProperty.ts deleted file mode 100644 index 668c13c..0000000 --- a/src/util/hasOwnProperty.ts +++ /dev/null @@ -1,5 +0,0 @@ -const has = Object.prototype.hasOwnProperty; - -export function hasOwnProperty(obj: object, key: string): boolean { - return has.call(obj, key); -} diff --git a/src/util/isEmpty.ts b/src/util/isEmpty.ts deleted file mode 100644 index cb3f76e..0000000 --- a/src/util/isEmpty.ts +++ /dev/null @@ -1,4 +0,0 @@ -export const isEmpty = (obj: object): boolean => { - for (const key in obj) if (Object.prototype.hasOwnProperty.call(obj, key)) return false; - return true; -}; diff --git a/src/util/lazyFunction.ts b/src/util/lazyFunction.ts deleted file mode 100644 index ec5afd7..0000000 --- a/src/util/lazyFunction.ts +++ /dev/null @@ -1,8 +0,0 @@ -export const lazy = any>(factory: () => T): T => { - let generated: T | undefined; - const fn = (...args: any[]) => { - if (!generated) generated = factory(); - return generated.apply(null, args); - }; - return fn as T; -}; diff --git a/src/util/objKeyCmp.ts b/src/util/objKeyCmp.ts deleted file mode 100644 index 18da990..0000000 --- a/src/util/objKeyCmp.ts +++ /dev/null @@ -1,5 +0,0 @@ -export const objKeyCmp = (a: string, b: string): number => { - const len1 = a.length; - const len2 = b.length; - return len1 === len2 ? (a > b ? 1 : -1) : len1 - len2; -}; diff --git a/src/util/sort/insertion.ts b/src/util/sort/insertion.ts deleted file mode 100644 index ff12dfb..0000000 --- a/src/util/sort/insertion.ts +++ /dev/null @@ -1,21 +0,0 @@ -/** - * Insertion sort, should be faster than built-int sort for small arrays. - * - * @todo Move this to `thingies` package. - * - * @param arr Array to sort. - * @returns Returns the same array instance. - */ -export const sort = (arr: T[]): T[] => { - const length = arr.length; - for (let i = 1; i < length; i++) { - const currentValue = arr[i]; - let position = i; - while (position !== 0 && arr[position - 1] > currentValue) { - arr[position] = arr[position - 1]; - position--; - } - arr[position] = currentValue; - } - return arr; -}; diff --git a/src/util/sort/insertion2.ts b/src/util/sort/insertion2.ts deleted file mode 100644 index 8525b7e..0000000 --- a/src/util/sort/insertion2.ts +++ /dev/null @@ -1,22 +0,0 @@ -/** - * Insertion sort, should be faster than built-int sort for small arrays. - * - * @todo Move this to `thingies` package. - * - * @param arr Array to sort. - * @param comparator Comparator function. - * @returns Returns the same array instance. - */ -export const sort = (arr: T[], comparator: (a: T, b: T) => number): T[] => { - const length = arr.length; - for (let i = 1; i < length; i++) { - const currentValue = arr[i]; - let position = i; - while (position !== 0 && comparator(arr[position - 1], currentValue) > 0) { - arr[position] = arr[position - 1]; - position--; - } - arr[position] = currentValue; - } - return arr; -}; diff --git a/src/util/strings/__tests__/asString.spec.ts b/src/util/strings/__tests__/asString.spec.ts deleted file mode 100644 index 80d924e..0000000 --- a/src/util/strings/__tests__/asString.spec.ts +++ /dev/null @@ -1,33 +0,0 @@ -import {asString} from '../asString'; - -const check = (str: string) => { - expect(asString(str)).toBe(JSON.stringify(str)); - expect(JSON.parse(asString(str))).toBe(str); -}; - -const generateStr = (): string => { - let str = ''; - for (let i = 0; i < 5; i++) str += String.fromCodePoint(Math.round(Math.random() * 0x6ffff)); - return str; -}; - -test('encodes the same as JSON.stringify()', () => { - check(''); - check('"'); - check("'"); - check('asdf'); - check('asdfasdfasdfasdfsadfasdfasdfasdfasdfasdfasdfasdfasdfasdfasdfsadfasdfasdfasdf'); - check('🍻'); - check('👩‍👩‍👦‍👦'); - check('Лексилогос'); - check('\b'); - check('\b\t\0'); - check('\0'); - check('\f'); - check('\r'); - check('\n'); -}); - -test('encodes the same as JSON.stringify(), autogenerated', () => { - for (let i = 0; i < 10000; i++) check(generateStr()); -}); diff --git a/src/util/strings/__tests__/utf8.spec.ts b/src/util/strings/__tests__/utf8.spec.ts deleted file mode 100644 index 9bbdaf5..0000000 --- a/src/util/strings/__tests__/utf8.spec.ts +++ /dev/null @@ -1,26 +0,0 @@ -import {utf8Size} from '../utf8'; - -describe('utf8Size', () => { - describe('computes correct size', () => { - const check = (str: string) => { - expect(utf8Size(str)).toBe(Buffer.from(str).byteLength); - }; - - test('encodes the same as JSON.stringify()', () => { - check(''); - check('"'); - check("'"); - check('asdf'); - check('asdfasdfasdfasdfsadfasdfasdfasdfasdfasdfasdfasdfasdfasdfasdfsadfasdfasdfasdf'); - check('🍻'); - check('👩‍👩‍👦‍👦'); - check('Лексилогос'); - check('\b'); - check('\b\t\0'); - check('\0'); - check('\f'); - check('\r'); - check('\n'); - }); - }); -}); diff --git a/src/util/strings/__tests__/util.spec.ts b/src/util/strings/__tests__/util.spec.ts deleted file mode 100644 index 2ae776b..0000000 --- a/src/util/strings/__tests__/util.spec.ts +++ /dev/null @@ -1,54 +0,0 @@ -import {isLetter, isPunctuation, isWhitespace} from '../util'; - -describe('isLetter()', () => { - it('should return true for letters', () => { - expect(isLetter('a')).toBe(true); - expect(isLetter('z')).toBe(true); - expect(isLetter('æ')).toBe(true); - expect(isLetter('б')).toBe(true); - expect(isLetter('A')).toBe(true); - }); - - it('should return true for numbers', () => { - expect(isLetter('0')).toBe(true); - expect(isLetter('1')).toBe(true); - expect(isLetter('9')).toBe(true); - }); - - it('should return false for non-letters', () => { - expect(isLetter('!')).toBe(false); - expect(isLetter(' ')).toBe(false); - expect(isLetter(' ')).toBe(false); - }); -}); - -describe('isPunctuation()', () => { - it('should return true for punctuation', () => { - expect(isPunctuation('.')).toBe(true); - expect(isPunctuation(',')).toBe(true); - expect(isPunctuation('?')).toBe(true); - expect(isPunctuation('!')).toBe(true); - expect(isPunctuation('…')).toBe(true); - }); - - it('should return false for non-punctuation', () => { - expect(isPunctuation('a')).toBe(false); - expect(isPunctuation('1')).toBe(false); - expect(isPunctuation(' ')).toBe(false); - }); -}); - -describe('isWhitespace()', () => { - it('should return true for whitespace', () => { - expect(isWhitespace(' ')).toBe(true); - expect(isWhitespace('\t')).toBe(true); - expect(isWhitespace('\n')).toBe(true); - expect(isWhitespace('\r')).toBe(true); - }); - - it('should return false for non-whitespace', () => { - expect(isWhitespace('a')).toBe(false); - expect(isWhitespace('1')).toBe(false); - expect(isWhitespace('.')).toBe(false); - }); -}); diff --git a/src/util/strings/__tests__/wordWrap.spec.ts b/src/util/strings/__tests__/wordWrap.spec.ts deleted file mode 100644 index c19d576..0000000 --- a/src/util/strings/__tests__/wordWrap.spec.ts +++ /dev/null @@ -1,42 +0,0 @@ -import {wordWrap} from '../wordWrap'; - -test('does not format a short line', () => { - expect(wordWrap('Hello')).toStrictEqual(['Hello']); -}); - -const text = - 'Acclaimed Harvard professor and entrepreneur Dr. David Sinclair believes that we will see human life expectancy increase to at least 100 years within this century. A world in which humans live significantly longer will have a major impact on economies, policies, healthcare, education, ethics, and more. Sinclair joined Bridgewater Portfolio Strategist Atul Lele to discuss the science and societal, political, systemic and ethical implications of humans living significantly longer lives.'; - -test('wraps long text', () => { - const result = wordWrap(text); - expect(result).toMatchInlineSnapshot(` - [ - "Acclaimed Harvard professor and entrepreneur Dr. ", - "David Sinclair believes that we will see human ", - "life expectancy increase to at least 100 years ", - "within this century. A world in which humans live ", - "significantly longer will have a major impact on ", - "economies, policies, healthcare, education, ", - "ethics, and more. Sinclair joined Bridgewater ", - "Portfolio Strategist Atul Lele to discuss the ", - "science and societal, political, systemic and ", - "ethical implications of humans living ", - "significantly longer lives.", - ] - `); -}); - -test('can specify line width', () => { - const result = wordWrap(text, {width: 80}); - expect(result).toMatchInlineSnapshot(` - [ - "Acclaimed Harvard professor and entrepreneur Dr. David Sinclair believes that we ", - "will see human life expectancy increase to at least 100 years within this ", - "century. A world in which humans live significantly longer will have a major ", - "impact on economies, policies, healthcare, education, ethics, and more. Sinclair ", - "joined Bridgewater Portfolio Strategist Atul Lele to discuss the science and ", - "societal, political, systemic and ethical implications of humans living ", - "significantly longer lives.", - ] - `); -}); diff --git a/src/util/strings/asString.ts b/src/util/strings/asString.ts deleted file mode 100644 index 34de018..0000000 --- a/src/util/strings/asString.ts +++ /dev/null @@ -1,22 +0,0 @@ -const stringify = JSON.stringify; - -/** Serialize text as a JSON string value. */ -export const asString = (str: string) => { - const length = str.length; - if (length > 41) return stringify(str); - let result = ''; - let last = 0; - let found = false; - let point = 255; - for (let i = 0; i < length && point >= 32; i++) { - point = str.charCodeAt(i); - if (point >= 0xd800 && point <= 0xdfff) return stringify(str); - if (point === 34 || point === 92) { - result += str.slice(last, i) + '\\'; - last = i; - found = true; - } - } - if (point < 32) return stringify(str); - return '"' + (!found ? str : result + str.slice(last)) + '"'; -}; diff --git a/src/util/strings/escape.ts b/src/util/strings/escape.ts deleted file mode 100644 index ad3d60e..0000000 --- a/src/util/strings/escape.ts +++ /dev/null @@ -1,134 +0,0 @@ -// License: https://github.com/BridgeAR/safe-stable-stringify/blob/78891ff37c6e8936118b8fa47ed59dd761c3208a/LICENSE - -const strEscapeSequencesRegExp = - /[\u0000-\u001f\u0022\u005c\ud800-\udfff]|[\ud800-\udbff](?![\udc00-\udfff])|(?:[^\ud800-\udbff]|^)[\udc00-\udfff]/; -const strEscapeSequencesReplacer = - /[\u0000-\u001f\u0022\u005c\ud800-\udfff]|[\ud800-\udbff](?![\udc00-\udfff])|(?:[^\ud800-\udbff]|^)[\udc00-\udfff]/g; -const meta = [ - '\\u0000', - '\\u0001', - '\\u0002', - '\\u0003', - '\\u0004', - '\\u0005', - '\\u0006', - '\\u0007', - '\\b', - '\\t', - '\\n', - '\\u000b', - '\\f', - '\\r', - '\\u000e', - '\\u000f', - '\\u0010', - '\\u0011', - '\\u0012', - '\\u0013', - '\\u0014', - '\\u0015', - '\\u0016', - '\\u0017', - '\\u0018', - '\\u0019', - '\\u001a', - '\\u001b', - '\\u001c', - '\\u001d', - '\\u001e', - '\\u001f', - '', - '', - '\\"', - '', - '', - '', - '', - '', - '', - '', - '', - '', - '', - '', - '', - '', - '', - '', - '', - '', - '', - '', - '', - '', - '', - '', - '', - '', - '', - '', - '', - '', - '', - '', - '', - '', - '', - '', - '', - '', - '', - '', - '', - '', - '', - '', - '', - '', - '', - '', - '', - '', - '', - '', - '', - '', - '', - '', - '', - '', - '\\\\', -]; - -const esc_ = (str: string): string => { - if (str.length === 2) return str[0] + '\\u' + str.charCodeAt(1).toString(16); - const charCode = str.charCodeAt(0); - return meta.length > charCode ? meta[charCode] : '\\u' + charCode.toString(16); -}; - -export const escape = (str: string): string => { - let point, - last = 0, - result = ''; - if (str.length < 5000 && !strEscapeSequencesRegExp.test(str)) return str; - if (str.length > 100) return str.replace(strEscapeSequencesReplacer, esc_); - for (let i = 0; i < str.length; i++) { - point = str.charCodeAt(i); - if (point === 34 || point === 92 || point < 32) { - result += str.slice(last, i) + meta[point]; - last = i + 1; - } else if (point >= 0xd800 && point <= 0xdfff) { - if (point <= 0xdbff && i + 1 < str.length) { - point = str.charCodeAt(i + 1); - if (point >= 0xdc00 && point <= 0xdfff) { - i++; - continue; - } - } - result += str.slice(last, i) + '\\u' + point.toString(16); - last = i + 1; - } - } - result += str.slice(last); - return result; -}; diff --git a/src/util/strings/flatstr.ts b/src/util/strings/flatstr.ts deleted file mode 100644 index 1479ac2..0000000 --- a/src/util/strings/flatstr.ts +++ /dev/null @@ -1,5 +0,0 @@ -export const flatstr = (s: string): string => { - (s) | 0; - Number(s); - return s; -}; diff --git a/src/util/strings/utf8.ts b/src/util/strings/utf8.ts deleted file mode 100644 index 9631bb3..0000000 --- a/src/util/strings/utf8.ts +++ /dev/null @@ -1,27 +0,0 @@ -/** - * Given a JavaScript string, computes how many bytes it will take to encode - * that string in UTF-8. - * - * @param str JavaScript string. - * @returns Length in bytes if encoded as UTF-8. - */ -export function utf8Size(str: string): number { - const length = str.length; - let size = 0; - let pos = 0; - while (pos < length) { - let value = str.charCodeAt(pos++); - if ((value & 0xffffff80) === 0) { - size++; - continue; - } else if ((value & 0xfffff800) === 0) size += 2; - else { - if (value >= 0xd800 && value <= 0xdbff && pos < length) { - const extra = str.charCodeAt(pos); - if ((extra & 0xfc00) === 0xdc00) value = (pos++, ((value & 0x3ff) << 10) + (extra & 0x3ff) + 0x10000); - } - size += 3 + +((value & 0xffff0000) !== 0); - } - } - return size; -} diff --git a/src/util/strings/util.ts b/src/util/strings/util.ts deleted file mode 100644 index a75f580..0000000 --- a/src/util/strings/util.ts +++ /dev/null @@ -1,8 +0,0 @@ -const LETTER_REGEX = /(\p{Letter}|\d)/u; -const WHITESPACE_REGEX = /\s/; - -export type CharPredicate = (char: string) => boolean; - -export const isLetter: CharPredicate = (char: string) => LETTER_REGEX.test(char[0]); -export const isWhitespace: CharPredicate = (char: string) => WHITESPACE_REGEX.test(char[0]); -export const isPunctuation: CharPredicate = (char: string) => !isLetter(char) && !isWhitespace(char); diff --git a/src/util/strings/wordWrap.ts b/src/util/strings/wordWrap.ts deleted file mode 100644 index ab6b61a..0000000 --- a/src/util/strings/wordWrap.ts +++ /dev/null @@ -1,21 +0,0 @@ -export interface WrapOptions { - width?: number; -} - -const lineMap = (line: string) => - line.slice(-1) === '\n' ? line.slice(0, line.length - 1).replace(/[ \t]*$/gm, '') : line; -const lineReduce = (acc: string[], line: string) => { - acc.push(...line.split('\n')); - return acc; -}; - -export const wordWrap = (str: string, options: WrapOptions = {}): string[] => { - if (!str) return []; - - const width = options.width || 50; - const regexString = '.{1,' + width + '}([\\s\u200B]+|$)|[^\\s\u200B]+?([\\s\u200B]+|$)'; - const re = new RegExp(regexString, 'g'); - const lines = (str.match(re) || []).map(lineMap).reduce(lineReduce, [] as string[]); - - return lines; -}; diff --git a/src/util/types.ts b/src/util/types.ts deleted file mode 100644 index 726479d..0000000 --- a/src/util/types.ts +++ /dev/null @@ -1,9 +0,0 @@ -export type Mutable = { - -readonly [P in keyof T]: T[P]; -}; - -export type Brand = S & {__TYPE__: T; __BRAND__: B}; - -export type MaybeArray = T | T[]; - -export type Ensure = T extends Ext ? T : never; diff --git a/yarn.lock b/yarn.lock index 9d38adb..21e435c 100644 --- a/yarn.lock +++ b/yarn.lock @@ -600,6 +600,13 @@ resolved "https://registry.yarnpkg.com/@jsonjoy.com/base64/-/base64-1.1.1.tgz#a717fd8840f7bad49c7fe66cc65db8bcfc4c4dc5" integrity sha512-LnFjVChaGY8cZVMwAIMjvA1XwQjZ/zIXHyh28IyJkyNkzof4Dkm1+KN9UIm3lHhREH4vs7XwZ0NpkZKnwOtEfg== +"@jsonjoy.com/util@^1.0.0": + version "1.0.0" + resolved "https://registry.yarnpkg.com/@jsonjoy.com/util/-/util-1.0.0.tgz#417a4e6c112501ac98e3a4e695f5ffa23ba01b2d" + integrity sha512-uTa/IyBC3/xTC5/qwMnY79ZqCA6ENQgsM6nzuAISa7pYiiUn+U4JIXoyaHEApX6k8KvTCBDNJs+k8U03bw5ffQ== + dependencies: + hyperdyperid "^1.2.0" + "@msgpack/msgpack@^3.0.0-beta2": version "3.0.0-beta2" resolved "https://registry.yarnpkg.com/@msgpack/msgpack/-/msgpack-3.0.0-beta2.tgz#5bccee30f84df220b33905e3d8249ba96deca0b7"