Skip to content

Commit 02c5374

Browse files
authored
30% faster startup and faster validation (#159)
1 parent e5cf898 commit 02c5374

File tree

4 files changed

+1799
-32
lines changed

4 files changed

+1799
-32
lines changed

build-schema-validator.js

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
'use strict'
2+
3+
const Ajv = require('ajv')
4+
const fs = require('fs')
5+
const path = require('path')
6+
const pack = require('ajv-pack')
7+
8+
const ajv = new Ajv({
9+
sourceCode: true // this option is required by ajv-pack
10+
})
11+
12+
const validate = ajv.compile(require('ajv/lib/refs/json-schema-draft-07.json'))
13+
14+
let moduleCode = `// This file is autogenerated by ${path.basename(__filename)}, do not edit
15+
16+
function nop () { return true }
17+
18+
${pack(ajv, validate).replace(/root\.refVal\[0\]/gm, 'nop')}
19+
`
20+
21+
fs.writeFileSync(path.join(__dirname, 'schema-validator.js'), moduleCode)

index.js

Lines changed: 22 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -2,22 +2,7 @@
22

33
var Ajv = require('ajv')
44
var merge = require('deepmerge')
5-
6-
// This Ajv instance is used to validate that the passed schema
7-
// is valid json schema. We reuse the instance to avoid having to
8-
// pay the ajv creation cost more than once.
9-
var ajv = new Ajv({
10-
// Ignore any unknown formats as they aren't used.
11-
unknownFormats: 'ignore',
12-
13-
// Ignoring unknown formats emits warnings, but we don't need to hear about
14-
// them.
15-
logger: {
16-
log: console.log,
17-
warn: function () {},
18-
error: console.error
19-
}
20-
})
5+
var validate = require('./schema-validator')
216

227
var uglify = null
238
var isLong
@@ -34,9 +19,29 @@ var addComma = `
3419
addComma = true
3520
`
3621

22+
function isValidSchema (schema, name) {
23+
if (!validate(schema)) {
24+
if (name) {
25+
name = `"${name}" `
26+
} else {
27+
name = ''
28+
}
29+
const first = validate.errors[0]
30+
const err = new Error(`${name}schema is invalid: data${first.dataPath} ${first.message}`)
31+
err.errors = isValidSchema.errors
32+
throw err
33+
}
34+
}
35+
3736
function build (schema, options) {
3837
options = options || {}
39-
isValidSchema(schema, options.schema)
38+
isValidSchema(schema)
39+
if (options.schema) {
40+
for (let key of Object.keys(options.schema)) {
41+
isValidSchema(options.schema[key], key)
42+
}
43+
}
44+
4045
/* eslint no-new-func: "off" */
4146
var code = `
4247
'use strict'
@@ -985,21 +990,6 @@ function loadUglify () {
985990
}
986991
}
987992

988-
function isValidSchema (schema, externalSchema) {
989-
if (externalSchema) {
990-
Object.keys(externalSchema).forEach(key => {
991-
try {
992-
ajv.addSchema(externalSchema[key], key)
993-
} catch (err) {
994-
err.message = '"' + key + '" ' + err.message
995-
throw err
996-
}
997-
})
998-
}
999-
ajv.compile(schema)
1000-
ajv.removeSchema()
1001-
}
1002-
1003993
function isEmpty (schema) {
1004994
for (var key in schema) {
1005995
if (schema.hasOwnProperty(key)) return false

package.json

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,7 @@
3131
},
3232
"homepage": "https://github.com/fastify/fast-json-stringify#readme",
3333
"devDependencies": {
34+
"ajv-pack": "^0.3.1",
3435
"benchmark": "^2.1.4",
3536
"is-my-json-valid": "^2.19.0",
3637
"long": "^4.0.0",
@@ -45,5 +46,10 @@
4546
"dependencies": {
4647
"ajv": "^6.8.1",
4748
"deepmerge": "^3.0.0"
49+
},
50+
"standard": {
51+
"ignore": [
52+
"schema-validator.js"
53+
]
4854
}
4955
}

0 commit comments

Comments
 (0)