Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
72 commits
Select commit Hold shift + click to select a range
6d73539
add a JSON schema benchmark case
claude Jul 27, 2026
416a54c
move JSON Schema link to post-runtime group
EskiMojo14 Jul 30, 2026
4c805d6
remove unstyled card class
EskiMojo14 Jul 30, 2026
c3840a3
move json schema route out of runtime group
EskiMojo14 Jul 30, 2026
871efe2
split json schema components into their own files and remove json sch…
EskiMojo14 Jul 30, 2026
2478079
place the support matrix in a collapsible details element
EskiMojo14 Jul 30, 2026
46bdf34
more _runtime cleanup
EskiMojo14 Jul 30, 2026
15f3638
allow sorting of JsonSchema results with useSortedResults hook
EskiMojo14 Jul 30, 2026
ed2d97f
add assertJsonSchemaDirection util
EskiMojo14 Jul 30, 2026
724d985
move json schema benchmarks into separate script/results
EskiMojo14 Jul 30, 2026
8a9d4f8
move route from /json-schema to /json-schema/conversion
EskiMojo14 Jul 30, 2026
c2a6964
constrain size of json schema output in benchmark view
EskiMojo14 Jul 30, 2026
5e9ec41
move components to own directories
EskiMojo14 Jul 30, 2026
8409d7f
fix vite config import
EskiMojo14 Jul 30, 2026
76a387a
fix import
EskiMojo14 Jul 30, 2026
9730a81
fix css import
EskiMojo14 Jul 30, 2026
c4c4208
remove .ts extensions from imports for consistency
EskiMojo14 Jul 30, 2026
75db1d4
ignore formatting for json schema results
EskiMojo14 Jul 30, 2026
0bf7e71
keep ts import for node script
EskiMojo14 Jul 30, 2026
f2f5bc3
fix e2e navigation test for JSON Schema conversion page
EskiMojo14 Jul 30, 2026
95731f2
show support matrix on homepage instead of benchmarks
EskiMojo14 Jul 30, 2026
09ee318
remove surplus information when impossible
EskiMojo14 Jul 30, 2026
f31bbbc
make standardJsonSchema optional in results and registry types
EskiMojo14 Jul 30, 2026
72d751b
shorten standardJsonSchema support options
EskiMojo14 Jul 30, 2026
e3641fd
when a separate package is needed for standard json schema support, d…
EskiMojo14 Jul 30, 2026
6f43ebc
tweak display of standard JSON Schema support in results card
EskiMojo14 Jul 30, 2026
9276e81
shorten "Already JSON Schema" to "JSON Schema" in benchmarks and cons…
EskiMojo14 Jul 30, 2026
60e8e97
write e2e tests for json-schema conversion page
EskiMojo14 Jul 30, 2026
99181b1
fix sidebar label in e2e test
EskiMojo14 Jul 30, 2026
c2e14cd
remove .ts extension from import path in matrix.tsx
EskiMojo14 Jul 30, 2026
70e5cf0
clarify None vs blank
EskiMojo14 Jul 30, 2026
86542c9
add support for draft-07 in typebox benchmarks
EskiMojo14 Aug 1, 2026
356c303
remove is-json-schema source option from benchmarks and types
EskiMojo14 Aug 1, 2026
cc9fe32
nest conversion benchmarks under `jsonSchema.conversion.toJson`, and …
EskiMojo14 Aug 1, 2026
aa532cf
add benchmarks for fromJson conversion
EskiMojo14 Aug 1, 2026
5fc81be
add fromJson benchmark for arktype
EskiMojo14 Aug 1, 2026
ed94988
fix tests
EskiMojo14 Aug 1, 2026
9410b46
add support for fromJSON in display
EskiMojo14 Aug 1, 2026
d01a671
remove source field and only measure runtime benchmarks for JSON sche…
EskiMojo14 Aug 1, 2026
753be9b
split toJson and fromJson benchmarks into separate pages
EskiMojo14 Aug 1, 2026
072d89a
switch icons for JSON Schema conversion links in sidebar
EskiMojo14 Aug 1, 2026
826a141
update e2e tests and fixtures for JSON schema conversion pages
EskiMojo14 Aug 1, 2026
5fa7a91
fix import
EskiMojo14 Aug 1, 2026
fbfb2f4
fix navigation e2e test
EskiMojo14 Aug 1, 2026
2152938
fix accepted json schemas generation script to handle multiple toJson…
EskiMojo14 Aug 1, 2026
410b1e6
create checkbox component
EskiMojo14 Aug 2, 2026
1b616a6
record JSON schema support matrix for libraries
EskiMojo14 Aug 2, 2026
f0a700a
more route specific components into route folder
EskiMojo14 Aug 2, 2026
3e6955f
create new support matrix component
EskiMojo14 Aug 2, 2026
c961305
display reason for lack of support in checkbox tooltip
EskiMojo14 Aug 2, 2026
0ccee61
fix imports
EskiMojo14 Aug 2, 2026
d0976e0
create Tabs component with view transition support and associated styles
EskiMojo14 Aug 2, 2026
3eed829
create tab link components and add view transition support for tab na…
EskiMojo14 Aug 3, 2026
1d5c797
add support matrix tab to schema to json benchmark page
EskiMojo14 Aug 3, 2026
8b4f688
support placing controls inside list items by allowing ListItemConten…
EskiMojo14 Aug 3, 2026
3e471dc
create responsive support matrix component with table and card views
EskiMojo14 Aug 3, 2026
3d70070
remove ajv and ata fromJson benchmarks, and add sury
EskiMojo14 Aug 3, 2026
6658544
narrow generate type - we don't test runtime performance with boolean…
EskiMojo14 Aug 3, 2026
1b6effb
move standard json schema to support matrix
EskiMojo14 Aug 3, 2026
f3b78f2
add source for non-standard JSON schema conversion
EskiMojo14 Aug 3, 2026
84e3161
disable page transitions when switching tabs
EskiMojo14 Aug 3, 2026
c58b0b3
make sure e2e tests run on correct tab
EskiMojo14 Aug 3, 2026
478cf93
fix view transition issues
EskiMojo14 Aug 3, 2026
6b03b50
tests for support matrix tab in to-json page
EskiMojo14 Aug 3, 2026
018b9c1
enforce absolute paths for bench package
EskiMojo14 Aug 3, 2026
de195fe
fix output types for valibot and zod v3
EskiMojo14 Aug 4, 2026
7a07a8f
Update bench results (a212e14)
github-actions[bot] Aug 4, 2026
29d599c
fix import
EskiMojo14 Aug 4, 2026
f968e75
fix openGraph url
EskiMojo14 Aug 4, 2026
abfbdf9
prevent nested label elements in list stories
EskiMojo14 Aug 4, 2026
9a8aebd
rename standardJsonSchemaProps to jsonSourceProps for clarity
EskiMojo14 Aug 4, 2026
a044722
Update bench results (47337c6)
github-actions[bot] Aug 4, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
30 changes: 29 additions & 1 deletion .github/workflows/bench-pr.yml
Original file line number Diff line number Diff line change
Expand Up @@ -148,8 +148,31 @@ jobs:
name: bench-results
path: bench/bench.json

