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 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 `v16.9.1`
21
+ - Node.js `v18.12.1`
22
22
 
23
23
  ```
24
- FJS creation x 8,443 ops/sec ±1.01% (90 runs sampled)
25
- CJS creation x 183,219 ops/sec ±0.13% (96 runs sampled)
26
- AJV Serialize creation x 83,541,848 ops/sec ±0.24% (98 runs sampled)
27
- JSON.stringify array x 5,363 ops/sec ±0.11% (100 runs sampled)
28
- fast-json-stringify array x 6,747 ops/sec ±0.13% (98 runs sampled)
29
- compile-json-stringify array x 7,121 ops/sec ±0.42% (98 runs sampled)
30
- AJV Serialize array x 7,533 ops/sec ±0.13% (98 runs sampled)
31
- JSON.stringify long string x 16,461 ops/sec ±0.12% (98 runs sampled)
32
- fast-json-stringify long string x 16,443 ops/sec ±0.37% (99 runs sampled)
33
- compile-json-stringify long string x 16,458 ops/sec ±0.09% (98 runs sampled)
34
- AJV Serialize long string x 21,433 ops/sec ±0.08% (95 runs sampled)
35
- JSON.stringify short string x 12,035,664 ops/sec ±0.62% (96 runs sampled)
36
- fast-json-stringify short string x 38,281,060 ops/sec ±0.24% (98 runs sampled)
37
- compile-json-stringify short string x 32,388,037 ops/sec ±0.27% (97 runs sampled)
38
- AJV Serialize short string x 32,288,612 ops/sec ±0.32% (95 runs sampled)
39
- JSON.stringify obj x 3,068,185 ops/sec ±0.16% (98 runs sampled)
40
- fast-json-stringify obj x 10,082,694 ops/sec ±0.10% (97 runs sampled)
41
- compile-json-stringify obj x 17,037,963 ops/sec ±1.17% (97 runs sampled)
42
- AJV Serialize obj x 9,660,041 ops/sec ±0.11% (97 runs sampled)
43
- JSON stringify date x 1,084,008 ops/sec ±0.16% (98 runs sampled)
44
- fast-json-stringify date format x 1,781,044 ops/sec ±0.48% (99 runs sampled)
45
- compile-json-stringify date format x 1,086,187 ops/sec ±0.16% (99 runs sampled)
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
- if (location.isValidated) {
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 = '#', isValidated = false) {
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) {
@@ -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.0",
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
- "scripts": {
8
- "bench": "node ./benchmark/bench.js",
9
- "bench:cmp": "node ./benchmark/bench-cmp-branch.js",
10
- "bench:cmp:ci": "node ./benchmark/bench-cmp-branch.js --ci",
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.24.9",
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
+ }
@@ -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
+ })