@fncts/schema 0.0.14 → 0.0.15
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/AST.d.ts +29 -12
- package/Guard.d.ts +9 -0
- package/ParseError.d.ts +40 -3
- package/Parser/api.d.ts +0 -6
- package/Parser/interpreter.d.ts +1 -2
- package/Show.d.ts +1 -1
- package/_cjs/AST.cjs +115 -65
- package/_cjs/AST.cjs.map +1 -1
- package/_cjs/Guard.cjs +278 -0
- package/_cjs/Guard.cjs.map +1 -0
- package/_cjs/ParseError.cjs +77 -3
- package/_cjs/ParseError.cjs.map +1 -1
- package/_cjs/Parser/api.cjs +11 -23
- package/_cjs/Parser/api.cjs.map +1 -1
- package/_cjs/Parser/interpreter.cjs +93 -141
- package/_cjs/Parser/interpreter.cjs.map +1 -1
- package/_cjs/Schema/api.cjs +27 -28
- package/_cjs/Schema/api.cjs.map +1 -1
- package/_cjs/Show.cjs +23 -12
- package/_cjs/Show.cjs.map +1 -1
- package/_mjs/AST.mjs +107 -61
- package/_mjs/AST.mjs.map +1 -1
- package/_mjs/Guard.mjs +269 -0
- package/_mjs/Guard.mjs.map +1 -0
- package/_mjs/ParseError.mjs +72 -2
- package/_mjs/ParseError.mjs.map +1 -1
- package/_mjs/Parser/api.mjs +10 -21
- package/_mjs/Parser/api.mjs.map +1 -1
- package/_mjs/Parser/interpreter.mjs +94 -142
- package/_mjs/Parser/interpreter.mjs.map +1 -1
- package/_mjs/Schema/api.mjs +27 -28
- package/_mjs/Schema/api.mjs.map +1 -1
- package/_mjs/Show.mjs +23 -12
- package/_mjs/Show.mjs.map +1 -1
- package/_src/AST.ts +96 -47
- package/_src/Guard.ts +268 -0
- package/_src/ParseError.ts +88 -4
- package/_src/Parser/api.ts +8 -21
- package/_src/Parser/interpreter.ts +87 -121
- package/_src/Schema/api.ts +3 -10
- package/_src/Show.ts +28 -15
- package/package.json +3 -3
|
@@ -1,8 +1,7 @@
|
|
|
1
|
-
import type { Literal } from "../AST.js";
|
|
2
|
-
import type { Hook } from "../ASTAnnotation.js";
|
|
3
1
|
import type { MutableVector } from "@fncts/base/collection/immutable/Vector";
|
|
4
2
|
import type { Validation } from "@fncts/base/data/Branded";
|
|
5
3
|
|
|
4
|
+
import { globalValue } from "@fncts/base/data/Global";
|
|
6
5
|
import {
|
|
7
6
|
isBigInt,
|
|
8
7
|
isBoolean,
|
|
@@ -14,10 +13,32 @@ import {
|
|
|
14
13
|
isUndefined,
|
|
15
14
|
} from "@fncts/base/util/predicates";
|
|
16
15
|
|
|
17
|
-
import { ASTTag, concrete } from "../AST.js";
|
|
16
|
+
import { ASTTag, concrete, getSearchTree } from "../AST.js";
|
|
17
|
+
import { RefinementError, TransformationError } from "../ParseError.js";
|
|
18
18
|
import { getKeysForIndexSignature, getTemplateLiteralRegex, memoize, ownKeys } from "../utils.js";
|
|
19
19
|
|
|
20
|
-
const
|
|
20
|
+
const decodeMemoMap = globalValue(
|
|
21
|
+
Symbol.for("fncts.schema.Parser.decodeMemoMap"),
|
|
22
|
+
() => new WeakMap<AST, Parser<any>>(),
|
|
23
|
+
);
|
|
24
|
+
|
|
25
|
+
const encodeMemoMap = globalValue(
|
|
26
|
+
Symbol.for("fncts.schema.Parser.encodeMemoMap"),
|
|
27
|
+
() => new WeakMap<AST, Parser<any>>(),
|
|
28
|
+
);
|
|
29
|
+
|
|
30
|
+
function goMemo(ast: AST, isDecoding: boolean): Parser<any> {
|
|
31
|
+
const memoMap = isDecoding ? decodeMemoMap : encodeMemoMap;
|
|
32
|
+
const memo = memoMap.get(ast);
|
|
33
|
+
if (memo) {
|
|
34
|
+
return memo;
|
|
35
|
+
}
|
|
36
|
+
const parser = go(ast, isDecoding);
|
|
37
|
+
memoMap.set(ast, parser);
|
|
38
|
+
return parser;
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
function go(ast: AST, isDecoding: boolean): Parser<any> {
|
|
21
42
|
concrete(ast);
|
|
22
43
|
switch (ast._tag) {
|
|
23
44
|
case ASTTag.Declaration:
|
|
@@ -53,18 +74,18 @@ const go = memoize(function go(ast: AST): Parser<any> {
|
|
|
53
74
|
return Parser.fromRefinement(ast, (u): u is any => isString(u) && regex.test(u));
|
|
54
75
|
}
|
|
55
76
|
case ASTTag.Tuple: {
|
|
56
|
-
const elements = ast.elements.map((e) =>
|
|
57
|
-
const rest = ast.rest.map((rest) => rest.map(
|
|
77
|
+
const elements = ast.elements.map((e) => goMemo(e.type, isDecoding));
|
|
78
|
+
const rest = ast.rest.map((rest) => rest.map((ast) => goMemo(ast, isDecoding)));
|
|
58
79
|
return Parser.make((input, options) => {
|
|
59
80
|
if (!Array.isArray(input)) {
|
|
60
|
-
return ParseResult.fail(ParseError.TypeError(unknownArray, input));
|
|
81
|
+
return ParseResult.fail(ParseError.TypeError(AST.unknownArray, input));
|
|
61
82
|
}
|
|
62
83
|
const output: Array<any> = [];
|
|
63
84
|
const errors: MutableVector<ParseError> = Vector.emptyPushable();
|
|
64
85
|
const allErrors = options?.allErrors;
|
|
65
86
|
let i = 0;
|
|
66
87
|
for (; i < elements.length; i++) {
|
|
67
|
-
if (input.length < i +
|
|
88
|
+
if (input.length < i + 1) {
|
|
68
89
|
if (!ast.elements[i]!.isOptional) {
|
|
69
90
|
const e = ParseError.IndexError(i, Vector(ParseError.MissingError));
|
|
70
91
|
errors.push(e);
|
|
@@ -73,23 +94,24 @@ const go = memoize(function go(ast: AST): Parser<any> {
|
|
|
73
94
|
} else {
|
|
74
95
|
return ParseResult.failures(errors);
|
|
75
96
|
}
|
|
76
|
-
}
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
97
|
+
}
|
|
98
|
+
} else {
|
|
99
|
+
const parser = elements[i]!;
|
|
100
|
+
const t = parser(input[i], options);
|
|
101
|
+
Either.concrete(t);
|
|
102
|
+
if (t.isLeft()) {
|
|
103
|
+
const e = ParseError.IndexError(i, t.left.errors);
|
|
104
|
+
errors.push(e);
|
|
105
|
+
if (allErrors) {
|
|
106
|
+
continue;
|
|
107
|
+
} else {
|
|
108
|
+
return ParseResult.failures(errors);
|
|
88
109
|
}
|
|
89
|
-
output.push(t.right);
|
|
90
110
|
}
|
|
111
|
+
output.push(t.right);
|
|
91
112
|
}
|
|
92
113
|
}
|
|
114
|
+
|
|
93
115
|
if (rest.isJust()) {
|
|
94
116
|
const head = rest.value.unsafeHead!;
|
|
95
117
|
const tail = rest.value.tail;
|
|
@@ -148,11 +170,13 @@ const go = memoize(function go(ast: AST): Parser<any> {
|
|
|
148
170
|
if (ast.propertySignatures.length === 0 && ast.indexSignatures.length === 0) {
|
|
149
171
|
return Parser.fromRefinement(ast, (u): u is Exclude<typeof u, null> => u !== null);
|
|
150
172
|
}
|
|
151
|
-
const propertySignatureTypes = ast.propertySignatures.map((f) =>
|
|
152
|
-
const indexSignatures = ast.indexSignatures.map(
|
|
173
|
+
const propertySignatureTypes = ast.propertySignatures.map((f) => goMemo(f.type, isDecoding));
|
|
174
|
+
const indexSignatures = ast.indexSignatures.map(
|
|
175
|
+
(is) => [goMemo(is.parameter, isDecoding), goMemo(is.type, isDecoding)] as const,
|
|
176
|
+
);
|
|
153
177
|
return Parser.make((input, options) => {
|
|
154
178
|
if (!isRecord(input)) {
|
|
155
|
-
return ParseResult.fail(ParseError.TypeError(unknownRecord, input));
|
|
179
|
+
return ParseResult.fail(ParseError.TypeError(AST.unknownRecord, input));
|
|
156
180
|
}
|
|
157
181
|
const output: any = {};
|
|
158
182
|
const expectedKeys: any = {};
|
|
@@ -247,13 +271,13 @@ const go = memoize(function go(ast: AST): Parser<any> {
|
|
|
247
271
|
});
|
|
248
272
|
}
|
|
249
273
|
case ASTTag.Union: {
|
|
250
|
-
const searchTree = getSearchTree(ast.types);
|
|
274
|
+
const searchTree = getSearchTree(ast.types, isDecoding);
|
|
251
275
|
const ownKeys = Reflect.ownKeys(searchTree.keys);
|
|
252
276
|
const len = ownKeys.length;
|
|
253
277
|
const otherwise = searchTree.otherwise;
|
|
254
278
|
const map = new Map<any, Parser<any>>();
|
|
255
279
|
ast.types.forEach((ast) => {
|
|
256
|
-
map.set(ast,
|
|
280
|
+
map.set(ast, goMemo(ast, isDecoding));
|
|
257
281
|
});
|
|
258
282
|
return Parser.make((input, options) => {
|
|
259
283
|
const errors = Vector.emptyPushable<ParseError>();
|
|
@@ -289,7 +313,7 @@ const go = memoize(function go(ast: AST): Parser<any> {
|
|
|
289
313
|
}
|
|
290
314
|
}
|
|
291
315
|
} else {
|
|
292
|
-
errors.push(ParseError.TypeError(unknownRecord, input));
|
|
316
|
+
errors.push(ParseError.TypeError(AST.unknownRecord, input));
|
|
293
317
|
}
|
|
294
318
|
}
|
|
295
319
|
for (let i = 0; i < otherwise.length; i++) {
|
|
@@ -308,33 +332,52 @@ const go = memoize(function go(ast: AST): Parser<any> {
|
|
|
308
332
|
});
|
|
309
333
|
}
|
|
310
334
|
case ASTTag.Lazy: {
|
|
311
|
-
const f = () =>
|
|
335
|
+
const f = () => goMemo(ast.getAST(), isDecoding);
|
|
312
336
|
const get = memoize<void, Parser<any>>(f);
|
|
313
337
|
return Parser.make((a, options) => get()(a, options));
|
|
314
338
|
}
|
|
315
339
|
case ASTTag.Refinement: {
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
|
|
340
|
+
if (isDecoding) {
|
|
341
|
+
const from = goMemo(ast.from, isDecoding);
|
|
342
|
+
return Parser.make((input, options) =>
|
|
343
|
+
from(input, options)
|
|
344
|
+
.mapLeft((failure) => ParseFailure(Vector(RefinementError(ast, input, "From", failure.errors))))
|
|
345
|
+
.flatMap((a) =>
|
|
346
|
+
ast
|
|
347
|
+
.decode(a, options)
|
|
348
|
+
.mapLeft((failure) => ParseFailure(Vector(RefinementError(ast, input, "Predicate", failure.errors)))),
|
|
349
|
+
),
|
|
350
|
+
);
|
|
351
|
+
} else {
|
|
352
|
+
const from = goMemo(ast.from, true);
|
|
353
|
+
const to = goMemo(ast.from.getTo, false);
|
|
319
354
|
return Parser.make((input, options) =>
|
|
320
355
|
to(input, options)
|
|
321
356
|
.flatMap((a) => ast.decode(a, options))
|
|
322
357
|
.flatMap((a) => from(a, options)),
|
|
323
358
|
);
|
|
324
359
|
}
|
|
325
|
-
return Parser.make((input, options) => from(input, options).flatMap((a) => ast.decode(a, options)));
|
|
326
360
|
}
|
|
327
361
|
case ASTTag.Transform: {
|
|
328
|
-
const
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
|
|
362
|
+
const transformation = isDecoding ? ast.decode : ast.encode;
|
|
363
|
+
const from = isDecoding ? goMemo(ast.from, true) : goMemo(ast.to, false);
|
|
364
|
+
const to = isDecoding ? goMemo(ast.to, true) : goMemo(ast.from, false);
|
|
365
|
+
return Parser.make((input, options) =>
|
|
366
|
+
from(input, options)
|
|
367
|
+
.mapLeft((failure) =>
|
|
368
|
+
ParseFailure(Vector(TransformationError(ast, input, isDecoding ? "Encoded" : "Type", failure.errors))),
|
|
369
|
+
)
|
|
370
|
+
.flatMap((a) =>
|
|
371
|
+
transformation(a, options).mapLeft((failure) =>
|
|
372
|
+
ParseFailure(Vector(TransformationError(ast, input, "Transformation", failure.errors))),
|
|
373
|
+
),
|
|
374
|
+
)
|
|
375
|
+
.flatMap((a) =>
|
|
376
|
+
to(a, options).mapLeft((failure) =>
|
|
377
|
+
ParseFailure(Vector(TransformationError(ast, input, isDecoding ? "Type" : "Encoded", failure.errors))),
|
|
378
|
+
),
|
|
379
|
+
),
|
|
380
|
+
);
|
|
338
381
|
}
|
|
339
382
|
case ASTTag.Validation: {
|
|
340
383
|
return Parser.make((u, options) => {
|
|
@@ -358,85 +401,8 @@ const go = memoize(function go(ast: AST): Parser<any> {
|
|
|
358
401
|
});
|
|
359
402
|
}
|
|
360
403
|
}
|
|
361
|
-
});
|
|
362
|
-
|
|
363
|
-
export function parserFor(ast: AST): Parser<any> {
|
|
364
|
-
return go(ast);
|
|
365
|
-
}
|
|
366
|
-
|
|
367
|
-
const unknownArray = AST.createTuple(Vector.empty(), Just(Vector(AST.unknownKeyword)), true);
|
|
368
|
-
|
|
369
|
-
const unknownRecord = AST.createTypeLiteral(
|
|
370
|
-
Vector.empty(),
|
|
371
|
-
Vector(
|
|
372
|
-
AST.createIndexSignature(AST.stringKeyword, AST.unknownKeyword, true),
|
|
373
|
-
AST.createIndexSignature(AST.symbolKeyword, AST.unknownKeyword, true),
|
|
374
|
-
),
|
|
375
|
-
);
|
|
376
|
-
|
|
377
|
-
function getLiterals(ast: AST): ReadonlyArray<[PropertyKey, Literal]> {
|
|
378
|
-
AST.concrete(ast);
|
|
379
|
-
switch (ast._tag) {
|
|
380
|
-
case ASTTag.Declaration:
|
|
381
|
-
return getLiterals(ast.type);
|
|
382
|
-
case ASTTag.TypeLiteral: {
|
|
383
|
-
const out: Array<[PropertyKey, Literal]> = [];
|
|
384
|
-
for (let i = 0; i < ast.propertySignatures.length; i++) {
|
|
385
|
-
const propertySignature = ast.propertySignatures[i]!;
|
|
386
|
-
if (propertySignature.type.isLiteral() && !propertySignature.isOptional) {
|
|
387
|
-
out.push([propertySignature.name, propertySignature.type]);
|
|
388
|
-
}
|
|
389
|
-
}
|
|
390
|
-
return out;
|
|
391
|
-
}
|
|
392
|
-
case ASTTag.Refinement:
|
|
393
|
-
return getLiterals(ast.from);
|
|
394
|
-
case ASTTag.Transform:
|
|
395
|
-
return ast.isReversed ? getLiterals(ast.to) : getLiterals(ast.from.getFrom);
|
|
396
|
-
}
|
|
397
|
-
return [];
|
|
398
404
|
}
|
|
399
405
|
|
|
400
|
-
function
|
|
401
|
-
|
|
402
|
-
readonly [key: PropertyKey]: {
|
|
403
|
-
buckets: { [literal: string]: ReadonlyArray<AST> };
|
|
404
|
-
ast: AST;
|
|
405
|
-
};
|
|
406
|
-
};
|
|
407
|
-
otherwise: ReadonlyArray<AST>;
|
|
408
|
-
} {
|
|
409
|
-
const keys: {
|
|
410
|
-
[key: PropertyKey]: {
|
|
411
|
-
buckets: { [literal: string]: Array<AST> };
|
|
412
|
-
ast: AST;
|
|
413
|
-
};
|
|
414
|
-
} = {};
|
|
415
|
-
const otherwise: Array<AST> = [];
|
|
416
|
-
for (let i = 0; i < members.length; i++) {
|
|
417
|
-
const member = members[i]!;
|
|
418
|
-
const tags = getLiterals(member);
|
|
419
|
-
if (tags.length > 0) {
|
|
420
|
-
for (let j = 0; j < tags.length; j++) {
|
|
421
|
-
const [key, literal] = tags[j]!;
|
|
422
|
-
const hash = String(literal.literal);
|
|
423
|
-
keys[key]! ||= { buckets: {}, ast: AST.neverKeyword };
|
|
424
|
-
const buckets = keys[key]!.buckets;
|
|
425
|
-
if (Object.prototype.hasOwnProperty.call(buckets, hash)) {
|
|
426
|
-
if (j < tags.length - 1) {
|
|
427
|
-
continue;
|
|
428
|
-
}
|
|
429
|
-
buckets[hash]!.push(member);
|
|
430
|
-
keys[key]!.ast = AST.createUnion(Vector(keys[key]!.ast, literal));
|
|
431
|
-
} else {
|
|
432
|
-
buckets[hash]! = [member];
|
|
433
|
-
keys[key]!.ast = AST.createUnion(Vector(keys[key]!.ast, literal));
|
|
434
|
-
break;
|
|
435
|
-
}
|
|
436
|
-
}
|
|
437
|
-
} else {
|
|
438
|
-
otherwise.push(member);
|
|
439
|
-
}
|
|
440
|
-
}
|
|
441
|
-
return { keys, otherwise };
|
|
406
|
+
export function parserFor(ast: AST, isDecoding: boolean): Parser<any> {
|
|
407
|
+
return goMemo(ast, isDecoding);
|
|
442
408
|
}
|
package/_src/Schema/api.ts
CHANGED
|
@@ -1,7 +1,5 @@
|
|
|
1
1
|
import type { Literal, ParseOptions, TemplateLiteral, TypeLiteral } from "../AST.js";
|
|
2
2
|
import type { Brand, Validation } from "@fncts/base/data/Branded";
|
|
3
|
-
import type { Check } from "@fncts/typelevel";
|
|
4
|
-
import type { OptionalKeys, RequiredKeys } from "@fncts/typelevel/Object";
|
|
5
3
|
|
|
6
4
|
import { show } from "@fncts/base/data/Showable";
|
|
7
5
|
|
|
@@ -51,11 +49,7 @@ export function filter<A, B extends A>(refinement: Refinement<A, B>): (self: Sch
|
|
|
51
49
|
export function filter<A>(predicate: Predicate<A>): (self: Schema<A>) => Schema<A>;
|
|
52
50
|
export function filter<A>(predicate: Predicate<A>) {
|
|
53
51
|
return (self: Schema<A>): Schema<A> => {
|
|
54
|
-
const ast: AST = AST.createRefinement(
|
|
55
|
-
self.ast,
|
|
56
|
-
(a: A) => (predicate(a) ? ParseResult.succeed(a) : ParseResult.fail(ParseError.TypeError(ast, a))),
|
|
57
|
-
false,
|
|
58
|
-
);
|
|
52
|
+
const ast: AST = AST.createRefinement(self.ast, predicate);
|
|
59
53
|
return Schema.fromAST(ast);
|
|
60
54
|
};
|
|
61
55
|
}
|
|
@@ -67,8 +61,7 @@ export function brand<A, K extends string>(validation: Validation<A, K>) {
|
|
|
67
61
|
return (self: Schema<A>): Schema<A & Brand.Valid<A, K>> => {
|
|
68
62
|
const ast = AST.createRefinement(
|
|
69
63
|
self.ast,
|
|
70
|
-
|
|
71
|
-
false,
|
|
64
|
+
validation.validate,
|
|
72
65
|
self.ast.annotations.annotate(ASTAnnotation.Brand, Vector(validation)),
|
|
73
66
|
);
|
|
74
67
|
return Schema.fromAST(ast);
|
|
@@ -528,7 +521,7 @@ export function transformOrFail<A, B>(
|
|
|
528
521
|
encode: (input: B, options?: ParseOptions) => ParseResult<A>,
|
|
529
522
|
) {
|
|
530
523
|
return (from: Schema<A>): Schema<B> => {
|
|
531
|
-
return Schema.fromAST(AST.createTransform(from.ast, to.ast, decode, encode
|
|
524
|
+
return Schema.fromAST(AST.createTransform(from.ast, to.ast, decode, encode));
|
|
532
525
|
};
|
|
533
526
|
}
|
|
534
527
|
|
package/_src/Show.ts
CHANGED
|
@@ -1,18 +1,31 @@
|
|
|
1
1
|
import type { TemplateLiteral, TemplateLiteralSpan } from "@fncts/schema/AST";
|
|
2
2
|
|
|
3
|
+
import { globalValue } from "@fncts/base/data/Global";
|
|
3
4
|
import { ASTTag } from "@fncts/schema/AST";
|
|
4
5
|
import { ASTAnnotation } from "@fncts/schema/ASTAnnotation";
|
|
5
6
|
import { memoize } from "@fncts/schema/utils";
|
|
6
7
|
|
|
8
|
+
const showMemoMap = globalValue(Symbol.for("fncts.schema.Guard.showMemoMap"), () => new WeakMap<AST, Eval<string>>());
|
|
9
|
+
|
|
10
|
+
function goMemo(ast: AST): Eval<string> {
|
|
11
|
+
const memo = showMemoMap.get(ast);
|
|
12
|
+
if (memo) {
|
|
13
|
+
return memo;
|
|
14
|
+
}
|
|
15
|
+
const s = go(ast);
|
|
16
|
+
showMemoMap.set(ast, s);
|
|
17
|
+
return s;
|
|
18
|
+
}
|
|
19
|
+
|
|
7
20
|
/**
|
|
8
21
|
* @tsplus getter fncts.schema.Schema show
|
|
9
22
|
*/
|
|
10
23
|
export function show<A>(self: Schema<A>): string {
|
|
11
|
-
const ev =
|
|
24
|
+
const ev = goMemo(self.ast);
|
|
12
25
|
return ev.run;
|
|
13
26
|
}
|
|
14
27
|
|
|
15
|
-
|
|
28
|
+
function go(ast: AST): Eval<string> {
|
|
16
29
|
AST.concrete(ast);
|
|
17
30
|
switch (ast._tag) {
|
|
18
31
|
case ASTTag.Declaration: {
|
|
@@ -20,7 +33,7 @@ const go = memoize(function go(ast: AST): Eval<string> {
|
|
|
20
33
|
() => Eval.now("Unknown Type"),
|
|
21
34
|
(id) => {
|
|
22
35
|
return ast.typeParameters
|
|
23
|
-
.traverse(Eval.Applicative)(
|
|
36
|
+
.traverse(Eval.Applicative)(goMemo)
|
|
24
37
|
.map((ts) => {
|
|
25
38
|
if (ts.length <= 0) {
|
|
26
39
|
return id;
|
|
@@ -66,11 +79,11 @@ const go = memoize(function go(ast: AST): Eval<string> {
|
|
|
66
79
|
return Eval.now("`" + formatTemplateLiteral(ast) + "`");
|
|
67
80
|
case ASTTag.Tuple:
|
|
68
81
|
return Do((Δ) => {
|
|
69
|
-
const elements = Δ(ast.elements.
|
|
82
|
+
const elements = Δ(ast.elements.traverse(Eval.Applicative)((element) => goMemo(element.type)));
|
|
70
83
|
const restElements = Δ(
|
|
71
84
|
ast.rest.match(
|
|
72
85
|
() => Eval.now(Vector.empty<string>()),
|
|
73
|
-
(rest) => rest.traverse(Eval.Applicative)(
|
|
86
|
+
(rest) => rest.traverse(Eval.Applicative)(goMemo),
|
|
74
87
|
),
|
|
75
88
|
);
|
|
76
89
|
|
|
@@ -93,9 +106,9 @@ const go = memoize(function go(ast: AST): Eval<string> {
|
|
|
93
106
|
});
|
|
94
107
|
case ASTTag.TypeLiteral:
|
|
95
108
|
return Do((Δ) => {
|
|
96
|
-
const propertySignatures = Δ(ast.propertySignatures.traverse(Eval.Applicative)((ps) =>
|
|
109
|
+
const propertySignatures = Δ(ast.propertySignatures.traverse(Eval.Applicative)((ps) => goMemo(ps.type)));
|
|
97
110
|
const indexSignatures = Δ(
|
|
98
|
-
ast.indexSignatures.traverse(Eval.Applicative)((is) =>
|
|
111
|
+
ast.indexSignatures.traverse(Eval.Applicative)((is) => goMemo(is.parameter).zip(goMemo(is.type))),
|
|
99
112
|
);
|
|
100
113
|
|
|
101
114
|
const required: Array<[PropertyKey, string]> = [];
|
|
@@ -123,26 +136,26 @@ const go = memoize(function go(ast: AST): Eval<string> {
|
|
|
123
136
|
});
|
|
124
137
|
case ASTTag.Union:
|
|
125
138
|
return ast.types
|
|
126
|
-
.traverse(Eval.Applicative)(
|
|
139
|
+
.traverse(Eval.Applicative)(goMemo)
|
|
127
140
|
.map((ts) => ts.join(" | "));
|
|
128
141
|
case ASTTag.Lazy: {
|
|
129
|
-
const f = () =>
|
|
130
|
-
const get = memoize<
|
|
131
|
-
return Eval.defer(() => get(
|
|
142
|
+
const f = () => goMemo(ast.getAST());
|
|
143
|
+
const get = memoize<void, Eval<string>>(f);
|
|
144
|
+
return Eval.defer(() => get());
|
|
132
145
|
}
|
|
133
146
|
case ASTTag.Enum: {
|
|
134
147
|
return Eval.now(ast.enums.map(([name]) => name).join(" | "));
|
|
135
148
|
}
|
|
136
149
|
case ASTTag.Refinement: {
|
|
137
150
|
return ast.annotations.get(ASTAnnotation.Identifier).match(
|
|
138
|
-
() =>
|
|
151
|
+
() => goMemo(ast.from).map((from) => `Refined<${from}>`),
|
|
139
152
|
(id) => Eval.now(id),
|
|
140
153
|
);
|
|
141
154
|
}
|
|
142
155
|
case ASTTag.Transform:
|
|
143
|
-
return
|
|
156
|
+
return goMemo(ast.to);
|
|
144
157
|
case ASTTag.Validation: {
|
|
145
|
-
return
|
|
158
|
+
return goMemo(ast.from).map((from) => {
|
|
146
159
|
const validationNames = ast.validation.map((v) => v.name).join(" & ");
|
|
147
160
|
|
|
148
161
|
if (validationNames.length <= 0) {
|
|
@@ -153,7 +166,7 @@ const go = memoize(function go(ast: AST): Eval<string> {
|
|
|
153
166
|
});
|
|
154
167
|
}
|
|
155
168
|
}
|
|
156
|
-
}
|
|
169
|
+
}
|
|
157
170
|
|
|
158
171
|
function formatTemplateLiteralSpan(span: TemplateLiteralSpan): string {
|
|
159
172
|
switch (span.type._tag) {
|
package/package.json
CHANGED