bench-json-schema:
needs: build-schemas
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
with:
repository: ${{ github.event.pull_request.head.repo.full_name || github.repository }}
ref: ${{ github.head_ref }}
- name: Download schemas
uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8.0.1
with:
name: schemas-build
path: schemas/dist/
- name: Setup environment
uses: ./.github/actions/environments
- name: Run JSON schema benchmark
run: pnpm bench:json-schema
- name: Upload JSON schema results
uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1
with:
name: json-schema-results
path: bench/json-schema.json

collect-results:
needs: [gate, bench-stack, bench-download, bench-bench]
needs: [gate, bench-stack, bench-download, bench-bench, bench-json-schema]
if: needs.gate.outputs.should_run == 'true' && github.event.pull_request.head.repo.full_name == github.repository
runs-on: ubuntu-latest
steps:
Expand All @@ -173,6 +196,11 @@ jobs:
with:
name: download-results
path: .
- name: Download JSON schema results
uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8.0.1
with:
name: json-schema-results
path: bench

- name: Derive short commit SHA
env:
Expand Down
28 changes: 27 additions & 1 deletion .github/workflows/bench.yml
Original file line number Diff line number Diff line change
Expand Up @@ -111,8 +111,28 @@ jobs:
name: bench-results
path: bench/bench.json

