fast-json-stringify 5.4.0 → 5.4.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +29 -23
- package/index.js +6 -7
- package/lib/location.js +2 -4
- package/lib/ref-resolver.js +21 -1
- package/lib/serializer.js +8 -0
- package/package.json +18 -15
- package/test/anyof.test.js +28 -0
package/README.md
CHANGED
|
@@ -18,31 +18,37 @@ fast-json-stringify requires a [JSON Schema Draft 7](https://json-schema.org/spe
|
|
|
18
18
|
##### Benchmarks
|
|
19
19
|
|
|
20
20
|
- Machine: `EX41S-SSD, Intel Core i7, 4Ghz, 64GB RAM, 4C/8T, SSD`.
|
|
21
|
-
- Node.js `
|
|
21
|
+
- Node.js `v18.12.1`
|
|
22
22
|
|
|
23
23
|
```
|
|
24
|
-
FJS creation x
|
|
25
|
-
CJS creation x
|
|
26
|
-
AJV Serialize creation x
|
|
27
|
-
JSON.stringify array x 5,
|
|
28
|
-
fast-json-stringify array x 6,
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
24
|
+
FJS creation x 4,129 ops/sec ±0.82% (92 runs sampled)
|
|
25
|
+
CJS creation x 184,196 ops/sec ±0.12% (97 runs sampled)
|
|
26
|
+
AJV Serialize creation x 61,130,591 ops/sec ±0.40% (92 runs sampled)
|
|
27
|
+
JSON.stringify array x 5,057 ops/sec ±0.10% (100 runs sampled)
|
|
28
|
+
fast-json-stringify array default x 6,243 ops/sec ±0.14% (98 runs sampled)
|
|
29
|
+
fast-json-stringify array json-stringify x 6,261 ops/sec ±0.30% (99 runs sampled)
|
|
30
|
+
compile-json-stringify array x 6,842 ops/sec ±0.18% (96 runs sampled)
|
|
31
|
+
AJV Serialize array x 6,964 ops/sec ±0.11% (95 runs sampled)
|
|
32
|
+
JSON.stringify large array x 248 ops/sec ±0.07% (90 runs sampled)
|
|
33
|
+
fast-json-stringify large array default x 99.96 ops/sec ±0.22% (74 runs sampled)
|
|
34
|
+
fast-json-stringify large array json-stringify x 248 ops/sec ±0.07% (90 runs sampled)
|
|
35
|
+
compile-json-stringify large array x 317 ops/sec ±0.09% (89 runs sampled)
|
|
36
|
+
AJV Serialize large array x 111 ops/sec ±0.07% (33 runs sampled)
|
|
37
|
+
JSON.stringify long string x 16,002 ops/sec ±0.09% (98 runs sampled)
|
|
38
|
+
fast-json-stringify long string x 15,979 ops/sec ±0.09% (96 runs sampled)
|
|
39
|
+
compile-json-stringify long string x 15,952 ops/sec ±0.31% (97 runs sampled)
|
|
40
|
+
AJV Serialize long string x 21,416 ops/sec ±0.08% (98 runs sampled)
|
|
41
|
+
JSON.stringify short string x 12,944,272 ops/sec ±0.09% (96 runs sampled)
|
|
42
|
+
fast-json-stringify short string x 30,585,790 ops/sec ±0.27% (97 runs sampled)
|
|
43
|
+
compile-json-stringify short string x 30,656,406 ops/sec ±0.12% (96 runs sampled)
|
|
44
|
+
AJV Serialize short string x 30,406,785 ops/sec ±0.37% (96 runs sampled)
|
|
45
|
+
JSON.stringify obj x 3,153,043 ops/sec ±0.33% (99 runs sampled)
|
|
46
|
+
fast-json-stringify obj x 6,866,434 ops/sec ±0.11% (100 runs sampled)
|
|
47
|
+
compile-json-stringify obj x 15,886,723 ops/sec ±0.15% (98 runs sampled)
|
|
48
|
+
AJV Serialize obj x 8,969,043 ops/sec ±0.36% (97 runs sampled)
|
|
49
|
+
JSON stringify date x 1,126,547 ops/sec ±0.09% (97 runs sampled)
|
|
50
|
+
fast-json-stringify date format x 1,836,188 ops/sec ±0.12% (99 runs sampled)
|
|
51
|
+
compile-json-stringify date format x 1,125,735 ops/sec ±0.19% (98 runs sampled)
|
|
46
52
|
```
|
|
47
53
|
|
|
48
54
|
#### Table of contents:
|
package/index.js
CHANGED
|
@@ -56,11 +56,7 @@ function resolveRef (location, ref) {
|
|
|
56
56
|
throw new Error(`Cannot find reference "${ref}"`)
|
|
57
57
|
}
|
|
58
58
|
|
|
59
|
-
|
|
60
|
-
validatorSchemasIds.add(schemaId)
|
|
61
|
-
}
|
|
62
|
-
|
|
63
|
-
const newLocation = new Location(schema, schemaId, jsonPointer, location.isValidated)
|
|
59
|
+
const newLocation = new Location(schema, schemaId, jsonPointer)
|
|
64
60
|
if (schema.$ref !== undefined) {
|
|
65
61
|
return resolveRef(newLocation, schema.$ref)
|
|
66
62
|
}
|
|
@@ -137,6 +133,11 @@ function build (schema, options) {
|
|
|
137
133
|
for (const schemaId of validatorSchemasIds) {
|
|
138
134
|
const schema = refResolver.getSchema(schemaId)
|
|
139
135
|
validator.addSchema(schema, schemaId)
|
|
136
|
+
|
|
137
|
+
const dependencies = refResolver.getSchemaDependencies(schemaId)
|
|
138
|
+
for (const [schemaId, schema] of Object.entries(dependencies)) {
|
|
139
|
+
validator.addSchema(schema, schemaId)
|
|
140
|
+
}
|
|
140
141
|
}
|
|
141
142
|
|
|
142
143
|
const dependenciesName = ['validator', 'serializer', contextFunctionCode]
|
|
@@ -454,7 +455,6 @@ function mergeAllOfSchema (location, schema, mergedSchema) {
|
|
|
454
455
|
}
|
|
455
456
|
|
|
456
457
|
function addIfThenElse (location, input) {
|
|
457
|
-
location.isValidated = true
|
|
458
458
|
validatorSchemasIds.add(location.getSchemaId())
|
|
459
459
|
|
|
460
460
|
const schema = merge({}, location.schema)
|
|
@@ -840,7 +840,6 @@ function buildValue (location, input) {
|
|
|
840
840
|
let code = ''
|
|
841
841
|
|
|
842
842
|
if (type === undefined && (schema.anyOf || schema.oneOf)) {
|
|
843
|
-
location.isValidated = true
|
|
844
843
|
validatorSchemasIds.add(location.getSchemaId())
|
|
845
844
|
|
|
846
845
|
const type = schema.anyOf ? 'anyOf' : 'oneOf'
|
package/lib/location.js
CHANGED
|
@@ -1,11 +1,10 @@
|
|
|
1
1
|
'use strict'
|
|
2
2
|
|
|
3
3
|
class Location {
|
|
4
|
-
constructor (schema, schemaId, jsonPointer = '#'
|
|
4
|
+
constructor (schema, schemaId, jsonPointer = '#') {
|
|
5
5
|
this.schema = schema
|
|
6
6
|
this.schemaId = schemaId
|
|
7
7
|
this.jsonPointer = jsonPointer
|
|
8
|
-
this.isValidated = isValidated
|
|
9
8
|
this.mergedSchemaId = null
|
|
10
9
|
}
|
|
11
10
|
|
|
@@ -13,8 +12,7 @@ class Location {
|
|
|
13
12
|
const propertyLocation = new Location(
|
|
14
13
|
this.schema[propertyName],
|
|
15
14
|
this.schemaId,
|
|
16
|
-
this.jsonPointer + '/' + propertyName
|
|
17
|
-
this.isValidated
|
|
15
|
+
this.jsonPointer + '/' + propertyName
|
|
18
16
|
)
|
|
19
17
|
|
|
20
18
|
if (this.mergedSchemaId !== null) {
|
package/lib/ref-resolver.js
CHANGED
|
@@ -28,6 +28,18 @@ class RefResolver {
|
|
|
28
28
|
return getDataByJSONPointer(schema.schema, jsonPointer)
|
|
29
29
|
}
|
|
30
30
|
|
|
31
|
+
getSchemaDependencies (schemaId, dependencies = {}) {
|
|
32
|
+
const schema = this.schemas[schemaId]
|
|
33
|
+
|
|
34
|
+
for (const dependencySchemaId of schema.dependencies) {
|
|
35
|
+
if (dependencies[dependencySchemaId] !== undefined) continue
|
|
36
|
+
dependencies[dependencySchemaId] = this.getSchema(dependencySchemaId)
|
|
37
|
+
this.getSchemaDependencies(dependencySchemaId, dependencies)
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
return dependencies
|
|
41
|
+
}
|
|
42
|
+
|
|
31
43
|
insertSchemaBySchemaId (schema, schemaId) {
|
|
32
44
|
if (
|
|
33
45
|
this.schemas[schemaId] !== undefined &&
|
|
@@ -35,7 +47,7 @@ class RefResolver {
|
|
|
35
47
|
) {
|
|
36
48
|
throw new Error(`There is already another schema with id ${schemaId}`)
|
|
37
49
|
}
|
|
38
|
-
this.schemas[schemaId] = { schema, anchors: {} }
|
|
50
|
+
this.schemas[schemaId] = { schema, anchors: {}, dependencies: [] }
|
|
39
51
|
}
|
|
40
52
|
|
|
41
53
|
insertSchemaByAnchor (schema, schemaId, anchor) {
|
|
@@ -60,6 +72,14 @@ class RefResolver {
|
|
|
60
72
|
}
|
|
61
73
|
}
|
|
62
74
|
|
|
75
|
+
const ref = schema.$ref
|
|
76
|
+
if (ref !== undefined && typeof ref === 'string') {
|
|
77
|
+
if (ref.charAt(0) !== '#') {
|
|
78
|
+
const dependencySchemaId = ref.split('#')[0]
|
|
79
|
+
this.schemas[rootSchemaId].dependencies.push(dependencySchemaId)
|
|
80
|
+
}
|
|
81
|
+
}
|
|
82
|
+
|
|
63
83
|
for (const key in schema) {
|
|
64
84
|
if (typeof schema[key] === 'object' && schema[key] !== null) {
|
|
65
85
|
this.insertSchemaSubschemas(schema[key], rootSchemaId)
|
package/lib/serializer.js
CHANGED
|
@@ -1,5 +1,8 @@
|
|
|
1
1
|
'use strict'
|
|
2
2
|
|
|
3
|
+
// eslint-disable-next-line
|
|
4
|
+
const STR_ESCAPE = /[\u0000-\u001f\u0022\u005c\ud800-\udfff]|[\ud800-\udbff](?![\udc00-\udfff])|(?:[^\ud800-\udbff]|^)[\udc00-\udfff]/
|
|
5
|
+
|
|
3
6
|
module.exports = class Serializer {
|
|
4
7
|
constructor (options = {}) {
|
|
5
8
|
switch (options.rounding) {
|
|
@@ -94,6 +97,11 @@ module.exports = class Serializer {
|
|
|
94
97
|
str = str.toString()
|
|
95
98
|
}
|
|
96
99
|
|
|
100
|
+
// Fast escape chars check
|
|
101
|
+
if (!STR_ESCAPE.test(str)) {
|
|
102
|
+
return quotes + str + quotes
|
|
103
|
+
}
|
|
104
|
+
|
|
97
105
|
if (str.length < 42) {
|
|
98
106
|
return this.asStringSmall(str)
|
|
99
107
|
} else {
|
package/package.json
CHANGED
|
@@ -1,21 +1,13 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "fast-json-stringify",
|
|
3
|
-
"version": "5.4.
|
|
3
|
+
"version": "5.4.1",
|
|
4
4
|
"description": "Stringify your JSON at max speed",
|
|
5
5
|
"main": "index.js",
|
|
6
6
|
"types": "index.d.ts",
|
|
7
|
-
"
|
|
8
|
-
"
|
|
9
|
-
"
|
|
10
|
-
|
|
11
|
-
"benchmark": "node ./benchmark/bench-cmp-lib.js",
|
|
12
|
-
"lint": "standard",
|
|
13
|
-
"lint:fix": "standard --fix",
|
|
14
|
-
"test:typescript": "tsc --project ./test/types/tsconfig.json && tsd",
|
|
15
|
-
"test:unit": "tap -J test/*.test.js test/**/*.test.js",
|
|
16
|
-
"test": "npm run test:unit && npm run test:typescript"
|
|
17
|
-
},
|
|
18
|
-
"precommit": ["lint", "test"],
|
|
7
|
+
"precommit": [
|
|
8
|
+
"lint",
|
|
9
|
+
"test"
|
|
10
|
+
],
|
|
19
11
|
"repository": {
|
|
20
12
|
"type": "git",
|
|
21
13
|
"url": "git+https://github.com/fastify/fast-json-stringify.git"
|
|
@@ -34,7 +26,7 @@
|
|
|
34
26
|
"homepage": "https://github.com/fastify/fast-json-stringify#readme",
|
|
35
27
|
"devDependencies": {
|
|
36
28
|
"@fastify/pre-commit": "^2.0.2",
|
|
37
|
-
"@sinclair/typebox": "^0.
|
|
29
|
+
"@sinclair/typebox": "^0.25.2",
|
|
38
30
|
"benchmark": "^2.1.4",
|
|
39
31
|
"cli-select": "^1.1.2",
|
|
40
32
|
"compile-json-stringify": "^0.1.2",
|
|
@@ -65,5 +57,16 @@
|
|
|
65
57
|
"runkitExampleFilename": "./examples/example.js",
|
|
66
58
|
"tsd": {
|
|
67
59
|
"directory": "test/types"
|
|
60
|
+
},
|
|
61
|
+
"scripts": {
|
|
62
|
+
"bench": "node ./benchmark/bench.js",
|
|
63
|
+
"bench:cmp": "node ./benchmark/bench-cmp-branch.js",
|
|
64
|
+
"bench:cmp:ci": "node ./benchmark/bench-cmp-branch.js --ci",
|
|
65
|
+
"benchmark": "node ./benchmark/bench-cmp-lib.js",
|
|
66
|
+
"lint": "standard",
|
|
67
|
+
"lint:fix": "standard --fix",
|
|
68
|
+
"test:typescript": "tsc --project ./test/types/tsconfig.json && tsd",
|
|
69
|
+
"test:unit": "tap -J test/*.test.js test/**/*.test.js",
|
|
70
|
+
"test": "npm run test:unit && npm run test:typescript"
|
|
68
71
|
}
|
|
69
|
-
}
|
|
72
|
+
}
|
package/test/anyof.test.js
CHANGED
|
@@ -616,3 +616,31 @@ test('anyOf with a nested external schema', (t) => {
|
|
|
616
616
|
const stringify = build(schema, { schema: externalSchemas })
|
|
617
617
|
t.equal(stringify('foo'), '"foo"')
|
|
618
618
|
})
|
|
619
|
+
|
|
620
|
+
test('object with ref and validated properties', (t) => {
|
|
621
|
+
t.plan(1)
|
|
622
|
+
|
|
623
|
+
const externalSchemas = {
|
|
624
|
+
RefSchema: {
|
|
625
|
+
$id: 'RefSchema',
|
|
626
|
+
type: 'string'
|
|
627
|
+
}
|
|
628
|
+
}
|
|
629
|
+
|
|
630
|
+
const schema = {
|
|
631
|
+
$id: 'root',
|
|
632
|
+
type: 'object',
|
|
633
|
+
properties: {
|
|
634
|
+
id: {
|
|
635
|
+
anyOf: [
|
|
636
|
+
{ type: 'string' },
|
|
637
|
+
{ type: 'number' }
|
|
638
|
+
]
|
|
639
|
+
},
|
|
640
|
+
reference: { $ref: 'RefSchema' }
|
|
641
|
+
}
|
|
642
|
+
}
|
|
643
|
+
|
|
644
|
+
const stringify = build(schema, { schema: externalSchemas })
|
|
645
|
+
t.equal(stringify({ id: 1, reference: 'hi' }), '{"id":1,"reference":"hi"}')
|
|
646
|
+
})
|