Skip to content

Commit 3b064b1

Browse files
committed
Redesign operation cache
1 parent b7d2346 commit 3b064b1

40 files changed

+798
-1269
lines changed

IDEAS.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,8 @@
66
- Add `S.uint8Array` and `S.enableUint8Array`
77
- Updated `InvalidType` error code to include the received schema
88
- Updated internal representation of object schema - removed `items` fields. Updated internalt representation of tuple schema - `items` field is now an array of schemas instead of array of items. The `item` type is removed.
9+
- Removed `Failed parsing/converting/asserting` when the error is at root
10+
- Renamed `Failed parsing/converting/asserting at path` to `Failed at path`
911

1012
### TS
1113

docs/js-usage.md

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -97,7 +97,7 @@ If the data is invalid, the function will throw an error.
9797

9898
```ts
9999
S.parser(Player)({ username: "billie", xp: "not a number" });
100-
// => throws S.Error: Failed parsing at ["xp"]: Expected number, got string
100+
// => throws S.Error: Failed at ["xp"]: Expected number, got string
101101
```
102102

103103
**Sury** API explicitly tells you that it might throw an error. If you need you can catch it and perform `err instanceof S.Error` check. But **Sury** provides a convenient API which does it for you:
@@ -290,7 +290,7 @@ S.assert(
290290
}),
291291
"example.com"
292292
);
293-
// Throws S.Error: Failed asserting: Invalid email address
293+
// Throws S.Error: Invalid email address
294294
```
295295

296296
### Standard Schema
@@ -852,7 +852,7 @@ const TestSchema = S.instance(Test);
852852

853853
const blob: any = "whatever";
854854
S.parser(TestSchema)(new Test()); // passes
855-
S.parser(TestSchema)(blob); // throws S.Error: Failed parsing: Expected Test, received "whatever"
855+
S.parser(TestSchema)(blob); // throws S.Error: Expected Test, received "whatever"
856856
```
857857

858858
## Meta
@@ -945,8 +945,8 @@ const numberSetSchema = mySet(S.number);
945945
type NumberSet = S.Infer<typeof numberSetSchema>; // Set<number>
946946

947947
S.parser(numberSetSchema)(new Set([1, 2, 3])); // passes
948-
S.parser(numberSetSchema)(new Set([1, 2, "3"])); // throws S.Error: Failed parsing: At item 3 - Expected number, received "3"
949-
S.parser(numberSetSchema)([1, 2, 3]); // throws S.Error: Failed parsing: Expected Set<number>, received [1, 2, 3]
948+
S.parser(numberSetSchema)(new Set([1, 2, "3"])); // throws S.Error: At item 3 - Expected number, received "3"
949+
S.parser(numberSetSchema)([1, 2, 3]); // throws S.Error: Expected Set<number>, received [1, 2, 3]
950950
```
951951

952952
## Recursive schemas
@@ -1134,7 +1134,7 @@ S.parser(reversed)("bar");
11341134
// {"foo": "bar"}
11351135

11361136
S.parser(reversed)(123);
1137-
// throws S.error with the message: `Failed parsing: Expected string, received 123`
1137+
// throws S.error with the message: `Expected string, received 123`
11381138
```
11391139

11401140
Reverses the schema. This gets especially magical for schemas with transformations 🪄
@@ -1147,7 +1147,7 @@ This very powerful API allows you to coerce another data type in a declarative w
11471147
const schema = S.string.with(S.to, S.number);
11481148

11491149
S.parser(schema)("123"); //? 123.
1150-
S.parser(schema)("abc"); //? throws: Failed parsing: Expected number, received "abc"
1150+
S.parser(schema)("abc"); //? throws: Expected number, received "abc"
11511151

11521152
// Reverse works correctly as well 🔥
11531153
S.encoder(schema)(123); //? "123"
@@ -1176,7 +1176,7 @@ const schema = S.string.with(
11761176
);
11771177

11781178
S.parser(schema)("123"); //? 123
1179-
S.parser(schema)("abc"); //? throws: Failed parsing: Invalid number
1179+
S.parser(schema)("abc"); //? throws: Invalid number
11801180

