@arrirpc/schema 0.69.2 → 0.71.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/README.md +139 -137
- package/dist/index.cjs +59 -51
- package/dist/index.d.cts +20 -11
- package/dist/index.d.mts +20 -11
- package/dist/index.d.ts +20 -11
- package/dist/index.mjs +36 -32
- package/dist/shared/{schema.4e2863ed.cjs → schema.BcsXcrqv.cjs} +479 -349
- package/dist/shared/{schema.cdac4a20.d.ts → schema.DLX0nTwB.d.cts} +5 -4
- package/dist/shared/{schema.cdac4a20.d.cts → schema.DLX0nTwB.d.mts} +5 -4
- package/dist/shared/{schema.cdac4a20.d.mts → schema.DLX0nTwB.d.ts} +5 -4
- package/dist/shared/{schema.25b78dac.mjs → schema.O5uzRO_D.mjs} +470 -344
- package/dist/testSuites.cjs +11 -11
- package/dist/testSuites.d.cts +7 -6
- package/dist/testSuites.d.mts +7 -6
- package/dist/testSuites.d.ts +7 -6
- package/dist/testSuites.mjs +11 -11
- package/package.json +4 -3
package/README.md
CHANGED
|
@@ -2,13 +2,15 @@
|
|
|
2
2
|
|
|
3
3
|
A type builder and validation library for [Arri Type Definitions](/specifications/arri_type_definition.md). A lot of inspiration was taken from both [Typebox](https://github.com/sinclairzx81/typebox) and [Zod](https://github.com/colinhacks/zod) when designing this library.
|
|
4
4
|
|
|
5
|
+
This library also supports [standard-schema](https://github.com/standard-schema/standard-schema) meaning it can be used with any third-party library that accepts standard schema.
|
|
6
|
+
|
|
5
7
|
## Project Philosophy
|
|
6
8
|
|
|
7
9
|
The goals of this project are as follows:
|
|
8
10
|
|
|
9
|
-
-
|
|
10
|
-
-
|
|
11
|
-
-
|
|
11
|
+
- Portable type definitions
|
|
12
|
+
- High performance validation, parsing, and serialization
|
|
13
|
+
- Consistent error reporting for parsing and serialization errors
|
|
12
14
|
|
|
13
15
|
I am not looking to support every feature of Typescript's type system or even every possible representation of JSON. The goal is that the data models defined through this library can be used as a source of truth across multiple programming languages. Both JSON and Typescript have to be limited to accomplish this.
|
|
14
16
|
|
|
@@ -16,42 +18,42 @@ I am not looking to support every feature of Typescript's type system or even ev
|
|
|
16
18
|
|
|
17
19
|
Originally this library was created as a way for building schemas for [Json Type Definition](https://jsontypedef.com/). However over time parts of the internal schema were modified to better suite the goals of Arri RPC. Some of these modifications include:
|
|
18
20
|
|
|
19
|
-
-
|
|
20
|
-
-
|
|
21
|
-
-
|
|
21
|
+
- Adding support for 64-bit integers
|
|
22
|
+
- Replacing the `additionalProperties` field with `strict` to allow for additional properties by default.
|
|
23
|
+
- Restrict `ref` to only be used for recursive references.
|
|
22
24
|
|
|
23
25
|
## Table of Contents
|
|
24
26
|
|
|
25
|
-
-
|
|
26
|
-
-
|
|
27
|
-
-
|
|
28
|
-
-
|
|
29
|
-
-
|
|
30
|
-
-
|
|
31
|
-
-
|
|
32
|
-
-
|
|
33
|
-
-
|
|
34
|
-
-
|
|
35
|
-
-
|
|
36
|
-
-
|
|
37
|
-
-
|
|
38
|
-
-
|
|
39
|
-
-
|
|
40
|
-
-
|
|
41
|
-
-
|
|
42
|
-
-
|
|
43
|
-
-
|
|
44
|
-
-
|
|
45
|
-
-
|
|
46
|
-
-
|
|
47
|
-
-
|
|
48
|
-
-
|
|
49
|
-
-
|
|
50
|
-
-
|
|
51
|
-
-
|
|
52
|
-
-
|
|
53
|
-
-
|
|
54
|
-
-
|
|
27
|
+
- [Installation](#installation)
|
|
28
|
+
- [Basic Example](#basic-example)
|
|
29
|
+
- [Usage With @arrirpc/server](#usage-with-arrirpcserver)
|
|
30
|
+
- [Supported Types](#supported-types)
|
|
31
|
+
- [Primitives](#primitives)
|
|
32
|
+
- [Enums](#enums)
|
|
33
|
+
- [Arrays / Lists](#arrays--lists)
|
|
34
|
+
- [Objects](#objects)
|
|
35
|
+
- [Records / Maps](#records--maps)
|
|
36
|
+
- [Discriminated Unions](#discriminated-unions)
|
|
37
|
+
- [Recursive Types](#recursive-types)
|
|
38
|
+
- [Modifiers](#modifiers)
|
|
39
|
+
- [Optional](#optional)
|
|
40
|
+
- [Nullable](#nullable)
|
|
41
|
+
- [Extend](#extend)
|
|
42
|
+
- [Omit](#omit)
|
|
43
|
+
- [Pick](#pick)
|
|
44
|
+
- [Partial](#partial)
|
|
45
|
+
- [Utilities](#utilities)
|
|
46
|
+
- [Validate](#validate)
|
|
47
|
+
- [Parse](#parse)
|
|
48
|
+
- [Safe Parse](#safe-parse)
|
|
49
|
+
- [Coerce](#coerce)
|
|
50
|
+
- [Safe Coerce](#safe-coerce)
|
|
51
|
+
- [Serialize](#serialize)
|
|
52
|
+
- [Errors](#errors)
|
|
53
|
+
- [Compiled Validators](#compiled-validators)
|
|
54
|
+
- [Metadata](#metadata)
|
|
55
|
+
- [Benchmarks](#benchmarks)
|
|
56
|
+
- [Development](#development)
|
|
55
57
|
|
|
56
58
|
## Installation
|
|
57
59
|
|
|
@@ -66,7 +68,7 @@ pnpm install @arrirpc/schema
|
|
|
66
68
|
## Basic Example
|
|
67
69
|
|
|
68
70
|
```ts
|
|
69
|
-
import { a } from
|
|
71
|
+
import { a } from '@arrirpc/schema';
|
|
70
72
|
|
|
71
73
|
const User = a.object({
|
|
72
74
|
id: a.string(),
|
|
@@ -81,12 +83,12 @@ a.parse(User, `{"id": "1", "name": "John Doe"}`);
|
|
|
81
83
|
a.parse(User, `{"id": "1", "name": null}`);
|
|
82
84
|
|
|
83
85
|
// returns true
|
|
84
|
-
a.validate(User, { id:
|
|
86
|
+
a.validate(User, { id: '1', name: 'John Doe' });
|
|
85
87
|
// returns false
|
|
86
|
-
a.validate(User, { id:
|
|
88
|
+
a.validate(User, { id: '1', name: null });
|
|
87
89
|
|
|
88
90
|
// outputs valid json
|
|
89
|
-
a.serialize(User, { id:
|
|
91
|
+
a.serialize(User, { id: '1', name: 'John Doe' });
|
|
90
92
|
```
|
|
91
93
|
|
|
92
94
|
## Usage With @arrirpc/server
|
|
@@ -94,8 +96,8 @@ a.serialize(User, { id: "1", name: "John Doe" });
|
|
|
94
96
|
See [here](/languages/ts/ts-server/README.md) for full details.
|
|
95
97
|
|
|
96
98
|
```ts
|
|
97
|
-
import { a } from
|
|
98
|
-
import { defineRpc } from
|
|
99
|
+
import { a } from '@arrirpc/schema';
|
|
100
|
+
import { defineRpc } from '@arrirpc/server';
|
|
99
101
|
|
|
100
102
|
export default defineRpc({
|
|
101
103
|
params: a.object({
|
|
@@ -141,11 +143,11 @@ Enum schemas allow you to specify a predefine list of accepted strings
|
|
|
141
143
|
**Usage**
|
|
142
144
|
|
|
143
145
|
```ts
|
|
144
|
-
const Status = a.enumerator([
|
|
146
|
+
const Status = a.enumerator(['ACTIVE', 'INACTIVE', 'UNKNOWN']);
|
|
145
147
|
type Status = a.infer<typeof Status>; // "ACTIVE" | "INACTIVE" | "UNKNOWN";
|
|
146
148
|
|
|
147
|
-
a.validate(Status,
|
|
148
|
-
a.validate(Status,
|
|
149
|
+
a.validate(Status, 'BLAH'); // false
|
|
150
|
+
a.validate(Status, 'ACTIVE'); // true
|
|
149
151
|
```
|
|
150
152
|
|
|
151
153
|
**Outputted JTD**
|
|
@@ -165,7 +167,7 @@ const MyList = a.array(a.string());
|
|
|
165
167
|
type MyList = a.infer<typeof MyList>; // string[];
|
|
166
168
|
|
|
167
169
|
a.validate(MyList, [1, 2]); // false
|
|
168
|
-
a.validate(MyList, [
|
|
170
|
+
a.validate(MyList, ['hello', 'world']); // true
|
|
169
171
|
```
|
|
170
172
|
|
|
171
173
|
**Outputted JTD**
|
|
@@ -191,12 +193,12 @@ const User = a.object({
|
|
|
191
193
|
type User = a.infer<typeof User>; // { id: string; email: string; created: Date; }
|
|
192
194
|
|
|
193
195
|
a.validate({
|
|
194
|
-
id:
|
|
195
|
-
email:
|
|
196
|
+
id: '1',
|
|
197
|
+
email: 'johndoe@example.com',
|
|
196
198
|
created: new Date(),
|
|
197
199
|
}); // true
|
|
198
200
|
a.validate({
|
|
199
|
-
id:
|
|
201
|
+
id: '1',
|
|
200
202
|
email: null,
|
|
201
203
|
created: new Date(),
|
|
202
204
|
}); // false
|
|
@@ -237,10 +239,10 @@ const UserStrict = a.object(
|
|
|
237
239
|
);
|
|
238
240
|
|
|
239
241
|
a.parse(UserStrict, {
|
|
240
|
-
id:
|
|
241
|
-
name:
|
|
242
|
+
id: '1',
|
|
243
|
+
name: 'johndoe',
|
|
242
244
|
created: new Date(),
|
|
243
|
-
bio:
|
|
245
|
+
bio: 'my name is joe',
|
|
244
246
|
}); // fails parsing because of the additional field "bio"
|
|
245
247
|
```
|
|
246
248
|
|
|
@@ -276,7 +278,7 @@ a.validate(R, {
|
|
|
276
278
|
world: false,
|
|
277
279
|
}); // true;
|
|
278
280
|
a.validate(R, {
|
|
279
|
-
hello:
|
|
281
|
+
hello: 'world',
|
|
280
282
|
}); // false;
|
|
281
283
|
```
|
|
282
284
|
|
|
@@ -295,7 +297,7 @@ a.validate(R, {
|
|
|
295
297
|
**Usage**
|
|
296
298
|
|
|
297
299
|
```ts
|
|
298
|
-
const Shape = a.discriminator(
|
|
300
|
+
const Shape = a.discriminator('type', {
|
|
299
301
|
RECTANGLE: a.object({
|
|
300
302
|
width: a.float32(),
|
|
301
303
|
height: a.float32(),
|
|
@@ -307,20 +309,20 @@ const Shape = a.discriminator("type", {
|
|
|
307
309
|
type Shape = a.infer<typeof Shape>; // { type: "RECTANGLE"; width: number; height: number; } | { type: "CIRCLE"; radius: number; }
|
|
308
310
|
|
|
309
311
|
// Infer specific sub types of the union
|
|
310
|
-
type ShapeTypeRectangle = a.inferSubType<Shape,
|
|
311
|
-
type ShapeTypeCircle = a.inferSubType<Shape,
|
|
312
|
+
type ShapeTypeRectangle = a.inferSubType<Shape, 'type', 'RECTANGLE'>; // { type "RECTANGLE"; width: number; height: number; };
|
|
313
|
+
type ShapeTypeCircle = a.inferSubType<Shape, 'type', 'CIRCLE'>; // { type "CIRCLE"; radius: number; }
|
|
312
314
|
|
|
313
315
|
a.validate(Shape, {
|
|
314
|
-
type:
|
|
316
|
+
type: 'RECTANGLE',
|
|
315
317
|
width: 1,
|
|
316
318
|
height: 1.5,
|
|
317
319
|
}); // true
|
|
318
320
|
a.validate(Shape, {
|
|
319
|
-
type:
|
|
321
|
+
type: 'CIRCLE',
|
|
320
322
|
radius: 5,
|
|
321
323
|
}); // true
|
|
322
324
|
a.validate(Shape, {
|
|
323
|
-
type:
|
|
325
|
+
type: 'CIRCLE',
|
|
324
326
|
width: 1,
|
|
325
327
|
height: 1.5,
|
|
326
328
|
}); // false
|
|
@@ -385,7 +387,7 @@ const BinaryTree = a.recursive<BinaryTree>(
|
|
|
385
387
|
right: a.nullable(self),
|
|
386
388
|
}),
|
|
387
389
|
{
|
|
388
|
-
id:
|
|
390
|
+
id: 'BinaryTree',
|
|
389
391
|
},
|
|
390
392
|
);
|
|
391
393
|
|
|
@@ -506,7 +508,7 @@ const A = a.object(
|
|
|
506
508
|
a: a.string(),
|
|
507
509
|
b: a.float32(),
|
|
508
510
|
},
|
|
509
|
-
{ id:
|
|
511
|
+
{ id: 'A' },
|
|
510
512
|
);
|
|
511
513
|
console.log(A.metadata.id); // "A"
|
|
512
514
|
|
|
@@ -545,7 +547,7 @@ const A = a.object({
|
|
|
545
547
|
});
|
|
546
548
|
// { a: string; b: number; }
|
|
547
549
|
|
|
548
|
-
const B = a.omit(A, [
|
|
550
|
+
const B = a.omit(A, ['a']);
|
|
549
551
|
// { b: number; }
|
|
550
552
|
```
|
|
551
553
|
|
|
@@ -561,7 +563,7 @@ const A = a.object({
|
|
|
561
563
|
});
|
|
562
564
|
// { a: string; b: number; c: Date; }
|
|
563
565
|
|
|
564
|
-
const B = a.pick(A, [
|
|
566
|
+
const B = a.pick(A, ['a', 'c']);
|
|
565
567
|
// { a: string; c: Date; }
|
|
566
568
|
```
|
|
567
569
|
|
|
@@ -593,7 +595,7 @@ const User = a.object({
|
|
|
593
595
|
name: a.string(),
|
|
594
596
|
});
|
|
595
597
|
a.validate(User, true); // false
|
|
596
|
-
a.validate(User, { id:
|
|
598
|
+
a.validate(User, { id: '1', name: 'john doe' }); // true
|
|
597
599
|
|
|
598
600
|
if (a.validate(User, someInput)) {
|
|
599
601
|
console.log(someInput.id); // intellisense works here
|
|
@@ -644,9 +646,9 @@ const A = a.object({
|
|
|
644
646
|
});
|
|
645
647
|
|
|
646
648
|
a.coerce(A, {
|
|
647
|
-
a:
|
|
648
|
-
b:
|
|
649
|
-
c:
|
|
649
|
+
a: '1',
|
|
650
|
+
b: 'true',
|
|
651
|
+
c: '500.24',
|
|
650
652
|
});
|
|
651
653
|
// { a: "1", b: true, c: 500.24 };
|
|
652
654
|
```
|
|
@@ -681,7 +683,7 @@ const User = a.object({
|
|
|
681
683
|
name: a.string(),
|
|
682
684
|
});
|
|
683
685
|
|
|
684
|
-
a.serialize(User, { id:
|
|
686
|
+
a.serialize(User, { id: '1', name: 'john doe' });
|
|
685
687
|
// {"id":"1","name":"john doe"}
|
|
686
688
|
```
|
|
687
689
|
|
|
@@ -697,7 +699,7 @@ const User = a.object({
|
|
|
697
699
|
date: a.timestamp(),
|
|
698
700
|
});
|
|
699
701
|
|
|
700
|
-
a.errors(User, { id: 1, date:
|
|
702
|
+
a.errors(User, { id: 1, date: 'hello world' });
|
|
701
703
|
/**
|
|
702
704
|
* [
|
|
703
705
|
* {
|
|
@@ -730,7 +732,7 @@ const $$User = a.compile(User);
|
|
|
730
732
|
|
|
731
733
|
$$User.validate(someInput);
|
|
732
734
|
$$User.parse(someJson);
|
|
733
|
-
$$User.serialize({ id:
|
|
735
|
+
$$User.serialize({ id: '1', email: null, created: new Date() });
|
|
734
736
|
```
|
|
735
737
|
|
|
736
738
|
In most cases, the compiled validators will be much faster than the standard utilities. However there is some overhead with compiling the schemas so ideally each validator would be compiled once. Additionally the resulting methods make use of eval so they can only be used in an environment that you control such as a backend server. They WILL NOT work in a browser environment.
|
|
@@ -747,9 +749,9 @@ $$User.compiledCode.serialize; // the generated serialization code
|
|
|
747
749
|
|
|
748
750
|
Metadata is used during cross-language code generation. Arri schemas allow you to specify the following metadata fields:
|
|
749
751
|
|
|
750
|
-
-
|
|
751
|
-
-
|
|
752
|
-
-
|
|
752
|
+
- id - Will be used as the type name in any arri client generators
|
|
753
|
+
- description - Will be added as a description comment above any generated types
|
|
754
|
+
- isDeprecated - Will mark any generated code with the deprecation annotation of target language
|
|
753
755
|
|
|
754
756
|
### Examples
|
|
755
757
|
|
|
@@ -764,8 +766,8 @@ const BookSchema = a.object(
|
|
|
764
766
|
publishDate: a.timestamp(),
|
|
765
767
|
},
|
|
766
768
|
{
|
|
767
|
-
id:
|
|
768
|
-
description:
|
|
769
|
+
id: 'Book',
|
|
770
|
+
description: 'This is a book',
|
|
769
771
|
},
|
|
770
772
|
);
|
|
771
773
|
```
|
|
@@ -831,14 +833,14 @@ Because IDs are really important for producing concise type names. Arri validate
|
|
|
831
833
|
|
|
832
834
|
```ts
|
|
833
835
|
// ID will be set to "Book"
|
|
834
|
-
const BookSchema = a.object(
|
|
836
|
+
const BookSchema = a.object('Book', {
|
|
835
837
|
title: a.string(),
|
|
836
838
|
author: a.string(),
|
|
837
839
|
publishDate: a.timestamp(),
|
|
838
840
|
});
|
|
839
841
|
|
|
840
842
|
// ID will be set to "Message"
|
|
841
|
-
const MessageSchema = a.discriminator(
|
|
843
|
+
const MessageSchema = a.discriminator('Message', 'type', {
|
|
842
844
|
TEXT: a.object({
|
|
843
845
|
userId: a.string(),
|
|
844
846
|
content: a.string(),
|
|
@@ -850,7 +852,7 @@ const MessageSchema = a.discriminator("Message", "type", {
|
|
|
850
852
|
});
|
|
851
853
|
|
|
852
854
|
// ID will be set to "BTree"
|
|
853
|
-
const BinaryTreeSchema = a.recursive(
|
|
855
|
+
const BinaryTreeSchema = a.recursive('BTree', (self) =>
|
|
854
856
|
a.object({
|
|
855
857
|
left: a.nullable(self),
|
|
856
858
|
right: a.nullable(self),
|
|
@@ -862,7 +864,7 @@ const BinaryTreeSchema = a.recursive("BTree", (self) =>
|
|
|
862
864
|
|
|
863
865
|
## Benchmarks
|
|
864
866
|
|
|
865
|
-
_Last Updated: 2024-
|
|
867
|
+
_Last Updated: 2024-12-27_
|
|
866
868
|
|
|
867
869
|
All benchmarks were run on my personal desktop. You can view the methodology used in [./benchmarks/src](./benchmark/src).
|
|
868
870
|
|
|
@@ -907,44 +909,44 @@ The following data was used in these benchmarks. Relevant schemas were created i
|
|
|
907
909
|
|
|
908
910
|
#### Validation
|
|
909
911
|
|
|
910
|
-
| Library | op/s
|
|
911
|
-
| ---------------------------- |
|
|
912
|
-
| **Arri (Compiled)** |
|
|
913
|
-
| Typebox (Compiled) |
|
|
914
|
-
| Ajv -JTD (Compiled) |
|
|
915
|
-
| Ajv - JTD |
|
|
916
|
-
| Ajv - JSON Schema (Compiled) | 12,
|
|
917
|
-
| Ajv -JSON Schema |
|
|
918
|
-
| **Arri** | 2,
|
|
919
|
-
| Typebox |
|
|
920
|
-
| Zod |
|
|
912
|
+
| Library | op/s |
|
|
913
|
+
| ---------------------------- | -------------- |
|
|
914
|
+
| **Arri (Compiled)** | **51,149,033** |
|
|
915
|
+
| Typebox (Compiled) | 47,826,755 |
|
|
916
|
+
| Ajv -JTD (Compiled) | 32,001,140 |
|
|
917
|
+
| Ajv - JTD | 12,731,224 |
|
|
918
|
+
| Ajv - JSON Schema (Compiled) | 12,371,095 |
|
|
919
|
+
| Ajv -JSON Schema | 8,811,605 |
|
|
920
|
+
| **Arri** | **2,151,961** |
|
|
921
|
+
| Typebox | 1,024,386 |
|
|
922
|
+
| Zod | 471,700 |
|
|
921
923
|
|
|
922
924
|
#### Parsing
|
|
923
925
|
|
|
924
|
-
| Library | op/s
|
|
925
|
-
| ------------------- |
|
|
926
|
-
| JSON.parse |
|
|
927
|
-
| **Arri (Compiled)** |
|
|
928
|
-
| **Arri** | 378,
|
|
929
|
-
| Ajv -JTD (Compiled) |
|
|
926
|
+
| Library | op/s |
|
|
927
|
+
| ------------------- | ----------- |
|
|
928
|
+
| JSON.parse | 785,364 |
|
|
929
|
+
| **Arri (Compiled)** | **736,957** |
|
|
930
|
+
| **Arri** | **378,841** |
|
|
931
|
+
| Ajv -JTD (Compiled) | 230,124 |
|
|
930
932
|
|
|
931
933
|
#### Serialization
|
|
932
934
|
|
|
933
|
-
| Library | op/s
|
|
934
|
-
| ------------------------------------------ |
|
|
935
|
-
| **Arri (Compiled)** | 4,
|
|
936
|
-
| **Arri (Compiled) Validate and Serialize** | 3,
|
|
937
|
-
| Ajv - JTD (Compiled) | 2,
|
|
938
|
-
| JSON.stringify |
|
|
939
|
-
| Arri |
|
|
935
|
+
| Library | op/s |
|
|
936
|
+
| ------------------------------------------ | ------------- |
|
|
937
|
+
| **Arri (Compiled)** | **4,131,382** |
|
|
938
|
+
| **Arri (Compiled) Validate and Serialize** | **3,710,794** |
|
|
939
|
+
| Ajv - JTD (Compiled) | 2,066,041 |
|
|
940
|
+
| JSON.stringify | 1,599,758 |
|
|
941
|
+
| Arri | 467,417 |
|
|
940
942
|
|
|
941
943
|
#### Coercion
|
|
942
944
|
|
|
943
|
-
| Library | op/s
|
|
944
|
-
| -------- |
|
|
945
|
-
| **Arri** |
|
|
946
|
-
| Zod | 466
|
|
947
|
-
| Typebox |
|
|
945
|
+
| Library | op/s |
|
|
946
|
+
| -------- | ----------- |
|
|
947
|
+
| **Arri** | **820,103** |
|
|
948
|
+
| Zod | 465,466 |
|
|
949
|
+
| Typebox | 405,292 |
|
|
948
950
|
|
|
949
951
|
### Integers
|
|
950
952
|
|
|
@@ -952,44 +954,44 @@ The following benchmarks measure how quickly each library operates on a single i
|
|
|
952
954
|
|
|
953
955
|
#### Validation
|
|
954
956
|
|
|
955
|
-
| Library | op/s
|
|
956
|
-
| ---------------------------- |
|
|
957
|
-
|
|
|
958
|
-
| **Arri (Compiled)** |
|
|
959
|
-
|
|
|
960
|
-
| Ajv - JTD (Compiled) |
|
|
961
|
-
|
|
|
962
|
-
|
|
|
963
|
-
| Ajv - JSON Schema |
|
|
964
|
-
|
|
|
965
|
-
| Zod | 1,
|
|
957
|
+
| Library | op/s |
|
|
958
|
+
| ---------------------------- | --------------- |
|
|
959
|
+
| Typebox (Compiled) | 196,718,452 |
|
|
960
|
+
| **Arri (Compiled)** | **190,853,038** |
|
|
961
|
+
| Ajv - JSON Schema (Compiled) | 189,905,832 |
|
|
962
|
+
| Ajv - JTD (Compiled) | 143,619,126 |
|
|
963
|
+
| **Arri** | **89,428,888** |
|
|
964
|
+
| Typebox | 48,408,435 |
|
|
965
|
+
| Ajv - JSON Schema | 36,560,467 |
|
|
966
|
+
| Ajv - JTD | 35,639,616 |
|
|
967
|
+
| Zod | 1,286,707 |
|
|
966
968
|
|
|
967
969
|
#### Parsing
|
|
968
970
|
|
|
969
|
-
| Library | op/s
|
|
970
|
-
| -------------------- |
|
|
971
|
-
| **Arri (Compiled)** |
|
|
972
|
-
| **Arri** |
|
|
973
|
-
| JSON.parse() |
|
|
974
|
-
| Ajv - JTD (Compiled) |
|
|
971
|
+
| Library | op/s |
|
|
972
|
+
| -------------------- | --------------- |
|
|
973
|
+
| **Arri (Compiled)** | **131,214,018** |
|
|
974
|
+
| **Arri** | **56,134,552** |
|
|
975
|
+
| JSON.parse() | 21,001,320 |
|
|
976
|
+
| Ajv - JTD (Compiled) | 9,441,285 |
|
|
975
977
|
|
|
976
978
|
#### Serialization
|
|
977
979
|
|
|
978
|
-
| Library | op/s
|
|
979
|
-
| -------------------- |
|
|
980
|
-
| Ajv - JTD (Compiled) |
|
|
981
|
-
| **Arri (Compiled)** |
|
|
982
|
-
| **Arri** |
|
|
983
|
-
| JSON.stringify |
|
|
980
|
+
| Library | op/s |
|
|
981
|
+
| -------------------- | --------------- |
|
|
982
|
+
| Ajv - JTD (Compiled) | 199,802,584 |
|
|
983
|
+
| **Arri (Compiled)** | **194,399,849** |
|
|
984
|
+
| **Arri** | **65,097,829** |
|
|
985
|
+
| JSON.stringify | 16,853,237 |
|
|
984
986
|
|
|
985
987
|
#### Coercion
|
|
986
988
|
|
|
987
|
-
| Library | op/s
|
|
988
|
-
| ----------------- |
|
|
989
|
-
| Arri
|
|
990
|
-
| TypeBox | 34,
|
|
991
|
-
| Ajv - JSON Schema |
|
|
992
|
-
| Zod | 1,
|
|
989
|
+
| Library | op/s |
|
|
990
|
+
| ----------------- | -------------- |
|
|
991
|
+
| **Arri** | **55,840,221** |
|
|
992
|
+
| TypeBox | 34,403,424 |
|
|
993
|
+
| Ajv - JSON Schema | 22,190,607 |
|
|
994
|
+
| Zod | 1,195,111 |
|
|
993
995
|
|
|
994
996
|
## Development
|
|
995
997
|
|