bench-json-schema:
needs: build-schemas
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
- name: Download schemas
uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8.0.1
with:
name: schemas-build
path: schemas/dist/
- name: Setup environment
uses: ./.github/actions/environments
- name: Run JSON schema benchmark
run: pnpm bench:json-schema
- name: Upload JSON schema results
uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1
with:
name: json-schema-results
path: bench/json-schema.json

collect-results:
needs: [bench-stack, bench-download, bench-bench]
needs: [bench-stack, bench-download, bench-bench, bench-json-schema]
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
Expand All @@ -132,6 +152,12 @@ jobs:
with:
name: download-results
path: .
- name: Download JSON schema results
uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8.0.1
with:
name: json-schema-results
path: bench

- name: Derive short commit SHA
env:
SOURCE_SHA: ${{ github.sha }}
Expand Down
1 change: 1 addition & 0 deletions .oxfmtrc.jsonc
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
"bench/bench.json",
"bench/download.json",
"bench/stack.json",
"bench/json-schema.json",
"schemas/libraries/**/download_compiled/**",
"schemas/libraries/**/*.gen.ts",
"website/**/routeTree.gen.ts",
Expand Down
2 changes: 1 addition & 1 deletion bench/bench.json

Large diffs are not rendered by default.

5 changes: 5 additions & 0 deletions bench/json-schema.d.json.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
import type { JsonSchemaBenchResults } from ".";

declare const results: JsonSchemaBenchResults;

export default results;
1 change: 1 addition & 0 deletions bench/json-schema.json

Large diffs are not rendered by default.

10 changes: 10 additions & 0 deletions bench/oxlint.config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,17 @@ import { baseConfig } from "../oxlint.config.ts";