11811181
S.encodeOrThrow(schema)(123); //? "123"
11821182
```
@@ -1213,7 +1213,7 @@ Used internally for readable error messages.
12131213

12141214
```ts
12151215
S.parser(S.schema(false))(true);
1216-
// => Throws S.Error with the following message: Failed parsing: Expected false, received true".
1216+
// => Throws S.Error with the following message: Expected false, received true".
12171217
```
12181218

12191219
You can catch the error using `S.safe` and `S.safeAsync` helpers:

docs/rescript-usage.md

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -676,7 +676,7 @@ let schema = S.object(_ => ())->S.strict
676676
{
677677
"someField": "value",
678678
}->S.parseOrThrow(schema)
679-
// throws S.error with the message: `Failed parsing: Unrecognized key "unknownKey"`
679+
// throws S.error with the message: `Unrecognized key "unknownKey"`
680680
```
681681

682682
By default **Sury** silently strips unrecognized keys when parsing objects. You can change the behaviour to disallow unrecognized keys with the `S.strict` function.
@@ -1037,7 +1037,7 @@ The `S.unknown` schema represents any data.
10371037
let schema = S.never
10381038
10391039
%raw(`undefined`)->S.parseOrThrow(schema)
1040-
// throws S.error with the message: `Failed parsing: Expected never, received undefined`
1040+
// throws S.error with the message: `Expected never, received undefined`
10411041
```
10421042

10431043
The `never` schema will fail parsing for every value.
@@ -1192,8 +1192,8 @@ let mySet = itemSchema => {
11921192
let intSetSchema = mySet(S.int)
11931193
11941194
S.parseOrThrow(%raw(`new Set([1, 2, 3])`), intSetSchema) // passes
1195-
S.parseOrThrow(%raw(`new Set([1, 2, "3"])`), intSetSchema) // throws S.Error: Failed parsing: Expected int32, received "3"
1196-
S.parseOrThrow(%raw(`[1, 2, 3]`), intSetSchema) // throws S.Error: Failed parsing: Expected Set.t<int32>, received [1, 2, 3]
1195+
S.parseOrThrow(%raw(`new Set([1, 2, "3"])`), intSetSchema) // throws S.Error: Expected int32, received "3"
1196+
S.parseOrThrow(%raw(`[1, 2, 3]`), intSetSchema) // throws S.Error: Expected Set.t<int32>, received [1, 2, 3]
11971197
```
11981198

11991199
## Refinements
@@ -1382,7 +1382,7 @@ let reversed = schema->S.reverse
13821382
// {"foo": "bar"}
13831383
13841384
123->S.parseOrThrow(reversed)
1385-
// throws S.error with the message: `Failed parsing: Expected string, received 123`
1385+
// throws S.error with the message: `Expected string, received 123`
13861386
```
13871387

13881388
Reverses the schema. This gets especially magical for schemas with transformations 🪄
@@ -1397,7 +1397,7 @@ This very powerful API allows you to coerce another data type in a declarative w
13971397
let schema = S.string->S.to(S.float)
13981398
13991399
"123"->S.parseOrThrow(schema) //? 123.
1400-
"abc"->S.parseOrThrow(schema) //? throws: Failed parsing: Expected number, received "abc"
1400+
"abc"->S.parseOrThrow(schema) //? throws: Expected number, received "abc"
14011401
14021402
// Reverse works correctly as well 🔥
14031403
123.->S.reverseConvertOrThrow(schema) //? "123"
@@ -1467,7 +1467,7 @@ This can be useful to optimise `S.object` parsing when you construct the input d
14671467
let schema = S.literal(false)
14681468
14691469
true->S.parseOrThrow(schema)
1470-
// throws S.error with the message: `Failed parsing: Expected false, received true`
1470+
// throws S.error with the message: `Expected false, received true`
14711471
```
14721472

14731473
If you want to handle the error, the best way to use `try/catch` block:

