Skip to content

Commit

Permalink
v8.0.2 🚀
Browse files Browse the repository at this point in the history
  • Loading branch information
DZakh committed Jul 28, 2024
1 parent bc3089c commit f43ef80
Show file tree
Hide file tree
Showing 5 changed files with 63 additions and 4 deletions.
21 changes: 21 additions & 0 deletions docs/js-usage.md
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@
- [JSON string](#json-string)
- [Describe](#describe)
- [Custom schema](#custom-schema)
- [Recursive schemas](#recursive-schemas)
- [Refinements](#refinements)
- [Transforms](#transforms)
- [Functions on schema](#functions-on-schema)
Expand Down Expand Up @@ -486,6 +487,26 @@ const mySetSchema = S.custom("MySet", (input, s) => {
type MySet = S.Output<typeof mySetSchema>; // Set<any>
```

## Recursive schemas

You can define a recursive schema in **rescript-schema**. Unfortunately, TypeScript derives the Schema type as `unknown` so you need to explicitly specify the type and it'll start correctly typechecking.

```ts
type Node = {
id: string;
children: Node[];
};

let nodeSchema = S.recursive<Node>((nodeSchema) =>
S.object({
id: S.string,
children: S.array(nodeSchema),
})
);
```

> 🧠 Despite supporting recursive schema, passing cyclical data into rescript-schema will cause an infinite loop.
## Refinements

**rescript-schema** lets you provide custom validation logic via refinements. It's useful to add checks that's not possible to cover with type system. For instance: checking that a number is an integer or that a string is a valid email address.
Expand Down
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "rescript-schema",
"version": "8.0.1",
"version": "8.0.2",
"description": "🧬 The fastest parser in the entire JavaScript ecosystem with a focus on small bundle size and top-notch DX",
"keywords": [
"ReScript",
Expand Down
33 changes: 33 additions & 0 deletions packages/tests/src/core/S_test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1328,6 +1328,39 @@ test("Assert passes with valid data", (t) => {
t.pass();
});

test("Successfully parses recursive object", (t) => {
type Node = {
id: string;
children: Node[];
};

let nodeSchema = S.recursive<Node>((nodeSchema) =>
S.object({
id: S.string,
children: S.array(nodeSchema),
})
);

expectType<TypeEqual<typeof nodeSchema, S.Schema<Node, Node>>>(true);

t.deepEqual(
nodeSchema.parseOrThrow({
id: "1",
children: [
{ id: "2", children: [] },
{ id: "3", children: [{ id: "4", children: [] }] },
],
}),
{
id: "1",
children: [
{ id: "2", children: [] },
{ id: "3", children: [{ id: "4", children: [] }] },
],
}
);
});

test("Example", (t) => {
// Create login schema with email and password
const loginSchema = S.object({
Expand Down
10 changes: 7 additions & 3 deletions src/S.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -86,7 +86,7 @@ export function tuple<A extends UnknownSchema, B extends UnknownSchema[]>(
[Input<A>, ...SchemaTupleInput<B>]
>;
export function tuple<Output>(
definer: (ctx: {
definer: (s: {
item: <InputIndex extends number, ItemOutput>(
inputIndex: InputIndex,
schema: Schema<ItemOutput, unknown>
Expand Down Expand Up @@ -136,13 +136,13 @@ export const union: <A extends UnknownSchema, B extends UnknownSchema[]>(
>;

export function schema<Value>(
definer: (ctx: {
definer: (s: {
matches: <Output>(schema: Schema<Output, unknown>) => Output;
}) => Value
): Schema<Value, unknown>;

export function object<Output>(
definer: (ctx: {
definer: (s: {
field: <InputFieldName extends string, FieldOutput>(
inputFieldName: InputFieldName,
schema: Schema<FieldOutput, unknown>
Expand Down Expand Up @@ -194,6 +194,10 @@ export function custom<Output, Input = unknown>(
serializer: (value: Output, s: EffectCtx<unknown, unknown>) => Input
): Schema<Output, Input>;

export function recursive<Output, Input = Output>(
definer: (schema: Schema<Output, Input>) => Schema<Output, Input>
): Schema<Output, Input>;

export function name(schema: Schema<unknown, unknown>): string;
export function setName<Output, Input>(
schema: Schema<Output, Input>,
Expand Down
1 change: 1 addition & 0 deletions src/S.js
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ export const jsonString = S.jsonString;
export const union = S.union;
export const object = S.js_object;
export const schema = S.schema;
export const recursive = S.recursive;
export const merge = S.js_merge;
export const Object = S.$$Object;
export const custom = S.js_custom;
Expand Down

1 comment on commit f43ef80

@github-actions
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Benchmark

Benchmark suite Current: f43ef80 Previous: 315a5ee Ratio
Parse string 818941691 ops/sec (±0.10%) 819212043 ops/sec (±0.14%) 1.00
Serialize string 819866798 ops/sec (±0.08%) 820083660 ops/sec (±0.06%) 1.00
Advanced object schema factory 480449 ops/sec (±0.14%) 467043 ops/sec (±0.75%) 0.97
Parse advanced object 56339978 ops/sec (±0.99%) 57303490 ops/sec (±0.58%) 1.02
Assert advanced object 173990167 ops/sec (±0.08%) 173972597 ops/sec (±0.13%) 1.00
Create and parse advanced object 95005 ops/sec (±0.34%) 95135 ops/sec (±0.17%) 1.00
Parse advanced strict object 25408704 ops/sec (±0.33%) 25413209 ops/sec (±1.32%) 1.00
Assert advanced strict object 30514617 ops/sec (±0.61%) 30800487 ops/sec (±0.22%) 1.01
Serialize advanced object 75224894 ops/sec (±0.31%) 74296846 ops/sec (±0.34%) 0.99

This comment was automatically generated by workflow using github-action-benchmark.

Please sign in to comment.