New Case Study:See how Anthropic automated 95% of dependency reviews with Socket.Learn More
Socket
Sign inDemoInstall
Socket

jsonesc

Package Overview
Dependencies
Maintainers
1
Versions
19
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

jsonesc - npm Package Compare versions

Comparing version 0.3.0 to 0.4.0

benchmark/test.js

10

base93/README.md
# Base93
***Base93*** is a binary-to-text encoding schemes that represent binary data in an ASCII string format.
**Base93** is a binary-to-text encoding schemes that represent binary data in an ASCII string format.
It is based on Joachim Henke's [Base91](http://base91.sourceforge.net/) with [small modification](https://github.com/ticlo/jsonesc/commit/df4516616b6088ed2c07e8986094b25afb0a45cb#diff-e5daa9e13f272067963c7e68fd9afd3d) to optimize JSON encoding.
It is based on Joachim Henke's [BasE91](http://base91.sourceforge.net/) with [small modification](https://github.com/ticlo/jsonesc/commit/df4516616b6088ed2c07e8986094b25afb0a45cb#diff-e5daa9e13f272067963c7e68fd9afd3d) to optimize JSON encoding.
## Base93 vs Base91 vs Base64
## Base93 vs BasE91 vs Base64

@@ -12,6 +12,6 @@ ||Characters|JSON Encoded Size / Binary Size|

|Base93| \ " are not used|1.22551|
|Base91| \ - ' space are not used|1.23897*|
|BasE91| \ - ' space are not used|1.23897*|
|Base64|A-Z a-Z 0-9 + /|1.33333|
\* Base91's original encoding ratio is 1.22974, but in JSON it's a little bit worse since " will be encoded to \".
\* BasE91's original encoding ratio is 1.22974, but in JSON it's a little bit worse since " will be encoded to \\".

@@ -18,0 +18,0 @@ ## Source Code

@@ -56,2 +56,4 @@ const JsonEsc = require('../dist').default;

benchmark("JsonEsc encode", ()=>JsonEsc.stringify(sample));
benchmark("JsonEsc sorted encode", ()=>JsonEsc.stringify(sample, undefined, true));
benchmark("JsonEsc sorted indent encode", ()=>JsonEsc.stringify(sample, 1, true));
benchmark("MsgPack encode", ()=>MsgPack.encode(sample));

@@ -58,0 +60,0 @@ benchmark("BSON encode", ()=>bson.serialize(bsonSample));

@@ -63,9 +63,9 @@ "use strict";

