typesea 0.1.0 → 0.2.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/CHANGELOG.md +67 -6
- package/README.md +98 -17
- package/dist/adapters/index.d.ts +50 -8
- package/dist/adapters/index.d.ts.map +1 -1
- package/dist/adapters/index.js +169 -48
- package/dist/aot/index.d.ts +18 -2
- package/dist/aot/index.d.ts.map +1 -1
- package/dist/aot/index.js +93 -14
- package/dist/async/index.d.ts +28 -56
- package/dist/async/index.d.ts.map +1 -1
- package/dist/async/index.js +94 -37
- package/dist/builders/composite.d.ts +37 -6
- package/dist/builders/composite.d.ts.map +1 -1
- package/dist/builders/composite.js +84 -10
- package/dist/builders/index.d.ts +2 -0
- package/dist/builders/index.d.ts.map +1 -1
- package/dist/builders/index.js +2 -0
- package/dist/builders/modifier.d.ts +30 -5
- package/dist/builders/modifier.d.ts.map +1 -1
- package/dist/builders/modifier.js +38 -5
- package/dist/builders/object/guard.d.ts +18 -22
- package/dist/builders/object/guard.d.ts.map +1 -1
- package/dist/builders/object/guard.js +26 -26
- package/dist/builders/object/index.d.ts +2 -0
- package/dist/builders/object/index.d.ts.map +1 -1
- package/dist/builders/object/index.js +2 -0
- package/dist/builders/object/schema.d.ts +55 -9
- package/dist/builders/object/schema.d.ts.map +1 -1
- package/dist/builders/object/schema.js +92 -15
- package/dist/builders/object/types.d.ts +5 -31
- package/dist/builders/object/types.d.ts.map +1 -1
- package/dist/builders/object/types.js +2 -0
- package/dist/builders/scalar.d.ts +29 -8
- package/dist/builders/scalar.d.ts.map +1 -1
- package/dist/builders/scalar.js +33 -8
- package/dist/builders/table.d.ts +4 -0
- package/dist/builders/table.d.ts.map +1 -1
- package/dist/builders/table.js +4 -0
- package/dist/builders/types.d.ts +14 -4
- package/dist/builders/types.d.ts.map +1 -1
- package/dist/builders/types.js +2 -0
- package/dist/compile/check-composite.d.ts +22 -1
- package/dist/compile/check-composite.d.ts.map +1 -1
- package/dist/compile/check-composite.js +564 -24
- package/dist/compile/check-scalar.d.ts +78 -0
- package/dist/compile/check-scalar.d.ts.map +1 -1
- package/dist/compile/check-scalar.js +432 -1
- package/dist/compile/check.d.ts +12 -0
- package/dist/compile/check.d.ts.map +1 -1
- package/dist/compile/check.js +37 -0
- package/dist/compile/context.d.ts +47 -9
- package/dist/compile/context.d.ts.map +1 -1
- package/dist/compile/context.js +51 -8
- package/dist/compile/graph-predicate.d.ts +4 -2
- package/dist/compile/graph-predicate.d.ts.map +1 -1
- package/dist/compile/graph-predicate.js +1907 -171
- package/dist/compile/guard.d.ts +15 -24
- package/dist/compile/guard.d.ts.map +1 -1
- package/dist/compile/guard.js +158 -74
- package/dist/compile/index.d.ts +3 -1
- package/dist/compile/index.d.ts.map +1 -1
- package/dist/compile/index.js +2 -0
- package/dist/compile/issue.d.ts +110 -0
- package/dist/compile/issue.d.ts.map +1 -1
- package/dist/compile/issue.js +184 -1
- package/dist/compile/names.d.ts +12 -2
- package/dist/compile/names.d.ts.map +1 -1
- package/dist/compile/names.js +19 -3
- package/dist/compile/predicate.d.ts +24 -0
- package/dist/compile/predicate.d.ts.map +1 -1
- package/dist/compile/predicate.js +131 -5
- package/dist/compile/runtime.d.ts +80 -12
- package/dist/compile/runtime.d.ts.map +1 -1
- package/dist/compile/runtime.js +25 -6
- package/dist/compile/source.d.ts +10 -2
- package/dist/compile/source.d.ts.map +1 -1
- package/dist/compile/source.js +361 -26
- package/dist/compile/types.d.ts +20 -0
- package/dist/compile/types.d.ts.map +1 -1
- package/dist/compile/types.js +2 -0
- package/dist/decoder/index.d.ts +32 -46
- package/dist/decoder/index.d.ts.map +1 -1
- package/dist/decoder/index.js +102 -38
- package/dist/evaluate/check-composite.d.ts +59 -0
- package/dist/evaluate/check-composite.d.ts.map +1 -1
- package/dist/evaluate/check-composite.js +151 -3
- package/dist/evaluate/check-scalar.d.ts +16 -0
- package/dist/evaluate/check-scalar.d.ts.map +1 -1
- package/dist/evaluate/check-scalar.js +32 -0
- package/dist/evaluate/check.d.ts +7 -0
- package/dist/evaluate/check.d.ts.map +1 -1
- package/dist/evaluate/check.js +43 -0
- package/dist/evaluate/index.d.ts +2 -0
- package/dist/evaluate/index.d.ts.map +1 -1
- package/dist/evaluate/index.js +2 -0
- package/dist/evaluate/issue.d.ts +11 -1
- package/dist/evaluate/issue.d.ts.map +1 -1
- package/dist/evaluate/issue.js +15 -1
- package/dist/evaluate/predicate.d.ts +16 -5
- package/dist/evaluate/predicate.d.ts.map +1 -1
- package/dist/evaluate/predicate.js +20 -5
- package/dist/evaluate/shared.d.ts +59 -13
- package/dist/evaluate/shared.d.ts.map +1 -1
- package/dist/evaluate/shared.js +66 -8
- package/dist/evaluate/state.d.ts +35 -13
- package/dist/evaluate/state.d.ts.map +1 -1
- package/dist/evaluate/state.js +35 -2
- package/dist/guard/base.d.ts +79 -29
- package/dist/guard/base.d.ts.map +1 -1
- package/dist/guard/base.js +91 -29
- package/dist/guard/error.d.ts +10 -5
- package/dist/guard/error.d.ts.map +1 -1
- package/dist/guard/error.js +10 -5
- package/dist/guard/index.d.ts +2 -0
- package/dist/guard/index.d.ts.map +1 -1
- package/dist/guard/index.js +2 -0
- package/dist/guard/number.d.ts +26 -11
- package/dist/guard/number.d.ts.map +1 -1
- package/dist/guard/number.js +30 -11
- package/dist/guard/props.d.ts +27 -3
- package/dist/guard/props.d.ts.map +1 -1
- package/dist/guard/props.js +27 -3
- package/dist/guard/read.d.ts +62 -9
- package/dist/guard/read.d.ts.map +1 -1
- package/dist/guard/read.js +83 -10
- package/dist/guard/registry.d.ts +12 -2
- package/dist/guard/registry.d.ts.map +1 -1
- package/dist/guard/registry.js +15 -3
- package/dist/guard/string.d.ts +33 -13
- package/dist/guard/string.d.ts.map +1 -1
- package/dist/guard/string.js +37 -13
- package/dist/guard/types.d.ts +92 -40
- package/dist/guard/types.d.ts.map +1 -1
- package/dist/guard/types.js +2 -0
- package/dist/index.d.ts +1 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/internal/index.d.ts +42 -6
- package/dist/internal/index.d.ts.map +1 -1
- package/dist/internal/index.js +51 -8
- package/dist/ir/builder.d.ts +16 -126
- package/dist/ir/builder.d.ts.map +1 -1
- package/dist/ir/builder.js +77 -137
- package/dist/ir/freeze.d.ts +4 -0
- package/dist/ir/freeze.d.ts.map +1 -1
- package/dist/ir/freeze.js +59 -0
- package/dist/ir/index.d.ts +3 -1
- package/dist/ir/index.d.ts.map +1 -1
- package/dist/ir/index.js +2 -0
- package/dist/ir/regexp.d.ts +2 -0
- package/dist/ir/regexp.d.ts.map +1 -1
- package/dist/ir/regexp.js +2 -0
- package/dist/ir/types.d.ts +90 -55
- package/dist/ir/types.d.ts.map +1 -1
- package/dist/ir/types.js +2 -0
- package/dist/ir/validate.d.ts +8 -1
- package/dist/ir/validate.d.ts.map +1 -1
- package/dist/ir/validate.js +477 -61
- package/dist/issue/index.d.ts +41 -9
- package/dist/issue/index.d.ts.map +1 -1
- package/dist/issue/index.js +61 -11
- package/dist/json-schema/emit-combinator.d.ts +44 -4
- package/dist/json-schema/emit-combinator.d.ts.map +1 -1
- package/dist/json-schema/emit-combinator.js +44 -4
- package/dist/json-schema/emit-composite.d.ts +10 -0
- package/dist/json-schema/emit-composite.d.ts.map +1 -1
- package/dist/json-schema/emit-composite.js +15 -1
- package/dist/json-schema/emit-scalar.d.ts +26 -3
- package/dist/json-schema/emit-scalar.d.ts.map +1 -1
- package/dist/json-schema/emit-scalar.js +70 -9
- package/dist/json-schema/emit-types.d.ts +11 -1
- package/dist/json-schema/emit-types.d.ts.map +1 -1
- package/dist/json-schema/emit-types.js +2 -0
- package/dist/json-schema/emit.d.ts +12 -1
- package/dist/json-schema/emit.d.ts.map +1 -1
- package/dist/json-schema/emit.js +12 -1
- package/dist/json-schema/freeze.d.ts +13 -2
- package/dist/json-schema/freeze.d.ts.map +1 -1
- package/dist/json-schema/freeze.js +41 -8
- package/dist/json-schema/index.d.ts +16 -2
- package/dist/json-schema/index.d.ts.map +1 -1
- package/dist/json-schema/index.js +23 -3
- package/dist/json-schema/issue.d.ts +4 -1
- package/dist/json-schema/issue.d.ts.map +1 -1
- package/dist/json-schema/issue.js +4 -1
- package/dist/json-schema/read.d.ts +24 -3
- package/dist/json-schema/read.d.ts.map +1 -1
- package/dist/json-schema/read.js +59 -12
- package/dist/json-schema/types.d.ts +38 -15
- package/dist/json-schema/types.d.ts.map +1 -1
- package/dist/json-schema/types.js +2 -0
- package/dist/kind/index.d.ts +15 -28
- package/dist/kind/index.d.ts.map +1 -1
- package/dist/kind/index.js +15 -10
- package/dist/lower/index.d.ts +6 -1
- package/dist/lower/index.d.ts.map +1 -1
- package/dist/lower/index.js +411 -44
- package/dist/message/index.d.ts +46 -10
- package/dist/message/index.d.ts.map +1 -1
- package/dist/message/index.js +88 -17
- package/dist/optimize/algebraic.d.ts +54 -0
- package/dist/optimize/algebraic.d.ts.map +1 -0
- package/dist/optimize/algebraic.js +314 -0
- package/dist/optimize/compact.d.ts +8 -1
- package/dist/optimize/compact.d.ts.map +1 -1
- package/dist/optimize/compact.js +13 -2
- package/dist/optimize/domain.d.ts +16 -0
- package/dist/optimize/domain.d.ts.map +1 -0
- package/dist/optimize/domain.js +615 -0
- package/dist/optimize/fold-boolean.d.ts +17 -2
- package/dist/optimize/fold-boolean.d.ts.map +1 -1
- package/dist/optimize/fold-boolean.js +59 -14
- package/dist/optimize/fold-common.d.ts +43 -8
- package/dist/optimize/fold-common.d.ts.map +1 -1
- package/dist/optimize/fold-common.js +37 -6
- package/dist/optimize/fold-constraints.d.ts +33 -0
- package/dist/optimize/fold-constraints.d.ts.map +1 -0
- package/dist/optimize/fold-constraints.js +484 -0
- package/dist/optimize/fold-scalar.d.ts +98 -13
- package/dist/optimize/fold-scalar.d.ts.map +1 -1
- package/dist/optimize/fold-scalar.js +98 -13
- package/dist/optimize/fold.d.ts +8 -1
- package/dist/optimize/fold.d.ts.map +1 -1
- package/dist/optimize/fold.js +22 -2
- package/dist/optimize/index.d.ts +9 -1
- package/dist/optimize/index.d.ts.map +1 -1
- package/dist/optimize/index.js +18 -3
- package/dist/optimize/map-node.d.ts +3 -1
- package/dist/optimize/map-node.d.ts.map +1 -1
- package/dist/optimize/map-node.js +45 -3
- package/dist/optimize/peephole.d.ts +16 -0
- package/dist/optimize/peephole.d.ts.map +1 -0
- package/dist/optimize/peephole.js +254 -0
- package/dist/optimize/remap.d.ts +2 -0
- package/dist/optimize/remap.d.ts.map +1 -1
- package/dist/optimize/remap.js +2 -0
- package/dist/optimize/rewrite.d.ts +13 -8
- package/dist/optimize/rewrite.d.ts.map +1 -1
- package/dist/optimize/rewrite.js +13 -8
- package/dist/plan/cache.d.ts +9 -3
- package/dist/plan/cache.d.ts.map +1 -1
- package/dist/plan/cache.js +21 -5
- package/dist/plan/index.d.ts +2 -0
- package/dist/plan/index.d.ts.map +1 -1
- package/dist/plan/index.js +2 -0
- package/dist/plan/predicate.d.ts +2 -0
- package/dist/plan/predicate.d.ts.map +1 -1
- package/dist/plan/predicate.js +268 -29
- package/dist/plan/schema-predicate.d.ts +6 -0
- package/dist/plan/schema-predicate.d.ts.map +1 -1
- package/dist/plan/schema-predicate.js +117 -13
- package/dist/plan/types.d.ts +2 -0
- package/dist/plan/types.d.ts.map +1 -1
- package/dist/plan/types.js +2 -0
- package/dist/result/index.d.ts +19 -5
- package/dist/result/index.d.ts.map +1 -1
- package/dist/result/index.js +10 -2
- package/dist/schema/common.d.ts +69 -6
- package/dist/schema/common.d.ts.map +1 -1
- package/dist/schema/common.js +104 -10
- package/dist/schema/freeze.d.ts +4 -0
- package/dist/schema/freeze.d.ts.map +1 -1
- package/dist/schema/freeze.js +18 -0
- package/dist/schema/index.d.ts +3 -0
- package/dist/schema/index.d.ts.map +1 -1
- package/dist/schema/index.js +3 -0
- package/dist/schema/lazy.d.ts +4 -0
- package/dist/schema/lazy.d.ts.map +1 -1
- package/dist/schema/lazy.js +4 -0
- package/dist/schema/literal.d.ts +7 -1
- package/dist/schema/literal.d.ts.map +1 -1
- package/dist/schema/literal.js +7 -1
- package/dist/schema/types.d.ts +20 -96
- package/dist/schema/types.d.ts.map +1 -1
- package/dist/schema/types.js +5 -1
- package/dist/schema/undefined.d.ts +17 -0
- package/dist/schema/undefined.d.ts.map +1 -0
- package/dist/schema/undefined.js +72 -0
- package/dist/schema/validate.d.ts +8 -1
- package/dist/schema/validate.d.ts.map +1 -1
- package/dist/schema/validate.js +146 -55
- package/docs/api.md +57 -0
- package/docs/assets/benchmark-headline.svg +163 -0
- package/docs/engine-notes.md +58 -15
- package/docs/index.html +130 -110
- package/package.json +65 -65
package/dist/aot/index.js
CHANGED
|
@@ -3,7 +3,13 @@ import { SchemaTag } from "../kind/index.js";
|
|
|
3
3
|
import { err, ok } from "../result/index.js";
|
|
4
4
|
import { freezeSchema, isSchemaValue } from "../schema/index.js";
|
|
5
5
|
/**
|
|
6
|
-
* @brief
|
|
6
|
+
* @brief Emit a standalone validator module for a guard schema.
|
|
7
|
+
* @param guard Guard whose schema is exported.
|
|
8
|
+
* @param options Optional function name and compile mode.
|
|
9
|
+
* @returns Result carrying source text, or closed issues for unsupported schema nodes.
|
|
10
|
+
* @details AOT output cannot close over runtime side tables. The schema is
|
|
11
|
+
* scanned before code emission so lazy, refine, and symbol-literal constructs
|
|
12
|
+
* fail as explicit issues instead of producing partially faithful source.
|
|
7
13
|
*/
|
|
8
14
|
export function emitAotModule(guard, options) {
|
|
9
15
|
const schema = readAotSchema(guard);
|
|
@@ -13,7 +19,7 @@ export function emitAotModule(guard, options) {
|
|
|
13
19
|
if (issues.length !== 0) {
|
|
14
20
|
return err(freezeAotIssues(issues));
|
|
15
21
|
}
|
|
16
|
-
const bundle = emitCompiledSourceBundle(schema, config.name);
|
|
22
|
+
const bundle = emitCompiledSourceBundle(schema, config.name, config.mode);
|
|
17
23
|
if (bundle.dynamicSchemas.length !== 0) {
|
|
18
24
|
return err(freezeAotIssues([
|
|
19
25
|
{
|
|
@@ -29,25 +35,36 @@ export function emitAotModule(guard, options) {
|
|
|
29
35
|
}));
|
|
30
36
|
}
|
|
31
37
|
/**
|
|
32
|
-
* @brief
|
|
38
|
+
* @brief Normalize the guard input used by AOT emission.
|
|
39
|
+
* @param guard Candidate guard-like value.
|
|
40
|
+
* @returns Frozen schema safe for source generation.
|
|
41
|
+
* @throws TypeError when the value is not a TypeSea guard.
|
|
42
|
+
* @details The schema slot is descriptor-read to reject forged prototypes before
|
|
43
|
+
* the generator traverses schema data.
|
|
33
44
|
*/
|
|
34
45
|
function readAotSchema(guard) {
|
|
35
46
|
if (!isRecord(guard)) {
|
|
36
47
|
throw new TypeError("AOT guard must be a TypeSea guard");
|
|
37
48
|
}
|
|
38
|
-
const schema = guard
|
|
49
|
+
const schema = readOwnDataProperty(guard, "schema");
|
|
39
50
|
if (!isSchemaValue(schema)) {
|
|
40
51
|
throw new TypeError("AOT guard must contain a valid TypeSea schema");
|
|
41
52
|
}
|
|
42
53
|
return freezeSchema(schema);
|
|
43
54
|
}
|
|
44
55
|
/**
|
|
45
|
-
* @brief
|
|
56
|
+
* @brief Normalize AOT compile options.
|
|
57
|
+
* @details AOT helpers serialize only portable data because standalone modules cannot close
|
|
58
|
+
* over runtime side tables.
|
|
59
|
+
* @param options Optional user options object.
|
|
60
|
+
* @returns Complete options with defaults.
|
|
61
|
+
* @throws TypeError when option fields have unsupported types.
|
|
46
62
|
*/
|
|
47
63
|
function readOptions(options) {
|
|
48
64
|
if (options === undefined) {
|
|
49
65
|
return {
|
|
50
|
-
name: "typesea_aot"
|
|
66
|
+
name: "typesea_aot",
|
|
67
|
+
mode: "safe"
|
|
51
68
|
};
|
|
52
69
|
}
|
|
53
70
|
if (!isRecord(options)) {
|
|
@@ -56,18 +73,45 @@ function readOptions(options) {
|
|
|
56
73
|
const name = options.name;
|
|
57
74
|
if (name === undefined) {
|
|
58
75
|
return {
|
|
59
|
-
name: "typesea_aot"
|
|
76
|
+
name: "typesea_aot",
|
|
77
|
+
mode: readAotMode(options)
|
|
60
78
|
};
|
|
61
79
|
}
|
|
62
80
|
if (typeof name !== "string") {
|
|
63
81
|
throw new TypeError("AOT name must be a string");
|
|
64
82
|
}
|
|
65
83
|
return {
|
|
66
|
-
name
|
|
84
|
+
name,
|
|
85
|
+
mode: readAotMode(options)
|
|
67
86
|
};
|
|
68
87
|
}
|
|
69
88
|
/**
|
|
70
|
-
* @brief
|
|
89
|
+
* @brief Normalize the requested AOT compile mode.
|
|
90
|
+
* @details AOT helpers serialize only portable data because standalone modules cannot close
|
|
91
|
+
* over runtime side tables.
|
|
92
|
+
* @param options Options object already accepted as a record.
|
|
93
|
+
* @returns Safe, unsafe, or unchecked codegen mode.
|
|
94
|
+
* @throws TypeError when the mode is outside the supported set.
|
|
95
|
+
*/
|
|
96
|
+
function readAotMode(options) {
|
|
97
|
+
const mode = options["mode"];
|
|
98
|
+
if (mode === undefined) {
|
|
99
|
+
return "safe";
|
|
100
|
+
}
|
|
101
|
+
if (mode === "safe" || mode === "unsafe" || mode === "unchecked") {
|
|
102
|
+
return mode;
|
|
103
|
+
}
|
|
104
|
+
throw new TypeError("AOT mode must be \"safe\", \"unsafe\", or \"unchecked\"");
|
|
105
|
+
}
|
|
106
|
+
/**
|
|
107
|
+
* @brief Walk a schema tree and record constructs that AOT cannot preserve.
|
|
108
|
+
* @param schema Current schema node.
|
|
109
|
+
* @param path Diagnostic path to the current node.
|
|
110
|
+
* @param issues Mutable issue vector owned by the caller.
|
|
111
|
+
* @param seen Schema object set used to avoid repeated traversal.
|
|
112
|
+
* @details Runtime compilation can keep dynamic schemas in side tables; emitted
|
|
113
|
+
* modules cannot. This scan keeps the public API honest by refusing source that
|
|
114
|
+
* would silently weaken lazy, refine, or symbol literal semantics.
|
|
71
115
|
*/
|
|
72
116
|
function scanAotSchema(schema, path, issues, seen) {
|
|
73
117
|
if (seen.has(schema)) {
|
|
@@ -131,6 +175,8 @@ function scanAotSchema(schema, path, issues, seen) {
|
|
|
131
175
|
}
|
|
132
176
|
/**
|
|
133
177
|
* @brief scan schema array.
|
|
178
|
+
* @details AOT helpers serialize only portable data because standalone modules cannot close
|
|
179
|
+
* over runtime side tables.
|
|
134
180
|
*/
|
|
135
181
|
function scanSchemaArray(schemas, path, issues, seen) {
|
|
136
182
|
for (let index = 0; index < schemas.length; index += 1) {
|
|
@@ -142,6 +188,8 @@ function scanSchemaArray(schemas, path, issues, seen) {
|
|
|
142
188
|
}
|
|
143
189
|
/**
|
|
144
190
|
* @brief scan object entries.
|
|
191
|
+
* @details AOT helpers serialize only portable data because standalone modules cannot close
|
|
192
|
+
* over runtime side tables.
|
|
145
193
|
*/
|
|
146
194
|
function scanObjectEntries(entries, path, issues, seen) {
|
|
147
195
|
for (let index = 0; index < entries.length; index += 1) {
|
|
@@ -153,6 +201,8 @@ function scanObjectEntries(entries, path, issues, seen) {
|
|
|
153
201
|
}
|
|
154
202
|
/**
|
|
155
203
|
* @brief emit module source.
|
|
204
|
+
* @details AOT helpers serialize only portable data because standalone modules cannot close
|
|
205
|
+
* over runtime side tables.
|
|
156
206
|
*/
|
|
157
207
|
function emitModuleSource(bundle) {
|
|
158
208
|
return [
|
|
@@ -170,9 +220,8 @@ function emitModuleSource(bundle) {
|
|
|
170
220
|
"const __typesea=(function(l,r,k,u,d,m,sk){",
|
|
171
221
|
bundle.source,
|
|
172
222
|
"})(l,r,k,u,d,m,sk);",
|
|
173
|
-
"const freezeIssues=function(xs){if(xs.length===0)return Object.freeze([]);const out=new Array(xs.length);for(let i=0;i<xs.length;i+=1){const x=xs[i];const p=x.path.slice();Object.freeze(p);const y={path:p,code:x.code,expected:x.expected,actual:x.actual,message:x.message};Object.freeze(y);out[i]=y;}return Object.freeze(out);};",
|
|
174
223
|
"export function is(value){return __typesea.is(value);}",
|
|
175
|
-
"export function check(value){
|
|
224
|
+
"export function check(value){return __typesea.result(value);}",
|
|
176
225
|
"export function assert(value){const result=check(value);if(!result.ok){const error=new Error(\"TypeSea assertion failed\");Object.defineProperty(error,\"issues\",{configurable:false,enumerable:true,value:result.error,writable:false});throw error;}}",
|
|
177
226
|
"export default Object.freeze({is,check,assert});",
|
|
178
227
|
""
|
|
@@ -180,6 +229,8 @@ function emitModuleSource(bundle) {
|
|
|
180
229
|
}
|
|
181
230
|
/**
|
|
182
231
|
* @brief emit declaration source.
|
|
232
|
+
* @details AOT helpers serialize only portable data because standalone modules cannot close
|
|
233
|
+
* over runtime side tables.
|
|
183
234
|
*/
|
|
184
235
|
function emitDeclarationSource() {
|
|
185
236
|
return [
|
|
@@ -207,6 +258,8 @@ function emitDeclarationSource() {
|
|
|
207
258
|
}
|
|
208
259
|
/**
|
|
209
260
|
* @brief serialize literal array.
|
|
261
|
+
* @details AOT helpers serialize only portable data because standalone modules cannot close
|
|
262
|
+
* over runtime side tables.
|
|
210
263
|
*/
|
|
211
264
|
function serializeLiteralArray(values) {
|
|
212
265
|
const parts = new Array(values.length);
|
|
@@ -220,6 +273,8 @@ function serializeLiteralArray(values) {
|
|
|
220
273
|
}
|
|
221
274
|
/**
|
|
222
275
|
* @brief serialize literal.
|
|
276
|
+
* @details AOT helpers serialize only portable data because standalone modules cannot close
|
|
277
|
+
* over runtime side tables.
|
|
223
278
|
*/
|
|
224
279
|
function serializeLiteral(value) {
|
|
225
280
|
switch (typeof value) {
|
|
@@ -253,6 +308,8 @@ function serializeLiteral(value) {
|
|
|
253
308
|
}
|
|
254
309
|
/**
|
|
255
310
|
* @brief serialize reg exp array.
|
|
311
|
+
* @details AOT helpers serialize only portable data because standalone modules cannot close
|
|
312
|
+
* over runtime side tables.
|
|
256
313
|
*/
|
|
257
314
|
function serializeRegExpArray(values) {
|
|
258
315
|
const parts = new Array(values.length);
|
|
@@ -265,7 +322,8 @@ function serializeRegExpArray(values) {
|
|
|
265
322
|
return `[${parts.join(",")}]`;
|
|
266
323
|
}
|
|
267
324
|
/**
|
|
268
|
-
* @brief push issue.
|
|
325
|
+
* @brief Execute push issue.
|
|
326
|
+
* @details This helper keeps a local invariant explicit at the module boundary.
|
|
269
327
|
*/
|
|
270
328
|
function pushIssue(path, issues, code, message) {
|
|
271
329
|
issues.push({
|
|
@@ -275,7 +333,8 @@ function pushIssue(path, issues, code, message) {
|
|
|
275
333
|
});
|
|
276
334
|
}
|
|
277
335
|
/**
|
|
278
|
-
* @brief freeze aot issues.
|
|
336
|
+
* @brief Execute freeze aot issues.
|
|
337
|
+
* @details This helper keeps a local invariant explicit at the module boundary.
|
|
279
338
|
*/
|
|
280
339
|
function freezeAotIssues(issues) {
|
|
281
340
|
for (let index = 0; index < issues.length; index += 1) {
|
|
@@ -288,8 +347,28 @@ function freezeAotIssues(issues) {
|
|
|
288
347
|
return Object.freeze(issues);
|
|
289
348
|
}
|
|
290
349
|
/**
|
|
291
|
-
* @brief
|
|
350
|
+
* @brief Accept option and guard records before local field reads.
|
|
351
|
+
* @details AOT helpers serialize only portable data because standalone modules cannot close
|
|
352
|
+
* over runtime side tables.
|
|
353
|
+
* @param value Candidate object.
|
|
354
|
+
* @returns True for non-array objects.
|
|
292
355
|
*/
|
|
293
356
|
function isRecord(value) {
|
|
294
357
|
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
295
358
|
}
|
|
359
|
+
/**
|
|
360
|
+
* @brief Read one own data slot from an AOT input object.
|
|
361
|
+
* @details AOT helpers serialize only portable data because standalone modules cannot close
|
|
362
|
+
* over runtime side tables.
|
|
363
|
+
* @param value Object being normalized.
|
|
364
|
+
* @param key Field name or symbol.
|
|
365
|
+
* @returns Stored field value, or undefined when absent.
|
|
366
|
+
*/
|
|
367
|
+
function readOwnDataProperty(value, key) {
|
|
368
|
+
const descriptor = Object.getOwnPropertyDescriptor(value, key);
|
|
369
|
+
if (descriptor === undefined ||
|
|
370
|
+
!Object.prototype.hasOwnProperty.call(descriptor, "value")) {
|
|
371
|
+
return undefined;
|
|
372
|
+
}
|
|
373
|
+
return descriptor.value;
|
|
374
|
+
}
|
package/dist/async/index.d.ts
CHANGED
|
@@ -1,110 +1,82 @@
|
|
|
1
1
|
import { type DecodeSource, type Decoder, type InferDecoder } from "../decoder/index.js";
|
|
2
2
|
import type { Guard, Presence, RuntimeValue } from "../guard/index.js";
|
|
3
3
|
import { type CheckResult } from "../issue/index.js";
|
|
4
|
-
/**
|
|
5
|
-
* @brief async decode runner.
|
|
6
|
-
*/
|
|
7
4
|
type AsyncDecodeRunner<TValue> = (value: unknown) => Promise<CheckResult<TValue>>;
|
|
8
|
-
/**
|
|
9
|
-
* @brief async predicate.
|
|
10
|
-
*/
|
|
11
5
|
type AsyncPredicate<TValue> = (value: TValue) => boolean | Promise<boolean>;
|
|
12
|
-
/**
|
|
13
|
-
* @brief async mapper.
|
|
14
|
-
*/
|
|
15
6
|
type AsyncMapper<TValue, TNext> = (value: TValue) => TNext | Promise<TNext>;
|
|
16
7
|
/**
|
|
17
|
-
* @brief async decoder
|
|
8
|
+
* @brief Private runner slot for async decoder instances.
|
|
9
|
+
* @details Decoder helpers keep validation failures explicit in Result values while
|
|
10
|
+
* preserving the original input value.
|
|
18
11
|
*/
|
|
19
12
|
declare const AsyncDecoderRunSymbol: unique symbol;
|
|
20
|
-
/**
|
|
21
|
-
* @brief async decode source.
|
|
22
|
-
*/
|
|
23
13
|
export type AsyncDecodeSource = DecodeSource | AsyncDecoder<unknown>;
|
|
24
|
-
/**
|
|
25
|
-
* @brief infer async decoder.
|
|
26
|
-
*/
|
|
27
14
|
export type InferAsyncDecoder<TSource> = TSource extends AsyncDecoder<infer TValue> ? TValue : InferDecoder<TSource>;
|
|
28
15
|
/**
|
|
29
|
-
* @brief
|
|
16
|
+
* @brief Promise-returning decode pipeline.
|
|
17
|
+
* @details The API keeps validation failures in Result values; rejected
|
|
18
|
+
* promises are reserved for programmer errors thrown by user mappers.
|
|
30
19
|
*/
|
|
31
20
|
export interface AsyncDecoder<TValue> {
|
|
32
|
-
/**
|
|
33
|
-
* @brief decode async.
|
|
34
|
-
*/
|
|
35
21
|
decodeAsync(value: unknown): Promise<CheckResult<TValue>>;
|
|
36
|
-
/**
|
|
37
|
-
* @brief refine async.
|
|
38
|
-
*/
|
|
39
22
|
refineAsync(predicate: AsyncPredicate<TValue>, name: string): BaseAsyncDecoder<TValue>;
|
|
40
|
-
/**
|
|
41
|
-
* @brief transform async.
|
|
42
|
-
*/
|
|
43
23
|
transformAsync<TNext>(mapper: AsyncMapper<TValue, TNext>): BaseAsyncDecoder<TNext>;
|
|
44
|
-
/**
|
|
45
|
-
* @brief pipe async.
|
|
46
|
-
*/
|
|
47
24
|
pipeAsync<TNext extends AsyncDecodeSource>(next: TNext): BaseAsyncDecoder<InferAsyncDecoder<TNext>>;
|
|
48
25
|
}
|
|
49
26
|
/**
|
|
50
|
-
* @brief
|
|
51
|
-
* @details
|
|
52
|
-
*
|
|
27
|
+
* @brief Frozen wrapper around one async decode runner.
|
|
28
|
+
* @details Receiver validation mirrors BaseDecoder so detached method calls do
|
|
29
|
+
* not bypass TypeSea's object construction checks.
|
|
53
30
|
*/
|
|
54
31
|
export declare class BaseAsyncDecoder<TValue> implements AsyncDecoder<TValue> {
|
|
55
32
|
private readonly [AsyncDecoderRunSymbol];
|
|
56
|
-
/**
|
|
57
|
-
* @brief constructor.
|
|
58
|
-
* @post The receiver is initialized according to the class invariant before it can be observed.
|
|
59
|
-
*/
|
|
60
33
|
constructor(run: AsyncDecodeRunner<TValue>);
|
|
61
|
-
/**
|
|
62
|
-
* @brief decode async.
|
|
63
|
-
*/
|
|
64
34
|
decodeAsync(this: unknown, value: unknown): Promise<CheckResult<TValue>>;
|
|
65
|
-
/**
|
|
66
|
-
* @brief refine async.
|
|
67
|
-
*/
|
|
68
35
|
refineAsync(predicate: AsyncPredicate<TValue>, name: string): BaseAsyncDecoder<TValue>;
|
|
69
|
-
/**
|
|
70
|
-
* @brief transform async.
|
|
71
|
-
*/
|
|
72
36
|
transformAsync<TNext>(mapper: AsyncMapper<TValue, TNext>): BaseAsyncDecoder<TNext>;
|
|
73
|
-
/**
|
|
74
|
-
* @brief pipe async.
|
|
75
|
-
*/
|
|
76
37
|
pipeAsync<TNext extends AsyncDecodeSource>(next: TNext): BaseAsyncDecoder<InferAsyncDecoder<TNext>>;
|
|
77
38
|
}
|
|
78
39
|
/**
|
|
79
|
-
* @brief async decoder.
|
|
40
|
+
* @brief Wrap a guard, decoder, or async decoder as an async decoder pipeline.
|
|
41
|
+
* @details Decoder helpers keep validation failures explicit in Result values while
|
|
42
|
+
* preserving the original input value.
|
|
80
43
|
*/
|
|
81
44
|
export declare function asyncDecoder<TValue, TPresence extends Presence>(source: Guard<TValue, TPresence>): BaseAsyncDecoder<RuntimeValue<TValue, TPresence>>;
|
|
82
45
|
/**
|
|
83
|
-
* @brief async decoder.
|
|
46
|
+
* @brief Execute async decoder.
|
|
47
|
+
* @details This helper keeps a local invariant explicit at the module boundary.
|
|
84
48
|
*/
|
|
85
49
|
export declare function asyncDecoder<TValue>(source: Decoder<TValue> | AsyncDecoder<TValue>): BaseAsyncDecoder<TValue>;
|
|
86
50
|
/**
|
|
87
|
-
* @brief async
|
|
51
|
+
* @brief Build an async decoder and append an async refinement.
|
|
52
|
+
* @details Decoder helpers keep validation failures explicit in Result values while
|
|
53
|
+
* preserving the original input value.
|
|
88
54
|
*/
|
|
89
55
|
export declare function asyncRefine<TValue, TPresence extends Presence>(source: Guard<TValue, TPresence>, predicate: AsyncPredicate<RuntimeValue<TValue, TPresence>>, name: string): BaseAsyncDecoder<RuntimeValue<TValue, TPresence>>;
|
|
90
56
|
/**
|
|
91
|
-
* @brief async refine.
|
|
57
|
+
* @brief Execute async refine.
|
|
58
|
+
* @details This helper keeps a local invariant explicit at the module boundary.
|
|
92
59
|
*/
|
|
93
60
|
export declare function asyncRefine<TValue>(source: Decoder<TValue> | AsyncDecoder<TValue>, predicate: AsyncPredicate<TValue>, name: string): BaseAsyncDecoder<TValue>;
|
|
94
61
|
/**
|
|
95
|
-
* @brief async
|
|
62
|
+
* @brief Build an async decoder and append an async mapper.
|
|
63
|
+
* @details Decoder helpers keep validation failures explicit in Result values while
|
|
64
|
+
* preserving the original input value.
|
|
96
65
|
*/
|
|
97
66
|
export declare function asyncTransform<TValue, TPresence extends Presence, TNext>(source: Guard<TValue, TPresence>, mapper: AsyncMapper<RuntimeValue<TValue, TPresence>, TNext>): BaseAsyncDecoder<TNext>;
|
|
98
67
|
/**
|
|
99
|
-
* @brief async transform.
|
|
68
|
+
* @brief Execute async transform.
|
|
69
|
+
* @details This helper keeps a local invariant explicit at the module boundary.
|
|
100
70
|
*/
|
|
101
71
|
export declare function asyncTransform<TValue, TNext>(source: Decoder<TValue> | AsyncDecoder<TValue>, mapper: AsyncMapper<TValue, TNext>): BaseAsyncDecoder<TNext>;
|
|
102
72
|
/**
|
|
103
|
-
* @brief async pipe.
|
|
73
|
+
* @brief Execute async pipe.
|
|
74
|
+
* @details This helper keeps a local invariant explicit at the module boundary.
|
|
104
75
|
*/
|
|
105
76
|
export declare function asyncPipe<TNext extends AsyncDecodeSource>(source: AsyncDecodeSource, next: TNext): BaseAsyncDecoder<InferAsyncDecoder<TNext>>;
|
|
106
77
|
/**
|
|
107
|
-
* @brief
|
|
78
|
+
* @brief Check async decoder value.
|
|
79
|
+
* @details This helper keeps a local invariant explicit at the module boundary.
|
|
108
80
|
*/
|
|
109
81
|
export declare function isAsyncDecoderValue(value: unknown): value is AsyncDecoder<unknown>;
|
|
110
82
|
export {};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/async/index.ts"],"names":[],"mappings":"AAAA,OAAO,
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/async/index.ts"],"names":[],"mappings":"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"}
|
package/dist/async/index.js
CHANGED
|
@@ -4,23 +4,23 @@ import { freezeIssueArray, makeIssue } from "../issue/index.js";
|
|
|
4
4
|
import { err, ok } from "../result/index.js";
|
|
5
5
|
import { freezeSchema, isSchemaValue } from "../schema/index.js";
|
|
6
6
|
/**
|
|
7
|
-
* @brief async decoder
|
|
7
|
+
* @brief Private runner slot for async decoder instances.
|
|
8
|
+
* @details Decoder helpers keep validation failures explicit in Result values while
|
|
9
|
+
* preserving the original input value.
|
|
8
10
|
*/
|
|
9
11
|
const AsyncDecoderRunSymbol = Symbol("TypeSea.asyncDecoder.run");
|
|
10
12
|
/**
|
|
11
|
-
* @brief
|
|
13
|
+
* @brief Real async decoder instances tracked without extending object lifetime.
|
|
14
|
+
* @details Decoder helpers keep validation failures explicit in Result values while
|
|
15
|
+
* preserving the original input value.
|
|
12
16
|
*/
|
|
13
17
|
const constructedAsyncDecoders = new WeakSet();
|
|
14
18
|
/**
|
|
15
|
-
* @brief
|
|
16
|
-
* @details
|
|
17
|
-
*
|
|
19
|
+
* @brief Frozen wrapper around one async decode runner.
|
|
20
|
+
* @details Receiver validation mirrors BaseDecoder so detached method calls do
|
|
21
|
+
* not bypass TypeSea's object construction checks.
|
|
18
22
|
*/
|
|
19
23
|
export class BaseAsyncDecoder {
|
|
20
|
-
/**
|
|
21
|
-
* @brief constructor.
|
|
22
|
-
* @post The receiver is initialized according to the class invariant before it can be observed.
|
|
23
|
-
*/
|
|
24
24
|
constructor(run) {
|
|
25
25
|
if (typeof run !== "function") {
|
|
26
26
|
throw new TypeError("async decoder run must be a function");
|
|
@@ -29,15 +29,9 @@ export class BaseAsyncDecoder {
|
|
|
29
29
|
constructedAsyncDecoders.add(this);
|
|
30
30
|
Object.freeze(this);
|
|
31
31
|
}
|
|
32
|
-
/**
|
|
33
|
-
* @brief decode async.
|
|
34
|
-
*/
|
|
35
32
|
decodeAsync(value) {
|
|
36
33
|
return readAsyncDecoderRunner(this, "async decoder receiver")(value);
|
|
37
34
|
}
|
|
38
|
-
/**
|
|
39
|
-
* @brief refine async.
|
|
40
|
-
*/
|
|
41
35
|
refineAsync(predicate, name) {
|
|
42
36
|
if (typeof predicate !== "function") {
|
|
43
37
|
throw new TypeError("async refinement predicate must be a function");
|
|
@@ -58,9 +52,6 @@ export class BaseAsyncDecoder {
|
|
|
58
52
|
return failRefinement(name, decoded.value);
|
|
59
53
|
});
|
|
60
54
|
}
|
|
61
|
-
/**
|
|
62
|
-
* @brief transform async.
|
|
63
|
-
*/
|
|
64
55
|
transformAsync(mapper) {
|
|
65
56
|
if (typeof mapper !== "function") {
|
|
66
57
|
throw new TypeError("async transform mapper must be a function");
|
|
@@ -74,9 +65,6 @@ export class BaseAsyncDecoder {
|
|
|
74
65
|
return ok(await mapper(decoded.value));
|
|
75
66
|
});
|
|
76
67
|
}
|
|
77
|
-
/**
|
|
78
|
-
* @brief pipe async.
|
|
79
|
-
*/
|
|
80
68
|
pipeAsync(next) {
|
|
81
69
|
const run = readAsyncDecoderRunner(this, "async pipe receiver");
|
|
82
70
|
const nextRun = readAsyncDecodeSourceRunner(next, "async pipe target");
|
|
@@ -90,44 +78,58 @@ export class BaseAsyncDecoder {
|
|
|
90
78
|
}
|
|
91
79
|
}
|
|
92
80
|
/**
|
|
93
|
-
* @brief async decoder.
|
|
81
|
+
* @brief Execute async decoder.
|
|
82
|
+
* @details This helper keeps a local invariant explicit at the module boundary.
|
|
94
83
|
*/
|
|
95
84
|
export function asyncDecoder(source) {
|
|
96
85
|
return makeAsyncDecoder(source);
|
|
97
86
|
}
|
|
98
87
|
/**
|
|
99
|
-
* @brief async refine.
|
|
88
|
+
* @brief Execute async refine.
|
|
89
|
+
* @details This helper keeps a local invariant explicit at the module boundary.
|
|
100
90
|
*/
|
|
101
91
|
export function asyncRefine(source, predicate, name) {
|
|
102
92
|
return makeAsyncDecoder(source).refineAsync(predicate, name);
|
|
103
93
|
}
|
|
104
94
|
/**
|
|
105
|
-
* @brief async transform.
|
|
95
|
+
* @brief Execute async transform.
|
|
96
|
+
* @details This helper keeps a local invariant explicit at the module boundary.
|
|
106
97
|
*/
|
|
107
98
|
export function asyncTransform(source, mapper) {
|
|
108
99
|
return makeAsyncDecoder(source).transformAsync(mapper);
|
|
109
100
|
}
|
|
110
101
|
/**
|
|
111
|
-
* @brief async pipe.
|
|
102
|
+
* @brief Execute async pipe.
|
|
103
|
+
* @details This helper keeps a local invariant explicit at the module boundary.
|
|
112
104
|
*/
|
|
113
105
|
export function asyncPipe(source, next) {
|
|
114
106
|
return makeAsyncDecoder(source).pipeAsync(next);
|
|
115
107
|
}
|
|
116
108
|
/**
|
|
117
|
-
* @brief
|
|
109
|
+
* @brief Check async decoder value.
|
|
110
|
+
* @details This helper keeps a local invariant explicit at the module boundary.
|
|
118
111
|
*/
|
|
119
112
|
export function isAsyncDecoderValue(value) {
|
|
120
113
|
return isConstructedAsyncDecoder(value);
|
|
121
114
|
}
|
|
122
115
|
/**
|
|
123
|
-
* @brief
|
|
116
|
+
* @brief Construct an async decoder from a guard, decoder, or async decoder.
|
|
117
|
+
* @details Decoder helpers keep validation failures explicit in Result values while
|
|
118
|
+
* preserving the original input value.
|
|
119
|
+
* @param source Source pipeline element.
|
|
120
|
+
* @returns Async decoder wrapping the normalized runner.
|
|
124
121
|
*/
|
|
125
122
|
function makeAsyncDecoder(source) {
|
|
126
123
|
const run = readAsyncDecodeSourceRunner(source, "async decoder source");
|
|
127
124
|
return new BaseAsyncDecoder(run);
|
|
128
125
|
}
|
|
129
126
|
/**
|
|
130
|
-
* @brief
|
|
127
|
+
* @brief Resolve an async decode source into a promise-returning runner.
|
|
128
|
+
* @param source Candidate source supplied to async decoder composition.
|
|
129
|
+
* @param label Message prefix for TypeError diagnostics.
|
|
130
|
+
* @returns Runner that always reports through a Promise.
|
|
131
|
+
* @details Sync decoders and guards are wrapped with Promise.resolve so the
|
|
132
|
+
* outer async pipeline has one uniform scheduling shape.
|
|
131
133
|
*/
|
|
132
134
|
function readAsyncDecodeSourceRunner(source, label) {
|
|
133
135
|
if (isConstructedAsyncDecoder(source)) {
|
|
@@ -140,7 +142,13 @@ function readAsyncDecodeSourceRunner(source, label) {
|
|
|
140
142
|
return (value) => Promise.resolve(checkSchema(schema, value));
|
|
141
143
|
}
|
|
142
144
|
/**
|
|
143
|
-
* @brief
|
|
145
|
+
* @brief Read the private runner from a constructed async decoder.
|
|
146
|
+
* @details Decoder helpers keep validation failures explicit in Result values while
|
|
147
|
+
* preserving the original input value.
|
|
148
|
+
* @param value Candidate async decoder object.
|
|
149
|
+
* @param label Message prefix for TypeError diagnostics.
|
|
150
|
+
* @returns Stored async decode runner.
|
|
151
|
+
* @throws TypeError when the value was not registered by the constructor.
|
|
144
152
|
*/
|
|
145
153
|
function readAsyncDecoderRunner(value, label) {
|
|
146
154
|
if (!isConstructedAsyncDecoder(value)) {
|
|
@@ -149,26 +157,41 @@ function readAsyncDecoderRunner(value, label) {
|
|
|
149
157
|
return value[AsyncDecoderRunSymbol];
|
|
150
158
|
}
|
|
151
159
|
/**
|
|
152
|
-
* @brief
|
|
160
|
+
* @brief Test async decoder identity through the private registry.
|
|
161
|
+
* @details Decoder helpers keep validation failures explicit in Result values while
|
|
162
|
+
* preserving the original input value.
|
|
163
|
+
* @param value Candidate async decoder.
|
|
164
|
+
* @returns True when TypeSea constructed the instance.
|
|
153
165
|
*/
|
|
154
166
|
function isConstructedAsyncDecoder(value) {
|
|
155
167
|
return isRecord(value) && constructedAsyncDecoders.has(value);
|
|
156
168
|
}
|
|
157
169
|
/**
|
|
158
|
-
* @brief
|
|
170
|
+
* @brief Normalize a guard-like source used in an async decode pipeline.
|
|
171
|
+
* @details Decoder helpers keep validation failures explicit in Result values while
|
|
172
|
+
* preserving the original input value.
|
|
173
|
+
* @param value Candidate guard-like source.
|
|
174
|
+
* @param label Message prefix for TypeError diagnostics.
|
|
175
|
+
* @returns Frozen schema used by the promise-wrapped check runner.
|
|
176
|
+
* @throws TypeError when the schema slot is absent or malformed.
|
|
159
177
|
*/
|
|
160
178
|
function readGuardSchema(value, label) {
|
|
161
179
|
if (!isRecord(value)) {
|
|
162
180
|
throw new TypeError(`${label} must be a TypeSea guard or decoder`);
|
|
163
181
|
}
|
|
164
|
-
const schema = value
|
|
182
|
+
const schema = readOwnDataProperty(value, "schema");
|
|
165
183
|
if (!isSchemaValue(schema)) {
|
|
166
184
|
throw new TypeError(`${label} must contain a valid TypeSea schema`);
|
|
167
185
|
}
|
|
168
186
|
return freezeSchema(schema);
|
|
169
187
|
}
|
|
170
188
|
/**
|
|
171
|
-
* @brief
|
|
189
|
+
* @brief Build a single-issue failure for an async refinement.
|
|
190
|
+
* @details Decoder helpers keep validation failures explicit in Result values while
|
|
191
|
+
* preserving the original input value.
|
|
192
|
+
* @param name Diagnostic refinement name.
|
|
193
|
+
* @param value Runtime value rejected by the predicate.
|
|
194
|
+
* @returns Failure result with a root-level refinement issue.
|
|
172
195
|
*/
|
|
173
196
|
function failRefinement(name, value) {
|
|
174
197
|
return err(freezeIssueArray([
|
|
@@ -176,7 +199,11 @@ function failRefinement(name, value) {
|
|
|
176
199
|
]));
|
|
177
200
|
}
|
|
178
201
|
/**
|
|
179
|
-
* @brief
|
|
202
|
+
* @brief Produce the compact runtime type label used in async decoder issues.
|
|
203
|
+
* @details Decoder helpers keep validation failures explicit in Result values while
|
|
204
|
+
* preserving the original input value.
|
|
205
|
+
* @param value Runtime value.
|
|
206
|
+
* @returns Stable diagnostic type name.
|
|
180
207
|
*/
|
|
181
208
|
function actualType(value) {
|
|
182
209
|
if (value === null) {
|
|
@@ -197,13 +224,23 @@ function actualType(value) {
|
|
|
197
224
|
return typeof value;
|
|
198
225
|
}
|
|
199
226
|
/**
|
|
200
|
-
* @brief
|
|
227
|
+
* @brief Accept only the literal boolean success value from async predicates.
|
|
228
|
+
* @details Decoder helpers keep validation failures explicit in Result values while
|
|
229
|
+
* preserving the original input value.
|
|
230
|
+
* @param value Predicate return value.
|
|
231
|
+
* @returns True only for `true`.
|
|
201
232
|
*/
|
|
202
233
|
function isStrictTrue(value) {
|
|
203
234
|
return value === true;
|
|
204
235
|
}
|
|
205
236
|
/**
|
|
206
|
-
* @brief
|
|
237
|
+
* @brief Define one immutable async decoder instance slot.
|
|
238
|
+
* @details Decoder helpers keep validation failures explicit in Result values while
|
|
239
|
+
* preserving the original input value.
|
|
240
|
+
* @param target Async decoder instance.
|
|
241
|
+
* @param key Public key or private symbol.
|
|
242
|
+
* @param value Stored field value.
|
|
243
|
+
* @param enumerable Whether the field should appear in enumeration.
|
|
207
244
|
*/
|
|
208
245
|
function defineReadonlyProperty(target, key, value, enumerable) {
|
|
209
246
|
Object.defineProperty(target, key, {
|
|
@@ -214,8 +251,28 @@ function defineReadonlyProperty(target, key, value, enumerable) {
|
|
|
214
251
|
});
|
|
215
252
|
}
|
|
216
253
|
/**
|
|
217
|
-
* @brief
|
|
254
|
+
* @brief Accept objects that can carry async decoder or guard fields.
|
|
255
|
+
* @details Decoder helpers keep validation failures explicit in Result values while
|
|
256
|
+
* preserving the original input value.
|
|
257
|
+
* @param value Candidate object.
|
|
258
|
+
* @returns True for non-array objects.
|
|
218
259
|
*/
|
|
219
260
|
function isRecord(value) {
|
|
220
261
|
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
221
262
|
}
|
|
263
|
+
/**
|
|
264
|
+
* @brief Read one own data slot from an async decode source.
|
|
265
|
+
* @details Decoder helpers keep validation failures explicit in Result values while
|
|
266
|
+
* preserving the original input value.
|
|
267
|
+
* @param value Object being normalized.
|
|
268
|
+
* @param key Field name or symbol.
|
|
269
|
+
* @returns Stored field value, or undefined when absent.
|
|
270
|
+
*/
|
|
271
|
+
function readOwnDataProperty(value, key) {
|
|
272
|
+
const descriptor = Object.getOwnPropertyDescriptor(value, key);
|
|
273
|
+
if (descriptor === undefined ||
|
|
274
|
+
!Object.prototype.hasOwnProperty.call(descriptor, "value")) {
|
|
275
|
+
return undefined;
|
|
276
|
+
}
|
|
277
|
+
return descriptor.value;
|
|
278
|
+
}
|