packages/sury/scripts/pack/Pack.res

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -144,7 +144,7 @@ let filesMapping = [
144144
("reverse", "S.reverse"),
145145
("parser", "S.parser"),
146146
("asyncParser", "S.asyncParser"),
147-
("decoder", "S.decoder"),
147+
("decoder", "S.getDecoder"),
148148
("asyncDecoder", "S.asyncDecoder"),
149149
("encoder", "S.encoder"),
150150
("asyncEncoder", "S.asyncEncoder"),

packages/sury/scripts/pack/Pack.res.mjs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -183,7 +183,7 @@ let filesMapping = [
183183
],
184184
[
185185
"decoder",
186-
"S.decoder"
186+
"S.getDecoder"
187187
],
188188
[
189189
"asyncDecoder",

packages/sury/src/S.js

Lines changed: 70 additions & 70 deletions
Original file line numberDiff line numberDiff line change
@@ -1,71 +1,71 @@
11
/* @ts-self-types="./S.d.ts" */
2-
import * as S from "./Sury.res.mjs"
3-
export { unit as void } from "./Sury.res.mjs"
4-
export var Error = S.ErrorClass.value
5-
export var string = S.string
6-
export var boolean = S.bool
7-
export var int32 = S.int
8-
export var number = S.float
9-
export var bigint = S.bigint
10-
export var symbol = S.symbol
11-
export var never = S.never
12-
export var unknown = S.unknown
13-
export var any = S.unknown
14-
export var optional = S.js_optional
15-
export var nullable = S.js_nullable
16-
export var nullish = S.nullable
17-
export var array = S.array
18-
export var instance = S.instance
19-
export var unnest = S.unnest
20-
export var record = S.dict
21-
export var json = S.json
22-
export var enableJson = S.enableJson
23-
export var jsonString = S.jsonString
24-
export var enableJsonString = S.enableJsonString
25-
export var jsonStringWithSpace = S.jsonStringWithSpace
26-
export var uint8Array = S.uint8Array
27-
export var enableUint8Array = S.enableUint8Array
28-
export var union = S.js_union
29-
export var object = S.object
30-
export var schema = S.js_schema
31-
export var safe = S.js_safe
32-
export var safeAsync = S.js_safeAsync
33-
export var reverse = S.reverse
34-
export var parser = S.parser
35-
export var asyncParser = S.asyncParser
36-
export var decoder = S.decoder
37-
export var asyncDecoder = S.asyncDecoder
38-
export var encoder = S.encoder
39-
export var asyncEncoder = S.asyncEncoder
40-
export var assert = S.js_assert
41-
export var recursive = S.recursive
42-
export var merge = S.js_merge
43-
export var strict = S.strict
44-
export var deepStrict = S.deepStrict
45-
export var strip = S.strip
46-
export var deepStrip = S.deepStrip
47-
export var to = S.js_to
48-
export var toJSONSchema = S.toJSONSchema
49-
export var fromJSONSchema = S.fromJSONSchema
50-
export var extendJSONSchema = S.extendJSONSchema
51-
export var shape = S.shape
52-
export var tuple = S.tuple
53-
export var asyncParserRefine = S.js_asyncParserRefine
54-
export var refine = S.js_refine
55-
export var meta = S.meta
56-
export var toExpression = S.toExpression
57-
export var noValidation = S.noValidation
58-
export var compile = S.compile
59-
export var port = S.port
60-
export var min = S.min
61-
export var max = S.max
62-
export var length = S.length
63-
export var email = S.email
64-
export var uuid = S.uuid
65-
export var cuid = S.cuid
66-
export var url = S.url
67-
export var pattern = S.pattern
68-
export var datetime = S.datetime
69-
export var trim = S.trim
70-
export var global = S.global
71-
export var brand = S.brand
2+
import * as S from "./Sury.res.mjs";
3+
export { unit as void } from "./Sury.res.mjs";
4+
export var Error = S.ErrorClass.value;
5+
export var string = S.string;
6+
export var boolean = S.bool;
7+
export var int32 = S.int;
8+
export var number = S.float;
9+
export var bigint = S.bigint;
10+
export var symbol = S.symbol;
11+
export var never = S.never;
12+
export var unknown = S.unknown;
13+
export var any = S.unknown;
14+
export var optional = S.js_optional;
15+
export var nullable = S.js_nullable;
16+
export var nullish = S.nullable;
17+
export var array = S.array;
18+
export var instance = S.instance;
19+
export var unnest = S.unnest;
20+
export var record = S.dict;
21+
export var json = S.json;
22+
export var enableJson = S.enableJson;
23+
export var jsonString = S.jsonString;
24+
export var enableJsonString = S.enableJsonString;
25+
export var jsonStringWithSpace = S.jsonStringWithSpace;
26+
export var uint8Array = S.uint8Array;
27+
export var enableUint8Array = S.enableUint8Array;
28+
export var union = S.js_union;
29+
export var object = S.object;
30+
export var schema = S.js_schema;
31+
export var safe = S.js_safe;
32+
export var safeAsync = S.js_safeAsync;
33+
export var reverse = S.reverse;
34+
export var parser = S.parser;
35+
export var asyncParser = S.asyncParser;
36+
export var decoder = S.getDecoder;
37+
export var asyncDecoder = S.asyncDecoder;
38+
export var encoder = S.encoder;
39+
export var asyncEncoder = S.asyncEncoder;
40+
export var assert = S.js_assert;
41+
export var recursive = S.recursive;
42+
export var merge = S.js_merge;
43+
export var strict = S.strict;
44+
export var deepStrict = S.deepStrict;
45+
export var strip = S.strip;
46+
export var deepStrip = S.deepStrip;
47+
export var to = S.js_to;
48+
export var toJSONSchema = S.toJSONSchema;
49+
export var fromJSONSchema = S.fromJSONSchema;
50+
export var extendJSONSchema = S.extendJSONSchema;
51+
export var shape = S.shape;
52+
export var tuple = S.tuple;
53+
export var asyncParserRefine = S.js_asyncParserRefine;
54+
export var refine = S.js_refine;
55+
export var meta = S.meta;
56+
export var toExpression = S.toExpression;
57+
export var noValidation = S.noValidation;
58+
export var compile = S.compile;
59+
export var port = S.port;
60+
export var min = S.min;
61+
export var max = S.max;
62+
export var length = S.length;
63+
export var email = S.email;
64+
export var uuid = S.uuid;
65+
export var cuid = S.cuid;
66+
export var url = S.url;
67+
export var pattern = S.pattern;
68+
export var datetime = S.datetime;
69+
export var trim = S.trim;
70+
export var global = S.global;
71+
export var brand = S.brand;

packages/sury/src/S.res.mjs

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -76,7 +76,9 @@ let shape = Sury.shape;
7676

7777
let to = Sury.to;
7878

79-
let compile = Sury.compile;
79+
let makeConvertOrThrow = Sury.makeConvertOrThrow;
80+
81+
let makeAsyncConvertOrThrow = Sury.makeAsyncConvertOrThrow;
8082

8183
let parseOrThrow = Sury.parseOrThrow;
8284

@@ -224,7 +226,8 @@ export {
224226
refine,
225227
shape,
226228
to,
227-
compile,
229+
makeConvertOrThrow,
230+
makeAsyncConvertOrThrow,
228231
parseOrThrow,
229232
parseJsonOrThrow,
230233
parseJsonStringOrThrow,

packages/sury/src/S.resi

Lines changed: 2 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -273,11 +273,7 @@ type s<'value> = {
273273

274274
module Flag: {
275275
@inline let none: flag
276-
@inline let typeValidation: flag
277276
@inline let async: flag
278-
@inline let assertOutput: flag
279-
@inline let jsonableOutput: flag
280-
@inline let jsonStringOutput: flag
281277

282278
external with: (flag, flag) => flag = "%orint"
283279
let has: (flag, flag) => bool
@@ -335,29 +331,8 @@ let shape: (t<'value>, 'value => 'shape) => t<'shape>
335331

336332
let to: (t<'from>, t<'to>) => t<'to>
337333

338-
type rec input<'value, 'computed> =
339-
| @as("Output") Value: input<'value, 'value>
340-
| @as("Input") Unknown: input<'value, unknown>
341-
| Any: input<'value, 'any>
342-
| Json: input<'value, Js.Json.t>
343-
| JsonString: input<'value, string>
344-
type rec output<'value, 'computed> =
345-
| @as("Output") Value: output<'value, 'value>
346-
| @as("Input") Unknown: output<'value, unknown>
347-
| Assert: output<'value, unit>
348-
| Json: output<'value, Js.Json.t>
349-
| JsonString: output<'value, string>
350-
type rec mode<'output, 'computed> =
351-
| Sync: mode<'output, 'output>
352-
| Async: mode<'output, promise<'output>>
353-
354-
let compile: (
355-
t<'value>,
356-
~input: input<'value, 'input>,
357-
~output: output<'value, 'transformedOutput>,
358-
~mode: mode<'transformedOutput, 'output>,
359-
~typeValidation: bool=?,
360-
) => 'input => 'output
334+
let makeConvertOrThrow: (t<'from>, t<'to>, ~flag: flag=?) => 'from => 'to
335+
let makeAsyncConvertOrThrow: (t<'from>, t<'to>, ~flag: flag=?) => 'from => promise<'to>
361336

362337
let parseOrThrow: ('any, t<'value>) => 'value
363338
let parseJsonOrThrow: (Js.Json.t, t<'value>) => 'value

0 commit comments

Comments
 (0)