export default defineConfig({
extends: [baseConfig],
jsPlugins: [
...baseConfig.jsPlugins,
{ name: "no-relative", specifier: "eslint-plugin-no-relative-import-paths" },
],
env: {
node: true,
},
rules: {
"no-relative/no-relative-import-paths": [
"error",
{ allowSameFolder: true, rootDir: "bench/src", prefix: "#src" },
],
},
});
5 changes: 5 additions & 0 deletions bench/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -4,14 +4,19 @@
"type": "module",
"main": "./src/index.ts",
"types": "./src/index.ts",
"imports": {
"#src/*": "./src/*"
},
"exports": {
".": "./src/index.ts",
"./bench.json": "./bench.json",
"./download.json": "./download.json",
"./json-schema.json": "./json-schema.json",
"./stack.json": "./stack.json"
},
"scripts": {
"bench": "node ./src/scripts/bench/orchestrate.ts",
"bench:json-schema": "node ./src/scripts/json-schema/orchestrate.ts",
"download": "node ./src/scripts/download.ts",
"stack": "node ./src/scripts/stack.ts",
"typecheck": "tsc"
Expand Down
56 changes: 46 additions & 10 deletions bench/src/bench/registry.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,29 +2,39 @@ import type {
BaseBenchmarkConfig,
BenchmarksConfig,
ErrorType,
JsonSchemaDirection,
JsonSchemaTarget,
OptimizeType,
StringFormat,
} from "@schema-benchmarks/schemas";
import type { Compute, DistributiveOmit, OneOf, Satisfies } from "@schema-benchmarks/utils";

import type { DataType } from "../results/types.ts";
import type { DataType } from "#src/results/types.ts";

export type BenchmarkType = Exclude<keyof BenchmarksConfig, "library" | "stack">;
export type BenchmarkType = Exclude<keyof BenchmarksConfig, "library" | "stack" | "jsonSchema">;

interface BaseBenchInfo extends DistributiveOmit<BaseBenchmarkConfig, "optimizeType"> {
libraryName: string;
version: string;
}

/** Every case but the JSON schema one, where how a library validates says nothing. */
interface RuntimeBenchInfo {
optimizeType: OptimizeType;
}

type BenchInfoByType = Satisfies<
{
initialization: unknown;
validation: { dataType: DataType };
parsing: { dataType: DataType; errorType: ErrorType };
standard: { dataType: DataType; errorType: ErrorType };
string: { stringFormat: StringFormat; dataType: DataType };
codec: { codecType: "encode" | "decode"; codecId: string; acceptsUnknown?: boolean };
initialization: RuntimeBenchInfo;
validation: RuntimeBenchInfo & { dataType: DataType };
parsing: RuntimeBenchInfo & { dataType: DataType; errorType: ErrorType };
standard: RuntimeBenchInfo & { dataType: DataType; errorType: ErrorType };
string: RuntimeBenchInfo & { stringFormat: StringFormat; dataType: DataType };
codec: RuntimeBenchInfo & {
codecType: "encode" | "decode";
codecId: string;
acceptsUnknown?: boolean;
};
},
Record<BenchmarkType, unknown>
>;
Expand All @@ -35,8 +45,34 @@ export type BenchmarkConfigEntry = OneOf<
}[BenchmarkType]
>;

