You're Invited:Meet the Socket Team at BlackHat and DEF CON in Las Vegas, Aug 4-6.RSVP
Socket
Book a DemoInstallSign in
Socket

json-as

Package Overview
Dependencies
Maintainers
1
Versions
195
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

json-as - npm Package Compare versions

Comparing version

to
0.4.3

as-pect.asconfig.json

18

assembly/__benches__/benchmark.ts

@@ -1,4 +0,4 @@

import { JSON, parseBooleanArray, parseMap, parseNumberArray } from "..";
import { JSON } from "..";
@json
class Vector {
class Vec2 {
x: f32;

@@ -8,3 +8,3 @@ y: f32;

const vec: Vector = blackbox<Vector>({
const vec: Vec2 = blackbox<Vec2>({
x: 0.0,

@@ -30,3 +30,3 @@ y: 0.0,

bench("Stringify Vector", () => {
bench("Stringify Object (Vec2)", () => {
blackbox(JSON.stringify(vec));

@@ -55,4 +55,4 @@ });

bench("Parse Vector", () => {
blackbox(parseMap<Map<string, f32>>(blackbox('{"x":0.0,"y":0.0}')));
bench("Parse Object (Vec2)", () => {
blackbox(JSON.parse<Vec2>(blackbox('{"x":0.0,"y":0.0}')));
});

@@ -62,3 +62,3 @@

blackbox(
parseBooleanArray<boolean[]>(blackbox("[true,false,true,false,true]"))
JSON.parse<boolean[]>(blackbox("[true,false,true,false,true]"))
);

@@ -68,7 +68,7 @@ });

bench("Parse Integer Array", () => {
blackbox(parseNumberArray<u32[]>(blackbox("[1,2,3,4,5]")));
blackbox(JSON.parse<u32[]>(blackbox("[1,2,3,4,5]")));
});
bench("Parse Float Array", () => {
blackbox(parseNumberArray<f32[]>(blackbox("[1.0,2.0,3.0,4.0,5.0]")));
blackbox(JSON.parse<f32[]>(blackbox("[1.0,2.0,3.0,4.0,5.0]")));
});
export const commaCode = ",".charCodeAt(0);
export const quoteCode = "".charCodeAt(0);
export const quoteCode = "\"".charCodeAt(0);
export const backSlashCode = "\\".charCodeAt(0);

@@ -4,0 +4,0 @@ export const leftBraceCode = "{".charCodeAt(0);

@@ -29,13 +29,9 @@ import { StringSink } from "as-string-sink/assembly";

// String
if (isString(data)) {
return serializeString(<string>data);
if (isString<T>()) {
return '"' + (<string>data).replaceAll('"', '\\"') + '"';
}
// Boolean
else if (isBoolean(data)) {
else if (isBoolean<T>()) {
return data ? "true" : "false";
}
// Null
else if (isNullable<T>() && data == null) {
return "null";
}
// Integers/Floats

@@ -50,16 +46,24 @@ // @ts-ignore

else if (isDefined(data.__JSON_Serialize)) {
//@ts-ignore
// @ts-ignore
return data.__JSON_Serialize();
}
// ArrayLike
else if (isArrayLike(data)) {
else if (isArrayLike<T>()) {
let result = new StringSink("[");
// @ts-ignore
if (data.length == 0) return "[]";
// @ts-ignore
for (let i = 0; i < data.length - 1; i++) {
// @ts-ignore
result.write(stringify(unchecked(data[i])));
result.write(",");
}
// @ts-ignore
result.write(stringify(unchecked(data[data.length - 1])));
result.write("]");
return result.toString();
}
// Null
else if (isNullable<T>() && data == null) {
return "null";
} else {

@@ -96,3 +100,3 @@ return "null";

let key: string = ''
let instr: u32 = 0
let instr: boolean = false
let char: u32 = 0

@@ -102,5 +106,6 @@ let depth: u32 = 0

for (let i: u32 = 1; i < len; i++) {
char = data.charCodeAt(i)
if (char === "\"".charCodeAt(0) && data.charCodeAt(i - 1) !== "/".charCodeAt(0)) instr = (instr ? 0 : 1)
else if (instr === 0) {
char = data.charCodeAt(i);
if (instr === false && char === quoteCode) instr = true;
else if (instr === true && char === quoteCode && data.charCodeAt(i - 1) !== "/".charCodeAt(0)) instr = false;
if (instr === false) {
if (char === leftBraceCode || char === leftBracketCode) depth++

@@ -110,2 +115,3 @@ if (char === rightBraceCode || char === rightBracketCode) fdepth++

if (depth !== 0 && depth === fdepth) {
//console.log(`Found Struct: ${data.slice(lastPos + 1, i + 1)}`)
result.set(key, data.slice(lastPos + 1, i + 1))

@@ -118,8 +124,9 @@ // Reset the depth

}
if (depth === 0) {
if (!instr && depth === 0) {
if (char === colonCode) {
key = data.slice(lastPos + 1, i - 1)
//console.log(`Found Key: ${data.slice(lastPos + 1, i - 1)}`)
lastPos = i
}
else if (char === commaCode) {
} else if (char === commaCode) {
//console.log(`Found Comma: ${data.slice(lastPos + 1, i)}`)
if ((i - lastPos) > 0) result.set(key, data.slice(lastPos + 1, i))

@@ -131,3 +138,5 @@ lastPos = i + 1

if ((len - lastPos) > 0) result.set(key, data.slice(lastPos + 1, len))
if ((len - lastPos) > 1 && (len - lastPos) !== 0) {
result.set(key, data.slice(lastPos + 1, len))
}
// @ts-ignore

@@ -142,9 +151,5 @@ return schema.__JSON_Deserialize(result)

// @ts-ignore
@inline
function serializeString(data: string): string {
return '"' + data.replaceAll('"', '\\"') + '"';
}
// @ts-ignore
@inline
function parseString(data: string): string {

@@ -312,35 +317,2 @@ return data.slice(1, data.length - 1).replaceAll('\\"', '"');

export function parseObject(data: string): void {
//const obj = instantiate<T>()
const result = new Array<string>();
let lastPos: u32 = 0;
let char: u32 = 0;
let i: u32 = 1;
let key: string = "";
let isKey: boolean = false;
for (; i < u32(data.length - 1); i++) {
char = data.charCodeAt(i);
if (isKey == false) {
if (char == colonCode) {
key = data.slice(lastPos + 2, i - 1);
//console.log(`Found Key: ${key}`);
result.push(key);
lastPos = ++i;
isKey = true;
}
} else {
if (char == commaCode) {
const val = data.slice(lastPos, i);
lastPos = i;
isKey = false;
//console.log(`Found Val: ${val}`)
result.push(val);
}
}
}
result.push(data.slice(lastPos, data.length - 1));
//console.log(stringify(result))
//return obj
}
class Nullable { }
import "wasi";
import { JSON } from ".";
// @ts-ignore
@json

@@ -9,2 +10,4 @@ class Vec2 {

}
// @ts-ignore
@json

@@ -31,7 +34,26 @@ class Player {

const stringified = JSON.stringify<Player>(data);
// '{"firstName":"Emmet","lastName":"West","lastActive":[8,27,2022],"age":23}'
// {
// "firstName": "Emmet",
// "lastName": "West",
// "lastActive": [8, 27, 2022],
// "age": 23,
// "pos": {
// "x": -3.4000000953674318,
// "y": 1.2000000476837159
// }
// }
console.log(`Stringified: ${stringified}`);
const parsed = JSON.parse<Player>(stringified)
// { firstName: "Emmet", lastName: "West", "lastActive": [8,27,2022], age: 23 }
console.log(`Parsed: ${JSON.stringify(parsed)}`)
data.age = 16
console.log(`Stringified2: ${JSON.stringify<Player>(data)}`);
const parsed = JSON.parse<Player>(stringified);
// Player {
// firstName: "Emmet",
// lastName: "West",
// lastActive: [8, 27, 2022],
// age: 23,
// pos: {
// x: -3.4000000953674318,
// y: 1.2000000476837159
// }
// }
console.log(`Parsed: ${JSON.stringify(parsed)}`);
{
"name": "json-as",
"version": "0.4.2",
"version": "0.4.3",
"description": "JSON encoder/decoder for AssemblyScript",

@@ -20,2 +20,3 @@ "types": "assembly/index.ts",

"devDependencies": {
"@as-pect/cli": "^7.0.7",
"@as-tral/cli": "^1.1.1",

@@ -25,4 +26,2 @@ "as-console": "^6.0.2",

"assemblyscript-prettier": "^1.0.2",
"benchmark": "^2.1.4",
"microtime": "^3.0.0",
"typescript": "^4.7.2"

@@ -32,3 +31,3 @@ },

"as-string-sink": "^0.5.0",
"as-variant": "^0.3.0"
"as-variant": "^0.4.0"
},

@@ -44,3 +43,4 @@ "repository": {

"deserialize",
"dynamic"
"dynamic",
"serde"
],

@@ -47,0 +47,0 @@ "bugs": {

@@ -70,12 +70,42 @@ # AS-JSON

const stringified = JSON.stringify<Player>(data);
// '{"firstName":"Emmet","lastName":"West","lastActive":[8,27,2022],"age":23}'
// {
// "firstName": "Emmet",
// "lastName": "West",
// "lastActive": [8, 27, 2022],
// "age": 23,
// "pos": {
// "x": -3.4000000953674318,
// "y": 1.2000000476837159
// }
// }
console.log(`Stringified: ${stringified}`);
const parsed = JSON.parse<Player>(stringified)
// { firstName: "Emmet", lastName: "West", "lastActive": [8,27,2022], age: 23 }
console.log(`Parsed: ${JSON.stringify(parsed)}`)
const parsed = JSON.parse<Player>(stringified);
// Player {
// firstName: "Emmet",
// lastName: "West",
// lastActive: [8, 27, 2022],
// age: 23,
// pos: {
// x: -3.4000000953674318,
// y: 1.2000000476837159
// }
// }
console.log(`Parsed: ${JSON.stringify(parsed)}`);
```
## FAQ
- Does it support the full JSON spec?
Yes, as-json supports the full JSON specification and trys to mimic the JSON API as much as possible
- What are the differences between as-json and the JSON API?
The main difference between as-json and the JSON API is the ability to create new fields in objects during runtime. Since classes are static, Map ser/de support will be added soon allowing the user to parse and stringify dynamic objects and their properties
- Does this support nested structures?
Yes, as-json supports nested structures
- Does this support whitespace?
No, as-json does not support whitespace yet. That will come once we find a performant way to work around whitespace.
- How fast is it?
Really fast. For example, here are some benchmarks for ser/de a Vec2 with as-json
## Issues
Please submit an issue to https://github.com/JairusSW/as-json/issues if you find anything wrong with this library

@@ -8,4 +8,4 @@ import { ClassDecorator, registerDecorator } from "visitor-as/dist/decorator.js";

this.sources = [];
this.encodeStmts = new Map();
this.decodeCode = new Map();
this.encodeStmts = [];
this.decodeStmts = [];
}

@@ -19,11 +19,6 @@ visitMethodDeclaration(node) { }

const type = getName(node.type);
const className = this.currentClass.name.text;
if (!this.encodeStmts.has(className))
this.encodeStmts.set(className, []);
if (!this.decodeCode.has(className))
this.decodeCode.set(className, []);
// @ts-ignore
this.encodeStmts.get(className).push(`this.__JSON_Serialized += '' + '"' + '${name}' + '"' + ':' + JSON.stringify<${type}>(this.${name}) + ',';`);
this.encodeStmts.push(`"${name}":\${JSON.stringify<${type}>(this.${name})},`);
// @ts-ignore
this.decodeCode.get(className).push(`${name}: JSON.parse<${type}>(values.get("${name}")),\n`);
this.decodeStmts.push(`${name}: JSON.parse<${type}>(values.get("${name}")),\n`);
}

@@ -36,16 +31,12 @@ visitClassDeclaration(node) {

const name = getName(node);
this.encodeStmts.delete(name);
this.decodeCode.delete(name);
this.visit(node.members);
const serializedProp = `__JSON_Serialized: string = "";`;
let serializeFunc = ``;
if (this.encodeStmts.has(name) && this.encodeStmts.get(name)) {
if (this.encodeStmts.length > 0) {
const stmt = this.encodeStmts[this.encodeStmts.length - 1];
this.encodeStmts[this.encodeStmts.length - 1] = stmt.slice(0, stmt.length - 1);
serializeFunc = `
@inline
__JSON_Serialize(): string {
if (!this.__JSON_Serialized) {
${ // @ts-ignore
this.encodeStmts.get(name).join("\n")};
this.__JSON_Serialized = "{" + this.__JSON_Serialized.slice(0, this.__JSON_Serialized.length - 1) + "}";
}
return this.__JSON_Serialized;
return \`{${this.encodeStmts.join("")}}\`;
}

@@ -56,2 +47,3 @@ `;

serializeFunc = `
@inline
__JSON_Serialize(): string {

@@ -63,10 +55,13 @@ return "{}";

const deserializeFunc = `
@inline
__JSON_Deserialize(values: Map<string, string>): ${name} {
return {
${ // @ts-ignore
this.decodeCode.get(name) ? this.decodeCode.get(name).join("") : ""}
this.decodeStmts.join("")}
}
}
`;
//console.log(serializedProp, serializeFunc, deserializeFunc)
this.encodeStmts = [];
this.decodeStmts = [];
console.log(serializeFunc, deserializeFunc);
const serializedProperty = SimpleParser.parseClassMember(serializedProp, node);

@@ -73,0 +68,0 @@ node.members.push(serializedProperty);

{
"name": "@json-as/transform",
"version": "0.4.2",
"version": "0.4.3",
"description": "JSON encoder/decoder for AssemblyScript",

@@ -5,0 +5,0 @@ "main": "./lib/index.js",

@@ -14,4 +14,4 @@ import {

public sources: Source[] = [];
public encodeStmts = new Map<string, string[]>();
public decodeCode = new Map<string, string[]>();
public encodeStmts: string[] = [];
public decodeStmts: string[] = [];

@@ -27,12 +27,9 @@ visitMethodDeclaration(node: MethodDeclaration): void {}

const className = this.currentClass!.name.text
if (!this.encodeStmts.has(className)) this.encodeStmts.set(className, [])
if (!this.decodeCode.has(className)) this.decodeCode.set(className, [])
// @ts-ignore
this.encodeStmts.get(className).push(
`this.__JSON_Serialized += '' + '"' + '${name}' + '"' + ':' + JSON.stringify<${type}>(this.${name}) + ',';`
this.encodeStmts.push(
`"${name}":\${JSON.stringify<${type}>(this.${name})},`
);
// @ts-ignore
this.decodeCode.get(className).push(
this.decodeStmts.push(
`${name}: JSON.parse<${type}>(values.get("${name}")),\n`

@@ -50,4 +47,2 @@ );

this.encodeStmts.delete(name);
this.decodeCode.delete(name);
this.visit(node.members);

@@ -59,11 +54,9 @@

if (this.encodeStmts.has(name) && this.encodeStmts.get(name)) {
if (this.encodeStmts.length > 0) {
const stmt = this.encodeStmts[this.encodeStmts.length - 1]!
this.encodeStmts[this.encodeStmts.length - 1] = stmt!.slice(0, stmt.length - 1)
serializeFunc = `
@inline
__JSON_Serialize(): string {
if (!this.__JSON_Serialized) {
${// @ts-ignore
this.encodeStmts.get(name).join("\n")};
this.__JSON_Serialized = "{" + this.__JSON_Serialized.slice(0, this.__JSON_Serialized.length - 1) + "}";
}
return this.__JSON_Serialized;
return \`{${this.encodeStmts.join("")}}\`;
}

@@ -73,2 +66,3 @@ `

serializeFunc = `
@inline
__JSON_Serialize(): string {

@@ -81,10 +75,13 @@ return "{}";

const deserializeFunc = `
@inline
__JSON_Deserialize(values: Map<string, string>): ${name} {
return {
${// @ts-ignore
this.decodeCode.get(name) ? this.decodeCode.get(name).join("") : ""}
this.decodeStmts.join("")}
}
}
`;
//console.log(serializedProp, serializeFunc, deserializeFunc)
this.encodeStmts = [];
this.decodeStmts = [];
console.log(serializeFunc, deserializeFunc)
const serializedProperty = SimpleParser.parseClassMember(serializedProp, node);

@@ -91,0 +88,0 @@ node.members.push(serializedProperty);

@@ -17,3 +17,3 @@ {

// "outFile": "./", /* Concatenate and emit output to single file. */
"outDir": "./lib/" /* Specify the root directory of input files. Use to control the output directory structure with --outDir. */,
"outDir": "./lib" /* Specify the root directory of input files. Use to control the output directory structure with --outDir. */,
// "composite": true, /* Enable project compilation */

@@ -20,0 +20,0 @@ // "tsBuildInfoFile": "./", /* Specify file to store incremental compilation information */