@sourcemeta/blaze 14.20.2 → 15.0.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.
Files changed (4) hide show
  1. package/README.md +75 -4
  2. package/index.d.mts +5 -0
  3. package/index.mjs +428 -172
  4. package/package.json +1 -1
package/README.md CHANGED
@@ -18,10 +18,10 @@ npm install --save @sourcemeta/blaze
18
18
 
19
19
  ## Usage
20
20
 
21
- Blaze evaluates pre-compiled schema templates. Compile your JSON
22
- Schema using the
23
- [jsonschema](https://github.com/sourcemeta/jsonschema) CLI
24
- ([compile docs](https://github.com/sourcemeta/jsonschema/blob/main/docs/compile.markdown)):
21
+ Blaze evaluates pre-compiled schema templates. Compile your JSON Schema using
22
+ the [JSON Schema CLI](https://github.com/sourcemeta/jsonschema) (see the
23
+ [`compile`](https://github.com/sourcemeta/jsonschema/blob/main/docs/compile.markdown)
24
+ command):
25
25
 
26
26
  ```sh
27
27
  npm install --global @sourcemeta/jsonschema
@@ -67,3 +67,74 @@ const result = evaluator.validate(instance,
67
67
  });
68
68
  console.log(result); // true or false
69
69
  ```
70
+
71
+ ### Parsing large integers
72
+
73
+ JavaScript's
74
+ [`JSON.parse`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/JSON/parse)
75
+ silently truncates integers that exceed
76
+ [`Number.MAX_SAFE_INTEGER`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Number/MAX_SAFE_INTEGER)
77
+ to IEEE 754 double-precision floats. If your schemas or instances contain large
78
+ integers, pass `Blaze.reviver` to `JSON.parse` to preserve them as
79
+ [`BigInt`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/BigInt)
80
+ values. This relies on the
81
+ [`JSON.parse` source text
82
+ access](https://github.com/tc39/proposal-json-parse-with-source) proposal
83
+ (Stage 4, shipped in all major engines):
84
+
85
+ ```javascript
86
+ const template =
87
+ JSON.parse(readFileSync("template.json", "utf-8"), Blaze.reviver);
88
+ const evaluator = new Blaze(template);
89
+
90
+ const instance =
91
+ JSON.parse(readFileSync("instance.json", "utf-8"), Blaze.reviver);
92
+ console.log(evaluator.validate(instance));
93
+ ```
94
+
95
+ The evaluator handles `BigInt` values natively in all numeric instructions.
96
+ Without a reviver, large integers are silently truncated and validation may
97
+ produce incorrect results for affected values.
98
+
99
+ ## Why compile separately?
100
+
101
+ Unlike validators that compile and evaluate in a single step, Blaze separates
102
+ the two. You compile your schemas ahead of time using the [JSON Schema
103
+ CLI](https://github.com/sourcemeta/jsonschema) (`jsonschema compile
104
+ schema.json`) on CI or at build time.
105
+
106
+ The compilation step analyses the schema, resolves all references, and produces
107
+ a set of optimised low-level instructions serialised as JSON that every
108
+ evaluator can rely on. This evaluator package then executes those instructions
109
+ against your data, with no knowledge of JSON Schema itself.
110
+
111
+ - **Consistent validation across languages.** The same compiled schema produces
112
+ identical results whether evaluated in JavaScript, Python, Java, or C++ (we
113
+ are working hard increase the number of ports) so you never have to rely on
114
+ multiple implementations with different interpretations of the standard
115
+
116
+ - **No schema processing at startup.** The evaluator loads pre-compiled
117
+ instructions. There is no reference resolution, or vocabulary processing at
118
+ runtime
119
+
120
+ - **Schema governance.** Compiled schemas can be managed, versioned, and
121
+ distributed centrally via [Sourcemeta One](https://one.sourcemeta.com),
122
+ ensuring all consumers validate against the same compiled artifact
123
+
124
+ ## Limitations
125
+
126
+ **No arbitrary-precision real number support.** Large integers can be preserved
127
+ as `BigInt` using a reviver (see above), but JavaScript has no equivalent type
128
+ for arbitrary-precision real numbers. `JSON.parse` truncates values like
129
+ `0.1000000000000000000000000000000001` to IEEE 754 doubles, and there is no
130
+ reviver-based workaround:
131
+
132
+ ```
133
+ $ node --eval "console.log(JSON.parse('0.1000000000000000000000000000000001'))"
134
+ 0.1
135
+ ```
136
+
137
+ Numeric keywords like `multipleOf` that depend on exact decimal arithmetic may
138
+ produce incorrect results for real values that lose precision during parsing.
139
+ The TC39 [Decimal proposal](https://github.com/tc39/proposal-decimal) (Stage 2)
140
+ aims to address this in the future.
package/index.d.mts CHANGED
@@ -10,6 +10,11 @@ export type EvaluationCallback = (
10
10
  ) => void;
11
11
 
12
12
  export declare class Blaze {
13
+ static reviver(
14
+ key: string,
15
+ value: unknown,
16
+ context: { source: string }
17
+ ): unknown;
13
18
  constructor(template: Template);
14
19
  validate(instance: unknown, callback?: EvaluationCallback): boolean;
15
20
  }
package/index.mjs CHANGED
@@ -1,10 +1,10 @@
1
- const JSON_VERSION = 1;
1
+ const JSON_VERSION = 4;
2
2
  const DEPTH_LIMIT = 300;
3
- const ANNOTATION_EMIT = 44;
4
- const ANNOTATION_TO_PARENT = 45;
5
- const ANNOTATION_BASENAME_TO_PARENT = 46;
6
- const CONTROL_GROUP_START = 85;
7
- const CONTROL_EVALUATE_END = 89;
3
+ const ANNOTATION_EMIT = 49;
4
+ const ANNOTATION_TO_PARENT = 50;
5
+ const ANNOTATION_BASENAME_TO_PARENT = 51;
6
+ const CONTROL_GROUP_START = 92;
7
+ const CONTROL_EVALUATE_END = 96;
8
8
  const URI_REGEX = /^[a-zA-Z][a-zA-Z0-9+\-.]*:[^\s]*$/;
9
9
 
10
10
  function buildJsonPointer(tokens, length) {
@@ -33,6 +33,7 @@ function jsonTypeOf(value) {
33
33
  switch (typeof value) {
34
34
  case 'boolean': return Type.Boolean;
35
35
  case 'number': return Number.isInteger(value) ? Type.Integer : Type.Real;
36
+ case 'bigint': return Type.Integer;
36
37
  case 'string': return Type.String;
37
38
  case 'object': return Array.isArray(value) ? Type.Array : Type.Object;
38
39
  default: return Type.Null;
@@ -40,7 +41,8 @@ function jsonTypeOf(value) {
40
41
  }
41
42
 
42
43
  function isIntegral(value) {
43
- return typeof value === 'number' && Number.isFinite(value) && Math.floor(value) === value;
44
+ return typeof value === 'bigint' ||
45
+ (typeof value === 'number' && Number.isFinite(value) && Math.floor(value) === value);
44
46
  }
45
47
 
46
48
  function resolveInstance(instance, relativeInstanceLocation) {
@@ -150,7 +152,7 @@ function prepareInstruction(instruction) {
150
152
  function resolveJumpTargets(instructions, targets) {
151
153
  for (let index = 0; index < instructions.length; index++) {
152
154
  const instruction = instructions[index];
153
- if (instruction[0] === 91) {
155
+ if (instruction[0] === 98) {
154
156
  const targetIndex = instruction[5];
155
157
  if (targetIndex < targets.length) {
156
158
  instruction[5] = targets[targetIndex];
@@ -185,7 +187,7 @@ function collectAnchorNames(targets, result) {
185
187
  function collectAnchorNamesFromInstructions(instructions, result) {
186
188
  for (let index = 0; index < instructions.length; index++) {
187
189
  const instruction = instructions[index];
188
- if (instruction[0] === 90 && typeof instruction[5] === 'string') {
190
+ if (instruction[0] === 97 && typeof instruction[5] === 'string') {
189
191
  result.add(instruction[5]);
190
192
  }
191
193
  if (instruction[6]) {
@@ -250,7 +252,7 @@ function compileInstructionToCode(instruction, captures, visited, budget) {
250
252
  if (cr.length !== 0) return null;
251
253
  switch (op) {
252
254
  case 11: return '{if(_es(' + tv + ')!==' + cv + ')return false;}';
253
- case 38: return 'if(' + tv + '!=null&&typeof ' + tv + "==='object'&&!Array.isArray(" + tv + ')){' + emitResolve('t', tv, cr) + 'if(t!==void 0&&_es(t)!==' + cv + ')return false;}';
255
+ case 42: return 'if(' + tv + '!=null&&typeof ' + tv + "==='object'&&!Array.isArray(" + tv + ')){' + emitResolve('t', tv, cr) + 'if(t!==void 0&&_es(t)!==' + cv + ')return false;}';
254
256
  default: return null;
255
257
  }
256
258
  }
@@ -286,49 +288,52 @@ function compileInstructionToCode(instruction, captures, visited, budget) {
286
288
  case 25: { var r=R('t'); return r?r+TO+'return true;var s=0;for(var k in t)s++;return s>'+value+';':null; }
287
289
  case 26: { if(typeof value==='string'||typeof value==='number'||typeof value==='boolean'||value===null){var r=R('t');return r?r+'return t==='+JSON.stringify(value)+';':null;}return fb(26); }
288
290
  case 27: return fb(27); case 28: return fb(28);
289
- case 29: { var r=R('t'); return r?r+"if(typeof t!=='number')return true;return t>="+value+';':null; }
290
- case 30: { var r=R('t'); return r?r+"if(typeof t!=='number')return true;return t<="+value+';':null; }
291
- case 31: { var r=R('t'); return r?r+"if(typeof t!=='number')return true;return t>"+value+';':null; }
292
- case 32: { var r=R('t'); return r?r+"if(typeof t!=='number')return true;return t<"+value+';':null; }
293
- case 33: return fb(33); case 34: return fb(34); case 35: return fb(35);
294
- case 36: { var r=R('t'); return r?IO+r+'if(t===void 0)return true;var a=_jt(t);return a==='+value+'||('+value+'===2&&_ii(t));':null; }
295
- case 37: return fb(37);
296
- case 38: { var r=R('t'); return r?IO+r+'if(t===void 0)return true;return _es(t)==='+value+';':null; }
291
+ case 29: { var r=R('t'),v=typeof value==='bigint'?value+'n':value; return r?r+"var tt=typeof t;if(tt!=='number'&&tt!=='bigint')return true;return t>="+v+';':null; }
292
+ case 30: { var r=R('t'),v=typeof value==='bigint'?value+'n':value; return r?r+"var tt=typeof t;if(tt!=='number'&&tt!=='bigint')return true;return t<="+v+';':null; }
293
+ case 31: { var r=R('t'),v=typeof value==='bigint'?value+'n':value; return r?r+"var tt=typeof t;if(tt!=='number'&&tt!=='bigint')return true;return t>"+v+';':null; }
294
+ case 32: { var r=R('t'),v=typeof value==='bigint'?value+'n':value; return r?r+"var tt=typeof t;if(tt!=='number'&&tt!=='bigint')return true;return t<"+v+';':null; }
295
+ case 33: return fb(33); case 34: return fb(34);
296
+ case 35: return fb(35); case 36: return fb(36); case 37: return fb(37); case 38: return fb(38);
297
297
  case 39: return fb(39);
298
- case 40: { var r=R('t'); return r?IO+r+'if(t===void 0)return true;return('+value+'&(1<<_es(t)))!==0;':null; }
299
- case 41: return fb(41); case 42: return fb(42); case 43: return fb(43);
300
- case 44: return 'return true;'; case 45: return 'return true;'; case 46: return 'return true;'; case 47: return 'return true;';
301
- case 48: { var r=R('t'); if(!r)return null; if(!children||children.length===0)return 'return false;'; var c=r; for(var j=0;j<children.length;j++)c+='if(!'+cc(children[j],'t')+')return true;'; return c+'return false;'; }
302
- case 49: return fb(49);
303
- case 50: { var r=R('t'); if(!r)return null; if(!children||children.length===0)return 'return true;'; if(value){var c=r+'var __r=false;';for(var j=0;j<children.length;j++)c+='if('+cc(children[j],'t')+')__r=true;';return c+'return __r;';} var c=r;for(var j=0;j<children.length;j++)c+='if('+cc(children[j],'t')+')return true;';return c+'return false;'; }
304
- case 51: { var r=R('t'); if(!r)return null; if(!children||children.length===0)return 'return true;'; return r+seq(children,'t')+'return true;'; }
305
- case 52: { var r=R('t'); if(!r)return null; if(!children||children.length===0)return 'return false;'; var c=r+'var __r=true,__m=false;';for(var j=0;j<children.length;j++){c+='if('+cc(children[j],'t')+'){if(__m){__r=false;'+(!value?'return false;':'')+ '}else __m=true;}';}return c+'return __r&&__m;'; }
306
- case 53: return fb(53);
307
- case 54: { var r=R('t'); if(!r)return null; var c=r+'if(_jt(t)!=='+value+')return true;'; if(children&&children.length>0)c+=seq(children,'t'); return c+'return true;'; }
308
- case 55: { var r=R('t'); if(!r)return null; var c=r+TO+'return true;if(!Object.hasOwn(t,'+JSON.stringify(value)+'))return true;'; if(children&&children.length>0)c+=seq(children,'t'); return c+'return true;'; }
309
- case 56: { var r=R('t'); if(!r)return null; var c=r+'if(!Array.isArray(t)||t.length<='+value+')return true;'; if(children&&children.length>0)c+=seq(children,'t'); return c+'return true;'; }
310
- case 57: return fb(57); case 58: return fb(58);
311
- case 59: { var r=R('t'); if(!r)return null; if(!children||children.length===0)return r+'return true;'; var mi=captures.length; captures.push(value); var gf=''; for(var gi=0;gi<children.length;gi++){var gc=children[gi][6]; if(gc&&gc.length>0){gf+='function(i,d,_t,_v){'+lb(gc,'i')+'return true;},';}else{gf+='null,';}} return r+TO+'return true;var __cg=['+gf+'];for(var k in t){var __mi=_c['+mi+'][k];if(__mi!==void 0){var __cf=__cg[__mi];if(__cf&&!__cf(t,d,_t,_v))return false;}}return true;'; }
312
- case 60: { var r=R('t'); if(!r)return null; if(!children||children.length===0)return r+'return true;'; var mi=captures.length; captures.push(value); var gf=''; for(var gi=0;gi<children.length;gi++){var gc=children[gi][6]; if(gc&&gc.length>0){gf+='function(i,d,_t,_v){'+lb(gc,'i')+'return true;},';}else{gf+='null,';}} return r+TO+'return true;var __cg=['+gf+'];for(var k in t){var __mi=_c['+mi+'][k];if(__mi===void 0)return false;var __cf=__cg[__mi];if(__cf&&!__cf(t,d,_t,_v))return false;}return true;'; }
313
- case 61: { var r=R('t'); if(!r)return null; if(!children||children.length===0)return r+'return true;'; return r+TO+'return true;for(var k in t){'+lb(children,'t[k]')+'}return true;'; }
314
- case 62: return fb(62); case 63: return fb(63); case 64: return fb(64); case 65: return fb(65); case 66: return fb(66);
315
- case 67: return fb(67); case 68: return fb(68); case 69: return fb(69); case 70: return fb(70);
316
- case 71: { var r=R('t'); return r?r+TO+'return true;for(var k in t){if(_es(t[k])!=='+value+')return false;}return true;':null; }
298
+ case 40: { var r=R('t'); return r?IO+r+'if(t===void 0)return true;var a=_jt(t);return a==='+value+'||('+value+'===2&&_ii(t));':null; }
299
+ case 41: return fb(41);
300
+ case 42: { var r=R('t'); return r?IO+r+'if(t===void 0)return true;return _es(t)==='+value+';':null; }
301
+ case 43: return fb(43);
302
+ case 44: { var r=R('t'); return r?IO+r+'if(t===void 0)return true;return('+value+'&(1<<_es(t)))!==0;':null; }
303
+ case 45: return fb(45); case 46: return fb(46); case 47: return fb(47);
304
+ case 48: return fb(48);
305
+ case 49: return 'return true;'; case 50: return 'return true;'; case 51: return 'return true;'; case 52: return 'return true;';
306
+ case 53: { var r=R('t'); if(!r)return null; if(!children||children.length===0)return 'return false;'; var c=r; for(var j=0;j<children.length;j++)c+='if(!'+cc(children[j],'t')+')return true;'; return c+'return false;'; }
307
+ case 54: return fb(54);
308
+ case 55: { var r=R('t'); if(!r)return null; if(!children||children.length===0)return 'return true;'; if(value){var c=r+'var __r=false;';for(var j=0;j<children.length;j++)c+='if('+cc(children[j],'t')+')__r=true;';return c+'return __r;';} var c=r;for(var j=0;j<children.length;j++)c+='if('+cc(children[j],'t')+')return true;';return c+'return false;'; }
309
+ case 56: { var r=R('t'); if(!r)return null; if(!children||children.length===0)return 'return true;'; return r+seq(children,'t')+'return true;'; }
310
+ case 57: { var r=R('t'); if(!r)return null; if(!children||children.length===0)return 'return false;'; var c=r+'var __r=true,__m=false;';for(var j=0;j<children.length;j++){c+='if('+cc(children[j],'t')+'){if(__m){__r=false;'+(!value?'return false;':'')+ '}else __m=true;}';}return c+'return __r&&__m;'; }
311
+ case 58: return fb(58);
312
+ case 59: { var r=R('t'); if(!r)return null; var c=r+'if(_jt(t)!=='+value+')return true;'; if(children&&children.length>0)c+=seq(children,'t'); return c+'return true;'; }
313
+ case 60: { var r=R('t'); if(!r)return null; var c=r+TO+'return true;if(!Object.hasOwn(t,'+JSON.stringify(value)+'))return true;'; if(children&&children.length>0)c+=seq(children,'t'); return c+'return true;'; }
314
+ case 61: { var r=R('t'); if(!r)return null; var c=r+'if(!Array.isArray(t)||t.length<='+value+')return true;'; if(children&&children.length>0)c+=seq(children,'t'); return c+'return true;'; }
315
+ case 62: return fb(62); case 63: return fb(63);
316
+ case 64: { var r=R('t'); if(!r)return null; if(!children||children.length===0)return r+'return true;'; var mi=captures.length; captures.push(value); var gf=''; for(var gi=0;gi<children.length;gi++){var gc=children[gi][6]; if(gc&&gc.length>0){gf+='function(i,d,_t,_v){'+lb(gc,'i')+'return true;},';}else{gf+='null,';}} return r+TO+'return true;var __cg=['+gf+'];for(var k in t){var __mi=_c['+mi+'][k];if(__mi!==void 0){var __cf=__cg[__mi];if(__cf&&!__cf(t,d,_t,_v))return false;}}return true;'; }
317
+ case 65: { var r=R('t'); if(!r)return null; if(!children||children.length===0)return r+'return true;'; var mi=captures.length; captures.push(value); var gf=''; for(var gi=0;gi<children.length;gi++){var gc=children[gi][6]; if(gc&&gc.length>0){gf+='function(i,d,_t,_v){'+lb(gc,'i')+'return true;},';}else{gf+='null,';}} return r+TO+'return true;var __cg=['+gf+'];for(var k in t){var __mi=_c['+mi+'][k];if(__mi===void 0)return false;var __cf=__cg[__mi];if(__cf&&!__cf(t,d,_t,_v))return false;}return true;'; }
318
+ case 66: { var r=R('t'); if(!r)return null; if(!children||children.length===0)return r+'return true;'; return r+TO+'return true;for(var k in t){'+lb(children,'t[k]')+'}return true;'; }
319
+ case 67: return fb(67); case 68: return fb(68); case 69: return fb(69); case 70: return fb(70); case 71: return fb(71);
317
320
  case 72: return fb(72); case 73: return fb(73); case 74: return fb(74); case 75: return fb(75);
318
- case 76: { var r=R('t'); if(!r)return null; if(!children||children.length===0)return r+'return true;'; return r+'if(!Array.isArray(t))return true;for(var j=0;j<t.length;j++){'+lb(children,'t[j]')+'}return true;'; }
319
- case 77: { var r=R('t'); if(!r)return null; if(!children||children.length===0)return r+'return true;'; return r+'if(!Array.isArray(t)||'+value+'>=t.length)return true;for(var j='+value+';j<t.length;j++){'+lb(children,'t[j]')+'}return true;'; }
320
- case 78: return fb(78);
321
- case 79: { var r=R('t'); return r?r+'if(!Array.isArray(t))return true;for(var j=0;j<t.length;j++){var a=_jt(t[j]);if(a!=='+value+'&&!('+value+'===2&&_ii(t[j])))return false;}return true;':null; }
322
- case 80: { var r=R('t'); return r?r+'if(!Array.isArray(t))return true;for(var j=0;j<t.length;j++){if(_es(t[j])!=='+value+')return false;}return true;':null; }
323
- case 81: { var r=R('t'); return r?r+'if(!Array.isArray(t))return true;for(var j=0;j<t.length;j++){if(('+value+'&(1<<_es(t[j])))===0)return false;}return true;':null; }
324
- case 82: return fb(82); case 83: return fb(83); case 84: return fb(84);
325
- case 85: { if(!children||children.length===0)return 'return true;'; var c=''; for(var j=0;j<children.length;j++){var r2=compileInstructionToCode(children[j],captures,visited,budget); if(r2===null){var ci=captures.length;captures.push(children[j]);c+='if(!_e(_c['+ci+'],i,d+1,_t,_v))return false;';}else{budget[0]-=r2.length;c+='if(!(function(i,d,_t,_v){'+r2+'})(i,d+1,_t,_v))return false;';}} return c+'return true;'; }
326
- case 86: { var r=R('t'); if(!r)return null; var c=r+TO+'return true;if(!Object.hasOwn(t,'+JSON.stringify(value)+'))return true;'; if(children&&children.length>0)c+=seq(children,'i'); return c+'return true;'; }
327
- case 87: { var c=IO+'if(!Object.hasOwn(i,'+JSON.stringify(value)+'))return true;'; if(children&&children.length>0)c+=seq(children,'i'); return c+'return true;'; }
328
- case 88: { var c='if(_jt(i)!=='+value+')return true;'; if(children&&children.length>0)c+=seq(children,'i'); return c+'return true;'; }
329
- case 89: return 'return true;';
330
- case 90: return fb(90);
331
- case 91: { if(!value)return 'return true;'; if(visited&&visited.has(instruction))return fb(91); if(!visited)visited=new Set(); visited.add(instruction); var r=R('t'); if(!r)return fb(91); var c=r; for(var j=0;j<value.length;j++){var r2=compileInstructionToCode(value[j],captures,visited,budget); if(r2===null){var ci=captures.length;captures.push(value[j]);c+='if(!_e(_c['+ci+'],t,d+1,_t,_v))return false;';}else{budget[0]-=r2.length;c+='if(!(function(i,d,_t,_v){'+r2+'})(t,d+1,_t,_v))return false;';}} return c+'return true;'; }
321
+ case 76: { var r=R('t'); return r?r+TO+'return true;for(var k in t){if(_es(t[k])!=='+value+')return false;}return true;':null; }
322
+ case 77: return fb(77); case 78: return fb(78); case 79: return fb(79); case 80: return fb(80);
323
+ case 81: { var r=R('t'); if(!r)return null; if(!children||children.length===0)return r+'return true;'; return r+'if(!Array.isArray(t))return true;for(var j=0;j<t.length;j++){'+lb(children,'t[j]')+'}return true;'; }
324
+ case 82: { var r=R('t'); if(!r)return null; if(!children||children.length===0)return r+'return true;'; return r+'if(!Array.isArray(t)||'+value+'>=t.length)return true;for(var j='+value+';j<t.length;j++){'+lb(children,'t[j]')+'}return true;'; }
325
+ case 83: return fb(83);
326
+ case 84: { var r=R('t'); return r?r+'if(!Array.isArray(t))return true;for(var j=0;j<t.length;j++){var a=_jt(t[j]);if(a!=='+value+'&&!('+value+'===2&&_ii(t[j])))return false;}return true;':null; }
327
+ case 85: { var r=R('t'); return r?r+'if(!Array.isArray(t))return true;for(var j=0;j<t.length;j++){if(_es(t[j])!=='+value+')return false;}return true;':null; }
328
+ case 86: { var r=R('t'); return r?r+'if(!Array.isArray(t))return true;for(var j=0;j<t.length;j++){if(('+value+'&(1<<_es(t[j])))===0)return false;}return true;':null; }
329
+ case 87: return fb(87); case 88: return fb(88); case 89: return fb(89); case 90: return fb(90); case 91: return fb(91);
330
+ case 92: { if(!children||children.length===0)return 'return true;'; var c=''; for(var j=0;j<children.length;j++){var r2=compileInstructionToCode(children[j],captures,visited,budget); if(r2===null){var ci=captures.length;captures.push(children[j]);c+='if(!_e(_c['+ci+'],i,d+1,_t,_v))return false;';}else{budget[0]-=r2.length;c+='if(!(function(i,d,_t,_v){'+r2+'})(i,d+1,_t,_v))return false;';}} return c+'return true;'; }
331
+ case 93: { var r=R('t'); if(!r)return null; var c=r+TO+'return true;if(!Object.hasOwn(t,'+JSON.stringify(value)+'))return true;'; if(children&&children.length>0)c+=seq(children,'i'); return c+'return true;'; }
332
+ case 94: { var c=IO+'if(!Object.hasOwn(i,'+JSON.stringify(value)+'))return true;'; if(children&&children.length>0)c+=seq(children,'i'); return c+'return true;'; }
333
+ case 95: { var c='if(_jt(i)!=='+value+')return true;'; if(children&&children.length>0)c+=seq(children,'i'); return c+'return true;'; }
334
+ case 96: return 'return true;';
335
+ case 97: return fb(97);
336
+ case 98: { if(!value)return 'return true;'; if(visited&&visited.has(instruction))return fb(98); if(!visited)visited=new Set(); visited.add(instruction); var r=R('t'); if(!r)return fb(98); var c=r; for(var j=0;j<value.length;j++){var r2=compileInstructionToCode(value[j],captures,visited,budget); if(r2===null){var ci=captures.length;captures.push(value[j]);c+='if(!_e(_c['+ci+'],t,d+1,_t,_v))return false;';}else{budget[0]-=r2.length;c+='if(!(function(i,d,_t,_v){'+r2+'})(t,d+1,_t,_v))return false;';}} return c+'return true;'; }
332
337
  default: return null;
333
338
  }
334
339
  }
@@ -366,7 +371,35 @@ function generateNativeValidator(template) {
366
371
  }
367
372
  }
368
373
 
374
+ function sourceToBigInt(source) {
375
+ // Plain integer like "99999999999999999999999999999999999"
376
+ if (/^-?[0-9]+$/.test(source)) return BigInt(source);
377
+ // Exponential notation like "9.9999999999999999e+34". Parse the coefficient
378
+ // and exponent to reconstruct the exact integer, as `BigInt` cannot parse
379
+ // exponential notation directly
380
+ const match = source.match(/^(-?)([0-9]+)\.?([0-9]*)[eE][+]?([0-9]+)$/);
381
+ if (!match) return null;
382
+ const exponent = parseInt(match[4]) - match[3].length;
383
+ if (exponent < 0) return null;
384
+ return BigInt(match[1] + match[2] + match[3]) * (10n ** BigInt(exponent));
385
+ }
386
+
387
+ function reviver(_key, value, context) {
388
+ // On older engines, `JSON.parse` calls the reviver with only two arguments
389
+ if (context === undefined) return value;
390
+ if (typeof value !== 'number') return value;
391
+ const source = context.source;
392
+ // Only convert when `JSON.parse` actually truncated the value, avoiding
393
+ // unnecessary `BigInt` conversion for integers that are exactly
394
+ // representable as doubles
395
+ if (String(value) === source) return value;
396
+ const bigint = sourceToBigInt(source);
397
+ return bigint !== null ? bigint : value;
398
+ }
399
+
369
400
  class Blaze {
401
+ static reviver = reviver;
402
+
370
403
  constructor(template) {
371
404
  if (!Array.isArray(template) || template[0] !== JSON_VERSION) {
372
405
  throw new Error(
@@ -623,7 +656,7 @@ function evaluateInstructionTracked(instruction, instance, depth, template, eval
623
656
  if (!handler) return true;
624
657
 
625
658
  const type = instruction[0];
626
- if (type < 85 || type > 89) {
659
+ if (type < 92 || type > 96) {
627
660
  if (evaluator.trackMode) {
628
661
  evaluator.pushPath(instruction[1]);
629
662
  }
@@ -691,6 +724,7 @@ function effectiveTypeStrictReal(value) {
691
724
  switch (typeof value) {
692
725
  case 'boolean': return Type.Boolean;
693
726
  case 'number': return Number.isInteger(value) ? Type.Integer : Type.Real;
727
+ case 'bigint': return Type.Integer;
694
728
  case 'string': return Type.String;
695
729
  case 'object': return Array.isArray(value) ? Type.Array : Type.Object;
696
730
  default: return Type.Null;
@@ -730,6 +764,7 @@ function fastHash(value) {
730
764
  switch (typeof value) {
731
765
  case 'boolean': return value ? 1 : 0;
732
766
  case 'number': return 4 + ((value | 0) & 255);
767
+ case 'bigint': return 4 + Number(value & 255n);
733
768
  case 'string': return 3 + value.length;
734
769
  case 'object':
735
770
  if (Array.isArray(value)) {
@@ -782,7 +817,15 @@ function isUnique(array) {
782
817
  }
783
818
 
784
819
  function isDivisibleBy(value, divisor) {
785
- if (divisor === 0) return false;
820
+ if (divisor === 0 || divisor === 0n) return false;
821
+ if (typeof value === 'bigint' && typeof divisor === 'bigint') {
822
+ return value % divisor === 0n;
823
+ }
824
+ if (typeof value === 'bigint') {
825
+ value = Number(value);
826
+ } else if (typeof divisor === 'bigint') {
827
+ divisor = Number(divisor);
828
+ }
786
829
  const remainder = value % divisor;
787
830
  if (remainder === 0) return true;
788
831
  return Math.abs(remainder) < 1e-9 || Math.abs(remainder - divisor) < 1e-9 ||
@@ -1231,7 +1274,8 @@ function AssertionEqualsAnyStringHash(instruction, instance, depth, template, ev
1231
1274
 
1232
1275
  function AssertionGreaterEqual(instruction, instance, depth, template, evaluator) {
1233
1276
  const target = resolveInstance(instance, instruction[2]);
1234
- if (typeof target !== 'number') return true;
1277
+ const targetType = typeof target;
1278
+ if (targetType !== 'number' && targetType !== 'bigint') return true;
1235
1279
  if (evaluator.callbackMode) evaluator.callbackPush(instruction);
1236
1280
  const __result = target >= instruction[5];
1237
1281
  if (evaluator.callbackMode) evaluator.callbackPop(instruction, __result);
@@ -1240,7 +1284,8 @@ function AssertionGreaterEqual(instruction, instance, depth, template, evaluator
1240
1284
 
1241
1285
  function AssertionLessEqual(instruction, instance, depth, template, evaluator) {
1242
1286
  const target = resolveInstance(instance, instruction[2]);
1243
- if (typeof target !== 'number') return true;
1287
+ const targetType = typeof target;
1288
+ if (targetType !== 'number' && targetType !== 'bigint') return true;
1244
1289
  if (evaluator.callbackMode) evaluator.callbackPush(instruction);
1245
1290
  const __result = target <= instruction[5];
1246
1291
  if (evaluator.callbackMode) evaluator.callbackPop(instruction, __result);
@@ -1249,7 +1294,8 @@ function AssertionLessEqual(instruction, instance, depth, template, evaluator) {
1249
1294
 
1250
1295
  function AssertionGreater(instruction, instance, depth, template, evaluator) {
1251
1296
  const target = resolveInstance(instance, instruction[2]);
1252
- if (typeof target !== 'number') return true;
1297
+ const targetType = typeof target;
1298
+ if (targetType !== 'number' && targetType !== 'bigint') return true;
1253
1299
  if (evaluator.callbackMode) evaluator.callbackPush(instruction);
1254
1300
  const __result = target > instruction[5];
1255
1301
  if (evaluator.callbackMode) evaluator.callbackPop(instruction, __result);
@@ -1258,7 +1304,8 @@ function AssertionGreater(instruction, instance, depth, template, evaluator) {
1258
1304
 
1259
1305
  function AssertionLess(instruction, instance, depth, template, evaluator) {
1260
1306
  const target = resolveInstance(instance, instruction[2]);
1261
- if (typeof target !== 'number') return true;
1307
+ const targetType = typeof target;
1308
+ if (targetType !== 'number' && targetType !== 'bigint') return true;
1262
1309
  if (evaluator.callbackMode) evaluator.callbackPush(instruction);
1263
1310
  const __result = target < instruction[5];
1264
1311
  if (evaluator.callbackMode) evaluator.callbackPop(instruction, __result);
@@ -1276,13 +1323,50 @@ function AssertionUnique(instruction, instance, depth, template, evaluator) {
1276
1323
 
1277
1324
  function AssertionDivisible(instruction, instance, depth, template, evaluator) {
1278
1325
  const target = resolveInstance(instance, instruction[2]);
1279
- if (typeof target !== 'number') return true;
1326
+ const targetType = typeof target;
1327
+ if (targetType !== 'number' && targetType !== 'bigint') return true;
1280
1328
  if (evaluator.callbackMode) evaluator.callbackPush(instruction);
1281
1329
  const __result = isDivisibleBy(target, instruction[5]);
1282
1330
  if (evaluator.callbackMode) evaluator.callbackPop(instruction, __result);
1283
1331
  return __result;
1284
1332
  };
1285
1333
 
1334
+ function AssertionTypeIntegerBounded(instruction, instance, depth, template, evaluator) {
1335
+ const target = resolveInstance(instance, instruction[2]);
1336
+ if (evaluator.callbackMode) evaluator.callbackPush(instruction);
1337
+ const range = instruction[5];
1338
+ const __result = (typeof target === 'bigint' || Number.isInteger(target)) && target >= range[0] && target <= range[1];
1339
+ if (evaluator.callbackMode) evaluator.callbackPop(instruction, __result);
1340
+ return __result;
1341
+ };
1342
+
1343
+ function AssertionTypeIntegerBoundedStrict(instruction, instance, depth, template, evaluator) {
1344
+ const target = resolveInstance(instance, instruction[2]);
1345
+ if (evaluator.callbackMode) evaluator.callbackPush(instruction);
1346
+ const range = instruction[5];
1347
+ const __result = (typeof target === 'bigint' || Number.isInteger(target)) && target >= range[0] && target <= range[1];
1348
+ if (evaluator.callbackMode) evaluator.callbackPop(instruction, __result);
1349
+ return __result;
1350
+ };
1351
+
1352
+ function AssertionTypeIntegerLowerBound(instruction, instance, depth, template, evaluator) {
1353
+ const target = resolveInstance(instance, instruction[2]);
1354
+ if (evaluator.callbackMode) evaluator.callbackPush(instruction);
1355
+ const range = instruction[5];
1356
+ const __result = (typeof target === 'bigint' || Number.isInteger(target)) && target >= range[0];
1357
+ if (evaluator.callbackMode) evaluator.callbackPop(instruction, __result);
1358
+ return __result;
1359
+ };
1360
+
1361
+ function AssertionTypeIntegerLowerBoundStrict(instruction, instance, depth, template, evaluator) {
1362
+ const target = resolveInstance(instance, instruction[2]);
1363
+ if (evaluator.callbackMode) evaluator.callbackPush(instruction);
1364
+ const range = instruction[5];
1365
+ const __result = (typeof target === 'bigint' || Number.isInteger(target)) && target >= range[0];
1366
+ if (evaluator.callbackMode) evaluator.callbackPop(instruction, __result);
1367
+ return __result;
1368
+ };
1369
+
1286
1370
  function AssertionStringType(instruction, instance, depth, template, evaluator) {
1287
1371
  const target = evaluator.propertyTarget !== undefined
1288
1372
  ? evaluator.propertyTarget : resolveInstance(instance, instruction[2]);
@@ -1428,6 +1512,37 @@ function AssertionArrayPrefixEvaluate(instruction, instance, depth, template, ev
1428
1512
  return true;
1429
1513
  };
1430
1514
 
1515
+ function AssertionObjectPropertiesSimple(instruction, instance, depth, template, evaluator) {
1516
+ const target = resolveInstance(instance, instruction[2]);
1517
+ if (evaluator.callbackMode) evaluator.callbackPush(instruction);
1518
+ if (!isObject(target)) {
1519
+ if (evaluator.callbackMode) evaluator.callbackPop(instruction, false);
1520
+ return false;
1521
+ }
1522
+ const value = instruction[5];
1523
+ const children = instruction[6];
1524
+ for (let index = 0; index < value.length; index++) {
1525
+ const entry = value[index];
1526
+ const name = entry[0];
1527
+ const required = entry[2];
1528
+ if (!Object.hasOwn(target, name)) {
1529
+ if (required) {
1530
+ if (evaluator.callbackMode) evaluator.callbackPop(instruction, false);
1531
+ return false;
1532
+ }
1533
+ continue;
1534
+ }
1535
+ if (index < children.length) {
1536
+ if (!evaluateInstructionFast(children[index], target[name], depth + 1, template, evaluator)) {
1537
+ if (evaluator.callbackMode) evaluator.callbackPop(instruction, false);
1538
+ return false;
1539
+ }
1540
+ }
1541
+ }
1542
+ if (evaluator.callbackMode) evaluator.callbackPop(instruction, true);
1543
+ return true;
1544
+ };
1545
+
1431
1546
  function AnnotationEmit(instruction, instance, depth, template, evaluator) {
1432
1547
  if (evaluator.callbackMode) evaluator.callbackAnnotation(instruction);
1433
1548
  return true;
@@ -2288,6 +2403,56 @@ function LoopItemsPropertiesExactlyTypeStrictHash(instruction, instance, depth,
2288
2403
  if (evaluator.callbackMode) evaluator.callbackPop(instruction, true);
2289
2404
  return true;
2290
2405
  };
2406
+
2407
+ function LoopItemsIntegerBounded(instruction, instance, depth, template, evaluator) {
2408
+ const target = resolveInstance(instance, instruction[2]);
2409
+ if (!Array.isArray(target) || target.length === 0) return true;
2410
+ if (evaluator.callbackMode) evaluator.callbackPush(instruction);
2411
+ const minimum = instruction[5][0];
2412
+ const maximum = instruction[5][1];
2413
+ for (let index = 0; index < target.length; index++) {
2414
+ const element = target[index];
2415
+ const elementType = typeof element;
2416
+ if (elementType !== 'number' && elementType !== 'bigint') {
2417
+ if (evaluator.callbackMode) evaluator.callbackPop(instruction, false);
2418
+ return false;
2419
+ }
2420
+ if (element < minimum || element > maximum) {
2421
+ if (evaluator.callbackMode) evaluator.callbackPop(instruction, false);
2422
+ return false;
2423
+ }
2424
+ }
2425
+ if (evaluator.callbackMode) evaluator.callbackPop(instruction, true);
2426
+ return true;
2427
+ };
2428
+
2429
+ function LoopItemsIntegerBoundedSized(instruction, instance, depth, template, evaluator) {
2430
+ const value = instruction[5];
2431
+ const minimum = value[0][0];
2432
+ const maximum = value[0][1];
2433
+ const minimumSize = value[1][0];
2434
+ const target = resolveInstance(instance, instruction[2]);
2435
+ if (evaluator.callbackMode) evaluator.callbackPush(instruction);
2436
+ if (!Array.isArray(target) || target.length < minimumSize) {
2437
+ if (evaluator.callbackMode) evaluator.callbackPop(instruction, false);
2438
+ return false;
2439
+ }
2440
+ for (let index = 0; index < target.length; index++) {
2441
+ const element = target[index];
2442
+ const elementType = typeof element;
2443
+ if (elementType !== 'number' && elementType !== 'bigint') {
2444
+ if (evaluator.callbackMode) evaluator.callbackPop(instruction, false);
2445
+ return false;
2446
+ }
2447
+ if (element < minimum || element > maximum) {
2448
+ if (evaluator.callbackMode) evaluator.callbackPop(instruction, false);
2449
+ return false;
2450
+ }
2451
+ }
2452
+ if (evaluator.callbackMode) evaluator.callbackPop(instruction, true);
2453
+ return true;
2454
+ };
2455
+
2291
2456
  function LoopContains(instruction, instance, depth, template, evaluator) {
2292
2457
  const target = resolveInstance(instance, instruction[2]);
2293
2458
  if (!Array.isArray(target)) return true;
@@ -2467,63 +2632,70 @@ const handlers = [
2467
2632
  AssertionLess, // 32
2468
2633
  AssertionUnique, // 33
2469
2634
  AssertionDivisible, // 34
2470
- AssertionStringType, // 35
2471
- AssertionPropertyType, // 36
2472
- AssertionPropertyTypeEvaluate, // 37
2473
- AssertionPropertyTypeStrict, // 38
2474
- AssertionPropertyTypeStrictEvaluate, // 39
2475
- AssertionPropertyTypeStrictAny, // 40
2476
- AssertionPropertyTypeStrictAnyEvaluate, // 41
2477
- AssertionArrayPrefix, // 42
2478
- AssertionArrayPrefixEvaluate, // 43
2479
- AnnotationEmit, // 44
2480
- AnnotationToParent, // 45
2481
- AnnotationBasenameToParent, // 46
2482
- Evaluate, // 47
2483
- LogicalNot, // 48
2484
- LogicalNotEvaluate, // 49
2485
- LogicalOr, // 50
2486
- LogicalAnd, // 51
2487
- LogicalXor, // 52
2488
- LogicalCondition, // 53
2489
- LogicalWhenType, // 54
2490
- LogicalWhenDefines, // 55
2491
- LogicalWhenArraySizeGreater, // 56
2492
- LoopPropertiesUnevaluated, // 57
2493
- LoopPropertiesUnevaluatedExcept, // 58
2494
- LoopPropertiesMatch, // 59
2495
- LoopPropertiesMatchClosed, // 60
2496
- LoopProperties, // 61
2497
- LoopPropertiesEvaluate, // 62
2498
- LoopPropertiesRegex, // 63
2499
- LoopPropertiesRegexClosed, // 64
2500
- LoopPropertiesStartsWith, // 65
2501
- LoopPropertiesExcept, // 66
2502
- LoopPropertiesType, // 67
2503
- LoopPropertiesTypeEvaluate, // 68
2504
- LoopPropertiesExactlyTypeStrict, // 69
2505
- LoopPropertiesExactlyTypeStrictHash, // 70
2506
- LoopPropertiesTypeStrict, // 71
2507
- LoopPropertiesTypeStrictEvaluate, // 72
2508
- LoopPropertiesTypeStrictAny, // 73
2509
- LoopPropertiesTypeStrictAnyEvaluate, // 74
2510
- LoopKeys, // 75
2511
- LoopItems, // 76
2512
- LoopItemsFrom, // 77
2513
- LoopItemsUnevaluated, // 78
2514
- LoopItemsType, // 79
2515
- LoopItemsTypeStrict, // 80
2516
- LoopItemsTypeStrictAny, // 81
2517
- LoopItemsPropertiesExactlyTypeStrictHash, // 82
2518
- LoopItemsPropertiesExactlyTypeStrictHash, // 83
2519
- LoopContains, // 84
2520
- ControlGroup, // 85
2521
- ControlGroupWhenDefines, // 86
2522
- ControlGroupWhenDefinesDirect, // 87
2523
- ControlGroupWhenType, // 88
2524
- ControlEvaluate, // 89
2525
- ControlDynamicAnchorJump, // 90
2526
- ControlJump // 91
2635
+ AssertionTypeIntegerBounded, // 35
2636
+ AssertionTypeIntegerBoundedStrict, // 36
2637
+ AssertionTypeIntegerLowerBound, // 37
2638
+ AssertionTypeIntegerLowerBoundStrict, // 38
2639
+ AssertionStringType, // 39
2640
+ AssertionPropertyType, // 40
2641
+ AssertionPropertyTypeEvaluate, // 41
2642
+ AssertionPropertyTypeStrict, // 42
2643
+ AssertionPropertyTypeStrictEvaluate, // 43
2644
+ AssertionPropertyTypeStrictAny, // 44
2645
+ AssertionPropertyTypeStrictAnyEvaluate, // 45
2646
+ AssertionArrayPrefix, // 46
2647
+ AssertionArrayPrefixEvaluate, // 47
2648
+ AssertionObjectPropertiesSimple, // 48
2649
+ AnnotationEmit, // 49
2650
+ AnnotationToParent, // 50
2651
+ AnnotationBasenameToParent, // 51
2652
+ Evaluate, // 52
2653
+ LogicalNot, // 53
2654
+ LogicalNotEvaluate, // 54
2655
+ LogicalOr, // 55
2656
+ LogicalAnd, // 56
2657
+ LogicalXor, // 57
2658
+ LogicalCondition, // 58
2659
+ LogicalWhenType, // 59
2660
+ LogicalWhenDefines, // 60
2661
+ LogicalWhenArraySizeGreater, // 61
2662
+ LoopPropertiesUnevaluated, // 62
2663
+ LoopPropertiesUnevaluatedExcept, // 63
2664
+ LoopPropertiesMatch, // 64
2665
+ LoopPropertiesMatchClosed, // 65
2666
+ LoopProperties, // 66
2667
+ LoopPropertiesEvaluate, // 67
2668
+ LoopPropertiesRegex, // 68
2669
+ LoopPropertiesRegexClosed, // 69
2670
+ LoopPropertiesStartsWith, // 70
2671
+ LoopPropertiesExcept, // 71
2672
+ LoopPropertiesType, // 72
2673
+ LoopPropertiesTypeEvaluate, // 73
2674
+ LoopPropertiesExactlyTypeStrict, // 74
2675
+ LoopPropertiesExactlyTypeStrictHash, // 75
2676
+ LoopPropertiesTypeStrict, // 76
2677
+ LoopPropertiesTypeStrictEvaluate, // 77
2678
+ LoopPropertiesTypeStrictAny, // 78
2679
+ LoopPropertiesTypeStrictAnyEvaluate, // 79
2680
+ LoopKeys, // 80
2681
+ LoopItems, // 81
2682
+ LoopItemsFrom, // 82
2683
+ LoopItemsUnevaluated, // 83
2684
+ LoopItemsType, // 84
2685
+ LoopItemsTypeStrict, // 85
2686
+ LoopItemsTypeStrictAny, // 86
2687
+ LoopItemsPropertiesExactlyTypeStrictHash, // 87
2688
+ LoopItemsPropertiesExactlyTypeStrictHash, // 88
2689
+ LoopItemsIntegerBounded, // 89
2690
+ LoopItemsIntegerBoundedSized, // 90
2691
+ LoopContains, // 91
2692
+ ControlGroup, // 92
2693
+ ControlGroupWhenDefines, // 93
2694
+ ControlGroupWhenDefinesDirect, // 94
2695
+ ControlGroupWhenType, // 95
2696
+ ControlEvaluate, // 96
2697
+ ControlDynamicAnchorJump, // 97
2698
+ ControlJump // 98
2527
2699
  ];
2528
2700
 
2529
2701
  function AssertionTypeArrayBounded_fast(instruction, instance, depth, template, evaluator) {
@@ -3101,25 +3273,29 @@ function AssertionObjectSizeGreater_fast(instruction, instance, depth, template,
3101
3273
 
3102
3274
  function AssertionGreaterEqual_fast(instruction, instance, depth, template, evaluator) {
3103
3275
  const target = resolveInstance(instance, instruction[2]);
3104
- if (typeof target !== 'number') return true;
3276
+ const targetType = typeof target;
3277
+ if (targetType !== 'number' && targetType !== 'bigint') return true;
3105
3278
  return target >= instruction[5];
3106
3279
  }
3107
3280
 
3108
3281
  function AssertionLessEqual_fast(instruction, instance, depth, template, evaluator) {
3109
3282
  const target = resolveInstance(instance, instruction[2]);
3110
- if (typeof target !== 'number') return true;
3283
+ const targetType = typeof target;
3284
+ if (targetType !== 'number' && targetType !== 'bigint') return true;
3111
3285
  return target <= instruction[5];
3112
3286
  }
3113
3287
 
3114
3288
  function AssertionGreater_fast(instruction, instance, depth, template, evaluator) {
3115
3289
  const target = resolveInstance(instance, instruction[2]);
3116
- if (typeof target !== 'number') return true;
3290
+ const targetType = typeof target;
3291
+ if (targetType !== 'number' && targetType !== 'bigint') return true;
3117
3292
  return target > instruction[5];
3118
3293
  }
3119
3294
 
3120
3295
  function AssertionLess_fast(instruction, instance, depth, template, evaluator) {
3121
3296
  const target = resolveInstance(instance, instruction[2]);
3122
- if (typeof target !== 'number') return true;
3297
+ const targetType = typeof target;
3298
+ if (targetType !== 'number' && targetType !== 'bigint') return true;
3123
3299
  return target < instruction[5];
3124
3300
  }
3125
3301
 
@@ -3131,7 +3307,8 @@ function AssertionUnique_fast(instruction, instance, depth, template, evaluator)
3131
3307
 
3132
3308
  function AssertionDivisible_fast(instruction, instance, depth, template, evaluator) {
3133
3309
  const target = resolveInstance(instance, instruction[2]);
3134
- if (typeof target !== 'number') return true;
3310
+ const targetType = typeof target;
3311
+ if (targetType !== 'number' && targetType !== 'bigint') return true;
3135
3312
  return isDivisibleBy(target, instruction[5]);
3136
3313
  }
3137
3314
 
@@ -3239,6 +3416,26 @@ function AssertionArrayPrefixEvaluate_fast(instruction, instance, depth, templat
3239
3416
  return true;
3240
3417
  }
3241
3418
 
3419
+ function AssertionObjectPropertiesSimple_fast(instruction, instance, depth, template, evaluator) {
3420
+ const target = resolveInstance(instance, instruction[2]);
3421
+ if (!isObject(target)) return false;
3422
+ const value = instruction[5];
3423
+ const children = instruction[6];
3424
+ for (let index = 0; index < value.length; index++) {
3425
+ const entry = value[index];
3426
+ const name = entry[0];
3427
+ const required = entry[2];
3428
+ if (!Object.hasOwn(target, name)) {
3429
+ if (required) return false;
3430
+ continue;
3431
+ }
3432
+ if (index < children.length) {
3433
+ if (!evaluateInstructionFast(children[index], target[name], depth + 1, template, evaluator)) return false;
3434
+ }
3435
+ }
3436
+ return true;
3437
+ }
3438
+
3242
3439
  function AnnotationEmit_fast() { return true; }
3243
3440
  function AnnotationToParent_fast() { return true; }
3244
3441
  function AnnotationBasenameToParent_fast() { return true; }
@@ -3622,37 +3819,89 @@ function ControlDynamicAnchorJump_fast(instruction, instance, depth, template, e
3622
3819
  return false;
3623
3820
  }
3624
3821
 
3822
+ function LoopItemsIntegerBounded_fast(instruction, instance, depth, template, evaluator) {
3823
+ const target = resolveInstance(instance, instruction[2]);
3824
+ if (!Array.isArray(target) || target.length === 0) return true;
3825
+ const minimum = instruction[5][0];
3826
+ const maximum = instruction[5][1];
3827
+ for (let index = 0; index < target.length; index++) {
3828
+ const element = target[index];
3829
+ const elementType = typeof element;
3830
+ if ((elementType !== 'number' && elementType !== 'bigint') || element < minimum || element > maximum) return false;
3831
+ }
3832
+ return true;
3833
+ }
3834
+
3835
+ function LoopItemsIntegerBoundedSized_fast(instruction, instance, depth, template, evaluator) {
3836
+ const value = instruction[5];
3837
+ const minimum = value[0][0];
3838
+ const maximum = value[0][1];
3839
+ const minimumSize = value[1][0];
3840
+ const target = resolveInstance(instance, instruction[2]);
3841
+ if (!Array.isArray(target) || target.length < minimumSize) return false;
3842
+ for (let index = 0; index < target.length; index++) {
3843
+ const element = target[index];
3844
+ const elementType = typeof element;
3845
+ if ((elementType !== 'number' && elementType !== 'bigint') || element < minimum || element > maximum) return false;
3846
+ }
3847
+ return true;
3848
+ }
3849
+
3850
+ function AssertionTypeIntegerBounded_fast(instruction, instance, depth, template, evaluator) {
3851
+ const target = resolveInstance(instance, instruction[2]);
3852
+ const range = instruction[5];
3853
+ return (typeof target === 'bigint' || Number.isInteger(target)) && target >= range[0] && target <= range[1];
3854
+ }
3855
+
3856
+ function AssertionTypeIntegerBoundedStrict_fast(instruction, instance, depth, template, evaluator) {
3857
+ const target = resolveInstance(instance, instruction[2]);
3858
+ const range = instruction[5];
3859
+ return (typeof target === 'bigint' || Number.isInteger(target)) && target >= range[0] && target <= range[1];
3860
+ }
3861
+
3862
+ function AssertionTypeIntegerLowerBound_fast(instruction, instance, depth, template, evaluator) {
3863
+ const target = resolveInstance(instance, instruction[2]);
3864
+ const range = instruction[5];
3865
+ return (typeof target === 'bigint' || Number.isInteger(target)) && target >= range[0];
3866
+ }
3867
+
3868
+ function AssertionTypeIntegerLowerBoundStrict_fast(instruction, instance, depth, template, evaluator) {
3869
+ const target = resolveInstance(instance, instruction[2]);
3870
+ const range = instruction[5];
3871
+ return (typeof target === 'bigint' || Number.isInteger(target)) && target >= range[0];
3872
+ }
3873
+
3625
3874
  const fastHandlers = handlers.slice();
3626
3875
  fastHandlers[15] = AssertionTypeArrayBounded_fast;
3627
- fastHandlers[81] = LoopItemsTypeStrictAny_fast;
3628
- fastHandlers[38] = AssertionPropertyTypeStrict_fast;
3876
+ fastHandlers[86] = LoopItemsTypeStrictAny_fast;
3877
+ fastHandlers[42] = AssertionPropertyTypeStrict_fast;
3629
3878
  fastHandlers[11] = AssertionTypeStrict_fast;
3630
3879
  fastHandlers[4] = AssertionDefinesAllStrict_fast;
3631
3880
  fastHandlers[26] = AssertionEqual_fast;
3632
- fastHandlers[59] = LoopPropertiesMatch_fast;
3633
- fastHandlers[50] = LogicalOr_fast;
3634
- fastHandlers[91] = ControlJump_fast;
3881
+ fastHandlers[64] = LoopPropertiesMatch_fast;
3882
+ fastHandlers[55] = LogicalOr_fast;
3883
+ fastHandlers[98] = ControlJump_fast;
3635
3884
  fastHandlers[28] = AssertionEqualsAnyStringHash_fast;
3636
- fastHandlers[52] = LogicalXor_fast;
3885
+ fastHandlers[57] = LogicalXor_fast;
3637
3886
  fastHandlers[2] = AssertionDefinesStrict_fast;
3638
- fastHandlers[76] = LoopItems_fast;
3639
- fastHandlers[60] = LoopPropertiesMatchClosed_fast;
3887
+ fastHandlers[81] = LoopItems_fast;
3888
+ fastHandlers[65] = LoopPropertiesMatchClosed_fast;
3640
3889
  fastHandlers[13] = AssertionTypeStringBounded_fast;
3641
- fastHandlers[51] = LogicalAnd_fast;
3890
+ fastHandlers[56] = LogicalAnd_fast;
3642
3891
  fastHandlers[8] = AssertionPropertyDependencies_fast;
3643
3892
  fastHandlers[10] = AssertionTypeAny_fast;
3644
- fastHandlers[53] = LogicalCondition_fast;
3645
- fastHandlers[66] = LoopPropertiesExcept_fast;
3893
+ fastHandlers[58] = LogicalCondition_fast;
3894
+ fastHandlers[71] = LoopPropertiesExcept_fast;
3646
3895
  fastHandlers[19] = AssertionRegex_fast;
3647
- fastHandlers[61] = LoopProperties_fast;
3896
+ fastHandlers[66] = LoopProperties_fast;
3648
3897
  fastHandlers[1] = AssertionDefines_fast;
3649
- fastHandlers[54] = LogicalWhenType_fast;
3650
- fastHandlers[55] = LogicalWhenDefines_fast;
3898
+ fastHandlers[59] = LogicalWhenType_fast;
3899
+ fastHandlers[60] = LogicalWhenDefines_fast;
3651
3900
  fastHandlers[0] = AssertionFail_fast;
3652
- fastHandlers[84] = LoopContains_fast;
3653
- fastHandlers[48] = LogicalNot_fast;
3654
- fastHandlers[79] = LoopItemsType_fast;
3655
- fastHandlers[80] = LoopItemsTypeStrict_fast;
3901
+ fastHandlers[91] = LoopContains_fast;
3902
+ fastHandlers[53] = LogicalNot_fast;
3903
+ fastHandlers[84] = LoopItemsType_fast;
3904
+ fastHandlers[85] = LoopItemsTypeStrict_fast;
3656
3905
  fastHandlers[27] = AssertionEqualsAny_fast;
3657
3906
  fastHandlers[3] = AssertionDefinesAll_fast;
3658
3907
  fastHandlers[5] = AssertionDefinesExactly_fast;
@@ -3676,39 +3925,46 @@ fastHandlers[31] = AssertionGreater_fast;
3676
3925
  fastHandlers[32] = AssertionLess_fast;
3677
3926
  fastHandlers[33] = AssertionUnique_fast;
3678
3927
  fastHandlers[34] = AssertionDivisible_fast;
3679
- fastHandlers[35] = AssertionStringType_fast;
3680
- fastHandlers[36] = AssertionPropertyType_fast;
3681
- fastHandlers[37] = AssertionPropertyTypeEvaluate_fast;
3682
- fastHandlers[39] = AssertionPropertyTypeStrictEvaluate_fast;
3683
- fastHandlers[40] = AssertionPropertyTypeStrictAny_fast;
3684
- fastHandlers[41] = AssertionPropertyTypeStrictAnyEvaluate_fast;
3685
- fastHandlers[42] = AssertionArrayPrefix_fast;
3686
- fastHandlers[43] = AssertionArrayPrefixEvaluate_fast;
3687
- fastHandlers[44] = AnnotationEmit_fast;
3688
- fastHandlers[45] = AnnotationToParent_fast;
3689
- fastHandlers[46] = AnnotationBasenameToParent_fast;
3690
- fastHandlers[47] = Evaluate_fast;
3691
- fastHandlers[49] = LogicalNotEvaluate_fast;
3692
- fastHandlers[56] = LogicalWhenArraySizeGreater_fast;
3693
- fastHandlers[57] = LoopPropertiesUnevaluated_fast;
3694
- fastHandlers[58] = LoopPropertiesUnevaluatedExcept_fast;
3695
- fastHandlers[62] = LoopPropertiesEvaluate_fast;
3696
- fastHandlers[63] = LoopPropertiesRegex_fast;
3697
- fastHandlers[64] = LoopPropertiesRegexClosed_fast;
3698
- fastHandlers[65] = LoopPropertiesStartsWith_fast;
3699
- fastHandlers[67] = LoopPropertiesType_fast;
3700
- fastHandlers[68] = LoopPropertiesTypeEvaluate_fast;
3701
- fastHandlers[69] = LoopPropertiesExactlyTypeStrict_fast;
3702
- fastHandlers[70] = LoopPropertiesExactlyTypeStrictHash_fast;
3703
- fastHandlers[71] = LoopPropertiesTypeStrict_fast;
3704
- fastHandlers[72] = LoopPropertiesTypeStrictEvaluate_fast;
3705
- fastHandlers[73] = LoopPropertiesTypeStrictAny_fast;
3706
- fastHandlers[74] = LoopPropertiesTypeStrictAnyEvaluate_fast;
3707
- fastHandlers[75] = LoopKeys_fast;
3708
- fastHandlers[77] = LoopItemsFrom_fast;
3709
- fastHandlers[78] = LoopItemsUnevaluated_fast;
3710
- fastHandlers[82] = LoopItemsPropertiesExactlyTypeStrictHash_fast;
3711
- fastHandlers[83] = LoopItemsPropertiesExactlyTypeStrictHash_fast;
3712
- fastHandlers[90] = ControlDynamicAnchorJump_fast;
3928
+ fastHandlers[35] = AssertionTypeIntegerBounded_fast;
3929
+ fastHandlers[36] = AssertionTypeIntegerBoundedStrict_fast;
3930
+ fastHandlers[37] = AssertionTypeIntegerLowerBound_fast;
3931
+ fastHandlers[38] = AssertionTypeIntegerLowerBoundStrict_fast;
3932
+ fastHandlers[39] = AssertionStringType_fast;
3933
+ fastHandlers[40] = AssertionPropertyType_fast;
3934
+ fastHandlers[41] = AssertionPropertyTypeEvaluate_fast;
3935
+ fastHandlers[43] = AssertionPropertyTypeStrictEvaluate_fast;
3936
+ fastHandlers[44] = AssertionPropertyTypeStrictAny_fast;
3937
+ fastHandlers[45] = AssertionPropertyTypeStrictAnyEvaluate_fast;
3938
+ fastHandlers[46] = AssertionArrayPrefix_fast;
3939
+ fastHandlers[47] = AssertionArrayPrefixEvaluate_fast;
3940
+ fastHandlers[48] = AssertionObjectPropertiesSimple_fast;
3941
+ fastHandlers[49] = AnnotationEmit_fast;
3942
+ fastHandlers[50] = AnnotationToParent_fast;
3943
+ fastHandlers[51] = AnnotationBasenameToParent_fast;
3944
+ fastHandlers[52] = Evaluate_fast;
3945
+ fastHandlers[54] = LogicalNotEvaluate_fast;
3946
+ fastHandlers[61] = LogicalWhenArraySizeGreater_fast;
3947
+ fastHandlers[62] = LoopPropertiesUnevaluated_fast;
3948
+ fastHandlers[63] = LoopPropertiesUnevaluatedExcept_fast;
3949
+ fastHandlers[67] = LoopPropertiesEvaluate_fast;
3950
+ fastHandlers[68] = LoopPropertiesRegex_fast;
3951
+ fastHandlers[69] = LoopPropertiesRegexClosed_fast;
3952
+ fastHandlers[70] = LoopPropertiesStartsWith_fast;
3953
+ fastHandlers[72] = LoopPropertiesType_fast;
3954
+ fastHandlers[73] = LoopPropertiesTypeEvaluate_fast;
3955
+ fastHandlers[74] = LoopPropertiesExactlyTypeStrict_fast;
3956
+ fastHandlers[75] = LoopPropertiesExactlyTypeStrictHash_fast;
3957
+ fastHandlers[76] = LoopPropertiesTypeStrict_fast;
3958
+ fastHandlers[77] = LoopPropertiesTypeStrictEvaluate_fast;
3959
+ fastHandlers[78] = LoopPropertiesTypeStrictAny_fast;
3960
+ fastHandlers[79] = LoopPropertiesTypeStrictAnyEvaluate_fast;
3961
+ fastHandlers[80] = LoopKeys_fast;
3962
+ fastHandlers[82] = LoopItemsFrom_fast;
3963
+ fastHandlers[83] = LoopItemsUnevaluated_fast;
3964
+ fastHandlers[87] = LoopItemsPropertiesExactlyTypeStrictHash_fast;
3965
+ fastHandlers[88] = LoopItemsPropertiesExactlyTypeStrictHash_fast;
3966
+ fastHandlers[89] = LoopItemsIntegerBounded_fast;
3967
+ fastHandlers[90] = LoopItemsIntegerBoundedSized_fast;
3968
+ fastHandlers[97] = ControlDynamicAnchorJump_fast;
3713
3969
 
3714
3970
  export { Blaze };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@sourcemeta/blaze",
3
- "version": "14.20.2",
3
+ "version": "15.0.0",
4
4
  "description": "A pure JavaScript port of the evaluator from Blaze, a high-performance C++ JSON Schema validator. Zero dependencies. Supports Draft 4, Draft 6, Draft 7, 2019-09, and 2020-12 with schema-specific code generation for near-native speed",
5
5
  "type": "module",
6
6
  "main": "./index.mjs",