|
1 | 1 | # fast-json-stringify
|
2 | 2 |
|
3 |
| -[](http://standardjs.com/) [](https://dev.azure.com/fastify/fastify/_build/latest?definitionId=3&branchName=master) [](https://travis-ci.org/fastify/fast-json-stringify) [](https://www.npmjs.com/package/fast-json-stringify) |
| 3 | +[](http://standardjs.com/) |
| 4 | + |
| 5 | +[](https://www.npmjs.com/package/fast-json-stringify) |
| 6 | + |
4 | 7 |
|
5 | 8 | __fast-json-stringify__ is significantly faster than `JSON.stringify()` for small payloads. Its performance advantage shrinks as your payload grows. It pairs well with [__flatstr__](https://www.npmjs.com/package/flatstr), which triggers a V8 optimization that improves performance when eventually converting the string to a `Buffer`.
|
6 | 9 |
|
@@ -97,10 +100,34 @@ And nested ones, too.
|
97 | 100 | <a name="specific"></a>
|
98 | 101 | #### Specific use cases
|
99 | 102 |
|
100 |
| -| Instance | Serialized as | |
101 |
| -| -----------|------------------------------| |
102 |
| -| `Date` | `string` via `toISOString()` | |
103 |
| -| `RegExp` | `string` | |
| 103 | +| Instance | Serialized as | |
| 104 | +| -------- | ---------------------------- | |
| 105 | +| `Date` | `string` via `toISOString()` | |
| 106 | +| `RegExp` | `string` | |
| 107 | +| `BigInt` | `integer` via `toString` | |
| 108 | + |
| 109 | +[JSON Schema built-in formats](https://json-schema.org/understanding-json-schema/reference/string.html#built-in-formats) for dates are supported and will be serialized as: |
| 110 | + |
| 111 | +| Format | Serialized format example | |
| 112 | +| ----------- | -------------------------- | |
| 113 | +| `date-time` | `2020-04-03T09:11:08.615Z` | |
| 114 | +| `date` | `2020-04-03` | |
| 115 | +| `time` | `09:11:08` | |
| 116 | + |
| 117 | +Example with a MomentJS object: |
| 118 | + |
| 119 | +```javascript |
| 120 | +const moment = require('moment') |
| 121 | + |
| 122 | +const stringify = fastJson({ |
| 123 | + title: 'Example Schema with string date-time field', |
| 124 | + type: 'string', |
| 125 | + format: 'date-time' |
| 126 | +} |
| 127 | + |
| 128 | +console.log(stringify(moment())) // '"YYYY-MM-DDTHH:mm:ss.sssZ"' |
| 129 | +``` |
| 130 | +
|
104 | 131 |
|
105 | 132 | <a name="required"></a>
|
106 | 133 | #### Required
|
@@ -214,6 +241,7 @@ console.log(stringify(obj)) // '{"matchfoo":"42","otherfoo":"str","matchnum":3,"
|
214 | 241 | If *additionalProperties* is not present or is set to `false`, every property that is not explicitly listed in the *properties* and *patternProperties* objects,will be ignored, as described in <a href="#missingFields">Missing fields</a>.
|
215 | 242 | Missing fields are ignored to avoid having to rewrite objects before serializing. However, other schema rules would throw in similar situations.
|
216 | 243 | If *additionalProperties* is set to `true`, it will be used by `JSON.stringify` to stringify the additional properties. If you want to achieve maximum performance, we strongly encourage you to use a fixed schema where possible.
|
| 244 | +The additional properties will always be serialzied at the end of the object. |
217 | 245 | Example:
|
218 | 246 | ```javascript
|
219 | 247 | const stringify = fastJson({
|
@@ -246,7 +274,7 @@ const obj = {
|
246 | 274 | nomatchint: 313
|
247 | 275 | }
|
248 | 276 |
|
249 |
| -console.log(stringify(obj)) // '{"matchfoo":"42","otherfoo":"str","matchnum":3,"nomatchstr":"valar morghulis",nomatchint:"313","nickname":"nick"}' |
| 277 | +console.log(stringify(obj)) // '{"nickname":"nick","matchfoo":"42","otherfoo":"str","matchnum":3,"nomatchstr":"valar morghulis",nomatchint:"313"}' |
250 | 278 | ```
|
251 | 279 |
|
252 | 280 | #### AnyOf
|
@@ -397,14 +425,65 @@ const externalSchema = {
|
397 | 425 | strings: require('./string-def.json')
|
398 | 426 | }
|
399 | 427 |
|
| 428 | +const stringify = fastJson(schema, { schema: externalSchema }) |
| 429 | +``` |
| 430 | +External definitions can also reference each other. |
| 431 | +Example: |
| 432 | +```javascript |
| 433 | +const schema = { |
| 434 | + title: 'Example Schema', |
| 435 | + type: 'object', |
| 436 | + properties: { |
| 437 | + foo: { |
| 438 | + $ref: 'strings#/definitions/foo' |
| 439 | + } |
| 440 | + } |
| 441 | +} |
| 442 | + |
| 443 | +const externalSchema = { |
| 444 | + strings: { |
| 445 | + definitions: { |
| 446 | + foo: { |
| 447 | + $ref: 'things#/definitions/foo' |
| 448 | + } |
| 449 | + } |
| 450 | + }, |
| 451 | + things: { |
| 452 | + definitions: { |
| 453 | + foo: { |
| 454 | + type: 'string' |
| 455 | + } |
| 456 | + } |
| 457 | + } |
| 458 | +} |
| 459 | + |
400 | 460 | const stringify = fastJson(schema, { schema: externalSchema })
|
401 | 461 | ```
|
402 | 462 |
|
403 | 463 | <a name="long"></a>
|
404 | 464 | #### Long integers
|
405 |
| -Long integers (64-bit) are supported using the [long](https://github.com/dcodeIO/long.js) module. |
| 465 | +By default the library will handle automatically [BigInt](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/BigInt) from Node.js v10.3 and above. |
| 466 | +If you can't use BigInts in your environment, long integers (64-bit) are also supported using the [long](https://github.com/dcodeIO/long.js) module. |
406 | 467 | Example:
|
407 | 468 | ```javascript
|
| 469 | +// => using native BigInt |
| 470 | +const stringify = fastJson({ |
| 471 | + title: 'Example Schema', |
| 472 | + type: 'object', |
| 473 | + properties: { |
| 474 | + id: { |
| 475 | + type: 'integer' |
| 476 | + } |
| 477 | + } |
| 478 | +}) |
| 479 | + |
| 480 | +const obj = { |
| 481 | + id: 18446744073709551615n |
| 482 | +} |
| 483 | + |
| 484 | +console.log(stringify(obj)) // '{"id":18446744073709551615}' |
| 485 | + |
| 486 | +// => using the long library |
408 | 487 | const Long = require('long')
|
409 | 488 |
|
410 | 489 | const stringify = fastJson({
|
@@ -470,6 +549,31 @@ allowing user input to directly supply a schema.
|
470 | 549 | It can't be guaranteed that allowing user input for the schema couldn't feasibly expose an attack
|
471 | 550 | vector.
|
472 | 551 |
|
| 552 | +<a name="debug"></a> |
| 553 | +### Debug Mode |
| 554 | +
|
| 555 | +The debug mode can be activated during your development to understand what is going on when things do not |
| 556 | +work as you expect. |
| 557 | +
|
| 558 | +```js |
| 559 | +const debugCompiled = fastJson({ |
| 560 | + title: 'default string', |
| 561 | + type: 'object', |
| 562 | + properties: { |
| 563 | + firstName: { |
| 564 | + type: 'string' |
| 565 | + } |
| 566 | + } |
| 567 | +}, { debugMode: true }) |
| 568 | + |
| 569 | +console.log(debugCompiled) // it is an array of functions that can create your `stringify` function |
| 570 | +console.log(debugCompiled.toString()) // print a "ready to read" string function, you can save it to a file |
| 571 | + |
| 572 | +const rawString = debugCompiled.toString() |
| 573 | +const stringify = fastJson.restore(rawString) // use the generated string to get back the `stringify` function |
| 574 | +console.log(stringify({ firstName: 'Foo', surname: 'bar' })) // '{"firstName":"Foo"}' |
| 575 | +``` |
| 576 | +
|
473 | 577 | <a name="acknowledgements"></a>
|
474 | 578 | ## Acknowledgements
|
475 | 579 |
|
|
0 commit comments