export class CaseRegistry extends Map<string, BenchmarkConfigEntry> {
add(entry: BenchmarkConfigEntry) {
export type JsonSchemaBenchmarkType = keyof NonNullable<BenchmarksConfig["jsonSchema"]>;

export type JsonSchemaInfoByType = Satisfies<
{
conversion:
| {
conversionType: "toJson";
target: JsonSchemaTarget;
direction: JsonSchemaDirection;
jsonSchema: string;
}
| {
conversionType: "fromJson";
};
},
Record<JsonSchemaBenchmarkType, unknown>
>;

export type JsonSchemaBenchmarkConfigEntry = OneOf<
{
[Type in JsonSchemaBenchmarkType]: Compute<
{ type: Type } & BaseBenchInfo & JsonSchemaInfoByType[Type]
>;
}[JsonSchemaBenchmarkType]
>;

export class Registry<Entry> extends Map<string, Entry> {
add(entry: Entry) {
const id = crypto.randomUUID();
this.set(id, entry);
return id;
Expand Down
85 changes: 77 additions & 8 deletions bench/src/results/types.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
import {
errorTypeSchema,
jsonSchemaDirectionSchema,
jsonSchemaTargetSchema,
optimizeTypeSchema,
stringFormatSchema,
} from "@schema-benchmarks/schemas";
Expand All @@ -18,44 +20,111 @@ export const baseBenchResultSchema = v.object({
snippet: v.string(),
throws: v.optional(v.boolean()),
mean: v.number(),
optimizeType: optimizeTypeSchema,
});
export type BaseBenchResult = v.InferOutput<typeof baseBenchResultSchema>;

export const initializationResultSchema = v.object({
export const runtimeBenchResultSchema = v.object({
...baseBenchResultSchema.entries,
optimizeType: optimizeTypeSchema,
});
export type RuntimeBenchResult = v.InferOutput<typeof runtimeBenchResultSchema>;

export const initializationResultSchema = v.object({
...runtimeBenchResultSchema.entries,
type: v.literal("initialization"),
});
export type InitializationResult = v.InferOutput<typeof initializationResultSchema>;

export const validationResultSchema = v.object({
...baseBenchResultSchema.entries,
...runtimeBenchResultSchema.entries,
type: v.literal("validation"),
});
export type ValidationResult = v.InferOutput<typeof validationResultSchema>;

export const parsingResultSchema = v.object({
...baseBenchResultSchema.entries,
...runtimeBenchResultSchema.entries,
type: v.literal("parsing"),
errorType: errorTypeSchema,
});
export type ParsingResult = v.InferOutput<typeof parsingResultSchema>;

const standardResultSchema = v.object({
...baseBenchResultSchema.entries,
...runtimeBenchResultSchema.entries,
errorType: errorTypeSchema,
type: v.literal("standard"),
});
export type StandardResult = v.InferOutput<typeof standardResultSchema>;

const jsonSchemaSourceResultSchema = v.union([
v.picklist(["native", "opt-in"]),
v.object({
type: v.literal("package"),
package: v.string(),
}),
]);
export type JsonSchemaSourceResult = v.InferOutput<typeof jsonSchemaSourceResultSchema>;

const schemaConversionToJsonResultSchema = v.object({
...v.omit(baseBenchResultSchema, ["throws"]).entries,
target: jsonSchemaTargetSchema,
direction: jsonSchemaDirectionSchema,
/** The JSON schema the library generated, so it can be compared with the others. */
jsonSchema: v.string(),
});
export type SchemaToJsonResult = v.InferOutput<typeof schemaConversionToJsonResultSchema>;

const schemaConversionFromJsonResultSchema = v.object({
...v.omit(baseBenchResultSchema, ["throws"]).entries,
});
export type SchemaFromJsonResult = v.InferOutput<typeof schemaConversionFromJsonResultSchema>;

export type JsonSchemaConversionResult = OneOf<SchemaToJsonResult | SchemaFromJsonResult>;

export const jsonSchemaSupportMatrixSchema = v.object(
v.entriesFromList(
jsonSchemaTargetSchema.options,
v.optional(
v.object(v.entriesFromList(jsonSchemaDirectionSchema.options, v.optional(v.string()))),
),
),
);
export type JsonSchemaSupportMatrix = v.InferOutput<typeof jsonSchemaSupportMatrixSchema>;

export const jsonSchemaSupportMatricesSchema = v.record(
v.string(),
v.object({
version: v.string(),
source: jsonSchemaSourceResultSchema,
standardJsonSchema: v.optional(jsonSchemaSourceResultSchema),
matrix: jsonSchemaSupportMatrixSchema,
}),
);
export type JsonSchemaSupportMatrices = v.InferOutput<typeof jsonSchemaSupportMatricesSchema>;

export const jsonSchemaBenchResultsSchema = v.object({
conversion: v.object({
toJson: v.array(schemaConversionToJsonResultSchema),
fromJson: v.array(schemaConversionFromJsonResultSchema),
toJsonSupport: jsonSchemaSupportMatricesSchema,
}),
});
export type JsonSchemaBenchResults = v.InferOutput<typeof jsonSchemaBenchResultsSchema>;
export const getEmptyJsonSchemaResults = (): JsonSchemaBenchResults => ({
conversion: {
toJson: [],
fromJson: [],
toJsonSupport: {},
},
});

const stringResultSchema = v.object({
...baseBenchResultSchema.entries,
...runtimeBenchResultSchema.entries,
type: v.literal("string"),
});
export type StringResult = v.InferOutput<typeof stringResultSchema>;

export const codecResultSchema = v.object({
...v.omit(baseBenchResultSchema, ["snippet", "mean"]).entries,
...v.omit(runtimeBenchResultSchema, ["snippet", "mean"]).entries,
encode: v.object({
snippet: v.string(),
mean: v.number(),
Expand All @@ -70,7 +139,7 @@ export const codecResultSchema = v.object({

export type CodecResult = v.InferOutput<typeof codecResultSchema>;

export type BenchResult = OneOf<
export type RuntimeResult = OneOf<
InitializationResult | ValidationResult | ParsingResult | StandardResult | StringResult
>;

Expand Down
Loading
Loading