static decode(str, offset = 0, length = -1) {
let len = offset + length;
if (length < 0 || len > str.length) {
len = str.length;
let end = offset + length;
if (length < 0 || end > str.length) {
end = str.length;
}
let output = new Array(Math.ceil((len - offset) * 7 / 8));
let output = new Array(Math.ceil((end - offset) * 7 / 8));
let dbq = 0, dn = 0, dv = -1, current = 0;
for (let i = offset; i < len; ++i) {
for (let i = offset; i < end; ++i) {
let code = str.charCodeAt(i);

@@ -72,0 +72,0 @@ if (code > 126)

@@ -13,3 +13,3 @@ "use strict";

if (type && encoder) {
this._encodeTable.set(type.prototype, encoder);
this._encodeTable.set(type, encoder);
}

@@ -23,3 +23,3 @@ if (decoder) {

let prefixLen = prefix.length;
this._encodeTable.set(type.prototype, (self) => `${prefix}${encoder(self)}`);
this._encodeTable.set(type, (self) => `${prefix}${encoder(self)}`);
this._decodeTable[key] = (str) => decoder(str.substr(prefixLen));

@@ -67,3 +67,3 @@ }

if (value) {
let encoder = this._encodeTable.get(value.__proto__);
let encoder = this._encodeTable.get(value.constructor);
if (encoder) {

@@ -83,6 +83,91 @@ return encoder(value);

}
stringifySorted(input, space) {
let spacesCached = 0;
let colon = ':';
let getSpacer = (level) => '';
if (space >= 0) {
colon = ': ';
let spaces = ['\n'];
getSpacer = (level) => {
if (level < spacesCached) {
return spaces[level];
}
return spaces[level] = '\n'.padEnd((level - 1) * space + 1);
};
}
let encodeValue = (value, level) => {
switch (typeof value) {
case 'number': {
if (value !== value) {
return '"\\u001bNaN"';
}
if (value === Infinity) {
return '"\\u001bInf"';
}
if (value === -Infinity) {
return '"\\u001b-Inf"';
}
return value;
}
case 'object': {
if (value) {
switch (value.constructor) {
case Object: {
let keys = Object.keys(value);
keys.sort();
let items = [];
for (let key of keys) {
let val = value[key];
if (val !== undefined) {
items.push(`${JSON.stringify(key)}${colon}${encodeValue(val, level + 1)}`);
}
}
if (items.length === 0) {
return '{}';
}
else {
return `{${getSpacer(level + 1)}${items.join(`,${getSpacer(level + 1)}`)}${getSpacer(level)}}`;
}
}
case Array: {
let items = [];
for (let val of value) {
if (val !== undefined) {
items.push(`${encodeValue(val, level + 1)}`);
}
else {
items.push('null');
}
}
if (items.length === 0) {
return '[]';
}
else {
return `[${getSpacer(level + 1)}${items.join(`,${getSpacer(level + 1)}`)}${getSpacer(level)}]`;
}
}
default: {
let encoder = this._encodeTable.get(value.constructor);
if (encoder) {
return JSON.stringify(encoder(value));
}
}
}
}
return 'null';
}
default: {
return JSON.stringify(value);
}
}
};
return encodeValue(input, 0);
}
static parse(str) {
return JsonEsc.defaultEncoder.parse(str);
}
static stringify(input, space) {
static stringify(input, space, sortKeys = false) {
if (sortKeys === true) {
return JsonEsc.defaultEncoder.stringifySorted(input, space);
}
let dateToJSON = Date.prototype.toJSON;

@@ -89,0 +174,0 @@ delete Date.prototype.toJSON;

{
"name": "jsonesc",
"version": "0.3.0",
"version": "0.4.0",
"description": "Json Escape",

@@ -5,0 +5,0 @@ "repository": {

@@ -17,3 +17,3 @@ # Json Escape

new Uint8Array([1,2,3,4])
] );
], 1);
// returns:

@@ -31,3 +31,3 @@ [

JsonEsc allows additional data types to be serialized in JSON, such as binary date (Uint8Array) and Date, while still keeps the verbose nature of JSON.<br>
This makes JsonEsc much easier to debug and trouble shoot than binary formats like BSON and MsgPack
The output string is still a 100% valid JSON, and compatible with any JSON editing/parsing tool or library. This makes JsonEsc much easier to debug and trouble shoot than binary formats like BSON and MsgPack

@@ -39,8 +39,7 @@ ### Performance

#### benchmark result
Benchmark on Chrome 67 with [sample data](https://github.com/ticlo/jsonesc/blob/master/benchmark/sample-data.js)
Benchmark with [sample data](https://github.com/ticlo/jsonesc/blob/master/benchmark/sample-data.js) on Chrome 67, Firefox59, Edge 42
Chrome 67, Firefox59, Edge 42 <br>
[Time are all in ms, smaller is better](https://github.com/ticlo/jsonesc/blob/master/benchmark/benchmark.js)
||Encode<br>Chrome|Decode<br>Chrome|Encode<br>Firefox|Decode<br>Firefox|Encode<br>Edge|Decode<br>Edge|
||Chrome<br>Encode|Chrome<br>Decode|Firefox<br>Encode|Firefox<br>Decode|Edge<br>Encode|Edge<br>Decode|
|:----:|:----:|:----:|:----:|:----:|:----:|:----:|

@@ -51,2 +50,9 @@ |JsonEsc|***0.1161***|0.1606|***0.1394***|***0.1553***|***0.0899***|***0.0753***|

## API
```typescript
JsonEsc.stringify(inpt:any, space?:number, sortKeys?:boolean = false);
JsonEsc.parse(inpt:string);
```
## Custom Types

@@ -80,3 +86,3 @@

But if you still prefer Base64, just use these lines to register Uint8Array with a base64 encoder/decoder
If you still prefer Base64, just use these lines to register Uint8Array with a base64 encoder/decoder

@@ -83,0 +89,0 @@ ```javascript

@@ -65,10 +65,10 @@ // last character is not same as original base93

static decode(str: string, offset: number = 0, length: number = -1): number[] {
let len = offset + length;
if (length < 0 || len > str.length) {
len = str.length;
let end = offset + length;
if (length < 0 || end > str.length) {
end = str.length;
}
let output: number[] = new Array(Math.ceil((len - offset) * 7 / 8));
let output: number[] = new Array(Math.ceil((end - offset) * 7 / 8));
let dbq = 0, dn = 0, dv = -1, current = 0;
for (let i = offset; i < len; ++i) {
for (let i = offset; i < end; ++i) {
let code = str.charCodeAt(i);

@@ -75,0 +75,0 @@ if (code > 126) continue;

@@ -13,7 +13,7 @@ import * as Codec from './codec';

registerRaw(key: string, type: { prototype: object },
registerRaw(key: string, type: object,
encoder: (self: object) => string,
decoder: (str: string) => object) {
if (type && encoder) {
this._encodeTable.set(type.prototype, encoder);
this._encodeTable.set(type, encoder);
}

@@ -24,3 +24,3 @@ if (decoder) {

}
register(key: string, type: { prototype: object },
register(key: string, type: object,
encoder: (self: object) => string,

@@ -30,3 +30,3 @@ decoder: (str: string) => object) {

let prefixLen = prefix.length;
this._encodeTable.set(type.prototype, (self: object) => `${prefix}${encoder(self)}`);
this._encodeTable.set(type, (self: object) => `${prefix}${encoder(self)}`);
this._decodeTable[key] = (str: string) => decoder(str.substr(prefixLen));

@@ -76,3 +76,3 @@ }

if (value) {
let encoder = this._encodeTable.get(value.__proto__);
let encoder = this._encodeTable.get(value.constructor);
if (encoder) {

@@ -91,6 +91,88 @@ return encoder(value);

stringify(input: any, space?: string | number): string {
stringify(input: any, space?: number): string {
return JSON.stringify(input, (key: string, value: any) => this.replacer(key, value), space);
}
stringifySorted(input: any, space?: number): string {
let spacesCached = 0;
let colon = ':';
let getSpacer = (level: number) => '';
if (space >= 0) {
colon = ': ';
let spaces: string[] = ['\n'];
getSpacer = (level: number) => {
if (level < spacesCached) {
return spaces[level];
}
return spaces[level] = '\n'.padEnd((level - 1) * space + 1);
};
}
let encodeValue = (value: any, level: number) => {
switch (typeof value) {
case 'number': {
if (value !== value) {
return '"\\u001bNaN"';
}
if (value === Infinity) {
return '"\\u001bInf"';
}
if (value === -Infinity) {
return '"\\u001b-Inf"';
}
return value;
}
case 'object': {
if (value) {
switch (value.constructor) {
case Object: {
let keys = Object.keys(value);
keys.sort();
let items: string[] = [];
for (let key of keys) {
let val = value[key];
if (val !== undefined) {
items.push(`${JSON.stringify(key)}${colon}${encodeValue(val, level + 1)}`);
}
}
if (items.length === 0) {
return '{}';
} else {
return `{${getSpacer(level + 1)}${items.join(`,${getSpacer(level + 1)}`)}${getSpacer(level)}}`;
}
}
case Array: {
let items: string[] = [];
for (let val of value) {
if (val !== undefined) {
items.push(`${encodeValue(val, level + 1)}`);
} else {
items.push('null');
}
}
if (items.length === 0) {
return '[]';
} else {
return `[${getSpacer(level + 1)}${items.join(`,${getSpacer(level + 1)}`)}${getSpacer(level)}]`;
}
}
default: {
let encoder = this._encodeTable.get(value.constructor);
if (encoder) {
return JSON.stringify(encoder(value));
}
}
}
}
return 'null';
}
default: {
return JSON.stringify(value);
}
}
};
return encodeValue(input, 0);
}
private static defaultEncoder: JsonEsc = new JsonEsc();

@@ -100,3 +182,6 @@ static parse(str: string): any {

}
static stringify(input: any, space?: string | number): string {
static stringify(input: any, space?: number, sortKeys: boolean = false): string {
if (sortKeys === true) {
return JsonEsc.defaultEncoder.stringifySorted(input, space);
}
let dateToJSON = Date.prototype.toJSON;

@@ -103,0 +188,0 @@ delete Date.prototype.toJSON;

import JsonEsc from '../dist/index';
import { assert } from 'chai';
const nanStr = '"\\u001bNaN"';
const infStr = '"\\u001bInf"';
const ninfStr = '"\\u001b-Inf"';
describe('esc', () => {
it('numbers', () => {
let nanStr = '"\\u001bNaN"';
let infStr = '"\\u001bInf"';
let ninfStr = '"\\u001b-Inf"';

@@ -48,1 +49,19 @@ assert.isNaN(JsonEsc.parse(nanStr), 'decode NaN');

});
describe('sorted', () => {
it('basic', () => {
assert.equal(JsonEsc.stringify(NaN, undefined, true), nanStr, 'encode NaN');
assert.equal(JsonEsc.stringify(1, undefined, true), '1', 'encode 1');
assert.equal(JsonEsc.stringify("", undefined, true), '""', 'encode string');
assert.equal(JsonEsc.stringify({}, undefined, true), '{}', 'blank Object');
assert.equal(JsonEsc.stringify([], undefined, true), '[]', 'blank array');
assert.equal(JsonEsc.stringify({ c: 1, a: 2, b: 3 }, undefined, true), '{"a":2,"b":3,"c":1}');
assert.equal(JsonEsc.stringify({ c: 1, a: 2, b: 3 }, 1, true), `{
"a": 2,
"b": 3,
"c": 1
}`);
});
});

@@ -7,3 +7,3 @@ {

"lib": [
"es6"
"es2017"
],

@@ -13,2 +13,3 @@ "alwaysStrict": true,

"sourceMap": true,
"declaration": true,
"outDir": "dist"

@@ -15,0 +16,0 @@ },

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc