@ghostry/fabricator 0.0.1
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/LICENSE +21 -0
- package/README.md +47 -0
- package/dist/esm/Adapter/Core.js +47 -0
- package/dist/esm/Adapter/Types.js +1 -0
- package/dist/esm/Bound.js +81 -0
- package/dist/esm/Distribution/index.js +200 -0
- package/dist/esm/Enumeration/Enumerate.js +103 -0
- package/dist/esm/Enumeration/Plan.js +286 -0
- package/dist/esm/Enumeration/Types.js +1 -0
- package/dist/esm/Error/index.js +201 -0
- package/dist/esm/Fabricator/Constructor.js +328 -0
- package/dist/esm/Fabricator/Types.js +1 -0
- package/dist/esm/Instance/Core.js +119 -0
- package/dist/esm/Instance/Types.js +1 -0
- package/dist/esm/Primitive/always/Fabricator.js +13 -0
- package/dist/esm/Primitive/always/Registry.js +11 -0
- package/dist/esm/Primitive/always/Schema.js +10 -0
- package/dist/esm/Primitive/always/Types.js +1 -0
- package/dist/esm/Primitive/always/index.js +5 -0
- package/dist/esm/Primitive/array/Fabricator.js +45 -0
- package/dist/esm/Primitive/array/Registry.js +26 -0
- package/dist/esm/Primitive/array/Schema.js +17 -0
- package/dist/esm/Primitive/array/Types.js +1 -0
- package/dist/esm/Primitive/array/index.js +5 -0
- package/dist/esm/Primitive/bigint/Fabricator.js +54 -0
- package/dist/esm/Primitive/bigint/Registry.js +31 -0
- package/dist/esm/Primitive/bigint/Schema.js +17 -0
- package/dist/esm/Primitive/bigint/Types.js +1 -0
- package/dist/esm/Primitive/bigint/index.js +5 -0
- package/dist/esm/Primitive/boolean/Fabricator.js +44 -0
- package/dist/esm/Primitive/boolean/Outcomes.js +5 -0
- package/dist/esm/Primitive/boolean/Registry.js +11 -0
- package/dist/esm/Primitive/boolean/Schema.js +33 -0
- package/dist/esm/Primitive/boolean/Types.js +1 -0
- package/dist/esm/Primitive/boolean/index.js +6 -0
- package/dist/esm/Primitive/choice/Fabricator.js +37 -0
- package/dist/esm/Primitive/choice/Registry.js +38 -0
- package/dist/esm/Primitive/choice/Schema.js +17 -0
- package/dist/esm/Primitive/choice/Types.js +1 -0
- package/dist/esm/Primitive/choice/index.js +5 -0
- package/dist/esm/Primitive/date/Fabricator.js +86 -0
- package/dist/esm/Primitive/date/Registry.js +61 -0
- package/dist/esm/Primitive/date/Schema.js +17 -0
- package/dist/esm/Primitive/date/Types.js +1 -0
- package/dist/esm/Primitive/date/index.js +5 -0
- package/dist/esm/Primitive/enum/Fabricator.js +33 -0
- package/dist/esm/Primitive/enum/Registry.js +33 -0
- package/dist/esm/Primitive/enum/Schema.js +17 -0
- package/dist/esm/Primitive/enum/Types.js +1 -0
- package/dist/esm/Primitive/enum/index.js +5 -0
- package/dist/esm/Primitive/index.js +24 -0
- package/dist/esm/Primitive/namespace.js +21 -0
- package/dist/esm/Primitive/null/Fabricator.js +14 -0
- package/dist/esm/Primitive/null/Registry.js +8 -0
- package/dist/esm/Primitive/null/Schema.js +10 -0
- package/dist/esm/Primitive/null/Types.js +1 -0
- package/dist/esm/Primitive/null/index.js +5 -0
- package/dist/esm/Primitive/nullable/Fabricator.js +58 -0
- package/dist/esm/Primitive/nullable/Outcomes.js +5 -0
- package/dist/esm/Primitive/nullable/Registry.js +13 -0
- package/dist/esm/Primitive/nullable/Schema.js +36 -0
- package/dist/esm/Primitive/nullable/Types.js +1 -0
- package/dist/esm/Primitive/nullable/index.js +6 -0
- package/dist/esm/Primitive/nullish/Fabricator.js +64 -0
- package/dist/esm/Primitive/nullish/Outcomes.js +6 -0
- package/dist/esm/Primitive/nullish/Registry.js +13 -0
- package/dist/esm/Primitive/nullish/Schema.js +36 -0
- package/dist/esm/Primitive/nullish/Types.js +1 -0
- package/dist/esm/Primitive/nullish/index.js +6 -0
- package/dist/esm/Primitive/number/Fabricator.js +73 -0
- package/dist/esm/Primitive/number/Registry.js +59 -0
- package/dist/esm/Primitive/number/Schema.js +18 -0
- package/dist/esm/Primitive/number/Types.js +1 -0
- package/dist/esm/Primitive/number/defaults.js +21 -0
- package/dist/esm/Primitive/number/index.js +5 -0
- package/dist/esm/Primitive/object/Fabricator.js +77 -0
- package/dist/esm/Primitive/object/Registry.js +146 -0
- package/dist/esm/Primitive/object/Schema.js +18 -0
- package/dist/esm/Primitive/object/Types.js +1 -0
- package/dist/esm/Primitive/object/compute/Fabricator.js +24 -0
- package/dist/esm/Primitive/object/compute/Registry.js +15 -0
- package/dist/esm/Primitive/object/compute/Schema.js +13 -0
- package/dist/esm/Primitive/object/compute/Types.js +1 -0
- package/dist/esm/Primitive/object/compute/index.js +5 -0
- package/dist/esm/Primitive/object/index.js +9 -0
- package/dist/esm/Primitive/object/omittable/Fabricator.js +57 -0
- package/dist/esm/Primitive/object/omittable/Outcomes.js +5 -0
- package/dist/esm/Primitive/object/omittable/Registry.js +13 -0
- package/dist/esm/Primitive/object/omittable/Schema.js +36 -0
- package/dist/esm/Primitive/object/omittable/Types.js +1 -0
- package/dist/esm/Primitive/object/omittable/index.js +6 -0
- package/dist/esm/Primitive/object/optional/Fabricator.js +55 -0
- package/dist/esm/Primitive/object/optional/Outcomes.js +6 -0
- package/dist/esm/Primitive/object/optional/Registry.js +13 -0
- package/dist/esm/Primitive/object/optional/Schema.js +36 -0
- package/dist/esm/Primitive/object/optional/Types.js +1 -0
- package/dist/esm/Primitive/object/optional/index.js +6 -0
- package/dist/esm/Primitive/opaque/Fabricator.js +19 -0
- package/dist/esm/Primitive/opaque/Registry.js +11 -0
- package/dist/esm/Primitive/opaque/Schema.js +10 -0
- package/dist/esm/Primitive/opaque/Types.js +1 -0
- package/dist/esm/Primitive/opaque/index.js +5 -0
- package/dist/esm/Primitive/record/Fabricator.js +55 -0
- package/dist/esm/Primitive/record/Registry.js +26 -0
- package/dist/esm/Primitive/record/Schema.js +17 -0
- package/dist/esm/Primitive/record/Types.js +1 -0
- package/dist/esm/Primitive/record/index.js +5 -0
- package/dist/esm/Primitive/recursive/Fabricator.js +33 -0
- package/dist/esm/Primitive/recursive/Registry.js +20 -0
- package/dist/esm/Primitive/recursive/Schema.js +10 -0
- package/dist/esm/Primitive/recursive/Terminate.js +236 -0
- package/dist/esm/Primitive/recursive/Types.js +1 -0
- package/dist/esm/Primitive/recursive/index.js +7 -0
- package/dist/esm/Primitive/recursive/self/Fabricator.js +15 -0
- package/dist/esm/Primitive/recursive/self/Registry.js +9 -0
- package/dist/esm/Primitive/recursive/self/Schema.js +10 -0
- package/dist/esm/Primitive/recursive/self/Types.js +1 -0
- package/dist/esm/Primitive/recursive/self/index.js +5 -0
- package/dist/esm/Primitive/string/Constants.js +73 -0
- package/dist/esm/Primitive/string/Fabricator.js +109 -0
- package/dist/esm/Primitive/string/Registry.js +25 -0
- package/dist/esm/Primitive/string/Schema.js +18 -0
- package/dist/esm/Primitive/string/Types.js +1 -0
- package/dist/esm/Primitive/string/index.js +6 -0
- package/dist/esm/Primitive/symbol/Fabricator.js +33 -0
- package/dist/esm/Primitive/symbol/Registry.js +17 -0
- package/dist/esm/Primitive/symbol/Schema.js +17 -0
- package/dist/esm/Primitive/symbol/Types.js +1 -0
- package/dist/esm/Primitive/symbol/index.js +5 -0
- package/dist/esm/Primitive/tuple/Fabricator.js +33 -0
- package/dist/esm/Primitive/tuple/Registry.js +13 -0
- package/dist/esm/Primitive/tuple/Schema.js +17 -0
- package/dist/esm/Primitive/tuple/Types.js +1 -0
- package/dist/esm/Primitive/tuple/index.js +5 -0
- package/dist/esm/Primitive/undefinable/Fabricator.js +58 -0
- package/dist/esm/Primitive/undefinable/Outcomes.js +5 -0
- package/dist/esm/Primitive/undefinable/Registry.js +13 -0
- package/dist/esm/Primitive/undefinable/Schema.js +36 -0
- package/dist/esm/Primitive/undefinable/Types.js +1 -0
- package/dist/esm/Primitive/undefinable/index.js +6 -0
- package/dist/esm/Primitive/undefined/Fabricator.js +16 -0
- package/dist/esm/Primitive/undefined/Registry.js +8 -0
- package/dist/esm/Primitive/undefined/Schema.js +10 -0
- package/dist/esm/Primitive/undefined/Types.js +1 -0
- package/dist/esm/Primitive/undefined/index.js +5 -0
- package/dist/esm/Random/CallSite.js +56 -0
- package/dist/esm/Random/Generator/sfc32.js +16 -0
- package/dist/esm/Random/Types.js +1 -0
- package/dist/esm/Random/index.js +151 -0
- package/dist/esm/Schema/Core.js +68 -0
- package/dist/esm/Schema/Registry.js +17 -0
- package/dist/esm/Schema/Types.js +1 -0
- package/dist/esm/Types.js +11 -0
- package/dist/esm/Utility/Core.js +36 -0
- package/dist/esm/Utility/DeepMerge.js +18 -0
- package/dist/esm/Utility/Digest.js +28 -0
- package/dist/esm/Utility/ShallowMerge.js +13 -0
- package/dist/esm/Utility/Types.js +1 -0
- package/dist/esm/index.js +11 -0
- package/dist/esm/internal.js +5 -0
- package/dist/types/Adapter/Core.d.ts +64 -0
- package/dist/types/Adapter/Types.d.ts +145 -0
- package/dist/types/Bound.d.ts +68 -0
- package/dist/types/Distribution/index.d.ts +157 -0
- package/dist/types/Enumeration/Enumerate.d.ts +35 -0
- package/dist/types/Enumeration/Plan.d.ts +44 -0
- package/dist/types/Enumeration/Types.d.ts +86 -0
- package/dist/types/Error/index.d.ts +541 -0
- package/dist/types/Fabricator/Constructor.d.ts +43 -0
- package/dist/types/Fabricator/Types.d.ts +150 -0
- package/dist/types/Instance/Core.d.ts +98 -0
- package/dist/types/Instance/Types.d.ts +167 -0
- package/dist/types/Primitive/always/Fabricator.d.ts +19 -0
- package/dist/types/Primitive/always/Registry.d.ts +3 -0
- package/dist/types/Primitive/always/Schema.d.ts +19 -0
- package/dist/types/Primitive/always/Types.d.ts +23 -0
- package/dist/types/Primitive/always/index.d.ts +5 -0
- package/dist/types/Primitive/array/Fabricator.d.ts +22 -0
- package/dist/types/Primitive/array/Registry.d.ts +18 -0
- package/dist/types/Primitive/array/Schema.d.ts +23 -0
- package/dist/types/Primitive/array/Types.d.ts +44 -0
- package/dist/types/Primitive/array/index.d.ts +5 -0
- package/dist/types/Primitive/bigint/Fabricator.d.ts +19 -0
- package/dist/types/Primitive/bigint/Registry.d.ts +19 -0
- package/dist/types/Primitive/bigint/Schema.d.ts +27 -0
- package/dist/types/Primitive/bigint/Types.d.ts +33 -0
- package/dist/types/Primitive/bigint/index.d.ts +5 -0
- package/dist/types/Primitive/boolean/Fabricator.d.ts +19 -0
- package/dist/types/Primitive/boolean/Outcomes.d.ts +12 -0
- package/dist/types/Primitive/boolean/Registry.d.ts +14 -0
- package/dist/types/Primitive/boolean/Schema.d.ts +28 -0
- package/dist/types/Primitive/boolean/Types.d.ts +26 -0
- package/dist/types/Primitive/boolean/index.d.ts +6 -0
- package/dist/types/Primitive/choice/Fabricator.d.ts +32 -0
- package/dist/types/Primitive/choice/Registry.d.ts +38 -0
- package/dist/types/Primitive/choice/Schema.d.ts +24 -0
- package/dist/types/Primitive/choice/Types.d.ts +35 -0
- package/dist/types/Primitive/choice/index.d.ts +5 -0
- package/dist/types/Primitive/date/Fabricator.d.ts +19 -0
- package/dist/types/Primitive/date/Registry.d.ts +82 -0
- package/dist/types/Primitive/date/Schema.d.ts +28 -0
- package/dist/types/Primitive/date/Types.d.ts +34 -0
- package/dist/types/Primitive/date/index.d.ts +5 -0
- package/dist/types/Primitive/enum/Fabricator.d.ts +19 -0
- package/dist/types/Primitive/enum/Registry.d.ts +39 -0
- package/dist/types/Primitive/enum/Schema.d.ts +23 -0
- package/dist/types/Primitive/enum/Types.d.ts +44 -0
- package/dist/types/Primitive/enum/index.d.ts +5 -0
- package/dist/types/Primitive/index.d.ts +28 -0
- package/dist/types/Primitive/namespace.d.ts +38 -0
- package/dist/types/Primitive/null/Fabricator.d.ts +19 -0
- package/dist/types/Primitive/null/Registry.d.ts +3 -0
- package/dist/types/Primitive/null/Schema.d.ts +16 -0
- package/dist/types/Primitive/null/Types.d.ts +15 -0
- package/dist/types/Primitive/null/index.d.ts +5 -0
- package/dist/types/Primitive/nullable/Fabricator.d.ts +31 -0
- package/dist/types/Primitive/nullable/Outcomes.d.ts +9 -0
- package/dist/types/Primitive/nullable/Registry.d.ts +3 -0
- package/dist/types/Primitive/nullable/Schema.d.ts +36 -0
- package/dist/types/Primitive/nullable/Types.d.ts +48 -0
- package/dist/types/Primitive/nullable/index.d.ts +6 -0
- package/dist/types/Primitive/nullish/Fabricator.d.ts +36 -0
- package/dist/types/Primitive/nullish/Outcomes.d.ts +9 -0
- package/dist/types/Primitive/nullish/Registry.d.ts +3 -0
- package/dist/types/Primitive/nullish/Schema.d.ts +36 -0
- package/dist/types/Primitive/nullish/Types.d.ts +58 -0
- package/dist/types/Primitive/nullish/index.d.ts +6 -0
- package/dist/types/Primitive/number/Fabricator.d.ts +19 -0
- package/dist/types/Primitive/number/Registry.d.ts +52 -0
- package/dist/types/Primitive/number/Schema.d.ts +32 -0
- package/dist/types/Primitive/number/Types.d.ts +56 -0
- package/dist/types/Primitive/number/defaults.d.ts +18 -0
- package/dist/types/Primitive/number/index.d.ts +5 -0
- package/dist/types/Primitive/object/Fabricator.d.ts +56 -0
- package/dist/types/Primitive/object/Registry.d.ts +23 -0
- package/dist/types/Primitive/object/Schema.d.ts +41 -0
- package/dist/types/Primitive/object/Types.d.ts +85 -0
- package/dist/types/Primitive/object/compute/Fabricator.d.ts +31 -0
- package/dist/types/Primitive/object/compute/Registry.d.ts +4 -0
- package/dist/types/Primitive/object/compute/Schema.d.ts +21 -0
- package/dist/types/Primitive/object/compute/Types.d.ts +56 -0
- package/dist/types/Primitive/object/compute/index.d.ts +5 -0
- package/dist/types/Primitive/object/index.d.ts +8 -0
- package/dist/types/Primitive/object/omittable/Fabricator.d.ts +37 -0
- package/dist/types/Primitive/object/omittable/Outcomes.d.ts +9 -0
- package/dist/types/Primitive/object/omittable/Registry.d.ts +3 -0
- package/dist/types/Primitive/object/omittable/Schema.d.ts +32 -0
- package/dist/types/Primitive/object/omittable/Types.d.ts +57 -0
- package/dist/types/Primitive/object/omittable/index.d.ts +6 -0
- package/dist/types/Primitive/object/optional/Fabricator.d.ts +45 -0
- package/dist/types/Primitive/object/optional/Outcomes.d.ts +9 -0
- package/dist/types/Primitive/object/optional/Registry.d.ts +3 -0
- package/dist/types/Primitive/object/optional/Schema.d.ts +32 -0
- package/dist/types/Primitive/object/optional/Types.d.ts +72 -0
- package/dist/types/Primitive/object/optional/index.d.ts +6 -0
- package/dist/types/Primitive/opaque/Fabricator.d.ts +19 -0
- package/dist/types/Primitive/opaque/Registry.d.ts +12 -0
- package/dist/types/Primitive/opaque/Schema.d.ts +22 -0
- package/dist/types/Primitive/opaque/Types.d.ts +18 -0
- package/dist/types/Primitive/opaque/index.d.ts +5 -0
- package/dist/types/Primitive/record/Fabricator.d.ts +25 -0
- package/dist/types/Primitive/record/Registry.d.ts +17 -0
- package/dist/types/Primitive/record/Schema.d.ts +27 -0
- package/dist/types/Primitive/record/Types.d.ts +85 -0
- package/dist/types/Primitive/record/index.d.ts +5 -0
- package/dist/types/Primitive/recursive/Fabricator.d.ts +47 -0
- package/dist/types/Primitive/recursive/Registry.d.ts +22 -0
- package/dist/types/Primitive/recursive/Schema.d.ts +21 -0
- package/dist/types/Primitive/recursive/Terminate.d.ts +20 -0
- package/dist/types/Primitive/recursive/Types.d.ts +82 -0
- package/dist/types/Primitive/recursive/index.d.ts +6 -0
- package/dist/types/Primitive/recursive/self/Fabricator.d.ts +29 -0
- package/dist/types/Primitive/recursive/self/Registry.d.ts +7 -0
- package/dist/types/Primitive/recursive/self/Schema.d.ts +20 -0
- package/dist/types/Primitive/recursive/self/Types.d.ts +28 -0
- package/dist/types/Primitive/recursive/self/index.d.ts +5 -0
- package/dist/types/Primitive/string/Constants.d.ts +58 -0
- package/dist/types/Primitive/string/Fabricator.d.ts +24 -0
- package/dist/types/Primitive/string/Registry.d.ts +44 -0
- package/dist/types/Primitive/string/Schema.d.ts +65 -0
- package/dist/types/Primitive/string/Types.d.ts +77 -0
- package/dist/types/Primitive/string/index.d.ts +6 -0
- package/dist/types/Primitive/symbol/Fabricator.d.ts +24 -0
- package/dist/types/Primitive/symbol/Registry.d.ts +16 -0
- package/dist/types/Primitive/symbol/Schema.d.ts +24 -0
- package/dist/types/Primitive/symbol/Types.d.ts +19 -0
- package/dist/types/Primitive/symbol/index.d.ts +5 -0
- package/dist/types/Primitive/tuple/Fabricator.d.ts +37 -0
- package/dist/types/Primitive/tuple/Registry.d.ts +3 -0
- package/dist/types/Primitive/tuple/Schema.d.ts +24 -0
- package/dist/types/Primitive/tuple/Types.d.ts +53 -0
- package/dist/types/Primitive/tuple/index.d.ts +5 -0
- package/dist/types/Primitive/undefinable/Fabricator.d.ts +31 -0
- package/dist/types/Primitive/undefinable/Outcomes.d.ts +9 -0
- package/dist/types/Primitive/undefinable/Registry.d.ts +3 -0
- package/dist/types/Primitive/undefinable/Schema.d.ts +36 -0
- package/dist/types/Primitive/undefinable/Types.d.ts +48 -0
- package/dist/types/Primitive/undefinable/index.d.ts +6 -0
- package/dist/types/Primitive/undefined/Fabricator.d.ts +19 -0
- package/dist/types/Primitive/undefined/Registry.d.ts +3 -0
- package/dist/types/Primitive/undefined/Schema.d.ts +16 -0
- package/dist/types/Primitive/undefined/Types.d.ts +15 -0
- package/dist/types/Primitive/undefined/index.d.ts +5 -0
- package/dist/types/Random/CallSite.d.ts +59 -0
- package/dist/types/Random/Generator/sfc32.d.ts +10 -0
- package/dist/types/Random/Types.d.ts +384 -0
- package/dist/types/Random/index.d.ts +107 -0
- package/dist/types/Schema/Core.d.ts +44 -0
- package/dist/types/Schema/Registry.d.ts +20 -0
- package/dist/types/Schema/Types.d.ts +70 -0
- package/dist/types/Types.d.ts +78 -0
- package/dist/types/Utility/Core.d.ts +35 -0
- package/dist/types/Utility/DeepMerge.d.ts +14 -0
- package/dist/types/Utility/Digest.d.ts +9 -0
- package/dist/types/Utility/ShallowMerge.d.ts +6 -0
- package/dist/types/Utility/Types.d.ts +4 -0
- package/dist/types/index.d.ts +186 -0
- package/dist/types/internal.d.ts +64 -0
- package/package.json +53 -0
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
import { Adaptation } from "../Types";
|
|
2
|
+
import type { Adaptations, AdaptationsOf, Adapter, Adapting, WithAdaptations } from "./Types";
|
|
3
|
+
type OverrideSchemaAdaptation<$Schema extends object, $Map extends Adaptations> = Omit<$Schema, typeof Adaptation> & {
|
|
4
|
+
readonly [Adaptation]?: WithAdaptations<AdaptationsOf<$Schema>, $Map>;
|
|
5
|
+
};
|
|
6
|
+
/**
|
|
7
|
+
* One adapter's entry, keyed by `$Adapter["key"]`. Written as a mapped
|
|
8
|
+
* type rather than built inline: a computed key in an object literal
|
|
9
|
+
* (`{ [adapter.key]: produce }`) widens to a `string` index signature,
|
|
10
|
+
* which no adapter's literal-keyed dispatch matches.
|
|
11
|
+
*/
|
|
12
|
+
export type AdaptationEntry<$Adapter extends Adapter, $Returnable> = {
|
|
13
|
+
readonly [$K in $Adapter["key"]]: (schema: any) => $Returnable;
|
|
14
|
+
};
|
|
15
|
+
/**
|
|
16
|
+
* A copy of `schema` carrying `produce` as `adapter`'s adaptation:
|
|
17
|
+
* that adapter's prior entry is replaced (via {@link layer}), every
|
|
18
|
+
* other adapter's is carried forward. Every kind's `.adapt(...)` is a
|
|
19
|
+
* call to this, re-typed to that kind's own
|
|
20
|
+
* `Schema<..., WithAdaptations<...>>`.
|
|
21
|
+
*
|
|
22
|
+
* Takes the adapter and producer separately rather than a prebuilt map
|
|
23
|
+
* so the key stays a literal, per {@link AdaptationEntry}. The return
|
|
24
|
+
* type mirrors the merge (rather than handing back `$Schema`) so call
|
|
25
|
+
* sites need no cast: `AdaptationsOf<$Schema>` recovers the prior map
|
|
26
|
+
* from whichever kind's `Core` was passed in.
|
|
27
|
+
*/
|
|
28
|
+
export declare function withAdaptations<const $Schema extends object, const $Adapter extends Adapter, $Returnable>(schema: $Schema, adapter: $Adapter, produce: (adapting: Adapting<any>) => $Returnable): OverrideSchemaAdaptation<$Schema, AdaptationEntry<$Adapter, $Returnable>>;
|
|
29
|
+
/**
|
|
30
|
+
* {@link withAdaptations} at the map level, for a kind that keeps its
|
|
31
|
+
* adaptations beside its schema rather than on it — `object`, whose
|
|
32
|
+
* `extend`/`refine`/`override` each rebuild the schema from scratch, so
|
|
33
|
+
* `Registry.ts`'s `make` has to thread the map through explicitly (see
|
|
34
|
+
* its `adapt`).
|
|
35
|
+
*
|
|
36
|
+
* `undefined` rather than an empty map when there is nothing to carry,
|
|
37
|
+
* for the same reason `patched` drops the symbol: an absent map and an
|
|
38
|
+
* empty one mean the same thing, and only one of them should exist at
|
|
39
|
+
* runtime.
|
|
40
|
+
*/
|
|
41
|
+
export declare function mergeAdaptations<$Prior extends Adaptations, const $Adapter extends Adapter, $Returnable>(prior: $Prior | undefined, adapter: $Adapter, produce: (adapting: Adapting<any>) => $Returnable): WithAdaptations<$Prior, AdaptationEntry<$Adapter, $Returnable>> | undefined;
|
|
42
|
+
/**
|
|
43
|
+
* Walk `schema` with `adapter`, resolving each node to its external
|
|
44
|
+
* counterpart. Every adapter's entry point is a call to this.
|
|
45
|
+
*
|
|
46
|
+
* The adaptation lookup lives here, ahead of the adapter's own
|
|
47
|
+
* per-kind dispatch, so an explicit adaptation wins over the kind's
|
|
48
|
+
* mapping — and here rather than in each adapter so it applies at
|
|
49
|
+
* *every* node the walk reaches, not just the one it started from.
|
|
50
|
+
* That is why an adapter recurses through the {@link Recurse} it is
|
|
51
|
+
* handed rather than calling its own `convert` again: a nested
|
|
52
|
+
* `object` field, `array` element, or `choice` option gets the same
|
|
53
|
+
* treatment as the root.
|
|
54
|
+
*
|
|
55
|
+
* Paired with {@link layer}: together they make `toTypeBox(schema)`
|
|
56
|
+
* *inside* an adaptation resolve to the layer that adaptation replaced
|
|
57
|
+
* instead of re-entering itself. This reads the entry; `layer` already
|
|
58
|
+
* substituted the previous one into the argument. Splitting the two
|
|
59
|
+
* across packages is how they drift.
|
|
60
|
+
*/
|
|
61
|
+
export declare function drive<$Context, $Returnable>(adapter: Adapter<string, $Context, $Returnable>, schema: {
|
|
62
|
+
[Adaptation]?: Adaptations;
|
|
63
|
+
}, context: $Context): $Returnable;
|
|
64
|
+
export {};
|
|
@@ -0,0 +1,145 @@
|
|
|
1
|
+
import type { Adaptation, Meta } from "../Types";
|
|
2
|
+
/**
|
|
3
|
+
* One adapter's override for one schema, *as stored* in `[Adaptation]` —
|
|
4
|
+
* the loosest signature the mechanism needs. An adapter states its real
|
|
5
|
+
* return type on {@link Adapter.convert}, and `.adapt(...)` checks a
|
|
6
|
+
* supplied adaptation against that; nothing here reads either end.
|
|
7
|
+
*
|
|
8
|
+
* Not the shape a caller writes: a kind's `.adapt(...)` takes a producer
|
|
9
|
+
* of {@link Adapting}, which `Adapter/Core.ts`'s `withAdaptations`/
|
|
10
|
+
* `mergeAdaptations` wrap into this one entry point-side. The stored
|
|
11
|
+
* form stays schema-taking so `patched`/`layer` treat an incoming
|
|
12
|
+
* producer and a prior layered entry as one type, and so
|
|
13
|
+
* `AdaptationEntry`'s `(schema: any) => $Returnable` is an accurate
|
|
14
|
+
* account of what a schema carries.
|
|
15
|
+
*/
|
|
16
|
+
export type SchemaAdaptation = (schema: any) => unknown;
|
|
17
|
+
/**
|
|
18
|
+
* What a kind's `.adapt(adapter, produce)` hands its producer: the schema
|
|
19
|
+
* being adapted, and that schema's `[Meta]` — one object rather than two
|
|
20
|
+
* parameters, so destructuring picks whichever half is needed and neither
|
|
21
|
+
* is reachable only through a well-known symbol.
|
|
22
|
+
*
|
|
23
|
+
* `schema` carries whichever adaptation for this same adapter it
|
|
24
|
+
* replaced, absent at the bottom of the stack (see `Adapter/Core.ts`'s
|
|
25
|
+
* `layer`) — so `toTypeBox(schema)` inside a producer resolves to the
|
|
26
|
+
* previous layer, or to the kind's ordinary mapping when there is none.
|
|
27
|
+
* `meta` is read off that same substituted schema, so the two keys
|
|
28
|
+
* describe one object.
|
|
29
|
+
*
|
|
30
|
+
* `meta`'s shape is the kind's own config blob, derived by indexed
|
|
31
|
+
* access rather than named separately so no kind states its own `Meta`
|
|
32
|
+
* twice in an `adapt` signature. **Readable but not stabilized**: an
|
|
33
|
+
* adaptation may read it; a kind stays free to restructure it — nothing
|
|
34
|
+
* outside a kind's own files should *interpret* another kind's `[Meta]`.
|
|
35
|
+
*
|
|
36
|
+
* A kind with no bare-form default carries no `[Meta]` at runtime until
|
|
37
|
+
* configured (`string`/`bigint`'s registry exports — see "Anatomy of a
|
|
38
|
+
* primitive"), so `meta` can be `undefined` there despite this type.
|
|
39
|
+
* Same imprecision `Schema<$Meta>` already states, and why the TypeBox
|
|
40
|
+
* adapter reads `[Meta]` defensively for those kinds.
|
|
41
|
+
*/
|
|
42
|
+
export type Adapting<$Schema extends {
|
|
43
|
+
[Meta]: unknown;
|
|
44
|
+
}> = {
|
|
45
|
+
readonly schema: $Schema;
|
|
46
|
+
readonly meta: $Schema[typeof Meta];
|
|
47
|
+
};
|
|
48
|
+
/**
|
|
49
|
+
* What a Schema's `[Adaptation]` holds: each adapter's override, under
|
|
50
|
+
* that adapter's own key.
|
|
51
|
+
*
|
|
52
|
+
* Open rather than a closed registry of known libraries: an adapter is
|
|
53
|
+
* a value (see {@link Adapter}), not a name this package knows. Nothing
|
|
54
|
+
* has to be declared for a third party's adapter to work, and two
|
|
55
|
+
* adapters for different versions of the same library collide with
|
|
56
|
+
* nothing.
|
|
57
|
+
*/
|
|
58
|
+
export type Adaptations = {
|
|
59
|
+
readonly [key: string]: SchemaAdaptation;
|
|
60
|
+
};
|
|
61
|
+
/**
|
|
62
|
+
* An {@link Adaptations} update as `withAdaptations` accepts it. Identical
|
|
63
|
+
* except that an explicitly-`undefined` entry *removes* that adapter's
|
|
64
|
+
* override — how the layering hands an adaptation the schema it is
|
|
65
|
+
* adapting with its own entry replaced by the previous one, or absent
|
|
66
|
+
* at the bottom of the stack.
|
|
67
|
+
*
|
|
68
|
+
* Not what a kind's `.adapt(...)` accepts: removal is an internal need
|
|
69
|
+
* of the layering, and letting a caller express it would produce a
|
|
70
|
+
* `[Adaptation]` type that `exactOptionalPropertyTypes` rejects against
|
|
71
|
+
* {@link Adaptations}.
|
|
72
|
+
*/
|
|
73
|
+
export type Patch = {
|
|
74
|
+
readonly [key: string]: SchemaAdaptation | undefined;
|
|
75
|
+
};
|
|
76
|
+
/**
|
|
77
|
+
* How an adapter recurses into a nested schema — handed to
|
|
78
|
+
* {@link Adapter.convert} by `Adapter/Core.ts`'s `drive` rather than
|
|
79
|
+
* being the adapter's own private recursion, so every nested node goes
|
|
80
|
+
* back through the adaptation lookup, not only the outermost one.
|
|
81
|
+
*
|
|
82
|
+
* `$Context` is the adapter's own, and opaque here: an adapter that
|
|
83
|
+
* needs to carry something down its recursion (the enclosing
|
|
84
|
+
* `T.recursive`'s placeholder, say) threads it through unchanged.
|
|
85
|
+
* `$Returnable` is likewise the adapter's own — stated so a nested
|
|
86
|
+
* node's result drops straight into a composite
|
|
87
|
+
* (`Type.Array(recurse(element, context))`) with no cast at any call
|
|
88
|
+
* site.
|
|
89
|
+
*/
|
|
90
|
+
export type Recurse<$Context, $Returnable> = (schema: any, context: $Context) => $Returnable;
|
|
91
|
+
/**
|
|
92
|
+
* An adapter to one external schema library: a plain value, imported
|
|
93
|
+
* directly by whoever adapts a schema (`schema.adapt(typebox, ...)`)
|
|
94
|
+
* and by whoever converts one. Nothing to register — no global
|
|
95
|
+
* interface to declaration-merge, and no name chosen anywhere but here.
|
|
96
|
+
*
|
|
97
|
+
* `key` is the adapter's `[Adaptation]` namespace. Read off the value
|
|
98
|
+
* as a literal type, so a wrong one is an import error rather than an
|
|
99
|
+
* entry nothing looks up. Give it something collision-proof — a package
|
|
100
|
+
* specifier, versioned when a library's major rewrite means two
|
|
101
|
+
* adapters can coexist.
|
|
102
|
+
*
|
|
103
|
+
* `convert`'s declared return type is this adapter's external bound:
|
|
104
|
+
* the type every `.adapt(...)` against it must produce, and why an
|
|
105
|
+
* adaptation that returns the wrong thing fails at the call site.
|
|
106
|
+
*
|
|
107
|
+
* Deliberately *not* carrying the adapter's type-level mapping. An
|
|
108
|
+
* adapter package declares its own conversion entry point with its own
|
|
109
|
+
* return type (`toTypeBox<$S>(schema: $S): ToTypeBox<$S>`), so nothing
|
|
110
|
+
* has to compute a type-level mapping out of a stored value — which
|
|
111
|
+
* would need the interface-member-lookup encoding `ValueOf`'s
|
|
112
|
+
* `$Bindings` uses, for no gain.
|
|
113
|
+
*/
|
|
114
|
+
export interface Adapter<$Key extends string = string, $Context = unknown, $Returnable = unknown> {
|
|
115
|
+
readonly key: $Key;
|
|
116
|
+
convert(schema: any, recurse: Recurse<$Context, $Returnable>, context: $Context): $Returnable;
|
|
117
|
+
}
|
|
118
|
+
/**
|
|
119
|
+
* The adaptations a Schema (or a built Fabricator, which carries them
|
|
120
|
+
* identically) declares, or `{}` for one that declares none.
|
|
121
|
+
*
|
|
122
|
+
* The two steps — extract the map, then match against it — are
|
|
123
|
+
* load-bearing, and why no adapter matches
|
|
124
|
+
* `{ [Adaptation]?: Record<Key, ...> }` directly. Every kind's `Core`
|
|
125
|
+
* declares `[Adaptation]` as *optional*, and a conditional matching an
|
|
126
|
+
* optional property against a schema that lacks it entirely still
|
|
127
|
+
* *succeeds*, inferring `unknown` (the same behavior `ValueOf` relies
|
|
128
|
+
* on for `[Produces]`) — so a direct match would resolve every
|
|
129
|
+
* unadapted schema to whatever the adapter's adaptation branch
|
|
130
|
+
* produces. Constraining the `infer` sends that case here, to `{}`,
|
|
131
|
+
* which then fails each adapter's `Record<Key, ...>` check as it
|
|
132
|
+
* should.
|
|
133
|
+
*/
|
|
134
|
+
export type AdaptationsOf<$Schema> = $Schema extends {
|
|
135
|
+
[Adaptation]?: infer $Adaptations extends Adaptations;
|
|
136
|
+
} ? $Adaptations : {};
|
|
137
|
+
/**
|
|
138
|
+
* `$Prior` with `$Map` applied: an adapter named in `$Map` takes its new
|
|
139
|
+
* entry; one it doesn't name is carried forward. `Omit` first (rather
|
|
140
|
+
* than a plain `$Prior & $Map`) so a replaced entry is genuinely
|
|
141
|
+
* replaced — intersecting two call signatures for the same adapter
|
|
142
|
+
* would produce an overload, from which an adapter's `infer` would
|
|
143
|
+
* read whichever member TypeScript happens to resolve last.
|
|
144
|
+
*/
|
|
145
|
+
export type WithAdaptations<$Prior extends Adaptations, $Map extends Adaptations> = Omit<$Prior, keyof $Map> & $Map;
|
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Canonical endpoint stored on `[Meta].whereby`. Call sites still accept a
|
|
3
|
+
* scalar (inclusive) via {@link InputBound}; `.whereby()` runs {@link toBound}
|
|
4
|
+
* so adapters always see this shape — never a scalar/object union.
|
|
5
|
+
*/
|
|
6
|
+
export type Bound<$T> = {
|
|
7
|
+
value: $T;
|
|
8
|
+
exclusive: boolean;
|
|
9
|
+
};
|
|
10
|
+
/**
|
|
11
|
+
* What `.whereby({ min, max })` accepts: a scalar is inclusive, an object
|
|
12
|
+
* names an endpoint policy. `exclusive` is required on the object form so
|
|
13
|
+
* that form exists only to state one.
|
|
14
|
+
*/
|
|
15
|
+
export type InputBound<$T> = $T | Bound<$T>;
|
|
16
|
+
/**
|
|
17
|
+
* Collapse a call-site bound to the stored shape. A `Date` is a scalar here
|
|
18
|
+
* (`isPlainObject` rejects it); only a `{ value, exclusive }` literal is
|
|
19
|
+
* already canonical.
|
|
20
|
+
*/
|
|
21
|
+
export declare function toBound<$T>(input: InputBound<$T>): Bound<$T>;
|
|
22
|
+
/**
|
|
23
|
+
* Inclusive integer interval implied by a discrete Bound pair. Exclusive min
|
|
24
|
+
* is `value + 1`, exclusive max is `value - 1` — the same unit the length/
|
|
25
|
+
* integer/bigint draws already use. Empty iff `min > max`.
|
|
26
|
+
*/
|
|
27
|
+
export declare function effectiveDiscrete(min: Bound<number>, max: Bound<number>): {
|
|
28
|
+
min: number;
|
|
29
|
+
max: number;
|
|
30
|
+
};
|
|
31
|
+
export declare function effectiveDiscreteBigint(min: Bound<bigint>, max: Bound<bigint>): {
|
|
32
|
+
min: bigint;
|
|
33
|
+
max: bigint;
|
|
34
|
+
};
|
|
35
|
+
export declare function assertNonemptyDiscrete(label: string, min: Bound<number>, max: Bound<number>): void;
|
|
36
|
+
export declare function assertNonemptyDiscreteBigint(label: string, min: Bound<bigint>, max: Bound<bigint>): void;
|
|
37
|
+
/**
|
|
38
|
+
* Continuous emptiness: inverted bounds, a point range with either end
|
|
39
|
+
* exclusive, or both ends exclusive with no float strictly between them.
|
|
40
|
+
* Sampling still uses the closed interval and {@link constrainContinuous}
|
|
41
|
+
* steps off an exclusive endpoint — this check is what makes that step
|
|
42
|
+
* always have somewhere to land.
|
|
43
|
+
*/
|
|
44
|
+
export declare function assertNonemptyContinuous(label: string, min: Bound<number>, max: Bound<number>): void;
|
|
45
|
+
/**
|
|
46
|
+
* One ulp toward `toward` from `value`. Approximate, and enough to leave
|
|
47
|
+
* an exclusive endpoint without rejection-looping a truncated distribution
|
|
48
|
+
* that clamped onto it.
|
|
49
|
+
*/
|
|
50
|
+
export declare function towardInterior(value: number, toward: number): number;
|
|
51
|
+
/**
|
|
52
|
+
* After a closed-interval draw: if the result equals an exclusive endpoint,
|
|
53
|
+
* step one ulp toward the interior. Does not resample — a truncated
|
|
54
|
+
* distribution's mass on the bound would otherwise loop.
|
|
55
|
+
*/
|
|
56
|
+
export declare function constrainContinuous(next: () => number, min: Bound<number>, max: Bound<number>): () => number;
|
|
57
|
+
export declare function epochBound(bound: Bound<Date>): Bound<number>;
|
|
58
|
+
/**
|
|
59
|
+
* Array/string `length`: a bare number is an exact count; an omitted `min`
|
|
60
|
+
* is inclusive `0`. Always stored as a Bound pair so adapters have one path.
|
|
61
|
+
*/
|
|
62
|
+
export declare function toLengthRange(length: number | {
|
|
63
|
+
max: InputBound<number>;
|
|
64
|
+
min?: InputBound<number> | undefined;
|
|
65
|
+
}, label: string): {
|
|
66
|
+
min: Bound<number>;
|
|
67
|
+
max: Bound<number>;
|
|
68
|
+
};
|
|
@@ -0,0 +1,157 @@
|
|
|
1
|
+
import type { Stream } from "../Random/Types";
|
|
2
|
+
/**
|
|
3
|
+
* How randomly generated values cluster within a `{ min, max }` range.
|
|
4
|
+
* Without one, generation is uniform — every value in the range is
|
|
5
|
+
* equally likely.
|
|
6
|
+
*
|
|
7
|
+
* Each variant is a tagged object so distributions stay
|
|
8
|
+
* introspectable and serializable. The `custom` variant is the escape
|
|
9
|
+
* hatch: a shaping function `(u) => p` mapping a uniform draw in
|
|
10
|
+
* `[0, 1)` to a position in `[0, 1)` within the range.
|
|
11
|
+
*/
|
|
12
|
+
export type Distribution = Distribution.Uniform | Distribution.Normal | Distribution.Skew | Distribution.Triangular | Distribution.Logarithmic | Distribution.Multi | Distribution.Custom;
|
|
13
|
+
export type Range = {
|
|
14
|
+
min: number;
|
|
15
|
+
max: number;
|
|
16
|
+
};
|
|
17
|
+
export declare namespace Distribution {
|
|
18
|
+
type Uniform = {
|
|
19
|
+
kind: "uniform";
|
|
20
|
+
};
|
|
21
|
+
const uniform: () => Uniform;
|
|
22
|
+
type Normal = {
|
|
23
|
+
kind: "normal";
|
|
24
|
+
mean?: number | undefined;
|
|
25
|
+
spread?: number | undefined;
|
|
26
|
+
};
|
|
27
|
+
/**
|
|
28
|
+
* Bell curve truncated to the range. `mean` defaults to the range's
|
|
29
|
+
* center; `spread` (standard deviation) defaults to a sixth of the
|
|
30
|
+
* span, placing the bounds at roughly ±3σ before truncation.
|
|
31
|
+
*/
|
|
32
|
+
const normal: (params?: {
|
|
33
|
+
mean?: number;
|
|
34
|
+
spread?: number;
|
|
35
|
+
}) => Normal;
|
|
36
|
+
type Skew = {
|
|
37
|
+
kind: "skew";
|
|
38
|
+
exponent: number;
|
|
39
|
+
};
|
|
40
|
+
/**
|
|
41
|
+
* Power curve. `exponent > 1` biases toward `min`, `exponent < 1`
|
|
42
|
+
* biases toward `max`, and `exponent === 1` is uniform.
|
|
43
|
+
*/
|
|
44
|
+
const skew: (exponent: number) => Distribution;
|
|
45
|
+
type Triangular = {
|
|
46
|
+
kind: "triangular";
|
|
47
|
+
mode?: number | undefined;
|
|
48
|
+
};
|
|
49
|
+
/**
|
|
50
|
+
* Linear ramps peaking at `mode` (defaults to the range's center).
|
|
51
|
+
*/
|
|
52
|
+
const triangular: (params?: {
|
|
53
|
+
mode?: number;
|
|
54
|
+
}) => Distribution;
|
|
55
|
+
type Logarithmic = {
|
|
56
|
+
kind: "logarithmic";
|
|
57
|
+
};
|
|
58
|
+
/**
|
|
59
|
+
* Log-uniform (reciprocal): density proportional to `1/x`, so values
|
|
60
|
+
* spread evenly across orders of magnitude and cluster toward `min`.
|
|
61
|
+
* Requires a strictly positive range — the logarithm is undefined at
|
|
62
|
+
* or below zero.
|
|
63
|
+
*/
|
|
64
|
+
const logarithmic: () => Distribution;
|
|
65
|
+
type Multi = {
|
|
66
|
+
kind: "multi";
|
|
67
|
+
components: ReadonlyArray<{
|
|
68
|
+
weight: number;
|
|
69
|
+
distribution: Distribution;
|
|
70
|
+
}>;
|
|
71
|
+
};
|
|
72
|
+
/**
|
|
73
|
+
* A weighted blend of component distributions, each drawn over the
|
|
74
|
+
* same range. Localized components with distinct centers (e.g. two
|
|
75
|
+
* `normal`s at different means) produce the separate peaks of a
|
|
76
|
+
* multimodal distribution. Weights are relative — they need not sum
|
|
77
|
+
* to 1.
|
|
78
|
+
*/
|
|
79
|
+
const multi: (components: ReadonlyArray<{
|
|
80
|
+
weight: number;
|
|
81
|
+
distribution: Distribution;
|
|
82
|
+
}>) => Distribution;
|
|
83
|
+
type Custom = {
|
|
84
|
+
kind: "custom";
|
|
85
|
+
shape: (u: number) => number;
|
|
86
|
+
};
|
|
87
|
+
/**
|
|
88
|
+
* Escape hatch: `shape` maps a uniform draw in `[0, 1)` to a
|
|
89
|
+
* position in `[0, 1)` within the range (an inverse CDF). The output
|
|
90
|
+
* is clamped to `[0, 1]` so the result always lands within the
|
|
91
|
+
* bounds.
|
|
92
|
+
*/
|
|
93
|
+
const custom: (shape: (u: number) => number) => Distribution;
|
|
94
|
+
}
|
|
95
|
+
/**
|
|
96
|
+
* Build a sampler that draws values within `range` following
|
|
97
|
+
* `distribution`. Each call consumes one fresh uniform draw and, by
|
|
98
|
+
* construction, returns a value within `[min, max]` — distributions
|
|
99
|
+
* with mass outside the range (e.g. a normal's tails) are truncated
|
|
100
|
+
* via their inverse CDF rather than rejected or clamped.
|
|
101
|
+
*/
|
|
102
|
+
export declare function sampler(distribution: Distribution, range: Range, stream: Stream): () => number;
|
|
103
|
+
export declare function sample<$T>(list: ReadonlyArray<$T>, stream: Stream): $T;
|
|
104
|
+
/**
|
|
105
|
+
* Fisher–Yates (Durstenfeld) shuffle: a new array holding `items` in a
|
|
106
|
+
* uniformly random order — every permutation is equally likely. Does
|
|
107
|
+
* not mutate `items`, matching `sample`/`weighted`'s read-only
|
|
108
|
+
* convention.
|
|
109
|
+
*/
|
|
110
|
+
export declare function shuffle<$T>(items: ReadonlyArray<$T>, stream: Stream): $T[];
|
|
111
|
+
/**
|
|
112
|
+
* `weighted()`'s own inclusion rule: whether this entry stays in the
|
|
113
|
+
* draw table. `0` is valid and disables the outcome; negative/`NaN`
|
|
114
|
+
* are rejected earlier by {@link isValidWeight}. Exposed so
|
|
115
|
+
* `Enumeration/Plan.ts` and the construction guards share one
|
|
116
|
+
* definition of "will this be drawn" rather than each writing
|
|
117
|
+
* `weight > 0`.
|
|
118
|
+
*/
|
|
119
|
+
export declare function isDrawable(weight: number): boolean;
|
|
120
|
+
/**
|
|
121
|
+
* Whether a weight is *expressible* at all, as opposed to whether it is
|
|
122
|
+
* drawable. `0` is valid and disables the outcome; a negative weight or
|
|
123
|
+
* `NaN` is a mistake. `Infinity` is rejected because it cannot be summed
|
|
124
|
+
* into a usable draw table — every cumulative bound becomes `Infinity`,
|
|
125
|
+
* so `weighted()`'s `x < weight` scan matches nothing.
|
|
126
|
+
*/
|
|
127
|
+
export declare function isValidWeight(weight: number): boolean;
|
|
128
|
+
/**
|
|
129
|
+
* Outcomes that still have a positive weight after applying the
|
|
130
|
+
* baseline of `1` for any unspecified (missing or explicitly
|
|
131
|
+
* `undefined`) key. The one home of that `?? 1` default, so
|
|
132
|
+
* `assertDrawableKeyedWeights` and `Enumeration/Plan.ts` cannot drift.
|
|
133
|
+
*/
|
|
134
|
+
export declare function drawableOutcomes<$Outcome extends string>(outcomes: ReadonlyArray<$Outcome>, weights: Readonly<Record<string, number | undefined>> | undefined): ReadonlyArray<$Outcome>;
|
|
135
|
+
/**
|
|
136
|
+
* Two-stage guard for a `[weight, item]` list (`enum`/`choice`'s
|
|
137
|
+
* `.weighted()` registries). Stage 1 rejects any entry that is not
|
|
138
|
+
* {@link isValidWeight}; stage 2 rejects a list with no
|
|
139
|
+
* {@link isDrawable} entry left. `label` names the call site
|
|
140
|
+
* (`"T.enum.weighted"`/`"T.choice.weighted"`), `noun` the kind of
|
|
141
|
+
* entry (`"member"`/`"option"`).
|
|
142
|
+
*/
|
|
143
|
+
export declare function assertDrawableWeights(label: string, noun: string, items: ReadonlyArray<readonly [number, unknown]>): void;
|
|
144
|
+
/**
|
|
145
|
+
* The same two-stage guard as {@link assertDrawableWeights}, for the
|
|
146
|
+
* kinds whose `.weighted(...)` weighs a *fixed, named* outcome set
|
|
147
|
+
* (`boolean`'s `true`/`false`; `nullable`/`nullish`/`undefinable`/
|
|
148
|
+
* `object.omittable`/`object.optional`'s presence outcomes) rather than a
|
|
149
|
+
* caller-supplied list. Stage 2 must see the kind's **full** outcome list
|
|
150
|
+
* — an omitted key still defaults to `1` — hence `outcomes`.
|
|
151
|
+
*
|
|
152
|
+
* An explicitly-`undefined` value means "unspecified" — `Weights`'
|
|
153
|
+
* keys are all optional and fall back to a baseline of `1` — so it is
|
|
154
|
+
* skipped in stage 1 and defaulted in stage 2.
|
|
155
|
+
*/
|
|
156
|
+
export declare function assertDrawableKeyedWeights<$Outcome extends string>(label: string, outcomes: ReadonlyArray<$Outcome>, weights: Readonly<Record<string, number | undefined>>): void;
|
|
157
|
+
export declare function weighted<const $Item>(weights: ReadonlyArray<readonly [number, $Item]>, stream: Stream, label: string): () => $Item;
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
import type { Stack } from "../Instance/Types";
|
|
2
|
+
import type { RandomSource } from "../Random/Types";
|
|
3
|
+
import type { Enumerable, Limits } from "./Types";
|
|
4
|
+
/**
|
|
5
|
+
* Typed `combinatorial`/`coverage` boundary, closing over one
|
|
6
|
+
* instance's `source` and its already-validated `limits` — same shape
|
|
7
|
+
* as `Constructor(source, stack)`. No separate `clock`: `source`
|
|
8
|
+
* already carries its resolved clock (`Random/Types.ts`'s
|
|
9
|
+
* `Options.clock`), so `Constructor`'s `toConstructionContext` reads
|
|
10
|
+
* it off whichever root a construction resolves against. `plan`/
|
|
11
|
+
* `resolve` (`./Plan.ts`) do the untyped recursive work; this is the
|
|
12
|
+
* one precisely-typed layer, mirroring `Constructor.ts`'s `make`/
|
|
13
|
+
* `construct` split.
|
|
14
|
+
*
|
|
15
|
+
* Two derived seeds — one per API — each an independent, deterministic
|
|
16
|
+
* fork off the *effective* source's seed (`effectiveSource()` below —
|
|
17
|
+
* the active `wrap` frame's, or this instance's `source`; read fresh
|
|
18
|
+
* on every `combinatorial(...)`/`coverage(...)` call, not once when
|
|
19
|
+
* `enumerables()` was built, so the same `combinatorial` reference
|
|
20
|
+
* behaves differently inside an active `wrap`).
|
|
21
|
+
* `new Fabricator(schema, { seed })` (see `Constructor.ts`'s
|
|
22
|
+
* `construct()`) forks a fully isolated `RandomSource` and opens an
|
|
23
|
+
* `"unattributed"` scope, so `resolveCallerFile()` is never called —
|
|
24
|
+
* the lazy-generator attribution hazard a plain `function*` would
|
|
25
|
+
* invite simply doesn't arise — the instance's construction counters
|
|
26
|
+
* are never touched, and the same seed reproduces regardless of which
|
|
27
|
+
* file `combinatorial(...)`/`coverage(...)` is called from. Each
|
|
28
|
+
* `fork()` starts from a fresh source, so reusing one seed across many
|
|
29
|
+
* builds (different schemas, or the same schema rebuilt per iteration)
|
|
30
|
+
* never lets one build's draws leak into another's.
|
|
31
|
+
*/
|
|
32
|
+
export declare function enumerables(source: RandomSource, limits: Limits, stack: Stack): {
|
|
33
|
+
combinatorial: Enumerable;
|
|
34
|
+
coverage: Enumerable;
|
|
35
|
+
};
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
import type { Axis, Orderer, Pin, Resolvable } from "./Types";
|
|
2
|
+
type Planning = {
|
|
3
|
+
strategy: "product";
|
|
4
|
+
orderer?: Orderer | undefined;
|
|
5
|
+
} | {
|
|
6
|
+
strategy: "cycle";
|
|
7
|
+
orderer: Orderer;
|
|
8
|
+
};
|
|
9
|
+
/**
|
|
10
|
+
* Enumerable shape of a built Fabricator tree: how many distinct
|
|
11
|
+
* combinations, and how to reproduce the `index`-th as a `Pin`.
|
|
12
|
+
* Exhaustive kind dispatch lives in `axisFor`; this wrapper applies
|
|
13
|
+
* `"cycle"` permutation uniformly, once, to whatever axis `axisFor`
|
|
14
|
+
* computes — so every recursive call (`axisFor` cases call back into
|
|
15
|
+
* `plan`, never `axisFor` directly) gets its *own* independent
|
|
16
|
+
* permutation, decorrelating equal-width siblings without any
|
|
17
|
+
* per-kind case needing to know strategy beyond `Strategy`'s own
|
|
18
|
+
* widen/narrow rules.
|
|
19
|
+
*
|
|
20
|
+
* Width is a function of schema shape *and* weights: a zero-weighted
|
|
21
|
+
* outcome is not fabricable, so `axisFor` filters through `isDrawable`
|
|
22
|
+
* / `drawableOutcomes` rather than treating the declared branch set as
|
|
23
|
+
* the axis. Without that, `coverage()` would pin a value `fabricate()`
|
|
24
|
+
* can never produce. Defaulting of unspecified keyed weights goes
|
|
25
|
+
* through `drawableOutcomes` so the `?? 1` baseline is never
|
|
26
|
+
* re-implemented here.
|
|
27
|
+
*
|
|
28
|
+
* Skipped for width-1 axes (nothing to permute) and under `"product"`
|
|
29
|
+
* (mixed-radix decode already visits every combination, so permuting
|
|
30
|
+
* would only reorder identical output — see `Orderer`). `orders` is
|
|
31
|
+
* therefore only ever read when `strategy === "cycle"` and is safe to
|
|
32
|
+
* omit otherwise.
|
|
33
|
+
*/
|
|
34
|
+
export declare function plan(node: Resolvable, planning: Planning): Axis;
|
|
35
|
+
/**
|
|
36
|
+
* Reproduce the value a `Pin` describes against the built Fabricator
|
|
37
|
+
* it was planned from. `pin === undefined` is universal — `plan()`
|
|
38
|
+
* gave this node a width-1 axis, so there is nothing to pin and it
|
|
39
|
+
* fabricates normally. Every other case only arises for kinds
|
|
40
|
+
* `plan()` treats as enumerable axes, so this switch does not need to
|
|
41
|
+
* be exhaustive the way `plan()`'s is.
|
|
42
|
+
*/
|
|
43
|
+
export declare function resolve(node: Resolvable, pin: Pin): unknown;
|
|
44
|
+
export {};
|
|
@@ -0,0 +1,86 @@
|
|
|
1
|
+
import type { Kind as SchemaKind } from "../Primitive";
|
|
2
|
+
import type { AnySchema, ValueOf } from "../Schema/Types";
|
|
3
|
+
import type { Children, Kind, Meta } from "../Types";
|
|
4
|
+
import type { PlainObject } from "../Utility/Types";
|
|
5
|
+
/**
|
|
6
|
+
* How a composite with more than one child combines their widths.
|
|
7
|
+
* `"product"` is the cartesian product — width is the product of every
|
|
8
|
+
* child's width; `at(index)` mixed-radix decodes to a full combination
|
|
9
|
+
* (`combinatorial`). `"cycle"` (`coverage`) takes the widest child as
|
|
10
|
+
* the composite's width, cycling narrower children to fill it — see
|
|
11
|
+
* CLAUDE.md's "sum vs product" note for why cycling only ever applies
|
|
12
|
+
* to `object`/`tuple` and never to a sum node (`choice`, the presence
|
|
13
|
+
* wrappers), which always total their children's widths regardless of
|
|
14
|
+
* strategy.
|
|
15
|
+
*/
|
|
16
|
+
export type Strategy = "product" | "cycle";
|
|
17
|
+
/**
|
|
18
|
+
* A fresh, reproducible permutation of `0..width-1` each call — one
|
|
19
|
+
* per width-`>1` node `plan()` visits, in walk order, so two nodes of
|
|
20
|
+
* the same width never receive the same permutation (which would
|
|
21
|
+
* otherwise iterate them in lockstep — see CLAUDE.md's note on why a
|
|
22
|
+
* constant phase offset isn't enough). Only consulted under `"cycle"`;
|
|
23
|
+
* `"product"`'s mixed-radix decode already visits every combination,
|
|
24
|
+
* so permuting there would only reorder identical output. Built in
|
|
25
|
+
* `Enumerate.ts` (which can reach `Random/`), then threaded through
|
|
26
|
+
* `plan()` as data — `Plan.ts` stays a total function and never
|
|
27
|
+
* imports randomness.
|
|
28
|
+
*/
|
|
29
|
+
export type Orderer = (width: bigint) => ReadonlyArray<bigint>;
|
|
30
|
+
/**
|
|
31
|
+
* Recipe for one enumerated combination against a built Fabricator
|
|
32
|
+
* tree: `undefined` for a drawn (not chosen) node — fabricate
|
|
33
|
+
* normally; `{ value }` for a literal (enum member, boolean, `null`,
|
|
34
|
+
* `undefined`, `Omitted`); `{ slots }`/`{ fields }` for a
|
|
35
|
+
* tuple/object, recursing per position/key; `{ branch, inner }` for a
|
|
36
|
+
* choice's chosen option, or a presence wrapper's "present" arm,
|
|
37
|
+
* recursing into whichever child was picked.
|
|
38
|
+
*/
|
|
39
|
+
export type Pin = undefined | {
|
|
40
|
+
value: unknown;
|
|
41
|
+
} | {
|
|
42
|
+
slots: ReadonlyArray<Pin>;
|
|
43
|
+
} | {
|
|
44
|
+
fields: Record<string, Pin>;
|
|
45
|
+
} | {
|
|
46
|
+
branch: number;
|
|
47
|
+
inner: Pin;
|
|
48
|
+
};
|
|
49
|
+
/**
|
|
50
|
+
* One enumerable dimension: how many distinct outcomes, and the `Pin`
|
|
51
|
+
* for the `index`-th (`0 <= index < width`). Widths are `bigint` so a
|
|
52
|
+
* schema with many combined axes can be counted exactly — a `number`
|
|
53
|
+
* would silently lose precision past `Number.MAX_SAFE_INTEGER` and
|
|
54
|
+
* eventually overflow to `Infinity`, which would make a combinatorial
|
|
55
|
+
* limit's error message state a false count.
|
|
56
|
+
*/
|
|
57
|
+
export type Axis = {
|
|
58
|
+
readonly width: bigint;
|
|
59
|
+
readonly at: (index: bigint) => Pin;
|
|
60
|
+
};
|
|
61
|
+
/**
|
|
62
|
+
* Resolved, already-validated enumeration limits — `initialize()` is
|
|
63
|
+
* where `limits.combinatorial` is defaulted and checked
|
|
64
|
+
* (`Number.isSafeInteger(limit) && limit >= 1`), so `Enumerate()`
|
|
65
|
+
* always receives a value it can trust without re-validating.
|
|
66
|
+
* `coverage` carries no limit here: its count is the widest single
|
|
67
|
+
* axis, linear in the schema as written rather than a product, so
|
|
68
|
+
* there is nothing for a limit to protect against.
|
|
69
|
+
*/
|
|
70
|
+
export type Limits = {
|
|
71
|
+
combinatorial: number;
|
|
72
|
+
};
|
|
73
|
+
/**
|
|
74
|
+
* The shape both `combinatorial` and `coverage` share — strategy and
|
|
75
|
+
* limit differ internally, neither visible here. Takes a Schema, not
|
|
76
|
+
* a built Fabricator: `AnySchema` excludes `Fabricator<any>` (which
|
|
77
|
+
* carries no `[Produces]`), so `ValueOf` can't silently degrade to
|
|
78
|
+
* `unknown`.
|
|
79
|
+
*/
|
|
80
|
+
export type Enumerable = <const $Schema extends AnySchema>(schema: $Schema) => Iterable<ValueOf<$Schema>>;
|
|
81
|
+
export type Resolvable = {
|
|
82
|
+
[Kind]: SchemaKind;
|
|
83
|
+
[Meta]: PlainObject<any>;
|
|
84
|
+
[Children]: any;
|
|
85
|
+
fabricate: (...params: any[]) => unknown;
|
|
86
|
+
};
|