fast-json-stringify 3.0.3 → 3.1.0
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/.github/workflows/benchmark.yml +6 -1
- package/README.md +59 -3
- package/bench.js +69 -7
- package/example.js +1 -1
- package/index.js +59 -3
- package/package.json +4 -3
- package/test/array.test.js +46 -2
|
@@ -8,6 +8,8 @@ jobs:
|
|
|
8
8
|
benchmark:
|
|
9
9
|
if: ${{ github.event.label.name == 'benchmark' }}
|
|
10
10
|
runs-on: ubuntu-latest
|
|
11
|
+
permissions:
|
|
12
|
+
contents: read
|
|
11
13
|
outputs:
|
|
12
14
|
PR-BENCH-12: ${{ steps.benchmark-pr.outputs.BENCH_RESULT12 }}
|
|
13
15
|
PR-BENCH-14: ${{ steps.benchmark-pr.outputs.BENCH_RESULT14 }}
|
|
@@ -21,7 +23,8 @@ jobs:
|
|
|
21
23
|
steps:
|
|
22
24
|
- uses: actions/checkout@v2
|
|
23
25
|
with:
|
|
24
|
-
|
|
26
|
+
persist-credentials: false
|
|
27
|
+
ref: ${{github.event.pull_request.head.sha}}
|
|
25
28
|
repository: ${{github.event.pull_request.head.repo.full_name}}
|
|
26
29
|
|
|
27
30
|
- uses: actions/setup-node@v2
|
|
@@ -64,6 +67,8 @@ jobs:
|
|
|
64
67
|
output-benchmark:
|
|
65
68
|
needs: [benchmark]
|
|
66
69
|
runs-on: ubuntu-latest
|
|
70
|
+
permissions:
|
|
71
|
+
pull-requests: write
|
|
67
72
|
steps:
|
|
68
73
|
- name: Comment PR
|
|
69
74
|
uses: thollander/actions-comment-pull-request@v1
|
package/README.md
CHANGED
|
@@ -56,11 +56,12 @@ compile-json-stringify date format x 1,086,187 ops/sec ±0.16% (99 runs sampled)
|
|
|
56
56
|
- <a href="#missingFields">`Missing fields`</a>
|
|
57
57
|
- <a href="#patternProperties">`Pattern Properties`</a>
|
|
58
58
|
- <a href="#additionalProperties">`Additional Properties`</a>
|
|
59
|
-
- <a href="#
|
|
59
|
+
- <a href="#AnyOf-and-OneOf">`AnyOf` and `OneOf`</a>
|
|
60
60
|
- <a href="#ref">`Reuse - $ref`</a>
|
|
61
61
|
- <a href="#long">`Long integers`</a>
|
|
62
62
|
- <a href="#integer">`Integers`</a>
|
|
63
63
|
- <a href="#nullable">`Nullable`</a>
|
|
64
|
+
- <a href="#largearrays">`Large Arrays`</a>
|
|
64
65
|
- <a href="#security">`Security Notice`</a>
|
|
65
66
|
- <a href="#acknowledgements">`Acknowledgements`</a>
|
|
66
67
|
- <a href="#license">`License`</a>
|
|
@@ -117,6 +118,8 @@ const stringify = fastJson(mySchema, {
|
|
|
117
118
|
- `schema`: external schemas references by $ref property. [More details](#ref)
|
|
118
119
|
- `ajv`: [ajv v8 instance's settings](https://ajv.js.org/options.html) for those properties that require `ajv`. [More details](#anyof)
|
|
119
120
|
- `rounding`: setup how the `integer` types will be rounded when not integers. [More details](#integer)
|
|
121
|
+
- `largeArrayMechanism`: set the mechanism that should be used to handle large
|
|
122
|
+
(by default `20000` or more items) arrays. [More details](#largearrays)
|
|
120
123
|
|
|
121
124
|
|
|
122
125
|
<a name="api"></a>
|
|
@@ -268,7 +271,7 @@ const stringify = fastJson({
|
|
|
268
271
|
const obj = {
|
|
269
272
|
nickname: 'nick',
|
|
270
273
|
matchfoo: 42,
|
|
271
|
-
otherfoo: 'str'
|
|
274
|
+
otherfoo: 'str',
|
|
272
275
|
matchnum: 3
|
|
273
276
|
}
|
|
274
277
|
|
|
@@ -311,7 +314,7 @@ const stringify = fastJson({
|
|
|
311
314
|
const obj = {
|
|
312
315
|
nickname: 'nick',
|
|
313
316
|
matchfoo: 42,
|
|
314
|
-
otherfoo: 'str'
|
|
317
|
+
otherfoo: 'str',
|
|
315
318
|
matchnum: 3,
|
|
316
319
|
nomatchstr: 'valar morghulis',
|
|
317
320
|
nomatchint: 313
|
|
@@ -582,6 +585,59 @@ Otherwise, instead of raising an error, null values will be coerced as follows:
|
|
|
582
585
|
- `string` -> `""`
|
|
583
586
|
- `boolean` -> `false`
|
|
584
587
|
|
|
588
|
+
<a name="largearrays"></a>
|
|
589
|
+
#### Large Arrays
|
|
590
|
+
|
|
591
|
+
Large arrays are, for the scope of this document, defined as arrays containing,
|
|
592
|
+
by default, `20000` elements or more. That value can be adjusted via the option
|
|
593
|
+
parameter `largeArraySize`.
|
|
594
|
+
|
|
595
|
+
At some point the overhead caused by the default mechanism used by
|
|
596
|
+
`fast-json-stringify` to handle arrays starts increasing exponentially, leading
|
|
597
|
+
to slow overall executions.
|
|
598
|
+
|
|
599
|
+
##### Settings
|
|
600
|
+
|
|
601
|
+
In order to improve that the user can set the `largeArrayMechanism` and
|
|
602
|
+
`largeArraySize` options.
|
|
603
|
+
|
|
604
|
+
`largeArrayMechanism`'s default value is `default`. Valid values for it are:
|
|
605
|
+
|
|
606
|
+
- `default` - This option is a compromise between performance and feature set by
|
|
607
|
+
still providing the expected functionality out of this lib but giving up some
|
|
608
|
+
possible performance gain. With this option set, **large arrays** would be
|
|
609
|
+
stringified by joining their stringified elements using `Array.join` instead of
|
|
610
|
+
string concatenation for better performance
|
|
611
|
+
- `json-stringify` - This option will remove support for schema validation
|
|
612
|
+
within **large arrays** completely. By doing so the overhead previously
|
|
613
|
+
mentioned is nulled, greatly improving execution time. Mind there's no change
|
|
614
|
+
in behavior for arrays not considered _large_
|
|
615
|
+
|
|
616
|
+
`largeArraySize`'s default value is `20000`. Valid values for it are
|
|
617
|
+
integer-like values, such as:
|
|
618
|
+
|
|
619
|
+
- `20000`
|
|
620
|
+
- `2e4`
|
|
621
|
+
- `'20000'`
|
|
622
|
+
- `'2e4'` - _note this will be converted to `2`, not `20000`_
|
|
623
|
+
- `1.5` - _note this will be converted to `1`_
|
|
624
|
+
|
|
625
|
+
##### Benchmarks
|
|
626
|
+
|
|
627
|
+
For reference, here goes some benchmarks for comparison over the three
|
|
628
|
+
mechanisms. Benchmarks conducted on an old machine.
|
|
629
|
+
|
|
630
|
+
- Machine: `ST1000LM024 HN-M 1TB HDD, Intel Core i7-3610QM @ 2.3GHz, 12GB RAM, 4C/8T`.
|
|
631
|
+
- Node.js `v16.13.1`
|
|
632
|
+
|
|
633
|
+
```
|
|
634
|
+
JSON.stringify large array x 157 ops/sec ±0.73% (86 runs sampled)
|
|
635
|
+
fast-json-stringify large array default x 48.72 ops/sec ±4.92% (48 runs sampled)
|
|
636
|
+
fast-json-stringify large array json-stringify x 157 ops/sec ±0.76% (86 runs sampled)
|
|
637
|
+
compile-json-stringify large array x 175 ops/sec ±4.47% (79 runs sampled)
|
|
638
|
+
AJV Serialize large array x 58.76 ops/sec ±4.59% (60 runs sampled)
|
|
639
|
+
```
|
|
640
|
+
|
|
585
641
|
<a name="security"></a>
|
|
586
642
|
## Security notice
|
|
587
643
|
|
package/bench.js
CHANGED
|
@@ -3,6 +3,10 @@
|
|
|
3
3
|
const benchmark = require('benchmark')
|
|
4
4
|
const suite = new benchmark.Suite()
|
|
5
5
|
|
|
6
|
+
const STR_LEN = 1e4
|
|
7
|
+
const LARGE_ARRAY_SIZE = 2e4
|
|
8
|
+
const MULTI_ARRAY_LENGHT = 1e3
|
|
9
|
+
|
|
6
10
|
const schema = {
|
|
7
11
|
title: 'Example Schema',
|
|
8
12
|
type: 'object',
|
|
@@ -89,7 +93,8 @@ const obj = {
|
|
|
89
93
|
|
|
90
94
|
const date = new Date()
|
|
91
95
|
|
|
92
|
-
const multiArray =
|
|
96
|
+
const multiArray = new Array(MULTI_ARRAY_LENGHT)
|
|
97
|
+
const largeArray = new Array(LARGE_ARRAY_SIZE)
|
|
93
98
|
|
|
94
99
|
const CJS = require('compile-json-stringify')
|
|
95
100
|
const CJSStringify = CJS(schemaCJS)
|
|
@@ -99,7 +104,10 @@ const CJSStringifyString = CJS({ type: 'string' })
|
|
|
99
104
|
|
|
100
105
|
const FJS = require('.')
|
|
101
106
|
const stringify = FJS(schema)
|
|
102
|
-
const
|
|
107
|
+
const stringifyArrayDefault = FJS(arraySchema)
|
|
108
|
+
const stringifyArrayJSONStringify = FJS(arraySchema, {
|
|
109
|
+
largeArrayMechanism: 'json-stringify'
|
|
110
|
+
})
|
|
103
111
|
const stringifyDate = FJS(dateFormatSchema)
|
|
104
112
|
const stringifyString = FJS({ type: 'string' })
|
|
105
113
|
let str = ''
|
|
@@ -110,18 +118,48 @@ const ajvSerialize = ajv.compileSerializer(schemaAJVJTD)
|
|
|
110
118
|
const ajvSerializeArray = ajv.compileSerializer(arraySchemaAJVJTD)
|
|
111
119
|
const ajvSerializeString = ajv.compileSerializer({ type: 'string' })
|
|
112
120
|
|
|
121
|
+
const getRandomString = (length) => {
|
|
122
|
+
if (!Number.isInteger(length)) {
|
|
123
|
+
throw new Error('Expected integer length')
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
const validCharacters = 'abcdefghijklmnopqrstuvwxyz'
|
|
127
|
+
const nValidCharacters = 26
|
|
128
|
+
|
|
129
|
+
let result = ''
|
|
130
|
+
for (let i = 0; i < length; ++i) {
|
|
131
|
+
result += validCharacters[Math.floor(Math.random() * nValidCharacters)]
|
|
132
|
+
}
|
|
133
|
+
|
|
134
|
+
return result[0].toUpperCase() + result.slice(1)
|
|
135
|
+
}
|
|
136
|
+
|
|
113
137
|
// eslint-disable-next-line
|
|
114
|
-
for (
|
|
138
|
+
for (let i = 0; i < STR_LEN; i++) {
|
|
139
|
+
largeArray[i] = {
|
|
140
|
+
firstName: getRandomString(8),
|
|
141
|
+
lastName: getRandomString(6),
|
|
142
|
+
age: Math.ceil(Math.random() * 99)
|
|
143
|
+
}
|
|
144
|
+
|
|
115
145
|
str += i
|
|
116
146
|
if (i % 100 === 0) {
|
|
117
147
|
str += '"'
|
|
118
148
|
}
|
|
119
149
|
}
|
|
120
150
|
|
|
151
|
+
for (let i = STR_LEN; i < LARGE_ARRAY_SIZE; ++i) {
|
|
152
|
+
largeArray[i] = {
|
|
153
|
+
firstName: getRandomString(10),
|
|
154
|
+
lastName: getRandomString(4),
|
|
155
|
+
age: Math.ceil(Math.random() * 99)
|
|
156
|
+
}
|
|
157
|
+
}
|
|
158
|
+
|
|
121
159
|
Number(str)
|
|
122
160
|
|
|
123
|
-
for (i = 0; i <
|
|
124
|
-
multiArray
|
|
161
|
+
for (let i = 0; i < MULTI_ARRAY_LENGHT; i++) {
|
|
162
|
+
multiArray[i] = obj
|
|
125
163
|
}
|
|
126
164
|
|
|
127
165
|
suite.add('FJS creation', function () {
|
|
@@ -138,8 +176,12 @@ suite.add('JSON.stringify array', function () {
|
|
|
138
176
|
JSON.stringify(multiArray)
|
|
139
177
|
})
|
|
140
178
|
|
|
141
|
-
suite.add('fast-json-stringify array', function () {
|
|
142
|
-
|
|
179
|
+
suite.add('fast-json-stringify array default', function () {
|
|
180
|
+
stringifyArrayDefault(multiArray)
|
|
181
|
+
})
|
|
182
|
+
|
|
183
|
+
suite.add('fast-json-stringify array json-stringify', function () {
|
|
184
|
+
stringifyArrayJSONStringify(multiArray)
|
|
143
185
|
})
|
|
144
186
|
|
|
145
187
|
suite.add('compile-json-stringify array', function () {
|
|
@@ -150,6 +192,26 @@ suite.add('AJV Serialize array', function () {
|
|
|
150
192
|
ajvSerializeArray(multiArray)
|
|
151
193
|
})
|
|
152
194
|
|
|
195
|
+
suite.add('JSON.stringify large array', function () {
|
|
196
|
+
JSON.stringify(largeArray)
|
|
197
|
+
})
|
|
198
|
+
|
|
199
|
+
suite.add('fast-json-stringify large array default', function () {
|
|
200
|
+
stringifyArrayDefault(largeArray)
|
|
201
|
+
})
|
|
202
|
+
|
|
203
|
+
suite.add('fast-json-stringify large array json-stringify', function () {
|
|
204
|
+
stringifyArrayJSONStringify(largeArray)
|
|
205
|
+
})
|
|
206
|
+
|
|
207
|
+
suite.add('compile-json-stringify large array', function () {
|
|
208
|
+
CJSStringifyArray(largeArray)
|
|
209
|
+
})
|
|
210
|
+
|
|
211
|
+
suite.add('AJV Serialize large array', function () {
|
|
212
|
+
ajvSerializeArray(largeArray)
|
|
213
|
+
})
|
|
214
|
+
|
|
153
215
|
suite.add('JSON.stringify long string', function () {
|
|
154
216
|
JSON.stringify(str)
|
|
155
217
|
})
|
package/example.js
CHANGED
package/index.js
CHANGED
|
@@ -3,6 +3,7 @@
|
|
|
3
3
|
/* eslint no-prototype-builtins: 0 */
|
|
4
4
|
|
|
5
5
|
const Ajv = require('ajv')
|
|
6
|
+
const fastUri = require('fast-uri')
|
|
6
7
|
const ajvFormats = require('ajv-formats')
|
|
7
8
|
const merge = require('deepmerge')
|
|
8
9
|
const clone = require('rfdc')({ proto: true })
|
|
@@ -10,7 +11,14 @@ const fjsCloned = Symbol('fast-json-stringify.cloned')
|
|
|
10
11
|
const { randomUUID } = require('crypto')
|
|
11
12
|
|
|
12
13
|
const validate = require('./schema-validator')
|
|
14
|
+
|
|
15
|
+
let largeArraySize = 2e4
|
|
13
16
|
let stringSimilarity = null
|
|
17
|
+
let largeArrayMechanism = 'default'
|
|
18
|
+
const validLargeArrayMechanisms = [
|
|
19
|
+
'default',
|
|
20
|
+
'json-stringify'
|
|
21
|
+
]
|
|
14
22
|
|
|
15
23
|
const addComma = `
|
|
16
24
|
if (addComma) {
|
|
@@ -52,7 +60,7 @@ function build (schema, options) {
|
|
|
52
60
|
|
|
53
61
|
options = options || {}
|
|
54
62
|
|
|
55
|
-
ajvInstance = new Ajv({ ...options.ajv, strictSchema: false })
|
|
63
|
+
ajvInstance = new Ajv({ ...options.ajv, strictSchema: false, uriResolver: fastUri })
|
|
56
64
|
ajvFormats(ajvInstance)
|
|
57
65
|
|
|
58
66
|
isValidSchema(schema)
|
|
@@ -72,6 +80,22 @@ function build (schema, options) {
|
|
|
72
80
|
}
|
|
73
81
|
}
|
|
74
82
|
|
|
83
|
+
if (options.largeArrayMechanism) {
|
|
84
|
+
if (validLargeArrayMechanisms.includes(options.largeArrayMechanism)) {
|
|
85
|
+
largeArrayMechanism = options.largeArrayMechanism
|
|
86
|
+
} else {
|
|
87
|
+
throw new Error(`Unsupported large array mechanism ${options.rounding}`)
|
|
88
|
+
}
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
if (options.largeArraySize) {
|
|
92
|
+
if (!Number.isNaN(Number.parseInt(options.largeArraySize, 10))) {
|
|
93
|
+
largeArraySize = options.largeArraySize
|
|
94
|
+
} else {
|
|
95
|
+
throw new Error(`Unsupported large array size. Expected integer-like, got ${options.largeArraySize}`)
|
|
96
|
+
}
|
|
97
|
+
}
|
|
98
|
+
|
|
75
99
|
/* eslint no-new-func: "off" */
|
|
76
100
|
let code = `
|
|
77
101
|
'use strict'
|
|
@@ -189,7 +213,7 @@ const numberKeywords = [
|
|
|
189
213
|
|
|
190
214
|
/**
|
|
191
215
|
* Infer type based on keyword in order to generate optimized code
|
|
192
|
-
* https://
|
|
216
|
+
* https://datatracker.ietf.org/doc/html/draft-handrews-json-schema-validation-01#section-6
|
|
193
217
|
*/
|
|
194
218
|
function inferTypeByKeyword (schema) {
|
|
195
219
|
// eslint-disable-next-line
|
|
@@ -1028,6 +1052,11 @@ function buildArray (location, code, name, key = null) {
|
|
|
1028
1052
|
|
|
1029
1053
|
code += `
|
|
1030
1054
|
var l = obj.length
|
|
1055
|
+
if (l && l >= ${largeArraySize}) {`
|
|
1056
|
+
|
|
1057
|
+
const concatSnippet = `
|
|
1058
|
+
}
|
|
1059
|
+
|
|
1031
1060
|
var jsonOutput= ''
|
|
1032
1061
|
for (var i = 0; i < l; i++) {
|
|
1033
1062
|
var json = ''
|
|
@@ -1039,7 +1068,25 @@ function buildArray (location, code, name, key = null) {
|
|
|
1039
1068
|
}
|
|
1040
1069
|
}
|
|
1041
1070
|
return \`[\${jsonOutput}]\`
|
|
1071
|
+
}`
|
|
1072
|
+
|
|
1073
|
+
switch (largeArrayMechanism) {
|
|
1074
|
+
case 'default':
|
|
1075
|
+
code += `
|
|
1076
|
+
return \`[\${obj.map(${result.mapFnName}).join(',')}]\``
|
|
1077
|
+
break
|
|
1078
|
+
|
|
1079
|
+
case 'json-stringify':
|
|
1080
|
+
code += `
|
|
1081
|
+
return JSON.stringify(obj)`
|
|
1082
|
+
break
|
|
1083
|
+
|
|
1084
|
+
default:
|
|
1085
|
+
throw new Error(`Unsupported large array mechanism ${largeArrayMechanism}`)
|
|
1042
1086
|
}
|
|
1087
|
+
|
|
1088
|
+
code += `
|
|
1089
|
+
${concatSnippet}
|
|
1043
1090
|
${result.laterCode}
|
|
1044
1091
|
`
|
|
1045
1092
|
|
|
@@ -1147,22 +1194,27 @@ function nested (laterCode, name, key, location, subKey, isArray) {
|
|
|
1147
1194
|
|
|
1148
1195
|
switch (type) {
|
|
1149
1196
|
case 'null':
|
|
1197
|
+
funcName = '$asNull'
|
|
1150
1198
|
code += `
|
|
1151
1199
|
json += $asNull()
|
|
1152
1200
|
`
|
|
1153
1201
|
break
|
|
1154
1202
|
case 'string': {
|
|
1203
|
+
funcName = '$asString'
|
|
1155
1204
|
const stringSerializer = getStringSerializer(schema.format)
|
|
1156
1205
|
code += nullable ? `json += obj${accessor} === null ? null : ${stringSerializer}(obj${accessor})` : `json += ${stringSerializer}(obj${accessor})`
|
|
1157
1206
|
break
|
|
1158
1207
|
}
|
|
1159
1208
|
case 'integer':
|
|
1209
|
+
funcName = '$asInteger'
|
|
1160
1210
|
code += nullable ? `json += obj${accessor} === null ? null : $asInteger(obj${accessor})` : `json += $asInteger(obj${accessor})`
|
|
1161
1211
|
break
|
|
1162
1212
|
case 'number':
|
|
1213
|
+
funcName = '$asNumber'
|
|
1163
1214
|
code += nullable ? `json += obj${accessor} === null ? null : $asNumber(obj${accessor})` : `json += $asNumber(obj${accessor})`
|
|
1164
1215
|
break
|
|
1165
1216
|
case 'boolean':
|
|
1217
|
+
funcName = '$asBoolean'
|
|
1166
1218
|
code += nullable ? `json += obj${accessor} === null ? null : $asBoolean(obj${accessor})` : `json += $asBoolean(obj${accessor})`
|
|
1167
1219
|
break
|
|
1168
1220
|
case 'object':
|
|
@@ -1180,6 +1232,7 @@ function nested (laterCode, name, key, location, subKey, isArray) {
|
|
|
1180
1232
|
`
|
|
1181
1233
|
break
|
|
1182
1234
|
case undefined:
|
|
1235
|
+
funcName = '$asNull'
|
|
1183
1236
|
if ('anyOf' in schema) {
|
|
1184
1237
|
// beware: dereferenceOfRefs has side effects and changes schema.anyOf
|
|
1185
1238
|
const anyOfLocations = dereferenceOfRefs(location, 'anyOf')
|
|
@@ -1318,7 +1371,8 @@ function nested (laterCode, name, key, location, subKey, isArray) {
|
|
|
1318
1371
|
|
|
1319
1372
|
return {
|
|
1320
1373
|
code,
|
|
1321
|
-
laterCode
|
|
1374
|
+
laterCode,
|
|
1375
|
+
mapFnName: funcName
|
|
1322
1376
|
}
|
|
1323
1377
|
}
|
|
1324
1378
|
|
|
@@ -1334,6 +1388,8 @@ function isEmpty (schema) {
|
|
|
1334
1388
|
|
|
1335
1389
|
module.exports = build
|
|
1336
1390
|
|
|
1391
|
+
module.exports.validLargeArrayMechanisms = validLargeArrayMechanisms
|
|
1392
|
+
|
|
1337
1393
|
module.exports.restore = function ({ code, ajv }) {
|
|
1338
1394
|
// eslint-disable-next-line
|
|
1339
1395
|
return (Function.apply(null, ['ajv', code])
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "fast-json-stringify",
|
|
3
|
-
"version": "3.0
|
|
3
|
+
"version": "3.1.0",
|
|
4
4
|
"description": "Stringify your JSON at max speed",
|
|
5
5
|
"main": "index.js",
|
|
6
6
|
"types": "index.d.ts",
|
|
@@ -39,14 +39,15 @@
|
|
|
39
39
|
"proxyquire": "^2.1.3",
|
|
40
40
|
"semver": "^7.1.0",
|
|
41
41
|
"standard": "^16.0.1",
|
|
42
|
-
"tap": "^
|
|
42
|
+
"tap": "^16.0.1",
|
|
43
43
|
"typescript": "^4.0.2",
|
|
44
44
|
"webpack": "^5.40.0"
|
|
45
45
|
},
|
|
46
46
|
"dependencies": {
|
|
47
|
-
"ajv": "^8.
|
|
47
|
+
"ajv": "^8.10.0",
|
|
48
48
|
"ajv-formats": "^2.1.1",
|
|
49
49
|
"deepmerge": "^4.2.2",
|
|
50
|
+
"fast-uri": "^1.0.1",
|
|
50
51
|
"rfdc": "^1.2.0",
|
|
51
52
|
"string-similarity": "^4.0.1"
|
|
52
53
|
},
|
package/test/array.test.js
CHANGED
|
@@ -5,12 +5,12 @@ const test = require('tap').test
|
|
|
5
5
|
const validator = require('is-my-json-valid')
|
|
6
6
|
const build = require('..')
|
|
7
7
|
|
|
8
|
-
function buildTest (schema, toStringify) {
|
|
8
|
+
function buildTest (schema, toStringify, options) {
|
|
9
9
|
test(`render a ${schema.title} as JSON`, (t) => {
|
|
10
10
|
t.plan(3)
|
|
11
11
|
|
|
12
12
|
const validate = validator(schema)
|
|
13
|
-
const stringify = build(schema)
|
|
13
|
+
const stringify = build(schema, options)
|
|
14
14
|
const output = stringify(toStringify)
|
|
15
15
|
|
|
16
16
|
t.same(JSON.parse(output), toStringify)
|
|
@@ -319,3 +319,47 @@ test('object array with anyOf and symbol', (t) => {
|
|
|
319
319
|
])
|
|
320
320
|
t.equal(value, '[{"name":"name-0","option":"Foo"},{"name":"name-1","option":"Bar"}]')
|
|
321
321
|
})
|
|
322
|
+
|
|
323
|
+
const largeArray = new Array(2e4).fill({ a: 'test', b: 1 })
|
|
324
|
+
buildTest({
|
|
325
|
+
title: 'large array with default mechanism',
|
|
326
|
+
type: 'object',
|
|
327
|
+
properties: {
|
|
328
|
+
ids: {
|
|
329
|
+
type: 'array',
|
|
330
|
+
items: {
|
|
331
|
+
type: 'object',
|
|
332
|
+
properties: {
|
|
333
|
+
a: { type: 'string' },
|
|
334
|
+
b: { type: 'number' }
|
|
335
|
+
}
|
|
336
|
+
}
|
|
337
|
+
}
|
|
338
|
+
}
|
|
339
|
+
}, {
|
|
340
|
+
ids: largeArray
|
|
341
|
+
}, {
|
|
342
|
+
largeArraySize: 2e4,
|
|
343
|
+
largeArrayMechanism: 'default'
|
|
344
|
+
})
|
|
345
|
+
|
|
346
|
+
buildTest({
|
|
347
|
+
title: 'large array with json-stringify mechanism',
|
|
348
|
+
type: 'object',
|
|
349
|
+
properties: {
|
|
350
|
+
ids: {
|
|
351
|
+
type: 'array',
|
|
352
|
+
items: {
|
|
353
|
+
type: 'object',
|
|
354
|
+
properties: {
|
|
355
|
+
a: { type: 'string' },
|
|
356
|
+
b: { type: 'number' }
|
|
357
|
+
}
|
|
358
|
+
}
|
|
359
|
+
}
|
|
360
|
+
}
|
|
361
|
+
}, {
|
|
362
|
+
ids: largeArray
|
|
363
|
+
}, {
|
|
364
|
+
largeArrayMechanism: 'json-stringify'
|
|
365
|
+
})
|